zyrk 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/VERSION +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +7 -11
- package/dist/commands/maintenance.d.ts.map +1 -1
- package/dist/commands/maintenance.js +22 -2
- package/dist/fetch/package.d.ts.map +1 -1
- package/dist/fetch/package.js +2 -1
- package/dist/fetch/registry.d.ts +5 -0
- package/dist/fetch/registry.d.ts.map +1 -1
- package/dist/fetch/registry.js +84 -10
- package/dist/install/import-npm-workspace.d.ts +1 -1
- package/dist/install/import-npm-workspace.d.ts.map +1 -1
- package/dist/install/import-npm-workspace.js +1 -1
- package/dist/install/import-npm.d.ts +1 -1
- package/dist/install/import-npm.d.ts.map +1 -1
- package/dist/install/import-npm.js +3 -2
- package/dist/install/registry-policy.d.ts +9 -0
- package/dist/install/registry-policy.d.ts.map +1 -0
- package/dist/install/registry-policy.js +30 -0
- package/dist/install/registry.d.ts.map +1 -1
- package/dist/install/registry.js +18 -13
- package/dist/install/run.d.ts.map +1 -1
- package/dist/install/run.js +11 -3
- package/dist/install/workspace-graph.d.ts.map +1 -1
- package/dist/install/workspace-graph.js +4 -3
- package/dist/install/workspace-install.d.ts.map +1 -1
- package/dist/install/workspace-install.js +12 -3
- package/dist/install/workspace-lock.d.ts +1 -1
- package/dist/install/workspace-lock.d.ts.map +1 -1
- package/dist/install/workspace-lock.js +5 -1
- package/dist/lockfile/fingerprints.d.ts +1 -0
- package/dist/lockfile/fingerprints.d.ts.map +1 -1
- package/dist/lockfile/fingerprints.js +3 -0
- package/dist/resolve/resolver.d.ts +1 -0
- package/dist/resolve/resolver.d.ts.map +1 -1
- package/dist/resolve/resolver.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,8 +116,10 @@ Default registry and authentication settings are loaded from user/project
|
|
|
116
116
|
token placeholders are supported. Credentials are restricted to their configured
|
|
117
117
|
scheme, host, port, and path; redirects cannot expand that scope. Use
|
|
118
118
|
`--registry=https://your-registry.example/` on install for an explicit registry.
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
Scoped registries route metadata, exact sources, imports and tool commands by
|
|
120
|
+
the real package name, including aliases. Advisory requests are partitioned by
|
|
121
|
+
registry; private names never fall back to a public endpoint. Disabled TLS
|
|
122
|
+
verification is rejected before lookup. Git sources, non-workspace local sources, and overrides remain unsupported;
|
|
121
123
|
they fail explicitly. Optional dependencies incompatible with the selected platform
|
|
122
124
|
are omitted; missing packages, integrity failures, and other optional failures
|
|
123
125
|
remain errors. Platform selection is recorded in the lock. macOS, Windows, and
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v0.5.
|
|
1
|
+
v0.5.1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAoEA,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAwEF,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAqZjB"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { installedRegistryConfig } from "../install/registry-policy.js";
|
|
1
2
|
/** Self-contained runtime deployment and explicit local Docker commands. */
|
|
2
3
|
import { constants } from "node:fs";
|
|
3
4
|
import { open, copyFile, chmod, lstat, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rename, rm, symlink, writeFile, } from "node:fs/promises";
|
|
@@ -141,16 +142,14 @@ export async function runDeployCommand(options) {
|
|
|
141
142
|
manifestFingerprint(manifest))
|
|
142
143
|
throw error("ZYRK_LOCK_MISMATCH", "Deployment manifest, lock, and installed generation disagree.");
|
|
143
144
|
if (resolved.nodes.length) {
|
|
144
|
-
const
|
|
145
|
-
if (origins.size !== 1)
|
|
146
|
-
throw error("ZYRK_DEPLOY_NONRELOCATABLE", "Mixed-origin deployment requires a validated registry adapter.");
|
|
145
|
+
const registryConfig = installedRegistryConfig(state, resolved.nodes);
|
|
147
146
|
const patches = await loadProjectPatches(project);
|
|
148
147
|
const policy = object(manifest.zyrk) ? manifest.zyrk : {};
|
|
149
148
|
assertFrozenCompatible(doc, {
|
|
150
149
|
manifest: manifestFingerprint(manifest),
|
|
151
150
|
scripts: scriptPolicyFingerprint(policy.scripts),
|
|
152
151
|
config: configFingerprint({
|
|
153
|
-
|
|
152
|
+
...registryConfig,
|
|
154
153
|
linker: "shared",
|
|
155
154
|
platform: currentPlatform(),
|
|
156
155
|
...(Array.isArray(policy.mutablePackages)
|
|
@@ -800,15 +799,12 @@ async function exportWorkspace(options, project, manifest, state, out, parent, f
|
|
|
800
799
|
const policy = object(manifest.zyrk) ? manifest.zyrk : {};
|
|
801
800
|
if (locked.doc.zyrk.scripts !== scriptPolicyFingerprint(policy.scripts))
|
|
802
801
|
throw error("ZYRK_LOCK_MISMATCH", "Workspace deployment build policy changed after installation.");
|
|
803
|
-
const
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (origins.size > 1)
|
|
807
|
-
throw error("ZYRK_DEPLOY_NONRELOCATABLE", "Mixed-origin workspace export requires a validated registry adapter.");
|
|
808
|
-
if (origins.size === 1) {
|
|
802
|
+
const registryNodesForPolicy = locked.graph.nodes.filter((n) => n.kind === "registry");
|
|
803
|
+
if (registryNodesForPolicy.length || state.registryConfig !== undefined) {
|
|
804
|
+
const registryConfig = installedRegistryConfig(state, registryNodesForPolicy);
|
|
809
805
|
const patches = await loadProjectPatches(project);
|
|
810
806
|
const expected = configFingerprint({
|
|
811
|
-
|
|
807
|
+
...registryConfig,
|
|
812
808
|
linker: "shared",
|
|
813
809
|
platform: currentPlatform(),
|
|
814
810
|
...(Array.isArray(policy.mutablePackages)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../src/commands/maintenance.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvE,QAAA,MAAM,UAAU,YAAI,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAC5E,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IAChD,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,QAAQ,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAUF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,GAAG,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../src/commands/maintenance.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASvE,QAAA,MAAM,UAAU,YAAI,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAC5E,KAAK,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IAChD,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,QAAQ,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAUF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,GAAG,WAAW,CAAC,CAgQvC"}
|
|
@@ -126,6 +126,7 @@ export async function runMaintenanceCommand(options) {
|
|
|
126
126
|
scripts: scriptPolicyFingerprint(object(manifest.zyrk) ? manifest.zyrk.scripts : undefined),
|
|
127
127
|
config: configFingerprint({
|
|
128
128
|
registry: options.registry.origin,
|
|
129
|
+
registries: options.registry.scopedRegistries,
|
|
129
130
|
linker: "shared",
|
|
130
131
|
platform: currentPlatform(),
|
|
131
132
|
...(object(manifest.zyrk) && Array.isArray(manifest.zyrk.mutablePackages)
|
|
@@ -146,7 +147,7 @@ export async function runMaintenanceCommand(options) {
|
|
|
146
147
|
: lockedGraph(lock.doc).nodes;
|
|
147
148
|
const packages = Object.create(null);
|
|
148
149
|
for (const node of graphNodes) {
|
|
149
|
-
if (node.origin !== options.registry.
|
|
150
|
+
if (node.origin !== options.registry.originFor(node.name))
|
|
150
151
|
throw new ZyrkError("ZYRK_POLICY_DENIED", "Cannot audit a graph from a different registry origin.", {
|
|
151
152
|
remedy: "Select the registry recorded by the lockfile before sending dependency names.",
|
|
152
153
|
});
|
|
@@ -158,7 +159,26 @@ export async function runMaintenanceCommand(options) {
|
|
|
158
159
|
return base;
|
|
159
160
|
let response;
|
|
160
161
|
try {
|
|
161
|
-
|
|
162
|
+
const groups = new Map();
|
|
163
|
+
for (const [name, versions] of Object.entries(packages)) {
|
|
164
|
+
const client = options.registry.forPackage(name);
|
|
165
|
+
let selected = groups.get(client);
|
|
166
|
+
if (!selected) {
|
|
167
|
+
selected = Object.create(null);
|
|
168
|
+
groups.set(client, selected);
|
|
169
|
+
}
|
|
170
|
+
selected[name] = versions;
|
|
171
|
+
}
|
|
172
|
+
const replies = await Promise.all([...groups].map(async ([client, selected]) => {
|
|
173
|
+
const reply = await client.auditAdvisories(selected);
|
|
174
|
+
if (!object(reply) ||
|
|
175
|
+
Object.keys(reply).some((name) => !Object.hasOwn(selected, name)))
|
|
176
|
+
return null;
|
|
177
|
+
return reply;
|
|
178
|
+
}));
|
|
179
|
+
response = replies.some((reply) => reply === null)
|
|
180
|
+
? null
|
|
181
|
+
: Object.assign({}, ...replies);
|
|
162
182
|
}
|
|
163
183
|
catch {
|
|
164
184
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/fetch/package.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAA6B,MAAM,eAAe,CAAC;AAE1E;;2EAE2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,IAAI,IAAI,CAAC;IACnB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACjB,GACL;IAAE,SAAS,EAAE,cAAc,CAAC;IAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,KAAK,IAAI,IAAI,CAAA;CAAE,CAuDzE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../src/fetch/package.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAA6B,MAAM,eAAe,CAAC;AAE1E;;2EAE2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,IAAI,IAAI,CAAC;IACnB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACjB,GACL;IAAE,SAAS,EAAE,cAAc,CAAC;IAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,KAAK,IAAI,IAAI,CAAA;CAAE,CAuDzE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAgJxB"}
|
package/dist/fetch/package.js
CHANGED
|
@@ -72,7 +72,8 @@ export function createFetchOperation(options = {}) {
|
|
|
72
72
|
* Callers resolve the version first; this function never guesses.
|
|
73
73
|
*/
|
|
74
74
|
export async function fetchAndCommitSource(options) {
|
|
75
|
-
const { store,
|
|
75
|
+
const { store, txn, name, version } = options;
|
|
76
|
+
const registry = options.registry.forPackage(name);
|
|
76
77
|
const label = `${name}@${version}`;
|
|
77
78
|
// ---- 1. Metadata: exact version entry for the resolved identity ----
|
|
78
79
|
options.operation?.checkpoint();
|
package/dist/fetch/registry.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface Packument {
|
|
|
48
48
|
modified?: string;
|
|
49
49
|
}
|
|
50
50
|
export interface RegistryClientOptions {
|
|
51
|
+
scopedRegistries?: Readonly<Record<string, string>>;
|
|
51
52
|
/** Registry base URL; must be http(s). Trailing slash optional. */
|
|
52
53
|
registry: string;
|
|
53
54
|
userAgent: string;
|
|
@@ -83,6 +84,10 @@ export declare class RegistryClient {
|
|
|
83
84
|
/** Credential-free registry origin; participates in source identity (§8.1). */
|
|
84
85
|
get origin(): string;
|
|
85
86
|
get registry(): string;
|
|
87
|
+
/** Routing always follows the real package name, including npm aliases. */
|
|
88
|
+
forPackage(name: string): RegistryClient;
|
|
89
|
+
originFor(name: string): string;
|
|
90
|
+
get scopedRegistries(): Readonly<Record<string, string>>;
|
|
86
91
|
/** Fetch the (abbreviated) packument for an exact package name. */
|
|
87
92
|
packument(name: string, options?: {
|
|
88
93
|
signal?: AbortSignal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/fetch/registry.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/fetch/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch/registry.js
CHANGED
|
@@ -22,6 +22,8 @@ export const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
|
|
|
22
22
|
/** npm's abbreviated packument media type, used for installs. */
|
|
23
23
|
const INSTALL_V1_ACCEPT = "application/vnd.npm.install-v1+json";
|
|
24
24
|
export class RegistryClient {
|
|
25
|
+
#routeBoundaries = [];
|
|
26
|
+
#scopedClients = new Map();
|
|
25
27
|
#registry;
|
|
26
28
|
#origin;
|
|
27
29
|
#userAgent;
|
|
@@ -30,7 +32,7 @@ export class RegistryClient {
|
|
|
30
32
|
#maxTarballBytes;
|
|
31
33
|
#maxMetadataBytes;
|
|
32
34
|
#maxTotalMetadataBytes;
|
|
33
|
-
#
|
|
35
|
+
#metadataBudget = { bytes: 0 };
|
|
34
36
|
#maxMetadataVersions;
|
|
35
37
|
#requestDeadlineMs;
|
|
36
38
|
#signal;
|
|
@@ -59,13 +61,51 @@ export class RegistryClient {
|
|
|
59
61
|
base.timeout = options.timeoutMs;
|
|
60
62
|
const parsed = safeTransportOptions(options.fetchOptions ?? {}, registry);
|
|
61
63
|
this.#fetchOptions = { ...base, ...parsed.transport, strictSSL: true };
|
|
62
|
-
|
|
64
|
+
const boundary = new URL(registry);
|
|
65
|
+
this.#credentials = parsed.credentials.filter(({ scope }) => scope.origin === boundary.origin &&
|
|
66
|
+
(scope.pathname.startsWith(boundary.pathname) ||
|
|
67
|
+
boundary.pathname.startsWith(scope.pathname)));
|
|
63
68
|
this.#maxMetadataBytes = positiveLimit(options.maxMetadataBytes ?? 32 * 1024 * 1024, "maxMetadataBytes");
|
|
64
69
|
this.#maxTotalMetadataBytes = positiveLimit(options.maxTotalMetadataBytes ?? 128 * 1024 * 1024, "maxTotalMetadataBytes");
|
|
65
70
|
this.#maxMetadataVersions = positiveLimit(options.maxMetadataVersions ?? 100_000, "maxMetadataVersions");
|
|
66
71
|
this.#requestDeadlineMs = positiveLimit(options.requestDeadlineMs ?? 120_000, "requestDeadlineMs");
|
|
67
72
|
positiveLimit(this.#maxTarballBytes, "maxTarballBytes");
|
|
68
73
|
this.#signal = options.signal;
|
|
74
|
+
const { scopedRegistries, ...baseOptions } = options;
|
|
75
|
+
for (const [scope, selected] of Object.entries(scopedRegistries ?? {}).sort(([a], [b]) => a.localeCompare(b))) {
|
|
76
|
+
if (!/^@[a-z0-9][a-z0-9._-]*$/.test(scope))
|
|
77
|
+
throw new ZyrkError("ZYRK_POLICY_DENIED", "Invalid scoped registry name.", { remedy: "Use an npm @scope registry setting." });
|
|
78
|
+
const { headers, ...childFetchOptions } = options.fetchOptions ?? {};
|
|
79
|
+
const client = new RegistryClient({
|
|
80
|
+
...baseOptions,
|
|
81
|
+
fetchOptions: childFetchOptions,
|
|
82
|
+
registry: selected,
|
|
83
|
+
});
|
|
84
|
+
// Raw Authorization headers are scoped once to the original registry.
|
|
85
|
+
// Cloning must never reinterpret them as credentials for a child host.
|
|
86
|
+
for (const authorization of Object.values((headers ?? {}))) {
|
|
87
|
+
const originalScope = new URL(registry), childScope = new URL(client.registry);
|
|
88
|
+
if (originalScope.origin === childScope.origin &&
|
|
89
|
+
(originalScope.pathname.startsWith(childScope.pathname) ||
|
|
90
|
+
childScope.pathname.startsWith(originalScope.pathname)))
|
|
91
|
+
client.#credentials.push({ scope: originalScope, authorization });
|
|
92
|
+
}
|
|
93
|
+
client.#credentials.sort((a, b) => b.scope.pathname.length - a.scope.pathname.length);
|
|
94
|
+
client.#metadataBudget = this.#metadataBudget;
|
|
95
|
+
this.#scopedClients.set(scope, client);
|
|
96
|
+
}
|
|
97
|
+
// A containing public registry must not borrow a credential belonging to a
|
|
98
|
+
// narrower configured private registry on the same host. Explicit broad
|
|
99
|
+
// credentials retain their declared scope, including use by child routes.
|
|
100
|
+
const clients = [this, ...this.#scopedClients.values()];
|
|
101
|
+
const boundaries = clients.map((client) => new URL(client.registry));
|
|
102
|
+
for (const client of clients) {
|
|
103
|
+
const own = new URL(client.registry);
|
|
104
|
+
client.#routeBoundaries = boundaries;
|
|
105
|
+
client.#credentials = client.#credentials.filter(({ scope }) => !boundaries.some((boundary) => boundary.origin === scope.origin &&
|
|
106
|
+
boundary.pathname.length > own.pathname.length &&
|
|
107
|
+
scope.pathname.startsWith(boundary.pathname)));
|
|
108
|
+
}
|
|
69
109
|
}
|
|
70
110
|
/** Credential-free registry origin; participates in source identity (§8.1). */
|
|
71
111
|
get origin() {
|
|
@@ -74,9 +114,24 @@ export class RegistryClient {
|
|
|
74
114
|
get registry() {
|
|
75
115
|
return this.#registry;
|
|
76
116
|
}
|
|
117
|
+
/** Routing always follows the real package name, including npm aliases. */
|
|
118
|
+
forPackage(name) {
|
|
119
|
+
validateRegistryPackageName(name);
|
|
120
|
+
return name.startsWith("@")
|
|
121
|
+
? (this.#scopedClients.get(name.slice(0, name.indexOf("/"))) ?? this)
|
|
122
|
+
: this;
|
|
123
|
+
}
|
|
124
|
+
originFor(name) {
|
|
125
|
+
return this.forPackage(name).origin;
|
|
126
|
+
}
|
|
127
|
+
get scopedRegistries() {
|
|
128
|
+
return Object.fromEntries([...this.#scopedClients].map(([scope, client]) => [scope, client.origin]));
|
|
129
|
+
}
|
|
77
130
|
/** Fetch the (abbreviated) packument for an exact package name. */
|
|
78
131
|
async packument(name, options = {}) {
|
|
79
|
-
|
|
132
|
+
const selected = this.forPackage(name);
|
|
133
|
+
if (selected !== this)
|
|
134
|
+
return selected.packument(name, options);
|
|
80
135
|
const url = `${this.#registry}${escapePackageName(name)}`;
|
|
81
136
|
this.#logger?.debug("fetching packument", { name, url });
|
|
82
137
|
let raw;
|
|
@@ -96,6 +151,14 @@ export class RegistryClient {
|
|
|
96
151
|
versions.some((version) => typeof version !== "string"))
|
|
97
152
|
throw new ZyrkError("ZYRK_POLICY_DENIED", "Invalid registry advisory package versions.");
|
|
98
153
|
}
|
|
154
|
+
const routes = new Set(Object.keys(packages).map((name) => this.forPackage(name)));
|
|
155
|
+
if (routes.size > 1)
|
|
156
|
+
throw new ZyrkError("ZYRK_POLICY_DENIED", "Mixed-registry audit requests must be partitioned by registry.", {
|
|
157
|
+
remedy: "Audit each selected registry independently so private names are never disclosed across origins.",
|
|
158
|
+
});
|
|
159
|
+
const selected = [...routes][0];
|
|
160
|
+
if (selected && selected !== this)
|
|
161
|
+
return selected.auditAdvisories(packages, options);
|
|
99
162
|
const body = JSON.stringify(packages);
|
|
100
163
|
if (Buffer.byteLength(body) > this.#maxMetadataBytes)
|
|
101
164
|
throw resourceLimit("advisory request bytes", this.#maxMetadataBytes, "maxMetadataBytes");
|
|
@@ -107,10 +170,10 @@ export class RegistryClient {
|
|
|
107
170
|
}
|
|
108
171
|
}
|
|
109
172
|
#countMetadataBytes(bytes, responseBytes) {
|
|
110
|
-
this.#
|
|
173
|
+
this.#metadataBudget.bytes += bytes;
|
|
111
174
|
if (responseBytes > this.#maxMetadataBytes)
|
|
112
175
|
throw resourceLimit("metadata bytes", this.#maxMetadataBytes, "maxMetadataBytes");
|
|
113
|
-
if (this.#
|
|
176
|
+
if (this.#metadataBudget.bytes > this.#maxTotalMetadataBytes)
|
|
114
177
|
throw resourceLimit("total metadata bytes", this.#maxTotalMetadataBytes, "maxTotalMetadataBytes");
|
|
115
178
|
}
|
|
116
179
|
async #readMetadata(response) {
|
|
@@ -226,6 +289,15 @@ export class RegistryClient {
|
|
|
226
289
|
throw mapFetchError(error, `download tarball for ${options.label}`);
|
|
227
290
|
}
|
|
228
291
|
}
|
|
292
|
+
#insideAdvisoryBoundary(url) {
|
|
293
|
+
const registryScope = new URL(this.#registry);
|
|
294
|
+
return (url.origin === registryScope.origin &&
|
|
295
|
+
url.pathname.startsWith(registryScope.pathname) &&
|
|
296
|
+
!/%(?:2f|5c|2e)/i.test(url.pathname) &&
|
|
297
|
+
!this.#routeBoundaries.some((boundary) => boundary.origin === url.origin &&
|
|
298
|
+
boundary.pathname.length > registryScope.pathname.length &&
|
|
299
|
+
url.pathname.startsWith(boundary.pathname)));
|
|
300
|
+
}
|
|
229
301
|
async #withRequest(url, accept, consume, signal, request = {}) {
|
|
230
302
|
const controller = new AbortController();
|
|
231
303
|
let active;
|
|
@@ -246,6 +318,10 @@ export class RegistryClient {
|
|
|
246
318
|
cancel();
|
|
247
319
|
try {
|
|
248
320
|
let current = parseTarballUrl(url, "registry request");
|
|
321
|
+
if (request.method === "POST" && !this.#insideAdvisoryBoundary(current))
|
|
322
|
+
throw new ZyrkError("ZYRK_FETCH_REFUSED", "Registry advisory endpoint overlaps another configured registry or has an ambiguous path.", {
|
|
323
|
+
remedy: "Use a distinct advisory endpoint within the selected registry's own route.",
|
|
324
|
+
});
|
|
249
325
|
let crossedBoundary = false;
|
|
250
326
|
for (let hop = 0; hop <= 10; hop++) {
|
|
251
327
|
if (controller.signal.aborted)
|
|
@@ -317,10 +393,8 @@ export class RegistryClient {
|
|
|
317
393
|
if (current.protocol === "https:" && next.protocol !== "https:")
|
|
318
394
|
throw new ZyrkError("ZYRK_FETCH_REFUSED", "Registry HTTPS downgrade redirect refused.", { remedy: "Use HTTPS for every registry redirect." });
|
|
319
395
|
if (request.method === "POST") {
|
|
320
|
-
const registryScope = new URL(this.#registry);
|
|
321
396
|
if (![307, 308].includes(active.status) ||
|
|
322
|
-
next
|
|
323
|
-
!next.pathname.startsWith(registryScope.pathname))
|
|
397
|
+
!this.#insideAdvisoryBoundary(next))
|
|
324
398
|
throw new ZyrkError("ZYRK_FETCH_REFUSED", "Registry advisory redirect crosses its authorized endpoint boundary or changes POST semantics.", {
|
|
325
399
|
remedy: "Configure the advisory service directly within the selected registry; private package names are never forwarded outside that boundary.",
|
|
326
400
|
});
|
|
@@ -421,8 +495,8 @@ export function validateRegistryPackageName(name) {
|
|
|
421
495
|
// eslint-disable-next-line no-control-regex
|
|
422
496
|
if (/[\u0000-\u0020\u007f]/.test(name))
|
|
423
497
|
bad("control or whitespace character");
|
|
424
|
-
if (!/^(?:@[
|
|
425
|
-
bad("
|
|
498
|
+
if (!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(name))
|
|
499
|
+
bad("name must use supported lowercase npm package characters");
|
|
426
500
|
for (const segment of name.split("/")) {
|
|
427
501
|
if (segment === "." || segment === "..")
|
|
428
502
|
bad("path-like segment");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NpmLockDoc } from "../lockfile/types.ts";
|
|
2
2
|
import type { WorkspaceProject } from "./workspaces.ts";
|
|
3
3
|
import type { WorkspaceGraph } from "./workspace-graph.ts";
|
|
4
|
-
export declare function importNpmWorkspaceLock(doc: NpmLockDoc, project: WorkspaceProject, origin: string): WorkspaceGraph;
|
|
4
|
+
export declare function importNpmWorkspaceLock(doc: NpmLockDoc, project: WorkspaceProject, origin: string | ((name: string) => string)): WorkspaceGraph;
|
|
5
5
|
//# sourceMappingURL=import-npm-workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-npm-workspace.d.ts","sourceRoot":"","sources":["../../src/install/import-npm-workspace.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"import-npm-workspace.d.ts","sourceRoot":"","sources":["../../src/install/import-npm-workspace.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAC1C,cAAc,CAyThB"}
|
|
@@ -62,7 +62,7 @@ export function importNpmWorkspaceLock(doc, project, origin) {
|
|
|
62
62
|
if (doc.zyrk ||
|
|
63
63
|
![2, 3].includes(doc.lockfileVersion ?? 0) ||
|
|
64
64
|
!doc.packages ||
|
|
65
|
-
!cleanUrl(origin))
|
|
65
|
+
(typeof origin === "string" && !cleanUrl(origin)))
|
|
66
66
|
throw lockMismatch("workspace adoption needs an unannotated npm v2/v3 lock");
|
|
67
67
|
const packages = doc.packages;
|
|
68
68
|
const graph = { nodes: [], importers: {}, omissions: [] };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { NpmLockDoc } from "../lockfile/types.ts";
|
|
2
2
|
import type { FinalizedGraph } from "../resolve/resolver.ts";
|
|
3
|
-
export declare function importNpmLock(doc: NpmLockDoc, requirements: Record<string, string>, origin: string): FinalizedGraph;
|
|
3
|
+
export declare function importNpmLock(doc: NpmLockDoc, requirements: Record<string, string>, origin: string | ((name: string) => string)): FinalizedGraph;
|
|
4
4
|
//# sourceMappingURL=import-npm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-npm.d.ts","sourceRoot":"","sources":["../../src/install/import-npm.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACV,cAAc,EAEf,MAAM,wBAAwB,CAAC;AAKhC,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"import-npm.d.ts","sourceRoot":"","sources":["../../src/install/import-npm.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACV,cAAc,EAEf,MAAM,wBAAwB,CAAC;AAKhC,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAC1C,cAAc,CA4KhB"}
|
|
@@ -32,6 +32,7 @@ export function importNpmLock(doc, requirements, origin) {
|
|
|
32
32
|
if (!entry || entry.link === true || entry.inBundle === true)
|
|
33
33
|
throw lockMismatch("npm lock contains an unsupported linked or bundled selection");
|
|
34
34
|
const request = parseRequirement(edgeName, spec);
|
|
35
|
+
const selectedOrigin = typeof origin === "string" ? origin : origin(request.realName);
|
|
35
36
|
const name = typeof entry.name === "string" ? entry.name : request.realName;
|
|
36
37
|
const integrity = typeof entry.integrity === "string"
|
|
37
38
|
? canonicalStrongSri(entry.integrity)
|
|
@@ -55,13 +56,13 @@ export function importNpmLock(doc, requirements, origin) {
|
|
|
55
56
|
key: `${name}@${entry.version}#${sha512Hex(location).slice(0, 16)}`,
|
|
56
57
|
name,
|
|
57
58
|
version: entry.version,
|
|
58
|
-
origin,
|
|
59
|
+
origin: selectedOrigin,
|
|
59
60
|
integrity,
|
|
60
61
|
sourceId: sourceIdOf({
|
|
61
62
|
sourceType: "registry",
|
|
62
63
|
name,
|
|
63
64
|
version: entry.version,
|
|
64
|
-
origin,
|
|
65
|
+
origin: selectedOrigin,
|
|
65
66
|
integrity,
|
|
66
67
|
}),
|
|
67
68
|
tarballUrl: entry.resolved,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type InstalledRegistryConfig = {
|
|
2
|
+
registry: string;
|
|
3
|
+
registries?: Readonly<Record<string, string>>;
|
|
4
|
+
};
|
|
5
|
+
export declare function installedRegistryConfig(state: Record<string, unknown>, nodes: readonly {
|
|
6
|
+
name: string;
|
|
7
|
+
origin: string;
|
|
8
|
+
}[]): InstalledRegistryConfig;
|
|
9
|
+
//# sourceMappingURL=registry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-policy.d.ts","sourceRoot":"","sources":["../../src/install/registry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/C,CAAC;AACF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,GACjD,uBAAuB,CAqCzB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Credential-free routing captured with the exact installed generation. */
|
|
2
|
+
import { cleanUrl, lockMismatch } from "./lock.js";
|
|
3
|
+
export function installedRegistryConfig(state, nodes) {
|
|
4
|
+
const object = (x) => !!x && typeof x === "object" && !Array.isArray(x);
|
|
5
|
+
const raw = state.registryConfig;
|
|
6
|
+
if (raw === undefined) {
|
|
7
|
+
const origins = new Set(nodes.map((n) => n.origin));
|
|
8
|
+
if (origins.size !== 1)
|
|
9
|
+
throw lockMismatch("legacy installed state has no exact registry routing");
|
|
10
|
+
return { registry: [...origins][0] };
|
|
11
|
+
}
|
|
12
|
+
if (!object(raw) ||
|
|
13
|
+
Object.keys(raw).some((k) => !["registry", "registries"].includes(k)) ||
|
|
14
|
+
typeof raw.registry !== "string" ||
|
|
15
|
+
!cleanUrl(raw.registry) ||
|
|
16
|
+
!object(raw.registries) ||
|
|
17
|
+
Object.entries(raw.registries).some(([scope, url]) => !/^@[a-z0-9][a-z0-9._-]*$/.test(scope) ||
|
|
18
|
+
typeof url !== "string" ||
|
|
19
|
+
!cleanUrl(url)))
|
|
20
|
+
throw lockMismatch("installed registry routing is malformed");
|
|
21
|
+
const registries = raw.registries;
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
const expected = node.name.startsWith("@")
|
|
24
|
+
? (registries[node.name.slice(0, node.name.indexOf("/"))] ?? raw.registry)
|
|
25
|
+
: raw.registry;
|
|
26
|
+
if (node.origin !== expected)
|
|
27
|
+
throw lockMismatch("installed registry routing disagrees with selected sources");
|
|
28
|
+
}
|
|
29
|
+
return { registry: raw.registry, registries };
|
|
30
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/install/registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAKxE,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/install/registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAKxE,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuI1B"}
|
package/dist/install/registry.js
CHANGED
|
@@ -11,6 +11,7 @@ import { cleanUrl } from "./lock.js";
|
|
|
11
11
|
export async function installRegistry(options) {
|
|
12
12
|
let registry = DEFAULT_REGISTRY;
|
|
13
13
|
const auth = {};
|
|
14
|
+
const scopedRegistries = {};
|
|
14
15
|
const home = options.env.HOME ?? os.homedir();
|
|
15
16
|
const project = (await findWorkspaceRoot(options.cwd)) ??
|
|
16
17
|
(await findProjectBoundary(options.cwd)) ??
|
|
@@ -64,9 +65,7 @@ export async function installRegistry(options) {
|
|
|
64
65
|
if (key === "registry")
|
|
65
66
|
registry = value;
|
|
66
67
|
if (/^@.+:registry$/.test(key))
|
|
67
|
-
|
|
68
|
-
remedy: "Use npm for mixed-registry projects; zyrk will not silently fetch a private scope from a public registry.",
|
|
69
|
-
});
|
|
68
|
+
scopedRegistries[key.slice(0, -9)] = value;
|
|
70
69
|
if (key === "strict-ssl" && value === "false")
|
|
71
70
|
throw new ZyrkError("ZYRK_POLICY_DENIED", "Disabling registry TLS verification is not supported.", {
|
|
72
71
|
remedy: "Configure a trusted HTTPS registry with valid TLS certificates.",
|
|
@@ -80,18 +79,24 @@ export async function installRegistry(options) {
|
|
|
80
79
|
options.env.npm_config_registry ??
|
|
81
80
|
options.env.NPM_CONFIG_REGISTRY ??
|
|
82
81
|
registry;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
82
|
+
const validate = (registry) => {
|
|
83
|
+
if (!cleanUrl(registry))
|
|
84
|
+
throw new ZyrkError("ZYRK_POLICY_DENIED", "Registry URL must be HTTP(S) without credentials, query parameters, or fragments.", {
|
|
85
|
+
remedy: "Use a credential-free registry URL and configure URL-scoped credentials separately in .npmrc.",
|
|
86
|
+
});
|
|
87
|
+
const url = new URL(registry);
|
|
88
|
+
if (url.protocol !== "https:" &&
|
|
89
|
+
!["127.0.0.1", "localhost", "[::1]"].includes(url.hostname))
|
|
90
|
+
throw new ZyrkError("ZYRK_POLICY_DENIED", "Remote registries require HTTPS.", {
|
|
91
|
+
remedy: "Select an HTTPS registry; HTTP is limited to loopback development registries.",
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
validate(registry);
|
|
95
|
+
for (const selected of Object.values(scopedRegistries))
|
|
96
|
+
validate(selected);
|
|
93
97
|
return new RegistryClient({
|
|
94
98
|
registry,
|
|
99
|
+
scopedRegistries,
|
|
95
100
|
userAgent: `zyrk/${options.version}`,
|
|
96
101
|
fetchOptions: auth,
|
|
97
102
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAWtB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAgC3C,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EACL,OAAO,GACP,uBAAuB,GACvB,eAAe,GACf,SAAS,GACT,cAAc,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AA6GF,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/install/run.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAWtB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAgC3C,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EACL,OAAO,GACP,uBAAuB,GACvB,eAAe,GACf,SAAS,GACT,cAAc,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AA6GF,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAsxBxB"}
|
package/dist/install/run.js
CHANGED
|
@@ -197,6 +197,7 @@ export async function installProject(options) {
|
|
|
197
197
|
scripts: scriptPolicyFingerprint(scriptPolicy(manifest)),
|
|
198
198
|
config: configFingerprint({
|
|
199
199
|
registry: options.registry.origin,
|
|
200
|
+
registries: options.registry.scopedRegistries,
|
|
200
201
|
linker: "shared",
|
|
201
202
|
platform: currentPlatform(),
|
|
202
203
|
...(object(manifest.zyrk) &&
|
|
@@ -214,7 +215,7 @@ export async function installProject(options) {
|
|
|
214
215
|
if (existing && !existing.zyrk) {
|
|
215
216
|
if (options.frozen || options.offline || specs.length)
|
|
216
217
|
throw lockMismatch("npm-only lockfile requires a non-frozen adoption install before adding packages");
|
|
217
|
-
resolved = importNpmLock(existing, allDeps, options.registry.
|
|
218
|
+
resolved = importNpmLock(existing, allDeps, (name) => options.registry.originFor(name));
|
|
218
219
|
}
|
|
219
220
|
if (existing?.zyrk &&
|
|
220
221
|
specs.length === 0 &&
|
|
@@ -242,6 +243,7 @@ export async function installProject(options) {
|
|
|
242
243
|
resolved = await resolveRequirements({
|
|
243
244
|
provider: {
|
|
244
245
|
origin: options.registry.origin,
|
|
246
|
+
originFor: (name) => options.registry.originFor(name),
|
|
245
247
|
packument: (name) => options.registry.packument(name, {
|
|
246
248
|
signal: operation.operation.signal,
|
|
247
249
|
}),
|
|
@@ -342,7 +344,7 @@ export async function installProject(options) {
|
|
|
342
344
|
if (!packageName(node.name) ||
|
|
343
345
|
!cleanUrl(node.origin) ||
|
|
344
346
|
!cleanUrl(node.tarballUrl) ||
|
|
345
|
-
node.origin !== options.registry.
|
|
347
|
+
node.origin !== options.registry.originFor(node.name))
|
|
346
348
|
throw error("ZYRK_POLICY_DENIED", "Selected source has an unsupported or credential-bearing registry origin or archive URL.");
|
|
347
349
|
}
|
|
348
350
|
const selectedRoots = resolved.roots.filter((r) => !options.omitDev ||
|
|
@@ -458,7 +460,9 @@ export async function installProject(options) {
|
|
|
458
460
|
if (options.offline)
|
|
459
461
|
throw error("ZYRK_OFFLINE_MISSING", `Verified source for ${node.name}@${node.version} is missing from the store.`);
|
|
460
462
|
const tarball = path.join(txn.dir, `${node.sourceId}.tgz`);
|
|
461
|
-
const download = await options.registry
|
|
463
|
+
const download = await options.registry
|
|
464
|
+
.forPackage(node.name)
|
|
465
|
+
.downloadTarball({
|
|
462
466
|
signal: operation.operation.signal,
|
|
463
467
|
onBytes: operation.operation.consumeArchiveBytes,
|
|
464
468
|
url: node.tarballUrl,
|
|
@@ -680,6 +684,10 @@ export async function installProject(options) {
|
|
|
680
684
|
instances: registration.instances,
|
|
681
685
|
activeContexts: registration.contexts,
|
|
682
686
|
lockDigest: sha512Hex(canonicalJson(doc)),
|
|
687
|
+
registryConfig: {
|
|
688
|
+
registry: options.registry.origin,
|
|
689
|
+
registries: options.registry.scopedRegistries,
|
|
690
|
+
},
|
|
683
691
|
graphDigest: digest,
|
|
684
692
|
platform: process.platform,
|
|
685
693
|
arch: process.arch,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-graph.d.ts","sourceRoot":"","sources":["../../src/install/workspace-graph.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EAChB,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACrC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,QAAQ,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACrC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AACvE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACxE,CAAC;AAYF,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"workspace-graph.d.ts","sourceRoot":"","sources":["../../src/install/workspace-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -151,7 +151,8 @@ export async function resolveWorkspaceGraph(project, provider, options = {}) {
|
|
|
151
151
|
const key = `${requirement.realName}@${version}#${sha512Hex(parent.key + "\0" + name).slice(0, 16)}`;
|
|
152
152
|
if (byKey.has(key))
|
|
153
153
|
return key;
|
|
154
|
-
|
|
154
|
+
const origin = provider.originFor?.(requirement.realName) ?? provider.origin;
|
|
155
|
+
if (!cleanUrl(origin) || !cleanUrl(entry.dist.tarball))
|
|
155
156
|
fail("unsafe registry source metadata");
|
|
156
157
|
const bin = typeof entry.bin === "string"
|
|
157
158
|
? { [requirement.realName.split("/").at(-1)]: entry.bin }
|
|
@@ -165,10 +166,10 @@ export async function resolveWorkspaceGraph(project, provider, options = {}) {
|
|
|
165
166
|
sourceType: "registry",
|
|
166
167
|
name: requirement.realName,
|
|
167
168
|
version,
|
|
168
|
-
origin
|
|
169
|
+
origin,
|
|
169
170
|
integrity,
|
|
170
171
|
}),
|
|
171
|
-
origin
|
|
172
|
+
origin,
|
|
172
173
|
integrity,
|
|
173
174
|
tarballUrl: entry.dist.tarball,
|
|
174
175
|
bin,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace-install.d.ts","sourceRoot":"","sources":["../../src/install/workspace-install.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAwH9D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA+pBxB"}
|
|
@@ -61,7 +61,7 @@ async function readNpmWorkspaceImport(root, project, options) {
|
|
|
61
61
|
catch {
|
|
62
62
|
throw lockMismatch("npm workspace adoption needs an existing readable JSON lock");
|
|
63
63
|
}
|
|
64
|
-
const graph = importNpmWorkspaceLock(npmDoc, project, options.registry.
|
|
64
|
+
const graph = importNpmWorkspaceLock(npmDoc, project, (name) => options.registry.originFor(name));
|
|
65
65
|
// Prove the complete graph and ordinary npm projection are representable
|
|
66
66
|
// before any project state is created. Actual policy fingerprints are added
|
|
67
67
|
// under the install lock after policy validation.
|
|
@@ -70,6 +70,7 @@ async function readNpmWorkspaceImport(root, project, options) {
|
|
|
70
70
|
scripts: scriptPolicyFingerprint(undefined),
|
|
71
71
|
config: configFingerprint({
|
|
72
72
|
registry: options.registry.origin,
|
|
73
|
+
registries: options.registry.scopedRegistries,
|
|
73
74
|
linker: "shared",
|
|
74
75
|
}),
|
|
75
76
|
});
|
|
@@ -131,6 +132,7 @@ export async function installWorkspaceProject(options) {
|
|
|
131
132
|
scripts: scriptPolicyFingerprint(policy),
|
|
132
133
|
config: configFingerprint({
|
|
133
134
|
registry: options.registry.origin,
|
|
135
|
+
registries: options.registry.scopedRegistries,
|
|
134
136
|
linker: "shared",
|
|
135
137
|
platform: currentPlatform(),
|
|
136
138
|
...(mutable !== undefined
|
|
@@ -144,7 +146,7 @@ export async function installWorkspaceProject(options) {
|
|
|
144
146
|
: undefined;
|
|
145
147
|
let existing = options.importNpm
|
|
146
148
|
? null
|
|
147
|
-
: await readWorkspaceLock(root, project, options.registry.
|
|
149
|
+
: await readWorkspaceLock(root, project, (name) => options.registry.originFor(name)), graph = imported;
|
|
148
150
|
if (existing) {
|
|
149
151
|
const ext = existing.doc.zyrk;
|
|
150
152
|
if (!mutation.changed &&
|
|
@@ -160,6 +162,7 @@ export async function installWorkspaceProject(options) {
|
|
|
160
162
|
throw lockMismatch("offline/frozen workspace install needs a compatible lock");
|
|
161
163
|
graph = await resolveWorkspaceGraph(project, {
|
|
162
164
|
origin: options.registry.origin,
|
|
165
|
+
originFor: (name) => options.registry.originFor(name),
|
|
163
166
|
packument: (name) => options.registry.packument(name, {
|
|
164
167
|
signal: operation.operation.signal,
|
|
165
168
|
}),
|
|
@@ -264,7 +267,9 @@ export async function installWorkspaceProject(options) {
|
|
|
264
267
|
throw new ZyrkError("ZYRK_OFFLINE_MISSING", `Verified workspace dependency ${node.name}@${node.version} is missing.`, {
|
|
265
268
|
remedy: "Fetch the exact locked sources online before retrying offline.",
|
|
266
269
|
});
|
|
267
|
-
const archive = path.join(txn.dir, `${node.sourceId}.tgz`), download = await options.registry
|
|
270
|
+
const archive = path.join(txn.dir, `${node.sourceId}.tgz`), download = await options.registry
|
|
271
|
+
.forPackage(node.name)
|
|
272
|
+
.downloadTarball({
|
|
268
273
|
url: node.tarballUrl,
|
|
269
274
|
expectedIntegrity: node.integrity,
|
|
270
275
|
destPath: archive,
|
|
@@ -508,6 +513,10 @@ export async function installWorkspaceProject(options) {
|
|
|
508
513
|
instances: registration.instances,
|
|
509
514
|
activeContexts: registration.contexts,
|
|
510
515
|
lockDigest: sha512Hex(canonicalJson(doc)),
|
|
516
|
+
registryConfig: {
|
|
517
|
+
registry: options.registry.origin,
|
|
518
|
+
registries: options.registry.scopedRegistries,
|
|
519
|
+
},
|
|
511
520
|
graphDigest: graphHash(sourceGraph),
|
|
512
521
|
platform: process.platform,
|
|
513
522
|
arch: process.arch,
|
|
@@ -9,7 +9,7 @@ export type WorkspaceFingerprints = {
|
|
|
9
9
|
export declare function safeImporter(id: unknown): id is string;
|
|
10
10
|
export declare function workspaceLockDoc(project: WorkspaceProject, graph: WorkspaceGraph, fp: WorkspaceFingerprints): NpmLockDoc;
|
|
11
11
|
export declare function validateWorkspaceLockDoc(doc: unknown): WorkspaceGraph;
|
|
12
|
-
export declare function readWorkspaceLock(root: string, project?: WorkspaceProject, registryOrigin?: string): Promise<{
|
|
12
|
+
export declare function readWorkspaceLock(root: string, project?: WorkspaceProject, registryOrigin?: string | ((name: string) => string)): Promise<{
|
|
13
13
|
doc: NpmLockDoc;
|
|
14
14
|
graph: WorkspaceGraph;
|
|
15
15
|
} | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-lock.d.ts","sourceRoot":"","sources":["../../src/install/workspace-lock.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AASvD,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,MAAM,CAqBtD;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,cAAc,EACrB,EAAE,EAAE,qBAAqB,GACxB,UAAU,CAyCZ;AACD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAgTrE;AACD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"workspace-lock.d.ts","sourceRoot":"","sources":["../../src/install/workspace-lock.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AASvD,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,MAAM,CAqBtD;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,cAAc,EACrB,EAAE,EAAE,qBAAqB,GACxB,UAAU,CAyCZ;AACD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAgTrE;AACD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GACnD,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAAC,CA2C5D"}
|
|
@@ -333,7 +333,11 @@ export async function readWorkspaceLock(root, project, registryOrigin) {
|
|
|
333
333
|
throw lockMismatch("workspace importer is missing");
|
|
334
334
|
}
|
|
335
335
|
if (registryOrigin &&
|
|
336
|
-
graph.nodes.some((n) => n.kind === "registry" &&
|
|
336
|
+
graph.nodes.some((n) => n.kind === "registry" &&
|
|
337
|
+
n.origin !==
|
|
338
|
+
(typeof registryOrigin === "string"
|
|
339
|
+
? registryOrigin
|
|
340
|
+
: registryOrigin(n.name))))
|
|
337
341
|
throw lockMismatch("workspace registry origin differs");
|
|
338
342
|
return { doc: doc, graph };
|
|
339
343
|
}
|
|
@@ -32,6 +32,7 @@ export declare function scriptPolicyFingerprint(policy: unknown): string;
|
|
|
32
32
|
export type ResolutionConfig = {
|
|
33
33
|
/** Credential-free registry origin. */
|
|
34
34
|
registry: string;
|
|
35
|
+
registries?: Readonly<Record<string, string>>;
|
|
35
36
|
linker: "shared" | "local";
|
|
36
37
|
patches?: string;
|
|
37
38
|
mutablePackages?: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprints.d.ts","sourceRoot":"","sources":["../../src/lockfile/fingerprints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CA2BzE;AAED,eAAO,MAAM,qBAAqB;IAAK,OAAO;IAAU,KAAK;IAAM,IAAI;CAAM,CAAC;AAE9E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAG/D;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"fingerprints.d.ts","sourceRoot":"","sources":["../../src/lockfile/fingerprints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CA2BzE;AAED,eAAO,MAAM,qBAAqB;IAAK,OAAO;IAAU,KAAK;IAAM,IAAI;CAAM,CAAC;AAE9E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAG/D;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAalE"}
|
|
@@ -55,6 +55,9 @@ export function scriptPolicyFingerprint(policy) {
|
|
|
55
55
|
export function configFingerprint(config) {
|
|
56
56
|
return fingerprintOf({
|
|
57
57
|
registry: config.registry,
|
|
58
|
+
...(config.registries && Object.keys(config.registries).length
|
|
59
|
+
? { registries: config.registries }
|
|
60
|
+
: {}),
|
|
58
61
|
linker: config.linker,
|
|
59
62
|
...(config.patches === undefined ? {} : { patches: config.patches }),
|
|
60
63
|
...(config.platform === undefined ? {} : { platform: config.platform }),
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import { type Packument } from "../fetch/registry.ts";
|
|
23
23
|
export type MetadataProvider = {
|
|
24
24
|
readonly origin: string;
|
|
25
|
+
originFor?(name: string): string;
|
|
25
26
|
packument(name: string): Promise<Packument>;
|
|
26
27
|
};
|
|
27
28
|
export type EdgeKind = "prod" | "optional" | "peer";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/resolve/resolver.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/resolve/resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/resolve/resolver.js
CHANGED
|
@@ -381,14 +381,14 @@ class ResolverState {
|
|
|
381
381
|
throw internal("missing finalized key");
|
|
382
382
|
const existing = byKey.get(key);
|
|
383
383
|
if (existing !== undefined) {
|
|
384
|
-
assertMergeable(existing, occ, keys, this.provider.origin);
|
|
384
|
+
assertMergeable(existing, occ, keys, this.provider.originFor?.(occ.name) ?? this.provider.origin);
|
|
385
385
|
continue;
|
|
386
386
|
}
|
|
387
387
|
byKey.set(key, occ);
|
|
388
388
|
}
|
|
389
389
|
const nodes = [...byKey.entries()]
|
|
390
390
|
.sort((a, b) => compareStrings(a[0], b[0]))
|
|
391
|
-
.map(([key, occ]) => toResolved(occ, key, keys, this.provider.origin));
|
|
391
|
+
.map(([key, occ]) => toResolved(occ, key, keys, this.provider.originFor?.(occ.name) ?? this.provider.origin));
|
|
392
392
|
const roots = rootLinks.map((link) => {
|
|
393
393
|
const target = keys.get(link.child);
|
|
394
394
|
if (target === undefined)
|