nx 23.1.0 → 23.1.2
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/bin/nx.js +2 -1
- package/dist/release/changelog-renderer/index.js +4 -5
- package/dist/release/index.d.ts +1 -1
- package/dist/src/ai/configure-ai-agents-disclaimer.d.ts +5 -0
- package/dist/src/ai/configure-ai-agents-disclaimer.js +31 -0
- package/dist/src/analytics/analytics.d.ts +6 -0
- package/dist/src/analytics/analytics.js +16 -8
- package/dist/src/analytics/index.d.ts +1 -1
- package/dist/src/analytics/index.js +2 -1
- package/dist/src/command-line/add/add.js +13 -1
- package/dist/src/command-line/affected/affected.js +1 -0
- package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +2 -2
- package/dist/src/command-line/graph/graph.d.ts +1 -0
- package/dist/src/command-line/graph/graph.js +15 -6
- package/dist/src/command-line/import/import.js +2 -3
- package/dist/src/command-line/init/ai-agent-prompts.d.ts +1 -1
- package/dist/src/command-line/init/ai-agent-prompts.js +7 -6
- package/dist/src/command-line/init/command-object.js +10 -2
- package/dist/src/command-line/init/configure-plugins.js +3 -2
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +4 -2
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-turborepo.js +4 -3
- package/dist/src/command-line/init/implementation/angular/index.js +4 -2
- package/dist/src/command-line/init/implementation/angular/integrated-workspace.js +2 -5
- package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +3 -0
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +4 -1
- package/dist/src/command-line/init/implementation/utils.d.ts +3 -3
- package/dist/src/command-line/init/implementation/utils.js +22 -3
- package/dist/src/command-line/init/init-v2.js +4 -5
- package/dist/src/command-line/migrate/execute-migration.d.ts +72 -0
- package/dist/src/command-line/migrate/execute-migration.js +389 -0
- package/dist/src/command-line/migrate/migrate-ui-api.js +17 -12
- package/dist/src/command-line/migrate/migrate.d.ts +5 -45
- package/dist/src/command-line/migrate/migrate.js +122 -402
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +1 -1
- package/dist/src/command-line/nx-cloud/connect/view-logs.js +2 -0
- package/dist/src/command-line/release/changelog.js +5 -0
- package/dist/src/command-line/release/index.d.ts +1 -1
- package/dist/src/command-line/release/utils/git.js +7 -3
- package/dist/src/command-line/release/utils/release-graph.d.ts +19 -2
- package/dist/src/command-line/release/utils/release-graph.js +71 -19
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +7 -1
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +1 -1
- package/dist/src/command-line/release/utils/shared.d.ts +2 -2
- package/dist/src/command-line/release/version/release-group-processor.d.ts +24 -0
- package/dist/src/command-line/release/version/release-group-processor.js +80 -6
- package/dist/src/command-line/release/version/version-actions.d.ts +27 -2
- package/dist/src/command-line/release/version/version-actions.js +9 -1
- package/dist/src/command-line/release/version.js +9 -5
- package/dist/src/command-line/reset/reset.js +6 -1
- package/dist/src/command-line/run/run-one.js +1 -0
- package/dist/src/command-line/run-many/run-many.js +1 -0
- package/dist/src/command-line/show/show-target/info.js +11 -2
- package/dist/src/command-line/show/show-target/inputs.js +50 -153
- package/dist/src/command-line/show/show-target/outputs.js +48 -173
- package/dist/src/command-line/show/show-target/utils.d.ts +28 -0
- package/dist/src/command-line/show/show-target/utils.js +83 -3
- package/dist/src/command-line/watch/watch.js +13 -0
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/dist/src/commands-runner/create-command-graph.js +5 -0
- package/dist/src/config/nx-json.d.ts +5 -3
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/core/graph/styles.js +1 -1
- package/dist/src/daemon/client/client.d.ts +52 -3
- package/dist/src/daemon/client/client.js +177 -55
- package/dist/src/daemon/client/daemon-environment.d.ts +17 -0
- package/dist/src/daemon/client/daemon-environment.js +110 -2
- package/dist/src/daemon/client/daemon-socket-messenger.js +4 -0
- package/dist/src/daemon/message-types/daemon-message.d.ts +32 -0
- package/dist/src/daemon/message-types/daemon-message.js +25 -0
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.d.ts +5 -0
- package/dist/src/daemon/server/file-watching/file-watcher-sockets.js +16 -0
- package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +1 -1
- package/dist/src/daemon/server/latest-nx.js +5 -2
- package/dist/src/daemon/server/server.js +31 -4
- package/dist/src/daemon/server/shutdown-utils.d.ts +5 -0
- package/dist/src/daemon/server/shutdown-utils.js +11 -4
- package/dist/src/daemon/socket-utils.d.ts +1 -0
- package/dist/src/daemon/socket-utils.js +24 -3
- package/dist/src/daemon/tmp-dir.d.ts +43 -3
- package/dist/src/daemon/tmp-dir.js +437 -15
- package/dist/src/devkit-internals.d.ts +96 -3
- package/dist/src/devkit-internals.js +200 -4
- package/dist/src/generators/internal-utils/format-changed-files-with-prettier-if-available.d.ts +5 -0
- package/dist/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +9 -2
- package/dist/src/generators/tree.d.ts +4 -2
- package/dist/src/generators/utils/nx-json.js +13 -3
- package/dist/src/hasher/check-task-files.d.ts +86 -0
- package/dist/src/hasher/check-task-files.js +378 -0
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.d.ts +12 -0
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.js +250 -0
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.md +50 -0
- package/dist/src/native/index.d.ts +31 -2
- package/dist/src/native/index.js +71 -28
- package/dist/src/native/native-bindings.js +3 -0
- package/dist/src/native/native-file-cache-location.d.ts +17 -1
- package/dist/src/native/native-file-cache-location.js +86 -12
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/nx-cloud/utilities/get-cloud-options.js +5 -2
- package/dist/src/nx-cloud/utilities/onboarding.js +5 -2
- package/dist/src/plugins/js/lock-file/bun-parser.js +43 -10
- package/dist/src/plugins/js/lock-file/npm-parser.js +71 -27
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +110 -17
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +15 -9
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +3 -0
- package/dist/src/plugins/js/lock-file/yarn-parser.js +32 -5
- package/dist/src/plugins/js/project-graph/affected/npm-packages.js +51 -20
- package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +14 -4
- package/dist/src/plugins/js/utils/register.d.ts +18 -0
- package/dist/src/plugins/js/utils/register.js +81 -0
- package/dist/src/plugins/js/utils/typescript.d.ts +9 -0
- package/dist/src/plugins/js/utils/typescript.js +15 -0
- package/dist/src/project-graph/affected/affected-project-graph-models.d.ts +1 -1
- package/dist/src/project-graph/affected/affected-project-graph.d.ts +1 -1
- package/dist/src/project-graph/affected/affected-project-graph.js +2 -2
- package/dist/src/project-graph/affected/locators/project-glob-changes.js +5 -2
- package/dist/src/project-graph/build-project-graph.js +7 -1
- package/dist/src/project-graph/error-types.d.ts +12 -1
- package/dist/src/project-graph/error-types.js +68 -3
- package/dist/src/project-graph/file-utils.js +6 -1
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +1 -0
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +22 -1
- package/dist/src/project-graph/plugins/isolation/messaging.d.ts +16 -3
- package/dist/src/project-graph/plugins/isolation/messaging.js +3 -0
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +58 -8
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +1 -0
- package/dist/src/project-graph/plugins/transpiler.js +4 -0
- package/dist/src/project-graph/project-graph.js +23 -0
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +10 -12
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.js +93 -63
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +5 -8
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +16 -15
- package/dist/src/project-graph/utils/project-configuration/source-maps.d.ts +12 -5
- package/dist/src/project-graph/utils/project-configuration/source-maps.js +21 -7
- package/dist/src/project-graph/utils/project-configuration/target-defaults.d.ts +1 -1
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +26 -27
- package/dist/src/project-graph/utils/project-configuration/target-merging.js +50 -8
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +149 -6
- package/dist/src/project-graph/utils/project-configuration/utils.d.ts +15 -0
- package/dist/src/project-graph/utils/project-configuration/utils.js +42 -6
- package/dist/src/project-graph/utils/project-configuration-utils.d.ts +15 -12
- package/dist/src/project-graph/utils/project-configuration-utils.js +79 -101
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +11 -4
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +15 -6
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +5 -4
- package/dist/src/tasks-runner/life-cycles/performance-report.d.ts +18 -8
- package/dist/src/tasks-runner/life-cycles/performance-report.js +66 -29
- package/dist/src/tasks-runner/run-command.js +4 -2
- package/dist/src/tasks-runner/task-env.d.ts +9 -0
- package/dist/src/tasks-runner/task-env.js +31 -4
- package/dist/src/tasks-runner/task-orchestrator.d.ts +4 -1
- package/dist/src/tasks-runner/task-orchestrator.js +23 -10
- package/dist/src/tasks-runner/utils.js +2 -6
- package/dist/src/utils/acknowledge-build-scripts.d.ts +13 -0
- package/dist/src/utils/acknowledge-build-scripts.js +102 -0
- package/dist/src/utils/analytics-prompt.d.ts +0 -6
- package/dist/src/utils/analytics-prompt.js +0 -51
- package/dist/src/utils/assert-workspace-validity.js +7 -2
- package/dist/src/utils/catalog/manager-utils.d.ts +1 -2
- package/dist/src/utils/catalog/manager-utils.js +22 -5
- package/dist/src/utils/catalog/pnpm-manager.d.ts +1 -0
- package/dist/src/utils/catalog/pnpm-manager.js +3 -15
- package/dist/src/utils/catalog/yarn-manager.d.ts +1 -0
- package/dist/src/utils/catalog/yarn-manager.js +3 -15
- package/dist/src/utils/command-line-utils.js +30 -20
- package/dist/src/utils/fileutils.d.ts +5 -0
- package/dist/src/utils/fileutils.js +7 -2
- package/dist/src/utils/git-revision.d.ts +12 -0
- package/dist/src/utils/git-revision.js +25 -0
- package/dist/src/utils/git-utils.d.ts +16 -3
- package/dist/src/utils/git-utils.js +146 -52
- package/dist/src/utils/git-worktrees.d.ts +30 -0
- package/dist/src/utils/git-worktrees.js +212 -0
- package/dist/src/utils/ignore.d.ts +128 -1
- package/dist/src/utils/ignore.js +182 -12
- package/dist/src/utils/long-running-target.d.ts +10 -0
- package/dist/src/utils/long-running-target.js +19 -0
- package/dist/src/utils/min-release-age/behavior/bun.js +7 -11
- package/dist/src/utils/min-release-age/behavior/npm.js +5 -2
- package/dist/src/utils/min-release-age/behavior/pnpm.js +9 -7
- package/dist/src/utils/min-release-age/packument.js +1 -1
- package/dist/src/utils/nx-tmp-dir.d.ts +18 -0
- package/dist/src/utils/nx-tmp-dir.js +40 -0
- package/dist/src/utils/owned-private-dir.d.ts +132 -0
- package/dist/src/utils/owned-private-dir.js +323 -0
- package/dist/src/utils/package-json.js +11 -7
- package/dist/src/utils/package-manager-config/bunfig.d.ts +14 -0
- package/dist/src/utils/package-manager-config/bunfig.js +49 -0
- package/dist/src/utils/package-manager-config/npmrc.d.ts +23 -0
- package/dist/src/utils/package-manager-config/npmrc.js +124 -0
- package/dist/src/utils/package-manager-config/pnpm-config.d.ts +17 -0
- package/dist/src/utils/package-manager-config/pnpm-config.js +60 -0
- package/dist/src/utils/package-manager.d.ts +23 -2
- package/dist/src/utils/package-manager.js +264 -43
- package/dist/src/utils/provenance.js +18 -16
- package/dist/src/utils/registry-config/bun.d.ts +2 -0
- package/dist/src/utils/registry-config/bun.js +257 -0
- package/dist/src/utils/registry-config/index.d.ts +13 -0
- package/dist/src/utils/registry-config/index.js +102 -0
- package/dist/src/utils/registry-config/pnpm.d.ts +2 -0
- package/dist/src/utils/registry-config/pnpm.js +1551 -0
- package/dist/src/utils/registry-config/utils.d.ts +195 -0
- package/dist/src/utils/registry-config/utils.js +496 -0
- package/dist/src/utils/registry-config/yarn-berry.d.ts +2 -0
- package/dist/src/utils/registry-config/yarn-berry.js +612 -0
- package/dist/src/utils/registry-config/yarn-classic.d.ts +2 -0
- package/dist/src/utils/registry-config/yarn-classic.js +1001 -0
- package/dist/src/utils/safe-spawn.d.ts +24 -0
- package/dist/src/utils/safe-spawn.js +104 -0
- package/dist/src/utils/shell-quoting.d.ts +15 -0
- package/dist/src/utils/shell-quoting.js +35 -0
- package/dist/src/utils/wait-for-socket-connection.d.ts +11 -0
- package/dist/src/utils/wait-for-socket-connection.js +14 -8
- package/dist/src/utils/workspace-id.d.ts +20 -0
- package/dist/src/utils/workspace-id.js +54 -0
- package/migrations.json +13 -1
- package/package.json +22 -17
- package/dist/src/migrations/update-17-3-0/nx-release-path.d.ts +0 -3
- package/dist/src/migrations/update-17-3-0/nx-release-path.js +0 -47
- package/dist/src/utils/min-release-age/npmrc.d.ts +0 -15
- package/dist/src/utils/min-release-age/npmrc.js +0 -45
|
@@ -8,6 +8,7 @@ const semver_1 = require("semver");
|
|
|
8
8
|
const find_project_for_path_1 = require("../../../../project-graph/utils/find-project-for-path");
|
|
9
9
|
const fileutils_1 = require("../../../../utils/fileutils");
|
|
10
10
|
const get_package_name_from_import_path_1 = require("../../../../utils/get-package-name-from-import-path");
|
|
11
|
+
const path_1 = require("../../../../utils/path");
|
|
11
12
|
const workspace_root_1 = require("../../../../utils/workspace-root");
|
|
12
13
|
const packages_1 = require("../../utils/packages");
|
|
13
14
|
const resolve_relative_to_dir_1 = require("../../utils/resolve-relative-to-dir");
|
|
@@ -161,11 +162,19 @@ class TargetProjectLocator {
|
|
|
161
162
|
return externalNodeName;
|
|
162
163
|
}
|
|
163
164
|
const version = (0, semver_1.clean)(externalPackageJson.version);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
const isAliasImport = packageName !== externalPackageJson.name;
|
|
166
|
+
let matchingExternalNode = null;
|
|
167
|
+
if (isAliasImport) {
|
|
168
|
+
// Prefer the alias node when both the alias import and the resolved package
|
|
169
|
+
// exist in the graph, otherwise generated package.json files lose the alias key.
|
|
167
170
|
const aliasNpmProjectKey = `npm:${packageName}@npm:${externalPackageJson.name}@${version}`;
|
|
168
|
-
matchingExternalNode =
|
|
171
|
+
matchingExternalNode =
|
|
172
|
+
this.npmProjects[aliasNpmProjectKey] ??
|
|
173
|
+
this.npmProjects[`npm:${packageName}`];
|
|
174
|
+
}
|
|
175
|
+
if (!matchingExternalNode) {
|
|
176
|
+
matchingExternalNode =
|
|
177
|
+
this.npmProjects[`npm:${externalPackageJson.name}@${version}`];
|
|
169
178
|
}
|
|
170
179
|
if (!matchingExternalNode) {
|
|
171
180
|
// Fallback to package name as key. This can happen if the version in project graph is not the same as in the resolved package.json.
|
|
@@ -338,6 +347,7 @@ class TargetProjectLocator {
|
|
|
338
347
|
}));
|
|
339
348
|
}
|
|
340
349
|
findProjectOfResolvedModule(resolvedModule) {
|
|
350
|
+
resolvedModule = (0, path_1.normalizePath)(resolvedModule);
|
|
341
351
|
if (resolvedModule.startsWith('node_modules/') ||
|
|
342
352
|
resolvedModule.includes('/node_modules/')) {
|
|
343
353
|
return undefined;
|
|
@@ -96,6 +96,24 @@ export declare function ensureNodeNextEsmResolverRegistered(): void;
|
|
|
96
96
|
* unaffected when both files exist. Idempotent on repeat calls.
|
|
97
97
|
*/
|
|
98
98
|
export declare function ensureCjsResolverPatched(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Make Node's module resolver honor the given export conditions for the rest of
|
|
101
|
+
* the process, via `module.registerHooks()`. Used when a local plugin is loaded
|
|
102
|
+
* from source in-process (no child process to pass `--conditions` to at spawn):
|
|
103
|
+
* the hook appends the conditions to every resolution so the plugin's transitive
|
|
104
|
+
* workspace imports resolve to source the same way the plugin entry did.
|
|
105
|
+
*
|
|
106
|
+
* No-op when:
|
|
107
|
+
* - `conditions` is empty (nothing to inject);
|
|
108
|
+
* - every target condition is already active at startup (a spawned plugin
|
|
109
|
+
* worker or daemon was launched with the full `--conditions` set, so Node's
|
|
110
|
+
* resolver already honors them and the per-resolve hook would be redundant);
|
|
111
|
+
* - `module.registerHooks` is unavailable (Node < 22.15 / < 23.5). Those
|
|
112
|
+
* runtimes keep the `NODE_OPTIONS=--conditions` escape hatch.
|
|
113
|
+
*
|
|
114
|
+
* Idempotent and best-effort.
|
|
115
|
+
*/
|
|
116
|
+
export declare function ensureResolveConditionsInjected(conditions: string[]): void;
|
|
99
117
|
/**
|
|
100
118
|
* Whether Nx will defer to Node's native TypeScript stripping for the next
|
|
101
119
|
* `.ts` load. Mirrors the gate used by `loadTsFile`/`registerTsProject` so
|
|
@@ -5,6 +5,7 @@ exports.forceRegisterEsmLoader = forceRegisterEsmLoader;
|
|
|
5
5
|
exports.nodeNextEsmResolveHook = nodeNextEsmResolveHook;
|
|
6
6
|
exports.ensureNodeNextEsmResolverRegistered = ensureNodeNextEsmResolverRegistered;
|
|
7
7
|
exports.ensureCjsResolverPatched = ensureCjsResolverPatched;
|
|
8
|
+
exports.ensureResolveConditionsInjected = ensureResolveConditionsInjected;
|
|
8
9
|
exports.isNativeStripPreferred = isNativeStripPreferred;
|
|
9
10
|
exports.registerTsProject = registerTsProject;
|
|
10
11
|
exports.getSwcTranspiler = getSwcTranspiler;
|
|
@@ -388,6 +389,86 @@ const isInvokedByTsx = (() => {
|
|
|
388
389
|
return (requireArgs.some((a) => isTsxPath(a)) ||
|
|
389
390
|
importArgs.some((a) => isTsxPath(a)));
|
|
390
391
|
})();
|
|
392
|
+
let resolveConditionsInjected = false;
|
|
393
|
+
/**
|
|
394
|
+
* Make Node's module resolver honor the given export conditions for the rest of
|
|
395
|
+
* the process, via `module.registerHooks()`. Used when a local plugin is loaded
|
|
396
|
+
* from source in-process (no child process to pass `--conditions` to at spawn):
|
|
397
|
+
* the hook appends the conditions to every resolution so the plugin's transitive
|
|
398
|
+
* workspace imports resolve to source the same way the plugin entry did.
|
|
399
|
+
*
|
|
400
|
+
* No-op when:
|
|
401
|
+
* - `conditions` is empty (nothing to inject);
|
|
402
|
+
* - every target condition is already active at startup (a spawned plugin
|
|
403
|
+
* worker or daemon was launched with the full `--conditions` set, so Node's
|
|
404
|
+
* resolver already honors them and the per-resolve hook would be redundant);
|
|
405
|
+
* - `module.registerHooks` is unavailable (Node < 22.15 / < 23.5). Those
|
|
406
|
+
* runtimes keep the `NODE_OPTIONS=--conditions` escape hatch.
|
|
407
|
+
*
|
|
408
|
+
* Idempotent and best-effort.
|
|
409
|
+
*/
|
|
410
|
+
function ensureResolveConditionsInjected(conditions) {
|
|
411
|
+
if (resolveConditionsInjected)
|
|
412
|
+
return;
|
|
413
|
+
resolveConditionsInjected = true;
|
|
414
|
+
if (!conditions.length)
|
|
415
|
+
return;
|
|
416
|
+
// Skip only when Node already honors every target condition (e.g. a worker or
|
|
417
|
+
// daemon spawned with the full `--conditions` set); a partial overlap still
|
|
418
|
+
// needs the hook to add the missing ones.
|
|
419
|
+
const activeConditions = getConditionsActiveAtStartup();
|
|
420
|
+
if (conditions.every((condition) => activeConditions.has(condition)))
|
|
421
|
+
return;
|
|
422
|
+
const module = require('node:module');
|
|
423
|
+
const registerHooks = module.registerHooks;
|
|
424
|
+
if (typeof registerHooks !== 'function')
|
|
425
|
+
return;
|
|
426
|
+
try {
|
|
427
|
+
registerHooks.call(module, {
|
|
428
|
+
resolve(specifier, context, nextResolve) {
|
|
429
|
+
const merged = context.conditions
|
|
430
|
+
? [...context.conditions, ...conditions]
|
|
431
|
+
: conditions;
|
|
432
|
+
return nextResolve(specifier, { ...context, conditions: merged });
|
|
433
|
+
},
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
// Best-effort: leave Node's native resolution in place rather than failing.
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Export conditions this process was started with, parsed from `--conditions`
|
|
442
|
+
* (or its `-C` alias) in `process.execArgv` and `NODE_OPTIONS`. Node's resolver
|
|
443
|
+
* already honors these, so the injected hook only needs to cover target
|
|
444
|
+
* conditions not present here.
|
|
445
|
+
*/
|
|
446
|
+
function getConditionsActiveAtStartup() {
|
|
447
|
+
const active = new Set();
|
|
448
|
+
const collect = (tokens) => {
|
|
449
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
450
|
+
const token = tokens[i];
|
|
451
|
+
if (token === '--conditions' || token === '-C') {
|
|
452
|
+
const value = tokens[i + 1];
|
|
453
|
+
if (value) {
|
|
454
|
+
active.add(value);
|
|
455
|
+
i++;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
else if (token.startsWith('--conditions=')) {
|
|
459
|
+
active.add(token.slice('--conditions='.length));
|
|
460
|
+
}
|
|
461
|
+
else if (token.startsWith('-C=')) {
|
|
462
|
+
active.add(token.slice('-C='.length));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
collect(process.execArgv ?? []);
|
|
467
|
+
const nodeOptions = process.env.NODE_OPTIONS;
|
|
468
|
+
if (nodeOptions)
|
|
469
|
+
collect(nodeOptions.split(/\s+/).filter(Boolean));
|
|
470
|
+
return active;
|
|
471
|
+
}
|
|
391
472
|
/**
|
|
392
473
|
* Whether the current Node.js runtime exposes native TypeScript type
|
|
393
474
|
* stripping. This is the authoritative gate - it correctly handles every
|
|
@@ -20,4 +20,13 @@ export declare function getRootTsConfigCustomConditions(root?: string): string[]
|
|
|
20
20
|
* `migrate-development-custom-condition` (21.5).
|
|
21
21
|
*/
|
|
22
22
|
export declare function getRootTsConfigResolveExportsConditions(root?: string): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Node `--conditions <name>` CLI args for spawning a plugin worker or the daemon
|
|
25
|
+
* with the plugin-resolution conditions active at startup. Mirrors the set Nx
|
|
26
|
+
* uses to resolve the plugin entry (`getRootTsConfigResolveExportsConditions`)
|
|
27
|
+
* so the entry and the plugin's transitive workspace imports resolve the same
|
|
28
|
+
* way; Node's own resolver otherwise ignores TypeScript `customConditions` and a
|
|
29
|
+
* source-loaded plugin's imports land on their unbuilt `dist`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getPluginResolveConditionNodeArgs(root?: string): string[];
|
|
23
32
|
export declare function findNodes(node: Node, kind: SyntaxKind | SyntaxKind[], max?: number): Node[];
|
|
@@ -8,6 +8,7 @@ exports.getRootTsConfigFileName = getRootTsConfigFileName;
|
|
|
8
8
|
exports.getRootTsConfigPath = getRootTsConfigPath;
|
|
9
9
|
exports.getRootTsConfigCustomConditions = getRootTsConfigCustomConditions;
|
|
10
10
|
exports.getRootTsConfigResolveExportsConditions = getRootTsConfigResolveExportsConditions;
|
|
11
|
+
exports.getPluginResolveConditionNodeArgs = getPluginResolveConditionNodeArgs;
|
|
11
12
|
exports.findNodes = findNodes;
|
|
12
13
|
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
13
14
|
const fs_1 = require("fs");
|
|
@@ -113,6 +114,20 @@ function getRootTsConfigResolveExportsConditions(root = workspace_root_1.workspa
|
|
|
113
114
|
? conditions
|
|
114
115
|
: [...conditions, 'development'];
|
|
115
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Node `--conditions <name>` CLI args for spawning a plugin worker or the daemon
|
|
119
|
+
* with the plugin-resolution conditions active at startup. Mirrors the set Nx
|
|
120
|
+
* uses to resolve the plugin entry (`getRootTsConfigResolveExportsConditions`)
|
|
121
|
+
* so the entry and the plugin's transitive workspace imports resolve the same
|
|
122
|
+
* way; Node's own resolver otherwise ignores TypeScript `customConditions` and a
|
|
123
|
+
* source-loaded plugin's imports land on their unbuilt `dist`.
|
|
124
|
+
*/
|
|
125
|
+
function getPluginResolveConditionNodeArgs(root = workspace_root_1.workspaceRoot) {
|
|
126
|
+
return getRootTsConfigResolveExportsConditions(root).flatMap((c) => [
|
|
127
|
+
'--conditions',
|
|
128
|
+
c,
|
|
129
|
+
]);
|
|
130
|
+
}
|
|
116
131
|
function findNodes(node, kind, max = Infinity) {
|
|
117
132
|
if (!node || max == 0) {
|
|
118
133
|
return [];
|
|
@@ -7,5 +7,5 @@ export interface AffectedProjectGraphContext {
|
|
|
7
7
|
touchedProjects: string[];
|
|
8
8
|
}
|
|
9
9
|
export interface TouchedProjectLocator<T extends Change = Change> {
|
|
10
|
-
(fileChanges: FileChange<T>[], projectGraphNodes?: Record<string, ProjectGraphProjectNode>, nxJson?: NxJsonConfiguration<any>, packageJson?: any, projectGraph?: ProjectGraph): string[] | Promise<string[]>;
|
|
10
|
+
(fileChanges: FileChange<T>[], projectGraphNodes?: Record<string, ProjectGraphProjectNode>, nxJson?: NxJsonConfiguration<any>, packageJson?: any, projectGraph?: ProjectGraph, projectDeletionAffectsAllProjects?: boolean): string[] | Promise<string[]>;
|
|
11
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { FileChange } from '../file-utils';
|
|
2
2
|
import { NxJsonConfiguration } from '../../config/nx-json';
|
|
3
3
|
import { ProjectGraph } from '../../config/project-graph';
|
|
4
|
-
export declare function filterAffected(graph: ProjectGraph, touchedFiles: FileChange[], nxJson?: NxJsonConfiguration, packageJson?: any): Promise<ProjectGraph>;
|
|
4
|
+
export declare function filterAffected(graph: ProjectGraph, touchedFiles: FileChange[], nxJson?: NxJsonConfiguration, packageJson?: any, projectDeletionAffectsAllProjects?: boolean): Promise<ProjectGraph>;
|
|
@@ -7,7 +7,7 @@ const touched_projects_1 = require("../../plugins/js/project-graph/affected/touc
|
|
|
7
7
|
const operators_1 = require("../operators");
|
|
8
8
|
const configuration_1 = require("../../config/configuration");
|
|
9
9
|
const project_glob_changes_1 = require("./locators/project-glob-changes");
|
|
10
|
-
async function filterAffected(graph, touchedFiles, nxJson = (0, configuration_1.readNxJson)(), packageJson = (0, file_utils_1.readPackageJson)()) {
|
|
10
|
+
async function filterAffected(graph, touchedFiles, nxJson = (0, configuration_1.readNxJson)(), packageJson = (0, file_utils_1.readPackageJson)(), projectDeletionAffectsAllProjects = true) {
|
|
11
11
|
// Additional affected logic should be in this array.
|
|
12
12
|
const touchedProjectLocators = [
|
|
13
13
|
workspace_projects_1.getTouchedProjects,
|
|
@@ -18,7 +18,7 @@ async function filterAffected(graph, touchedFiles, nxJson = (0, configuration_1.
|
|
|
18
18
|
const touchedProjects = [];
|
|
19
19
|
for (const locator of touchedProjectLocators) {
|
|
20
20
|
performance.mark(locator.name + ':start');
|
|
21
|
-
const projects = await locator(touchedFiles, graph.nodes, nxJson, packageJson, graph);
|
|
21
|
+
const projects = await locator(touchedFiles, graph.nodes, nxJson, packageJson, graph, projectDeletionAffectsAllProjects);
|
|
22
22
|
performance.mark(locator.name + ':end');
|
|
23
23
|
performance.measure(locator.name, locator.name + ':start', locator.name + ':end');
|
|
24
24
|
touchedProjects.push(...projects);
|
|
@@ -9,7 +9,7 @@ const fs_1 = require("fs");
|
|
|
9
9
|
const retrieve_workspace_files_1 = require("../../utils/retrieve-workspace-files");
|
|
10
10
|
const globs_1 = require("../../../utils/globs");
|
|
11
11
|
const get_plugins_1 = require("../../plugins/get-plugins");
|
|
12
|
-
const getTouchedProjectsFromProjectGlobChanges = async (touchedFiles, projectGraphNodes) => {
|
|
12
|
+
const getTouchedProjectsFromProjectGlobChanges = async (touchedFiles, projectGraphNodes, _nxJson, _packageJson, _projectGraph, projectDeletionAffectsAllProjects = true) => {
|
|
13
13
|
const globPattern = await (async () => {
|
|
14
14
|
// TODO: We need a quicker way to get patterns that should not
|
|
15
15
|
// require starting up plugin workers
|
|
@@ -33,7 +33,10 @@ const getTouchedProjectsFromProjectGlobChanges = async (touchedFiles, projectGra
|
|
|
33
33
|
// If the file no longer exists on disk, then it was deleted
|
|
34
34
|
if (!(0, fs_1.existsSync)((0, path_1.join)(workspace_root_1.workspaceRoot, touchedFile.file))) {
|
|
35
35
|
// If any project has been deleted, we must assume all projects were affected
|
|
36
|
-
|
|
36
|
+
if (projectDeletionAffectsAllProjects) {
|
|
37
|
+
return Object.keys(projectGraphNodes);
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
37
40
|
}
|
|
38
41
|
// Modified project config files are under a project's root, and implicitly
|
|
39
42
|
// mark it as affected. Thus, we don't need to handle it here.
|
|
@@ -7,6 +7,7 @@ exports.applyProjectMetadata = applyProjectMetadata;
|
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const perf_hooks_1 = require("perf_hooks");
|
|
10
|
+
const analytics_1 = require("../analytics");
|
|
10
11
|
const configuration_1 = require("../config/configuration");
|
|
11
12
|
const file_hasher_1 = require("../hasher/file-hasher");
|
|
12
13
|
const typescript_1 = require("../plugins/js/utils/typescript");
|
|
@@ -222,7 +223,12 @@ async function updateProjectGraphWithPlugins(context, initProjectGraph, plugins,
|
|
|
222
223
|
perf_hooks_1.performance.measure(`${plugin.name}:createDependencies`, {
|
|
223
224
|
start: `${plugin.name}:createDependencies - start`,
|
|
224
225
|
end: `${plugin.name}:createDependencies - end`,
|
|
225
|
-
detail: {
|
|
226
|
+
detail: {
|
|
227
|
+
track: true,
|
|
228
|
+
...(analytics_1.customDimensions && {
|
|
229
|
+
[analytics_1.customDimensions.sampleRate]: analytics_1.PERF_SPAN_SAMPLE_RATE,
|
|
230
|
+
}),
|
|
231
|
+
},
|
|
226
232
|
});
|
|
227
233
|
}));
|
|
228
234
|
perf_hooks_1.performance.mark('createDependencies:end');
|
|
@@ -3,6 +3,7 @@ import { ProjectConfiguration } from '../config/workspace-json-project-json';
|
|
|
3
3
|
import { CreateNodesFunction } from './plugins/public-api';
|
|
4
4
|
import { ConfigurationResult } from './utils/project-configuration-utils';
|
|
5
5
|
import type { ConfigurationSourceMaps } from './utils/project-configuration/source-maps';
|
|
6
|
+
import type { WorktreeConflictAdvice } from '../utils/git-worktrees';
|
|
6
7
|
export type ProjectGraphErrorTypes = AggregateCreateNodesError | MergeNodesError | CreateMetadataError | ProjectsWithNoNameError | MultipleProjectsWithSameNameError | ProcessDependenciesError | WorkspaceValidityError;
|
|
7
8
|
export declare class StaleProjectGraphCacheError extends Error {
|
|
8
9
|
constructor();
|
|
@@ -29,7 +30,17 @@ export declare class ProjectGraphError extends Error {
|
|
|
29
30
|
export declare class MultipleProjectsWithSameNameError extends Error {
|
|
30
31
|
conflicts: Map<string, string[]>;
|
|
31
32
|
projects: Record<string, ProjectConfiguration>;
|
|
32
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Set when some of the duplicates come from git worktrees nested in the
|
|
35
|
+
* workspace, which is a different fix than renaming them.
|
|
36
|
+
*/
|
|
37
|
+
worktreeAdvice?: WorktreeConflictAdvice;
|
|
38
|
+
constructor(conflicts: Map<string, string[]>, projects: Record<string, ProjectConfiguration>,
|
|
39
|
+
/**
|
|
40
|
+
* Set when some of the duplicates come from git worktrees nested in the
|
|
41
|
+
* workspace, which is a different fix than renaming them.
|
|
42
|
+
*/
|
|
43
|
+
worktreeAdvice?: WorktreeConflictAdvice);
|
|
33
44
|
}
|
|
34
45
|
export declare class ProjectWithExistingNameError extends Error {
|
|
35
46
|
projectName: string;
|
|
@@ -92,19 +92,44 @@ class ProjectGraphError extends Error {
|
|
|
92
92
|
exports.ProjectGraphError = ProjectGraphError;
|
|
93
93
|
_ProjectGraphError_partialProjectGraph = new WeakMap(), _ProjectGraphError_partialSourceMaps = new WeakMap();
|
|
94
94
|
class MultipleProjectsWithSameNameError extends Error {
|
|
95
|
-
constructor(conflicts, projects
|
|
95
|
+
constructor(conflicts, projects,
|
|
96
|
+
/**
|
|
97
|
+
* Set when some of the duplicates come from git worktrees nested in the
|
|
98
|
+
* workspace, which is a different fix than renaming them.
|
|
99
|
+
*/
|
|
100
|
+
worktreeAdvice) {
|
|
96
101
|
super([
|
|
97
102
|
`The following projects are defined in multiple locations:`,
|
|
98
103
|
...Array.from(conflicts.entries()).map(([project, roots]) => [`- ${project}: `, ...roots.map((r) => ` - ${r}`)].join('\n')),
|
|
99
104
|
'',
|
|
100
|
-
|
|
105
|
+
...(worktreeAdvice?.ignoreTargets.length
|
|
106
|
+
? [
|
|
107
|
+
'Some of these are inside git worktrees nested in this workspace. A worktree is a full checkout, so every project in it collides with the one it was checked out from.',
|
|
108
|
+
'',
|
|
109
|
+
// Which `.gitignore` matters: a leading slash anchors to the
|
|
110
|
+
// directory holding the file, and these paths are relative to
|
|
111
|
+
// the workspace, which is not always the repository root.
|
|
112
|
+
'To fix those, add the following to the .gitignore in the workspace root:',
|
|
113
|
+
...worktreeAdvice.ignoreTargets.map((target) => ` ${target}`),
|
|
114
|
+
// Ignoring the worktrees settles only the duplicates they
|
|
115
|
+
// explain; anything left is an ordinary name collision and still
|
|
116
|
+
// needs the ordinary answer.
|
|
117
|
+
...(worktreeAdvice.explainsAllConflicts
|
|
118
|
+
? []
|
|
119
|
+
: ['', `The rest are not from worktrees. ${RENAME_ADVICE}`]),
|
|
120
|
+
]
|
|
121
|
+
: [
|
|
122
|
+
`To fix this, ${RENAME_ADVICE[0].toLowerCase()}${RENAME_ADVICE.slice(1)}`,
|
|
123
|
+
]),
|
|
101
124
|
].join('\n'));
|
|
102
125
|
this.conflicts = conflicts;
|
|
103
126
|
this.projects = projects;
|
|
127
|
+
this.worktreeAdvice = worktreeAdvice;
|
|
104
128
|
this.name = this.constructor.name;
|
|
105
129
|
}
|
|
106
130
|
}
|
|
107
131
|
exports.MultipleProjectsWithSameNameError = MultipleProjectsWithSameNameError;
|
|
132
|
+
const RENAME_ADVICE = "Set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.";
|
|
108
133
|
class ProjectWithExistingNameError extends Error {
|
|
109
134
|
constructor(projectName, projectRoot) {
|
|
110
135
|
super(`The project "${projectName}" is defined in multiple locations.`);
|
|
@@ -242,9 +267,48 @@ class AggregateCreateNodesError extends Error {
|
|
|
242
267
|
errorTuple.length === 2)) {
|
|
243
268
|
throw new Error('AggregateCreateNodesError must be constructed with an array of tuples where the first element is a filename or undefined and the second element is the underlying error.');
|
|
244
269
|
}
|
|
270
|
+
// Plugins pass through whatever value they caught, which is not
|
|
271
|
+
// guaranteed to be an Error. Coerce so formatting can rely on
|
|
272
|
+
// message and stack being present.
|
|
273
|
+
for (const errorTuple of errors) {
|
|
274
|
+
errorTuple[1] = coerceToError(errorTuple[1]);
|
|
275
|
+
}
|
|
245
276
|
}
|
|
246
277
|
}
|
|
247
278
|
exports.AggregateCreateNodesError = AggregateCreateNodesError;
|
|
279
|
+
function coerceToError(value) {
|
|
280
|
+
if (value instanceof Error) {
|
|
281
|
+
return value;
|
|
282
|
+
}
|
|
283
|
+
let message;
|
|
284
|
+
let stack;
|
|
285
|
+
if (typeof value === 'object' && value !== null) {
|
|
286
|
+
const candidate = value;
|
|
287
|
+
if (typeof candidate.message === 'string') {
|
|
288
|
+
message = candidate.message;
|
|
289
|
+
if (typeof candidate.stack === 'string') {
|
|
290
|
+
stack = candidate.stack;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
try {
|
|
295
|
+
message = JSON.stringify(value);
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Circular structures cannot be stringified.
|
|
299
|
+
message = String(value);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
message = String(value);
|
|
305
|
+
}
|
|
306
|
+
const error = new Error(message);
|
|
307
|
+
// A synthesized stack would point at this coercion site rather than
|
|
308
|
+
// the original failure, so prefer the original stack or just the message.
|
|
309
|
+
error.stack = stack ?? message;
|
|
310
|
+
return error;
|
|
311
|
+
}
|
|
248
312
|
function formatAggregateCreateNodesError(error, pluginName) {
|
|
249
313
|
const errorCount = error.errors.length > 1 ? `${error.errors.length} errors` : 'An error';
|
|
250
314
|
const pluginLocation = error.pluginIndex
|
|
@@ -270,7 +334,8 @@ function formatAggregateCreateNodesError(error, pluginName) {
|
|
|
270
334
|
}
|
|
271
335
|
for (const e of errors) {
|
|
272
336
|
const messageLines = e.message.split('\n');
|
|
273
|
-
|
|
337
|
+
// Errors deserialized from a plugin worker may arrive without a stack.
|
|
338
|
+
const stackLines = (e.stack ?? e.message).split('\n');
|
|
274
339
|
if (file) {
|
|
275
340
|
errorBodyLines.push(...messageLines.map((line) => ` ${line}`));
|
|
276
341
|
errorStackLines.push(...stackLines.map((line) => ` ${line}`));
|
|
@@ -12,6 +12,7 @@ const fs_1 = require("fs");
|
|
|
12
12
|
const os_1 = require("os");
|
|
13
13
|
const path_1 = require("path");
|
|
14
14
|
const fileutils_1 = require("../utils/fileutils");
|
|
15
|
+
const git_revision_1 = require("../utils/git-revision");
|
|
15
16
|
const ignore_1 = require("../utils/ignore");
|
|
16
17
|
const json_diff_1 = require("../utils/json-diff");
|
|
17
18
|
const workspace_root_1 = require("../utils/workspace-root");
|
|
@@ -116,11 +117,14 @@ function readLockFileAtRevision(file, lockFileName, revision, readFileAtRevision
|
|
|
116
117
|
}
|
|
117
118
|
exports.TEN_MEGABYTES = 1024 * 10000;
|
|
118
119
|
function defaultReadFileAtRevision(file, revision) {
|
|
120
|
+
if (revision) {
|
|
121
|
+
(0, git_revision_1.assertValidGitRevision)(revision);
|
|
122
|
+
}
|
|
119
123
|
try {
|
|
120
124
|
const filePathInGitRepository = getFilePathInGitRepository(file);
|
|
121
125
|
return !revision
|
|
122
126
|
? (0, fs_1.readFileSync)(file, 'utf-8')
|
|
123
|
-
: (0, child_process_1.
|
|
127
|
+
: (0, child_process_1.execFileSync)('git', ['show', `${revision}:${filePathInGitRepository}`], {
|
|
124
128
|
maxBuffer: exports.TEN_MEGABYTES,
|
|
125
129
|
stdio: ['pipe', 'pipe', 'ignore'],
|
|
126
130
|
windowsHide: true,
|
|
@@ -140,6 +144,7 @@ function defaultReadBunLockFileAtRevision(file, revision) {
|
|
|
140
144
|
windowsHide: true,
|
|
141
145
|
}).trim();
|
|
142
146
|
}
|
|
147
|
+
(0, git_revision_1.assertValidGitRevision)(revision);
|
|
143
148
|
const filePathInGitRepository = getFilePathInGitRepository(file);
|
|
144
149
|
const tempDirectory = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'nx-bun-lock-'));
|
|
145
150
|
const tempLockfilePath = (0, path_1.join)(tempDirectory, 'bun.lockb');
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IsolatedPlugin = void 0;
|
|
4
|
+
exports.getPluginWorkerSocketId = getPluginWorkerSocketId;
|
|
4
5
|
const child_process_1 = require("child_process");
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
5
7
|
const net_1 = require("net");
|
|
6
8
|
const path = require("path");
|
|
7
9
|
const logger_1 = require("../../../daemon/logger");
|
|
8
10
|
const socket_utils_1 = require("../../../daemon/socket-utils");
|
|
9
11
|
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
|
|
12
|
+
const typescript_1 = require("../../../plugins/js/utils/typescript");
|
|
10
13
|
const installation_directory_1 = require("../../../utils/installation-directory");
|
|
11
14
|
const logger_2 = require("../../../utils/logger");
|
|
12
15
|
const progress_topics_1 = require("../../../utils/progress-topics");
|
|
13
16
|
const wait_for_socket_connection_1 = require("../../../utils/wait-for-socket-connection");
|
|
17
|
+
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
14
18
|
const resolve_plugin_1 = require("../resolve-plugin");
|
|
15
19
|
const messaging_1 = require("./messaging");
|
|
16
20
|
const plugin_lifecycle_manager_1 = require("./plugin-lifecycle-manager");
|
|
@@ -335,6 +339,10 @@ class IsolatedPlugin {
|
|
|
335
339
|
exports.IsolatedPlugin = IsolatedPlugin;
|
|
336
340
|
// --- Worker Spawning Utilities ---
|
|
337
341
|
global.nxPluginWorkerCount ??= 0;
|
|
342
|
+
function getPluginWorkerSocketId() {
|
|
343
|
+
const counter = global.nxPluginWorkerCount++;
|
|
344
|
+
return `${process.pid}-${counter.toString(36)}-${(0, crypto_1.randomBytes)(4).toString('hex')}`;
|
|
345
|
+
}
|
|
338
346
|
async function startPluginWorker(name) {
|
|
339
347
|
performance.mark(`start-plugin-worker:${name}`);
|
|
340
348
|
const isWorkerTypescript = path.extname(__filename) === '.ts';
|
|
@@ -351,12 +359,25 @@ async function startPluginWorker(name) {
|
|
|
351
359
|
}
|
|
352
360
|
: {}),
|
|
353
361
|
};
|
|
354
|
-
|
|
362
|
+
// Keep the host pid readable for diagnostics, the counter collision-free
|
|
363
|
+
// within this process, and entropy for a reused pid across process runs. The
|
|
364
|
+
// suffix is a base36 counter plus four random bytes: eleven characters after
|
|
365
|
+
// the pid until the counter passes 36, and fixed-length where the
|
|
366
|
+
// `performance.now()` stamp it replaced varied with process uptime. That
|
|
367
|
+
// keeps the socket path inside the 95-character budget `assertValidSocketPath`
|
|
368
|
+
// enforces.
|
|
369
|
+
const ipcPath = (0, socket_utils_1.getPluginOsSocketPath)(getPluginWorkerSocketId());
|
|
355
370
|
const worker = (0, child_process_1.spawn)(process.execPath, [
|
|
371
|
+
// Spawn the worker with the same resolve conditions Nx uses for plugin
|
|
372
|
+
// entries so the plugin's transitive workspace imports resolve to source.
|
|
373
|
+
...(0, typescript_1.getPluginResolveConditionNodeArgs)(),
|
|
356
374
|
...(isWorkerTypescript ? ['--require', 'ts-node/register'] : []),
|
|
357
375
|
workerPath,
|
|
358
376
|
ipcPath,
|
|
359
377
|
name,
|
|
378
|
+
// The host's root. The worker validates against this rather than re-resolving,
|
|
379
|
+
// so the two agree by construction.
|
|
380
|
+
workspace_root_1.workspaceRoot,
|
|
360
381
|
], {
|
|
361
382
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
362
383
|
env,
|
|
@@ -107,10 +107,23 @@ type PluginMessageDefs = DefineMessages<{
|
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
109
|
}>;
|
|
110
|
+
/**
|
|
111
|
+
* The sender's workspace root. Only the *worker* asserts on it, for host→worker
|
|
112
|
+
* messages; results and notifications carry the field but the host does not
|
|
113
|
+
* check it. The daemon channel is checked in the same one direction — the
|
|
114
|
+
* server validates inbound client messages and the client does not validate
|
|
115
|
+
* responses — so the two are alike rather than one being weaker.
|
|
116
|
+
* Optional and stamped centrally in `sendMessageOverSocket`, so the many
|
|
117
|
+
* message constructors need not set it; undefined is treated as not foreign,
|
|
118
|
+
* which is why this detects a shared socket directory rather than an attacker.
|
|
119
|
+
*/
|
|
120
|
+
export type WorkspaceStampedMessage = {
|
|
121
|
+
workspaceRoot?: string;
|
|
122
|
+
};
|
|
110
123
|
/** Union of all plugin worker message types */
|
|
111
|
-
export type PluginWorkerMessage = AllMessages<PluginMessageDefs
|
|
124
|
+
export type PluginWorkerMessage = AllMessages<PluginMessageDefs> & WorkspaceStampedMessage;
|
|
112
125
|
/** Union of all plugin worker result types */
|
|
113
|
-
export type PluginWorkerResult = AllResults<PluginMessageDefs
|
|
126
|
+
export type PluginWorkerResult = AllResults<PluginMessageDefs> & WorkspaceStampedMessage;
|
|
114
127
|
/** Result type for the load message */
|
|
115
128
|
export type PluginWorkerLoadResult = ResultOf<PluginMessageDefs, 'load'>;
|
|
116
129
|
/**
|
|
@@ -122,7 +135,7 @@ export type PluginWorkerEmitLogNotification = {
|
|
|
122
135
|
type: 'emitLog';
|
|
123
136
|
level: 'log' | 'warn' | 'error';
|
|
124
137
|
message: string;
|
|
125
|
-
};
|
|
138
|
+
} & WorkspaceStampedMessage;
|
|
126
139
|
export type PluginWorkerNotification = PluginWorkerEmitLogNotification;
|
|
127
140
|
export declare function isPluginWorkerNotification(message: Serializable): message is PluginWorkerNotification;
|
|
128
141
|
export declare function isPluginWorkerMessage(message: Serializable): message is PluginWorkerMessage;
|
|
@@ -7,6 +7,7 @@ exports.consumeMessage = consumeMessage;
|
|
|
7
7
|
exports.sendMessageOverSocket = sendMessageOverSocket;
|
|
8
8
|
const socket_utils_1 = require("../../../daemon/socket-utils");
|
|
9
9
|
const consume_messages_from_socket_1 = require("../../../utils/consume-messages-from-socket");
|
|
10
|
+
const workspace_root_1 = require("../../../utils/workspace-root");
|
|
10
11
|
const NOTIFICATION_TYPES = [
|
|
11
12
|
'emitLog',
|
|
12
13
|
];
|
|
@@ -81,6 +82,8 @@ async function consumeMessage(socket, raw, handlers) {
|
|
|
81
82
|
* Sends a message over the socket with proper formatting.
|
|
82
83
|
*/
|
|
83
84
|
function sendMessageOverSocket(socket, message) {
|
|
85
|
+
// Stamped here rather than in each constructor, mirroring the daemon.
|
|
86
|
+
message.workspaceRoot = workspace_root_1.workspaceRoot;
|
|
84
87
|
socket.write((0, socket_utils_1.serialize)(message));
|
|
85
88
|
socket.write(consume_messages_from_socket_1.MESSAGE_END_SEQ);
|
|
86
89
|
}
|