@antongolub/lockfile 0.0.0-snapshot.44 → 0.0.0-snapshot.46
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/SCHEMAS.md +1 -0
- package/dist/{_npm-flat-types-DwOV4BpV.d.ts → _npm-flat-types-C3oOIC0o.d.ts} +1 -1
- package/dist/{_pnpm-flat-core-_4KM9kQj.d.ts → _pnpm-flat-core-C5VUToQP.d.ts} +1 -1
- package/dist/{_yarn-berry-core-EKBJ_ohM.d.ts → _yarn-berry-core-sjtp6At6.d.ts} +1 -1
- package/dist/complete.d.ts +68 -0
- package/dist/complete.js +298 -0
- package/dist/formats/bun-text.d.ts +1 -1
- package/dist/formats/bun-text.js +54 -12
- package/dist/formats/npm-1.d.ts +1 -1
- package/dist/formats/npm-1.js +54 -12
- package/dist/formats/npm-2.d.ts +2 -2
- package/dist/formats/npm-2.js +78 -17
- package/dist/formats/npm-3.d.ts +2 -2
- package/dist/formats/npm-3.js +78 -17
- package/dist/formats/pnpm-v5.d.ts +1 -1
- package/dist/formats/pnpm-v5.js +96 -16
- package/dist/formats/pnpm-v6.d.ts +2 -2
- package/dist/formats/pnpm-v6.js +91 -16
- package/dist/formats/pnpm-v9.d.ts +2 -2
- package/dist/formats/pnpm-v9.js +91 -16
- package/dist/formats/yarn-berry-v10.d.ts +24 -0
- package/dist/formats/yarn-berry-v10.js +2380 -0
- package/dist/formats/yarn-berry-v4.d.ts +2 -2
- package/dist/formats/yarn-berry-v4.js +159 -27
- package/dist/formats/yarn-berry-v5.d.ts +2 -2
- package/dist/formats/yarn-berry-v5.js +159 -27
- package/dist/formats/yarn-berry-v6.d.ts +2 -2
- package/dist/formats/yarn-berry-v6.js +159 -27
- package/dist/formats/yarn-berry-v7.d.ts +2 -2
- package/dist/formats/yarn-berry-v7.js +159 -27
- package/dist/formats/yarn-berry-v8.d.ts +2 -2
- package/dist/formats/yarn-berry-v8.js +159 -27
- package/dist/formats/yarn-berry-v9.d.ts +2 -2
- package/dist/formats/yarn-berry-v9.js +159 -27
- package/dist/formats/yarn-classic.d.ts +1 -1
- package/dist/formats/yarn-classic.js +84 -13
- package/dist/{graph-BzsItuAI.d.ts → graph-XpDkFSjz.d.ts} +3 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +1973 -156
- package/dist/modify-C4BdPHYO.d.ts +218 -0
- package/dist/modify.d.ts +20 -0
- package/dist/modify.js +988 -0
- package/dist/optimize-Du6S8Ld1.d.ts +33 -0
- package/dist/optimize.d.ts +24 -0
- package/dist/optimize.js +132 -0
- package/dist/registry.d.ts +60 -0
- package/dist/registry.js +649 -0
- package/dist/types-Ci06KZkZ.d.ts +46 -0
- package/package.json +22 -1
package/SCHEMAS.md
CHANGED
|
@@ -33,6 +33,7 @@ berry's `__metadata`.
|
|
|
33
33
|
| `yarn-berry-v6` | `__metadata.version: 6` | yarn `>=3.2 <4` | yarn `>=3.2` |
|
|
34
34
|
| `yarn-berry-v8` | `__metadata.version: 8` | yarn `>=4.0 <4.14` | yarn `>=4` |
|
|
35
35
|
| `yarn-berry-v9` | `__metadata.version: 9` | yarn `>=4.14` | yarn `>=4.14` |
|
|
36
|
+
| `yarn-berry-v10` | `__metadata.version: 10` | yarn 5 (dev branch) | yarn 5+ (preview — reverse-engineered from yarnpkg/berry master) |
|
|
36
37
|
|
|
37
38
|
**Schema numbers that don't exist:**
|
|
38
39
|
- `__metadata.version: 1` and `2` were never used by berry.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { N as NodeId, D as Diagnostic, G as Graph, E as EdgeTriple, a as Node, b as EdgeKind } from './graph-XpDkFSjz.js';
|
|
2
|
+
import { R as RegistryAdapter } from './types-Ci06KZkZ.js';
|
|
3
|
+
|
|
4
|
+
interface CompletionSeed {
|
|
5
|
+
/** NodeIds the modifier added in the just-completed mutate phase. */
|
|
6
|
+
recentlyAdded: Set<NodeId>;
|
|
7
|
+
/** NodeIds the mutate phase orphaned. The completion frontier excludes
|
|
8
|
+
* these — optimize phase collects. */
|
|
9
|
+
recentlyOrphaned: Set<NodeId>;
|
|
10
|
+
}
|
|
11
|
+
interface CompletionResult {
|
|
12
|
+
graph: Graph;
|
|
13
|
+
added: NodeId[];
|
|
14
|
+
wired: EdgeTriple[];
|
|
15
|
+
unresolved: Diagnostic[];
|
|
16
|
+
}
|
|
17
|
+
interface CompletionOptions {
|
|
18
|
+
seed?: CompletionSeed;
|
|
19
|
+
onDiagnostic?: (d: Diagnostic) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Walk graph, query registry for missing transitive deps, wire edges.
|
|
23
|
+
* Monotone-additive: returned graph ⊇ input graph (no removals).
|
|
24
|
+
*/
|
|
25
|
+
declare function completeTransitives(graph: Graph, registry: RegistryAdapter, options?: CompletionOptions): Promise<CompletionResult>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Walk consumer → root via incoming-edge BFS.
|
|
29
|
+
* Returns nodes in BFS order: consumer first, deeper ancestors last.
|
|
30
|
+
* Cycles tolerated via `seen`.
|
|
31
|
+
*/
|
|
32
|
+
declare function ancestorsOf(graph: Graph, consumer: NodeId): Node[];
|
|
33
|
+
/**
|
|
34
|
+
* Find-up resolve per ADR-0023 §5.1.
|
|
35
|
+
*
|
|
36
|
+
* Returns the closest-ancestor satisfying node, or undefined if either
|
|
37
|
+
* (a) no ancestor declares `name` at all → caller may install nested at the
|
|
38
|
+
* consumer's level, or
|
|
39
|
+
* (b) the closest ancestor that declares `name` does so with a conflicting
|
|
40
|
+
* range → "block hoist", caller installs nested fallback (npm-3 style).
|
|
41
|
+
*
|
|
42
|
+
* Tiebreaker:
|
|
43
|
+
* 1. Highest semver-comparable version wins (`semver.rcompare`).
|
|
44
|
+
* 2. On version tie, lowest NodeId lex order wins.
|
|
45
|
+
*
|
|
46
|
+
* `depKind` is part of the §5.1 normative signature but does NOT affect the
|
|
47
|
+
* algorithm body in v1: every dep-kind (dep / dev / optional / peer) follows
|
|
48
|
+
* the same closest-ancestor reuse + block-hoist contract. The parameter is
|
|
49
|
+
* carried verbatim so future kind-filtered hoist policies (e.g. peer-deps
|
|
50
|
+
* needing a stricter find-up, or optional-deps allowed to silently fail
|
|
51
|
+
* differently from regular deps) can branch on it without a signature
|
|
52
|
+
* migration. Per the ADR §5.1 pseudocode body and the v1 normative scope, no
|
|
53
|
+
* kind-specific branch is taken yet.
|
|
54
|
+
*/
|
|
55
|
+
declare function resolveFindUp(graph: Graph, consumerId: NodeId, name: string, range: string, depKind: EdgeKind): NodeId | undefined;
|
|
56
|
+
|
|
57
|
+
type CompletionDiagnosticCode = 'COMPLETION_NODE_ADDED' | 'COMPLETION_EDGE_RESOLVED' | 'COMPLETION_UNRESOLVED' | 'COMPLETION_NODE_UNKNOWN' | 'COMPLETION_VERSION_UNKNOWN' | 'COMPLETION_PEER_CONTEXT_INCOMPLETE';
|
|
58
|
+
interface CompletionDiagnostic extends Diagnostic {
|
|
59
|
+
code: CompletionDiagnosticCode;
|
|
60
|
+
}
|
|
61
|
+
declare function completionNodeAdded(nodeId: NodeId): CompletionDiagnostic;
|
|
62
|
+
declare function completionEdgeResolved(triple: EdgeTriple): CompletionDiagnostic;
|
|
63
|
+
declare function completionUnresolved(consumer: NodeId, depName: string, depRange: string): CompletionDiagnostic;
|
|
64
|
+
declare function completionNodeUnknown(nodeId: NodeId): CompletionDiagnostic;
|
|
65
|
+
declare function completionVersionUnknown(nodeId: NodeId): CompletionDiagnostic;
|
|
66
|
+
declare function completionPeerContextIncomplete(nodeId: NodeId, peerName: string, peerRange: string): CompletionDiagnostic;
|
|
67
|
+
|
|
68
|
+
export { type CompletionDiagnostic, type CompletionDiagnosticCode, type CompletionOptions, type CompletionResult, type CompletionSeed, ancestorsOf, completeTransitives, completionEdgeResolved, completionNodeAdded, completionNodeUnknown, completionPeerContextIncomplete, completionUnresolved, completionVersionUnknown, resolveFindUp };
|
package/dist/complete.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import 'crypto';
|
|
2
|
+
import 'buffer';
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
|
|
5
|
+
// src/main/ts/errors.ts
|
|
6
|
+
|
|
7
|
+
// src/main/ts/graph.ts
|
|
8
|
+
function serializeNodeId(name, version, peerContext, patch) {
|
|
9
|
+
const base = toTarballKey({ name, version});
|
|
10
|
+
if (peerContext.length === 0) return base;
|
|
11
|
+
return base + peerContext.map((p) => `(${p})`).join("");
|
|
12
|
+
}
|
|
13
|
+
function toTarballKey(inputs) {
|
|
14
|
+
const slots = [];
|
|
15
|
+
return slots.length === 0 ? `${inputs.name}@${inputs.version}` : `${inputs.name}@${inputs.version}+${slots.sort(cmpStr).join("+")}`;
|
|
16
|
+
}
|
|
17
|
+
var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
18
|
+
var cmpStr2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
19
|
+
function ancestorsOf(graph, consumer) {
|
|
20
|
+
const consumerNode = graph.getNode(consumer);
|
|
21
|
+
if (consumerNode === void 0) return [];
|
|
22
|
+
const result = [consumerNode];
|
|
23
|
+
const seen = /* @__PURE__ */ new Set([consumer]);
|
|
24
|
+
const queue = [consumer];
|
|
25
|
+
while (queue.length > 0) {
|
|
26
|
+
const cur = queue.shift();
|
|
27
|
+
for (const edge of graph.in(cur)) {
|
|
28
|
+
if (seen.has(edge.src)) continue;
|
|
29
|
+
const srcNode = graph.getNode(edge.src);
|
|
30
|
+
if (srcNode === void 0) continue;
|
|
31
|
+
seen.add(edge.src);
|
|
32
|
+
result.push(srcNode);
|
|
33
|
+
queue.push(edge.src);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
function resolveFindUp(graph, consumerId, name, range, depKind) {
|
|
39
|
+
const path = ancestorsOf(graph, consumerId);
|
|
40
|
+
for (const ancestor of path) {
|
|
41
|
+
const candidates = [];
|
|
42
|
+
for (const edge of graph.out(ancestor.id)) {
|
|
43
|
+
const dst = graph.getNode(edge.dst);
|
|
44
|
+
if (dst === void 0) continue;
|
|
45
|
+
if (dst.name === name) candidates.push(dst);
|
|
46
|
+
}
|
|
47
|
+
if (candidates.length === 0) continue;
|
|
48
|
+
const satisfying = candidates.filter((c) => safeSatisfies(c.version, range));
|
|
49
|
+
if (satisfying.length === 0) {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
satisfying.sort((a, b) => {
|
|
53
|
+
const v = semverRcompareSafe(a.version, b.version);
|
|
54
|
+
if (v !== 0) return v;
|
|
55
|
+
return cmpStr2(a.id, b.id);
|
|
56
|
+
});
|
|
57
|
+
return satisfying[0].id;
|
|
58
|
+
}
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
function safeSatisfies(version, range) {
|
|
62
|
+
try {
|
|
63
|
+
return semver.satisfies(version, range);
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function semverRcompareSafe(a, b) {
|
|
69
|
+
const va = semver.valid(a);
|
|
70
|
+
const vb = semver.valid(b);
|
|
71
|
+
if (va !== null && vb !== null) return semver.rcompare(a, b);
|
|
72
|
+
return cmpStr2(b, a);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/main/ts/complete/diagnostics.ts
|
|
76
|
+
function completionNodeAdded(nodeId) {
|
|
77
|
+
return {
|
|
78
|
+
code: "COMPLETION_NODE_ADDED",
|
|
79
|
+
severity: "info",
|
|
80
|
+
subject: nodeId,
|
|
81
|
+
message: `completion added ${nodeId}`
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function completionEdgeResolved(triple) {
|
|
85
|
+
return {
|
|
86
|
+
code: "COMPLETION_EDGE_RESOLVED",
|
|
87
|
+
severity: "info",
|
|
88
|
+
subject: triple,
|
|
89
|
+
message: `wired ${triple.src} \u2192${triple.kind} ${triple.dst} via find-up reuse`
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function completionUnresolved(consumer, depName, depRange) {
|
|
93
|
+
return {
|
|
94
|
+
code: "COMPLETION_UNRESOLVED",
|
|
95
|
+
severity: "warning",
|
|
96
|
+
subject: consumer,
|
|
97
|
+
message: `cannot resolve ${depName}@${depRange} for consumer ${consumer}`
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function completionNodeUnknown(nodeId) {
|
|
101
|
+
return {
|
|
102
|
+
code: "COMPLETION_NODE_UNKNOWN",
|
|
103
|
+
severity: "warning",
|
|
104
|
+
subject: nodeId,
|
|
105
|
+
message: `registry has no packument for ${nodeId}`
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function completionVersionUnknown(nodeId) {
|
|
109
|
+
return {
|
|
110
|
+
code: "COMPLETION_VERSION_UNKNOWN",
|
|
111
|
+
severity: "warning",
|
|
112
|
+
subject: nodeId,
|
|
113
|
+
message: `packument lacks version for ${nodeId}`
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function completionPeerContextIncomplete(nodeId, peerName, peerRange) {
|
|
117
|
+
return {
|
|
118
|
+
code: "COMPLETION_PEER_CONTEXT_INCOMPLETE",
|
|
119
|
+
severity: "warning",
|
|
120
|
+
subject: nodeId,
|
|
121
|
+
message: `peer ${peerName}@${peerRange} unresolved at completion for ${nodeId}`
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/main/ts/complete/tree-complete.ts
|
|
126
|
+
var EMPTY_SEED = {
|
|
127
|
+
recentlyAdded: /* @__PURE__ */ new Set(),
|
|
128
|
+
recentlyOrphaned: /* @__PURE__ */ new Set()
|
|
129
|
+
};
|
|
130
|
+
async function completeTransitives(graph, registry, options = {}) {
|
|
131
|
+
const seed = options.seed ?? EMPTY_SEED;
|
|
132
|
+
const onDiagnostic = options.onDiagnostic;
|
|
133
|
+
const visited = /* @__PURE__ */ new Set();
|
|
134
|
+
const added = [];
|
|
135
|
+
const wired = [];
|
|
136
|
+
const unresolved = [];
|
|
137
|
+
let currentGraph = graph;
|
|
138
|
+
const emit = (d) => {
|
|
139
|
+
unresolved.push(d);
|
|
140
|
+
if (onDiagnostic !== void 0) onDiagnostic(d);
|
|
141
|
+
};
|
|
142
|
+
const emitAndLand = (d) => {
|
|
143
|
+
emit(d);
|
|
144
|
+
currentGraph = currentGraph.mutate((m) => {
|
|
145
|
+
m.diagnostic(d);
|
|
146
|
+
}).graph;
|
|
147
|
+
};
|
|
148
|
+
const frontier = [];
|
|
149
|
+
for (const root of currentGraph.roots()) {
|
|
150
|
+
if (!seed.recentlyOrphaned.has(root)) frontier.push(root);
|
|
151
|
+
}
|
|
152
|
+
for (const id of seed.recentlyAdded) {
|
|
153
|
+
if (!seed.recentlyOrphaned.has(id)) frontier.push(id);
|
|
154
|
+
}
|
|
155
|
+
while (frontier.length > 0) {
|
|
156
|
+
const nodeId = frontier.shift();
|
|
157
|
+
if (visited.has(nodeId)) continue;
|
|
158
|
+
visited.add(nodeId);
|
|
159
|
+
const node = currentGraph.getNode(nodeId);
|
|
160
|
+
if (node === void 0) continue;
|
|
161
|
+
if (node.workspacePath !== void 0) {
|
|
162
|
+
for (const edge of currentGraph.out(nodeId)) {
|
|
163
|
+
if (!visited.has(edge.dst)) frontier.push(edge.dst);
|
|
164
|
+
}
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const packument = await registry.packument(node.name);
|
|
168
|
+
if (packument === void 0) {
|
|
169
|
+
for (const edge of currentGraph.out(nodeId)) {
|
|
170
|
+
if (!visited.has(edge.dst)) frontier.push(edge.dst);
|
|
171
|
+
}
|
|
172
|
+
emitAndLand(completionNodeUnknown(nodeId));
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const pv = packument.versions[node.version];
|
|
176
|
+
if (pv === void 0) {
|
|
177
|
+
for (const edge of currentGraph.out(nodeId)) {
|
|
178
|
+
if (!visited.has(edge.dst)) frontier.push(edge.dst);
|
|
179
|
+
}
|
|
180
|
+
emitAndLand(completionVersionUnknown(nodeId));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const depBuckets = [
|
|
184
|
+
{ deps: pv.dependencies, kind: "dep" },
|
|
185
|
+
{ deps: pv.devDependencies, kind: "dev" },
|
|
186
|
+
{ deps: pv.optionalDependencies, kind: "optional" },
|
|
187
|
+
{ deps: pv.peerDependencies, kind: "peer" }
|
|
188
|
+
];
|
|
189
|
+
for (const { deps, kind } of depBuckets) {
|
|
190
|
+
if (deps === void 0) continue;
|
|
191
|
+
const depNames = Object.keys(deps).sort(cmpStr3);
|
|
192
|
+
for (const depName of depNames) {
|
|
193
|
+
const depRange = deps[depName];
|
|
194
|
+
if (alreadyWired(currentGraph, nodeId, depName, kind)) continue;
|
|
195
|
+
const targetId = resolveFindUp(currentGraph, nodeId, depName, depRange);
|
|
196
|
+
if (targetId !== void 0) {
|
|
197
|
+
if (kind === "peer") {
|
|
198
|
+
emitAndLand(completionPeerContextIncomplete(nodeId, depName, depRange));
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const triple2 = { src: nodeId, dst: targetId, kind };
|
|
202
|
+
const resolvedDiag = completionEdgeResolved(triple2);
|
|
203
|
+
const result2 = currentGraph.mutate((m) => {
|
|
204
|
+
m.addEdge(nodeId, targetId, kind, { range: depRange });
|
|
205
|
+
m.diagnostic(resolvedDiag);
|
|
206
|
+
});
|
|
207
|
+
currentGraph = result2.graph;
|
|
208
|
+
wired.push(triple2);
|
|
209
|
+
emit(resolvedDiag);
|
|
210
|
+
if (!visited.has(targetId)) frontier.push(targetId);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const resolved = await registry.resolve(depName, depRange);
|
|
214
|
+
if (resolved === void 0) {
|
|
215
|
+
if (kind === "peer") {
|
|
216
|
+
emitAndLand(completionPeerContextIncomplete(nodeId, depName, depRange));
|
|
217
|
+
} else {
|
|
218
|
+
emitAndLand(completionUnresolved(nodeId, depName, depRange));
|
|
219
|
+
}
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const newId = serializeNodeId(resolved.name, resolved.version, []);
|
|
223
|
+
const newNode = {
|
|
224
|
+
id: newId,
|
|
225
|
+
name: resolved.name,
|
|
226
|
+
version: resolved.version,
|
|
227
|
+
peerContext: []
|
|
228
|
+
};
|
|
229
|
+
const { inputs, payload } = projectPackumentVersion(resolved);
|
|
230
|
+
if (kind === "peer") {
|
|
231
|
+
emitAndLand(completionPeerContextIncomplete(nodeId, depName, depRange));
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
let alreadyAdded = false;
|
|
235
|
+
const nodeAddedDiag = completionNodeAdded(newId);
|
|
236
|
+
const result = currentGraph.mutate((m) => {
|
|
237
|
+
if (currentGraph.getNode(newId) === void 0) {
|
|
238
|
+
m.addNode(newNode);
|
|
239
|
+
m.setTarball(inputs, payload);
|
|
240
|
+
m.diagnostic(nodeAddedDiag);
|
|
241
|
+
} else {
|
|
242
|
+
alreadyAdded = true;
|
|
243
|
+
}
|
|
244
|
+
m.addEdge(nodeId, newId, kind, { range: depRange });
|
|
245
|
+
});
|
|
246
|
+
currentGraph = result.graph;
|
|
247
|
+
if (!alreadyAdded) {
|
|
248
|
+
added.push(newId);
|
|
249
|
+
emit(nodeAddedDiag);
|
|
250
|
+
}
|
|
251
|
+
const triple = { src: nodeId, dst: newId, kind };
|
|
252
|
+
wired.push(triple);
|
|
253
|
+
if (!visited.has(newId)) frontier.push(newId);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
for (const edge of currentGraph.out(nodeId)) {
|
|
257
|
+
if (!visited.has(edge.dst)) frontier.push(edge.dst);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
graph: currentGraph,
|
|
262
|
+
added,
|
|
263
|
+
wired,
|
|
264
|
+
unresolved
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function alreadyWired(graph, src, depName, kind) {
|
|
268
|
+
for (const edge of graph.out(src, kind)) {
|
|
269
|
+
const dst = graph.getNode(edge.dst);
|
|
270
|
+
if (dst !== void 0 && dst.name === depName) return true;
|
|
271
|
+
}
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
function projectPackumentVersion(pv) {
|
|
275
|
+
return {
|
|
276
|
+
inputs: {
|
|
277
|
+
name: pv.name,
|
|
278
|
+
version: pv.version
|
|
279
|
+
// patch is always undefined per §4.2 — completion does not synthesise patches.
|
|
280
|
+
},
|
|
281
|
+
payload: {
|
|
282
|
+
integrity: pv.integrity,
|
|
283
|
+
engines: pv.engines,
|
|
284
|
+
os: pv.os,
|
|
285
|
+
cpu: pv.cpu,
|
|
286
|
+
libc: pv.libc,
|
|
287
|
+
bin: pv.bin,
|
|
288
|
+
bundledDependencies: pv.bundledDependencies,
|
|
289
|
+
deprecated: pv.deprecated,
|
|
290
|
+
resolution: pv.tarball === void 0 ? void 0 : { type: "tarball", url: pv.tarball }
|
|
291
|
+
// license intentionally undefined — not carried on PackumentVersion;
|
|
292
|
+
// recipe-layer enrich may refine later per §4.2 footnote.
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
var cmpStr3 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
297
|
+
|
|
298
|
+
export { ancestorsOf, completeTransitives, completionEdgeResolved, completionNodeAdded, completionNodeUnknown, completionPeerContextIncomplete, completionUnresolved, completionVersionUnknown, resolveFindUp };
|
package/dist/formats/bun-text.js
CHANGED
|
@@ -98,9 +98,13 @@ function tarballKeyInputsOfNode(node) {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
101
|
+
var cmpAlias = (a, b) => a === b ? 0 : a === void 0 ? -1 : b === void 0 ? 1 : cmpStr(a, b);
|
|
101
102
|
var cmpEdgeBy = (end) => (a, b) => {
|
|
102
103
|
const c = cmpStr(end === "dst" ? a.dst : a.src, end === "dst" ? b.dst : b.src);
|
|
103
|
-
|
|
104
|
+
if (c !== 0) return c;
|
|
105
|
+
const k = cmpStr(a.kind, b.kind);
|
|
106
|
+
if (k !== 0) return k;
|
|
107
|
+
return cmpAlias(a.attrs?.alias, b.attrs?.alias);
|
|
104
108
|
};
|
|
105
109
|
function emptyState() {
|
|
106
110
|
return {
|
|
@@ -136,7 +140,7 @@ function removeMatching(arr, pred) {
|
|
|
136
140
|
arr.splice(i, 1);
|
|
137
141
|
return true;
|
|
138
142
|
}
|
|
139
|
-
var tripleKey = (e) => `${e.src}\0${e.kind}\0${e.dst}`;
|
|
143
|
+
var tripleKey = (e) => `${e.src}\0${e.kind}\0${e.dst}\0${e.attrs?.alias ?? ""}`;
|
|
140
144
|
function rebindNodeId(s, oldId, newId, newNode) {
|
|
141
145
|
s.nodes.set(newId, newNode);
|
|
142
146
|
s.nodes.delete(oldId);
|
|
@@ -146,7 +150,9 @@ function rebindNodeId(s, oldId, newId, newNode) {
|
|
|
146
150
|
for (const e of outs) {
|
|
147
151
|
const peerInc = s.incoming.get(e.dst);
|
|
148
152
|
if (peerInc) {
|
|
149
|
-
const idx = peerInc.findIndex(
|
|
153
|
+
const idx = peerInc.findIndex(
|
|
154
|
+
(x) => x.src === oldId && x.kind === e.kind && x.dst === e.dst && x.attrs?.alias === e.attrs?.alias
|
|
155
|
+
);
|
|
150
156
|
if (idx >= 0) peerInc[idx] = e;
|
|
151
157
|
}
|
|
152
158
|
}
|
|
@@ -156,11 +162,25 @@ function rebindNodeId(s, oldId, newId, newNode) {
|
|
|
156
162
|
for (const e of ins) {
|
|
157
163
|
const peerOut = s.outgoing.get(e.src);
|
|
158
164
|
if (peerOut) {
|
|
159
|
-
const idx = peerOut.findIndex(
|
|
165
|
+
const idx = peerOut.findIndex(
|
|
166
|
+
(x) => x.src === e.src && x.kind === e.kind && x.dst === oldId && x.attrs?.alias === e.attrs?.alias
|
|
167
|
+
);
|
|
160
168
|
if (idx >= 0) peerOut[idx] = e;
|
|
161
169
|
}
|
|
162
170
|
}
|
|
163
171
|
}
|
|
172
|
+
function protocolOf(range) {
|
|
173
|
+
const colonIdx = range.indexOf(":");
|
|
174
|
+
if (colonIdx <= 0) return void 0;
|
|
175
|
+
const prefix = range.slice(0, colonIdx);
|
|
176
|
+
return /^[a-z][a-z0-9+.-]*$/i.test(prefix) ? prefix : void 0;
|
|
177
|
+
}
|
|
178
|
+
function isPublishedSelfLink(edge) {
|
|
179
|
+
const range = edge.attrs?.range;
|
|
180
|
+
if (range === void 0) return false;
|
|
181
|
+
const proto = protocolOf(range);
|
|
182
|
+
return proto === void 0 || proto === "npm";
|
|
183
|
+
}
|
|
164
184
|
function validate(s) {
|
|
165
185
|
for (const d of s.diagnostics) {
|
|
166
186
|
if (d.severity === "error") {
|
|
@@ -178,16 +198,26 @@ function validate(s) {
|
|
|
178
198
|
}
|
|
179
199
|
const k = tripleKey(e);
|
|
180
200
|
if (seen.has(k)) {
|
|
181
|
-
|
|
201
|
+
const aliasSuffix = e.attrs?.alias !== void 0 ? ` (alias=${e.attrs.alias})` : "";
|
|
202
|
+
throw new GraphError("INVARIANT_VIOLATION", `duplicate edge: ${e.src} \u2192${e.kind} ${e.dst}${aliasSuffix}`);
|
|
182
203
|
}
|
|
183
204
|
seen.add(k);
|
|
184
205
|
}
|
|
185
206
|
}
|
|
186
207
|
for (const [id, node] of s.nodes) {
|
|
187
208
|
if (node.workspacePath !== void 0) {
|
|
188
|
-
const inc = s.incoming.get(id);
|
|
189
|
-
|
|
190
|
-
|
|
209
|
+
const inc = s.incoming.get(id) ?? [];
|
|
210
|
+
for (const edge of inc) {
|
|
211
|
+
if (s.nodes.get(edge.src)?.workspacePath !== void 0) continue;
|
|
212
|
+
if (isPublishedSelfLink(edge)) {
|
|
213
|
+
s.diagnostics.push({
|
|
214
|
+
code: "SEAL_PUBLISHED_SELF_LINK",
|
|
215
|
+
subject: id,
|
|
216
|
+
severity: "info",
|
|
217
|
+
message: `published self-link: ${edge.src} \u2192${edge.kind} ${id} (range ${edge.attrs?.range}) \u2014 published dependency resolved to co-located workspace`
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
191
221
|
throw new GraphError("INVARIANT_VIOLATION", `workspace node has incoming edges: ${id}`);
|
|
192
222
|
}
|
|
193
223
|
}
|
|
@@ -468,8 +498,10 @@ var GraphImpl = class _GraphImpl {
|
|
|
468
498
|
if (!next.nodes.has(src)) throw new GraphError("PATCH_REJECTED", `addEdge: src ${src} missing`);
|
|
469
499
|
if (!next.nodes.has(dst)) throw new GraphError("PATCH_REJECTED", `addEdge: dst ${dst} missing`);
|
|
470
500
|
const existing = next.outgoing.get(src) ?? [];
|
|
471
|
-
|
|
472
|
-
|
|
501
|
+
const newAlias = attrs?.alias;
|
|
502
|
+
if (existing.some((e2) => e2.dst === dst && e2.kind === kind && e2.attrs?.alias === newAlias)) {
|
|
503
|
+
const aliasSuffix = newAlias !== void 0 ? ` (alias=${newAlias})` : "";
|
|
504
|
+
throw new GraphError("PATCH_REJECTED", `addEdge: duplicate ${src} \u2192${kind} ${dst}${aliasSuffix}`);
|
|
473
505
|
}
|
|
474
506
|
const e = attrs ? { src, dst, kind, attrs } : { src, dst, kind };
|
|
475
507
|
pushTo(next.outgoing, src, e);
|
|
@@ -478,11 +510,15 @@ var GraphImpl = class _GraphImpl {
|
|
|
478
510
|
},
|
|
479
511
|
removeEdge(src, dst, kind) {
|
|
480
512
|
const outs = next.outgoing.get(src);
|
|
481
|
-
|
|
513
|
+
let removedAlias;
|
|
514
|
+
const found = outs?.findIndex((e) => e.dst === dst && e.kind === kind) ?? -1;
|
|
515
|
+
if (!outs || found < 0) {
|
|
482
516
|
throw new GraphError("PATCH_REJECTED", `removeEdge: ${src} \u2192${kind} ${dst} missing`);
|
|
483
517
|
}
|
|
518
|
+
removedAlias = outs[found]?.attrs?.alias;
|
|
519
|
+
outs.splice(found, 1);
|
|
484
520
|
const ins = next.incoming.get(dst);
|
|
485
|
-
if (ins) removeMatching(ins, (e) => e.src === src && e.kind === kind);
|
|
521
|
+
if (ins) removeMatching(ins, (e) => e.src === src && e.kind === kind && e.attrs?.alias === removedAlias);
|
|
486
522
|
applied.push({ kind: "edge-removed", subject: { src, dst, kind } });
|
|
487
523
|
},
|
|
488
524
|
replacePeerContext(id, peers) {
|
|
@@ -527,6 +563,12 @@ var GraphImpl = class _GraphImpl {
|
|
|
527
563
|
throw new GraphError("PATCH_REJECTED", `removeTarball: ${key} missing`);
|
|
528
564
|
}
|
|
529
565
|
applied.push({ kind: "tarball-removed", subject: key });
|
|
566
|
+
},
|
|
567
|
+
// ADR-0023 §8.6 — write-side diagnostic emit. Append to the staged
|
|
568
|
+
// diagnostics list; the resulting Graph.diagnostics() surfaces it
|
|
569
|
+
// once mutate() settles. Same append semantics as Builder.diagnostic.
|
|
570
|
+
diagnostic(d) {
|
|
571
|
+
next.diagnostics.push(d);
|
|
530
572
|
}
|
|
531
573
|
};
|
|
532
574
|
transaction(m);
|
package/dist/formats/npm-1.d.ts
CHANGED
package/dist/formats/npm-1.js
CHANGED
|
@@ -99,9 +99,13 @@ function tarballKeyInputsOfNode(node) {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
102
|
+
var cmpAlias = (a, b) => a === b ? 0 : a === void 0 ? -1 : b === void 0 ? 1 : cmpStr(a, b);
|
|
102
103
|
var cmpEdgeBy = (end) => (a, b) => {
|
|
103
104
|
const c = cmpStr(end === "dst" ? a.dst : a.src, end === "dst" ? b.dst : b.src);
|
|
104
|
-
|
|
105
|
+
if (c !== 0) return c;
|
|
106
|
+
const k = cmpStr(a.kind, b.kind);
|
|
107
|
+
if (k !== 0) return k;
|
|
108
|
+
return cmpAlias(a.attrs?.alias, b.attrs?.alias);
|
|
105
109
|
};
|
|
106
110
|
function emptyState() {
|
|
107
111
|
return {
|
|
@@ -137,7 +141,7 @@ function removeMatching(arr, pred) {
|
|
|
137
141
|
arr.splice(i, 1);
|
|
138
142
|
return true;
|
|
139
143
|
}
|
|
140
|
-
var tripleKey = (e) => `${e.src}\0${e.kind}\0${e.dst}`;
|
|
144
|
+
var tripleKey = (e) => `${e.src}\0${e.kind}\0${e.dst}\0${e.attrs?.alias ?? ""}`;
|
|
141
145
|
function rebindNodeId(s, oldId, newId, newNode) {
|
|
142
146
|
s.nodes.set(newId, newNode);
|
|
143
147
|
s.nodes.delete(oldId);
|
|
@@ -147,7 +151,9 @@ function rebindNodeId(s, oldId, newId, newNode) {
|
|
|
147
151
|
for (const e of outs) {
|
|
148
152
|
const peerInc = s.incoming.get(e.dst);
|
|
149
153
|
if (peerInc) {
|
|
150
|
-
const idx = peerInc.findIndex(
|
|
154
|
+
const idx = peerInc.findIndex(
|
|
155
|
+
(x) => x.src === oldId && x.kind === e.kind && x.dst === e.dst && x.attrs?.alias === e.attrs?.alias
|
|
156
|
+
);
|
|
151
157
|
if (idx >= 0) peerInc[idx] = e;
|
|
152
158
|
}
|
|
153
159
|
}
|
|
@@ -157,11 +163,25 @@ function rebindNodeId(s, oldId, newId, newNode) {
|
|
|
157
163
|
for (const e of ins) {
|
|
158
164
|
const peerOut = s.outgoing.get(e.src);
|
|
159
165
|
if (peerOut) {
|
|
160
|
-
const idx = peerOut.findIndex(
|
|
166
|
+
const idx = peerOut.findIndex(
|
|
167
|
+
(x) => x.src === e.src && x.kind === e.kind && x.dst === oldId && x.attrs?.alias === e.attrs?.alias
|
|
168
|
+
);
|
|
161
169
|
if (idx >= 0) peerOut[idx] = e;
|
|
162
170
|
}
|
|
163
171
|
}
|
|
164
172
|
}
|
|
173
|
+
function protocolOf(range) {
|
|
174
|
+
const colonIdx = range.indexOf(":");
|
|
175
|
+
if (colonIdx <= 0) return void 0;
|
|
176
|
+
const prefix = range.slice(0, colonIdx);
|
|
177
|
+
return /^[a-z][a-z0-9+.-]*$/i.test(prefix) ? prefix : void 0;
|
|
178
|
+
}
|
|
179
|
+
function isPublishedSelfLink(edge) {
|
|
180
|
+
const range = edge.attrs?.range;
|
|
181
|
+
if (range === void 0) return false;
|
|
182
|
+
const proto = protocolOf(range);
|
|
183
|
+
return proto === void 0 || proto === "npm";
|
|
184
|
+
}
|
|
165
185
|
function validate(s) {
|
|
166
186
|
for (const d of s.diagnostics) {
|
|
167
187
|
if (d.severity === "error") {
|
|
@@ -179,16 +199,26 @@ function validate(s) {
|
|
|
179
199
|
}
|
|
180
200
|
const k = tripleKey(e);
|
|
181
201
|
if (seen.has(k)) {
|
|
182
|
-
|
|
202
|
+
const aliasSuffix = e.attrs?.alias !== void 0 ? ` (alias=${e.attrs.alias})` : "";
|
|
203
|
+
throw new GraphError("INVARIANT_VIOLATION", `duplicate edge: ${e.src} \u2192${e.kind} ${e.dst}${aliasSuffix}`);
|
|
183
204
|
}
|
|
184
205
|
seen.add(k);
|
|
185
206
|
}
|
|
186
207
|
}
|
|
187
208
|
for (const [id, node] of s.nodes) {
|
|
188
209
|
if (node.workspacePath !== void 0) {
|
|
189
|
-
const inc = s.incoming.get(id);
|
|
190
|
-
|
|
191
|
-
|
|
210
|
+
const inc = s.incoming.get(id) ?? [];
|
|
211
|
+
for (const edge of inc) {
|
|
212
|
+
if (s.nodes.get(edge.src)?.workspacePath !== void 0) continue;
|
|
213
|
+
if (isPublishedSelfLink(edge)) {
|
|
214
|
+
s.diagnostics.push({
|
|
215
|
+
code: "SEAL_PUBLISHED_SELF_LINK",
|
|
216
|
+
subject: id,
|
|
217
|
+
severity: "info",
|
|
218
|
+
message: `published self-link: ${edge.src} \u2192${edge.kind} ${id} (range ${edge.attrs?.range}) \u2014 published dependency resolved to co-located workspace`
|
|
219
|
+
});
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
192
222
|
throw new GraphError("INVARIANT_VIOLATION", `workspace node has incoming edges: ${id}`);
|
|
193
223
|
}
|
|
194
224
|
}
|
|
@@ -469,8 +499,10 @@ var GraphImpl = class _GraphImpl {
|
|
|
469
499
|
if (!next.nodes.has(src)) throw new GraphError("PATCH_REJECTED", `addEdge: src ${src} missing`);
|
|
470
500
|
if (!next.nodes.has(dst)) throw new GraphError("PATCH_REJECTED", `addEdge: dst ${dst} missing`);
|
|
471
501
|
const existing = next.outgoing.get(src) ?? [];
|
|
472
|
-
|
|
473
|
-
|
|
502
|
+
const newAlias = attrs?.alias;
|
|
503
|
+
if (existing.some((e2) => e2.dst === dst && e2.kind === kind && e2.attrs?.alias === newAlias)) {
|
|
504
|
+
const aliasSuffix = newAlias !== void 0 ? ` (alias=${newAlias})` : "";
|
|
505
|
+
throw new GraphError("PATCH_REJECTED", `addEdge: duplicate ${src} \u2192${kind} ${dst}${aliasSuffix}`);
|
|
474
506
|
}
|
|
475
507
|
const e = attrs ? { src, dst, kind, attrs } : { src, dst, kind };
|
|
476
508
|
pushTo(next.outgoing, src, e);
|
|
@@ -479,11 +511,15 @@ var GraphImpl = class _GraphImpl {
|
|
|
479
511
|
},
|
|
480
512
|
removeEdge(src, dst, kind) {
|
|
481
513
|
const outs = next.outgoing.get(src);
|
|
482
|
-
|
|
514
|
+
let removedAlias;
|
|
515
|
+
const found = outs?.findIndex((e) => e.dst === dst && e.kind === kind) ?? -1;
|
|
516
|
+
if (!outs || found < 0) {
|
|
483
517
|
throw new GraphError("PATCH_REJECTED", `removeEdge: ${src} \u2192${kind} ${dst} missing`);
|
|
484
518
|
}
|
|
519
|
+
removedAlias = outs[found]?.attrs?.alias;
|
|
520
|
+
outs.splice(found, 1);
|
|
485
521
|
const ins = next.incoming.get(dst);
|
|
486
|
-
if (ins) removeMatching(ins, (e) => e.src === src && e.kind === kind);
|
|
522
|
+
if (ins) removeMatching(ins, (e) => e.src === src && e.kind === kind && e.attrs?.alias === removedAlias);
|
|
487
523
|
applied.push({ kind: "edge-removed", subject: { src, dst, kind } });
|
|
488
524
|
},
|
|
489
525
|
replacePeerContext(id, peers) {
|
|
@@ -528,6 +564,12 @@ var GraphImpl = class _GraphImpl {
|
|
|
528
564
|
throw new GraphError("PATCH_REJECTED", `removeTarball: ${key} missing`);
|
|
529
565
|
}
|
|
530
566
|
applied.push({ kind: "tarball-removed", subject: key });
|
|
567
|
+
},
|
|
568
|
+
// ADR-0023 §8.6 — write-side diagnostic emit. Append to the staged
|
|
569
|
+
// diagnostics list; the resulting Graph.diagnostics() surfaces it
|
|
570
|
+
// once mutate() settles. Same append semantics as Builder.diagnostic.
|
|
571
|
+
diagnostic(d) {
|
|
572
|
+
next.diagnostics.push(d);
|
|
531
573
|
}
|
|
532
574
|
};
|
|
533
575
|
transaction(m);
|