@antongolub/lockfile 0.0.0-snapshot.56 → 0.0.0-snapshot.58

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.
Files changed (46) hide show
  1. package/dist/{_npm-flat-types-DnyApcb5.d.ts → _npm-flat-types-C6TSaidU.d.ts} +1 -1
  2. package/dist/{_pnpm-flat-core-CTAPp1B_.d.ts → _pnpm-flat-core-NEg8x-yf.d.ts} +1 -1
  3. package/dist/{_yarn-berry-core-BX8m074X.d.ts → _yarn-berry-core-CLT-3m_j.d.ts} +1 -1
  4. package/dist/complete.d.ts +2 -2
  5. package/dist/complete.js +1 -1
  6. package/dist/formats/bun-text.d.ts +1 -1
  7. package/dist/formats/bun-text.js +30 -9
  8. package/dist/formats/npm-1.d.ts +1 -1
  9. package/dist/formats/npm-1.js +68 -17
  10. package/dist/formats/npm-2.d.ts +2 -2
  11. package/dist/formats/npm-2.js +73 -17
  12. package/dist/formats/npm-3.d.ts +2 -2
  13. package/dist/formats/npm-3.js +73 -17
  14. package/dist/formats/pnpm-v5.d.ts +1 -1
  15. package/dist/formats/pnpm-v5.js +30 -11
  16. package/dist/formats/pnpm-v6.d.ts +2 -2
  17. package/dist/formats/pnpm-v6.js +30 -11
  18. package/dist/formats/pnpm-v9.d.ts +2 -2
  19. package/dist/formats/pnpm-v9.js +30 -11
  20. package/dist/formats/yarn-berry-v10.d.ts +2 -2
  21. package/dist/formats/yarn-berry-v10.js +207 -55
  22. package/dist/formats/yarn-berry-v4.d.ts +2 -2
  23. package/dist/formats/yarn-berry-v4.js +207 -55
  24. package/dist/formats/yarn-berry-v5.d.ts +2 -2
  25. package/dist/formats/yarn-berry-v5.js +207 -55
  26. package/dist/formats/yarn-berry-v6.d.ts +2 -2
  27. package/dist/formats/yarn-berry-v6.js +207 -55
  28. package/dist/formats/yarn-berry-v7.d.ts +2 -2
  29. package/dist/formats/yarn-berry-v7.js +207 -55
  30. package/dist/formats/yarn-berry-v8.d.ts +2 -2
  31. package/dist/formats/yarn-berry-v8.js +207 -55
  32. package/dist/formats/yarn-berry-v9.d.ts +2 -2
  33. package/dist/formats/yarn-berry-v9.js +207 -55
  34. package/dist/formats/yarn-classic.d.ts +1 -1
  35. package/dist/formats/yarn-classic.js +132 -26
  36. package/dist/{graph-hx9HLuBV.d.ts → graph-B_G4OKqF.d.ts} +9 -1
  37. package/dist/index.d.ts +4 -4
  38. package/dist/index.js +275 -71
  39. package/dist/{modify-DowGqC4i.d.ts → modify-VjOK9KTg.d.ts} +2 -2
  40. package/dist/modify.d.ts +3 -3
  41. package/dist/modify.js +2 -2
  42. package/dist/{optimize-BK8NKQc1.d.ts → optimize-cMIkc20f.d.ts} +1 -1
  43. package/dist/optimize.d.ts +2 -2
  44. package/dist/registry.d.ts +3 -3
  45. package/dist/{types-D-9ZZM6k.d.ts → types-CGeGAM7Z.d.ts} +1 -1
  46. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { D as Diagnostic, O as OverrideConstraint } from './graph-hx9HLuBV.js';
1
+ import { D as Diagnostic, O as OverrideConstraint } from './graph-B_G4OKqF.js';
2
2
 
3
3
  interface NpmFamilyParseOptions {
4
4
  }
@@ -1,4 +1,4 @@
1
- import { D as Diagnostic, O as OverrideConstraint } from './graph-hx9HLuBV.js';
1
+ import { D as Diagnostic, O as OverrideConstraint } from './graph-B_G4OKqF.js';
2
2
 
3
3
  interface PnpmFamilyParseOptions {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { O as OverrideConstraint, D as Diagnostic } from './graph-hx9HLuBV.js';
1
+ import { O as OverrideConstraint, D as Diagnostic } from './graph-B_G4OKqF.js';
2
2
 
3
3
  interface YarnBerryFamilyParseOptions {
4
4
  workspaceRoot?: string;
@@ -1,5 +1,5 @@
1
- import { N as NodeId, D as Diagnostic, G as Graph, E as EdgeTriple, a as Node, b as EdgeKind } from './graph-hx9HLuBV.js';
2
- import { R as RegistryAdapter } from './types-D-9ZZM6k.js';
1
+ import { N as NodeId, D as Diagnostic, G as Graph, E as EdgeTriple, a as Node, b as EdgeKind } from './graph-B_G4OKqF.js';
2
+ import { R as RegistryAdapter } from './types-CGeGAM7Z.js';
3
3
 
4
4
  interface CompletionSeed {
5
5
  /** NodeIds the modifier added in the just-completed mutate phase. */
package/dist/complete.js CHANGED
@@ -5,7 +5,7 @@ import semver from 'semver';
5
5
  // src/main/ts/errors.ts
6
6
 
7
7
  // src/main/ts/graph.ts
8
- function serializeNodeId(name, version, peerContext, patch) {
8
+ function serializeNodeId(name, version, peerContext, patch, source) {
9
9
  const base = toTarballKey({ name, version});
10
10
  if (peerContext.length === 0) return base;
11
11
  return base + peerContext.map((p) => `(${p})`).join("");
@@ -1,4 +1,4 @@
1
- import { D as Diagnostic, G as Graph } from '../graph-hx9HLuBV.js';
1
+ import { D as Diagnostic, G as Graph } from '../graph-B_G4OKqF.js';
2
2
 
3
3
  interface BunTextParseOptions {
4
4
  }
@@ -33,15 +33,15 @@ var GraphError = class extends Error {
33
33
  this.code = code;
34
34
  }
35
35
  };
36
- function serializeNodeId(name, version, peerContext, patch) {
37
- const base = toTarballKey({ name, version, patch });
36
+ function serializeNodeId(name, version, peerContext, patch, source) {
37
+ const base = toTarballKey({ name, version, patch, source });
38
38
  if (peerContext.length === 0) return base;
39
39
  return base + peerContext.map((p) => `(${p})`).join("");
40
40
  }
41
41
  function acceptedNodeIds(node) {
42
- const bare = serializeNodeId(node.name, node.version, node.peerContext);
42
+ const bare = serializeNodeId(node.name, node.version, node.peerContext, void 0, node.source);
43
43
  if (node.patch === void 0) return [bare];
44
- const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch);
44
+ const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch, node.source);
45
45
  return bare === patched ? [bare] : [bare, patched];
46
46
  }
47
47
  function carriesPatchInNodeId(node) {
@@ -49,7 +49,8 @@ function carriesPatchInNodeId(node) {
49
49
  return stripPeerContextFromNodeId(node.id) === toTarballKey({
50
50
  name: node.name,
51
51
  version: node.version,
52
- patch: node.patch
52
+ patch: node.patch,
53
+ source: node.source
53
54
  });
54
55
  }
55
56
  function stripPeerContextFromNodeId(id) {
@@ -87,19 +88,39 @@ function refuseSentinelMutation(patch, opName, subject) {
87
88
  });
88
89
  }
89
90
  }
91
+ var SRC_TOKEN_RE = /^[0-9a-f]{16}$/;
92
+ function validateSourceToken(source) {
93
+ if (source.length === 0) {
94
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not be empty` });
95
+ }
96
+ if (source.includes("+")) {
97
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain '+'` });
98
+ }
99
+ if (/\s/.test(source)) {
100
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain whitespace` });
101
+ }
102
+ if (!SRC_TOKEN_RE.test(source)) {
103
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must be 16 lowercase-hex chars` });
104
+ }
105
+ }
90
106
  function toTarballKey(inputs) {
91
107
  const slots = [];
92
108
  if (inputs.patch !== void 0) {
93
109
  validatePatchToken(inputs.patch);
94
110
  slots.push(`patch=${inputs.patch}`);
95
111
  }
112
+ if (inputs.source !== void 0) {
113
+ validateSourceToken(inputs.source);
114
+ slots.push(`src=${inputs.source}`);
115
+ }
96
116
  return slots.length === 0 ? `${inputs.name}@${inputs.version}` : `${inputs.name}@${inputs.version}+${slots.sort(cmpStr).join("+")}`;
97
117
  }
98
118
  function tarballKeyInputsOfNode(node) {
99
119
  return {
100
120
  name: node.name,
101
121
  version: node.version,
102
- patch: node.patch
122
+ patch: node.patch,
123
+ source: node.source
103
124
  };
104
125
  }
105
126
  var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
@@ -498,7 +519,7 @@ var GraphImpl = class _GraphImpl {
498
519
  }
499
520
  rebindNodeId(next, id, newNode.id, newNode);
500
521
  }
501
- applied.push({ kind: "node-replaced", subject: newNode.id });
522
+ applied.push(newNode.id === id ? { kind: "node-replaced", subject: newNode.id } : { kind: "node-replaced", subject: newNode.id, oldSubject: id });
502
523
  },
503
524
  addEdge(src, dst, kind, attrs) {
504
525
  if (!next.nodes.has(src)) throw new GraphError("PATCH_REJECTED", `addEdge: src ${src} missing`);
@@ -534,7 +555,7 @@ var GraphImpl = class _GraphImpl {
534
555
  for (const p of peers) {
535
556
  if (!next.nodes.has(p)) throw new GraphError("PATCH_REJECTED", `replacePeerContext: peer ${p} missing`);
536
557
  }
537
- const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch) : serializeNodeId(old.name, old.version, peers);
558
+ const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch, old.source) : serializeNodeId(old.name, old.version, peers, void 0, old.source);
538
559
  if (newId !== id && next.nodes.has(newId)) {
539
560
  throw new GraphError("PATCH_REJECTED", `replacePeerContext: target id ${newId} already exists`);
540
561
  }
@@ -555,7 +576,7 @@ var GraphImpl = class _GraphImpl {
555
576
  pushTo(next.outgoing, newId, e);
556
577
  pushTo(next.incoming, p, e);
557
578
  }
558
- applied.push({ kind: "peer-context-replaced", subject: newId });
579
+ applied.push(newId === id ? { kind: "peer-context-replaced", subject: newId } : { kind: "peer-context-replaced", subject: newId, oldSubject: id });
559
580
  },
560
581
  setTarball(inputs, payload) {
561
582
  const key = toTarballKey(inputs);
@@ -1,4 +1,4 @@
1
- import { D as Diagnostic, G as Graph } from '../graph-hx9HLuBV.js';
1
+ import { D as Diagnostic, G as Graph } from '../graph-B_G4OKqF.js';
2
2
 
3
3
  interface Npm1ParseOptions {
4
4
  }
@@ -1,4 +1,4 @@
1
- import 'crypto';
1
+ import { createHash } from 'crypto';
2
2
  import 'buffer';
3
3
  import semver from 'semver';
4
4
 
@@ -34,15 +34,15 @@ var GraphError = class extends Error {
34
34
  this.code = code;
35
35
  }
36
36
  };
37
- function serializeNodeId(name, version, peerContext, patch) {
38
- const base = toTarballKey({ name, version, patch });
37
+ function serializeNodeId(name, version, peerContext, patch, source) {
38
+ const base = toTarballKey({ name, version, patch, source });
39
39
  if (peerContext.length === 0) return base;
40
40
  return base + peerContext.map((p) => `(${p})`).join("");
41
41
  }
42
42
  function acceptedNodeIds(node) {
43
- const bare = serializeNodeId(node.name, node.version, node.peerContext);
43
+ const bare = serializeNodeId(node.name, node.version, node.peerContext, void 0, node.source);
44
44
  if (node.patch === void 0) return [bare];
45
- const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch);
45
+ const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch, node.source);
46
46
  return bare === patched ? [bare] : [bare, patched];
47
47
  }
48
48
  function carriesPatchInNodeId(node) {
@@ -50,7 +50,8 @@ function carriesPatchInNodeId(node) {
50
50
  return stripPeerContextFromNodeId(node.id) === toTarballKey({
51
51
  name: node.name,
52
52
  version: node.version,
53
- patch: node.patch
53
+ patch: node.patch,
54
+ source: node.source
54
55
  });
55
56
  }
56
57
  function stripPeerContextFromNodeId(id) {
@@ -88,19 +89,39 @@ function refuseSentinelMutation(patch, opName, subject) {
88
89
  });
89
90
  }
90
91
  }
92
+ var SRC_TOKEN_RE = /^[0-9a-f]{16}$/;
93
+ function validateSourceToken(source) {
94
+ if (source.length === 0) {
95
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not be empty` });
96
+ }
97
+ if (source.includes("+")) {
98
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain '+'` });
99
+ }
100
+ if (/\s/.test(source)) {
101
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain whitespace` });
102
+ }
103
+ if (!SRC_TOKEN_RE.test(source)) {
104
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must be 16 lowercase-hex chars` });
105
+ }
106
+ }
91
107
  function toTarballKey(inputs) {
92
108
  const slots = [];
93
109
  if (inputs.patch !== void 0) {
94
110
  validatePatchToken(inputs.patch);
95
111
  slots.push(`patch=${inputs.patch}`);
96
112
  }
113
+ if (inputs.source !== void 0) {
114
+ validateSourceToken(inputs.source);
115
+ slots.push(`src=${inputs.source}`);
116
+ }
97
117
  return slots.length === 0 ? `${inputs.name}@${inputs.version}` : `${inputs.name}@${inputs.version}+${slots.sort(cmpStr).join("+")}`;
98
118
  }
99
119
  function tarballKeyInputsOfNode(node) {
100
120
  return {
101
121
  name: node.name,
102
122
  version: node.version,
103
- patch: node.patch
123
+ patch: node.patch,
124
+ source: node.source
104
125
  };
105
126
  }
106
127
  var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
@@ -499,7 +520,7 @@ var GraphImpl = class _GraphImpl {
499
520
  }
500
521
  rebindNodeId(next, id, newNode.id, newNode);
501
522
  }
502
- applied.push({ kind: "node-replaced", subject: newNode.id });
523
+ applied.push(newNode.id === id ? { kind: "node-replaced", subject: newNode.id } : { kind: "node-replaced", subject: newNode.id, oldSubject: id });
503
524
  },
504
525
  addEdge(src, dst, kind, attrs) {
505
526
  if (!next.nodes.has(src)) throw new GraphError("PATCH_REJECTED", `addEdge: src ${src} missing`);
@@ -535,7 +556,7 @@ var GraphImpl = class _GraphImpl {
535
556
  for (const p of peers) {
536
557
  if (!next.nodes.has(p)) throw new GraphError("PATCH_REJECTED", `replacePeerContext: peer ${p} missing`);
537
558
  }
538
- const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch) : serializeNodeId(old.name, old.version, peers);
559
+ const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch, old.source) : serializeNodeId(old.name, old.version, peers, void 0, old.source);
539
560
  if (newId !== id && next.nodes.has(newId)) {
540
561
  throw new GraphError("PATCH_REJECTED", `replacePeerContext: target id ${newId} already exists`);
541
562
  }
@@ -556,7 +577,7 @@ var GraphImpl = class _GraphImpl {
556
577
  pushTo(next.outgoing, newId, e);
557
578
  pushTo(next.incoming, p, e);
558
579
  }
559
- applied.push({ kind: "peer-context-replaced", subject: newId });
580
+ applied.push(newId === id ? { kind: "peer-context-replaced", subject: newId } : { kind: "peer-context-replaced", subject: newId, oldSubject: id });
560
581
  },
561
582
  setTarball(inputs, payload) {
562
583
  const key = toTarballKey(inputs);
@@ -697,8 +718,6 @@ function emitDropped(nodeId, feature, reason, onDiagnostic) {
697
718
  message: `${feature} dropped on emit: ${reason}`
698
719
  });
699
720
  }
700
-
701
- // src/main/ts/recipe/resolution.ts
702
721
  var HEX40_RE = /^[0-9a-f]{40}$/i;
703
722
  var SHA_FRAG_RE = /^[0-9a-f]{7,64}$/i;
704
723
  var GITHUB_HOST = "github.com";
@@ -884,6 +903,36 @@ function normaliseDirectoryPath(raw) {
884
903
  if (p === "./") return ".";
885
904
  return p;
886
905
  }
906
+ var REGISTRY_HOSTS = /* @__PURE__ */ new Set([
907
+ "registry.npmjs.org",
908
+ "registry.yarnpkg.com"
909
+ ]);
910
+ function hostOfTarballUrl(url) {
911
+ if (!url.startsWith("http://") && !url.startsWith("https://")) return void 0;
912
+ const noScheme = url.replace(/^https?:\/\//, "");
913
+ const host = noScheme.split("/")[0];
914
+ return host === void 0 || host.length === 0 ? void 0 : host;
915
+ }
916
+ function sourceDiscriminatorOf(resolution) {
917
+ const sourceString = canonicalSourceStringOf(resolution);
918
+ return sourceString === void 0 ? void 0 : sha256Prefix16(sourceString);
919
+ }
920
+ function canonicalSourceStringOf(resolution) {
921
+ switch (resolution.type) {
922
+ case "git":
923
+ return `git\0${resolution.url}\0${resolution.sha}`;
924
+ case "tarball": {
925
+ const host = hostOfTarballUrl(resolution.url);
926
+ return host !== void 0 && REGISTRY_HOSTS.has(host) ? void 0 : `tarball\0${host ?? resolution.url}`;
927
+ }
928
+ case "directory":
929
+ case "unknown":
930
+ return void 0;
931
+ }
932
+ }
933
+ function sha256Prefix16(input) {
934
+ return createHash("sha256").update(input, "utf8").digest("hex").slice(0, 16);
935
+ }
887
936
  function stringifyForNpm(can) {
888
937
  switch (can.type) {
889
938
  case "tarball":
@@ -996,7 +1045,9 @@ function parse2(input, _options = {}) {
996
1045
  });
997
1046
  continue;
998
1047
  }
999
- const id = `${declaredName}@${version}`;
1048
+ const resolved = entry.resolved ?? (isUrlLikeVersion(version) ? version : void 0);
1049
+ const source = resolved !== void 0 ? sourceDiscriminatorOf(parse(resolved, { sourceKind: "npm-resolved" })) : void 0;
1050
+ const id = serializeNodeId(declaredName, version, [], void 0, source);
1000
1051
  const installPath = parentPath === "" ? `node_modules/${declaredName}` : `${parentPath}/node_modules/${declaredName}`;
1001
1052
  if (!seenIds.has(id)) {
1002
1053
  seenIds.add(id);
@@ -1006,8 +1057,8 @@ function parse2(input, _options = {}) {
1006
1057
  version,
1007
1058
  peerContext: []
1008
1059
  };
1009
- const resolved = entry.resolved ?? (isUrlLikeVersion(version) ? version : void 0);
1010
1060
  if (resolved !== void 0) node.resolution = resolved;
1061
+ if (source !== void 0) node.source = source;
1011
1062
  builder.addNode(node);
1012
1063
  const payload = {};
1013
1064
  if (entry.integrity !== void 0) {
@@ -1027,7 +1078,7 @@ function parse2(input, _options = {}) {
1027
1078
  payload.resolution = canonical;
1028
1079
  }
1029
1080
  if (Object.keys(payload).length > 0) {
1030
- builder.setTarball({ name: declaredName, version }, payload);
1081
+ builder.setTarball({ name: declaredName, version, source }, payload);
1031
1082
  }
1032
1083
  }
1033
1084
  const sc = ensureSidecar(nodeSidecar, id);
@@ -1275,7 +1326,7 @@ function optimize(graph, _options = {}) {
1275
1326
  (a, b) => cmpStr2(`${a.src} ${a.kind} ${a.dst}`, `${b.src} ${b.kind} ${b.dst}`)
1276
1327
  );
1277
1328
  for (const node of graph.nodes()) {
1278
- const inputs = { name: node.name, version: node.version, patch: node.patch };
1329
+ const inputs = { name: node.name, version: node.version, patch: node.patch, source: node.source };
1279
1330
  const key = toTarballKey(inputs);
1280
1331
  if (unreachable.has(node.id)) {
1281
1332
  tarballsToRemove.set(key, inputs);
@@ -1631,7 +1682,7 @@ function planManifestEnrich(graph, sidecar, manifests) {
1631
1682
  const member = memberByName.get(node.name);
1632
1683
  if (member === void 0) continue;
1633
1684
  if (member.manifest.version !== void 0 && node.version !== member.manifest.version) continue;
1634
- if (graph.tarball({ name: node.name, version: node.version }) !== void 0) continue;
1685
+ if (graph.tarballOf(node.id) !== void 0) continue;
1635
1686
  memberNodeReplacements.push({ ...node, workspacePath: member.path });
1636
1687
  }
1637
1688
  for (const [name, { path, manifest }] of memberByName) {
@@ -1,5 +1,5 @@
1
- import { G as Graph, D as Diagnostic } from '../graph-hx9HLuBV.js';
2
- import { N as NpmFamilyEnrichOptions, a as NpmFamilyOptimizeOptions, b as NpmFamilyParseOptions, c as NpmFamilyStringifyOptions } from '../_npm-flat-types-DnyApcb5.js';
1
+ import { G as Graph, D as Diagnostic } from '../graph-B_G4OKqF.js';
2
+ import { N as NpmFamilyEnrichOptions, a as NpmFamilyOptimizeOptions, b as NpmFamilyParseOptions, c as NpmFamilyStringifyOptions } from '../_npm-flat-types-C6TSaidU.js';
3
3
 
4
4
  interface Npm2ParseOptions extends NpmFamilyParseOptions {
5
5
  }
@@ -1,5 +1,5 @@
1
1
  import semver from 'semver';
2
- import 'crypto';
2
+ import { createHash } from 'crypto';
3
3
  import 'buffer';
4
4
 
5
5
  // src/main/ts/formats/_npm-core.ts
@@ -47,15 +47,15 @@ function nameOf(id) {
47
47
  }
48
48
  return lastAt < 0 ? id : id.slice(0, lastAt);
49
49
  }
50
- function serializeNodeId(name, version, peerContext, patch) {
51
- const base = toTarballKey({ name, version, patch });
50
+ function serializeNodeId(name, version, peerContext, patch, source) {
51
+ const base = toTarballKey({ name, version, patch, source });
52
52
  if (peerContext.length === 0) return base;
53
53
  return base + peerContext.map((p) => `(${p})`).join("");
54
54
  }
55
55
  function acceptedNodeIds(node) {
56
- const bare = serializeNodeId(node.name, node.version, node.peerContext);
56
+ const bare = serializeNodeId(node.name, node.version, node.peerContext, void 0, node.source);
57
57
  if (node.patch === void 0) return [bare];
58
- const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch);
58
+ const patched = serializeNodeId(node.name, node.version, node.peerContext, node.patch, node.source);
59
59
  return bare === patched ? [bare] : [bare, patched];
60
60
  }
61
61
  function carriesPatchInNodeId(node) {
@@ -63,7 +63,8 @@ function carriesPatchInNodeId(node) {
63
63
  return stripPeerContextFromNodeId(node.id) === toTarballKey({
64
64
  name: node.name,
65
65
  version: node.version,
66
- patch: node.patch
66
+ patch: node.patch,
67
+ source: node.source
67
68
  });
68
69
  }
69
70
  function stripPeerContextFromNodeId(id) {
@@ -101,19 +102,39 @@ function refuseSentinelMutation(patch, opName, subject) {
101
102
  });
102
103
  }
103
104
  }
105
+ var SRC_TOKEN_RE = /^[0-9a-f]{16}$/;
106
+ function validateSourceToken(source) {
107
+ if (source.length === 0) {
108
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not be empty` });
109
+ }
110
+ if (source.includes("+")) {
111
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain '+'` });
112
+ }
113
+ if (/\s/.test(source)) {
114
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must not contain whitespace` });
115
+ }
116
+ if (!SRC_TOKEN_RE.test(source)) {
117
+ throw new LockfileError({ code: "INVALID_INPUT", message: `source slot must be 16 lowercase-hex chars` });
118
+ }
119
+ }
104
120
  function toTarballKey(inputs) {
105
121
  const slots = [];
106
122
  if (inputs.patch !== void 0) {
107
123
  validatePatchToken(inputs.patch);
108
124
  slots.push(`patch=${inputs.patch}`);
109
125
  }
126
+ if (inputs.source !== void 0) {
127
+ validateSourceToken(inputs.source);
128
+ slots.push(`src=${inputs.source}`);
129
+ }
110
130
  return slots.length === 0 ? `${inputs.name}@${inputs.version}` : `${inputs.name}@${inputs.version}+${slots.sort(cmpStr).join("+")}`;
111
131
  }
112
132
  function tarballKeyInputsOfNode(node) {
113
133
  return {
114
134
  name: node.name,
115
135
  version: node.version,
116
- patch: node.patch
136
+ patch: node.patch,
137
+ source: node.source
117
138
  };
118
139
  }
119
140
  var cmpStr = (a, b) => a < b ? -1 : a > b ? 1 : 0;
@@ -512,7 +533,7 @@ var GraphImpl = class _GraphImpl {
512
533
  }
513
534
  rebindNodeId(next, id, newNode.id, newNode);
514
535
  }
515
- applied.push({ kind: "node-replaced", subject: newNode.id });
536
+ applied.push(newNode.id === id ? { kind: "node-replaced", subject: newNode.id } : { kind: "node-replaced", subject: newNode.id, oldSubject: id });
516
537
  },
517
538
  addEdge(src, dst, kind, attrs) {
518
539
  if (!next.nodes.has(src)) throw new GraphError("PATCH_REJECTED", `addEdge: src ${src} missing`);
@@ -548,7 +569,7 @@ var GraphImpl = class _GraphImpl {
548
569
  for (const p of peers) {
549
570
  if (!next.nodes.has(p)) throw new GraphError("PATCH_REJECTED", `replacePeerContext: peer ${p} missing`);
550
571
  }
551
- const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch) : serializeNodeId(old.name, old.version, peers);
572
+ const newId = carriesPatchInNodeId(old) ? serializeNodeId(old.name, old.version, peers, old.patch, old.source) : serializeNodeId(old.name, old.version, peers, void 0, old.source);
552
573
  if (newId !== id && next.nodes.has(newId)) {
553
574
  throw new GraphError("PATCH_REJECTED", `replacePeerContext: target id ${newId} already exists`);
554
575
  }
@@ -569,7 +590,7 @@ var GraphImpl = class _GraphImpl {
569
590
  pushTo(next.outgoing, newId, e);
570
591
  pushTo(next.incoming, p, e);
571
592
  }
572
- applied.push({ kind: "peer-context-replaced", subject: newId });
593
+ applied.push(newId === id ? { kind: "peer-context-replaced", subject: newId } : { kind: "peer-context-replaced", subject: newId, oldSubject: id });
573
594
  },
574
595
  setTarball(inputs, payload) {
575
596
  const key = toTarballKey(inputs);
@@ -751,8 +772,6 @@ function overrideParentRefDropped(pkg, to) {
751
772
  message: `override ${pkg}=${to}: npm $name self-ref has no yarn/pnpm equivalent; emitted verbatim`
752
773
  };
753
774
  }
754
-
755
- // src/main/ts/recipe/resolution.ts
756
775
  var HEX40_RE = /^[0-9a-f]{40}$/i;
757
776
  var SHA_FRAG_RE = /^[0-9a-f]{7,64}$/i;
758
777
  var GITHUB_HOST = "github.com";
@@ -938,6 +957,36 @@ function normaliseDirectoryPath(raw) {
938
957
  if (p === "./") return ".";
939
958
  return p;
940
959
  }
960
+ var REGISTRY_HOSTS = /* @__PURE__ */ new Set([
961
+ "registry.npmjs.org",
962
+ "registry.yarnpkg.com"
963
+ ]);
964
+ function hostOfTarballUrl(url) {
965
+ if (!url.startsWith("http://") && !url.startsWith("https://")) return void 0;
966
+ const noScheme = url.replace(/^https?:\/\//, "");
967
+ const host = noScheme.split("/")[0];
968
+ return host === void 0 || host.length === 0 ? void 0 : host;
969
+ }
970
+ function sourceDiscriminatorOf(resolution) {
971
+ const sourceString = canonicalSourceStringOf(resolution);
972
+ return sourceString === void 0 ? void 0 : sha256Prefix16(sourceString);
973
+ }
974
+ function canonicalSourceStringOf(resolution) {
975
+ switch (resolution.type) {
976
+ case "git":
977
+ return `git\0${resolution.url}\0${resolution.sha}`;
978
+ case "tarball": {
979
+ const host = hostOfTarballUrl(resolution.url);
980
+ return host !== void 0 && REGISTRY_HOSTS.has(host) ? void 0 : `tarball\0${host ?? resolution.url}`;
981
+ }
982
+ case "directory":
983
+ case "unknown":
984
+ return void 0;
985
+ }
986
+ }
987
+ function sha256Prefix16(input) {
988
+ return createHash("sha256").update(input, "utf8").digest("hex").slice(0, 16);
989
+ }
941
990
  function stringifyForNpm(can) {
942
991
  switch (can.type) {
943
992
  case "tarball":
@@ -1268,19 +1317,22 @@ function parseFamily(input, _options, config) {
1268
1317
  if (version === void 0) {
1269
1318
  throw parseFailed(config, `entry ${JSON.stringify(path)} missing version`);
1270
1319
  }
1271
- const id = `${tailName}@${version}`;
1320
+ const source = sourceDiscriminatorOfNpmEntry(entry);
1321
+ const id = serializeNodeId(tailName, version, [], void 0, source);
1272
1322
  pathToId.set(path, id);
1273
1323
  const existing = idToEntry.get(id);
1274
1324
  if (existing === void 0) {
1275
1325
  idToEntry.set(id, entry);
1276
- builder.addNode({
1326
+ const node = {
1277
1327
  id,
1278
1328
  name: tailName,
1279
1329
  version,
1280
1330
  peerContext: []
1281
- });
1331
+ };
1332
+ if (source !== void 0) node.source = source;
1333
+ builder.addNode(node);
1282
1334
  if (entry.integrity !== void 0 || hasTarballPayload(entry)) {
1283
- builder.setTarball({ name: tailName, version }, tarballPayloadOf(entry, id, diagnostics));
1335
+ builder.setTarball({ name: tailName, version, source }, tarballPayloadOf(entry, id, diagnostics));
1284
1336
  }
1285
1337
  }
1286
1338
  }
@@ -1530,7 +1582,7 @@ function optimizeFamily(graph, config, _options = {}) {
1530
1582
  (a, b) => cmpStr2(`${a.src} ${a.kind} ${a.dst}`, `${b.src} ${b.kind} ${b.dst}`)
1531
1583
  );
1532
1584
  for (const node of graph.nodes()) {
1533
- const inputs = { name: node.name, version: node.version, patch: node.patch };
1585
+ const inputs = { name: node.name, version: node.version, patch: node.patch, source: node.source };
1534
1586
  const key = toTarballKey(inputs);
1535
1587
  if (unreachable.has(node.id)) {
1536
1588
  tarballsToRemove.set(key, inputs);
@@ -1639,6 +1691,10 @@ function nameFromInstallPath(config, path, entry) {
1639
1691
  function hasTarballPayload(entry) {
1640
1692
  return entry.integrity !== void 0 || entry.engines !== void 0 || entry.funding !== void 0 || entry.license !== void 0 || entry.bin !== void 0 || entry.deprecated !== void 0 || entry.cpu !== void 0 || entry.os !== void 0 || entry.libc !== void 0 || entry.resolved !== void 0;
1641
1693
  }
1694
+ function sourceDiscriminatorOfNpmEntry(entry) {
1695
+ if (typeof entry.resolved !== "string" || entry.link) return void 0;
1696
+ return sourceDiscriminatorOf(parse(entry.resolved, { sourceKind: "npm-resolved" }));
1697
+ }
1642
1698
  function tarballPayloadOf(entry, subject, diagnostics) {
1643
1699
  const payload = {};
1644
1700
  if (entry.integrity !== void 0) {
@@ -1,5 +1,5 @@
1
- import { G as Graph, D as Diagnostic } from '../graph-hx9HLuBV.js';
2
- import { N as NpmFamilyEnrichOptions, a as NpmFamilyOptimizeOptions, b as NpmFamilyParseOptions, c as NpmFamilyStringifyOptions } from '../_npm-flat-types-DnyApcb5.js';
1
+ import { G as Graph, D as Diagnostic } from '../graph-B_G4OKqF.js';
2
+ import { N as NpmFamilyEnrichOptions, a as NpmFamilyOptimizeOptions, b as NpmFamilyParseOptions, c as NpmFamilyStringifyOptions } from '../_npm-flat-types-C6TSaidU.js';
3
3
 
4
4
  interface Npm3ParseOptions extends NpmFamilyParseOptions {
5
5
  }