@nx/react 17.0.0-beta.5 → 17.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/generators.json +3 -3
  2. package/package.json +6 -6
  3. package/plugins/storybook/index.js +5 -1
  4. package/src/generators/application/application.js +11 -13
  5. package/src/generators/application/schema.d.ts +1 -1
  6. package/src/generators/component/component.d.ts +1 -0
  7. package/src/generators/component/component.js +21 -72
  8. package/src/generators/component/{get-component-tests.d.ts → lib/get-component-tests.d.ts} +1 -1
  9. package/src/generators/component/lib/normalize-options.d.ts +3 -0
  10. package/src/generators/component/lib/normalize-options.js +48 -0
  11. package/src/generators/component/schema.d.ts +25 -0
  12. package/src/generators/component/schema.json +19 -18
  13. package/src/generators/hook/hook.d.ts +1 -0
  14. package/src/generators/hook/hook.js +44 -31
  15. package/src/generators/hook/schema.d.ts +13 -0
  16. package/src/generators/hook/schema.json +14 -7
  17. package/src/generators/host/schema.d.ts +1 -1
  18. package/src/generators/library/lib/add-linting.js +4 -4
  19. package/src/generators/library/library.js +8 -9
  20. package/src/generators/library/schema.d.ts +1 -1
  21. package/src/generators/redux/redux.d.ts +1 -0
  22. package/src/generators/redux/redux.js +28 -9
  23. package/src/generators/redux/schema.d.ts +1 -1
  24. package/src/generators/redux/schema.json +7 -3
  25. package/src/generators/remote/schema.d.ts +1 -1
  26. package/src/generators/storybook-configuration/schema.d.ts +1 -1
  27. package/src/generators/storybook-configuration/schema.json +6 -3
  28. package/src/utils/lint.d.ts +1 -1
  29. package/src/utils/lint.js +1 -1
  30. package/src/utils/testing-generators.js +2 -2
  31. package/src/generators/component/noramlized-schema.d.ts +0 -8
  32. package/src/generators/component/noramlized-schema.js +0 -2
  33. /package/src/generators/component/{get-component-tests.js → lib/get-component-tests.js} +0 -0
  34. /package/src/generators/redux/files/{__directory__/__fileName__.slice.spec.ts__tmpl__ → __fileName__.slice.spec.ts__tmpl__} +0 -0
  35. /package/src/generators/redux/files/{__directory__/__fileName__.slice.ts__tmpl__ → __fileName__.slice.ts__tmpl__} +0 -0
package/generators.json CHANGED
@@ -25,13 +25,13 @@
25
25
  "description": "Create a React library."
26
26
  },
27
27
  "component": {
28
- "factory": "./src/generators/component/component#componentGenerator",
28
+ "factory": "./src/generators/component/component#componentGeneratorInternal",
29
29
  "schema": "./src/generators/component/schema.json",
30
30
  "description": "Create a React component.",
31
31
  "aliases": ["c"]
32
32
  },
33
33
  "redux": {
34
- "factory": "./src/generators/redux/redux#reduxGenerator",
34
+ "factory": "./src/generators/redux/redux#reduxGeneratorInternal",
35
35
  "schema": "./src/generators/redux/schema.json",
36
36
  "description": "Create a Redux slice for a project.",
37
37
  "aliases": ["slice"]
@@ -61,7 +61,7 @@
61
61
  "hidden": false
62
62
  },
63
63
  "hook": {
64
- "factory": "./src/generators/hook/hook#hookGenerator",
64
+ "factory": "./src/generators/hook/hook#hookGeneratorInternal",
65
65
  "schema": "./src/generators/hook/schema.json",
66
66
  "description": "Create a hook.",
67
67
  "aliases": ["c"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/react",
3
- "version": "17.0.0-beta.5",
3
+ "version": "17.0.0-beta.8",
4
4
  "private": false,
5
5
  "description": "The React plugin for Nx contains executors and generators for managing React 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.",
6
6
  "repository": {
@@ -37,11 +37,11 @@
37
37
  "file-loader": "^6.2.0",
38
38
  "minimatch": "3.0.5",
39
39
  "tslib": "^2.3.0",
40
- "@nx/devkit": "17.0.0-beta.5",
41
- "@nx/js": "17.0.0-beta.5",
42
- "@nx/linter": "17.0.0-beta.5",
43
- "@nx/web": "17.0.0-beta.5",
44
- "@nrwl/react": "17.0.0-beta.5"
40
+ "@nx/devkit": "17.0.0-beta.8",
41
+ "@nx/js": "17.0.0-beta.8",
42
+ "@nx/eslint": "17.0.0-beta.8",
43
+ "@nx/web": "17.0.0-beta.8",
44
+ "@nrwl/react": "17.0.0-beta.8"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public"
@@ -119,7 +119,11 @@ const webpack = async (storybookWebpackConfig = {}, options) => {
119
119
  }
120
120
  const { withNx, withWeb } = require('@nx/webpack');
121
121
  const projectData = await getProjectData(options);
122
- const tsconfigPath = (0, path_1.join)(projectData.projectRoot, 'tsconfig.storybook.json');
122
+ const tsconfigPath = (0, fs_1.existsSync)((0, path_1.join)(projectData.projectRoot, 'tsconfig.storybook.json'))
123
+ ? (0, path_1.join)(projectData.projectRoot, 'tsconfig.storybook.json')
124
+ : (0, path_1.join)(projectData.projectRoot, 'tsconfig.json');
125
+ // The 'tsconfig.json' is mainly for the cypress test to be able to run
126
+ // because it will look into the cypress project dir and it will not find tsconfig.storybook.json
123
127
  fixBabelConfigurationIfNeeded(storybookWebpackConfig, projectData);
124
128
  const builderOptions = {
125
129
  ...options,
@@ -12,8 +12,8 @@ const set_defaults_1 = require("./lib/set-defaults");
12
12
  const add_styled_dependencies_1 = require("../../rules/add-styled-dependencies");
13
13
  const devkit_1 = require("@nx/devkit");
14
14
  const init_1 = require("../init/init");
15
- const linter_1 = require("@nx/linter");
16
- const lint_project_1 = require("@nx/linter/src/generators/lint-project/lint-project");
15
+ const eslint_1 = require("@nx/eslint");
16
+ const lint_project_1 = require("@nx/eslint/src/generators/lint-project/lint-project");
17
17
  const versions_1 = require("../../utils/versions");
18
18
  const install_common_dependencies_1 = require("./lib/install-common-dependencies");
19
19
  const create_ts_config_1 = require("../../utils/create-ts-config");
@@ -21,11 +21,11 @@ const add_swc_dependencies_1 = require("@nx/js/src/utils/swc/add-swc-dependencie
21
21
  const chalk = require("chalk");
22
22
  const show_possible_warnings_1 = require("./lib/show-possible-warnings");
23
23
  const add_e2e_1 = require("./lib/add-e2e");
24
- const eslint_file_1 = require("@nx/linter/src/generators/utils/eslint-file");
24
+ const eslint_file_1 = require("@nx/eslint/src/generators/utils/eslint-file");
25
25
  async function addLinting(host, options) {
26
26
  const tasks = [];
27
- if (options.linter === linter_1.Linter.EsLint) {
28
- const lintTask = await (0, linter_1.lintProjectGenerator)(host, {
27
+ if (options.linter === eslint_1.Linter.EsLint) {
28
+ const lintTask = await (0, eslint_1.lintProjectGenerator)(host, {
29
29
  linter: options.linter,
30
30
  project: options.projectName,
31
31
  tsConfigPaths: [
@@ -96,11 +96,10 @@ async function applicationGeneratorInternal(host, schema) {
96
96
  includeVitest: options.unitTestRunner === 'vitest',
97
97
  inSourceTests: options.inSourceTests,
98
98
  rollupOptionsExternal: [
99
- `'react'`,
100
- `'react-dom'`,
101
- `'react/jsx-runtime'`,
99
+ "'react'",
100
+ "'react-dom'",
101
+ "'react/jsx-runtime'",
102
102
  ],
103
- rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
104
103
  imports: [
105
104
  options.compiler === 'swc'
106
105
  ? `import react from '@vitejs/plugin-react-swc'`
@@ -145,11 +144,10 @@ async function applicationGeneratorInternal(host, schema) {
145
144
  includeVitest: true,
146
145
  inSourceTests: options.inSourceTests,
147
146
  rollupOptionsExternal: [
148
- `'react'`,
149
- `'react-dom'`,
150
- `'react/jsx-runtime'`,
147
+ "'react'",
148
+ "'react-dom'",
149
+ "'react/jsx-runtime'",
151
150
  ],
152
- rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
153
151
  imports: [
154
152
  options.compiler === 'swc'
155
153
  ? `import react from '@vitejs/plugin-react-swc'`
@@ -1,5 +1,5 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
- import type { Linter } from '@nx/linter';
2
+ import type { Linter } from '@nx/eslint';
3
3
  import type { SupportedStyles } from '../../../typings/style';
4
4
 
5
5
  export interface Schema {
@@ -1,4 +1,5 @@
1
1
  import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import { Schema } from './schema';
3
3
  export declare function componentGenerator(host: Tree, schema: Schema): Promise<GeneratorCallback>;
4
+ export declare function componentGeneratorInternal(host: Tree, schema: Schema): Promise<GeneratorCallback>;
4
5
  export default componentGenerator;
@@ -1,17 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.componentGenerator = void 0;
3
+ exports.componentGeneratorInternal = exports.componentGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
6
+ const path_1 = require("path");
5
7
  const add_styled_dependencies_1 = require("../../rules/add-styled-dependencies");
6
- const assertion_1 = require("../../utils/assertion");
7
8
  const ast_utils_1 = require("../../utils/ast-utils");
8
9
  const get_in_source_vitest_tests_template_1 = require("../../utils/get-in-source-vitest-tests-template");
9
10
  const versions_1 = require("../../utils/versions");
10
- const get_component_tests_1 = require("./get-component-tests");
11
- const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
12
- const path_1 = require("path");
11
+ const get_component_tests_1 = require("./lib/get-component-tests");
12
+ const normalize_options_1 = require("./lib/normalize-options");
13
13
  async function componentGenerator(host, schema) {
14
- const options = await normalizeOptions(host, schema);
14
+ return componentGeneratorInternal(host, {
15
+ nameAndDirectoryFormat: 'derived',
16
+ ...schema,
17
+ });
18
+ }
19
+ exports.componentGenerator = componentGenerator;
20
+ async function componentGeneratorInternal(host, schema) {
21
+ const options = await (0, normalize_options_1.normalizeOptions)(host, schema);
15
22
  createComponentFiles(host, options);
16
23
  const tasks = [];
17
24
  const styledTask = (0, add_styled_dependencies_1.addStyledModuleDependencies)(host, options);
@@ -26,11 +33,10 @@ async function componentGenerator(host, schema) {
26
33
  }
27
34
  return (0, devkit_1.runTasksInSerial)(...tasks);
28
35
  }
29
- exports.componentGenerator = componentGenerator;
36
+ exports.componentGeneratorInternal = componentGeneratorInternal;
30
37
  function createComponentFiles(host, options) {
31
- const componentDir = (0, devkit_1.joinPathFragments)(options.projectSourceRoot, options.directory);
32
38
  const componentTests = (0, get_component_tests_1.getComponentTests)(options);
33
- (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, './files'), componentDir, {
39
+ (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, './files'), options.directory, {
34
40
  ...options,
35
41
  componentTests,
36
42
  inSourceVitestTests: (0, get_in_source_vitest_tests_template_1.getInSourceVitestTestsTemplate)(componentTests),
@@ -73,72 +79,15 @@ function addExportsToBarrel(host, options) {
73
79
  const indexSource = host.read(indexFilePath, 'utf-8');
74
80
  if (indexSource !== null) {
75
81
  const indexSourceFile = tsModule.createSourceFile(indexFilePath, indexSource, tsModule.ScriptTarget.Latest, true);
76
- const changes = (0, devkit_1.applyChangesToString)(indexSource, (0, ast_utils_1.addImport)(indexSourceFile, `export * from './${options.directory}/${options.fileName}';`));
82
+ const relativePathFromIndex = getRelativeImportToFile(indexFilePath, options.filePath);
83
+ const changes = (0, devkit_1.applyChangesToString)(indexSource, (0, ast_utils_1.addImport)(indexSourceFile, `export * from '${relativePathFromIndex}';`));
77
84
  host.write(indexFilePath, changes);
78
85
  }
79
86
  }
80
87
  }
81
- async function normalizeOptions(host, options) {
82
- assertValidOptions(options);
83
- const { className, fileName } = (0, devkit_1.names)(options.name);
84
- const componentFileName = options.fileName ?? (options.pascalCaseFiles ? className : fileName);
85
- const project = (0, devkit_1.getProjects)(host).get(options.project);
86
- if (!project) {
87
- devkit_1.logger.error(`Cannot find the ${options.project} project. Please double check the project name.`);
88
- throw new Error();
89
- }
90
- const { sourceRoot: projectSourceRoot, projectType } = project;
91
- const directory = await getDirectory(host, options);
92
- const styledModule = /^(css|scss|less|none)$/.test(options.style)
93
- ? null
94
- : options.style;
95
- if (options.export && projectType === 'application') {
96
- devkit_1.logger.warn(`The "--export" option should not be used with applications and will do nothing.`);
97
- }
98
- options.classComponent = options.classComponent ?? false;
99
- options.routing = options.routing ?? false;
100
- options.globalCss = options.globalCss ?? false;
101
- options.inSourceTests = options.inSourceTests ?? false;
102
- return {
103
- ...options,
104
- directory,
105
- styledModule,
106
- hasStyles: options.style !== 'none',
107
- className,
108
- fileName: componentFileName,
109
- projectSourceRoot,
110
- };
111
- }
112
- async function getDirectory(host, options) {
113
- const genNames = (0, devkit_1.names)(options.name);
114
- const fileName = options.pascalCaseDirectory === true
115
- ? genNames.className
116
- : genNames.fileName;
117
- const workspace = (0, devkit_1.getProjects)(host);
118
- let baseDir;
119
- if (options.directory) {
120
- baseDir = options.directory;
121
- }
122
- else {
123
- baseDir =
124
- workspace.get(options.project).projectType === 'application'
125
- ? 'app'
126
- : 'lib';
127
- }
128
- return options.flat ? baseDir : (0, devkit_1.joinPathFragments)(baseDir, fileName);
129
- }
130
- function assertValidOptions(options) {
131
- (0, assertion_1.assertValidStyle)(options.style);
132
- const slashes = ['/', '\\'];
133
- slashes.forEach((s) => {
134
- if (options.name.indexOf(s) !== -1) {
135
- const [name, ...rest] = options.name.split(s).reverse();
136
- let suggestion = rest.map((x) => x.toLowerCase()).join(s);
137
- if (options.directory) {
138
- suggestion = `${options.directory}${s}${suggestion}`;
139
- }
140
- throw new Error(`Found "${s}" in the component name. Did you mean to use the --directory option (e.g. \`nx g c ${name} --directory ${suggestion}\`)?`);
141
- }
142
- });
88
+ function getRelativeImportToFile(indexPath, filePath) {
89
+ const { name, dir } = (0, path_1.parse)(filePath);
90
+ const relativeDirToTarget = (0, path_1.relative)((0, path_1.dirname)(indexPath), dir);
91
+ return `./${(0, devkit_1.joinPathFragments)(relativeDirToTarget, name)}`;
143
92
  }
144
93
  exports.default = componentGenerator;
@@ -1,2 +1,2 @@
1
- import { NormalizedSchema } from './noramlized-schema';
1
+ import { NormalizedSchema } from '../schema';
2
2
  export declare function getComponentTests(schema: NormalizedSchema): string;
@@ -0,0 +1,3 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import { NormalizedSchema, Schema } from '../schema';
3
+ export declare function normalizeOptions(tree: Tree, options: Schema): Promise<NormalizedSchema>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeOptions = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
6
+ const assertion_1 = require("../../../utils/assertion");
7
+ async function normalizeOptions(tree, options) {
8
+ (0, assertion_1.assertValidStyle)(options.style);
9
+ const { artifactName: name, directory, fileName, filePath, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(tree, {
10
+ artifactType: 'component',
11
+ callingGenerator: '@nx/react:component',
12
+ name: options.name,
13
+ directory: options.directory,
14
+ derivedDirectory: options.derivedDirectory ?? options.directory,
15
+ flat: options.flat,
16
+ nameAndDirectoryFormat: options.nameAndDirectoryFormat,
17
+ project: options.project,
18
+ fileExtension: 'tsx',
19
+ fileName: options.fileName,
20
+ pascalCaseFile: options.pascalCaseFiles,
21
+ pascalCaseDirectory: options.pascalCaseDirectory,
22
+ });
23
+ const project = (0, devkit_1.readProjectConfiguration)(tree, projectName);
24
+ const { className } = (0, devkit_1.names)(name);
25
+ const { sourceRoot: projectSourceRoot, projectType } = project;
26
+ const styledModule = /^(css|scss|less|none)$/.test(options.style)
27
+ ? null
28
+ : options.style;
29
+ if (options.export && projectType === 'application') {
30
+ devkit_1.logger.warn(`The "--export" option should not be used with applications and will do nothing.`);
31
+ }
32
+ options.classComponent = options.classComponent ?? false;
33
+ options.routing = options.routing ?? false;
34
+ options.globalCss = options.globalCss ?? false;
35
+ options.inSourceTests = options.inSourceTests ?? false;
36
+ return {
37
+ ...options,
38
+ project: projectName,
39
+ directory,
40
+ styledModule,
41
+ hasStyles: options.style !== 'none',
42
+ className,
43
+ fileName,
44
+ filePath,
45
+ projectSourceRoot,
46
+ };
47
+ }
48
+ exports.normalizeOptions = normalizeOptions;
@@ -2,19 +2,44 @@ import { SupportedStyles } from '../../../typings/style';
2
2
 
3
3
  export interface Schema {
4
4
  name: string;
5
+ /**
6
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18.
7
+ */
5
8
  project: string;
6
9
  style: SupportedStyles;
7
10
  skipTests?: boolean;
8
11
  directory?: string;
9
12
  export?: boolean;
13
+ /**
14
+ * @deprecated Provide the `name` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18.
15
+ */
10
16
  pascalCaseFiles?: boolean;
17
+ /**
18
+ * @deprecated Provide the `directory` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18.
19
+ */
11
20
  pascalCaseDirectory?: boolean;
12
21
  classComponent?: boolean;
13
22
  routing?: boolean;
14
23
  js?: boolean;
24
+ /**
25
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. This option will be removed in Nx v18.
26
+ */
15
27
  flat?: boolean;
16
28
  globalCss?: boolean;
17
29
  fileName?: string;
18
30
  inSourceTests?: boolean;
19
31
  skipFormat?: boolean;
32
+ nameAndDirectoryFormat?: 'as-provided' | 'derived';
33
+ // Used by other wrapping generators to preserve previous behavior
34
+ // e.g. @nx/next:component
35
+ derivedDirectory?: string;
36
+ }
37
+
38
+ export interface NormalizedSchema extends Schema {
39
+ projectSourceRoot: string;
40
+ fileName: string;
41
+ filePath: string;
42
+ className: string;
43
+ styledModule: null | string;
44
+ hasStyles: boolean;
20
45
  }
@@ -5,16 +5,6 @@
5
5
  "title": "Create a React Component",
6
6
  "description": "Create a React Component for Nx.",
7
7
  "type": "object",
8
- "examples": [
9
- {
10
- "command": "nx g component my-component --project=mylib",
11
- "description": "Generate a component in the `mylib` library"
12
- },
13
- {
14
- "command": "nx g component my-component --project=mylib --classComponent",
15
- "description": "Generate a class component in the `mylib` library"
16
- }
17
- ],
18
8
  "properties": {
19
9
  "project": {
20
10
  "type": "string",
@@ -23,8 +13,7 @@
23
13
  "$default": {
24
14
  "$source": "projectName"
25
15
  },
26
- "x-prompt": "What is the name of the project for this component?",
27
- "x-priority": "important"
16
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18."
28
17
  },
29
18
  "name": {
30
19
  "type": "string",
@@ -45,7 +34,10 @@
45
34
  "message": "Which stylesheet format would you like to use?",
46
35
  "type": "list",
47
36
  "items": [
48
- { "value": "css", "label": "CSS" },
37
+ {
38
+ "value": "css",
39
+ "label": "CSS"
40
+ },
49
41
  {
50
42
  "value": "scss",
51
43
  "label": "SASS(.scss) [ http://sass-lang.com ]"
@@ -86,14 +78,20 @@
86
78
  },
87
79
  "directory": {
88
80
  "type": "string",
89
- "description": "Create the component under this directory (can be nested).",
81
+ "description": "The directory at which to create the component file. When `--nameAndDirectoryFormat=as-provided`, it will be relative to the current working directory. Otherwise, it will be relative to the project root.",
90
82
  "alias": "dir",
91
83
  "x-priority": "important"
92
84
  },
85
+ "nameAndDirectoryFormat": {
86
+ "description": "Whether to generate the component in the directory as provided, relative to the current working directory and ignoring the project (`as-provided`) or generate it using the project and directory relative to the workspace root (`derived`).",
87
+ "type": "string",
88
+ "enum": ["as-provided", "derived"]
89
+ },
93
90
  "flat": {
94
91
  "type": "boolean",
95
92
  "description": "Create component at the source root rather than its own directory.",
96
- "default": false
93
+ "default": false,
94
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. This option will be removed in Nx v18."
97
95
  },
98
96
  "export": {
99
97
  "type": "boolean",
@@ -106,13 +104,15 @@
106
104
  "type": "boolean",
107
105
  "description": "Use pascal case component file name (e.g. `App.tsx`).",
108
106
  "alias": "P",
109
- "default": false
107
+ "default": false,
108
+ "x-deprecated": "Provide the `name` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18."
110
109
  },
111
110
  "pascalCaseDirectory": {
112
111
  "type": "boolean",
113
112
  "description": "Use pascal case directory name (e.g. `App/App.tsx`).",
114
113
  "alias": "R",
115
- "default": false
114
+ "default": false,
115
+ "x-deprecated": "Provide the `directory` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18."
116
116
  },
117
117
  "classComponent": {
118
118
  "type": "boolean",
@@ -145,5 +145,6 @@
145
145
  "x-priority": "internal"
146
146
  }
147
147
  },
148
- "required": ["name", "project"]
148
+ "required": ["name"],
149
+ "examplesFile": "../../../docs/component-examples.md"
149
150
  }
@@ -1,4 +1,5 @@
1
1
  import { Tree } from '@nx/devkit';
2
2
  import { Schema } from './schema';
3
3
  export declare function hookGenerator(host: Tree, schema: Schema): Promise<void>;
4
+ export declare function hookGeneratorInternal(host: Tree, schema: Schema): Promise<void>;
4
5
  export default hookGenerator;
@@ -1,21 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hookGenerator = void 0;
3
+ exports.hookGeneratorInternal = exports.hookGenerator = void 0;
4
4
  // TODO(jack): Remove inline renderHook function when RTL releases with its own version
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const ast_utils_1 = require("../../utils/ast-utils");
7
7
  const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
8
8
  const path_1 = require("path");
9
+ const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
9
10
  async function hookGenerator(host, schema) {
11
+ return hookGeneratorInternal(host, {
12
+ nameAndDirectoryFormat: 'derived',
13
+ ...schema,
14
+ });
15
+ }
16
+ exports.hookGenerator = hookGenerator;
17
+ async function hookGeneratorInternal(host, schema) {
10
18
  const options = await normalizeOptions(host, schema);
11
19
  createFiles(host, options);
12
20
  addExportsToBarrel(host, options);
13
21
  return await (0, devkit_1.formatFiles)(host);
14
22
  }
15
- exports.hookGenerator = hookGenerator;
23
+ exports.hookGeneratorInternal = hookGeneratorInternal;
16
24
  function createFiles(host, options) {
17
- const hookDir = (0, devkit_1.joinPathFragments)(options.projectSourceRoot, options.directory);
18
- (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, './files'), hookDir, {
25
+ (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, './files'), options.directory, {
19
26
  ...options,
20
27
  tmpl: '',
21
28
  });
@@ -51,7 +58,20 @@ function addExportsToBarrel(host, options) {
51
58
  }
52
59
  async function normalizeOptions(host, options) {
53
60
  assertValidOptions(options);
54
- let base = options.name;
61
+ const { artifactName: name, directory: _directory, fileName: _fileName, nameAndDirectoryFormat, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(host, {
62
+ artifactType: 'hook',
63
+ callingGenerator: '@nx/react:hook',
64
+ name: options.name,
65
+ directory: options.directory,
66
+ derivedDirectory: options.directory,
67
+ flat: options.flat,
68
+ nameAndDirectoryFormat: options.nameAndDirectoryFormat,
69
+ project: options.project,
70
+ fileExtension: 'tsx',
71
+ pascalCaseFile: options.pascalCaseFiles,
72
+ pascalCaseDirectory: options.pascalCaseDirectory,
73
+ });
74
+ let base = _fileName;
55
75
  if (base.startsWith('use-')) {
56
76
  base = base.substring(4);
57
77
  }
@@ -59,21 +79,32 @@ async function normalizeOptions(host, options) {
59
79
  base = base.substring(3);
60
80
  }
61
81
  const { className, fileName } = (0, devkit_1.names)(base);
62
- const hookFilename = options.pascalCaseFiles
63
- ? 'use'.concat(className)
64
- : 'use-'.concat(fileName);
82
+ // If using `as-provided` file and directory, then don't normalize.
83
+ // Otherwise, support legacy behavior of prefixing filename with `use-`.
84
+ const hookFilename = nameAndDirectoryFormat === 'as-provided'
85
+ ? fileName
86
+ : options.pascalCaseFiles
87
+ ? 'use'.concat(className)
88
+ : 'use-'.concat(fileName);
65
89
  const hookName = 'use'.concat(className);
66
90
  const hookTypeName = 'Use'.concat(className);
67
91
  const project = (0, devkit_1.getProjects)(host).get(options.project);
68
- if (!project) {
69
- devkit_1.logger.error(`Cannot find the ${options.project} project. Please double check the project name.`);
70
- throw new Error();
71
- }
72
92
  const { sourceRoot: projectSourceRoot, projectType } = project;
73
- const directory = await getDirectory(host, options, base);
74
93
  if (options.export && projectType === 'application') {
75
94
  devkit_1.logger.warn(`The "--export" option should not be used with applications and will do nothing.`);
76
95
  }
96
+ // Support legacy behavior of derived directory to prefix with `use-`.
97
+ let directory = _directory;
98
+ if (nameAndDirectoryFormat === 'derived') {
99
+ const parts = directory.split('/');
100
+ parts.pop();
101
+ if (!options.flat) {
102
+ parts.push(options.pascalCaseDirectory
103
+ ? 'use'.concat(className)
104
+ : 'use-'.concat(fileName));
105
+ }
106
+ directory = parts.join('/');
107
+ }
77
108
  return {
78
109
  ...options,
79
110
  directory,
@@ -83,24 +114,6 @@ async function normalizeOptions(host, options) {
83
114
  projectSourceRoot,
84
115
  };
85
116
  }
86
- async function getDirectory(host, options, baseHookName) {
87
- const { className, fileName } = (0, devkit_1.names)(baseHookName);
88
- const hookFileName = options.pascalCaseDirectory === true
89
- ? 'use'.concat(className)
90
- : 'use-'.concat(fileName);
91
- const workspace = (0, devkit_1.getProjects)(host);
92
- let baseDir;
93
- if (options.directory) {
94
- baseDir = options.directory;
95
- }
96
- else {
97
- baseDir =
98
- workspace.get(options.project).projectType === 'application'
99
- ? 'app'
100
- : 'lib';
101
- }
102
- return options.flat ? baseDir : (0, devkit_1.joinPathFragments)(baseDir, hookFileName);
103
- }
104
117
  function assertValidOptions(options) {
105
118
  const slashes = ['/', '\\'];
106
119
  slashes.forEach((s) => {
@@ -1,11 +1,24 @@
1
1
  export interface Schema {
2
2
  name: string;
3
+ /**
4
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18.
5
+ */
3
6
  project: string;
4
7
  skipTests?: boolean;
5
8
  directory?: string;
6
9
  export?: boolean;
10
+ /**
11
+ * @deprecated Provide the `name` option instead and use the `as-provided` format. This option will be removed in Nx v18.
12
+ */
7
13
  pascalCaseFiles?: boolean;
14
+ /**
15
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. This option will be removed in Nx v18.
16
+ */
8
17
  pascalCaseDirectory?: boolean;
18
+ /**
19
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. This option will be removed in Nx v18.
20
+ */
9
21
  flat?: boolean;
10
22
  js?: boolean;
23
+ nameAndDirectoryFormat?: 'as-provided' | 'derived';
11
24
  }
@@ -19,8 +19,7 @@
19
19
  "$default": {
20
20
  "$source": "projectName"
21
21
  },
22
- "x-prompt": "What is the name of the project for this hook?",
23
- "x-priority": "important"
22
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18."
24
23
  },
25
24
  "name": {
26
25
  "type": "string",
@@ -45,13 +44,19 @@
45
44
  },
46
45
  "directory": {
47
46
  "type": "string",
48
- "description": "Create the hook under this directory (can be nested).",
47
+ "description": "The directory at which to create the hook file. When `--nameAndDirectoryFormat=as-provided`, it will be relative to the current working directory. Otherwise, it will be relative to the project root.",
49
48
  "x-priority": "important"
50
49
  },
50
+ "nameAndDirectoryFormat": {
51
+ "description": "Whether to generate the component in the directory as provided, relative to the current working directory and ignoring the project (`as-provided`) or generate it using the project and directory relative to the workspace root (`derived`).",
52
+ "type": "string",
53
+ "enum": ["as-provided", "derived"]
54
+ },
51
55
  "flat": {
52
56
  "type": "boolean",
53
57
  "description": "Create hook at the source root rather than its own directory.",
54
- "default": false
58
+ "default": false,
59
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. It will be removed in Nx v18."
55
60
  },
56
61
  "export": {
57
62
  "type": "boolean",
@@ -64,14 +69,16 @@
64
69
  "type": "boolean",
65
70
  "description": "Use pascal case hook file name (e.g. `useHook.ts`).",
66
71
  "alias": "P",
67
- "default": false
72
+ "default": false,
73
+ "x-deprecated": "Provide the `name` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18."
68
74
  },
69
75
  "pascalCaseDirectory": {
70
76
  "type": "boolean",
71
77
  "description": "Use pascal case directory name (e.g. `useHook/useHook.ts`).",
72
78
  "alias": "R",
73
- "default": false
79
+ "default": false,
80
+ "x-deprecated": "Provide the `directory` in pascal-case and use the `as-provided` format. This option will be removed in Nx v18."
74
81
  }
75
82
  },
76
- "required": ["name", "project"]
83
+ "required": ["name"]
77
84
  }
@@ -1,5 +1,5 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
- import type { Linter } from '@nx/linter';
2
+ import type { Linter } from '@nx/eslint';
3
3
  import type { SupportedStyles } from '../../../typings';
4
4
 
5
5
  export interface Schema {
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addLinting = void 0;
4
- const linter_1 = require("@nx/linter");
4
+ const eslint_1 = require("@nx/eslint");
5
5
  const path_1 = require("nx/src/utils/path");
6
6
  const devkit_1 = require("@nx/devkit");
7
7
  const lint_1 = require("../../../utils/lint");
8
- const eslint_file_1 = require("@nx/linter/src/generators/utils/eslint-file");
8
+ const eslint_file_1 = require("@nx/eslint/src/generators/utils/eslint-file");
9
9
  async function addLinting(host, options) {
10
- if (options.linter === linter_1.Linter.EsLint) {
11
- const lintTask = await (0, linter_1.lintProjectGenerator)(host, {
10
+ if (options.linter === eslint_1.Linter.EsLint) {
11
+ const lintTask = await (0, eslint_1.lintProjectGenerator)(host, {
12
12
  linter: options.linter,
13
13
  project: options.name,
14
14
  tsConfigPaths: [
@@ -69,11 +69,10 @@ async function libraryGeneratorInternal(host, schema) {
69
69
  includeVitest: options.unitTestRunner === 'vitest',
70
70
  inSourceTests: options.inSourceTests,
71
71
  rollupOptionsExternal: [
72
- `'react'`,
73
- `'react-dom'`,
74
- `'react/jsx-runtime'`,
72
+ "'react'",
73
+ "'react-dom'",
74
+ "'react/jsx-runtime'",
75
75
  ],
76
- rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
77
76
  imports: [
78
77
  options.compiler === 'swc'
79
78
  ? `import react from '@vitejs/plugin-react-swc'`
@@ -124,18 +123,18 @@ async function libraryGeneratorInternal(host, schema) {
124
123
  includeVitest: true,
125
124
  inSourceTests: options.inSourceTests,
126
125
  rollupOptionsExternal: [
127
- `'react'`,
128
- `'react-dom'`,
129
- `'react/jsx-runtime'`,
126
+ "'react'",
127
+ "'react-dom'",
128
+ "'react/jsx-runtime'",
130
129
  ],
131
- rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
132
130
  imports: [`import react from '@vitejs/plugin-react'`],
133
131
  plugins: ['react()'],
134
132
  }, true);
135
133
  }
136
134
  if (options.component) {
137
135
  const componentTask = await (0, component_1.default)(host, {
138
- name: options.fileName,
136
+ nameAndDirectoryFormat: 'as-provided',
137
+ name: (0, devkit_1.joinPathFragments)(options.projectRoot, 'src/lib', options.fileName),
139
138
  project: options.name,
140
139
  flat: true,
141
140
  style: options.style,
@@ -1,5 +1,5 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
- import type { Linter } from '@nx/linter';
2
+ import type { Linter } from '@nx/eslint';
3
3
  import type { SupportedStyles } from '../../../typings/style';
4
4
 
5
5
  export interface Schema {
@@ -1,4 +1,5 @@
1
1
  import { Schema } from './schema';
2
2
  import { Tree } from '@nx/devkit';
3
3
  export declare function reduxGenerator(host: Tree, schema: Schema): Promise<import("@nx/devkit").GeneratorCallback>;
4
+ export declare function reduxGeneratorInternal(host: Tree, schema: Schema): Promise<import("@nx/devkit").GeneratorCallback>;
4
5
  export default reduxGenerator;
@@ -1,15 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reduxGenerator = void 0;
3
+ exports.reduxGeneratorInternal = exports.reduxGenerator = void 0;
4
4
  const path = require("path");
5
5
  const ast_utils_1 = require("../../utils/ast-utils");
6
6
  const versions_1 = require("../../utils/versions");
7
7
  const devkit_1 = require("@nx/devkit");
8
8
  const js_1 = require("@nx/js");
9
9
  const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
10
+ const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
10
11
  let tsModule;
11
12
  async function reduxGenerator(host, schema) {
12
- const options = normalizeOptions(host, schema);
13
+ return reduxGeneratorInternal(host, {
14
+ nameAndDirectoryFormat: 'derived',
15
+ ...schema,
16
+ });
17
+ }
18
+ exports.reduxGenerator = reduxGenerator;
19
+ async function reduxGeneratorInternal(host, schema) {
20
+ const options = await normalizeOptions(host, schema);
13
21
  generateReduxFiles(host, options);
14
22
  addExportsToBarrel(host, options);
15
23
  const installTask = addReduxPackageDependencies(host);
@@ -18,9 +26,9 @@ async function reduxGenerator(host, schema) {
18
26
  await (0, devkit_1.formatFiles)(host);
19
27
  return installTask;
20
28
  }
21
- exports.reduxGenerator = reduxGenerator;
29
+ exports.reduxGeneratorInternal = reduxGeneratorInternal;
22
30
  function generateReduxFiles(host, options) {
23
- (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, './files'), options.filesPath, {
31
+ (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, './files'), options.directory, {
24
32
  ...options,
25
33
  tmpl: '',
26
34
  });
@@ -76,12 +84,23 @@ function updateReducerConfiguration(host, options) {
76
84
  }));
77
85
  host.write(options.appMainFilePath, changes);
78
86
  }
79
- function normalizeOptions(host, options) {
87
+ async function normalizeOptions(host, options) {
88
+ const { artifactName: name, directory, fileName, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(host, {
89
+ artifactType: 'slice',
90
+ callingGenerator: '@nx/react:redux',
91
+ name: options.name,
92
+ directory: options.directory,
93
+ derivedDirectory: options.directory,
94
+ flat: true,
95
+ nameAndDirectoryFormat: options.nameAndDirectoryFormat,
96
+ project: options.project,
97
+ fileExtension: 'tsx',
98
+ });
80
99
  let appProjectSourcePath;
81
100
  let appMainFilePath;
82
- const extraNames = (0, devkit_1.names)(options.name);
101
+ const extraNames = (0, devkit_1.names)(name);
83
102
  const projects = (0, devkit_1.getProjects)(host);
84
- const project = projects.get(options.project);
103
+ const project = projects.get(projectName);
85
104
  const { sourceRoot, projectType } = project;
86
105
  const tsConfigJson = (0, devkit_1.readJson)(host, (0, js_1.getRootTsConfigPathInTree)(host));
87
106
  const tsPaths = tsConfigJson.compilerOptions
@@ -111,14 +130,14 @@ function normalizeOptions(host, options) {
111
130
  return {
112
131
  ...options,
113
132
  ...extraNames,
133
+ fileName,
114
134
  constantName: (0, devkit_1.names)(options.name).constantName.toUpperCase(),
115
- directory: (0, devkit_1.names)(options.directory ?? '').fileName,
135
+ directory,
116
136
  projectType,
117
137
  projectSourcePath: sourceRoot,
118
138
  projectModulePath: modulePath,
119
139
  appProjectSourcePath,
120
140
  appMainFilePath,
121
- filesPath: (0, devkit_1.joinPathFragments)(sourceRoot, projectType === 'application' ? 'app' : 'lib'),
122
141
  };
123
142
  }
124
143
  exports.default = reduxGenerator;
@@ -4,6 +4,7 @@ export interface Schema {
4
4
  directory?: string;
5
5
  appProject?: string;
6
6
  js?: string;
7
+ nameAndDirectoryFormat?: 'as-provided' | 'derived';
7
8
  }
8
9
 
9
10
  interface NormalizedSchema extends Schema {
@@ -12,7 +13,6 @@ interface NormalizedSchema extends Schema {
12
13
  projectModulePath: string;
13
14
  appProjectSourcePath: string;
14
15
  appMainFilePath: string;
15
- filesPath: string;
16
16
  className: string;
17
17
  constantName: string;
18
18
  propertyName: string;
@@ -22,16 +22,20 @@
22
22
  "$default": {
23
23
  "$source": "projectName"
24
24
  },
25
- "x-prompt": "What is the name of the project for this slice?",
26
- "x-priority": "important"
25
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18."
27
26
  },
28
27
  "directory": {
29
28
  "type": "string",
30
29
  "alias": "dir",
31
30
  "default": "",
32
- "description": "The name of the folder used to contain/group the generated Redux files.",
31
+ "description": "The directory at which to create the Redux files. When `--nameAndDirectoryFormat=as-provided`, it will be relative to the current working directory. Otherwise, it will be relative to the project root.",
33
32
  "x-priority": "important"
34
33
  },
34
+ "nameAndDirectoryFormat": {
35
+ "description": "Whether to generate the component in the directory as provided, relative to the current working directory and ignoring the project (`as-provided`) or generate it using the project and directory relative to the workspace root (`derived`).",
36
+ "type": "string",
37
+ "enum": ["as-provided", "derived"]
38
+ },
35
39
  "appProject": {
36
40
  "type": "string",
37
41
  "description": "The application project to add the slice to.",
@@ -1,5 +1,5 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
- import type { Linter } from '@nx/linter';
2
+ import type { Linter } from '@nx/eslint';
3
3
  import type { SupportedStyles } from '../../../typings';
4
4
  import type { NormalizedSchema as ApplicationNormalizedSchema } from '../application/schema';
5
5
 
@@ -1,4 +1,4 @@
1
- import { Linter } from '@nx/linter';
1
+ import { Linter } from '@nx/eslint';
2
2
 
3
3
  export interface StorybookConfigureSchema {
4
4
  name: string;
@@ -28,7 +28,8 @@
28
28
  },
29
29
  "configureCypress": {
30
30
  "type": "boolean",
31
- "description": "Run the cypress-configure generator."
31
+ "description": "Run the cypress-configure generator.",
32
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
32
33
  },
33
34
  "generateStories": {
34
35
  "type": "boolean",
@@ -39,7 +40,8 @@
39
40
  },
40
41
  "generateCypressSpecs": {
41
42
  "type": "boolean",
42
- "description": "Automatically generate test files in the Cypress E2E app generated by the `cypress-configure` generator."
43
+ "description": "Automatically generate test files in the Cypress E2E app generated by the `cypress-configure` generator.",
44
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
43
45
  },
44
46
  "configureStaticServe": {
45
47
  "type": "boolean",
@@ -50,7 +52,8 @@
50
52
  },
51
53
  "cypressDirectory": {
52
54
  "type": "string",
53
- "description": "A directory where the Cypress project will be placed. Placed at the root by default."
55
+ "description": "A directory where the Cypress project will be placed. Placed at the root by default.",
56
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
54
57
  },
55
58
  "js": {
56
59
  "type": "boolean",
@@ -9,7 +9,7 @@ export declare const extraEslintDependencies: {
9
9
  };
10
10
  };
11
11
  /**
12
- * @deprecated Use `addExtendsToLintConfig` from `@nx/linter` instead.
12
+ * @deprecated Use `addExtendsToLintConfig` from `@nx/eslint` instead.
13
13
  */
14
14
  export declare const extendReactEslintJson: (json: Linter.Config) => {
15
15
  ignorePatterns?: string | string[];
package/src/utils/lint.js CHANGED
@@ -12,7 +12,7 @@ exports.extraEslintDependencies = {
12
12
  },
13
13
  };
14
14
  /**
15
- * @deprecated Use `addExtendsToLintConfig` from `@nx/linter` instead.
15
+ * @deprecated Use `addExtendsToLintConfig` from `@nx/eslint` instead.
16
16
  */
17
17
  const extendReactEslintJson = (json) => {
18
18
  const { extends: pluginExtends, ...config } = json;
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLib = exports.createApp = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const application_1 = require("../generators/application/application");
6
- const linter_1 = require("@nx/linter");
6
+ const eslint_1 = require("@nx/eslint");
7
7
  async function createApp(tree, appName) {
8
8
  await (0, application_1.default)(tree, {
9
9
  e2eTestRunner: 'none',
10
- linter: linter_1.Linter.EsLint,
10
+ linter: eslint_1.Linter.EsLint,
11
11
  skipFormat: true,
12
12
  style: 'css',
13
13
  unitTestRunner: 'none',
@@ -1,8 +0,0 @@
1
- import { Schema } from './schema';
2
- export interface NormalizedSchema extends Schema {
3
- projectSourceRoot: string;
4
- fileName: string;
5
- className: string;
6
- styledModule: null | string;
7
- hasStyles: boolean;
8
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });