diff --git a/.cspell.json b/.cspell.json index f1806362b47..21ca6f8fc23 100644 --- a/.cspell.json +++ b/.cspell.json @@ -62,6 +62,7 @@ "declarators", "destructure", "destructured", + "discoverability", "dprint", "errored", "erroring", @@ -71,6 +72,7 @@ "esquery", "esrecurse", "estree", + "globby", "IDE's", "IIFE", "IIFEs", @@ -120,6 +122,7 @@ "unoptimized", "unprefixed", "upsert", + "warnonunsupportedtypescriptversion", "Zacher" ], "overrides": [ diff --git a/.eslintrc.js b/.eslintrc.js index 7380b874d88..99f3f5d3e41 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -40,6 +40,11 @@ module.exports = { tsconfigRootDir: __dirname, warnOnUnsupportedTypeScriptVersion: false, EXPERIMENTAL_useSourceOfProjectReferenceRedirect: false, + cacheLifetime: { + // we pretty well never create/change tsconfig structure - so need to ever evict the cache + // in the rare case that we do - just need to manually restart their IDE. + glob: 'Infinity', + }, }, rules: { // make sure we're not leveraging any deprecated APIs @@ -106,6 +111,13 @@ module.exports = { // curly: ['error', 'all'], + eqeqeq: [ + 'error', + 'always', + { + null: 'never', + }, + ], 'no-mixed-operators': 'error', 'no-console': 'error', 'no-process-exit': 'error', @@ -186,6 +198,8 @@ module.exports = { // enforce a sort order across the codebase 'simple-import-sort/imports': 'error', + + 'one-var': ['error', 'never'], }, overrides: [ // all test files diff --git a/.github/actions/prepare-build/action.yml b/.github/actions/prepare-build/action.yml index ce69eddedc5..d656587ca56 100644 --- a/.github/actions/prepare-build/action.yml +++ b/.github/actions/prepare-build/action.yml @@ -19,4 +19,4 @@ runs: shell: bash # Website will be built by the Netlify GitHub App run: | - yarn build --exclude website + npx nx run-many --target=build --parallel --exclude website diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3e72e13f7a9..b5037407620 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,7 +8,7 @@ Otherwise we may not be able to review your PR. - [ ] Addresses an existing open issue: fixes #000 - [ ] That issue was marked as [accepting prs](https://github.com/typescript-eslint/typescript-eslint/issues?q=is%3Aopen+is%3Aissue+label%3A%22accepting+prs%22) -- [ ] Steps in [CONTRIBUTING.md](https://github.com/typescript-eslint/typescript-eslint/blob/main/CONTRIBUTING.md) were taken +- [ ] Steps in [Contributing](https://typescript-eslint.io/contributing) were taken ## Overview diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a681df192af..5d6c59a303a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -7,6 +7,9 @@ 'eslint-scope', // this dep is now ESM only 'execa', + // Some kind of weird caching issue: + // https://github.com/typescript-eslint/typescript-eslint/issues/6230 + 'ts-node', // the nx packages get updated using the nx migrate CLI '@nrwl/cli', '@nrwl/devkit', diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a3384f1eaa..def7977921b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -144,7 +144,7 @@ jobs: - name: Install uses: ./.github/actions/prepare-install with: - node-version: ${{ env.PRIMARY_NODE_VERSION }} + node-version: ${{ matrix.node-version }} - name: Build uses: ./.github/actions/prepare-build diff --git a/.gitignore b/.gitignore index 2ce061c3d4d..0973f04542e 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,9 @@ jspm_packages/ # Editor-specific metadata folders .vs +# nodejs cpu profiles +*.cpuprofile + .DS_Store .idea dist diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d651f565a8..9ad61e896af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,41 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + + +### Bug Fixes + +* **ast-spec:** a JSXEmptyExpression is not a possible JSXExpression ([#6321](https://github.com/typescript-eslint/typescript-eslint/issues/6321)) ([4b27777](https://github.com/typescript-eslint/typescript-eslint/commit/4b27777ed26cc83d6efc52a89b2d3fc6c01bc0d7)) +* **eslint-plugin:** [ban-ts-comment] counts graphemes instead of `String.prototype.length` ([#5704](https://github.com/typescript-eslint/typescript-eslint/issues/5704)) ([09d57ce](https://github.com/typescript-eslint/typescript-eslint/commit/09d57cec8901880c6b24ea80dfa7d9fcdc463930)) +* **eslint-plugin:** [prefer-optional-chain] fix `ThisExpression` and `PrivateIdentifier` errors ([#6028](https://github.com/typescript-eslint/typescript-eslint/issues/6028)) ([85e783c](https://github.com/typescript-eslint/typescript-eslint/commit/85e783c1fabe96d390729a5796d6d346e401692b)) +* **eslint-plugin:** [prefer-optional-chain] fixer produces wrong logic ([#5919](https://github.com/typescript-eslint/typescript-eslint/issues/5919)) ([b0f6c8e](https://github.com/typescript-eslint/typescript-eslint/commit/b0f6c8ec0b372696ef26ca3a2b4f82dafd9dc417)), closes [#1438](https://github.com/typescript-eslint/typescript-eslint/issues/1438) + + +### Features + +* **eslint-plugin:** add `key-spacing` rule extension for interface & type declarations ([#6211](https://github.com/typescript-eslint/typescript-eslint/issues/6211)) ([67706e7](https://github.com/typescript-eslint/typescript-eslint/commit/67706e72e332bf11c82fdf51f3d417d3c93a86cf)) + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + + +### Bug Fixes + +* **typescript-estree:** fix typo in FAQ link ([#6346](https://github.com/typescript-eslint/typescript-eslint/issues/6346)) ([eefc578](https://github.com/typescript-eslint/typescript-eslint/commit/eefc5781b0f455264e4e58e33c27f8a91b3ab5e3)) + + +### Features + +* **eslint-plugin:** [naming-convention] add support for `#private` modifier on class members ([#6259](https://github.com/typescript-eslint/typescript-eslint/issues/6259)) ([c8a6d80](https://github.com/typescript-eslint/typescript-eslint/commit/c8a6d8096080228b6d122c861fe140ac97f17cbe)) + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/typescript-eslint diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b1c6bfe4f0d..53748bda265 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -10,77 +10,54 @@ Thanks goes to these wonderful people:
Brad Zacher

Armano

Josh Goldberg
-
Oleksandr T.
+
Michaël De Boey
-
Michaël De Boey

Reyad Attiyat
-
Gareth Jones

Sosuke Suzuki
+
Gareth Jones

Patricio Trevino
+
Joshua Chen
-
Joshua Chen

YeonJuan

Nicholas C. Zakas

Jed Fox
-
Rafael Santana
- -
Ben Lichtman

Nikita
+ +
Taeheon Kim

Scott O'Hara

Retsam
- -
Kai Cataldo

Rasmus Eneman
-
Rebecca Stevens
-
Toru Nagashima
-
Yosuke Ota
+
Toru Nagashima
+
Yosuke Ota

JounQin

Lucas Azzola

Simen Bekkhus
-
Danny Fritz
-
Ika
+
Danny Fritz
+
Omri Luzon

cherryblossom
-
mackie
+
Mackie Underdown

Bryan Mishkin
-
Kanitkorn Sujautra
-
Omri Luzon
+
Kanitkorn Sujautra
+
Sviatoslav Zaytsev

Zzzen

Anix
-
Daniil Dubrava

Pete Gonzalez
-
ldrick
-
Susisu
+
ldrick

SHIMA RYUHEI
-
Gavin Barron
-
Kevin Partington
-
Lucas Duailibe
- -
Niles Salter
-
Pavel Birukov
-
Shahar "Dawn" Or
-
kmin-jeong
-
koooge
- - -
thomas michael wallace
-
Juan García
-
Daniel Nixon
-
Yasar Siddiqui
-
Yusuke Tanaka
diff --git a/docs/Architecture.md b/docs/Architecture.mdx similarity index 100% rename from docs/Architecture.md rename to docs/Architecture.mdx diff --git a/docs/Custom_Rules.md b/docs/Custom_Rules.mdx similarity index 100% rename from docs/Custom_Rules.md rename to docs/Custom_Rules.mdx diff --git a/docs/Getting_Started.md b/docs/Getting_Started.mdx similarity index 94% rename from docs/Getting_Started.md rename to docs/Getting_Started.mdx index 91c978322f4..cdaf39899a9 100644 --- a/docs/Getting_Started.md +++ b/docs/Getting_Started.mdx @@ -73,6 +73,6 @@ ESLint will lint all TypeScript compatible files within the current folder, and ## Next Steps -We provide a plethora of powerful rules that utilize the power of TypeScript's type information. [Visit the next page for a setup guide](./linting/Typed_Linting.md 'Visit the next page for a typed rules setup guide'). +We provide a plethora of powerful rules that utilize the power of TypeScript's type information. [Visit the next page for a setup guide](./linting/Typed_Linting.mdx 'Visit the next page for a typed rules setup guide'). -If you're having problems getting this working, please have a look at our [Troubleshooting & FAQs](./linting/Troubleshooting.md). +If you're having problems getting this working, please have a look at our [Troubleshooting & FAQs](./linting/Troubleshooting.mdx). diff --git a/docs/MAINTENANCE.md b/docs/Maintenance.mdx similarity index 100% rename from docs/MAINTENANCE.md rename to docs/Maintenance.mdx diff --git a/docs/architecture/ESLint_Plugin.mdx b/docs/architecture/ESLint_Plugin.mdx index eca60141555..6db78ddfceb 100644 --- a/docs/architecture/ESLint_Plugin.mdx +++ b/docs/architecture/ESLint_Plugin.mdx @@ -8,7 +8,7 @@ sidebar_label: eslint-plugin > The TypeScript plugin for ESLint. ✨ :::info -See [Getting Started](../Getting_Started.md) for documentation on how to lint your TypeScript code with ESLint. +See [Getting Started](../Getting_Started.mdx) for documentation on how to lint your TypeScript code with ESLint. ::: `@typescript-eslint/eslint-plugin` is an ESLint plugin used to load in custom rules and rule configurations lists from typescript-eslint. diff --git a/docs/architecture/ESLint_Plugin_TSLint.mdx b/docs/architecture/ESLint_Plugin_TSLint.mdx index 582d93aab8e..525b1c07247 100644 --- a/docs/architecture/ESLint_Plugin_TSLint.mdx +++ b/docs/architecture/ESLint_Plugin_TSLint.mdx @@ -8,8 +8,8 @@ sidebar_label: eslint-plugin-tslint > ESLint plugin that allows running TSLint rules within ESLint to help you migrate from TSLint to ESLint. ✨ :::caution -Per [What About TSLint?](../linting/troubleshooting/TSLint.md), we highly recommend migrating off TSLint. -See [Getting Started](../Getting_Started.md) for documentation on how to lint your TypeScript code with ESLint. +Per [What About TSLint?](../linting/troubleshooting/TSLint.mdx), we highly recommend migrating off TSLint. +See [Getting Started](../Getting_Started.mdx) for documentation on how to lint your TypeScript code with ESLint. ::: ## Installation diff --git a/docs/architecture/Parser.mdx b/docs/architecture/Parser.mdx index 9f5d51a53bb..5039dc1bec5 100644 --- a/docs/architecture/Parser.mdx +++ b/docs/architecture/Parser.mdx @@ -30,6 +30,9 @@ The following additional configuration options are available by specifying them ```ts interface ParserOptions { + cacheLifetime?: { + glob?: number | 'Infinity'; + }; ecmaFeatures?: { jsx?: boolean; globalReturn?: boolean; @@ -49,6 +52,14 @@ interface ParserOptions { } ``` +### `cacheLifetime` + +This option allows you to granularly control our internal cache expiry lengths. + +You can specify the number of seconds as an integer number, or the string 'Infinity' if you never want the cache to expire. + +By default cache entries will be evicted after 30 seconds, or will persist indefinitely if the parser infers that it is a single run. + ### `ecmaFeatures` Optional additional options to describe how to parse the raw syntax. @@ -226,7 +237,8 @@ For example, by default it will ensure that a glob like `./**/tsconfig.json` wil > Default `undefined`. -This option allows you to provide the root directory for relative tsconfig paths specified in the `project` option above. +This option allows you to provide the root directory for relative TSConfig paths specified in the `project` option above. +Doing so ensures running ESLint from a directory other than the root will still be able to find your TSConfig. ### `warnOnUnsupportedTypeScriptVersion` diff --git a/docs/architecture/TypeScript-ESTree.mdx b/docs/architecture/TypeScript-ESTree.mdx index 066030b0afe..f74aa65e223 100644 --- a/docs/architecture/TypeScript-ESTree.mdx +++ b/docs/architecture/TypeScript-ESTree.mdx @@ -226,7 +226,23 @@ interface ParseAndGenerateServicesOptions extends ParseOptions { allowAutomaticSingleRunInference?: boolean; /** - * Path to a file exporting a custom ModuleResolver. + * Granular control of the expiry lifetime of our internal caches. + * You can specify the number of seconds as an integer number, or the string + * 'Infinity' if you never want the cache to expire. + * + * By default cache entries will be evicted after 30 seconds, or will persist + * indefinitely if `allowAutomaticSingleRunInference = true` AND the parser + * infers that it is a single run. + */ + cacheLifetime?: { + /** + * Glob resolution for `parserOptions.project` values. + */ + glob?: number | 'Infinity'; + }; + + /** + * Path to a file exporting a custom `ModuleResolver`. */ moduleResolver?: string; } @@ -273,6 +289,23 @@ const { ast, services } = parseAndGenerateServices(code, { }); ``` +##### `ModuleResolver` + +The `moduleResolver` option allows you to specify the path to a module with a custom module resolver implementation. The module is expected to adhere to the following interface: + +```ts +interface ModuleResolver { + version: 1; + resolveModuleNames( + moduleNames: string[], + containingFile: string, + reusedNames: string[] | undefined, + redirectedReference: ts.ResolvedProjectReference | undefined, + options: ts.CompilerOptions, + ): (ts.ResolvedModule | undefined)[]; +} +``` + #### `parseWithNodeMaps(code, options)` Parses the given string of code with the options provided and returns both the ESTree-compatible AST as well as the node maps. diff --git a/docs/contributing/Discussions.md b/docs/contributing/Discussions.md new file mode 100644 index 00000000000..52de9991409 --- /dev/null +++ b/docs/contributing/Discussions.md @@ -0,0 +1,28 @@ +--- +id: discussions +title: Discussions +--- + +Most proposals in the typescript-eslint repository happen in [GitHub Issues](https://docs.github.com/issues). +We generally try to keep conversations inside issues for their discoverability and ability to be linked to [GitHub Pull Requests](https://docs.github.com/pull-requests). + +We have [GitHub Discussions](https://docs.github.com/discussions) enabled to enable three kinds of deeper, threaded conversations: + +- **Community Feedback**: Questions from the maintainer team that should be raised to the broader community +- **RFCs (Requests For Comments)**: Formalized proposals for larger changes that should be discussed before turned into issues +- **Technical Discussions**: Deeper questions about typescript-eslint's architecture and/or APIs + +Before filing a Discussion, search the issue tracker for any related conversations. +Link to them in the Discussion, along with a detailed description of what you'd like to discuss. + +:::tip +For change proposals that match an [existing issue format](https://github.com/typescript-eslint/typescript-eslint/issues/new/choose), keep to filing issues. +Most don't need to be moved to this separate format. +We can always move an issue to a discussion if it becomes unexpectedly deep. +::: + +:::caution +Please don't use Discussions as a support forum. +We don't have the maintainer-budget to handle that. +See [Issues > Questions and Support Requests](./Issues.mdx#questions-and-support-requests). +::: diff --git a/docs/contributing/Issues.mdx b/docs/contributing/Issues.mdx index ae61dd0e312..d577248b2e6 100644 --- a/docs/contributing/Issues.mdx +++ b/docs/contributing/Issues.mdx @@ -21,6 +21,7 @@ Please don't: - Leave useless comments such as _"+1"_ or _"when's this getting fixed?"_ that only act as spam - If you have nothing to add but enthusiasm and joy, add a reaction such as 👍 + - One exception: if an issue has been blocked on a question to a maintainer for 3 or more months, please ping us - we probably lost track of it - Bring up unrelated topics in existing issues: instead, file a new issue - Comment on closed PRs: instead, [file a new issue](#raising-issues) - Comment on commits directly, as those comments are not searchable: instead, file a new issue diff --git a/docs/contributing/Pull_Requests.mdx b/docs/contributing/Pull_Requests.mdx index edb76feb7d6..c5af830718c 100644 --- a/docs/contributing/Pull_Requests.mdx +++ b/docs/contributing/Pull_Requests.mdx @@ -19,8 +19,9 @@ Please don't: - Force push after opening a PR - Reasoning: GitHub is not able to track changes across force pushes, which makes it take longer for us to perform incremental reviews -- Comment asking for updates +- Comment on an existing PR asking for updates - Reasoning: Your PR hasn't been forgotten! The volunteer maintainers have limited time to work on the project, and they will get to it as soon as they are able. + - One exception: if a PR has been blocked on a question to a maintainer for 3 or more months, please ping us - we probably lost track of it. ### Raising a PR diff --git a/docs/linting/CONFIGURATIONS.mdx b/docs/linting/CONFIGURATIONS.mdx index aec668a16dd..10d3f6293d5 100644 --- a/docs/linting/CONFIGURATIONS.mdx +++ b/docs/linting/CONFIGURATIONS.mdx @@ -18,7 +18,7 @@ Most projects should extend from at least one of: - [`strict`](#strict): Additional strict rules that can also catch bugs but are more opinionated than recommended rules. :::tip -We recommend most projects use [`recommended-requiring-type-checking`](#recommended-requiring-type-checking) (which requires [typed linting](./Typed_Linting.md)). +We recommend most projects use [`recommended-requiring-type-checking`](#recommended-requiring-type-checking) (which requires [typed linting](./Typed_Linting.mdx)). ::: :::note diff --git a/docs/linting/Troubleshooting.md b/docs/linting/Troubleshooting.mdx similarity index 99% rename from docs/linting/Troubleshooting.md rename to docs/linting/Troubleshooting.mdx index 67e4316608f..cb59af28447 100644 --- a/docs/linting/Troubleshooting.md +++ b/docs/linting/Troubleshooting.mdx @@ -35,11 +35,11 @@ If you don't find an existing extension rule, or the extension rule doesn't work - If you **do not** want to lint the file: - Use [one of the options ESLint offers](https://eslint.org/docs/latest/user-guide/configuring/ignoring-code) to ignore files, namely a `.eslintignore` file, or `ignorePatterns` config. - If you **do** want to lint the file: - - If you **do not** want to lint the file with [type-aware linting](./Typed_Linting.md): + - If you **do not** want to lint the file with [type-aware linting](./Typed_Linting.mdx): - Use [ESLint's `overrides` configuration](https://eslint.org/docs/latest/user-guide/configuring/configuration-files#configuration-based-on-glob-patterns) to configure the file to not be parsed with type information. - A popular setup is to omit the above additions from top-level configuration and only apply them to TypeScript files via an override. - Alternatively, you can add `parserOptions: { project: null }` to an override for the files you wish to exclude. Note that `{ project: undefined }` will not work. - - If you **do** want to lint the file with [type-aware linting](./Typed_Linting.md): + - If you **do** want to lint the file with [type-aware linting](./Typed_Linting.mdx): - Check the `include` option of each of the tsconfigs that you provide to `parserOptions.project` - you must ensure that all files match an `include` glob, or else our tooling will not be able to find it. - If your file shouldn't be a part of one of your existing tsconfigs (for example, it is a script/tool local to the repo), then consider creating a new tsconfig (we advise calling it `tsconfig.eslint.json`) in your project root which lists this file in its `include`. For an example of this, you can check out the configuration we use in this repo: - [`tsconfig.eslint.json`](https://github.com/typescript-eslint/typescript-eslint/blob/main/tsconfig.eslint.json) @@ -64,7 +64,7 @@ For example, many projects have files like: In that case, viewing the `.eslintrc.cjs` in an IDE with the ESLint extension will show the error notice that the file couldn't be linted because it isn't included in `tsconfig.json`. -See our docs on [type aware linting](./Typed_Linting.md) for more information. +See our docs on [type aware linting](./Typed_Linting.mdx) for more information. ## I get errors telling me "The file must be included in at least one of the projects provided" diff --git a/docs/linting/Typed_Linting.md b/docs/linting/Typed_Linting.mdx similarity index 81% rename from docs/linting/Typed_Linting.md rename to docs/linting/Typed_Linting.mdx index 3e1beb396a8..7d9de2f25bb 100644 --- a/docs/linting/Typed_Linting.md +++ b/docs/linting/Typed_Linting.mdx @@ -8,30 +8,30 @@ To tap into TypeScript's additional powers, there are two small changes you need ```js title=".eslintrc.js" module.exports = { - root: true, - parser: '@typescript-eslint/parser', - // Added lines start - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - // Added lines end - plugins: ['@typescript-eslint'], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', // Add this line 'plugin:@typescript-eslint/recommended-requiring-type-checking', ], + plugins: ['@typescript-eslint'], + parser: '@typescript-eslint/parser', + // Added lines start + parserOptions: { + project: ['./tsconfig.json'], + tsconfigRootDir: __dirname, + }, + // Added lines end + root: true, }; ``` In more detail: -- `parserOptions.tsconfigRootDir` tells our parser the absolute path of your project's root directory. +- `plugin:@typescript-eslint/recommended-requiring-type-checking` is another [recommended configuration](./CONFIGURATIONS.mdx) we provide. This one contains recommended rules that additionally require type information. - `parserOptions.project` tells our parser the relative path where your project's `tsconfig.json` is. - - If your project is a multi-package monorepo, see [our docs on configuring a monorepo](./typed-linting/Monorepos.md). -- `plugin:@typescript-eslint/recommended-requiring-type-checking` is another recommended configuration we provide. This one contains rules that specifically require type information. + - If your project is a multi-package monorepo, see [our docs on configuring a monorepo](./typed-linting/Monorepos.mdx). +- `parserOptions.tsconfigRootDir` tells our parser the absolute path of your project's root directory (see [Parser#tsconfigRootDir](../architecture/Parser.mdx#tsconfigRootDir)). With that done, run the same lint command you ran before. You may see new rules reporting errors based on type information! @@ -53,8 +53,8 @@ This means that generally they usually only run a complete lint before a push, o ### I get errors telling me "The file must be included in at least one of the projects provided" You're using an outdated version of `@typescript-eslint/parser`. -Update to the latest version to see a more informative version of this error message, explained in our [Troubleshooting and FAQs page](./Troubleshooting.md#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file). +Update to the latest version to see a more informative version of this error message, explained in our [Troubleshooting and FAQs page](./Troubleshooting.mdx#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file). ## Troubleshooting -If you're having problems getting this working, please have a look at our [Troubleshooting and FAQs page](./Troubleshooting.md). +If you're having problems getting this working, please have a look at our [Troubleshooting and FAQs page](./Troubleshooting.mdx). diff --git a/docs/linting/troubleshooting/Formatting.md b/docs/linting/troubleshooting/Formatting.mdx similarity index 100% rename from docs/linting/troubleshooting/Formatting.md rename to docs/linting/troubleshooting/Formatting.mdx diff --git a/docs/linting/troubleshooting/Performance.md b/docs/linting/troubleshooting/Performance.md index 6f696a7a05f..f4d0f9e3d53 100644 --- a/docs/linting/troubleshooting/Performance.md +++ b/docs/linting/troubleshooting/Performance.md @@ -3,7 +3,7 @@ id: performance-troubleshooting title: Performance Troubleshooting --- -As mentioned in the [type-aware linting doc](../Typed_Linting.md), if you're using type-aware linting, your lint times should be roughly the same as your build times. +As mentioned in the [type-aware linting doc](../Typed_Linting.mdx), if you're using type-aware linting, your lint times should be roughly the same as your build times. If you're experiencing times much slower than that, then there are a few common culprits. @@ -53,7 +53,7 @@ Across a large codebase, these can add up, and severely impact performance. We recommend not using this rule, and instead using a tool like [`prettier`](https://www.npmjs.com/package/prettier) to enforce a standardized formatting. -See our [documentation on formatting](./Formatting.md) for more information. +See our [documentation on formatting](./Formatting.mdx) for more information. ## `eslint-plugin-prettier` diff --git a/docs/linting/troubleshooting/TSLint.md b/docs/linting/troubleshooting/TSLint.mdx similarity index 100% rename from docs/linting/troubleshooting/TSLint.md rename to docs/linting/troubleshooting/TSLint.mdx diff --git a/docs/linting/typed-linting/Monorepos.md b/docs/linting/typed-linting/Monorepos.mdx similarity index 96% rename from docs/linting/typed-linting/Monorepos.md rename to docs/linting/typed-linting/Monorepos.mdx index e55d2064779..7b01b81d662 100644 --- a/docs/linting/typed-linting/Monorepos.md +++ b/docs/linting/typed-linting/Monorepos.mdx @@ -38,7 +38,7 @@ Be sure to update your `.eslintrc.js` to point at this new config file. ## One `tsconfig.json` per package (and an optional one in the root) -The `parserOptions.project` option introduced in [Linting with Type Information](../Typed_Linting.md) accepts an array of relative paths. +The `parserOptions.project` option introduced in [Linting with Type Information](../Typed_Linting.mdx) accepts an array of relative paths. Paths may be provided as [Node globs](https://github.com/isaacs/node-glob/blob/f5a57d3d6e19b324522a3fa5bdd5075fd1aa79d1/README.md#glob-primer). For each file being linted, the first matching project path will be used as its backing TSConfig. @@ -104,4 +104,4 @@ As an interim workaround, consider one of the following: ## Troubleshooting -If you're having problems getting this working, please have a look at our [Troubleshooting FAQ](../Troubleshooting.md). +If you're having problems getting this working, please have a look at our [Troubleshooting FAQ](../Troubleshooting.mdx). diff --git a/docs/maintenance/BRANDING.md b/docs/maintenance/Branding.mdx similarity index 92% rename from docs/maintenance/BRANDING.md rename to docs/maintenance/Branding.mdx index 25c08b216e6..d4e84d90dea 100644 --- a/docs/maintenance/BRANDING.md +++ b/docs/maintenance/Branding.mdx @@ -31,7 +31,12 @@ You can call it _blurple_ if you want. Our logo is also a halfway between [ESLint's logo](https://en.wikipedia.org/wiki/ESLint#/media/File:ESLint_logo.svg) and [TypeScript's logo](https://en.wikipedia.org/wiki/TypeScript#/media/File:Typescript.svg): -typescript-eslint logo +typescript-eslint logo - [Logo PNG download](/img/logo.png) - [Logo SVG download](/img/logo.svg) diff --git a/docs/maintenance/ISSUES.md b/docs/maintenance/Issues.mdx similarity index 73% rename from docs/maintenance/ISSUES.md rename to docs/maintenance/Issues.mdx index ebddcc6df1b..fc8a89711de 100644 --- a/docs/maintenance/ISSUES.md +++ b/docs/maintenance/Issues.mdx @@ -3,7 +3,7 @@ id: issues title: Issues --- -This document serves as a guide for how you might manage issues, also known as issue triaging. +This document serves as a guide for how you might manage our [GitHub Issues](https://docs.github.com/issues), also known as issue triaging. Use your best judgement when triaging issues, and most of all remember to be **kind, friendly, and encouraging** when responding to users. Many users are new to open source and/or typed linting. @@ -93,13 +93,41 @@ These bugs should be reported with a link to a GitHub repository that can be che If you cannot reproduce the issue as described using repository's README.md and issue description, it has not provided enough information. Consider using a specific response like the _Needs Full Reproduction_ response. -### ✨ Rule Enhancements +### 🏗 Feature Requests -TODO: This will be filled out... soon! +For any feature request, make sure the requested support is either: -### 🚀 New Rules +- Very useful for at least one commonly used way to run TypeScript (e.g. tsc-built CLI package; bundler-managed web app) +- Relevant for _most_ projects that would be using typescript-eslint -TODO: This will be filled out... soon! +We avoid features that: + +- Are only relevant for a minority of users, as they aren't likely worth the maintenance burden +- Aren't TypeScript-specific (e.g. should be in ESLint core instead) +- Are only relevant with specific userland frameworks or libraries, such as Jest or React +- Are for "formatting" functionality (we [strongly recommend users use a separate dedicated formatter](../linting/troubleshooting/Formatting.mdx)) + +#### ✨ Rule Enhancements + +We're generally accepting of rule enhancements that meet the above feature request criteria. +If a rule enhancement would substantially change the target area of the rule, consider whether it should instead be a new rule. +Common signs of this are the rule's original name now being inaccurate, or some options being relevant just for the old functionality. + +Enhancements that can cause new reports to be reported are considered breaking changes. +We have two common strategies for them: + +- Treat the enhancement as a breaking change, and block merging it until the next major version +- Add an option to disable the new logic: which is a breaking change if opt-in, and a non-breaking change if opt-out +- Add an option to enable the new logic: which is a breaking change if opt-out, and a non-breaking change if opt-in + +See [Can we standardize logical direction of rule options?](https://github.com/typescript-eslint/typescript-eslint/discussions/6101) for context on naming options. + +For enhancements meant to limit which kinds of nodes the rule targets, mark the issue as blocked on [RFC: Common format to specify a type or value as a rule option](https://github.com/typescript-eslint/typescript-eslint/discussions/6017). + +#### 🚀 New Rules + +We're generally accepting of new rules that meet the above feature request criteria. +The biggest exception is rules that can roughly be implemented with [`@typescript-eslint/ban-types`](https://typescript-eslint.io/rules/ban-types) and/or [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax). ## Pruning Old Issues diff --git a/docs/maintenance/PULL_REQUESTS.md b/docs/maintenance/Pull_Requests.mdx similarity index 100% rename from docs/maintenance/PULL_REQUESTS.md rename to docs/maintenance/Pull_Requests.mdx diff --git a/docs/maintenance/RELEASES.md b/docs/maintenance/Releases.mdx similarity index 92% rename from docs/maintenance/RELEASES.md rename to docs/maintenance/Releases.mdx index 211294d488b..87fb87529df 100644 --- a/docs/maintenance/RELEASES.md +++ b/docs/maintenance/Releases.mdx @@ -10,6 +10,27 @@ We release a canary version for each commit to `main` that passes all required c This release is goes to the `canary` tag on npm and it is versioned as an incremental canary patch release on top of the current `latest` version. I.e. if the current version is `5.6.1`, then the first canary version will be `5.6.2-alpha.0`, the second `5.6.2-alpha.1`, and so on. +### Installing Canary Versions + +To try out the latest canary versions of typescript-eslint, install `@typescript-eslint/eslint-plugin@canary` and `@typescript-eslint/parser@canary`. +Note that npm may need a `--force` to override version requirements. + + + +### npm + +```bash +npm i @typescript-eslint/eslint-plugin@canary @typescript-eslint/parser@canary --save-dev --force +``` + +### Yarn + +```bash +yarn add @typescript-eslint/eslint-plugin@canary @typescript-eslint/parser@canary --save-dev +``` + + + ## Latest We release a latest version every Monday at 1pm US Eastern time using the latest commit to `main` at that time. This release is performed automatically by a Github action located in a private repository. This release goes to the standard `latest` tag on npm. diff --git a/docs/maintenance/VERSIONING.md b/docs/maintenance/Versioning.mdx similarity index 91% rename from docs/maintenance/VERSIONING.md rename to docs/maintenance/Versioning.mdx index 0dd31ae90c1..68a007c89c1 100644 --- a/docs/maintenance/VERSIONING.md +++ b/docs/maintenance/Versioning.mdx @@ -1,6 +1,5 @@ --- id: versioning -sidebar_label: Versioning title: Versioning --- @@ -15,11 +14,21 @@ Additionally, we promote to the `latest` tag on NPM once per week, **on Mondays The latest version under the `latest` tag is: -NPM Version + + NPM Version + The latest version under the `canary` tag **(latest commit to `main`)** is: -NPM Version + + NPM Version + :::note The only exception to the automated publishes described above is when we are in the final phases of creating the next major version of the libraries - e.g. going from `1.x.x` to `2.x.x`. @@ -28,9 +37,22 @@ During these periods, we manually publish `canary` releases until we are happy w ## Dependant Versions +> See [Versioning > Dependant Version Upgrades](./versioning/dependant-version-upgrades.mdx) for maintenance steps to update these versions. + +### ESLint + +> The version range of ESLint currently supported is `^6.0.0 || ^7.0.0 || ^8.0.0`. + +We generally support at least the latest two major versions of ESLint. + +### Node + +This project makes an effort to support Active LTS and Maintenance LTS release statuses of Node according to [Node's release document](https://nodejs.org/en/about/releases). +Support for specific Current status releases are considered periodically. + ### TypeScript -> The version range of TypeScript currently supported is `>=3.3.1 <4.9.0`. +> The version range of TypeScript currently supported is `>=3.3.1 <5.0.0`. These versions are what we test against. @@ -42,18 +64,7 @@ Note that our packages have an open `peerDependency` requirement in order to all If you use a non-supported version of TypeScript, the parser will log a warning to the console. If you want to disable this warning, you can configure this in your `parserOptions`. -See: [`@typescript-eslint/parser`](./packages/parser/ TODO JOSH) and [`@typescript-eslint/typescript-estree`](./packages/typescript-estree/ TODO JOSH). - -### ESLint - -> The version range of ESLint currently supported is `^6.0.0 || ^7.0.0 || ^8.0.0`. - -We generally support at least the latest two major versions of ESLint. - -### Node - -This project makes an effort to support Active LTS and Maintenance LTS release statuses of Node according to [Node's release document](https://nodejs.org/en/about/releases). -Support for specific Current status releases are considered periodically. +See: [Parser > `warnOnUnsupportedTypeScriptVersion`](../architecture/Parser.mdx#warnonunsupportedtypescriptversion). ## Breaking Changes diff --git a/docs/maintenance/issues/Rule_Deprecations.md b/docs/maintenance/issues/Rule_Deprecations.mdx similarity index 100% rename from docs/maintenance/issues/Rule_Deprecations.md rename to docs/maintenance/issues/Rule_Deprecations.mdx diff --git a/docs/maintenance/versioning/dependant-version-upgrades.mdx b/docs/maintenance/versioning/dependant-version-upgrades.mdx new file mode 100644 index 00000000000..bf1a17f2829 --- /dev/null +++ b/docs/maintenance/versioning/dependant-version-upgrades.mdx @@ -0,0 +1,121 @@ +--- +id: dependant-version-upgrades +title: Dependant Version Upgrades +--- + +## ESLint + +The typescript-eslint repository contains four kinds of version ranges for the `eslint` package: + +- Integration tests: Pinned to our lowest supported ESLint version +- Packages with a `*` `peerDependency` version: These fall back to the explicit `peerDependency` versions +- Packages with explicit `peerDependency` versions: The full range of supported ESLint major versions +- [Root `package.json`](https://github.com/typescript-eslint/typescript-eslint/blob/main/package.json)'s' `devDependency`: A relatively recent release, used only for repository development + +:::tip +Whenever you discover any new areas of work that are blocked by dropping an old ESLint version, such as new ESLint API deprecations, add a _TODO_ comment that will be caught by the regular expressions under [Removing Support for an Old ESLint Version](#removing-support-for-an-old-eslint-version). +::: + +### Adding Support for a New ESLint Version + +1. Upgrade the root `package.json` `devDependency` to the latest ESLint +1. Add the new major version to the explicit `peerDependency` versions +1. Check [`eslint-visitor-keys`](https://www.npmjs.com/package/eslint-visitor-keys) for a new version to be upgraded to as well. +1. Update [Versioning > ESLint](../Versioning.mdx#eslint) + +### Removing Support for an Old ESLint Version + +1. Increase the integration tests to the next lowest supported major version (`*.0.0`) +1. Remove the old major versions from packages with explicit `peerDependency` versions +1. Search for source code comments (excluding `CHANGELOG.md` files) that mention a now-unsupported version of ESLint. + - For example, to remove support for v5, searches might include: + - `/eslint.*5/i` + - `/todo.*eslint.*5/i` + - `/todo.*eslint/i` +1. Update [Versioning > ESLint](../Versioning.mdx#eslint) + +See [chore: drop support for ESLint v6](https://github.com/typescript-eslint/typescript-eslint/pull/5972) for reference. + +## Node + +The typescript-eslint repository contains three kinds of version ranges for Node: + +- [`.github/workflows/ci.yml`](https://github.com/typescript-eslint/typescript-eslint/blob/main/.github/workflows/ci.yml)'s `PRIMARY_NODE_VERSION`: Set to the highest Node version we support +- `node-version`: Set to a tuple of our [lowest, highest] supported versions for our unit tests in CI +- `engines` field in all `package.json`s: explicitly lists all supported Node ranges + +Change those numbers accordingly when adding support for a new Node version or removing support for an old Node version. + +See [feat: drop support for node v12](https://github.com/typescript-eslint/typescript-eslint/pull/5918) + [chore: test node v14 on ci.yml](https://github.com/typescript-eslint/typescript-eslint/pull/5512) for reference. + +## TypeScript + +### Adding Support for a New TypeScript Version + +We generally start the process of supporting a new TypeScript version just after the first beta release for that version is made available. + +1. Create and pin an issue with a title like _TypeScript X.Y Support_, `accepting prs`, `AST`, `dependencies`, and `New TypeScript Version` labels, and the following contents: + + 1. A link to the _TypeScript X.Y Iteration Plan_ issue from the Microsoft issue tracker + 2. The following text: + + ```md + This issue is just to track all of the new features and their implementation state in this project. + As with all releases, we will not necessarily support all features until closer to the full release when everything the features are stabilised. + + _Please be patient._ ❤️ + ``` + + 3. A heading starting with `🔲 ` for each new TypeScript feature called out in the iteration plan that will impact us + 4. A heading titled _🔲 `lib.d.ts` Updates_ and the content _We will need to regenerate our types within `scope-manager`_ + 5. A heading titled _Other changes with no impact to us_ containing a list of other changes that we don't believe will impact us + +1. At this stage, it's fine to send and/or review PRs that implement necessary features, but wait to merge them until the new TypeScript version's RC is released + - Whenever a PR is created, add ` (#1234)` to its respective heading, and change the heading's emoji from 🔲 to 🏗 + - Search for `expectBabelToNotSupport` to see how to support syntaxes not yet supported by Babel +1. Once the TypeScript RC version is released, start merging PRs + - Whenever a PR is merged, change the respective heading's emoji from 🏗 to ✅ +1. Create a PR with a title like `feat: update TypeScript to X.Y-rc` and the following changes: + - In the root `package.json`, add `|| X.Y.2-rc2` to the `dependency` on `typescript` + - In the root `package.json`, change the `devDependency` on `typescript` to `~X.Y.2-rc2` + - Change the `SUPPORTED_TYPESCRIPT_VERSIONS` constant's `<` version to the next version of TypeScript + - Change the `SUPPORTED_PRERELEASE_RANGES` constant to equal `['X.Y.2-rc']` + - Rename and update `patches/typescript*` to the new TypeScript version + - Run `yarn generate:lib` to update `scope-manager` +1. Once all PRs needed for the RC update PR are merged, merge the RC update PR +1. Once TypeScript releases the stable X.Y version, create and merge a PR with a title like `chore: bump TypeScript from X.YRC to X.Y` and the following changes: + - In the root `package.json`, remove `|| X.Y.2-rc2` from the `dependency` on `typescript`, and bump its `<` version to the next version of TypeScript + - In the root `package.json`, change the `devDependency` on `typescript` to `~X.Y.3` + - Rename and update `patches/typescript*` to the new TypeScript version + - Any other changes made necessary due to changes in TypeScript between the RC version and stable version + - Update the supported version range in [Versioning](../Versioning.mdx) +1. Update [Versioning > TypeScript](../Versioning.mdx#typescript) +1. Send a PR that updates this documentation page to point to your newer issues and PRs + - Also update any of these steps if you go with a different process + +See for reference (caveat: these don't follow the exact process described here): + +- [TypeScript 4.7 Support](https://github.com/typescript-eslint/typescript-eslint/issues/4800) +- [TypeScript 4.8 Support](https://github.com/typescript-eslint/typescript-eslint/issues/5227) +- [feat: support TypeScript 4.8](https://github.com/typescript-eslint/typescript-eslint/pull/5551) +- [feat: support TypeScript 4.9](https://github.com/typescript-eslint/typescript-eslint/pull/5716) +- [chore: bump TS from 4.9RC to 4.9](https://github.com/typescript-eslint/typescript-eslint/commit/a40a311bb52a2b1cfac43851b201f8cfc96c8d5d) + +### Removing Support for an Old TypeScript Version + +A single PR can remove support for old TypeScript versions as a breaking change: + +1. Update the root `package.json` `devDependency` +1. Update the `SUPPORTED_TYPESCRIPT_VERSIONS` constant in `warnAboutTSVersion.ts` +1. Update the `versions` constant in `version-check.ts` +1. Update [Versioning > TypeScript](../Versioning.mdx#typescript) +1. Search for source code comments (excluding `CHANGELOG.md` files) that mention a now-unsupported version of TypeScript. + - For example, to remove support for v4.3, searches might include: + - `4.3` + - `/is.*4.*3/i` + - `/semver.*4.*3/i` + - `/semver.satisfies/` + - `/todo.*ts/i` + - `/todo.*typescript/i` + +See [feat: bump minimum supported TS version to 4.2.4](https://github.com/typescript-eslint/typescript-eslint/pull/5915). diff --git a/lerna.json b/lerna.json index d9674ac9fb9..e150bc530f7 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "5.48.2", + "version": "5.50.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/nx.json b/nx.json index b34a91f7800..731dc56a3c7 100644 --- a/nx.json +++ b/nx.json @@ -1,22 +1,12 @@ { "$schema": "./node_modules/nx/schemas/nx-schema.json", "npmScope": "typescript-eslint", - "affected": { - "defaultBase": "main" - }, - "workspaceLayout": { - "libsDir": "packages" - }, "tasksRunnerOptions": { "default": { "runner": "@nrwl/nx-cloud", "options": { "cacheableOperations": ["build", "lint", "package", "prebuild", "test"], - "accessToken": "YjFjNTBhOWUtY2JmNy00ZDhiLWE5N2UtZjliNDAwNmIzOTdjfHJlYWQtd3JpdGU=", - "canTrackAnalytics": false, - "showUsageWarnings": true, - "runtimeCacheInputs": ["node -v", "echo $NETLIFY"], - "parallel": 1 + "accessToken": "YjFjNTBhOWUtY2JmNy00ZDhiLWE5N2UtZjliNDAwNmIzOTdjfHJlYWQtd3JpdGU=" } } }, @@ -26,11 +16,32 @@ "inputs": ["production", "^production"] }, "test": { + "inputs": [ + "default", + "{workspaceRoot}/jest.config.js", + "{workspaceRoot}/jest.config.base.js" + ], "outputs": ["{projectRoot}/coverage"] + }, + "lint": { + "inputs": [ + "default", + "{workspaceRoot}/.eslintrc.js", + "{workspaceRoot}/.eslintignore" + ] } }, "namedInputs": { - "default": ["{projectRoot}/**/*", "sharedGlobals"], + "default": [ + "{projectRoot}/**/*", + "sharedGlobals", + { + "runtime": "node -v" + }, + { + "runtime": "echo $NETLIFY" + } + ], "sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"], "production": ["default"] } diff --git a/package.json b/package.json index e38db1983e6..f8b24d34edf 100644 --- a/package.json +++ b/package.json @@ -22,28 +22,28 @@ "url": "https://github.com/typescript-eslint/typescript-eslint/issues" }, "scripts": { - "build": "nx run-many --target=build --all --parallel --exclude website", + "build": "nx run-many --target=build --parallel --exclude website", "check-clean-workspace-after-install": "git diff --quiet --exit-code", - "check-configs": "nx run-many --target=check-configs --all --parallel", - "check-docs": "nx run-many --target=check-docs --all --parallel", + "check-configs": "nx run-many --target=check-configs --parallel", + "check-docs": "nx run-many --target=check-docs --parallel", "check-format": "prettier --list-different .", "check-spelling": "cspell --config=.cspell.json \"**/*.{md,mdx,ts,mts,cts,js,cjs,mjs,tsx,jsx}\"", "clean": "lerna clean -y && nx run-many --target=clean", "format": "prettier --write .", - "generate-contributors": "yarn ts-node --transpile-only ./tools/generate-contributors.ts", - "generate-sponsors": "yarn ts-node --transpile-only ./tools/generate-sponsors.ts", - "generate-website-dts": "yarn ts-node --transpile-only ./tools/generate-website-dts.ts", + "generate-contributors": "yarn tsx ./tools/generate-contributors.ts", + "generate-sponsors": "yarn tsx ./tools/generate-sponsors.ts", + "generate-website-dts": "yarn tsx ./tools/generate-website-dts.ts", "generate-lib": "nx generate-lib @typescript-eslint/scope-manager", "lint-fix": "eslint . --fix", "lint-markdown-fix": "yarn lint-markdown --fix", "lint-markdown": "markdownlint \"**/*.md\" --config=.markdownlint.json --ignore-path=.markdownlintignore", - "lint": "nx run-many --target=lint --all --parallel", - "postinstall": "yarn ts-node --transpile-only ./tools/postinstall.ts", + "lint": "nx run-many --target=lint --parallel", + "postinstall": "yarn tsx ./tools/postinstall.ts", "pre-commit": "yarn lint-staged", "start": "nx run website:start", - "test": "nx run-many --target=test --all --parallel", + "test": "nx run-many --target=test --parallel", "test-integration": "yarn jest -c ./tests/integration/jest.config.js", - "typecheck": "nx run-many --target=typecheck --all --parallel" + "typecheck": "nx run-many --target=typecheck --parallel" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -52,11 +52,11 @@ "@babel/code-frame": "^7.18.6", "@babel/core": "^7.20.2", "@babel/eslint-parser": "^7.19.1", - "@babel/parser": "^7.20.3", + "@babel/parser": "^7.20.7", "@babel/types": "^7.20.2", + "@nrwl/jest": "15.6.3", "@nrwl/nx-cloud": "15.0.2", - "@nrwl/jest": "15.3.2", - "@nrwl/workspace": "15.3.2", + "@nrwl/workspace": "15.6.3", "@swc/core": "^1.3.1", "@swc/jest": "^0.2.21", "@types/babel__code-frame": "^7.0.3", @@ -86,7 +86,7 @@ "eslint-plugin-eslint-plugin": "^5.0.1", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.0.0", - "eslint-plugin-simple-import-sort": "^8.0.0", + "eslint-plugin-simple-import-sort": "^10.0.0", "execa": "5.1.1", "glob": "^8.0.1", "husky": "^8.0.1", @@ -94,19 +94,20 @@ "jest-diff": "^29.0.3", "jest-snapshot": "^29.0.3", "jest-specific-snapshot": "^7.0.0", - "lerna": "6.4.0", + "lerna": "6.4.1", "lint-staged": "^13.0.0", "make-dir": "^3.1.0", - "markdownlint-cli": "^0.32.0", + "markdownlint-cli": "^0.33.0", "ncp": "^2.0.0", - "nx": "15.3.2", + "nx": "15.6.3", "patch-package": "^6.4.7", "prettier": "2.8.1", "pretty-format": "^29.0.3", - "rimraf": "^3.0.2", + "rimraf": "^4.0.0", "tmp": "^0.2.1", - "ts-node": "^10.7.0", + "ts-node": "10.7.0", "tslint": "^6.1.3", + "tsx": "^3.12.1", "typescript": ">=3.3.1 <5.0.0" }, "resolutions": { diff --git a/packages/ast-spec/CHANGELOG.md b/packages/ast-spec/CHANGELOG.md index 7568a697270..3b4168eff86 100644 --- a/packages/ast-spec/CHANGELOG.md +++ b/packages/ast-spec/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + + +### Bug Fixes + +* **ast-spec:** a JSXEmptyExpression is not a possible JSXExpression ([#6321](https://github.com/typescript-eslint/typescript-eslint/issues/6321)) ([4b27777](https://github.com/typescript-eslint/typescript-eslint/commit/4b27777ed26cc83d6efc52a89b2d3fc6c01bc0d7)) + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/ast-spec + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/ast-spec diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index ed1d776f4be..c5e160a5c41 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/ast-spec", - "version": "5.48.2", + "version": "5.50.0", "description": "Complete specification for the TypeScript-ESTree AST", "private": true, "keywords": [ diff --git a/packages/ast-spec/project.json b/packages/ast-spec/project.json index 682cdbf3d91..41721d18d71 100644 --- a/packages/ast-spec/project.json +++ b/packages/ast-spec/project.json @@ -10,7 +10,7 @@ "cwd": "packages/ast-spec", "commands": ["yarn build"] }, - "outputs": ["packages/ast-spec/dist/**/*.ts"] + "outputs": ["{projectRoot}/dist/**/*.ts"] }, "lint": { "executor": "@nrwl/linter:eslint", diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/1-TSESTree-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/1-TSESTree-Error.shot deleted file mode 100644 index e9efe0512eb..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/1-TSESTree-Error.shot +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AST Fixtures element AccessorProperty _error_ modifier-declare TSESTree - Error 1`] = `"NO ERROR"`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/2-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/2-Babel-Error.shot deleted file mode 100644 index 7d44c5a9712..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/2-Babel-Error.shot +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AST Fixtures element AccessorProperty _error_ modifier-declare Babel - Error 1`] = `[SyntaxError: Missing semicolon. (2:22)]`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/3-Alignment-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/3-Alignment-Error.shot deleted file mode 100644 index a6fbd60e31c..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/snapshots/3-Alignment-Error.shot +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AST Fixtures element AccessorProperty _error_ modifier-declare Error Alignment 1`] = `"Babel errored but TSESTree didn't"`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.ts b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.ts deleted file mode 100644 index 61e0e137a0e..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - expectBabelToNotSupport: 'https://github.com/babel/babel/issues/15205', -} satisfies ASTFixtureConfig; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-AST.shot new file mode 100644 index 00000000000..147bdd6cb25 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-AST.shot @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract-with-value Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + abstract: true, + body: ClassBody { + type: "ClassBody", + body: Array [ + ClassAccessorProperty { + type: "ClassAccessorProperty", + abstract: true, + computed: false, + key: Identifier { + type: "Identifier", + name: "foo", + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSNumberKeyword { + type: "TSNumberKeyword", + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [44, 52], + loc: { + start: { column: 23, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + value: Literal { + type: "Literal", + raw: "1", + value: 1, + + range: [55, 56], + loc: { + start: { column: 34, line: 2 }, + end: { column: 35, line: 2 }, + }, + }, + + range: [23, 57], + loc: { + start: { column: 2, line: 2 }, + end: { column: 36, line: 2 }, + }, + }, + ], + + range: [19, 59], + loc: { + start: { column: 19, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + superClass: null, + + range: [0, 59], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 60], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/4-Babel-Tokens.shot new file mode 100644 index 00000000000..1d49b0c7ad1 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,136 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract-with-value Babel - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "abstract", + + range: [0, 8], + loc: { + start: { column: 0, line: 1 }, + end: { column: 8, line: 1 }, + }, + }, + Keyword { + type: "Keyword", + value: "class", + + range: [9, 14], + loc: { + start: { column: 9, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [19, 20], + loc: { + start: { column: 19, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abstract", + + range: [23, 31], + loc: { + start: { column: 2, line: 2 }, + end: { column: 10, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [32, 40], + loc: { + start: { column: 11, line: 2 }, + end: { column: 19, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "foo", + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [44, 45], + loc: { + start: { column: 23, line: 2 }, + end: { column: 24, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "number", + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "=", + + range: [53, 54], + loc: { + start: { column: 32, line: 2 }, + end: { column: 33, line: 2 }, + }, + }, + Numeric { + type: "Numeric", + value: "1", + + range: [55, 56], + loc: { + start: { column: 34, line: 2 }, + end: { column: 35, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [56, 57], + loc: { + start: { column: 35, line: 2 }, + end: { column: 36, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [58, 59], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 00000000000..27b36ea8b18 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,108 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract-with-value AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + ClassDeclaration { + type: 'ClassDeclaration', + abstract: true, + body: ClassBody { + type: 'ClassBody', + body: Array [ +- TSAbstractAccessorProperty { +- type: 'TSAbstractAccessorProperty', ++ ClassAccessorProperty { ++ type: 'ClassAccessorProperty', ++ abstract: true, + computed: false, +- declare: false, + key: Identifier { + type: 'Identifier', + name: 'foo', + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, +- override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: 'TSTypeAnnotation', + typeAnnotation: TSNumberKeyword { + type: 'TSNumberKeyword', + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [44, 52], + loc: { + start: { column: 23, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, +- value: null, ++ value: Literal { ++ type: 'Literal', ++ raw: '1', ++ value: 1, ++ ++ range: [55, 56], ++ loc: { ++ start: { column: 34, line: 2 }, ++ end: { column: 35, line: 2 }, ++ }, ++ }, + + range: [23, 57], + loc: { + start: { column: 2, line: 2 }, + end: { column: 36, line: 2 }, + }, + }, + ], + + range: [19, 59], + loc: { + start: { column: 19, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: 'Identifier', + name: 'Foo', + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + superClass: null, + + range: [0, 59], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 60], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, + }" +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/6-AST-Alignment-Tokens.shot similarity index 50% rename from packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-Error.shot rename to packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/6-AST-Alignment-Tokens.shot index c49a847cd3a..fd832b249e4 100644 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/3-Babel-Error.shot +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract-with-value/snapshots/6-AST-Alignment-Tokens.shot @@ -1,3 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AST Fixtures element AccessorProperty modifier-abstract-with-value Babel - Error 1`] = `[SyntaxError: Missing semicolon. (2:23)]`; +exports[`AST Fixtures element AccessorProperty modifier-abstract-with-value AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.ts b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.ts deleted file mode 100644 index 61e0e137a0e..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - expectBabelToNotSupport: 'https://github.com/babel/babel/issues/15205', -} satisfies ASTFixtureConfig; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-AST.shot new file mode 100644 index 00000000000..6423ad41435 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-AST.shot @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + abstract: true, + body: ClassBody { + type: "ClassBody", + body: Array [ + ClassAccessorProperty { + type: "ClassAccessorProperty", + abstract: true, + computed: false, + key: Identifier { + type: "Identifier", + name: "foo", + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSNumberKeyword { + type: "TSNumberKeyword", + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [44, 52], + loc: { + start: { column: 23, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + value: null, + + range: [23, 53], + loc: { + start: { column: 2, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + ], + + range: [19, 55], + loc: { + start: { column: 19, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + superClass: null, + + range: [0, 55], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 56], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/4-Babel-Tokens.shot new file mode 100644 index 00000000000..41f02a22191 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,116 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract Babel - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "abstract", + + range: [0, 8], + loc: { + start: { column: 0, line: 1 }, + end: { column: 8, line: 1 }, + }, + }, + Keyword { + type: "Keyword", + value: "class", + + range: [9, 14], + loc: { + start: { column: 9, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [19, 20], + loc: { + start: { column: 19, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abstract", + + range: [23, 31], + loc: { + start: { column: 2, line: 2 }, + end: { column: 10, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [32, 40], + loc: { + start: { column: 11, line: 2 }, + end: { column: 19, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "foo", + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [44, 45], + loc: { + start: { column: 23, line: 2 }, + end: { column: 24, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "number", + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [52, 53], + loc: { + start: { column: 31, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [54, 55], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 00000000000..cecb46eb91f --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-abstract AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + ClassDeclaration { + type: 'ClassDeclaration', + abstract: true, + body: ClassBody { + type: 'ClassBody', + body: Array [ +- TSAbstractAccessorProperty { +- type: 'TSAbstractAccessorProperty', ++ ClassAccessorProperty { ++ type: 'ClassAccessorProperty', ++ abstract: true, + computed: false, +- declare: false, + key: Identifier { + type: 'Identifier', + name: 'foo', + + range: [41, 44], + loc: { + start: { column: 20, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, +- override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: 'TSTypeAnnotation', + typeAnnotation: TSNumberKeyword { + type: 'TSNumberKeyword', + + range: [46, 52], + loc: { + start: { column: 25, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [44, 52], + loc: { + start: { column: 23, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + value: null, + + range: [23, 53], + loc: { + start: { column: 2, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + ], + + range: [19, 55], + loc: { + start: { column: 19, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: 'Identifier', + name: 'Foo', + + range: [15, 18], + loc: { + start: { column: 15, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + superClass: null, + + range: [0, 55], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 56], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, + }" +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/6-AST-Alignment-Tokens.shot similarity index 53% rename from packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-Error.shot rename to packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/6-AST-Alignment-Tokens.shot index 6f975b3a497..8d5295e9c35 100644 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/3-Babel-Error.shot +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-abstract/snapshots/6-AST-Alignment-Tokens.shot @@ -1,3 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AST Fixtures element AccessorProperty modifier-abstract Babel - Error 1`] = `[SyntaxError: Missing semicolon. (2:23)]`; +exports[`AST Fixtures element AccessorProperty modifier-abstract AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/fixture.ts b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/fixture.ts similarity index 100% rename from packages/ast-spec/src/element/AccessorProperty/fixtures/_error_/modifier-declare/fixture.ts rename to packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/fixture.ts diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/1-TSESTree-AST.shot new file mode 100644 index 00000000000..0b61be5984a --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/1-TSESTree-AST.shot @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare TSESTree - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + body: ClassBody { + type: "ClassBody", + body: Array [ + AccessorProperty { + type: "AccessorProperty", + computed: false, + declare: true, + key: Identifier { + type: "Identifier", + name: "foo", + + range: [31, 34], + loc: { + start: { column: 19, line: 2 }, + end: { column: 22, line: 2 }, + }, + }, + override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSNumberKeyword { + type: "TSNumberKeyword", + + range: [36, 42], + loc: { + start: { column: 24, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + + range: [34, 42], + loc: { + start: { column: 22, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + value: null, + + range: [14, 43], + loc: { + start: { column: 2, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + ], + + range: [10, 45], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 45], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 46], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/2-TSESTree-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/2-TSESTree-Tokens.shot new file mode 100644 index 00000000000..c9f1a1a1da8 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/2-TSESTree-Tokens.shot @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare TSESTree - Tokens 1`] = ` +Array [ + Keyword { + type: "Keyword", + value: "class", + + range: [0, 5], + loc: { + start: { column: 0, line: 1 }, + end: { column: 5, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [10, 11], + loc: { + start: { column: 10, line: 1 }, + end: { column: 11, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "declare", + + range: [14, 21], + loc: { + start: { column: 2, line: 2 }, + end: { column: 9, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [22, 30], + loc: { + start: { column: 10, line: 2 }, + end: { column: 18, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "foo", + + range: [31, 34], + loc: { + start: { column: 19, line: 2 }, + end: { column: 22, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [34, 35], + loc: { + start: { column: 22, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "number", + + range: [36, 42], + loc: { + start: { column: 24, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [42, 43], + loc: { + start: { column: 30, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [44, 45], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/3-Babel-AST.shot new file mode 100644 index 00000000000..057e8de958a --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/3-Babel-AST.shot @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + body: ClassBody { + type: "ClassBody", + body: Array [ + ClassAccessorProperty { + type: "ClassAccessorProperty", + computed: false, + declare: true, + key: Identifier { + type: "Identifier", + name: "foo", + + range: [31, 34], + loc: { + start: { column: 19, line: 2 }, + end: { column: 22, line: 2 }, + }, + }, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSNumberKeyword { + type: "TSNumberKeyword", + + range: [36, 42], + loc: { + start: { column: 24, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + + range: [34, 42], + loc: { + start: { column: 22, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + value: null, + + range: [14, 43], + loc: { + start: { column: 2, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + ], + + range: [10, 45], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 45], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 46], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/4-Babel-Tokens.shot new file mode 100644 index 00000000000..991730e68ff --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare Babel - Tokens 1`] = ` +Array [ + Keyword { + type: "Keyword", + value: "class", + + range: [0, 5], + loc: { + start: { column: 0, line: 1 }, + end: { column: 5, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [10, 11], + loc: { + start: { column: 10, line: 1 }, + end: { column: 11, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "declare", + + range: [14, 21], + loc: { + start: { column: 2, line: 2 }, + end: { column: 9, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [22, 30], + loc: { + start: { column: 10, line: 2 }, + end: { column: 18, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "foo", + + range: [31, 34], + loc: { + start: { column: 19, line: 2 }, + end: { column: 22, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [34, 35], + loc: { + start: { column: 22, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "number", + + range: [36, 42], + loc: { + start: { column: 24, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [42, 43], + loc: { + start: { column: 30, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [44, 45], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 00000000000..76e4314a3c6 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + ClassDeclaration { + type: 'ClassDeclaration', + body: ClassBody { + type: 'ClassBody', + body: Array [ +- AccessorProperty { +- type: 'AccessorProperty', ++ ClassAccessorProperty { ++ type: 'ClassAccessorProperty', + computed: false, + declare: true, + key: Identifier { + type: 'Identifier', + name: 'foo', + + range: [31, 34], + loc: { + start: { column: 19, line: 2 }, + end: { column: 22, line: 2 }, + }, + }, +- override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: 'TSTypeAnnotation', + typeAnnotation: TSNumberKeyword { + type: 'TSNumberKeyword', + + range: [36, 42], + loc: { + start: { column: 24, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + + range: [34, 42], + loc: { + start: { column: 22, line: 2 }, + end: { column: 30, line: 2 }, + }, + }, + value: null, + + range: [14, 43], + loc: { + start: { column: 2, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + ], + + range: [10, 45], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: 'Identifier', + name: 'Foo', + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 45], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 46], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, + }" +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/6-AST-Alignment-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/6-AST-Alignment-Tokens.shot new file mode 100644 index 00000000000..491288c619b --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/modifier-declare/snapshots/6-AST-Alignment-Tokens.shot @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty modifier-declare AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.ts b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.ts deleted file mode 100644 index 61e0e137a0e..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - expectBabelToNotSupport: 'https://github.com/babel/babel/issues/15205', -} satisfies ASTFixtureConfig; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-AST.shot new file mode 100644 index 00000000000..b1451f6ef4d --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-AST.shot @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-no-value Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + body: ClassBody { + type: "ClassBody", + body: Array [ + ClassAccessorProperty { + type: "ClassAccessorProperty", + computed: false, + key: Identifier { + type: "Identifier", + name: "prop", + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSStringKeyword { + type: "TSStringKeyword", + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + + range: [27, 35], + loc: { + start: { column: 15, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + value: null, + + range: [14, 36], + loc: { + start: { column: 2, line: 2 }, + end: { column: 24, line: 2 }, + }, + }, + ], + + range: [10, 38], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 38], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 39], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/4-Babel-Tokens.shot new file mode 100644 index 00000000000..3c588981ba1 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,96 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-no-value Babel - Tokens 1`] = ` +Array [ + Keyword { + type: "Keyword", + value: "class", + + range: [0, 5], + loc: { + start: { column: 0, line: 1 }, + end: { column: 5, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [10, 11], + loc: { + start: { column: 10, line: 1 }, + end: { column: 11, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [14, 22], + loc: { + start: { column: 2, line: 2 }, + end: { column: 10, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "prop", + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [27, 28], + loc: { + start: { column: 15, line: 2 }, + end: { column: 16, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "string", + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [35, 36], + loc: { + start: { column: 23, line: 2 }, + end: { column: 24, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [37, 38], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 00000000000..d5ff97f0998 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-no-value AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + ClassDeclaration { + type: 'ClassDeclaration', + body: ClassBody { + type: 'ClassBody', + body: Array [ +- AccessorProperty { +- type: 'AccessorProperty', ++ ClassAccessorProperty { ++ type: 'ClassAccessorProperty', + computed: false, +- declare: false, + key: Identifier { + type: 'Identifier', + name: 'prop', + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, +- override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: 'TSTypeAnnotation', + typeAnnotation: TSStringKeyword { + type: 'TSStringKeyword', + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + + range: [27, 35], + loc: { + start: { column: 15, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + value: null, + + range: [14, 36], + loc: { + start: { column: 2, line: 2 }, + end: { column: 24, line: 2 }, + }, + }, + ], + + range: [10, 38], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: 'Identifier', + name: 'Foo', + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 38], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 39], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, + }" +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/6-AST-Alignment-Tokens.shot similarity index 51% rename from packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-Error.shot rename to packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/6-AST-Alignment-Tokens.shot index 95932fa9389..285c4824154 100644 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/3-Babel-Error.shot +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-no-value/snapshots/6-AST-Alignment-Tokens.shot @@ -1,3 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AST Fixtures element AccessorProperty with-annotation-no-value Babel - Error 1`] = `[SyntaxError: Missing semicolon. (2:15)]`; +exports[`AST Fixtures element AccessorProperty with-annotation-no-value AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.ts b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.ts deleted file mode 100644 index 61e0e137a0e..00000000000 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - expectBabelToNotSupport: 'https://github.com/babel/babel/issues/15205', -} satisfies ASTFixtureConfig; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-AST.shot new file mode 100644 index 00000000000..dbe2364b124 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-AST.shot @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-with-value Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + ClassDeclaration { + type: "ClassDeclaration", + body: ClassBody { + type: "ClassBody", + body: Array [ + ClassAccessorProperty { + type: "ClassAccessorProperty", + computed: false, + key: Identifier { + type: "Identifier", + name: "prop", + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, + static: false, + typeAnnotation: TSTypeAnnotation { + type: "TSTypeAnnotation", + typeAnnotation: TSStringKeyword { + type: "TSStringKeyword", + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + + range: [27, 35], + loc: { + start: { column: 15, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + value: Literal { + type: "Literal", + raw: "'str'", + value: "str", + + range: [38, 43], + loc: { + start: { column: 26, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [14, 44], + loc: { + start: { column: 2, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + ], + + range: [10, 46], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 46], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: "script", + + range: [0, 47], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, +} +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/4-Babel-Tokens.shot new file mode 100644 index 00000000000..d8a82e4c1bb --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,116 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-with-value Babel - Tokens 1`] = ` +Array [ + Keyword { + type: "Keyword", + value: "class", + + range: [0, 5], + loc: { + start: { column: 0, line: 1 }, + end: { column: 5, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "Foo", + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [10, 11], + loc: { + start: { column: 10, line: 1 }, + end: { column: 11, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "accessor", + + range: [14, 22], + loc: { + start: { column: 2, line: 2 }, + end: { column: 10, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "prop", + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ":", + + range: [27, 28], + loc: { + start: { column: 15, line: 2 }, + end: { column: 16, line: 2 }, + }, + }, + Identifier { + type: "Identifier", + value: "string", + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "=", + + range: [36, 37], + loc: { + start: { column: 24, line: 2 }, + end: { column: 25, line: 2 }, + }, + }, + String { + type: "String", + value: "'str'", + + range: [38, 43], + loc: { + start: { column: 26, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ";", + + range: [43, 44], + loc: { + start: { column: 31, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [45, 46], + loc: { + start: { column: 0, line: 3 }, + end: { column: 1, line: 3 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 00000000000..0e95b7b4620 --- /dev/null +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,105 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures element AccessorProperty with-annotation-with-value AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + ClassDeclaration { + type: 'ClassDeclaration', + body: ClassBody { + type: 'ClassBody', + body: Array [ +- AccessorProperty { +- type: 'AccessorProperty', ++ ClassAccessorProperty { ++ type: 'ClassAccessorProperty', + computed: false, +- declare: false, + key: Identifier { + type: 'Identifier', + name: 'prop', + + range: [23, 27], + loc: { + start: { column: 11, line: 2 }, + end: { column: 15, line: 2 }, + }, + }, +- override: false, + static: false, + typeAnnotation: TSTypeAnnotation { + type: 'TSTypeAnnotation', + typeAnnotation: TSStringKeyword { + type: 'TSStringKeyword', + + range: [29, 35], + loc: { + start: { column: 17, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + + range: [27, 35], + loc: { + start: { column: 15, line: 2 }, + end: { column: 23, line: 2 }, + }, + }, + value: Literal { + type: 'Literal', + raw: '\\\\'str\\\\'', + value: 'str', + + range: [38, 43], + loc: { + start: { column: 26, line: 2 }, + end: { column: 31, line: 2 }, + }, + }, + + range: [14, 44], + loc: { + start: { column: 2, line: 2 }, + end: { column: 32, line: 2 }, + }, + }, + ], + + range: [10, 46], + loc: { + start: { column: 10, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + id: Identifier { + type: 'Identifier', + name: 'Foo', + + range: [6, 9], + loc: { + start: { column: 6, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + superClass: null, + + range: [0, 46], + loc: { + start: { column: 0, line: 1 }, + end: { column: 1, line: 3 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 47], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 4 }, + }, + }" +`; diff --git a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-Error.shot b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/6-AST-Alignment-Tokens.shot similarity index 51% rename from packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-Error.shot rename to packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/6-AST-Alignment-Tokens.shot index 58104f64f7b..2d68aa8d59a 100644 --- a/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/3-Babel-Error.shot +++ b/packages/ast-spec/src/element/AccessorProperty/fixtures/with-annotation-with-value/snapshots/6-AST-Alignment-Tokens.shot @@ -1,3 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AST Fixtures element AccessorProperty with-annotation-with-value Babel - Error 1`] = `[SyntaxError: Missing semicolon. (2:15)]`; +exports[`AST Fixtures element AccessorProperty with-annotation-with-value AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/unions/JSXExpression.ts b/packages/ast-spec/src/unions/JSXExpression.ts index 78dfad53525..d30c150cc6f 100644 --- a/packages/ast-spec/src/unions/JSXExpression.ts +++ b/packages/ast-spec/src/unions/JSXExpression.ts @@ -1,8 +1,4 @@ -import type { JSXEmptyExpression } from '../jsx/JSXEmptyExpression/spec'; import type { JSXExpressionContainer } from '../jsx/JSXExpressionContainer/spec'; import type { JSXSpreadChild } from '../jsx/JSXSpreadChild/spec'; -export type JSXExpression = - | JSXEmptyExpression - | JSXExpressionContainer - | JSXSpreadChild; +export type JSXExpression = JSXExpressionContainer | JSXSpreadChild; diff --git a/packages/ast-spec/tests/fixtures-with-differences-ast.shot b/packages/ast-spec/tests/fixtures-with-differences-ast.shot index e6ea1804e84..233fc7f4f95 100644 --- a/packages/ast-spec/tests/fixtures-with-differences-ast.shot +++ b/packages/ast-spec/tests/fixtures-with-differences-ast.shot @@ -29,6 +29,9 @@ Set { "element/AccessorProperty/fixtures/key-computed-string/fixture.ts", "element/AccessorProperty/fixtures/key-private/fixture.ts", "element/AccessorProperty/fixtures/key-string/fixture.ts", + "element/AccessorProperty/fixtures/modifier-abstract-with-value/fixture.ts", + "element/AccessorProperty/fixtures/modifier-abstract/fixture.ts", + "element/AccessorProperty/fixtures/modifier-declare/fixture.ts", "element/AccessorProperty/fixtures/modifier-override/fixture.ts", "element/AccessorProperty/fixtures/modifier-private/fixture.ts", "element/AccessorProperty/fixtures/modifier-protected/fixture.ts", @@ -37,6 +40,8 @@ Set { "element/AccessorProperty/fixtures/modifier-static/fixture.ts", "element/AccessorProperty/fixtures/no-annotation-no-value/fixture.ts", "element/AccessorProperty/fixtures/no-annotation-with-value/fixture.ts", + "element/AccessorProperty/fixtures/with-annotation-no-value/fixture.ts", + "element/AccessorProperty/fixtures/with-annotation-with-value/fixture.ts", "expression/TSSatisfiesExpression/fixtures/arrow-func-with-parentheses/fixture.ts", } `; diff --git a/packages/ast-spec/tests/fixtures-with-differences-errors.shot b/packages/ast-spec/tests/fixtures-with-differences-errors.shot index 68799952497..ad9289156df 100644 --- a/packages/ast-spec/tests/fixtures-with-differences-errors.shot +++ b/packages/ast-spec/tests/fixtures-with-differences-errors.shot @@ -21,7 +21,6 @@ Object { "declaration/TSInterfaceDeclaration/fixtures/_error_/non-identifier-extends/fixture.ts", "declaration/TSTypeAliasDeclaration/fixtures/_error_/missing-type-parameter/fixture.ts", "declaration/VariableDeclaration/fixtures/_error_/missing-id-without-value/fixture.ts", - "element/AccessorProperty/fixtures/_error_/modifier-declare/fixture.ts", "element/AccessorProperty/fixtures/_error_/modifier-override-with-no-extends/fixture.ts", }, "TSESTree errored but Babel didn't": Set { diff --git a/packages/ast-spec/tests/fixtures-without-babel-support.shot b/packages/ast-spec/tests/fixtures-without-babel-support.shot index a4022f6319b..0ecfffa63d0 100644 --- a/packages/ast-spec/tests/fixtures-without-babel-support.shot +++ b/packages/ast-spec/tests/fixtures-without-babel-support.shot @@ -1,10 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`AST Fixtures List fixtures we expect babel to not support 1`] = ` -Map { - "element/AccessorProperty/fixtures/modifier-abstract-with-value/fixture.ts" => "https://github.com/babel/babel/issues/15205", - "element/AccessorProperty/fixtures/modifier-abstract/fixture.ts" => "https://github.com/babel/babel/issues/15205", - "element/AccessorProperty/fixtures/with-annotation-no-value/fixture.ts" => "https://github.com/babel/babel/issues/15205", - "element/AccessorProperty/fixtures/with-annotation-with-value/fixture.ts" => "https://github.com/babel/babel/issues/15205", -} -`; +exports[`AST Fixtures List fixtures we expect babel to not support 1`] = `Map {}`; diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 3068aa41637..0cd6ad00030 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 5834211a3ea..7b81526e7ed 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "5.48.2", + "version": "5.50.0", "private": true, "main": "dist/index.js", "scripts": { @@ -14,9 +14,9 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/type-utils": "5.50.0", + "@typescript-eslint/utils": "5.50.0", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index a471d56c790..b2551812889 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index be111fe61d6..23bf62f3fc5 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "5.48.2", + "version": "5.50.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "ESLint plugin that wraps a TSLint configuration and lints the whole source using TSLint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/utils": "5.50.0", "lodash": "^4.17.21" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "5.48.2" + "@typescript-eslint/parser": "5.50.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 5a9330fc575..25cce92ccc4 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,35 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + + +### Bug Fixes + +* **eslint-plugin:** [ban-ts-comment] counts graphemes instead of `String.prototype.length` ([#5704](https://github.com/typescript-eslint/typescript-eslint/issues/5704)) ([09d57ce](https://github.com/typescript-eslint/typescript-eslint/commit/09d57cec8901880c6b24ea80dfa7d9fcdc463930)) +* **eslint-plugin:** [prefer-optional-chain] fix `ThisExpression` and `PrivateIdentifier` errors ([#6028](https://github.com/typescript-eslint/typescript-eslint/issues/6028)) ([85e783c](https://github.com/typescript-eslint/typescript-eslint/commit/85e783c1fabe96d390729a5796d6d346e401692b)) +* **eslint-plugin:** [prefer-optional-chain] fixer produces wrong logic ([#5919](https://github.com/typescript-eslint/typescript-eslint/issues/5919)) ([b0f6c8e](https://github.com/typescript-eslint/typescript-eslint/commit/b0f6c8ec0b372696ef26ca3a2b4f82dafd9dc417)), closes [#1438](https://github.com/typescript-eslint/typescript-eslint/issues/1438) + + +### Features + +* **eslint-plugin:** add `key-spacing` rule extension for interface & type declarations ([#6211](https://github.com/typescript-eslint/typescript-eslint/issues/6211)) ([67706e7](https://github.com/typescript-eslint/typescript-eslint/commit/67706e72e332bf11c82fdf51f3d417d3c93a86cf)) + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + + +### Features + +* **eslint-plugin:** [naming-convention] add support for `#private` modifier on class members ([#6259](https://github.com/typescript-eslint/typescript-eslint/issues/6259)) ([c8a6d80](https://github.com/typescript-eslint/typescript-eslint/commit/c8a6d8096080228b6d122c861fe140ac97f17cbe)) + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/eslint-plugin diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index b9dd0cecd03..9c98f8c7d4b 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -5,6 +5,6 @@ An ESLint plugin which provides lint rules for TypeScript codebases. [![NPM Version](https://img.shields.io/npm/v/@typescript-eslint/eslint-plugin.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin) [![NPM Downloads](https://img.shields.io/npm/dm/@typescript-eslint/eslint-plugin.svg?style=flat-square)](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin) -👉 See **https://typescript-eslint.io/architecture/utils** for our Getting Started docs. +👉 See **https://typescript-eslint.io/getting-started** for our Getting Started docs. > See https://typescript-eslint.io for general documentation on typescript-eslint, the tooling that allows you to run ESLint and Prettier on TypeScript code. diff --git a/packages/eslint-plugin/docs/rules/ban-types.md b/packages/eslint-plugin/docs/rules/ban-types.md index 016b2a7217e..3f2e663669a 100644 --- a/packages/eslint-plugin/docs/rules/ban-types.md +++ b/packages/eslint-plugin/docs/rules/ban-types.md @@ -72,12 +72,6 @@ The default options provide a set of "best practices", intended to provide safet - This is a point of confusion for many developers, who think it means "any object type". - See [this comment for more information](https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492). -:::important - -The default options suggest using `Record`; this was a stylistic decision, as the built-in `Record` type is considered to look cleaner. - -::: -
Default Options @@ -115,15 +109,16 @@ const defaultTypes = { Object: { message: [ 'The `Object` type actually means "any non-nullish value", so it is marginally better than `unknown`.', - '- If you want a type meaning "any object", you probably want `Record` instead.', + '- If you want a type meaning "any object", you probably want `object` instead.', '- If you want a type meaning "any value", you probably want `unknown` instead.', ].join('\n'), }, '{}': { message: [ '`{}` actually means "any non-nullish value".', - '- If you want a type meaning "any object", you probably want `Record` instead.', + '- If you want a type meaning "any object", you probably want `object` instead.', '- If you want a type meaning "any value", you probably want `unknown` instead.', + '- If you want a type meaning "empty object", you probably want `Record` instead.', ].join('\n'), }, }; diff --git a/packages/eslint-plugin/docs/rules/consistent-type-imports.md b/packages/eslint-plugin/docs/rules/consistent-type-imports.md index 045b7c2fa7d..baa41eccda1 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-imports.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-imports.md @@ -95,3 +95,9 @@ If you are using [type-aware linting](https://typescript-eslint.io/linting/typed ## When Not To Use It - If you specifically want to use both import kinds for stylistic reasons, you can disable this rule. + +## Related To + +- [`no-import-type-side-effects`](./no-import-type-side-effects.md) +- [`import/consistent-type-specifier-style`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/consistent-type-specifier-style.md) +- [`import/no-duplicates` with `{"prefer-inline": true}`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-duplicates.md#inline-type-imports) diff --git a/packages/eslint-plugin/docs/rules/key-spacing.md b/packages/eslint-plugin/docs/rules/key-spacing.md new file mode 100644 index 00000000000..35108c28f86 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/key-spacing.md @@ -0,0 +1,12 @@ +--- +description: 'Enforce consistent spacing between property names and type annotations in types and interfaces.' +--- + +> 🛑 This file is source code, not the primary documentation location! 🛑 +> +> See **https://typescript-eslint.io/rules/key-spacing** for documentation. + +## Examples + +This rule extends the base [`eslint/key-spacing`](https://eslint.org/docs/rules/key-spacing) rule. +This version adds support for type annotations on interfaces, classes and type literals properties. diff --git a/packages/eslint-plugin/docs/rules/naming-convention.md b/packages/eslint-plugin/docs/rules/naming-convention.md index f5922ba3653..ab0405592c4 100644 --- a/packages/eslint-plugin/docs/rules/naming-convention.md +++ b/packages/eslint-plugin/docs/rules/naming-convention.md @@ -159,7 +159,7 @@ If these are provided, the identifier must start with one of the provided values - Accepts one or array of selectors to define an option block that applies to one or multiple selectors. - For example, if you provide `{ selector: ['function', 'variable'] }`, then it will apply the same option to variable and function nodes. - See [Allowed Selectors, Modifiers and Types](#allowed-selectors-modifiers-and-types) below for the complete list of allowed selectors. -- `modifiers` allows you to specify which modifiers to granularly apply to, such as the accessibility (`private`/`protected`/`public`), or if the thing is `static`, etc. +- `modifiers` allows you to specify which modifiers to granularly apply to, such as the accessibility (`#private`/`private`/`protected`/`public`), or if the thing is `static`, etc. - The name must match _all_ of the modifiers. - For example, if you provide `{ modifiers: ['private','readonly','static'] }`, then it will only match something that is `private static readonly`, and something that is just `private` will not match. - The following `modifiers` are allowed: @@ -172,6 +172,7 @@ If these are provided, the identifier must start with one of the provided values - `requiresQuotes` - matches any name that requires quotes as it is not a valid identifier (i.e. has a space, a dash, etc in it). - `public` - matches any member that is either explicitly declared as `public`, or has no visibility modifier (i.e. implicitly public). - `abstract`,`override`,`private`,`protected`,`readonly`,`static` - matches any member explicitly declared with the given modifier. + - `#private` - matches any member with a private identifier (an identifier that starts with `#`) - `async` - matches any method, function, or function variable which is async via the `async` keyword (e.g. does not match functions that return promises without using `async` keyword) - `types` allows you to specify which types to match. This option supports simple, primitive types only (`array`,`boolean`,`function`,`number`,`string`). - The name must match _one_ of the types. @@ -204,7 +205,7 @@ Individual Selectors match specific, well-defined sets. There is no overlap betw - Allowed `modifiers`: `destructured`, `unused`. - Allowed `types`: `boolean`, `string`, `number`, `function`, `array`. - `classProperty` - matches any class property. Does not match properties that have direct function expression or arrow function expression values. - - Allowed `modifiers`: `abstract`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. + - Allowed `modifiers`: `abstract`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. - Allowed `types`: `array`, `boolean`, `function`, `number`, `string`. - `objectLiteralProperty` - matches any object literal property. Does not match properties that have direct function expression or arrow function expression values. - Allowed `modifiers`: `public`, `requiresQuotes`. @@ -216,7 +217,7 @@ Individual Selectors match specific, well-defined sets. There is no overlap betw - Allowed `modifiers`: `private`, `protected`, `public`, `readonly`. - Allowed `types`: `array`, `boolean`, `function`, `number`, `string`. - `classMethod` - matches any class method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors. - - Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `requiresQuotes`, `static`. + - Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `requiresQuotes`, `static`. - Allowed `types`: none. - `objectLiteralMethod` - matches any object literal method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors. - Allowed `modifiers`: `async`, `public`, `requiresQuotes`. @@ -257,16 +258,16 @@ Group Selectors are provided for convenience, and essentially bundle up sets of - Allowed `modifiers`: `async`, `unused`. - Allowed `types`: none. - `memberLike` - matches the same as `accessor`, `enumMember`, `method`, `parameterProperty`, `property`. - - Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. + - Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. - Allowed `types`: none. - `typeLike` - matches the same as `class`, `enum`, `interface`, `typeAlias`, `typeParameter`. - Allowed `modifiers`: `abstract`, `unused`. - Allowed `types`: none. - `property` - matches the same as `classProperty`, `objectLiteralProperty`, `typeProperty`. - - Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. + - Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. - Allowed `types`: `array`, `boolean`, `function`, `number`, `string`. - `method` - matches the same as `classMethod`, `objectLiteralMethod`, `typeMethod`. - - Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. + - Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`. - Allowed `types`: none. ## FAQ diff --git a/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md b/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md new file mode 100644 index 00000000000..35b8f2c5282 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md @@ -0,0 +1,75 @@ +--- +description: 'Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers.' +--- + +> 🛑 This file is source code, not the primary documentation location! 🛑 +> +> See **https://typescript-eslint.io/rules/no-import-type-side-effects** for documentation. + +The [`--verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax) compiler option causes TypeScript to do simple and predictable transpilation on import declarations. +Namely, it completely removes import declarations with a top-level `type` qualifier, and it removes any import specifiers with an inline `type` qualifier. + +The latter behavior does have one potentially surprising effect in that in certain cases TS can leave behind a "side effect" import at runtime: + +```ts +import { type A, type B } from 'mod'; + +// is transpiled to + +import {} from 'mod'; +// which is the same as +import 'mod'; +``` + +For the rare case of needing to import for side effects, this may be desirable - but for most cases you will not want to leave behind an unnecessary side effect import. + +## Examples + +This rule enforces that you use a top-level `type` qualifier for imports when it only imports specifiers with an inline `type` qualifier + + + +### ❌ Incorrect + +```ts +import { type A } from 'mod'; +import { type A as AA } from 'mod'; +import { type A, type B } from 'mod'; +import { type A as AA, type B as BB } from 'mod'; +``` + +### ✅ Correct + +```ts +import type { A } from 'mod'; +import type { A as AA } from 'mod'; +import type { A, B } from 'mod'; +import type { A as AA, B as BB } from 'mod'; + +import T from 'mod'; +import type T from 'mod'; + +import * as T from 'mod'; +import type * as T from 'mod'; + +import { T } from 'mod'; +import type { T } from 'mod'; +import { T, U } from 'mod'; +import type { T, U } from 'mod'; +import { type T, U } from 'mod'; +import { T, type U } from 'mod'; + +import type T, { U } from 'mod'; +import T, { type U } from 'mod'; +``` + +## When Not To Use It + +- If you want to leave behind side effect imports, then you shouldn't use this rule. +- If you're not using TypeScript 5.0's `verbatimModuleSyntax` option, then you don't need this rule. + +## Related To + +- [`consistent-type-imports`](./consistent-type-imports.md) +- [`import/consistent-type-specifier-style`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/consistent-type-specifier-style.md) +- [`import/no-duplicates` with `{"prefer-inline": true}`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-duplicates.md#inline-type-imports) diff --git a/packages/eslint-plugin/docs/rules/unified-signatures.md b/packages/eslint-plugin/docs/rules/unified-signatures.md index 5736561d2ff..609eb3a7bb5 100644 --- a/packages/eslint-plugin/docs/rules/unified-signatures.md +++ b/packages/eslint-plugin/docs/rules/unified-signatures.md @@ -38,6 +38,13 @@ function x(x: number | string): void; function y(...x: number[]): void; ``` +```ts +// This rule won't check overload signatures with different rest parameter types. +// See https://github.com/microsoft/TypeScript/issues/5077 +function f(...a: number[]): void; +function f(...a: string[]): void; +``` + ## Options ### `ignoreDifferentlyNamedParameters` @@ -53,11 +60,6 @@ function f(a: number): void; function f(a: string): void; ``` -```ts -function f(...a: number[]): void; -function f(...b: string[]): void; -``` - ### ✅ Correct ```ts @@ -65,9 +67,4 @@ function f(a: number): void; function f(b: string): void; ``` -```ts -function f(...a: number[]): void; -function f(...a: string[]): void; -``` - ## Options diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 1fb0d6cf047..724b3eea0f1 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "5.48.2", + "version": "5.50.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -37,17 +37,18 @@ "clean": "tsc -b tsconfig.build.json --clean", "postclean": "rimraf dist && rimraf coverage", "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", - "generate:breaking-changes": "../../node_modules/.bin/ts-node tools/generate-breaking-changes.ts", - "generate:configs": "../../node_modules/.bin/ts-node tools/generate-configs.ts", + "generate:breaking-changes": "yarn tsx tools/generate-breaking-changes.ts", + "generate:configs": "yarn tsx tools/generate-configs.ts", "lint": "nx lint", "test": "jest --coverage", "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/type-utils": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/type-utils": "5.50.0", + "@typescript-eslint/utils": "5.50.0", "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", @@ -62,6 +63,7 @@ "@types/prettier": "*", "chalk": "^5.0.1", "cross-fetch": "^3.1.5", + "grapheme-splitter": "^1.0.4", "json-schema": "*", "markdown-table": "^3.0.2", "marked": "^4.0.15", diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 20ea892f581..eb3856f10c3 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -37,6 +37,8 @@ export = { '@typescript-eslint/indent': 'error', 'init-declarations': 'off', '@typescript-eslint/init-declarations': 'error', + 'key-spacing': 'off', + '@typescript-eslint/key-spacing': 'error', 'keyword-spacing': 'off', '@typescript-eslint/keyword-spacing': 'error', 'lines-between-class-members': 'off', @@ -53,7 +55,6 @@ export = { 'no-dupe-class-members': 'off', '@typescript-eslint/no-dupe-class-members': 'error', '@typescript-eslint/no-duplicate-enum-values': 'error', - 'no-duplicate-imports': 'off', '@typescript-eslint/no-dynamic-delete': 'error', 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', @@ -69,6 +70,7 @@ export = { '@typescript-eslint/no-for-in-array': 'error', 'no-implied-eval': 'off', '@typescript-eslint/no-implied-eval': 'error', + '@typescript-eslint/no-import-type-side-effects': 'error', '@typescript-eslint/no-inferrable-types': 'error', 'no-invalid-this': 'off', '@typescript-eslint/no-invalid-this': 'error', @@ -86,7 +88,6 @@ export = { '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', '@typescript-eslint/no-non-null-assertion': 'error', - '@typescript-eslint/parameter-properties': 'error', 'no-redeclare': 'off', '@typescript-eslint/no-redeclare': 'error', '@typescript-eslint/no-redundant-type-constituents': 'error', @@ -126,6 +127,7 @@ export = { '@typescript-eslint/object-curly-spacing': 'error', 'padding-line-between-statements': 'off', '@typescript-eslint/padding-line-between-statements': 'error', + '@typescript-eslint/parameter-properties': 'error', '@typescript-eslint/prefer-as-const': 'error', '@typescript-eslint/prefer-enum-initializers': 'error', '@typescript-eslint/prefer-for-of': 'error', diff --git a/packages/eslint-plugin/src/configs/strict.ts b/packages/eslint-plugin/src/configs/strict.ts index ccd44b85a0a..99b4e83b508 100644 --- a/packages/eslint-plugin/src/configs/strict.ts +++ b/packages/eslint-plugin/src/configs/strict.ts @@ -8,8 +8,8 @@ export = { '@typescript-eslint/array-type': 'warn', '@typescript-eslint/ban-tslint-comment': 'warn', '@typescript-eslint/class-literal-property-style': 'warn', - '@typescript-eslint/consistent-indexed-object-style': 'warn', '@typescript-eslint/consistent-generic-constructors': 'warn', + '@typescript-eslint/consistent-indexed-object-style': 'warn', '@typescript-eslint/consistent-type-assertions': 'warn', '@typescript-eslint/consistent-type-definitions': 'warn', 'dot-notation': 'off', diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 5f5ddfc0aad..498a9bf5ae1 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -65,7 +65,7 @@ export default util.createRule({ case AST_NODE_TYPES.TSDeclareFunction: case AST_NODE_TYPES.FunctionDeclaration: { const name = member.id?.name ?? null; - if (name === null) { + if (name == null) { return null; } return { @@ -143,7 +143,7 @@ export default util.createRule({ members.forEach(member => { const method = getMemberMethod(member); - if (method === null) { + if (method == null) { lastMethod = null; return; } diff --git a/packages/eslint-plugin/src/rules/ban-ts-comment.ts b/packages/eslint-plugin/src/rules/ban-ts-comment.ts index 9c55b437da6..511a951280e 100644 --- a/packages/eslint-plugin/src/rules/ban-ts-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-ts-comment.ts @@ -147,7 +147,10 @@ export default util.createRule<[Options], MessageIds>({ minimumDescriptionLength = defaultMinimumDescriptionLength, } = options; const format = descriptionFormats.get(fullDirective); - if (description.trim().length < minimumDescriptionLength) { + if ( + util.getStringLength(description.trim()) < + minimumDescriptionLength + ) { context.report({ data: { directive, minimumDescriptionLength }, node: comment, diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index dce41140515..f21dda8a249 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -36,7 +36,7 @@ function stringifyNode( function getCustomMessage( bannedType: null | string | { message?: string; fixWith?: string }, ): string { - if (bannedType === null) { + if (bannedType == null) { return ''; } diff --git a/packages/eslint-plugin/src/rules/comma-spacing.ts b/packages/eslint-plugin/src/rules/comma-spacing.ts index fda50d1b2e4..a1ebcc181f2 100644 --- a/packages/eslint-plugin/src/rules/comma-spacing.ts +++ b/packages/eslint-plugin/src/rules/comma-spacing.ts @@ -68,7 +68,7 @@ export default createRule({ let previousToken = sourceCode.getFirstToken(node); for (const element of node.elements) { let token: TSESTree.Token | null; - if (element === null) { + if (element == null) { token = sourceCode.getTokenAfter(previousToken!); if (token && isCommaToken(token)) { ignoredTokens.add(token); diff --git a/packages/eslint-plugin/src/rules/consistent-type-imports.ts b/packages/eslint-plugin/src/rules/consistent-type-imports.ts index a812116f2f8..4c5cf771901 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-imports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-imports.ts @@ -1,5 +1,5 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; -import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as util from '../util'; @@ -32,18 +32,6 @@ interface ReportValueImport { inlineTypeSpecifiers: TSESTree.ImportSpecifier[]; } -function isImportToken( - token: TSESTree.Token, -): token is TSESTree.KeywordToken & { value: 'import' } { - return token.type === AST_TOKEN_TYPES.Keyword && token.value === 'import'; -} - -function isTypeToken( - token: TSESTree.Token, -): token is TSESTree.IdentifierToken & { value: 'type' } { - return token.type === AST_TOKEN_TYPES.Identifier && token.value === 'type'; -} - type MessageIds = | 'typeOverValue' | 'someImportsAreOnlyTypes' @@ -751,7 +739,7 @@ export default util.createRule({ ) { if (report.typeSpecifiers.length === node.specifiers.length) { const importToken = util.nullThrows( - sourceCode.getFirstToken(node, isImportToken), + sourceCode.getFirstToken(node, util.isImportKeyword), util.NullThrowsReasons.MissingToken('import', node.type), ); // import type Type from 'foo' @@ -800,7 +788,7 @@ export default util.createRule({ // import type Foo from 'foo' // ^^^^^ insert const importToken = util.nullThrows( - sourceCode.getFirstToken(node, isImportToken), + sourceCode.getFirstToken(node, util.isImportKeyword), util.NullThrowsReasons.MissingToken('import', node.type), ); yield fixer.insertTextAfter(importToken, ' type'); @@ -945,14 +933,14 @@ export default util.createRule({ // import type Foo from 'foo' // ^^^^ remove const importToken = util.nullThrows( - sourceCode.getFirstToken(node, isImportToken), + sourceCode.getFirstToken(node, util.isImportKeyword), util.NullThrowsReasons.MissingToken('import', node.type), ); const typeToken = util.nullThrows( sourceCode.getFirstTokenBetween( importToken, node.specifiers[0]?.local ?? node.source, - isTypeToken, + util.isTypeKeyword, ), util.NullThrowsReasons.MissingToken('type', node.type), ); @@ -970,7 +958,7 @@ export default util.createRule({ // import { type Foo } from 'foo' // ^^^^ remove const typeToken = util.nullThrows( - sourceCode.getFirstToken(node, isTypeToken), + sourceCode.getFirstToken(node, util.isTypeKeyword), util.NullThrowsReasons.MissingToken('type', node.type), ); const afterToken = util.nullThrows( diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 8a3c2bbf437..bbddfc8d470 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -22,6 +22,7 @@ import explicitModuleBoundaryTypes from './explicit-module-boundary-types'; import funcCallSpacing from './func-call-spacing'; import indent from './indent'; import initDeclarations from './init-declarations'; +import keySpacing from './key-spacing'; import keywordSpacing from './keyword-spacing'; import linesBetweenClassMembers from './lines-between-class-members'; import memberDelimiterStyle from './member-delimiter-style'; @@ -47,6 +48,7 @@ import noFloatingPromises from './no-floating-promises'; import noForInArray from './no-for-in-array'; import noImplicitAnyCatch from './no-implicit-any-catch'; import noImpliedEval from './no-implied-eval'; +import noImportTypeSideEffects from './no-import-type-side-effects'; import noInferrableTypes from './no-inferrable-types'; import noInvalidThis from './no-invalid-this'; import noInvalidVoidType from './no-invalid-void-type'; @@ -153,6 +155,7 @@ export default { 'func-call-spacing': funcCallSpacing, indent: indent, 'init-declarations': initDeclarations, + 'key-spacing': keySpacing, 'keyword-spacing': keywordSpacing, 'lines-between-class-members': linesBetweenClassMembers, 'member-delimiter-style': memberDelimiterStyle, @@ -178,6 +181,7 @@ export default { 'no-for-in-array': noForInArray, 'no-implicit-any-catch': noImplicitAnyCatch, 'no-implied-eval': noImpliedEval, + 'no-import-type-side-effects': noImportTypeSideEffects, 'no-inferrable-types': noInferrableTypes, 'no-invalid-this': noInvalidThis, 'no-invalid-void-type': noInvalidVoidType, diff --git a/packages/eslint-plugin/src/rules/key-spacing.ts b/packages/eslint-plugin/src/rules/key-spacing.ts new file mode 100644 index 00000000000..2562107ee05 --- /dev/null +++ b/packages/eslint-plugin/src/rules/key-spacing.ts @@ -0,0 +1,431 @@ +import type { TSESTree } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; + +import * as util from '../util'; +import { getESLintCoreRule } from '../util/getESLintCoreRule'; + +const baseRule = getESLintCoreRule('key-spacing'); + +export type Options = util.InferOptionsTypeFromRule; +export type MessageIds = util.InferMessageIdsTypeFromRule; + +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +const baseSchema = Array.isArray(baseRule.meta.schema) + ? baseRule.meta.schema[0] + : baseRule.meta.schema; + +/** + * TODO: replace with native .at() once Node 14 stops being supported + */ +function at(arr: T[], position: number): T | undefined { + if (position < 0) { + return arr[arr.length + position]; + } + return arr[position]; +} + +export default util.createRule({ + name: 'key-spacing', + meta: { + type: 'layout', + docs: { + description: + 'Enforce consistent spacing between property names and type annotations in types and interfaces', + recommended: false, + extendsBaseRule: true, + }, + fixable: 'whitespace', + hasSuggestions: baseRule.meta.hasSuggestions, + schema: [baseSchema], + messages: baseRule.meta.messages, + }, + defaultOptions: [{}], + + create(context, [options]) { + const sourceCode = context.getSourceCode(); + const baseRules = baseRule.create(context); + + /** + * @returns the column of the position after converting all unicode characters in the line to 1 char length + */ + function adjustedColumn(position: TSESTree.Position): number { + const line = position.line - 1; // position.line is 1-indexed + return util.getStringLength( + at(sourceCode.lines, line)!.slice(0, position.column), + ); + } + + /** + * Starting from the given a node (a property.key node here) looks forward + * until it finds the last token before a colon punctuator and returns it. + */ + function getLastTokenBeforeColon(node: TSESTree.Node): TSESTree.Token { + const colonToken = sourceCode.getTokenAfter(node, util.isColonToken)!; + + return sourceCode.getTokenBefore(colonToken)!; + } + + type KeyTypeNode = + | TSESTree.TSIndexSignature + | TSESTree.TSPropertySignature + | TSESTree.PropertyDefinition; + + type KeyTypeNodeWithTypeAnnotation = KeyTypeNode & { + typeAnnotation: TSESTree.TSTypeAnnotation; + }; + + function isKeyTypeNode( + node: TSESTree.Node, + ): node is KeyTypeNodeWithTypeAnnotation { + return ( + (node.type === AST_NODE_TYPES.TSPropertySignature || + node.type === AST_NODE_TYPES.TSIndexSignature || + node.type === AST_NODE_TYPES.PropertyDefinition) && + !!node.typeAnnotation + ); + } + + /** + * To handle index signatures, to get the whole text for the parameters + */ + function getKeyText(node: KeyTypeNodeWithTypeAnnotation): string { + if (node.type !== AST_NODE_TYPES.TSIndexSignature) { + return sourceCode.getText(node.key); + } + + const code = sourceCode.getText(node); + return code.slice( + 0, + sourceCode.getTokenAfter( + at(node.parameters, -1)!, + util.isClosingBracketToken, + )!.range[1] - node.range[0], + ); + } + + /** + * To handle index signatures, be able to get the end position of the parameters + */ + function getKeyLocEnd( + node: KeyTypeNodeWithTypeAnnotation, + ): TSESTree.Position { + return getLastTokenBeforeColon( + node.type !== AST_NODE_TYPES.TSIndexSignature + ? node.key + : at(node.parameters, -1)!, + ).loc.end; + } + + function checkBeforeColon( + node: KeyTypeNodeWithTypeAnnotation, + expectedWhitespaceBeforeColon: number, + mode: 'strict' | 'minimum', + ): void { + const { typeAnnotation } = node; + const colon = typeAnnotation.loc.start.column; + const keyEnd = getKeyLocEnd(node); + const difference = colon - keyEnd.column - expectedWhitespaceBeforeColon; + if (mode === 'strict' ? difference : difference < 0) { + context.report({ + node, + messageId: difference > 0 ? 'extraKey' : 'missingKey', + fix: fixer => { + if (difference > 0) { + return fixer.removeRange([ + typeAnnotation.range[0] - difference, + typeAnnotation.range[0], + ]); + } else { + return fixer.insertTextBefore( + typeAnnotation, + ' '.repeat(-difference), + ); + } + }, + data: { + computed: '', + key: getKeyText(node), + }, + }); + } + } + + function checkAfterColon( + node: KeyTypeNodeWithTypeAnnotation, + expectedWhitespaceAfterColon: number, + mode: 'strict' | 'minimum', + ): void { + const { typeAnnotation } = node; + const colon = typeAnnotation.loc.start.column; + const typeStart = typeAnnotation.typeAnnotation.loc.start.column; + const difference = typeStart - colon - 1 - expectedWhitespaceAfterColon; + if (mode === 'strict' ? difference : difference < 0) { + context.report({ + node, + messageId: difference > 0 ? 'extraValue' : 'missingValue', + fix: fixer => { + if (difference > 0) { + return fixer.removeRange([ + typeAnnotation.typeAnnotation.range[0] - difference, + typeAnnotation.typeAnnotation.range[0], + ]); + } else { + return fixer.insertTextBefore( + typeAnnotation.typeAnnotation, + ' '.repeat(-difference), + ); + } + }, + data: { + computed: '', + key: getKeyText(node), + }, + }); + } + } + + // adapted from https://github.com/eslint/eslint/blob/ba74253e8bd63e9e163bbee0540031be77e39253/lib/rules/key-spacing.js#L356 + function continuesAlignGroup( + lastMember: TSESTree.Node, + candidate: TSESTree.Node, + ): boolean { + const groupEndLine = lastMember.loc.start.line; + const candidateValueStartLine = ( + isKeyTypeNode(candidate) ? candidate.typeAnnotation : candidate + ).loc.start.line; + + if (candidateValueStartLine === groupEndLine) { + return false; + } + + if (candidateValueStartLine - groupEndLine === 1) { + return true; + } + + /* + * Check that the first comment is adjacent to the end of the group, the + * last comment is adjacent to the candidate property, and that successive + * comments are adjacent to each other. + */ + const leadingComments = sourceCode.getCommentsBefore(candidate); + + if ( + leadingComments.length && + leadingComments[0].loc.start.line - groupEndLine <= 1 && + candidateValueStartLine - at(leadingComments, -1)!.loc.end.line <= 1 + ) { + for (let i = 1; i < leadingComments.length; i++) { + if ( + leadingComments[i].loc.start.line - + leadingComments[i - 1].loc.end.line > + 1 + ) { + return false; + } + } + return true; + } + + return false; + } + + function checkAlignGroup(group: TSESTree.Node[]): void { + let alignColumn = 0; + const align: 'value' | 'colon' = + (typeof options.align === 'object' + ? options.align.on + : typeof options.multiLine?.align === 'object' + ? options.multiLine.align.on + : options.multiLine?.align ?? options.align) ?? 'colon'; + const beforeColon = + (typeof options.align === 'object' + ? options.align.beforeColon + : options.multiLine + ? typeof options.multiLine.align === 'object' + ? options.multiLine.align.beforeColon + : options.multiLine.beforeColon + : options.beforeColon) ?? false; + const expectedWhitespaceBeforeColon = beforeColon ? 1 : 0; + const afterColon = + (typeof options.align === 'object' + ? options.align.afterColon + : options.multiLine + ? typeof options.multiLine.align === 'object' + ? options.multiLine.align.afterColon + : options.multiLine.afterColon + : options.afterColon) ?? true; + const expectedWhitespaceAfterColon = afterColon ? 1 : 0; + const mode = + (typeof options.align === 'object' + ? options.align.mode + : options.multiLine + ? typeof options.multiLine.align === 'object' + ? // same behavior as in original rule + options.multiLine.align.mode ?? options.multiLine.mode + : options.multiLine.mode + : options.mode) ?? 'strict'; + + for (const node of group) { + if (isKeyTypeNode(node)) { + const keyEnd = adjustedColumn(getKeyLocEnd(node)); + alignColumn = Math.max( + alignColumn, + align === 'colon' + ? keyEnd + expectedWhitespaceBeforeColon + : keyEnd + + ':'.length + + expectedWhitespaceAfterColon + + expectedWhitespaceBeforeColon, + ); + } + } + + for (const node of group) { + if (!isKeyTypeNode(node)) { + continue; + } + const { typeAnnotation } = node; + const toCheck = + align === 'colon' ? typeAnnotation : typeAnnotation.typeAnnotation; + const difference = adjustedColumn(toCheck.loc.start) - alignColumn; + + if (difference) { + context.report({ + node, + messageId: + difference > 0 + ? align === 'colon' + ? 'extraKey' + : 'extraValue' + : align === 'colon' + ? 'missingKey' + : 'missingValue', + fix: fixer => { + if (difference > 0) { + return fixer.removeRange([ + toCheck.range[0] - difference, + toCheck.range[0], + ]); + } else { + return fixer.insertTextBefore(toCheck, ' '.repeat(-difference)); + } + }, + data: { + computed: '', + key: getKeyText(node), + }, + }); + } + + if (align === 'colon') { + checkAfterColon(node, expectedWhitespaceAfterColon, mode); + } else { + checkBeforeColon(node, expectedWhitespaceBeforeColon, mode); + } + } + } + + function checkIndividualNode( + node: TSESTree.Node, + { singleLine }: { singleLine: boolean }, + ): void { + const beforeColon = + (singleLine + ? options.singleLine + ? options.singleLine.beforeColon + : options.beforeColon + : options.multiLine + ? options.multiLine.beforeColon + : options.beforeColon) ?? false; + const expectedWhitespaceBeforeColon = beforeColon ? 1 : 0; + const afterColon = + (singleLine + ? options.singleLine + ? options.singleLine.afterColon + : options.afterColon + : options.multiLine + ? options.multiLine.afterColon + : options.afterColon) ?? true; + const expectedWhitespaceAfterColon = afterColon ? 1 : 0; + const mode = + (singleLine + ? options.singleLine + ? options.singleLine.mode + : options.mode + : options.multiLine + ? options.multiLine.mode + : options.mode) ?? 'strict'; + + if (isKeyTypeNode(node)) { + checkBeforeColon(node, expectedWhitespaceBeforeColon, mode); + checkAfterColon(node, expectedWhitespaceAfterColon, mode); + } + } + + function validateBody( + body: + | TSESTree.TSTypeLiteral + | TSESTree.TSInterfaceBody + | TSESTree.ClassBody, + ): void { + const isSingleLine = body.loc.start.line === body.loc.end.line; + + const members = + body.type === AST_NODE_TYPES.TSTypeLiteral ? body.members : body.body; + + let alignGroups: TSESTree.Node[][] = []; + let unalignedElements: TSESTree.Node[] = []; + + if (options.align || options.multiLine?.align) { + let currentAlignGroup: TSESTree.Node[] = []; + alignGroups.push(currentAlignGroup); + + let prevNode: TSESTree.Node | undefined = undefined; + + for (const node of members) { + let prevAlignedNode = at(currentAlignGroup, -1); + if (prevAlignedNode !== prevNode) { + prevAlignedNode = undefined; + } + + if (prevAlignedNode && continuesAlignGroup(prevAlignedNode, node)) { + currentAlignGroup.push(node); + } else if (prevNode?.loc.start.line === node.loc.start.line) { + if (prevAlignedNode) { + // Here, prevNode === prevAlignedNode === currentAlignGroup.at(-1) + unalignedElements.push(prevAlignedNode); + currentAlignGroup.pop(); + } + unalignedElements.push(node); + } else { + currentAlignGroup = [node]; + alignGroups.push(currentAlignGroup); + } + + prevNode = node; + } + + unalignedElements = unalignedElements.concat( + ...alignGroups.filter(group => group.length === 1), + ); + alignGroups = alignGroups.filter(group => group.length >= 2); + } else { + unalignedElements = members; + } + + for (const group of alignGroups) { + checkAlignGroup(group); + } + + for (const node of unalignedElements) { + checkIndividualNode(node, { singleLine: isSingleLine }); + } + } + return { + ...baseRules, + TSTypeLiteral: validateBody, + TSInterfaceBody: validateBody, + ClassBody: validateBody, + }; + }, +}); diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 81e0ae6484e..f8db5ade0ca 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -489,7 +489,7 @@ function getRank( ): number { const type = getNodeType(node); - if (type === null) { + if (type == null) { // shouldn't happen but just in case, put it on the end return orderConfig.length - 1; } @@ -842,7 +842,7 @@ export default util.createRule({ supportsModifiers, ); - if (grouped === null) { + if (grouped == null) { return false; } diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts index bc2547ffa3f..02900ab1d8b 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts @@ -91,32 +91,33 @@ enum Modifiers { public = 1 << 3, protected = 1 << 4, private = 1 << 5, - abstract = 1 << 6, + '#private' = 1 << 6, + abstract = 1 << 7, // destructured variable - destructured = 1 << 7, + destructured = 1 << 8, // variables declared in the top-level scope - global = 1 << 8, + global = 1 << 9, // things that are exported - exported = 1 << 9, + exported = 1 << 10, // things that are unused - unused = 1 << 10, + unused = 1 << 11, // properties that require quoting - requiresQuotes = 1 << 11, + requiresQuotes = 1 << 12, // class members that are overridden - override = 1 << 12, + override = 1 << 13, // class methods, object function properties, or functions that are async via the `async` keyword - async = 1 << 13, + async = 1 << 14, // make sure TypeModifiers starts at Modifiers + 1 or else sorting won't work } type ModifiersString = keyof typeof Modifiers; enum TypeModifiers { - boolean = 1 << 12, - string = 1 << 13, - number = 1 << 14, - function = 1 << 15, - array = 1 << 16, + boolean = 1 << 15, + string = 1 << 16, + number = 1 << 17, + function = 1 << 18, + array = 1 << 19, } type TypeModifiersString = keyof typeof TypeModifiers; diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/schema.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/schema.ts index 179b6dd7f43..ff91d2e156d 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/schema.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/schema.ts @@ -190,6 +190,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = { ...selectorSchema('memberLike', false, [ 'abstract', 'private', + '#private', 'protected', 'public', 'readonly', @@ -201,6 +202,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = { ...selectorSchema('classProperty', true, [ 'abstract', 'private', + '#private', 'protected', 'public', 'readonly', @@ -226,6 +228,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = { ...selectorSchema('property', true, [ 'abstract', 'private', + '#private', 'protected', 'public', 'readonly', @@ -238,6 +241,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = { ...selectorSchema('classMethod', false, [ 'abstract', 'private', + '#private', 'protected', 'public', 'requiresQuotes', @@ -254,6 +258,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = { ...selectorSchema('method', false, [ 'abstract', 'private', + '#private', 'protected', 'public', 'requiresQuotes', diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/types.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/types.ts index e900b4c5f17..d5c15994b8b 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/types.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/types.ts @@ -64,7 +64,7 @@ type ValidatorFunction = ( node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal, modifiers?: Set, ) => void; -type ParsedOptions = Record; +type ParsedOptions = Record; type Context = Readonly>; export type { diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/validator.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/validator.ts index e96ff19e374..c2b87ccc33b 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/validator.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/validator.ts @@ -101,25 +101,25 @@ function createValidator( let name: string | null = originalName; name = validateUnderscore('leading', config, name, node, originalName); - if (name === null) { + if (name == null) { // fail return; } name = validateUnderscore('trailing', config, name, node, originalName); - if (name === null) { + if (name == null) { // fail return; } name = validateAffix('prefix', config, name, node, originalName); - if (name === null) { + if (name == null) { // fail return; } name = validateAffix('suffix', config, name, node, originalName); - if (name === null) { + if (name == null) { // fail return; } @@ -383,7 +383,7 @@ function createValidator( modifiers: Set, ): boolean { const formats = config.format; - if (formats === null || formats.length === 0) { + if (!formats?.length) { return true; } @@ -427,7 +427,7 @@ function isCorrectType( context: Context, selector: Selectors, ): boolean { - if (config.types === null) { + if (config.types == null) { return true; } diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 05f3dd0f2a6..f5a59614851 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -95,7 +95,7 @@ export default util.createRule({ .getParserServices(context, true) .program.getCompilerOptions(); function handleMember( - validator: ValidatorFunction | null, + validator: ValidatorFunction, node: | TSESTree.PropertyNonComputedName | TSESTree.PropertyDefinitionNonComputedName @@ -127,7 +127,9 @@ export default util.createRule({ | TSESTree.TSParameterProperty, ): Set { const modifiers = new Set(); - if (node.accessibility) { + if ('key' in node && node.key.type === AST_NODE_TYPES.PrivateIdentifier) { + modifiers.add(Modifiers['#private']); + } else if (node.accessibility) { modifiers.add(Modifiers[node.accessibility]); } else { modifiers.add(Modifiers.public); @@ -213,176 +215,198 @@ export default util.createRule({ ); } - return { + const selectors: { + readonly [k in keyof TSESLint.RuleListener]: Readonly<{ + validator: ValidatorFunction; + handler: ( + node: Parameters>[0], + validator: ValidatorFunction, + ) => void; + }>; + } = { // #region variable - VariableDeclarator(node: TSESTree.VariableDeclarator): void { - const validator = validators.variable; - if (!validator) { - return; - } - const identifiers = getIdentifiersFromPattern(node.id); + VariableDeclarator: { + validator: validators.variable, + handler: (node, validator): void => { + const identifiers = getIdentifiersFromPattern(node.id); - const baseModifiers = new Set(); - const parent = node.parent; - if (parent?.type === AST_NODE_TYPES.VariableDeclaration) { - if (parent.kind === 'const') { - baseModifiers.add(Modifiers.const); - } + const baseModifiers = new Set(); + const parent = node.parent; + if (parent?.type === AST_NODE_TYPES.VariableDeclaration) { + if (parent.kind === 'const') { + baseModifiers.add(Modifiers.const); + } - if (isGlobal(context.getScope())) { - baseModifiers.add(Modifiers.global); + if (isGlobal(context.getScope())) { + baseModifiers.add(Modifiers.global); + } } - } - identifiers.forEach(id => { - const modifiers = new Set(baseModifiers); + identifiers.forEach(id => { + const modifiers = new Set(baseModifiers); - if (isDestructured(id)) { - modifiers.add(Modifiers.destructured); - } + if (isDestructured(id)) { + modifiers.add(Modifiers.destructured); + } - if (isExported(parent, id.name, context.getScope())) { - modifiers.add(Modifiers.exported); - } + if (isExported(parent, id.name, context.getScope())) { + modifiers.add(Modifiers.exported); + } - if (isUnused(id.name)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(id.name)) { + modifiers.add(Modifiers.unused); + } - if (isAsyncVariableIdentifier(id)) { - modifiers.add(Modifiers.async); - } + if (isAsyncVariableIdentifier(id)) { + modifiers.add(Modifiers.async); + } - validator(id, modifiers); - }); + validator(id, modifiers); + }); + }, }, // #endregion // #region function - 'FunctionDeclaration, TSDeclareFunction, FunctionExpression'( - node: - | TSESTree.FunctionDeclaration - | TSESTree.TSDeclareFunction - | TSESTree.FunctionExpression, - ): void { - const validator = validators.function; - if (!validator || node.id === null) { - return; - } + 'FunctionDeclaration, TSDeclareFunction, FunctionExpression': { + validator: validators.function, + handler: ( + node: + | TSESTree.FunctionDeclaration + | TSESTree.TSDeclareFunction + | TSESTree.FunctionExpression, + validator, + ): void => { + if (node.id == null) { + return; + } - const modifiers = new Set(); - // functions create their own nested scope - const scope = context.getScope().upper; + const modifiers = new Set(); + // functions create their own nested scope + const scope = context.getScope().upper; - if (isGlobal(scope)) { - modifiers.add(Modifiers.global); - } + if (isGlobal(scope)) { + modifiers.add(Modifiers.global); + } - if (isExported(node, node.id.name, scope)) { - modifiers.add(Modifiers.exported); - } + if (isExported(node, node.id.name, scope)) { + modifiers.add(Modifiers.exported); + } - if (isUnused(node.id.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(node.id.name, scope)) { + modifiers.add(Modifiers.unused); + } - if (node.async) { - modifiers.add(Modifiers.async); - } + if (node.async) { + modifiers.add(Modifiers.async); + } - validator(node.id, modifiers); + validator(node.id, modifiers); + }, }, // #endregion function // #region parameter - 'FunctionDeclaration, TSDeclareFunction, TSEmptyBodyFunctionExpression, FunctionExpression, ArrowFunctionExpression'( - node: - | TSESTree.FunctionDeclaration - | TSESTree.TSDeclareFunction - | TSESTree.TSEmptyBodyFunctionExpression - | TSESTree.FunctionExpression - | TSESTree.ArrowFunctionExpression, - ): void { - const validator = validators.parameter; - if (!validator) { - return; - } - - node.params.forEach(param => { - if (param.type === AST_NODE_TYPES.TSParameterProperty) { - return; - } - - const identifiers = getIdentifiersFromPattern(param); - - identifiers.forEach(i => { - const modifiers = new Set(); - - if (isDestructured(i)) { - modifiers.add(Modifiers.destructured); - } - - if (isUnused(i.name)) { - modifiers.add(Modifiers.unused); - } - - validator(i, modifiers); - }); - }); - }, + 'FunctionDeclaration, TSDeclareFunction, TSEmptyBodyFunctionExpression, FunctionExpression, ArrowFunctionExpression': + { + validator: validators.parameter, + handler: ( + node: + | TSESTree.FunctionDeclaration + | TSESTree.TSDeclareFunction + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.FunctionExpression + | TSESTree.ArrowFunctionExpression, + validator, + ): void => { + node.params.forEach(param => { + if (param.type === AST_NODE_TYPES.TSParameterProperty) { + return; + } + + const identifiers = getIdentifiersFromPattern(param); + + identifiers.forEach(i => { + const modifiers = new Set(); + + if (isDestructured(i)) { + modifiers.add(Modifiers.destructured); + } + + if (isUnused(i.name)) { + modifiers.add(Modifiers.unused); + } + + validator(i, modifiers); + }); + }); + }, + }, // #endregion parameter // #region parameterProperty - TSParameterProperty(node): void { - const validator = validators.parameterProperty; - if (!validator) { - return; - } - - const modifiers = getMemberModifiers(node); + TSParameterProperty: { + validator: validators.parameterProperty, + handler: (node, validator): void => { + const modifiers = getMemberModifiers(node); - const identifiers = getIdentifiersFromPattern(node.parameter); + const identifiers = getIdentifiersFromPattern(node.parameter); - identifiers.forEach(i => { - validator(i, modifiers); - }); + identifiers.forEach(i => { + validator(i, modifiers); + }); + }, }, // #endregion parameterProperty // #region property - ':not(ObjectPattern) > Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'( - node: TSESTree.PropertyNonComputedName, - ): void { - const modifiers = new Set([Modifiers.public]); - handleMember(validators.objectLiteralProperty, node, modifiers); - }, - - ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]'( - node: - | TSESTree.PropertyDefinitionNonComputedName - | TSESTree.TSAbstractPropertyDefinitionNonComputedName, - ): void { - const modifiers = getMemberModifiers(node); - handleMember(validators.classProperty, node, modifiers); - }, - - 'TSPropertySignature[computed = false]'( - node: TSESTree.TSPropertySignatureNonComputedName, - ): void { - const modifiers = new Set([Modifiers.public]); - if (node.readonly) { - modifiers.add(Modifiers.readonly); - } + ':not(ObjectPattern) > Property[computed = false][kind = "init"][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]': + { + validator: validators.objectLiteralProperty, + handler: ( + node: TSESTree.PropertyNonComputedName, + validator, + ): void => { + const modifiers = new Set([Modifiers.public]); + handleMember(validator, node, modifiers); + }, + }, + + ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type != "ArrowFunctionExpression"][value.type != "FunctionExpression"][value.type != "TSEmptyBodyFunctionExpression"]': + { + validator: validators.classProperty, + handler: ( + node: + | TSESTree.PropertyDefinitionNonComputedName + | TSESTree.TSAbstractPropertyDefinitionNonComputedName, + validator, + ): void => { + const modifiers = getMemberModifiers(node); + handleMember(validator, node, modifiers); + }, + }, + + 'TSPropertySignature[computed = false]': { + validator: validators.typeProperty, + handler: ( + node: TSESTree.TSPropertySignatureNonComputedName, + validator, + ): void => { + const modifiers = new Set([Modifiers.public]); + if (node.readonly) { + modifiers.add(Modifiers.readonly); + } - handleMember(validators.typeProperty, node, modifiers); + handleMember(validator, node, modifiers); + }, }, // #endregion property @@ -393,18 +417,22 @@ export default util.createRule({ 'Property[computed = false][kind = "init"][value.type = "ArrowFunctionExpression"]', 'Property[computed = false][kind = "init"][value.type = "FunctionExpression"]', 'Property[computed = false][kind = "init"][value.type = "TSEmptyBodyFunctionExpression"]', - ].join(', ')]( - node: - | TSESTree.PropertyNonComputedName - | TSESTree.TSMethodSignatureNonComputedName, - ): void { - const modifiers = new Set([Modifiers.public]); - - if (isAsyncMemberOrProperty(node)) { - modifiers.add(Modifiers.async); - } + ].join(', ')]: { + validator: validators.objectLiteralMethod, + handler: ( + node: + | TSESTree.PropertyNonComputedName + | TSESTree.TSMethodSignatureNonComputedName, + validator, + ): void => { + const modifiers = new Set([Modifiers.public]); + + if (isAsyncMemberOrProperty(node)) { + modifiers.add(Modifiers.async); + } - handleMember(validators.objectLiteralMethod, node, modifiers); + handleMember(validator, node, modifiers); + }, }, [[ @@ -412,203 +440,218 @@ export default util.createRule({ ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type = "FunctionExpression"]', ':matches(PropertyDefinition, TSAbstractPropertyDefinition)[computed = false][value.type = "TSEmptyBodyFunctionExpression"]', ':matches(MethodDefinition, TSAbstractMethodDefinition)[computed = false][kind = "method"]', - ].join(', ')]( - node: - | TSESTree.PropertyDefinitionNonComputedName - | TSESTree.TSAbstractPropertyDefinitionNonComputedName - | TSESTree.MethodDefinitionNonComputedName - | TSESTree.TSAbstractMethodDefinitionNonComputedName, - ): void { - const modifiers = getMemberModifiers(node); - - if (isAsyncMemberOrProperty(node)) { - modifiers.add(Modifiers.async); - } + ].join(', ')]: { + validator: validators.classMethod, + handler: ( + node: + | TSESTree.PropertyDefinitionNonComputedName + | TSESTree.TSAbstractPropertyDefinitionNonComputedName + | TSESTree.MethodDefinitionNonComputedName + | TSESTree.TSAbstractMethodDefinitionNonComputedName, + validator, + ): void => { + const modifiers = getMemberModifiers(node); + + if (isAsyncMemberOrProperty(node)) { + modifiers.add(Modifiers.async); + } - handleMember(validators.classMethod, node, modifiers); + handleMember(validator, node, modifiers); + }, }, - 'TSMethodSignature[computed = false]'( - node: TSESTree.TSMethodSignatureNonComputedName, - ): void { - const modifiers = new Set([Modifiers.public]); - handleMember(validators.typeMethod, node, modifiers); + 'TSMethodSignature[computed = false]': { + validator: validators.typeMethod, + handler: ( + node: TSESTree.TSMethodSignatureNonComputedName, + validator, + ): void => { + const modifiers = new Set([Modifiers.public]); + handleMember(validator, node, modifiers); + }, }, // #endregion method // #region accessor - 'Property[computed = false]:matches([kind = "get"], [kind = "set"])'( - node: TSESTree.PropertyNonComputedName, - ): void { - const modifiers = new Set([Modifiers.public]); - handleMember(validators.accessor, node, modifiers); + 'Property[computed = false]:matches([kind = "get"], [kind = "set"])': { + validator: validators.accessor, + handler: (node: TSESTree.PropertyNonComputedName, validator): void => { + const modifiers = new Set([Modifiers.public]); + handleMember(validator, node, modifiers); + }, }, - 'MethodDefinition[computed = false]:matches([kind = "get"], [kind = "set"])'( - node: TSESTree.MethodDefinitionNonComputedName, - ): void { - const modifiers = getMemberModifiers(node); - handleMember(validators.accessor, node, modifiers); - }, + 'MethodDefinition[computed = false]:matches([kind = "get"], [kind = "set"])': + { + validator: validators.accessor, + handler: ( + node: TSESTree.MethodDefinitionNonComputedName, + validator, + ): void => { + const modifiers = getMemberModifiers(node); + handleMember(validator, node, modifiers); + }, + }, // #endregion accessor // #region enumMember // computed is optional, so can't do [computed = false] - 'TSEnumMember[computed != true]'( - node: TSESTree.TSEnumMemberNonComputedName, - ): void { - const validator = validators.enumMember; - if (!validator) { - return; - } - - const id = node.id; - const modifiers = new Set(); - - if (requiresQuoting(id, compilerOptions.target)) { - modifiers.add(Modifiers.requiresQuotes); - } + 'TSEnumMember[computed != true]': { + validator: validators.enumMember, + handler: ( + node: TSESTree.TSEnumMemberNonComputedName, + validator, + ): void => { + const id = node.id; + const modifiers = new Set(); + + if (requiresQuoting(id, compilerOptions.target)) { + modifiers.add(Modifiers.requiresQuotes); + } - validator(id, modifiers); + validator(id, modifiers); + }, }, // #endregion enumMember // #region class - 'ClassDeclaration, ClassExpression'( - node: TSESTree.ClassDeclaration | TSESTree.ClassExpression, - ): void { - const validator = validators.class; - if (!validator) { - return; - } - - const id = node.id; - if (id === null) { - return; - } + 'ClassDeclaration, ClassExpression': { + validator: validators.class, + handler: ( + node: TSESTree.ClassDeclaration | TSESTree.ClassExpression, + validator, + ): void => { + const id = node.id; + if (id == null) { + return; + } - const modifiers = new Set(); - // classes create their own nested scope - const scope = context.getScope().upper; + const modifiers = new Set(); + // classes create their own nested scope + const scope = context.getScope().upper; - if (node.abstract) { - modifiers.add(Modifiers.abstract); - } + if (node.abstract) { + modifiers.add(Modifiers.abstract); + } - if (isExported(node, id.name, scope)) { - modifiers.add(Modifiers.exported); - } + if (isExported(node, id.name, scope)) { + modifiers.add(Modifiers.exported); + } - if (isUnused(id.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(id.name, scope)) { + modifiers.add(Modifiers.unused); + } - validator(id, modifiers); + validator(id, modifiers); + }, }, // #endregion class // #region interface - TSInterfaceDeclaration(node): void { - const validator = validators.interface; - if (!validator) { - return; - } - - const modifiers = new Set(); - const scope = context.getScope(); + TSInterfaceDeclaration: { + validator: validators.interface, + handler: (node, validator): void => { + const modifiers = new Set(); + const scope = context.getScope(); - if (isExported(node, node.id.name, scope)) { - modifiers.add(Modifiers.exported); - } + if (isExported(node, node.id.name, scope)) { + modifiers.add(Modifiers.exported); + } - if (isUnused(node.id.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(node.id.name, scope)) { + modifiers.add(Modifiers.unused); + } - validator(node.id, modifiers); + validator(node.id, modifiers); + }, }, // #endregion interface // #region typeAlias - TSTypeAliasDeclaration(node): void { - const validator = validators.typeAlias; - if (!validator) { - return; - } + TSTypeAliasDeclaration: { + validator: validators.typeAlias, + handler: (node, validator): void => { + const modifiers = new Set(); + const scope = context.getScope(); - const modifiers = new Set(); - const scope = context.getScope(); - - if (isExported(node, node.id.name, scope)) { - modifiers.add(Modifiers.exported); - } + if (isExported(node, node.id.name, scope)) { + modifiers.add(Modifiers.exported); + } - if (isUnused(node.id.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(node.id.name, scope)) { + modifiers.add(Modifiers.unused); + } - validator(node.id, modifiers); + validator(node.id, modifiers); + }, }, // #endregion typeAlias // #region enum - TSEnumDeclaration(node): void { - const validator = validators.enum; - if (!validator) { - return; - } - - const modifiers = new Set(); - // enums create their own nested scope - const scope = context.getScope().upper; + TSEnumDeclaration: { + validator: validators.enum, + handler: (node, validator): void => { + const modifiers = new Set(); + // enums create their own nested scope + const scope = context.getScope().upper; - if (isExported(node, node.id.name, scope)) { - modifiers.add(Modifiers.exported); - } + if (isExported(node, node.id.name, scope)) { + modifiers.add(Modifiers.exported); + } - if (isUnused(node.id.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(node.id.name, scope)) { + modifiers.add(Modifiers.unused); + } - validator(node.id, modifiers); + validator(node.id, modifiers); + }, }, // #endregion enum // #region typeParameter - 'TSTypeParameterDeclaration > TSTypeParameter'( - node: TSESTree.TSTypeParameter, - ): void { - const validator = validators.typeParameter; - if (!validator) { - return; - } - - const modifiers = new Set(); - const scope = context.getScope(); + 'TSTypeParameterDeclaration > TSTypeParameter': { + validator: validators.typeParameter, + handler: (node: TSESTree.TSTypeParameter, validator): void => { + const modifiers = new Set(); + const scope = context.getScope(); - if (isUnused(node.name.name, scope)) { - modifiers.add(Modifiers.unused); - } + if (isUnused(node.name.name, scope)) { + modifiers.add(Modifiers.unused); + } - validator(node.name, modifiers); + validator(node.name, modifiers); + }, }, // #endregion typeParameter }; + + return Object.fromEntries( + Object.entries(selectors) + .map(([selector, { validator, handler }]) => { + return [ + selector, + (node: Parameters[0]): void => { + handler(node, validator); + }, + ] as const; + }) + .filter((s): s is NonNullable => s != null), + ); }, }); diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index 0ae6698c533..d88cd05ff6f 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -135,7 +135,7 @@ export default util.createRule({ node: TSESTree.NewExpression | TSESTree.CallExpression, ): void { const calleeName = getCalleeName(node.callee); - if (calleeName === null) { + if (calleeName == null) { return; } diff --git a/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts new file mode 100644 index 00000000000..ce80a654afe --- /dev/null +++ b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts @@ -0,0 +1,76 @@ +import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; + +import * as util from '../util'; + +type Options = []; +type MessageIds = 'useTopLevelQualifier'; + +export default util.createRule({ + name: 'no-import-type-side-effects', + meta: { + type: 'problem', + docs: { + description: + 'Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers', + recommended: false, + }, + fixable: 'code', + messages: { + useTopLevelQualifier: + 'TypeScript will only remove the inline type specifiers which will leave behind a side effect import at runtime. Convert this to a top-level type qualifier to properly remove the entire import.', + }, + schema: [], + }, + defaultOptions: [], + create(context) { + const sourceCode = context.getSourceCode(); + return { + 'ImportDeclaration[importKind!="type"]'( + node: TSESTree.ImportDeclaration, + ): void { + const specifiers: TSESTree.ImportSpecifier[] = []; + for (const specifier of node.specifiers) { + if ( + specifier.type !== AST_NODE_TYPES.ImportSpecifier || + specifier.importKind !== 'type' + ) { + return; + } + specifiers.push(specifier); + } + + context.report({ + node, + messageId: 'useTopLevelQualifier', + fix(fixer) { + const fixes: TSESLint.RuleFix[] = []; + for (const specifier of specifiers) { + const qualifier = util.nullThrows( + sourceCode.getFirstToken(specifier, util.isTypeKeyword), + util.NullThrowsReasons.MissingToken( + 'type keyword', + 'import specifier', + ), + ); + fixes.push( + fixer.removeRange([ + qualifier.range[0], + specifier.imported.range[0], + ]), + ); + } + + const importKeyword = util.nullThrows( + sourceCode.getFirstToken(node, util.isImportKeyword), + util.NullThrowsReasons.MissingToken('import keyword', 'import'), + ); + fixes.push(fixer.insertTextAfter(importKeyword, ' type')); + + return fixes; + }, + }); + }, + }; + }, +}); diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index effbed48eaa..1bc83c07c70 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -147,7 +147,7 @@ export default util.createRule({ } case AST_NODE_TYPES.TSNullKeyword: - return init.type === AST_NODE_TYPES.Literal && init.value === null; + return init.type === AST_NODE_TYPES.Literal && init.value == null; case AST_NODE_TYPES.TSStringKeyword: return ( diff --git a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts index 7b9492972e8..2c0d84364e4 100644 --- a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts +++ b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts @@ -25,7 +25,7 @@ export default util.createRule({ }, defaultOptions: [], create(context) { - /* istanbul ignore if */ if (baseRule === null) { + /* istanbul ignore if */ if (baseRule == null) { throw new Error( '@typescript-eslint/no-loss-of-precision requires at least ESLint v7.1.0', ); diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index b6914ae2c39..15bf0c501d1 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -250,7 +250,7 @@ export default util.createRule({ function checkVariableDeclaration(node: TSESTree.VariableDeclarator): void { const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); - if (tsNode.initializer === undefined || node.init === null) { + if (tsNode.initializer === undefined || node.init == null) { return; } const varType = checker.getTypeAtLocation(tsNode.name); @@ -344,7 +344,7 @@ export default util.createRule({ function checkReturnStatement(node: TSESTree.ReturnStatement): void { const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); - if (tsNode.expression === undefined || node.argument === null) { + if (tsNode.expression === undefined || node.argument == null) { return; } const contextualType = checker.getContextualType(tsNode.expression); @@ -368,7 +368,7 @@ export default util.createRule({ const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); const value = tsNode.initializer; if ( - node.value === null || + node.value == null || value === undefined || !ts.isJsxExpression(value) || value.expression === undefined diff --git a/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts index 8706703c9ba..a79fa4062b1 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts @@ -27,7 +27,7 @@ function isDefinitionWithAssignment(definition: Definition): boolean { const variableDeclarator = definition.node; return ( - variableDeclarator.definite === true || variableDeclarator.init !== null + variableDeclarator.definite === true || variableDeclarator.init != null ); } diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 5a6872f5748..42f12748af9 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -384,7 +384,7 @@ export default createRule({ | TSESTree.ForStatement | TSESTree.WhileStatement, ): void { - if (node.test === null) { + if (node.test == null) { // e.g. `for(;;)` return; } diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts index fbf3b41e966..632ad6c5ba0 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts @@ -53,7 +53,7 @@ export default util.createRule({ const alias = tryGetAliasedSymbol(symbol, checker); - return alias !== null && symbolIsNamespaceInScope(alias); + return alias != null && symbolIsNamespaceInScope(alias); } function getSymbolInScope( diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index 5153ed47fcd..b88cd82d39d 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -21,7 +21,7 @@ function parseOptions(options: string | Config | null): Required { if (typeof options === 'string') { functions = options !== 'nofunc'; - } else if (typeof options === 'object' && options !== null) { + } else if (typeof options === 'object' && options != null) { functions = options.functions !== false; classes = options.classes !== false; enums = options.enums !== false; @@ -64,7 +64,7 @@ function isOuterEnum( reference: TSESLint.Scope.Reference, ): boolean { return ( - variable.defs[0].type == DefinitionType.TSEnumName && + variable.defs[0].type === DefinitionType.TSEnumName && variable.scope.variableScope !== reference.from.variableScope ); } diff --git a/packages/eslint-plugin/src/rules/prefer-for-of.ts b/packages/eslint-plugin/src/rules/prefer-for-of.ts index 9bb8802a7da..ddde074a234 100644 --- a/packages/eslint-plugin/src/rules/prefer-for-of.ts +++ b/packages/eslint-plugin/src/rules/prefer-for-of.ts @@ -24,8 +24,7 @@ export default util.createRule({ node: TSESTree.Node | null, ): node is TSESTree.VariableDeclaration { return ( - node !== null && - node.type === AST_NODE_TYPES.VariableDeclaration && + node?.type === AST_NODE_TYPES.VariableDeclaration && node.kind !== 'const' && node.declarations.length === 1 ); @@ -39,7 +38,7 @@ export default util.createRule({ } function isZeroInitialized(node: TSESTree.VariableDeclarator): boolean { - return node.init !== null && isLiteral(node.init, 0); + return node.init != null && isLiteral(node.init, 0); } function isMatchingIdentifier( @@ -54,8 +53,7 @@ export default util.createRule({ name: string, ): TSESTree.Expression | null { if ( - node !== null && - node.type === AST_NODE_TYPES.BinaryExpression && + node?.type === AST_NODE_TYPES.BinaryExpression && node.operator === '<' && isMatchingIdentifier(node.left, name) && node.right.type === AST_NODE_TYPES.MemberExpression && diff --git a/packages/eslint-plugin/src/rules/prefer-function-type.ts b/packages/eslint-plugin/src/rules/prefer-function-type.ts index 95b3ee5d33b..db5dde69d00 100644 --- a/packages/eslint-plugin/src/rules/prefer-function-type.ts +++ b/packages/eslint-plugin/src/rules/prefer-function-type.ts @@ -82,8 +82,7 @@ export default util.createRule({ typeof member.returnType !== 'undefined' ) { if ( - tsThisTypes !== null && - tsThisTypes.length > 0 && + tsThisTypes?.length && node.type === AST_NODE_TYPES.TSInterfaceDeclaration ) { // the message can be confusing if we don't point directly to the `this` node instead of the whole member @@ -205,7 +204,7 @@ export default util.createRule({ // inside an interface keep track of all ThisType references. // unless it's inside a nested type literal in which case it's invalid code anyway // we don't want to incorrectly say "it refers to name" while typescript says it's completely invalid. - if (literalNesting === 0 && tsThisTypes !== null) { + if (literalNesting === 0 && tsThisTypes != null) { tsThisTypes.push(node); } }, diff --git a/packages/eslint-plugin/src/rules/prefer-includes.ts b/packages/eslint-plugin/src/rules/prefer-includes.ts index 9c50ce118f8..720d5fbe809 100644 --- a/packages/eslint-plugin/src/rules/prefer-includes.ts +++ b/packages/eslint-plugin/src/rules/prefer-includes.ts @@ -38,7 +38,7 @@ export default createRule({ function isNumber(node: TSESTree.Node, value: number): boolean { const evaluated = getStaticValue(node, globalScope); - return evaluated !== null && evaluated.value === value; + return evaluated != null && evaluated.value === value; } function isPositiveCheck(node: TSESTree.BinaryExpression): boolean { diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts index 9a4949b734b..efccc2ccfd2 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts @@ -10,6 +10,7 @@ type ValidChainTarget = | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.Identifier + | TSESTree.PrivateIdentifier | TSESTree.MemberExpression | TSESTree.ThisExpression | TSESTree.MetaProperty; @@ -164,7 +165,9 @@ export default util.createRule({ break; } + let invalidOptionallyChainedPrivateProperty; ({ + invalidOptionallyChainedPrivateProperty, expressionCount, previousLeftText, optionallyChainedCode, @@ -178,6 +181,9 @@ export default util.createRule({ previous, current, )); + if (invalidOptionallyChainedPrivateProperty) { + return; + } } reportIfMoreThanOne({ @@ -243,7 +249,9 @@ export default util.createRule({ break; } + let invalidOptionallyChainedPrivateProperty; ({ + invalidOptionallyChainedPrivateProperty, expressionCount, previousLeftText, optionallyChainedCode, @@ -257,6 +265,9 @@ export default util.createRule({ previous, current, )); + if (invalidOptionallyChainedPrivateProperty) { + return; + } } reportIfMoreThanOne({ @@ -343,7 +354,10 @@ export default util.createRule({ return `${calleeText}${argumentsText}`; } - if (node.type === AST_NODE_TYPES.Identifier) { + if ( + node.type === AST_NODE_TYPES.Identifier || + node.type === AST_NODE_TYPES.PrivateIdentifier + ) { return node.name; } @@ -381,15 +395,12 @@ export default util.createRule({ // cases should match the list in ALLOWED_MEMBER_OBJECT_TYPES switch (node.object.type) { - case AST_NODE_TYPES.CallExpression: - case AST_NODE_TYPES.Identifier: - objectText = getText(node.object); - break; - case AST_NODE_TYPES.MemberExpression: objectText = getMemberExpressionText(node.object); break; + case AST_NODE_TYPES.CallExpression: + case AST_NODE_TYPES.Identifier: case AST_NODE_TYPES.MetaProperty: case AST_NODE_TYPES.ThisExpression: objectText = getText(node.object); @@ -397,7 +408,7 @@ export default util.createRule({ /* istanbul ignore next */ default: - throw new Error(`Unexpected member object type: ${node.object.type}`); + return ''; } let propertyText: string; @@ -420,9 +431,7 @@ export default util.createRule({ /* istanbul ignore next */ default: - throw new Error( - `Unexpected member property type: ${node.object.type}`, - ); + return ''; } return `${objectText}${node.optional ? '?.' : ''}[${propertyText}]`; @@ -432,12 +441,12 @@ export default util.createRule({ case AST_NODE_TYPES.Identifier: propertyText = getText(node.property); break; + case AST_NODE_TYPES.PrivateIdentifier: + propertyText = '#' + getText(node.property); + break; - /* istanbul ignore next */ default: - throw new Error( - `Unexpected member property type: ${node.object.type}`, - ); + propertyText = sourceCode.getText(node.property); } return `${objectText}${node.optional ? '?.' : '.'}${propertyText}`; @@ -461,6 +470,7 @@ const ALLOWED_COMPUTED_PROP_TYPES: ReadonlySet = new Set([ ]); const ALLOWED_NON_COMPUTED_PROP_TYPES: ReadonlySet = new Set([ AST_NODE_TYPES.Identifier, + AST_NODE_TYPES.PrivateIdentifier, ]); interface ReportIfMoreThanOneOptions { @@ -490,10 +500,20 @@ function reportIfMoreThanOne({ shouldHandleChainedAnds && previous.right.type === AST_NODE_TYPES.BinaryExpression ) { + let operator = previous.right.operator; + if ( + previous.right.operator === '!==' && + // TODO(#4820): Use the type checker to know whether this is `null` + previous.right.right.type === AST_NODE_TYPES.Literal && + previous.right.right.raw === 'null' + ) { + // case like foo !== null && foo.bar !== null + operator = '!='; + } // case like foo && foo.bar !== someValue - optionallyChainedCode += ` ${ - previous.right.operator - } ${sourceCode.getText(previous.right.right)}`; + optionallyChainedCode += ` ${operator} ${sourceCode.getText( + previous.right.right, + )}`; } context.report({ @@ -515,6 +535,7 @@ function reportIfMoreThanOne({ } interface NormalizedPattern { + invalidOptionallyChainedPrivateProperty: boolean; expressionCount: number; previousLeftText: string; optionallyChainedCode: string; @@ -531,6 +552,7 @@ function normalizeRepeatingPatterns( current: TSESTree.Node, ): NormalizedPattern { const leftText = previousLeftText; + let invalidOptionallyChainedPrivateProperty = false; // omit weird doubled up expression that make no sense like foo.bar && foo.bar if (rightText !== previousLeftText) { expressionCount += 1; @@ -566,6 +588,11 @@ function normalizeRepeatingPatterns( diff === '?.buzz' */ const diff = rightText.replace(leftText, ''); + if (diff.startsWith('.#')) { + // Do not handle direct optional chaining on private properties because of a typescript bug (https://github.com/microsoft/TypeScript/issues/42734) + // We still allow in computed properties + invalidOptionallyChainedPrivateProperty = true; + } if (diff.startsWith('?')) { // item was "pre optional chained" optionallyChainedCode += diff; @@ -581,6 +608,7 @@ function normalizeRepeatingPatterns( util.NullThrowsReasons.MissingParent, ); return { + invalidOptionallyChainedPrivateProperty, expressionCount, previousLeftText, optionallyChainedCode, diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 13452d48f86..60bf310947f 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -123,7 +123,7 @@ export default createRule({ if ( argumentNode.type === AST_NODE_TYPES.Literal && - typeof argumentNode.value == 'string' + typeof argumentNode.value === 'string' ) { const regExp = RegExp(argumentNode.value); return context.report({ diff --git a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts index 31a570652dc..104637062bb 100644 --- a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts +++ b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts @@ -60,7 +60,7 @@ export default createRule({ */ function isNull(node: TSESTree.Node): node is TSESTree.Literal { const evaluated = getStaticValue(node, globalScope); - return evaluated != null && evaluated.value === null; + return evaluated != null && evaluated.value == null; } /** diff --git a/packages/eslint-plugin/src/rules/space-before-function-paren.ts b/packages/eslint-plugin/src/rules/space-before-function-paren.ts index 4a3f9042e78..5ff33aeb4fe 100644 --- a/packages/eslint-plugin/src/rules/space-before-function-paren.ts +++ b/packages/eslint-plugin/src/rules/space-before-function-paren.ts @@ -140,7 +140,8 @@ export default util.createRule({ return; } - let leftToken: TSESTree.Token, rightToken: TSESTree.Token; + let leftToken: TSESTree.Token; + let rightToken: TSESTree.Token; if (node.typeParameters) { leftToken = sourceCode.getLastToken(node.typeParameters)!; rightToken = sourceCode.getTokenAfter(leftToken)!; diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index cff8960dac8..43d4913b4ca 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -121,7 +121,7 @@ export default createRule({ const unionTypes = unionTypeParts(discriminantType); const caseTypes: Set = new Set(); for (const switchCase of node.cases) { - if (switchCase.test === null) { + if (switchCase.test == null) { // Switch has 'default' branch - do nothing. return; } diff --git a/packages/eslint-plugin/src/rules/triple-slash-reference.ts b/packages/eslint-plugin/src/rules/triple-slash-reference.ts index 5780d55cb5c..4425e666338 100644 --- a/packages/eslint-plugin/src/rules/triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/triple-slash-reference.ts @@ -87,7 +87,7 @@ export default util.createRule({ } }, Program(node): void { - if (lib === 'always' && path === 'always' && types == 'always') { + if (lib === 'always' && path === 'always' && types === 'always') { return; } programNode = node; diff --git a/packages/eslint-plugin/src/util/getESLintCoreRule.ts b/packages/eslint-plugin/src/util/getESLintCoreRule.ts index 1678903acd3..80962a677b0 100644 --- a/packages/eslint-plugin/src/util/getESLintCoreRule.ts +++ b/packages/eslint-plugin/src/util/getESLintCoreRule.ts @@ -12,6 +12,7 @@ interface RuleMap { 'dot-notation': typeof import('eslint/lib/rules/dot-notation'); indent: typeof import('eslint/lib/rules/indent'); 'init-declarations': typeof import('eslint/lib/rules/init-declarations'); + 'key-spacing': typeof import('eslint/lib/rules/key-spacing'); 'keyword-spacing': typeof import('eslint/lib/rules/keyword-spacing'); 'lines-between-class-members': typeof import('eslint/lib/rules/lines-between-class-members'); 'no-dupe-args': typeof import('eslint/lib/rules/no-dupe-args'); diff --git a/packages/eslint-plugin/src/util/getStringLength.ts b/packages/eslint-plugin/src/util/getStringLength.ts new file mode 100644 index 00000000000..65a22551949 --- /dev/null +++ b/packages/eslint-plugin/src/util/getStringLength.ts @@ -0,0 +1,17 @@ +import GraphemeSplitter from 'grapheme-splitter'; + +let splitter: GraphemeSplitter; + +function isASCII(value: string): boolean { + return /^[\u0020-\u007f]*$/u.test(value); +} + +export function getStringLength(value: string): number { + if (isASCII(value)) { + return value.length; + } + + splitter ??= new GraphemeSplitter(); + + return splitter.countGraphemes(value); +} diff --git a/packages/eslint-plugin/src/util/index.ts b/packages/eslint-plugin/src/util/index.ts index b2ad2927773..53a19a96d36 100644 --- a/packages/eslint-plugin/src/util/index.ts +++ b/packages/eslint-plugin/src/util/index.ts @@ -5,6 +5,7 @@ export * from './collectUnusedVariables'; export * from './createRule'; export * from './getFunctionHeadLoc'; export * from './getOperatorPrecedence'; +export * from './getStringLength'; export * from './getThisExpression'; export * from './getWrappingFixer'; export * from './isNodeEqual'; diff --git a/packages/eslint-plugin/src/util/isNullLiteral.ts b/packages/eslint-plugin/src/util/isNullLiteral.ts index f8695f26092..85bf4588212 100644 --- a/packages/eslint-plugin/src/util/isNullLiteral.ts +++ b/packages/eslint-plugin/src/util/isNullLiteral.ts @@ -2,5 +2,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; export function isNullLiteral(i: TSESTree.Node): boolean { - return i.type === AST_NODE_TYPES.Literal && i.value === null; + return i.type === AST_NODE_TYPES.Literal && i.value == null; } diff --git a/packages/eslint-plugin/src/util/misc.ts b/packages/eslint-plugin/src/util/misc.ts index fa9c5ccf528..8362736bd62 100644 --- a/packages/eslint-plugin/src/util/misc.ts +++ b/packages/eslint-plugin/src/util/misc.ts @@ -210,6 +210,7 @@ function typeNodeRequiresParentheses( return ( node.type === AST_NODE_TYPES.TSFunctionType || node.type === AST_NODE_TYPES.TSConstructorType || + node.type === AST_NODE_TYPES.TSConditionalType || (node.type === AST_NODE_TYPES.TSUnionType && text.startsWith('|')) || (node.type === AST_NODE_TYPES.TSIntersectionType && text.startsWith('&')) ); diff --git a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts index 7e8ef295ba9..54855f19cf3 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts @@ -45,6 +45,14 @@ ruleTester.run('ts-expect-error', rule, { }, ], }, + { + code: noFormat`// @ts-expect-error 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦`, + options: [ + { + 'ts-expect-error': 'allow-with-description', + }, + ], + }, ], invalid: [ { @@ -228,6 +236,22 @@ if (false) { }, ], }, + { + code: noFormat`// @ts-expect-error 👨‍👩‍👧‍👦`, + options: [ + { + 'ts-expect-error': 'allow-with-description', + }, + ], + errors: [ + { + data: { directive: 'expect-error', minimumDescriptionLength: 3 }, + messageId: 'tsDirectiveCommentRequiresDescription', + line: 1, + column: 1, + }, + ], + }, ], }); @@ -266,6 +290,14 @@ ruleTester.run('ts-ignore', rule, { }, ], }, + { + code: noFormat`// @ts-ignore 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦`, + options: [ + { + 'ts-ignore': 'allow-with-description', + }, + ], + }, ], invalid: [ { @@ -460,6 +492,22 @@ if (false) { }, ], }, + { + code: noFormat`// @ts-ignore 👨‍👩‍👧‍👦`, + options: [ + { + 'ts-ignore': 'allow-with-description', + }, + ], + errors: [ + { + data: { directive: 'ignore', minimumDescriptionLength: 3 }, + messageId: 'tsDirectiveCommentRequiresDescription', + line: 1, + column: 1, + }, + ], + }, ], }); @@ -498,6 +546,14 @@ ruleTester.run('ts-nocheck', rule, { }, ], }, + { + code: noFormat`// @ts-nocheck 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦`, + options: [ + { + 'ts-nocheck': 'allow-with-description', + }, + ], + }, ], invalid: [ { @@ -668,6 +724,22 @@ if (false) { }, ], }, + { + code: noFormat`// @ts-nocheck 👨‍👩‍👧‍👦`, + options: [ + { + 'ts-nocheck': 'allow-with-description', + }, + ], + errors: [ + { + data: { directive: 'nocheck', minimumDescriptionLength: 3 }, + messageId: 'tsDirectiveCommentRequiresDescription', + line: 1, + column: 1, + }, + ], + }, ], }); @@ -700,6 +772,14 @@ ruleTester.run('ts-check', rule, { }, ], }, + { + code: noFormat`// @ts-check 👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👩‍👧‍👦`, + options: [ + { + 'ts-check': 'allow-with-description', + }, + ], + }, ], invalid: [ { @@ -863,5 +943,21 @@ if (false) { }, ], }, + { + code: noFormat`// @ts-check 👨‍👩‍👧‍👦`, + options: [ + { + 'ts-check': 'allow-with-description', + }, + ], + errors: [ + { + data: { directive: 'check', minimumDescriptionLength: 3 }, + messageId: 'tsDirectiveCommentRequiresDescription', + line: 1, + column: 1, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/indent/indent.test.ts b/packages/eslint-plugin/tests/rules/indent/indent.test.ts index 65fe9240377..f9191d3ef10 100644 --- a/packages/eslint-plugin/tests/rules/indent/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent/indent.test.ts @@ -638,7 +638,7 @@ type Foo = string | { }) .filter( (error): error is TSESLint.TestCaseError => - error !== null, + error != null, ), }; if (invalid.errors.length > 0) { diff --git a/packages/eslint-plugin/tests/rules/key-spacing.test.ts b/packages/eslint-plugin/tests/rules/key-spacing.test.ts new file mode 100644 index 00000000000..40206258671 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/key-spacing.test.ts @@ -0,0 +1,1278 @@ +/* eslint-disable eslint-comments/no-use */ +// this rule tests the new lines, which prettier will want to fix and break the tests +/* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ +/* eslint-enable eslint-comments/no-use */ +import rule from '../../src/rules/key-spacing'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('key-spacing', rule, { + valid: [ + // align: value + { + code: ` +interface X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + "a:b": number; + abcde: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +let x: { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +let x: { + a: number; + "𐌘": string; + [𐌘]: Date; + "🌷": "bar", // 2 code points + "🎁": "baz", // 2 code points + "🇮🇳": "qux", // 4 code points + "🏳️‍🌈": "xyz", // 6 code points +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + abc: string; c: number; +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + abc: string; c: number; de: boolean; + abcef: number; +}; + `, + options: [{ align: 'colon' }], + }, + { + code: ` +interface X { + a : number; + abc; + abcef: number; +}; + `, + options: [{ align: 'colon' }], + }, + { + code: ` +interface X { + a?: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + // Some comment + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + // Some comment + // on multiple lines + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + /** + * Some comment + * on multiple lines + */ + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + /** + * Doc comment + */ + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +interface X { + a: number; + + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +class X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +class X { + a?: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +class X { + x: number; + z = 1; + xbcef: number; + } + `, + options: [{ align: 'value' }], + }, + { + code: ` +class X { + a: number; + + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +type X = { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +type X = { + a: number; + + abc: string +}; + `, + options: [{ align: 'value' }], + }, + { + code: ` +type X = { + a : number; + abc: string +}; + `, + options: [{ align: 'value', mode: 'minimum' }], + }, + { + code: ` +type X = { + a : number; + abc: string +}; + `, + options: [ + { + align: { + on: 'value', + mode: 'minimum', + beforeColon: false, + afterColon: true, + }, + }, + ], + }, + { + code: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }; + abc: string +} + `, + options: [{ align: 'value' }], + }, + { + code: ` +class X { + a: number; + prop: { + abc: number; + a: number; + }; + abc: string + x = 1; + d: number; + z: number = 1; + ef: string; +} + `, + options: [{ align: 'value' }], + }, + // align: colon + { + code: ` +interface X { + a : number; + abc: string +}; + `, + options: [{ align: 'colon' }], + }, + { + code: ` +interface X { + a :number; + abc:string +}; + `, + options: [{ align: 'colon', afterColon: false }], + }, + { + code: ` +interface X { + a : number; + abc: string +}; + `, + options: [{ align: 'colon', mode: 'minimum' }], + }, + // no align + { + code: ` +interface X { + a: number; + abc: string +}; + `, + options: [{}], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [{ beforeColon: true }], + }, + // singleLine / multiLine + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + align: { on: 'value', beforeColon: true, afterColon: true }, + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: false, afterColon: false }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + align: { beforeColon: true, afterColon: true }, // defaults to 'colon' + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: false, afterColon: false }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: true, afterColon: true, align: 'value' }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { + beforeColon: true, + afterColon: true, + align: { + on: 'colon', + mode: 'strict', + afterColon: true, + beforeColon: true, + }, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { + beforeColon: true, + afterColon: true, + align: { + mode: 'strict', + afterColon: true, + beforeColon: true, + }, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + beforeColon: true, + afterColon: true, + align: { + on: 'colon', + mode: 'strict', + afterColon: true, + beforeColon: true, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + beforeColon: true, + afterColon: true, + align: { + mode: 'strict', + afterColon: true, + beforeColon: true, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc: string + + xadzd : number; +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { + beforeColon: true, + afterColon: true, + align: { + on: 'colon', + mode: 'strict', + afterColon: true, + beforeColon: false, + }, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc: string + + xadzd : number; +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { + beforeColon: true, + afterColon: true, + mode: 'strict', + align: { + on: 'colon', + afterColon: true, + beforeColon: false, + }, + }, + }, + ], + }, + { + code: ` +interface X { + a : number; + abc: string + + xadzd : number; +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { + beforeColon: true, + afterColon: true, + mode: 'minimum', + align: { + on: 'colon', + afterColon: true, + beforeColon: false, + }, + }, + }, + ], + }, + { + code: ` +interface X { a:number; abc:string; }; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + }, + ], + invalid: [ + // align: value + { + code: ` +interface X { + a: number; + abc: string +}; + `, + output: ` +interface X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +interface X { + a: number; + "a:c": string +}; + `, + output: ` +interface X { + a: number; + "a:c": string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +let x: { + a: number; + abc: string +}; + `, + output: ` +let x: { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +let x: { + a: number; + abc: string +}; + `, + output: ` +let x: { + a: number; + abc: string +}; + `, + options: [{ align: { on: 'value' } }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +let x: { + a: number; + "🌷": "bar", // 2 code points + "🎁": "baz", // 2 code points + "🇮🇳": "qux", // 4 code points + "🏳️‍🌈": "xyz", // 6 code points + [𐌘]: string + "𐌘": string +}; + `, + output: ` +let x: { + a: number; + "🌷": "bar", // 2 code points + "🎁": "baz", // 2 code points + "🇮🇳": "qux", // 4 code points + "🏳️‍🌈": "xyz", // 6 code points + [𐌘]: string + "𐌘": string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +class X { + a: number; + abc: string +}; + `, + output: ` +class X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +class X { + a: number; + abc: string +}; + `, + output: ` +class X { + a: number; + abc: string +}; + `, + options: [{ align: 'value', mode: 'minimum' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +class X { + a: number; + b; + abc: string +}; + `, + output: ` +class X { + a: number; + b; + abc: string +}; + `, + options: [{ align: 'value', mode: 'minimum' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +type X = { + a: number; + abc: string +}; + `, + output: ` +type X = { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +interface X { + a: number; + abc: string +}; + `, + output: ` +interface X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +class X { + a: number; + abc: string +}; + `, + output: ` +class X { + a: number; + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +class X { + x: number; + z = 1; + xbcef: number; + } + `, + output: ` +class X { + x: number; + z = 1; + xbcef: number; + } + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +interface X { + a: number; + + abc : string +}; + `, + output: ` +interface X { + a: number; + + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }, { messageId: 'extraKey' }], + }, + { + code: ` +class X { + a: number; + + abc : string +}; + `, + output: ` +class X { + a: number; + + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }, { messageId: 'extraKey' }], + }, + { + code: ` +interface X { + a: number; + // Some comment + + // interrupted in the middle + abc: string +}; + `, + output: ` +interface X { + a: number; + // Some comment + + // interrupted in the middle + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +interface X { + a: number; + /** + * Multiline comment + */ + + /** interrupted in the middle */ + abc: string +}; + `, + output: ` +interface X { + a: number; + /** + * Multiline comment + */ + + /** interrupted in the middle */ + abc: string +}; + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + output: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + output: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'missingValue' }], + }, + { + code: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + output: ` +interface X { + a: number; + prop: { + abc: number; + a: number; + }, + abc: string +} + `, + options: [{ align: 'value' }], + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +class X { + a: number; + prop: { + abc: number; + a?: number; + }; + abc: string; + x = 1; + d: number; + z: number = 1; + ef: string; +} + `, + output: ` +class X { + a: number; + prop: { + abc: number; + a?: number; + }; + abc: string; + x = 1; + d: number; + z: number = 1; + ef: string; +} + `, + options: [{ align: 'value' }], + errors: [ + { messageId: 'extraValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + ], + }, + // align: colon + { + code: ` +interface X { + a : number; + abc: string +}; + `, + output: ` +interface X { + a : number; + abc: string +}; + `, + options: [{ align: 'colon' }], + errors: [{ messageId: 'extraKey' }], + }, + { + code: ` +interface X { + a : number; + abc: string +}; + `, + output: ` +interface X { + a : number; + abc: string +}; + `, + options: [{ align: { on: 'colon' } }], + errors: [{ messageId: 'extraKey' }], + }, + { + code: ` +interface X { + a : number; + abc: string +}; + `, + output: ` +interface X { + a : number; + abc : string +}; + `, + options: [{ align: 'colon', beforeColon: true, afterColon: true }], + errors: [{ messageId: 'missingKey' }], + }, + // no align + { + code: ` +interface X { + [x: number]: string; +} + `, + output: ` +interface X { + [x: number]: string; +} + `, + errors: [{ messageId: 'extraValue' }], + }, + { + code: ` +interface X { + [x: number]:string; +} + `, + output: ` +interface X { + [x: number]: string; +} + `, + errors: [{ messageId: 'missingValue' }], + }, + // singleLine / multiLine + { + code: ` +interface X { + a:number; + abc:string +}; + `, + output: ` +interface X { + a : number; + abc : string +}; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + errors: [ + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + ], + }, + { + code: ` +interface X { a : number; abc : string; }; + `, + output: ` +interface X { a:number; abc:string; }; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: false }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + errors: [ + { messageId: 'extraKey' }, + { messageId: 'extraValue' }, + { messageId: 'extraKey' }, + { messageId: 'extraValue' }, + ], + }, + { + code: ` +interface X { a : number; abc : string; }; + `, + output: ` +interface X { a: number; abc: string; }; + `, + options: [ + { + singleLine: { beforeColon: false, afterColon: true }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + errors: [{ messageId: 'extraKey' }, { messageId: 'extraKey' }], + }, + { + code: ` +interface X { a:number; abc:string; }; + `, + output: ` +interface X { a : number; abc : string; }; + `, + options: [ + { + singleLine: { beforeColon: true, afterColon: true, mode: 'strict' }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + errors: [ + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + ], + }, + { + code: ` +interface X { a:number; abc: string; }; + `, + output: ` +interface X { a : number; abc : string; }; + `, + options: [ + { + singleLine: { beforeColon: true, afterColon: true, mode: 'minimum' }, + multiLine: { beforeColon: true, afterColon: true }, + }, + ], + errors: [ + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + { messageId: 'missingKey' }, + ], + }, + { + code: ` +interface X { a : number; abc : string; }; + `, + output: ` +interface X { a:number; abc:string; }; + `, + options: [ + { + beforeColon: false, + afterColon: false, + }, + ], + errors: [ + { messageId: 'extraKey' }, + { messageId: 'extraValue' }, + { messageId: 'extraKey' }, + { messageId: 'extraValue' }, + ], + }, + { + code: ` +interface X { a:number; abc:string; }; + `, + output: ` +interface X { a : number; abc : string; }; + `, + options: [ + { + beforeColon: true, + afterColon: true, + mode: 'strict', + }, + ], + errors: [ + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + { messageId: 'missingKey' }, + { messageId: 'missingValue' }, + ], + }, + { + code: ` +type Wacky = { + a: number; + b: string; + agc: number; + middle: Date | { + inner: { + a: boolean; + bc: boolean; + "🌷": "rose"; + } + [x: number]: string; + abc: boolean; + } +} & { + a: "string"; + abc: number; +} + `, + output: ` +type Wacky = { + a: number; + b: string; + agc: number; + middle: Date | { + inner: { + a: boolean; + bc: boolean; + "🌷": "rose"; + } + [x: number]: string; + abc: boolean; + } +} & { + a: "string"; + abc: number; +} + `, + options: [{ align: 'value' }], + errors: [ + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + ], + }, + { + code: ` +class Wacky { + a: number; + b?: string; + public z: number; + abc = 10; + private override xy: number; + static x = "test"; + static abcdef: number = 1; + get fn(): number { return 0; }; + inter: number; + get fn2(): number { + return 1; + }; + agc: number; + middle: Date | { + inner: { + a: boolean; + bc: boolean; + "🌷": "rose"; + } + [x: number]: string; + abc: boolean; + } +} + `, + output: ` +class Wacky { + a: number; + b?: string; + public z: number; + abc = 10; + private override xy: number; + static x = "test"; + static abcdef: number = 1; + get fn(): number { return 0; }; + inter: number; + get fn2(): number { + return 1; + }; + agc: number; + middle: Date | { + inner: { + a: boolean; + bc: boolean; + "🌷": "rose"; + } + [x: number]: string; + abc: boolean; + } +} + `, + options: [{ align: 'value' }], + errors: [ + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + { messageId: 'missingValue' }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts b/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts index 9917aec3cb7..b55ce321f00 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts @@ -867,6 +867,29 @@ ruleTester.run('naming-convention', rule, { }, ], }, + { + code: ` + class foo { + private someAttribute = 1; + #some_attribute = 1; + + private someMethod() {} + #some_method() {} + } + `, + parserOptions, + options: [ + { + selector: 'memberLike', + format: ['camelCase'], + }, + { + selector: ['memberLike'], + modifiers: ['#private'], + format: ['snake_case'], + }, + ], + }, ], invalid: [ { @@ -1972,5 +1995,89 @@ ruleTester.run('naming-convention', rule, { }, ], }, + { + code: ` + class foo { + private firstPrivateField = 1; + // ❌ error + private first_private_field = 1; + // ❌ error + #secondPrivateField = 1; + #second_private_field = 1; + } + `, + parserOptions, + options: [ + { + selector: 'memberLike', + format: ['camelCase'], + }, + { + selector: ['memberLike'], + modifiers: ['#private'], + format: ['snake_case'], + }, + ], + errors: [ + { + messageId: 'doesNotMatchFormat', + data: { + type: 'Class Property', + name: 'first_private_field', + formats: 'camelCase', + }, + }, + { + messageId: 'doesNotMatchFormat', + data: { + type: 'Class Property', + name: 'secondPrivateField', + formats: 'snake_case', + }, + }, + ], + }, + { + code: ` + class foo { + private firstPrivateMethod() {} + // ❌ error + private first_private_method() {} + // ❌ error + #secondPrivateMethod() {} + #second_private_method() {} + } + `, + parserOptions, + options: [ + { + selector: 'memberLike', + format: ['camelCase'], + }, + { + selector: ['memberLike'], + modifiers: ['#private'], + format: ['snake_case'], + }, + ], + errors: [ + { + messageId: 'doesNotMatchFormat', + data: { + type: 'Class Method', + name: 'first_private_method', + formats: 'camelCase', + }, + }, + { + messageId: 'doesNotMatchFormat', + data: { + type: 'Class Method', + name: 'secondPrivateMethod', + formats: 'snake_case', + }, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts b/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts new file mode 100644 index 00000000000..9dade06a943 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts @@ -0,0 +1,44 @@ +import rule from '../../src/rules/no-import-type-side-effects'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('no-import-type-side-effects', rule, { + valid: [ + "import T from 'mod';", + "import * as T from 'mod';", + "import { T } from 'mod';", + "import type { T } from 'mod';", + "import type { T, U } from 'mod';", + "import { type T, U } from 'mod';", + "import { T, type U } from 'mod';", + "import type T from 'mod';", + "import type T, { U } from 'mod';", + "import T, { type U } from 'mod';", + "import type * as T from 'mod';", + ], + invalid: [ + { + code: "import { type A } from 'mod';", + output: "import type { A } from 'mod';", + errors: [{ messageId: 'useTopLevelQualifier' }], + }, + { + code: "import { type A as AA } from 'mod';", + output: "import type { A as AA } from 'mod';", + errors: [{ messageId: 'useTopLevelQualifier' }], + }, + { + code: "import { type A, type B } from 'mod';", + output: "import type { A, B } from 'mod';", + errors: [{ messageId: 'useTopLevelQualifier' }], + }, + { + code: "import { type A as AA, type B as BB } from 'mod';", + output: "import type { A as AA, B as BB } from 'mod';", + errors: [{ messageId: 'useTopLevelQualifier' }], + }, + ], +}); diff --git a/packages/eslint-plugin/tests/rules/prefer-optional-chain/base-cases.ts b/packages/eslint-plugin/tests/rules/prefer-optional-chain/base-cases.ts new file mode 100644 index 00000000000..99cfe6b0ff9 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/prefer-optional-chain/base-cases.ts @@ -0,0 +1,228 @@ +import type { TSESLint } from '@typescript-eslint/utils'; + +import type rule from '../../../src/rules/prefer-optional-chain'; +import type { + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule, +} from '../../../src/util'; + +type InvalidTestCase = TSESLint.InvalidTestCase< + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule +>; + +interface BaseCase { + canReplaceAndWithOr: boolean; + output: string; + code: string; +} + +const mapper = (c: BaseCase): InvalidTestCase => ({ + code: c.code.trim(), + output: null, + errors: [ + { + messageId: 'preferOptionalChain', + suggestions: [ + { + messageId: 'optionalChainSuggest', + output: c.output.trim(), + }, + ], + }, + ], +}); + +const baseCases: Array = [ + // chained members + { + code: 'foo && foo.bar', + output: 'foo?.bar', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz', + output: 'foo.bar?.baz', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo()', + output: 'foo?.()', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar()', + output: 'foo.bar?.()', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz', + output: 'foo?.bar?.baz?.buzz', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz && foo.bar.baz.buzz', + output: 'foo.bar?.baz?.buzz', + canReplaceAndWithOr: true, + }, + // case with a jump (i.e. a non-nullish prop) + { + code: 'foo && foo.bar && foo.bar.baz.buzz', + output: 'foo?.bar?.baz.buzz', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz.buzz', + output: 'foo.bar?.baz.buzz', + canReplaceAndWithOr: true, + }, + // case where for some reason there is a doubled up expression + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz && foo.bar.baz.buzz', + output: 'foo?.bar?.baz?.buzz', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz && foo.bar.baz && foo.bar.baz.buzz', + output: 'foo.bar?.baz?.buzz', + canReplaceAndWithOr: true, + }, + // chained members with element access + { + code: 'foo && foo[bar] && foo[bar].baz && foo[bar].baz.buzz', + output: 'foo?.[bar]?.baz?.buzz', + canReplaceAndWithOr: true, + }, + { + // case with a jump (i.e. a non-nullish prop) + code: 'foo && foo[bar].baz && foo[bar].baz.buzz', + output: 'foo?.[bar].baz?.buzz', + canReplaceAndWithOr: true, + }, + // case with a property access in computed property + { + code: 'foo && foo[bar.baz] && foo[bar.baz].buzz', + output: 'foo?.[bar.baz]?.buzz', + canReplaceAndWithOr: true, + }, + // case with this keyword + { + code: 'foo[this.bar] && foo[this.bar].baz', + output: 'foo[this.bar]?.baz', + canReplaceAndWithOr: true, + }, + // chained calls + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz()', + output: 'foo?.bar?.baz?.buzz()', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz && foo.bar.baz.buzz()', + output: 'foo?.bar?.baz?.buzz?.()', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz && foo.bar.baz.buzz && foo.bar.baz.buzz()', + output: 'foo.bar?.baz?.buzz?.()', + canReplaceAndWithOr: true, + }, + // case with a jump (i.e. a non-nullish prop) + { + code: 'foo && foo.bar && foo.bar.baz.buzz()', + output: 'foo?.bar?.baz.buzz()', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar.baz.buzz()', + output: 'foo.bar?.baz.buzz()', + canReplaceAndWithOr: true, + }, + { + // case with a jump (i.e. a non-nullish prop) + code: 'foo && foo.bar && foo.bar.baz.buzz && foo.bar.baz.buzz()', + output: 'foo?.bar?.baz.buzz?.()', + canReplaceAndWithOr: true, + }, + { + // case with a call expr inside the chain for some inefficient reason + code: 'foo && foo.bar() && foo.bar().baz && foo.bar().baz.buzz && foo.bar().baz.buzz()', + output: 'foo?.bar()?.baz?.buzz?.()', + canReplaceAndWithOr: true, + }, + // chained calls with element access + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz[buzz]()', + output: 'foo?.bar?.baz?.[buzz]()', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz[buzz] && foo.bar.baz[buzz]()', + output: 'foo?.bar?.baz?.[buzz]?.()', + canReplaceAndWithOr: true, + }, + // (partially) pre-optional chained + { + code: 'foo && foo?.bar && foo?.bar.baz && foo?.bar.baz[buzz] && foo?.bar.baz[buzz]()', + output: 'foo?.bar?.baz?.[buzz]?.()', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo?.bar.baz && foo?.bar.baz[buzz]', + output: 'foo?.bar.baz?.[buzz]', + canReplaceAndWithOr: true, + }, + { + code: 'foo && foo?.() && foo?.().bar', + output: 'foo?.()?.bar', + canReplaceAndWithOr: true, + }, + { + code: 'foo.bar && foo.bar?.() && foo.bar?.().baz', + output: 'foo.bar?.()?.baz', + canReplaceAndWithOr: true, + }, + { + code: 'foo !== null && foo.bar !== null', + output: 'foo?.bar != null', + canReplaceAndWithOr: false, + }, + { + code: 'foo != null && foo.bar != null', + output: 'foo?.bar != null', + canReplaceAndWithOr: false, + }, + { + code: 'foo != null && foo.bar !== null', + output: 'foo?.bar != null', + canReplaceAndWithOr: false, + }, + { + code: 'foo !== null && foo.bar != null', + output: 'foo?.bar != null', + canReplaceAndWithOr: false, + }, +]; + +interface Selector { + all(): Array; + select>( + key: K, + value: BaseCase[K], + ): Selector; +} + +const selector = (cases: Array): Selector => ({ + all: () => cases.map(mapper), + select: >( + key: K, + value: BaseCase[K], + ): Selector => { + const selectedCases = baseCases.filter(c => c[key] === value); + return selector(selectedCases); + }, +}); + +const { all, select } = selector(baseCases); + +export { all, select }; diff --git a/packages/eslint-plugin/tests/rules/prefer-optional-chain.test.ts b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts similarity index 85% rename from packages/eslint-plugin/tests/rules/prefer-optional-chain.test.ts rename to packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts index 120ad20aaea..a18de12bf7b 100644 --- a/packages/eslint-plugin/tests/rules/prefer-optional-chain.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts @@ -1,160 +1,11 @@ -import type { TSESLint } from '@typescript-eslint/utils'; - -import rule from '../../src/rules/prefer-optional-chain'; -import type { - InferMessageIdsTypeFromRule, - InferOptionsTypeFromRule, -} from '../../src/util'; -import { noFormat, RuleTester } from '../RuleTester'; +import rule from '../../../src/rules/prefer-optional-chain'; +import { noFormat, RuleTester } from '../../RuleTester'; +import * as BaseCases from './base-cases'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -const baseCases = [ - // chained members - { - code: 'foo && foo.bar', - output: 'foo?.bar', - }, - { - code: 'foo.bar && foo.bar.baz', - output: 'foo.bar?.baz', - }, - { - code: 'foo && foo()', - output: 'foo?.()', - }, - { - code: 'foo.bar && foo.bar()', - output: 'foo.bar?.()', - }, - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz', - output: 'foo?.bar?.baz?.buzz', - }, - { - code: 'foo.bar && foo.bar.baz && foo.bar.baz.buzz', - output: 'foo.bar?.baz?.buzz', - }, - // case with a jump (i.e. a non-nullish prop) - { - code: 'foo && foo.bar && foo.bar.baz.buzz', - output: 'foo?.bar?.baz.buzz', - }, - { - code: 'foo.bar && foo.bar.baz.buzz', - output: 'foo.bar?.baz.buzz', - }, - // case where for some reason there is a doubled up expression - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz && foo.bar.baz.buzz', - output: 'foo?.bar?.baz?.buzz', - }, - { - code: 'foo.bar && foo.bar.baz && foo.bar.baz && foo.bar.baz.buzz', - output: 'foo.bar?.baz?.buzz', - }, - // chained members with element access - { - code: 'foo && foo[bar] && foo[bar].baz && foo[bar].baz.buzz', - output: 'foo?.[bar]?.baz?.buzz', - }, - { - // case with a jump (i.e. a non-nullish prop) - code: 'foo && foo[bar].baz && foo[bar].baz.buzz', - output: 'foo?.[bar].baz?.buzz', - }, - // case with a property access in computed property - { - code: 'foo && foo[bar.baz] && foo[bar.baz].buzz', - output: 'foo?.[bar.baz]?.buzz', - }, - // case with this keyword - { - code: 'foo[this.bar] && foo[this.bar].baz', - output: 'foo[this.bar]?.baz', - }, - // chained calls - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz()', - output: 'foo?.bar?.baz?.buzz()', - }, - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz.buzz && foo.bar.baz.buzz()', - output: 'foo?.bar?.baz?.buzz?.()', - }, - { - code: 'foo.bar && foo.bar.baz && foo.bar.baz.buzz && foo.bar.baz.buzz()', - output: 'foo.bar?.baz?.buzz?.()', - }, - // case with a jump (i.e. a non-nullish prop) - { - code: 'foo && foo.bar && foo.bar.baz.buzz()', - output: 'foo?.bar?.baz.buzz()', - }, - { - code: 'foo.bar && foo.bar.baz.buzz()', - output: 'foo.bar?.baz.buzz()', - }, - { - // case with a jump (i.e. a non-nullish prop) - code: 'foo && foo.bar && foo.bar.baz.buzz && foo.bar.baz.buzz()', - output: 'foo?.bar?.baz.buzz?.()', - }, - { - // case with a call expr inside the chain for some inefficient reason - code: 'foo && foo.bar() && foo.bar().baz && foo.bar().baz.buzz && foo.bar().baz.buzz()', - output: 'foo?.bar()?.baz?.buzz?.()', - }, - // chained calls with element access - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz[buzz]()', - output: 'foo?.bar?.baz?.[buzz]()', - }, - { - code: 'foo && foo.bar && foo.bar.baz && foo.bar.baz[buzz] && foo.bar.baz[buzz]()', - output: 'foo?.bar?.baz?.[buzz]?.()', - }, - // (partially) pre-optional chained - { - code: 'foo && foo?.bar && foo?.bar.baz && foo?.bar.baz[buzz] && foo?.bar.baz[buzz]()', - output: 'foo?.bar?.baz?.[buzz]?.()', - }, - { - code: 'foo && foo?.bar.baz && foo?.bar.baz[buzz]', - output: 'foo?.bar.baz?.[buzz]', - }, - { - code: 'foo && foo?.() && foo?.().bar', - output: 'foo?.()?.bar', - }, - { - code: 'foo.bar && foo.bar?.() && foo.bar?.().baz', - output: 'foo.bar?.()?.baz', - }, -].map( - c => - ({ - code: c.code.trim(), - output: null, - errors: [ - { - messageId: 'preferOptionalChain', - suggestions: [ - { - messageId: 'optionalChainSuggest', - output: c.output.trim(), - }, - ], - }, - ], - } as TSESLint.InvalidTestCase< - InferMessageIdsTypeFromRule, - InferOptionsTypeFromRule - >), -); - ruleTester.run('prefer-optional-chain', rule, { valid: [ '!a || !b;', @@ -194,6 +45,16 @@ ruleTester.run('prefer-optional-chain', rule, { 'match && match$1 !== undefined;', 'foo !== null && foo !== undefined;', "x['y'] !== undefined && x['y'] !== null;", + // private properties + 'this.#a && this.#b;', + '!this.#a || !this.#b;', + 'a.#foo?.bar;', + '!a.#foo?.bar;', + '!foo().#a || a;', + '!a.b.#a || a;', + '!new A().#b || a;', + '!(await a).#b || a;', + "!(foo as any).bar || 'anything';", // currently do not handle complex computed properties 'foo && foo[bar as string] && foo[bar as string].baz;', 'foo && foo[1 + 2] && foo[1 + 2].baz;', @@ -217,20 +78,24 @@ ruleTester.run('prefer-optional-chain', rule, { '!import.meta && !import.meta.foo;', 'new.target || new.target.length;', '!new.target || true;', + // Do not handle direct optional chaining on private properties because of a typescript bug (https://github.com/microsoft/TypeScript/issues/42734) + // We still allow in computed properties + 'foo && foo.#bar;', + '!foo || !foo.#bar;', ], invalid: [ - ...baseCases, + ...BaseCases.all(), // it should ignore whitespace in the expressions - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/\./g, '. '), })), - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/\./g, '.\n'), })), // it should ignore parts of the expression that aren't part of the expression chain - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: `${c.code} && bing`, errors: [ @@ -245,7 +110,7 @@ ruleTester.run('prefer-optional-chain', rule, { }, ], })), - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: `${c.code} && bing.bong`, errors: [ @@ -261,22 +126,42 @@ ruleTester.run('prefer-optional-chain', rule, { ], })), // strict nullish equality checks x !== null && x.y !== null - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/&&/g, '!== null &&'), })), - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/&&/g, '!= null &&'), })), - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/&&/g, '!== undefined &&'), })), - ...baseCases.map(c => ({ + ...BaseCases.all().map(c => ({ ...c, code: c.code.replace(/&&/g, '!= undefined &&'), })), + + // replace && with ||: foo && foo.bar -> !foo || !foo.bar + ...BaseCases.select('canReplaceAndWithOr', true) + .all() + .map(c => ({ + ...c, + code: c.code.replace(/(^|\s)foo/g, '$1!foo').replace(/&&/g, '||'), + errors: [ + { + ...c.errors[0], + suggestions: [ + { + ...c.errors[0].suggestions![0], + output: `!${c.errors[0].suggestions![0].output}`, + }, + ], + }, + ], + })), + // two errors { code: noFormat`foo && foo.bar && foo.bar.baz || baz && baz.bar && baz.bar.foo`, @@ -1211,21 +1096,6 @@ foo?.bar(/* comment */a, }, ], }, - ...baseCases.map(c => ({ - ...c, - code: c.code.replace(/foo/g, '!foo').replace(/&&/g, '||'), - errors: [ - { - ...c.errors[0], - suggestions: [ - { - ...c.errors[0].suggestions![0], - output: `!${c.errors[0].suggestions![0].output}`, - }, - ], - }, - ], - })), // case with this keyword at the start of expression { code: '!this.bar || !this.bar.baz;', @@ -1384,7 +1254,6 @@ foo?.bar(/* comment */a, }, ], }, - { code: noFormat`import.meta && import.meta?.() && import.meta?.().baz;`, output: null, diff --git a/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts b/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts index 82a25e2f472..c9fe331c99d 100644 --- a/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts @@ -1083,7 +1083,7 @@ function addOptional< function makeOptional(code: string): string; function makeOptional(code: string | null | undefined): string | null; function makeOptional(code: string | null | undefined): string | null { - if (code === null || code === undefined) { + if (code == null) { return null; } return ( diff --git a/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts index 1aa6f8a6c9a..42f9ab8153a 100644 --- a/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts @@ -359,6 +359,7 @@ type T = 1 | string | {} | A; }, ], }, + "type A = string | (T extends number ? 'hi' : 'there');", ], invalid: [ ...invalid('|'), @@ -376,5 +377,18 @@ type T = 1 | string | {} | A; }, ], }, + { + output: "type A = string | (T extends number ? 'hi' : 'there');", + code: "type A = (T extends number ? 'hi' : 'there') | string;", + errors: [ + { + messageId: 'notSortedNamed', + data: { + type: 'Union', + name: 'A', + }, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 53deb3aa1bb..7801773b539 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -10,12 +10,5 @@ { "path": "../parser/tsconfig.build.json" }, { "path": "../scope-manager/tsconfig.build.json" }, { "path": "../type-utils/tsconfig.build.json" } - ], - "ts-node": { - "compilerOptions": { - "module": "ESNext" - }, - "files": true, - "transpileOnly": true - } + ] } diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 09b54ae4a51..38682f60c5b 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -141,6 +141,58 @@ declare module 'eslint/lib/rules/indent' { export = rule; } +declare module 'eslint/lib/rules/key-spacing' { + import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; + import type { RuleFunction } from '@typescript-eslint/utils/dist/ts-eslint'; + + type Options = [ + { + beforeColon?: boolean; + afterColon?: boolean; + mode?: 'strict' | 'minimum'; + align?: + | 'value' + | 'colon' + | { + on?: 'value' | 'colon'; + beforeColon?: boolean; + afterColon?: boolean; + mode?: 'strict' | 'minimum'; + }; + singleLine?: { + beforeColon?: boolean; + afterColon?: boolean; + mode?: 'strict' | 'minimum'; + }; + multiLine?: { + beforeColon?: boolean; + afterColon?: boolean; + mode?: 'strict' | 'minimum'; + align?: + | 'value' + | 'colon' + | { + on?: 'value' | 'colon'; + beforeColon?: boolean; + afterColon?: boolean; + mode?: 'strict' | 'minimum'; + }; + }; + }, + ]; + type MessageIds = 'extraKey' | 'extraValue' | 'missingKey' | 'missingValue'; + + const rule: TSESLint.RuleModule< + MessageIds, + Options, + { + ObjectExpression: RuleFunction; + Property: RuleFunction; + } + >; + export = rule; +} + declare module 'eslint/lib/rules/keyword-spacing' { import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import type { RuleFunction } from '@typescript-eslint/utils/dist/ts-eslint'; diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index e523d92e652..a11333dc15c 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/README.md b/packages/experimental-utils/README.md index d1468f928b1..a285229f638 100644 --- a/packages/experimental-utils/README.md +++ b/packages/experimental-utils/README.md @@ -19,4 +19,4 @@ You should switch to importing from that non-experimental package instead. ## Contributing -[See the contributing guide here](../../CONTRIBUTING.md) +[See the contributing guide here](https://typescript-eslint.io). diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 856659150c0..e3d44a14dfe 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "5.48.2", + "version": "5.50.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/utils": "5.48.2" + "@typescript-eslint/utils": "5.50.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index d7fb9b8cf70..8dd79a4e7d1 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 158d680deb8..72b9df7a210 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "5.48.2", + "version": "5.50.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -45,9 +45,9 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/typescript-estree": "5.50.0", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index da3bfbc639d..4243c56c73e 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/scope-manager + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/scope-manager + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/scope-manager diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index d47002cc6d5..afa72f7662a 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "5.48.2", + "version": "5.50.0", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -38,12 +38,12 @@ "typecheck": "nx typecheck" }, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2" + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/visitor-keys": "5.50.0" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/typescript-estree": "5.50.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/scope-manager/project.json b/packages/scope-manager/project.json index 9d4a6c37c9a..9694ae86163 100644 --- a/packages/scope-manager/project.json +++ b/packages/scope-manager/project.json @@ -69,9 +69,7 @@ "options": { "parallel": false, "cwd": "packages/scope-manager", - "commands": [ - "../../node_modules/.bin/ts-node --files --transpile-only tools/generate-lib.ts" - ] + "commands": ["yarn tsx tools/generate-lib.ts"] } } }, diff --git a/packages/scope-manager/src/ScopeManager.ts b/packages/scope-manager/src/ScopeManager.ts index 5368cca1dc3..7f4b2a5f705 100644 --- a/packages/scope-manager/src/ScopeManager.ts +++ b/packages/scope-manager/src/ScopeManager.ts @@ -140,7 +140,7 @@ class ScopeManager { protected nestScope(scope: T): T; protected nestScope(scope: Scope): Scope { if (scope instanceof GlobalScope) { - assert(this.currentScope === null); + assert(this.currentScope == null); this.globalScope = scope; } this.currentScope = scope; diff --git a/packages/scope-manager/src/referencer/ClassVisitor.ts b/packages/scope-manager/src/referencer/ClassVisitor.ts index 5f84e37404f..662b70813c8 100644 --- a/packages/scope-manager/src/referencer/ClassVisitor.ts +++ b/packages/scope-manager/src/referencer/ClassVisitor.ts @@ -163,7 +163,7 @@ class ClassVisitor extends Visitor { * } */ if ( - keyName !== null && + keyName != null && this.#classNode.body.body.find( (node): node is TSESTree.MethodDefinition => node !== methodNode && diff --git a/packages/scope-manager/src/referencer/PatternVisitor.ts b/packages/scope-manager/src/referencer/PatternVisitor.ts index 308c4c29208..53de28469e8 100644 --- a/packages/scope-manager/src/referencer/PatternVisitor.ts +++ b/packages/scope-manager/src/referencer/PatternVisitor.ts @@ -97,10 +97,7 @@ class PatternVisitor extends VisitorBase { this.#callback(pattern, { topLevel: pattern === this.#rootPattern, - rest: - lastRestElement !== null && - lastRestElement !== undefined && - lastRestElement.argument === pattern, + rest: lastRestElement != null && lastRestElement.argument === pattern, assignments: this.#assignments, }); } diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index e7b41127ba4..7a14de51df1 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -124,7 +124,7 @@ class Referencer extends Visitor { } private referenceJsxPragma(): void { - if (this.#jsxPragma === null || this.#hasReferencedJsxFactory) { + if (this.#jsxPragma == null || this.#hasReferencedJsxFactory) { return; } this.#hasReferencedJsxFactory = this.referenceInSomeUpperScope( @@ -134,7 +134,7 @@ class Referencer extends Visitor { private referenceJsxFragment(): void { if ( - this.#jsxFragmentName === null || + this.#jsxFragmentName == null || this.#hasReferencedJsxFragmentFactory ) { return; diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index a43e040edda..3548d5254c6 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index dc0877b239b..0e3d35976d4 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "description": "Code fixtures used to test the typescript-estree parser.", "name": "@typescript-eslint/shared-fixtures", - "version": "5.48.2", + "version": "5.50.0", "private": true } diff --git a/packages/shared-fixtures/project.json b/packages/shared-fixtures/project.json index 18cfac97135..412bca4935f 100644 --- a/packages/shared-fixtures/project.json +++ b/packages/shared-fixtures/project.json @@ -1,6 +1,6 @@ { + "name": "shared-fixtures", "$schema": "../../node_modules/nx/schemas/project-schema.json", "type": "library", - "implicitDependencies": [], - "name": "shared-fixtures" + "implicitDependencies": [] } diff --git a/packages/type-utils/CHANGELOG.md b/packages/type-utils/CHANGELOG.md index b53e13ae8c4..26f418c1436 100644 --- a/packages/type-utils/CHANGELOG.md +++ b/packages/type-utils/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/type-utils + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/type-utils + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/type-utils diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index c1d495285a1..2b44585a682 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/type-utils", - "version": "5.48.2", + "version": "5.50.0", "description": "Type utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -39,13 +39,13 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/typescript-estree": "5.48.2", - "@typescript-eslint/utils": "5.48.2", + "@typescript-eslint/typescript-estree": "5.50.0", + "@typescript-eslint/utils": "5.50.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, "devDependencies": { - "@typescript-eslint/parser": "5.48.2", + "@typescript-eslint/parser": "5.50.0", "typescript": "*" }, "peerDependencies": { diff --git a/packages/type-utils/tests/isTypeReadonly.test.ts b/packages/type-utils/tests/isTypeReadonly.test.ts index 382091a2375..0b171dc12a2 100644 --- a/packages/type-utils/tests/isTypeReadonly.test.ts +++ b/packages/type-utils/tests/isTypeReadonly.test.ts @@ -4,8 +4,8 @@ import path from 'path'; import type * as ts from 'typescript'; import { - type ReadonlynessOptions, isTypeReadonly, + type ReadonlynessOptions, } from '../src/isTypeReadonly'; describe('isTypeReadonly', () => { diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 05fa0254117..0cd6d24aa09 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/types diff --git a/packages/types/package.json b/packages/types/package.json index 9c81da261ee..ccc72bcd698 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "5.48.2", + "version": "5.50.0", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", @@ -29,13 +29,13 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { - "prebuild": "yarn ts-node --transpile-only ./tools/copy-ast-spec.ts", + "prebuild": "yarn tsx ./tools/copy-ast-spec.ts", "build": "tsc -b tsconfig.build.json", "postbuild": "downlevel-dts dist _ts3.4/dist", "clean": "tsc -b tsconfig.build.json --clean", "postclean": "rimraf dist && rimraf src/generated && rimraf _ts3.4 && rimraf coverage", "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore", - "generate:lib": "../../node_modules/.bin/ts-node --files --transpile-only ../scope-manager/tools/generate-lib.ts", + "generate:lib": "yarn tsx ../scope-manager/tools/generate-lib.ts", "lint": "nx lint", "typecheck": "tsc -p tsconfig.json --noEmit" }, diff --git a/packages/types/src/parser-options.ts b/packages/types/src/parser-options.ts index b3149231215..a7fe3ce3ab3 100644 --- a/packages/types/src/parser-options.ts +++ b/packages/types/src/parser-options.ts @@ -3,6 +3,7 @@ import type { Program } from 'typescript'; import type { Lib } from './lib'; type DebugLevel = boolean | ('typescript-eslint' | 'eslint' | 'typescript')[]; +type CacheDurationSeconds = number | 'Infinity'; type EcmaVersion = | 3 @@ -59,7 +60,17 @@ interface ParserOptions { tsconfigRootDir?: string; warnOnUnsupportedTypeScriptVersion?: boolean; moduleResolver?: string; + cacheLifetime?: { + glob?: CacheDurationSeconds; + }; + [additionalProperties: string]: unknown; } -export { DebugLevel, EcmaVersion, ParserOptions, SourceType }; +export { + CacheDurationSeconds, + DebugLevel, + EcmaVersion, + ParserOptions, + SourceType, +}; diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index fdeef706469..b74f9d0a82d 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + + +### Bug Fixes + +* **typescript-estree:** fix typo in FAQ link ([#6346](https://github.com/typescript-eslint/typescript-eslint/issues/6346)) ([eefc578](https://github.com/typescript-eslint/typescript-eslint/commit/eefc5781b0f455264e4e58e33c27f8a91b3ab5e3)) + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 89db7c8c611..728c8d417e9 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "5.48.2", + "version": "5.50.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -42,8 +42,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/visitor-keys": "5.50.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -59,7 +59,7 @@ "@types/is-glob": "*", "@types/semver": "*", "@types/tmp": "*", - "@typescript-eslint/shared-fixtures": "5.48.2", + "@typescript-eslint/shared-fixtures": "5.50.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index ea02be41276..d4dd9f124a7 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -22,7 +22,7 @@ export function convertComments( ast, (_, comment) => { const type = - comment.kind == ts.SyntaxKind.SingleLineCommentTrivia + comment.kind === ts.SyntaxKind.SingleLineCommentTrivia ? AST_TOKEN_TYPES.Line : AST_TOKEN_TYPES.Block; const range: TSESTree.Range = [comment.pos, comment.end]; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index b21a42614da..70ee9da4e0c 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -2183,7 +2183,7 @@ export class Converter { type: AST_NODE_TYPES.Literal, raw: rawValue, value: value, - bigint: value === null ? bigint : String(value), + bigint: value == null ? bigint : String(value), range, }); } diff --git a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts index 15d88e5f454..d9d4de9c833 100644 --- a/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts +++ b/packages/typescript-estree/src/create-program/getWatchProgramsForProjects.ts @@ -8,6 +8,7 @@ import type { CanonicalPath } from './shared'; import { canonicalDirname, createDefaultCompilerOptionsFromExtra, + createHash, getCanonicalFileName, getModuleResolver, } from './shared'; @@ -105,19 +106,6 @@ function diagnosticReporter(diagnostic: ts.Diagnostic): void { ); } -/** - * Hash content for compare content. - * @param content hashed contend - * @returns hashed result - */ -function createHash(content: string): string { - // No ts.sys in browser environments. - if (ts.sys?.createHash) { - return ts.sys.createHash(content); - } - return content; -} - function updateCachedFileList( tsconfigPath: CanonicalPath, program: ts.Program, diff --git a/packages/typescript-estree/src/create-program/shared.ts b/packages/typescript-estree/src/create-program/shared.ts index dd50f757dce..e8de9796928 100644 --- a/packages/typescript-estree/src/create-program/shared.ts +++ b/packages/typescript-estree/src/create-program/shared.ts @@ -124,12 +124,26 @@ function getModuleResolver(moduleResolverPath: string): ModuleResolver { return moduleResolver; } +/** + * Hash content for compare content. + * @param content hashed contend + * @returns hashed result + */ +function createHash(content: string): string { + // No ts.sys in browser environments. + if (ts.sys?.createHash) { + return ts.sys.createHash(content); + } + return content; +} + export { ASTAndProgram, CORE_COMPILER_OPTIONS, canonicalDirname, CanonicalPath, createDefaultCompilerOptionsFromExtra, + createHash, ensureAbsolutePath, getCanonicalFileName, getAstFromProgram, diff --git a/packages/typescript-estree/src/getModifiers.ts b/packages/typescript-estree/src/getModifiers.ts index d8f8e716f9e..a584a7659a7 100644 --- a/packages/typescript-estree/src/getModifiers.ts +++ b/packages/typescript-estree/src/getModifiers.ts @@ -31,7 +31,7 @@ export function getModifiers( export function getDecorators( node: ts.Node | null | undefined, ): undefined | ts.Decorator[] { - if (node == undefined) { + if (node == null) { return undefined; } diff --git a/packages/typescript-estree/src/parseSettings/ExpiringCache.ts b/packages/typescript-estree/src/parseSettings/ExpiringCache.ts new file mode 100644 index 00000000000..f296c9f5f59 --- /dev/null +++ b/packages/typescript-estree/src/parseSettings/ExpiringCache.ts @@ -0,0 +1,69 @@ +import type { CacheDurationSeconds } from '@typescript-eslint/types'; + +export const DEFAULT_TSCONFIG_CACHE_DURATION_SECONDS = 30; +const ZERO_HR_TIME: [number, number] = [0, 0]; + +/** + * A map with key-level expiration. + */ +export class ExpiringCache { + readonly #cacheDurationSeconds: CacheDurationSeconds; + /** + * The mapping of path-like string to the resolved TSConfig(s) + */ + protected readonly map = new Map< + TKey, + Readonly<{ + value: TValue; + lastSeen: [number, number]; + }> + >(); + + constructor(cacheDurationSeconds: CacheDurationSeconds) { + this.#cacheDurationSeconds = cacheDurationSeconds; + } + + set(key: TKey, value: TValue): this { + this.map.set(key, { + value, + lastSeen: + this.#cacheDurationSeconds === 'Infinity' + ? // no need to waste time calculating the hrtime in infinity mode as there's no expiry + ZERO_HR_TIME + : process.hrtime(), + }); + return this; + } + + get(key: TKey): TValue | undefined { + const entry = this.map.get(key); + if (entry?.value != null) { + if (this.#cacheDurationSeconds === 'Infinity') { + return entry.value; + } + + const ageSeconds = process.hrtime(entry.lastSeen)[0]; + if (ageSeconds < this.#cacheDurationSeconds) { + // cache hit woo! + return entry.value; + } else { + // key has expired - clean it up to free up memory + this.cleanupKey(key); + } + } + // no hit :'( + return undefined; + } + + protected cleanupKey(key: TKey): void { + this.map.delete(key); + } + + get size(): number { + return this.map.size; + } + + clear(): void { + this.map.clear(); + } +} diff --git a/packages/typescript-estree/src/parseSettings/createParseSettings.ts b/packages/typescript-estree/src/parseSettings/createParseSettings.ts index b1cde9d4c9a..e7267a85268 100644 --- a/packages/typescript-estree/src/parseSettings/createParseSettings.ts +++ b/packages/typescript-estree/src/parseSettings/createParseSettings.ts @@ -1,15 +1,10 @@ import debug from 'debug'; -import { sync as globSync } from 'globby'; -import isGlob from 'is-glob'; -import type { CanonicalPath } from '../create-program/shared'; -import { - ensureAbsolutePath, - getCanonicalFileName, -} from '../create-program/shared'; +import { ensureAbsolutePath } from '../create-program/shared'; import type { TSESTreeOptions } from '../parser-options'; import type { MutableParseSettings } from './index'; import { inferSingleRun } from './inferSingleRun'; +import { resolveProjectList } from './resolveProjectList'; import { warnAboutTSVersion } from './warnAboutTSVersion'; const log = debug( @@ -98,23 +93,13 @@ export function createParseSettings( // Providing a program overrides project resolution if (!parseSettings.programs) { - const projectFolderIgnoreList = ( - options.projectFolderIgnoreList ?? ['**/node_modules/**'] - ) - .reduce((acc, folder) => { - if (typeof folder === 'string') { - acc.push(folder); - } - return acc; - }, []) - // prefix with a ! for not match glob - .map(folder => (folder.startsWith('!') ? folder : `!${folder}`)); - - parseSettings.projects = prepareAndTransformProjects( - tsconfigRootDir, - options.project, - projectFolderIgnoreList, - ); + parseSettings.projects = resolveProjectList({ + cacheLifetime: options.cacheLifetime, + project: options.project, + projectFolderIgnoreList: options.projectFolderIgnoreList, + singleRun: parseSettings.singleRun, + tsconfigRootDir: tsconfigRootDir, + }); } warnAboutTSVersion(parseSettings); @@ -144,58 +129,3 @@ function enforceString(code: unknown): string { function getFileName(jsx?: boolean): string { return jsx ? 'estree.tsx' : 'estree.ts'; } - -function getTsconfigPath( - tsconfigPath: string, - tsconfigRootDir: string, -): CanonicalPath { - return getCanonicalFileName( - ensureAbsolutePath(tsconfigPath, tsconfigRootDir), - ); -} - -/** - * Normalizes, sanitizes, resolves and filters the provided project paths - */ -function prepareAndTransformProjects( - tsconfigRootDir: string, - projectsInput: string | string[] | undefined, - ignoreListInput: string[], -): CanonicalPath[] { - const sanitizedProjects: string[] = []; - - // Normalize and sanitize the project paths - if (typeof projectsInput === 'string') { - sanitizedProjects.push(projectsInput); - } else if (Array.isArray(projectsInput)) { - for (const project of projectsInput) { - if (typeof project === 'string') { - sanitizedProjects.push(project); - } - } - } - - if (sanitizedProjects.length === 0) { - return []; - } - - // Transform glob patterns into paths - const nonGlobProjects = sanitizedProjects.filter(project => !isGlob(project)); - const globProjects = sanitizedProjects.filter(project => isGlob(project)); - const uniqueCanonicalProjectPaths = new Set( - nonGlobProjects - .concat( - globSync([...globProjects, ...ignoreListInput], { - cwd: tsconfigRootDir, - }), - ) - .map(project => getTsconfigPath(project, tsconfigRootDir)), - ); - - log( - 'parserOptions.project (excluding ignored) matched projects: %s', - uniqueCanonicalProjectPaths, - ); - - return Array.from(uniqueCanonicalProjectPaths); -} diff --git a/packages/typescript-estree/src/parseSettings/index.ts b/packages/typescript-estree/src/parseSettings/index.ts index 0a9734d1b24..53b1acf4a6f 100644 --- a/packages/typescript-estree/src/parseSettings/index.ts +++ b/packages/typescript-estree/src/parseSettings/index.ts @@ -98,7 +98,7 @@ export interface MutableParseSettings { /** * Normalized paths to provided project paths. */ - projects: CanonicalPath[]; + projects: readonly CanonicalPath[]; /** * Whether to add the `range` property to AST nodes. diff --git a/packages/typescript-estree/src/parseSettings/resolveProjectList.ts b/packages/typescript-estree/src/parseSettings/resolveProjectList.ts new file mode 100644 index 00000000000..72e9539d2b9 --- /dev/null +++ b/packages/typescript-estree/src/parseSettings/resolveProjectList.ts @@ -0,0 +1,146 @@ +import debug from 'debug'; +import { sync as globSync } from 'globby'; +import isGlob from 'is-glob'; + +import type { CanonicalPath } from '../create-program/shared'; +import { + createHash, + ensureAbsolutePath, + getCanonicalFileName, +} from '../create-program/shared'; +import type { TSESTreeOptions } from '../parser-options'; +import { + DEFAULT_TSCONFIG_CACHE_DURATION_SECONDS, + ExpiringCache, +} from './ExpiringCache'; + +const log = debug( + 'typescript-eslint:typescript-estree:parser:parseSettings:resolveProjectList', +); + +let RESOLUTION_CACHE: ExpiringCache | null = + null; + +/** + * Normalizes, sanitizes, resolves and filters the provided project paths + */ +export function resolveProjectList( + options: Readonly<{ + cacheLifetime?: TSESTreeOptions['cacheLifetime']; + project: TSESTreeOptions['project']; + projectFolderIgnoreList: TSESTreeOptions['projectFolderIgnoreList']; + singleRun: boolean; + tsconfigRootDir: string; + }>, +): readonly CanonicalPath[] { + const sanitizedProjects: string[] = []; + + // Normalize and sanitize the project paths + if (typeof options.project === 'string') { + sanitizedProjects.push(options.project); + } else if (Array.isArray(options.project)) { + for (const project of options.project) { + if (typeof project === 'string') { + sanitizedProjects.push(project); + } + } + } + + if (sanitizedProjects.length === 0) { + return []; + } + + const projectFolderIgnoreList = ( + options.projectFolderIgnoreList ?? ['**/node_modules/**'] + ) + .reduce((acc, folder) => { + if (typeof folder === 'string') { + acc.push(folder); + } + return acc; + }, []) + // prefix with a ! for not match glob + .map(folder => (folder.startsWith('!') ? folder : `!${folder}`)); + + const cacheKey = getHash({ + project: sanitizedProjects, + projectFolderIgnoreList, + tsconfigRootDir: options.tsconfigRootDir, + }); + if (RESOLUTION_CACHE == null) { + // note - we initialize the global cache based on the first config we encounter. + // this does mean that you can't have multiple lifetimes set per folder + // I doubt that anyone will really bother reconfiguring this, let alone + // try to do complicated setups, so we'll deal with this later if ever. + RESOLUTION_CACHE = new ExpiringCache( + options.singleRun + ? 'Infinity' + : options.cacheLifetime?.glob ?? + DEFAULT_TSCONFIG_CACHE_DURATION_SECONDS, + ); + } else { + const cached = RESOLUTION_CACHE.get(cacheKey); + if (cached) { + return cached; + } + } + + // Transform glob patterns into paths + const nonGlobProjects = sanitizedProjects.filter(project => !isGlob(project)); + const globProjects = sanitizedProjects.filter(project => isGlob(project)); + + const uniqueCanonicalProjectPaths = new Set( + nonGlobProjects + .concat( + globProjects.length === 0 + ? [] + : globSync([...globProjects, ...projectFolderIgnoreList], { + cwd: options.tsconfigRootDir, + }), + ) + .map(project => + getCanonicalFileName( + ensureAbsolutePath(project, options.tsconfigRootDir), + ), + ), + ); + + log( + 'parserOptions.project (excluding ignored) matched projects: %s', + uniqueCanonicalProjectPaths, + ); + + const returnValue = Array.from(uniqueCanonicalProjectPaths); + RESOLUTION_CACHE.set(cacheKey, returnValue); + return returnValue; +} + +function getHash({ + project, + projectFolderIgnoreList, + tsconfigRootDir, +}: Readonly<{ + project: readonly string[]; + projectFolderIgnoreList: readonly string[]; + tsconfigRootDir: string; +}>): string { + // create a stable representation of the config + const hashObject = { + tsconfigRootDir, + // the project order does matter and can impact the resolved globs + project, + // the ignore order won't doesn't ever matter + projectFolderIgnoreList: [...projectFolderIgnoreList].sort(), + }; + + return createHash(JSON.stringify(hashObject)); +} + +/** + * Exported for testing purposes only + * @internal + */ +export function clearGlobResolutionCache(): void { + RESOLUTION_CACHE?.clear(); + RESOLUTION_CACHE = null; +} diff --git a/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts b/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts index 191ac029325..13eef19e796 100644 --- a/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts +++ b/packages/typescript-estree/src/parseSettings/warnAboutTSVersion.ts @@ -3,7 +3,7 @@ import * as ts from 'typescript'; import type { ParseSettings } from './index'; /** - * This needs to be kept in sync with /docs/maintenance/VERSIONING.md + * This needs to be kept in sync with /docs/maintenance/Versioning.md * in the typescript-eslint monorepo */ const SUPPORTED_TYPESCRIPT_VERSIONS = '>=3.3.1 <5.0.0'; diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index 632d9e6ae88..8cfe3c934c2 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -1,4 +1,7 @@ -import type { DebugLevel } from '@typescript-eslint/types'; +import type { + CacheDurationSeconds, + DebugLevel, +} from '@typescript-eslint/types'; import type * as ts from 'typescript'; import type { TSESTree, TSESTreeToTSNode, TSNode, TSToken } from './ts-estree'; @@ -168,6 +171,25 @@ interface ParseAndGenerateServicesOptions extends ParseOptions { */ allowAutomaticSingleRunInference?: boolean; + /** + * Granular control of the expiry lifetime of our internal caches. + * You can specify the number of seconds as an integer number, or the string + * 'Infinity' if you never want the cache to expire. + * + * By default cache entries will be evicted after 30 seconds, or will persist + * indefinitely if `allowAutomaticSingleRunInference = true` AND the parser + * infers that it is a single run. + */ + cacheLifetime?: { + /** + * Glob resolution for `parserOptions.project` values. + */ + glob?: CacheDurationSeconds; + }; + + /** + * Path to a file exporting a custom `ModuleResolver`. + */ moduleResolver?: string; } diff --git a/packages/typescript-estree/src/simple-traverse.ts b/packages/typescript-estree/src/simple-traverse.ts index 13c763ec228..2d51cdbe4fa 100644 --- a/packages/typescript-estree/src/simple-traverse.ts +++ b/packages/typescript-estree/src/simple-traverse.ts @@ -5,7 +5,7 @@ import type { TSESTree } from './ts-estree'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function isValidNode(x: any): x is TSESTree.Node { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - return x !== null && typeof x === 'object' && typeof x.type === 'string'; + return x != null && typeof x === 'object' && typeof x.type === 'string'; } function getVisitorKeysForNode( diff --git a/packages/typescript-estree/tests/lib/parse.test.ts b/packages/typescript-estree/tests/lib/parse.test.ts index 3e84dd3e069..0f286efdb19 100644 --- a/packages/typescript-estree/tests/lib/parse.test.ts +++ b/packages/typescript-estree/tests/lib/parse.test.ts @@ -1,10 +1,14 @@ +import type { CacheDurationSeconds } from '@typescript-eslint/types'; import debug from 'debug'; +import * as globbyModule from 'globby'; import { join, resolve } from 'path'; +import type * as typescriptModule from 'typescript'; import * as parser from '../../src'; import * as astConverterModule from '../../src/ast-converter'; import * as sharedParserUtilsModule from '../../src/create-program/shared'; import type { TSESTreeOptions } from '../../src/parser-options'; +import { clearGlobResolutionCache } from '../../src/parseSettings/resolveProjectList'; import { createSnapshotTestBlock } from '../../tools/test-utils'; const FIXTURES_DIR = join(__dirname, '../fixtures/simpleProject'); @@ -38,7 +42,7 @@ jest.mock('../../src/create-program/shared', () => { // Tests in CI by default run with lowercase program file names, // resulting in path.relative results starting with many "../"s jest.mock('typescript', () => { - const ts = jest.requireActual('typescript'); + const ts = jest.requireActual('typescript'); return { ...ts, sys: { @@ -48,10 +52,21 @@ jest.mock('typescript', () => { }; }); +jest.mock('globby', () => { + const globby = jest.requireActual('globby'); + return { + ...globby, + sync: jest.fn(globby.sync), + }; +}); + +const hrtimeSpy = jest.spyOn(process, 'hrtime'); + const astConverterMock = jest.mocked(astConverterModule.astConverter); const createDefaultCompilerOptionsFromExtra = jest.mocked( sharedParserUtilsModule.createDefaultCompilerOptionsFromExtra, ); +const globbySyncMock = jest.mocked(globbyModule.sync); /** * Aligns paths between environments, node for windows uses `\`, for linux and mac uses `/` @@ -63,6 +78,7 @@ function alignErrorPath(error: Error): never { beforeEach(() => { jest.clearAllMocks(); + clearGlobResolutionCache(); }); describe('parseWithNodeMaps()', () => { @@ -749,8 +765,69 @@ describe('parseAndGenerateServices', () => { it('ignores a folder when given a string glob', () => { const ignore = ['**/ignoreme/**']; + // cspell:disable-next-line expect(testParse('ignoreme', ignore)).toThrow(); + // cspell:disable-next-line expect(testParse('includeme', ignore)).not.toThrow(); }); }); + + describe('cacheLifetime', () => { + describe('glob', () => { + function doParse(lifetime: CacheDurationSeconds): void { + parser.parseAndGenerateServices('const x = 1', { + cacheLifetime: { + glob: lifetime, + }, + filePath: join(FIXTURES_DIR, 'file.ts'), + tsconfigRootDir: FIXTURES_DIR, + project: ['./**/tsconfig.json', './**/tsconfig.extra.json'], + }); + } + + it('should cache globs if the lifetime is non-zero', () => { + doParse(30); + expect(globbySyncMock).toHaveBeenCalledTimes(1); + doParse(30); + // shouldn't call globby again due to the caching + expect(globbySyncMock).toHaveBeenCalledTimes(1); + }); + + it('should not cache globs if the lifetime is zero', () => { + doParse(0); + expect(globbySyncMock).toHaveBeenCalledTimes(1); + doParse(0); + // should call globby again because we specified immediate cache expiry + expect(globbySyncMock).toHaveBeenCalledTimes(2); + }); + + it('should evict the cache if the entry expires', () => { + hrtimeSpy.mockReturnValueOnce([1, 0]); + + doParse(30); + expect(globbySyncMock).toHaveBeenCalledTimes(1); + + // wow so much time has passed + hrtimeSpy.mockReturnValueOnce([Number.MAX_VALUE, 0]); + + doParse(30); + // shouldn't call globby again due to the caching + expect(globbySyncMock).toHaveBeenCalledTimes(2); + }); + + it('should infinitely cache if passed Infinity', () => { + hrtimeSpy.mockReturnValueOnce([1, 0]); + + doParse('Infinity'); + expect(globbySyncMock).toHaveBeenCalledTimes(1); + + // wow so much time has passed + hrtimeSpy.mockReturnValueOnce([Number.MAX_VALUE, 0]); + + doParse('Infinity'); + // shouldn't call globby again due to the caching + expect(globbySyncMock).toHaveBeenCalledTimes(1); + }); + }); + }); }); diff --git a/packages/typescript-estree/tests/lib/semanticInfo-singleRun.test.ts b/packages/typescript-estree/tests/lib/semanticInfo-singleRun.test.ts index 33daa30a13f..b605dd6ea5f 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo-singleRun.test.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo-singleRun.test.ts @@ -2,6 +2,7 @@ import glob from 'glob'; import * as path from 'path'; import { getCanonicalFileName } from '../../src/create-program/shared'; +import { createProgramFromConfigFile as createProgramFromConfigFileOriginal } from '../../src/create-program/useProvidedPrograms'; import { clearParseAndGenerateServicesCalls, clearProgramCache, @@ -69,9 +70,9 @@ jest.mock('../../src/create-program/getWatchProgramsForProjects', () => { }; }); -const { - createProgramFromConfigFile, -} = require('../../src/create-program/useProvidedPrograms'); +const createProgramFromConfigFile = jest.mocked( + createProgramFromConfigFileOriginal, +); const FIXTURES_DIR = './tests/fixtures/semanticInfo'; const testFiles = glob.sync(`**/*.src.ts`, { @@ -97,7 +98,7 @@ describe('semanticInfo - singleRun', () => { // ensure caches are clean for each test clearProgramCache(); // ensure invocations of mock are clean for each test - (createProgramFromConfigFile as jest.Mock).mockClear(); + createProgramFromConfigFile.mockClear(); // Do not track invocations per file across tests clearParseAndGenerateServicesCalls(); }); @@ -232,7 +233,7 @@ describe('semanticInfo - singleRun', () => { const optionsWithReversedTsconfigs = { ...options, // Now the matching tsconfig comes first - project: options.project.reverse(), + project: [...options.project].reverse(), }; const resultProgram = parseAndGenerateServices( @@ -248,7 +249,7 @@ describe('semanticInfo - singleRun', () => { expect(createProgramFromConfigFile).toHaveBeenNthCalledWith( 1, - resolvedProject(tsconfigs[0]), + resolvedProject(tsconfigs[1]), ); // Restore process data diff --git a/packages/typescript-estree/tools/test-utils.ts b/packages/typescript-estree/tools/test-utils.ts index 6f40b597ca7..aef5601ebe2 100644 --- a/packages/typescript-estree/tools/test-utils.ts +++ b/packages/typescript-estree/tools/test-utils.ts @@ -92,7 +92,7 @@ type UnknownObject = Record; function isObjectLike(value: unknown | null): value is UnknownObject { return ( - typeof value === 'object' && !(value instanceof RegExp) && value !== null + typeof value === 'object' && !(value instanceof RegExp) && value != null ); } diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 4e845751401..ec49364f3e7 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/utils + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/utils + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/utils diff --git a/packages/utils/package.json b/packages/utils/package.json index a6e266b5638..13e83257c67 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "5.48.2", + "version": "5.50.0", "description": "Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -41,9 +41,9 @@ "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/typescript-estree": "5.50.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -52,7 +52,7 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "devDependencies": { - "@typescript-eslint/parser": "5.48.2", + "@typescript-eslint/parser": "5.50.0", "typescript": "*" }, "funding": { diff --git a/packages/utils/src/ast-utils/predicates.ts b/packages/utils/src/ast-utils/predicates.ts index 6a65cab7625..36e08ee5c42 100644 --- a/packages/utils/src/ast-utils/predicates.ts +++ b/packages/utils/src/ast-utils/predicates.ts @@ -139,6 +139,20 @@ const isAwaitKeyword = isTokenOfTypeWithConditions(AST_TOKEN_TYPES.Identifier, { value: 'await', }); +/** + * Checks if a possible token is the `type` keyword. + */ +const isTypeKeyword = isTokenOfTypeWithConditions(AST_TOKEN_TYPES.Identifier, { + value: 'type', +}); + +/** + * Checks if a possible token is the `import` keyword. + */ +const isImportKeyword = isTokenOfTypeWithConditions(AST_TOKEN_TYPES.Keyword, { + value: 'import', +}); + const isLoop = isNodeOfTypes([ AST_NODE_TYPES.DoWhileStatement, AST_NODE_TYPES.ForStatement, @@ -156,6 +170,7 @@ export { isFunctionOrFunctionType, isFunctionType, isIdentifier, + isImportKeyword, isLoop, isLogicalOrOperator, isNonNullAssertionPunctuator, @@ -167,5 +182,6 @@ export { isTSConstructorType, isTSFunctionType, isTypeAssertion, + isTypeKeyword, isVariableDeclarator, }; diff --git a/packages/utils/src/eslint-utils/applyDefault.ts b/packages/utils/src/eslint-utils/applyDefault.ts index 85cd3b3653b..f16ae798715 100644 --- a/packages/utils/src/eslint-utils/applyDefault.ts +++ b/packages/utils/src/eslint-utils/applyDefault.ts @@ -16,7 +16,7 @@ function applyDefault( JSON.stringify(defaultOptions), ) as AsMutable; - if (userOptions === null || userOptions === undefined) { + if (userOptions == null) { return options; } diff --git a/packages/utils/src/eslint-utils/nullThrows.ts b/packages/utils/src/eslint-utils/nullThrows.ts index df644c2befb..1a79b2e09d4 100644 --- a/packages/utils/src/eslint-utils/nullThrows.ts +++ b/packages/utils/src/eslint-utils/nullThrows.ts @@ -18,7 +18,7 @@ function nullThrows(value: T | null | undefined, message: string): T { // so ignore it in coverage metrics. /* istanbul ignore if */ - if (value === null || value === undefined) { + if (value == null) { throw new Error(`Non-null Assertion Failed: ${message}`); } diff --git a/packages/utils/src/ts-eslint/SourceCode.ts b/packages/utils/src/ts-eslint/SourceCode.ts index 447c9debedb..a44cdee3676 100644 --- a/packages/utils/src/ts-eslint/SourceCode.ts +++ b/packages/utils/src/ts-eslint/SourceCode.ts @@ -389,10 +389,25 @@ namespace SourceCode { } export type FilterPredicate = (token: TSESTree.Token) => boolean; + export type GetFilterPredicate = + // https://github.com/prettier/prettier/issues/14275 + // prettier-ignore + TFilter extends (( + token: TSESTree.Token, + ) => token is infer U extends TSESTree.Token) + ? U + : TDefault; + export type GetFilterPredicateFromOptions = + TOptions extends { filter?: FilterPredicate } + ? GetFilterPredicate + : GetFilterPredicate; export type ReturnTypeFromOptions = T extends { includeComments: true } - ? TSESTree.Token - : Exclude; + ? GetFilterPredicateFromOptions + : GetFilterPredicateFromOptions< + T, + Exclude + >; export type CursorWithSkipOptions = | number diff --git a/packages/utils/tests/eslint-utils/nullThrows.test.ts b/packages/utils/tests/eslint-utils/nullThrows.test.ts new file mode 100644 index 00000000000..7997fecaa6d --- /dev/null +++ b/packages/utils/tests/eslint-utils/nullThrows.test.ts @@ -0,0 +1,31 @@ +import { nullThrows, NullThrowsReasons } from '../../src/eslint-utils'; + +describe('nullThrows', () => { + it('returns a falsy value when it exists', () => { + const value = 0; + + const actual = nullThrows(value, NullThrowsReasons.MissingParent); + + expect(actual).toBe(value); + }); + + it('returns a truthy value when it exists', () => { + const value = { abc: 'def' }; + + const actual = nullThrows(value, NullThrowsReasons.MissingParent); + + expect(actual).toBe(value); + }); + + it('throws an error when the value is null', () => { + expect(() => nullThrows(null, NullThrowsReasons.MissingParent)).toThrow( + NullThrowsReasons.MissingParent, + ); + }); + + it('throws an error when the value is undefined', () => { + expect(() => + nullThrows(undefined, NullThrowsReasons.MissingParent), + ).toThrow(NullThrowsReasons.MissingParent); + }); +}); diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index 702c037410c..a7c260ce870 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/visitor-keys diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index f182435ffaa..14527dc3f80 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "5.48.2", + "version": "5.50.0", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "keywords": [ "eslint", @@ -39,7 +39,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.48.2", + "@typescript-eslint/types": "5.50.0", "eslint-visitor-keys": "^3.3.0" }, "devDependencies": { diff --git a/packages/website-eslint/CHANGELOG.md b/packages/website-eslint/CHANGELOG.md index 5f592d724ee..ea36b42047a 100644 --- a/packages/website-eslint/CHANGELOG.md +++ b/packages/website-eslint/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package @typescript-eslint/website-eslint + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package @typescript-eslint/website-eslint + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package @typescript-eslint/website-eslint diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 743c8ccd515..6bb1f6d3f90 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/website-eslint", - "version": "5.48.2", + "version": "5.50.0", "private": true, "description": "ESLint which works in browsers.", "engines": { @@ -16,19 +16,19 @@ "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore" }, "dependencies": { - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/utils": "5.48.2" + "@typescript-eslint/types": "5.50.0", + "@typescript-eslint/utils": "5.50.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^23.0.0", "@rollup/plugin-json": "^5.0.0", "@rollup/plugin-node-resolve": "^15.0.0", "@rollup/pluginutils": "^5.0.0", - "@typescript-eslint/eslint-plugin": "5.48.2", - "@typescript-eslint/parser": "5.48.2", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", - "@typescript-eslint/visitor-keys": "5.48.2", + "@typescript-eslint/eslint-plugin": "5.50.0", + "@typescript-eslint/parser": "5.50.0", + "@typescript-eslint/scope-manager": "5.50.0", + "@typescript-eslint/typescript-estree": "5.50.0", + "@typescript-eslint/visitor-keys": "5.50.0", "eslint": "*", "rollup": "^2.75.4", "rollup-plugin-terser": "^7.0.2", diff --git a/packages/website-eslint/project.json b/packages/website-eslint/project.json index 517439cbec3..862c5b948f1 100644 --- a/packages/website-eslint/project.json +++ b/packages/website-eslint/project.json @@ -1,6 +1,6 @@ { + "name": "website-eslint", "$schema": "../../node_modules/nx/schemas/project-schema.json", "type": "library", - "implicitDependencies": [], - "name": "website-eslint" + "implicitDependencies": [] } diff --git a/packages/website/CHANGELOG.md b/packages/website/CHANGELOG.md index 85e5fb0e5ef..547367d081f 100644 --- a/packages/website/CHANGELOG.md +++ b/packages/website/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.50.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.49.0...v5.50.0) (2023-01-31) + +**Note:** Version bump only for package website + + + + + +# [5.49.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.2...v5.49.0) (2023-01-23) + +**Note:** Version bump only for package website + + + + + ## [5.48.2](https://github.com/typescript-eslint/typescript-eslint/compare/v5.48.1...v5.48.2) (2023-01-16) **Note:** Version bump only for package website diff --git a/packages/website/data/sponsors.json b/packages/website/data/sponsors.json index e026d1389ef..f7c3f749e9d 100644 --- a/packages/website/data/sponsors.json +++ b/packages/website/data/sponsors.json @@ -10,30 +10,44 @@ "id": "Nx (by Nrwl)", "image": "https://images.opencollective.com/nx/0efbe42/logo.png", "name": "Nx (by Nrwl)", - "totalDonations": 600000, + "totalDonations": 625000, "website": "https://nx.dev" }, { "id": "ESLint", "image": "https://images.opencollective.com/eslint/96b09dc/logo.png", "name": "ESLint", - "totalDonations": 245000, + "totalDonations": 260000, "website": "https://eslint.org/" }, + { + "id": "Hugging Face", + "image": "https://images.opencollective.com/huggingface/5c934ee/logo.png", + "name": "Hugging Face", + "totalDonations": 200000, + "website": "https://huggingface.co" + }, { "id": "Airbnb", "image": "https://images.opencollective.com/airbnb/d327d66/logo.png", "name": "Airbnb", - "totalDonations": 150800, + "totalDonations": 155800, "website": "https://www.airbnb.com/" }, { "id": "GitBook", "image": "https://images.opencollective.com/gitbook/d35a8e7/logo.png", "name": "GitBook", - "totalDonations": 130000, + "totalDonations": 140000, "website": "https://www.gitbook.com" }, + { + "id": "Codecademy", + "image": "https://images.opencollective.com/codecademy/d56a48d/logo.png", + "name": "Codecademy", + "totalDonations": 130000, + "website": "https://codecademy.com" + }, { "id": "n8n.io - n8n GmbH", "image": "https://images.opencollective.com/n8n/dca2f0c/logo.png", @@ -48,13 +62,6 @@ "totalDonations": 120000, "website": "https://blog.coinbase.com/engineering-and-security/home" }, - { - "id": "Codecademy", - "image": "https://images.opencollective.com/codecademy/d56a48d/logo.png", - "name": "Codecademy", - "totalDonations": 120000, - "website": "https://codecademy.com" - }, { "id": "Sentry", "image": "https://images.opencollective.com/sentry/9620d33/logo.png", @@ -73,9 +80,16 @@ "id": "Sourcegraph", "image": "https://images.opencollective.com/sourcegraph/67e40ff/logo.png", "name": "Sourcegraph", - "totalDonations": 70000, + "totalDonations": 80000, "website": "https://about.sourcegraph.com" }, + { + "id": "Codiga", + "image": "https://images.opencollective.com/codiga/1065f9f/logo.png", + "name": "Codiga", + "totalDonations": 60000, + "website": "https://www.codiga.io" + }, { "id": "Future Processing", "image": "https://images.opencollective.com/future-processing/1410d26/logo.png", @@ -83,13 +97,6 @@ "totalDonations": 54000, "website": "https://www.future-processing.com/" }, - { - "id": "Codiga", - "image": "https://images.opencollective.com/codiga/1065f9f/logo.png", - "name": "Codiga", - "totalDonations": 50000, - "website": "https://www.codiga.io" - }, { "id": "Whitebox", "image": "https://images.opencollective.com/whiteboxinc/ef0d11d/logo.png", @@ -101,7 +108,7 @@ "id": "STORIS", "image": "https://images.opencollective.com/storis/dfb0e13/logo.png", "name": "STORIS", - "totalDonations": 30000, + "totalDonations": 31500, "website": "https://www.storis.com/" }, { @@ -111,6 +118,13 @@ "totalDonations": 30000, "website": "https://www.monito.com" }, + { + "id": "DeepSource", + "image": "https://images.opencollective.com/deepsource/0f18cea/logo.png", + "name": "DeepSource", + "totalDonations": 30000, + "website": "https://deepsource.io/" + }, { "id": "revo.js", "image": "https://images.opencollective.com/revojsro/82623a7/logo.png", @@ -126,17 +140,17 @@ "website": "https://twitter.com/nevir" }, { - "id": "DeepSource", - "image": "https://images.opencollective.com/deepsource/0f18cea/logo.png", - "name": "DeepSource", + "id": "tRPC", + "image": "https://images.opencollective.com/trpc/82704a8/logo.png", + "name": "tRPC", "totalDonations": 20000, - "website": "https://deepsource.io/" + "website": "https://trpc.io" }, { "id": "David Johnston", "image": "https://images.opencollective.com/blacksheepcode/976d69a/avatar.png", "name": "David Johnston", - "totalDonations": 16000, + "totalDonations": 16500, "website": "https://blacksheepcode.com" }, { @@ -157,14 +171,14 @@ "id": "Evil Martians", "image": "https://images.opencollective.com/evilmartians/707ab4d/logo.png", "name": "Evil Martians", - "totalDonations": 11000, + "totalDonations": 11500, "website": "https://evilmartians.com/" }, { "id": "Balsa", "image": "https://images.opencollective.com/balsa/77de498/logo.png", "name": "Balsa", - "totalDonations": 11000, + "totalDonations": 11500, "website": "https://balsa.com" }, { @@ -187,19 +201,5 @@ "name": "Laserhub", "totalDonations": 10000, "website": "https://laserhub.com/" - }, - { - "id": "tRPC", - "image": "https://images.opencollective.com/trpc/82704a8/logo.png", - "name": "tRPC", - "totalDonations": 10000, - "website": "https://trpc.io" - }, - { - "id": "Hugging Face", - "image": "https://images.opencollective.com/huggingface/5c934ee/logo.png", - "name": "Hugging Face", - "totalDonations": 10000, - "website": "https://huggingface.co" } ] diff --git a/packages/website/docusaurusConfig.ts b/packages/website/docusaurusConfig.ts index bfa844fc2f0..ab543e80783 100644 --- a/packages/website/docusaurusConfig.ts +++ b/packages/website/docusaurusConfig.ts @@ -76,7 +76,7 @@ const themeConfig: ThemeCommonConfig & AlgoliaThemeConfig = { items: [ { to: 'getting-started/', - label: 'Getting started', + label: 'Docs', position: 'left', }, { diff --git a/packages/website/package.json b/packages/website/package.json index 3905e9fc46d..8f4ee2b74aa 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "website", - "version": "5.48.2", + "version": "5.50.0", "private": true, "scripts": { "build": "docusaurus build", @@ -21,8 +21,8 @@ "@docusaurus/remark-plugin-npm2yarn": "~2.2.0", "@docusaurus/theme-common": "~2.2.0", "@mdx-js/react": "1.6.22", - "@typescript-eslint/parser": "5.48.2", - "@typescript-eslint/website-eslint": "5.48.2", + "@typescript-eslint/parser": "5.50.0", + "@typescript-eslint/website-eslint": "5.50.0", "clsx": "^1.1.1", "eslint": "*", "json-schema": "^0.4.0", @@ -48,7 +48,7 @@ "@types/react": "^18.0.9", "@types/react-helmet": "^6.1.5", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "5.48.2", + "@typescript-eslint/eslint-plugin": "5.50.0", "copy-webpack-plugin": "^11.0.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.29.4", diff --git a/packages/website/sidebars/sidebar.base.js b/packages/website/sidebars/sidebar.base.js index e6e7401727f..2a097b02a70 100644 --- a/packages/website/sidebars/sidebar.base.js +++ b/packages/website/sidebars/sidebar.base.js @@ -37,19 +37,6 @@ module.exports = { type: 'category', }, 'custom-rules', - { - items: [ - 'contributing/issues', - 'contributing/local-development', - 'contributing/pull-requests', - ], - label: 'Contributing', - link: { - id: 'contributing', - type: 'doc', - }, - type: 'category', - }, { items: [ 'architecture/eslint-plugin', @@ -66,6 +53,20 @@ module.exports = { }, type: 'category', }, + { + items: [ + 'contributing/discussions', + 'contributing/issues', + 'contributing/local-development', + 'contributing/pull-requests', + ], + label: 'Contributing', + link: { + id: 'contributing', + type: 'doc', + }, + type: 'category', + }, { items: [ 'maintenance/branding', @@ -81,7 +82,16 @@ module.exports = { }, 'maintenance/pull-requests', 'maintenance/releases', - 'maintenance/versioning', + { + collapsible: false, + items: ['maintenance/versioning/dependant-version-upgrades'], + label: 'Versioning', + link: { + id: 'maintenance/versioning', + type: 'doc', + }, + type: 'category', + }, ], label: 'Maintenance', link: { diff --git a/packages/website/src/components/FinancialContributors/Sponsor.tsx b/packages/website/src/components/FinancialContributors/Sponsor.tsx index 06f53dd438f..c50ab89b609 100644 --- a/packages/website/src/components/FinancialContributors/Sponsor.tsx +++ b/packages/website/src/components/FinancialContributors/Sponsor.tsx @@ -1,17 +1,17 @@ import React from 'react'; import styles from './styles.module.css'; -import type { SponsorData, SponsorIncludeOptions } from './types'; +import type { SponsorData } from './types'; interface SponsorProps { - include?: SponsorIncludeOptions; + includeName?: boolean; sponsor: SponsorData; } -export function Sponsor({ include = {}, sponsor }: SponsorProps): JSX.Element { +export function Sponsor({ includeName, sponsor }: SponsorProps): JSX.Element { let children = {`${sponsor.name}; - if (include.name) { + if (includeName) { children = ( <> {children} @@ -20,19 +20,15 @@ export function Sponsor({ include = {}, sponsor }: SponsorProps): JSX.Element { ); } - if (include.link) { - children = ( - - {children} - - ); - } - - return children; + return ( + + {children} + + ); } diff --git a/packages/website/src/components/FinancialContributors/Sponsors/index.tsx b/packages/website/src/components/FinancialContributors/Sponsors/index.tsx index dfcdad8c7b9..6c2d8874593 100644 --- a/packages/website/src/components/FinancialContributors/Sponsors/index.tsx +++ b/packages/website/src/components/FinancialContributors/Sponsors/index.tsx @@ -2,12 +2,12 @@ import clsx from 'clsx'; import React from 'react'; import { Sponsor } from '../Sponsor'; -import type { SponsorData, SponsorIncludeOptions } from '../types'; +import type { SponsorData } from '../types'; import styles from './styles.module.css'; interface SponsorsProps { className: string; - include?: SponsorIncludeOptions; + includeName?: boolean; expanded?: boolean; sponsors: SponsorData[]; title: string; @@ -16,7 +16,7 @@ interface SponsorsProps { export function Sponsors({ className, - include, + includeName, title, tier, sponsors, @@ -27,7 +27,7 @@ export function Sponsors({
    {sponsors.map(sponsor => (
  • - +
  • ))}
diff --git a/packages/website/src/components/FinancialContributors/Sponsors/styles.module.css b/packages/website/src/components/FinancialContributors/Sponsors/styles.module.css index b92051eddcb..526e1ab745e 100644 --- a/packages/website/src/components/FinancialContributors/Sponsors/styles.module.css +++ b/packages/website/src/components/FinancialContributors/Sponsors/styles.module.css @@ -82,7 +82,6 @@ .tierArea { margin: 16px 0; width: auto; - padding: 0 60px; } .tier-gold-supporter { diff --git a/packages/website/src/components/FinancialContributors/index.tsx b/packages/website/src/components/FinancialContributors/index.tsx index d71bd065004..0460e1e8694 100644 --- a/packages/website/src/components/FinancialContributors/index.tsx +++ b/packages/website/src/components/FinancialContributors/index.tsx @@ -16,14 +16,13 @@ export function FinancialContributors(): JSX.Element {
-

{description}

+ {description}
{ - await page.goto('/'); - await new AxeBuilder({ page }).analyze(); +test.describe('Website', () => { + test('Axe', async ({ page }) => { + await page.goto('/'); + await new AxeBuilder({ page }).analyze(); + }); + + test('should have no errors', async ({ page }) => { + const errorMessages: string[] = []; + page.on('console', msg => { + if (['error', 'warning'].includes(msg.type())) { + errorMessages.push(`[${msg.type()}] ${msg.text()}`); + } + }); + await page.goto('/'); + expect(errorMessages).toStrictEqual([ + "[error] Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot", + ]); + }); }); diff --git a/yarn.lock b/yarn.lock index 2d237c3ce2c..1c5ec83ed4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -441,10 +441,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@*", "@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.8", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2", "@babel/parser@^7.20.3": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" - integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== +"@babel/parser@*", "@babel/parser@^7.1.0", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.8", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2", "@babel/parser@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" + integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -1966,6 +1966,40 @@ url-loader "^4.1.1" webpack "^5.73.0" +"@esbuild-kit/cjs-loader@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.1.tgz#5c1183ac3906223f0da3bb4ff5b74d0f0b13c326" + integrity sha512-lhc/XLith28QdW0HpHZvZKkorWgmCNT7sVelMHDj3HFdTfdqkwEKvT+aXVQtNAmCC39VJhunDkWhONWB7335mg== + dependencies: + "@esbuild-kit/core-utils" "^3.0.0" + get-tsconfig "^4.2.0" + +"@esbuild-kit/core-utils@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@esbuild-kit/core-utils/-/core-utils-3.0.0.tgz#e0f8463a32b4a9c9b456a7f9c31a5e038c8d2c19" + integrity sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ== + dependencies: + esbuild "~0.15.10" + source-map-support "^0.5.21" + +"@esbuild-kit/esm-loader@^2.5.0": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@esbuild-kit/esm-loader/-/esm-loader-2.5.4.tgz#cd31fe93963f3e21b1c1d07eef2bd2df1b574326" + integrity sha512-afmtLf6uqxD5IgwCzomtqCYIgz/sjHzCWZFvfS5+FzeYxOURPUo4QcHtqJxbxWOMOogKriZanN/1bJQE/ZL93A== + dependencies: + "@esbuild-kit/core-utils" "^3.0.0" + get-tsconfig "^4.2.0" + +"@esbuild/android-arm@0.15.18": + version "0.15.18" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80" + integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw== + +"@esbuild/linux-loong64@0.15.18": + version "0.15.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" + integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ== + "@eslint/eslintrc@^1.2.3": version "1.2.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.3.tgz#fcaa2bcef39e13d6e9e7f6271f4cc7cae1174886" @@ -2288,39 +2322,39 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@lerna/add@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-6.4.0.tgz#47f09f693da750063820b728330c8be40caabde1" - integrity sha512-xLsYRqfF4l78wLcOGCeiYw/YCBwRlX76+PAvLTD//7f4o8Xygowp1Uqb+a4n2oWmvDlilHiTxs424oTds6n75w== +"@lerna/add@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-6.4.1.tgz#fa20fe9ff875dc5758141262c8cde0d9a6481ec4" + integrity sha512-YSRnMcsdYnQtQQK0NSyrS9YGXvB3jzvx183o+JTH892MKzSlBqwpBHekCknSibyxga1HeZ0SNKQXgsHAwWkrRw== dependencies: - "@lerna/bootstrap" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/npm-conf" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/bootstrap" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/npm-conf" "6.4.1" + "@lerna/validation-error" "6.4.1" dedent "^0.7.0" npm-package-arg "8.1.1" p-map "^4.0.0" pacote "^13.6.1" semver "^7.3.4" -"@lerna/bootstrap@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-6.4.0.tgz#eaff82b2026f9897c70935506e2518c725df41f9" - integrity sha512-tgaFJDitwtwAO2kWIdcOWYjcLb6VdEZpakcDPMRICfCyKpcPQ62OYGkjMASzDhgkdJE0wgWRJKBoPUKUVc1I5w== - dependencies: - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/has-npm-version" "6.4.0" - "@lerna/npm-install" "6.4.0" - "@lerna/package-graph" "6.4.0" - "@lerna/pulse-till-done" "6.4.0" - "@lerna/rimraf-dir" "6.4.0" - "@lerna/run-lifecycle" "6.4.0" - "@lerna/run-topologically" "6.4.0" - "@lerna/symlink-binary" "6.4.0" - "@lerna/symlink-dependencies" "6.4.0" - "@lerna/validation-error" "6.4.0" +"@lerna/bootstrap@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-6.4.1.tgz#a76ff22c3160d134fb60bcfddb3f8b0759b4f1ff" + integrity sha512-64cm0mnxzxhUUjH3T19ZSjPdn28vczRhhTXhNAvOhhU0sQgHrroam1xQC1395qbkV3iosSertlu8e7xbXW033w== + dependencies: + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/has-npm-version" "6.4.1" + "@lerna/npm-install" "6.4.1" + "@lerna/package-graph" "6.4.1" + "@lerna/pulse-till-done" "6.4.1" + "@lerna/rimraf-dir" "6.4.1" + "@lerna/run-lifecycle" "6.4.1" + "@lerna/run-topologically" "6.4.1" + "@lerna/symlink-binary" "6.4.1" + "@lerna/symlink-dependencies" "6.4.1" + "@lerna/validation-error" "6.4.1" "@npmcli/arborist" "5.3.0" dedent "^0.7.0" get-port "^5.1.1" @@ -2332,100 +2366,100 @@ p-waterfall "^2.1.1" semver "^7.3.4" -"@lerna/changed@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-6.4.0.tgz#c2e47a172ade68a5a582d8224df6f9a7002fefae" - integrity sha512-9LJ3bb64xNi+XsUnb1KrVSvJybU4+UQmT5rSI/f3UpwLKjKNJuqauFnLgy1S0fWq4Lvd6H5W8BJOYiLJtaUiFw== +"@lerna/changed@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-6.4.1.tgz#4da6d08df7c53bc90c0c0d9d04839f91dd6d70a9" + integrity sha512-Z/z0sTm3l/iZW0eTSsnQpcY5d6eOpNO0g4wMOK+hIboWG0QOTc8b28XCnfCUO+33UisKl8PffultgoaHMKkGgw== dependencies: - "@lerna/collect-updates" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/listable" "6.4.0" - "@lerna/output" "6.4.0" + "@lerna/collect-updates" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/listable" "6.4.1" + "@lerna/output" "6.4.1" -"@lerna/check-working-tree@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-6.4.0.tgz#e9babfdff4b6d7efcf6470ed6281d7a44c7f7b4e" - integrity sha512-8CHlAoOCg6rmay1vzQYQccozsozlSdYUxJ6D7jZxMBHoDVMHSxS0q3efOkzCj3EsAOzf5TuOhVB8T2ms8/ckQw== +"@lerna/check-working-tree@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-6.4.1.tgz#c0dcb5c474faf214865058e2fedda44962367a4e" + integrity sha512-EnlkA1wxaRLqhJdn9HX7h+JYxqiTK9aWEFOPqAE8lqjxHn3RpM9qBp1bAdL7CeUk3kN1lvxKwDEm0mfcIyMbPA== dependencies: - "@lerna/collect-uncommitted" "6.4.0" - "@lerna/describe-ref" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/collect-uncommitted" "6.4.1" + "@lerna/describe-ref" "6.4.1" + "@lerna/validation-error" "6.4.1" -"@lerna/child-process@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.4.0.tgz#09738b47430f6c33f259a04b46ebbf28e116f544" - integrity sha512-5lNIjdHMx0G32TCLhwb1B4htH1utKP05lE+SeICUz03GFjQQw6UukCnoUf0Ae8ROsisXCwTFjiNxRxdnEcXTfA== +"@lerna/child-process@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.4.1.tgz#d697fb769f4c5b57c59f87471eb9b3d65be904a3" + integrity sha512-dvEKK0yKmxOv8pccf3I5D/k+OGiLxQp5KYjsrDtkes2pjpCFfQAMbmpol/Tqx6w/2o2rSaRrLsnX8TENo66FsA== dependencies: chalk "^4.1.0" execa "^5.0.0" strong-log-transformer "^2.1.0" -"@lerna/clean@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-6.4.0.tgz#0243d21e0b66d40ebf3a8d112c9462d7fe5a0a0c" - integrity sha512-NG3qbcTemcvI4RFF0sjwENCFHZivbbbFwo+Y+Y3IRFl3h6g6FF3GGByIizK/ZyKIeB/xpdisF9Ck0rums4J1Sg== +"@lerna/clean@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-6.4.1.tgz#e9ee365ee6879ee998b78b3269fad02b5f385771" + integrity sha512-FuVyW3mpos5ESCWSkQ1/ViXyEtsZ9k45U66cdM/HnteHQk/XskSQw0sz9R+whrZRUDu6YgYLSoj1j0YAHVK/3A== dependencies: - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/prompt" "6.4.0" - "@lerna/pulse-till-done" "6.4.0" - "@lerna/rimraf-dir" "6.4.0" + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/prompt" "6.4.1" + "@lerna/pulse-till-done" "6.4.1" + "@lerna/rimraf-dir" "6.4.1" p-map "^4.0.0" p-map-series "^2.1.0" p-waterfall "^2.1.1" -"@lerna/cli@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-6.4.0.tgz#51e6f341c34f333c8d8fd1002060b5468b34d134" - integrity sha512-HYLDKEM1flTkJEGRiWFP/kOnXnvcJUNV0vlWoJbmUCPZFsSGCVEQvSshrwPxF2hABYi1m/UgHhGbWkbRUcH11Q== +"@lerna/cli@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-6.4.1.tgz#2b2d093baace40e822caee8c90f698e98a437a2f" + integrity sha512-2pNa48i2wzFEd9LMPKWI3lkW/3widDqiB7oZUM1Xvm4eAOuDWc9I3RWmAUIVlPQNf3n4McxJCvsZZ9BpQN50Fg== dependencies: - "@lerna/global-options" "6.4.0" + "@lerna/global-options" "6.4.1" dedent "^0.7.0" npmlog "^6.0.2" yargs "^16.2.0" -"@lerna/collect-uncommitted@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-6.4.0.tgz#8e0477d4b0922e1fd2396c0a26dea38f91a9c236" - integrity sha512-TLL4YXgf39R/DODvsGgKIYO91ebmZlQnthA84yDnZXnEN0cCmOCEHTgvIeWFFV3UrxAUbW3ChcccwVeiWiakhA== +"@lerna/collect-uncommitted@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-6.4.1.tgz#ae62bcaa5ecaa5b7fbc41eb9ae90b6711be156ec" + integrity sha512-5IVQGhlLrt7Ujc5ooYA1Xlicdba/wMcDSnbQwr8ufeqnzV2z4729pLCVk55gmi6ZienH/YeBPHxhB5u34ofE0Q== dependencies: - "@lerna/child-process" "6.4.0" + "@lerna/child-process" "6.4.1" chalk "^4.1.0" npmlog "^6.0.2" -"@lerna/collect-updates@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-6.4.0.tgz#da19018e73ab4b10a6d057796a2261e4a93803fd" - integrity sha512-szBOZCq5TiIKgdlQ/bPrvWm4DTVamHvOLdsCtx/Kp+W/2gioJL1ds7+PouJaPlQ8g7uMf5iP6s9tOxxiB459ug== +"@lerna/collect-updates@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-6.4.1.tgz#4f7cf1c411f3253d0104e7b64cb0aa315a5dfc81" + integrity sha512-pzw2/FC+nIqYkknUHK9SMmvP3MsLEjxI597p3WV86cEDN3eb1dyGIGuHiKShtjvT08SKSwpTX+3bCYvLVxtC5Q== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/describe-ref" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/describe-ref" "6.4.1" minimatch "^3.0.4" npmlog "^6.0.2" slash "^3.0.0" -"@lerna/command@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-6.4.0.tgz#218ea11cc3f4969d727ab5fd6ffa9242cb439f0c" - integrity sha512-aToAXY79oqnQqob0043PJ+Ae56f/XADIRpWGN45DvLmnLAOBcQdISyJCJHCFHALLEKA4f29vgaC8LFAl5J03Ag== +"@lerna/command@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-6.4.1.tgz#96c4f5d88792c6c638738c66fcc3a7ad0d2487e2" + integrity sha512-3Lifj8UTNYbRad8JMP7IFEEdlIyclWyyvq/zvNnTS9kCOEymfmsB3lGXr07/AFoi6qDrvN64j7YSbPZ6C6qonw== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/package-graph" "6.4.0" - "@lerna/project" "6.4.0" - "@lerna/validation-error" "6.4.0" - "@lerna/write-log-file" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/package-graph" "6.4.1" + "@lerna/project" "6.4.1" + "@lerna/validation-error" "6.4.1" + "@lerna/write-log-file" "6.4.1" clone-deep "^4.0.1" dedent "^0.7.0" execa "^5.0.0" is-ci "^2.0.0" npmlog "^6.0.2" -"@lerna/conventional-commits@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-6.4.0.tgz#176a5422acae5463b31c05aa05bfabedf418f25c" - integrity sha512-rbf7FCLatthMacQUXV3o/o8KSDi0a0nXsDW7v0wNow1KFPUhK5pc0m8a4TxiXMiLDVVn0YzVNHmoP0ns2vyCnA== +"@lerna/conventional-commits@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-6.4.1.tgz#b8d44a8a71865b4d37b900137acef623f3a0a11b" + integrity sha512-NIvCOjStjQy5O8VojB7/fVReNNDEJOmzRG2sTpgZ/vNS4AzojBQZ/tobzhm7rVkZZ43R9srZeuhfH9WgFsVUSA== dependencies: - "@lerna/validation-error" "6.4.0" + "@lerna/validation-error" "6.4.1" conventional-changelog-angular "^5.0.12" conventional-changelog-core "^4.2.4" conventional-recommended-bump "^6.1.0" @@ -2436,24 +2470,24 @@ pify "^5.0.0" semver "^7.3.4" -"@lerna/create-symlink@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-6.4.0.tgz#856125ad8c723333e70eb78eff168d1160c85537" - integrity sha512-M4m1ujGImF9oTGGH3FK1HIHko9tG/l9bZtEfUA/Lv32d23QtKOVJ3e+iUmodHkogWI33d4UD1ORw8pROHoSH9Q== +"@lerna/create-symlink@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-6.4.1.tgz#0efec22d78dd814a70d8345ced52c39beb05874b" + integrity sha512-rNivHFYV1GAULxnaTqeGb2AdEN2OZzAiZcx5CFgj45DWXQEGwPEfpFmCSJdXhFZbyd3K0uiDlAXjAmV56ov3FQ== dependencies: cmd-shim "^5.0.0" fs-extra "^9.1.0" npmlog "^6.0.2" -"@lerna/create@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.4.0.tgz#08676cfed541dfe6d581a902c2f4483d79f3e969" - integrity sha512-stywh4hsKfdNm093d/Nga6Otoz+P/lxzUXmNzoo8+T6ug9o9qBQZGbYCqON4VSvJNU0htgAJ9O8RnOZqCoqw5A== +"@lerna/create@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.4.1.tgz#3fc8556adadff1265432a6cee69ee14465798e71" + integrity sha512-qfQS8PjeGDDlxEvKsI/tYixIFzV2938qLvJohEKWFn64uvdLnXCamQ0wvRJST8p1ZpHWX4AXrB+xEJM3EFABrA== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/npm-conf" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/npm-conf" "6.4.1" + "@lerna/validation-error" "6.4.1" dedent "^0.7.0" fs-extra "^9.1.0" init-package-json "^3.0.2" @@ -2467,218 +2501,218 @@ validate-npm-package-name "^4.0.0" yargs-parser "20.2.4" -"@lerna/describe-ref@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-6.4.0.tgz#13a4fc7390202e0f76d6ec7e9e4bf93a746810e7" - integrity sha512-hlPaz+NUCKhocL5R8c7nDc3rurcG1CGlZeWqTIz09VwU2hhXD5VGKcPJKpQQPLI2I0fzXAQoxjE5gunMUgZkfQ== +"@lerna/describe-ref@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-6.4.1.tgz#c0a0beca5dfeada3a39b030f69c8c98f5623bb13" + integrity sha512-MXGXU8r27wl355kb1lQtAiu6gkxJ5tAisVJvFxFM1M+X8Sq56icNoaROqYrvW6y97A9+3S8Q48pD3SzkFv31Xw== dependencies: - "@lerna/child-process" "6.4.0" + "@lerna/child-process" "6.4.1" npmlog "^6.0.2" -"@lerna/diff@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-6.4.0.tgz#979651727afec6b5ba9b4966be306ea0dff88c93" - integrity sha512-Ih0m+qdB17ycRTYcSqtDkhKOTqrKv3QNzOFrQlfH/f0y0ljJSaLzOzA3eRHnRG41M9jlQ8o0J2NM6PtWOodi+Q== +"@lerna/diff@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-6.4.1.tgz#ca9e62a451ce199faaa7ef5990ded3fad947e2f9" + integrity sha512-TnzJsRPN2fOjUrmo5Boi43fJmRtBJDsVgwZM51VnLoKcDtO1kcScXJ16Od2Xx5bXbp5dES5vGDLL/USVVWfeAg== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/validation-error" "6.4.1" npmlog "^6.0.2" -"@lerna/exec@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-6.4.0.tgz#e025bbd64a6b641f3e647cc87c2db9429fb6c8b3" - integrity sha512-AFz5kMoBJtRr5HK5MJIQGnW8Jp4wPFTIYPvxgNvNAFJum9skrk2bfEFUJ/e2G5imd0zSNzm7pZHzRujEcD6tJA== - dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/profiler" "6.4.0" - "@lerna/run-topologically" "6.4.0" - "@lerna/validation-error" "6.4.0" +"@lerna/exec@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-6.4.1.tgz#493ce805b6959e8299ec58fab8d31fd01ed209ba" + integrity sha512-KAWfuZpoyd3FMejHUORd0GORMr45/d9OGAwHitfQPVs4brsxgQFjbbBEEGIdwsg08XhkDb4nl6IYVASVTq9+gA== + dependencies: + "@lerna/child-process" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/profiler" "6.4.1" + "@lerna/run-topologically" "6.4.1" + "@lerna/validation-error" "6.4.1" p-map "^4.0.0" -"@lerna/filter-options@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-6.4.0.tgz#e15353ba2ce28a97f365912bceee650e55de1630" - integrity sha512-ezKSB0eEXCnNjecZLQcUyuCOf0jQcb8JVcCncbHbjsQdP8apTnXrKPoVlMwDJ/ihWK13Z3myJcVJXfoqiuvveQ== +"@lerna/filter-options@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-6.4.1.tgz#571d37436878fab8b2ac84ca1c3863acd3515cfb" + integrity sha512-efJh3lP2T+9oyNIP2QNd9EErf0Sm3l3Tz8CILMsNJpjSU6kO43TYWQ+L/ezu2zM99KVYz8GROLqDcHRwdr8qUA== dependencies: - "@lerna/collect-updates" "6.4.0" - "@lerna/filter-packages" "6.4.0" + "@lerna/collect-updates" "6.4.1" + "@lerna/filter-packages" "6.4.1" dedent "^0.7.0" npmlog "^6.0.2" -"@lerna/filter-packages@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-6.4.0.tgz#d7aae5a657fff8d9feec477c79e64697dc0d7c26" - integrity sha512-h9Z1Zy3Ihn03HIiaAutFwUMMKoV8pMHJaX1sGKqDzt3q+5TdX/TDbhzcbjo84LK3WaUCV54x3bLsm5z58HbkHA== +"@lerna/filter-packages@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-6.4.1.tgz#e138b182816a049c81de094069cad12aaa41a236" + integrity sha512-LCMGDGy4b+Mrb6xkcVzp4novbf5MoZEE6ZQF1gqG0wBWqJzNcKeFiOmf352rcDnfjPGZP6ct5+xXWosX/q6qwg== dependencies: - "@lerna/validation-error" "6.4.0" + "@lerna/validation-error" "6.4.1" multimatch "^5.0.0" npmlog "^6.0.2" -"@lerna/get-npm-exec-opts@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-6.4.0.tgz#3c0f62cce691974813c20284b3d91fe8064780ca" - integrity sha512-qOu0mgWpLvpnfrSa10jci5+9GU1VcnQvMHywalY5IjpmbDT+RQjb/ELZfrWihSvx5QawVwUYXaAJ5mqRppwvfQ== +"@lerna/get-npm-exec-opts@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-6.4.1.tgz#42681f6db4238277889b3423f87308eda5dc01ec" + integrity sha512-IvN/jyoklrWcjssOf121tZhOc16MaFPOu5ii8a+Oy0jfTriIGv929Ya8MWodj75qec9s+JHoShB8yEcMqZce4g== dependencies: npmlog "^6.0.2" -"@lerna/get-packed@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-6.4.0.tgz#53f082eb5fdc01ccdd69decc1119a0093165363d" - integrity sha512-tqfmg301LQcQ+miGno7x0sdkAGwDfrAsFstzoh2sfYmua+rc5XBWnwpE1QUTHJOU2WHD/GPrbfQRGhwHyKCkpw== +"@lerna/get-packed@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-6.4.1.tgz#b3b8b907002d50bf8792dd97e2729249c0b0e0cd" + integrity sha512-uaDtYwK1OEUVIXn84m45uPlXShtiUcw6V9TgB3rvHa3rrRVbR7D4r+JXcwVxLGrAS7LwxVbYWEEO/Z/bX7J/Lg== dependencies: fs-extra "^9.1.0" ssri "^9.0.1" tar "^6.1.0" -"@lerna/github-client@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-6.4.0.tgz#4d531a71e9eaa0e7a41039bb86a26136c833954f" - integrity sha512-0PVcyMs6vusYYddvUDaBKwHwReqNGa9HSPIYfI1EnmVUnGz2KwVI8duXuo30tZibB1jpgsDNsF8RNxnjPjmZnQ== +"@lerna/github-client@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-6.4.1.tgz#25d19b440395a6039b9162ee58dadb9dce990ff0" + integrity sha512-ridDMuzmjMNlcDmrGrV9mxqwUKzt9iYqCPwVYJlRYrnE3jxyg+RdooquqskVFj11djcY6xCV2Q2V1lUYwF+PmA== dependencies: - "@lerna/child-process" "6.4.0" + "@lerna/child-process" "6.4.1" "@octokit/plugin-enterprise-rest" "^6.0.1" "@octokit/rest" "^19.0.3" git-url-parse "^13.1.0" npmlog "^6.0.2" -"@lerna/gitlab-client@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-6.4.0.tgz#0028d5f5750b2163f825a10c9129e05530e97ca9" - integrity sha512-1BTPV74cyBbCC+bD0QRibIkpvZUOjxk9kNC4EGb5TsXofI/5U3ePWfQUd3CKfZ5Or7gR68obwjVXvQga/Csf4A== +"@lerna/gitlab-client@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-6.4.1.tgz#a01d962dc52a55b8272ea52bc54d72c5fd9db6f9" + integrity sha512-AdLG4d+jbUvv0jQyygQUTNaTCNSMDxioJso6aAjQ/vkwyy3fBJ6FYzX74J4adSfOxC2MQZITFyuG+c9ggp7pyQ== dependencies: node-fetch "^2.6.1" npmlog "^6.0.2" -"@lerna/global-options@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-6.4.0.tgz#16e5453e0e8308fbaeb5ff60e3f2c9ddc724eaa0" - integrity sha512-YQ3i3Z0wXzYQbqEN1qQmKW8O3SQw/o+H/j9PAn7VJ1FvVJHKQryiSAUscTh3qOrRipLBds1gEdQxBOQHcr0RMw== +"@lerna/global-options@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-6.4.1.tgz#7df76b1d38500606a8dc3ce0804bab6894c4f4a3" + integrity sha512-UTXkt+bleBB8xPzxBPjaCN/v63yQdfssVjhgdbkQ//4kayaRA65LyEtJTi9rUrsLlIy9/rbeb+SAZUHg129fJg== -"@lerna/has-npm-version@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-6.4.0.tgz#4c2ebfbe0d373d1cabaa01ee3c50738f46f68695" - integrity sha512-01mBJtqCgbCxx7HHOXTZXQuWX+43o1hzhdjHxhkmf41vjrEKHaAAQ6NZYrzldX3vylFXByYX4ksYtvoSFuNRvQ== +"@lerna/has-npm-version@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-6.4.1.tgz#04eba7df687e665294834253b659430efc1e01bb" + integrity sha512-vW191w5iCkwNWWWcy4542ZOpjKYjcP/pU3o3+w6NM1J3yBjWZcNa8lfzQQgde2QkGyNi+i70o6wIca1o0sdKwg== dependencies: - "@lerna/child-process" "6.4.0" + "@lerna/child-process" "6.4.1" semver "^7.3.4" -"@lerna/import@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-6.4.0.tgz#4c2f5b111bceabfb477518792ab2426cf8924f45" - integrity sha512-7n/9VargFVJQPNj/uwXZwkKiUSjzD4ZJ74RDRiQQk3VYm7SH37C0l8/Z7jzUR1P8K8ZXgG3di3DMuGnkW/pDpw== +"@lerna/import@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-6.4.1.tgz#b5696fed68a32d32398d66f95192267f1da5110e" + integrity sha512-oDg8g1PNrCM1JESLsG3rQBtPC+/K9e4ohs0xDKt5E6p4l7dc0Ib4oo0oCCT/hGzZUlNwHxrc2q9JMRzSAn6P/Q== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/prompt" "6.4.0" - "@lerna/pulse-till-done" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/prompt" "6.4.1" + "@lerna/pulse-till-done" "6.4.1" + "@lerna/validation-error" "6.4.1" dedent "^0.7.0" fs-extra "^9.1.0" p-map-series "^2.1.0" -"@lerna/info@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/info/-/info-6.4.0.tgz#9b7ba52ec023238f3d846de80148b525dc6c6eb8" - integrity sha512-sQvW26EMHLGMZBwMMyu/3xq0rCnjoX1CwPfd9BevqhJqiqG/ByARN7Y//xx3R78X5/8bJINaddDYZiqn1O1bcQ== +"@lerna/info@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/info/-/info-6.4.1.tgz#30354fcb82c99b1f0ed753f957fbaca5b250c3fa" + integrity sha512-Ks4R7IndIr4vQXz+702gumPVhH6JVkshje0WKA3+ew2qzYZf68lU1sBe1OZsQJU3eeY2c60ax+bItSa7aaIHGw== dependencies: - "@lerna/command" "6.4.0" - "@lerna/output" "6.4.0" + "@lerna/command" "6.4.1" + "@lerna/output" "6.4.1" envinfo "^7.7.4" -"@lerna/init@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-6.4.0.tgz#9ecb1201368664de9e1788d9ecd8c47a94ffa603" - integrity sha512-Gvd3K43EAb9EbgeXnAHqP+U0L0dnMtsuwqRlZK7eE12zq1XeRRNRbwPYX7C6NcskQG1rCEXdNYFfuEfjW1UGYg== +"@lerna/init@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-6.4.1.tgz#ea4905ca976189db4b0bf04d78919060146bf684" + integrity sha512-CXd/s/xgj0ZTAoOVyolOTLW2BG7uQOhWW4P/ktlwwJr9s3c4H/z+Gj36UXw3q5X1xdR29NZt7Vc6fvROBZMjUQ== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/project" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/project" "6.4.1" fs-extra "^9.1.0" p-map "^4.0.0" write-json-file "^4.3.0" -"@lerna/link@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-6.4.0.tgz#4fa76d98b3e4a2a26636709754616917b81ee938" - integrity sha512-iwE77+W/nfbXETXpp2+T2scL/hWIIsQ2a8Vs/w3xWwaJYntNkJroyFUWnYjdTNSGuqJeUBxGOubKKUvgGGHp8w== +"@lerna/link@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-6.4.1.tgz#f31ed1f6aea1581e358a9ff545be78b61e923175" + integrity sha512-O8Rt7MAZT/WT2AwrB/+HY76ktnXA9cDFO9rhyKWZGTHdplbzuJgfsGzu8Xv0Ind+w+a8xLfqtWGPlwiETnDyrw== dependencies: - "@lerna/command" "6.4.0" - "@lerna/package-graph" "6.4.0" - "@lerna/symlink-dependencies" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/command" "6.4.1" + "@lerna/package-graph" "6.4.1" + "@lerna/symlink-dependencies" "6.4.1" + "@lerna/validation-error" "6.4.1" p-map "^4.0.0" slash "^3.0.0" -"@lerna/list@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-6.4.0.tgz#6a34e7efc7709e9f72bbdfe95ca96ad8674734ad" - integrity sha512-PQxYzJ0PUrIlI5d2b2j0aBP08cQMXLxRpA6hua7k6uhoe0ygp4avn+Dv9CXkAj1GgdvhU61pRFTkFmlQr2RTTA== +"@lerna/list@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-6.4.1.tgz#12ad83902e148d1e5ba007149b72b14636f9f1ba" + integrity sha512-7a6AKgXgC4X7nK6twVPNrKCiDhrCiAhL/FE4u9HYhHqw9yFwyq8Qe/r1RVOkAOASNZzZ8GuBvob042bpunupCw== dependencies: - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/listable" "6.4.0" - "@lerna/output" "6.4.0" + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/listable" "6.4.1" + "@lerna/output" "6.4.1" -"@lerna/listable@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-6.4.0.tgz#808cce8aa41500ce5e22c19b4e0d93bd17e211aa" - integrity sha512-g/86PO8bMYxbtV4oRS8JjeqYimtN5v5C16PIxtLEPtDK9sYx7EOCleTS1dI5FyQ1qMA4JdMU5eBPelNCtKbsYg== +"@lerna/listable@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-6.4.1.tgz#6f5c83865391c6beeb41802951c674e2de119bde" + integrity sha512-L8ANeidM10aoF8aL3L/771Bb9r/TRkbEPzAiC8Iy2IBTYftS87E3rT/4k5KBEGYzMieSKJaskSFBV0OQGYV1Cw== dependencies: - "@lerna/query-graph" "6.4.0" + "@lerna/query-graph" "6.4.1" chalk "^4.1.0" columnify "^1.6.0" -"@lerna/log-packed@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-6.4.0.tgz#9813a0f42b291658fa236cac53e4c168f2094a32" - integrity sha512-+ZbhilD/x5s9MzUGqCa43PWWlxGhANta2uQOHOwbBVkBMhCMythdcbgfO3rnfrIUU1JdQCGbUUXO5hUkm09QFA== +"@lerna/log-packed@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-6.4.1.tgz#43eae50d5c0cd906b1977a58b62b35541cf89ec1" + integrity sha512-Pwv7LnIgWqZH4vkM1rWTVF+pmWJu7d0ZhVwyhCaBJUsYbo+SyB2ZETGygo3Z/A+vZ/S7ImhEEKfIxU9bg5lScQ== dependencies: byte-size "^7.0.0" columnify "^1.6.0" has-unicode "^2.0.1" npmlog "^6.0.2" -"@lerna/npm-conf@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-6.4.0.tgz#6228c6a0418182639a65bb194f4661d3a3531b5d" - integrity sha512-2T7sg6XV00hsXk2OL7PscNwRxANsllDQwwdJMT4mzTSZWxGzhwXtgJ15sZXCt+PNOUjsSvGhwZthxp555GfA8Q== +"@lerna/npm-conf@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-6.4.1.tgz#64dba237ff41472a24f96192669c1bc0dce15edb" + integrity sha512-Q+83uySGXYk3n1pYhvxtzyGwBGijYgYecgpiwRG1YNyaeGy+Mkrj19cyTWubT+rU/kM5c6If28+y9kdudvc7zQ== dependencies: config-chain "^1.1.12" pify "^5.0.0" -"@lerna/npm-dist-tag@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-6.4.0.tgz#78e2af4b2f373efec7727d04e465a9bc94b9ace5" - integrity sha512-df26FdMitwG20YViW7WXba/6N33BBHxI46RSiNEH0CNrqH4MxKztO9nVzxoxznqTOEEiXjOlUq+fKWxPKOj+hg== +"@lerna/npm-dist-tag@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-6.4.1.tgz#f14e7176f7e323284e8aa8636b44818a61738fd1" + integrity sha512-If1Hn4q9fn0JWuBm455iIZDWE6Fsn4Nv8Tpqb+dYf0CtoT5Hn+iT64xSiU5XJw9Vc23IR7dIujkEXm2MVbnvZw== dependencies: - "@lerna/otplease" "6.4.0" + "@lerna/otplease" "6.4.1" npm-package-arg "8.1.1" npm-registry-fetch "^13.3.0" npmlog "^6.0.2" -"@lerna/npm-install@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-6.4.0.tgz#3bd9882caa80db79d249db3838c67e3a98a72e4e" - integrity sha512-F5YciWIq17SVXy4sFaPmHBv7C4IwBK6CbSot/aHAfBw0m7pDAwuTjMXwX14wfLqRsSpYbKOzT5xTWn6RaH9+nw== +"@lerna/npm-install@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-6.4.1.tgz#99f5748cb43de9786ea2b538c94a7183d38fc476" + integrity sha512-7gI1txMA9qTaT3iiuk/8/vL78wIhtbbOLhMf8m5yQ2G+3t47RUA8MNgUMsq4Zszw9C83drayqesyTf0u8BzVRg== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/get-npm-exec-opts" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/get-npm-exec-opts" "6.4.1" fs-extra "^9.1.0" npm-package-arg "8.1.1" npmlog "^6.0.2" signal-exit "^3.0.3" write-pkg "^4.0.0" -"@lerna/npm-publish@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-6.4.0.tgz#39b9bfc1713aff566a6b87532fe7fc7e7ba60328" - integrity sha512-E8tz5HvPoO0Rt8gcDRV4W4Z/Bnv3uVeKyNQYa4w5GCHEWb7f2oHOicDkjafN2dRjYr1a3X1v4k8grB8gUItnCw== +"@lerna/npm-publish@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-6.4.1.tgz#baf07b108ae8b32932612db63206bcd5b5ee0e88" + integrity sha512-lbNEg+pThPAD8lIgNArm63agtIuCBCF3umxvgTQeLzyqUX6EtGaKJFyz/6c2ANcAuf8UfU7WQxFFbOiolibXTQ== dependencies: - "@lerna/otplease" "6.4.0" - "@lerna/run-lifecycle" "6.4.0" + "@lerna/otplease" "6.4.1" + "@lerna/run-lifecycle" "6.4.1" fs-extra "^9.1.0" libnpmpublish "^6.0.4" npm-package-arg "8.1.1" @@ -2686,85 +2720,85 @@ pify "^5.0.0" read-package-json "^5.0.1" -"@lerna/npm-run-script@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-6.4.0.tgz#4bcedcdedd87d5a23dfdabc344ede32058f62dac" - integrity sha512-ebNX56fFLPm2+WZYo9s+zGk9l2axnoe1qwOqTvHHx9i+7aV630rm6nl9IgI6ivpt6zVPgWvVdU9ez+6bcopQuw== +"@lerna/npm-run-script@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-6.4.1.tgz#86db4f15d359b8a371db666aa51c9b2b87b602f3" + integrity sha512-HyvwuyhrGqDa1UbI+pPbI6v+wT6I34R0PW3WCADn6l59+AyqLOCUQQr+dMW7jdYNwjO6c/Ttbvj4W58EWsaGtQ== dependencies: - "@lerna/child-process" "6.4.0" - "@lerna/get-npm-exec-opts" "6.4.0" + "@lerna/child-process" "6.4.1" + "@lerna/get-npm-exec-opts" "6.4.1" npmlog "^6.0.2" -"@lerna/otplease@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-6.4.0.tgz#222979a62d394a81e49d62d9121f2dafbfde3996" - integrity sha512-IoI8MeVk1GaBDVCc//GDqLrVh/OziMXhocjxcdh54NS5D2vtXu4BEVThjJMzsQI9svIfUsQurF/mL7xsFfxKdQ== +"@lerna/otplease@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-6.4.1.tgz#9573e053c43e7139442da96fe655aa02749cb8a3" + integrity sha512-ePUciFfFdythHNMp8FP5K15R/CoGzSLVniJdD50qm76c4ATXZHnGCW2PGwoeAZCy4QTzhlhdBq78uN0wAs75GA== dependencies: - "@lerna/prompt" "6.4.0" + "@lerna/prompt" "6.4.1" -"@lerna/output@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/output/-/output-6.4.0.tgz#95ce3ab54d0c5499aea231c8c51b102d2eb2f5cc" - integrity sha512-J9mS9lx+qZbuKZvvkxk39osuPK4FV2sLxtR+9EBXAVu39AXYb8DMsN8S6KLXt0ff+XbIr3m6xQRf4c0hTu0P1A== +"@lerna/output@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-6.4.1.tgz#327baf768b8fb63db9d52f68288d387379f814f7" + integrity sha512-A1yRLF0bO+lhbIkrryRd6hGSD0wnyS1rTPOWJhScO/Zyv8vIPWhd2fZCLR1gI2d/Kt05qmK3T/zETTwloK7Fww== dependencies: npmlog "^6.0.2" -"@lerna/pack-directory@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-6.4.0.tgz#3af8705c1df8132a79b0712085d3af79c0dc4128" - integrity sha512-gKWtBhRbI0e6+3kqIogqg0K6QxnNrvJMGDTFkyvVRhKmH4tNEpeKhBM4yNtJdTGIOcm+Tu9IKzm+nkk6r0GzHQ== +"@lerna/pack-directory@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-6.4.1.tgz#e78aae4e7944057d8fc6cb4dd8ae50be7a95c2fd" + integrity sha512-kBtDL9bPP72/Nl7Gqa2CA3Odb8CYY1EF2jt801f+B37TqRLf57UXQom7yF3PbWPCPmhoU+8Fc4RMpUwSbFC46Q== dependencies: - "@lerna/get-packed" "6.4.0" - "@lerna/package" "6.4.0" - "@lerna/run-lifecycle" "6.4.0" - "@lerna/temp-write" "6.4.0" + "@lerna/get-packed" "6.4.1" + "@lerna/package" "6.4.1" + "@lerna/run-lifecycle" "6.4.1" + "@lerna/temp-write" "6.4.1" npm-packlist "^5.1.1" npmlog "^6.0.2" tar "^6.1.0" -"@lerna/package-graph@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-6.4.0.tgz#77123cbb31cc7c61e3bfb69b75ebee4af143465b" - integrity sha512-3Z1IyexsjNV/uGK8hfvUCcwP7je+MFXTxG33malZBKi9a7hEhV0ssb29ZKwetjtkCqefsVUNFTjyn7DR1YSjzg== +"@lerna/package-graph@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-6.4.1.tgz#7a18024d531f0bd88609944e572b4861f0f8868f" + integrity sha512-fQvc59stRYOqxT3Mn7g/yI9/Kw5XetJoKcW5l8XeqKqcTNDURqKnN0qaNBY6lTTLOe4cR7gfXF2l1u3HOz0qEg== dependencies: - "@lerna/prerelease-id-from-version" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/prerelease-id-from-version" "6.4.1" + "@lerna/validation-error" "6.4.1" npm-package-arg "8.1.1" npmlog "^6.0.2" semver "^7.3.4" -"@lerna/package@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/package/-/package-6.4.0.tgz#c2b48c2cc26f5c5aa32fa4b2628c0c40b5348481" - integrity sha512-/nYlPQbsypYJHLcQSptIAa1oGXoTyjSyk9uH9PW/YVl6SywqcNinT72OPAEfKgpl+61swzz/NPqdoAiPr/s3Sg== +"@lerna/package@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-6.4.1.tgz#ebbd4c5f58f4b6cf77019271a686be9585272a3b" + integrity sha512-TrOah58RnwS9R8d3+WgFFTu5lqgZs7M+e1dvcRga7oSJeKscqpEK57G0xspvF3ycjfXQwRMmEtwPmpkeEVLMzA== dependencies: load-json-file "^6.2.0" npm-package-arg "8.1.1" write-pkg "^4.0.0" -"@lerna/prerelease-id-from-version@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-6.4.0.tgz#a6b27bcb484f5a2635f520e30ad1bec2da327db6" - integrity sha512-D3P5O4y7C7t4mutsTGynAJ4JwDy4QR/mJGBRpzSCb/W9o3p/oS9BHNAWuoADPOMVCs/VDVc5omH8CKO6tYP8gQ== +"@lerna/prerelease-id-from-version@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-6.4.1.tgz#65eb1835cdfd112783eea6b596812c64f535386b" + integrity sha512-uGicdMFrmfHXeC0FTosnUKRgUjrBJdZwrmw7ZWMb5DAJGOuTzrvJIcz5f0/eL3XqypC/7g+9DoTgKjX3hlxPZA== dependencies: semver "^7.3.4" -"@lerna/profiler@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-6.4.0.tgz#9f6e40ff15b822e1072e28054f83abd4bbf63955" - integrity sha512-YmsmJj0mb4gefa3Px0EoiRAVjmorz5rym7BZut3nWmn41paebRKeQkMlpZDxUQo37N3b8b/UpBdMZNzlHfDb4g== +"@lerna/profiler@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-6.4.1.tgz#0d5e017e1389e35960d671f43db7eb16337fda1b" + integrity sha512-dq2uQxcu0aq6eSoN+JwnvHoAnjtZAVngMvywz5bTAfzz/sSvIad1v8RCpJUMBQHxaPtbfiNvOIQgDZOmCBIM4g== dependencies: fs-extra "^9.1.0" npmlog "^6.0.2" upath "^2.0.1" -"@lerna/project@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/project/-/project-6.4.0.tgz#22592f47b2f24d8673ffa3a08d5c080d8cd4efe4" - integrity sha512-LDA6qo4pYxhUKUtKArLS6Nw+cx7h4timzssf2goKJvJtlTDMslRXYbPGHHgbmTKuqRL3whfNFLVhLjnY2tq9ew== +"@lerna/project@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-6.4.1.tgz#0519323aa8bde5b73fc0bf1c428385a556a445f0" + integrity sha512-BPFYr4A0mNZ2jZymlcwwh7PfIC+I6r52xgGtJ4KIrIOB6mVKo9u30dgYJbUQxmSuMRTOnX7PJZttQQzSda4gEg== dependencies: - "@lerna/package" "6.4.0" - "@lerna/validation-error" "6.4.0" + "@lerna/package" "6.4.1" + "@lerna/validation-error" "6.4.1" cosmiconfig "^7.0.0" dedent "^0.7.0" dot-prop "^6.0.1" @@ -2777,38 +2811,38 @@ resolve-from "^5.0.0" write-json-file "^4.3.0" -"@lerna/prompt@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-6.4.0.tgz#a40fb56ab21ed9139533f72215aa2a6bc6a56c10" - integrity sha512-tQ8NcRZDqIOhohOPh5rL2WpY/7KQBZqi1yYeC89UP+Syxfsd333NtuG+EHQ/f2duMQuuGclBmTIce5empaejxQ== +"@lerna/prompt@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-6.4.1.tgz#5ede06b4c8e17ec3045180b10ec5bd313cbc8585" + integrity sha512-vMxCIgF9Vpe80PnargBGAdS/Ib58iYEcfkcXwo7mYBCxEVcaUJFKZ72FEW8rw+H5LkxBlzrBJyfKRoOe0ks9gQ== dependencies: inquirer "^8.2.4" npmlog "^6.0.2" -"@lerna/publish@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-6.4.0.tgz#f02899151e46672e37441f02320c3cddb91cd0eb" - integrity sha512-8TQSB794jjRejC3OPiTs81v3rv3DhNrkrbgFOrASx4suvH1SHsJKRXSS4xsCLiyv9b8NzodxfCPmSriOAhynUw== - dependencies: - "@lerna/check-working-tree" "6.4.0" - "@lerna/child-process" "6.4.0" - "@lerna/collect-updates" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/describe-ref" "6.4.0" - "@lerna/log-packed" "6.4.0" - "@lerna/npm-conf" "6.4.0" - "@lerna/npm-dist-tag" "6.4.0" - "@lerna/npm-publish" "6.4.0" - "@lerna/otplease" "6.4.0" - "@lerna/output" "6.4.0" - "@lerna/pack-directory" "6.4.0" - "@lerna/prerelease-id-from-version" "6.4.0" - "@lerna/prompt" "6.4.0" - "@lerna/pulse-till-done" "6.4.0" - "@lerna/run-lifecycle" "6.4.0" - "@lerna/run-topologically" "6.4.0" - "@lerna/validation-error" "6.4.0" - "@lerna/version" "6.4.0" +"@lerna/publish@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-6.4.1.tgz#e1bdfa67297ca4a3054863e7acfc8482bf613c35" + integrity sha512-/D/AECpw2VNMa1Nh4g29ddYKRIqygEV1ftV8PYXVlHpqWN7VaKrcbRU6pn0ldgpFlMyPtESfv1zS32F5CQ944w== + dependencies: + "@lerna/check-working-tree" "6.4.1" + "@lerna/child-process" "6.4.1" + "@lerna/collect-updates" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/describe-ref" "6.4.1" + "@lerna/log-packed" "6.4.1" + "@lerna/npm-conf" "6.4.1" + "@lerna/npm-dist-tag" "6.4.1" + "@lerna/npm-publish" "6.4.1" + "@lerna/otplease" "6.4.1" + "@lerna/output" "6.4.1" + "@lerna/pack-directory" "6.4.1" + "@lerna/prerelease-id-from-version" "6.4.1" + "@lerna/prompt" "6.4.1" + "@lerna/pulse-till-done" "6.4.1" + "@lerna/run-lifecycle" "6.4.1" + "@lerna/run-topologically" "6.4.1" + "@lerna/validation-error" "6.4.1" + "@lerna/version" "6.4.1" fs-extra "^9.1.0" libnpmaccess "^6.0.3" npm-package-arg "8.1.1" @@ -2819,100 +2853,100 @@ pacote "^13.6.1" semver "^7.3.4" -"@lerna/pulse-till-done@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-6.4.0.tgz#ca7612f6058f238c138078ddfd0ddafe25712b3a" - integrity sha512-Di7KLRAoRBN0rag5jDbZlV9WpH+a3L50AIIasSEr2vwMd/w/vPdRAyJ8uJ6zwAUdTyYYxIpeFL43IaMFtH6zeQ== +"@lerna/pulse-till-done@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-6.4.1.tgz#85c38a43939bf5e21b61091d0bcf73a1109a59db" + integrity sha512-efAkOC1UuiyqYBfrmhDBL6ufYtnpSqAG+lT4d/yk3CzJEJKkoCwh2Hb692kqHHQ5F74Uusc8tcRB7GBcfNZRWA== dependencies: npmlog "^6.0.2" -"@lerna/query-graph@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-6.4.0.tgz#ab60de919246d04f05f2bd59170ca302f9947da3" - integrity sha512-nh+NeYBs21qKwsJmYT1aa+LG5Q1LVLOgyW25cR3lsTvibtGccrua19nt97Va9Seuknnvz8/UkQ0LUrz8eSXjqw== +"@lerna/query-graph@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-6.4.1.tgz#3c224a49ff392d08ce8aeeaa1af4458f522a2b78" + integrity sha512-gBGZLgu2x6L4d4ZYDn4+d5rxT9RNBC+biOxi0QrbaIq83I+JpHVmFSmExXK3rcTritrQ3JT9NCqb+Yu9tL9adQ== dependencies: - "@lerna/package-graph" "6.4.0" + "@lerna/package-graph" "6.4.1" -"@lerna/resolve-symlink@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-6.4.0.tgz#1d3d5aa699bc93eff47b9d279ec3ac8ee37ba535" - integrity sha512-fFNrsGN5VxOERBezz9c2EzxdZO/eG6nf8sKzWq8MnbABeVsAxaUb6gAcMtvXxCP+qGCH0ECJIbv16CyrkelgcA== +"@lerna/resolve-symlink@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-6.4.1.tgz#ab42dcbd03bc4028ec77ee481c5db8884ebaf40a" + integrity sha512-gnqltcwhWVLUxCuwXWe/ch9WWTxXRI7F0ZvCtIgdfOpbosm3f1g27VO1LjXeJN2i6ks03qqMowqy4xB4uMR9IA== dependencies: fs-extra "^9.1.0" npmlog "^6.0.2" read-cmd-shim "^3.0.0" -"@lerna/rimraf-dir@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-6.4.0.tgz#b515fbf944ac1c310ab31430e56514e65d19e449" - integrity sha512-p1kPWlnYg6otbfMN95ojZPPLK+r+FE2EvaxCIMHJIYPo5rmdhYg+07uUASck+de/AuRgqpT5OGmjrAauRpWxeA== +"@lerna/rimraf-dir@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-6.4.1.tgz#116e379f653135b3ae955dcba703bdf212cab51a" + integrity sha512-5sDOmZmVj0iXIiEgdhCm0Prjg5q2SQQKtMd7ImimPtWKkV0IyJWxrepJFbeQoFj5xBQF7QB5jlVNEfQfKhD6pQ== dependencies: - "@lerna/child-process" "6.4.0" + "@lerna/child-process" "6.4.1" npmlog "^6.0.2" path-exists "^4.0.0" rimraf "^3.0.2" -"@lerna/run-lifecycle@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-6.4.0.tgz#18a251f24144a803779160ab3039725266cbfc78" - integrity sha512-45r4VfSK+EwC6emVEzIidTglFlRSUlr/jmfHnZt5wWdY8laGGf21zs0g70w9tgdXW5J6PQmjgoAnoUAafbn5aA== +"@lerna/run-lifecycle@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-6.4.1.tgz#1eac136afae97e197bdb564e67fb385f4d346685" + integrity sha512-42VopI8NC8uVCZ3YPwbTycGVBSgukJltW5Saein0m7TIqFjwSfrcP0n7QJOr+WAu9uQkk+2kBstF5WmvKiqgEA== dependencies: - "@lerna/npm-conf" "6.4.0" + "@lerna/npm-conf" "6.4.1" "@npmcli/run-script" "^4.1.7" npmlog "^6.0.2" p-queue "^6.6.2" -"@lerna/run-topologically@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-6.4.0.tgz#f3d388983fa417bf958ae5aeeb92d7624ee147f1" - integrity sha512-Wwsg2JhckeQKeHJdCHV6yZQh1akLcMAvVBEWpAmEEM1Kyb4hsUI/1LEexjexddjOmz8ZDjBH9uhuj5FE5q2qmg== +"@lerna/run-topologically@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-6.4.1.tgz#640b07d83f1d1e6d3bc36f81a74957839bb1672f" + integrity sha512-gXlnAsYrjs6KIUGDnHM8M8nt30Amxq3r0lSCNAt+vEu2sMMEOh9lffGGaJobJZ4bdwoXnKay3uER/TU8E9owMw== dependencies: - "@lerna/query-graph" "6.4.0" + "@lerna/query-graph" "6.4.1" p-queue "^6.6.2" -"@lerna/run@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-6.4.0.tgz#c57575f732e3b33474df3774a9af8425a3ad0725" - integrity sha512-tJ0TbcR9mG0IcaWahT2rm4RTpHdYgwRNEv/NHE/MuckNGew7D8D+IAyOHtV4dCc7hc1ccbWFD1QioEiSKmd3ag== - dependencies: - "@lerna/command" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/npm-run-script" "6.4.0" - "@lerna/output" "6.4.0" - "@lerna/profiler" "6.4.0" - "@lerna/run-topologically" "6.4.0" - "@lerna/timer" "6.4.0" - "@lerna/validation-error" "6.4.0" +"@lerna/run@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-6.4.1.tgz#985279f071ff23ae15f92837f85f979a1352fc01" + integrity sha512-HRw7kS6KNqTxqntFiFXPEeBEct08NjnL6xKbbOV6pXXf+lXUQbJlF8S7t6UYqeWgTZ4iU9caIxtZIY+EpW93mQ== + dependencies: + "@lerna/command" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/npm-run-script" "6.4.1" + "@lerna/output" "6.4.1" + "@lerna/profiler" "6.4.1" + "@lerna/run-topologically" "6.4.1" + "@lerna/timer" "6.4.1" + "@lerna/validation-error" "6.4.1" fs-extra "^9.1.0" - nx ">=14.8.6 < 16" + nx ">=15.4.2 < 16" p-map "^4.0.0" -"@lerna/symlink-binary@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-6.4.0.tgz#d6f4d5e2133f6a69f99239df7f20ead6bc97395c" - integrity sha512-PwIaSD4pbBv/E5ulGE1dTOOOzpyec4jT1QHEeVfYOQNJKn3rh7Rx8B/PFN58pHuuUtUrLbb/Qajt02LYqdT1Dg== +"@lerna/symlink-binary@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-6.4.1.tgz#d8e1b653a7ae9fe38834851c66c92278e3bb25ae" + integrity sha512-poZX90VmXRjL/JTvxaUQPeMDxFUIQvhBkHnH+dwW0RjsHB/2Tu4QUAsE0OlFnlWQGsAtXF4FTtW8Xs57E/19Kw== dependencies: - "@lerna/create-symlink" "6.4.0" - "@lerna/package" "6.4.0" + "@lerna/create-symlink" "6.4.1" + "@lerna/package" "6.4.1" fs-extra "^9.1.0" p-map "^4.0.0" -"@lerna/symlink-dependencies@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-6.4.0.tgz#7752d3d2e7f51f127c7923c3cc9f9fb191984e09" - integrity sha512-ivaBmPqKUb956K3gnH+0FrI0xMqiATu6grJmHNvYSixgKyS3eE694FGRwv3Fgm5a/e0TZ9FlbkPgBR+h78D3nA== +"@lerna/symlink-dependencies@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-6.4.1.tgz#988203cc260406b64d61294367821a0f26419ee6" + integrity sha512-43W2uLlpn3TTYuHVeO/2A6uiTZg6TOk/OSKi21ujD7IfVIYcRYCwCV+8LPP12R3rzyab0JWkWnhp80Z8A2Uykw== dependencies: - "@lerna/create-symlink" "6.4.0" - "@lerna/resolve-symlink" "6.4.0" - "@lerna/symlink-binary" "6.4.0" + "@lerna/create-symlink" "6.4.1" + "@lerna/resolve-symlink" "6.4.1" + "@lerna/symlink-binary" "6.4.1" fs-extra "^9.1.0" p-map "^4.0.0" p-map-series "^2.1.0" -"@lerna/temp-write@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/temp-write/-/temp-write-6.4.0.tgz#ac0ed7b335580241455b5fdc7b8779c56701e593" - integrity sha512-73sVS9SIIulRUip8jAbhkQ8NuXN++cuRqbENPU6+P2Z9l98L1qHdIVY2gzEPZgk8nKhIDc50vkHkIpIABukY4Q== +"@lerna/temp-write@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/temp-write/-/temp-write-6.4.1.tgz#1c46d05b633597c77b0c5f5ab46c1315195f7786" + integrity sha512-7uiGFVoTyos5xXbVQg4bG18qVEn9dFmboXCcHbMj5mc/+/QmU9QeNz/Cq36O5TY6gBbLnyj3lfL5PhzERWKMFg== dependencies: graceful-fs "^4.1.15" is-stream "^2.0.0" @@ -2920,37 +2954,37 @@ temp-dir "^1.0.0" uuid "^8.3.2" -"@lerna/timer@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-6.4.0.tgz#25757bae2e79ee7d5ca30ab3fbc80bd8e03f27f8" - integrity sha512-8A8El4Z6J7RGShXWZOxwvZIUfyWsQ4WCm0ZZgaw/nUhSJhMl5H4LEmHW5j8+rE8awr7OovNEGTzc5FwbHWrYlg== +"@lerna/timer@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-6.4.1.tgz#47fe50b56bd2fc32396a2559f7bb65de8200f07d" + integrity sha512-ogmjFTWwRvevZr76a2sAbhmu3Ut2x73nDIn0bcwZwZ3Qc3pHD8eITdjs/wIKkHse3J7l3TO5BFJPnrvDS7HLnw== -"@lerna/validation-error@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-6.4.0.tgz#4434ae77005a70af278e303ed20e4a555caf716d" - integrity sha512-lsfZMp8/DuwTUGJUNOOAlW/tuhj/wqprqQL+KH1rd/53zYx5rglZnQBiyHndS1SsV2FSj0JPZtvuO89o5qEInA== +"@lerna/validation-error@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-6.4.1.tgz#2cab92c2be395158c3d65fa57ddb73892617d7e8" + integrity sha512-fxfJvl3VgFd7eBfVMRX6Yal9omDLs2mcGKkNYeCEyt4Uwlz1B5tPAXyk/sNMfkKV2Aat/mlK5tnY13vUrMKkyA== dependencies: npmlog "^6.0.2" -"@lerna/version@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-6.4.0.tgz#90bcb78b749f5810513f4ae8cbd556ec091699a9" - integrity sha512-E5+8s0IMrQA9LEKo3npV/VRBZCgD7a3ZLPSlloX3SAFT9ZRJOE/RC1ajLxomL4q2StafuEriLH3cYujOBOAefA== - dependencies: - "@lerna/check-working-tree" "6.4.0" - "@lerna/child-process" "6.4.0" - "@lerna/collect-updates" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/conventional-commits" "6.4.0" - "@lerna/github-client" "6.4.0" - "@lerna/gitlab-client" "6.4.0" - "@lerna/output" "6.4.0" - "@lerna/prerelease-id-from-version" "6.4.0" - "@lerna/prompt" "6.4.0" - "@lerna/run-lifecycle" "6.4.0" - "@lerna/run-topologically" "6.4.0" - "@lerna/temp-write" "6.4.0" - "@lerna/validation-error" "6.4.0" +"@lerna/version@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-6.4.1.tgz#01011364df04240ce92dffed1d2fa76bb9f959ff" + integrity sha512-1/krPq0PtEqDXtaaZsVuKev9pXJCkNC1vOo2qCcn6PBkODw/QTAvGcUi0I+BM2c//pdxge9/gfmbDo1lC8RtAQ== + dependencies: + "@lerna/check-working-tree" "6.4.1" + "@lerna/child-process" "6.4.1" + "@lerna/collect-updates" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/conventional-commits" "6.4.1" + "@lerna/github-client" "6.4.1" + "@lerna/gitlab-client" "6.4.1" + "@lerna/output" "6.4.1" + "@lerna/prerelease-id-from-version" "6.4.1" + "@lerna/prompt" "6.4.1" + "@lerna/run-lifecycle" "6.4.1" + "@lerna/run-topologically" "6.4.1" + "@lerna/temp-write" "6.4.1" + "@lerna/validation-error" "6.4.1" "@nrwl/devkit" ">=15.4.2 < 16" chalk "^4.1.0" dedent "^0.7.0" @@ -2965,10 +2999,10 @@ slash "^3.0.0" write-json-file "^4.3.0" -"@lerna/write-log-file@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-6.4.0.tgz#420a9771f200898e467bc5e4e8b37b2e80576ccc" - integrity sha512-cH9Lqtj6zjPTghaDqbJy3r/2q0CGWwIdcVTi/22gCwYQwZpavhJAr0BxgS2du4EK5a5iccHUj4dZXVFchQY0mQ== +"@lerna/write-log-file@6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-6.4.1.tgz#b9b959e4b853cdabf0309bc5da1513fa025117ec" + integrity sha512-LE4fueQSDrQo76F4/gFXL0wnGhqdG7WHVH8D8TrKouF2Afl4NHltObCm4WsSMPjcfciVnZQFfx1ruxU4r/enHQ== dependencies: npmlog "^6.0.2" write-file-atomic "^4.0.1" @@ -3212,24 +3246,24 @@ read-package-json-fast "^2.0.3" which "^2.0.2" -"@nrwl/cli@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.3.2.tgz#dd713e6d6a064587a0ededd75d301b72f820e222" - integrity sha512-3xlH5LlNDzQ1mvVk+8w2WPoDwaOuUKR+9+38nnxTW6jW8g8S+h259/2IGsXnJ+cD7oEv3TARTC6aCrwVNn7egA== +"@nrwl/cli@15.5.3": + version "15.5.3" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.5.3.tgz#13277e5a0e8ba713850bcf13fa76717ea747a2bb" + integrity sha512-NWf9CWswvdYM6YzXuweaZPAZ2erMtQrrHZdgFbUGeojZBZ+b4TCGzLWNodZj4yQOa/eTwlyPMYO2LEw9CoapDQ== dependencies: - nx "15.3.2" + nx "15.5.3" -"@nrwl/cli@15.4.5": - version "15.4.5" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.4.5.tgz#2a8f663e5265379812ba83c0577abdc94dcdba8f" - integrity sha512-f13s0/hzS9jsV1+QPr1Lp3Um+3dOHD8gEP2h7uw17rEPrtJ5ggRKMj/HcZ9dkT9zDM9EmPtVTb6k38ON+NWcUw== +"@nrwl/cli@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/cli/-/cli-15.6.3.tgz#999531d6efb30afc39373bdcbd7e78254a3a3fd3" + integrity sha512-K4E0spofThZXMnhA6R8hkUTdfqmwSnUE2+DlD5Y3jqsvKTAgwF5U41IFkEouFZCf+dWjy0RA20bWoX48EVFtmQ== dependencies: - nx "15.4.5" + nx "15.6.3" -"@nrwl/devkit@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.3.2.tgz#44ea9bc038ce87d9ea24447f6b3f3e1351a58787" - integrity sha512-h0MmDOjvhBJCrpXaAEK6eojpO5juaV6OEX0XjadPAQs4McxTALJxNP7Te6wIfgsY8t9WecARPIt85zKsLJeCjg== +"@nrwl/devkit@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-15.6.3.tgz#e4e96c53ba3304786a49034286c8511534b2b194" + integrity sha512-/JDvdzNxUM+C1PCZPCrvmFx+OfywqZdOq1GS9QR8C0VctTLG4D/SGSFD88O1SAdcbH/f1mMiBGfEYZYd23fghQ== dependencies: "@phenomnomnominal/tsquery" "4.1.1" ejs "^3.1.7" @@ -3238,9 +3272,9 @@ tslib "^2.3.0" "@nrwl/devkit@>=15.4.2 < 16": - version "15.4.5" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.4.5.tgz#22b7aa16bc14c171f061f770060d9af480d5f1cb" - integrity sha512-oag+wJgusKz+rwvgcVy9i8bNtTo7ikbjVVtSOmyVBE0ZrgN1CMFjugBj4FEjKGtd73djjpvW9Mm36uJRujrc2w== + version "15.5.3" + resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-15.5.3.tgz#16fac0147c2ab6ebba7b5357b2b959ad46b6eb26" + integrity sha512-GGNLLGXDGWflrpaLimnE6hChfZfq3+XWZ0LJWL0IuCnchngPbNzuyh8S8KPgNKKgq4Nv0hglWefIwMg2UhHysA== dependencies: "@phenomnomnominal/tsquery" "4.1.1" ejs "^3.1.7" @@ -3248,16 +3282,16 @@ semver "7.3.4" tslib "^2.3.0" -"@nrwl/jest@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-15.3.2.tgz#5616af79444914e8a6c4b0dd7426eac8993accfb" - integrity sha512-3ksxm7gtJjXp/WeThxs2H5bAYI0zWQwquTjaNwaGKWvtwjtUbu+sM4zEF2HgOu4CKP6In3wFA4q0gZH7QlCEsw== +"@nrwl/jest@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/jest/-/jest-15.6.3.tgz#66b1c387352cbbf666959fd7fe921d4980c6084a" + integrity sha512-pG8ESEJFkgyBGOOVZ6bFohklkDXn7JrDPSjmnoKvcOzprluPS7Nx4Ce5bw7wk2Ul3fqJcpAcH5LAZvb+HtA85w== dependencies: "@jest/reporters" "28.1.1" "@jest/test-result" "28.1.1" - "@nrwl/devkit" "15.3.2" + "@nrwl/devkit" "15.6.3" "@phenomnomnominal/tsquery" "4.1.1" - chalk "4.1.0" + chalk "^4.1.0" dotenv "~10.0.0" identity-obj-proxy "3.0.0" jest-config "28.1.1" @@ -3266,12 +3300,12 @@ resolve.exports "1.1.0" tslib "^2.3.0" -"@nrwl/linter@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-15.3.2.tgz#7c947ece44d964d7331795e405966da71a02318b" - integrity sha512-sMOgmMufH5jhsseRLipKTk7GTfW3l0edjHFj9zVo49tQmGjMeurXdIw4MkJhX23JdSc1w1JGdrqeUi10iqtMyg== +"@nrwl/linter@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/linter/-/linter-15.6.3.tgz#9cffa150109c604827c06ce0ccd5c925d4cd7c01" + integrity sha512-efGOduHbUa/L6MuJLb2SoDwi4hEKpz6lM1X/Yg36dYDjLuJdpLC23K4WwEOQeZL6jkcUerfY65W8NMPinAHWKg== dependencies: - "@nrwl/devkit" "15.3.2" + "@nrwl/devkit" "15.6.3" "@phenomnomnominal/tsquery" "4.1.1" tmp "~0.2.1" tslib "^2.3.0" @@ -3290,29 +3324,29 @@ tar "6.1.11" yargs-parser ">=21.0.1" -"@nrwl/tao@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.3.2.tgz#3498bd6596e582cbc5b922a45e5d8db5bcb2ce47" - integrity sha512-iP7e7gxSLn7xahz13Mj0c6KMSd9S2sUmD1Z6+F/H/lThikkrgURckSyZFtAW6OQNYOkWWi9RwdzVsH5He0syhQ== +"@nrwl/tao@15.5.3": + version "15.5.3" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.5.3.tgz#08c05715d2ecb108ed8b2c5381b9017cf1448b4a" + integrity sha512-vgPLIW9IoBfQ4IkHRT5RC4LqNwFBK5jmHYmFIRgbIeFRudFBbnpmOaKRME0OwN7qJ6964PVVbzahAPvYVD02xw== dependencies: - nx "15.3.2" + nx "15.5.3" -"@nrwl/tao@15.4.5": - version "15.4.5" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.4.5.tgz#d07f6d06cecb6acb84259e0654cfc59fcc5edd53" - integrity sha512-UMtxXxTWqbyZOdyD9Zt2IsDY/JVXIFZtY6pO4jPha7+UIHWf2Zi8Dszs6UoUTS4mqpNMIkKymwpZGtkDTfiAJA== +"@nrwl/tao@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/tao/-/tao-15.6.3.tgz#b24e11345375dea96bc386c60b9b1102a7584932" + integrity sha512-bDZbPIbU5Mf2BvX0q8GjPxrm1WkYyfW+gp7mLuuJth2sEpZiCr47mSwuGko/y4CKXvIX46VQcAS0pKQMKugXsg== dependencies: - nx "15.4.5" + nx "15.6.3" -"@nrwl/workspace@15.3.2": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-15.3.2.tgz#143609997f1e391083a2934a7e5305f0ef385ea5" - integrity sha512-h5WtTpRTHBmcO/V7WPnkzGJADQtAubZAinTn5ptkvFOYr0jnidwiVOidm0AgNvYMJtHIUf8h3jbKUIBAsRFF0g== +"@nrwl/workspace@15.6.3": + version "15.6.3" + resolved "https://registry.npmjs.org/@nrwl/workspace/-/workspace-15.6.3.tgz#a9fd3c5692dfaebb04642e4e86d930d144bc2fed" + integrity sha512-RkCmDvcMXCVanR0RS8CZ14D7OMojSyvAal+b37P521MpizDkiN+zdRKewKvyOonzDeTAmZODtYccQ/uM5DjRfQ== dependencies: - "@nrwl/devkit" "15.3.2" - "@nrwl/linter" "15.3.2" + "@nrwl/devkit" "15.6.3" + "@nrwl/linter" "15.6.3" "@parcel/watcher" "2.0.4" - chalk "4.1.0" + chalk "^4.1.0" chokidar "^3.5.1" cli-cursor "3.1.0" cli-spinners "2.6.1" @@ -3320,12 +3354,13 @@ enquirer "~2.3.6" figures "3.2.0" flat "^5.0.2" - fs-extra "^10.1.0" + fs-extra "^11.1.0" glob "7.1.4" ignore "^5.0.4" + jsonc-parser "3.2.0" minimatch "3.0.5" npm-run-path "^4.0.1" - nx "15.3.2" + nx "15.6.3" open "^8.4.0" rxjs "^6.5.4" semver "7.3.4" @@ -5671,7 +5706,7 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commander@^9.3.0, commander@^9.4.0, commander@~9.4.0: +commander@^9.3.0, commander@^9.4.0, commander@~9.4.1: version "9.4.1" resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== @@ -6831,6 +6866,134 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" +esbuild-android-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz#20a7ae1416c8eaade917fb2453c1259302c637a5" + integrity sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA== + +esbuild-android-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz#9cc0ec60581d6ad267568f29cf4895ffdd9f2f04" + integrity sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ== + +esbuild-darwin-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz#428e1730ea819d500808f220fbc5207aea6d4410" + integrity sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg== + +esbuild-darwin-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz#b6dfc7799115a2917f35970bfbc93ae50256b337" + integrity sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA== + +esbuild-freebsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz#4e190d9c2d1e67164619ae30a438be87d5eedaf2" + integrity sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA== + +esbuild-freebsd-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz#18a4c0344ee23bd5a6d06d18c76e2fd6d3f91635" + integrity sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA== + +esbuild-linux-32@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz#9a329731ee079b12262b793fb84eea762e82e0ce" + integrity sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg== + +esbuild-linux-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz#532738075397b994467b514e524aeb520c191b6c" + integrity sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw== + +esbuild-linux-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz#5372e7993ac2da8f06b2ba313710d722b7a86e5d" + integrity sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug== + +esbuild-linux-arm@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz#e734aaf259a2e3d109d4886c9e81ec0f2fd9a9cc" + integrity sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA== + +esbuild-linux-mips64le@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz#c0487c14a9371a84eb08fab0e1d7b045a77105eb" + integrity sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ== + +esbuild-linux-ppc64le@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz#af048ad94eed0ce32f6d5a873f7abe9115012507" + integrity sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w== + +esbuild-linux-riscv64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz#423ed4e5927bd77f842bd566972178f424d455e6" + integrity sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg== + +esbuild-linux-s390x@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz#21d21eaa962a183bfb76312e5a01cc5ae48ce8eb" + integrity sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ== + +esbuild-netbsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz#ae75682f60d08560b1fe9482bfe0173e5110b998" + integrity sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg== + +esbuild-openbsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz#79591a90aa3b03e4863f93beec0d2bab2853d0a8" + integrity sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ== + +esbuild-sunos-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz#fd528aa5da5374b7e1e93d36ef9b07c3dfed2971" + integrity sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw== + +esbuild-windows-32@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz#0e92b66ecdf5435a76813c4bc5ccda0696f4efc3" + integrity sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ== + +esbuild-windows-64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz#0fc761d785414284fc408e7914226d33f82420d0" + integrity sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw== + +esbuild-windows-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz#5b5bdc56d341d0922ee94965c89ee120a6a86eb7" + integrity sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ== + +esbuild@~0.15.10: + version "0.15.18" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.18.tgz#ea894adaf3fbc036d32320a00d4d6e4978a2f36d" + integrity sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q== + optionalDependencies: + "@esbuild/android-arm" "0.15.18" + "@esbuild/linux-loong64" "0.15.18" + esbuild-android-64 "0.15.18" + esbuild-android-arm64 "0.15.18" + esbuild-darwin-64 "0.15.18" + esbuild-darwin-arm64 "0.15.18" + esbuild-freebsd-64 "0.15.18" + esbuild-freebsd-arm64 "0.15.18" + esbuild-linux-32 "0.15.18" + esbuild-linux-64 "0.15.18" + esbuild-linux-arm "0.15.18" + esbuild-linux-arm64 "0.15.18" + esbuild-linux-mips64le "0.15.18" + esbuild-linux-ppc64le "0.15.18" + esbuild-linux-riscv64 "0.15.18" + esbuild-linux-s390x "0.15.18" + esbuild-netbsd-64 "0.15.18" + esbuild-openbsd-64 "0.15.18" + esbuild-sunos-64 "0.15.18" + esbuild-windows-32 "0.15.18" + esbuild-windows-64 "0.15.18" + esbuild-windows-arm64 "0.15.18" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -6972,10 +7135,10 @@ eslint-plugin-react@^7.29.4: semver "^6.3.0" string.prototype.matchall "^4.0.7" -eslint-plugin-simple-import-sort@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz#9d9a2372b0606e999ea841b10458a370a6ccc160" - integrity sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw== +eslint-plugin-simple-import-sort@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz#cc4ceaa81ba73252427062705b64321946f61351" + integrity sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw== eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" @@ -7541,6 +7704,15 @@ fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.0.tgz#5784b102104433bb0e090f48bfc4a30742c357ed" + integrity sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^7.0.1, fs-extra@~7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -7707,6 +7879,11 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.2.0.tgz#ff368dd7104dab47bf923404eb93838245c66543" + integrity sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg== + git-raw-commits@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" @@ -7909,6 +8086,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -8339,10 +8521,10 @@ ignore-walk@^5.0.1: dependencies: minimatch "^5.0.1" -ignore@^5.0.4, ignore@^5.0.5, ignore@^5.2.0, ignore@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +ignore@^5.0.4, ignore@^5.0.5, ignore@^5.2.0, ignore@~5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== image-size@^1.0.1: version "1.0.1" @@ -9422,16 +9604,11 @@ json5@^2.1.2, json5@^2.2.0, json5@^2.2.1, json5@^2.2.2: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@3.2.0, jsonc-parser@^3.2.0: +jsonc-parser@3.2.0, jsonc-parser@^3.2.0, jsonc-parser@~3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== -jsonc-parser@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d" - integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg== - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -9537,30 +9714,30 @@ latest-version@^5.1.0: dependencies: package-json "^6.3.0" -lerna@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.4.0.tgz#ca706a0d6ea1310c49e5fbd0b5234149ef0bec0c" - integrity sha512-XqfWovJwkHFoCkNXpidJgzyl6lE523Y29tKvMoGTOfOnEmC05Fadj7wLnNHomP8UEL7A+63Wau5bC5ymigfeRw== - dependencies: - "@lerna/add" "6.4.0" - "@lerna/bootstrap" "6.4.0" - "@lerna/changed" "6.4.0" - "@lerna/clean" "6.4.0" - "@lerna/cli" "6.4.0" - "@lerna/command" "6.4.0" - "@lerna/create" "6.4.0" - "@lerna/diff" "6.4.0" - "@lerna/exec" "6.4.0" - "@lerna/filter-options" "6.4.0" - "@lerna/import" "6.4.0" - "@lerna/info" "6.4.0" - "@lerna/init" "6.4.0" - "@lerna/link" "6.4.0" - "@lerna/list" "6.4.0" - "@lerna/publish" "6.4.0" - "@lerna/run" "6.4.0" - "@lerna/validation-error" "6.4.0" - "@lerna/version" "6.4.0" +lerna@6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.4.1.tgz#a1e5abcb6c00de3367f50d75eca449e382525e0f" + integrity sha512-0t8TSG4CDAn5+vORjvTFn/ZEGyc4LOEsyBUpzcdIxODHPKM4TVOGvbW9dBs1g40PhOrQfwhHS+3fSx/42j42dQ== + dependencies: + "@lerna/add" "6.4.1" + "@lerna/bootstrap" "6.4.1" + "@lerna/changed" "6.4.1" + "@lerna/clean" "6.4.1" + "@lerna/cli" "6.4.1" + "@lerna/command" "6.4.1" + "@lerna/create" "6.4.1" + "@lerna/diff" "6.4.1" + "@lerna/exec" "6.4.1" + "@lerna/filter-options" "6.4.1" + "@lerna/import" "6.4.1" + "@lerna/info" "6.4.1" + "@lerna/init" "6.4.1" + "@lerna/link" "6.4.1" + "@lerna/list" "6.4.1" + "@lerna/publish" "6.4.1" + "@lerna/run" "6.4.1" + "@lerna/validation-error" "6.4.1" + "@lerna/version" "6.4.1" "@nrwl/devkit" ">=15.4.2 < 16" import-local "^3.0.2" inquirer "^8.2.4" @@ -9612,6 +9789,11 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +lines-and-columns@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" + integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + linkify-it@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" @@ -9938,31 +10120,25 @@ markdown-table@^3.0.2: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.2.tgz#9b59eb2c1b22fe71954a65ff512887065a7bb57c" integrity sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA== -markdownlint-cli@^0.32.0: - version "0.32.2" - resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.32.2.tgz#b7b5c5808039aef4022aef603efaa607caf8e0de" - integrity sha512-xmJT1rGueUgT4yGNwk6D0oqQr90UJ7nMyakXtqjgswAkEhYYqjHew9RY8wDbOmh2R270IWjuKSeZzHDEGPAUkQ== +markdownlint-cli@^0.33.0: + version "0.33.0" + resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.33.0.tgz#703af1234c32c309ab52fcd0e8bc797a34e2b096" + integrity sha512-zMK1oHpjYkhjO+94+ngARiBBrRDEUMzooDHBAHtmEIJ9oYddd9l3chCReY2mPlecwH7gflQp1ApilTo+o0zopQ== dependencies: - commander "~9.4.0" + commander "~9.4.1" get-stdin "~9.0.0" glob "~8.0.3" - ignore "~5.2.0" + ignore "~5.2.4" js-yaml "^4.1.0" - jsonc-parser "~3.1.0" - markdownlint "~0.26.2" - markdownlint-rule-helpers "~0.17.2" - minimatch "~5.1.0" + jsonc-parser "~3.2.0" + markdownlint "~0.27.0" + minimatch "~5.1.2" run-con "~1.2.11" -markdownlint-rule-helpers@~0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz#64d6e8c66e497e631b0e40cf1cef7ca622a0b654" - integrity sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA== - -markdownlint@~0.26.2: - version "0.26.2" - resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.26.2.tgz#11d3d03e7f0dd3c2e239753ee8fd064a861d9237" - integrity sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w== +markdownlint@~0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.27.0.tgz#9dabf7710a4999e2835e3c68317f1acd0bc89049" + integrity sha512-HtfVr/hzJJmE0C198F99JLaeada+646B5SaG2pVoEakLFI6iRGsvMqrnnrflq8hm1zQgwskEgqSnhDW11JBp0w== dependencies: markdown-it "13.0.1" @@ -10180,10 +10356,10 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1, minimatch@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== +minimatch@^5.0.1, minimatch@~5.1.2: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" @@ -10618,20 +10794,19 @@ nth-check@^2.0.0, nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nx@15.3.2: - version "15.3.2" - resolved "https://registry.yarnpkg.com/nx/-/nx-15.3.2.tgz#3269b7c1c0be4dc4c389a4c54f463eb43636d542" - integrity sha512-i/y9pkZj6OACnk/+VmJaqrRIhY9VZw0twyeUp9z3gy7KElFoQZ7EMm4LcacFpVYy/MTsHYi0c87CDzkSyPogOA== +nx@15.5.3, "nx@>=15.4.2 < 16": + version "15.5.3" + resolved "https://registry.npmjs.org/nx/-/nx-15.5.3.tgz#bf6252e7d9e17121dd82dec4f6fce319b9e005fa" + integrity sha512-PHB8VbiBLP108xb+yR8IGEsYWr7OcmDDOjHL+73oP4lVjyPgT8wdTMe6tI5LdBgv+KZ+0kiThK3ckvcPsfgvLQ== dependencies: - "@nrwl/cli" "15.3.2" - "@nrwl/tao" "15.3.2" + "@nrwl/cli" "15.5.3" + "@nrwl/tao" "15.5.3" "@parcel/watcher" "2.0.4" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "^3.0.0-rc.18" "@zkochan/js-yaml" "0.0.6" axios "^1.0.0" - chalk "4.1.0" - chokidar "^3.5.1" + chalk "^4.1.0" cli-cursor "3.1.0" cli-spinners "2.6.1" cliui "^7.0.2" @@ -10640,11 +10815,12 @@ nx@15.3.2: fast-glob "3.2.7" figures "3.2.0" flat "^5.0.2" - fs-extra "^10.1.0" + fs-extra "^11.1.0" glob "7.1.4" ignore "^5.0.4" js-yaml "4.1.0" jsonc-parser "3.2.0" + lines-and-columns "~2.0.3" minimatch "3.0.5" npm-run-path "^4.0.1" open "^8.4.0" @@ -10653,26 +10829,25 @@ nx@15.3.2: strong-log-transformer "^2.1.0" tar-stream "~2.2.0" tmp "~0.2.1" - tsconfig-paths "^3.9.0" + tsconfig-paths "^4.1.2" tslib "^2.3.0" v8-compile-cache "2.3.0" yargs "^17.6.2" yargs-parser "21.1.1" -nx@15.4.5, "nx@>=14.8.6 < 16", "nx@>=15.4.2 < 16": - version "15.4.5" - resolved "https://registry.yarnpkg.com/nx/-/nx-15.4.5.tgz#12daa740256fa29ba634fbc4f3f87b6d078c2990" - integrity sha512-1spZL6sgOV8JJJuN8W5CLtJYwTOnlyaV32jPXfidavU0QMS8MP+rW3+NUQ9Uzc1UYhOu8llZWtnen93neVGQRw== +nx@15.6.3: + version "15.6.3" + resolved "https://registry.npmjs.org/nx/-/nx-15.6.3.tgz#900087bce38c6e5975660c23ebd41ead1bf54f98" + integrity sha512-3t0A0GPLNen1yPAyE+VGZ3nkAzZYb5nfXtAcx8SHBlKq4u42yBY3khBmP1y4Og3jhIwFIj7J7Npeh8ZKrthmYQ== dependencies: - "@nrwl/cli" "15.4.5" - "@nrwl/tao" "15.4.5" + "@nrwl/cli" "15.6.3" + "@nrwl/tao" "15.6.3" "@parcel/watcher" "2.0.4" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "^3.0.0-rc.18" "@zkochan/js-yaml" "0.0.6" axios "^1.0.0" - chalk "4.1.0" - chokidar "^3.5.1" + chalk "^4.1.0" cli-cursor "3.1.0" cli-spinners "2.6.1" cliui "^7.0.2" @@ -10681,11 +10856,12 @@ nx@15.4.5, "nx@>=14.8.6 < 16", "nx@>=15.4.2 < 16": fast-glob "3.2.7" figures "3.2.0" flat "^5.0.2" - fs-extra "^10.1.0" + fs-extra "^11.1.0" glob "7.1.4" ignore "^5.0.4" js-yaml "4.1.0" jsonc-parser "3.2.0" + lines-and-columns "~2.0.3" minimatch "3.0.5" npm-run-path "^4.0.1" open "^8.4.0" @@ -12386,12 +12562,10 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@*, rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" +rimraf@*, rimraf@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.1.1.tgz#ec29817863e5d82d22bca82f9dc4325be2f1e72b" + integrity sha512-Z4Y81w8atcvaJuJuBB88VpADRH66okZAuEm+Jtaufa+s7rZmIz+Hik2G53kGaNytE7lsfXyWktTmfVz0H9xuDg== rimraf@^2.6.3: version "2.7.1" @@ -12400,6 +12574,13 @@ rimraf@^2.6.3: dependencies: glob "^7.1.3" +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rollup-plugin-terser@^7.0.0, rollup-plugin-terser@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" @@ -12865,7 +13046,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@~0.5.20: +source-map-support@^0.5.21, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -13483,7 +13664,7 @@ ts-essentials@^2.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== -ts-node@^10.7.0: +ts-node@10.7.0: version "10.7.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== @@ -13502,7 +13683,7 @@ ts-node@^10.7.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" -tsconfig-paths@^3.14.1, tsconfig-paths@^3.9.0: +tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== @@ -13564,6 +13745,17 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsx@^3.12.1: + version "3.12.1" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-3.12.1.tgz#d07532004c573bfea50a4ac687aa7270b3e34277" + integrity sha512-Rcg1x+rNe7qwlP8j7kx4VjP/pJo/V57k+17hlrn6a7FuQLNwkaw5W4JF75tYornNVCxkXdSUnqlIT8JY/ttvIw== + dependencies: + "@esbuild-kit/cjs-loader" "^2.4.0" + "@esbuild-kit/core-utils" "^3.0.0" + "@esbuild-kit/esm-loader" "^2.5.0" + optionalDependencies: + fsevents "~2.3.2" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"