diff --git a/.npmignore b/.npmignore index 9d7dfff..578b5bd 100644 --- a/.npmignore +++ b/.npmignore @@ -10,6 +10,5 @@ src/ .node-version cspell.json lefthook.yml -.sortpackagerc.json LICENSE commit-message-template \ No newline at end of file diff --git a/.sortpackagerc.json b/.sortpackagerc.json deleted file mode 100644 index e403d3c..0000000 --- a/.sortpackagerc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/sort-package-json.json" -} diff --git a/README.md b/README.md index 536b3e2..e32bea3 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,8 @@ Pattern matching for TypeScript/ESM environments (F#-style, not regex). - **node --test** + `--experimental-strip-types` — test runner (Node 22.6+, flag dropped on Node 24). - **c8** — code coverage for `test:ci`. - **oxlint** — Rust-based linter. -- **oxfmt** — Rust-based formatter (Prettier-compatible). +- **oxfmt** — Rust-based formatter (Prettier-compatible). Formats JS/TS, JSON/JSONC, YAML, Markdown, MDX, and more; built-in `package.json` key sorting replaces `sort-package-json`. - **cspell** — spell checking. -- **sort-package-json** — keep `package.json` keys alphabetized. - **lefthook** — git pre-commit hooks. ### Requirements @@ -40,4 +39,4 @@ Pattern matching for TypeScript/ESM environments (F#-style, not regex). - Commit signing (GPG). - Set up commit message template: `npm run use:git-commit-message`. - See `commit-message-template`. -- Type-only tests use `expect-type`'s `expectTypeOf(...)` inside `node --test` cases. \ No newline at end of file +- Type-only tests use `expect-type`'s `expectTypeOf(...)` inside `node --test` cases. diff --git a/cspell.json b/cspell.json index 60b1e41..b106a8e 100644 --- a/cspell.json +++ b/cspell.json @@ -11,7 +11,6 @@ "nodenext", "oxfmtrc", "oxlintrc", - "sortpackagerc", "EDITMSG", "typescriptteam", "gitmoji", diff --git a/lefthook.yml b/lefthook.yml index ce67689..edf454b 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -7,11 +7,9 @@ pre-commit: glob: "*.{ts,tsx,js,jsx,mjs,cjs}" run: sh -c 'LEFTHOOK_FILES="$0" npm run check:oxlint' {staged_files} oxfmt: - glob: "*.{ts,tsx,js,jsx,mjs,cjs}" + glob: "*.{ts,tsx,js,jsx,mjs,cjs,json,jsonc,yaml,yml,md,mdx}" run: sh -c 'LEFTHOOK_FILES="$0" npm run check:oxfmt' {staged_files} cspell: run: sh -c 'LEFTHOOK_FILES="$0" npm run check:cspell' {staged_files} - sort-package-json: - run: npm run check:package typecheck: - run: npm run check:tsc \ No newline at end of file + run: npm run check:tsc diff --git a/package-lock.json b/package-lock.json index 3c47d4f..d129ed0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "lefthook": "^2.1.12", "oxfmt": "^0.66.0", "oxlint": "^1.81.0", - "sort-package-json": "^4.0.0", "tslib": "^2.8.1", "type-fest": "^5.9.0", "typescript": "^7.0.2" @@ -2164,32 +2163,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/detect-indent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", - "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/detect-newline": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz", - "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", @@ -2356,16 +2329,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/git-hooks-list": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-4.2.1.tgz", - "integrity": "sha512-WNvqJjOxxs/8ZP9+DWdwWJ7cDsd60NHf39XnD82pDVrKO5q7xfPqpkK6hwEAmBa/ZSEE4IOoR75EzbbIuwGlMw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/fisker/git-hooks-list?sponsor=1" - } - }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", @@ -2451,19 +2414,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-safe-filename": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-safe-filename/-/is-safe-filename-0.1.1.tgz", @@ -3009,35 +2959,6 @@ "url": "https://github.com/sponsors/cyyynthia" } }, - "node_modules/sort-object-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-2.1.0.tgz", - "integrity": "sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/sort-package-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-4.0.0.tgz", - "integrity": "sha512-6aYOlYI9AWioZ+rzu+4zKLmoFqJP0/fHDxrd7X04yqEibikY+5YVF0EYlyGn4v6X2PJY7yAUWV7oeP+i5rOm/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-indent": "^7.0.2", - "detect-newline": "^4.0.1", - "git-hooks-list": "^4.1.1", - "is-plain-obj": "^4.1.0", - "semver": "^7.7.3", - "sort-object-keys": "^2.0.1", - "tinyglobby": "^0.2.15" - }, - "bin": { - "sort-package-json": "cli.js" - }, - "engines": { - "node": ">=22" - } - }, "node_modules/string-width": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", diff --git a/package.json b/package.json index fb3eeb2..9be29f3 100644 --- a/package.json +++ b/package.json @@ -3,46 +3,47 @@ "version": "0.0.0", "description": "Pattern matching for TypeScript/ESM environments (F#-style, not regex)", "keywords": [ - "pattern-matching", - "pattern", - "match", - "algebraic-data-types", "adt", + "algebraic-data-types", + "match", + "pattern", + "pattern-matching", "typescript" ], + "license": "MIT", "repository": { "type": "git", "url": "https://github.com/tmueller/tiny-pattern-ts.git" }, - "license": "MIT", - "sideEffects": false, + "files": [ + "dist", + "README.md", + "LICENSE" + ], "type": "module", + "sideEffects": false, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } }, - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "files": [ - "dist", - "README.md", - "LICENSE" - ], + "publishConfig": { + "access": "public" + }, "scripts": { "build": "tsc -p tsconfig.build.json", - "check": "npm run check:oxlint && npm run check:oxfmt && npm run check:tsc && npm run check:cspell && npm run check:package && npm run check:outdated", + "check": "npm run check:oxlint && npm run check:oxfmt && npm run check:tsc && npm run check:cspell && npm run check:outdated", "check:cspell": "cspell lint ${LEFTHOOK_FILES:-.}", "check:outdated": "check-outdated --ignore-pre-releases --ignore-packages @oxfmt/binding-darwin-arm64,@oxfmt/binding-darwin-x64,@oxfmt/binding-linux-arm64-gnu,@oxfmt/binding-linux-arm64-musl,@oxfmt/binding-linux-x64-gnu,@oxfmt/binding-linux-x64-musl,@oxfmt/binding-win32-x64-msvc,@oxlint/binding-darwin-arm64,@oxlint/binding-darwin-x64,@oxlint/binding-linux-arm64-gnu,@oxlint/binding-linux-arm64-musl,@oxlint/binding-linux-x64-gnu,@oxlint/binding-linux-x64-musl,@oxlint/binding-win32-x64-msvc", - "check:oxfmt": "oxfmt --check ${LEFTHOOK_FILES:-src}", + "check:oxfmt": "oxfmt --check ${LEFTHOOK_FILES:-.}", "check:oxlint": "oxlint ${LEFTHOOK_FILES:-src}", - "check:package": "sort-package-json --check", "check:tsc": "tsc --noEmit", "clean": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"", - "fix:oxfmt": "oxfmt src", + "fix:oxfmt": "oxfmt ${LEFTHOOK_FILES:-.}", "fix:oxlint": "oxlint --fix src", - "fix:package": "sort-package-json --write", "test": "npm run check:tsc && node --test --strip-types src/", "test:ci": "c8 --reporter=text --reporter=lcov --reporter=html node --test --strip-types src/", "test:unit": "node --test --strip-types src/", @@ -57,7 +58,6 @@ "lefthook": "^2.1.12", "oxfmt": "^0.66.0", "oxlint": "^1.81.0", - "sort-package-json": "^4.0.0", "tslib": "^2.8.1", "type-fest": "^5.9.0", "typescript": "^7.0.2" @@ -80,8 +80,5 @@ }, "engines": { "node": ">=26" - }, - "publishConfig": { - "access": "public" } -} \ No newline at end of file +} diff --git a/project-specs.md b/project-specs.md index b4b41e7..856ee25 100644 --- a/project-specs.md +++ b/project-specs.md @@ -27,21 +27,21 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte - `eslint/sort-keys` — handler/case order is semantic, not alphabetical. - `eslint/id-length` — `T`, `R`, `U`, `V` are standard TS generics. - `import/no-named-export` — false positive on library entry re-exports. - For `*.test.ts` files additionally: `no-unused-expressions` (for - `expectTypeOf(...)` calls), `no-empty-file` (we have a single import - per test file in some cases), `import/no-nodejs-modules` (we use - `node:test`/`node:assert`/`node:fs` intentionally), `eslint/no-magic-numbers` - (literals in tests are fine). + For `*.test.ts` files additionally: `no-unused-expressions` (for + `expectTypeOf(...)` calls), `no-empty-file` (we have a single import + per test file in some cases), `import/no-nodejs-modules` (we use + `node:test`/`node:assert`/`node:fs` intentionally), `eslint/no-magic-numbers` + (literals in tests are fine). - **Import sorting**: built into oxfmt (no separate plugin). - **cspell**: Basic spelling configuration. Words dictionary in `cspell.json` covers tooling names (`oxlint`, `oxfmt`, `oxc`, `nodenext`, - `oxfmtrc`, `oxlintrc`, `sortpackagerc`, `EDITMSG`, `typescriptteam`, + `oxfmtrc`, `oxlintrc`, `EDITMSG`, `typescriptteam`, `gitmoji`, `dbaeumer`, `msvc`) and a few library names (`tslib`, `typefest`, `lefthook`). - **Lefthook**: Pre-commit checks (run in parallel, lefthook v2 schema). Single source of truth for the underlying commands is in - `package.json#scripts`; the lefthook config only describes *what to - run on which files*. Hooks that should run on staged files + `package.json#scripts`; the lefthook config only describes _what to + run on which files_. Hooks that should run on staged files (`oxlint`, `oxfmt`, `cspell`) set the `LEFTHOOK_FILES` env var to the staged-files list via a `sh -c` wrapper, and the npm script uses `${LEFTHOOK_FILES:-}` to default to the full project @@ -52,17 +52,14 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte `sh -c 'LEFTHOOK_FILES="$0" npm run check:oxfmt' {staged_files}` - `pre-commit.commands.cspell`: `sh -c 'LEFTHOOK_FILES="$0" npm run check:cspell' {staged_files}` - - `pre-commit.commands.sort-package-json`: - `npm run check:package` (no file args needed) - `pre-commit.commands.typecheck`: `npm run check:tsc` (no file args needed) - `outdated` is intentionally NOT a pre-commit check (it can flag - upstream patch releases that aren't actionable locally); it runs in - CI and via the explicit `lefthook run outdated` command. + `outdated` is intentionally NOT a pre-commit check (it can flag + upstream patch releases that aren't actionable locally); it runs in + CI and via the explicit `lefthook run outdated` command. - **Additional Dev Dependencies**: - lefthook - - sort-package-json - check-outdated - c8 (coverage for `node --test`) - expect-type (type-level assertions in tests) @@ -119,7 +116,7 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte - **.npmignore**: Ignore `node_modules/`, `coverage/`, `*.log`, `*.tsbuildinfo`, `src/`, `.vscode/`, `.editorconfig`, `.oxfmtrc.json`, `.oxlintrc.json`, `.node-version`, `cspell.json`, - `lefthook.yml`, `.sortpackagerc.json`, `commit-message-template`. + `lefthook.yml`, `commit-message-template`. (Note: `dist/` is included via `package.json#files`, not by absence from `.npmignore`.) - **.oxfmtrc.json**: oxfmt configuration (Prettier-shaped). @@ -171,27 +168,35 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte ### CHECK - `check`: Run all checks in order — `check:oxlint`, `check:oxfmt`, - `check:tsc`, `check:cspell`, `check:package`, `check:outdated`. + `check:tsc`, `check:cspell`, `check:outdated`. - `check:oxlint`: `oxlint ${LEFTHOOK_FILES:-src}` — lints `src/` by default; when invoked from the lefthook pre-commit hook with `LEFTHOOK_FILES` set to the staged-files list, lints only those files. This is the single source of truth for the oxlint command and is shared between the manual `npm run check` and the pre-commit - hook. -- `check:oxfmt`: `oxfmt --check ${LEFTHOOK_FILES:-src}` — same - pattern as `check:oxlint` (whole `src/` by default, staged files - from lefthook). + hook. oxlint only understands JS/TS-family languages, so config + files (JSON/YAML/Markdown) are intentionally outside its scope; + they are checked only by oxfmt. +- `check:oxfmt`: `oxfmt --check ${LEFTHOOK_FILES:-.}` — formats the + whole project (`.`) by default, including JS/TS, JSON/JSONC, + YAML, Markdown, MDX and other supported file types. From lefthook + pre-commit, the `LEFTHOOK_FILES` env var scopes to the staged + files matching `*.{ts,tsx,js,jsx,mjs,cjs,json,jsonc,yaml,yml,md,mdx}`. + Built-in `sortPackageJson: true` keeps `package.json` keys + alphabetized (replaces the former `sort-package-json` tool). + Built-in import sorting (enabled via `sortImports: true`) replaces + any external import-sort plugin. - `check:tsc`: `tsc --noEmit`. - `check:cspell`: `cspell lint ${LEFTHOOK_FILES:-.}` — walks the project root by default; from lefthook, only the staged files. -- `check:package`: `sort-package-json --check`. - `check:outdated`: `check-outdated --ignore-pre-releases --ignore-packages @oxfmt/binding-*,@oxlint/binding-*`. The oxc native bindings are declared as `optionalDependencies` so the correct one is selected per platform automatically; the `*`-platform bindings show as "not installed" on the current platform and are explicitly ignored here. ### FIX - `fix:oxlint`: `oxlint --fix src`. -- `fix:oxfmt`: `oxfmt src`. -- `fix:package`: `sort-package-json --write`. +- `fix:oxfmt`: `oxfmt ${LEFTHOOK_FILES:-.}` — same scoping as + `check:oxfmt` (whole project by default, staged files from + lefthook). Writes changes in place. (There is no `fix` aggregator in the scripts; run the `fix:*` scripts individually.) @@ -223,11 +228,11 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte to main and before publishing. - **Publishing to npm**: Only publish from CI on tagged commits. - **Recommended Workflow**: - 1. Develop and merge PRs to main - 2. Run all checks via CI - 3. Bump version with `npm version ` - 4. Push tag to GitHub - 5. CI builds and publishes to npm on tag + 1. Develop and merge PRs to main + 2. Run all checks via CI + 3. Bump version with `npm version ` + 4. Push tag to GitHub + 5. CI builds and publishes to npm on tag ## 8. NPM Keywords @@ -263,16 +268,16 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte - **Source Directory**: All source code resides in `src/` and is exported via `src/index.ts`. - **Configuration**: - - `sideEffects: false` in `package.json` (set). - - ESM-only exports; `package.json#exports` field maps `.` to - `{"types": "./dist/index.d.ts", "import": "./dist/index.js"}`. - - Avoid top-level side effects in modules. - - Explicit re-exports in `index.ts` for best results. + - `sideEffects: false` in `package.json` (set). + - ESM-only exports; `package.json#exports` field maps `.` to + `{"types": "./dist/index.d.ts", "import": "./dist/index.js"}`. + - Avoid top-level side effects in modules. + - Explicit re-exports in `index.ts` for best results. - Source structure (current): - - `src/index.ts` — public barrel. - - `src/match.ts` — `match(value).with(...).exhaustive() / .otherwise(...)` builder. - - `src/pattern.ts` — `P.literal`, `P.type`, `P.when`, `P.any`, `P.shape` constructors and the `Matcher` interface. - - `src/index.test.ts` — runtime + type-level tests using `node --test` + `expect-type`. + - `src/index.ts` — public barrel. + - `src/match.ts` — `match(value).with(...).exhaustive() / .otherwise(...)` builder. + - `src/pattern.ts` — `P.literal`, `P.type`, `P.when`, `P.any`, `P.shape` constructors and the `Matcher` interface. + - `src/index.test.ts` — runtime + type-level tests using `node --test` + `expect-type`. - The human will implement the source code. ## 11. Included Templates from typescript-lib-starter-tiny @@ -326,25 +331,25 @@ Resolves #... - Project title and description - Development - - Build: `npm run build` - - Test: `npm run test`, `npm run test:ci` - - Checks: `npm run check`, `npm run fix:oxfmt`, `npm run fix:oxlint` + - Build: `npm run build` + - Test: `npm run test`, `npm run test:ci` + - Checks: `npm run check`, `npm run fix:oxfmt`, `npm run fix:oxlint` - Tooling section listing TypeScript 7, node --test, c8, oxlint, oxfmt, - cspell, sort-package-json, lefthook + cspell, lefthook - Requirements: Node.js >= 26 - VSCode integration - - Debugging - - Running tests - - oxc.oxc-vscode provides oxlint and oxfmt in-editor + - Debugging + - Running tests + - oxc.oxc-vscode provides oxlint and oxfmt in-editor - Workflows - - Version updates via `npm version` - - Publishing via GitHub Actions on tagged commits + - Version updates via `npm version` + - Publishing via GitHub Actions on tagged commits - Contribution guidelines - - Commit signing (GPG) - - How to set up commit message template (`npm run use:git-commit-message`) - - Reference to commit-message-template - - Type-level tests use `expect-type`'s `expectTypeOf(...)` inside - `node --test` cases + - Commit signing (GPG) + - How to set up commit message template (`npm run use:git-commit-message`) + - Reference to commit-message-template + - Type-level tests use `expect-type`'s `expectTypeOf(...)` inside + `node --test` cases ## 12. Project Initialization & Commit Strategy @@ -353,24 +358,24 @@ Resolves #... - Create a feature branch: `feature/setup`. - For each technology or tool added (and its configuration), create a separate commit: - - Prepend each commit message with a matching gitmoji (e.g. - `:sparkles:` for new features, `:wrench:` for config, - `:bug:` for fixes, `:fire:` for removals, - `:white_check_mark:` for tests, `:tada:` for initial commit). - - Example commit messages used in this project: - - `:tada: Initial commit with empty README` - - `:wrench: Track .vscode/settings.json for workspace settings` - - `:construction_worker: Added GitHub Actions workflow for CI/CD` - - `:test_tube: Added Vitest configuration with coverage` (later removed) - - `:sparkles: Scaffolded src/index.ts entry point for library code` - - `:wrench: Replace Vite/Vitest with TypeScript 7 and node --test` - - `:wrench: Replace ESLint and Prettier with oxlint and oxfmt` - - `:fire: Remove Vite scaffold leftovers` - - `:sparkles: Add initial pattern-matching API` - - `:white_check_mark: Add expect-type for type-level tests` - - `:wrench: Declare Node 26 as the supported runtime` - - `:bug: Use .ts extensions in imports for node --strip-types` - - `:wrench: Remove Prettier from editor formatter config` + - Prepend each commit message with a matching gitmoji (e.g. + `:sparkles:` for new features, `:wrench:` for config, + `:bug:` for fixes, `:fire:` for removals, + `:white_check_mark:` for tests, `:tada:` for initial commit). + - Example commit messages used in this project: + - `:tada: Initial commit with empty README` + - `:wrench: Track .vscode/settings.json for workspace settings` + - `:construction_worker: Added GitHub Actions workflow for CI/CD` + - `:test_tube: Added Vitest configuration with coverage` (later removed) + - `:sparkles: Scaffolded src/index.ts entry point for library code` + - `:wrench: Replace Vite/Vitest with TypeScript 7 and node --test` + - `:wrench: Replace ESLint and Prettier with oxlint and oxfmt` + - `:fire: Remove Vite scaffold leftovers` + - `:sparkles: Add initial pattern-matching API` + - `:white_check_mark: Add expect-type for type-level tests` + - `:wrench: Declare Node 26 as the supported runtime` + - `:bug: Use .ts extensions in imports for node --strip-types` + - `:wrench: Remove Prettier from editor formatter config` - Each commit should include only the relevant files and configuration for that technology/tool. This approach ensures a clean, understandable project history and makes it easy to review or revert specific setup @@ -434,10 +439,10 @@ Resolves #... ``` - `.vscode/extensions.json` recommends: - - `oxc.oxc-vscode` (oxlint + oxfmt, replaces eslint/prettier/vitest) - - `streetsidesoftware.code-spell-checker` (cspell) - - `typescriptteam.native-preview` (TypeScript 7 nightly support; - replaces the older `ms-vscode.vscode-typescript-next`) + - `oxc.oxc-vscode` (oxlint + oxfmt, replaces eslint/prettier/vitest) + - `streetsidesoftware.code-spell-checker` (cspell) + - `typescriptteam.native-preview` (TypeScript 7 nightly support; + replaces the older `ms-vscode.vscode-typescript-next`) ```json {