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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#### Set cache on executor-based target defaults
|
|
2
|
+
|
|
3
|
+
Maintains compatibility with how cacheability was resolved before Nx 23.
|
|
4
|
+
|
|
5
|
+
Target defaults resolve to a single key rather than merging them. When a target matches both a target name key and an executor key, the executor key is the one that applies, and the target name key is not read at all. Earlier versions of Nx also derived cacheability from target names, so `"cache": true` on the target name key still took effect even when an executor key applied. Nx 23 reads cacheability from the resolved target only.
|
|
6
|
+
|
|
7
|
+
This migration copies `cache` onto each executor key that applies to a target whose target name key enables it, so those targets remain cacheable.
|
|
8
|
+
|
|
9
|
+
An executor key applies to every target that resolves through it, so the migration updates a key only when it can establish that caching is right for all of them. It leaves the key unchanged when the key already declares `cache`, when it declares `continuous: true`, when every entry on the key is filtered so none of them always applies, when a target through it is continuous or is a long-running target such as `serve`, `dev`, or `start`, when the executor's own schema marks its targets continuous, or when a target through it has no target name key enabling `cache`. It never updates the `nx:run-commands` or `nx:run-script` keys, because targets written with `command` and targets derived from `package.json` scripts resolve through those keys without naming them.
|
|
10
|
+
|
|
11
|
+
Where the migration makes no change, Nx still decides at run time, per target rather than per key: a target whose target name key enables `cache`, and whose resolved configuration still leaves `cache` undefined, gets it back and is reported as a deprecated fallback. Because that test is applied to the resolved target rather than to the key, it also covers the cases where a key looks decided but is not for this project — an executor key whose entries are all filtered, or whose only `cache` declaration is filtered out here. It equally covers the targets left behind because a sibling target through the same key does not opt in, and the targets reaching the `nx:run-commands` and `nx:run-script` keys. Three cases get no fallback and no warning. A continuous or long-running target, because caching it is invalid. A target whose resolved configuration already sets `cache`. And a target whose target name key was discarded as incompatible, because its entry named an executor the target does not use — before Nx 23 that target was cacheable, since cacheability was matched on target name alone and the entry's `executor` was never read. Restoring it here would mean setting `cache` with no executor key to point the user at and no migration able to retire the behavior, so it is deliberately left alone. Set `cache` on those targets directly.
|
|
12
|
+
|
|
13
|
+
Targets are read from each project's `project.json` and from the `nx.targets` block of its `package.json`. Targets inferred by a plugin, and targets derived from `package.json` scripts, are not visible to the migration — the latter is why the `nx:run-script` key is never updated. A key that looks safe here may still serve an inferred target. Set `cache` on the executor key by hand only after checking that no target reaching it is continuous; Nx rejects a target that is both cacheable and continuous. Nx names both keys in a run-time warning. That warning is emitted during project graph construction, so while the daemon is running it goes to `.nx/workspace-data/d/daemon.log` rather than the terminal; CI runs, where the daemon is disabled, print it normally.
|
|
14
|
+
|
|
15
|
+
#### Sample code changes
|
|
16
|
+
|
|
17
|
+
Given a project with a `build` target that uses the `@nx/angular:webpack-browser` executor:
|
|
18
|
+
|
|
19
|
+
##### Before
|
|
20
|
+
|
|
21
|
+
```json title="nx.json"
|
|
22
|
+
{
|
|
23
|
+
"targetDefaults": {
|
|
24
|
+
"build": {
|
|
25
|
+
"cache": true,
|
|
26
|
+
"dependsOn": ["^build"]
|
|
27
|
+
},
|
|
28
|
+
"@nx/angular:webpack-browser": {
|
|
29
|
+
"inputs": ["production", "^production"]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
##### After
|
|
36
|
+
|
|
37
|
+
```json title="nx.json"
|
|
38
|
+
{
|
|
39
|
+
"targetDefaults": {
|
|
40
|
+
"build": {
|
|
41
|
+
"cache": true,
|
|
42
|
+
"dependsOn": ["^build"]
|
|
43
|
+
},
|
|
44
|
+
"@nx/angular:webpack-browser": {
|
|
45
|
+
"inputs": ["production", "^production"],
|
|
46
|
+
"cache": true
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
@@ -326,6 +326,7 @@ export interface EventDimensions {
|
|
|
326
326
|
packageName: string
|
|
327
327
|
packageVersion: string
|
|
328
328
|
duration: string
|
|
329
|
+
sampleRate: string
|
|
329
330
|
taskCount: string
|
|
330
331
|
projectCount: string
|
|
331
332
|
cachedTaskCount: string
|
|
@@ -411,6 +412,16 @@ export declare function getEventDimensions(): EventDimensions
|
|
|
411
412
|
*/
|
|
412
413
|
export declare function getFilesForOutputsBatch(directory: string, entriesBatch: Array<Array<string>>): Array<Array<string>>
|
|
413
414
|
|
|
415
|
+
/**
|
|
416
|
+
* The same list, for JavaScript callers that walk a tree rather than the
|
|
417
|
+
* filesystem - `visitNotIgnoredFiles` - so both sides apply one baseline
|
|
418
|
+
* instead of maintaining a second copy that drifts.
|
|
419
|
+
*
|
|
420
|
+
* The patterns are gitignore-shaped, so they read the same to the `ignore`
|
|
421
|
+
* crate here and the `ignore` npm package there.
|
|
422
|
+
*/
|
|
423
|
+
export declare function getHardcodedIgnorePatterns(): Array<string>
|
|
424
|
+
|
|
414
425
|
/**
|
|
415
426
|
* If `workspace_root` is inside a git worktree, returns the main repo root.
|
|
416
427
|
* Returns `None` when already in the main repo (or not in a git repo at all).
|
|
@@ -487,14 +498,14 @@ export interface HashInputs {
|
|
|
487
498
|
* so the caller can set it as an env var for child processes.
|
|
488
499
|
* Used by CLI and daemon.
|
|
489
500
|
*/
|
|
490
|
-
export declare function initializeTelemetry(connection: ExternalObject<NxDbConnection>, workspaceId: string, userId: string, nxVersion: string, packageManagerName: string, packageManagerVersion: string | undefined | null, nodeVersion: string, osArch: string, osPlatform: string, osRelease: string, isCi: boolean, isNxCloud: boolean): string
|
|
501
|
+
export declare function initializeTelemetry(connection: ExternalObject<NxDbConnection>, workspaceId: string, userId: string | undefined | null, nxVersion: string, packageManagerName: string, packageManagerVersion: string | undefined | null, nodeVersion: string, osArch: string, osPlatform: string, osRelease: string, isCi: boolean, isNxCloud: boolean): string
|
|
491
502
|
|
|
492
503
|
/**
|
|
493
504
|
* Initialize telemetry with a pre-fetched session ID.
|
|
494
505
|
* No DB connection — used by plugin workers that inherit the
|
|
495
506
|
* session ID from their parent process via env var.
|
|
496
507
|
*/
|
|
497
|
-
export declare function initializeTelemetryWithSessionId(sessionId: string, workspaceId: string, userId: string, nxVersion: string, packageManagerName: string, packageManagerVersion: string | undefined | null, nodeVersion: string, osArch: string, osPlatform: string, osRelease: string, isCi: boolean, isNxCloud: boolean): void
|
|
508
|
+
export declare function initializeTelemetryWithSessionId(sessionId: string, workspaceId: string, userId: string | undefined | null, nxVersion: string, packageManagerName: string, packageManagerVersion: string | undefined | null, nodeVersion: string, osArch: string, osPlatform: string, osRelease: string, isCi: boolean, isNxCloud: boolean): void
|
|
498
509
|
|
|
499
510
|
export interface InputsInput {
|
|
500
511
|
input: string
|
|
@@ -557,6 +568,24 @@ export interface Link {
|
|
|
557
568
|
|
|
558
569
|
export declare function logDebug(message: string): void
|
|
559
570
|
|
|
571
|
+
/**
|
|
572
|
+
* Checks which `paths` match the given `globs`, using the same glob engine
|
|
573
|
+
* as the task hasher (`build_glob_set`). Used to statically match
|
|
574
|
+
* `dependentTasksOutputFiles` globs against candidate paths.
|
|
575
|
+
*/
|
|
576
|
+
export declare function matchGlobPaths(globs: Array<string>, paths: Array<string>): Array<boolean>
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Statically checks which `paths` would be captured by the given output
|
|
580
|
+
* `entries`, without touching the file system. Mirrors `expand_outputs`
|
|
581
|
+
* semantics: entries match themselves and anything nested under them (so a
|
|
582
|
+
* directory entry captures its contents), negated (`!`-prefixed) entries
|
|
583
|
+
* exclude matches from the whole entry set, and a non-empty list with only
|
|
584
|
+
* negated entries matches everything not excluded. An empty list matches
|
|
585
|
+
* nothing.
|
|
586
|
+
*/
|
|
587
|
+
export declare function matchOutputPaths(entries: Array<string>, paths: Array<string>): Array<boolean>
|
|
588
|
+
|
|
560
589
|
/** Combined metadata for groups and processes */
|
|
561
590
|
export interface Metadata {
|
|
562
591
|
/** Group-level metadata */
|
package/dist/src/native/index.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
const { join, basename } = require('path');
|
|
2
|
-
const {
|
|
3
|
-
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
renameSync,
|
|
7
|
-
statSync,
|
|
8
|
-
unlinkSync,
|
|
9
|
-
} = require('fs');
|
|
2
|
+
const { copyFileSync, renameSync, statSync, unlinkSync } = require('fs');
|
|
3
|
+
const { createHash } = require('crypto');
|
|
10
4
|
const Module = require('module');
|
|
11
5
|
const { nxVersion } = require('../utils/versions');
|
|
12
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
ensureSecureNativeFileCacheLocation,
|
|
8
|
+
} = require('./native-file-cache-location');
|
|
13
9
|
|
|
14
10
|
const MAX_COPY_RETRIES = 3;
|
|
15
11
|
|
|
@@ -73,6 +69,14 @@ function statsOrNull(path) {
|
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
71
|
|
|
72
|
+
function removeIfPresent(path) {
|
|
73
|
+
try {
|
|
74
|
+
unlinkSync(path);
|
|
75
|
+
} catch {
|
|
76
|
+
// Ignore cleanup errors
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
function isNoExecError(e) {
|
|
77
81
|
return e.code === 'EACCES' || e.code === 'EPERM';
|
|
78
82
|
}
|
|
@@ -95,20 +99,44 @@ Module._load = function (request, parent, isMain) {
|
|
|
95
99
|
const nativeLocation = require.resolve(modulePath);
|
|
96
100
|
const fileName = basename(nativeLocation);
|
|
97
101
|
|
|
98
|
-
//
|
|
99
|
-
|
|
102
|
+
// null when the cache dir cannot be created *and trusted*; loading in place
|
|
103
|
+
// from node_modules is safer than loading out of a directory we don't own.
|
|
104
|
+
const nativeFileCacheLocation = ensureSecureNativeFileCacheLocation();
|
|
105
|
+
if (!nativeFileCacheLocation) {
|
|
106
|
+
return originalLoad.apply(this, [nativeLocation, parent, isMain]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// nxVersion alone is not enough: in a source checkout it is the placeholder
|
|
110
|
+
// 0.0.1 for every worktree, so hashing the resolved binding path keeps each
|
|
111
|
+
// checkout in its own entry.
|
|
112
|
+
const cacheKey =
|
|
113
|
+
nxVersion +
|
|
114
|
+
'-' +
|
|
115
|
+
createHash('sha256')
|
|
116
|
+
.update(nativeLocation)
|
|
117
|
+
.digest('hex')
|
|
118
|
+
.substring(0, 12);
|
|
119
|
+
|
|
100
120
|
// This is a path to copy to, not the one that gets loaded
|
|
101
121
|
const tmpTmpFile = join(
|
|
102
122
|
nativeFileCacheLocation,
|
|
103
|
-
|
|
123
|
+
cacheKey + '-' + Math.random() + fileName
|
|
104
124
|
);
|
|
105
125
|
// This is the path that will get loaded
|
|
106
|
-
const tmpFile = join(nativeFileCacheLocation,
|
|
107
|
-
const
|
|
126
|
+
const tmpFile = join(nativeFileCacheLocation, cacheKey + '-' + fileName);
|
|
127
|
+
const sourceStats = statSync(nativeLocation);
|
|
128
|
+
const expectedFileSize = sourceStats.size;
|
|
108
129
|
const existingFileStats = statsOrNull(tmpFile);
|
|
109
130
|
|
|
110
|
-
//
|
|
111
|
-
|
|
131
|
+
// Size alone does not detect a rebuilt binding: a small Rust edit routinely
|
|
132
|
+
// produces a byte-identical size. The copy is taken after the build, so a
|
|
133
|
+
// cache entry older than the source means the source was rebuilt since.
|
|
134
|
+
const isFresh =
|
|
135
|
+
existingFileStats?.size === expectedFileSize &&
|
|
136
|
+
existingFileStats.mtimeMs >= sourceStats.mtimeMs;
|
|
137
|
+
|
|
138
|
+
// If the file to be loaded already exists and is current, just load it
|
|
139
|
+
if (isFresh) {
|
|
112
140
|
try {
|
|
113
141
|
return originalLoad.apply(this, [tmpFile, parent, isMain]);
|
|
114
142
|
} catch (e) {
|
|
@@ -119,20 +147,36 @@ Module._load = function (request, parent, isMain) {
|
|
|
119
147
|
throw e;
|
|
120
148
|
}
|
|
121
149
|
}
|
|
122
|
-
if (!existsSync(nativeFileCacheLocation)) {
|
|
123
|
-
mkdirSync(nativeFileCacheLocation, { recursive: true });
|
|
124
|
-
}
|
|
125
150
|
|
|
126
151
|
// Retry copying up to 3 times, validating after each copy
|
|
152
|
+
let attemptsMade = 0;
|
|
153
|
+
let cacheError = null;
|
|
127
154
|
for (let attempt = 1; attempt <= MAX_COPY_RETRIES; attempt++) {
|
|
155
|
+
attemptsMade = attempt;
|
|
128
156
|
// First copy to a unique location for each process
|
|
129
|
-
|
|
157
|
+
try {
|
|
158
|
+
copyFileSync(nativeLocation, tmpTmpFile);
|
|
159
|
+
} catch (e) {
|
|
160
|
+
// Permission errors won't heal on retry, and a throwing copy can still
|
|
161
|
+
// have left a partial file behind.
|
|
162
|
+
cacheError = e;
|
|
163
|
+
removeIfPresent(tmpTmpFile);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
130
166
|
|
|
131
167
|
// Validate the copy - check file size matches expected
|
|
132
168
|
const copiedFileStats = statsOrNull(tmpTmpFile);
|
|
133
169
|
if (copiedFileStats?.size === expectedFileSize) {
|
|
134
170
|
// Copy succeeded, rename to final location and load
|
|
135
|
-
|
|
171
|
+
try {
|
|
172
|
+
renameSync(tmpTmpFile, tmpFile);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
// Unguarded, this throws out of `require` and native-bindings.js
|
|
175
|
+
// reports it as a missing optional dependency, which it is not.
|
|
176
|
+
cacheError = e;
|
|
177
|
+
removeIfPresent(tmpTmpFile);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
136
180
|
try {
|
|
137
181
|
return originalLoad.apply(this, [tmpFile, parent, isMain]);
|
|
138
182
|
} catch (e) {
|
|
@@ -145,16 +189,15 @@ Module._load = function (request, parent, isMain) {
|
|
|
145
189
|
}
|
|
146
190
|
|
|
147
191
|
// Copy failed validation, clean up the malformed file
|
|
148
|
-
|
|
149
|
-
unlinkSync(tmpTmpFile);
|
|
150
|
-
} catch {
|
|
151
|
-
// Ignore cleanup errors
|
|
152
|
-
}
|
|
192
|
+
removeIfPresent(tmpTmpFile);
|
|
153
193
|
}
|
|
154
194
|
|
|
155
|
-
//
|
|
195
|
+
// Name the errno: ENOSPC, EROFS, EACCES and EDQUOT are all actionable and
|
|
196
|
+
// otherwise indistinguishable.
|
|
156
197
|
console.warn(
|
|
157
|
-
`Warning: Failed to copy native module to cache after ${
|
|
198
|
+
`Warning: Failed to copy native module to cache after ${attemptsMade} attempt${
|
|
199
|
+
attemptsMade === 1 ? '' : 's'
|
|
200
|
+
}${cacheError ? ` (${cacheError.code ?? cacheError.message})` : ''}. ` +
|
|
158
201
|
`Loading from original location instead. ` +
|
|
159
202
|
`This may cause file locking issues on Windows.`
|
|
160
203
|
);
|
|
@@ -610,6 +610,7 @@ module.exports.getBinaryTarget = nativeBinding.getBinaryTarget
|
|
|
610
610
|
module.exports.getDefaultMaxCacheSize = nativeBinding.getDefaultMaxCacheSize
|
|
611
611
|
module.exports.getEventDimensions = nativeBinding.getEventDimensions
|
|
612
612
|
module.exports.getFilesForOutputsBatch = nativeBinding.getFilesForOutputsBatch
|
|
613
|
+
module.exports.getHardcodedIgnorePatterns = nativeBinding.getHardcodedIgnorePatterns
|
|
613
614
|
module.exports.getMainWorktreeRoot = nativeBinding.getMainWorktreeRoot
|
|
614
615
|
module.exports.getTransformableOutputs = nativeBinding.getTransformableOutputs
|
|
615
616
|
module.exports.GroupType = nativeBinding.GroupType
|
|
@@ -625,6 +626,8 @@ module.exports.isEditorInstalled = nativeBinding.isEditorInstalled
|
|
|
625
626
|
module.exports.killProcessTree = nativeBinding.killProcessTree
|
|
626
627
|
module.exports.killProcessTreeGraceful = nativeBinding.killProcessTreeGraceful
|
|
627
628
|
module.exports.logDebug = nativeBinding.logDebug
|
|
629
|
+
module.exports.matchGlobPaths = nativeBinding.matchGlobPaths
|
|
630
|
+
module.exports.matchOutputPaths = nativeBinding.matchOutputPaths
|
|
628
631
|
module.exports.parseTaskStatus = nativeBinding.parseTaskStatus
|
|
629
632
|
module.exports.remove = nativeBinding.remove
|
|
630
633
|
module.exports.restoreTerminal = nativeBinding.restoreTerminal
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Path of the current user's native binary cache. Nothing about the constant is
|
|
3
|
+
* owner-only — `ensureSecureNativeFileCacheLocation` is what establishes that,
|
|
4
|
+
* and on Windows nothing does, since the OS temp dir is already per-account.
|
|
5
|
+
*/
|
|
6
|
+
export declare const NATIVE_CACHE_ROOT: string;
|
|
7
|
+
export declare function getNativeFileCacheLocationToDelete(): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Create the native file cache dir, or return `null` if it cannot be created
|
|
10
|
+
* *securely* — in which case the caller loads the binding in place.
|
|
11
|
+
*
|
|
12
|
+
* The stable top-level container is verified as safe for private children. The
|
|
13
|
+
* uid directory and every directory loaded through are owner-only.
|
|
14
|
+
* `ensureOwnedPrivateDir` refuses a directory or symlink another local user
|
|
15
|
+
* planted before us.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ensureSecureNativeFileCacheLocation(cacheRoot?: string): string | null;
|
|
@@ -1,23 +1,97 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
3
|
+
exports.NATIVE_CACHE_ROOT = void 0;
|
|
4
|
+
exports.getNativeFileCacheLocationToDelete = getNativeFileCacheLocationToDelete;
|
|
5
|
+
exports.ensureSecureNativeFileCacheLocation = ensureSecureNativeFileCacheLocation;
|
|
5
6
|
const path_1 = require("path");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const nx_tmp_dir_1 = require("../utils/nx-tmp-dir");
|
|
8
9
|
const versions_1 = require("../utils/versions");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const owned_private_dir_1 = require("../utils/owned-private-dir");
|
|
11
|
+
/**
|
|
12
|
+
* Path of the current user's native binary cache. Nothing about the constant is
|
|
13
|
+
* owner-only — `ensureSecureNativeFileCacheLocation` is what establishes that,
|
|
14
|
+
* and on Windows nothing does, since the OS temp dir is already per-account.
|
|
15
|
+
*/
|
|
16
|
+
exports.NATIVE_CACHE_ROOT = (0, path_1.join)(nx_tmp_dir_1.NX_USER_TMP_DIR, 'native-cache');
|
|
17
|
+
/**
|
|
18
|
+
* The configured cache dir, normalized. `resolve` strips a trailing slash, which
|
|
19
|
+
* would otherwise defeat the guards downstream: `lstat` on a path ending in `/`
|
|
20
|
+
* resolves a symlink rather than reporting it, and `O_NOFOLLOW` then opens the
|
|
21
|
+
* target. `NX_SOCKET_DIR` is normalized for the same reason.
|
|
22
|
+
*/
|
|
23
|
+
function configuredCacheDir() {
|
|
24
|
+
const dir = process.env.NX_NATIVE_FILE_CACHE_DIRECTORY;
|
|
25
|
+
return dir ? (0, path_1.resolve)(dir) : undefined;
|
|
26
|
+
}
|
|
27
|
+
function getNativeFileCacheLocationToDelete() {
|
|
28
|
+
const configured = configuredCacheDir();
|
|
29
|
+
if (configured !== undefined) {
|
|
30
|
+
// Checked for ownership before it is handed to a recursive delete: being
|
|
31
|
+
// configured does not make it ours. Weaker than the load path below, which
|
|
32
|
+
// also enforces mode and validates the version directory.
|
|
33
|
+
return (0, owned_private_dir_1.isOwnedRealDirectory)(configured) ? configured : null;
|
|
12
34
|
}
|
|
13
|
-
|
|
14
|
-
|
|
35
|
+
return (0, owned_private_dir_1.isSafeSharedRoot)(nx_tmp_dir_1.NX_TMP_DIR).status === 'ok' &&
|
|
36
|
+
(0, owned_private_dir_1.isOwnedRealDirectory)(nx_tmp_dir_1.NX_USER_TMP_DIR) &&
|
|
37
|
+
(0, owned_private_dir_1.isOwnedRealDirectory)(exports.NATIVE_CACHE_ROOT)
|
|
38
|
+
? (0, path_1.join)(exports.NATIVE_CACHE_ROOT, versions_1.nxVersion)
|
|
39
|
+
: null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create the native file cache dir, or return `null` if it cannot be created
|
|
43
|
+
* *securely* — in which case the caller loads the binding in place.
|
|
44
|
+
*
|
|
45
|
+
* The stable top-level container is verified as safe for private children. The
|
|
46
|
+
* uid directory and every directory loaded through are owner-only.
|
|
47
|
+
* `ensureOwnedPrivateDir` refuses a directory or symlink another local user
|
|
48
|
+
* planted before us.
|
|
49
|
+
*/
|
|
50
|
+
function ensureSecureNativeFileCacheLocation(
|
|
51
|
+
// Test seam: lets a spec plant a hostile directory under a root it controls.
|
|
52
|
+
cacheRoot = exports.NATIVE_CACHE_ROOT) {
|
|
53
|
+
const configured = configuredCacheDir();
|
|
54
|
+
if (configured !== undefined) {
|
|
55
|
+
const dir = configured;
|
|
15
56
|
try {
|
|
16
|
-
|
|
57
|
+
// Held to the same 0700 bar as the default location: a `.node` is loaded
|
|
58
|
+
// out of here. Unlike NX_SOCKET_DIR it is not additionally refused for
|
|
59
|
+
// naming one of Nx's own roots, which is the only case that throws.
|
|
60
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(dir), { recursive: true });
|
|
61
|
+
const established = (0, owned_private_dir_1.ensureOwnedPrivateDir)(dir);
|
|
62
|
+
if (established.status !== 'ok') {
|
|
63
|
+
// The guard's own reason rather than a fixed sentence: `not-created
|
|
64
|
+
// (EACCES)` and `foreign-owner` are exactly what the catch below
|
|
65
|
+
// promises to tell apart, and one string for all of them cannot.
|
|
66
|
+
throw new owned_private_dir_1.DirectoryRefusedError(established.refusal);
|
|
67
|
+
}
|
|
68
|
+
return dir;
|
|
17
69
|
}
|
|
18
70
|
catch (e) {
|
|
19
|
-
//
|
|
71
|
+
// Never discard a configured directory silently — the socket directory
|
|
72
|
+
// follows the same rule. A typo, EACCES or EROFS is otherwise
|
|
73
|
+
// indistinguishable from a working cache.
|
|
74
|
+
console.warn(`Nx could not use the configured native file cache directory ${dir} (${e?.code ?? e?.message ?? e}). Loading the native binding in place instead.`);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const userRoot = (0, path_1.dirname)(cacheRoot);
|
|
79
|
+
const sharedRoot = (0, path_1.dirname)(userRoot);
|
|
80
|
+
// Outermost first: the stable shared container must either belong to root or
|
|
81
|
+
// to us, and must be sticky if peers can write there. The uid directory then
|
|
82
|
+
// becomes the owner-only boundary for sockets and native-cache alike.
|
|
83
|
+
if ((0, owned_private_dir_1.ensureSafeSharedRoot)(sharedRoot).status !== 'ok') {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
for (const root of [userRoot, cacheRoot]) {
|
|
87
|
+
if ((0, owned_private_dir_1.ensureOwnedPrivateDir)(root).status !== 'ok') {
|
|
88
|
+
return null;
|
|
20
89
|
}
|
|
21
|
-
return (0, path_1.join)((0, os_1.tmpdir)(), `nx-native-file-cache-${hash.digest('hex').substring(0, 7)}`);
|
|
22
90
|
}
|
|
91
|
+
// Verified, not assumed: this is the directory we load a `.node` out of.
|
|
92
|
+
const versionDir = (0, path_1.join)(cacheRoot, versions_1.nxVersion);
|
|
93
|
+
if ((0, owned_private_dir_1.ensureOwnedPrivateDir)(versionDir).status !== 'ok') {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return versionDir;
|
|
23
97
|
}
|
|
Binary file
|
|
Binary file
|
|
@@ -5,12 +5,15 @@ exports.getCloudUrl = getCloudUrl;
|
|
|
5
5
|
exports.removeTrailingSlash = removeTrailingSlash;
|
|
6
6
|
exports.isNxCloudId = isNxCloudId;
|
|
7
7
|
const nx_json_1 = require("../../config/nx-json");
|
|
8
|
-
const run_command_1 = require("../../tasks-runner/run-command");
|
|
9
8
|
const workspace_root_1 = require("../../utils/workspace-root");
|
|
10
9
|
function getCloudOptions(directory = workspace_root_1.workspaceRoot) {
|
|
10
|
+
// Required lazily: this module is reachable from the @nx/devkit/internal
|
|
11
|
+
// barrel that plugin workers load, and run-command eagerly pulls in the whole
|
|
12
|
+
// task-execution subsystem.
|
|
13
|
+
const { getRunnerOptions, } = require('../../tasks-runner/run-command');
|
|
11
14
|
const nxJson = (0, nx_json_1.readNxJson)(directory);
|
|
12
15
|
// TODO: The default is not always cloud? But it's not handled at the moment
|
|
13
|
-
return
|
|
16
|
+
return getRunnerOptions('default', nxJson, {}, true);
|
|
14
17
|
}
|
|
15
18
|
function getCloudUrl() {
|
|
16
19
|
return removeTrailingSlash(process.env.NX_CLOUD_API || process.env.NRWL_API || `https://cloud.nx.app`);
|
|
@@ -5,7 +5,6 @@ exports.getNxCloudAppOnBoardingUrl = getNxCloudAppOnBoardingUrl;
|
|
|
5
5
|
exports.readNxCloudToken = readNxCloudToken;
|
|
6
6
|
const is_workspace_claimed_1 = require("./is-workspace-claimed");
|
|
7
7
|
const url_shorten_1 = require("./url-shorten");
|
|
8
|
-
const run_command_1 = require("../../tasks-runner/run-command");
|
|
9
8
|
const nx_json_1 = require("../../generators/utils/nx-json");
|
|
10
9
|
async function createNxCloudOnboardingURLForWelcomeApp(tree, token) {
|
|
11
10
|
token = token || readNxCloudToken(tree);
|
|
@@ -22,7 +21,11 @@ async function getNxCloudAppOnBoardingUrl(token) {
|
|
|
22
21
|
return onboardingUrl;
|
|
23
22
|
}
|
|
24
23
|
function readNxCloudToken(tree) {
|
|
24
|
+
// Required lazily: this module is re-exported from the @nx/devkit/internal
|
|
25
|
+
// barrel that plugin workers load, and run-command eagerly pulls in the whole
|
|
26
|
+
// task-execution subsystem.
|
|
27
|
+
const { getRunnerOptions, } = require('../../tasks-runner/run-command');
|
|
25
28
|
const nxJson = (0, nx_json_1.readNxJson)(tree);
|
|
26
|
-
const { accessToken, nxCloudId } =
|
|
29
|
+
const { accessToken, nxCloudId } = getRunnerOptions('default', nxJson, {}, true);
|
|
27
30
|
return accessToken || nxCloudId;
|
|
28
31
|
}
|
|
@@ -12,6 +12,16 @@ const project_graph_1 = require("../../../config/project-graph");
|
|
|
12
12
|
const file_hasher_1 = require("../../../hasher/file-hasher");
|
|
13
13
|
const project_graph_builder_1 = require("../../../project-graph/project-graph-builder");
|
|
14
14
|
const json_1 = require("../../../utils/json");
|
|
15
|
+
// Highest bun.lock version this parser has been verified against:
|
|
16
|
+
// - 1: workspace packages are no longer listed with their dependencies
|
|
17
|
+
// - 2: identical content, stricter validation in Bun's own reader
|
|
18
|
+
// - 3: values in "overrides" may be objects holding rules scoped to a parent
|
|
19
|
+
// package (`"parent": { "child": "1.0.0" }`) and keys may carry a version
|
|
20
|
+
// selector (`"parent@1"`, `"child@<2"`). This parser never reads
|
|
21
|
+
// "overrides"; the resolved packages are listed in "packages" as before.
|
|
22
|
+
// Newer versions are parsed on a best-effort basis instead of being rejected
|
|
23
|
+
// outright.
|
|
24
|
+
const MAX_KNOWN_LOCKFILE_VERSION = 3;
|
|
15
25
|
const DEPENDENCY_TYPES = [
|
|
16
26
|
'dependencies',
|
|
17
27
|
'devDependencies',
|
|
@@ -356,9 +366,12 @@ function parseLockFile(lockFileContent, lockFileHash) {
|
|
|
356
366
|
if (typeof result.lockfileVersion !== 'number') {
|
|
357
367
|
throw new Error(`Lockfile version must be a number, got ${typeof result.lockfileVersion}`);
|
|
358
368
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
throw new Error(`Unsupported lockfile version ${result.lockfileVersion}.
|
|
369
|
+
if (!Number.isInteger(result.lockfileVersion) ||
|
|
370
|
+
result.lockfileVersion < 0) {
|
|
371
|
+
throw new Error(`Unsupported lockfile version ${result.lockfileVersion}. Lockfile version must be a non-negative integer`);
|
|
372
|
+
}
|
|
373
|
+
if (result.lockfileVersion > MAX_KNOWN_LOCKFILE_VERSION) {
|
|
374
|
+
console.warn(`bun.lock has lockfileVersion ${result.lockfileVersion}, which is newer than the version ${MAX_KNOWN_LOCKFILE_VERSION} this version of Nx was tested with. Attempting to parse it anyway.`);
|
|
362
375
|
}
|
|
363
376
|
}
|
|
364
377
|
if (!result.packages || typeof result.packages !== 'object') {
|
|
@@ -616,7 +629,7 @@ function processPackageForDependencies(packageKey, packageData, lockFile, index,
|
|
|
616
629
|
const deps = packageDependencies[depType];
|
|
617
630
|
if (!deps || typeof deps !== 'object')
|
|
618
631
|
continue;
|
|
619
|
-
const depDependencies = processDependencyEntries(deps, sourceNodeName, index, ctx, workspacePackages
|
|
632
|
+
const depDependencies = processDependencyEntries(deps, packageKey, sourceNodeName, lockFile, index, ctx, workspacePackages);
|
|
620
633
|
dependencies.push(...depDependencies);
|
|
621
634
|
}
|
|
622
635
|
return dependencies;
|
|
@@ -634,12 +647,12 @@ function extractPackageDependencies(packageData) {
|
|
|
634
647
|
}
|
|
635
648
|
return undefined;
|
|
636
649
|
}
|
|
637
|
-
function processDependencyEntries(deps, sourceNodeName, index, ctx, workspacePackages
|
|
650
|
+
function processDependencyEntries(deps, sourcePackageKey, sourceNodeName, lockFile, index, ctx, workspacePackages) {
|
|
638
651
|
const dependencies = [];
|
|
639
652
|
const depsEntries = Object.entries(deps);
|
|
640
653
|
for (const [packageName, versionSpec] of depsEntries) {
|
|
641
654
|
try {
|
|
642
|
-
const dependency = processSingleDependency(packageName, versionSpec, sourceNodeName, index, ctx, workspacePackages
|
|
655
|
+
const dependency = processSingleDependency(packageName, versionSpec, sourcePackageKey, sourceNodeName, lockFile, index, ctx, workspacePackages);
|
|
643
656
|
if (dependency) {
|
|
644
657
|
dependencies.push(dependency);
|
|
645
658
|
}
|
|
@@ -650,7 +663,7 @@ function processDependencyEntries(deps, sourceNodeName, index, ctx, workspacePac
|
|
|
650
663
|
}
|
|
651
664
|
return dependencies;
|
|
652
665
|
}
|
|
653
|
-
function processSingleDependency(packageName, versionSpec, sourceNodeName, index, ctx, workspacePackages
|
|
666
|
+
function processSingleDependency(packageName, versionSpec, sourcePackageKey, sourceNodeName, lockFile, index, ctx, workspacePackages) {
|
|
654
667
|
if (typeof packageName !== 'string' || typeof versionSpec !== 'string') {
|
|
655
668
|
return null;
|
|
656
669
|
}
|
|
@@ -663,14 +676,22 @@ function processSingleDependency(packageName, versionSpec, sourceNodeName, index
|
|
|
663
676
|
}
|
|
664
677
|
let targetPackageName = packageName;
|
|
665
678
|
let targetVersion = versionSpec;
|
|
666
|
-
|
|
667
|
-
|
|
679
|
+
// A "<parent>/<name>" entry records what this parent actually resolved the
|
|
680
|
+
// dependency to. Overrides scoped to a parent (bun.lock v3) can pick a
|
|
681
|
+
// version outside the declared range, so it takes precedence over matching
|
|
682
|
+
// the range against the versions in the lockfile.
|
|
683
|
+
const nestedVersion = resolveNestedVersion(sourcePackageKey, packageName, lockFile);
|
|
684
|
+
const aliasTarget = nestedVersion ? null : resolveAliasTarget(versionSpec);
|
|
685
|
+
if (nestedVersion) {
|
|
686
|
+
targetVersion = nestedVersion;
|
|
687
|
+
}
|
|
688
|
+
else if (aliasTarget) {
|
|
668
689
|
targetPackageName = aliasTarget.packageName;
|
|
669
690
|
targetVersion = aliasTarget.version;
|
|
670
691
|
}
|
|
671
692
|
else {
|
|
672
693
|
// O(1) lookup using index instead of O(n) scan
|
|
673
|
-
const resolvedVersion = findResolvedVersion(packageName, versionSpec, index, manifests);
|
|
694
|
+
const resolvedVersion = findResolvedVersion(packageName, versionSpec, index, lockFile.manifests);
|
|
674
695
|
if (!resolvedVersion) {
|
|
675
696
|
return null;
|
|
676
697
|
}
|
|
@@ -693,6 +714,18 @@ function processSingleDependency(packageName, versionSpec, sourceNodeName, index
|
|
|
693
714
|
return null;
|
|
694
715
|
}
|
|
695
716
|
}
|
|
717
|
+
function resolveNestedVersion(sourcePackageKey, packageName, lockFile) {
|
|
718
|
+
const nestedEntry = lockFile.packages[`${sourcePackageKey}/${packageName}`];
|
|
719
|
+
if (!Array.isArray(nestedEntry) || typeof nestedEntry[0] !== 'string') {
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
const { name, version } = getCachedSpecInfo(nestedEntry[0]);
|
|
723
|
+
// aliases ("alias@npm:real@1.0.0") are resolved to the real package by the caller
|
|
724
|
+
if (name !== packageName || !version || version.startsWith('npm:')) {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
return version;
|
|
728
|
+
}
|
|
696
729
|
function resolveTargetNodeName(targetPackageName, targetVersion, ctx) {
|
|
697
730
|
const hoistedNodeName = `npm:${targetPackageName}`;
|
|
698
731
|
const versionedNodeName = `npm:${targetPackageName}@${targetVersion}`;
|