@nx/devkit 20.7.0 → 20.7.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/devkit",
3
- "version": "20.7.0",
3
+ "version": "20.7.1",
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": {
@@ -7,11 +7,15 @@ 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
- validateOptions(options);
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,6 +48,9 @@ async function determineProjectNameAndRootOptions(tree, options) {
44
48
  projectRoot = (0, devkit_exports_1.joinPathFragments)(relativeCwd, name);
45
49
  }
46
50
  }
51
+ if (projectRoot.startsWith('..')) {
52
+ throw new Error(`The resolved project root "${projectRoot}" is outside of the workspace root "${devkit_exports_1.workspaceRoot}".`);
53
+ }
47
54
  const importPath = options.importPath ?? resolveImportPath(tree, name, projectRoot);
48
55
  return {
49
56
  projectName: name,
@@ -80,34 +87,26 @@ async function ensureRootProjectName(options, projectType) {
80
87
  options.name = result.name;
81
88
  }
82
89
  }
83
- function validateOptions(options) {
84
- if (options.directory === '.') {
85
- /**
86
- * Root projects must provide name option
87
- */
88
- if (!options.name) {
89
- throw new Error(`Root projects must also specify name option.`);
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.`);
90
106
  }
91
107
  }
92
- else {
93
- /**
94
- * Both directory and name (if present) must match one of two cases:
95
- *
96
- * 1. Valid npm package names (e.g., '@scope/name' or 'name').
97
- * 2. Names starting with a letter and can contain any character except whitespace and ':'.
98
- *
99
- * The second case is to support the legacy behavior (^[a-zA-Z].*$) with the difference
100
- * that it doesn't allow the ":" character. It was wrong to allow it because it would
101
- * conflict with the notation for tasks.
102
- */
103
- const pattern = '(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$';
104
- const validationRegex = new RegExp(pattern);
105
- if (options.name && !validationRegex.test(options.name)) {
106
- throw new Error(`The name should match the pattern "${pattern}". The provided value "${options.name}" does not match.`);
107
- }
108
- if (!validationRegex.test(options.directory)) {
109
- throw new Error(`The directory should match the pattern "${pattern}". The provided value "${options.directory}" does not match.`);
110
- }
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.`);
111
110
  }
112
111
  }
113
112
  function getImportPath(npmScope, name) {