feat(nuxt): nuxt executors, generators, docs (#19855)

This commit is contained in:
Katerina Skroumpelou 2023-11-07 17:15:32 +02:00 committed by GitHub
parent 8730395082
commit b3423679c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 1622 additions and 1078 deletions

View File

@ -2601,7 +2601,7 @@
"githubRoot": "https://github.com/nrwl/nx/blob/master",
"name": "vue",
"packageName": "@nx/vue",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Vitest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"documents": {
"/nx-api/vue/documents/overview": {
"id": "overview",

View File

@ -2573,7 +2573,7 @@
"source": "/packages/vite/src"
},
{
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Vitest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"documents": [
{
"id": "overview",

View File

@ -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 [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",
"examplesFile": "---\ntitle: Vue application generator examples\ndescription: This page contains examples for the @nx/vue:app generator.\n---\n\n## 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"],

View File

@ -10,12 +10,8 @@
"type": "object",
"examples": [
{
"command": "nx g component my-component --project=mylib",
"description": "Generate a component in the `mylib` library"
},
{
"command": "nx g component my-component --project=mylib --classComponent",
"description": "Generate a class component in the `mylib` library"
"command": "nx g @nx/vue:component --directory=my-app/src/app/one --name=one --nameAndDirectoryFormat=as-provided --unitTestRunner=vitest",
"description": "Generate a component in the `my-app` application"
}
],
"properties": {

View File

@ -60,7 +60,7 @@
}
},
"required": ["project"],
"examplesFile": "This generator will generate stories for all your components in your project. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).\n\n```bash\nnx g @nx/vue:stories project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#auto-generate-stories).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..\n\nYou must provide a `name` for the generator to work.\n\nBy default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nx/vue:stories --name=ui --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*\n```\n\nThis will generate stories for all the components in the `ui` project, except for the ones in the `libs/ui/src/not-stories` directory, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\nBy default, Nx will ignore the following paths:\n\n```text\n*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx\n```\n\nbut you can change this behaviour easily, as explained above.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nx/vue:stories --name=ui --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n",
"examplesFile": "---\ntitle: Stories generator examples\ndescription: This page contains examples for the @nx/vue:stories generator.\n---\n\nThis generator will generate stories for all your components in your project. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).\n\nYou can also use this generator to generate stories for your **Nuxt** project:\n\n```bash\nnx g @nx/vue:stories project-name\n```\n\nor\n\n```bash\nnx g @nx/nuxt:stories project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#auto-generate-stories).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..\n\nYou must provide a `name` for the generator to work.\n\nBy default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nx/vue:stories --name=ui --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*\n```\n\nThis will generate stories for all the components in the `ui` project, except for the ones in the `libs/ui/src/not-stories` directory, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\nBy default, Nx will ignore the following paths:\n\n```text\n*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx\n```\n\nbut you can change this behaviour easily, as explained above.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nx/vue:stories --name=ui --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n",
"presets": []
},
"description": "Create stories for all components declared in an app or library.",

View File

@ -73,7 +73,7 @@
}
},
"required": ["name"],
"examplesFile": "This generator will set up Storybook for your **Vue** project. You can also use this generator to generate Storybook configuration for your **Next.js** project. By default, starting Nx 16, Storybook v7 is used.\n\n```bash\nnx g @nx/vue:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#generate-storybook-configuration-for-a-vue-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. Also, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/vue/writing-tests/test-runner). You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n\nYou must provide a `name` for the generator to work.\n\nBy default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration\n\n```bash\nnx g @nx/vue:storybook-configuration ui\n```\n\nThis will generate Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory, eg. `.storybook/main.ts`).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nx/vue:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\nBy default, Nx will ignore the following paths:\n\n```text\n*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx\n```\n\nbut you can change this behaviour easily, as explained above.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nx/vue:storybook-configuration ui --generateStories=true --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n\n### Generate Storybook configuration using JavaScript\n\n```bash\nnx g @nx/vue:storybook-configuration ui --tsConfiguration=false\n```\n\nBy default, our generator generates TypeScript Storybook configuration files. You can choose to use JavaScript for the Storybook configuration files of your project (the files inside the `.storybook` directory, eg. `.storybook/main.js`).\n",
"examplesFile": "---\ntitle: Storybook configuration generator examples\ndescription: This page contains examples for the @nx/vue:storybook-configuration generator.\n---\n\nThis generator will set up Storybook for your **Vue** project. You can also use this generator to generate Storybook configuration for your **Nuxt** project.\n\n```bash\nnx g @nx/vue:storybook-configuration project-name\n```\n\nor\n\n```bash\nnx g @nx/nuxt:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#generate-storybook-configuration-for-a-vue-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. Also, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/vue/writing-tests/test-runner). You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n\nYou must provide a `name` for the generator to work.\n\nBy default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration\n\n```bash\nnx g @nx/vue:storybook-configuration ui\n```\n\nThis will generate Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory, eg. `.storybook/main.ts`).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nx/vue:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\nBy default, Nx will ignore the following paths:\n\n```text\n*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx\n```\n\nbut you can change this behaviour easily, as explained above.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nx/vue:storybook-configuration ui --generateStories=true --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n\n### Generate Storybook configuration using JavaScript\n\n```bash\nnx g @nx/vue:storybook-configuration ui --tsConfiguration=false\n```\n\nBy default, our generator generates TypeScript Storybook configuration files. You can choose to use JavaScript for the Storybook configuration files of your project (the files inside the `.storybook` directory, eg. `.storybook/main.js`).\n",
"presets": []
},
"description": "Set up storybook for a Vue app or library.",

View File

@ -2148,6 +2148,20 @@
}
]
},
{
"name": "nuxt",
"id": "nuxt",
"description": "Nuxt package.",
"itemList": [
{
"id": "overview",
"path": "/nx-api/nuxt",
"name": "Overview of the Nx Nuxt Plugin",
"description": "The Nx Plugin for Nuxt contains generators for managing Nuxt applications within a Nx workspace. This page also explains how to configure Nuxt on your Nx workspace.",
"file": "shared/packages/nuxt/nuxt-plugin"
}
]
},
{
"name": "webpack",
"id": "webpack",

View File

@ -362,7 +362,7 @@
{
"name": "vue",
"packageName": "vue",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Vitest, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"path": "generated/packages/vite.json",
"schemas": {
"executors": [],

View File

@ -0,0 +1,52 @@
---
title: Overview of the Nx Nuxt Plugin
description: The Nx Plugin for Nuxt contains generators for managing Nuxt applications within a Nx workspace. This page also explains how to configure Nuxt on your Nx workspace.
---
The Nx plugin for [Nuxt](https://nuxt.com/).
## Setting up a new Nx workspace with Nuxt
You can create a new workspace that uses Nuxt with one of the following commands:
- Generate a new monorepo with a Nuxt app
```shell
npx create-nx-workspace@latest --preset=nuxt
```
## Add Nuxt to an existing workspace
There are a number of ways to use Nuxt in your existing workspace.
### Install the `@nx/nuxt` plugin
{% tabs %}
{% tab label="npm" %}
```shell
npm install -D @nx/nuxt
```
{% /tab %}
{% tab label="yarn" %}
```shell
yarn add -D @nx/nuxt
```
{% /tab %}
{% tab label="pnpm" %}
```shell
pnpm install -D @nx/nuxt
```
{% /tab %}
{% /tabs %}
### Generate a new Nuxt app
```shell
nx g @nx/nuxt:app my-app
```

View File

@ -1,27 +1,41 @@
---
title: Set up Storybook for Vue Projects
description: This guide explains how to set up Storybook for Vue projects in your Nx workspace.
title: Set up Storybook for Vue and Nuxt Projects
description: This guide explains how to set up Storybook for Vue and Nuxt projects in your Nx workspace.
---
# Set up Storybook for Vue Projects
# Set up Storybook for Vue and Nuxt Projects
This guide will walk you through setting up [Storybook](https://storybook.js.org) for Vue projects in your Nx workspace.
This guide will walk you through setting up [Storybook](https://storybook.js.org) for Vue and Nuxt projects in your Nx workspace.
{% callout type="warning" title="Set up Storybook in your workspace" %}
You first need to set up Storybook for your Nx workspace, if you haven't already. You can read the [Storybook plugin overview guide](/nx-api/storybook) to get started.
{% /callout %}
## Generate Storybook Configuration for a Vue project
## Generate Storybook Configuration for a Vue or Nuxt project
You can generate Storybook configuration for an individual Vue project by using the [`@nx/vue:storybook-configuration` generator](/nx-api/vue/generators/storybook-configuration), like this:
You can generate Storybook configuration for an individual Vue or Nuxt project by using the [`@nx/vue:storybook-configuration` generator](/nx-api/vue/generators/storybook-configuration), like this:
{% tabs %}
{% tab label="Vue" %}
```shell
nx g @nx/vue:storybook-configuration project-name
```
{% /tab %}
{% tab label="Nuxt" %}
```shell
nx g @nx/nuxt:storybook-configuration my-nuxt-app
```
{% /tab %}
{% /tabs %}
## Auto-generate Stories
The [`@nx/vue:storybook-configuration` generator](/nx-api/vue/generators/storybook-configuration) has the option to automatically generate `*.stories.ts` files for each component declared in the library. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).
The [`@nx/vue:storybook-configuration` generator](/nx-api/vue/generators/storybook-configuration) has the option to automatically generate `*.stories.ts` files for each component declared in the library.
```text
<some-folder>/
@ -31,10 +45,24 @@ The [`@nx/vue:storybook-configuration` generator](/nx-api/vue/generators/storybo
If you add more components to your project, and want to generate stories for all your (new) components at any point, you can use the [`@nx/vue:stories` generator](/nx-api/vue/generators/stories):
{% tabs %}
{% tab label="Vue" %}
```shell
nx g @nx/vue:stories --project=<project-name>
```
{% /tab %}
{% tab label="Nuxt" %}
```shell
nx g @nx/nuxt:stories --project=<project-name>
```
{% /tab %}
{% /tabs %}
{% callout type="note" title="Example" %}
Let's take for a example a library in your workspace, under `libs/feature/ui`, called `feature-ui`. This library contains a component, called `my-button`.

View File

@ -15,7 +15,10 @@ describe('Nuxt Plugin', () => {
proj = newProject({
unsetProjectNameAndRootFormat: false,
});
runCLI(`generate @nx/nuxt:app ${app} --unitTestRunner=none`);
runCLI(`generate @nx/nuxt:app ${app} --unitTestRunner=vitest`);
runCLI(
`generate @nx/nuxt:component --directory=${app}/src/components/one --name=one --nameAndDirectoryFormat=as-provided --unitTestRunner=vitest`
);
});
afterAll(() => {
@ -30,9 +33,20 @@ describe('Nuxt Plugin', () => {
);
});
it('should test application', async () => {
const result = runCLI(`test ${app}`);
expect(result).toContain(`Successfully ran target test for project ${app}`);
});
// TODO(katerina): Enable when TypeScript version is 5.2.2 - when Angular 17 PR is merged
xit('should lint application', async () => {
const result = runCLI(`lint ${app}`);
expect(result).toContain(`Successfully ran target lint for project ${app}`);
});
it('should build storybook for app', () => {
runCLI(
`generate @nx/vue:storybook-configuration ${app} --generateStories --no-interactive`
`generate @nx/nuxt:storybook-configuration ${app} --generateStories --no-interactive`
);
runCLI(`run ${app}:build-storybook --verbose`);
checkFilesExist(`dist/storybook/${app}/index.html`);

View File

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Nuxt.js</title><path d="M13.4642 19.8295h8.9218c.2834 0 .5618-.0723.8072-.2098a1.5899 1.5899 0 0 0 .5908-.5732 1.5293 1.5293 0 0 0 .216-.783 1.529 1.529 0 0 0-.2167-.7828L17.7916 7.4142a1.5904 1.5904 0 0 0-.5907-.573 1.6524 1.6524 0 0 0-.807-.2099c-.2833 0-.5616.0724-.807.2098a1.5904 1.5904 0 0 0-.5907.5731L13.4642 9.99l-2.9954-5.0366a1.5913 1.5913 0 0 0-.591-.573 1.6533 1.6533 0 0 0-.8071-.2098c-.2834 0-.5617.0723-.8072.2097a1.5913 1.5913 0 0 0-.591.573L.2168 17.4808A1.5292 1.5292 0 0 0 0 18.2635c-.0001.2749.0744.545.216.783a1.59 1.59 0 0 0 .5908.5732c.2454.1375.5238.2098.8072.2098h5.6003c2.219 0 3.8554-.9454 4.9813-2.7899l2.7337-4.5922L16.3935 9.99l4.3944 7.382h-5.8586ZM7.123 17.3694l-3.9083-.0009 5.8586-9.8421 2.9232 4.921-1.9572 3.2892c-.7478 1.1967-1.5972 1.6328-2.9163 1.6328z"/></svg>

After

Width:  |  Height:  |  Size: 879 B

View File

@ -16,6 +16,7 @@ export const iconsMap: Record<string, string> = {
nest: '/images/icons/nestjs.svg',
next: '/images/icons/nextdotjs.svg',
node: '/images/icons/nodedotjs.svg',
nuxt: '/images/icons/nuxtdotjs.svg',
nx: '/images/icons/nx.svg',
playwright: '/images/icons/playwright.svg',
plugin: '/images/icons/nx.svg',

View File

@ -64,8 +64,6 @@
"@ngrx/router-store": "~16.0.0",
"@ngrx/store": "~16.0.0",
"@nguniversal/builders": "~16.2.0",
"@nuxt/kit": "^3.7.4",
"@nuxt/schema": "^3.7.4",
"@nx/angular": "17.0.0-rc.2",
"@nx/cypress": "17.0.0-rc.2",
"@nx/devkit": "17.0.0-rc.2",
@ -158,7 +156,6 @@
"cytoscape-popper": "^2.0.0",
"cz-git": "^1.4.0",
"czg": "^1.4.0",
"defu": "^6.1.2",
"detect-port": "^1.5.1",
"dotenv": "~16.3.1",
"dotenv-expand": "^10.0.0",
@ -230,6 +227,7 @@
"ng-packagr": "~16.2.0",
"node-fetch": "^2.6.7",
"npm-package-arg": "11.0.1",
"nuxi": "npm:nuxi-nightly@3.9.2-1699007958.251cab5",
"nx": "17.0.0-rc.2",
"octokit": "^2.0.14",
"open": "^8.4.0",

View File

@ -66,7 +66,14 @@ interface VueArguments extends BaseArguments {
stack: 'vue';
workspaceType: 'standalone' | 'integrated';
appName: string;
// framework: 'none' | 'nuxt';
style: string;
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}
interface NuxtArguments extends BaseArguments {
stack: 'nuxt';
workspaceType: 'standalone' | 'integrated';
appName: string;
style: string;
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}
@ -88,6 +95,7 @@ type Arguments =
| ReactArguments
| AngularArguments
| VueArguments
| NuxtArguments
| NodeArguments
| UnknownStackArguments;
@ -112,6 +120,8 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
describe: chalk.dim`Customizes the initial content of your workspace. Default presets include: [${Object.values(
Preset
)
// TODO(katerina): Remove this option when @nx/nuxt is released.
.filter((p) => p !== Preset.NuxtStandalone && p !== Preset.Nuxt)
.map((p) => `"${p}"`)
.join(
', '
@ -357,7 +367,7 @@ async function determineFolder(
async function determineStack(
parsedArgs: yargs.Arguments<Arguments>
): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'unknown'> {
): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'nuxt' | 'unknown'> {
if (parsedArgs.preset) {
switch (parsedArgs.preset) {
case Preset.Angular:
@ -373,6 +383,9 @@ async function determineStack(
case Preset.VueStandalone:
case Preset.VueMonorepo:
return 'vue';
case Preset.NuxtStandalone:
case Preset.Nuxt:
return 'nuxt';
case Preset.Nest:
case Preset.NodeStandalone:
case Preset.Express:
@ -437,6 +450,8 @@ async function determinePresetOptions(
return determineAngularOptions(parsedArgs);
case 'vue':
return determineVueOptions(parsedArgs);
case 'nuxt':
return determineNuxtOptions(parsedArgs);
case 'node':
return determineNodeOptions(parsedArgs);
default:
@ -670,6 +685,69 @@ async function determineVueOptions(
return { preset, style, appName, e2eTestRunner };
}
async function determineNuxtOptions(
parsedArgs: yargs.Arguments<NuxtArguments>
): Promise<Partial<Arguments>> {
let preset: Preset;
let style: undefined | string = undefined;
let appName: string;
let e2eTestRunner: undefined | 'none' | 'cypress' | 'playwright' = undefined;
if (parsedArgs.preset) {
preset = parsedArgs.preset;
} else {
const workspaceType = await determineStandaloneOrMonorepo();
if (workspaceType === 'standalone') {
preset = Preset.NuxtStandalone;
} else {
preset = Preset.Nuxt;
}
}
if (preset === Preset.NuxtStandalone) {
appName = parsedArgs.appName ?? parsedArgs.name;
} else {
appName = await determineAppName(parsedArgs);
}
e2eTestRunner = await determineE2eTestRunner(parsedArgs);
if (parsedArgs.style) {
style = parsedArgs.style;
} else {
const reply = await enquirer.prompt<{ style: string }>([
{
name: 'style',
message: `Default stylesheet format`,
initial: 'css' as any,
type: 'autocomplete',
choices: [
{
name: 'css',
message: 'CSS',
},
{
name: 'scss',
message: 'SASS(.scss) [ http://sass-lang.com ]',
},
{
name: 'less',
message: 'LESS [ http://lesscss.org ]',
},
{
name: 'none',
message: 'None',
},
],
},
]);
style = reply.style;
}
return { preset, style, appName, e2eTestRunner };
}
async function determineAngularOptions(
parsedArgs: yargs.Arguments<AngularArguments>
): Promise<Partial<Arguments>> {
@ -929,7 +1007,11 @@ async function determineStandaloneOrMonorepo(): Promise<
async function determineAppName(
parsedArgs: yargs.Arguments<
ReactArguments | AngularArguments | NodeArguments | VueArguments
| ReactArguments
| AngularArguments
| NodeArguments
| VueArguments
| NuxtArguments
>
): Promise<string> {
if (parsedArgs.appName) return parsedArgs.appName;

View File

@ -23,6 +23,10 @@ export const presetOptions: { name: Preset; message: string }[] = [
name: Preset.VueMonorepo,
message: 'vue [a monorepo with a single Vue application]',
},
{
name: Preset.Nuxt,
message: 'nuxt [a monorepo with a single Nuxt application]',
},
{
name: Preset.NextJs,
message: 'next.js [a monorepo with a single Next.js application]',

View File

@ -11,6 +11,8 @@ export enum Preset {
ReactStandalone = 'react-standalone',
VueMonorepo = 'vue-monorepo',
VueStandalone = 'vue-standalone',
Nuxt = 'nuxt',
NuxtStandalone = 'nuxt-standalone',
NextJs = 'next',
NextJsStandalone = 'nextjs-standalone',
ReactNative = 'react-native',

View File

@ -29,7 +29,13 @@
"error",
{
"buildTargets": ["build-base"],
"ignoredDependencies": ["nx", "typescript"]
"ignoredDependencies": [
"nx",
"typescript",
"@nx/cypress",
"@nx/playwright",
"nuxi"
]
}
]
}

View File

@ -3,6 +3,42 @@ title: Nuxt application generator examples
description: This page contains examples for the @nx/nuxt:app generator.
---
Your new Nuxt application will be generated with the following directory structure, following the suggested [directory structure](https://nuxt.com/docs/guide/directory-structure) for Nuxt applications:
```text
my-nuxt-app
├── nuxt.config.ts
├── project.json
├── src
│   ├── app.vue
│   ├── assets
│   │   └── css
│   │   └── styles.css
│   ├── components
│   │   └── NxWelcome.vue
│   ├── pages
│   │   ├── about.vue
│   │   └── index.vue
│   ├── public
│   │   └── favicon.ico
│   └── server
│   ├── api
│   │   └── greet.ts
│   └── tsconfig.json
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
└── vitest.config.ts
```
Your new app will contain the following:
- Two pages (home and about) under `pages`
- A component (`NxWelcome`) under `components`
- A `greet` API endpoint that returns a JSON response under `/api/greet`
- Configuration for `vitest`
- Your app's entrypoint (`app.vue`) will contain the navigation links to the home and about pages, and the `nuxt-page` component to display the contents of your pages.
## Examples
{% tabs %}
@ -13,21 +49,45 @@ The command below uses the `as-provided` directory flag behavior, which is the d
{% /callout %}
```shell
nx g app myapp --directory=apps/nested/myapp
nx g @nx/nuxt:app myapp --directory=apps/nested/myapp
```
{% /tab %}
{% tab label="Use a custom Express server" %}
{% tab label="Create app with vitest configured" %}
```shell
nx g app myapp --custom-server
nx g @nx/nuxt:app myapp --directory=apps/nested/myapp --unitTestRunner=vitest
```
{% /tab %}
{% tab label="Use plain JavaScript (not TypeScript)" %}
```shell
nx g app myapp --js
nx g @nx/nuxt:app myapp --js
```
{% /tab %}
{% /tabs %}
## Generate pages and components
You can use the the [`@nx/vue:component` generator](/nx-api/vue/generators/component) to generate new pages and components for your application. You can read more on the [`@nx/vue:component` generator documentation page](/nx-api/vue/generators/component), but here are some examples:
{% tabs %}
{% tab label="New page" %}
```shell
nx g @nx/nuxt:component --directory=my-app/src/pages --name=my-page
```
{% /tab %}
{% tab label="New component" %}
```shell
nx g @nx/nuxt:component --directory=my-app/src/components/my-cmp --name=my-cmp
```
{% /tab %}

View File

@ -1,46 +0,0 @@
This generator will generate stories for all your components in your project. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).
```bash
nx g @nx/nuxt:stories project-name
```
You can read more about how this generator works, in the [Storybook for Nuxt overview page](/recipes/storybook/overview-nuxt#auto-generate-stories).
When running this generator, you will be prompted to provide the following:
- The `name` of the project you want to generate the configuration for.
- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..
You must provide a `name` for the generator to work.
By default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.
There are a number of other options available. Let's take a look at some examples.
## Examples
### Ignore certain paths when generating stories
```bash
nx g @nx/nuxt:stories --name=ui --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*
```
This will generate stories for all the components in the `ui` project, except for the ones in the `libs/ui/src/not-stories` directory, and also for components that their file name is of the pattern `*.other.*`.
This is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.
By default, Nx will ignore the following paths:
```text
*.stories.ts, *.stories.tsx, *.stories.js, *.stories.jsx, *.stories.mdx
```
but you can change this behaviour easily, as explained above.
### Generate stories using JavaScript instead of TypeScript
```bash
nx g @nx/nuxt:stories --name=ui --js=true
```
This will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.

View File

@ -1,20 +1,25 @@
This generator will set up Storybook for your **Nuxt** project. You can also use this generator to generate Storybook configuration for your **Next.js** project. By default, starting Nx 16, Storybook v7 is used.
---
title: Storybook configuration generator examples
description: This page contains examples for the @nx/nuxt:storybook-configuration generator.
---
This generator calls the `@nx/vue:storybook-configuration` generator under the hood. It will set up Storybook for your **Nuxt** project.
```bash
nx g @nx/nuxt:storybook-configuration project-name
```
You can read more about how this generator works, in the [Storybook for Nuxt overview page](/recipes/storybook/overview-nuxt#generate-storybook-configuration-for-a-nuxt-project).
You can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#generate-storybook-configuration-for-a-vue-project).
When running this generator, you will be prompted to provide the following:
- The `name` of the project you want to generate the configuration for.
- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/nuxt/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. Also, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/nuxt/writing-tests/test-runner). You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..
- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. Also, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/vue/writing-tests/test-runner). You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..
- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.
You must provide a `name` for the generator to work.
By default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/nuxt/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.
By default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/vue/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.
There are a number of other options available. Let's take a look at some examples.

View File

@ -1,3 +1,14 @@
{
"executors": {}
"executors": {
"build": {
"implementation": "./src/executors/build/build.impl",
"schema": "./src/executors/build/schema.json",
"description": "Build with Nuxt."
},
"serve": {
"implementation": "./src/executors/serve/serve.impl",
"schema": "./src/executors/serve/schema.json",
"description": "Serve with Nuxt."
}
}
}

View File

@ -1,6 +1,7 @@
{
"name": "Nx Nuxt",
"version": "0.1",
"extends": ["@nx/vue"],
"generators": {
"init": {
"factory": "./src/generators/init/init",
@ -15,30 +16,11 @@
"aliases": ["app"],
"description": "Create a Nuxt application."
},
"component": {
"factory": "./src/generators/component/component",
"schema": "./src/generators/component/schema.json",
"aliases": ["c"],
"x-type": "component",
"description": "Create a Vue component for your Nuxt application."
},
"page": {
"factory": "./src/generators/page/page",
"schema": "./src/generators/page/schema.json",
"x-type": "page",
"description": "Create a new page for your Nuxt application."
},
"storybook-configuration": {
"factory": "./src/generators/storybook-configuration/configuration",
"schema": "./src/generators/storybook-configuration/schema.json",
"description": "Set up storybook for a Nuxt app.",
"hidden": false
},
"stories": {
"factory": "./src/generators/stories/stories",
"schema": "./src/generators/stories/schema.json",
"description": "Create stories for all components declared in an app or library.",
"hidden": false
}
}
}

View File

@ -2,4 +2,3 @@ export * from './src/utils/versions';
export { applicationGenerator } from './src/generators/application/application';
export { type InitSchema } from './src/generators/init/schema';
export { nuxtInitGenerator } from './src/generators/init/init';
export * from './plugins/with-nuxt';

View File

@ -2,7 +2,7 @@
"name": "@nx/nuxt",
"version": "0.0.1",
"private": true,
"description": "The Nuxt plugin for Nx contains executors and generators for managing Nuxt applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"description": "The Nuxt plugin for Nx contains executors and generators for managing Nuxt applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Vitest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"repository": {
"type": "git",
"url": "https://github.com/nrwl/nx.git",
@ -28,17 +28,12 @@
"migrations": "./migrations.json"
},
"dependencies": {
"defu": "^6.1.2",
"fs-extra": "^11.1.0",
"nuxi": "npm:nuxi-nightly@3.9.2-1699007958.251cab5",
"tslib": "^2.3.0",
"@nx/devkit": "file:../devkit",
"@nx/js": "file:../js",
"@nx/eslint": "file:../eslint",
"@nx/vue": "file:../vue",
"@nx/cypress": "file:../cypress",
"@nx/playwright": "file:../playwright",
"@nuxt/kit": "^3.7.4",
"@nuxt/schema": "^3.7.4"
"@nx/vue": "file:../vue"
},
"publishConfig": {
"access": "public"

View File

@ -1,49 +0,0 @@
import { join, resolve } from 'path';
import { workspaceRoot } from '@nx/devkit';
import { existsSync } from 'fs-extra';
import { defineNuxtModule } from '@nuxt/kit';
import { defu } from 'defu';
import { NuxtModule } from '@nuxt/schema';
export const NxNuxtModule: NuxtModule = defineNuxtModule({
meta: { name: '@nx/nuxt/module', configKey: 'nx' },
setup(_options, nuxt) {
nuxt.options.alias = defu(nuxt.options.alias, nxTsPaths());
},
});
/**
* read the compilerOptions.paths option from a tsconfig and return as aliases for Nuxt
**/
function nxTsPaths() {
const tsConfigPath = getTsConfig(join(workspaceRoot, 'tsconfig.base.json'));
const tsPaths = require(tsConfigPath)?.compilerOptions?.paths as Record<
string,
string[]
>;
const alias: Record<string, string> = {};
if (tsPaths) {
for (const p in tsPaths) {
// '@org/something/*': ['libs/something/src/*'] => '@org/something': '{pathToWorkspaceRoot}/libs/something/src'
alias[p.replace(/\/\*$/, '')] = join(
workspaceRoot,
tsPaths[p][0].replace(/\/\*$/, '')
);
}
}
return alias;
}
function getTsConfig(preferredTsConfigPath: string): string {
return [
resolve(preferredTsConfigPath),
resolve(join(workspaceRoot, 'tsconfig.base.json')),
resolve(join(workspaceRoot, 'tsconfig.json')),
].find((tsPath) => {
if (existsSync(tsPath)) {
return tsPath;
}
});
}

View File

@ -0,0 +1,59 @@
import { ExecutorContext, joinPathFragments } from '@nx/devkit';
import { NuxtBuildExecutorOptions } from './schema';
// Required because nuxi is ESM package.
export function loadNuxiDynamicImport() {
return Function('return import("nuxi")')() as Promise<typeof import('nuxi')>;
}
export async function* nuxtBuildExecutor(
options: NuxtBuildExecutorOptions,
context: ExecutorContext
) {
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
const { runCommand } = await loadNuxiDynamicImport();
try {
await runCommand('build', [projectRoot], {
overrides: {
...options,
workspaceDir: context.root,
buildDir: joinPathFragments(context.root, options.outputPath, '.nuxt'),
typescript: {
typeCheck: true,
tsConfig: {
extends: joinPathFragments(
context.root,
projectRoot,
'tsconfig.app.json'
),
},
},
imports: {
autoImport: false,
},
nitro: {
output: {
dir: joinPathFragments(context.root, options.outputPath, '.output'),
serverDir: joinPathFragments(
context.root,
options.outputPath,
'.output/server'
),
publicDir: joinPathFragments(
context.root,
options.outputPath,
'.output/public'
),
},
},
},
});
return { success: true };
} catch (e) {
console.error(e);
return { success: false, error: e };
}
}
export default nuxtBuildExecutor;

View File

@ -0,0 +1,4 @@
import { convertNxExecutor } from '@nx/devkit';
import nuxtBuildExecutor from './build.impl';
export default convertNxExecutor(nuxtBuildExecutor);

View File

@ -0,0 +1,6 @@
export interface NuxtBuildExecutorOptions {
debug?: boolean;
dev?: boolean;
ssr?: boolean;
outputPath: string;
}

View File

@ -0,0 +1,36 @@
{
"version": 2,
"outputCapture": "direct-nodejs",
"title": "Nuxt Prod Builder",
"cli": "nx",
"description": "Builds a Nuxt application for production.",
"type": "object",
"presets": [
{
"name": "Default minimum setup",
"keys": []
}
],
"properties": {
"debug": {
"type": "boolean",
"description": "Set to true to enable debug mode."
},
"dev": {
"type": "boolean",
"description": "Whether Nuxt is running in development mode."
},
"ssr": {
"type": "boolean",
"description": "Whether to enable rendering of HTML - either dynamically (in server mode) or at generate time. If set to false generated pages will have no content."
},
"outputPath": {
"type": "string",
"description": "The output path of the generated files.",
"x-completion-type": "directory",
"x-priority": "important"
}
},
"definitions": {},
"required": []
}

View File

@ -0,0 +1,4 @@
import { convertNxExecutor } from '@nx/devkit';
import nuxtServeExecutor from './serve.impl';
export default convertNxExecutor(nuxtServeExecutor);

View File

@ -0,0 +1,8 @@
export interface NuxtServeExecutorOptions {
debug?: boolean;
dev?: boolean;
ssr?: boolean;
port?: number;
host?: string;
https?: boolean | Json;
}

View File

@ -0,0 +1,50 @@
{
"version": 2,
"outputCapture": "direct-nodejs",
"title": "Nuxt Server",
"cli": "nx",
"description": "Serves a Nuxt application for development.",
"type": "object",
"presets": [
{
"name": "Default minimum setup",
"keys": []
}
],
"properties": {
"debug": {
"type": "boolean",
"description": "Set to true to enable debug mode."
},
"dev": {
"type": "boolean",
"description": "Whether Nuxt is running in development mode."
},
"ssr": {
"type": "boolean",
"description": "Whether to enable rendering of HTML - either dynamically (in server mode) or at generate time. If set to false generated pages will have no content."
},
"port": {
"type": "number",
"description": "Port to listen on.",
"x-priority": "important"
},
"host": {
"description": "Hostname of the server.",
"type": "string"
},
"https": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "object"
}
],
"description": "Listen with https protocol with a self-signed certificate by default."
}
},
"definitions": {},
"required": []
}

View File

@ -0,0 +1,90 @@
import { ExecutorContext, joinPathFragments } from '@nx/devkit';
import { NuxtServeExecutorOptions } from './schema';
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';
// Required because nuxi is ESM package.
export function loadNuxiDynamicImport() {
return Function('return import("nuxi")')() as Promise<typeof import('nuxi')>;
}
export async function* nuxtServeExecutor(
options: NuxtServeExecutorOptions,
context: ExecutorContext
) {
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
yield* createAsyncIterable<{ success: boolean; baseUrl: string }>(
async ({ next, error }) => {
try {
const { runCommand } = await loadNuxiDynamicImport();
await runCommand('dev', [projectRoot], {
overrides: getConfigOverrides(options, context.root, projectRoot),
});
next({
success: true,
baseUrl: `${options.https ? 'https' : 'http'}://${
options.host ?? 'localhost'
}:${options.port ?? '4200'}`,
});
} catch (err) {
console.error(err);
error(new Error(`Nuxt app exited with message ${err.message}`));
}
}
);
}
function getConfigOverrides(
options: NuxtServeExecutorOptions,
workspaceRoot: string,
projectRoot: string
): { [key: string]: any } {
const json: { [key: string]: any } = {
workspaceDir: workspaceRoot,
typescript: {
typeCheck: true,
tsConfig: {
extends: joinPathFragments(
workspaceRoot,
projectRoot,
'tsconfig.app.json'
),
},
},
};
if (options.debug !== undefined) {
json.debug = options.debug;
}
if (options.dev !== undefined) {
json.dev = options.dev;
}
if (options.ssr !== undefined) {
json.ssr = options.ssr;
}
if (options.https !== undefined) {
if (!json.devServer) {
json.devServer = {};
}
json.devServer.https = options.https;
}
if (options.port) {
if (!json.devServer) {
json.devServer = {};
}
json.devServer.port = options.port;
}
if (options.host) {
if (!json.devServer) {
json.devServer = {};
}
json.devServer.host = options.host;
}
return json;
}
export default nuxtServeExecutor;

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`app generated files content - as-provided should add nuxt entries in .gitignore 1`] = `
exports[`app generated files content - as-provided general application should add nuxt entries in .gitignore 1`] = `
"
# Nuxt dev/build outputs
.output
@ -10,7 +10,7 @@ exports[`app generated files content - as-provided should add nuxt entries in .g
.cache"
`;
exports[`app generated files content - as-provided should configure eslint correctly 1`] = `
exports[`app generated files content - as-provided general application should configure eslint correctly 1`] = `
"{
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
@ -26,20 +26,26 @@ exports[`app generated files content - as-provided should configure eslint corre
"
`;
exports[`app generated files content - as-provided should configure nuxt correctly 1`] = `
"import { NxNuxtModule } from '@nx/nuxt';
exports[`app generated files content - as-provided general application should configure nuxt correctly 1`] = `
"import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [NxNuxtModule],
srcDir: 'src',
devtools: { enabled: true },
css: ['~/assets/css/styles.css'],
devServer: {
host: 'localhost',
port: 4200,
},
vite: {
plugins: [nxViteTsPaths()],
},
});
"
`;
exports[`app generated files content - as-provided should configure tsconfig and project.json correctly 1`] = `
exports[`app generated files content - as-provided general application should configure tsconfig and project.json correctly 1`] = `
"{
"name": "my-app",
"$schema": "../node_modules/nx/schemas/project-schema.json",
@ -47,25 +53,15 @@ exports[`app generated files content - as-provided should configure tsconfig and
"sourceRoot": "my-app/src",
"targets": {
"serve": {
"executor": "nx:run-commands",
"outputs": [
"{workspaceRoot}/{projectRoot}/.output",
"{workspaceRoot}/{projectRoot}/.nuxt"
],
"options": {
"command": "npx nuxi dev --port=4200",
"cwd": "my-app"
}
"executor": "@nx/nuxt:serve",
"outputs": ["{options.outputFile}"],
"options": {}
},
"build": {
"executor": "nx:run-commands",
"outputs": [
"{workspaceRoot}/{projectRoot}/.output",
"{workspaceRoot}/{projectRoot}/.nuxt"
],
"executor": "@nx/nuxt:build",
"outputs": ["{options.outputFile}"],
"options": {
"command": "npx nuxi build",
"cwd": "my-app"
"outputPath": "dist/my-app"
}
},
"lint": {
@ -80,7 +76,8 @@ exports[`app generated files content - as-provided should configure tsconfig and
"outputs": ["{options.reportsDirectory}"],
"options": {
"passWithNoTests": true,
"reportsDirectory": "../coverage/my-app"
"reportsDirectory": "../coverage/my-app",
"config": "my-app/vitest.config.ts"
}
}
}
@ -88,14 +85,14 @@ exports[`app generated files content - as-provided should configure tsconfig and
"
`;
exports[`app generated files content - as-provided should configure tsconfig and project.json correctly 2`] = `
exports[`app generated files content - as-provided general application should configure tsconfig and project.json correctly 2`] = `
"{
"compilerOptions": {},
"files": [],
"include": [],
"references": [
{
"path": "./.nuxt/tsconfig.json"
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
@ -106,7 +103,67 @@ exports[`app generated files content - as-provided should configure tsconfig and
"
`;
exports[`app generated files content - as-provided should create all new files in the correct location 1`] = `
exports[`app generated files content - as-provided general application should configure vitest correctly 1`] = `
"import { defineVitestConfig } from 'nuxt-vitest/config';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineVitestConfig({
plugins: [nxViteTsPaths()],
test: {
globals: true,
cache: {
dir: '../node_modules/.vitest',
},
include: ['my-app/src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
environment: 'nuxt',
},
});
"
`;
exports[`app generated files content - as-provided general application should configure vitest correctly 2`] = `
"{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"],
"composite": true
},
"include": [
"vitest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"src/**/*.d.ts"
]
}
"
`;
exports[`app generated files content - as-provided general application should configure vitest correctly 3`] = `
"{
"compilerOptions": {},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../tsconfig.base.json"
}
"
`;
exports[`app generated files content - as-provided general application should create all new files in the correct location 1`] = `
[
".prettierrc",
"package.json",
@ -117,7 +174,6 @@ exports[`app generated files content - as-provided should create all new files i
"my-app/.npmrc",
"my-app/nuxt.config.ts",
"my-app/src/app.vue",
"my-app/src/assets/css/styles.css",
"my-app/src/components/NxWelcome.vue",
"my-app/src/pages/about.vue",
"my-app/src/pages/index.vue",
@ -125,12 +181,13 @@ exports[`app generated files content - as-provided should create all new files i
"my-app/src/public/favicon.ico",
"my-app/src/server/api/greet.ts",
"my-app/src/server/tsconfig.json",
"my-app/tsconfig.app.json",
"my-app/tsconfig.json",
".gitignore",
".eslintrc.json",
".eslintignore",
"my-app/.eslintrc.json",
"my-app/vite.config.ts",
"my-app/vitest.config.ts",
"my-app/tsconfig.spec.json",
"my-app-e2e/project.json",
"my-app-e2e/src/e2e/app.cy.ts",
@ -143,3 +200,85 @@ exports[`app generated files content - as-provided should create all new files i
"my-app-e2e/.eslintrc.json",
]
`;
exports[`app generated files content - as-provided styles setup should configure css 1`] = `
"import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
css: ['~/assets/css/styles.css'],
vite: {
plugins: [nxViteTsPaths()],
},
});
"
`;
exports[`app generated files content - as-provided styles setup should configure less 1`] = `
"import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
css: ['~/assets/css/styles.less'],
vite: {
plugins: [nxViteTsPaths()],
},
});
"
`;
exports[`app generated files content - as-provided styles setup should configure scss 1`] = `
"import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
css: ['~/assets/css/styles.scss'],
vite: {
plugins: [nxViteTsPaths()],
},
});
"
`;
exports[`app generated files content - as-provided styles setup should not configure styles 1`] = `
"import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
srcDir: 'src',
devtools: { enabled: true },
devServer: {
host: 'localhost',
port: 4200,
},
vite: {
plugins: [nxViteTsPaths()],
},
});
"
`;

View File

@ -1,5 +1,5 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree } from '@nx/devkit';
import { Tree, readJson } from '@nx/devkit';
import { applicationGenerator } from './application';
describe('app', () => {
@ -7,11 +7,13 @@ describe('app', () => {
const name = 'my-app';
describe('generated files content - as-provided', () => {
describe('general application', () => {
beforeAll(async () => {
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, {
name,
projectNameAndRootFormat: 'as-provided',
unitTestRunner: 'vitest',
});
});
it('should create all new files in the correct location', async () => {
@ -31,9 +33,70 @@ describe('app', () => {
expect(tree.read('my-app/.eslintrc.json', 'utf-8')).toMatchSnapshot();
});
it('should configure vitest correctly', () => {
expect(tree.read('my-app/vitest.config.ts', 'utf-8')).toMatchSnapshot();
expect(
tree.read('my-app/tsconfig.spec.json', 'utf-8')
).toMatchSnapshot();
expect(tree.read('my-app/tsconfig.json', 'utf-8')).toMatchSnapshot();
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['vitest']).toEqual('0.31.4');
expect(packageJson.devDependencies['nuxt-vitest']).toEqual('^0.11.0');
});
it('should configure tsconfig and project.json correctly', () => {
expect(tree.read('my-app/project.json', 'utf-8')).toMatchSnapshot();
expect(tree.read('my-app/tsconfig.json', 'utf-8')).toMatchSnapshot();
});
});
describe('styles setup', () => {
beforeAll(async () => {
tree = createTreeWithEmptyWorkspace();
});
it('should configure css', async () => {
await applicationGenerator(tree, {
name: 'myapp1',
projectNameAndRootFormat: 'as-provided',
unitTestRunner: 'none',
style: 'css',
});
expect(tree.exists('myapp1/src/assets/css/styles.css')).toBeTruthy();
expect(tree.read('myapp1/nuxt.config.ts', 'utf-8')).toMatchSnapshot();
});
it('should configure scss', async () => {
await applicationGenerator(tree, {
name: 'myapp2',
projectNameAndRootFormat: 'as-provided',
unitTestRunner: 'none',
style: 'scss',
});
expect(tree.exists('myapp2/src/assets/css/styles.scss')).toBeTruthy();
expect(tree.read('myapp2/nuxt.config.ts', 'utf-8')).toMatchSnapshot();
});
it('should configure less', async () => {
await applicationGenerator(tree, {
name: 'myapp3',
projectNameAndRootFormat: 'as-provided',
unitTestRunner: 'none',
style: 'less',
});
expect(tree.exists('myapp3/src/assets/css/styles.less')).toBeTruthy();
expect(tree.read('myapp3/nuxt.config.ts', 'utf-8')).toMatchSnapshot();
});
it('should not configure styles', async () => {
await applicationGenerator(tree, {
name: 'myapp4',
projectNameAndRootFormat: 'as-provided',
unitTestRunner: 'none',
style: 'none',
});
expect(tree.exists('myapp4/src/assets/css/styles.css')).toBeFalsy();
expect(tree.read('myapp4/nuxt.config.ts', 'utf-8')).toMatchSnapshot();
});
});
});
});

View File

@ -1,10 +1,9 @@
import * as path from 'path';
import {
addProjectConfiguration,
ensurePackage,
formatFiles,
generateFiles,
GeneratorCallback,
joinPathFragments,
offsetFromRoot,
runTasksInSerial,
toJS,
@ -19,14 +18,18 @@ import { updateGitIgnore } from '../../utils/update-gitignore';
import { addBuildTarget, addServeTarget } from './lib/add-targets';
import { Linter } from '@nx/eslint';
import { addE2e } from './lib/add-e2e';
import { nxVersion } from '../../utils/versions';
import { addLinting } from '../../utils/add-linting';
import { addVitest } from './lib/add-vitest';
export async function applicationGenerator(tree: Tree, schema: Schema) {
const tasks: GeneratorCallback[] = [];
const options = await normalizeOptions(tree, schema);
const outputPath = joinPathFragments('dist', options.appProjectRoot);
const projectOffsetFromRoot = offsetFromRoot(options.appProjectRoot);
const nuxtInitTask = await nuxtInitGenerator(tree, {
...options,
skipFormat: true,
@ -40,13 +43,25 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
targets: {},
});
generateFiles(tree, path.join(__dirname, './files'), options.appProjectRoot, {
generateFiles(
tree,
joinPathFragments(__dirname, './files'),
options.appProjectRoot,
{
...options,
offsetFromRoot: offsetFromRoot(options.appProjectRoot),
offsetFromRoot: projectOffsetFromRoot,
title: options.projectName,
dot: '.',
tmpl: '',
});
style: options.style,
}
);
if (options.style === 'none') {
tree.delete(
joinPathFragments(options.appProjectRoot, `src/assets/css/styles.none`)
);
}
createTsConfig(
tree,
@ -54,12 +69,13 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
projectRoot: options.appProjectRoot,
rootProject: options.rootProject,
unitTestRunner: options.unitTestRunner,
outputPath,
},
getRelativePathToRootTsConfig(tree, options.appProjectRoot)
);
addServeTarget(tree, options.name, options.appProjectRoot);
addBuildTarget(tree, options.name, options.appProjectRoot);
addServeTarget(tree, options.name);
addBuildTarget(tree, options.name, outputPath);
updateGitIgnore(tree);
@ -74,15 +90,7 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
);
if (options.unitTestRunner === 'vitest') {
const { vitestGenerator } = ensurePackage('@nx/vite', nxVersion);
tasks.push(
await vitestGenerator(tree, {
uiFramework: 'none',
project: options.projectName,
coverageProvider: 'c8',
skipFormat: true,
})
);
addVitest(tree, options, options.appProjectRoot, projectOffsetFromRoot);
}
tasks.push(await addE2e(tree, options));

View File

@ -1,9 +1,19 @@
import { NxNuxtModule } from '@nx/nuxt';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [NxNuxtModule],
srcDir: 'src',
devtools: { enabled: true },
css: ['~/assets/css/styles.css'],
devServer: {
host: 'localhost',
port: 4200,
},
<% if (style !== 'none') { %>
css: ['~/assets/css/styles.<%= style %>'],
<% } %>
vite: {
plugins: [
nxViteTsPaths()
],
}
});

View File

@ -1,16 +1,18 @@
<script setup lang="ts">
const route = useRoute();
</script>
<script setup lang="ts"></script>
<template>
<main>
<header>
<nav>
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink to="/about">About</NuxtLink>
<NuxtLink to="/">
Home
</NuxtLink>
<NuxtLink to="/about">
About
</NuxtLink>
</nav>
</header>
<nuxt-page></nuxt-page>
<nuxt-page />
</main>
</template>

View File

@ -50,7 +50,7 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
js: false,
linter: options.linter,
setParserOptionsProject: options.setParserOptionsProject,
webServerAddress: 'http://127.0.0.1:4200',
webServerAddress: 'http://localhost:4200',
webServerCommand: `${getPackageManagerCommand().exec} nx serve ${
options.projectName
}`,

View File

@ -1,26 +1,15 @@
import {
Tree,
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
} from '@nx/devkit';
export function addServeTarget(
tree: Tree,
projectName: string,
projectRoot: string
) {
export function addServeTarget(tree: Tree, projectName: string) {
const projectConfig = readProjectConfiguration(tree, projectName);
projectConfig.targets['serve'] = {
executor: 'nx:run-commands',
outputs: [
'{workspaceRoot}/{projectRoot}/.output',
'{workspaceRoot}/{projectRoot}/.nuxt',
],
options: {
command: 'npx nuxi dev --port=4200',
cwd: joinPathFragments(projectRoot),
},
executor: '@nx/nuxt:serve',
outputs: ['{options.outputFile}'],
options: {},
};
updateProjectConfiguration(tree, projectName, projectConfig);
}
@ -28,18 +17,14 @@ export function addServeTarget(
export function addBuildTarget(
tree: Tree,
projectName: string,
projectRoot: string
outputPath: string
) {
const projectConfig = readProjectConfiguration(tree, projectName);
projectConfig.targets['build'] = {
executor: 'nx:run-commands',
outputs: [
'{workspaceRoot}/{projectRoot}/.output',
'{workspaceRoot}/{projectRoot}/.nuxt',
],
executor: '@nx/nuxt:build',
outputs: ['{options.outputFile}'],
options: {
command: 'npx nuxi build',
cwd: joinPathFragments(projectRoot),
outputPath: outputPath,
},
};
updateProjectConfiguration(tree, projectName, projectConfig);

View File

@ -0,0 +1,88 @@
import {
Tree,
addDependenciesToPackageJson,
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
writeJson,
} from '@nx/devkit';
import { NormalizedSchema } from '../schema';
import {
happyDomVersion,
nuxtVitestVersion,
nxVersion,
vitestVersion,
} from '../../../utils/versions';
export function addVitest(
tree: Tree,
options: NormalizedSchema,
projectRoot: string,
projectOffsetFromRoot: string
) {
addDependenciesToPackageJson(
tree,
{},
{
'@nx/vite': nxVersion,
'@vitest/coverage-c8': vitestVersion,
'@vitest/ui': vitestVersion,
vitest: vitestVersion,
'nuxt-vitest': nuxtVitestVersion,
'happy-dom': happyDomVersion,
}
);
const projectConfig = readProjectConfiguration(tree, options.name);
projectConfig.targets['test'] = {
executor: '@nx/vite:test',
outputs: ['{options.reportsDirectory}'],
options: {
passWithNoTests: true,
reportsDirectory: `${projectOffsetFromRoot}coverage/${projectRoot}`,
config: `${projectRoot}/vitest.config.ts`,
},
};
updateProjectConfiguration(tree, options.name, projectConfig);
tree.write(
joinPathFragments(projectRoot, 'vitest.config.ts'),
`
import { defineVitestConfig } from 'nuxt-vitest/config';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineVitestConfig({
plugins: [nxViteTsPaths()],
test: {
globals: true,
cache: {
dir: '${projectOffsetFromRoot}node_modules/.vitest',
},
include: ['${projectRoot}/src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
environment: 'nuxt',
},
});
`
);
writeJson(tree, joinPathFragments(projectRoot, 'tsconfig.spec.json'), {
extends: './tsconfig.json',
compilerOptions: {
outDir: `${projectOffsetFromRoot}dist/out-tsc`,
types: ['vitest/globals', 'vitest/importMeta', 'vite/client', 'node'],
composite: true,
},
include: [
'vitest.config.ts',
'src/**/*.test.ts',
'src/**/*.spec.ts',
'src/**/*.test.tsx',
'src/**/*.spec.tsx',
'src/**/*.test.js',
'src/**/*.spec.js',
'src/**/*.test.jsx',
'src/**/*.spec.jsx',
'src/**/*.d.ts',
],
});
}

View File

@ -45,6 +45,7 @@ export async function normalizeOptions(
e2eProjectName,
e2eProjectRoot,
parsedTags,
style: options.style ?? 'none',
} as NormalizedSchema;
normalized.unitTestRunner ??= 'vitest';

View File

@ -80,7 +80,24 @@
"style": {
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css"
"alias": "s",
"default": "css",
"x-prompt": {
"message": "Which stylesheet format would you like to use?",
"type": "list",
"items": [
{ "value": "css", "label": "CSS" },
{
"value": "scss",
"label": "SASS(.scss) [ http://sass-lang.com ]"
},
{
"value": "less",
"label": "LESS [ http://lesscss.org ]"
},
{ "value": "none", "label": "None" }
]
}
},
"setParserOptionsProject": {
"type": "boolean",

View File

@ -1,27 +0,0 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree } from '@nx/devkit';
import { applicationGenerator } from '../application/application';
import { componentGenerator } from './component';
describe('component', () => {
let tree: Tree;
const name = 'my-app';
describe('generated files content - as-provided', () => {
beforeAll(async () => {
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, {
name,
projectNameAndRootFormat: 'as-provided',
});
});
it('should create a new vue component in the correct location', async () => {
await componentGenerator(tree, {
name: 'hello',
project: name,
});
expect(tree.exists('my-app/src/components/hello/hello.vue')).toBeTruthy();
});
});
});

View File

@ -1,22 +0,0 @@
import { formatFiles, Tree } from '@nx/devkit';
import { componentGenerator as vueComponentGenerator } from '@nx/vue';
import { Schema } from './schema';
/*
* This generator is basically the Vue one, but for Nuxt we
* are just adjusting some options
*/
export async function componentGenerator(host: Tree, options: Schema) {
await vueComponentGenerator(host, {
...options,
routing: false,
skipFormat: true,
directory: options.directory ?? 'components',
});
if (!options.skipFormat) {
await formatFiles(host);
}
}
export default componentGenerator;

View File

@ -1,12 +0,0 @@
export interface Schema {
project: string;
name: string;
skipTests?: boolean;
flat?: boolean;
pascalCaseFiles?: boolean;
pascalCaseDirectory?: boolean;
fileName?: string;
inSourceTests?: boolean;
skipFormat?: boolean;
directory?: string;
}

View File

@ -1,85 +0,0 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxNuxtComponent",
"title": "Create a Nuxt Component",
"description": "Create a Nuxt Component for Nx.",
"type": "object",
"examples": [
{
"command": "nx g component my-component --project=myapp",
"description": "Generate a component in the `myapp` application"
},
{
"command": "nx g component my-component --project=myapp --classComponent",
"description": "Generate a class component in the `myapp` application"
}
],
"properties": {
"project": {
"type": "string",
"description": "The name of the project.",
"alias": "p",
"$default": {
"$source": "projectName"
},
"x-prompt": "What is the name of the project for this component?",
"x-priority": "important"
},
"name": {
"type": "string",
"description": "The name of the component.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the component?",
"x-priority": "important"
},
"skipTests": {
"type": "boolean",
"description": "When true, does not create `spec.ts` test files for the new component.",
"default": false,
"x-priority": "internal"
},
"flat": {
"type": "boolean",
"description": "Create component at the source root rather than its own directory.",
"default": false
},
"directory": {
"type": "string",
"description": "Create the component under this directory (can be nested).",
"alias": "dir",
"x-priority": "important"
},
"pascalCaseFiles": {
"type": "boolean",
"description": "Use pascal case component file name (e.g. `App.vue`).",
"alias": "P",
"default": false
},
"pascalCaseDirectory": {
"type": "boolean",
"description": "Use pascal case directory name (e.g. `App/App.vue`).",
"alias": "R",
"default": false
},
"fileName": {
"type": "string",
"description": "Create a component with this file name."
},
"inSourceTests": {
"type": "boolean",
"default": false,
"description": "When using Vitest, separate spec files will not be generated and instead will be included within the source files. Read more on the Vitest docs site: https://vitest.dev/guide/in-source.html"
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false,
"x-priority": "internal"
}
},
"required": ["name", "project"]
}

View File

@ -4,17 +4,20 @@ exports[`init should add nuxt dependencies 1`] = `
{
"dependencies": {},
"devDependencies": {
"@nuxt/devtools": "1.0.0-beta.0",
"@nuxt/devtools": "1.0.0",
"@nuxt/ui-templates": "^1.3.1",
"@nx/js": "0.0.1",
"@nx/nuxt": "0.0.1",
"@nx/vite": "0.0.1",
"@swc-node/register": "~1.6.7",
"@swc/core": "~1.3.85",
"h3": "^1.8.2",
"nuxt": "^3.7.4",
"nuxt": "^3.8.0",
"prettier": "^2.6.2",
"typescript": "~5.1.3",
"vue": "^3.3.4",
"vue-router": "^4.2.4",
"vue-tsc": "^1.8.8",
},
"name": "@proj/source",
}

View File

@ -10,27 +10,28 @@ import {
nuxtDevtoolsVersion,
nuxtVersion,
h3Version,
nuxtUiTemplatesVersion,
} from '../../utils/versions';
import {
lessVersion,
sassVersion,
vueRouterVersion,
vueVersion,
vueTscVersion,
} from '@nx/vue';
import { InitSchema } from './schema';
function updateDependencies(host: Tree, schema: InitSchema) {
let dependencies: { [key: string]: string } = {
vue: vueVersion,
};
let devDependencies: { [key: string]: string } = {
'@nx/nuxt': nxVersion,
'@nx/vite': nxVersion, // needed for the nxViteTsPaths plugin
'@nuxt/devtools': nuxtDevtoolsVersion,
'@nuxt/ui-templates': nuxtUiTemplatesVersion,
nuxt: nuxtVersion,
h3: h3Version,
vue: vueVersion,
'vue-router': vueRouterVersion,
'vue-tsc': vueTscVersion,
};
if (schema.style === 'scss') {

View File

@ -1,53 +0,0 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree } from '@nx/devkit';
import { applicationGenerator } from '../application/application';
import { getDirectory, pageGenerator } from './page';
describe('page', () => {
let tree: Tree;
const name = 'my-app';
describe('getDirectory', () => {
it('should return "pages" if no directory is provided', () => {
expect(getDirectory(undefined)).toEqual('pages');
});
it('should return the directory unchanged if it already starts with "pages/"', () => {
expect(getDirectory('pages/someDir')).toEqual('pages/someDir');
});
it('should prepend "pages/" to the directory if it does not start with "pages/"', () => {
expect(getDirectory('someDir')).toEqual('pages/someDir');
});
it('should work with an empty string', () => {
expect(getDirectory('')).toEqual('pages');
});
});
describe('generated files content - as-provided', () => {
beforeAll(async () => {
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, {
name,
projectNameAndRootFormat: 'as-provided',
});
});
it('should create a new page in the correct location', async () => {
await pageGenerator(tree, {
name: 'about',
project: name,
});
expect(tree.exists('my-app/src/pages/about.vue')).toBeTruthy();
});
it('should create a new page in the correct location for nested directory', async () => {
await pageGenerator(tree, {
name: 'about',
project: name,
});
expect(tree.exists('my-app/src/pages/about.vue')).toBeTruthy();
});
});
});

View File

@ -1,29 +0,0 @@
import { formatFiles, joinPathFragments, Tree } from '@nx/devkit';
import { componentGenerator } from '../component/component';
import { Schema } from './schema';
export async function pageGenerator(host: Tree, options: Schema) {
await componentGenerator(host, {
...options,
directory: getDirectory(options.directory),
skipTests: true,
flat: true,
pascalCaseFiles: false, // it's good to keep route names lowercase
pascalCaseDirectory: false,
skipFormat: true,
});
if (!options.skipFormat) {
await formatFiles(host);
}
}
export function getDirectory(directory: string) {
return directory?.length > 0
? directory.startsWith('pages/')
? directory
: joinPathFragments('pages', directory)
: 'pages';
}
export default pageGenerator;

View File

@ -1,7 +0,0 @@
export interface Schema {
project: string;
name: string;
directory?: string;
fileName?: string;
skipFormat?: boolean;
}

View File

@ -1,52 +0,0 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxNuxtPage",
"title": "Create a Nuxt page",
"description": "Create a Nuxt page for Nx.",
"type": "object",
"examples": [
{
"command": "nx g page new-page --project=myapp",
"description": "Generate a page in the `myapp` application"
}
],
"properties": {
"project": {
"type": "string",
"description": "The name of the project.",
"alias": "p",
"$default": {
"$source": "projectName"
},
"x-prompt": "What is the name of the project for this page?",
"x-priority": "important"
},
"name": {
"type": "string",
"description": "The name of the page.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the page?",
"x-priority": "important"
},
"directory": {
"type": "string",
"description": "Create the page under this directory - all nested directories will be created under the pages directory.",
"alias": "dir"
},
"fileName": {
"type": "string",
"description": "Create a component with this file name."
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false,
"x-priority": "internal"
}
},
"required": ["name", "project"]
}

View File

@ -1,67 +0,0 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxNuxtStorybookStories",
"title": "Generate Nuxt Storybook stories",
"description": "Generate stories/specs for all components declared in a project.",
"type": "object",
"properties": {
"project": {
"type": "string",
"aliases": ["name", "projectName"],
"description": "Project for which to generate stories.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-prompt": "For which project do you want to generate stories?",
"x-priority": "important"
},
"generateCypressSpecs": {
"type": "boolean",
"description": "Automatically generate `*.spec.ts` files in the cypress e2e app generated by the cypress-configure generator."
},
"cypressProject": {
"type": "string",
"description": "The Cypress project to generate the stories under. This is inferred from `project` by default."
},
"interactionTests": {
"type": "boolean",
"description": "Set up Storybook interaction tests.",
"x-prompt": "Do you want to set up Storybook interaction tests?",
"x-priority": "important",
"default": true
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"ignorePaths": {
"type": "array",
"description": "Paths to ignore when looking for components.",
"items": {
"type": "string",
"description": "Path to ignore."
},
"default": [
"*.stories.ts,*.stories.tsx,*.stories.js,*.stories.jsx,*.stories.mdx"
],
"examples": [
"apps/my-app/src/not-stories/**",
"**/**/src/**/not-stories/**",
"libs/my-lib/**/*.something.ts",
"**/**/src/**/*.other.*",
"libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
]
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false,
"x-priority": "internal"
}
},
"required": ["project"],
"examplesFile": "../../../docs/stories-examples.md"
}

View File

@ -1,21 +0,0 @@
import { runTasksInSerial, Tree } from '@nx/devkit';
import {
storiesGenerator as vueStoriesGenerator,
StorybookStoriesSchema,
} from '@nx/vue';
/*
* This generator is basically the Vue one
*/
export async function storiesGenerator(
host: Tree,
options: StorybookStoriesSchema
) {
const storiesGenerator = await vueStoriesGenerator(host, {
...options,
});
return runTasksInSerial(storiesGenerator);
}
export default storiesGenerator;

View File

@ -29,3 +29,24 @@ export default config;
`;
exports[`nuxt:storybook-configuration should configure with vue3 framework and styles import 2`] = `""`;
exports[`nuxt:storybook-configuration should configure with vue3 framework and styles import 3`] = `
"{
"extends": "./tsconfig.json",
"compilerOptions": {
"emitDecoratorMetadata": true,
"composite": true
},
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"],
"include": [
"src/**/*.stories.ts",
"src/**/*.stories.js",
"src/**/*.stories.jsx",
"src/**/*.stories.tsx",
"src/**/*.stories.mdx",
".storybook/*.js",
".storybook/*.ts"
]
}
"
`;

View File

@ -2,8 +2,8 @@ import { logger, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Linter } from '@nx/eslint';
import applicationGenerator from '../application/application';
import componentGenerator from '../component/component';
import storybookConfigurationGenerator from './configuration';
import { componentGenerator } from '@nx/vue';
const componentContent = `<script setup lang="ts">
defineProps<{
@ -45,7 +45,9 @@ describe('nuxt:storybook-configuration', () => {
expect(
appTree.read('test-ui-app/.storybook/preview.ts', 'utf-8')
).toMatchSnapshot();
expect(appTree.exists('test-ui-app/tsconfig.storybook.json')).toBeTruthy();
expect(
appTree.read('test-ui-app/tsconfig.storybook.json', 'utf-8')
).toMatchSnapshot();
});
it('should generate stories for components and not pages', async () => {

View File

@ -3,6 +3,7 @@ import {
readProjectConfiguration,
runTasksInSerial,
Tree,
updateJson,
} from '@nx/devkit';
import { storybookConfigurationGenerator as vueStorybookConfigurationGenerator } from '@nx/vue';
import { Schema } from './schema';
@ -30,6 +31,18 @@ export async function storybookConfigurationGenerator(
`import '../src/assets/css/styles.css';`
);
updateJson(
host,
`${projectConfiguration.root}/tsconfig.storybook.json`,
(json) => {
json.compilerOptions = {
...json.compilerOptions,
composite: true,
};
return json;
}
);
await formatFiles(host);
return runTasksInSerial(storybookConfigurationGenerator);
}

View File

@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`update gitignore should add entries to .gitignore if they do not exist 1`] = `
"
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
.output_data
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache"
`;
exports[`update gitignore should not add duplicate entries to .gitignore if they already exist 1`] = `
"
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
"
`;

View File

@ -7,16 +7,18 @@ export function createTsConfig(
projectRoot: string;
rootProject?: boolean;
unitTestRunner?: string;
outputPath: string;
},
relativePathToRootTsConfig: string
) {
createAppTsConfig(host, options);
const json = {
compilerOptions: {},
files: [],
include: [],
references: [
{
path: './.nuxt/tsconfig.json',
path: './tsconfig.app.json',
},
],
} as any;
@ -41,3 +43,15 @@ export function createTsConfig(
writeJson(host, `${options.projectRoot}/tsconfig.json`, json);
}
function createAppTsConfig(host: Tree, options: { projectRoot: string }) {
const json = {
extends: './tsconfig.json',
compilerOptions: {
composite: true,
},
exclude: [],
};
writeJson(host, `${options.projectRoot}/tsconfig.app.json`, json);
}

View File

@ -0,0 +1,79 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree } from '@nx/devkit';
import { updateGitIgnore } from './update-gitignore';
describe('update gitignore', () => {
let tree: Tree;
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
});
it('should add entries to .gitignore if they do not exist', () => {
tree.write(
'.gitignore',
`
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
.output_data
`
);
updateGitIgnore(tree);
expect(tree.read('.gitignore', 'utf-8')).toMatchSnapshot();
});
it('should not add duplicate entries to .gitignore if they already exist', () => {
tree.write(
'.gitignore',
`
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
/out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
`
);
updateGitIgnore(tree);
expect(tree.read('.gitignore', 'utf-8')).toMatchSnapshot();
});
});

View File

@ -2,16 +2,24 @@ import { Tree } from '@nx/devkit';
export function updateGitIgnore(tree: Tree) {
const contents = tree.read('.gitignore', 'utf-8') ?? '';
tree.write(
'.gitignore',
[
contents,
const nuxtEntries = [
'# Nuxt dev/build outputs',
'.output',
'.data',
'.nuxt',
'.nitro',
'.cache',
].join('\n')
);
];
let newContents = contents;
for (const entry of nuxtEntries) {
const regex = new RegExp(`^${entry}$`, 'm');
if (!regex.test(newContents)) {
newContents += `\n${entry}`;
}
}
tree.write('.gitignore', [newContents].join('\n'));
}

View File

@ -1,9 +1,19 @@
export const nxVersion = require('../../package.json').version;
// nuxt deps
export const nuxtDevtoolsVersion = '1.0.0-beta.0';
export const nuxtVersion = '^3.7.4';
export const h3Version = '^1.8.2';
export const nuxtVersion = '^3.8.0';
export const nuxtDevtoolsVersion = '1.0.0';
export const nuxtUiTemplatesVersion = '^1.3.1';
// vitest versions
// https://github.com/vitest-dev/vitest/issues/3540
// https://github.com/danielroe/nuxt-vitest/issues/213#issuecomment-1588728111
export const vitestVersion = '0.31.4';
export const nuxtVitestVersion = '^0.11.0';
export const happyDomVersion = '^12.10.3';
// linting deps
export const nuxtEslintConfigVersion = '0.2.0';
// TODO(katerina): nuxi version in package.json - add latest - not nightly

View File

@ -34,7 +34,12 @@ import {
pleaseUpgrade,
storybookMajorVersion,
} from '../../utils/utilities';
import { coreJsVersion, nxVersion, tsNodeVersion } from '../../utils/versions';
import {
coreJsVersion,
nxVersion,
tsLibVersion,
tsNodeVersion,
} from '../../utils/versions';
import { interactionTestsDependencies } from './lib/interaction-testing.utils';
export async function configurationGenerator(
@ -96,6 +101,8 @@ export async function configurationGenerator(
const mainDir =
!!nextBuildTarget && projectType === 'application' ? 'components' : 'src';
const usesVite = !!viteBuildTarget || schema.uiFramework.endsWith('-vite');
createProjectStorybookDir(
tree,
schema.name,
@ -109,7 +116,7 @@ export async function configurationGenerator(
mainDir,
!!nextBuildTarget,
compiler === 'swc',
!!viteBuildTarget || schema.uiFramework.endsWith('-vite'),
usesVite,
viteConfigFilePath
);
@ -174,6 +181,10 @@ export async function configurationGenerator(
devDeps['ts-node'] = tsNodeVersion;
}
if (usesVite && !viteConfigFilePath) {
devDeps['tslib'] = tsLibVersion;
}
if (schema.interactionTests) {
devDeps = {
...devDeps,

View File

@ -6,6 +6,7 @@ export const storybookTestingLibraryVersion = '^0.2.2';
export const storybookJestVersion = '^0.2.3';
export const litVersion = '^2.6.1';
export const tsNodeVersion = '10.9.1';
export const tsLibVersion = '^2.3.0';
export const storybookVersion = '^7.5.3';
export const reactVersion = '^18.2.0';

View File

@ -35,8 +35,23 @@ function checkDependenciesInstalled(host: Tree, schema: InitGeneratorSchema) {
// base deps
devDependencies['@nx/vite'] = nxVersion;
devDependencies['vite'] = viteVersion;
// Do not install latest version if vitest already exists
// because version 0.32 and newer versions break nuxt-vitest
// https://github.com/vitest-dev/vitest/issues/3540
// https://github.com/danielroe/nuxt-vitest/issues/213#issuecomment-1588728111
if (
!packageJson.dependencies['vitest'] &&
!packageJson.devDependencies['vitest']
) {
devDependencies['vitest'] = vitestVersion;
devDependencies['@vitest/ui'] = vitestUiVersion;
}
if (
!packageJson.dependencies['@vitest/ui'] &&
!packageJson.devDependencies['@vitest/ui']
) {
devDependencies['@vitest/ui'] = vitestVersion;
}
if (schema.testEnvironment === 'jsdom') {
devDependencies['jsdom'] = jsdomVersion;

View File

@ -1,7 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"outDir": "<%= offsetFromRoot %>dist/out-tsc",
"types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"]
},
"include": [

View File

@ -1,3 +1,8 @@
---
title: Vue application generator examples
description: This page contains examples for the @nx/vue:app generator.
---
## Examples
{% tabs %}

View File

@ -0,0 +1,35 @@
---
title: Vue and Nuxt component generator examples
description: This page contains examples for the @nx/vue:component generator.
---
This generator will help you generate components for your Vue or your Nuxt projects.
## Examples
### Create a new component for your Vue app
```shell
nx g @nx/vue:component --directory=my-app/src/app/my-cmp --name=my-cmp
```
### Create a new component for your Nuxt app
As recommended in the [Nuxt documentation](https://nuxt.com/docs/guide/directory-structure/components), place your components into the `components` directory of your app. Nuxt automatically imports any components in this
directory.
Running the following will create a new component in the `my-app/src/components` directory:
```shell
nx g @nx/nuxt:component --directory=my-app/src/components/my-cmp --name=my-cmp
```
### Create a new page for your Nuxt app
As stated in the [Nuxt documentation](https://nuxt.com/docs/guide/directory-structure/pages), Nuxt provides _a file-based routing to create routes within your web application_. Place your pages into the `pages` directory of your app.
Running the following will create a new component (page) in the `my-app/src/pages` directory:
```shell
nx g @nx/nuxt:component --directory=my-app/src/pages --name=my-page
```

View File

@ -1,9 +1,22 @@
---
title: Stories generator examples
description: This page contains examples for the @nx/vue:stories generator.
---
This generator will generate stories for all your components in your project. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).
You can also use this generator to generate stories for your **Nuxt** project:
```bash
nx g @nx/vue:stories project-name
```
or
```bash
nx g @nx/nuxt:stories project-name
```
You can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#auto-generate-stories).
When running this generator, you will be prompted to provide the following:

View File

@ -1,9 +1,20 @@
This generator will set up Storybook for your **Vue** project. You can also use this generator to generate Storybook configuration for your **Next.js** project. By default, starting Nx 16, Storybook v7 is used.
---
title: Storybook configuration generator examples
description: This page contains examples for the @nx/vue:storybook-configuration generator.
---
This generator will set up Storybook for your **Vue** project. You can also use this generator to generate Storybook configuration for your **Nuxt** project.
```bash
nx g @nx/vue:storybook-configuration project-name
```
or
```bash
nx g @nx/nuxt:storybook-configuration project-name
```
You can read more about how this generator works, in the [Storybook for Vue overview page](/recipes/storybook/overview-vue#generate-storybook-configuration-for-a-vue-project).
When running this generator, you will be prompted to provide the following:

View File

@ -2,11 +2,14 @@ export * from './src/utils/versions';
export { applicationGenerator } from './src/generators/application/application';
export { libraryGenerator } from './src/generators/library/library';
export { componentGenerator } from './src/generators/component/component';
export { ComponentGeneratorSchema } from './src/generators/component/schema';
export { storybookConfigurationGenerator } from './src/generators/storybook-configuration/configuration';
export {
storiesGenerator,
StorybookStoriesSchema,
} from './src/generators/stories/stories';
export { setupTailwindGenerator } from './src/generators/setup-tailwind/setup-tailwind';
export { SetupTailwindOptions } from './src/generators/setup-tailwind/schema';
export { type InitSchema } from './src/generators/init/schema';
export { vueInitGenerator } from './src/generators/init/init';
export * from './src/utils/versions';

View File

@ -2,7 +2,7 @@
"name": "@nx/vue",
"version": "0.0.1",
"private": false,
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Vitest, Cypress, and Storybook.\n\n- Generators for applications, libraries, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"repository": {
"type": "git",
"url": "https://github.com/nrwl/nx.git",

View File

@ -1,16 +1,22 @@
import { formatFiles, generateFiles, toJS, Tree } from '@nx/devkit';
import { join } from 'path';
import { addExportsToBarrel, normalizeOptions } from './lib/utils';
import { NormalizedSchema, Schema } from './schema';
import { NormalizedSchema, ComponentGeneratorSchema } from './schema';
export async function componentGenerator(host: Tree, schema: Schema) {
export async function componentGenerator(
host: Tree,
schema: ComponentGeneratorSchema
) {
return componentGeneratorInternal(host, {
nameAndDirectoryFormat: 'derived',
...schema,
});
}
export async function componentGeneratorInternal(host: Tree, schema: Schema) {
export async function componentGeneratorInternal(
host: Tree,
schema: ComponentGeneratorSchema
) {
const options = await normalizeOptions(host, schema);
createComponentFiles(host, options);

View File

@ -10,14 +10,14 @@ import { parse, relative, dirname } from 'path';
import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript';
import { determineArtifactNameAndDirectoryOptions } from '@nx/devkit/src/generators/artifact-name-and-directory-utils';
import { NormalizedSchema, Schema } from '../schema';
import { NormalizedSchema, ComponentGeneratorSchema } from '../schema';
import { addImport } from '../../../utils/ast-utils';
let tsModule: typeof import('typescript');
export async function normalizeOptions(
host: Tree,
options: Schema
options: ComponentGeneratorSchema
): Promise<NormalizedSchema> {
const {
artifactName: name,

View File

@ -1,4 +1,4 @@
export interface Schema {
export interface ComponentGeneratorSchema {
name: string;
skipTests?: boolean;
directory?: string;
@ -28,7 +28,7 @@ export interface Schema {
project?: string;
}
export interface NormalizedSchema extends Schema {
export interface NormalizedSchema extends ComponentGeneratorSchema {
projectName: string;
projectSourceRoot: string;
fileName: string;

View File

@ -7,12 +7,8 @@
"type": "object",
"examples": [
{
"command": "nx g component my-component --project=mylib",
"description": "Generate a component in the `mylib` library"
},
{
"command": "nx g component my-component --project=mylib --classComponent",
"description": "Generate a class component in the `mylib` library"
"command": "nx g @nx/vue:component --directory=my-app/src/app/one --name=one --nameAndDirectoryFormat=as-provided --unitTestRunner=vitest",
"description": "Generate a component in the `my-app` application"
}
],
"properties": {

View File

@ -8,6 +8,11 @@ const knownStylesheetLocations = [
'src/styles.scss',
'src/styles.less',
// What we generate for nuxt by default
'src/assets/css/styles.css',
'src/assets/css/styles.scss',
'src/assets/css/styles.less',
// Other common locations (e.g. what `npm create vue` does)
'src/assets/styles.css',
'src/assets/styles.scss',

View File

@ -16,6 +16,9 @@ describe('vue setup-tailwind generator', () => {
${`src/assets/styles.css`}
${`src/assets/styles.scss`}
${`src/assets/styles.less`}
${`src/assets/css/styles.css`}
${`src/assets/css/styles.scss`}
${`src/assets/css/styles.less`}
`('should update existing stylesheet', async ({ stylesPath }) => {
const tree = createTreeWithEmptyWorkspace();
addProjectConfiguration(tree, 'example', {

View File

@ -33,7 +33,7 @@ export async function createAllStories(
projectConfiguration: ProjectConfiguration,
ignorePaths?: string[]
) {
const { sourceRoot, root } = projectConfiguration;
const { sourceRoot } = projectConfiguration;
let componentPaths: string[] = [];
const pathsToCheck = [
joinPathFragments(sourceRoot, 'app'), // Default component folder for apps

View File

@ -821,6 +821,136 @@ Nx comes with local caching already built-in (check your \`nx.json\`). On CI you
"
`;
exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for Nuxt preset 1`] = `
"# Proj
<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>
✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨
## Start the app
To start the development server run \`nx serve app1\`. Open your browser and navigate to http://localhost:4200/. Happy coding!
## Generate code
If you happen to use Nx plugins, you can leverage code generators that might come with it.
Run \`nx list\` to get a list of available plugins and whether they have generators. Then run \`nx list <plugin-name>\` to see what generators are available.
Learn more about [Nx generators on the docs](https://nx.dev/plugin-features/use-code-generators).
## Running tasks
To execute tasks with Nx use the following syntax:
\`\`\`
nx <target> <project> <...options>
\`\`\`
You can also run multiple targets:
\`\`\`
nx run-many -t <target1> <target2>
\`\`\`
..or add \`-p\` to filter specific projects
\`\`\`
nx run-many -t <target1> <target2> -p <proj1> <proj2>
\`\`\`
Targets can be defined in the \`package.json\` or \`projects.json\`. Learn more [in the docs](https://nx.dev/core-features/run-tasks).
## Want better Editor Integration?
Have a look at the [Nx Console extensions](https://nx.dev/nx-console). It provides autocomplete support, a UI for exploring and running tasks & generators, and more! Available for VSCode, IntelliJ and comes with a LSP for Vim users.
## Ready to deploy?
Just run \`nx build demoapp\` to build the application. The build artifacts will be stored in the \`dist/\` directory, ready to be deployed.
## Set up CI!
Nx comes with local caching already built-in (check your \`nx.json\`). On CI you might want to go a step further.
- [Set up remote caching](https://nx.dev/core-features/share-your-cache)
- [Set up task distribution across multiple machines](https://nx.dev/core-features/distribute-task-execution)
- [Learn more how to setup CI](https://nx.dev/recipes/ci)
## Connect with us!
- [Join the community](https://nx.dev/community)
- [Subscribe to the Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
- [Follow us on Twitter](https://twitter.com/nxdevtools)
"
`;
exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for NuxtStandalone preset 1`] = `
"# Proj
<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a>
✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨
## Start the app
To start the development server run \`nx serve app1\`. Open your browser and navigate to http://localhost:4200/. Happy coding!
## Generate code
If you happen to use Nx plugins, you can leverage code generators that might come with it.
Run \`nx list\` to get a list of available plugins and whether they have generators. Then run \`nx list <plugin-name>\` to see what generators are available.
Learn more about [Nx generators on the docs](https://nx.dev/plugin-features/use-code-generators).
## Running tasks
To execute tasks with Nx use the following syntax:
\`\`\`
nx <target> <project> <...options>
\`\`\`
You can also run multiple targets:
\`\`\`
nx run-many -t <target1> <target2>
\`\`\`
..or add \`-p\` to filter specific projects
\`\`\`
nx run-many -t <target1> <target2> -p <proj1> <proj2>
\`\`\`
Targets can be defined in the \`package.json\` or \`projects.json\`. Learn more [in the docs](https://nx.dev/core-features/run-tasks).
## Want better Editor Integration?
Have a look at the [Nx Console extensions](https://nx.dev/nx-console). It provides autocomplete support, a UI for exploring and running tasks & generators, and more! Available for VSCode, IntelliJ and comes with a LSP for Vim users.
## Ready to deploy?
Just run \`nx build demoapp\` to build the application. The build artifacts will be stored in the \`dist/\` directory, ready to be deployed.
## Set up CI!
Nx comes with local caching already built-in (check your \`nx.json\`). On CI you might want to go a step further.
- [Set up remote caching](https://nx.dev/core-features/share-your-cache)
- [Set up task distribution across multiple machines](https://nx.dev/core-features/distribute-task-execution)
- [Learn more how to setup CI](https://nx.dev/recipes/ci)
## Connect with us!
- [Join the community](https://nx.dev/community)
- [Subscribe to the Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
- [Follow us on Twitter](https://twitter.com/nxdevtools)
"
`;
exports[`@nx/workspace:generateWorkspaceFiles README.md should be created for ReactMonorepo preset 1`] = `
"# Proj

View File

@ -132,6 +132,18 @@ function getPresetDependencies({
},
};
case Preset.Nuxt:
case Preset.NuxtStandalone:
return {
dependencies: {},
dev: {
'@nx/nuxt': nxVersion,
'@nx/cypress': e2eTestRunner === 'cypress' ? nxVersion : undefined,
'@nx/playwright':
e2eTestRunner === 'playwright' ? nxVersion : undefined,
},
};
case Preset.ReactMonorepo:
case Preset.ReactStandalone:
return {

View File

@ -38,6 +38,8 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
Preset.ReactStandalone,
Preset.VueMonorepo,
Preset.VueStandalone,
Preset.Nuxt,
Preset.NuxtStandalone,
Preset.AngularMonorepo,
Preset.AngularStandalone,
Preset.Nest,

View File

@ -102,6 +102,7 @@ function createFiles(tree: Tree, options: NormalizedSchema) {
options.preset === Preset.AngularStandalone ||
options.preset === Preset.ReactStandalone ||
options.preset === Preset.VueStandalone ||
options.preset === Preset.NuxtStandalone ||
options.preset === Preset.NodeStandalone ||
options.preset === Preset.NextJsStandalone ||
options.preset === Preset.TsStandalone
@ -157,6 +158,7 @@ function addNpmScripts(tree: Tree, options: NormalizedSchema) {
options.preset === Preset.AngularStandalone ||
options.preset === Preset.ReactStandalone ||
options.preset === Preset.VueStandalone ||
options.preset === Preset.NuxtStandalone ||
options.preset === Preset.NodeStandalone ||
options.preset === Preset.NextJsStandalone
) {

View File

@ -99,6 +99,25 @@ describe('new', () => {
});
});
it('should generate necessary npm dependencies for nuxt preset', async () => {
await newGenerator(tree, {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
appName: 'app',
e2eTestRunner: 'cypress',
preset: Preset.Nuxt,
});
const { devDependencies } = readJson(tree, 'my-workspace/package.json');
expect(devDependencies).toStrictEqual({
'@nx/nuxt': nxVersion,
'@nx/cypress': nxVersion,
'@nx/workspace': nxVersion,
nx: nxVersion,
});
});
it('should generate necessary npm dependencies for angular preset', async () => {
await newGenerator(tree, {
...defaultOptions,

View File

@ -36,6 +36,16 @@ exports[`preset should create files (preset = angular-monorepo) 3`] = `
]
`;
exports[`preset should create files (preset = nuxt-standalone) 1`] = `
{
"executor": "@nx/nuxt:serve",
"options": {},
"outputs": [
"{options.outputFile}",
],
}
`;
exports[`preset should create files (preset = react-standalone bundler = vite) 1`] = `
{
"configurations": {

View File

@ -52,6 +52,17 @@ describe('preset', () => {
expect(readProjectConfiguration(tree, 'proj').targets.serve).toBeDefined();
});
it(`should create files (preset = ${Preset.Nuxt})`, async () => {
await presetGenerator(tree, {
name: 'proj',
preset: Preset.Nuxt,
style: 'css',
linter: 'eslint',
});
expect(tree.exists('apps/proj/src/app.vue')).toBe(true);
expect(readProjectConfiguration(tree, 'proj').targets.serve).toBeDefined();
});
it(`should create files (preset = ${Preset.NextJs})`, async () => {
await presetGenerator(tree, {
name: 'proj',
@ -123,4 +134,17 @@ describe('preset', () => {
readProjectConfiguration(tree, 'proj').targets.serve
).toMatchSnapshot();
});
it(`should create files (preset = ${Preset.NuxtStandalone})`, async () => {
await presetGenerator(tree, {
name: 'proj',
preset: Preset.NuxtStandalone,
style: 'css',
e2eTestRunner: 'cypress',
});
expect(tree.exists('nuxt.config.ts')).toBe(true);
expect(
readProjectConfiguration(tree, 'proj').targets.serve
).toMatchSnapshot();
});
});

View File

@ -102,6 +102,32 @@ async function createPreset(tree: Tree, options: Schema) {
e2eTestRunner: options.e2eTestRunner ?? 'cypress',
unitTestRunner: 'vitest',
});
} else if (options.preset === Preset.Nuxt) {
const { applicationGenerator: nuxtApplicationGenerator } = require('@nx' +
'/nuxt');
return nuxtApplicationGenerator(tree, {
name: options.name,
directory: join('apps', options.name),
projectNameAndRootFormat: 'as-provided',
style: options.style,
linter: options.linter,
e2eTestRunner: options.e2eTestRunner ?? 'cypress',
});
} else if (options.preset === Preset.NuxtStandalone) {
const { applicationGenerator: nuxtApplicationGenerator } = require('@nx' +
'/nuxt');
return nuxtApplicationGenerator(tree, {
name: options.name,
directory: '.',
projectNameAndRootFormat: 'as-provided',
style: options.style,
linter: options.linter,
rootProject: true,
e2eTestRunner: options.e2eTestRunner ?? 'cypress',
unitTestRunner: 'vitest',
});
} else if (options.preset === Preset.NextJs) {
const { applicationGenerator: nextApplicationGenerator } = require('@nx' +
'/next');

View File

@ -18,6 +18,8 @@ export enum Preset {
ReactNative = 'react-native',
VueMonorepo = 'vue-monorepo',
VueStandalone = 'vue-standalone',
Nuxt = 'nuxt',
NuxtStandalone = 'nuxt-standalone',
Expo = 'expo',
NextJs = 'next',
Nest = 'nest',

433
pnpm-lock.yaml generated
View File

@ -1,9 +1,5 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides:
minimist: ^1.2.6
underscore: ^1.12.1
@ -250,7 +246,7 @@ devDependencies:
version: 9.1.6(@nestjs/common@9.1.6)(@nestjs/core@9.1.6)
'@nestjs/schematics':
specifier: ^9.1.0
version: 9.1.0(typescript@5.1.3)
version: 9.1.0(chokidar@3.5.3)(typescript@4.9.4)
'@nestjs/swagger':
specifier: ^6.0.0
version: 6.1.3(@nestjs/common@9.1.6)(@nestjs/core@9.1.6)(reflect-metadata@0.1.13)
@ -269,12 +265,6 @@ devDependencies:
'@nguniversal/builders':
specifier: ~16.2.0
version: 16.2.0(@angular-devkit/build-angular@16.2.0)(@angular/common@16.2.0)(@angular/core@16.2.0)(@types/express@4.17.14)(typescript@5.1.3)
'@nuxt/kit':
specifier: ^3.7.4
version: 3.7.4(rollup@2.79.0)
'@nuxt/schema':
specifier: ^3.7.4
version: 3.7.4(rollup@2.79.0)
'@nx/angular':
specifier: 17.0.0-rc.2
version: 17.0.0-rc.2(@angular-devkit/build-angular@16.2.0)(@angular-devkit/core@16.2.0)(@angular-devkit/schematics@16.2.0)(@nguniversal/builders@16.2.0)(@schematics/angular@16.2.0)(@swc-node/register@1.6.8)(@swc/core@1.3.86)(@types/node@18.16.9)(cypress@13.0.0)(esbuild@0.19.5)(eslint@8.46.0)(html-webpack-plugin@5.5.0)(nx@17.0.0-rc.2)(rxjs@7.8.1)(ts-node@10.9.1)(typescript@5.1.3)(verdaccio@5.15.4)
@ -554,9 +544,6 @@ devDependencies:
czg:
specifier: ^1.4.0
version: 1.4.0
defu:
specifier: ^6.1.2
version: 6.1.2
detect-port:
specifier: ^1.5.1
version: 1.5.1
@ -589,7 +576,7 @@ devDependencies:
version: 2.14.0(eslint@8.46.0)
eslint-plugin-import:
specifier: 2.26.0
version: 2.26.0(@typescript-eslint/parser@6.9.1)(eslint@8.46.0)
version: 2.26.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.2)(eslint@8.46.0)
eslint-plugin-jsx-a11y:
specifier: 6.6.1
version: 6.6.1(eslint@8.46.0)
@ -770,6 +757,9 @@ devDependencies:
npm-package-arg:
specifier: 11.0.1
version: 11.0.1
nuxi:
specifier: npm:nuxi-nightly@3.9.2-1699007958.251cab5
version: /nuxi-nightly@3.9.2-1699007958.251cab5
nx:
specifier: 17.0.0-rc.2
version: 17.0.0-rc.2(@swc-node/register@1.6.8)(@swc/core@1.3.86)
@ -3566,11 +3556,6 @@ packages:
dependencies:
regenerator-runtime: 0.13.11
/@babel/standalone@7.23.1:
resolution: {integrity: sha512-a4muOYz1qUaSoybuUKwK90mRG4sf5rBeUbuzpuGLzG32ZDE/Y2YEebHDODFJN+BtyOKi19hrLfq2qbNyKMx0TA==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/template@7.22.5:
resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
engines: {node: '>=6.9.0'}
@ -5238,20 +5223,6 @@ packages:
- chokidar
dev: true
/@nestjs/schematics@9.1.0(typescript@5.1.3):
resolution: {integrity: sha512-/7CyMTnPJSK9/xD9CkCqwuHPOlHVlLC2RDnbdCJ7mIO07SdbBbY14msTqtYW9VRQtsjZPLh1GTChf7ryJUImwA==}
peerDependencies:
typescript: '>=4.3.5'
dependencies:
'@angular-devkit/core': 15.2.4(chokidar@3.5.3)
'@angular-devkit/schematics': 15.2.4(chokidar@3.5.3)
jsonc-parser: 3.2.0
pluralize: 8.0.0
typescript: 5.1.3
transitivePeerDependencies:
- chokidar
dev: true
/@nestjs/swagger@6.1.3(@nestjs/common@9.1.6)(@nestjs/core@9.1.6)(reflect-metadata@0.1.13):
resolution: {integrity: sha512-H9C/yRgLFb5QrAt6iGrYmIX9X7Q0zXkgZaTNUATljUBra+RCWrEUbLHBcGjTAOtcIyGV/vmyCLv68YSVcZoE0Q==}
peerDependencies:
@ -5784,42 +5755,6 @@ packages:
- typescript
dev: true
/@nrwl/js@15.8.0(@swc-node/register@1.6.8)(@swc/core@1.3.86)(nx@15.8.0)(prettier@2.7.1)(typescript@5.1.3):
resolution: {integrity: sha512-l2Q7oFpzx6ul7G0nKpMkrvnIEaOY+X8fc2g2Db5WqpnnBdfkrtWXZPg/O4DQ1p9O6BXrZ+Q2AK9bfgnliiwyEg==}
dependencies:
'@babel/core': 7.22.9
'@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.9)
'@babel/plugin-proposal-decorators': 7.21.0(@babel/core@7.22.9)
'@babel/plugin-transform-runtime': 7.22.9(@babel/core@7.22.9)
'@babel/preset-env': 7.22.5(@babel/core@7.22.9)
'@babel/preset-typescript': 7.22.5(@babel/core@7.22.9)
'@babel/runtime': 7.22.6
'@nrwl/devkit': 15.8.0(nx@15.8.0)(typescript@5.1.3)
'@nrwl/workspace': 15.8.0(@swc-node/register@1.6.8)(@swc/core@1.3.86)(eslint@8.46.0)(prettier@2.7.1)(typescript@5.1.3)
'@phenomnomnominal/tsquery': 4.1.1(typescript@5.1.3)
babel-plugin-const-enum: 1.2.0(@babel/core@7.22.9)
babel-plugin-macros: 2.8.0
babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.22.9)
chalk: 4.1.2
fast-glob: 3.2.7
fs-extra: 11.1.1
ignore: 5.2.4
js-tokens: 4.0.0
minimatch: 3.0.5
source-map-support: 0.5.19
tree-kill: 1.2.2
tslib: 2.6.1
transitivePeerDependencies:
- '@babel/traverse'
- '@swc-node/register'
- '@swc/core'
- debug
- nx
- prettier
- supports-color
- typescript
dev: true
/@nrwl/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):
resolution: {integrity: sha512-2SZu4KiiXmyjezB8j3+GrgQj2LopzYxp6hO9hIe+DE6N1eo1Dxq7cmOsX+q/w14eRurVNcvDoZxHJB63UjDSUQ==}
dependencies:
@ -5846,7 +5781,7 @@ packages:
optional: true
dependencies:
'@nrwl/devkit': 15.8.0(nx@15.8.0)(typescript@5.1.3)
'@nrwl/js': 15.8.0(@swc-node/register@1.6.8)(@swc/core@1.3.86)(nx@15.8.0)(prettier@2.7.1)(typescript@5.1.3)
'@nrwl/js': 15.8.0(@swc-node/register@1.6.8)(@swc/core@1.3.86)(eslint@8.46.0)(nx@17.0.0-rc.2)(prettier@2.7.1)(typescript@5.1.3)
'@phenomnomnominal/tsquery': 4.1.1(typescript@5.1.3)
eslint: 8.46.0
tmp: 0.2.1
@ -6126,57 +6061,6 @@ packages:
- debug
dev: true
/@nuxt/kit@3.7.4(rollup@2.79.0):
resolution: {integrity: sha512-/S5abZL62BITCvC/TY3KWA6N721U1Osln3cQdBb56XHIeafZCBVqTi92Xb0o7ovl72mMRhrKwRu7elzvz9oT/g==}
engines: {node: ^14.18.0 || >=16.10.0}
dependencies:
'@nuxt/schema': 3.7.4(rollup@2.79.0)
c12: 1.4.2
consola: 3.2.3
defu: 6.1.2
globby: 13.2.2
hash-sum: 2.0.0
ignore: 5.2.4
jiti: 1.20.0
knitwork: 1.0.0
mlly: 1.4.2
pathe: 1.1.1
pkg-types: 1.0.3
scule: 1.0.0
semver: 7.5.4
ufo: 1.3.1
unctx: 2.3.1
unimport: 3.4.0(rollup@2.79.0)
untyped: 1.4.0
transitivePeerDependencies:
- rollup
- supports-color
dev: true
/@nuxt/schema@3.7.4(rollup@2.79.0):
resolution: {integrity: sha512-q6js+97vDha4Fa2x2kDVEuokJr+CGIh1TY2wZp2PLZ7NhG3XEeib7x9Hq8XE8B6pD0GKBRy3eRPPOY69gekBCw==}
engines: {node: ^14.18.0 || >=16.10.0}
dependencies:
'@nuxt/ui-templates': 1.3.1
consola: 3.2.3
defu: 6.1.2
hookable: 5.5.3
pathe: 1.1.1
pkg-types: 1.0.3
postcss-import-resolver: 2.0.0
std-env: 3.4.3
ufo: 1.3.1
unimport: 3.4.0(rollup@2.79.0)
untyped: 1.4.0
transitivePeerDependencies:
- rollup
- supports-color
dev: true
/@nuxt/ui-templates@1.3.1:
resolution: {integrity: sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==}
dev: true
/@nuxtjs/opencollective@0.3.2:
resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==}
engines: {node: '>=8.0.0', npm: '>=5.0.0'}
@ -7833,21 +7717,6 @@ packages:
rollup: 2.79.0
dev: true
/@rollup/pluginutils@5.0.5(rollup@2.79.0):
resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
dependencies:
'@types/estree': 1.0.1
estree-walker: 2.0.2
picomatch: 2.3.1
rollup: 2.79.0
dev: true
/@rollup/pluginutils@5.0.5(rollup@3.21.0):
resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
engines: {node: '>=14.0.0'}
@ -11100,15 +10969,6 @@ packages:
- supports-color
dev: true
/agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
dependencies:
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
dev: true
/agentkeepalive@4.2.1:
resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==}
engines: {node: '>= 8.0.0'}
@ -12428,24 +12288,6 @@ packages:
engines: {node: '>= 0.8'}
dev: true
/c12@1.4.2:
resolution: {integrity: sha512-3IP/MuamSVRVw8W8+CHWAz9gKN4gd+voF2zm/Ln6D25C2RhytEZ1ABbC8MjKr4BR9rhoV1JQ7jJA158LDiTkLg==}
dependencies:
chokidar: 3.5.3
defu: 6.1.2
dotenv: 16.3.1
giget: 1.1.3
jiti: 1.20.0
mlly: 1.4.2
ohash: 1.1.3
pathe: 1.1.1
perfect-debounce: 1.0.0
pkg-types: 1.0.3
rc9: 2.1.1
transitivePeerDependencies:
- supports-color
dev: true
/c8@7.13.0:
resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==}
engines: {node: '>=10.12.0'}
@ -12746,7 +12588,7 @@ packages:
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
/chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@ -12945,10 +12787,6 @@ packages:
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
dev: true
/colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: true
/colors@1.1.2:
resolution: {integrity: sha512-ENwblkFQpqqia6b++zLD/KUWafYlVY/UNnAp7oz7LY7E924wmpye416wBOmvv/HMWzl8gL1kJlfvId/1Dg176w==}
engines: {node: '>=0.1.90'}
@ -13114,11 +12952,6 @@ packages:
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
dev: true
/consola@3.2.3:
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
engines: {node: ^14.18.0 || >=16.10.0}
dev: true
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: true
@ -14211,10 +14044,6 @@ packages:
/defined@1.0.1:
resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
/defu@6.1.2:
resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==}
dev: true
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
@ -14250,10 +14079,6 @@ packages:
engines: {node: '>=6'}
dev: true
/destr@2.0.1:
resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==}
dev: true
/destroy@1.0.4:
resolution: {integrity: sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==}
@ -14624,15 +14449,6 @@ packages:
- utf-8-validate
dev: true
/enhanced-resolve@4.5.0:
resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
engines: {node: '>=6.9.0'}
dependencies:
graceful-fs: 4.2.11
memory-fs: 0.5.0
tapable: 1.1.3
dev: true
/enhanced-resolve@5.10.0:
resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==}
engines: {node: '>=10.13.0'}
@ -14693,6 +14509,7 @@ packages:
requiresBuild: true
dependencies:
prr: 1.0.1
optional: true
/error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@ -15055,35 +14872,6 @@ 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:
@ -15124,37 +14912,6 @@ 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'}
@ -16211,6 +15968,14 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
optional: true
/fstream@1.0.12:
@ -16362,21 +16127,6 @@ packages:
assert-plus: 1.0.0
dev: true
/giget@1.1.3:
resolution: {integrity: sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q==}
hasBin: true
dependencies:
colorette: 2.0.20
defu: 6.1.2
https-proxy-agent: 7.0.2
mri: 1.2.0
node-fetch-native: 1.4.0
pathe: 1.1.1
tar: 6.2.0
transitivePeerDependencies:
- supports-color
dev: true
/git-raw-commits@2.0.11:
resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==}
engines: {node: '>=10'}
@ -16727,10 +16477,6 @@ packages:
dependencies:
function-bind: 1.1.1
/hash-sum@2.0.0:
resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
dev: true
/hast-util-parse-selector@2.2.5:
resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
dev: false
@ -16800,10 +16546,6 @@ packages:
react-is: 16.13.1
dev: true
/hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
dev: true
/hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@ -17088,16 +16830,6 @@ packages:
- supports-color
dev: true
/https-proxy-agent@7.0.2:
resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
dev: true
/human-signals@1.1.1:
resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
engines: {node: '>=8.12.0'}
@ -18037,7 +17769,7 @@ packages:
micromatch: 4.0.5
walker: 1.0.8
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
dev: true
/jest-leak-detector@29.5.0:
@ -18714,10 +18446,6 @@ packages:
engines: {node: '>= 8'}
dev: true
/knitwork@1.0.0:
resolution: {integrity: sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==}
dev: true
/language-subtag-registry@0.3.22:
resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==}
dev: true
@ -18945,6 +18673,7 @@ packages:
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
dev: false
/localtunnel@2.0.2:
resolution: {integrity: sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==}
@ -19481,14 +19210,6 @@ packages:
map-or-similar: 1.5.0
dev: true
/memory-fs@0.5.0:
resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==}
engines: {node: '>=4.3.0 <5.0.0 || >=5.10'}
dependencies:
errno: 0.1.8
readable-stream: 2.3.8
dev: true
/meow@8.1.2:
resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==}
engines: {node: '>=10'}
@ -19590,7 +19311,7 @@ packages:
nullthrows: 1.1.1
walker: 1.0.8
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
transitivePeerDependencies:
- supports-color
dev: true
@ -20248,6 +19969,7 @@ packages:
pathe: 1.1.1
pkg-types: 1.0.3
ufo: 1.3.1
dev: false
/modify-values@1.0.1:
resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==}
@ -20535,10 +20257,6 @@ packages:
lodash: 4.17.21
dev: true
/node-fetch-native@1.4.0:
resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==}
dev: true
/node-fetch@2.6.12:
resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
engines: {node: 4.x || >=6.0.0}
@ -20772,6 +20490,14 @@ packages:
resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==}
dev: true
/nuxi-nightly@3.9.2-1699007958.251cab5:
resolution: {integrity: sha512-KcQ8m6Ld8F+LzDi2c8OP100PIuX0i54jafXkYanRGF/kJtJILLSIVOQ7R9aiIJg4fCOm/QhK+yiU8X924MYfLA==}
engines: {node: ^14.18.0 || >=16.10.0}
hasBin: true
optionalDependencies:
fsevents: 2.3.3
dev: true
/nwsapi@2.2.2:
resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==}
dev: true
@ -21017,10 +20743,6 @@ packages:
- encoding
dev: true
/ohash@1.1.3:
resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==}
dev: true
/on-finished@2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
@ -21521,6 +21243,7 @@ packages:
/pathe@1.1.1:
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: false
/pathval@1.1.1:
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
@ -21540,10 +21263,6 @@ packages:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
dev: true
/perfect-debounce@1.0.0:
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
dev: true
/performance-now@2.1.0:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
dev: true
@ -21652,6 +21371,7 @@ packages:
jsonc-parser: 3.2.0
mlly: 1.4.2
pathe: 1.1.1
dev: false
/pkginfo@0.4.1:
resolution: {integrity: sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==}
@ -22003,12 +21723,6 @@ packages:
postcss-value-parser: 4.2.0
dev: true
/postcss-import-resolver@2.0.0:
resolution: {integrity: sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==}
dependencies:
enhanced-resolve: 4.5.0
dev: true
/postcss-import@14.1.0(postcss@8.4.19):
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
@ -23020,6 +22734,7 @@ packages:
/prr@1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
requiresBuild: true
optional: true
/pseudomap@1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
@ -23141,14 +22856,6 @@ packages:
webpack: 5.88.0(@swc/core@1.3.86)(esbuild@0.19.5)
dev: true
/rc9@2.1.1:
resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==}
dependencies:
defu: 6.1.2
destr: 2.0.1
flat: 5.0.2
dev: true
/react-colorful@5.6.1(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==}
peerDependencies:
@ -23986,7 +23693,7 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
dev: true
/rollup@3.21.0:
@ -23994,14 +23701,14 @@ packages:
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
/rollup@3.28.0:
resolution: {integrity: sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
dev: true
/rrweb-cssom@0.6.0:
@ -24216,10 +23923,6 @@ packages:
ajv-keywords: 5.1.0(ajv@8.12.0)
dev: true
/scule@1.0.0:
resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==}
dev: true
/secure-compare@3.0.1:
resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
dev: true
@ -24949,10 +24652,6 @@ packages:
resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==}
dev: false
/std-env@3.4.3:
resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
dev: true
/steno@0.4.4:
resolution: {integrity: sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==}
dependencies:
@ -25134,12 +24833,6 @@ packages:
acorn: 8.10.0
dev: false
/strip-literal@1.3.0:
resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
dependencies:
acorn: 8.10.0
dev: true
/strip-outer@2.0.0:
resolution: {integrity: sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -25450,11 +25143,6 @@ packages:
transitivePeerDependencies:
- ts-node
/tapable@1.1.3:
resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==}
engines: {node: '>=6'}
dev: true
/tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@ -26223,6 +25911,7 @@ packages:
/ufo@1.3.1:
resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
dev: false
/uglify-es@3.3.9:
resolution: {integrity: sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==}
@ -26251,15 +25940,6 @@ packages:
which-boxed-primitive: 1.0.2
dev: true
/unctx@2.3.1:
resolution: {integrity: sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==}
dependencies:
acorn: 8.10.0
estree-walker: 3.0.3
magic-string: 0.30.4
unplugin: 1.5.0
dev: true
/underscore.string@2.4.0:
resolution: {integrity: sha512-yxkabuCaIBnzfIvX3kBxQqCs0ar/bfJwDnFEHJUm/ZrRVhT3IItdRF5cZjARLzEnyQYtIUhsZ2LG2j3HidFOFQ==}
dev: true
@ -26303,24 +25983,6 @@ packages:
vfile: 5.3.7
dev: true
/unimport@3.4.0(rollup@2.79.0):
resolution: {integrity: sha512-M/lfFEgufIT156QAr/jWHLUn55kEmxBBiQsMxvRSIbquwmeJEyQYgshHDEvQDWlSJrVOOTAgnJ3FvlsrpGkanA==}
dependencies:
'@rollup/pluginutils': 5.0.5(rollup@2.79.0)
escape-string-regexp: 5.0.0
fast-glob: 3.3.1
local-pkg: 0.4.3
magic-string: 0.30.4
mlly: 1.4.2
pathe: 1.1.1
pkg-types: 1.0.3
scule: 1.0.0
strip-literal: 1.3.0
unplugin: 1.5.0
transitivePeerDependencies:
- rollup
dev: true
/union@0.5.0:
resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==}
engines: {node: '>= 0.8.0'}
@ -26467,21 +26129,6 @@ packages:
engines: {node: '>=8'}
dev: true
/untyped@1.4.0:
resolution: {integrity: sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==}
hasBin: true
dependencies:
'@babel/core': 7.22.9
'@babel/standalone': 7.23.1
'@babel/types': 7.22.5
defu: 6.1.2
jiti: 1.20.0
mri: 1.2.0
scule: 1.0.0
transitivePeerDependencies:
- supports-color
dev: true
/unzipper@0.10.11:
resolution: {integrity: sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==}
dependencies:
@ -26924,7 +26571,7 @@ packages:
rollup: 3.21.0
sass: 1.55.0
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
/vite@4.3.9(@types/node@18.16.9)(less@4.1.3)(sass@1.55.0):
resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
@ -26958,7 +26605,7 @@ packages:
rollup: 3.21.0
sass: 1.55.0
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
dev: false
/vite@4.4.7(@types/node@18.16.9)(less@4.1.3)(sass@1.64.1)(terser@5.19.2):
@ -26997,7 +26644,7 @@ packages:
sass: 1.64.1
terser: 5.19.2
optionalDependencies:
fsevents: 2.3.2
fsevents: 2.3.3
dev: true
/vitest@0.32.0(less@4.1.3)(sass@1.55.0):
@ -27979,3 +27626,7 @@ packages:
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: true
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false