@nx/devkit 21.0.0-beta.0 → 21.0.0-beta.10
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.
- package/package.json +1 -1
- package/src/executors/read-target-options.js +1 -1
- package/src/generators/format-files.js +7 -0
- package/src/generators/project-name-and-root-utils.d.ts +5 -2
- package/src/generators/project-name-and-root-utils.js +34 -45
- package/src/generators/target-defaults-utils.js +1 -1
- package/src/generators/update-ts-configs-to-js.js +2 -2
- package/src/utils/calculate-hash-for-create-nodes.d.ts +1 -0
- package/src/utils/calculate-hash-for-create-nodes.js +13 -0
- package/src/utils/package-json.js +10 -6
- package/src/utils/replace-package.js +1 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/devkit",
|
3
|
-
"version": "21.0.0-beta.
|
3
|
+
"version": "21.0.0-beta.10",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by leveraging the Nx Devkit](https://nx.dev/extending-nx/intro/getting-started) on our docs.",
|
6
6
|
"repository": {
|
@@ -17,7 +17,7 @@ function readTargetOptions({ project, target, configuration }, context) {
|
|
17
17
|
if (!targetConfiguration) {
|
18
18
|
throw new Error(`Unable to find target ${target} for project ${project}`);
|
19
19
|
}
|
20
|
-
const [nodeModule, executorName] = targetConfiguration.executor
|
20
|
+
const [nodeModule, executorName] = (0, devkit_internals_1.parseExecutor)(targetConfiguration.executor);
|
21
21
|
const { schema } = (0, devkit_internals_1.getExecutorInformation)(nodeModule, executorName, context.root, context.projectsConfigurations?.projects);
|
22
22
|
const defaultProject = (0, devkit_internals_1.calculateDefaultProjectName)(context.cwd, context.root, { version: 2, projects: context.projectsConfigurations.projects }, context.nxJsonConfiguration);
|
23
23
|
return (0, devkit_internals_1.combineOptionsForExecutor)({}, configuration ?? targetConfiguration.defaultConfiguration ?? '', targetConfiguration, schema, defaultProject, (0, path_1.relative)(context.root, context.cwd));
|
@@ -18,6 +18,13 @@ async function formatFiles(tree, options = {
|
|
18
18
|
let prettier;
|
19
19
|
try {
|
20
20
|
prettier = await Promise.resolve().then(() => require('prettier'));
|
21
|
+
/**
|
22
|
+
* Even after we discovered prettier in node_modules, we need to be sure that the user is intentionally using prettier
|
23
|
+
* before proceeding to format with it.
|
24
|
+
*/
|
25
|
+
if (!(0, devkit_internals_1.isUsingPrettierInTree)(tree)) {
|
26
|
+
return;
|
27
|
+
}
|
21
28
|
}
|
22
29
|
catch { }
|
23
30
|
if (options.sortRootTsconfigPaths) {
|
@@ -31,8 +31,11 @@ export type ProjectNameAndRootOptions = {
|
|
31
31
|
/**
|
32
32
|
* Normalized import path for the project.
|
33
33
|
*/
|
34
|
-
importPath
|
34
|
+
importPath: string;
|
35
35
|
};
|
36
36
|
export declare function determineProjectNameAndRootOptions(tree: Tree, options: ProjectGenerationOptions): Promise<ProjectNameAndRootOptions>;
|
37
37
|
export declare function resolveImportPath(tree: Tree, projectName: string, projectRoot: string): string;
|
38
|
-
export declare function
|
38
|
+
export declare function ensureRootProjectName(options: {
|
39
|
+
directory: string;
|
40
|
+
name?: string;
|
41
|
+
}, projectType: 'application' | 'library'): Promise<void>;
|
@@ -2,16 +2,20 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.determineProjectNameAndRootOptions = determineProjectNameAndRootOptions;
|
4
4
|
exports.resolveImportPath = resolveImportPath;
|
5
|
-
exports.
|
5
|
+
exports.ensureRootProjectName = ensureRootProjectName;
|
6
6
|
const enquirer_1 = require("enquirer");
|
7
7
|
const devkit_exports_1 = require("nx/src/devkit-exports");
|
8
8
|
const path_1 = require("path");
|
9
9
|
async function determineProjectNameAndRootOptions(tree, options) {
|
10
|
-
|
10
|
+
// root projects must provide name option
|
11
|
+
if (options.directory === '.' && !options.name) {
|
12
|
+
throw new Error(`When generating a root project, you must also specify the name option.`);
|
13
|
+
}
|
11
14
|
const directory = (0, devkit_exports_1.normalizePath)(options.directory);
|
12
15
|
const name = options.name ??
|
13
16
|
directory.match(/(@[^@/]+(\/[^@/]+)+)/)?.[1] ??
|
14
17
|
directory.substring(directory.lastIndexOf('/') + 1);
|
18
|
+
validateOptions(options.name, name, options.directory);
|
15
19
|
let projectSimpleName;
|
16
20
|
let projectFileName;
|
17
21
|
if (name.startsWith('@')) {
|
@@ -44,11 +48,10 @@ async function determineProjectNameAndRootOptions(tree, options) {
|
|
44
48
|
projectRoot = (0, devkit_exports_1.joinPathFragments)(relativeCwd, name);
|
45
49
|
}
|
46
50
|
}
|
47
|
-
|
48
|
-
|
49
|
-
importPath =
|
50
|
-
options.importPath ?? resolveImportPath(tree, name, projectRoot);
|
51
|
+
if (projectRoot.startsWith('..')) {
|
52
|
+
throw new Error(`The resolved project root "${projectRoot}" is outside of the workspace root "${devkit_exports_1.workspaceRoot}".`);
|
51
53
|
}
|
54
|
+
const importPath = options.importPath ?? resolveImportPath(tree, name, projectRoot);
|
52
55
|
return {
|
53
56
|
projectName: name,
|
54
57
|
names: {
|
@@ -74,50 +77,36 @@ function resolveImportPath(tree, projectName, projectRoot) {
|
|
74
77
|
}
|
75
78
|
return importPath;
|
76
79
|
}
|
77
|
-
async function
|
78
|
-
if (!options.name) {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
message: `What do you want to name the ${projectType}?`,
|
84
|
-
}).then(({ name }) => (options.name = name));
|
85
|
-
}
|
86
|
-
const { projectName } = await determineProjectNameAndRootOptions(tree, {
|
87
|
-
...options,
|
88
|
-
projectType,
|
80
|
+
async function ensureRootProjectName(options, projectType) {
|
81
|
+
if (!options.name && options.directory === '.' && getRelativeCwd() === '') {
|
82
|
+
const result = await (0, enquirer_1.prompt)({
|
83
|
+
type: 'input',
|
84
|
+
name: 'name',
|
85
|
+
message: `What do you want to name the ${projectType}?`,
|
89
86
|
});
|
90
|
-
options.name =
|
87
|
+
options.name = result.name;
|
91
88
|
}
|
92
89
|
}
|
93
|
-
function validateOptions(
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
90
|
+
function validateOptions(providedName, derivedName, directory) {
|
91
|
+
/**
|
92
|
+
* The provided name and the derived name from the provided directory must match one of two cases:
|
93
|
+
*
|
94
|
+
* 1. Valid npm package names (e.g., '@scope/name' or 'name').
|
95
|
+
* 2. Names starting with a letter and can contain any character except whitespace and ':'.
|
96
|
+
*
|
97
|
+
* The second case is to support the legacy behavior (^[a-zA-Z].*$) with the difference
|
98
|
+
* that it doesn't allow the ":" character. It was wrong to allow it because it would
|
99
|
+
* conflict with the notation for tasks.
|
100
|
+
*/
|
101
|
+
const pattern = '(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$';
|
102
|
+
const validationRegex = new RegExp(pattern);
|
103
|
+
if (providedName) {
|
104
|
+
if (!validationRegex.test(providedName)) {
|
105
|
+
throw new Error(`The name should match the pattern "${pattern}". The provided value "${providedName}" does not match.`);
|
100
106
|
}
|
101
107
|
}
|
102
|
-
else {
|
103
|
-
|
104
|
-
* Both directory and name (if present) must match one of two cases:
|
105
|
-
*
|
106
|
-
* 1. Valid npm package names (e.g., '@scope/name' or 'name').
|
107
|
-
* 2. Names starting with a letter and can contain any character except whitespace and ':'.
|
108
|
-
*
|
109
|
-
* The second case is to support the legacy behavior (^[a-zA-Z].*$) with the difference
|
110
|
-
* that it doesn't allow the ":" character. It was wrong to allow it because it would
|
111
|
-
* conflict with the notation for tasks.
|
112
|
-
*/
|
113
|
-
const pattern = '(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$';
|
114
|
-
const validationRegex = new RegExp(pattern);
|
115
|
-
if (options.name && !validationRegex.test(options.name)) {
|
116
|
-
throw new Error(`The name should match the pattern "${pattern}". The provided value "${options.name}" does not match.`);
|
117
|
-
}
|
118
|
-
if (!validationRegex.test(options.directory)) {
|
119
|
-
throw new Error(`The directory should match the pattern "${pattern}". The provided value "${options.directory}" does not match.`);
|
120
|
-
}
|
108
|
+
else if (!validationRegex.test(derivedName)) {
|
109
|
+
throw new Error(`The derived name from the provided directory should match the pattern "${pattern}". The derived name "${derivedName}" from the provided value "${directory}" does not match.`);
|
121
110
|
}
|
122
111
|
}
|
123
112
|
function getImportPath(npmScope, name) {
|
@@ -46,7 +46,7 @@ async function addE2eCiTargetDefaults(tree, e2ePlugin, buildTarget, pathToE2ECon
|
|
46
46
|
const ciTargetName = typeof foundPluginForApplication === 'string'
|
47
47
|
? 'e2e-ci'
|
48
48
|
: foundPluginForApplication.options?.ciTargetName ?? 'e2e-ci';
|
49
|
-
const ciTargetNameGlob = `${ciTargetName}
|
49
|
+
const ciTargetNameGlob = `${ciTargetName}--**/**`;
|
50
50
|
nxJson.targetDefaults ??= {};
|
51
51
|
const e2eCiTargetDefaults = nxJson.targetDefaults[ciTargetNameGlob];
|
52
52
|
if (!e2eCiTargetDefaults) {
|
@@ -26,9 +26,9 @@ function updateTsConfigsToJs(tree, options) {
|
|
26
26
|
}
|
27
27
|
if (updateConfigPath) {
|
28
28
|
(0, devkit_exports_1.updateJson)(tree, updateConfigPath, (json) => {
|
29
|
-
json.include = uniq([...json.include, 'src/**/*.js']);
|
29
|
+
json.include = uniq([...(json.include ?? []), 'src/**/*.js']);
|
30
30
|
json.exclude = uniq([
|
31
|
-
...json.exclude,
|
31
|
+
...(json.exclude ?? []),
|
32
32
|
'src/**/*.spec.js',
|
33
33
|
'src/**/*.test.js',
|
34
34
|
]);
|
@@ -1,2 +1,3 @@
|
|
1
1
|
import { CreateNodesContext, CreateNodesContextV2 } from 'nx/src/devkit-exports';
|
2
2
|
export declare function calculateHashForCreateNodes(projectRoot: string, options: object, context: CreateNodesContext | CreateNodesContextV2, additionalGlobs?: string[]): Promise<string>;
|
3
|
+
export declare function calculateHashesForCreateNodes(projectRoots: string[], options: object, context: CreateNodesContext | CreateNodesContextV2, additionalGlobs?: string[][]): Promise<string[]>;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.calculateHashForCreateNodes = calculateHashForCreateNodes;
|
4
|
+
exports.calculateHashesForCreateNodes = calculateHashesForCreateNodes;
|
4
5
|
const path_1 = require("path");
|
5
6
|
const devkit_exports_1 = require("nx/src/devkit-exports");
|
6
7
|
const devkit_internals_1 = require("nx/src/devkit-internals");
|
@@ -13,3 +14,15 @@ async function calculateHashForCreateNodes(projectRoot, options, context, additi
|
|
13
14
|
(0, devkit_internals_1.hashObject)(options),
|
14
15
|
]);
|
15
16
|
}
|
17
|
+
async function calculateHashesForCreateNodes(projectRoots, options, context, additionalGlobs = []) {
|
18
|
+
if (additionalGlobs.length &&
|
19
|
+
additionalGlobs.length !== projectRoots.length) {
|
20
|
+
throw new Error('If additionalGlobs is provided, it must be the same length as projectRoots');
|
21
|
+
}
|
22
|
+
return (0, devkit_internals_1.hashMultiGlobWithWorkspaceContext)(context.workspaceRoot, projectRoots.map((projectRoot, idx) => [
|
23
|
+
(0, path_1.join)(projectRoot, '**/*'),
|
24
|
+
...(additionalGlobs.length ? additionalGlobs[idx] : []),
|
25
|
+
])).then((hashes) => {
|
26
|
+
return hashes.map((hash) => (0, devkit_exports_1.hashArray)([hash, (0, devkit_internals_1.hashObject)(options)]));
|
27
|
+
});
|
28
|
+
}
|
@@ -176,14 +176,18 @@ function removeDependenciesFromPackageJson(tree, dependencies, devDependencies,
|
|
176
176
|
const currentPackageJson = (0, devkit_exports_1.readJson)(tree, packageJsonPath);
|
177
177
|
if (requiresRemovingOfPackages(currentPackageJson, dependencies, devDependencies)) {
|
178
178
|
(0, devkit_exports_1.updateJson)(tree, packageJsonPath, (json) => {
|
179
|
-
|
180
|
-
|
179
|
+
if (json.dependencies) {
|
180
|
+
for (const dep of dependencies) {
|
181
|
+
delete json.dependencies[dep];
|
182
|
+
}
|
183
|
+
json.dependencies = sortObjectByKeys(json.dependencies);
|
181
184
|
}
|
182
|
-
|
183
|
-
|
185
|
+
if (json.devDependencies) {
|
186
|
+
for (const devDep of devDependencies) {
|
187
|
+
delete json.devDependencies[devDep];
|
188
|
+
}
|
189
|
+
json.devDependencies = sortObjectByKeys(json.devDependencies);
|
184
190
|
}
|
185
|
-
json.dependencies = sortObjectByKeys(json.dependencies);
|
186
|
-
json.devDependencies = sortObjectByKeys(json.devDependencies);
|
187
191
|
return json;
|
188
192
|
});
|
189
193
|
}
|