nx 22.7.0-rc.1 → 22.7.0
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/dist/src/command-line/init/command-object.js +7 -68
- package/dist/src/command-line/init/configure-plugins.js +8 -2
- package/dist/src/command-line/init/implementation/utils.d.ts +7 -0
- package/dist/src/command-line/init/implementation/utils.js +71 -5
- package/dist/src/command-line/init/init-v2.js +50 -0
- package/dist/src/command-line/nx-cloud/connect/command-object.js +0 -6
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +55 -0
- package/dist/src/command-line/run/run-one.js +3 -2
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +2 -0
- package/dist/src/command-line/yargs-utils/shared-options.js +7 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/executors/run-commands/running-tasks.js +29 -16
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +2 -1
- package/dist/src/utils/delayed-spinner.js +2 -2
- package/dist/src/utils/versions.js +1 -4
- package/package.json +14 -14
- /package/{dist/schemas → schemas}/nx-schema.json +0 -0
- /package/{dist/schemas → schemas}/project-schema.json +0 -0
- /package/{dist/schemas → schemas}/workspace-schema.json +0 -0
|
@@ -3,12 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.yargsInitCommand = void 0;
|
|
4
4
|
const handle_import_1 = require("../../utils/handle-import");
|
|
5
5
|
const shared_options_1 = require("../yargs-utils/shared-options");
|
|
6
|
-
const native_1 = require("../../native");
|
|
7
|
-
const ai_output_1 = require("./utils/ai-output");
|
|
8
|
-
const ab_testing_1 = require("../../utils/ab-testing");
|
|
9
|
-
const versions_1 = require("../../utils/versions");
|
|
10
|
-
const is_ci_1 = require("../../utils/is-ci");
|
|
11
|
-
const package_manager_1 = require("../../utils/package-manager");
|
|
12
6
|
exports.yargsInitCommand = {
|
|
13
7
|
command: 'init',
|
|
14
8
|
describe: 'Adds Nx to any type of workspace. It installs nx, creates an nx.json configuration file and optionally sets up remote caching. For more info, check https://nx.dev/recipes/adopting-nx.',
|
|
@@ -33,70 +27,15 @@ exports.yargsInitCommand = {
|
|
|
33
27
|
return;
|
|
34
28
|
throw error;
|
|
35
29
|
});
|
|
36
|
-
const
|
|
37
|
-
(
|
|
38
|
-
|
|
39
|
-
nxVersion: versions_1.nxVersion,
|
|
40
|
-
useCloud: false,
|
|
41
|
-
meta: {
|
|
42
|
-
type: 'start',
|
|
43
|
-
nodeVersion: process.versions.node,
|
|
44
|
-
os: process.platform,
|
|
45
|
-
packageManager: (0, package_manager_1.detectPackageManager)(),
|
|
46
|
-
aiAgent,
|
|
47
|
-
isCI: (0, is_ci_1.isCI)(),
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
try {
|
|
51
|
-
const useV2 = await isInitV2();
|
|
52
|
-
if (useV2) {
|
|
53
|
-
// v2 records its own complete event with richer context
|
|
54
|
-
await require('./init-v2').initHandler(args);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
await require('./init-v1').initHandler(args);
|
|
58
|
-
await (0, ab_testing_1.recordStat)({
|
|
59
|
-
command: 'init',
|
|
60
|
-
nxVersion: versions_1.nxVersion,
|
|
61
|
-
useCloud: false,
|
|
62
|
-
meta: {
|
|
63
|
-
type: 'complete',
|
|
64
|
-
nodeVersion: process.versions.node,
|
|
65
|
-
os: process.platform,
|
|
66
|
-
packageManager: (0, package_manager_1.detectPackageManager)(),
|
|
67
|
-
aiAgent,
|
|
68
|
-
isCI: (0, is_ci_1.isCI)(),
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
process.exit(0);
|
|
30
|
+
const useV2 = await isInitV2();
|
|
31
|
+
if (useV2) {
|
|
32
|
+
await require('./init-v2').initHandler(args);
|
|
73
33
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await (0, ab_testing_1.recordStat)({
|
|
78
|
-
command: 'init',
|
|
79
|
-
nxVersion: versions_1.nxVersion,
|
|
80
|
-
useCloud: false,
|
|
81
|
-
meta: {
|
|
82
|
-
type: 'error',
|
|
83
|
-
errorCode,
|
|
84
|
-
errorMessage: errorMessage.substring(0, 250),
|
|
85
|
-
aiAgent,
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
// Output structured error for AI agents
|
|
89
|
-
if (aiAgent) {
|
|
90
|
-
const errorLogPath = (0, ai_output_1.writeErrorLog)(error);
|
|
91
|
-
(0, ai_output_1.writeAiOutput)((0, ai_output_1.buildErrorResult)(errorMessage, errorCode, errorLogPath));
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// Ensure the cursor is always restored just in case the user has bailed during interactive prompts
|
|
95
|
-
// Skip for AI agents to avoid corrupting NDJSON output
|
|
96
|
-
process.stdout.write('\x1b[?25h');
|
|
97
|
-
}
|
|
98
|
-
process.exit(1);
|
|
34
|
+
else {
|
|
35
|
+
// v1 path retained for `NX_ADD_PLUGINS=false`; slated for removal.
|
|
36
|
+
await require('./init-v1').initHandler(args);
|
|
99
37
|
}
|
|
38
|
+
process.exit(0);
|
|
100
39
|
},
|
|
101
40
|
};
|
|
102
41
|
async function isInitV2() {
|
|
@@ -35,8 +35,14 @@ function installPluginPackages(repoRoot, pmc = (0, package_manager_1.getPackageM
|
|
|
35
35
|
nxJson.installation.plugins[plugin] = versions_1.nxVersion;
|
|
36
36
|
}
|
|
37
37
|
(0, fileutils_1.writeJsonFile)((0, path_1.join)(repoRoot, 'nx.json'), nxJson);
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
try {
|
|
39
|
+
(0, child_process_1.runNxSync)('--version', { stdio: 'pipe' });
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (e?.stderr)
|
|
43
|
+
process.stderr.write(e.stderr);
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
/**
|
|
@@ -8,6 +8,13 @@ export declare function createNxJsonFromTurboJson(turboJson: Record<string, any>
|
|
|
8
8
|
export declare function addDepsToPackageJson(repoRoot: string, additionalPackages?: string[]): void;
|
|
9
9
|
export declare function updateGitIgnore(root: string): void;
|
|
10
10
|
export declare function runInstall(repoRoot: string, pmc?: PackageManagerCommands): void;
|
|
11
|
+
/**
|
|
12
|
+
* Coerce any thrown value into a non-empty telemetry string. The naive
|
|
13
|
+
* `error.message || String(error)` yields "" for bare `new Error()`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toErrorString(error: unknown): string;
|
|
16
|
+
export declare function readErrorStderr(error: unknown): string;
|
|
17
|
+
export declare function extractErrorName(error: unknown, stderr: string): string;
|
|
11
18
|
export declare function initCloud(installationSource: 'nx-init' | 'nx-init-angular' | 'nx-init-monorepo' | 'nx-init-nest' | 'nx-init-npm-repo' | 'nx-init-turborepo'): Promise<void>;
|
|
12
19
|
export declare function setNeverConnectToCloud(repoRoot: string): void;
|
|
13
20
|
export declare function addVsCodeRecommendedExtensions(repoRoot: string, extensions: string[]): void;
|
|
@@ -5,6 +5,9 @@ exports.createNxJsonFromTurboJson = createNxJsonFromTurboJson;
|
|
|
5
5
|
exports.addDepsToPackageJson = addDepsToPackageJson;
|
|
6
6
|
exports.updateGitIgnore = updateGitIgnore;
|
|
7
7
|
exports.runInstall = runInstall;
|
|
8
|
+
exports.toErrorString = toErrorString;
|
|
9
|
+
exports.readErrorStderr = readErrorStderr;
|
|
10
|
+
exports.extractErrorName = extractErrorName;
|
|
8
11
|
exports.initCloud = initCloud;
|
|
9
12
|
exports.setNeverConnectToCloud = setNeverConnectToCloud;
|
|
10
13
|
exports.addVsCodeRecommendedExtensions = addVsCodeRecommendedExtensions;
|
|
@@ -189,11 +192,74 @@ function updateGitIgnore(root) {
|
|
|
189
192
|
catch { }
|
|
190
193
|
}
|
|
191
194
|
function runInstall(repoRoot, pmc = (0, package_manager_1.getPackageManagerCommand)()) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
try {
|
|
196
|
+
(0, child_process_1.execSync)(pmc.install, {
|
|
197
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
198
|
+
encoding: 'utf8',
|
|
199
|
+
cwd: repoRoot,
|
|
200
|
+
windowsHide: true,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
if (e?.stderr)
|
|
205
|
+
process.stderr.write(e.stderr);
|
|
206
|
+
throw e;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Coerce any thrown value into a non-empty telemetry string. The naive
|
|
211
|
+
* `error.message || String(error)` yields "" for bare `new Error()`.
|
|
212
|
+
*/
|
|
213
|
+
function toErrorString(error) {
|
|
214
|
+
if (error == null)
|
|
215
|
+
return 'Unknown error';
|
|
216
|
+
if (error instanceof Error) {
|
|
217
|
+
if (error.message)
|
|
218
|
+
return error.message;
|
|
219
|
+
if (error.name && error.name !== 'Error')
|
|
220
|
+
return error.name;
|
|
221
|
+
// Drop `stack` — large and contains absolute paths (PII).
|
|
222
|
+
const keys = Object.getOwnPropertyNames(error).filter((k) => k !== 'stack');
|
|
223
|
+
const serialized = safeJsonStringify(error, keys);
|
|
224
|
+
if (serialized && serialized !== '{}')
|
|
225
|
+
return serialized;
|
|
226
|
+
return error.name || 'Error';
|
|
227
|
+
}
|
|
228
|
+
if (typeof error === 'object') {
|
|
229
|
+
const serialized = safeJsonStringify(error);
|
|
230
|
+
if (serialized && serialized !== '{}')
|
|
231
|
+
return serialized;
|
|
232
|
+
return Object.prototype.toString.call(error);
|
|
233
|
+
}
|
|
234
|
+
return String(error);
|
|
235
|
+
}
|
|
236
|
+
function readErrorStderr(error) {
|
|
237
|
+
const raw = error?.stderr;
|
|
238
|
+
if (typeof raw === 'string')
|
|
239
|
+
return raw;
|
|
240
|
+
if (raw && typeof raw.toString === 'function') {
|
|
241
|
+
return raw.toString('utf8');
|
|
242
|
+
}
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
function extractErrorName(error, stderr) {
|
|
246
|
+
const nodeCode = error?.code;
|
|
247
|
+
if (typeof nodeCode === 'string')
|
|
248
|
+
return nodeCode;
|
|
249
|
+
const m = stderr.match(/\b(E[A-Z0-9_]{2,}|ERR_[A-Z0-9_]+)\b/);
|
|
250
|
+
if (m)
|
|
251
|
+
return m[1];
|
|
252
|
+
if (error instanceof Error)
|
|
253
|
+
return error.name;
|
|
254
|
+
return typeof error;
|
|
255
|
+
}
|
|
256
|
+
function safeJsonStringify(value, replacer) {
|
|
257
|
+
try {
|
|
258
|
+
return JSON.stringify(value, replacer);
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return '';
|
|
262
|
+
}
|
|
197
263
|
}
|
|
198
264
|
async function initCloud(installationSource) {
|
|
199
265
|
const token = await (0, connect_to_nx_cloud_2.connectWorkspaceToCloud)({
|
|
@@ -60,8 +60,58 @@ async function initHandler(options, inner = false) {
|
|
|
60
60
|
return initHandlerImpl(options);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
async function recordInitError(error, baseMeta) {
|
|
64
|
+
const errorMessage = (0, utils_1.toErrorString)(error);
|
|
65
|
+
const errorCode = (0, ai_output_1.determineErrorCode)(error);
|
|
66
|
+
const stderr = (0, utils_1.readErrorStderr)(error).trim();
|
|
67
|
+
const telemetryMessage = (stderr ? `${errorMessage} | stderr: ${stderr.slice(-250)}` : errorMessage).slice(0, 500);
|
|
68
|
+
const errorName = (0, utils_1.extractErrorName)(error, stderr);
|
|
69
|
+
await (0, ab_testing_1.recordStat)({
|
|
70
|
+
command: 'init',
|
|
71
|
+
nxVersion: versions_1.nxVersion,
|
|
72
|
+
useCloud: false,
|
|
73
|
+
meta: {
|
|
74
|
+
type: 'error',
|
|
75
|
+
errorCode,
|
|
76
|
+
errorName,
|
|
77
|
+
errorMessage: telemetryMessage,
|
|
78
|
+
...baseMeta,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
if (baseMeta.aiAgent) {
|
|
82
|
+
const errorLogPath = (0, ai_output_1.writeErrorLog)(error);
|
|
83
|
+
(0, ai_output_1.writeAiOutput)((0, ai_output_1.buildErrorResult)(errorMessage, errorCode, errorLogPath));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Restore the cursor in case the user bailed during an interactive
|
|
87
|
+
// prompt. Skip for AI agents — it would corrupt NDJSON output.
|
|
88
|
+
process.stdout.write('\x1b[?25h');
|
|
89
|
+
}
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
63
92
|
async function initHandlerImpl(options) {
|
|
64
93
|
process.env.NX_RUNNING_NX_INIT = 'true';
|
|
94
|
+
const baseMeta = {
|
|
95
|
+
nodeVersion: process.versions.node,
|
|
96
|
+
os: process.platform,
|
|
97
|
+
packageManager: (0, package_manager_2.detectPackageManager)(),
|
|
98
|
+
aiAgent: (0, native_1.isAiAgent)(),
|
|
99
|
+
isCI: (0, is_ci_1.isCI)(),
|
|
100
|
+
};
|
|
101
|
+
(0, ab_testing_1.recordStat)({
|
|
102
|
+
command: 'init',
|
|
103
|
+
nxVersion: versions_1.nxVersion,
|
|
104
|
+
useCloud: false,
|
|
105
|
+
meta: { type: 'start', ...baseMeta },
|
|
106
|
+
});
|
|
107
|
+
try {
|
|
108
|
+
return await runInit(options, baseMeta);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
await recordInitError(error, baseMeta);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function runInit(options, baseMeta) {
|
|
65
115
|
const version = process.env.NX_VERSION ?? ((0, semver_1.prerelease)(versions_1.nxVersion) ? versions_1.nxVersion : 'latest');
|
|
66
116
|
if (process.env.NX_VERSION) {
|
|
67
117
|
output_1.output.log({ title: `Using version ${process.env.NX_VERSION}` });
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.yargsViewLogsCommand = exports.yargsConnectCommand = void 0;
|
|
4
4
|
const handle_import_1 = require("../../../utils/handle-import");
|
|
5
5
|
const documentation_1 = require("../../yargs-utils/documentation");
|
|
6
|
-
const versions_1 = require("../../../utils/versions");
|
|
7
6
|
const shared_options_1 = require("../../yargs-utils/shared-options");
|
|
8
7
|
exports.yargsConnectCommand = {
|
|
9
8
|
command: 'connect',
|
|
@@ -13,11 +12,6 @@ exports.yargsConnectCommand = {
|
|
|
13
12
|
handler: async (args) => {
|
|
14
13
|
const checkRemote = process.env.NX_SKIP_CHECK_REMOTE !== 'true';
|
|
15
14
|
await (await (0, handle_import_1.handleImport)('./connect-to-nx-cloud.js', __dirname)).connectToNxCloudCommand({ ...args, checkRemote });
|
|
16
|
-
await (await (0, handle_import_1.handleImport)('../../../utils/ab-testing.js', __dirname)).recordStat({
|
|
17
|
-
command: 'connect',
|
|
18
|
-
nxVersion: versions_1.nxVersion,
|
|
19
|
-
useCloud: true,
|
|
20
|
-
});
|
|
21
15
|
process.exit(0);
|
|
22
16
|
},
|
|
23
17
|
};
|
|
@@ -64,6 +64,61 @@ async function connectWorkspaceToCloud(options, directory = workspace_root_1.wor
|
|
|
64
64
|
return accessToken;
|
|
65
65
|
}
|
|
66
66
|
async function connectToNxCloudCommand(options, command) {
|
|
67
|
+
// `connectToNxCloudWithPrompt` (called from `migrate`) records its own stat; skip here to avoid double-counting.
|
|
68
|
+
const selfRecord = !command;
|
|
69
|
+
const baseMeta = {
|
|
70
|
+
nodeVersion: process.versions.node,
|
|
71
|
+
os: process.platform,
|
|
72
|
+
packageManager: (0, package_manager_1.detectPackageManager)(),
|
|
73
|
+
aiAgent: (0, native_1.isAiAgent)(),
|
|
74
|
+
isCI: (0, is_ci_1.isCI)(),
|
|
75
|
+
};
|
|
76
|
+
if (selfRecord) {
|
|
77
|
+
await (0, ab_testing_1.recordStat)({
|
|
78
|
+
command: 'connect',
|
|
79
|
+
nxVersion: versions_1.nxVersion,
|
|
80
|
+
useCloud: true,
|
|
81
|
+
meta: { type: 'start', ...baseMeta },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const result = await runConnectToNxCloud(options, command);
|
|
86
|
+
if (selfRecord) {
|
|
87
|
+
await (0, ab_testing_1.recordStat)({
|
|
88
|
+
command: 'connect',
|
|
89
|
+
nxVersion: versions_1.nxVersion,
|
|
90
|
+
useCloud: result,
|
|
91
|
+
meta: { type: 'complete', ...baseMeta },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (selfRecord) {
|
|
98
|
+
const message = (error instanceof Error && error.message) ||
|
|
99
|
+
String(error ?? 'Unknown error');
|
|
100
|
+
const errorName = typeof error?.code === 'string'
|
|
101
|
+
? error.code
|
|
102
|
+
: error instanceof Error
|
|
103
|
+
? error.name
|
|
104
|
+
: typeof error;
|
|
105
|
+
await (0, ab_testing_1.recordStat)({
|
|
106
|
+
command: 'connect',
|
|
107
|
+
nxVersion: versions_1.nxVersion,
|
|
108
|
+
useCloud: false,
|
|
109
|
+
meta: {
|
|
110
|
+
type: 'error',
|
|
111
|
+
errorCode: 'UNKNOWN',
|
|
112
|
+
errorName,
|
|
113
|
+
errorMessage: message.slice(0, 500),
|
|
114
|
+
...baseMeta,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function runConnectToNxCloud(options, command) {
|
|
67
122
|
const nxJson = (0, configuration_1.readNxJson)();
|
|
68
123
|
const installationSource = process.env.NX_CONSOLE
|
|
69
124
|
? 'nx-console'
|
|
@@ -103,7 +103,8 @@ function parseRunOneOptions(cwd, parsedArgs, projectGraph, nxJson) {
|
|
|
103
103
|
let project;
|
|
104
104
|
let target;
|
|
105
105
|
let configuration;
|
|
106
|
-
if (parsedArgs[PROJECT_TARGET_CONFIG]
|
|
106
|
+
if (typeof parsedArgs[PROJECT_TARGET_CONFIG] === 'string' &&
|
|
107
|
+
parsedArgs[PROJECT_TARGET_CONFIG].lastIndexOf(':') > 0) {
|
|
107
108
|
// run case
|
|
108
109
|
[project, target, configuration] = (0, split_target_1.splitTarget)(parsedArgs[PROJECT_TARGET_CONFIG], projectGraph, { currentProject: defaultProjectName });
|
|
109
110
|
// this is to account for "nx npmscript:dev"
|
|
@@ -115,7 +116,7 @@ function parseRunOneOptions(cwd, parsedArgs, projectGraph, nxJson) {
|
|
|
115
116
|
else if (parsedArgs.target) {
|
|
116
117
|
target = parsedArgs.target;
|
|
117
118
|
}
|
|
118
|
-
else if (parsedArgs[PROJECT_TARGET_CONFIG]) {
|
|
119
|
+
else if (typeof parsedArgs[PROJECT_TARGET_CONFIG] === 'string') {
|
|
119
120
|
// If project:target:configuration exists but has no colon, check if it's a project with run target
|
|
120
121
|
if (projectGraph.nodes[parsedArgs[PROJECT_TARGET_CONFIG]]?.data?.targets?.run) {
|
|
121
122
|
target = 'run';
|
|
@@ -316,6 +316,13 @@ function withRunOneOptions(yargs) {
|
|
|
316
316
|
.option('project', {
|
|
317
317
|
describe: 'Target project.',
|
|
318
318
|
type: 'string',
|
|
319
|
+
alias: 'p',
|
|
320
|
+
})
|
|
321
|
+
.option('target', {
|
|
322
|
+
describe: 'Target to run. Useful when the target name contains a colon, which conflicts with the positional `project:target:configuration` form.',
|
|
323
|
+
type: 'string',
|
|
324
|
+
alias: 't',
|
|
325
|
+
requiresArg: true,
|
|
319
326
|
})
|
|
320
327
|
.option('help', {
|
|
321
328
|
describe: 'Show Help.',
|