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,496 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPackageScope = getPackageScope;
|
|
4
|
+
exports.nerfDart = nerfDart;
|
|
5
|
+
exports.requestNerfDart = requestNerfDart;
|
|
6
|
+
exports.normalizeNpmConfigKey = normalizeNpmConfigKey;
|
|
7
|
+
exports.readNpmConfigEnv = readNpmConfigEnv;
|
|
8
|
+
exports.mergeNpmConfigEnv = mergeNpmConfigEnv;
|
|
9
|
+
exports.ignoresNpmConfigEnv = ignoresNpmConfigEnv;
|
|
10
|
+
exports.setRegistry = setRegistry;
|
|
11
|
+
exports.setScopedRegistry = setScopedRegistry;
|
|
12
|
+
exports.setAuthToken = setAuthToken;
|
|
13
|
+
exports.setAuthIdent = setAuthIdent;
|
|
14
|
+
exports.setClientCertificate = setClientCertificate;
|
|
15
|
+
exports.setCafile = setCafile;
|
|
16
|
+
exports.setStrictSsl = setStrictSsl;
|
|
17
|
+
exports.setProxies = setProxies;
|
|
18
|
+
exports.ancestorDirectories = ancestorDirectories;
|
|
19
|
+
exports.expandNpmEnvVars = expandNpmEnvVars;
|
|
20
|
+
exports.escapeNpmEnvExpr = escapeNpmEnvExpr;
|
|
21
|
+
exports.expandEnvVars = expandEnvVars;
|
|
22
|
+
exports.expandYarnEnvVars = expandYarnEnvVars;
|
|
23
|
+
exports.expandPnpmEnvVars = expandPnpmEnvVars;
|
|
24
|
+
exports.bridgePnpmEnvVars = bridgePnpmEnvVars;
|
|
25
|
+
exports.unresolvedPnpmEnvVars = unresolvedPnpmEnvVars;
|
|
26
|
+
exports.pnpmEnvVarsResolve = pnpmEnvVarsResolve;
|
|
27
|
+
exports.readEnvVar = readEnvVar;
|
|
28
|
+
exports.readExpandedKey = readExpandedKey;
|
|
29
|
+
exports.registryKeysFor = registryKeysFor;
|
|
30
|
+
exports.hasCredentialFor = hasCredentialFor;
|
|
31
|
+
exports.warnNativeCredential = warnNativeCredential;
|
|
32
|
+
const path_1 = require("path");
|
|
33
|
+
const semver_1 = require("semver");
|
|
34
|
+
const logger_1 = require("../logger");
|
|
35
|
+
function getPackageScope(packageName) {
|
|
36
|
+
if (packageName.startsWith('@')) {
|
|
37
|
+
const slash = packageName.indexOf('/');
|
|
38
|
+
if (slash > 0) {
|
|
39
|
+
return packageName.slice(0, slash);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Converts a registry URL into npm's nerf-dart key prefix (host + directory
|
|
46
|
+
* path), e.g. `https://r.example.com/npm/` -> `//r.example.com/npm/`.
|
|
47
|
+
* See https://github.com/npm/cli/blob/bb056c85059cfb39514614e31abba09f20ac1612/workspaces/config/lib/nerf-dart.js#L12-L17
|
|
48
|
+
*/
|
|
49
|
+
function nerfDart(registryUrl) {
|
|
50
|
+
try {
|
|
51
|
+
const url = new URL(registryUrl);
|
|
52
|
+
const dir = url.pathname.endsWith('/')
|
|
53
|
+
? url.pathname
|
|
54
|
+
: url.pathname.slice(0, url.pathname.lastIndexOf('/') + 1);
|
|
55
|
+
return `//${url.host}${dir}`;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Where npm and pnpm both begin a lookup for `registry`, and what
|
|
63
|
+
* registryKeysFor climbs from. Both append the trailing slash a registry path is
|
|
64
|
+
* missing before darting (npm darts the request URI; pnpm does it in
|
|
65
|
+
* getAuthHeaderByURI and pickSettingByUrl), so the walk starts at the request's
|
|
66
|
+
* own directory and still reaches a setting pinned to `//h/api/npm/` for a
|
|
67
|
+
* request to `https://h/api/npm`, which the plain dart begins above.
|
|
68
|
+
*
|
|
69
|
+
* A registry URL carrying a query or a fragment lands back on the plain dart:
|
|
70
|
+
* npm builds its request URI by concatenation, so the package name joins the
|
|
71
|
+
* query rather than the path, and its walk never reaches the deeper directory.
|
|
72
|
+
*/
|
|
73
|
+
function requestNerfDart(registry) {
|
|
74
|
+
return nerfDart(registry.endsWith('/') ? registry : `${registry}/`);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The setting name npm resolves an environment key to, null for a key npm does
|
|
78
|
+
* not read.
|
|
79
|
+
* See https://github.com/npm/cli/blob/bb056c85059cfb39514614e31abba09f20ac1612/workspaces/config/lib/index.js#L345-L356
|
|
80
|
+
*/
|
|
81
|
+
function npmConfigSetting(envKey) {
|
|
82
|
+
if (!/^npm_config_/i.test(envKey)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const key = envKey.slice('npm_config_'.length);
|
|
86
|
+
return key.startsWith('//') ? key : normalizeNpmConfigKey(key);
|
|
87
|
+
}
|
|
88
|
+
/** npm's key rewrite: non-leading `_` to `-`, then lowercased. */
|
|
89
|
+
function normalizeNpmConfigKey(key) {
|
|
90
|
+
return key.replace(/(?!^)_/g, '-').toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The value npm resolves for `setting` out of an environment: the last non-empty
|
|
94
|
+
* `npm_config_*` spelling wins (loadEnv). `setting` is the name npm looks the
|
|
95
|
+
* value up under, so a scope npm rewrites (`@my_scope`) finds nothing.
|
|
96
|
+
*/
|
|
97
|
+
function readNpmConfigEnv(env, setting) {
|
|
98
|
+
let value;
|
|
99
|
+
for (const [key, candidate] of Object.entries(env)) {
|
|
100
|
+
if (candidate && npmConfigSetting(key) === setting) {
|
|
101
|
+
value = candidate;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
const BRIDGED_SETTINGS = new Set([
|
|
107
|
+
'registry',
|
|
108
|
+
'ca',
|
|
109
|
+
'cafile',
|
|
110
|
+
'cert',
|
|
111
|
+
'key',
|
|
112
|
+
'strict-ssl',
|
|
113
|
+
'proxy',
|
|
114
|
+
'https-proxy',
|
|
115
|
+
'noproxy',
|
|
116
|
+
]);
|
|
117
|
+
/**
|
|
118
|
+
* Whether `setting` is one this module resolves on the package manager's behalf.
|
|
119
|
+
* `userconfig` is deliberately absent: it selects npm's own config file rather
|
|
120
|
+
* than a value the package manager resolves, and npm reading its own .npmrc is
|
|
121
|
+
* outside what the overlay reproduces.
|
|
122
|
+
*/
|
|
123
|
+
function isBridgedSetting(setting) {
|
|
124
|
+
return (setting.startsWith('//') ||
|
|
125
|
+
setting.endsWith(':registry') ||
|
|
126
|
+
BRIDGED_SETTINGS.has(setting));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Merges an npm_config_* overlay into the environment for a spawned npm, leaving
|
|
130
|
+
* one non-empty spelling per setting: the overlay's where it carries the setting,
|
|
131
|
+
* otherwise the ambient one npm itself would resolve. npm reads its env tier
|
|
132
|
+
* last-write-wins over the received key order, and both macOS `/bin/sh` and npm's
|
|
133
|
+
* own shell launcher rebuild that order, so a setting left spelled two ways
|
|
134
|
+
* (`NPM_CONFIG_REGISTRY` beside `npm_config_registry`) goes to whichever one they
|
|
135
|
+
* emit last instead of to the value resolved here.
|
|
136
|
+
*
|
|
137
|
+
* `managerIgnoresEnv` says which settings the package manager resolves without
|
|
138
|
+
* reading `npm_config_*`. Bridged settings it answers true for are dropped even
|
|
139
|
+
* where the overlay claims nothing: npm's env tier sits above every file, so
|
|
140
|
+
* leaving one in place stops npm from reaching the .npmrc chain the package
|
|
141
|
+
* manager itself resolved from. Settings outside the bridged set stay ambient
|
|
142
|
+
* either way.
|
|
143
|
+
*/
|
|
144
|
+
function mergeNpmConfigEnv(baseEnv, overlay, managerIgnoresEnv = IGNORES_NONE) {
|
|
145
|
+
const overlaid = new Set(Object.keys(overlay).map(npmConfigSetting).filter(Boolean));
|
|
146
|
+
const merged = {};
|
|
147
|
+
const keptSpelling = new Map();
|
|
148
|
+
for (const [key, value] of Object.entries(baseEnv)) {
|
|
149
|
+
const setting = npmConfigSetting(key);
|
|
150
|
+
if (setting === null) {
|
|
151
|
+
merged[key] = value;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// Even an empty ambient entry goes when the overlay carries the setting: a
|
|
155
|
+
// Windows environment is case-insensitive, and only the first spelling in
|
|
156
|
+
// it reaches the child, which would be this one rather than the overlay's.
|
|
157
|
+
if (overlaid.has(setting)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (managerIgnoresEnv(setting) && isBridgedSetting(setting)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// npm skips an empty value, so it neither overrides nor competes.
|
|
164
|
+
if (!value) {
|
|
165
|
+
merged[key] = value;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const superseded = keptSpelling.get(setting);
|
|
169
|
+
if (superseded !== undefined) {
|
|
170
|
+
delete merged[superseded];
|
|
171
|
+
}
|
|
172
|
+
keptSpelling.set(setting, key);
|
|
173
|
+
merged[key] = value;
|
|
174
|
+
}
|
|
175
|
+
return { ...merged, ...overlay };
|
|
176
|
+
}
|
|
177
|
+
const IGNORES_NONE = () => false;
|
|
178
|
+
const IGNORES_ALL = () => true;
|
|
179
|
+
// pnpm 11.6.0's readUrlScopedEnvConfig reads a `p?npm_config_//<dart>:<key>`
|
|
180
|
+
// entry from the environment again, except `:tokenHelper`, which it refuses to
|
|
181
|
+
// take from there. Named settings stay on pnpm's own `PNPM_CONFIG_*` prefix.
|
|
182
|
+
const IGNORES_ALL_BUT_URL_SCOPED = (setting) => !setting.startsWith('//') || setting.endsWith(':tokenHelper');
|
|
183
|
+
/**
|
|
184
|
+
* The settings the package manager resolves without reading `npm_config_*`, as
|
|
185
|
+
* a predicate over setting names. A bridged setting it returns true for is one
|
|
186
|
+
* the spawned npm never receives from the ambient environment; settings outside
|
|
187
|
+
* the bridged set it has no say over. pnpm reads them all up to 10.x and stops at 11.0.0,
|
|
188
|
+
* which switched to its own `PNPM_CONFIG_*` prefix, except that 11.6.0 restored
|
|
189
|
+
* the URL-scoped credential keys; yarn berry has never read any; npm reads them by
|
|
190
|
+
* definition, and bun reads them for the settings this module bridges.
|
|
191
|
+
*
|
|
192
|
+
* An undetermined or unparseable version answers false for every setting:
|
|
193
|
+
* bridging is skipped or falls open there anyway, so the ambient environment
|
|
194
|
+
* stays as it is.
|
|
195
|
+
*/
|
|
196
|
+
function ignoresNpmConfigEnv(packageManager, packageManagerVersion) {
|
|
197
|
+
const version = packageManagerVersion ? (0, semver_1.parse)(packageManagerVersion) : null;
|
|
198
|
+
if (!version) {
|
|
199
|
+
return IGNORES_NONE;
|
|
200
|
+
}
|
|
201
|
+
switch (packageManager) {
|
|
202
|
+
case 'npm':
|
|
203
|
+
case 'bun':
|
|
204
|
+
return IGNORES_NONE;
|
|
205
|
+
case 'pnpm':
|
|
206
|
+
if (version.major < 11) {
|
|
207
|
+
return IGNORES_NONE;
|
|
208
|
+
}
|
|
209
|
+
return (0, semver_1.gte)(version, '11.6.0') ? IGNORES_ALL_BUT_URL_SCOPED : IGNORES_ALL;
|
|
210
|
+
case 'yarn':
|
|
211
|
+
return version.major >= 2 ? IGNORES_ALL : IGNORES_NONE;
|
|
212
|
+
default: {
|
|
213
|
+
// A new PackageManager member fails typecheck here until classified above;
|
|
214
|
+
// callers outside a fall-open catch keep the ambient env instead of throwing.
|
|
215
|
+
const _exhaustive = packageManager;
|
|
216
|
+
return IGNORES_NONE;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function setRegistry(env, url) {
|
|
221
|
+
env['npm_config_registry'] = url;
|
|
222
|
+
}
|
|
223
|
+
function setScopedRegistry(env, scope, url) {
|
|
224
|
+
env[`npm_config_${scope}:registry`] = url;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Keyed on the registry's own directory rather than the parent a path missing
|
|
228
|
+
* its trailing slash darts to, so two registries under one parent keep separate
|
|
229
|
+
* keys instead of handing each other's credential out. The same holds for the
|
|
230
|
+
* two sinks below.
|
|
231
|
+
*/
|
|
232
|
+
function setAuthToken(env, registryUrl, token) {
|
|
233
|
+
const dart = requestNerfDart(registryUrl);
|
|
234
|
+
if (dart) {
|
|
235
|
+
env[`npm_config_${dart}:_authToken`] = token;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/** `_auth` carries base64(user:pass). */
|
|
239
|
+
function setAuthIdent(env, registryUrl, base64Ident) {
|
|
240
|
+
const dart = requestNerfDart(registryUrl);
|
|
241
|
+
if (dart) {
|
|
242
|
+
env[`npm_config_${dart}:_auth`] = base64Ident;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* npm presents a client certificate only when both halves are configured, so
|
|
247
|
+
* they are set together; each is a path, not the material itself.
|
|
248
|
+
* See https://github.com/npm/npm-registry-fetch/blob/v19.1.1/lib/auth.js#L170
|
|
249
|
+
*/
|
|
250
|
+
function setClientCertificate(env, registryUrl, certfile, keyfile) {
|
|
251
|
+
const dart = requestNerfDart(registryUrl);
|
|
252
|
+
if (dart) {
|
|
253
|
+
env[`npm_config_${dart}:certfile`] = certfile;
|
|
254
|
+
env[`npm_config_${dart}:keyfile`] = keyfile;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function setCafile(env, path) {
|
|
258
|
+
env['npm_config_cafile'] = path;
|
|
259
|
+
}
|
|
260
|
+
function setStrictSsl(env, value) {
|
|
261
|
+
env['npm_config_strict_ssl'] = String(value);
|
|
262
|
+
}
|
|
263
|
+
function setProxies(env, proxies) {
|
|
264
|
+
if (proxies.httpProxy) {
|
|
265
|
+
env['npm_config_proxy'] = proxies.httpProxy;
|
|
266
|
+
}
|
|
267
|
+
if (proxies.httpsProxy) {
|
|
268
|
+
env['npm_config_https_proxy'] = proxies.httpsProxy;
|
|
269
|
+
}
|
|
270
|
+
if (proxies.noProxy) {
|
|
271
|
+
env['npm_config_noproxy'] = proxies.noProxy;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Directories above `root` (exclusive), nearest first. yarn classic and berry
|
|
276
|
+
* both read rc files from ancestor directories, which npm never sees because
|
|
277
|
+
* its project-config walk stops at the first package.json.
|
|
278
|
+
*/
|
|
279
|
+
function ancestorDirectories(root) {
|
|
280
|
+
const dirs = [];
|
|
281
|
+
let current = (0, path_1.dirname)(root);
|
|
282
|
+
while (true) {
|
|
283
|
+
dirs.push(current);
|
|
284
|
+
const parent = (0, path_1.dirname)(current);
|
|
285
|
+
if (parent === current) {
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
current = parent;
|
|
289
|
+
}
|
|
290
|
+
return dirs;
|
|
291
|
+
}
|
|
292
|
+
const ENV_EXPR = /(?<!\\)(\\*)\$\{([^${}]+)\}/g;
|
|
293
|
+
function replaceEnvExpr(value, resolve, { keepEscaped = false } = {}) {
|
|
294
|
+
return value.replace(ENV_EXPR, (orig, esc, name) => {
|
|
295
|
+
if (esc.length % 2) {
|
|
296
|
+
return keepEscaped ? orig : orig.slice((esc.length + 1) / 2);
|
|
297
|
+
}
|
|
298
|
+
return esc.slice(esc.length / 2) + (resolve(name) ?? `$\{${name}}`);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
const NPM_ENV_EXPR = /(?<!\\)(\\*)\$\{([^${}?]+)(\?)?\}/g;
|
|
302
|
+
/**
|
|
303
|
+
* Resolves `${VAR}` references to the value npm itself ends up with, escapes
|
|
304
|
+
* consumed and the `${VAR?}` form falling back to an empty string. Use it to
|
|
305
|
+
* predict what a value npm reads for itself becomes, not to produce one for it:
|
|
306
|
+
* a bridged value goes through npm's own pass, which expandEnvVars accounts for.
|
|
307
|
+
* The `${VAR?}` form only landed in npm 11.6.0, so against an older spawned npm
|
|
308
|
+
* the prediction resolves a reference that npm itself would leave verbatim.
|
|
309
|
+
* See https://github.com/npm/cli/blob/v11.16.0/workspaces/config/lib/env-replace.js
|
|
310
|
+
*/
|
|
311
|
+
function expandNpmEnvVars(value, env = process.env) {
|
|
312
|
+
return value.replace(NPM_ENV_EXPR, (orig, esc, name, optional) => {
|
|
313
|
+
if (esc.length % 2) {
|
|
314
|
+
return orig.slice((esc.length + 1) / 2);
|
|
315
|
+
}
|
|
316
|
+
const fallback = optional ? '' : `$\{${name}}`;
|
|
317
|
+
return esc.slice(esc.length / 2) + (env[name] ?? fallback);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The value to bridge so that npm's own expansion produces `value`, for a
|
|
322
|
+
* resolution that consumed the package manager's escapes rather than leaving
|
|
323
|
+
* them for npm (a literal a reader never expanded, or an expander whose escape
|
|
324
|
+
* rule is not npm's). Each reference gets an odd run of backslashes, which npm
|
|
325
|
+
* halves back to what it started as. Only what npm's reader would act on is
|
|
326
|
+
* escaped, so a `${` it leaves alone is not turned into a literal backslash.
|
|
327
|
+
*/
|
|
328
|
+
function escapeNpmEnvExpr(value) {
|
|
329
|
+
return value.replace(NPM_ENV_EXPR, (_orig, esc, name, optional) => `${'\\'.repeat(esc.length * 2 + 1)}$\{${name}${optional ?? ''}}`);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Expands `${VAR}` references from the environment the way npm/bun ini readers
|
|
333
|
+
* do. Unknown variables are left verbatim. The result is bridged, so an escaped
|
|
334
|
+
* reference keeps its escape for the spawned npm to consume.
|
|
335
|
+
*/
|
|
336
|
+
function expandEnvVars(value, env = process.env) {
|
|
337
|
+
return replaceEnvExpr(value, (name) => env[name], { keepEscaped: true });
|
|
338
|
+
}
|
|
339
|
+
const YARN_ENV_EXPR = /(\\*)\$\{([^}]+)\}/g;
|
|
340
|
+
/**
|
|
341
|
+
* Expands `${VAR}` the way yarn classic's own envReplace does, which parts from
|
|
342
|
+
* npm's on both halves of its escape rule: an odd run of backslashes keeps
|
|
343
|
+
* every one of them along with the reference, and an even one drops all of them
|
|
344
|
+
* rather than half. A reference it resolves nothing for aborts yarn, so it
|
|
345
|
+
* throws here into the caller's fall-open.
|
|
346
|
+
* See https://github.com/yarnpkg/yarn/blob/v1.22.22/src/registries/npm-registry.js
|
|
347
|
+
*/
|
|
348
|
+
function expandYarnEnvVars(value, env = process.env) {
|
|
349
|
+
return value.replace(YARN_ENV_EXPR, (orig, esc, name) => {
|
|
350
|
+
if (esc.length % 2) {
|
|
351
|
+
return orig;
|
|
352
|
+
}
|
|
353
|
+
const resolved = env[name];
|
|
354
|
+
if (resolved === undefined) {
|
|
355
|
+
throw new Error(`Failed to replace env in config: ${orig}`);
|
|
356
|
+
}
|
|
357
|
+
return resolved;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
const PNPM_ENV_DEFAULT = /([^:-]+)(:?)-(.+)/;
|
|
361
|
+
/**
|
|
362
|
+
* One `${...}` reference as pnpm's getEnvValue resolves it: the variable, or the
|
|
363
|
+
* `${VAR-default}` fallback and its `${VAR:-default}` form, which falls back for
|
|
364
|
+
* an empty value too and not just an unset one. Undefined for a reference pnpm
|
|
365
|
+
* finds nothing for, which is what its two readers part ways over.
|
|
366
|
+
*/
|
|
367
|
+
function resolvePnpmEnvValue(name, env) {
|
|
368
|
+
const matched = name.match(PNPM_ENV_DEFAULT);
|
|
369
|
+
if (!matched) {
|
|
370
|
+
return env[name];
|
|
371
|
+
}
|
|
372
|
+
const [, variableName, colon, fallback] = matched;
|
|
373
|
+
const resolved = env[variableName];
|
|
374
|
+
if (resolved === undefined) {
|
|
375
|
+
return fallback;
|
|
376
|
+
}
|
|
377
|
+
return !resolved && colon ? fallback : resolved;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Expands `${VAR}` the way pnpm's @pnpm/config.env-replace does. A reference
|
|
381
|
+
* that resolves to nothing becomes an empty string, matching the envReplaceLossy
|
|
382
|
+
* reader pnpm takes its config through from 11.0.0; keeping it verbatim would
|
|
383
|
+
* put a literal `${VAR}` on the wire as if it were a credential. Below 11 the
|
|
384
|
+
* reader throws instead and the whole file goes with it (readPnpmNpmrcMap), so
|
|
385
|
+
* on that line nothing reaching this carries an unresolvable reference.
|
|
386
|
+
*
|
|
387
|
+
* This is what pnpm itself ends up with, escapes consumed. Use it for a key,
|
|
388
|
+
* which nothing expands a second time, and for a value compared against pnpm's
|
|
389
|
+
* own resolution; a value handed to the spawned npm goes through
|
|
390
|
+
* bridgePnpmEnvVars instead.
|
|
391
|
+
*/
|
|
392
|
+
function expandPnpmEnvVars(value, env = process.env) {
|
|
393
|
+
return replaceEnvExpr(value, (name) => resolvePnpmEnvValue(name, env) ?? '');
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* The same expansion in the form to hand the spawned npm: every `${VAR}` left in
|
|
397
|
+
* what pnpm resolved is escaped, so npm reproduces it instead of expanding a
|
|
398
|
+
* reference pnpm would have sent literally, whether that reference is one pnpm
|
|
399
|
+
* kept escaped or one a variable's own value carries.
|
|
400
|
+
*
|
|
401
|
+
* The escaping runs over pnpm's whole result rather than per reference, because
|
|
402
|
+
* a resolved value ending in a backslash joins the escape run of the reference
|
|
403
|
+
* behind it. Escaping each piece on its own leaves npm reading the merged run,
|
|
404
|
+
* whose parity says expand where pnpm's said keep.
|
|
405
|
+
*/
|
|
406
|
+
function bridgePnpmEnvVars(value, env = process.env) {
|
|
407
|
+
return escapeNpmEnvExpr(expandPnpmEnvVars(value, env));
|
|
408
|
+
}
|
|
409
|
+
/** The `${VAR}` references in `value` that pnpm's throwing reader dies on. */
|
|
410
|
+
function unresolvedPnpmEnvVars(value, env = process.env) {
|
|
411
|
+
const unresolved = [];
|
|
412
|
+
replaceEnvExpr(value, (name) => {
|
|
413
|
+
const resolved = resolvePnpmEnvValue(name, env);
|
|
414
|
+
if (resolved === undefined) {
|
|
415
|
+
unresolved.push(`$\{${name}}`);
|
|
416
|
+
}
|
|
417
|
+
return resolved ?? '';
|
|
418
|
+
});
|
|
419
|
+
return unresolved;
|
|
420
|
+
}
|
|
421
|
+
/** Whether every `${VAR}` in `value` is one pnpm's throwing reader gets past. */
|
|
422
|
+
function pnpmEnvVarsResolve(value, env = process.env) {
|
|
423
|
+
return unresolvedPnpmEnvVars(value, env).length === 0;
|
|
424
|
+
}
|
|
425
|
+
function readEnvVar(env, name) {
|
|
426
|
+
return env[name] ?? env[name.toLowerCase()] ?? env[name.toUpperCase()];
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Reads `map` under `setting`, matching how npm and pnpm both expand a `${VAR}`
|
|
430
|
+
* in an .npmrc key before they look a value up under it; `setting` is already
|
|
431
|
+
* the resolved form to match. Both readers assign in file order, so the last key
|
|
432
|
+
* that `expand` turns into `setting` wins, a literal one included.
|
|
433
|
+
*/
|
|
434
|
+
function readExpandedKey(map, setting, expand) {
|
|
435
|
+
let matched;
|
|
436
|
+
for (const [rawKey, value] of map) {
|
|
437
|
+
const expanded = rawKey.includes('${') ? expand(rawKey) : rawKey;
|
|
438
|
+
if (expanded === setting) {
|
|
439
|
+
matched = value;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return matched;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* The registry keys npm looks a setting up under for `dart`, nearest first: it
|
|
446
|
+
* strips one path segment at a time until only the host is left, which covers
|
|
447
|
+
* the key spelled with and without its trailing slash.
|
|
448
|
+
* See https://github.com/npm/npm-registry-fetch/blob/v18.0.2/lib/auth.js#L16-L26
|
|
449
|
+
*/
|
|
450
|
+
function registryKeysFor(dart) {
|
|
451
|
+
const keys = [];
|
|
452
|
+
let regKey = dart;
|
|
453
|
+
while (regKey.length > '//'.length) {
|
|
454
|
+
keys.push(regKey);
|
|
455
|
+
regKey = regKey.replace(/([^/]+|\/)$/, '');
|
|
456
|
+
}
|
|
457
|
+
return keys;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Whether npm would find a credential for `dart` among the values `read`
|
|
461
|
+
* exposes, at the dart or at any parent of it.
|
|
462
|
+
* See https://github.com/npm/npm-registry-fetch/blob/v18.0.2/lib/auth.js#L34-L49
|
|
463
|
+
*/
|
|
464
|
+
function hasCredentialFor(dart, read) {
|
|
465
|
+
return registryKeysFor(dart).some((regKey) => read(`${regKey}:_authToken`) ||
|
|
466
|
+
read(`${regKey}:_auth`) ||
|
|
467
|
+
(read(`${regKey}:username`) && read(`${regKey}:_password`)) ||
|
|
468
|
+
(read(`${regKey}:certfile`) && read(`${regKey}:keyfile`)));
|
|
469
|
+
}
|
|
470
|
+
const warnedNativeCredentials = new Set();
|
|
471
|
+
/**
|
|
472
|
+
* npm reads the user's own .npmrc chain and the overlay cannot switch that off,
|
|
473
|
+
* so npm can authenticate on a registry the package manager resolved but would
|
|
474
|
+
* have queried anonymously. The fetch still succeeds, so nothing else reports it.
|
|
475
|
+
* Warn only where the overlay is what sent npm to that registry: left to itself
|
|
476
|
+
* npm would have used its own resolution and the same credentials, which is what
|
|
477
|
+
* the user gets from npm anywhere else.
|
|
478
|
+
*
|
|
479
|
+
* `remediation` closes the message, because what the user can safely do about it
|
|
480
|
+
* depends on whether the package manager reads .npmrc at all.
|
|
481
|
+
*/
|
|
482
|
+
function warnNativeCredential(env, dart, packageManager, remediation, npmVisible) {
|
|
483
|
+
// Per registry: one migrate resolves several packages, and a scoped one can
|
|
484
|
+
// send npm to a registry no earlier package reached.
|
|
485
|
+
const warned = `${packageManager}\0${dart}`;
|
|
486
|
+
if (warnedNativeCredentials.has(warned) ||
|
|
487
|
+
env['npm_config_registry'] === undefined ||
|
|
488
|
+
// A credential the overlay carries is the package manager's own and
|
|
489
|
+
// outranks the file, so npm sending it reproduces rather than diverges.
|
|
490
|
+
hasCredentialFor(dart, (key) => env[`npm_config_${key}`]) ||
|
|
491
|
+
!hasCredentialFor(dart, npmVisible)) {
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
warnedNativeCredentials.add(warned);
|
|
495
|
+
logger_1.logger.warn(`npm will send the credential your .npmrc holds for ${dart} when fetching packages. ${packageManager} would not send it for this request. ${remediation}`);
|
|
496
|
+
}
|