@microwiseai/snapshot 0.5.0 → 0.5.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/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +195 -34
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/preflight.d.ts +31 -0
- package/dist/commands/preflight.d.ts.map +1 -0
- package/dist/commands/preflight.js +83 -0
- package/dist/commands/preflight.js.map +1 -0
- package/dist/commands/publish.d.ts +4 -0
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +35 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/distkit-closure-bridge.d.ts +102 -0
- package/dist/lib/distkit-closure-bridge.d.ts.map +1 -0
- package/dist/lib/distkit-closure-bridge.js +177 -0
- package/dist/lib/distkit-closure-bridge.js.map +1 -0
- package/dist/lib/distkit-closure-parity.d.ts +110 -0
- package/dist/lib/distkit-closure-parity.d.ts.map +1 -0
- package/dist/lib/distkit-closure-parity.js +134 -0
- package/dist/lib/distkit-closure-parity.js.map +1 -0
- package/dist/lib/distkit-routing-port.d.ts +37 -0
- package/dist/lib/distkit-routing-port.d.ts.map +1 -0
- package/dist/lib/distkit-routing-port.js +72 -0
- package/dist/lib/distkit-routing-port.js.map +1 -0
- package/dist/lib/install-timeline.d.ts +81 -0
- package/dist/lib/install-timeline.d.ts.map +1 -0
- package/dist/lib/install-timeline.js +243 -0
- package/dist/lib/install-timeline.js.map +1 -0
- package/dist/lib/preflight-adapter.d.ts +52 -0
- package/dist/lib/preflight-adapter.d.ts.map +1 -0
- package/dist/lib/preflight-adapter.js +224 -0
- package/dist/lib/preflight-adapter.js.map +1 -0
- package/dist/lib/transitive-resolver.d.ts +121 -0
- package/dist/lib/transitive-resolver.d.ts.map +1 -1
- package/dist/lib/transitive-resolver.js +190 -0
- package/dist/lib/transitive-resolver.js.map +1 -1
- package/node_modules/@gitdot/clone-lib/README.md +117 -0
- package/node_modules/@gitdot/clone-lib/dist/bin/gitdot-resolve.d.ts +9 -0
- package/node_modules/@gitdot/clone-lib/dist/bin/gitdot-resolve.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/bin/gitdot-resolve.js +154 -0
- package/node_modules/@gitdot/clone-lib/dist/bin/gitdot-resolve.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/clone.d.ts +21 -0
- package/node_modules/@gitdot/clone-lib/dist/clone.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/clone.js +228 -0
- package/node_modules/@gitdot/clone-lib/dist/clone.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/dotpath.d.ts +10 -0
- package/node_modules/@gitdot/clone-lib/dist/dotpath.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/dotpath.js +27 -0
- package/node_modules/@gitdot/clone-lib/dist/dotpath.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/git.d.ts +23 -0
- package/node_modules/@gitdot/clone-lib/dist/git.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/git.js +134 -0
- package/node_modules/@gitdot/clone-lib/dist/git.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/index.d.ts +17 -0
- package/node_modules/@gitdot/clone-lib/dist/index.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/index.js +35 -0
- package/node_modules/@gitdot/clone-lib/dist/index.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/lock.d.ts +24 -0
- package/node_modules/@gitdot/clone-lib/dist/lock.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/lock.js +97 -0
- package/node_modules/@gitdot/clone-lib/dist/lock.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/gitlab.d.ts +15 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/gitlab.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/gitlab.js +124 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/gitlab.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/index.d.ts +12 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/index.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/index.js +31 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/index.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/manifest.d.ts +32 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/manifest.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/manifest.js +159 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/manifest.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/member.d.ts +44 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/member.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/member.js +163 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/member.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/resolve.d.ts +18 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/resolve.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/resolve.js +155 -0
- package/node_modules/@gitdot/clone-lib/dist/resolve/resolve.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/types.d.ts +225 -0
- package/node_modules/@gitdot/clone-lib/dist/types.d.ts.map +1 -0
- package/node_modules/@gitdot/clone-lib/dist/types.js +9 -0
- package/node_modules/@gitdot/clone-lib/dist/types.js.map +1 -0
- package/node_modules/@gitdot/clone-lib/package.json +53 -0
- package/node_modules/@microwiseai/install-preflight/dist/index.d.ts +27 -0
- package/node_modules/@microwiseai/install-preflight/dist/index.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/index.js +26 -0
- package/node_modules/@microwiseai/install-preflight/dist/index.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/policy.d.ts +42 -0
- package/node_modules/@microwiseai/install-preflight/dist/policy.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/policy.js +79 -0
- package/node_modules/@microwiseai/install-preflight/dist/policy.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/preflight.d.ts +18 -0
- package/node_modules/@microwiseai/install-preflight/dist/preflight.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/preflight.js +0 -0
- package/node_modules/@microwiseai/install-preflight/dist/preflight.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/resolvers.d.ts +26 -0
- package/node_modules/@microwiseai/install-preflight/dist/resolvers.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/resolvers.js +63 -0
- package/node_modules/@microwiseai/install-preflight/dist/resolvers.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/semver.d.ts +45 -0
- package/node_modules/@microwiseai/install-preflight/dist/semver.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/semver.js +195 -0
- package/node_modules/@microwiseai/install-preflight/dist/semver.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/types.d.ts +136 -0
- package/node_modules/@microwiseai/install-preflight/dist/types.d.ts.map +1 -0
- package/node_modules/@microwiseai/install-preflight/dist/types.js +11 -0
- package/node_modules/@microwiseai/install-preflight/dist/types.js.map +1 -0
- package/node_modules/@microwiseai/install-preflight/package.json +49 -0
- package/package.json +12 -4
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot ↔ install-preflight adapter (thin).
|
|
3
|
+
*
|
|
4
|
+
* Maps a snapshot.json into the registry-agnostic preflight engine's inputs and
|
|
5
|
+
* runs the gate. The engine (@microwiseai/install-preflight) knows nothing about
|
|
6
|
+
* snapshots; all snapshot-specific knowledge lives here:
|
|
7
|
+
*
|
|
8
|
+
* • install groups (npm-proxy / glpkg / skit) + legacy packages/skits → channels
|
|
9
|
+
* + package requests, all probed ANONYMOUSLY (reproduces a first-time
|
|
10
|
+
* end-user with no token).
|
|
11
|
+
* • transitive closure discovery: uses the publisher's token to expand npm
|
|
12
|
+
* deps via the proxy, then hands the discovered nodes back to the engine to
|
|
13
|
+
* probe anonymously — so a private transitive dep (401 for end-users) is
|
|
14
|
+
* caught even though the publisher can see it.
|
|
15
|
+
* • [B] the snapshot's OWN version must be stable when promoted to `latest`.
|
|
16
|
+
*
|
|
17
|
+
* See architecture/decisions — this is the blocking preflight gate wired into
|
|
18
|
+
* `snapshot publish` and the `snapshot preflight` command.
|
|
19
|
+
*/
|
|
20
|
+
import { preflight, formatReport, createNpmPackumentResolver, checkStableRelease, } from '@microwiseai/install-preflight';
|
|
21
|
+
import { REGISTRY_PROXY_URL, GITLAB_GROUP_ID, getLicenseKey, getProxyAuthToken } from './config.js';
|
|
22
|
+
import { resolveDepsFromLicenseAPI, isDistkitClosureEnabled } from './transitive-resolver.js';
|
|
23
|
+
/** Installer groups whose members resolve as npm-style packages through the proxy. */
|
|
24
|
+
const NPM_LIKE_GROUPS = new Set(['npm-proxy', 'glpkg', 'gitlab-install', 'skit']);
|
|
25
|
+
/** Extract the `@scope` prefix of a package name, or null. */
|
|
26
|
+
function scopeOf(name) {
|
|
27
|
+
return name.startsWith('@') && name.includes('/') ? name.split('/')[0] : null;
|
|
28
|
+
}
|
|
29
|
+
/** True for names that legacy `packages`/`skits` maps treat as skits. */
|
|
30
|
+
function isSkitName(name) {
|
|
31
|
+
return name.endsWith('-kit') || name.endsWith('kit');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build one anonymous channel per installer lane actually used by the snapshot.
|
|
35
|
+
* All lanes hit the same registry-proxy packument endpoint (`GET /{name}`),
|
|
36
|
+
* differing only by id/scope for reporting.
|
|
37
|
+
*/
|
|
38
|
+
function buildChannels(scopes) {
|
|
39
|
+
const base = {
|
|
40
|
+
registryUrl: REGISTRY_PROXY_URL,
|
|
41
|
+
auth: { kind: 'anonymous' },
|
|
42
|
+
strategy: 'npm-packument',
|
|
43
|
+
scopes,
|
|
44
|
+
groupId: GITLAB_GROUP_ID,
|
|
45
|
+
};
|
|
46
|
+
return [
|
|
47
|
+
{ id: 'npm-proxy', ...base },
|
|
48
|
+
{ id: 'glpkg', ...base },
|
|
49
|
+
{ id: 'skit', ...base },
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
/** Collect the DIRECT pins declared by a snapshot into engine requests. */
|
|
53
|
+
function collectDirectRequests(snapshot) {
|
|
54
|
+
const requests = [];
|
|
55
|
+
const push = (channel, name, range) => {
|
|
56
|
+
requests.push({ name, range, channel });
|
|
57
|
+
};
|
|
58
|
+
// New installer-based structure.
|
|
59
|
+
if (snapshot.install) {
|
|
60
|
+
for (const [installer, pkgs] of Object.entries(snapshot.install)) {
|
|
61
|
+
const channel = installer === 'gitlab-install' ? 'glpkg' : installer;
|
|
62
|
+
for (const [name, version] of Object.entries(pkgs)) {
|
|
63
|
+
push(channel === 'npm-proxy' || channel === 'glpkg' || channel === 'skit' ? channel : 'npm-proxy', name, version);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Legacy maps.
|
|
68
|
+
if (snapshot.packages) {
|
|
69
|
+
for (const [name, version] of Object.entries(snapshot.packages)) {
|
|
70
|
+
push(isSkitName(name) ? 'skit' : 'npm-proxy', name, version);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (snapshot.skits) {
|
|
74
|
+
for (const [name, version] of Object.entries(snapshot.skits)) {
|
|
75
|
+
push('skit', name, version);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return requests;
|
|
79
|
+
}
|
|
80
|
+
/** Scopes declared by the snapshot's registry block (fallback to pins' scopes). */
|
|
81
|
+
function collectScopes(snapshot, requests) {
|
|
82
|
+
const scopes = new Set();
|
|
83
|
+
if (snapshot.registry) {
|
|
84
|
+
for (const scope of Object.keys(snapshot.registry))
|
|
85
|
+
scopes.add(scope);
|
|
86
|
+
}
|
|
87
|
+
if (scopes.size === 0) {
|
|
88
|
+
for (const r of requests) {
|
|
89
|
+
const s = scopeOf(r.name);
|
|
90
|
+
if (s)
|
|
91
|
+
scopes.add(s);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return Array.from(scopes);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Discover transitive npm deps via the proxy (token-authenticated), returning
|
|
98
|
+
* extra requests to probe ANONYMOUSLY. Failure is non-fatal: it returns a
|
|
99
|
+
* warning so coverage gaps are surfaced, never silently dropped.
|
|
100
|
+
*/
|
|
101
|
+
async function discoverTransitive(direct, scopes) {
|
|
102
|
+
const token = getLicenseKey() || getProxyAuthToken();
|
|
103
|
+
if (!token) {
|
|
104
|
+
return {
|
|
105
|
+
requests: [],
|
|
106
|
+
warning: 'Transitive-closure discovery skipped: no token available (login for full coverage). ' +
|
|
107
|
+
'Only directly-declared pins were checked.',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Expand npm/glpkg-lane pins within tracked scopes.
|
|
111
|
+
const npmDirect = direct.filter((r) => (r.channel === 'npm-proxy' || r.channel === 'glpkg') && scopes.some((s) => r.name.startsWith(s)));
|
|
112
|
+
if (npmDirect.length === 0 || scopes.length === 0)
|
|
113
|
+
return { requests: [] };
|
|
114
|
+
// ── §5-step6 CUTOVER SWITCH (behind SNAPSHOT_DISTKIT_CLOSURE) ──────────────
|
|
115
|
+
// flag ON: resolve the transitive closure CLIENT-SIDE via distkit walkClosure
|
|
116
|
+
// (subsumes /resolve-deps — §3d). PREFLIGHT probes the PRIVATE lane (a private
|
|
117
|
+
// transitive dep that 401s anonymously is the risk this gate exists for; public
|
|
118
|
+
// deps are npmjs-anonymous-trivial). §1.4 fail-loud: a resolver error propagates
|
|
119
|
+
// (NOT swallowed into a warning) — a partial closure would be a wrong gate.
|
|
120
|
+
// The full public-inclusive closure/lock is produced separately by
|
|
121
|
+
// resolveSnapshotToLock; it is not what the anonymous-probe gate needs.
|
|
122
|
+
if (isDistkitClosureEnabled()) {
|
|
123
|
+
// DYNAMIC import: the distkit bridge is loaded ONLY on the flag-ON path, so
|
|
124
|
+
// flag-OFF (default) has NO load-time dependency on distkit — 100% reversible
|
|
125
|
+
// and shippable even while distkit is unpublished/unlinked.
|
|
126
|
+
const { resolveTransitiveClosureFromPins } = await import('./distkit-closure-bridge.js');
|
|
127
|
+
const closure = await resolveTransitiveClosureFromPins(npmDirect.map((r) => ({ name: r.name, version: r.range })), scopes);
|
|
128
|
+
const directNames = new Set(direct.map((r) => `${r.channel}:${r.name}`));
|
|
129
|
+
const requests = [];
|
|
130
|
+
for (const node of closure) {
|
|
131
|
+
if (!scopes.some((s) => node.name.startsWith(s)))
|
|
132
|
+
continue; // private lane only (preflight)
|
|
133
|
+
if (directNames.has(`npm-proxy:${node.name}`) || directNames.has(`glpkg:${node.name}`))
|
|
134
|
+
continue;
|
|
135
|
+
requests.push({
|
|
136
|
+
name: node.name,
|
|
137
|
+
range: node.version,
|
|
138
|
+
channel: 'npm-proxy',
|
|
139
|
+
requestedBy: node.requestedBy.join(', ') || '(transitive closure)',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return { requests };
|
|
143
|
+
}
|
|
144
|
+
// flag OFF (default): legacy /resolve-deps path — COMPLETELY UNCHANGED.
|
|
145
|
+
try {
|
|
146
|
+
const resolved = await resolveDepsFromLicenseAPI({
|
|
147
|
+
packages: npmDirect.map((r) => `${r.name}@${r.range}`),
|
|
148
|
+
groupId: GITLAB_GROUP_ID,
|
|
149
|
+
scopes,
|
|
150
|
+
includePeer: true,
|
|
151
|
+
});
|
|
152
|
+
const directNames = new Set(direct.map((r) => `${r.channel}:${r.name}`));
|
|
153
|
+
const requests = [];
|
|
154
|
+
for (const [name, version] of Object.entries(resolved.dependencies)) {
|
|
155
|
+
if (directNames.has(`npm-proxy:${name}`) || directNames.has(`glpkg:${name}`))
|
|
156
|
+
continue;
|
|
157
|
+
requests.push({
|
|
158
|
+
name,
|
|
159
|
+
range: version,
|
|
160
|
+
channel: 'npm-proxy',
|
|
161
|
+
requestedBy: '(transitive closure)',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
for (const [name, version] of Object.entries(resolved.peerDependencies ?? {})) {
|
|
165
|
+
if (requests.some((r) => r.name === name) || directNames.has(`npm-proxy:${name}`))
|
|
166
|
+
continue;
|
|
167
|
+
requests.push({ name, range: version, channel: 'npm-proxy', requestedBy: '(peer dependency)' });
|
|
168
|
+
}
|
|
169
|
+
return { requests };
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
return {
|
|
173
|
+
requests: [],
|
|
174
|
+
warning: `Transitive-closure discovery failed (${err instanceof Error ? err.message : String(err)}). ` +
|
|
175
|
+
'Only directly-declared pins were checked — transitive private/unpublished deps may be missed.',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Build the full engine input for a snapshot: anonymous channels + direct pins
|
|
181
|
+
* (+ discovered transitive closure). Exposed for testing/other callers.
|
|
182
|
+
*/
|
|
183
|
+
export async function buildSnapshotPreflightInput(snapshot, options = {}) {
|
|
184
|
+
const { includeTransitive = true, distTag = 'latest' } = options;
|
|
185
|
+
const warnings = [];
|
|
186
|
+
const direct = collectDirectRequests(snapshot);
|
|
187
|
+
const scopes = collectScopes(snapshot, direct);
|
|
188
|
+
let packages = direct;
|
|
189
|
+
if (includeTransitive) {
|
|
190
|
+
const { requests, warning } = await discoverTransitive(direct, scopes);
|
|
191
|
+
if (warning)
|
|
192
|
+
warnings.push(warning);
|
|
193
|
+
packages = [...direct, ...requests];
|
|
194
|
+
}
|
|
195
|
+
const input = {
|
|
196
|
+
channels: buildChannels(scopes),
|
|
197
|
+
packages,
|
|
198
|
+
policy: { distTag, requireStableForTags: ['latest'], forbidPrereleaseDefaultResolve: true },
|
|
199
|
+
resolver: options.resolver,
|
|
200
|
+
};
|
|
201
|
+
return { input, warnings };
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Run the blocking preflight gate for a snapshot. Combines:
|
|
205
|
+
* [A] anonymous resolvability of the whole closure (engine), and
|
|
206
|
+
* [B] the snapshot's own version must be stable when promoted to `latest`.
|
|
207
|
+
*/
|
|
208
|
+
export async function runSnapshotPreflight(snapshot, options = {}) {
|
|
209
|
+
const distTag = options.distTag ?? 'latest';
|
|
210
|
+
const { input, warnings } = await buildSnapshotPreflightInput(snapshot, options);
|
|
211
|
+
options.log?.(`Preflight: probing ${input.packages.length} package(s) anonymously across ${input.channels.length} channel(s)...`);
|
|
212
|
+
const report = await preflight(input);
|
|
213
|
+
// [B] (b1): the snapshot itself must be a stable release when → latest.
|
|
214
|
+
const selfFinding = snapshot.version
|
|
215
|
+
? checkStableRelease(snapshot.version, { package: snapshot.name, channel: 'snapshot', requested: snapshot.version }, { distTag, requireStableForTags: ['latest'] })
|
|
216
|
+
: null;
|
|
217
|
+
if (selfFinding) {
|
|
218
|
+
report.findings.unshift(selfFinding);
|
|
219
|
+
report.ok = false;
|
|
220
|
+
}
|
|
221
|
+
return { report, warnings };
|
|
222
|
+
}
|
|
223
|
+
export { formatReport, createNpmPackumentResolver };
|
|
224
|
+
//# sourceMappingURL=preflight-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-adapter.js","sourceRoot":"","sources":["../../src/lib/preflight-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,SAAS,EACT,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,GAOnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAG9F,sFAAsF;AACtF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;AAmBlF,8DAA8D;AAC9D,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,yEAAyE;AACzE,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,MAAgB;IACrC,MAAM,IAAI,GAAG;QACX,WAAW,EAAE,kBAAkB;QAC/B,IAAI,EAAE,EAAE,IAAI,EAAE,WAAoB,EAAE;QACpC,QAAQ,EAAE,eAAwB;QAClC,MAAM;QACN,OAAO,EAAE,eAAe;KACzB,CAAC;IACF,OAAO;QACL,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE;QAC5B,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE;QACxB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,SAAS,qBAAqB,CAAC,QAAkB;IAC/C,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,CAAC,OAAe,EAAE,IAAY,EAAE,KAAa,EAAQ,EAAE;QAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,iCAAiC;IACjC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,SAAS,KAAK,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACpH,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,SAAS,aAAa,CAAC,QAAkB,EAAE,QAA0B;IACnE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAC/B,MAAwB,EACxB,MAAgB;IAEhB,MAAM,KAAK,GAAG,aAAa,EAAE,IAAI,iBAAiB,EAAE,CAAC;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,OAAO,EACL,sFAAsF;gBACtF,2CAA2C;SAC9C,CAAC;IACJ,CAAC;IAED,oDAAoD;IACpD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CACxG,CAAC;IACF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE3E,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,gFAAgF;IAChF,iFAAiF;IACjF,4EAA4E;IAC5E,mEAAmE;IACnE,wEAAwE;IACxE,IAAI,uBAAuB,EAAE,EAAE,CAAC;QAC9B,4EAA4E;QAC5E,8EAA8E;QAC9E,4DAA4D;QAC5D,MAAM,EAAE,gCAAgC,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,MAAM,gCAAgC,CACpD,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAC1D,MAAM,CACP,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAAE,SAAS,CAAC,gCAAgC;YAC5F,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;gBAAE,SAAS;YACjG,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,OAAO;gBACnB,OAAO,EAAE,WAAW;gBACpB,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,sBAAsB;aACnE,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC;IAED,wEAAwE;IACxE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC;YAC/C,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACtD,OAAO,EAAE,eAAe;YACxB,MAAM;YACN,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACpE,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;gBAAE,SAAS;YACvF,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,WAAW;gBACpB,WAAW,EAAE,sBAAsB;aACpC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9E,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;gBAAE,SAAS;YAC5F,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,OAAO,EACL,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;gBAC7F,+FAA+F;SAClG,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,QAAkB,EAClB,UAAoC,EAAE;IAEtC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;IACjE,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE/C,IAAI,QAAQ,GAAG,MAAM,CAAC;IACtB,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvE,IAAI,OAAO;YAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,KAAK,GAAmB;QAC5B,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC;QAC/B,QAAQ;QACR,MAAM,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,QAAQ,CAAC,EAAE,8BAA8B,EAAE,IAAI,EAAE;QAC3F,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAkB,EAClB,UAAoC,EAAE;IAEtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC5C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,2BAA2B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEjF,OAAO,CAAC,GAAG,EAAE,CAAC,sBAAsB,KAAK,CAAC,QAAQ,CAAC,MAAM,kCAAkC,KAAK,CAAC,QAAQ,CAAC,MAAM,gBAAgB,CAAC,CAAC;IAElI,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;IAEtC,wEAAwE;IACxE,MAAM,WAAW,GAA4B,QAAQ,CAAC,OAAO;QAC3D,CAAC,CAAC,kBAAkB,CAChB,QAAQ,CAAC,OAAO,EAChB,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,EAC5E,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,QAAQ,CAAC,EAAE,CAC9C;QACH,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACpC,MAA0B,CAAC,EAAE,GAAG,KAAK,CAAC;IACzC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,CAAC"}
|
|
@@ -43,6 +43,49 @@ export interface LicenseApiResolveDepsResponse {
|
|
|
43
43
|
dependencies: Record<string, string>;
|
|
44
44
|
peerDependencies?: Record<string, string>;
|
|
45
45
|
}
|
|
46
|
+
/** distkit-schema `Ecosystem` (opened union). Mirror. */
|
|
47
|
+
export type Ecosystem = 'npm' | 'pypi' | (string & {});
|
|
48
|
+
/** distkit-schema `Installer` (opened union). Mirror. */
|
|
49
|
+
export type Installer = 'npm' | 'glpkg' | 'skit' | 'pip' | (string & {});
|
|
50
|
+
/** distkit-schema `InstallTarget` (closed union). Mirror. */
|
|
51
|
+
export type InstallTarget = 'cli-global' | 'project-local';
|
|
52
|
+
/** distkit-schema `AccessTier` (closed union). Mirror. */
|
|
53
|
+
export type AccessTier = 'public' | 'authenticated' | 'licensed' | 'restricted';
|
|
54
|
+
/**
|
|
55
|
+
* The `package.json`-shaped manifest the distkit npm adapter's
|
|
56
|
+
* `parseDependencies` consumes (`adapters/npm.ts` `PackumentVersion`). Only the
|
|
57
|
+
* four dependency maps are meaningful to the adapter; everything else is ignored.
|
|
58
|
+
* This is what a ClosureRoot in the `'npm'` lane carries as its `manifest`.
|
|
59
|
+
*/
|
|
60
|
+
export interface NpmPackageJsonManifest {
|
|
61
|
+
dependencies?: Record<string, string>;
|
|
62
|
+
optionalDependencies?: Record<string, string>;
|
|
63
|
+
devDependencies?: Record<string, string>;
|
|
64
|
+
peerDependencies?: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Mirror of distkit `ClosureRoot` (closure.ts:57): one already-pinned entry
|
|
68
|
+
* package whose `manifest` declares the first level of dependencies distkit's
|
|
69
|
+
* walker will expand transitively. `manifest` is `unknown` in the contract (the
|
|
70
|
+
* adapter knows its own shape); for the npm lane we populate it with an
|
|
71
|
+
* {@link NpmPackageJsonManifest}.
|
|
72
|
+
*/
|
|
73
|
+
export interface ClosureRoot {
|
|
74
|
+
/** package name, e.g. "@microwiseai/foo". */
|
|
75
|
+
name: string;
|
|
76
|
+
/** exact version of the root (already pinned). */
|
|
77
|
+
version: string;
|
|
78
|
+
/** ecosystem of the root; omitted ⇒ the matching adapter's ecosystem (C4). */
|
|
79
|
+
ecosystem?: Ecosystem;
|
|
80
|
+
/** the root's manifest, fed to `EcosystemAdapter.parseDependencies`. */
|
|
81
|
+
manifest: unknown;
|
|
82
|
+
/** installer to record for produced entries (else the adapter's default). */
|
|
83
|
+
installer?: Installer;
|
|
84
|
+
/** intended install location for produced entries. */
|
|
85
|
+
installTarget?: InstallTarget;
|
|
86
|
+
/** observed access tier for produced entries (authority = license-mgr). */
|
|
87
|
+
accessTier?: AccessTier;
|
|
88
|
+
}
|
|
46
89
|
export interface ResolveOptions {
|
|
47
90
|
/** proxy를 통해 transitive deps 해석 */
|
|
48
91
|
resolveTransitive?: boolean;
|
|
@@ -82,6 +125,84 @@ export interface ResolveDepsFromLicenseOptions {
|
|
|
82
125
|
* // result.peerDependencies: { "typescript": "^5.0.0" }
|
|
83
126
|
*/
|
|
84
127
|
export declare function resolveDepsFromLicenseAPI(options: ResolveDepsFromLicenseOptions): Promise<LicenseApiResolveDepsResponse>;
|
|
128
|
+
/**
|
|
129
|
+
* Feature-flag gate for the new distkit closure path (§1.2 wiring target).
|
|
130
|
+
*
|
|
131
|
+
* OFF by default. Defined now so the future §1.2 caller has a single, documented
|
|
132
|
+
* switch; the collector itself is a pure additive export that no live path calls,
|
|
133
|
+
* so flipping this on has NO effect until §1.2 wires `walkClosure` behind it.
|
|
134
|
+
*
|
|
135
|
+
* Env: `SNAPSHOT_DISTKIT_CLOSURE=1` (or `true`).
|
|
136
|
+
*/
|
|
137
|
+
export declare const SNAPSHOT_DISTKIT_CLOSURE_FLAG: "SNAPSHOT_DISTKIT_CLOSURE";
|
|
138
|
+
/** True iff the distkit closure path is enabled via {@link SNAPSHOT_DISTKIT_CLOSURE_FLAG}. */
|
|
139
|
+
export declare function isDistkitClosureEnabled(): boolean;
|
|
140
|
+
/** Options for {@link collectNpmClosureRoots}. */
|
|
141
|
+
export interface CollectClosureRootsOptions {
|
|
142
|
+
/**
|
|
143
|
+
* Restrict roots to npm packages whose name starts with one of these scopes.
|
|
144
|
+
* Omitted ⇒ ALL declared npm packages become roots (recommended: distkit's
|
|
145
|
+
* walker expands each into its own transitive closure).
|
|
146
|
+
*/
|
|
147
|
+
scopes?: string[];
|
|
148
|
+
/** `installTarget` hint stamped on every produced root. Default `'cli-global'`. */
|
|
149
|
+
installTarget?: InstallTarget;
|
|
150
|
+
}
|
|
151
|
+
/** Result of {@link collectNpmClosureRoots}. */
|
|
152
|
+
export interface NpmClosureRootsResult {
|
|
153
|
+
/** one {@link ClosureRoot} per directly-declared npm entry package (ecosystem `'npm'`). */
|
|
154
|
+
roots: ClosureRoot[];
|
|
155
|
+
/** domain-walk + manifest-fetch failures (fail-soft at this pre-wiring stage). */
|
|
156
|
+
errors: Array<{
|
|
157
|
+
name: string;
|
|
158
|
+
error: string;
|
|
159
|
+
}>;
|
|
160
|
+
/** scope → groupId map collected from the snapshot `registry` fields (§1.3 routing feed). */
|
|
161
|
+
scopeGroups: Record<string, string>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Phase-2b §1.1 collector: walk the snapshot/skit domain graph and emit the npm
|
|
165
|
+
* lane as `ClosureRoot[]` for distkit's `walkClosure`.
|
|
166
|
+
*
|
|
167
|
+
* Reuses `traverseSnapshot` (the unchanged domain-graph walk: `extends`, `skits`,
|
|
168
|
+
* `install`, `packages`, `registry`, and skit.json `dependencies.{npm,skit,cli}`)
|
|
169
|
+
* to discover the directly-declared npm packages, then fetches each one's
|
|
170
|
+
* `package.json`-shaped manifest and maps it to a {@link ClosureRoot}:
|
|
171
|
+
*
|
|
172
|
+
* { name, version, ecosystem: 'npm', manifest, installTarget }
|
|
173
|
+
*
|
|
174
|
+
* NOTE (pre-wiring, fail-soft): a package whose manifest cannot be fetched is
|
|
175
|
+
* still emitted (with an empty `{}` manifest) and an error is recorded — so a
|
|
176
|
+
* parity fixture surfaces the gap. Authoritative fail-loud + range→exact version
|
|
177
|
+
* resolution move in with distkit's adapter at §1.2 / §1.4.
|
|
178
|
+
*
|
|
179
|
+
* This function is on NO live install path — it is the §1.1 deliverable only.
|
|
180
|
+
*/
|
|
181
|
+
export declare function collectNpmClosureRoots(snapshotName: string, options?: CollectClosureRootsOptions): Promise<NpmClosureRootsResult>;
|
|
182
|
+
/**
|
|
183
|
+
* Build `ClosureRoot[]` from an explicit list of npm pins (name + exact version),
|
|
184
|
+
* fetching each pin's `package.json`-shaped manifest from the registry-proxy
|
|
185
|
+
* packument. Extracted from {@link collectNpmClosureRoots} (behaviour-identical)
|
|
186
|
+
* so the §5-step6 install-resolution switch can build roots from the pins the
|
|
187
|
+
* preflight adapter already computed (WITHOUT re-walking the snapshot graph —
|
|
188
|
+
* important during `snapshot publish`, where the snapshot is LOCAL/unpublished).
|
|
189
|
+
*
|
|
190
|
+
* Deterministic (sorted by name). A pin whose manifest cannot be fetched is still
|
|
191
|
+
* emitted (empty `{}` manifest) AND recorded in `errors` — the caller decides
|
|
192
|
+
* fail-soft (collector §1.1) vs fail-loud (install path §1.4).
|
|
193
|
+
*/
|
|
194
|
+
export declare function buildNpmClosureRoots(pins: ReadonlyArray<{
|
|
195
|
+
name: string;
|
|
196
|
+
version: string;
|
|
197
|
+
}>, options?: {
|
|
198
|
+
installTarget?: InstallTarget;
|
|
199
|
+
}): Promise<{
|
|
200
|
+
roots: ClosureRoot[];
|
|
201
|
+
errors: Array<{
|
|
202
|
+
name: string;
|
|
203
|
+
error: string;
|
|
204
|
+
}>;
|
|
205
|
+
}>;
|
|
85
206
|
/**
|
|
86
207
|
* 캐시 클리어
|
|
87
208
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/transitive-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,GAAG,CAAC,EAAE,KAAK,CAAC;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC,uCAAuC;IACvC,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,sBAAsB;IACtB,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,kBAAkB;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAYD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAmWD,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,0BAA0B,CAAC,CAqDrC;AAMD,MAAM,WAAW,6BAA6B;IAC5C,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,6BAA6B,CAAC,CAiGxC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/transitive-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -427,10 +427,200 @@ export async function resolveDepsFromLicenseAPI(options) {
|
|
|
427
427
|
throw new Error(`[resolveDepsFromLicenseAPI] Network error: ${error instanceof Error ? error.message : String(error)}`);
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
|
+
// ============================================================
|
|
431
|
+
// Phase-2b §1.1 — ClosureRoot[] collector (distkit npm lane)
|
|
432
|
+
// ============================================================
|
|
433
|
+
//
|
|
434
|
+
// NEW PATH — behind a flag, called by NOBODY on the live install path yet.
|
|
435
|
+
//
|
|
436
|
+
// Scope (SSOT §1.1, §5 step 3): KEEP snapshot's snapshot/skit domain-graph walk
|
|
437
|
+
// (`traverseSnapshot`/`traverseSkit`) exactly as-is; only change the OUTPUT
|
|
438
|
+
// SHAPE. This collector reuses that walk (via a fresh TraversalContext, same as
|
|
439
|
+
// `resolveAllDependencies`) to discover the directly-declared npm entry packages,
|
|
440
|
+
// then emits one {@link ClosureRoot} per package for distkit's `walkClosure`.
|
|
441
|
+
//
|
|
442
|
+
// Explicitly OUT OF SCOPE here (later phases / sign-off gate):
|
|
443
|
+
// • §1.2 wiring distkit `walkClosure` / lock emit / cutover.
|
|
444
|
+
// • porting a cycle guard or first-writer dedup into this path — distkit's
|
|
445
|
+
// walker OWNS transitive cycle-safety + multi-parent dedup (§1.1 note). The
|
|
446
|
+
// `visited*` Sets used inside `traverseSnapshot`/`traverseSkit` are the
|
|
447
|
+
// snapshot DOMAIN-graph guard (extends/skit recursion) and stay on the
|
|
448
|
+
// legacy path only; they are NOT re-implemented for the npm closure here.
|
|
449
|
+
// • skit / glpkg lanes (§4 Phase-2c) — this collector is the npm lane only.
|
|
450
|
+
/**
|
|
451
|
+
* Feature-flag gate for the new distkit closure path (§1.2 wiring target).
|
|
452
|
+
*
|
|
453
|
+
* OFF by default. Defined now so the future §1.2 caller has a single, documented
|
|
454
|
+
* switch; the collector itself is a pure additive export that no live path calls,
|
|
455
|
+
* so flipping this on has NO effect until §1.2 wires `walkClosure` behind it.
|
|
456
|
+
*
|
|
457
|
+
* Env: `SNAPSHOT_DISTKIT_CLOSURE=1` (or `true`).
|
|
458
|
+
*/
|
|
459
|
+
export const SNAPSHOT_DISTKIT_CLOSURE_FLAG = 'SNAPSHOT_DISTKIT_CLOSURE';
|
|
460
|
+
/** True iff the distkit closure path is enabled via {@link SNAPSHOT_DISTKIT_CLOSURE_FLAG}. */
|
|
461
|
+
export function isDistkitClosureEnabled() {
|
|
462
|
+
const v = process.env[SNAPSHOT_DISTKIT_CLOSURE_FLAG];
|
|
463
|
+
return v === '1' || v === 'true';
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Cache of fetched npm root manifests (package.json-shaped), keyed `name@version`.
|
|
467
|
+
* Separate from {@link skitManifestCache} (that reads the packument `skit` field;
|
|
468
|
+
* this reads the standard npm dependency maps).
|
|
469
|
+
*/
|
|
470
|
+
const npmRootManifestCache = new Map();
|
|
471
|
+
/**
|
|
472
|
+
* Fetch an npm root's `package.json`-shaped manifest from the registry-proxy
|
|
473
|
+
* packument (`GET {REGISTRY_PROXY_URL}/{name}` → `{ 'dist-tags', versions }`).
|
|
474
|
+
*
|
|
475
|
+
* This is the npm analogue of {@link fetchSkitManifest}: same packument source,
|
|
476
|
+
* but it reads the standard npm dependency maps
|
|
477
|
+
* (`dependencies`/`optionalDependencies`/`devDependencies`/`peerDependencies`)
|
|
478
|
+
* that the distkit npm adapter's `parseDependencies` expects — NOT the `skit`
|
|
479
|
+
* field. Resolves the `latest` dist-tag; other specs are looked up as exact keys.
|
|
480
|
+
*
|
|
481
|
+
* @returns the manifest + the exact version it resolved to, or `null` if the
|
|
482
|
+
* package / version is not present (surfaced by the collector as an error;
|
|
483
|
+
* authoritative range→exact resolution is distkit's adapter job at §1.2).
|
|
484
|
+
*/
|
|
485
|
+
async function fetchNpmRootManifest(pkgName, version) {
|
|
486
|
+
const cacheKey = `${pkgName}@${version}`;
|
|
487
|
+
const cached = npmRootManifestCache.get(cacheKey);
|
|
488
|
+
if (cached) {
|
|
489
|
+
return cached;
|
|
490
|
+
}
|
|
491
|
+
const sessionToken = getLicenseKey();
|
|
492
|
+
const headers = {
|
|
493
|
+
'Accept': 'application/json',
|
|
494
|
+
};
|
|
495
|
+
if (sessionToken) {
|
|
496
|
+
headers['Authorization'] = `Bearer ${sessionToken}`;
|
|
497
|
+
}
|
|
498
|
+
try {
|
|
499
|
+
const url = `${REGISTRY_PROXY_URL}/${pkgName}`;
|
|
500
|
+
const response = await fetch(url, { headers });
|
|
501
|
+
if (!response.ok) {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
const data = await response.json();
|
|
505
|
+
const distTags = data['dist-tags'];
|
|
506
|
+
const versions = data['versions'];
|
|
507
|
+
// Resolve the `latest` dist-tag; otherwise treat `version` as an exact key.
|
|
508
|
+
// (Range specs are NOT resolved here — distkit's adapter owns range→exact at
|
|
509
|
+
// §1.2; an unresolvable spec yields null and a recorded collector error.)
|
|
510
|
+
let targetVersion = version;
|
|
511
|
+
if ((version === 'latest' || version === '') && distTags?.['latest']) {
|
|
512
|
+
targetVersion = distTags['latest'];
|
|
513
|
+
}
|
|
514
|
+
const versionData = versions?.[targetVersion];
|
|
515
|
+
if (!versionData) {
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
const manifest = {};
|
|
519
|
+
const deps = versionData['dependencies'];
|
|
520
|
+
const optional = versionData['optionalDependencies'];
|
|
521
|
+
const dev = versionData['devDependencies'];
|
|
522
|
+
const peer = versionData['peerDependencies'];
|
|
523
|
+
if (deps)
|
|
524
|
+
manifest.dependencies = { ...deps };
|
|
525
|
+
if (optional)
|
|
526
|
+
manifest.optionalDependencies = { ...optional };
|
|
527
|
+
if (dev)
|
|
528
|
+
manifest.devDependencies = { ...dev };
|
|
529
|
+
if (peer)
|
|
530
|
+
manifest.peerDependencies = { ...peer };
|
|
531
|
+
const result = { manifest, resolvedVersion: targetVersion };
|
|
532
|
+
npmRootManifestCache.set(cacheKey, result);
|
|
533
|
+
return result;
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Phase-2b §1.1 collector: walk the snapshot/skit domain graph and emit the npm
|
|
541
|
+
* lane as `ClosureRoot[]` for distkit's `walkClosure`.
|
|
542
|
+
*
|
|
543
|
+
* Reuses `traverseSnapshot` (the unchanged domain-graph walk: `extends`, `skits`,
|
|
544
|
+
* `install`, `packages`, `registry`, and skit.json `dependencies.{npm,skit,cli}`)
|
|
545
|
+
* to discover the directly-declared npm packages, then fetches each one's
|
|
546
|
+
* `package.json`-shaped manifest and maps it to a {@link ClosureRoot}:
|
|
547
|
+
*
|
|
548
|
+
* { name, version, ecosystem: 'npm', manifest, installTarget }
|
|
549
|
+
*
|
|
550
|
+
* NOTE (pre-wiring, fail-soft): a package whose manifest cannot be fetched is
|
|
551
|
+
* still emitted (with an empty `{}` manifest) and an error is recorded — so a
|
|
552
|
+
* parity fixture surfaces the gap. Authoritative fail-loud + range→exact version
|
|
553
|
+
* resolution move in with distkit's adapter at §1.2 / §1.4.
|
|
554
|
+
*
|
|
555
|
+
* This function is on NO live install path — it is the §1.1 deliverable only.
|
|
556
|
+
*/
|
|
557
|
+
export async function collectNpmClosureRoots(snapshotName, options = {}) {
|
|
558
|
+
const { scopes, installTarget = 'cli-global' } = options;
|
|
559
|
+
// 1. Reuse the unchanged snapshot/skit domain-graph walk (same ctx shape as
|
|
560
|
+
// resolveAllDependencies) to collect the directly-declared npm packages.
|
|
561
|
+
const ctx = {
|
|
562
|
+
visitedSnapshots: new Set(),
|
|
563
|
+
visitedSkits: new Set(),
|
|
564
|
+
collectedNpm: new Map(),
|
|
565
|
+
collectedSkit: new Map(),
|
|
566
|
+
errors: [],
|
|
567
|
+
scopeGroups: new Map(),
|
|
568
|
+
};
|
|
569
|
+
await traverseSnapshot(snapshotName, ctx);
|
|
570
|
+
// 2. Select npm entry packages → optionally filter by scope.
|
|
571
|
+
let entries = Array.from(ctx.collectedNpm.values());
|
|
572
|
+
if (scopes && scopes.length > 0) {
|
|
573
|
+
entries = entries.filter(p => scopes.some(scope => p.name.startsWith(scope)));
|
|
574
|
+
}
|
|
575
|
+
// 3. Fetch each root's package.json-shaped manifest and map → ClosureRoot[].
|
|
576
|
+
const { roots, errors: rootErrors } = await buildNpmClosureRoots(entries, { installTarget });
|
|
577
|
+
return {
|
|
578
|
+
roots,
|
|
579
|
+
errors: [...ctx.errors, ...rootErrors],
|
|
580
|
+
scopeGroups: Object.fromEntries(ctx.scopeGroups),
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Build `ClosureRoot[]` from an explicit list of npm pins (name + exact version),
|
|
585
|
+
* fetching each pin's `package.json`-shaped manifest from the registry-proxy
|
|
586
|
+
* packument. Extracted from {@link collectNpmClosureRoots} (behaviour-identical)
|
|
587
|
+
* so the §5-step6 install-resolution switch can build roots from the pins the
|
|
588
|
+
* preflight adapter already computed (WITHOUT re-walking the snapshot graph —
|
|
589
|
+
* important during `snapshot publish`, where the snapshot is LOCAL/unpublished).
|
|
590
|
+
*
|
|
591
|
+
* Deterministic (sorted by name). A pin whose manifest cannot be fetched is still
|
|
592
|
+
* emitted (empty `{}` manifest) AND recorded in `errors` — the caller decides
|
|
593
|
+
* fail-soft (collector §1.1) vs fail-loud (install path §1.4).
|
|
594
|
+
*/
|
|
595
|
+
export async function buildNpmClosureRoots(pins, options = {}) {
|
|
596
|
+
const { installTarget = 'cli-global' } = options;
|
|
597
|
+
const errors = [];
|
|
598
|
+
const roots = [];
|
|
599
|
+
for (const pkg of pins) {
|
|
600
|
+
const fetched = await fetchNpmRootManifest(pkg.name, pkg.version);
|
|
601
|
+
if (!fetched) {
|
|
602
|
+
errors.push({
|
|
603
|
+
name: `${pkg.name}@${pkg.version}`,
|
|
604
|
+
error: 'Failed to fetch npm root manifest (package/version not in packument, or non-exact spec)',
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
roots.push({
|
|
608
|
+
name: pkg.name,
|
|
609
|
+
version: fetched?.resolvedVersion ?? pkg.version,
|
|
610
|
+
ecosystem: 'npm',
|
|
611
|
+
manifest: fetched?.manifest ?? {},
|
|
612
|
+
installTarget,
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
// Deterministic order (parity-friendly; distkit re-sorts internally anyway).
|
|
616
|
+
roots.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
617
|
+
return { roots, errors };
|
|
618
|
+
}
|
|
430
619
|
/**
|
|
431
620
|
* 캐시 클리어
|
|
432
621
|
*/
|
|
433
622
|
export function clearTransitiveCache() {
|
|
434
623
|
skitManifestCache.clear();
|
|
624
|
+
npmRootManifestCache.clear();
|
|
435
625
|
}
|
|
436
626
|
//# sourceMappingURL=transitive-resolver.js.map
|