From c4490f233db92374ebbd23817d575a7beb82e31c Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 8 Jul 2021 18:42:35 +0300 Subject: [PATCH] add an option to use type keyword instead of an interface --- README.md | 19 +++++++++----- packages/extension/package-lock.json | 26 +++++++------------ packages/extension/package.json | 14 ++++++++-- packages/extension/src/config.ts | 3 +++ packages/extension/src/listener.ts | 9 ++++++- .../transforms/samplesToType/index.test.ts | 6 +++++ .../src/transforms/samplesToType/index.ts | 15 ++++++++--- packages/runtime/package-lock.json | 10 ++----- packages/runtime/package.json | 2 +- 9 files changed, 66 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 8f10a49..b40f2a8 100644 --- a/README.md +++ b/README.md @@ -84,12 +84,13 @@ From 1.4.0 forward also Promises are supported. All other values (functions etc. ## Extension Settings -| Setting | Type | Default | Description | -| ------------------------------- | ----------- | ------- | ------------------------------------------------------------------------------- | -| typehole.runtime.autoInstall | boolean | true | Install Typehole runtime package automatically when the first typehole is added | -| typehole.runtime.projectPath | string | | Project directory where Typehole runtime should be installed | -| typehole.runtime.packageManager | npm \| yarn | npm | Package manager to be used when installing the runtime | -| typehole.runtime.extensionPort | number | 17341 | HTTP port for HTTP extension to listen for incoming samples | +| Setting | Type | Default | Description | +| ------------------------------- | ----------------- | --------- | ------------------------------------------------------------------------------- | +| typehole.runtime.autoInstall | boolean | true | Install Typehole runtime package automatically when the first typehole is added | +| typehole.runtime.projectPath | string | | Project directory where Typehole runtime should be installed | +| typehole.runtime.packageManager | npm \| yarn | npm | Package manager to be used when installing the runtime | +| typehole.runtime.extensionPort | number | 17341 | HTTP port for HTTP extension to listen for incoming samples | +| typehole.typeOrInterface | interface \| type | interface | Keyword to be used for generated types | ## Runtime @@ -134,6 +135,12 @@ configure({ ## Release Notes +## [1.7.0] - 2021-07-08 + +### Added + +- New option "typehole.typeOrInterface" added for using `type` keyword instead of `interface`. All thanks to @akafaneh ๐ŸŽ‰ + ## [1.6.3] - 2021-06-20 ### Fixed diff --git a/packages/extension/package-lock.json b/packages/extension/package-lock.json index 123ac87..596d721 100644 --- a/packages/extension/package-lock.json +++ b/packages/extension/package-lock.json @@ -1,15 +1,15 @@ { "name": "typehole", - "version": "1.6.3", + "version": "1.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typehole", - "version": "1.6.3", + "version": "1.8.0", "dependencies": { "@phenomnomnominal/tsquery": "^4.1.1", - "@riku/json-to-ts": "^2.0.0", + "@riku/json-to-ts": "^2.1.0", "@types/esquery": "^1.0.1", "@types/npm": "^2.0.31", "esquery": "^1.4.0", @@ -823,7 +823,6 @@ "jest-resolve": "^26.6.2", "jest-util": "^26.6.2", "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -968,9 +967,9 @@ } }, "node_modules/@riku/json-to-ts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@riku/json-to-ts/-/json-to-ts-2.0.0.tgz", - "integrity": "sha512-0QhQ3BTDtBCkhESGqbqNBLBMBv/GzKkpzVq3Ew022pTTaj12PFCdoSAXhodueeDkvrBNr1+Pd3rtf3XkDUU10Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@riku/json-to-ts/-/json-to-ts-2.1.0.tgz", + "integrity": "sha512-BbXMw3UQlfRBNvLRWMrNyXXA0lZZkCXO2u3Wruy4jQOlAKNHc+7eoGEYZwPSz8FR5gwJVW/NQzHMhGh7w24Sqg==", "dependencies": { "es7-shim": "^6.0.0", "hash.js": "^1.0.3", @@ -2676,8 +2675,7 @@ "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -4600,7 +4598,6 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -5099,7 +5096,6 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dependencies": { - "graceful-fs": "^4.1.6", "universalify": "^2.0.0" }, "optionalDependencies": { @@ -6311,7 +6307,6 @@ "inBundle": true, "license": "MIT", "dependencies": { - "colors": "^1.1.2", "object-assign": "^4.1.0", "string-width": "^4.2.0" }, @@ -7285,7 +7280,6 @@ "inBundle": true, "license": "MIT", "dependencies": { - "encoding": "^0.1.12", "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" @@ -11971,9 +11965,9 @@ } }, "@riku/json-to-ts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@riku/json-to-ts/-/json-to-ts-2.0.0.tgz", - "integrity": "sha512-0QhQ3BTDtBCkhESGqbqNBLBMBv/GzKkpzVq3Ew022pTTaj12PFCdoSAXhodueeDkvrBNr1+Pd3rtf3XkDUU10Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@riku/json-to-ts/-/json-to-ts-2.1.0.tgz", + "integrity": "sha512-BbXMw3UQlfRBNvLRWMrNyXXA0lZZkCXO2u3Wruy4jQOlAKNHc+7eoGEYZwPSz8FR5gwJVW/NQzHMhGh7w24Sqg==", "requires": { "es7-shim": "^6.0.0", "hash.js": "^1.0.3", diff --git a/packages/extension/package.json b/packages/extension/package.json index 4cdabdb..7f20b97 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -4,7 +4,7 @@ "publisher": "rikurouvila", "description": "๐Ÿงช Take samples of runtime values and turn them into type definitions automatically", "repository": "https://github.com/rikukissa/typehole", - "version": "1.6.3", + "version": "1.8.0", "private": true, "icon": "images/logo.png", "galleryBanner": { @@ -32,6 +32,16 @@ "description": "Installs Typehole runtime package automatically when the first typehole is added", "scope": "window" }, + "typehole.typeOrInterface": { + "type": "string", + "enum": [ + "type", + "interface" + ], + "default": "interface", + "description": "Keyword to be used for generated types", + "scope": "window" + }, "typehole.runtime.extensionPort": { "type": "number", "default": 17341, @@ -99,7 +109,7 @@ }, "dependencies": { "@phenomnomnominal/tsquery": "^4.1.1", - "@riku/json-to-ts": "^2.0.0", + "@riku/json-to-ts": "^2.1.0", "@types/esquery": "^1.0.1", "@types/npm": "^2.0.31", "esquery": "^1.4.0", diff --git a/packages/extension/src/config.ts b/packages/extension/src/config.ts index 78bc279..ff8dd30 100644 --- a/packages/extension/src/config.ts +++ b/packages/extension/src/config.ts @@ -11,6 +11,9 @@ export function getConfiguration( extensionPort: configuration.get( "typehole.runtime.extensionPort" ) as number, + typeOrInterface: configuration.get("typehole.typeOrInterface") as + | "interface" + | "type", autoInstall: configuration.get("typehole.runtime.autoInstall") as boolean, projectPath: configuration.get("typehole.runtime.projectPath") as string, packageManager: configuration.get( diff --git a/packages/extension/src/listener.ts b/packages/extension/src/listener.ts index 82b7f47..89a893a 100644 --- a/packages/extension/src/listener.ts +++ b/packages/extension/src/listener.ts @@ -3,6 +3,7 @@ import f from "fastify"; import * as ts from "typescript"; import * as vscode from "vscode"; +import { getConfiguration } from "./config"; import { getEditorRange, getProjectRoot } from "./editor/utils"; import { error, log } from "./logger"; @@ -37,8 +38,14 @@ function createServer() { const body = request.body as any; log(body.id, "-", "New sample", JSON.stringify(request.body), "received"); + const editor = vscode.window.activeTextEditor; + const document = editor?.document; + const config = getConfiguration("", document); + const samples = addSample(body.id, body.sample); - const typeString = samplesToType(samples); + const typeString = samplesToType(samples, { + useTypeAlias: config.typeOrInterface === "type", + }); try { await onTypeExtracted(body.id, typeString); diff --git a/packages/extension/src/transforms/samplesToType/index.test.ts b/packages/extension/src/transforms/samplesToType/index.test.ts index d8e41d8..8486192 100644 --- a/packages/extension/src/transforms/samplesToType/index.test.ts +++ b/packages/extension/src/transforms/samplesToType/index.test.ts @@ -5,6 +5,12 @@ test("generates types and interfaces from samples", () => { `type TypeholeRoot = (boolean | TypeholeRootWrapper2 | null | number); interface TypeholeRootWrapper2 { a: number; +}` + ); + expect(samplesToType([1, { a: 2 }, true, null], { useTypeAlias: true })).toBe( + `type TypeholeRoot = (boolean | TypeholeRootWrapper2 | null | number); +type TypeholeRootWrapper2 = { + a: number; }` ); expect(samplesToType([{ a: 2 }])).toBe( diff --git a/packages/extension/src/transforms/samplesToType/index.ts b/packages/extension/src/transforms/samplesToType/index.ts index 5ddd8e6..bf53de9 100644 --- a/packages/extension/src/transforms/samplesToType/index.ts +++ b/packages/extension/src/transforms/samplesToType/index.ts @@ -1,6 +1,10 @@ import json2ts from "@riku/json-to-ts"; +import { Options } from "@riku/json-to-ts/build/src/model"; -export function samplesToType(samples: any[]): string { +export function samplesToType( + samples: any[], + jsonToTSOptions?: Options +): string { let wrapperType = null; let samplesWithoutWrapperTypes = []; for (const sample of samples) { @@ -13,9 +17,12 @@ export function samplesToType(samples: any[]): string { } // eslint-disable-next-line @typescript-eslint/naming-convention - const types = json2ts({ - __typeholeRootWrapper__: samplesWithoutWrapperTypes, - }).join("\n"); + const types = json2ts( + { + __typeholeRootWrapper__: samplesWithoutWrapperTypes, + }, + jsonToTSOptions + ).join("\n"); let root = types .match(/__typeholeRootWrapper__:\s(.+)/)![1] diff --git a/packages/runtime/package-lock.json b/packages/runtime/package-lock.json index d1f9f95..f4d9038 100644 --- a/packages/runtime/package-lock.json +++ b/packages/runtime/package-lock.json @@ -1,12 +1,12 @@ { "name": "typehole", - "version": "1.6.3", + "version": "1.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typehole", - "version": "1.6.3", + "version": "1.7.0", "license": "MIT", "dependencies": { "@types/isomorphic-fetch": "0.0.35", @@ -365,9 +365,6 @@ "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.6" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -522,9 +519,6 @@ "version": "2.21.0", "dev": true, "license": "MIT", - "dependencies": { - "fsevents": "~2.1.2" - }, "bin": { "rollup": "dist/bin/rollup" }, diff --git a/packages/runtime/package.json b/packages/runtime/package.json index d545353..ef06ee8 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,5 +1,5 @@ { - "version": "1.6.3", + "version": "1.7.0", "name": "typehole", "repository": "rikukissa/typehole", "description": "Turn runtime types into static typescript types automatically",