diff --git a/.circleci/config.yml b/.circleci/config.yml index 3c4ea56f14475..02a411c143698 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -161,11 +161,6 @@ jobs: command: | pnpm nx affected -t e2e-macos --parallel=1 --base=$NX_BASE --head=$NX_HEAD no_output_timeout: 45m - - run: - name: Close CI group - command: | - pnpm nx-cloud stop-all-agents - no_output_timeout: 45m # ------------------------- # WORKFLOWS(JOBS) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4e7af5cda8e0f..1fef57b7aeebd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -234,6 +234,12 @@ jobs: git checkout -b publish/$GITHUB_REF_NAME npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN pnpm nx-release --local=false $GITHUB_REF_NAME + - name: Trigger Docs Release + if: ${{ !github.event.release.prerelease }} + run: | + # We force recreate the branch in order to always be up to date and avoid merge conflicts within the automated workflow + git branch -f website + git push -f origin website env: GH_TOKEN: ${{ github.token }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 706824aa99681..f0e1b22a05355 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -4853,9 +4853,9 @@ "disableCollapsible": false }, { - "name": "workspace-layout", - "path": "/deprecated/workspace-layout", - "id": "workspace-layout", + "name": "As Provided vs. Derived", + "path": "/deprecated/as-provided-vs-derived", + "id": "as-provided-vs-derived", "isExternal": false, "children": [], "disableCollapsible": false @@ -4993,9 +4993,9 @@ "disableCollapsible": false }, { - "name": "workspace-layout", - "path": "/deprecated/workspace-layout", - "id": "workspace-layout", + "name": "As Provided vs. Derived", + "path": "/deprecated/as-provided-vs-derived", + "id": "as-provided-vs-derived", "isExternal": false, "children": [], "disableCollapsible": false diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index fde033f53ddd2..65a49ec204df0 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -6051,13 +6051,13 @@ "tags": [] }, { - "id": "workspace-layout", - "name": "workspace-layout", + "id": "as-provided-vs-derived", + "name": "As Provided vs. Derived", "description": "", - "file": "shared/deprecated/workspace-layout", + "file": "shared/deprecated/as-provided-vs-derived", "itemList": [], "isExternal": false, - "path": "/deprecated/workspace-layout", + "path": "/deprecated/as-provided-vs-derived", "tags": [] }, { @@ -6226,14 +6226,14 @@ "path": "/deprecated/workspace-lint", "tags": [] }, - "/deprecated/workspace-layout": { - "id": "workspace-layout", - "name": "workspace-layout", + "/deprecated/as-provided-vs-derived": { + "id": "as-provided-vs-derived", + "name": "As Provided vs. Derived", "description": "", - "file": "shared/deprecated/workspace-layout", + "file": "shared/deprecated/as-provided-vs-derived", "itemList": [], "isExternal": false, - "path": "/deprecated/workspace-layout", + "path": "/deprecated/as-provided-vs-derived", "tags": [] }, "/deprecated/workspace-generators": { diff --git a/docs/generated/packages/angular/generators/application.json b/docs/generated/packages/angular/generators/application.json index 9c4b999dce985..fa7a163df6ac4 100644 --- a/docs/generated/packages/angular/generators/application.json +++ b/docs/generated/packages/angular/generators/application.json @@ -177,7 +177,7 @@ }, "additionalProperties": false, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/angular:app my-app --directory=my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nx/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nx/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application (used for linting).\n\n```bash\nnx g @nx/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/angular:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/angular:app my-app --directory=my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Single File Components application\" %}\n\nCreate an application with Single File Components (inline styles and inline templates):\n\n```bash\nnx g @nx/angular:app my-app --inlineStyle --inlineTemplate\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone Components application\" %}\n\nCreate an application that is setup to use standalone components:\n\n```bash\nnx g @nx/angular:app my-app --standalone\n```\n\n{% /tab %}\n\n{% tab label=\"Set custom prefix and tags\" %}\n\nSet the prefix to apply to generated selectors and add tags to the application (used for linting).\n\n```bash\nnx g @nx/angular:app my-app --prefix=admin --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/angular/generators/federate-module.json b/docs/generated/packages/angular/generators/federate-module.json index 2d9e2c76f975f..2656515cbf058 100644 --- a/docs/generated/packages/angular/generators/federate-module.json +++ b/docs/generated/packages/angular/generators/federate-module.json @@ -15,19 +15,19 @@ ], "type": "object", "properties": { + "path": { + "type": "string", + "$default": { "$source": "argv", "index": 0 }, + "description": "The path to locate the federated module.", + "x-prompt": "What is the path to the module to be federated?" + }, "name": { "description": "The name of the module.", "type": "string", - "$default": { "$source": "argv", "index": 0 }, "x-prompt": "What name would you like to use for the module?", "pattern": "^[a-zA-Z][^:]*$", "x-priority": "important" }, - "path": { - "type": "string", - "description": "The path to locate the federated module.", - "x-prompt": "What is the path to the module to be federated?" - }, "remote": { "type": "string", "description": "The name of the remote.", diff --git a/docs/generated/packages/angular/generators/library.json b/docs/generated/packages/angular/generators/library.json index 5aac4e14276dc..77e8e9998e2a7 100644 --- a/docs/generated/packages/angular/generators/library.json +++ b/docs/generated/packages/angular/generators/library.json @@ -204,7 +204,7 @@ }, "additionalProperties": false, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Library\" %}\n\nCreates the `my-ui-lib` library with an `ui` tag:\n\n```bash\nnx g @nx/angular:library my-ui-lib --tags=ui\n```\n\n{% /tab %}\n\n{% tab label=\"Publishable Library\" %}\n\nCreates the `my-lib` library that can be built producing an output following the Angular Package Format (APF) to be distributed as an NPM package:\n\n```bash\nnx g @nx/angular:library my-lib --publishable --import-path=@my-org/my-lib\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable Library\" %}\n\nCreates the `my-lib` library with support for incremental builds:\n\n```bash\nnx g @nx/angular:library my-lib --buildable\n```\n\n{% /tab %}\n\n{% tab label=\"Nested Folder & Import\"%}\nCreates the `my-lib` library in the `nested` directory and sets the import path to `@myorg/nested/my-lib`:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/angular:library --directory=libs/nested/my-lib --importPath=@myorg/nested/my-lib my-lib\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone component\"%}\nCreates the `my-standalone-lib` library with a standalone component as an entry point instead of an ng-module. The component can be used via the `myorg-standalone-component` selector.\n\n```bash\nnx g @nx/angular:library --standalone --selector=myorg-standalone-component my-standalone-lib\n```\n\n{% /tab %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Library\" %}\n\nCreates the `my-ui-lib` library with an `ui` tag:\n\n```bash\nnx g @nx/angular:library my-ui-lib --tags=ui\n```\n\n{% /tab %}\n\n{% tab label=\"Publishable Library\" %}\n\nCreates the `my-lib` library that can be built producing an output following the Angular Package Format (APF) to be distributed as an NPM package:\n\n```bash\nnx g @nx/angular:library my-lib --publishable --import-path=@my-org/my-lib\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable Library\" %}\n\nCreates the `my-lib` library with support for incremental builds:\n\n```bash\nnx g @nx/angular:library my-lib --buildable\n```\n\n{% /tab %}\n\n{% tab label=\"Nested Folder & Import\"%}\nCreates the `my-lib` library in the `nested` directory and sets the import path to `@myorg/nested/my-lib`:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/angular:library --directory=libs/nested/my-lib --importPath=@myorg/nested/my-lib my-lib\n```\n\n{% /tab %}\n\n{% tab label=\"Standalone component\"%}\nCreates the `my-standalone-lib` library with a standalone component as an entry point instead of an ng-module. The component can be used via the `myorg-standalone-component` selector.\n\n```bash\nnx g @nx/angular:library --standalone --selector=myorg-standalone-component my-standalone-lib\n```\n\n{% /tab %}\n", "presets": [] }, "aliases": ["lib"], diff --git a/docs/generated/packages/esbuild/documents/overview.md b/docs/generated/packages/esbuild/documents/overview.md index b66ce9161ef94..082d6053b1686 100644 --- a/docs/generated/packages/esbuild/documents/overview.md +++ b/docs/generated/packages/esbuild/documents/overview.md @@ -37,7 +37,7 @@ yarn add -D @nx/esbuild ### Creating a new JS library {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} You can add a new library that builds using esbuild with: diff --git a/docs/generated/packages/eslint/executors/lint.json b/docs/generated/packages/eslint/executors/lint.json index 1e4453f0fc073..4a308613d4f5e 100644 --- a/docs/generated/packages/eslint/executors/lint.json +++ b/docs/generated/packages/eslint/executors/lint.json @@ -133,6 +133,11 @@ "type": "string", "description": "The equivalent of the `--print-config` flag on the ESLint CLI.", "x-completion-type": "file" + }, + "errorOnUnmatchedPattern": { + "type": "boolean", + "description": "When set to false, equivalent of the `--no-error-on-unmatched-pattern` flag on the ESLint CLI.", + "default": true } }, "required": ["lintFilePatterns"], diff --git a/docs/generated/packages/js/generators/library.json b/docs/generated/packages/js/generators/library.json index 524e1af8fafdb..62fa58c9e24cb 100644 --- a/docs/generated/packages/js/generators/library.json +++ b/docs/generated/packages/js/generators/library.json @@ -147,7 +147,7 @@ } }, "required": ["name"], - "examplesFile": "---\ntitle: JS library generator examples\ndescription: This page contains examples for the @nx/js:lib generator.\n---\n\nThe `@nx/js:lib` generator will generate a library for you, and it will configure it according to the options you provide.\n\n```bash\nnpx nx g @nx/js:lib mylib\n```\n\nBy default, the library that is generated when you use this executor without passing any options, like the example above, will be a buildable library, using the `@nx/js:tsc` executor as a builder.\n\nYou may configure the tools you want to use to build your library, or bundle it too, by passing the `--bundler` flag. The `--bundler` flag controls the compiler and/or the bundler that will be used to build your library. If you choose `tsc` or `swc`, the result will be a buildable library using either `tsc` or `swc` as the compiler. If you choose `rollup` or `vite`, the result will be a buildable library using `rollup` or `vite` as the bundler. In the case of `rollup`, it will default to the `tsc` compiler. If you choose `esbuild`, you may use the [`esbuildOptions` property](https://esbuild.github.io/api/) in your `project.json` under the `build` target options to specify whether you wish to bundle your library or not.\n\n## Examples\n\n{% tabs %}\n\n{% tab label=\"Buildable with default compiler (tsc)\" %}\n\nGenerate a buildable library using the `@nx/js:tsc` executor. This uses `tsc` as the compiler.\n\n```bash\nnpx nx g @nx/js:lib mylib\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable with SWC compiler\" %}\n\nGenerate a buildable library using [SWC](https://swc.rs) as the compiler. This will use the `@nx/js:swc` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=swc\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable with tsc\" %}\n\nGenerate a buildable library using tsc as the compiler. This will use the `@nx/js:tsc` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=tsc\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable, with Rollup as a bundler\" %}\n\nGenerate a buildable library using [Rollup](https://rollupjs.org) as the bundler. This will use the `@nx/rollup:rollup` executor. It will also use [SWC](https://swc.rs) as the compiler.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=rollup\n```\n\nIf you do not want to use `swc` as the compiler, and want to use the default `babel` compiler, you can do so in your `project.json` under the `build` target options, using the [`compiler` property](https://nx.dev/packages/rollup/executors/rollup#compiler):\n\n```jsonc {% fileName=\"libs/mylib/project.json\" %}\n\"build\": {\n \"executor\": \"@nx/rollup:rollup\",\n \"options\": {\n //...\n \"compiler\": \"babel\"\n }\n}\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable, with Vite as a bundler\" %}\n\nGenerate a buildable library using [Vite](https://vitejs.dev/) as the bundler. This will use the `@nx/vite:build` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Using ESBuild\" %}\n\nGenerate a buildable library using [ESBuild](https://esbuild.github.io/) as the bundler. This will use the `@nx/esbuild:esbuild` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=esbuild\n```\n\nIf you want to specify whether you want to bundle your library or not, you can do so in your `project.json` under the `build` target options, using the [`esbuildOptions` property](https://esbuild.github.io/api/):\n\n```jsonc {% fileName=\"libs/mylib/project.json\" %}\n\"build\": {\n \"executor\": \"@nx/esbuild:esbuild\",\n \"options\": {\n //...\n \"esbuildOptions\": {\n \"bundle\": true\n }\n }\n}\n```\n\n{% /tab %}\n\n{% tab label=\"Minimal publishing target\" %}\n\nGenerate a **publishable** library with a minimal publishing target. The result will be a buildable library using the `@nx/js:tsc` executor, using `tsc` as the compiler. You can change the compiler or the bundler by passing the `--bundler` flag.\n\n```bash\nnpx nx g lib mylib --publishable\n```\n\n{% /tab %}\n\n{% tab label=\"Using directory flag\" %}\n\nGenerate a library named `mylib` and put it under a directory named `myapp` (`libs/myapp/mylib`)\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=myapp`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```shell\nnpx nx g lib mylib --directory=libs/myapp/mylib\n```\n\n{% /tab %}\n\n{% tab label=\"Non-buildable library\" %}\n\nGenerate a non-buildable library.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=none\n```\n\n{% /tab %}\n\n{% /tabs %}\n", + "examplesFile": "---\ntitle: JS library generator examples\ndescription: This page contains examples for the @nx/js:lib generator.\n---\n\nThe `@nx/js:lib` generator will generate a library for you, and it will configure it according to the options you provide.\n\n```bash\nnpx nx g @nx/js:lib mylib\n```\n\nBy default, the library that is generated when you use this executor without passing any options, like the example above, will be a buildable library, using the `@nx/js:tsc` executor as a builder.\n\nYou may configure the tools you want to use to build your library, or bundle it too, by passing the `--bundler` flag. The `--bundler` flag controls the compiler and/or the bundler that will be used to build your library. If you choose `tsc` or `swc`, the result will be a buildable library using either `tsc` or `swc` as the compiler. If you choose `rollup` or `vite`, the result will be a buildable library using `rollup` or `vite` as the bundler. In the case of `rollup`, it will default to the `tsc` compiler. If you choose `esbuild`, you may use the [`esbuildOptions` property](https://esbuild.github.io/api/) in your `project.json` under the `build` target options to specify whether you wish to bundle your library or not.\n\n## Examples\n\n{% tabs %}\n\n{% tab label=\"Buildable with default compiler (tsc)\" %}\n\nGenerate a buildable library using the `@nx/js:tsc` executor. This uses `tsc` as the compiler.\n\n```bash\nnpx nx g @nx/js:lib mylib\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable with SWC compiler\" %}\n\nGenerate a buildable library using [SWC](https://swc.rs) as the compiler. This will use the `@nx/js:swc` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=swc\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable with tsc\" %}\n\nGenerate a buildable library using tsc as the compiler. This will use the `@nx/js:tsc` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=tsc\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable, with Rollup as a bundler\" %}\n\nGenerate a buildable library using [Rollup](https://rollupjs.org) as the bundler. This will use the `@nx/rollup:rollup` executor. It will also use [SWC](https://swc.rs) as the compiler.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=rollup\n```\n\nIf you do not want to use `swc` as the compiler, and want to use the default `babel` compiler, you can do so in your `project.json` under the `build` target options, using the [`compiler` property](https://nx.dev/packages/rollup/executors/rollup#compiler):\n\n```jsonc {% fileName=\"libs/mylib/project.json\" %}\n\"build\": {\n \"executor\": \"@nx/rollup:rollup\",\n \"options\": {\n //...\n \"compiler\": \"babel\"\n }\n}\n```\n\n{% /tab %}\n\n{% tab label=\"Buildable, with Vite as a bundler\" %}\n\nGenerate a buildable library using [Vite](https://vitejs.dev/) as the bundler. This will use the `@nx/vite:build` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=vite\n```\n\n{% /tab %}\n\n{% tab label=\"Using ESBuild\" %}\n\nGenerate a buildable library using [ESBuild](https://esbuild.github.io/) as the bundler. This will use the `@nx/esbuild:esbuild` executor.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=esbuild\n```\n\nIf you want to specify whether you want to bundle your library or not, you can do so in your `project.json` under the `build` target options, using the [`esbuildOptions` property](https://esbuild.github.io/api/):\n\n```jsonc {% fileName=\"libs/mylib/project.json\" %}\n\"build\": {\n \"executor\": \"@nx/esbuild:esbuild\",\n \"options\": {\n //...\n \"esbuildOptions\": {\n \"bundle\": true\n }\n }\n}\n```\n\n{% /tab %}\n\n{% tab label=\"Minimal publishing target\" %}\n\nGenerate a **publishable** library with a minimal publishing target. The result will be a buildable library using the `@nx/js:tsc` executor, using `tsc` as the compiler. You can change the compiler or the bundler by passing the `--bundler` flag.\n\n```bash\nnpx nx g lib mylib --publishable\n```\n\n{% /tab %}\n\n{% tab label=\"Using directory flag\" %}\n\nGenerate a library named `mylib` and put it under a directory named `myapp` (`libs/myapp/mylib`)\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=myapp`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```shell\nnpx nx g lib mylib --directory=libs/myapp/mylib\n```\n\n{% /tab %}\n\n{% tab label=\"Non-buildable library\" %}\n\nGenerate a non-buildable library.\n\n```bash\nnpx nx g @nx/js:lib mylib --bundler=none\n```\n\n{% /tab %}\n\n{% /tabs %}\n", "presets": [] }, "aliases": ["lib"], diff --git a/docs/generated/packages/next/generators/application.json b/docs/generated/packages/next/generators/application.json index 62dac6323b556..652508f2ebb37 100644 --- a/docs/generated/packages/next/generators/application.json +++ b/docs/generated/packages/next/generators/application.json @@ -133,7 +133,7 @@ } }, "required": [], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Create app in a directory\" %}\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```shell\nnx g app myapp --directory=apps/nested/myapp\n```\n\n{% /tab %}\n{% tab label=\"Use a custom Express server\" %}\n\n```shell\nnx g app myapp --custom-server\n```\n\n{% /tab %}\n{% tab label=\"Use plain JavaScript (not TypeScript)\" %}\n\n```shell\nnx g app myapp --js\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Create app in a directory\" %}\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```shell\nnx g app myapp --directory=apps/nested/myapp\n```\n\n{% /tab %}\n{% tab label=\"Use a custom Express server\" %}\n\n```shell\nnx g app myapp --custom-server\n```\n\n{% /tab %}\n{% tab label=\"Use plain JavaScript (not TypeScript)\" %}\n\n```shell\nnx g app myapp --js\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/next/generators/library.json b/docs/generated/packages/next/generators/library.json index d121edf5f0066..f760b525a7fde 100644 --- a/docs/generated/packages/next/generators/library.json +++ b/docs/generated/packages/next/generators/library.json @@ -149,7 +149,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Create a new lib\" %}\n\n```shell\nnx g lib my-lib\n```\n\n{% /tab %}\n{% tab label=\"Create a new lib under a directory\" %}\n\nThe following will create a library at `libs/shared/my-lib`.\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=shared`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```shell\nnx g lib my-lib --directory=libs/shared/my-lib\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Create a new lib\" %}\n\n```shell\nnx g lib my-lib\n```\n\n{% /tab %}\n{% tab label=\"Create a new lib under a directory\" %}\n\nThe following will create a library at `libs/shared/my-lib`.\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=shared`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```shell\nnx g lib my-lib --directory=libs/shared/my-lib\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["lib"], diff --git a/docs/generated/packages/react/generators/application.json b/docs/generated/packages/react/generators/application.json index 80d8b4a3d667a..13e85e18997b7 100644 --- a/docs/generated/packages/react/generators/application.json +++ b/docs/generated/packages/react/generators/application.json @@ -187,7 +187,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/react:app my-app --bundler=vite\n```\n\nWhen choosing `vite` as the bundler, your unit tests will be set up with `vitest`, unless you choose `none` for `unitTestRunner`.\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/react:app my-app --directory=apps/my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nx/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/react:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/react:app my-app --bundler=vite\n```\n\nWhen choosing `vite` as the bundler, your unit tests will be set up with `vitest`, unless you choose `none` for `unitTestRunner`.\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/react:app my-app --directory=apps/my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nx/react:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/react/generators/federate-module.json b/docs/generated/packages/react/generators/federate-module.json index a4fad24584eca..5eebeb4a220fc 100644 --- a/docs/generated/packages/react/generators/federate-module.json +++ b/docs/generated/packages/react/generators/federate-module.json @@ -15,19 +15,19 @@ ], "type": "object", "properties": { + "path": { + "type": "string", + "$default": { "$source": "argv", "index": 0 }, + "description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.", + "x-prompt": "What is the path to the module to be federated?" + }, "name": { "description": "The name of the module.", "type": "string", - "$default": { "$source": "argv", "index": 0 }, "x-prompt": "What name would you like to use for the module?", "pattern": "^[a-zA-Z][^:]*$", "x-priority": "important" }, - "path": { - "type": "string", - "description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.", - "x-prompt": "What is the path to the module to be federated?" - }, "remote": { "type": "string", "description": "The name of the remote.", diff --git a/docs/generated/packages/vue/generators/application.json b/docs/generated/packages/vue/generators/application.json index edb7e796dff60..5caddb43b0d65 100644 --- a/docs/generated/packages/vue/generators/application.json +++ b/docs/generated/packages/vue/generators/application.json @@ -79,7 +79,7 @@ }, "unitTestRunner": { "type": "string", - "enum": ["jest", "vitest", "none"], + "enum": ["vitest", "none"], "description": "Test runner to use for unit tests.", "x-prompt": "Which unit test runner would you like to use?", "default": "vitest" @@ -130,7 +130,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```shell\nnx g @nx/vue:app my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```shell\nnx g @nx/vue:app my-app --directory=apps/my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```shell\nnx g @nx/vue:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```shell\nnx g @nx/vue:app my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Specify directory and style extension\" %}\n\nCreate an application named `my-app` in the `my-dir` directory and use `scss` for styles:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```shell\nnx g @nx/vue:app my-app --directory=apps/my-dir/my-app --style=scss\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```shell\nnx g @nx/vue:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/generated/packages/vue/generators/component.json b/docs/generated/packages/vue/generators/component.json index 87e36aa3cbc3e..33c2e91948989 100644 --- a/docs/generated/packages/vue/generators/component.json +++ b/docs/generated/packages/vue/generators/component.json @@ -100,12 +100,6 @@ "type": "boolean", "default": false, "x-priority": "internal" - }, - "unitTestRunner": { - "type": "string", - "enum": ["vitest", "jest", "none"], - "description": "Test runner to use for unit tests.", - "x-prompt": "What unit test runner should be used?" } }, "required": ["name"], diff --git a/docs/generated/packages/vue/generators/library.json b/docs/generated/packages/vue/generators/library.json index 65dd7e0ce5ef4..88b416f1dc7ce 100644 --- a/docs/generated/packages/vue/generators/library.json +++ b/docs/generated/packages/vue/generators/library.json @@ -46,7 +46,7 @@ }, "unitTestRunner": { "type": "string", - "enum": ["vitest", "jest", "none"], + "enum": ["vitest", "none"], "description": "Test runner to use for unit tests.", "x-prompt": "What unit test runner should be used?" }, diff --git a/docs/generated/packages/web/generators/application.json b/docs/generated/packages/web/generators/application.json index 3cfcc5c56739f..c10525ee7b12e 100644 --- a/docs/generated/packages/web/generators/application.json +++ b/docs/generated/packages/web/generators/application.json @@ -106,7 +106,7 @@ } }, "required": ["name"], - "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/web:app my-app --bundler=vite\n```\n\nWhen choosing `vite` as the bundler, your unit tests will be set up with `vitest`, unless you choose `none` for `unitTestRunner`.\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/web:app my-app --directory=apps/my-dir/my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nx/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", + "examplesFile": "## Examples\n\n{% tabs %}\n{% tab label=\"Simple Application\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/web:application my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Application using Vite as bundler\" %}\n\nCreate an application named `my-app`:\n\n```bash\nnx g @nx/web:app my-app --bundler=vite\n```\n\nWhen choosing `vite` as the bundler, your unit tests will be set up with `vitest`, unless you choose `none` for `unitTestRunner`.\n\n{% /tab %}\n\n{% tab label=\"Specify directory\" %}\n\nCreate an application named `my-app` in the `my-dir` directory:\n\n{% callout type=\"note\" title=\"Directory Flag Behavior Changes\" %}\nThe command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details.\n{% /callout %}\n\n```bash\nnx g @nx/web:app my-app --directory=apps/my-dir/my-app\n```\n\n{% /tab %}\n\n{% tab label=\"Add tags\" %}\n\nAdd tags to the application (used for linting).\n\n```bash\nnx g @nx/web:app my-app --tags=scope:admin,type:ui\n```\n\n{% /tab %}\n{% /tabs %}\n", "presets": [] }, "aliases": ["app"], diff --git a/docs/map.json b/docs/map.json index 2ba258543d925..04b7176d5f2c3 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1370,9 +1370,9 @@ "file": "shared/deprecated/workspace-lint" }, { - "name": "workspace-layout", - "id": "workspace-layout", - "file": "shared/deprecated/workspace-layout" + "name": "As Provided vs. Derived", + "id": "as-provided-vs-derived", + "file": "shared/deprecated/as-provided-vs-derived" }, { "name": "Workspace Generators", diff --git a/docs/nx-cloud/reference/env-vars.md b/docs/nx-cloud/reference/env-vars.md index e6379b7bc2a53..b108e80d44806 100644 --- a/docs/nx-cloud/reference/env-vars.md +++ b/docs/nx-cloud/reference/env-vars.md @@ -2,13 +2,17 @@ ### NX_BRANCH and NX_CI_EXECUTION_ID +{% callout type="info" %} +For most CI providers, `nx-cloud` is able to determine both `NX_BRANCH` and `NX_CI_EXECUTION_ID` automatically. +{% /callout %} + When running commands on CI, `nx-cloud` needs to know the current branch and the current CI execution ID (something that -uniquely identifies the current CI run or job). **For most CI providers, `nx-cloud` is able to determine both -automatically, and you don't need to do anything.** For others, you need to set the `NX_BRANCH` and `NX_CI_EXECUTION_ID` -env variables manually. You need to set them on the main job and on all agents, and the values have to match. +uniquely identifies the current CI run or job). If you find you need to provide the `NX_BRANCH` and `NX_CI_EXECUTION_ID` +env variables manually you will need to set them on the main job _and_ on all agents. The value on the main job must match the value on the agent in each case. -To make GitHub, BitBucket and GitLab integrations works, you need to set `NX_BRANCH` to the PR number, when the PR -number is available. +{% callout type="warning" title="Version Control Integrations" %} +To make the GitHub, BitBucket and GitLab integrations work, `NX_BRANCH` must be set to the PR number, when available. Any other value will result in the integration failing and you won't get an Nx Cloud Report posted. +{% /callout %} Nx Cloud uses `NX_CI_EXECUTION_ID` to match the agents and the main job. Sometimes you might have multiple main jobs (e.g., when running CI on both Linux and Windows or when running the same commands against different versions diff --git a/docs/shared/deprecated/as-provided-vs-derived.md b/docs/shared/deprecated/as-provided-vs-derived.md new file mode 100644 index 0000000000000..07370c36d3d44 --- /dev/null +++ b/docs/shared/deprecated/as-provided-vs-derived.md @@ -0,0 +1,120 @@ +# As Provided vs. Derived Generator Path Options + +Nx is moving toward a more transparent and predictable way of determining where code will be generated when you run a generator. The new behavior is to take generator options _as provided_ and place the generated code in the exact folder that you specify. Nx will only use the new behavior in Nx version 18. The directory can be specified with a `--directory` flag or use a fully specified path (i.e. `libs/shared/my-lib/src/my-component`). The `--directory` flag will be calculated relative to where you run the command. + +In the past, Nx had lots of logic to try and _derive_ the best place to put code for you. This approach worked for some people, but there were always people that wanted to generate their code in a slightly different location. Accounting for these variations lead to either (1) people in repos with a different structure not being able to use these generators or (2) Nx introducing lots of flags to allow people to tweak where code was generated (flags like `--project`, `--flat`, `--pascalCaseFiles`, `--pascalCaseDirectory`, `--fileName`). It also caused some confusion when code was not generated in the expected location or frustration when the user did not know how to get Nx to derive the right thing. + +Here are some of the issues with the `derived` behavior that are addressed with `as-provided`: + +- Some generators had multiple flags for the same thing: `directory`, `path`, etc. Going forward, we only use `--directory` across all generators. +- Generators resolved the directory option inconsistently. Some resolved it relative to the workspace root while others resolved it relative to the project's source root. In the future, all generators will resolve the directory option relative to the current working directory. As such, your terminal's path autocomplete will work as expected and you can also `cd` right into the directory you want. +- Nx transformed the provided names to `kebab-case`. In the future, the name will be taken as provided. This allows for users to deviate from the `kebab-case` directory structure. Nx also included the directory in the project name, which lead to verbose names such as `products-product-detail-page`. Now that Nx takes options as provided, names will be as simple as you would like. You can keep it simple for feature projects (.e.g. `home-page`), or name libraries based on their import path like `@my-org/design-system/buttons`. You can do a mix of both, or deviate from this completely. Note that projects still need to have unique names so you might encounter an error when the name you provide is not valid, but you can resolve the conflict however suits your workspace best. + +## Using Nx Console + +You can use [Nx Console](/core-features/integrate-with-editors) for an intuitive experience running generators. + +1. If you right-click a folder and choose `Nx generate`, the `directory` field will be populated with that folder path. +2. As you fill out the generate form, Nx Console will show you a preview of where the new files will be generated. + +## Prompting + +To mitigate the impact of this change of direction, Nx will prompt you when running most generators until Nx 18. We know changing these habits may take time so this prompt allows you to choose the previous behavior. + +```{% command="nx g lib my-lib --directory=shared/my-lib" path="~/myorg" %} +✔ Which generator would you like to use? · @nx/node:library + +> NX Generating @nx/node:library + +? What should be the project name and where should it be generated? … +❯ As provided: + Name: my-lib + Root: shared/my-lib + Derived: + Name: shared-my-lib-my-lib + Root: packages/shared/my-lib/my-lib +``` + +There are two different kinds of generators that will prompt you to choose between `as-provided` and `derived`: + +- Project Generators (applications and libraries) +- Other Code Generators (components and other code) + +Your intent is your intent. However, the commands you write and run are based on how you think Nx will act. Nx used to derive the location of your code, but Nx will not in the future. In the future for the reasons stated above, Nx will _only_ take options as provided so you should no longer expect Nx to derive the location. We know it will take time to get used to the new way Nx calculates generated code paths and names. + +## Project Generators + +As of Nx 16.8.0, generating a project will prompt you to choose how Nx will calculate where the project should be located. For now, you can choose between `as-provided` and `derived` but `as-provided` will be the only option in Nx 18. The CLI flag to choose between the two algorithms for project generators is `--projectNameAndRootFormat`. + +### Generate Paths and Names `as-provided` + +This setting makes app or lib generators behave in the following way: + +- `nx g app my-app` creates a new application named `my-app` in the `/my-app` folder +- `nx g lib my-lib` creates a new library named `my-lib` in the `/my-lib` folder +- `cd apps/nested/my-app && nx g app my-app` creates a new application named `my-app` in the `/apps/nested/my-app` folder +- `nx g app my-app --directory=apps/nested/my-app` creates a new application named `my-app` in the `/apps/nested/my-app` folder +- `nx g lib my-lib --directory=libs/shared/ui/my-lib` creates a new library named `my-lib` in the `/libs/shared/ui/my-lib` folder + +### Use the Old `derived` Paths and Names + +Choosing `derived` makes Nx behave the way it did before version 16.8.0. Nx will check the `workspaceLayout` property in `nx.json` to determine how it should calculate the path to the new project. + +```json +{ + "workspaceLayout": { + "appsDir": "demos", + "libsDir": "packages" + } +} +``` + +These settings would store apps in `/demos/` and libraries in `/packages/`. The paths specified are relative to the +workspace root. + +This makes app or lib generators behave in the following way: + +- `nx g app my-app` creates a new application named `my-app` in the `/demos/my-app` folder +- `nx g lib my-lib` creates a new library named `my-lib` in the `/packages/my-lib` folder +- `nx g app my-app --directory=nested` creates a new application named `nested-my-app` in the `/demos/nested/my-app` folder +- `nx g lib my-lib --directory=shared/ui` creates a new library named `shared-ui-my-lib` in the `/packages/shared/ui/my-lib` folder + +If you accidentally generate a project in the wrong folder, use the [move generator](/nx-api/workspace/generators/move) to move it to the correct location. + +## Code Generators + +As of Nx 17, code generators such as `component`, `service`, and others will prompt you to choose whether or not Nx will derive the location based on your options or not. In Nx 18, Nx will take the generator options as provided. The following flags are deprecated and will be removed in Nx 18: `--project`, `--flat`, `--pascalCaseFiles`, `--pascalCaseDirectory`, `--fileName`. The CLI flag to choose between the two algorithms for code generators is `--nameAndDirectoryFormat`. + +### Generate Paths and Names `as-provided` + +This setting makes generators behave in the following way: + +- `nx g component my-component` creates a component in the root. +- `cd apps/nested/my-app && nx g component my-component` creates a new component named `my-component` in the `/apps/nested/my-app` folder +- `nx g component my-component --directory=apps/nested/my-app` creates a new component named `my-component` in the `/apps/nested/my-app` folder +- `nx g component apps/nested/my-app/my-component` creates a new component named `my-component` in the `/apps/nested/my-app` folder + +{% callout type="note" title="Must generate inside a project" %} +If the directory specified is not inside a project, an error will be thrown. +{% /callout %} + +### Use the Old `derived` Paths and Names + +Choosing `derived` makes Nx behave the way it did before version 17. Nx will use the deprecated flags (`--project`, `--flat`, `--pascalCaseFiles`, `--pascalCaseDirectory`, `--fileName`) to calculate where to generate the code. This behavior will not be available in Nx 18. + +This makes generators behave in the following way: + +- `nx g component my-component` creates a component in the default project. +- `nx g component my-component --project=my-app` creates a new component named `my-component` in the `/apps/nested/my-app` folder +- `nx g component apps/nested/my-app/my-component` creates a new component named `my-component` in the `/apps/nested/my-app` folder + +## Writing Scripts + +If you are using `nx generate` in a script or another environment where it cannot have an interactive prompt, the command will still behave as it did before. You should opt into the new behavior and change the command with a command line flag. + +```diff +- nx g lib lib1 --no-interactive` ++ nx g lib lib1 --directory libs/lib1 --projectNameAndRootFormat as-provided --no-interactive +- nx g c button --project lib1 --no-interactive ++ nx g c button --directory libs/lib1/src/lib/button --nameAndDirectoryFormat as-provided --no-interactive +``` diff --git a/docs/shared/deprecated/workspace-layout.md b/docs/shared/deprecated/workspace-layout.md deleted file mode 100644 index b614d46a009ce..0000000000000 --- a/docs/shared/deprecated/workspace-layout.md +++ /dev/null @@ -1,68 +0,0 @@ -# Workspace Layout and projectNameAndRootFormat - -As of Nx 16.8.0, generating a project will prompt you to choose how Nx will calculate where the project should be located. You can choose between `as-provided` and `derived`. `as-provided` will be the default in Nx 18. - -## `as-provided` - -This setting makes app or lib generators behave in the following way: - -- `nx g app my-app` creates a new application named `my-app` in the `/my-app` folder -- `nx g lib my-lib` creates a new library named `my-lib` in the `/my-lib` folder -- `nx g app my-app --directory=apps/nested/my-app` creates a new application named `my-app` in the `/apps/nested/my-app` folder -- `nx g lib my-lib --directory=libs/shared/ui/my-lib` creates a new library named `my-lib` in the `/libs/shared/ui/my-lib` folder - -## `derived` - -Choosing `derived` makes Nx behave the way it did before version 16.8.0. Nx will check the `workspaceLayout` property in `nx.json` to determine how it should calculate the path to the new project. - -```json -{ - "workspaceLayout": { - "appsDir": "demos", - "libsDir": "packages" - } -} -``` - -These settings would store apps in `/demos/` and libraries in `/packages/`. The paths specified are relative to the -workspace root. - -This makes app or lib generators behave in the following way: - -- `nx g app my-app` creates a new application named `my-app` in the `/demos/my-app` folder -- `nx g lib my-lib` creates a new library named `my-lib` in the `/packages/my-lib` folder -- `nx g app my-app --directory=nested` creates a new application named `nested-my-app` in the `/demos/nested/my-app` folder -- `nx g lib my-lib --directory=shared/ui` creates a new library named `shared-ui-my-lib` in the `/packages/shared/ui/my-lib` folder - -If you accidentally generate a project in the wrong folder, use the [move generator](/nx-api/workspace/generators/move) to move it to the correct location. - -## Skipping the Prompt - -You can skip the prompt in two ways: - -1. Specify a flag directly in the terminal `nx g app my-app --directory=apps/my-app --projectNameAndRootFormat=as-provided` -2. Set a default value for that property for every generator that you use. - -```jsonc {% fileName="nx.json" %} -{ - "generators": { - "@nx/node": { - "application": { - "projectNameAndRootFormat": "as-provided" - }, - "library": { - "projectNameAndRootFormat": "as-provided" - } - }, - "@nx/react": { - "application": { - "projectNameAndRootFormat": "as-provided" - }, - "library": { - "projectNameAndRootFormat": "as-provided" - } - } - // etc - } -} -``` diff --git a/docs/shared/guides/nx-and-angular-cli.md b/docs/shared/guides/nx-and-angular-cli.md index 94d1d75d69790..1fe052ab234ca 100644 --- a/docs/shared/guides/nx-and-angular-cli.md +++ b/docs/shared/guides/nx-and-angular-cli.md @@ -7,36 +7,60 @@ width="100%" /%} Nx evolved from being an extension of the Angular CLI to a [fully standalone CLI working with multiple frameworks](/getting-started/why-nx#how-does-nx-work). As a result, adopting Nx as an Angular user is relatively straightforward. This guide explores some of the similarities and in particular, added benefits of using Nx over the Angular CLI for your Angular project. -## Quick Overview Comparison - -Here's a quick side-by-side overview comparing the features between the Angular CLI and Nx. -_(Kudos to [Daniel Glejzner](https://twitter.com/DanielGlejzner) for helping with this)_ - -| Feature/Tool | Angular CLI | Nx | -| ---------------------------------------------------------- | --------------- | ------------- | -| Create Angular Apps | ✅ | ✅ | -| Generate Angular Components, Services, etc. | ✅ | ✅ | -| Building & Bundling | ✅ | ✅ | -| Local Development Server | ✅ | ✅ | -| Code Schematics | ✅ | ✅ | -| Automated Update with Migrations | ✅ | ✅ (Enhanced) | -| Generators | ✅ (Schematics) | ✅ | -| Executors | ✅ (Builders) | ✅ | -| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ | -| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ | -| First-Class Monorepo Support | ❌ | ✅ | -| Enforced Module Boundaries | ❌ | ✅ | -| Interactive Project Graph | ❌ | ✅ | -| Task Graph | ❌ | ✅ | -| Running Tasks in Parallel | ❌ | ✅ | -| Building, Testing Only What is Affected | ❌ | ✅ | -| Local Caching | ❌ | ✅ | -| Distributed Caching | ❌ | ✅ | -| Distributed Task Execution on CI | ❌ | ✅ | -| Custom Hashers | ❌ | ✅ | -| Extensible Plugin System | ❌ | ✅ | - -## Not just for Monorepos: Project Setup & Structure +## TL;DR: Why should I use Nx for my Angular project? + +Nx... + +- helps define clear architectural guidelines and promotes best practices to organize and scale your codebase. +- helps integrate modern tooling by actively working with devtool authors to make sure they work well with Nx and your framework of choice. +- is adaptable: start small with a single-project setup and grow it to a monorepo when needed. +- has an active community of contributors and plugin authors. +- has been proven in large enterprise-level projects. + +Note, the Nx team's focus is on building the best possible developer productivity tool. + +### Quick Overview Comparison + +Here's a quick side-by-side overview comparing the features between the Angular CLI and Nx. _(Kudos to [Daniel Glejzner](https://twitter.com/DanielGlejzner) for helping with this)_ + +| Feature/Tool | Angular CLI | Nx | +| ---------------------------------------------------------------------------------------------------------- | --------------- | ------------- | +| Create Angular Apps | ✅ | ✅ | +| Generate Angular Components, Services, etc. | ✅ | ✅ | +| Building & Bundling | ✅ | ✅ | +| Local Development Server | ✅ | ✅ | +| Code Schematics | ✅ | ✅ | +| Automated Update with Migrations | ✅ | ✅ (Enhanced) | +| Generators | ✅ (Schematics) | ✅ | +| Executors | ✅ (Builders) | ✅ | +| Advanced Generators (e.g. Module Federation, Tailwind,...) | ❌ | ✅ | +| Integrated Tooling (Jest, Cypress, Playwright etc.) | ❌ | ✅ | +| Support for [single-project Workspaces](/getting-started/tutorials/angular-standalone-tutorial) | ✅ | ✅ | +| First-Class [Monorepo Support](/getting-started/tutorials/angular-monorepo-tutorial) | ❌\* | ✅ | +| [Enforced Module Boundaries](/core-features/enforce-module-boundaries) | ❌ | ✅ | +| Interactive [Project Graph](/core-features/explore-graph) | ❌ | ✅ | +| Task Graph | ❌ | ✅ | +| [Running Tasks in Parallel](/recipes/running-tasks/run-tasks-in-parallel) | ❌ | ✅ | +| Building, Testing [Only What is Affected](/core-features/run-tasks#run-tasks-on-projects-affected-by-a-pr) | ❌ | ✅ | +| [Local Caching](/core-features/cache-task-results) | ❌\*\* | ✅ | +| [Distributed Caching](/core-features/remote-cache) | ❌ | ✅ | +| [Distributed Task Execution on CI](/core-features/distribute-task-execution) | ❌ | ✅ | +| Custom Hashers | ❌ | ✅ | +| [Extensible Plugin System](/extending-nx/intro/getting-started) | ❌ | ✅ | + +{% callout type="info" title="Notes" %} + +\* You can setup a monorepo with the Angular CLI creating buildable Angular ng-packagr projects, but the DX is not as optimized compared to what you'd get with Nx.` + +\*\* The Angular CLI has a [caching mechanism](https://angular.io/cli/cache) which persists the Webpack/ESBuild/"TS incremental build info" cache to disk. Nx leverages that cache as well but in addition adds a more powerful process-level caching on top that is framework agnostic.` + +{% /callout %} + +## Similarities and Differences + +Learn about the similarities between the Angular CLI and Nx which makes it easy to [migrate](#migrate-from-the-angular-cli) but also about how Nx goes beyond to further improve your developer productivity. + +### Not just for Monorepos: Project Setup & Structure Nx is not just exclusively for monorepos, but can create @@ -90,7 +114,7 @@ Note that even though the configuration is split, everything works similarly. Mi More details: Nx [project configuration](/reference/project-configuration). -## Executors vs. Builders, Generators vs. Schematics +### Executors vs. Builders, Generators vs. Schematics Nx comes with slightly different terminology than the Angular CLI for some features. @@ -122,7 +146,7 @@ You can also run Angular Schematics through the Nx ClI. So something like this w npx nx g @schematics/angular:component my-component ``` -## Running Commands +### Running Commands Commands are run in the very same way as with the Angular CLI. You just switch `ng` with `nx`. For example: @@ -132,7 +156,7 @@ npx nx serve Nx has more abilities to run commands in parallel, just for specific projects etc. Find out more [in the docs](/core-features/run-tasks). -## Integrating with Modern Tools +### Integrating with Modern Tools An Angular-based Nx Workspace already comes with a lot of batteries included: @@ -143,7 +167,7 @@ An Angular-based Nx Workspace already comes with a lot of batteries included: But Nx expands beyond just that, offering automated integration with a lot of modern tools such as [Storybook](https://storybook.js.org/) or [Tailwind](https://tailwindcss.com/) just to mention a few. -## 'ng update' vs. 'nx migrate' +### 'ng update' vs. 'nx migrate' Like the Angular CLI, Nx has a command that allows you to upgrade your existing workspace tools, packages, and source code to the next version. Instead of `ng update`, you run `nx migrate`: @@ -167,7 +191,7 @@ What's the difference? To reiterate: `nx migrate` runs the migrations written by the Angular team the same way `ng update` runs them. So everything should still work. You just get more control over how it works. You can learn more in our docs about [Automate Updating Dependencies](/core-features/automate-updating-dependencies). -## 'ng add' +### 'ng add' `ng add` is not natively supported by Nx. We want a consistent package install experience for developers working with Angular or non-Angular packages. @@ -179,7 +203,7 @@ npm install [package] && nx g [package]:ng-add Replace `[package]` with the package name you're trying to add. -## Speed +### Speed Nx is designed to be fast. The Angular CLI leverages Webpack's caching, which Nx also does since it relies on the Angular Devkit when it comes to compiling or running apps. But Nx goes way beyond that, introducing features vital for a fast CI experience, mainly when you have a monorepo. @@ -193,13 +217,13 @@ Features like And, Nx already uses fast, modern tooling like [ESBuild](/nx-api/esbuild), [Vite](/nx-api/vite), Vitest and [Rspack](/nx-api/rspack) for non-Angular stacks. So once Angular is ready to use these tools, Nx will also be ready. -## Editor Integration +### Editor Integration Nx goes beyond being just a CLI and comes with [Nx Console](/core-features/integrate-with-editors), a VSCode and WebStorm extension allowing you to run commands, generate code and visualize your workspace. ![Nx Console screenshot](/shared/images/nx-console/nx-console-screenshot.webp) -## Scaling: Start Simple, Grow to a Monorepo +### Scaling: Start Simple, Grow to a Monorepo Nx is really made to scale with you. You can @@ -208,7 +232,7 @@ Nx is really made to scale with you. You can - you can then migrate to a monorepo when you are ready and need one ([more here](/recipes/tips-n-tricks/standalone-to-integrated)) - or even [add Webpack Module Federation support](/recipes/angular/module-federation-with-ssr) -## Visualize your Workspace +### Visualize your Workspace As you start modularizing your Angular workspace, Nx can visualize it using the `nx graph` command or via [Nx Console](/core-features/integrate-with-editors) directly in your editor. @@ -322,24 +346,28 @@ As you start modularizing your Angular workspace, Nx can visualize it using the Learn more about the [graph features here](/core-features/explore-graph). -## Extensible and Customizable: Make it fit your own needs +### Extensible and Customizable: Make it fit your own needs -Nx is [built to be extensible](/getting-started/why-nx#how-does-nx-work). Just like the [packages published by the Nx core team](/nx-api) you can create your own Nx plugins by [extending Nx](/extending-nx/intro/getting-started). +Nx is [built to be extensible](/getting-started/why-nx#how-does-nx-work). Just like the [packages published by the Nx core team](/nx-api) you can create your own Nx plugins by [extending Nx](/extending-nx/intro/getting-started). This can be as simple as using [run-commands](/nx-api/nx/executors/run-commands) to integrate custom commands into the project configuration or as complex as [creating your own local executor](/extending-nx/recipes/local-executors). -This can be as simple as using [run-commands](/nx-api/nx/executors/run-commands) to integrate custom commands into the project configuration or as complex as [creating your own local executor](/extending-nx/recipes/local-executors). +And if you ever need to expand beyond Angular or diversify your stack, you can still keep using Nx, which is [battle-tested with many different technologies](/getting-started/intro#pick-your-stack). -## Diversification +## Migrate from the Angular CLI? -And if you ever need to expand beyond Angular or diversify your stack, you can still keep using Nx, which is [battle-tested with many different technologies](/getting-started/intro#pick-your-stack). +Migrating an Angular CLI project to Nx can be done by running + +```shell +npx nx@latest init +``` -## Being the best CLI for you! +or alternatively using the `--integrated` flag if you want to create an Nx monorepo right away. Learn more about all the details on the [dedicated docs page](/recipes/angular/migration/angular). -The Nx team's only mission is to build the best CLI for you. We don't build frameworks or libraries; we make tools for them! +There are also guides describing how to: -## Convinced? +- [manually migrate an Angular CLI app](/recipes/angular/migration/angular-manual) and +- how to [consolidate multiple Angular CLI projects into a single Nx monorepo](/recipes/angular/migration/angular-multiple) -If you're convinced, then here are some options for you: +You can learn more about Angular & Nx by following our dedicated tutorials: - [Tutorial: Building Angular Apps with the Nx Standalone Projects Setup](/getting-started/tutorials/angular-standalone-tutorial) - [Tutorial: Building Angular Apps in an Nx Monorepo](/getting-started/tutorials/angular-monorepo-tutorial) -- [Learn how to migrate from the Angular CLI to Nx](/recipes/angular/migration) diff --git a/docs/shared/guides/remix.md b/docs/shared/guides/remix.md index 75de279ff3b02..a66390fea9be2 100644 --- a/docs/shared/guides/remix.md +++ b/docs/shared/guides/remix.md @@ -38,7 +38,7 @@ npm install --save-dev @nx/remix ## Generate a Remix Application {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```{% command="nx g @nx/remix:app myapp --directory=apps/myapp" path="~/acme" %} diff --git a/docs/shared/guides/setup-incremental-builds-angular.md b/docs/shared/guides/setup-incremental-builds-angular.md index f48e5d1517756..22aabc30da960 100644 --- a/docs/shared/guides/setup-incremental-builds-angular.md +++ b/docs/shared/guides/setup-incremental-builds-angular.md @@ -53,7 +53,7 @@ node-linker=hoisted To enable incremental builds you need to use buildable libraries. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} You can generate a new buildable library with: diff --git a/docs/shared/migration/migration-angular.md b/docs/shared/migration/migration-angular.md index 72ff5c23148dd..a0200b2935239 100644 --- a/docs/shared/migration/migration-angular.md +++ b/docs/shared/migration/migration-angular.md @@ -132,7 +132,7 @@ If you're not ready to make the change yet, you can come back to this later: Once the script has run, commit the changes. Reverting this commit will effectively undo the changes made. -{% cards %} +{% cards cols="1" mdCols="3" smCols="3" lgCols="3" %} {% card title="Nx and the Angular CLI" description="Differences between Nx and the Angular CLI" type="documentation" url="/concepts/more-concepts/nx-and-angular" /%} diff --git a/docs/shared/migration/migration-angularjs.md b/docs/shared/migration/migration-angularjs.md index 881a839884582..b8087289328e2 100644 --- a/docs/shared/migration/migration-angularjs.md +++ b/docs/shared/migration/migration-angularjs.md @@ -54,7 +54,7 @@ Codebases with existing unit and e2e tests should continue to use whatever runne With the Angular capability added, generate your application: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/monorepo-ci-circle-ci.md b/docs/shared/monorepo-ci-circle-ci.md index a6893d5ff4879..a8884194c1e37 100644 --- a/docs/shared/monorepo-ci-circle-ci.md +++ b/docs/shared/monorepo-ci-circle-ci.md @@ -1,11 +1,8 @@ # Configuring CI Using CircleCI and Nx -The `CircleCI` can track the last successful run on the `main` branch and use this as a reference point for the `BASE`. The `Nx Orb` provides a convenient implementation of this functionality which you can drop into your existing CI config. -To understand why knowing the last successful build is important for the affected command, check out the [in-depth explanation in Orb's docs](https://github.com/nrwl/nx-orb#background). - -Below is an example of a Circle CI setup for an Nx workspace - building and testing only what is affected. For more details on how the orb is used, head over to the [official docs](https://circleci.com/developer/orbs/orb/nrwl/nx). +Below is an example of a Circle CI setup for an Nx workspace - building and testing only what is affected. For more details on how the Nx orb is used, head over to the [official docs](https://circleci.com/developer/orbs/orb/nrwl/nx). -```yaml +```yaml {% fileName=".circleci/config.yml" %} version: 2.1 orbs: nx: nrwl/nx@1.5.1 @@ -19,18 +16,17 @@ jobs: - nx/set-shas - run: npx nx format:check - - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t lint --parallel=3 - - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t test --parallel=3 --configuration=ci - - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t build --parallel=3 + - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t lint,test,build --parallel=3 --configuration=ci workflows: build: jobs: - main ``` -The `pr` and `main` jobs implement the CI workflow. +`CircleCI` can track the last successful run on the `main` branch and use this as a reference point for the `BASE`. The `Nx Orb` provides a convenient implementation of this functionality which you can drop into your existing CI config. +To understand why knowing the last successful build is important for the affected command, check out the [in-depth explanation in Orb's docs](https://github.com/nrwl/nx-orb#background). -### Using CircleCI on the private repository +### Using CircleCI in a private repository To use the [Nx Orb](https://github.com/nrwl/nx-orb) with a private repository on your main branch, you need to grant the orb access to your CircleCI API. You can do this by creating an environment variable called `CIRCLE_API_TOKEN` in the context or the project. @@ -42,7 +38,7 @@ It should be a user token, not the project token. Read more about [Distributed Task Execution (DTE)](/core-features/distribute-task-execution). -```yaml +```yaml {% fileName=".circleci/config.yml" %} version: 2.1 orbs: nx: nrwl/nx@1.5.1 @@ -69,7 +65,7 @@ jobs: - run: npx nx-cloud start-ci-run --stop-agents-after="build" - run: npx nx-cloud record -- npx nx format:check - - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t lint --parallel=3 & npx nx affected --base=$NX_BASE --head=$NX_HEAD -t test --parallel=3 --configuration=ci & npx nx affected --base=$NX_BASE --head=$NX_HEAD -t build --parallel=3 + - run: npx nx affected --base=$NX_BASE --head=$NX_HEAD -t lint,test,build --parallel=3 --configuration=ci workflows: build: jobs: diff --git a/docs/shared/monorepo-ci-github-actions.md b/docs/shared/monorepo-ci-github-actions.md index d6374ad2955c8..89ae55986dbda 100644 --- a/docs/shared/monorepo-ci-github-actions.md +++ b/docs/shared/monorepo-ci-github-actions.md @@ -1,11 +1,8 @@ # Configuring CI Using GitHub Actions and Nx -`GitHub` can track the last successful run on the `main` branch and use this as a reference point for the `BASE`. The `Nx Set SHAs` provides a convenient implementation of this functionality which you can drop into your existing CI config. -To understand why knowing the last successful build is important for the affected command, check out the [in-depth explanation in Actions's docs](https://github.com/marketplace/actions/nx-set-shas#background). - Below is an example of a GitHub setup for an Nx workspace - building and testing only what is affected. For more details on how the action is used, head over to the [official docs](https://github.com/marketplace/actions/nx-set-shas). -```yaml +```yaml {% fileName=".github/workflows/ci.yml" %} name: CI on: push: @@ -17,31 +14,29 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: nrwl/nx-set-shas@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'npm' - run: npm ci + - uses: nrwl/nx-set-shas@v3 + - run: git branch --track main origin/main - run: npx nx format:check - - run: npx nx affected -t lint --parallel=3 - - run: npx nx affected -t test --parallel=3 - - run: npx nx affected -t build --parallel=3 + - run: npx nx affected -t lint,test,build --parallel=3 ``` -The `pr` and `main` jobs implement the CI workflow. Setting `timeout-minutes` is needed only if you have very slow tasks. - -{% callout type="note" title="Tracking the origin branch" %} - -If you're using this action in the context of a branch you may need to add `run: "git branch --track main origin/main"` before running the `nx affected` command since `origin/main` won't exist. - -{% /callout %} +`GitHub` can track the last successful run on the `main` branch and use this as a reference point for the `BASE`. The `Nx Set SHAs` provides a convenient implementation of this functionality which you can drop into your existing CI config. +To understand why knowing the last successful build is important for the affected command, check out the [in-depth explanation in Actions's docs](https://github.com/marketplace/actions/nx-set-shas#background). ## Distributed Task Execution with Nx Cloud -Read more about [Distributed Task Execution (DTE)](/core-features/distribute-task-execution). +Read more about [Distributed Task Execution (DTE)](/core-features/distribute-task-execution). Use this [reusable GitHub workflow](https://github.com/nrwl/ci) to quickly set up DTE for your organization. -```yaml +```yaml {% fileName=".github/workflows/ci.yml" %} name: CI on: push: @@ -58,7 +53,7 @@ jobs: parallel-commands: | npx nx-cloud record -- npx nx format:check parallel-commands-on-agents: | - npx nx affected -t lint --parallel=3 & npx nx affected -t test --parallel=3 --configuration=ci & npx nx affected -t build --parallel=3 + npx nx affected -t lint,test,build --parallel=3 agents: name: Nx Cloud - Agents @@ -73,9 +68,9 @@ You can also use our [ci-workflow generator](/nx-api/workspace/generators/ci-wor Our [reusable GitHub workflow](https://github.com/nrwl/ci) represents a good set of defaults that works for a large number of our users. However, reusable GitHub workflows come with their [limitations](https://docs.github.com/en/actions/using-workflows/reusing-workflows). -If the existing workflow doesn't satisfy your needs you should create your custom workflow. This is what the above config roughly encapsulates: +If the reusable workflow above doesn't satisfy your needs you should create a custom workflow. This is what the GitHub workflow above roughly encapsulates: -```yaml +```yaml {% fileName=".github/workflows/ci.yml" %} name: CI on: push: @@ -95,7 +90,7 @@ jobs: name: Nx Cloud - Main Job runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout [Pull Request] if: ${{ github.event_name == 'pull_request' }} with: @@ -104,7 +99,7 @@ jobs: # We need to fetch all branches and commits so that Nx affected has a base to compare against. fetch-depth: 0 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Checkout [Default Branch] if: ${{ github.event_name != 'pull_request' }} with: @@ -117,16 +112,17 @@ jobs: package-json-path: '${{ github.workspace }}/package.json' - name: Use the package manager cache if available - uses: actions/cache@v3 + uses: actions/setup-node@v3 with: - path: ~/.npm - key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}- + node-version: 20 + cache: 'npm' - name: Install dependencies run: npm ci + - name: Check out the default branch + run: git branch --track main origin/main + - name: Initialize the Nx Cloud distributed CI run run: npx nx-cloud start-ci-run @@ -137,13 +133,7 @@ jobs: NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx-cloud record -- npx nx format:check & pids+=($!) # list of commands to be run on agents - npx nx affected -t lint --parallel=3 & - pids+=($!) - - npx nx affected -t test --parallel=3 & - pids+=($!) - - npx nx affected -t build --parallel=3 & + npx nx affected -t lint,test,build --parallel=3 & pids+=($!) # run all commands in parallel and bail if one of them fails @@ -168,7 +158,7 @@ jobs: agent: [1, 2, 3] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Set node/npm/yarn versions using volta - uses: volta-cli/action@v4 @@ -176,12 +166,10 @@ jobs: package-json-path: '${{ github.workspace }}/package.json' - name: Use the package manager cache if available - uses: actions/cache@v3 + uses: actions/setup-node@v3 with: - path: ~/.npm - key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}- + node-version: 20 + cache: 'npm' - name: Install dependencies run: npm ci diff --git a/docs/shared/packages/esbuild/esbuild-plugin.md b/docs/shared/packages/esbuild/esbuild-plugin.md index b66ce9161ef94..082d6053b1686 100644 --- a/docs/shared/packages/esbuild/esbuild-plugin.md +++ b/docs/shared/packages/esbuild/esbuild-plugin.md @@ -37,7 +37,7 @@ yarn add -D @nx/esbuild ### Creating a new JS library {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} You can add a new library that builds using esbuild with: diff --git a/docs/shared/recipes/add-stack/add-astro.md b/docs/shared/recipes/add-stack/add-astro.md index fd280641709c3..d44647cfe1939 100644 --- a/docs/shared/recipes/add-stack/add-astro.md +++ b/docs/shared/recipes/add-stack/add-astro.md @@ -90,7 +90,7 @@ npm i -DE @nx/js@ Then generate a project {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```{% command="nx g @nx/js:lib ui --directory=libs/ui --simpleName --minimal} diff --git a/docs/shared/recipes/add-stack/add-deno.md b/docs/shared/recipes/add-stack/add-deno.md index f26ebf038dde5..dd4188f2ec19f 100644 --- a/docs/shared/recipes/add-stack/add-deno.md +++ b/docs/shared/recipes/add-stack/add-deno.md @@ -42,7 +42,7 @@ yarn add --dev @nx/deno ## Create an Application {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Use the `app` generator to create a new Deno app. @@ -62,7 +62,7 @@ This starts the application on localhost:4200 by default. ## Create a Library {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} To create a new library, run: diff --git a/docs/shared/recipes/add-stack/add-dotnet.md b/docs/shared/recipes/add-stack/add-dotnet.md index c28490f8a4d19..25f4a5bc8477c 100644 --- a/docs/shared/recipes/add-stack/add-dotnet.md +++ b/docs/shared/recipes/add-stack/add-dotnet.md @@ -106,7 +106,7 @@ This generates the following files: Use the `app` generator to create a new .NET app. For this demo, use the `nx` path naming convention and the `web-api` project template. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell @@ -124,7 +124,7 @@ nx serve my-api To create a new library, run the library generator. Use the `classlib` template. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-express.md b/docs/shared/recipes/add-stack/add-express.md index 55c9eaaa56e3b..416cb0e815604 100644 --- a/docs/shared/recipes/add-stack/add-express.md +++ b/docs/shared/recipes/add-stack/add-express.md @@ -44,7 +44,7 @@ yarn add --dev @nx/express Use the `app` generator to create a new Express app. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell @@ -64,7 +64,7 @@ This starts the application on localhost:3333/api by default. The `@nx/express` plugin does not have a `library` generator, but we can use the `library` generator from the `@nx/js` plugin. To create a new library, install the `@nx/js` package and run: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-fastify.md b/docs/shared/recipes/add-stack/add-fastify.md index ddd1d88ec0f1e..48e8ff167758a 100644 --- a/docs/shared/recipes/add-stack/add-fastify.md +++ b/docs/shared/recipes/add-stack/add-fastify.md @@ -57,7 +57,7 @@ yarn add --dev @nx/node Use the `app` generator to create a new Fastify app. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell @@ -77,7 +77,7 @@ This starts the application on localhost:3000/api by default. To create a new library, run: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-lit.md b/docs/shared/recipes/add-stack/add-lit.md index 0b9f983964bce..90b3fcab6da4b 100644 --- a/docs/shared/recipes/add-stack/add-lit.md +++ b/docs/shared/recipes/add-stack/add-lit.md @@ -44,7 +44,7 @@ yarn add --dev @nx/node lit http-server ## Create an Application {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} We'll start with a node application and then tweak the settings to match what we need. Add a new node application to your workspace with the following command: @@ -168,7 +168,7 @@ nx serve my-lit-app ## Create a Library {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Let's create a library that our Lit application is going to consume. To create a new library, install the `@nx/js` package and run: diff --git a/docs/shared/recipes/add-stack/add-qwik.md b/docs/shared/recipes/add-stack/add-qwik.md index 7eb2c36abade8..66834e82474e2 100644 --- a/docs/shared/recipes/add-stack/add-qwik.md +++ b/docs/shared/recipes/add-stack/add-qwik.md @@ -61,7 +61,7 @@ If you need help finding the version of `nx` you are currently using, run `nx re Let's generate a new application using `qwik-nx`. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell @@ -73,7 +73,7 @@ nx g qwik-nx:app todo --directory=apps/todo Let's generate a new library using `qwik-nx`. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-rust.md b/docs/shared/recipes/add-stack/add-rust.md index 8431b40a3f621..a0e5994379799 100644 --- a/docs/shared/recipes/add-stack/add-rust.md +++ b/docs/shared/recipes/add-stack/add-rust.md @@ -61,7 +61,7 @@ Using the preset provided by `@monodon/rust` will: Let's generate a new application using `@monodon/rust`. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell @@ -73,7 +73,7 @@ nx g @monodon/rust:binary myapp --directory=apps/myapp Let's generate a new library using `@monodon/rust`. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-solid.md b/docs/shared/recipes/add-stack/add-solid.md index 070677c6f0391..1158d8c300807 100644 --- a/docs/shared/recipes/add-stack/add-solid.md +++ b/docs/shared/recipes/add-stack/add-solid.md @@ -54,7 +54,7 @@ pnpm i --save-dev @nx/web solid-devtools vite-plugin-solid ## Create an Application {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} We'll start with a web application and then tweak the settings to match what we need. Add a new web application to your @@ -233,7 +233,7 @@ You can now run `nx serve my-solid-app` and your Solid application can be viewed ## Create a Library {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Let's create a library that our Solid application is going to consume. To create a new library, install the `@nx/js` diff --git a/docs/shared/recipes/add-stack/add-svelte.md b/docs/shared/recipes/add-stack/add-svelte.md index 6dc35e18712e1..5415fab956574 100644 --- a/docs/shared/recipes/add-stack/add-svelte.md +++ b/docs/shared/recipes/add-stack/add-svelte.md @@ -274,7 +274,7 @@ Navigate to `http://localhost:4200` and you should see your application. Instead of having our Counter directly defined in `App.svelte` file, let's create a library that we can import into our application. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/add-stack/add-vue.md b/docs/shared/recipes/add-stack/add-vue.md index b9a471d9ca4a8..2bc87f1461e94 100644 --- a/docs/shared/recipes/add-stack/add-vue.md +++ b/docs/shared/recipes/add-stack/add-vue.md @@ -240,7 +240,7 @@ nx serve acme Instead of having our Counter directly defined in the app we can instead create a library that exports the Counter component. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Create a new library `nx generate @nx/js:library --name=Counter --directory=libs/counter --unitTestRunner=vitest --bundler=vite --importPath=@acme/counter` diff --git a/docs/shared/recipes/deployment/deno-deploy.md b/docs/shared/recipes/deployment/deno-deploy.md index 5b2ce65700ff5..91ed201f43d7b 100644 --- a/docs/shared/recipes/deployment/deno-deploy.md +++ b/docs/shared/recipes/deployment/deno-deploy.md @@ -43,7 +43,7 @@ pnpm add -D @nx/deno {% /tabs %} {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Then generate a new Deno app with the following command: diff --git a/docs/shared/recipes/deployment/deno-netlify-edge-functions.md b/docs/shared/recipes/deployment/deno-netlify-edge-functions.md index 4d6e000cc0261..1194f1a5b76c3 100644 --- a/docs/shared/recipes/deployment/deno-netlify-edge-functions.md +++ b/docs/shared/recipes/deployment/deno-netlify-edge-functions.md @@ -41,7 +41,7 @@ pnpm add -D @nx/deno {% /tabs %} {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} Then generate a new Deno app with the following command: diff --git a/docs/shared/recipes/module-federation/federate-a-module.md b/docs/shared/recipes/module-federation/federate-a-module.md index eb2db17cc9c23..7c4ca1c604d16 100644 --- a/docs/shared/recipes/module-federation/federate-a-module.md +++ b/docs/shared/recipes/module-federation/federate-a-module.md @@ -46,14 +46,14 @@ Now that we have created the module, we need to configure it to be federated. {%tab label="React"%} ```shell -nx generate @nx/react:federate-module Hello --remote=greeting --path=hello/src/index.ts --projectNameAndRootFormat=as-provided +nx generate @nx/react:federate-module hello/src/index.ts --name=hello --remote=greeting --projectNameAndRootFormat=as-provided ``` {% /tab %} {%tab label="Angular"%} ```shell -nx generate @nx/angular:federate-module Hello --remote=greeting --path=hello/src/index.ts --projectNameAndRootFormat=as-provided +nx generate @nx/angular:federate-module hello/src/index.ts --name=hello --remote=greeting --projectNameAndRootFormat=as-provided ``` {% /tab %} diff --git a/docs/shared/recipes/storybook/one-storybook-for-all.md b/docs/shared/recipes/storybook/one-storybook-for-all.md index 4442814c64494..e29ebedc23097 100644 --- a/docs/shared/recipes/storybook/one-storybook-for-all.md +++ b/docs/shared/recipes/storybook/one-storybook-for-all.md @@ -21,7 +21,7 @@ Let’s see how we can implement this solution: According to the framework you are using, use the corresponding generator to generate a new library. Let’s suppose that you are using React and all your stories are using the `@storybook/react-vite` framework: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/storybook/one-storybook-per-scope.md b/docs/shared/recipes/storybook/one-storybook-per-scope.md index b7832c2cc1421..ada7ed8a97486 100644 --- a/docs/shared/recipes/storybook/one-storybook-per-scope.md +++ b/docs/shared/recipes/storybook/one-storybook-per-scope.md @@ -87,7 +87,7 @@ Let's assume in this case that all our libraries are using Angular. Let's generate three Angular libraries, one for each scope, and let's call them `storybook-host-client`, `storybook-host-admin`, and `storybook-host-shared`. We can do this by running the following commands: {% callout type="note" title="Directory Flag Behavior Changes" %} -The commands below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The commands below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/docs/shared/recipes/storybook/one-storybook-with-composition.md b/docs/shared/recipes/storybook/one-storybook-with-composition.md index 7476c23af6129..f3a2457948ef2 100644 --- a/docs/shared/recipes/storybook/one-storybook-with-composition.md +++ b/docs/shared/recipes/storybook/one-storybook-with-composition.md @@ -29,7 +29,7 @@ We are going to assume that you are at the state where you already have your `st It does not matter which framework you use for the host Storybook library. It can be any framework really, and it does not have to be one of the frameworks that are used in the hosted apps. The only thing that is important is for this host library to have _at least one story_. This is important, or else Storybook will not load. The one story can be a component, for example, which would work like a title for the application, or any other introduction to your Storybook you see fit. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, omit the `--directory` flag. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} So, let’s use React for the Storybook Composition host library: diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 0d6e03b465ca4..0c9772cbd74ed 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -227,7 +227,7 @@ - [Deprecated](/deprecated) - [workspace.json](/deprecated/workspace-json) - [workspace-lint](/deprecated/workspace-lint) - - [workspace-layout](/deprecated/workspace-layout) + - [As Provided vs. Derived](/deprecated/as-provided-vs-derived) - [Workspace Generators](/deprecated/workspace-generators) - [Workspace Executors](/deprecated/workspace-executors) - [defaultCollection](/deprecated/default-collection) diff --git a/e2e/angular-core/src/module-federation.test.ts b/e2e/angular-core/src/module-federation.test.ts index 97f0bde368584..1b1ed145e066b 100644 --- a/e2e/angular-core/src/module-federation.test.ts +++ b/e2e/angular-core/src/module-federation.test.ts @@ -326,7 +326,7 @@ describe('Angular Module Federation', () => { // Federate Module runCLI( - `generate @nx/angular:federate-module ${module} --remote=${remote} --path=${lib}/src/index.ts --no-interactive` + `generate @nx/angular:federate-module ${lib}/src/index.ts --name=${module} --remote=${remote} --no-interactive` ); updateFile(`${lib}/src/index.ts`, `export { isEven } from './lib/${lib}';`); @@ -403,7 +403,7 @@ describe('Angular Module Federation', () => { // Federate Module runCLI( - `generate @nx/angular:federate-module ${module} --remote=${childRemote} --path=${lib}/src/index.ts --no-interactive` + `generate @nx/angular:federate-module ${lib}/src/index.ts --name=${module} --remote=${childRemote} --no-interactive` ); updateFile(`${lib}/src/index.ts`, `export { isEven } from './lib/${lib}';`); diff --git a/e2e/eslint/src/linter.test.ts b/e2e/eslint/src/linter.test.ts index 5eb0bd798df12..4dd88cf44f1f8 100644 --- a/e2e/eslint/src/linter.test.ts +++ b/e2e/eslint/src/linter.test.ts @@ -17,13 +17,6 @@ import { } from '@nx/e2e/utils'; import * as ts from 'typescript'; -/** - * Importing this helper from @typescript-eslint/type-utils to ensure - * compatibility with TS < 4.8 due to the API change in TS4.8. - * This helper allows for support of TS <= 4.8. - */ -import { getModifiers } from '@typescript-eslint/type-utils'; - describe('Linter', () => { describe('Integrated', () => { const myapp = uniq('myapp'); @@ -494,7 +487,7 @@ describe('Linter', () => { `libs/${mylib}/src/lib/${mylib}.ts`, (content) => `import { names } from '@nx/devkit';\n\n` + - content.replace(/return .*;/, `return names(${mylib}).className;`) + content.replace(/=> .*;/, `=> names(${mylib}).className;`) ); // output should now report missing dependency @@ -847,7 +840,7 @@ function updateGeneratedRuleImplementation( ) { return ts.factory.updateMethodDeclaration( node, - getModifiers(node), + node.modifiers, node.asteriskToken, node.name, node.questionToken, diff --git a/e2e/react-core/src/react-module-federation.test.ts b/e2e/react-core/src/react-module-federation.test.ts index 5f8831212c864..cb2bcf6504e69 100644 --- a/e2e/react-core/src/react-module-federation.test.ts +++ b/e2e/react-core/src/react-module-federation.test.ts @@ -475,7 +475,7 @@ describe('React Module Federation', () => { // Federate Module runCLI( - `generate @nx/react:federate-module ${module} --remote=${remote} --path=${lib}/src/index.ts --no-interactive` + `generate @nx/react:federate-module ${lib}/src/index.ts --name=${module} --remote=${remote} --no-interactive` ); updateFile( @@ -566,7 +566,7 @@ describe('React Module Federation', () => { // Federate Module runCLI( - `generate @nx/react:federate-module ${module} --remote=${childRemote} --path=${lib}/src/index.ts --no-interactive` + `generate @nx/react:federate-module ${lib}/src/index.ts --name=${module} --remote=${childRemote} --no-interactive` ); updateFile( diff --git a/package.json b/package.json index 4360d6425879c..00e52eec79d93 100644 --- a/package.json +++ b/package.json @@ -129,10 +129,10 @@ "@types/tmp": "^0.2.0", "@types/yargs": "^17.0.10", "@types/yarnpkg__lockfile": "^1.1.5", - "@typescript-eslint/eslint-plugin": "5.62.0", - "@typescript-eslint/parser": "5.62.0", - "@typescript-eslint/type-utils": "5.60.1", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "@typescript-eslint/type-utils": "^6.9.1", + "@typescript-eslint/utils": "^6.9.1", "@xstate/immer": "0.3.1", "@xstate/inspect": "0.7.0", "@xstate/react": "3.0.1", @@ -222,8 +222,8 @@ "mdast-util-to-markdown": "^1.5.0", "mdast-util-to-string": "^3.2.0", "memfs": "^3.0.1", - "metro-config": "0.76.7", - "metro-resolver": "0.76.7", + "metro-config": "0.76.8", + "metro-resolver": "0.76.8", "mini-css-extract-plugin": "~2.4.7", "minimatch": "3.0.5", "next-sitemap": "^3.1.10", diff --git a/packages/angular/docs/application-examples.md b/packages/angular/docs/application-examples.md index 1da04b4e5bdc5..45f621902c70a 100644 --- a/packages/angular/docs/application-examples.md +++ b/packages/angular/docs/application-examples.md @@ -16,7 +16,7 @@ nx g @nx/angular:application my-app Create an application named `my-app` in the `my-dir` directory and use `scss` for styles: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```bash diff --git a/packages/angular/docs/library-examples.md b/packages/angular/docs/library-examples.md index 4dc7eb33e6930..fe75d44e60554 100644 --- a/packages/angular/docs/library-examples.md +++ b/packages/angular/docs/library-examples.md @@ -35,7 +35,7 @@ nx g @nx/angular:library my-lib --buildable Creates the `my-lib` library in the `nested` directory and sets the import path to `@myorg/nested/my-lib`: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```bash diff --git a/packages/angular/package.json b/packages/angular/package.json index 0d5cff872a5ba..65393147490dc 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -47,7 +47,7 @@ }, "dependencies": { "@phenomnomnominal/tsquery": "~5.0.1", - "@typescript-eslint/type-utils": "^5.36.1", + "@typescript-eslint/type-utils": "^6.9.1", "chalk": "^4.1.0", "find-cache-dir": "^3.3.2", "ignore": "^5.0.4", diff --git a/packages/angular/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/angular/src/generators/application/__snapshots__/application.spec.ts.snap index ca8234587f71e..d7c8e0b891959 100644 --- a/packages/angular/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/angular/src/generators/application/__snapshots__/application.spec.ts.snap @@ -302,16 +302,9 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh }, }, "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "apps/my-dir/my-app/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", @@ -546,16 +539,9 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh }, }, "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "apps/my-app/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", @@ -1005,16 +991,9 @@ exports[`app nested should create project configs 1`] = ` }, }, "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "my-dir/my-app/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", @@ -1163,16 +1142,9 @@ exports[`app not nested should create project configs 1`] = ` }, }, "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "my-app/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", diff --git a/packages/angular/src/generators/federate-module/schema.json b/packages/angular/src/generators/federate-module/schema.json index d586d263da808..49caf7c66f0e6 100644 --- a/packages/angular/src/generators/federate-module/schema.json +++ b/packages/angular/src/generators/federate-module/schema.json @@ -12,22 +12,22 @@ ], "type": "object", "properties": { - "name": { - "description": "The name of the module.", + "path": { "type": "string", "$default": { "$source": "argv", "index": 0 }, + "description": "The path to locate the federated module.", + "x-prompt": "What is the path to the module to be federated?" + }, + "name": { + "description": "The name of the module.", + "type": "string", "x-prompt": "What name would you like to use for the module?", "pattern": "^[a-zA-Z][^:]*$", "x-priority": "important" }, - "path": { - "type": "string", - "description": "The path to locate the federated module.", - "x-prompt": "What is the path to the module to be federated?" - }, "remote": { "type": "string", "description": "The name of the remote.", diff --git a/packages/angular/src/generators/ng-add/migrators/projects/app.migrator.spec.ts b/packages/angular/src/generators/ng-add/migrators/projects/app.migrator.spec.ts index 93c0d0deedc41..8e58b23884017 100644 --- a/packages/angular/src/generators/ng-add/migrators/projects/app.migrator.spec.ts +++ b/packages/angular/src/generators/ng-add/migrators/projects/app.migrator.spec.ts @@ -1624,7 +1624,6 @@ describe('app migrator', () => { ).toStrictEqual([ 'build', 'lint', - 'test', 'e2e', 'myCustomTest', 'myCustomLint', @@ -1657,7 +1656,7 @@ describe('app migrator', () => { const { targetDefaults } = readNxJson(tree); expect( Object.keys(targetDefaults).filter((f) => targetDefaults[f].cache) - ).toStrictEqual(['build', 'lint', 'test', 'e2e', 'myCustomTest']); + ).toStrictEqual(['build', 'lint', 'e2e', 'myCustomTest']); }); }); }); diff --git a/packages/angular/src/generators/ng-add/migrators/projects/lib.migrator.spec.ts b/packages/angular/src/generators/ng-add/migrators/projects/lib.migrator.spec.ts index 302520deb51ad..68d1ebf7c952c 100644 --- a/packages/angular/src/generators/ng-add/migrators/projects/lib.migrator.spec.ts +++ b/packages/angular/src/generators/ng-add/migrators/projects/lib.migrator.spec.ts @@ -1280,7 +1280,6 @@ describe('lib migrator', () => { ).toStrictEqual([ 'build', 'lint', - 'test', 'e2e', 'myCustomBuild', 'myCustomTest', @@ -1307,7 +1306,7 @@ describe('lib migrator', () => { const { targetDefaults } = readNxJson(tree); expect( Object.keys(targetDefaults).filter((f) => targetDefaults[f].cache) - ).toStrictEqual(['build', 'lint', 'test', 'e2e', 'myCustomTest']); + ).toStrictEqual(['build', 'lint', 'e2e', 'myCustomTest']); }); }); }); diff --git a/packages/angular/src/generators/utils/insert-ngmodule-import.ts b/packages/angular/src/generators/utils/insert-ngmodule-import.ts index 64f51c704716d..f7debaf22dbc2 100644 --- a/packages/angular/src/generators/utils/insert-ngmodule-import.ts +++ b/packages/angular/src/generators/utils/insert-ngmodule-import.ts @@ -211,7 +211,7 @@ function findPropertyAssignment( ) as PropertyAssignment; } -let tsUtils: typeof import('@typescript-eslint/type-utils'); -function getTsEsLintTypeUtils(): typeof import('@typescript-eslint/type-utils') { +let tsUtils; +function getTsEsLintTypeUtils() { return tsUtils ?? require('@typescript-eslint/type-utils'); } diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts index 712a477d7b15e..70a59248deadd 100644 --- a/packages/create-nx-workspace/bin/create-nx-workspace.ts +++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts @@ -240,7 +240,6 @@ function normalizeAndWarnOnDeprecatedPreset( return async (args: yargs.Arguments): Promise => { if (!args.preset) return; if (deprecatedPresets[args.preset]) { - args.preset = deprecatedPresets[args.preset] as Preset; output.addVerticalSeparator(); output.note({ title: `The "${args.preset}" preset is deprecated.`, @@ -252,6 +251,7 @@ function normalizeAndWarnOnDeprecatedPreset( }" preset instead.`, ], }); + args.preset = deprecatedPresets[args.preset] as Preset; } }; } diff --git a/packages/detox/src/generators/application/files/app/jest.config.json.template b/packages/detox/src/generators/application/files/app/jest.config.json.template index 87dcb17a3ce8b..8a1f3a0057729 100644 --- a/packages/detox/src/generators/application/files/app/jest.config.json.template +++ b/packages/detox/src/generators/application/files/app/jest.config.json.template @@ -12,5 +12,12 @@ "reporters": ["detox/runners/jest/reporter"], "testEnvironment": "detox/runners/jest/testEnvironment", "verbose": true, - "setupFilesAfterEnv": ["/test-setup.ts"] + "setupFilesAfterEnv": ["/test-setup.ts"], + "transform": { + "^.+\\.(ts|js|html)$": [ + "ts-jest", + { "tsconfig": "/tsconfig.e2e.json" } + ] + } + } diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts new file mode 100644 index 0000000000000..6da602909df21 --- /dev/null +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.spec.ts @@ -0,0 +1,447 @@ +import { Tree } from 'nx/src/generators/tree'; +import { CreateNodes } from 'nx/src/utils/nx-plugin'; +import { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace'; +import { + addProjectConfiguration, + readProjectConfiguration, +} from 'nx/src/generators/utils/project-configuration'; + +import { replaceProjectConfigurationsWithPlugin } from './replace-project-configuration-with-plugin'; + +describe('replaceProjectConfigurationsWithPlugin', () => { + let tree: Tree; + let createNodes: CreateNodes; + + beforeEach(async () => { + tree = createTreeWithEmptyWorkspace(); + tree.write('proj/file.txt', ''); + createNodes = [ + 'proj/file.txt', + () => ({ + projects: { + proj: { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + dependsOn: ['^build-base'], + inputs: ['default', '^default'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + configurations: { + production: { + configFile: 'file.prod.txt', + }, + }, + }, + }, + }, + }, + }), + ]; + }); + + it('should not update the target when it uses a different executor', async () => { + const buildTarget = { + executor: 'nx:run-script', + inputs: ['default', '^default'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + }; + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: buildTarget, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual( + buildTarget + ); + }); + + describe('options', () => { + it('should be removed when there are no other options', async () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: ['default', '^default'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect( + readProjectConfiguration(tree, 'proj').targets.build + ).toBeUndefined(); + }); + + it('should not be removed when there are other options', async () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: ['default', '^default'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + watch: false, + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + options: { + watch: false, + }, + }); + }); + }); + + describe('inputs', () => { + it('should not be removed if there are additional inputs', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: ['default', '^default', '{workspaceRoot}/file.txt'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + inputs: ['default', '^default', '{workspaceRoot}/file.txt'], + }); + }); + + it('should not be removed if there are additional inputs which are objects', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: [ + 'default', + '^default', + { + env: 'HOME', + }, + ], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + inputs: [ + 'default', + '^default', + { + env: 'HOME', + }, + ], + }); + }); + + it('should not be removed if there are less inputs', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: ['default'], + outputs: ['{options.output}', '{projectRoot}/outputs'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + inputs: ['default'], + }); + }); + }); + + describe('outputs', () => { + it('should not be removed if there are additional outputs', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + inputs: ['default', '^default'], + outputs: [ + '{options.output}', + '{projectRoot}/outputs', + '{projectRoot}/more-outputs', + ], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + outputs: [ + '{options.output}', + '{projectRoot}/outputs', + '{projectRoot}/more-outputs', + ], + }); + }); + + it('should not be removed if there are less outputs', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + outputs: ['{options.output}'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + outputs: ['{options.output}'], + }); + }); + }); + + describe('dependsOn', () => { + it('should be removed when it is the same', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + dependsOn: ['^build-base'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect( + readProjectConfiguration(tree, 'proj').targets.build + ).toBeUndefined(); + }); + + it('should not be removed when there are more dependent tasks', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + dependsOn: ['^build-base', 'prebuild'], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + dependsOn: ['^build-base', 'prebuild'], + }); + }); + + it('should not be removed when there are less dependent tasks', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + dependsOn: [], + options: { + configFile: 'file.txt', + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + dependsOn: [], + }); + }); + }); + + describe('defaultConfiguration', () => { + it('should not be removed when the defaultConfiguration is different', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + options: { + configFile: 'file.txt', + }, + defaultConfiguration: 'other', + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + defaultConfiguration: 'other', + }); + }); + }); + + describe('configurations', () => { + it('should not be removed when an additional configuration is defined', () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: { + executor: 'nx:run-commands', + options: { + configFile: 'file.txt', + }, + configurations: { + other: { + configFile: 'other-file.txt', + }, + }, + }, + }, + }); + + replaceProjectConfigurationsWithPlugin( + tree, + new Map([['proj', 'proj']]), + 'plugin-path', + createNodes, + {} + ); + + expect(readProjectConfiguration(tree, 'proj').targets.build).toEqual({ + configurations: { + other: { + configFile: 'other-file.txt', + }, + }, + }); + }); + }); +}); diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts new file mode 100644 index 0000000000000..fc3aedcae3975 --- /dev/null +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts @@ -0,0 +1,206 @@ +import type { + ProjectConfiguration, + TargetConfiguration, +} from 'nx/src/config/workspace-json-project-json'; +import type { Tree } from 'nx/src/generators/tree'; +import type { CreateNodes } from 'nx/src/utils/nx-plugin'; +import { requireNx } from '../../nx'; +const { + readNxJson, + updateNxJson, + glob, + hashObject, + findProjectForPath, + readProjectConfiguration, + updateProjectConfiguration, +} = requireNx(); + +export function replaceProjectConfigurationsWithPlugin( + tree: Tree, + rootMappings: Map, + pluginPath: string, + createNodes: CreateNodes, + pluginOptions: T +): void { + const nxJson = readNxJson(tree); + const hasPlugin = nxJson.plugins?.some((p) => + typeof p === 'string' ? p === pluginPath : p.plugin === pluginPath + ); + + if (hasPlugin) { + return; + } + + nxJson.plugins ??= []; + nxJson.plugins.push({ + plugin: pluginPath, + options: pluginOptions, + }); + updateNxJson(tree, nxJson); + + const [pluginGlob, createNodesFunction] = createNodes; + const configFiles = glob(tree, [pluginGlob]); + + for (const configFile of configFiles) { + try { + const projectName = findProjectForPath(configFile, rootMappings); + const projectConfig = readProjectConfiguration(tree, projectName); + const nodes = createNodesFunction(configFile, pluginOptions, { + workspaceRoot: tree.root, + nxJsonConfiguration: readNxJson(tree), + }); + const node = nodes.projects[Object.keys(nodes.projects)[0]]; + + for (const [targetName, targetConfig] of Object.entries(node.targets)) { + const targetFromProjectConfig = projectConfig.targets[targetName]; + + if (targetFromProjectConfig.executor !== targetConfig.executor) { + continue; + } + + const targetFromCreateNodes = node.targets[targetName]; + + removeConfigurationDefinedByPlugin( + targetName, + targetFromProjectConfig, + targetFromCreateNodes, + projectConfig + ); + } + + updateProjectConfiguration(tree, projectName, projectConfig); + } catch (e) { + console.error(e); + } + } +} + +function removeConfigurationDefinedByPlugin( + targetName: string, + targetFromProjectConfig: TargetConfiguration, + targetFromCreateNodes: TargetConfiguration, + projectConfig: ProjectConfiguration +) { + // Executor + delete targetFromProjectConfig.executor; + + // Default Configuration + if ( + targetFromProjectConfig.defaultConfiguration === + targetFromCreateNodes.defaultConfiguration + ) { + delete targetFromProjectConfig.defaultConfiguration; + } + + // Cache + if (targetFromProjectConfig.cache === targetFromCreateNodes.cache) { + delete targetFromProjectConfig.cache; + } + + // Depends On + if ( + targetFromProjectConfig.dependsOn && + shouldRemoveArrayProperty( + targetFromProjectConfig.dependsOn, + targetFromCreateNodes.dependsOn + ) + ) { + delete targetFromProjectConfig.dependsOn; + } + + // Outputs + if ( + targetFromProjectConfig.outputs && + shouldRemoveArrayProperty( + targetFromProjectConfig.outputs, + targetFromCreateNodes.outputs + ) + ) { + delete targetFromProjectConfig.outputs; + } + + // Inputs + if ( + targetFromProjectConfig.inputs && + shouldRemoveArrayProperty( + targetFromProjectConfig.inputs, + targetFromCreateNodes.inputs + ) + ) { + delete targetFromProjectConfig.inputs; + } + + // Options + for (const [optionName, optionValue] of Object.entries( + targetFromProjectConfig.options ?? {} + )) { + if (targetFromCreateNodes.options[optionName] === optionValue) { + delete targetFromProjectConfig.options[optionName]; + } + } + if (Object.keys(targetFromProjectConfig.options).length === 0) { + delete targetFromProjectConfig.options; + } + + // Configurations + for (const [configName, configOptions] of Object.entries( + targetFromProjectConfig.configurations ?? {} + )) { + for (const [optionName, optionValue] of Object.entries(configOptions)) { + if ( + targetFromCreateNodes.configurations?.[configName]?.[optionName] === + optionValue + ) { + delete targetFromProjectConfig.configurations[configName][optionName]; + } + } + if (Object.keys(configOptions).length === 0) { + delete targetFromProjectConfig.configurations[configName]; + } + } + if (Object.keys(targetFromProjectConfig.configurations ?? {}).length === 0) { + delete targetFromProjectConfig.configurations; + } + + if (Object.keys(targetFromProjectConfig).length === 0) { + delete projectConfig.targets[targetName]; + } +} + +function shouldRemoveArrayProperty( + arrayValuesFromProjectConfiguration: (object | string)[], + arrayValuesFromCreateNodes: (object | string)[] +) { + const setOfArrayValuesFromProjectConfiguration = new Set( + arrayValuesFromProjectConfiguration + ); + loopThroughArrayValuesFromCreateNodes: for (const arrayValueFromCreateNodes of arrayValuesFromCreateNodes) { + if (typeof arrayValueFromCreateNodes === 'string') { + if ( + !setOfArrayValuesFromProjectConfiguration.has(arrayValueFromCreateNodes) + ) { + // If the inputs from the project configuration is missing an input from createNodes it was removed + return false; + } else { + setOfArrayValuesFromProjectConfiguration.delete( + arrayValueFromCreateNodes + ); + } + } else { + for (const arrayValue of setOfArrayValuesFromProjectConfiguration.values()) { + if ( + typeof arrayValue !== 'string' && + hashObject(arrayValue) === hashObject(arrayValueFromCreateNodes) + ) { + setOfArrayValuesFromProjectConfiguration.delete(arrayValue); + // Continue the outer loop, breaking out of this loop + continue loopThroughArrayValuesFromCreateNodes; + } + } + // If an input was not matched, that means the input was removed + return false; + } + } + // If there are still inputs in the project configuration, they have added additional inputs + return setOfArrayValuesFromProjectConfiguration.size === 0; +} diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 4099dce24ac6b..a50fee04c6b62 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -24,7 +24,7 @@ }, "homepage": "https://nx.dev", "peerDependencies": { - "@typescript-eslint/parser": "^5.60.1", + "@typescript-eslint/parser": "^6.9.1", "eslint-config-prettier": "^9.0.0" }, "peerDependenciesMeta": { @@ -35,8 +35,8 @@ "dependencies": { "@nx/devkit": "file:../devkit", "@nx/js": "file:../js", - "@typescript-eslint/type-utils": "^5.60.1", - "@typescript-eslint/utils": "^5.60.1", + "@typescript-eslint/type-utils": "^6.9.1", + "@typescript-eslint/utils": "^6.9.1", "chalk": "^4.1.0", "confusing-browser-globals": "^1.0.9", "jsonc-eslint-parser": "^2.1.0", diff --git a/packages/eslint-plugin/src/configs/react-base.ts b/packages/eslint-plugin/src/configs/react-base.ts index 892760cd1fcf9..791a4377b5492 100644 --- a/packages/eslint-plugin/src/configs/react-base.ts +++ b/packages/eslint-plugin/src/configs/react-base.ts @@ -8,7 +8,7 @@ * This configuration is intended to be combined with other configs from this * package. */ -import * as restrictedGlobals from 'confusing-browser-globals'; +import restrictedGlobals from 'confusing-browser-globals'; /** * Rule set originally adapted from: diff --git a/packages/eslint-plugin/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.spec.ts b/packages/eslint-plugin/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.spec.ts index d39970c561796..f75974eea62df 100644 --- a/packages/eslint-plugin/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.spec.ts +++ b/packages/eslint-plugin/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.spec.ts @@ -71,15 +71,13 @@ describe('update-16-0-0-add-nx-packages', () => { expect(tree.read('ignored-file.ts').toString()).toMatchInlineSnapshot(` "// eslint-disable-next-line @nx/enforce-module-boundaries - /* - * eslint-disable @nx/enforce-module-boundaries - */ - // eslint-disable-line @nx/enforce-module-boundaries - " - `); - expect(tree.read('plugin.ts').toString()).toMatchInlineSnapshot(` - "import * as p from '@nrwl/nx-plugin'; - " + /* + * eslint-disable @nx/enforce-module-boundaries + */ + // eslint-disable-line @nx/enforce-module-boundaries" `); + expect(tree.read('plugin.ts').toString()).toMatchInlineSnapshot( + `"import * as p from '@nrwl/nx-plugin'"` + ); }); }); diff --git a/packages/eslint-plugin/src/rules/dependency-checks.ts b/packages/eslint-plugin/src/rules/dependency-checks.ts index 190ef955d40d4..5bbca10f71466 100644 --- a/packages/eslint-plugin/src/rules/dependency-checks.ts +++ b/packages/eslint-plugin/src/rules/dependency-checks.ts @@ -4,8 +4,6 @@ import { AST } from 'jsonc-eslint-parser'; import { type JSONLiteral } from 'jsonc-eslint-parser/lib/parser/ast'; import { normalizePath, workspaceRoot } from '@nx/devkit'; import { findNpmDependencies } from '@nx/js/src/utils/find-npm-dependencies'; - -import { createESLintRule } from '../utils/create-eslint-rule'; import { readProjectGraph } from '../utils/project-graph-utils'; import { findProject, getSourceFilePath } from '../utils/runtime-lint-utils'; import { @@ -13,6 +11,8 @@ import { getPackageJson, getProductionDependencies, } from '../utils/package-json-utils'; +import type { RuleModule } from '@typescript-eslint/utils/ts-eslint'; +import { ESLintUtils } from '@typescript-eslint/utils'; export type Options = [ { @@ -34,13 +34,13 @@ export type MessageIds = export const RULE_NAME = 'dependency-checks'; -export default createESLintRule({ +export default ESLintUtils.RuleCreator(() => ``)({ name: RULE_NAME, meta: { type: 'suggestion', docs: { description: `Checks dependencies in project's package.json for version mismatches`, - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [ diff --git a/packages/eslint-plugin/src/rules/enforce-module-boundaries.ts b/packages/eslint-plugin/src/rules/enforce-module-boundaries.ts index b69fefad88f3d..93e49a406687e 100644 --- a/packages/eslint-plugin/src/rules/enforce-module-boundaries.ts +++ b/packages/eslint-plugin/src/rules/enforce-module-boundaries.ts @@ -8,15 +8,16 @@ import { import { isRelativePath } from 'nx/src/utils/fileutils'; import { checkCircularPath, - findFilesWithDynamicImports, findFilesInCircularPath, + findFilesWithDynamicImports, } from '../utils/graph-utils'; import { + appIsMFERemote, DepConstraint, findConstraintsFor, findDependenciesWithTags, - findProjectUsingImport, findProject, + findProjectUsingImport, findTransitiveExternalDependencies, getSourceFilePath, getTargetProjectBasedOnRelativeImport, @@ -27,12 +28,11 @@ import { hasNoneOfTheseTags, isAbsoluteImportIntoAnotherProject, isAngularSecondaryEntrypoint, + isComboDepConstraint, isDirectDependency, matchImportWithWildcard, onlyLoadChildren, stringifyTags, - isComboDepConstraint, - appIsMFERemote, } from '../utils/runtime-lint-utils'; import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; import { basename, dirname, relative } from 'path'; @@ -41,8 +41,9 @@ import { getBarrelEntryPointProjectNode, getRelativeImportPath, } from '../utils/ast-utils'; -import { createESLintRule } from '../utils/create-eslint-rule'; import { readProjectGraph } from '../utils/project-graph-utils'; +import type { RuleModule } from '@typescript-eslint/utils/ts-eslint'; +import { ESLintUtils } from '@typescript-eslint/utils'; type Options = [ { @@ -73,13 +74,13 @@ export type MessageIds = | 'notTagsConstraintViolation'; export const RULE_NAME = 'enforce-module-boundaries'; -export default createESLintRule({ +export default ESLintUtils.RuleCreator(() => ``)({ name: RULE_NAME, meta: { type: 'suggestion', docs: { description: `Ensure that module boundaries are respected within the monorepo`, - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [ diff --git a/packages/eslint-plugin/src/rules/nx-plugin-checks.ts b/packages/eslint-plugin/src/rules/nx-plugin-checks.ts index 8d56062ad2c54..ea0b5eb9660cb 100644 --- a/packages/eslint-plugin/src/rules/nx-plugin-checks.ts +++ b/packages/eslint-plugin/src/rules/nx-plugin-checks.ts @@ -1,5 +1,6 @@ import type { AST } from 'jsonc-eslint-parser'; import type { TSESLint } from '@typescript-eslint/utils'; +import { ESLintUtils } from '@typescript-eslint/utils'; import { ProjectGraphProjectNode, @@ -10,11 +11,9 @@ import { findProject, getSourceFilePath } from '../utils/runtime-lint-utils'; import { existsSync } from 'fs'; import { registerTsProject } from '@nx/js/src/internal'; import * as path from 'path'; - -import { createESLintRule } from '../utils/create-eslint-rule'; +import { join } from 'path'; import { readProjectGraph } from '../utils/project-graph-utils'; import { valid } from 'semver'; -import { join } from 'path'; type Options = [ { @@ -49,12 +48,12 @@ export type MessageIds = export const RULE_NAME = 'nx-plugin-checks'; -export default createESLintRule({ +export default ESLintUtils.RuleCreator(() => ``)({ name: RULE_NAME, meta: { docs: { description: 'Checks common nx-plugin configuration files for validity', - recommended: 'error', + recommended: 'recommended', }, schema: [ { diff --git a/packages/eslint-plugin/src/utils/create-eslint-rule.ts b/packages/eslint-plugin/src/utils/create-eslint-rule.ts deleted file mode 100644 index 68b7c15a666be..0000000000000 --- a/packages/eslint-plugin/src/utils/create-eslint-rule.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; - -export const createESLintRule = ESLintUtils.RuleCreator(() => ``); diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 58bd2c97a66f5..214f415f98425 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { + "moduleResolution": "node16", + "module": "node16", "types": ["node", "jest"] }, "include": [], diff --git a/packages/eslint-plugin/tsconfig.lib.json b/packages/eslint-plugin/tsconfig.lib.json index 1d2ddef3c1be3..fbc2a0755e458 100644 --- a/packages/eslint-plugin/tsconfig.lib.json +++ b/packages/eslint-plugin/tsconfig.lib.json @@ -1,7 +1,6 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "module": "commonjs", "outDir": "../../dist/out-tsc", "declaration": true, "types": ["node"] diff --git a/packages/eslint-plugin/tsconfig.spec.json b/packages/eslint-plugin/tsconfig.spec.json index 869c90c526a0f..a358285f72011 100644 --- a/packages/eslint-plugin/tsconfig.spec.json +++ b/packages/eslint-plugin/tsconfig.spec.json @@ -2,7 +2,6 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "module": "commonjs", "types": ["jest", "node"] }, "include": [ diff --git a/packages/eslint/migrations.json b/packages/eslint/migrations.json index 011866d8c0102..c2bc56b4a04f6 100644 --- a/packages/eslint/migrations.json +++ b/packages/eslint/migrations.json @@ -27,6 +27,11 @@ "version": "17.0.0-beta.7", "description": "update-17-0-0-rename-to-eslint", "implementation": "./src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint" + }, + "update-typescript-eslint": { + "version": "17.1.0-beta.1", + "description": "Updates for @typescript-utils/utils v6.9.1+", + "implementation": "./src/migrations/update-17-1-0/update-typescript-eslint" } }, "packageJsonUpdates": { @@ -82,6 +87,20 @@ "version": "^9.0.0" } } + }, + "17.1.0": { + "version": "17.1.0-beta.1", + "packages": { + "@typescript-eslint/parser": { + "version": "^6.9.1" + }, + "@typescript-eslint/eslint-plugin": { + "version": "^6.9.1" + }, + "@typescript-eslint/utils": { + "version": "^6.9.1" + } + } } } } diff --git a/packages/eslint/src/executors/lint/lint.impl.spec.ts b/packages/eslint/src/executors/lint/lint.impl.spec.ts index 96a2cef593597..7fa694129dc77 100644 --- a/packages/eslint/src/executors/lint/lint.impl.spec.ts +++ b/packages/eslint/src/executors/lint/lint.impl.spec.ts @@ -70,6 +70,7 @@ function createValidRunBuilderOptions( resolvePluginsRelativeTo: null, reportUnusedDisableDirectives: null, printConfig: null, + errorOnUnmatchedPattern: true, ...additionalOptions, }; } @@ -212,6 +213,34 @@ describe('Linter Builder', () => { mockIsPathIgnored.mockReturnValue(Promise.resolve(false)); }); + it('should not throw if no reports generated and errorOnUnmatchedPattern is false', async () => { + mockReports = []; + setupMocks(); + const result = lintExecutor( + createValidRunBuilderOptions({ + lintFilePatterns: ['includedFile1'], + errorOnUnmatchedPattern: false, + }), + mockContext + ); + await expect(result).resolves.not.toThrow(); + }); + + it('should not throw if pattern excluded and errorOnUnmatchedPattern is false', async () => { + mockReports = []; + setupMocks(); + mockIsPathIgnored.mockReturnValue(Promise.resolve(true)); + const result = lintExecutor( + createValidRunBuilderOptions({ + lintFilePatterns: ['includedFile1'], + errorOnUnmatchedPattern: false, + }), + mockContext + ); + await expect(result).resolves.not.toThrow(); + mockIsPathIgnored.mockReturnValue(Promise.resolve(false)); + }); + it('should create a new instance of the formatter with the selected user option', async () => { setupMocks(); await lintExecutor( diff --git a/packages/eslint/src/executors/lint/lint.impl.ts b/packages/eslint/src/executors/lint/lint.impl.ts index e4953f806ef7d..c6c6f2fa7ee9d 100644 --- a/packages/eslint/src/executors/lint/lint.impl.ts +++ b/packages/eslint/src/executors/lint/lint.impl.ts @@ -39,7 +39,8 @@ export default async function run( ? joinPathFragments(options.cacheLocation, projectName) : undefined; - const { printConfig, ...normalizedOptions } = options; + const { printConfig, errorOnUnmatchedPattern, ...normalizedOptions } = + options; /** * Until ESLint v9 is released and the new so called flat config is the default @@ -119,7 +120,7 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this throw err; } - if (lintResults.length === 0) { + if (lintResults.length === 0 && errorOnUnmatchedPattern) { const ignoredPatterns = ( await Promise.all( normalizedOptions.lintFilePatterns.map(async (pattern) => diff --git a/packages/eslint/src/executors/lint/schema.d.ts b/packages/eslint/src/executors/lint/schema.d.ts index 75f3383d2041d..99a3c7d013942 100644 --- a/packages/eslint/src/executors/lint/schema.d.ts +++ b/packages/eslint/src/executors/lint/schema.d.ts @@ -21,6 +21,7 @@ export interface Schema extends JsonObject { resolvePluginsRelativeTo: string | null; reportUnusedDisableDirectives: Linter.StringSeverity | null; printConfig?: string | null; + errorOnUnmatchedPattern?: boolean; } type Formatter = diff --git a/packages/eslint/src/executors/lint/schema.json b/packages/eslint/src/executors/lint/schema.json index ea840b69df8e3..13925b8339a43 100644 --- a/packages/eslint/src/executors/lint/schema.json +++ b/packages/eslint/src/executors/lint/schema.json @@ -137,6 +137,11 @@ "type": "string", "description": "The equivalent of the `--print-config` flag on the ESLint CLI.", "x-completion-type": "file" + }, + "errorOnUnmatchedPattern": { + "type": "boolean", + "description": "When set to false, equivalent of the `--no-error-on-unmatched-pattern` flag on the ESLint CLI.", + "default": true } }, "required": ["lintFilePatterns"], diff --git a/packages/eslint/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap b/packages/eslint/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap index da178f1e17fb6..0b542e8437f21 100644 --- a/packages/eslint/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap +++ b/packages/eslint/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap @@ -28,7 +28,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - recommended: 'error', + recommended: 'recommended', }, schema: [], messages: {}, @@ -84,7 +84,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - recommended: 'error', + recommended: 'recommended', }, schema: [], messages: {}, @@ -140,7 +140,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - recommended: 'error', + recommended: 'recommended', }, schema: [], messages: {}, diff --git a/packages/eslint/src/generators/workspace-rule/files/__name__.ts__tmpl__ b/packages/eslint/src/generators/workspace-rule/files/__name__.ts__tmpl__ index b20a24f002725..5cd2ecf7c6ad4 100644 --- a/packages/eslint/src/generators/workspace-rule/files/__name__.ts__tmpl__ +++ b/packages/eslint/src/generators/workspace-rule/files/__name__.ts__tmpl__ @@ -25,7 +25,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: ``, - recommended: 'error', + recommended: 'recommended', }, schema: [], messages: {}, diff --git a/packages/eslint/src/generators/workspace-rule/workspace-rule.spec.ts b/packages/eslint/src/generators/workspace-rule/workspace-rule.spec.ts index 110ba3783cfaa..1c9468d7ee9d4 100644 --- a/packages/eslint/src/generators/workspace-rule/workspace-rule.spec.ts +++ b/packages/eslint/src/generators/workspace-rule/workspace-rule.spec.ts @@ -1,4 +1,4 @@ -import { NxJsonConfiguration, readJson, Tree } from '@nx/devkit'; +import { Tree } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import { lintWorkspaceRuleGenerator } from './workspace-rule'; diff --git a/packages/eslint/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap b/packages/eslint/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap index d391e2f6eec17..dbc51f509da62 100644 --- a/packages/eslint/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap +++ b/packages/eslint/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap @@ -35,7 +35,8 @@ exports[`@nx/eslint:workspace-rules-project should generate the required files 2 "{ "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "commonjs" + "moduleResolution": "node16", + "module": "node16" }, "files": [], "include": [], @@ -69,7 +70,6 @@ exports[`@nx/eslint:workspace-rules-project should generate the required files 4 "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "module": "commonjs", "types": ["jest", "node"] }, "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] @@ -87,9 +87,6 @@ export default { }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/tools/eslint-rules', - moduleNameMapper: { - '@eslint/eslintrc': '@eslint/eslintrc/dist/eslintrc-universal.cjs', - }, }; " `; diff --git a/packages/eslint/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ b/packages/eslint/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ index 709828769d96e..23c840040a881 100644 --- a/packages/eslint/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ +++ b/packages/eslint/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ @@ -1,7 +1,8 @@ { "extends": "<%= rootTsConfigPath %>", "compilerOptions": { - "module": "commonjs" + "moduleResolution": "node16", + "module": "node16" }, "files": [], "include": [], diff --git a/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.spec.ts b/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.spec.ts index 9368d0e328910..28ca0af39efc6 100644 --- a/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.spec.ts +++ b/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.spec.ts @@ -81,16 +81,9 @@ describe('@nx/eslint:workspace-rules-project', () => { "sourceRoot": "tools/eslint-rules", "targets": { "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "tools/eslint-rules/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", diff --git a/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.ts b/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.ts index bcb39dbaea042..0b9bbaa217a69 100644 --- a/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.ts +++ b/packages/eslint/src/generators/workspace-rules-project/workspace-rules-project.ts @@ -1,12 +1,14 @@ import { + addDependenciesToPackageJson, addProjectConfiguration, ensurePackage, formatFiles, generateFiles, - joinPathFragments, + GeneratorCallback, offsetFromRoot, readNxJson, readProjectConfiguration, + runTasksInSerial, Tree, updateJson, updateNxJson, @@ -14,7 +16,7 @@ import { import { getRelativePathToRootTsConfig } from '@nx/js'; import { addSwcRegisterDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies'; import { join } from 'path'; -import { nxVersion } from '../../utils/versions'; +import { nxVersion, typescriptESLintVersion } from '../../utils/versions'; import { workspaceLintPluginDir } from '../../utils/workspace-lint-rules'; export const WORKSPACE_RULES_PROJECT_NAME = 'eslint-rules'; @@ -29,9 +31,11 @@ export async function lintWorkspaceRulesProjectGenerator( tree: Tree, options: LintWorkspaceRulesProjectGeneratorOptions = {} ) { - const { addPropertyToJestConfig, configurationGenerator } = ensurePackage< - typeof import('@nx/jest') - >('@nx/jest', nxVersion); + const { configurationGenerator } = ensurePackage( + '@nx/jest', + nxVersion + ); + const tasks: GeneratorCallback[] = []; // Noop if the workspace rules project already exists try { @@ -68,19 +72,23 @@ export async function lintWorkspaceRulesProjectGenerator( } // Add jest to the project and return installation task - const installTask = await configurationGenerator(tree, { - project: WORKSPACE_RULES_PROJECT_NAME, - supportTsx: false, - skipSerializers: true, - setupFile: 'none', - compiler: 'tsc', - skipFormat: true, - }); + tasks.push( + await configurationGenerator(tree, { + project: WORKSPACE_RULES_PROJECT_NAME, + supportTsx: false, + skipSerializers: true, + setupFile: 'none', + compiler: 'tsc', + skipFormat: true, + }) + ); updateJson( tree, join(workspaceLintPluginDir, 'tsconfig.spec.json'), (json) => { + delete json.compilerOptions?.module; + if (json.include) { json.include = json.include.map((v) => { if (v.startsWith('src/**')) { @@ -102,21 +110,21 @@ export async function lintWorkspaceRulesProjectGenerator( ); // Add swc dependencies - addSwcRegisterDependencies(tree); - - // Add extra config to the jest.config.ts file to allow ESLint 8 exports mapping to work with jest - addPropertyToJestConfig( - tree, - joinPathFragments(WORKSPACE_PLUGIN_DIR, 'jest.config.ts'), - 'moduleNameMapper', - { - '@eslint/eslintrc': '@eslint/eslintrc/dist/eslintrc-universal.cjs', - } + tasks.push(addSwcRegisterDependencies(tree)); + + tasks.push( + addDependenciesToPackageJson( + tree, + {}, + { + '@typescript-eslint/utils': typescriptESLintVersion, + } + ) ); if (!options.skipFormat) { await formatFiles(tree); } - return installTask; + return runTasksInSerial(...tasks); } diff --git a/packages/eslint/src/migrations/update-17-1-0/__snapshots__/update-typescript-eslint.spec.ts.snap b/packages/eslint/src/migrations/update-17-1-0/__snapshots__/update-typescript-eslint.spec.ts.snap new file mode 100644 index 0000000000000..63db3f321fc8d --- /dev/null +++ b/packages/eslint/src/migrations/update-17-1-0/__snapshots__/update-typescript-eslint.spec.ts.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`update-typescript-eslint migration should update the jest.config.ts 1`] = ` +"/* eslint-disable */ +export default { + displayName: 'eslint-rules', + preset: '../../jest.preset.js', + transform: { + '^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/tools/eslint-rules', + moduleNameMapper: {}, +}; +" +`; + +exports[`update-typescript-eslint migration should update the rules 1`] = ` +"/** + * This file sets you up with structure needed for an ESLint rule. + * + * It leverages utilities from @typescript-eslint to allow TypeScript to + * provide autocompletions etc for the configuration. + * + * Your rule's custom logic will live within the create() method below + * and you can learn more about writing ESLint rules on the official guide: + * + * https://eslint.org/docs/developer-guide/working-with-rules + * + * You can also view many examples of existing rules here: + * + * https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/rules + */ + +import { ESLintUtils } from '@typescript-eslint/utils'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace/lint-rule" +export const RULE_NAME = 'lint-rule'; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + type: 'problem', + docs: { + description: \`\`, + recommended: 'recommended', + }, + schema: [], + messages: {}, + }, + defaultOptions: [], + create(context) { + return {}; + }, +}); +" +`; + +exports[`update-typescript-eslint migration should update the tsconfig.json 1`] = ` +"{ + "compilerOptions": { + "module": "node16", + "moduleResolution": "node16" + } +} +" +`; + +exports[`update-typescript-eslint migration should update the tsconfig.json 2`] = ` +"{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["jest", "node"] + }, + "include": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*_spec.ts", + "**/*_test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx", + "**/*.d.ts", + "jest.config.ts" + ] +} +" +`; diff --git a/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.spec.ts b/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.spec.ts new file mode 100644 index 0000000000000..34bfd3f372c56 --- /dev/null +++ b/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.spec.ts @@ -0,0 +1,127 @@ +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import { Tree, writeJson } from '@nx/devkit'; + +import update from './update-typescript-eslint'; + +describe('update-typescript-eslint migration', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + + writeJson(tree, 'tools/eslint-rules/tsconfig.json', { + compilerOptions: { + module: 'commonjs', + }, + }); + writeJson(tree, 'tools/eslint-rules/tsconfig.spec.json', { + extends: './tsconfig.json', + compilerOptions: { + outDir: '../../dist/out-tsc', + module: 'commonjs', + types: ['jest', 'node'], + }, + include: [ + '**/*.spec.ts', + '**/*.test.ts', + '**/*_spec.ts', + '**/*_test.ts', + '**/*.spec.tsx', + '**/*.test.tsx', + '**/*.spec.js', + '**/*.test.js', + '**/*.spec.jsx', + '**/*.test.jsx', + '**/*.d.ts', + 'jest.config.ts', + ], + }); + + tree.write( + 'tools/eslint-rules/jest.config.ts', + `/* eslint-disable */ +export default { + displayName: 'eslint-rules', + preset: '../../jest.preset.js', + transform: { + '^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/tools/eslint-rules', + moduleNameMapper: { + '@eslint/eslintrc': '@eslint/eslintrc/dist/eslintrc-universal.cjs', + }, +}; +` + ); + + tree.write( + 'tools/eslint-rules/rules/rule.ts', + `/** + * This file sets you up with structure needed for an ESLint rule. + * + * It leverages utilities from @typescript-eslint to allow TypeScript to + * provide autocompletions etc for the configuration. + * + * Your rule's custom logic will live within the create() method below + * and you can learn more about writing ESLint rules on the official guide: + * + * https://eslint.org/docs/developer-guide/working-with-rules + * + * You can also view many examples of existing rules here: + * + * https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/rules + */ + +import { ESLintUtils } from '@typescript-eslint/utils'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace/lint-rule" +export const RULE_NAME = 'lint-rule'; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + type: 'problem', + docs: { + description: \`\`, + recommended: 'error', + }, + schema: [], + messages: {}, + }, + defaultOptions: [], + create(context) { + return {}; + }, +}); +` + ); + }); + + it('should update the tsconfig.json', async () => { + await update(tree); + + expect( + tree.read('tools/eslint-rules/tsconfig.json', 'utf-8') + ).toMatchSnapshot(); + expect( + tree.read('tools/eslint-rules/tsconfig.spec.json', 'utf-8') + ).toMatchSnapshot(); + }); + + it('should update the jest.config.ts', async () => { + await update(tree); + + expect( + tree.read('tools/eslint-rules/jest.config.ts', 'utf-8') + ).toMatchSnapshot(); + }); + + it('should update the rules', async () => { + await update(tree); + + expect( + tree.read('tools/eslint-rules/rules/rule.ts', 'utf-8') + ).toMatchSnapshot(); + }); +}); diff --git a/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.ts b/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.ts new file mode 100644 index 0000000000000..cc2844b62c28e --- /dev/null +++ b/packages/eslint/src/migrations/update-17-1-0/update-typescript-eslint.ts @@ -0,0 +1,107 @@ +import { + applyChangesToString, + ChangeType, + ensurePackage, + formatFiles, + StringChange, + Tree, + updateJson, + visitNotIgnoredFiles, +} from '@nx/devkit'; +import { nxVersion } from '../../utils/versions'; +import { extname } from 'path'; +import { + createSourceFile, + forEachChild, + isIdentifier, + isPropertyAssignment, + isStringLiteral, + type Node, + ScriptTarget, +} from 'typescript'; + +function updateJestConfig(tree: Tree) { + const jestConfigPath = 'tools/eslint-rules/jest.config.ts'; + if (tree.exists(jestConfigPath)) { + const { removePropertyFromJestConfig } = ensurePackage< + typeof import('@nx/jest') + >('@nx/jest', nxVersion); + + removePropertyFromJestConfig(tree, jestConfigPath, [ + 'moduleNameMapper', + '@eslint/eslintrc', + ]); + } +} + +function updateTsConfigs(tree: Tree) { + const tsConfigPath = 'tools/eslint-rules/tsconfig.json'; + if (tree.exists(tsConfigPath)) { + updateJson(tree, tsConfigPath, (tsConfig) => { + tsConfig.compilerOptions ??= {}; + tsConfig.compilerOptions.moduleResolution = 'node16'; + tsConfig.compilerOptions.module = 'node16'; + return tsConfig; + }); + } + const tsConfigSpec = 'tools/eslint-rules/tsconfig.spec.json'; + if (tree.exists(tsConfigSpec)) { + updateJson(tree, tsConfigSpec, (tsConfigSpec) => { + delete tsConfigSpec.compilerOptions?.module; + delete tsConfigSpec.compilerOptions?.moduleResolution; + return tsConfigSpec; + }); + } +} + +function updateRecommended(tree: Tree) { + visitNotIgnoredFiles(tree, 'tools/eslint-rules', (path) => { + if (extname(path) !== '.ts') { + return; + } + + const contents = tree.read(path, 'utf-8'); + const sourceFile = createSourceFile( + path, + contents, + ScriptTarget.ESNext, + true + ); + + const changes: StringChange[] = []; + + const visit = (node: Node) => { + if ( + isPropertyAssignment(node) && + isIdentifier(node.name) && + node.name.text === 'recommended' && + isStringLiteral(node.initializer) + ) { + changes.push({ + type: ChangeType.Delete, + start: node.initializer.getStart(sourceFile), + length: node.initializer.getWidth(sourceFile), + }); + changes.push({ + type: ChangeType.Insert, + index: node.initializer.getStart(sourceFile), + text: "'recommended'", + }); + } else { + forEachChild(node, visit); + } + }; + + forEachChild(sourceFile, visit); + + tree.write(path, applyChangesToString(contents, changes)); + }); +} + +export default async function update(tree: Tree) { + updateJestConfig(tree); + updateTsConfigs(tree); + updateRecommended(tree); + + await formatFiles(tree); +} diff --git a/packages/eslint/src/utils/versions.ts b/packages/eslint/src/utils/versions.ts index f7248ec13c5e2..e646a4ade1438 100644 --- a/packages/eslint/src/utils/versions.ts +++ b/packages/eslint/src/utils/versions.ts @@ -3,4 +3,4 @@ export const nxVersion = require('../../package.json').version; export const eslintVersion = '~8.46.0'; export const eslintrcVersion = '^2.1.1'; export const eslintConfigPrettierVersion = '^9.0.0'; -export const typescriptESLintVersion = '^5.60.1'; +export const typescriptESLintVersion = '^6.9.1'; diff --git a/packages/expo/migrations.json b/packages/expo/migrations.json index caecda8dc8320..5f42f04eea962 100644 --- a/packages/expo/migrations.json +++ b/packages/expo/migrations.json @@ -576,6 +576,35 @@ "alwaysAddToPackageJson": false } } + }, + "17.1.0": { + "version": "17.1.0-beta.0", + "packages": { + "expo": { + "version": "49.0.16", + "alwaysAddToPackageJson": false + }, + "@expo/cli": { + "version": "~0.10.13", + "alwaysAddToPackageJson": false + }, + "react-native": { + "version": "0.72.6", + "alwaysAddToPackageJson": false + }, + "react-native-web": { + "version": "~0.19.9", + "alwaysAddToPackageJson": false + }, + "metro-resolver": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + } + } } } } diff --git a/packages/expo/package.json b/packages/expo/package.json index f1132c184d93c..55dc9d5cfb133 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -29,8 +29,8 @@ "chalk": "^4.1.0", "enhanced-resolve": "^5.8.3", "fs-extra": "^11.1.0", - "metro-config": "0.76.7", - "metro-resolver": "0.76.7", + "metro-config": "~0.76.8", + "metro-resolver": "~0.76.8", "tslib": "^2.3.0", "tsconfig-paths": "^4.1.2", "tsconfig-paths-webpack-plugin": "^4.0.0", diff --git a/packages/expo/src/utils/versions.ts b/packages/expo/src/utils/versions.ts index 64968da743566..22fbef1b4a604 100644 --- a/packages/expo/src/utils/versions.ts +++ b/packages/expo/src/utils/versions.ts @@ -1,10 +1,10 @@ export const nxVersion = require('../../package.json').version; -export const expoVersion = '49.0.10'; +export const expoVersion = '49.0.16'; export const expoMetroConfigVersion = '~0.10.7'; export const expoSplashScreenVersion = '~0.20.5'; export const expoStatusBarVersion = '~1.6.0'; -export const expoCliVersion = '~0.10.12'; // @expo/cli +export const expoCliVersion = '~0.10.13'; // @expo/cli export const easCliVersion = '~5.2.0'; export const babelPresetExpoVersion = '~9.5.2'; @@ -13,13 +13,13 @@ export const reactDomVersion = '18.2.0'; export const reactTestRendererVersion = '18.2.0'; export const typesReactVersion = '18.0.28'; -export const reactNativeVersion = '0.72.4'; -export const reactNativeWebVersion = '~0.19.8'; +export const reactNativeVersion = '0.72.6'; +export const reactNativeWebVersion = '~0.19.9'; export const reactNativeSvgTransformerVersion = '1.0.0'; export const reactNativeSvgVersion = '13.9.0'; -export const metroVersion = '0.76.7'; +export const metroVersion = '0.76.8'; export const testingLibraryReactNativeVersion = '~12.3.0'; export const testingLibraryJestNativeVersion = '~5.4.3'; diff --git a/packages/jest/migrations.json b/packages/jest/migrations.json index d3420bb69af0f..19cbbdaebc217 100644 --- a/packages/jest/migrations.json +++ b/packages/jest/migrations.json @@ -29,6 +29,11 @@ "version": "16.5.0-beta.2", "description": "Add test-setup.ts to ignored files in production input", "implementation": "./src/migrations/update-16-5-0/add-test-setup-to-inputs-ignore" + }, + "move-options-to-target-defaults": { + "version": "17.1.0-beta.2", + "description": "Move jest executor options to nx.json targetDefaults", + "implementation": "./src/migrations/update-17-1-0/move-options-to-target-defaults" } }, "packageJsonUpdates": { diff --git a/packages/jest/src/generators/configuration/__snapshots__/configuration.spec.ts.snap b/packages/jest/src/generators/configuration/__snapshots__/configuration.spec.ts.snap index baf985127967c..efae77a353176 100644 --- a/packages/jest/src/generators/configuration/__snapshots__/configuration.spec.ts.snap +++ b/packages/jest/src/generators/configuration/__snapshots__/configuration.spec.ts.snap @@ -114,16 +114,9 @@ export default { exports[`jestProject should use jest.config.js in project config with --js flag 1`] = ` { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "libs/lib1/jest.config.js", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", diff --git a/packages/jest/src/generators/configuration/configuration.spec.ts b/packages/jest/src/generators/configuration/configuration.spec.ts index 95f2f048498b5..2af6696f8a8b8 100644 --- a/packages/jest/src/generators/configuration/configuration.spec.ts +++ b/packages/jest/src/generators/configuration/configuration.spec.ts @@ -84,13 +84,6 @@ describe('jestProject', () => { outputs: ['{workspaceRoot}/coverage/{projectRoot}'], options: { jestConfig: 'libs/lib1/jest.config.ts', - passWithNoTests: true, - }, - configurations: { - ci: { - ci: true, - codeCoverage: true, - }, }, }); }); diff --git a/packages/jest/src/generators/configuration/lib/update-workspace.ts b/packages/jest/src/generators/configuration/lib/update-workspace.ts index 5f72beba39321..8e1acc8a8a3da 100644 --- a/packages/jest/src/generators/configuration/lib/update-workspace.ts +++ b/packages/jest/src/generators/configuration/lib/update-workspace.ts @@ -28,13 +28,6 @@ export function updateWorkspace( normalizePath(projectConfig.root), `jest.config.${options.js ? 'js' : 'ts'}` ), - passWithNoTests: true, - }, - configurations: { - ci: { - ci: true, - codeCoverage: true, - }, }, }; diff --git a/packages/jest/src/generators/init/init.spec.ts b/packages/jest/src/generators/init/init.spec.ts index 253b0024ccf71..e2eb9f96e03b2 100644 --- a/packages/jest/src/generators/init/init.spec.ts +++ b/packages/jest/src/generators/init/init.spec.ts @@ -79,17 +79,26 @@ export default { const productionFileSet = readJson(tree, 'nx.json') .namedInputs.production; - const testDefaults = readJson(tree, 'nx.json') - .targetDefaults.test; + const jestDefaults = readJson(tree, 'nx.json') + .targetDefaults['@nx/jest:jest']; expect(productionFileSet).toContain( '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)' ); expect(productionFileSet).toContain('!{projectRoot}/tsconfig.spec.json'); expect(productionFileSet).toContain('!{projectRoot}/jest.config.[jt]s'); expect(productionFileSet).toContain('!{projectRoot}/src/test-setup.[jt]s'); - expect(testDefaults).toEqual({ + expect(jestDefaults).toEqual({ cache: true, inputs: ['default', '^production', '{workspaceRoot}/jest.preset.js'], + options: { + passWithNoTests: true, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, }); }); diff --git a/packages/jest/src/generators/init/init.ts b/packages/jest/src/generators/init/init.ts index 6ad8d03a6655c..1757985cfb346 100644 --- a/packages/jest/src/generators/init/init.ts +++ b/packages/jest/src/generators/init/init.ts @@ -64,7 +64,8 @@ function createJestConfig(tree: Tree, options: NormalizedSchema) { module.exports = { ...nxPreset }` ); - addTestInputs(tree); + updateProductionFileSet(tree); + addJestTargetDefaults(tree); } if (options.rootProject) { // we don't want any config to be made because the `configurationGenerator` will do it. @@ -113,7 +114,7 @@ function createJestConfig(tree: Tree, options: NormalizedSchema) { } } -function addTestInputs(tree: Tree) { +function updateProductionFileSet(tree: Tree) { const nxJson = readNxJson(tree); const productionFileSet = nxJson.namedInputs?.production; @@ -135,14 +136,33 @@ function addTestInputs(tree: Tree) { nxJson.namedInputs.production = Array.from(new Set(productionFileSet)); } - // Test targets depend on all their project's sources + production sources of dependencies + updateNxJson(tree, nxJson); +} + +function addJestTargetDefaults(tree: Tree) { + const nxJson = readNxJson(tree); + const productionFileSet = nxJson.namedInputs?.production; + nxJson.targetDefaults ??= {}; - nxJson.targetDefaults.test ??= {}; - nxJson.targetDefaults.test.inputs ??= [ + nxJson.targetDefaults['@nx/jest:jest'] ??= {}; + nxJson.targetDefaults['@nx/jest:jest'].cache ??= true; + + // Test targets depend on all their project's sources + production sources of dependencies + nxJson.targetDefaults['@nx/jest:jest'].inputs ??= [ 'default', productionFileSet ? '^production' : '^default', + '{workspaceRoot}/jest.preset.js', ]; - nxJson.targetDefaults.test.inputs.push('{workspaceRoot}/jest.preset.js'); + + nxJson.targetDefaults['@nx/jest:jest'].options ??= { + passWithNoTests: true, + }; + nxJson.targetDefaults['@nx/jest:jest'].configurations ??= { + ci: { + ci: true, + codeCoverage: true, + }, + }; updateNxJson(tree, nxJson); } diff --git a/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.spec.ts b/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.spec.ts new file mode 100644 index 0000000000000..38e8e15c396a3 --- /dev/null +++ b/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.spec.ts @@ -0,0 +1,562 @@ +import { createTree } from '@nx/devkit/testing'; + +let projectGraph: ProjectGraph; +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: jest.fn().mockImplementation(async () => { + return projectGraph; + }), +})); + +import { + addProjectConfiguration as _addProjectConfiguration, + ProjectGraph, + readNxJson, + readProjectConfiguration, + Tree, + updateNxJson, + writeJson, +} from '@nx/devkit'; + +function addProjectConfiguration(tree, name, project) { + _addProjectConfiguration(tree, name, project); + projectGraph.nodes[name] = { + name: name, + type: 'lib', + data: { + root: project.root, + targets: project.targets, + }, + }; +} + +import update from './move-options-to-target-defaults'; + +describe('move-options-to-target-defaults migration', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTree(); + + writeJson(tree, 'nx.json', { + namedInputs: { + production: ['default'], + }, + targetDefaults: {}, + }); + + projectGraph = { + nodes: {}, + dependencies: {}, + externalNodes: {}, + }; + }); + + it('should add config to nx.json and remove it from projects', async () => { + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + passWithNoTests: true, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + }, + }, + }); + addProjectConfiguration(tree, 'proj2', { + root: 'proj2', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + passWithNoTests: true, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets.test).toEqual({ + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + }, + }); + expect(readProjectConfiguration(tree, 'proj2').targets.test).toEqual({ + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + }); + }); + + it('should use test target defaults if all jest targets are test', async () => { + const nxJson = readNxJson(tree); + nxJson.targetDefaults['test'] = { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: false, + }, + }; + updateNxJson(tree, nxJson); + + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + passWithNoTests: true, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets.test).toEqual({ + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: false, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + passWithNoTests: true, + watch: false, + }, + }, + }); + }); + + it('should not remove config which does not match', async () => { + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + jestConfig: 'jest.config.js', + passWithNoTests: true, + watch: false, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets.test).toEqual({ + executor: '@nx/jest:jest', + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + jestConfig: 'jest.config.js', + watch: false, + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + }); + }); + + it('should not remove defaults if target uses other executors', async () => { + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + passWithNoTests: true, + }, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + }, + }, + }); + addProjectConfiguration(tree, 'proj2', { + root: 'proj2', + targets: { + test: { + executor: '@nx/vite:vitest', + options: {}, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets.test).toEqual({ + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.js', + }, + }); + expect(readProjectConfiguration(tree, 'proj2').targets.test).toEqual({ + executor: '@nx/vite:vitest', + options: {}, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + }); + }); + + it('should handle when jest and vite are used for test and jest and cypress are used for e2e', async () => { + const nxJson = readNxJson(tree); + nxJson.targetDefaults['test'] = { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: true, + }, + }; + nxJson.targetDefaults['e2e'] = { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: false, + }, + }; + updateNxJson(tree, nxJson); + + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + passWithNoTests: true, + }, + }, + e2e: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + passWithNoTests: true, + }, + }, + }, + }); + addProjectConfiguration(tree, 'proj2', { + root: 'proj2', + targets: { + test: { + executor: '@nx/vite:vitest', + options: {}, + }, + e2e: { + executor: '@nx/cypress:cypress', + options: {}, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets).toEqual({ + e2e: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + }); + + expect(readProjectConfiguration(tree, 'proj2').targets).toEqual({ + e2e: { + executor: '@nx/cypress:cypress', + options: {}, + }, + test: { + executor: '@nx/vite:vitest', + options: {}, + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + e2e: { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: false, + }, + }, + test: { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: true, + }, + }, + }); + }); + + it('should not assign things that had a default already', async () => { + const nxJson = readNxJson(tree); + nxJson.targetDefaults['test'] = { + cache: true, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }; + updateNxJson(tree, nxJson); + + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets).toEqual({ + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + }); + }); + + it('should remove target defaults which are not used anymore', async () => { + const nxJson = readNxJson(tree); + nxJson.targetDefaults['@nx/vite:test'] = { + cache: false, + inputs: ['default', '^production'], + }; + nxJson.targetDefaults['test'] = { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: true, + }, + }; + nxJson.targetDefaults['e2e'] = { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: false, + }, + }; + updateNxJson(tree, nxJson); + + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + passWithNoTests: true, + }, + }, + e2e: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + passWithNoTests: true, + }, + }, + }, + }); + addProjectConfiguration(tree, 'proj2', { + root: 'proj2', + targets: { + test: { + executor: '@nx/vite:test', + options: {}, + }, + e2e: { + executor: '@nx/cypress:cypress', + options: {}, + }, + }, + }); + + await update(tree); + + expect(readProjectConfiguration(tree, 'proj1').targets).toEqual({ + e2e: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + test: { + executor: '@nx/jest:jest', + options: { + jestConfig: 'jest.config.ts', + }, + }, + }); + + expect(readProjectConfiguration(tree, 'proj2').targets).toEqual({ + e2e: { + executor: '@nx/cypress:cypress', + options: {}, + }, + test: { + executor: '@nx/vite:test', + options: {}, + }, + }); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/jest:jest': { + cache: true, + configurations: { + ci: { + ci: true, + codeCoverage: true, + }, + }, + inputs: ['default', '^production'], + options: { + passWithNoTests: true, + }, + }, + '@nx/vite:test': { + cache: false, + inputs: ['default', '^production'], + }, + e2e: { + cache: false, + inputs: ['default', '^production', '{workspaceRoot}/other-file.txt'], + options: { + watch: false, + }, + }, + }); + }); +}); diff --git a/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.ts b/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.ts new file mode 100644 index 0000000000000..407d8f7b8a28b --- /dev/null +++ b/packages/jest/src/migrations/update-17-1-0/move-options-to-target-defaults.ts @@ -0,0 +1,185 @@ +import { + createProjectGraphAsync, + formatFiles, + getProjects, + ProjectConfiguration, + ProjectGraphProjectNode, + readNxJson, + TargetConfiguration, + TargetDefaults, + Tree, + updateNxJson, + updateProjectConfiguration, +} from '@nx/devkit'; +import { JestExecutorOptions } from '../../executors/jest/schema'; +import { + forEachExecutorOptions, + forEachExecutorOptionsInGraph, +} from '@nx/devkit/src/generators/executor-options-utils'; +import { readTargetDefaultsForTarget } from 'nx/src/project-graph/utils/project-configuration-utils'; + +export default async function update(tree: Tree) { + const nxJson = readNxJson(tree); + + // Don't override anything if there are already target defaults for jest + if (nxJson.targetDefaults?.['@nx/jest:jest']) { + return; + } + + nxJson.targetDefaults ??= {}; + + /** + * A set of targets which does not use any other executors + */ + const jestTargets = new Set(); + + const graph = await createProjectGraphAsync(); + + forEachExecutorOptionsInGraph( + graph, + '@nx/jest:jest', + (value, proj, targetName) => { + jestTargets.add(targetName); + } + ); + + // Workspace does not use jest? + if (jestTargets.size === 0) { + return; + } + // Use the project graph so targets which are inferred are considered + const projects = graph.nodes; + const projectMap = getProjects(tree); + + const jestDefaults: TargetConfiguration> = + (nxJson.targetDefaults['@nx/jest:jest'] = {}); + + // All jest targets have the same name + if (jestTargets.size === 1) { + const targetName = Array.from(jestTargets)[0]; + if (nxJson.targetDefaults[targetName]) { + Object.assign(jestDefaults, nxJson.targetDefaults[targetName]); + } + } + + jestDefaults.cache ??= true; + + const inputs = ['default']; + inputs.push(nxJson.namedInputs?.production ? '^production' : '^default'); + if (tree.exists('jest.preset.js')) { + inputs.push('{workspaceRoot}/jest.preset.js'); + } + jestDefaults.inputs ??= inputs; + + // Remember if there were already defaults so we don't assume the executor default + const passWithNoTestsPreviouslyInDefaults = + jestDefaults.options?.passWithNoTests !== undefined; + const ciCiPreviouslyInDefaults = + jestDefaults.configurations?.ci?.ci !== undefined; + const ciCodeCoveragePreviouslyInDefaults = + jestDefaults.configurations?.ci?.codeCoverage !== undefined; + + jestDefaults.options ??= {}; + jestDefaults.options.passWithNoTests ??= true; + jestDefaults.configurations ??= {}; + jestDefaults.configurations.ci ??= {}; + jestDefaults.configurations.ci.ci ??= true; + jestDefaults.configurations.ci.codeCoverage ??= true; + + // Cleanup old target defaults + for (const [targetDefaultKey, targetDefault] of Object.entries( + nxJson.targetDefaults + )) { + if ( + !isTargetDefaultUsed( + targetDefault, + nxJson.targetDefaults, + projects, + projectMap + ) + ) { + delete nxJson.targetDefaults[targetDefaultKey]; + } + } + + updateNxJson(tree, nxJson); + + forEachExecutorOptions( + tree, + '@nx/jest:jest', + (value, proj, targetName, configuration) => { + const projConfig = projectMap.get(proj); + + if (!configuration) { + // Options + if (value.passWithNoTests === jestDefaults.options.passWithNoTests) { + delete projConfig.targets[targetName].options.passWithNoTests; + } else if (!passWithNoTestsPreviouslyInDefaults) { + projConfig.targets[targetName].options.passWithNoTests ??= false; + } + + if (Object.keys(projConfig.targets[targetName].options).length === 0) { + delete projConfig.targets[targetName].options; + } + } else if (configuration === 'ci') { + // CI Config + if (value.ci === jestDefaults.configurations.ci.ci) { + delete projConfig.targets[targetName].configurations.ci.ci; + } else if (ciCiPreviouslyInDefaults) { + projConfig.targets[targetName].configurations.ci.ci ??= false; + } + if ( + value.codeCoverage === jestDefaults.configurations.ci.codeCoverage + ) { + delete projConfig.targets[targetName].configurations.ci.codeCoverage; + } else if (ciCodeCoveragePreviouslyInDefaults) { + projConfig.targets[targetName].configurations.ci.codeCoverage ??= + false; + } + + if ( + Object.keys(projConfig.targets[targetName].configurations.ci) + .length === 0 + ) { + delete projConfig.targets[targetName].configurations.ci; + } + if ( + Object.keys(projConfig.targets[targetName].configurations).length === + 0 + ) { + delete projConfig.targets[targetName].configurations; + } + } + + updateProjectConfiguration(tree, proj, projConfig); + } + ); + + await formatFiles(tree); +} + +/** + * Checks every target on every project to see if one of them uses the target default + */ +function isTargetDefaultUsed( + targetDefault: Partial, + targetDefaults: TargetDefaults, + projects: Record, + projectMap: Map +) { + for (const p of Object.values(projects)) { + for (const targetName in p.data?.targets ?? {}) { + if ( + readTargetDefaultsForTarget( + targetName, + targetDefaults, + // It might seem like we should use the graph here too but we don't want to pass an executor which was processed in the graph + projectMap.get(p.name).targets?.[targetName]?.executor + ) === targetDefault + ) { + return true; + } + } + } + return false; +} diff --git a/packages/js/docs/library-examples.md b/packages/js/docs/library-examples.md index 6172715ce1130..0e5d6fbd9ed44 100644 --- a/packages/js/docs/library-examples.md +++ b/packages/js/docs/library-examples.md @@ -118,7 +118,7 @@ npx nx g lib mylib --publishable Generate a library named `mylib` and put it under a directory named `myapp` (`libs/myapp/mylib`) {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=myapp`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=myapp`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.spec.ts b/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.spec.ts index f5f0127ef8278..b0def14c4bb5c 100644 --- a/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.spec.ts +++ b/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.spec.ts @@ -53,6 +53,17 @@ describe('remove-deprecated-build-options', () => { await expect(migration(tree)).resolves.not.toThrow(); }); + it('should work if a target is an empty object', async () => { + addProjectConfiguration(tree, 'proj', { + root: 'proj', + targets: { + build: {}, + }, + }); + + await expect(migration(tree)).resolves.not.toThrow(); + }); + it('should not update community executors', async () => { addProjectConfiguration(tree, 'proj', { root: 'proj', diff --git a/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.ts b/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.ts index 46a2e3d3cfef0..7a834a1a9ac5b 100644 --- a/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.ts +++ b/packages/js/src/migrations/update-17-0-0/remove-deprecated-build-options.ts @@ -19,7 +19,8 @@ export default async function (tree: Tree) { for (const target of Object.values(projectConfig.targets)) { if ( - target.executor.startsWith('@nx/') && + target.executor?.startsWith('@nx/') && + target.options && ('buildableProjectDepsInPackageJsonType' in target.options || 'updateBuildableProjectDepsInPackageJson' in target.options) ) { diff --git a/packages/js/src/utils/add-local-registry-scripts.spec.ts b/packages/js/src/utils/add-local-registry-scripts.spec.ts new file mode 100644 index 0000000000000..65ea0a45248c2 --- /dev/null +++ b/packages/js/src/utils/add-local-registry-scripts.spec.ts @@ -0,0 +1,33 @@ +import { addLocalRegistryScripts } from './add-local-registry-scripts'; +import { Tree, writeJson } from '@nx/devkit'; +import { createTree } from '@nx/devkit/testing'; + +describe('addLocalRegistryScripts', () => { + let tree: Tree; + const startLocalRegistryPath = 'tools/scripts/start-local-registry.ts'; + const stopLocalRegistryPath = 'tools/scripts/stop-local-registry.ts'; + + beforeEach(() => { + tree = createTree(); + writeJson(tree, 'project.json', { + name: 'mylib', + }); + }); + + it('should add "start-local-registry.ts" and "stop-local-registry.ts" in workspace\'s "tools/scripts" folder', () => { + expect(addLocalRegistryScripts(tree)).toEqual({ + startLocalRegistryPath, + stopLocalRegistryPath, + }); + + expect(tree.exists(startLocalRegistryPath)).toBe(true); + expect(tree.exists(stopLocalRegistryPath)).toBe(true); + }); + + it('should set published version to "0.0.0-e2e"', () => { + addLocalRegistryScripts(tree); + + const startLocalRegistry = tree.read(startLocalRegistryPath, 'utf-8'); + expect(/'0\.0\.0-e2e'/.test(startLocalRegistry)).toBe(true); + }); +}); diff --git a/packages/js/src/utils/add-local-registry-scripts.ts b/packages/js/src/utils/add-local-registry-scripts.ts index 0ef34f266b35f..947e11caadb52 100644 --- a/packages/js/src/utils/add-local-registry-scripts.ts +++ b/packages/js/src/utils/add-local-registry-scripts.ts @@ -22,7 +22,7 @@ export default async () => { const nx = require.resolve('nx'); execFileSync( nx, - ['run-many', '--targets', 'publish', '--ver', '1.0.0', '--tag', 'e2e'], + ['run-many', '--targets', 'publish', '--ver', '0.0.0-e2e', '--tag', 'e2e'], { env: process.env, stdio: 'inherit' } ); }; diff --git a/packages/js/src/utils/assets/copy-assets-handler.spec.ts b/packages/js/src/utils/assets/copy-assets-handler.spec.ts index 7e21cce3db997..4c7df97c8843f 100644 --- a/packages/js/src/utils/assets/copy-assets-handler.spec.ts +++ b/packages/js/src/utils/assets/copy-assets-handler.spec.ts @@ -118,70 +118,54 @@ describe('AssetInputOutputHandler', () => { deletedMockedWatchedFile(path.join(projectDir, 'docs/test1.md')); deletedMockedWatchedFile(path.join(projectDir, 'docs/test2.md')); - expect(callback.mock.calls).toEqual([ - [ - [ - { - type: 'create', - src: path.join(rootDir, 'LICENSE'), - dest: path.join(rootDir, 'dist/mylib/LICENSE'), - }, - ], - ], - [ - [ - { - type: 'create', - src: path.join(rootDir, 'mylib/README.md'), - dest: path.join(rootDir, 'dist/mylib/README.md'), - }, - ], - ], - [ - [ - { - type: 'create', - src: path.join(rootDir, 'mylib/docs/test1.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), - }, - ], - ], - [ - [ - { - type: 'create', - src: path.join(rootDir, 'mylib/docs/test2.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), - }, - ], - ], - [ - [ - { - type: 'update', - src: path.join(rootDir, 'mylib/docs/test1.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), - }, - ], - ], - [ - [ - { - type: 'delete', - src: path.join(rootDir, 'mylib/docs/test1.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), - }, - ], - ], - [ - [ - { - type: 'delete', - src: path.join(rootDir, 'mylib/docs/test2.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), - }, - ], - ], + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'LICENSE'), + dest: path.join(rootDir, 'dist/mylib/LICENSE'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'mylib/README.md'), + dest: path.join(rootDir, 'dist/mylib/README.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'mylib/docs/test1.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'mylib/docs/test2.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'update', + src: path.join(rootDir, 'mylib/docs/test1.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'delete', + src: path.join(rootDir, 'mylib/docs/test1.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'delete', + src: path.join(rootDir, 'mylib/docs/test2.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), + }, ]); dispose(); @@ -202,39 +186,31 @@ describe('AssetInputOutputHandler', () => { await sut.processAllAssetsOnce(); - expect(callback.mock.calls).toEqual([ - [ - [ - { - type: 'create', - src: path.join(rootDir, 'LICENSE'), - dest: path.join(rootDir, 'dist/mylib/LICENSE'), - }, - ], - ], - [ - [ - { - type: 'create', - src: path.join(rootDir, 'mylib/README.md'), - dest: path.join(rootDir, 'dist/mylib/README.md'), - }, - ], - ], - [ - [ - { - type: 'create', - src: path.join(rootDir, 'mylib/docs/test1.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), - }, - { - type: 'create', - src: path.join(rootDir, 'mylib/docs/test2.md'), - dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), - }, - ], - ], + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'LICENSE'), + dest: path.join(rootDir, 'dist/mylib/LICENSE'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'mylib/README.md'), + dest: path.join(rootDir, 'dist/mylib/README.md'), + }, + ]); + expect(callback).toHaveBeenCalledWith([ + { + type: 'create', + src: path.join(rootDir, 'mylib/docs/test1.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test1.md'), + }, + { + type: 'create', + src: path.join(rootDir, 'mylib/docs/test2.md'), + dest: path.join(rootDir, 'dist/mylib/docs/test2.md'), + }, ]); }); }); diff --git a/packages/nest/src/generators/library/library.spec.ts b/packages/nest/src/generators/library/library.spec.ts index 99cc8ebcb0531..a0e043056f2c5 100644 --- a/packages/nest/src/generators/library/library.spec.ts +++ b/packages/nest/src/generators/library/library.spec.ts @@ -34,13 +34,6 @@ describe('lib', () => { outputs: [`{workspaceRoot}/coverage/{projectRoot}`], options: { jestConfig: `my-lib/jest.config.ts`, - passWithNoTests: true, - }, - configurations: { - ci: { - ci: true, - codeCoverage: true, - }, }, }); }); diff --git a/packages/next/docs/application-examples.md b/packages/next/docs/application-examples.md index 5cce451866ad3..c83849cd858cd 100644 --- a/packages/next/docs/application-examples.md +++ b/packages/next/docs/application-examples.md @@ -4,7 +4,7 @@ {% tab label="Create app in a directory" %} {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/packages/next/docs/library-examples.md b/packages/next/docs/library-examples.md index f5a9693b98392..71b1bafcebc83 100644 --- a/packages/next/docs/library-examples.md +++ b/packages/next/docs/library-examples.md @@ -13,7 +13,7 @@ nx g lib my-lib The following will create a library at `libs/shared/my-lib`. {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=shared`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=shared`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/packages/node/src/generators/application/files/fastify/src/app/app.ts__tmpl__ b/packages/node/src/generators/application/files/fastify/src/app/app.ts__tmpl__ index 6c7d1a8640ee8..1645bc1d933e1 100644 --- a/packages/node/src/generators/application/files/fastify/src/app/app.ts__tmpl__ +++ b/packages/node/src/generators/application/files/fastify/src/app/app.ts__tmpl__ @@ -1,5 +1,5 @@ import * as path from 'path'; -import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; +import { FastifyInstance } from 'fastify'; import AutoLoad from '@fastify/autoload'; /* eslint-disable-next-line */ diff --git a/packages/node/src/generators/application/files/fastify/src/app/plugins/sensible.ts__tmpl__ b/packages/node/src/generators/application/files/fastify/src/app/plugins/sensible.ts__tmpl__ index ef7dfe03911f2..54badc2826d53 100644 --- a/packages/node/src/generators/application/files/fastify/src/app/plugins/sensible.ts__tmpl__ +++ b/packages/node/src/generators/application/files/fastify/src/app/plugins/sensible.ts__tmpl__ @@ -1,4 +1,4 @@ -import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; +import { FastifyInstance } from 'fastify'; import fp from 'fastify-plugin'; import sensible from '@fastify/sensible'; diff --git a/packages/node/src/generators/application/files/fastify/src/app/routes/root.ts__tmpl__ b/packages/node/src/generators/application/files/fastify/src/app/routes/root.ts__tmpl__ index 3b765e0794d75..e9edd35ce474c 100644 --- a/packages/node/src/generators/application/files/fastify/src/app/routes/root.ts__tmpl__ +++ b/packages/node/src/generators/application/files/fastify/src/app/routes/root.ts__tmpl__ @@ -1,7 +1,7 @@ -import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; +import { FastifyInstance } from 'fastify'; export default async function(fastify: FastifyInstance) { - fastify.get('/', async function(request: FastifyRequest, reply: FastifyReply) { + fastify.get('/', async function() { return { message: 'Hello API' }; }); } diff --git a/packages/node/src/generators/library/library.spec.ts b/packages/node/src/generators/library/library.spec.ts index 12966b6ed4449..632676c868549 100644 --- a/packages/node/src/generators/library/library.spec.ts +++ b/packages/node/src/generators/library/library.spec.ts @@ -40,13 +40,6 @@ describe('lib', () => { outputs: ['{workspaceRoot}/coverage/{projectRoot}'], options: { jestConfig: 'my-lib/jest.config.ts', - passWithNoTests: true, - }, - configurations: { - ci: { - ci: true, - codeCoverage: true, - }, }, }); expect( diff --git a/packages/nuxt/docs/application-examples.md b/packages/nuxt/docs/application-examples.md index 8b04c4dd98ae8..530a91e0f6357 100644 --- a/packages/nuxt/docs/application-examples.md +++ b/packages/nuxt/docs/application-examples.md @@ -9,7 +9,7 @@ description: This page contains examples for the @nx/nuxt:app generator. {% tab label="Create app in a directory" %} {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=nested`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/packages/nuxt/src/generators/application/application.ts b/packages/nuxt/src/generators/application/application.ts index 909ec9b7ab9e2..db19cf95e6df5 100644 --- a/packages/nuxt/src/generators/application/application.ts +++ b/packages/nuxt/src/generators/application/application.ts @@ -18,7 +18,6 @@ import { getRelativePathToRootTsConfig } from '@nx/js'; import { updateGitIgnore } from '../../utils/update-gitignore'; import { addBuildTarget, addServeTarget } from './lib/add-targets'; import { Linter } from '@nx/eslint'; -import { addJest } from '@nx/vue'; import { addE2e } from './lib/add-e2e'; import { nxVersion } from '../../utils/versions'; import { addLinting } from '../../utils/add-linting'; @@ -74,14 +73,6 @@ export async function applicationGenerator(tree: Tree, schema: Schema) { }) ); - if (options.unitTestRunner === 'jest') { - tasks.push( - await addJest(tree, { - name: options.name, - projectRoot: options.appProjectRoot, - }) - ); - } if (options.unitTestRunner === 'vitest') { const { vitestGenerator } = ensurePackage('@nx/vite', nxVersion); tasks.push( diff --git a/packages/nuxt/src/generators/application/schema.d.ts b/packages/nuxt/src/generators/application/schema.d.ts index f5525a2ed0651..db84d800e9821 100644 --- a/packages/nuxt/src/generators/application/schema.d.ts +++ b/packages/nuxt/src/generators/application/schema.d.ts @@ -7,7 +7,7 @@ export interface Schema { projectNameAndRootFormat?: ProjectNameAndRootFormat; linter?: Linter; skipFormat?: boolean; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; e2eTestRunner?: 'cypress' | 'playwright' | 'none'; tags?: string; js?: boolean; diff --git a/packages/nuxt/src/generators/application/schema.json b/packages/nuxt/src/generators/application/schema.json index cf8885c12b2f6..f8233d4787f68 100644 --- a/packages/nuxt/src/generators/application/schema.json +++ b/packages/nuxt/src/generators/application/schema.json @@ -42,7 +42,7 @@ }, "unitTestRunner": { "type": "string", - "enum": ["jest", "vitest", "none"], + "enum": ["vitest", "none"], "description": "Test runner to use for unit tests.", "x-prompt": "Which unit test runner would you like to use?", "default": "none" diff --git a/packages/nuxt/src/generators/component/schema.d.ts b/packages/nuxt/src/generators/component/schema.d.ts index 29587473dfa0b..567885995e4d8 100644 --- a/packages/nuxt/src/generators/component/schema.d.ts +++ b/packages/nuxt/src/generators/component/schema.d.ts @@ -9,5 +9,4 @@ export interface Schema { inSourceTests?: boolean; skipFormat?: boolean; directory?: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; } diff --git a/packages/nuxt/src/generators/component/schema.json b/packages/nuxt/src/generators/component/schema.json index f2fc52c8991ee..51fb677a5f2f3 100644 --- a/packages/nuxt/src/generators/component/schema.json +++ b/packages/nuxt/src/generators/component/schema.json @@ -79,12 +79,6 @@ "type": "boolean", "default": false, "x-priority": "internal" - }, - "unitTestRunner": { - "type": "string", - "enum": ["vitest", "jest", "none"], - "description": "Test runner to use for unit tests.", - "x-prompt": "What unit test runner should be used?" } }, "required": ["name", "project"] diff --git a/packages/nuxt/src/utils/add-linting.ts b/packages/nuxt/src/utils/add-linting.ts index a9d4cc1e77bac..20950c3ef4907 100644 --- a/packages/nuxt/src/utils/add-linting.ts +++ b/packages/nuxt/src/utils/add-linting.ts @@ -16,7 +16,7 @@ export async function addLinting( linter: Linter; projectName: string; projectRoot: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; rootProject?: boolean; } ) { diff --git a/packages/nx/src/command-line/init/implementation/add-nx-to-monorepo.ts b/packages/nx/src/command-line/init/implementation/add-nx-to-monorepo.ts index b8653323780e3..6b74bf22a9aac 100644 --- a/packages/nx/src/command-line/init/implementation/add-nx-to-monorepo.ts +++ b/packages/nx/src/command-line/init/implementation/add-nx-to-monorepo.ts @@ -13,6 +13,7 @@ import { initCloud, printFinalMessage, runInstall, + updateGitIgnore, } from './utils'; type Options = Pick; @@ -88,6 +89,7 @@ export async function addNxToMonorepo(options: Options) { scriptOutputs ); + updateGitIgnore(repoRoot); addDepsToPackageJson(repoRoot); output.log({ title: '📦 Installing dependencies' }); diff --git a/packages/nx/src/command-line/init/implementation/add-nx-to-nest.ts b/packages/nx/src/command-line/init/implementation/add-nx-to-nest.ts index 041453c4c01ed..e618c47965f12 100644 --- a/packages/nx/src/command-line/init/implementation/add-nx-to-nest.ts +++ b/packages/nx/src/command-line/init/implementation/add-nx-to-nest.ts @@ -23,6 +23,7 @@ import { markRootPackageJsonAsNxProject, printFinalMessage, runInstall, + updateGitIgnore, } from './utils'; import { nxVersion } from '../../../utils/versions'; @@ -117,6 +118,7 @@ export async function addNxToNest(options: Options, packageJson: PackageJson) { const pmc = getPackageManagerCommand(); + updateGitIgnore(repoRoot); addDepsToPackageJson(repoRoot); addNestPluginToPackageJson(repoRoot); markRootPackageJsonAsNxProject( diff --git a/packages/nx/src/command-line/init/implementation/add-nx-to-npm-repo.ts b/packages/nx/src/command-line/init/implementation/add-nx-to-npm-repo.ts index a129d3070551c..09f7a6a085d8a 100644 --- a/packages/nx/src/command-line/init/implementation/add-nx-to-npm-repo.ts +++ b/packages/nx/src/command-line/init/implementation/add-nx-to-npm-repo.ts @@ -11,6 +11,7 @@ import { markRootPackageJsonAsNxProject, printFinalMessage, runInstall, + updateGitIgnore, } from './utils'; type Options = Pick; @@ -72,6 +73,7 @@ export async function addNxToNpmRepo(options: Options) { const pmc = getPackageManagerCommand(); + updateGitIgnore(repoRoot); addDepsToPackageJson(repoRoot); markRootPackageJsonAsNxProject( repoRoot, diff --git a/packages/nx/src/command-line/init/implementation/utils.ts b/packages/nx/src/command-line/init/implementation/utils.ts index 4502dfe30323e..5157212ab390b 100644 --- a/packages/nx/src/command-line/init/implementation/utils.ts +++ b/packages/nx/src/command-line/init/implementation/utils.ts @@ -17,6 +17,7 @@ import { } from '../../../utils/package-manager'; import { joinPathFragments } from '../../../utils/path'; import { nxVersion } from '../../../utils/versions'; +import { readFileSync, writeFileSync } from 'fs'; export async function askAboutNxCloud(): Promise { return await enquirer @@ -121,6 +122,17 @@ export function addDepsToPackageJson(repoRoot: string) { writeJsonFile(path, json); } +export function updateGitIgnore(root: string) { + const ignorePath = join(root, '.gitignore'); + try { + let contents = readFileSync(ignorePath, 'utf-8'); + if (!contents.includes('.nx/cache')) { + contents = [contents, '', '.nx/cache'].join('\n'); + writeFileSync(ignorePath, contents, 'utf-8'); + } + } catch {} +} + export function runInstall( repoRoot: string, pmc: PackageManagerCommands = getPackageManagerCommand() diff --git a/packages/nx/src/command-line/init/init.ts b/packages/nx/src/command-line/init/init.ts index 4dbbb3c3c8718..b14f2eed0125c 100644 --- a/packages/nx/src/command-line/init/init.ts +++ b/packages/nx/src/command-line/init/init.ts @@ -2,7 +2,6 @@ import { execSync } from 'child_process'; import { prompt } from 'enquirer'; import { existsSync } from 'fs'; import { prerelease } from 'semver'; -import * as parser from 'yargs-parser'; import { addNxToMonorepo } from './implementation/add-nx-to-monorepo'; import { addNxToNest } from './implementation/add-nx-to-nest'; import { addNxToNpmRepo } from './implementation/add-nx-to-npm-repo'; diff --git a/packages/nx/src/devkit-internals.ts b/packages/nx/src/devkit-internals.ts index ed7d2be4e3af5..b8e3cca1f8a23 100644 --- a/packages/nx/src/devkit-internals.ts +++ b/packages/nx/src/devkit-internals.ts @@ -14,6 +14,7 @@ export { sortObjectByKeys } from './utils/object-sort'; export { stripIndent } from './utils/logger'; export { readModulePackageJson } from './utils/package-json'; export { splitByColons } from './utils/split-target'; +export { hashObject } from './hasher/file-hasher'; export { createProjectRootMappingsFromProjectConfigurations, findProjectForPath, diff --git a/packages/nx/src/generators/testing-utils/create-tree-with-empty-workspace.ts b/packages/nx/src/generators/testing-utils/create-tree-with-empty-workspace.ts index f945aae2548d0..f6344adeff5e6 100644 --- a/packages/nx/src/generators/testing-utils/create-tree-with-empty-workspace.ts +++ b/packages/nx/src/generators/testing-utils/create-tree-with-empty-workspace.ts @@ -43,9 +43,6 @@ function addCommonFiles(tree: Tree, addAppsAndLibsFolders: boolean): Tree { lint: { cache: true, }, - test: { - cache: true, - }, e2e: { cache: true, }, diff --git a/packages/nx/src/project-graph/utils/normalize-project-nodes.ts b/packages/nx/src/project-graph/utils/normalize-project-nodes.ts index 1d731d497803b..187f2a0ccb31e 100644 --- a/packages/nx/src/project-graph/utils/normalize-project-nodes.ts +++ b/packages/nx/src/project-graph/utils/normalize-project-nodes.ts @@ -23,7 +23,10 @@ export async function normalizeProjectNodes( nxJson: NxJsonConfiguration ) { const toAdd = []; - const projects = Object.keys(ctx.projects); + // Sorting projects by name to make sure that the order of projects in the graph is deterministic. + // This is important to ensure that expanded properties referencing projects (e.g. implicit dependencies) + // are also deterministic, and thus don't cause the calculated project configuration hash to shift. + const projects = Object.keys(ctx.projects).sort(); // Used for expanding implicit dependencies (e.g. `@proj/*` or `tag:foo`) const partialProjectGraphNodes = projects.reduce((graph, project) => { diff --git a/packages/nx/src/utils/params.spec.ts b/packages/nx/src/utils/params.spec.ts index 15316ade7a98e..ced3674210bfd 100644 --- a/packages/nx/src/utils/params.spec.ts +++ b/packages/nx/src/utils/params.spec.ts @@ -1743,6 +1743,44 @@ describe('params', () => { ]); }); + it('should use a multiselect if type is array and x-prompt uses shorthand', () => { + const prompts = getPromptsForSchema( + {}, + { + properties: { + pets: { + type: 'array', + 'x-prompt': 'What kind of pets do you have?', + items: { + enum: ['cat', 'dog', 'fish'], + }, + }, + }, + }, + { + version: 2, + projects: {}, + } + ); + + expect(prompts).toMatchInlineSnapshot(` + [ + { + "choices": [ + "cat", + "dog", + "fish", + ], + "limit": 10, + "message": "What kind of pets do you have?", + "name": "pets", + "type": "multiselect", + "validate": [Function], + }, + ] + `); + }); + describe('Project prompts', () => { it('should use an autocomplete prompt for a property named project', () => { const prompts = getPromptsForSchema( diff --git a/packages/nx/src/utils/params.ts b/packages/nx/src/utils/params.ts index 7fb629e79b852..7d46a27cdc079 100644 --- a/packages/nx/src/utils/params.ts +++ b/packages/nx/src/utils/params.ts @@ -785,10 +785,23 @@ export function getPromptsForSchema( // Normalize x-prompt if (typeof v['x-prompt'] === 'string') { const message = v['x-prompt']; - v['x-prompt'] = { - type: v.type === 'boolean' ? 'confirm' : 'input', - message, - }; + if (v.type === 'boolean') { + v['x-prompt'] = { + type: 'confirm', + message, + }; + } else if (v.type === 'array' && v.items?.enum) { + v['x-prompt'] = { + type: 'multiselect', + items: v.items.enum, + message, + }; + } else { + v['x-prompt'] = { + type: 'input', + message, + }; + } } question.message = v['x-prompt'].message; diff --git a/packages/plugin/src/generators/e2e-project/e2e.spec.ts b/packages/plugin/src/generators/e2e-project/e2e.spec.ts index d53e71afab712..5b042d22f751e 100644 --- a/packages/plugin/src/generators/e2e-project/e2e.spec.ts +++ b/packages/plugin/src/generators/e2e-project/e2e.spec.ts @@ -119,19 +119,12 @@ describe('NxPlugin e2e-project Generator', () => { expect(project.targets.e2e).toBeTruthy(); expect(project.targets.e2e).toMatchInlineSnapshot(` { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "dependsOn": [ "^build", ], "executor": "@nx/jest:jest", "options": { "jestConfig": "apps/my-plugin-e2e/jest.config.ts", - "passWithNoTests": true, "runInBand": true, }, "outputs": [ diff --git a/packages/plugin/src/generators/e2e-project/e2e.ts b/packages/plugin/src/generators/e2e-project/e2e.ts index 95340fe1f15a4..f413b79b21f03 100644 --- a/packages/plugin/src/generators/e2e-project/e2e.ts +++ b/packages/plugin/src/generators/e2e-project/e2e.ts @@ -148,7 +148,6 @@ async function addJest(host: Tree, options: NormalizedSchema) { ...testTarget.options, runInBand: true, }, - configurations: testTarget.configurations, }; // remove the jest build target diff --git a/packages/plugin/src/generators/plugin/plugin.spec.ts b/packages/plugin/src/generators/plugin/plugin.spec.ts index 0fa3c8f1e092f..a6d6c00fe3455 100644 --- a/packages/plugin/src/generators/plugin/plugin.spec.ts +++ b/packages/plugin/src/generators/plugin/plugin.spec.ts @@ -83,13 +83,6 @@ describe('NxPlugin Plugin Generator', () => { outputs: ['{workspaceRoot}/coverage/{projectRoot}'], options: { jestConfig: 'libs/my-plugin/jest.config.ts', - passWithNoTests: true, - }, - configurations: { - ci: { - ci: true, - codeCoverage: true, - }, }, }); }); diff --git a/packages/react-native/migrations.json b/packages/react-native/migrations.json index b902c4b33451d..2451a8b7aa1a9 100644 --- a/packages/react-native/migrations.json +++ b/packages/react-native/migrations.json @@ -501,6 +501,51 @@ "alwaysAddToPackageJson": false } } + }, + "17.1.0": { + "version": "17.1.0-beta.1", + "packages": { + "react-native": { + "version": "0.72.6", + "alwaysAddToPackageJson": false + }, + "metro": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro-resolver": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro-config": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro-react-native-babel-preset": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro-babel-register": { + "version": "0.76.8", + "alwaysAddToPackageJson": false + }, + "metro-react-native-babel-transformer": { + "version": "0.76.7", + "alwaysAddToPackageJson": false + }, + "@react-native-community/cli": { + "version": "11.3.7", + "alwaysAddToPackageJson": false + }, + "@react-native-community/cli-platform-android": { + "version": "11.3.7", + "alwaysAddToPackageJson": false + }, + "@react-native-community/cli-platform-ios": { + "version": "11.3.7", + "alwaysAddToPackageJson": false + } + } } } } diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 750392fb29158..7790f37142f5a 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -30,8 +30,8 @@ "fs-extra": "^11.1.0", "glob": "7.1.4", "ignore": "^5.0.4", - "metro-config": "0.76.7", - "metro-resolver": "0.76.7", + "metro-config": "~0.76.8", + "metro-resolver": "~0.76.8", "minimatch": "3.0.5", "node-fetch": "^2.6.7", "tsconfig-paths": "^4.1.2", diff --git a/packages/react-native/src/generators/application/files/app/Gemfile.template b/packages/react-native/src/generators/application/files/app/Gemfile.template index 1fa2c2e1abdee..6a7d5c7a49c35 100644 --- a/packages/react-native/src/generators/application/files/app/Gemfile.template +++ b/packages/react-native/src/generators/application/files/app/Gemfile.template @@ -3,4 +3,5 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version ruby ">= 2.6.10" -gem 'cocoapods', '~> 1.12' +gem 'cocoapods', '~> 1.13' +gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' diff --git a/packages/react-native/src/generators/library/library.spec.ts b/packages/react-native/src/generators/library/library.spec.ts index 261809755e6b9..8387f6001172a 100644 --- a/packages/react-native/src/generators/library/library.spec.ts +++ b/packages/react-native/src/generators/library/library.spec.ts @@ -296,16 +296,9 @@ describe('lib', () => { const projectConfiguration = readProjectConfiguration(appTree, 'my-lib'); expect(projectConfiguration.targets.test).toMatchInlineSnapshot(` { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "my-lib/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", diff --git a/packages/react-native/src/utils/versions.ts b/packages/react-native/src/utils/versions.ts index 7d7e4f1e65e36..88d0484059ea1 100644 --- a/packages/react-native/src/utils/versions.ts +++ b/packages/react-native/src/utils/versions.ts @@ -1,15 +1,15 @@ export const nxVersion = require('../../package.json').version; -export const reactNativeVersion = '0.72.4'; +export const reactNativeVersion = '0.72.6'; export const typesNodeVersion = '18.14.4'; -export const metroVersion = '0.76.7'; +export const metroVersion = '0.76.8'; export const reactNativeMetroConfigVersion = '^0.72.11'; -export const reactNativeCommunityCli = '11.3.6'; -export const reactNativeCommunityCliIos = '11.3.6'; -export const reactNativeCommunityCliAndroid = '11.3.6'; +export const reactNativeCommunityCli = '11.3.7'; +export const reactNativeCommunityCliIos = '11.3.7'; +export const reactNativeCommunityCliAndroid = '11.3.7'; export const reactVersion = '18.2.0'; export const reactDomVersion = '18.2.0'; diff --git a/packages/react/docs/application-examples.md b/packages/react/docs/application-examples.md index 50dd277c7560b..87969c975cc72 100644 --- a/packages/react/docs/application-examples.md +++ b/packages/react/docs/application-examples.md @@ -28,7 +28,7 @@ When choosing `vite` as the bundler, your unit tests will be set up with `vitest Create an application named `my-app` in the `my-dir` directory and use `scss` for styles: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```bash diff --git a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap index c2e7dd14828ce..9a922ce58ebab 100644 --- a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap @@ -22,7 +22,7 @@ if (import.meta.vitest) { // For more information please visit the Vitest docs site here: https://vitest.dev/guide/in-source.html const { it, expect, beforeEach } = import.meta.vitest; - let render: any; + let render: typeof import('@testing-library/react').render; beforeEach(async () => { render = (await import('@testing-library/react')).render; diff --git a/packages/react/src/generators/federate-module/schema.json b/packages/react/src/generators/federate-module/schema.json index 20175464132d1..90e3d47f97e67 100644 --- a/packages/react/src/generators/federate-module/schema.json +++ b/packages/react/src/generators/federate-module/schema.json @@ -12,22 +12,22 @@ ], "type": "object", "properties": { - "name": { - "description": "The name of the module.", + "path": { "type": "string", "$default": { "$source": "argv", "index": 0 }, + "description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.", + "x-prompt": "What is the path to the module to be federated?" + }, + "name": { + "description": "The name of the module.", + "type": "string", "x-prompt": "What name would you like to use for the module?", "pattern": "^[a-zA-Z][^:]*$", "x-priority": "important" }, - "path": { - "type": "string", - "description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.", - "x-prompt": "What is the path to the module to be federated?" - }, "remote": { "type": "string", "description": "The name of the remote.", diff --git a/packages/react/src/utils/get-in-source-vitest-tests-template.ts b/packages/react/src/utils/get-in-source-vitest-tests-template.ts index 4160c0a063bc7..7ddba1bc1ff09 100644 --- a/packages/react/src/utils/get-in-source-vitest-tests-template.ts +++ b/packages/react/src/utils/get-in-source-vitest-tests-template.ts @@ -5,7 +5,7 @@ if (import.meta.vitest) { // For more information please visit the Vitest docs site here: https://vitest.dev/guide/in-source.html const { it, expect, beforeEach } = import.meta.vitest; - let render: any; + let render: typeof import('@testing-library/react').render; beforeEach(async () => { render = (await import('@testing-library/react')).render; diff --git a/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap b/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap index c13046d0d5984..8174227b5c3e7 100644 --- a/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap +++ b/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap @@ -72,16 +72,9 @@ exports[`@nx/storybook:configuration for Storybook v7 basic functionalities shou }, }, "test": { - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true, - }, - }, "executor": "@nx/jest:jest", "options": { "jestConfig": "test-ui-lib/jest.config.ts", - "passWithNoTests": true, }, "outputs": [ "{workspaceRoot}/coverage/{projectRoot}", diff --git a/packages/storybook/src/migrations/update-16-5-0/__snapshots__/move-storybook-tsconfig.spec.ts.snap b/packages/storybook/src/migrations/update-16-5-0/__snapshots__/move-storybook-tsconfig.spec.ts.snap index 09131788e0d6c..8efb7dbd3f0f0 100644 --- a/packages/storybook/src/migrations/update-16-5-0/__snapshots__/move-storybook-tsconfig.spec.ts.snap +++ b/packages/storybook/src/migrations/update-16-5-0/__snapshots__/move-storybook-tsconfig.spec.ts.snap @@ -121,9 +121,6 @@ exports[`Ignore @nx/react/plugins/storybook in Storybook eslint plugin should up "lint": { "cache": true, }, - "test": { - "cache": true, - }, }, } `; diff --git a/packages/vite/migrations.json b/packages/vite/migrations.json index dcad886b1b0ee..1f3613f09a68f 100644 --- a/packages/vite/migrations.json +++ b/packages/vite/migrations.json @@ -35,6 +35,11 @@ "description": "Change vite-tsconfig-paths plugin for first party nx-vite-tsconfig-paths plugin", "cli": "nx", "implementation": "./src/migrations/update-16-6-0-change-ts-paths-plugin/change-ts-paths-plugin" + }, + "move-target-defaults": { + "version": "17.1.0-beta.2", + "description": "Move target defaults", + "implementation": "./src/migrations/update-17-1-0/move-target-defaults" } }, "packageJsonUpdates": { diff --git a/packages/vite/src/generators/init/init.spec.ts b/packages/vite/src/generators/init/init.spec.ts index 32152f5e5201e..26fdc56821f33 100644 --- a/packages/vite/src/generators/init/init.spec.ts +++ b/packages/vite/src/generators/init/init.spec.ts @@ -80,7 +80,9 @@ describe('@nx/vite:init', () => { const productionNamedInputs = readJson(tree, 'nx.json').namedInputs .production; - const testDefaults = readJson(tree, 'nx.json').targetDefaults.test; + const vitestDefaults = readJson(tree, 'nx.json').targetDefaults[ + '@nx/vite:test' + ]; expect(productionNamedInputs).toContain( '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)' @@ -88,7 +90,7 @@ describe('@nx/vite:init', () => { expect(productionNamedInputs).toContain( '!{projectRoot}/tsconfig.spec.json' ); - expect(testDefaults).toEqual({ + expect(vitestDefaults).toEqual({ cache: true, inputs: ['default', '^production'], }); diff --git a/packages/vite/src/generators/init/init.ts b/packages/vite/src/generators/init/init.ts index dccdcd1bb020c..30b26501aa6c1 100644 --- a/packages/vite/src/generators/init/init.ts +++ b/packages/vite/src/generators/init/init.ts @@ -93,8 +93,9 @@ export function createVitestConfig(tree: Tree) { } nxJson.targetDefaults ??= {}; - nxJson.targetDefaults.test ??= {}; - nxJson.targetDefaults.test.inputs ??= [ + nxJson.targetDefaults['@nx/vite:test'] ??= {}; + nxJson.targetDefaults['@nx/vite:test'].cache ??= true; + nxJson.targetDefaults['@nx/vite:test'].inputs ??= [ 'default', productionFileSet ? '^production' : '^default', ]; diff --git a/packages/vite/src/migrations/update-17-1-0/move-target-defaults.spec.ts b/packages/vite/src/migrations/update-17-1-0/move-target-defaults.spec.ts new file mode 100644 index 0000000000000..f481fb5c04048 --- /dev/null +++ b/packages/vite/src/migrations/update-17-1-0/move-target-defaults.spec.ts @@ -0,0 +1,79 @@ +import { createTree } from '@nx/devkit/testing'; +import { + addProjectConfiguration as _addProjectConfiguration, + ProjectGraph, + readNxJson, + Tree, + writeJson, +} from '@nx/devkit'; + +import update from './move-target-defaults'; + +let projectGraph: ProjectGraph; +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: jest.fn().mockImplementation(async () => { + return projectGraph; + }), +})); + +function addProjectConfiguration(tree, name, project) { + _addProjectConfiguration(tree, name, project); + projectGraph.nodes[name] = { + name: name, + type: 'lib', + data: { + root: project.root, + targets: project.targets, + }, + }; +} + +describe('move-target-defaults migration', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTree(); + writeJson(tree, 'nx.json', { + namedInputs: { + production: ['default'], + }, + targetDefaults: { + test: { + cache: true, + inputs: ['default', '^production'], + }, + }, + }); + + projectGraph = { + nodes: {}, + dependencies: {}, + externalNodes: {}, + }; + }); + + it('should add options to nx.json target defaults and remove them from projects', async () => { + addProjectConfiguration(tree, 'proj1', { + root: 'proj1', + targets: { + test: { + executor: '@nx/vite:test', + options: { + passWithNoTests: true, + reportsDirectory: '../../reports', + }, + }, + }, + }); + + await update(tree); + + expect(readNxJson(tree).targetDefaults).toEqual({ + '@nx/vite:test': { + cache: true, + inputs: ['default', '^production'], + }, + }); + }); +}); diff --git a/packages/vite/src/migrations/update-17-1-0/move-target-defaults.ts b/packages/vite/src/migrations/update-17-1-0/move-target-defaults.ts new file mode 100644 index 0000000000000..6c750f674e31e --- /dev/null +++ b/packages/vite/src/migrations/update-17-1-0/move-target-defaults.ts @@ -0,0 +1,112 @@ +import { + createProjectGraphAsync, + formatFiles, + getProjects, + ProjectConfiguration, + ProjectGraphProjectNode, + readNxJson, + TargetConfiguration, + TargetDefaults, + Tree, + updateNxJson, +} from '@nx/devkit'; +import { forEachExecutorOptionsInGraph } from '@nx/devkit/src/generators/executor-options-utils'; +import { VitestExecutorOptions } from '../../executors/test/schema'; +import { readTargetDefaultsForTarget } from 'nx/src/project-graph/utils/project-configuration-utils'; + +export default async function update(tree: Tree) { + const nxJson = readNxJson(tree); + + // Don't override anything if there are already target defaults for vitest + if (nxJson.targetDefaults?.['@nx/vite:test']) { + return; + } + + nxJson.targetDefaults ??= {}; + + /** + * A set of targets which does not use any other executors + */ + const vitestTargets = new Set(); + const graph = await createProjectGraphAsync(); + const projectMap = getProjects(tree); + + forEachExecutorOptionsInGraph( + graph, + '@nx/vite:test', + (value, proj, targetName) => { + vitestTargets.add(targetName); + } + ); + + // Workspace does not use vitest + if (vitestTargets.size === 0) { + return; + } + + // Use the project graph nodes so that targets which are inferred are considered + const projects = graph.nodes; + + const vitestDefaults: TargetConfiguration> = + (nxJson.targetDefaults['@nx/vite:test'] = {}); + + // All vitest targets have the same name + if (vitestTargets.size === 1) { + const targetName = Array.from(vitestTargets)[0]; + if (nxJson.targetDefaults[targetName]) { + Object.assign(vitestDefaults, nxJson.targetDefaults[targetName]); + } + } + + vitestDefaults.cache ??= true; + + const inputs = ['default']; + inputs.push(nxJson.namedInputs?.production ? '^production' : '^default'); + vitestDefaults.inputs ??= inputs; + + // Cleanup old target defaults + for (const [targetDefaultKey, targetDefault] of Object.entries( + nxJson.targetDefaults + )) { + if ( + !isTargetDefaultUsed( + targetDefault, + nxJson.targetDefaults, + projects, + projectMap + ) + ) { + delete nxJson.targetDefaults[targetDefaultKey]; + } + } + + updateNxJson(tree, nxJson); + + await formatFiles(tree); +} + +/** + * Checks every target on every project to see if one of them uses the target default + */ +function isTargetDefaultUsed( + targetDefault: Partial, + targetDefaults: TargetDefaults, + projects: Record, + projectMap: Map +) { + for (const p of Object.values(projects)) { + for (const targetName in p.data?.targets ?? {}) { + if ( + readTargetDefaultsForTarget( + targetName, + targetDefaults, + // It might seem like we should use the graph here too but we don't want to pass an executor which was processed in the graph + projectMap.get(p.name).targets?.[targetName]?.executor + ) === targetDefault + ) { + return true; + } + } + } + return false; +} diff --git a/packages/vue/.eslintrc.json b/packages/vue/.eslintrc.json index 6670bea634d29..d1d556aae4f5d 100644 --- a/packages/vue/.eslintrc.json +++ b/packages/vue/.eslintrc.json @@ -33,7 +33,6 @@ "nx", "typescript", "@nx/cypress", - "@nx/jest", "@nx/playwright", "@nx/storybook" ] diff --git a/packages/vue/docs/application-examples.md b/packages/vue/docs/application-examples.md index ed975322f3b52..5d369f772573e 100644 --- a/packages/vue/docs/application-examples.md +++ b/packages/vue/docs/application-examples.md @@ -16,7 +16,7 @@ nx g @nx/vue:app my-app Create an application named `my-app` in the `my-dir` directory and use `scss` for styles: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```shell diff --git a/packages/vue/index.ts b/packages/vue/index.ts index b06058f4b837d..4e0e5ad25da15 100644 --- a/packages/vue/index.ts +++ b/packages/vue/index.ts @@ -9,6 +9,5 @@ export { } from './src/generators/stories/stories'; export { type InitSchema } from './src/generators/init/schema'; export { vueInitGenerator } from './src/generators/init/init'; -export { addJest } from './src/generators/application/lib/add-jest'; export * from './src/utils/versions'; export * from './src/utils/add-linting'; diff --git a/packages/vue/package.json b/packages/vue/package.json index 605750b0f9288..c31219193ebb4 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -34,8 +34,7 @@ "@nx/js": "file:../js", "@nx/eslint": "file:../eslint", "@nx/vite": "file:../vite", - "@nx/web": "file:../web", - "@phenomnomnominal/tsquery": "~5.0.1" + "@nx/web": "file:../web" }, "publishConfig": { "access": "public" diff --git a/packages/vue/src/generators/application/application.ts b/packages/vue/src/generators/application/application.ts index 8ee38bd7ad3b3..63031e10643a3 100644 --- a/packages/vue/src/generators/application/application.ts +++ b/packages/vue/src/generators/application/application.ts @@ -14,7 +14,6 @@ import { addLinting } from '../../utils/add-linting'; import { addE2e } from './lib/add-e2e'; import { createApplicationFiles } from './lib/create-application-files'; import { addVite } from './lib/add-vite'; -import { addJest } from './lib/add-jest'; import { extractTsConfigBase } from '../../utils/create-ts-config'; export async function applicationGenerator( @@ -62,14 +61,6 @@ export async function applicationGenerator( tasks.push(await addVite(tree, options)); - if (options.unitTestRunner === 'jest') - tasks.push( - await addJest(tree, { - name: options.name, - projectRoot: options.appProjectRoot, - }) - ); - tasks.push(await addE2e(tree, options)); if (options.js) toJS(tree); diff --git a/packages/vue/src/generators/application/lib/add-jest.ts b/packages/vue/src/generators/application/lib/add-jest.ts deleted file mode 100644 index 8f390d8f828f2..0000000000000 --- a/packages/vue/src/generators/application/lib/add-jest.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - addDependenciesToPackageJson, - ensurePackage, - GeneratorCallback, - runTasksInSerial, - Tree, -} from '@nx/devkit'; -import { nxVersion, vueJest3Version } from '../../../utils/versions'; -import { setupJestProject } from '../../../utils/setup-jest'; - -export async function addJest( - tree: Tree, - options: { name: string; projectRoot: string } -): Promise { - const tasks: GeneratorCallback[] = []; - const { configurationGenerator } = ensurePackage( - '@nx/jest', - nxVersion - ); - tasks.push( - await configurationGenerator(tree, { - project: options.name, - skipFormat: true, - testEnvironment: 'jsdom', - compiler: 'babel', - }) - ); - - setupJestProject(tree, options.projectRoot); - - tasks.push( - addDependenciesToPackageJson( - tree, - {}, - { - '@vue/vue3-jest': vueJest3Version, - } - ) - ); - - return runTasksInSerial(...tasks); -} diff --git a/packages/vue/src/generators/application/schema.d.ts b/packages/vue/src/generators/application/schema.d.ts index 7df31a02a396d..533d798f8bd0b 100644 --- a/packages/vue/src/generators/application/schema.d.ts +++ b/packages/vue/src/generators/application/schema.d.ts @@ -8,7 +8,7 @@ export interface Schema { directory?: string; projectNameAndRootFormat?: ProjectNameAndRootFormat; tags?: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; inSourceTests?: boolean; e2eTestRunner: 'cypress' | 'playwright' | 'none'; linter: Linter; diff --git a/packages/vue/src/generators/application/schema.json b/packages/vue/src/generators/application/schema.json index f51136a5d236b..91c74b92d5908 100644 --- a/packages/vue/src/generators/application/schema.json +++ b/packages/vue/src/generators/application/schema.json @@ -85,7 +85,7 @@ }, "unitTestRunner": { "type": "string", - "enum": ["jest", "vitest", "none"], + "enum": ["vitest", "none"], "description": "Test runner to use for unit tests.", "x-prompt": "Which unit test runner would you like to use?", "default": "vitest" diff --git a/packages/vue/src/generators/component/schema.json b/packages/vue/src/generators/component/schema.json index daa4f3cb4de0b..b216ed10074e4 100644 --- a/packages/vue/src/generators/component/schema.json +++ b/packages/vue/src/generators/component/schema.json @@ -102,12 +102,6 @@ "type": "boolean", "default": false, "x-priority": "internal" - }, - "unitTestRunner": { - "type": "string", - "enum": ["vitest", "jest", "none"], - "description": "Test runner to use for unit tests.", - "x-prompt": "What unit test runner should be used?" } }, "required": ["name"] diff --git a/packages/vue/src/generators/library/__snapshots__/library.spec.ts.snap b/packages/vue/src/generators/library/__snapshots__/library.spec.ts.snap index 10935e3927fe4..1a60225062507 100644 --- a/packages/vue/src/generators/library/__snapshots__/library.spec.ts.snap +++ b/packages/vue/src/generators/library/__snapshots__/library.spec.ts.snap @@ -27,151 +27,6 @@ exports[`lib nested should create a local tsconfig.json 1`] = ` } `; -exports[`lib should add correct jest.config.ts and dependencies to package.json 1`] = ` -{ - "dependencies": { - "tslib": "^2.3.0", - "vue": "^3.3.4", - }, - "devDependencies": { - "@nx/cypress": "0.0.1", - "@nx/eslint": "0.0.1", - "@nx/eslint-plugin": "0.0.1", - "@nx/jest": "0.0.1", - "@nx/js": "0.0.1", - "@nx/rollup": "0.0.1", - "@nx/vite": "0.0.1", - "@nx/vue": "0.0.1", - "@swc-node/register": "~1.6.7", - "@swc/core": "~1.3.85", - "@types/jest": "^29.4.0", - "@types/node": "16.11.7", - "@typescript-eslint/eslint-plugin": "^5.60.1", - "@typescript-eslint/parser": "^5.60.1", - "@vitejs/plugin-vue": "^4.3.1", - "@vue/eslint-config-prettier": "7.1.0", - "@vue/eslint-config-typescript": "^11.0.3", - "@vue/test-utils": "^2.4.1", - "@vue/tsconfig": "^0.4.0", - "@vue/vue3-jest": "^29.2.6", - "babel-jest": "^29.4.1", - "eslint": "~8.46.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-vue": "^9.16.1", - "jest": "^29.4.1", - "jest-environment-jsdom": "^29.4.1", - "prettier": "^2.6.2", - "ts-jest": "^29.1.0", - "ts-node": "10.9.1", - "typescript": "~5.1.3", - "vue-tsc": "^1.8.8", - }, - "name": "@proj/source", -} -`; - -exports[`lib should add correct jest.config.ts and dependencies to package.json 2`] = ` -{ - "ignorePatterns": [ - "**/*", - ], - "overrides": [ - { - "files": [ - "*.ts", - "*.tsx", - "*.js", - "*.jsx", - "*.vue", - ], - "rules": { - "@nx/enforce-module-boundaries": [ - "error", - { - "allow": [], - "depConstraints": [ - { - "onlyDependOnLibsWithTags": [ - "*", - ], - "sourceTag": "*", - }, - ], - "enforceBuildableLibDependency": true, - }, - ], - }, - }, - { - "extends": [ - "plugin:@nx/typescript", - ], - "files": [ - "*.ts", - "*.tsx", - ], - "rules": {}, - }, - { - "extends": [ - "plugin:@nx/javascript", - ], - "files": [ - "*.js", - "*.jsx", - ], - "rules": {}, - }, - { - "env": { - "jest": true, - }, - "files": [ - "*.spec.ts", - "*.spec.tsx", - "*.spec.js", - "*.spec.jsx", - ], - "rules": {}, - }, - ], - "plugins": [ - "@nx", - ], - "root": true, -} -`; - -exports[`lib should add correct jest.config.ts and dependencies to package.json 3`] = ` -"/* eslint-disable */ -export default { - displayName: 'my-lib', - preset: '../jest.preset.js', - - coverageDirectory: '../coverage/my-lib', - moduleFileExtensions: ['js', 'ts', 'json', 'vue'], - transform: { - '^.+.[tj]sx?$': ['babel-jest'], - '^.+.vue$': [ - '@vue/vue3-jest', - { - tsConfig: './tsconfig.spec.json', - }, - ], - }, - testEnvironment: 'jsdom', - testMatch: ['**/*.spec.ts?(x)', '**/__tests__/*.ts?(x)'], -}; -" -`; - -exports[`lib should add correct jest.config.ts and dependencies to package.json 4`] = ` -"{ - "presets": ["@nx/js/babel"] -} -" -`; - exports[`lib should add vite types to tsconfigs and generate correct vite.config.ts file 1`] = ` "/// import { defineConfig } from 'vite'; @@ -243,8 +98,8 @@ exports[`lib should add vue, vite and vitest to package.json 1`] = ` "@nx/vue": "0.0.1", "@swc-node/register": "~1.6.7", "@swc/core": "~1.3.85", - "@typescript-eslint/eslint-plugin": "^5.60.1", - "@typescript-eslint/parser": "^5.60.1", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", "@vitejs/plugin-vue": "^4.3.1", "@vitest/coverage-c8": "~0.32.0", "@vitest/ui": "~0.32.0", diff --git a/packages/vue/src/generators/library/lib/add-jest.ts b/packages/vue/src/generators/library/lib/add-jest.ts deleted file mode 100644 index 9fcc2f3fab71a..0000000000000 --- a/packages/vue/src/generators/library/lib/add-jest.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - addDependenciesToPackageJson, - ensurePackage, - GeneratorCallback, - runTasksInSerial, - Tree, -} from '@nx/devkit'; - -import { nxVersion, vueJest3Version } from '../../../utils/versions'; -import { setupJestProject } from '../../../utils/setup-jest'; -import { NormalizedSchema } from '../schema'; - -export async function addJest( - tree: Tree, - options: NormalizedSchema -): Promise { - const tasks: GeneratorCallback[] = []; - const { configurationGenerator } = ensurePackage( - '@nx/jest', - nxVersion - ); - const jestTask = await configurationGenerator(tree, { - project: options.name, - skipFormat: true, - testEnvironment: 'jsdom', - compiler: 'babel', - }); - tasks.push(jestTask); - - setupJestProject(tree, options.projectRoot); - tasks.push( - addDependenciesToPackageJson( - tree, - {}, - { - '@vue/vue3-jest': vueJest3Version, - } - ) - ); - return runTasksInSerial(...tasks); -} diff --git a/packages/vue/src/generators/library/lib/normalize-options.spec.ts b/packages/vue/src/generators/library/lib/normalize-options.spec.ts deleted file mode 100644 index 6378029e20099..0000000000000 --- a/packages/vue/src/generators/library/lib/normalize-options.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { Tree } from '@nx/devkit'; -import { Linter } from '@nx/eslint'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { normalizeOptions } from './normalize-options'; - -describe('normalizeOptions', () => { - let tree: Tree; - - beforeEach(() => { - tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); - }); - - it('should set unitTestRunner=jest and bundler=none by default', async () => { - const options = await normalizeOptions(tree, { - name: 'test', - linter: Linter.None, - unitTestRunner: 'vitest', - }); - - expect(options).toMatchObject({ - bundler: 'none', - unitTestRunner: 'vitest', - }); - }); - - it('should set unitTestRunner=vitest by default when bundler is vite', async () => { - const options = await normalizeOptions(tree, { - name: 'test', - linter: Linter.None, - bundler: 'vite', - unitTestRunner: 'vitest', - }); - - expect(options).toMatchObject({ - bundler: 'vite', - unitTestRunner: 'vitest', - }); - }); - - it('should set maintain unitTestRunner when bundler is vite', async () => { - const options = await normalizeOptions(tree, { - name: 'test', - linter: Linter.None, - bundler: 'vite', - unitTestRunner: 'vitest', - }); - - expect(options).toMatchObject({ - bundler: 'vite', - unitTestRunner: 'vitest', - }); - }); -}); diff --git a/packages/vue/src/generators/library/library.spec.ts b/packages/vue/src/generators/library/library.spec.ts index 01d0e0c4df0a7..31285f9adccfd 100644 --- a/packages/vue/src/generators/library/library.spec.ts +++ b/packages/vue/src/generators/library/library.spec.ts @@ -84,14 +84,6 @@ describe('lib', () => { expect(readJson(tree, '/package.json')).toMatchSnapshot(); }); - it('should add correct jest.config.ts and dependencies to package.json', async () => { - await libraryGenerator(tree, { ...defaultSchema, unitTestRunner: 'jest' }); - expect(readJson(tree, '/package.json')).toMatchSnapshot(); - expect(readJson(tree, '.eslintrc.json')).toMatchSnapshot(); - expect(tree.read('my-lib/jest.config.ts', 'utf-8')).toMatchSnapshot(); - expect(tree.read('my-lib/.babelrc', 'utf-8')).toMatchSnapshot(); - }); - it('should update root tsconfig.base.json', async () => { await libraryGenerator(tree, defaultSchema); const tsconfigJson = readJson(tree, '/tsconfig.base.json'); diff --git a/packages/vue/src/generators/library/library.ts b/packages/vue/src/generators/library/library.ts index 7e76b6ba22d63..e3a87a4aa4b02 100644 --- a/packages/vue/src/generators/library/library.ts +++ b/packages/vue/src/generators/library/library.ts @@ -17,7 +17,6 @@ import { createLibraryFiles } from './lib/create-library-files'; import { extractTsConfigBase } from '../../utils/create-ts-config'; import componentGenerator from '../component/component'; import { addVite } from './lib/add-vite'; -import { addJest } from './lib/add-jest'; export async function libraryGenerator(tree: Tree, schema: Schema) { const tasks: GeneratorCallback[] = []; @@ -52,9 +51,6 @@ export async function libraryGenerator(tree: Tree, schema: Schema) { tasks.push(await addVite(tree, options)); - if (options.unitTestRunner === 'jest') - tasks.push(await addJest(tree, options)); - if (options.component) { await componentGenerator(tree, { name: options.name, diff --git a/packages/vue/src/generators/library/schema.d.ts b/packages/vue/src/generators/library/schema.d.ts index dca9062124bc1..3af9e8daae8ec 100644 --- a/packages/vue/src/generators/library/schema.d.ts +++ b/packages/vue/src/generators/library/schema.d.ts @@ -22,7 +22,7 @@ export interface Schema { skipTsConfig?: boolean; strict?: boolean; tags?: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; minimal?: boolean; e2eTestRunner?: 'cypress' | 'none'; } @@ -37,5 +37,5 @@ export interface NormalizedSchema extends Schema { parsedTags: string[]; appMain?: string; appSourceRoot?: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; } diff --git a/packages/vue/src/generators/library/schema.json b/packages/vue/src/generators/library/schema.json index d49706abb9740..577e8293f265b 100644 --- a/packages/vue/src/generators/library/schema.json +++ b/packages/vue/src/generators/library/schema.json @@ -46,7 +46,7 @@ }, "unitTestRunner": { "type": "string", - "enum": ["vitest", "jest", "none"], + "enum": ["vitest", "none"], "description": "Test runner to use for unit tests.", "x-prompt": "What unit test runner should be used?" }, diff --git a/packages/vue/src/generators/stories/lib/component-story.spec.ts b/packages/vue/src/generators/stories/lib/component-story.spec.ts index 3d332912ad69d..69aab18659655 100644 --- a/packages/vue/src/generators/stories/lib/component-story.spec.ts +++ b/packages/vue/src/generators/stories/lib/component-story.spec.ts @@ -116,7 +116,7 @@ export async function createTestUILib(libName: string): Promise { component: true, skipFormat: true, skipTsConfig: false, - unitTestRunner: 'jest', + unitTestRunner: 'vitest', projectNameAndRootFormat: 'as-provided', }); diff --git a/packages/vue/src/utils/add-linting.ts b/packages/vue/src/utils/add-linting.ts index aebee7677d88b..48468ef087d40 100644 --- a/packages/vue/src/utils/add-linting.ts +++ b/packages/vue/src/utils/add-linting.ts @@ -19,7 +19,7 @@ export async function addLinting( linter: Linter; name: string; projectRoot: string; - unitTestRunner?: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'vitest' | 'none'; setParserOptionsProject?: boolean; skipPackageJson?: boolean; rootProject?: boolean; diff --git a/packages/vue/src/utils/create-ts-config.ts b/packages/vue/src/utils/create-ts-config.ts index 336f154c89120..08c516b46272c 100644 --- a/packages/vue/src/utils/create-ts-config.ts +++ b/packages/vue/src/utils/create-ts-config.ts @@ -23,7 +23,7 @@ export function createTsConfig( jsxImportSource: 'vue', moduleResolution: 'node', resolveJsonModule: true, - verbatimModuleSyntax: options.unitTestRunner !== 'jest', + verbatimModuleSyntax: true, }, files: [], include: [], diff --git a/packages/vue/src/utils/setup-jest.ts b/packages/vue/src/utils/setup-jest.ts deleted file mode 100644 index 3b57a303241cb..0000000000000 --- a/packages/vue/src/utils/setup-jest.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - applyChangesToString, - ChangeType, - joinPathFragments, - offsetFromRoot, - Tree, - writeJson, -} from '@nx/devkit'; -import { ObjectLiteralExpression } from 'typescript'; - -export function setupJestProject(tree: Tree, projectRoot: string) { - updateJestConfigTsFile(tree, projectRoot); - writeBabelRcFile(tree, projectRoot); -} - -export function writeBabelRcFile(tree: Tree, projectRoot: string) { - writeJson(tree, joinPathFragments(projectRoot, '.babelrc'), { - presets: ['@nx/js/babel'], - }); -} - -export function updateJestConfigTsFile(tree: Tree, projectRoot: string) { - const jestConfigTs = joinPathFragments(projectRoot, 'jest.config.ts'); - if (tree.exists(jestConfigTs)) { - const { tsquery } = require('@phenomnomnominal/tsquery'); - let fileContent = tree.read(jestConfigTs, 'utf-8'); - const sourceFile = tsquery.ast(fileContent); - - const settingsObject = tsquery.query( - sourceFile, - 'ObjectLiteralExpression' - )?.[0] as ObjectLiteralExpression; - - if (settingsObject) { - const moduleFileExtensions = tsquery.query( - sourceFile, - `PropertyAssignment:has(Identifier:has([name="moduleFileExtensions"]))` - )?.[0]; - - if (moduleFileExtensions) { - fileContent = applyChangesToString(fileContent, [ - { - type: ChangeType.Delete, - start: moduleFileExtensions.getStart(), - length: - moduleFileExtensions.getEnd() - - moduleFileExtensions.getStart() + - 1, - }, - ]); - } - - const transformProperty = tsquery.query( - sourceFile, - `PropertyAssignment:has(Identifier:has([name="transform"]))` - )?.[0]; - - if (transformProperty) { - fileContent = applyChangesToString(fileContent, [ - { - type: ChangeType.Delete, - start: transformProperty.getStart(), - length: - transformProperty.getEnd() - transformProperty.getStart() + 1, - }, - ]); - } - - const settingsObjectUpdated = tsquery.query( - fileContent, - 'ObjectLiteralExpression' - )?.[0] as ObjectLiteralExpression; - - fileContent = applyChangesToString(fileContent, [ - { - type: ChangeType.Insert, - index: settingsObjectUpdated.getEnd() - 1, - text: `, - moduleFileExtensions: ['js', 'ts', 'json', 'vue'], - transform: { - '^.+\\.[tj]sx?$': ['babel-jest'], - '^.+\\.vue$': [ - '@vue/vue3-jest', - { - tsConfig: './tsconfig.spec.json', - }, - ], - }, - testEnvironment: 'jsdom', - testMatch: ['**/*.spec.ts?(x)', '**/__tests__/*.ts?(x)'], - `, - }, - ]); - tree.write(jestConfigTs, fileContent); - } else { - writeNewJestConfig(tree, projectRoot); - } - } else { - writeNewJestConfig(tree, projectRoot); - } -} - -function writeNewJestConfig(tree: Tree, projectRoot: string) { - tree.write( - joinPathFragments(projectRoot, 'jest.config.js'), - ` - module.exports = { - preset: '${offsetFromRoot}/jest.preset.js', - moduleFileExtensions: ['js', 'ts', 'json', 'vue'], - transform: { - '^.+\\.[tj]sx?$': ['babel-jest'], - '^.+\\.vue$': [ - '@vue/vue3-jest', - { - tsConfig: './tsconfig.spec.json', - }, - ], - }, - testEnvironment: 'jsdom', - testMatch: ['**/*.spec.ts?(x)', '**/__tests__/*.ts?(x)'], - }; - ` - ); -} diff --git a/packages/vue/src/utils/versions.ts b/packages/vue/src/utils/versions.ts index d87654c80c2fa..1ad4328846bd3 100644 --- a/packages/vue/src/utils/versions.ts +++ b/packages/vue/src/utils/versions.ts @@ -11,7 +11,6 @@ export const vueTsconfigVersion = '^0.4.0'; // test deps export const vueTestUtilsVersion = '^2.4.1'; export const vitePluginVueVersion = '^4.3.1'; -export const vueJest3Version = '^29.2.6'; // linting deps export const vueEslintConfigPrettierVersion = '7.1.0'; diff --git a/packages/web/docs/application-examples.md b/packages/web/docs/application-examples.md index 28be0e4214c8a..edec2100a5f89 100644 --- a/packages/web/docs/application-examples.md +++ b/packages/web/docs/application-examples.md @@ -28,7 +28,7 @@ When choosing `vite` as the bundler, your unit tests will be set up with `vitest Create an application named `my-app` in the `my-dir` directory: {% callout type="note" title="Directory Flag Behavior Changes" %} -The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [workspace layout documentation](/deprecated/workspace-layout) for more details. +The command below uses the `as-provided` directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the `derived` option, use `--directory=my-dir`. See the [as-provided vs. derived documentation](/deprecated/as-provided-vs-derived) for more details. {% /callout %} ```bash diff --git a/packages/webpack/src/utils/module-federation/get-remotes-for-host.ts b/packages/webpack/src/utils/module-federation/get-remotes-for-host.ts index 99d35cfffb6dd..917f1583bdbd5 100644 --- a/packages/webpack/src/utils/module-federation/get-remotes-for-host.ts +++ b/packages/webpack/src/utils/module-federation/get-remotes-for-host.ts @@ -35,7 +35,7 @@ function extractRemoteProjectsFromConfig( typeof key === 'string' && typeof parsedManifest[key] === 'string' ) ) { - remotes.push(Object.keys(parsedManifest)); + remotes.push(...Object.keys(parsedManifest)); } } } diff --git a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap index a87d26c72562a..0750263e95360 100644 --- a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap +++ b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap @@ -46,9 +46,6 @@ exports[`new should generate an empty nx.json 1`] = ` "lint": { "cache": true, }, - "test": { - "cache": true, - }, }, } `; diff --git a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts index a18db7f54b2cc..2c020b0941969 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.spec.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.spec.ts @@ -117,9 +117,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "lint": { "cache": true, }, - "test": { - "cache": true, - }, }, } `); @@ -166,9 +163,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "lint": { "cache": true, }, - "test": { - "cache": true, - }, }, } `); @@ -234,9 +228,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => { "lint": { "cache": true, }, - "test": { - "cache": true, - }, }, } `); diff --git a/packages/workspace/src/generators/new/generate-workspace-files.ts b/packages/workspace/src/generators/new/generate-workspace-files.ts index 9d6d16168190f..3b9b61ec1c260 100644 --- a/packages/workspace/src/generators/new/generate-workspace-files.ts +++ b/packages/workspace/src/generators/new/generate-workspace-files.ts @@ -75,9 +75,6 @@ function createNxJson( lint: { cache: true, }, - test: { - cache: true, - }, e2e: { cache: true, }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7786872fd88af..2fd2f24e59fd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -292,7 +292,7 @@ devDependencies: version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(eslint@8.46.0)(nx@17.0.0-rc.2)(verdaccio@5.15.4) '@nx/eslint-plugin': specifier: 17.0.0-rc.2 - version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@5.62.0)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) + version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@6.9.1)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) '@nx/jest': specifier: 17.0.0-rc.2 version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(nx@17.0.0-rc.2)(ts-node@10.9.1)(typescript@5.1.3)(verdaccio@5.15.4) @@ -468,17 +468,17 @@ devDependencies: specifier: ^1.1.5 version: 1.1.5 '@typescript-eslint/eslint-plugin': - specifier: 5.62.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.46.0)(typescript@5.1.3) + specifier: ^6.9.1 + version: 6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.46.0)(typescript@5.1.3) '@typescript-eslint/parser': - specifier: 5.62.0 - version: 5.62.0(eslint@8.46.0)(typescript@5.1.3) + specifier: ^6.9.1 + version: 6.9.1(eslint@8.46.0)(typescript@5.1.3) '@typescript-eslint/type-utils': - specifier: 5.60.1 - version: 5.60.1(eslint@8.46.0)(typescript@5.1.3) + specifier: ^6.9.1 + version: 6.9.1(eslint@8.46.0)(typescript@5.1.3) '@typescript-eslint/utils': - specifier: 5.62.0 - version: 5.62.0(eslint@8.46.0)(typescript@5.1.3) + specifier: ^6.9.1 + version: 6.9.1(eslint@8.46.0)(typescript@5.1.3) '@xstate/immer': specifier: 0.3.1 version: 0.3.1(immer@9.0.16)(xstate@4.34.0) @@ -589,7 +589,7 @@ devDependencies: version: 2.14.0(eslint@8.46.0) eslint-plugin-import: specifier: 2.26.0 - version: 2.26.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.2)(eslint@8.46.0) + version: 2.26.0(@typescript-eslint/parser@6.9.1)(eslint@8.46.0) eslint-plugin-jsx-a11y: specifier: 6.6.1 version: 6.6.1(eslint@8.46.0) @@ -747,11 +747,11 @@ devDependencies: specifier: ^3.0.1 version: 3.4.7 metro-config: - specifier: 0.76.7 - version: 0.76.7 + specifier: 0.76.8 + version: 0.76.8 metro-resolver: - specifier: 0.76.7 - version: 0.76.7 + specifier: 0.76.8 + version: 0.76.8 mini-css-extract-plugin: specifier: ~2.4.7 version: 2.4.7(webpack@5.88.0) @@ -2356,16 +2356,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-flow@7.18.6(@babel/core@7.22.9): - resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.22.9): resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==} engines: {node: '>=6.9.0'} @@ -2737,17 +2727,6 @@ packages: '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.22.9): - resolution: {integrity: sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.22.9) - dev: true - /@babel/plugin-transform-flow-strip-types@7.22.5(@babel/core@7.22.9): resolution: {integrity: sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==} engines: {node: '>=6.9.0'} @@ -3035,16 +3014,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.22.9): - resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-transform-react-display-name@7.22.5(@babel/core@7.22.9): resolution: {integrity: sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==} engines: {node: '>=6.9.0'} @@ -3085,20 +3054,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx@7.21.0(@babel/core@7.22.9): - resolution: {integrity: sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.9) - '@babel/types': 7.22.5 - dev: true - /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.9): resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} engines: {node: '>=6.9.0'} @@ -3213,19 +3168,6 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.22.9): - resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.9) - dev: true - /@babel/plugin-transform-typescript@7.22.9(@babel/core@7.22.9): resolution: {integrity: sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==} engines: {node: '>=6.9.0'} @@ -4505,12 +4447,7 @@ packages: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: eslint: 8.46.0 - eslint-visitor-keys: 3.3.0 - dev: true - - /@eslint-community/regexpp@4.5.0: - resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + eslint-visitor-keys: 3.4.3 dev: true /@eslint-community/regexpp@4.6.2: @@ -5720,7 +5657,7 @@ packages: dependencies: '@phenomnomnominal/tsquery': 4.1.1(typescript@5.1.3) ejs: 3.1.8 - ignore: 5.2.0 + ignore: 5.2.4 nx: 15.8.0(@swc-node/register@1.6.8)(@swc/core@1.3.86) semver: 7.3.4 tmp: 0.2.1 @@ -5736,7 +5673,7 @@ packages: dependencies: '@phenomnomnominal/tsquery': 4.1.1(typescript@5.1.3) ejs: 3.1.8 - ignore: 5.2.0 + ignore: 5.2.4 nx: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86) semver: 7.3.4 tmp: 0.2.1 @@ -5771,10 +5708,10 @@ packages: - verdaccio dev: true - /@nrwl/eslint-plugin-nx@17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@5.62.0)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4): + /@nrwl/eslint-plugin-nx@17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@6.9.1)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4): resolution: {integrity: sha512-qASP7I8CEuJWe0vJP7xde6uI/1kKIWOSsSnFcjlPSbwI+LxXBSSDRoGMm2MU/f2mt0qkxZX8WSNRBpxsbNbG+A==} dependencies: - '@nx/eslint-plugin': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@5.62.0)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) + '@nx/eslint-plugin': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@6.9.1)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -5829,7 +5766,7 @@ packages: chalk: 4.1.2 fast-glob: 3.2.7 fs-extra: 11.1.1 - ignore: 5.2.0 + ignore: 5.2.4 js-tokens: 4.0.0 minimatch: 3.0.5 source-map-support: 0.5.19 @@ -5866,7 +5803,7 @@ packages: chalk: 4.1.2 fast-glob: 3.2.7 fs-extra: 11.1.1 - ignore: 5.2.0 + ignore: 5.2.4 js-tokens: 4.0.0 minimatch: 3.0.5 source-map-support: 0.5.19 @@ -6283,7 +6220,7 @@ packages: '@nx/workspace': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.1.3) '@schematics/angular': 16.2.0 - '@typescript-eslint/type-utils': 5.60.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/type-utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) chalk: 4.1.2 enquirer: 2.3.6 esbuild: 0.19.5 @@ -6403,7 +6340,7 @@ packages: - verdaccio dev: true - /@nx/eslint-plugin@17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@5.62.0)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4): + /@nx/eslint-plugin@17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@6.9.1)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4): resolution: {integrity: sha512-FJvgyzbZguURGQREGPG+3nWhZTjCKKxCPw6uVONSusWsZ3JypQ9QsY0u8I8p4eybIWNkl2/zQbMfh30mv+JZWQ==} peerDependencies: '@typescript-eslint/parser': ^5.60.1 @@ -6412,11 +6349,11 @@ packages: eslint-config-prettier: optional: true dependencies: - '@nrwl/eslint-plugin-nx': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@5.62.0)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) + '@nrwl/eslint-plugin-nx': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(@typescript-eslint/parser@6.9.1)(eslint-config-prettier@9.0.0)(eslint@8.46.0)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) '@nx/devkit': 17.0.0-rc.2(nx@17.0.0-rc.2) '@nx/js': 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(nx@17.0.0-rc.2)(typescript@5.1.3)(verdaccio@5.15.4) - '@typescript-eslint/parser': 5.62.0(eslint@8.46.0)(typescript@5.1.3) - '@typescript-eslint/type-utils': 5.60.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/parser': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/type-utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) '@typescript-eslint/utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) chalk: 4.1.2 confusing-browser-globals: 1.0.11 @@ -10217,29 +10154,30 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.46.0)(typescript@5.1.3): - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/eslint-plugin@6.9.1(@typescript-eslint/parser@6.9.1)(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.46.0)(typescript@5.1.3) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) + '@eslint-community/regexpp': 4.6.2 + '@typescript-eslint/parser': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/type-utils': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/utils': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/visitor-keys': 6.9.1 debug: 4.3.4(supports-color@5.5.0) eslint: 8.46.0 graphemer: 1.4.0 - ignore: 5.2.0 - natural-compare-lite: 1.4.0 - semver: 7.5.3 - tsutils: 3.21.0(typescript@5.1.3) + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.1.3) typescript: 5.1.3 transitivePeerDependencies: - supports-color @@ -10265,6 +10203,27 @@ packages: - supports-color dev: true + /@typescript-eslint/parser@6.9.1(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.1.3) + '@typescript-eslint/visitor-keys': 6.9.1 + debug: 4.3.4(supports-color@5.5.0) + eslint: 8.46.0 + typescript: 5.1.3 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/scope-manager@5.59.2: resolution: {integrity: sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -10273,14 +10232,6 @@ packages: '@typescript-eslint/visitor-keys': 5.59.2 dev: true - /@typescript-eslint/scope-manager@5.60.1: - resolution: {integrity: sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.60.1 - '@typescript-eslint/visitor-keys': 5.60.1 - dev: true - /@typescript-eslint/scope-manager@5.62.0: resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -10289,6 +10240,14 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: true + /@typescript-eslint/scope-manager@6.9.1: + resolution: {integrity: sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/visitor-keys': 6.9.1 + dev: true + /@typescript-eslint/type-utils@5.59.2(eslint@8.46.0)(typescript@5.1.3): resolution: {integrity: sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -10309,8 +10268,8 @@ packages: - supports-color dev: true - /@typescript-eslint/type-utils@5.60.1(eslint@8.46.0)(typescript@5.1.3): - resolution: {integrity: sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==} + /@typescript-eslint/type-utils@5.62.0(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -10319,8 +10278,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3) - '@typescript-eslint/utils': 5.60.1(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) debug: 4.3.4(supports-color@5.5.0) eslint: 8.46.0 tsutils: 3.21.0(typescript@5.1.3) @@ -10329,21 +10288,21 @@ packages: - supports-color dev: true - /@typescript-eslint/type-utils@5.62.0(eslint@8.46.0)(typescript@5.1.3): - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/type-utils@6.9.1(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: '*' + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.46.0)(typescript@5.1.3) + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.1.3) + '@typescript-eslint/utils': 6.9.1(eslint@8.46.0)(typescript@5.1.3) debug: 4.3.4(supports-color@5.5.0) eslint: 8.46.0 - tsutils: 3.21.0(typescript@5.1.3) + ts-api-utils: 1.0.3(typescript@5.1.3) typescript: 5.1.3 transitivePeerDependencies: - supports-color @@ -10354,16 +10313,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types@5.60.1: - resolution: {integrity: sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - /@typescript-eslint/types@5.62.0: resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types@6.9.1: + resolution: {integrity: sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + /@typescript-eslint/typescript-estree@5.59.2(typescript@5.1.3): resolution: {integrity: sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -10385,8 +10344,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@5.60.1(typescript@5.1.3): - resolution: {integrity: sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==} + /@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.3): + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -10394,8 +10353,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.60.1 - '@typescript-eslint/visitor-keys': 5.60.1 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 @@ -10406,22 +10365,22 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.3): - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@6.9.1(typescript@5.1.3): + resolution: {integrity: sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/visitor-keys': 6.9.1 debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.3 - tsutils: 3.21.0(typescript@5.1.3) + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.1.3) typescript: 5.1.3 transitivePeerDependencies: - supports-color @@ -10447,8 +10406,8 @@ packages: - typescript dev: true - /@typescript-eslint/utils@5.60.1(eslint@8.46.0)(typescript@5.1.3): - resolution: {integrity: sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==} + /@typescript-eslint/utils@5.62.0(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -10456,9 +10415,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.2 - '@typescript-eslint/scope-manager': 5.60.1 - '@typescript-eslint/types': 5.60.1 - '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.3) eslint: 8.46.0 eslint-scope: 5.1.1 semver: 7.5.3 @@ -10467,21 +10426,20 @@ packages: - typescript dev: true - /@typescript-eslint/utils@5.62.0(eslint@8.46.0)(typescript@5.1.3): - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/utils@6.9.1(eslint@8.46.0)(typescript@5.1.3): + resolution: {integrity: sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.2 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.3) + '@typescript-eslint/scope-manager': 6.9.1 + '@typescript-eslint/types': 6.9.1 + '@typescript-eslint/typescript-estree': 6.9.1(typescript@5.1.3) eslint: 8.46.0 - eslint-scope: 5.1.1 - semver: 7.5.3 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript @@ -10492,15 +10450,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: '@typescript-eslint/types': 5.59.2 - eslint-visitor-keys: 3.3.0 - dev: true - - /@typescript-eslint/visitor-keys@5.60.1: - resolution: {integrity: sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.60.1 - eslint-visitor-keys: 3.3.0 + eslint-visitor-keys: 3.4.3 dev: true /@typescript-eslint/visitor-keys@5.62.0: @@ -10508,7 +10458,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.3.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@typescript-eslint/visitor-keys@6.9.1: + resolution: {integrity: sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.9.1 + eslint-visitor-keys: 3.4.3 dev: true /@verdaccio/commons-api@10.2.0: @@ -11973,7 +11931,7 @@ packages: /babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.22.9): resolution: {integrity: sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==} dependencies: - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) transitivePeerDependencies: - '@babel/core' dev: true @@ -12020,8 +11978,8 @@ packages: '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.9) '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.22.9) '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.9) - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.9) + '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.9) '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.9) @@ -12029,7 +11987,7 @@ packages: '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.9) '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-transform-flow-strip-types': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.9) @@ -12038,8 +11996,8 @@ packages: '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.9) @@ -15097,6 +15055,35 @@ packages: - supports-color dev: true + /eslint-module-utils@2.7.4(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.6)(eslint@8.46.0): + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + debug: 3.2.7(supports-color@8.1.1) + eslint: 8.46.0 + eslint-import-resolver-node: 0.3.6 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-plugin-cypress@2.14.0(eslint@8.46.0): resolution: {integrity: sha512-eW6tv7iIg7xujleAJX4Ujm649Bf5jweqa4ObPEIuueYRyLZt7qXGWhCY/n4bfeFW/j6nQZwbIBHKZt6EKcL/cg==} peerDependencies: @@ -15137,6 +15124,37 @@ packages: - supports-color dev: true + /eslint-plugin-import@2.26.0(@typescript-eslint/parser@6.9.1)(eslint@8.46.0): + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.9.1(eslint@8.46.0)(typescript@5.1.3) + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.46.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.4(@typescript-eslint/parser@6.9.1)(eslint-import-resolver-node@0.3.6)(eslint@8.46.0) + has: 1.0.3 + is-core-module: 2.11.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.1 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-jsx-a11y@6.6.1(eslint@8.46.0): resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} @@ -15306,7 +15324,7 @@ packages: dependencies: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.3.0 + eslint-visitor-keys: 3.4.3 dev: true /espree@9.6.1: @@ -16535,7 +16553,7 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.1 - ignore: 5.2.0 + ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -19505,8 +19523,8 @@ packages: engines: {node: '>= 0.6'} dev: true - /metro-babel-transformer@0.76.7: - resolution: {integrity: sha512-bgr2OFn0J4r0qoZcHrwEvccF7g9k3wdgTOgk6gmGHrtlZ1Jn3oCpklW/DfZ9PzHfjY2mQammKTc19g/EFGyOJw==} + /metro-babel-transformer@0.76.8: + resolution: {integrity: sha512-Hh6PW34Ug/nShlBGxkwQJSgPGAzSJ9FwQXhUImkzdsDgVu6zj5bx258J8cJVSandjNoQ8nbaHK6CaHlnbZKbyA==} engines: {node: '>=16'} dependencies: '@babel/core': 7.22.9 @@ -19516,30 +19534,30 @@ packages: - supports-color dev: true - /metro-cache-key@0.76.7: - resolution: {integrity: sha512-0pecoIzwsD/Whn/Qfa+SDMX2YyasV0ndbcgUFx7w1Ct2sLHClujdhQ4ik6mvQmsaOcnGkIyN0zcceMDjC2+BFQ==} + /metro-cache-key@0.76.8: + resolution: {integrity: sha512-buKQ5xentPig9G6T37Ww/R/bC+/V1MA5xU/D8zjnhlelsrPG6w6LtHUS61ID3zZcMZqYaELWk5UIadIdDsaaLw==} engines: {node: '>=16'} dev: true - /metro-cache@0.76.7: - resolution: {integrity: sha512-nWBMztrs5RuSxZRI7hgFgob5PhYDmxICh9FF8anm9/ito0u0vpPvRxt7sRu8fyeD2AHdXqE7kX32rWY0LiXgeg==} + /metro-cache@0.76.8: + resolution: {integrity: sha512-QBJSJIVNH7Hc/Yo6br/U/qQDUpiUdRgZ2ZBJmvAbmAKp2XDzsapnMwK/3BGj8JNWJF7OLrqrYHsRsukSbUBpvQ==} engines: {node: '>=16'} dependencies: - metro-core: 0.76.7 + metro-core: 0.76.8 rimraf: 3.0.2 dev: true - /metro-config@0.76.7: - resolution: {integrity: sha512-CFDyNb9bqxZemiChC/gNdXZ7OQkIwmXzkrEXivcXGbgzlt/b2juCv555GWJHyZSlorwnwJfY3uzAFu4A9iRVfg==} + /metro-config@0.76.8: + resolution: {integrity: sha512-SL1lfKB0qGHALcAk2zBqVgQZpazDYvYFGwCK1ikz0S6Y/CM2i2/HwuZN31kpX6z3mqjv/6KvlzaKoTb1otuSAA==} engines: {node: '>=16'} dependencies: connect: 3.6.6 cosmiconfig: 5.2.1 jest-validate: 29.5.0 - metro: 0.76.7 - metro-cache: 0.76.7 - metro-core: 0.76.7 - metro-runtime: 0.76.7 + metro: 0.76.8 + metro-cache: 0.76.8 + metro-core: 0.76.8 + metro-runtime: 0.76.8 transitivePeerDependencies: - bufferutil - encoding @@ -19547,16 +19565,16 @@ packages: - utf-8-validate dev: true - /metro-core@0.76.7: - resolution: {integrity: sha512-0b8KfrwPmwCMW+1V7ZQPkTy2tsEKZjYG9Pu1PTsu463Z9fxX7WaR0fcHFshv+J1CnQSUTwIGGjbNvj1teKe+pw==} + /metro-core@0.76.8: + resolution: {integrity: sha512-sl2QLFI3d1b1XUUGxwzw/KbaXXU/bvFYrSKz6Sg19AdYGWFyzsgZ1VISRIDf+HWm4R/TJXluhWMEkEtZuqi3qA==} engines: {node: '>=16'} dependencies: lodash.throttle: 4.1.1 - metro-resolver: 0.76.7 + metro-resolver: 0.76.8 dev: true - /metro-file-map@0.76.7: - resolution: {integrity: sha512-s+zEkTcJ4mOJTgEE2ht4jIo1DZfeWreQR3tpT3gDV/Y/0UQ8aJBTv62dE775z0GLsWZApiblAYZsj7ZE8P06nw==} + /metro-file-map@0.76.8: + resolution: {integrity: sha512-A/xP1YNEVwO1SUV9/YYo6/Y1MmzhL4ZnVgcJC3VmHp/BYVOXVStzgVbWv2wILe56IIMkfXU+jpXrGKKYhFyHVw==} engines: {node: '>=16'} dependencies: anymatch: 3.1.3 @@ -19577,8 +19595,8 @@ packages: - supports-color dev: true - /metro-inspector-proxy@0.76.7: - resolution: {integrity: sha512-rNZ/6edTl/1qUekAhAbaFjczMphM50/UjtxiKulo6vqvgn/Mjd9hVqDvVYfAMZXqPvlusD88n38UjVYPkruLSg==} + /metro-inspector-proxy@0.76.8: + resolution: {integrity: sha512-Us5o5UEd4Smgn1+TfHX4LvVPoWVo9VsVMn4Ldbk0g5CQx3Gu0ygc/ei2AKPGTwsOZmKxJeACj7yMH2kgxQP/iw==} engines: {node: '>=16'} hasBin: true dependencies: @@ -19594,22 +19612,22 @@ packages: - utf-8-validate dev: true - /metro-minify-terser@0.76.7: - resolution: {integrity: sha512-FQiZGhIxCzhDwK4LxyPMLlq0Tsmla10X7BfNGlYFK0A5IsaVKNJbETyTzhpIwc+YFRT4GkFFwgo0V2N5vxO5HA==} + /metro-minify-terser@0.76.8: + resolution: {integrity: sha512-Orbvg18qXHCrSj1KbaeSDVYRy/gkro2PC7Fy2tDSH1c9RB4aH8tuMOIXnKJE+1SXxBtjWmQ5Yirwkth2DyyEZA==} engines: {node: '>=16'} dependencies: terser: 5.19.2 dev: true - /metro-minify-uglify@0.76.7: - resolution: {integrity: sha512-FuXIU3j2uNcSvQtPrAJjYWHruPiQ+EpE++J9Z+VznQKEHcIxMMoQZAfIF2IpZSrZYfLOjVFyGMvj41jQMxV1Vw==} + /metro-minify-uglify@0.76.8: + resolution: {integrity: sha512-6l8/bEvtVaTSuhG1FqS0+Mc8lZ3Bl4RI8SeRIifVLC21eeSDp4CEBUWSGjpFyUDfi6R5dXzYaFnSgMNyfxADiQ==} engines: {node: '>=16'} dependencies: uglify-es: 3.3.9 dev: true - /metro-react-native-babel-preset@0.76.7(@babel/core@7.22.9): - resolution: {integrity: sha512-R25wq+VOSorAK3hc07NW0SmN8z9S/IR0Us0oGAsBcMZnsgkbOxu77Mduqf+f4is/wnWHc5+9bfiqdLnaMngiVw==} + /metro-react-native-babel-preset@0.76.8(@babel/core@7.22.9): + resolution: {integrity: sha512-Ptza08GgqzxEdK8apYsjTx2S8WDUlS2ilBlu9DR1CUcHmg4g3kOkFylZroogVAUKtpYQNYwAvdsjmrSdDNtiAg==} engines: {node: '>=16'} peerDependencies: '@babel/core': '*' @@ -19625,30 +19643,30 @@ packages: '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.9) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) '@babel/plugin-syntax-export-default-from': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-classes': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.9) '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-transform-flow-strip-types': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-transform-react-display-name': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-runtime': 7.22.9(@babel/core@7.22.9) '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.22.9) + '@babel/plugin-transform-typescript': 7.22.9(@babel/core@7.22.9) '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.9) '@babel/template': 7.22.5 babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.22.9) @@ -19657,42 +19675,42 @@ packages: - supports-color dev: true - /metro-resolver@0.76.7: - resolution: {integrity: sha512-pC0Wgq29HHIHrwz23xxiNgylhI8Rq1V01kQaJ9Kz11zWrIdlrH0ZdnJ7GC6qA0ErROG+cXmJ0rJb8/SW1Zp2IA==} + /metro-resolver@0.76.8: + resolution: {integrity: sha512-KccOqc10vrzS7ZhG2NSnL2dh3uVydarB7nOhjreQ7C4zyWuiW9XpLC4h47KtGQv3Rnv/NDLJYeDqaJ4/+140HQ==} engines: {node: '>=16'} dev: true - /metro-runtime@0.76.7: - resolution: {integrity: sha512-MuWHubQHymUWBpZLwuKZQgA/qbb35WnDAKPo83rk7JRLIFPvzXSvFaC18voPuzJBt1V98lKQIonh6MiC9gd8Ug==} + /metro-runtime@0.76.8: + resolution: {integrity: sha512-XKahvB+iuYJSCr3QqCpROli4B4zASAYpkK+j3a0CJmokxCDNbgyI4Fp88uIL6rNaZfN0Mv35S0b99SdFXIfHjg==} engines: {node: '>=16'} dependencies: '@babel/runtime': 7.22.6 react-refresh: 0.4.3 dev: true - /metro-source-map@0.76.7: - resolution: {integrity: sha512-Prhx7PeRV1LuogT0Kn5VjCuFu9fVD68eefntdWabrksmNY6mXK8pRqzvNJOhTojh6nek+RxBzZeD6MIOOyXS6w==} + /metro-source-map@0.76.8: + resolution: {integrity: sha512-Hh0ncPsHPVf6wXQSqJqB3K9Zbudht4aUtNpNXYXSxH+pteWqGAXnjtPsRAnCsCWl38wL0jYF0rJDdMajUI3BDw==} engines: {node: '>=16'} dependencies: '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 invariant: 2.2.4 - metro-symbolicate: 0.76.7 + metro-symbolicate: 0.76.8 nullthrows: 1.1.1 - ob1: 0.76.7 + ob1: 0.76.8 source-map: 0.5.7 vlq: 1.0.1 transitivePeerDependencies: - supports-color dev: true - /metro-symbolicate@0.76.7: - resolution: {integrity: sha512-p0zWEME5qLSL1bJb93iq+zt5fz3sfVn9xFYzca1TJIpY5MommEaS64Va87lp56O0sfEIvh4307Oaf/ZzRjuLiQ==} + /metro-symbolicate@0.76.8: + resolution: {integrity: sha512-LrRL3uy2VkzrIXVlxoPtqb40J6Bf1mlPNmUQewipc3qfKKFgtPHBackqDy1YL0njDsWopCKcfGtFYLn0PTUn3w==} engines: {node: '>=16'} hasBin: true dependencies: invariant: 2.2.4 - metro-source-map: 0.76.7 + metro-source-map: 0.76.8 nullthrows: 1.1.1 source-map: 0.5.7 through2: 2.0.5 @@ -19701,8 +19719,8 @@ packages: - supports-color dev: true - /metro-transform-plugins@0.76.7: - resolution: {integrity: sha512-iSmnjVApbdivjuzb88Orb0JHvcEt5veVyFAzxiS5h0QB+zV79w6JCSqZlHCrbNOkOKBED//LqtKbFVakxllnNg==} + /metro-transform-plugins@0.76.8: + resolution: {integrity: sha512-PlkGTQNqS51Bx4vuufSQCdSn2R2rt7korzngo+b5GCkeX5pjinPjnO2kNhQ8l+5bO0iUD/WZ9nsM2PGGKIkWFA==} engines: {node: '>=16'} dependencies: '@babel/core': 7.22.9 @@ -19714,8 +19732,8 @@ packages: - supports-color dev: true - /metro-transform-worker@0.76.7: - resolution: {integrity: sha512-cGvELqFMVk9XTC15CMVzrCzcO6sO1lURfcbgjuuPdzaWuD11eEyocvkTX0DPiRjsvgAmicz4XYxVzgYl3MykDw==} + /metro-transform-worker@0.76.8: + resolution: {integrity: sha512-mE1fxVAnJKmwwJyDtThildxxos9+DGs9+vTrx2ktSFMEVTtXS/bIv2W6hux1pqivqAfyJpTeACXHk5u2DgGvIQ==} engines: {node: '>=16'} dependencies: '@babel/core': 7.22.9 @@ -19723,12 +19741,12 @@ packages: '@babel/parser': 7.22.7 '@babel/types': 7.22.5 babel-preset-fbjs: 3.4.0(@babel/core@7.22.9) - metro: 0.76.7 - metro-babel-transformer: 0.76.7 - metro-cache: 0.76.7 - metro-cache-key: 0.76.7 - metro-source-map: 0.76.7 - metro-transform-plugins: 0.76.7 + metro: 0.76.8 + metro-babel-transformer: 0.76.8 + metro-cache: 0.76.8 + metro-cache-key: 0.76.8 + metro-source-map: 0.76.8 + metro-transform-plugins: 0.76.8 nullthrows: 1.1.1 transitivePeerDependencies: - bufferutil @@ -19737,15 +19755,15 @@ packages: - utf-8-validate dev: true - /metro@0.76.7: - resolution: {integrity: sha512-67ZGwDeumEPnrHI+pEDSKH2cx+C81Gx8Mn5qOtmGUPm/Up9Y4I1H2dJZ5n17MWzejNo0XAvPh0QL0CrlJEODVQ==} + /metro@0.76.8: + resolution: {integrity: sha512-oQA3gLzrrYv3qKtuWArMgHPbHu8odZOD9AoavrqSFllkPgOtmkBvNNDLCELqv5SjBfqjISNffypg+5UGG3y0pg==} engines: {node: '>=16'} hasBin: true dependencies: '@babel/code-frame': 7.22.5 '@babel/core': 7.22.9 - '@babel/generator': 7.22.5 - '@babel/parser': 7.22.5 + '@babel/generator': 7.22.9 + '@babel/parser': 7.22.7 '@babel/template': 7.22.5 '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 @@ -19764,24 +19782,24 @@ packages: jest-worker: 27.5.1 jsc-safe-url: 0.2.4 lodash.throttle: 4.1.1 - metro-babel-transformer: 0.76.7 - metro-cache: 0.76.7 - metro-cache-key: 0.76.7 - metro-config: 0.76.7 - metro-core: 0.76.7 - metro-file-map: 0.76.7 - metro-inspector-proxy: 0.76.7 - metro-minify-terser: 0.76.7 - metro-minify-uglify: 0.76.7 - metro-react-native-babel-preset: 0.76.7(@babel/core@7.22.9) - metro-resolver: 0.76.7 - metro-runtime: 0.76.7 - metro-source-map: 0.76.7 - metro-symbolicate: 0.76.7 - metro-transform-plugins: 0.76.7 - metro-transform-worker: 0.76.7 + metro-babel-transformer: 0.76.8 + metro-cache: 0.76.8 + metro-cache-key: 0.76.8 + metro-config: 0.76.8 + metro-core: 0.76.8 + metro-file-map: 0.76.8 + metro-inspector-proxy: 0.76.8 + metro-minify-terser: 0.76.8 + metro-minify-uglify: 0.76.8 + metro-react-native-babel-preset: 0.76.8(@babel/core@7.22.9) + metro-resolver: 0.76.8 + metro-runtime: 0.76.8 + metro-source-map: 0.76.8 + metro-symbolicate: 0.76.8 + metro-transform-plugins: 0.76.8 + metro-transform-worker: 0.76.8 mime-types: 2.1.35 - node-fetch: 2.6.7 + node-fetch: 2.6.12 nullthrows: 1.1.1 rimraf: 3.0.2 serialize-error: 2.1.0 @@ -20320,10 +20338,6 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -20900,8 +20914,8 @@ packages: resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} dev: true - /ob1@0.76.7: - resolution: {integrity: sha512-BQdRtxxoUNfSoZxqeBGOyuT9nEYSn18xZHwGMb0mMVpn2NBcYbnyKY4BK2LIHRgw33CBGlUmE+KMaNvyTpLLtQ==} + /ob1@0.76.8: + resolution: {integrity: sha512-dlBkJJV5M/msj9KYA9upc+nUWVwuOFFTbu28X6kZeGwcuW+JxaHSBZ70SYQnk5M+j5JbNLR6yKHmgW4M5E7X5g==} engines: {node: '>=16'} dev: true @@ -25894,6 +25908,15 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true + /ts-api-utils@1.0.3(typescript@5.1.3): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.1.3 + dev: true + /ts-dedent@2.2.0: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} diff --git a/scripts/commitizen.js b/scripts/commitizen.js index 20e89b6fe1360..9731498f0776f 100644 --- a/scripts/commitizen.js +++ b/scripts/commitizen.js @@ -27,6 +27,7 @@ const scopes = [ { value: 'vue', name: 'vue: anything Vue specific' }, { value: 'web', name: 'web: anything Web specific' }, { value: 'webpack', name: 'webpack: anything Webpack specific' }, + {value: 'module-federation', name: 'module-federation: anything Module Federation specific'}, ]; // precomputed scope diff --git a/tools/eslint-rules/jest.config.ts b/tools/eslint-rules/jest.config.ts index d98d764a4b97a..a99e5a1c6e393 100644 --- a/tools/eslint-rules/jest.config.ts +++ b/tools/eslint-rules/jest.config.ts @@ -12,9 +12,6 @@ export default { ], }, moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/tools/eslint-rules', - moduleNameMapper: { - '@eslint/eslintrc': '@eslint/eslintrc/dist/eslintrc-universal.cjs', - }, + testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/tools/eslint-rules/rules/valid-schema-description.ts b/tools/eslint-rules/rules/valid-schema-description.ts index ea02827577e48..74de032e787c8 100644 --- a/tools/eslint-rules/rules/valid-schema-description.ts +++ b/tools/eslint-rules/rules/valid-schema-description.ts @@ -10,7 +10,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: `Ensures that nx schemas contain valid descriptions in order to provide consistent --help output for commands`, - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [], diff --git a/tools/eslint-rules/tsconfig.json b/tools/eslint-rules/tsconfig.json index 51165861a766d..ca63ae2215e69 100644 --- a/tools/eslint-rules/tsconfig.json +++ b/tools/eslint-rules/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "module": "commonjs" + "moduleResolution": "node16", + "module": "node16" }, "files": [], "include": [], diff --git a/tools/eslint-rules/tsconfig.spec.json b/tools/eslint-rules/tsconfig.spec.json index f95b08f8f79e5..960d8000ceba8 100644 --- a/tools/eslint-rules/tsconfig.spec.json +++ b/tools/eslint-rules/tsconfig.spec.json @@ -2,7 +2,6 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "module": "commonjs", "types": ["jest", "node"] }, "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts", "jest.config.ts"] diff --git a/tools/workspace-plugin/src/generators/create-nodes-plugin/__snapshots__/generator.spec.ts.snap b/tools/workspace-plugin/src/generators/create-nodes-plugin/__snapshots__/generator.spec.ts.snap index e443843218d92..214e2bb562221 100644 --- a/tools/workspace-plugin/src/generators/create-nodes-plugin/__snapshots__/generator.spec.ts.snap +++ b/tools/workspace-plugin/src/generators/create-nodes-plugin/__snapshots__/generator.spec.ts.snap @@ -6,7 +6,7 @@ exports[`create-nodes-plugin/generator generator should run successfully 1`] = ` CreateNodesContext, TargetConfiguration, } from '@nx/devkit'; -import { basename, dirname, extname, join, resolve } from "path"; +import { basename, dirname, extname, join, resolve } from 'path'; import { registerTsProject } from '@nx/js/src/internal'; import { getRootTsConfigPath } from '@nx/js'; @@ -45,7 +45,7 @@ export const createNodes: CreateNodes = [ configFilePath, projectRoot, options, - context, + context ), }, }, @@ -57,12 +57,9 @@ function buildEslintTargets( configFilePath: string, projectRoot: string, options: EslintPluginOptions, - context: CreateNodesContext, + context: CreateNodesContext ) { - const eslintConfig = getEslintConfig( - configFilePath, - context - ); + const eslintConfig = getEslintConfig(configFilePath, context); const targetDefaults = readTargetDefaultsForTarget( options.targetName, @@ -72,10 +69,7 @@ function buildEslintTargets( const namedInputs = getNamedInputs(projectRoot, context); - const targets: Record< - string, - TargetConfiguration - > = {}; + const targets: Record> = {}; const baseTargetConfig: TargetConfiguration = { executor: 'executorName', @@ -92,9 +86,7 @@ function buildEslintTargets( targetDefaults?.inputs ?? 'production' in namedInputs ? ['default', '^production'] : ['default', '^default'], - outputs: - targetDefaults?.outputs ?? - getOutputs(projectRoot), + outputs: targetDefaults?.outputs ?? getOutputs(projectRoot), options: { ...baseTargetConfig.options, }, @@ -129,9 +121,7 @@ function getEslintConfig( return module.default ?? module; } -function getOutputs( - projectRoot: string, -): string[] { +function getOutputs(projectRoot: string): string[] { function getOutput(path: string): string { if (path.startsWith('..')) { return join('{workspaceRoot}', join(projectRoot, path)); @@ -179,7 +169,7 @@ describe('@nx/eslint/plugin', () => { }); it('should create nodes', () => { - mockEslintConfig({}) + mockEslintConfig({}); const nodes = createNodesFunction( 'TODO', { @@ -192,10 +182,7 @@ describe('@nx/eslint/plugin', () => { }); }); - -function mockEslintConfig( - config: any -) { +function mockEslintConfig(config: any) { jest.mock( 'TODO', () => ({ @@ -208,3 +195,30 @@ function mockEslintConfig( } " `; + +exports[`create-nodes-plugin/generator generator should run successfully 3`] = ` +"import { formatFiles, getProjects, Tree } from '@nx/devkit'; +import { createNodes } from '../../plugins/plugin'; + +import { createProjectRootMappingsFromProjectConfigurations } from 'nx/src/project-graph/utils/find-project-for-path'; +import { replaceProjectConfigurationsWithPlugin } from '@nx/devkit/src/utils/replace-project-configuration-with-plugin'; + +export default async function update(tree: Tree) { + const proj = Object.fromEntries(getProjects(tree).entries()); + + const rootMappings = createProjectRootMappingsFromProjectConfigurations(proj); + + replaceProjectConfigurationsWithPlugin( + tree, + rootMappings, + '@nx/eslint/plugin', + createNodes, + { + targetName: 'TODO', + } + ); + + await formatFiles(tree); +} +" +`; diff --git a/tools/workspace-plugin/src/generators/create-nodes-plugin/files/src/migrations/update-17-2-0/add-__dirName__-plugin.ts b/tools/workspace-plugin/src/generators/create-nodes-plugin/files/src/migrations/update-17-2-0/add-__dirName__-plugin.ts new file mode 100644 index 0000000000000..4d7ad936ef845 --- /dev/null +++ b/tools/workspace-plugin/src/generators/create-nodes-plugin/files/src/migrations/update-17-2-0/add-__dirName__-plugin.ts @@ -0,0 +1,23 @@ +import { formatFiles, getProjects, Tree } from '@nx/devkit'; +import { createNodes } from '../../plugins/plugin'; + +import { createProjectRootMappingsFromProjectConfigurations } from 'nx/src/project-graph/utils/find-project-for-path'; +import { replaceProjectConfigurationsWithPlugin } from '@nx/devkit/src/utils/replace-project-configuration-with-plugin'; + +export default async function update(tree: Tree) { + const proj = Object.fromEntries(getProjects(tree).entries()); + + const rootMappings = createProjectRootMappingsFromProjectConfigurations(proj); + + replaceProjectConfigurationsWithPlugin( + tree, + rootMappings, + '@nx/<%= dirName %>/plugin', + createNodes, + { + targetName: 'TODO', + } + ); + + await formatFiles(tree); +} diff --git a/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.spec.ts b/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.spec.ts index b0d375c463a12..19ac42bcb2dd8 100644 --- a/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.spec.ts +++ b/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.spec.ts @@ -1,25 +1,43 @@ import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { Tree } from '@nx/devkit'; +import { addProjectConfiguration, Tree, writeJson } from '@nx/devkit'; -import { generatorGenerator, GeneratorGeneratorSchema } from './generator'; +import { generatorGenerator } from './generator'; +import { setCwd } from '@nx/devkit/internal-testing-utils'; describe('create-nodes-plugin/generator generator', () => { let tree: Tree; - const options: GeneratorGeneratorSchema = {}; beforeEach(() => { tree = createTreeWithEmptyWorkspace(); + addProjectConfiguration(tree, 'eslint', { + root: 'packages/eslint', + targets: { + build: {}, + }, + }); + + writeJson(tree, 'packages/eslint/package.json', {}); + jest.spyOn(process, 'cwd').mockReturnValue('/virtual/packages/eslint'); + + setCwd('packages/eslint'); }); it('should run successfully', async () => { - await generatorGenerator(tree, options); + await generatorGenerator(tree); expect( tree.read('packages/eslint/src/plugins/plugin.ts').toString() ).toMatchSnapshot(); expect( tree.read('packages/eslint/src/plugins/plugin.spec.ts').toString() ).toMatchSnapshot(); + expect( + tree + .read( + 'packages/eslint/src/migrations/update-17-2-0/add-eslint-plugin.ts' + ) + .toString() + ).toMatchSnapshot(); }); }); diff --git a/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.ts b/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.ts index f4c45045738af..5bee926ea16ec 100644 --- a/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.ts +++ b/tools/workspace-plugin/src/generators/create-nodes-plugin/generator.ts @@ -1,20 +1,27 @@ -import { generateFiles, names, Tree } from '@nx/devkit'; +import { formatFiles, generateFiles, names, Tree } from '@nx/devkit'; import { basename, join, relative } from 'path'; +import migrationGenerator from '@nx/plugin/src/generators/migration/migration'; -export interface GeneratorGeneratorSchema {} - -export async function generatorGenerator( - tree: Tree, - options: GeneratorGeneratorSchema -) { +export async function generatorGenerator(tree: Tree) { const cwd = process.cwd(); const { className, propertyName } = names(basename(cwd)); + await migrationGenerator(tree, { + name: `add-${basename(cwd)}-plugin`, + packageVersion: '17.2.0-beta.0', + description: `Add @nx/${basename(cwd)}/plugin`, + nameAndDirectoryFormat: 'as-provided', + directory: `src/migrations/update-17-2-0`, + skipFormat: true, + }); + generateFiles(tree, join(__dirname, 'files'), relative(tree.root, cwd), { dirName: basename(cwd), className, propertyName, }); + + await formatFiles(tree); } export default generatorGenerator;