From ca718dd359bab60057e6df1256324291efd05546 Mon Sep 17 00:00:00 2001 From: Guillaume Humbert Date: Thu, 9 Mar 2023 14:52:19 +0100 Subject: [PATCH 1/5] Remove LTS configs other than the base one --- README.md | 28 -------- bases/node-lts-strictest-esm.combined.json | 31 --------- bases/node-lts-strictest.combined.json | 31 --------- scripts/generate-lts.ts | 74 ++++------------------ 4 files changed, 11 insertions(+), 153 deletions(-) delete mode 100644 bases/node-lts-strictest-esm.combined.json delete mode 100644 bases/node-lts-strictest.combined.json diff --git a/README.md b/README.md index 0bad833..6a53068 100644 --- a/README.md +++ b/README.md @@ -132,34 +132,6 @@ Add to your `tsconfig.json`: ```json "extends": "@tsconfig/next/tsconfig.json" ``` -### Node LTS + ESM + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node-lts-strictest-esm -yarn add --dev @tsconfig/node-lts-strictest-esm -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node-lts-strictest-esm/tsconfig.json" -``` -### Node LTS + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node-lts-strictest -yarn add --dev @tsconfig/node-lts-strictest -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node-lts-strictest/tsconfig.json" -``` ### Node LTS tsconfig.json Install: diff --git a/bases/node-lts-strictest-esm.combined.json b/bases/node-lts-strictest-esm.combined.json deleted file mode 100644 index d95a4cd..0000000 --- a/bases/node-lts-strictest-esm.combined.json +++ /dev/null @@ -1,31 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends esm extends node18 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node LTS + ESM + Strictest", - "_version": "18.12.1", - "compilerOptions": { - "lib": [ - "es2022" - ], - "module": "es2022", - "target": "es2022", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/bases/node-lts-strictest.combined.json b/bases/node-lts-strictest.combined.json deleted file mode 100644 index 41cbb38..0000000 --- a/bases/node-lts-strictest.combined.json +++ /dev/null @@ -1,31 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends node18 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node LTS + Strictest", - "_version": "18.12.1", - "compilerOptions": { - "lib": [ - "es2022" - ], - "module": "commonjs", - "target": "es2022", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/scripts/generate-lts.ts b/scripts/generate-lts.ts index e23300c..10ad743 100644 --- a/scripts/generate-lts.ts +++ b/scripts/generate-lts.ts @@ -15,12 +15,6 @@ interface NodeReleaseMetadata { security: boolean; } -type CombinedConfigInput = { - base: string; - extends: [...string[]]; - name: string; -}; - type Tsconfig = Record; const versionRegex = /v(\d+)\.(\d+)\.(\d+)/; @@ -45,74 +39,28 @@ const lts = releasesJson ); const baseMajorVersion = (lts.version.match(versionRegex) || [])[1]; const base = `node${baseMajorVersion}`; -const name = "node-lts"; const versioned = { $schema: "https://json.schemastore.org/tsconfig", display: "Node LTS", _version: lts.version.substring(lts.version.indexOf("v") + 1) }; -const inputs: CombinedConfigInput[] = [ - { base, extends: ["esm", "strictest"], name }, - { base, extends: ["strictest"], name }, - { base, extends: [], name } -]; - import * as path from "https://deno.land/std/path/mod.ts"; import stripJsonComments from "https://esm.sh/strip-json-comments"; import { deepMerge } from "https://deno.land/std/collections/deep_merge.ts"; -function merge(configs: readonly Tsconfig[]): Tsconfig { - let result: Tsconfig = {}; - - for (const config of configs) { - result = deepMerge(result, config); - } - - result.display = configs.map((x) => x.display).join(" + "); - - return result; -} +const packageText = await Deno.readTextFile(path.join(Deno.cwd(), "bases", `${base}.json`)); -function writeCombinedConfig(input: CombinedConfigInput, config: Tsconfig): Promise { - const filePath = - input.extends.length > 0 - ? path.join(Deno.cwd(), "bases", `${input.name}-${[...input.extends].reverse().join("-")}.combined.json`) - : path.join(Deno.cwd(), "bases", `${input.name}.json`); - const serializedConfig = - "// This file was autogenerated by a script\n" + - `// Equivalent to a config of: ${[input.base, ...input.extends].reverse().join(" extends ")}\n` + - JSON.stringify(config, null, " "); - - return Deno.writeTextFile(filePath, serializedConfig); -} +const parsed = JSON.parse(stripJsonComments(packageText)) as Tsconfig; -const configCache: Map = new Map(); +// This is to get the _version property to show up directly under the display property +const parsedAndOrdered = deepMerge(versioned, parsed); +parsedAndOrdered.display = versioned.display; -// Populate configs cache -for (const input of new Set(inputs.map((x) => [x.base, x.extends]).flat(2))) { - const packageText = await Deno.readTextFile(path.join(Deno.cwd(), "bases", `${input}.json`)); - - const parsed = JSON.parse(stripJsonComments(packageText)) as Tsconfig; - - // This is to get the _version property to show up directly under the display property - configCache.set(input, deepMerge(versioned, parsed)); -} - -const mergedConfigs: Map = new Map(); - -for (const input of inputs) { - const configs = [input.base, ...input.extends].map((name) => { - const c = configCache.get(name)!; - if (name === input.base) { - c.display = "Node LTS"; - } - return c; - }); - - const merged = merge(configs); - - mergedConfigs.set(input, merged); -} +const serializedConfig = + "// This file was autogenerated by a script\n" + + `// Equivalent to a config of: ${base}\n` + + JSON.stringify(parsedAndOrdered, null, " "); -await Promise.all([...mergedConfigs].map(([names, config]) => writeCombinedConfig(names, config))); +const filePath = path.join(Deno.cwd(), "bases/node-lts.json"); +Deno.writeTextFile(filePath, serializedConfig); From 0ae4791797d8ba3dd2bca9aca880eb2d3e30e6fb Mon Sep 17 00:00:00 2001 From: Guillaume Humbert Date: Thu, 9 Mar 2023 14:57:55 +0100 Subject: [PATCH 2/5] Remove all combined configs --- README.md | 70 --------------------- bases/next-strictest.json | 31 --------- bases/node16-strictest-esm.combined.json | 30 --------- bases/node16-strictest.combined.json | 30 --------- bases/node18-strictest-esm.combined.json | 30 --------- bases/node18-strictest.combined.json | 30 --------- scripts/create-npm-packages.ts | 2 +- scripts/generate-combined.ts | 80 ------------------------ scripts/update-markdown-readme.ts | 2 +- 9 files changed, 2 insertions(+), 303 deletions(-) delete mode 100644 bases/next-strictest.json delete mode 100644 bases/node16-strictest-esm.combined.json delete mode 100644 bases/node16-strictest.combined.json delete mode 100644 bases/node18-strictest-esm.combined.json delete mode 100644 bases/node18-strictest.combined.json delete mode 100644 scripts/generate-combined.ts diff --git a/README.md b/README.md index 6a53068..090fb9d 100644 --- a/README.md +++ b/README.md @@ -104,20 +104,6 @@ Add to your `tsconfig.json`: ```json "extends": "@tsconfig/esm/tsconfig.json" ``` -### Next.js + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/next-strictest -yarn add --dev @tsconfig/next-strictest -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/next-strictest/tsconfig.json" -``` ### Next.js tsconfig.json Install: @@ -188,34 +174,6 @@ Add to your `tsconfig.json`: ```json "extends": "@tsconfig/node14/tsconfig.json" ``` -### Node 16 + ESM + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node16-strictest-esm -yarn add --dev @tsconfig/node16-strictest-esm -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node16-strictest-esm/tsconfig.json" -``` -### Node 16 + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node16-strictest -yarn add --dev @tsconfig/node16-strictest -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node16-strictest/tsconfig.json" -``` ### Node 16 tsconfig.json Install: @@ -244,34 +202,6 @@ Add to your `tsconfig.json`: ```json "extends": "@tsconfig/node17/tsconfig.json" ``` -### Node 18 + ESM + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node18-strictest-esm -yarn add --dev @tsconfig/node18-strictest-esm -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node18-strictest-esm/tsconfig.json" -``` -### Node 18 + Strictest tsconfig.json - -Install: - -```sh -npm install --save-dev @tsconfig/node18-strictest -yarn add --dev @tsconfig/node18-strictest -``` - -Add to your `tsconfig.json`: - -```json -"extends": "@tsconfig/node18-strictest/tsconfig.json" -``` ### Node 18 tsconfig.json Install: diff --git a/bases/next-strictest.json b/bases/next-strictest.json deleted file mode 100644 index d7e1115..0000000 --- a/bases/next-strictest.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Next.js + Strictest", - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "incremental": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve" - } -} diff --git a/bases/node16-strictest-esm.combined.json b/bases/node16-strictest-esm.combined.json deleted file mode 100644 index 84733aa..0000000 --- a/bases/node16-strictest-esm.combined.json +++ /dev/null @@ -1,30 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends esm extends node16 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node 16 + ESM + Strictest", - "compilerOptions": { - "lib": [ - "es2021" - ], - "module": "es2022", - "target": "es2021", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/bases/node16-strictest.combined.json b/bases/node16-strictest.combined.json deleted file mode 100644 index 677adb9..0000000 --- a/bases/node16-strictest.combined.json +++ /dev/null @@ -1,30 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends node16 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node 16 + Strictest", - "compilerOptions": { - "lib": [ - "es2021" - ], - "module": "commonjs", - "target": "es2021", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/bases/node18-strictest-esm.combined.json b/bases/node18-strictest-esm.combined.json deleted file mode 100644 index 8fe5854..0000000 --- a/bases/node18-strictest-esm.combined.json +++ /dev/null @@ -1,30 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends esm extends node18 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node 18 + ESM + Strictest", - "compilerOptions": { - "lib": [ - "es2022" - ], - "module": "es2022", - "target": "es2022", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/bases/node18-strictest.combined.json b/bases/node18-strictest.combined.json deleted file mode 100644 index 9634d95..0000000 --- a/bases/node18-strictest.combined.json +++ /dev/null @@ -1,30 +0,0 @@ -// This file was autogenerated by a script -// Equivalent to a config of: strictest extends node18 -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Node 18 + Strictest", - "compilerOptions": { - "lib": [ - "es2022" - ], - "module": "commonjs", - "target": "es2022", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "importsNotUsedAsValues": "error", - "checkJs": true - } -} \ No newline at end of file diff --git a/scripts/create-npm-packages.ts b/scripts/create-npm-packages.ts index d0b3d43..19fc831 100644 --- a/scripts/create-npm-packages.ts +++ b/scripts/create-npm-packages.ts @@ -5,7 +5,7 @@ for await (const tsconfigEntry of Deno.readDir("bases")) { if (!tsconfigEntry.isFile) continue const tsconfigFilePath = path.join("bases", tsconfigEntry.name) - const name = path.basename(tsconfigEntry.name).replace(".json", "").replace(".combined", "") + const name = path.basename(tsconfigEntry.name).replace(".json", "") // Make the folder const packagePath = path.join("packages", name) diff --git a/scripts/generate-combined.ts b/scripts/generate-combined.ts deleted file mode 100644 index 6cc69c4..0000000 --- a/scripts/generate-combined.ts +++ /dev/null @@ -1,80 +0,0 @@ -// deno run --allow-read --allow-write scripts/generate-combined.ts -// - -const inputs: CombinedConfigInput[] = [ - { base: "node16", extends: ["esm", "strictest"] }, - { base: "node16", extends: ["strictest"] }, - { base: "node18", extends: ["esm", "strictest"] }, - { base: "node18", extends: ["strictest"] }, -]; - -import * as path from "https://deno.land/std/path/mod.ts"; -import stripJsonComments from "https://esm.sh/strip-json-comments"; -import { deepMerge } from "https://deno.land/std/collections/deep_merge.ts"; - -type CombinedConfigInput = { - base: string; - extends: [string, ...string[]]; -}; -type Tsconfig = Record; - -function merge(configs: readonly Tsconfig[]): Tsconfig { - let result: Tsconfig = {}; - - for (const config of configs) { - result = deepMerge(result, config); - } - - result.display = configs.map((x) => x.display).join(" + "); - - return result; -} - -async function writeCombinedConfig( - input: CombinedConfigInput, - config: Tsconfig, -): Promise { - const filePath = path.join( - Deno.cwd(), - "bases", - `${input.base}-${[...input.extends].reverse().join("-")}.combined.json`, - ); - const serializedConfig = "// This file was autogenerated by a script\n" + - `// Equivalent to a config of: ${ - [input.base, ...input.extends].reverse().join(" extends ") - }\n` + - JSON.stringify(config, null, " "); - - return Deno.writeTextFile(filePath, serializedConfig); -} - -const configCache: Map = new Map(); - -// Populate configs cache -for (const input of new Set(inputs.map((x) => [x.base, x.extends]).flat(2))) { - const packageText = await Deno.readTextFile( - path.join(Deno.cwd(), "bases", `${input}.json`), - ); - - const parsed = JSON.parse(stripJsonComments(packageText)) as Tsconfig; - - configCache.set(input, parsed); -} - -const mergedConfigs: Map = new Map(); - -for (const input of inputs) { - const configs = [input.base, ...input.extends].map((name) => - configCache.get(name)! - ); - - const merged = merge(configs); - - mergedConfigs.set(input, merged); -} - -await Promise.all( - [...mergedConfigs].map(([names, config]) => - writeCombinedConfig(names, config) - ), -); diff --git a/scripts/update-markdown-readme.ts b/scripts/update-markdown-readme.ts index a06b20f..d26f6c8 100644 --- a/scripts/update-markdown-readme.ts +++ b/scripts/update-markdown-readme.ts @@ -16,7 +16,7 @@ const sortedPaths = paths.sort((l, r) => l.localeCompare(r)).filter(r => !r.incl const basePaths = ["recommended.json", ...sortedPaths] for (const base of basePaths) { const tsconfigFilePath = path.join("bases", base) - const name = path.basename(base).replace(".json", "").replace(".combined", "") + const name = path.basename(base).replace(".json", "") const tsconfigText = await Deno.readTextFile(tsconfigFilePath) const tsconfigJSON = JSON.parse(stripJsonComments(tsconfigText)) From 4ca4143cb9fe2808ca14a253c85aa3f6ac70dc7c Mon Sep 17 00:00:00 2001 From: Guillaume Humbert Date: Thu, 9 Mar 2023 15:07:41 +0100 Subject: [PATCH 3/5] Add a note to the README about combined configs --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 090fb9d..d818d30 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,24 @@ Add to your `tsconfig.json`: +### What about combined configs? + +Because of previous limitations in the config extension system of TypeScript, +this repo used to provide combined configs from a few common bases (like Node + ESM, +Node + Strictest and so on). + +This issue is now moot since TypeScript v5.0.0, which provides the [ability to +extend from multiple configs at once](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-rc/#supporting-multiple-configuration-files-in-extends). For instance, if you want +to start from a Node 18 + Strictest base config, you can install both +`@tsconfig/node18` and `@tsconfig/strictest` packages and extend those configs like so: + +```jsonc +// tsconfig.json +{ + "extends": ["@tsconfig/strictest/tsconfig", "@tsconfig/node18/tsconfig"] +} +``` + ### Contributing ```sh From 00fa4eeb82d0cd700df26ba5f7e0ec011781adb1 Mon Sep 17 00:00:00 2001 From: Guillaume Humbert Date: Thu, 9 Mar 2023 15:09:36 +0100 Subject: [PATCH 4/5] Use new `verbatimModuleSyntax` setting for TS v5 --- bases/strictest.json | 2 +- bases/svelte.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bases/strictest.json b/bases/strictest.json index 8ade1b3..61559d0 100644 --- a/bases/strictest.json +++ b/bases/strictest.json @@ -12,7 +12,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, - "importsNotUsedAsValues": "error", + "verbatimModuleSyntax": true, "checkJs": true, "esModuleInterop": true, diff --git a/bases/svelte.json b/bases/svelte.json index 21b0613..bc4a426 100644 --- a/bases/svelte.json +++ b/bases/svelte.json @@ -10,7 +10,7 @@ Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript to enforce using `import type` instead of `import` for Types. */ - "importsNotUsedAsValues": "error", + "verbatimModuleSyntax": true, /** TypeScript doesn't know about import usages in the template because it only sees the script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher. From f96211418bc5b68c8fed636eaf4020486eb26a8a Mon Sep 17 00:00:00 2001 From: Guillaume Humbert Date: Fri, 24 Mar 2023 18:06:25 +0100 Subject: [PATCH 5/5] Bump major version of impacted configs --- bases/strictest.json | 3 ++- bases/svelte.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bases/strictest.json b/bases/strictest.json index 61559d0..3fa08a3 100644 --- a/bases/strictest.json +++ b/bases/strictest.json @@ -20,5 +20,6 @@ "forceConsistentCasingInFileNames": true }, "$schema": "https://json.schemastore.org/tsconfig", - "display": "Strictest" + "display": "Strictest", + "_version": "2.0.0" } diff --git a/bases/svelte.json b/bases/svelte.json index bc4a426..90bb5ba 100644 --- a/bases/svelte.json +++ b/bases/svelte.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/tsconfig", "display": "Svelte", - "_version": "3.0.0", + "_version": "4.0.0", "compilerOptions": { "moduleResolution": "node",