@vltpkg/graph 0.0.0-2 → 0.0.0-20

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 (129) hide show
  1. package/README.md +148 -12
  2. package/dist/esm/actual/load.d.ts +44 -3
  3. package/dist/esm/actual/load.d.ts.map +1 -1
  4. package/dist/esm/actual/load.js +114 -70
  5. package/dist/esm/actual/load.js.map +1 -1
  6. package/dist/esm/browser.d.ts +1 -1
  7. package/dist/esm/dependencies.d.ts +15 -5
  8. package/dist/esm/dependencies.d.ts.map +1 -1
  9. package/dist/esm/dependencies.js +67 -2
  10. package/dist/esm/dependencies.js.map +1 -1
  11. package/dist/esm/diff.d.ts +1 -0
  12. package/dist/esm/diff.d.ts.map +1 -1
  13. package/dist/esm/diff.js +6 -0
  14. package/dist/esm/diff.js.map +1 -1
  15. package/dist/esm/edge.d.ts +1 -1
  16. package/dist/esm/edge.d.ts.map +1 -1
  17. package/dist/esm/edge.js +1 -1
  18. package/dist/esm/edge.js.map +1 -1
  19. package/dist/esm/graph.d.ts +17 -10
  20. package/dist/esm/graph.d.ts.map +1 -1
  21. package/dist/esm/graph.js +52 -12
  22. package/dist/esm/graph.js.map +1 -1
  23. package/dist/esm/ideal/add-nodes.d.ts +6 -1
  24. package/dist/esm/ideal/add-nodes.d.ts.map +1 -1
  25. package/dist/esm/ideal/add-nodes.js +9 -4
  26. package/dist/esm/ideal/add-nodes.js.map +1 -1
  27. package/dist/esm/ideal/append-nodes.d.ts +2 -1
  28. package/dist/esm/ideal/append-nodes.d.ts.map +1 -1
  29. package/dist/esm/ideal/append-nodes.js +22 -5
  30. package/dist/esm/ideal/append-nodes.js.map +1 -1
  31. package/dist/esm/ideal/build.d.ts +4 -0
  32. package/dist/esm/ideal/build.d.ts.map +1 -1
  33. package/dist/esm/ideal/build.js +2 -0
  34. package/dist/esm/ideal/build.js.map +1 -1
  35. package/dist/esm/ideal/get-importer-specs.d.ts +3 -2
  36. package/dist/esm/ideal/get-importer-specs.d.ts.map +1 -1
  37. package/dist/esm/ideal/get-importer-specs.js +7 -5
  38. package/dist/esm/ideal/get-importer-specs.js.map +1 -1
  39. package/dist/esm/index.d.ts +4 -2
  40. package/dist/esm/index.d.ts.map +1 -1
  41. package/dist/esm/index.js +2 -0
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/esm/install.d.ts +4 -5
  44. package/dist/esm/install.d.ts.map +1 -1
  45. package/dist/esm/install.js +143 -23
  46. package/dist/esm/install.js.map +1 -1
  47. package/dist/esm/lockfile/load-nodes.d.ts +1 -1
  48. package/dist/esm/lockfile/load-nodes.d.ts.map +1 -1
  49. package/dist/esm/lockfile/load-nodes.js +33 -10
  50. package/dist/esm/lockfile/load-nodes.js.map +1 -1
  51. package/dist/esm/lockfile/load.d.ts +18 -5
  52. package/dist/esm/lockfile/load.d.ts.map +1 -1
  53. package/dist/esm/lockfile/load.js +23 -6
  54. package/dist/esm/lockfile/load.js.map +1 -1
  55. package/dist/esm/lockfile/save.d.ts +8 -3
  56. package/dist/esm/lockfile/save.d.ts.map +1 -1
  57. package/dist/esm/lockfile/save.js +26 -12
  58. package/dist/esm/lockfile/save.js.map +1 -1
  59. package/dist/esm/lockfile/types.d.ts +7 -3
  60. package/dist/esm/lockfile/types.d.ts.map +1 -1
  61. package/dist/esm/lockfile/types.js.map +1 -1
  62. package/dist/esm/modifiers.d.ts +189 -0
  63. package/dist/esm/modifiers.d.ts.map +1 -0
  64. package/dist/esm/modifiers.js +330 -0
  65. package/dist/esm/modifiers.js.map +1 -0
  66. package/dist/esm/node.d.ts +32 -4
  67. package/dist/esm/node.d.ts.map +1 -1
  68. package/dist/esm/node.js +60 -2
  69. package/dist/esm/node.js.map +1 -1
  70. package/dist/esm/reify/add-edge.d.ts +1 -1
  71. package/dist/esm/reify/add-edge.d.ts.map +1 -1
  72. package/dist/esm/reify/add-edge.js +36 -14
  73. package/dist/esm/reify/add-edge.js.map +1 -1
  74. package/dist/esm/reify/bin-paths.d.ts +1 -1
  75. package/dist/esm/reify/bin-paths.d.ts.map +1 -1
  76. package/dist/esm/reify/bin-paths.js.map +1 -1
  77. package/dist/esm/reify/build.js +6 -3
  78. package/dist/esm/reify/build.js.map +1 -1
  79. package/dist/esm/reify/calculate-save-value.d.ts +3 -0
  80. package/dist/esm/reify/calculate-save-value.d.ts.map +1 -0
  81. package/dist/esm/reify/calculate-save-value.js +45 -0
  82. package/dist/esm/reify/calculate-save-value.js.map +1 -0
  83. package/dist/esm/reify/delete-edge.js +1 -1
  84. package/dist/esm/reify/delete-edge.js.map +1 -1
  85. package/dist/esm/reify/delete-nodes.d.ts.map +1 -1
  86. package/dist/esm/reify/delete-nodes.js +4 -0
  87. package/dist/esm/reify/delete-nodes.js.map +1 -1
  88. package/dist/esm/reify/index.d.ts +2 -0
  89. package/dist/esm/reify/index.d.ts.map +1 -1
  90. package/dist/esm/reify/index.js +13 -1
  91. package/dist/esm/reify/index.js.map +1 -1
  92. package/dist/esm/reify/internal-hoist.d.ts +9 -0
  93. package/dist/esm/reify/internal-hoist.d.ts.map +1 -0
  94. package/dist/esm/reify/internal-hoist.js +121 -0
  95. package/dist/esm/reify/internal-hoist.js.map +1 -0
  96. package/dist/esm/reify/update-importers-package-json.d.ts +1 -1
  97. package/dist/esm/reify/update-importers-package-json.d.ts.map +1 -1
  98. package/dist/esm/reify/update-importers-package-json.js +35 -12
  99. package/dist/esm/reify/update-importers-package-json.js.map +1 -1
  100. package/dist/esm/remove-optional-subgraph.js +1 -1
  101. package/dist/esm/remove-optional-subgraph.js.map +1 -1
  102. package/dist/esm/resolve-save-type.d.ts +7 -0
  103. package/dist/esm/resolve-save-type.d.ts.map +1 -0
  104. package/dist/esm/resolve-save-type.js +5 -0
  105. package/dist/esm/resolve-save-type.js.map +1 -0
  106. package/dist/esm/types.d.ts +15 -3
  107. package/dist/esm/types.d.ts.map +1 -1
  108. package/dist/esm/types.js.map +1 -1
  109. package/dist/esm/uninstall.d.ts +3 -5
  110. package/dist/esm/uninstall.d.ts.map +1 -1
  111. package/dist/esm/uninstall.js +0 -3
  112. package/dist/esm/uninstall.js.map +1 -1
  113. package/dist/esm/update.d.ts +11 -0
  114. package/dist/esm/update.d.ts.map +1 -0
  115. package/dist/esm/update.js +49 -0
  116. package/dist/esm/update.js.map +1 -0
  117. package/dist/esm/visualization/human-readable-output.d.ts +3 -4
  118. package/dist/esm/visualization/human-readable-output.d.ts.map +1 -1
  119. package/dist/esm/visualization/human-readable-output.js +33 -19
  120. package/dist/esm/visualization/human-readable-output.js.map +1 -1
  121. package/dist/esm/visualization/json-output.d.ts +4 -0
  122. package/dist/esm/visualization/json-output.d.ts.map +1 -1
  123. package/dist/esm/visualization/json-output.js +2 -0
  124. package/dist/esm/visualization/json-output.js.map +1 -1
  125. package/dist/esm/visualization/mermaid-output.d.ts +6 -0
  126. package/dist/esm/visualization/mermaid-output.d.ts.map +1 -1
  127. package/dist/esm/visualization/mermaid-output.js +64 -9
  128. package/dist/esm/visualization/mermaid-output.js.map +1 -1
  129. package/package.json +27 -25
@@ -1,29 +1,149 @@
1
- import { PackageInfoClient } from '@vltpkg/package-info';
2
1
  import { load as actualLoad } from "./actual/load.js";
3
2
  import { build as idealBuild } from "./ideal/build.js";
4
3
  import { reify } from "./reify/index.js";
4
+ import { GraphModifier } from "./modifiers.js";
5
+ import { init } from '@vltpkg/init';
6
+ import { error } from '@vltpkg/error-cause';
7
+ import { asError } from '@vltpkg/types';
8
+ import { getDependencies } from "./dependencies.js";
9
+ import { RollbackRemove } from '@vltpkg/rollback-remove';
10
+ import { existsSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+ import { load as loadVirtual } from "./lockfile/load.js";
13
+ import { getImporterSpecs } from "./ideal/get-importer-specs.js";
5
14
  export const install = async (options, add) => {
6
- const mainManifest = options.packageJson.read(options.projectRoot);
7
- const graph = await idealBuild({
8
- ...options,
9
- add,
10
- mainManifest,
11
- loadManifests: true,
12
- packageInfo: new PackageInfoClient(options),
13
- });
14
- const act = actualLoad({
15
- ...options,
16
- mainManifest,
17
- loadManifests: true,
18
- });
19
- const diff = await reify({
20
- ...options,
21
- packageInfo: new PackageInfoClient(options),
22
- add,
23
- actual: act,
24
- graph,
25
- loadManifests: true,
26
- });
27
- return { graph, diff };
15
+ if (options.expectLockfile || options.frozenLockfile) {
16
+ const lockfilePath = resolve(options.projectRoot, 'vlt-lock.json');
17
+ if (!existsSync(lockfilePath)) {
18
+ throw error('vlt-lock.json file is required when using --expect-lockfile, --frozen-lockfile, or ci command', {
19
+ path: lockfilePath,
20
+ });
21
+ }
22
+ }
23
+ let mainManifest = undefined;
24
+ try {
25
+ mainManifest = options.packageJson.read(options.projectRoot);
26
+ }
27
+ catch (err) {
28
+ if (asError(err).message === 'Could not read package.json file') {
29
+ await init({ cwd: options.projectRoot });
30
+ mainManifest = options.packageJson.read(options.projectRoot, {
31
+ reload: true,
32
+ });
33
+ }
34
+ else {
35
+ throw err;
36
+ }
37
+ }
38
+ if (options.frozenLockfile) {
39
+ if (add?.modifiedDependencies) {
40
+ const dependencies = [];
41
+ for (const [, deps] of add) {
42
+ for (const [name] of deps) {
43
+ dependencies.push(name);
44
+ }
45
+ }
46
+ throw error('Cannot add dependencies when using --frozen-lockfile', { found: dependencies.join(', ') });
47
+ }
48
+ const lockfileGraph = loadVirtual({
49
+ ...options,
50
+ mainManifest,
51
+ skipLoadingNodesOnModifiersChange: false,
52
+ });
53
+ const emptyAdd = Object.assign(new Map(), { modifiedDependencies: false });
54
+ const emptyRemove = Object.assign(new Map(), {
55
+ modifiedDependencies: false,
56
+ });
57
+ const importerSpecs = getImporterSpecs({
58
+ graph: lockfileGraph,
59
+ add: emptyAdd,
60
+ remove: emptyRemove,
61
+ ...options,
62
+ });
63
+ // Check for spec changes by comparing package.json specs with lockfile edges
64
+ const specChanges = [];
65
+ for (const importer of lockfileGraph.importers) {
66
+ const deps = getDependencies(importer, options);
67
+ for (const [depName, dep] of deps) {
68
+ const edge = importer.edgesOut.get(depName);
69
+ if (edge?.spec) {
70
+ if (edge.spec.toString() !== dep.spec.toString()) {
71
+ const node = lockfileGraph.nodes.get(importer.id);
72
+ /* c8 ignore next */
73
+ const location = node?.location || importer.id;
74
+ specChanges.push(` ${location}: ${depName} spec changed from "${edge.spec}" to "${dep.spec}"`);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ if (importerSpecs.add.modifiedDependencies ||
80
+ importerSpecs.remove.modifiedDependencies ||
81
+ specChanges.length > 0) {
82
+ const details = [];
83
+ if (specChanges.length > 0) {
84
+ details.push(...specChanges);
85
+ }
86
+ for (const [importerId, deps] of importerSpecs.add) {
87
+ if (deps.size > 0) {
88
+ const node = lockfileGraph.nodes.get(importerId);
89
+ const location = node?.location || importerId;
90
+ const depNames = Array.from(deps.keys());
91
+ details.push(` ${location}: ${deps.size} dependencies to add (${depNames.join(', ')})`);
92
+ }
93
+ }
94
+ for (const [importerId, deps] of importerSpecs.remove) {
95
+ if (deps.size > 0) {
96
+ const node = lockfileGraph.nodes.get(importerId);
97
+ const location = node?.location || importerId;
98
+ const depNames = Array.from(deps);
99
+ details.push(` ${location}: ${deps.size} dependencies to remove (${depNames.join(', ')})`);
100
+ }
101
+ }
102
+ const lockfilePath = resolve(options.projectRoot, 'vlt-lock.json');
103
+ throw error('Lockfile is out of sync with package.json. Run "vlt install" to update.\n' +
104
+ details.join('\n'), {
105
+ path: lockfilePath,
106
+ });
107
+ }
108
+ }
109
+ const remover = new RollbackRemove();
110
+ if (options.cleanInstall) {
111
+ const nodeModulesPath = resolve(options.projectRoot, 'node_modules');
112
+ if (existsSync(nodeModulesPath)) {
113
+ await remover.rm(nodeModulesPath);
114
+ remover.confirm();
115
+ }
116
+ }
117
+ try {
118
+ const modifiers = GraphModifier.maybeLoad(options);
119
+ const act = actualLoad({
120
+ ...options,
121
+ mainManifest,
122
+ loadManifests: true,
123
+ modifiers: undefined, // modifiers should not be used here
124
+ });
125
+ const graph = await idealBuild({
126
+ ...options,
127
+ actual: act,
128
+ add,
129
+ mainManifest,
130
+ loadManifests: true,
131
+ modifiers,
132
+ });
133
+ const diff = await reify({
134
+ ...options,
135
+ add,
136
+ actual: act,
137
+ graph,
138
+ loadManifests: true,
139
+ modifiers,
140
+ });
141
+ return { graph, diff };
142
+ }
143
+ catch (err) {
144
+ /* c8 ignore next */
145
+ await remover.rollback().catch(() => { });
146
+ throw err;
147
+ }
28
148
  };
29
149
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/install.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAErD,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAQxC,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC1B,OAAuB,EACvB,GAAiC,EACjC,EAAE;IACF,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAElE,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC;QAC7B,GAAG,OAAO;QACV,GAAG;QACH,YAAY;QACZ,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI,iBAAiB,CAAC,OAAO,CAAC;KAC5C,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,UAAU,CAAC;QACrB,GAAG,OAAO;QACV,YAAY;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC;QACvB,GAAG,OAAO;QACV,WAAW,EAAE,IAAI,iBAAiB,CAAC,OAAO,CAAC;QAC3C,GAAG;QACH,MAAM,EAAE,GAAG;QACX,KAAK;QACL,aAAa,EAAE,IAAI;KACpB,CAAC,CAAA;IAEF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACxB,CAAC,CAAA","sourcesContent":["import type { PackageInfoClientOptions } from '@vltpkg/package-info'\nimport { PackageInfoClient } from '@vltpkg/package-info'\nimport type { PackageJson } from '@vltpkg/package-json'\nimport type { LoadOptions } from './actual/load.ts'\nimport { load as actualLoad } from './actual/load.ts'\nimport type { AddImportersDependenciesMap } from './dependencies.ts'\nimport { build as idealBuild } from './ideal/build.ts'\nimport { reify } from './reify/index.ts'\n\nexport type InstallOptions = PackageInfoClientOptions &\n LoadOptions & {\n projectRoot: string\n packageJson: PackageJson\n }\n\nexport const install = async (\n options: InstallOptions,\n add?: AddImportersDependenciesMap,\n) => {\n const mainManifest = options.packageJson.read(options.projectRoot)\n\n const graph = await idealBuild({\n ...options,\n add,\n mainManifest,\n loadManifests: true,\n packageInfo: new PackageInfoClient(options),\n })\n const act = actualLoad({\n ...options,\n mainManifest,\n loadManifests: true,\n })\n const diff = await reify({\n ...options,\n packageInfo: new PackageInfoClient(options),\n add,\n actual: act,\n graph,\n loadManifests: true,\n })\n\n return { graph, diff }\n}\n"]}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/install.ts"],"names":[],"mappings":"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","sourcesContent":["import { load as actualLoad } from './actual/load.ts'\nimport { build as idealBuild } from './ideal/build.ts'\nimport { reify } from './reify/index.ts'\nimport { GraphModifier } from './modifiers.ts'\nimport { init } from '@vltpkg/init'\nimport { error } from '@vltpkg/error-cause'\nimport type { NormalizedManifest } from '@vltpkg/types'\nimport { asError } from '@vltpkg/types'\nimport type { PackageInfoClient } from '@vltpkg/package-info'\nimport type { LoadOptions } from './actual/load.ts'\nimport { getDependencies } from './dependencies.ts'\nimport type {\n AddImportersDependenciesMap,\n Dependency,\n} from './dependencies.ts'\nimport { RollbackRemove } from '@vltpkg/rollback-remove'\nimport type { DepID } from '@vltpkg/dep-id'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { load as loadVirtual } from './lockfile/load.ts'\nimport { getImporterSpecs } from './ideal/get-importer-specs.ts'\n\nexport type InstallOptions = LoadOptions & {\n packageInfo: PackageInfoClient\n cleanInstall?: boolean // Only set by ci command for clean install\n}\n\nexport const install = async (\n options: InstallOptions,\n add?: AddImportersDependenciesMap,\n) => {\n if (options.expectLockfile || options.frozenLockfile) {\n const lockfilePath = resolve(options.projectRoot, 'vlt-lock.json')\n if (!existsSync(lockfilePath)) {\n throw error(\n 'vlt-lock.json file is required when using --expect-lockfile, --frozen-lockfile, or ci command',\n {\n path: lockfilePath,\n },\n )\n }\n }\n\n let mainManifest: NormalizedManifest | undefined = undefined\n try {\n mainManifest = options.packageJson.read(options.projectRoot)\n } catch (err) {\n if (asError(err).message === 'Could not read package.json file') {\n await init({ cwd: options.projectRoot })\n mainManifest = options.packageJson.read(options.projectRoot, {\n reload: true,\n })\n } else {\n throw err\n }\n }\n\n if (options.frozenLockfile) {\n if (add?.modifiedDependencies) {\n const dependencies: string[] = []\n for (const [, deps] of add) {\n for (const [name] of deps) {\n dependencies.push(name)\n }\n }\n throw error(\n 'Cannot add dependencies when using --frozen-lockfile',\n { found: dependencies.join(', ') },\n )\n }\n\n const lockfileGraph = loadVirtual({\n ...options,\n mainManifest,\n skipLoadingNodesOnModifiersChange: false,\n })\n\n const emptyAdd = Object.assign(\n new Map<DepID, Map<string, Dependency>>(),\n { modifiedDependencies: false },\n )\n const emptyRemove = Object.assign(new Map<DepID, Set<string>>(), {\n modifiedDependencies: false,\n })\n const importerSpecs = getImporterSpecs({\n graph: lockfileGraph,\n add: emptyAdd,\n remove: emptyRemove,\n ...options,\n })\n\n // Check for spec changes by comparing package.json specs with lockfile edges\n const specChanges: string[] = []\n for (const importer of lockfileGraph.importers) {\n const deps = getDependencies(importer, options)\n for (const [depName, dep] of deps) {\n const edge = importer.edgesOut.get(depName)\n if (edge?.spec) {\n if (edge.spec.toString() !== dep.spec.toString()) {\n const node = lockfileGraph.nodes.get(importer.id)\n /* c8 ignore next */\n const location = node?.location || importer.id\n specChanges.push(\n ` ${location}: ${depName} spec changed from \"${edge.spec}\" to \"${dep.spec}\"`,\n )\n }\n }\n }\n }\n\n if (\n importerSpecs.add.modifiedDependencies ||\n importerSpecs.remove.modifiedDependencies ||\n specChanges.length > 0\n ) {\n const details: string[] = []\n\n if (specChanges.length > 0) {\n details.push(...specChanges)\n }\n\n for (const [importerId, deps] of importerSpecs.add) {\n if (deps.size > 0) {\n const node = lockfileGraph.nodes.get(importerId)\n const location = node?.location || importerId\n const depNames = Array.from(deps.keys())\n details.push(\n ` ${location}: ${deps.size} dependencies to add (${depNames.join(', ')})`,\n )\n }\n }\n\n for (const [importerId, deps] of importerSpecs.remove) {\n if (deps.size > 0) {\n const node = lockfileGraph.nodes.get(importerId)\n const location = node?.location || importerId\n const depNames = Array.from(deps)\n details.push(\n ` ${location}: ${deps.size} dependencies to remove (${depNames.join(', ')})`,\n )\n }\n }\n\n const lockfilePath = resolve(\n options.projectRoot,\n 'vlt-lock.json',\n )\n throw error(\n 'Lockfile is out of sync with package.json. Run \"vlt install\" to update.\\n' +\n details.join('\\n'),\n {\n path: lockfilePath,\n },\n )\n }\n }\n\n const remover = new RollbackRemove()\n if (options.cleanInstall) {\n const nodeModulesPath = resolve(\n options.projectRoot,\n 'node_modules',\n )\n if (existsSync(nodeModulesPath)) {\n await remover.rm(nodeModulesPath)\n remover.confirm()\n }\n }\n\n try {\n const modifiers = GraphModifier.maybeLoad(options)\n\n const act = actualLoad({\n ...options,\n mainManifest,\n loadManifests: true,\n modifiers: undefined, // modifiers should not be used here\n })\n const graph = await idealBuild({\n ...options,\n actual: act,\n add,\n mainManifest,\n loadManifests: true,\n modifiers,\n })\n const diff = await reify({\n ...options,\n add,\n actual: act,\n graph,\n loadManifests: true,\n modifiers,\n })\n\n return { graph, diff }\n } catch (err) {\n /* c8 ignore next */\n await remover.rollback().catch(() => {})\n throw err\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  import type { LockfileData } from './types.ts';
2
2
  import type { GraphLike } from '../types.ts';
3
- export declare const loadNodes: (graph: GraphLike, nodes: LockfileData["nodes"]) => void;
3
+ export declare const loadNodes: (graph: GraphLike, nodes: LockfileData["nodes"], actual?: GraphLike) => void;
4
4
  //# sourceMappingURL=load-nodes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-nodes.d.ts","sourceRoot":"","sources":["../../../src/lockfile/load-nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,eAAO,MAAM,SAAS,UACb,SAAS,SACT,YAAY,CAAC,OAAO,CAAC,SAmC7B,CAAA"}
1
+ {"version":3,"file":"load-nodes.d.ts","sourceRoot":"","sources":["../../../src/lockfile/load-nodes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,eAAO,MAAM,SAAS,UACb,SAAS,SACT,YAAY,CAAC,OAAO,CAAC,WACnB,SAAS,SAqEnB,CAAA"}
@@ -1,30 +1,53 @@
1
1
  import { splitDepID } from '@vltpkg/dep-id/browser';
2
2
  import { getBooleanFlagsFromNum } from "./types.js";
3
- export const loadNodes = (graph, nodes) => {
3
+ export const loadNodes = (graph, nodes, actual) => {
4
4
  const entries = Object.entries(nodes);
5
5
  for (const [id, lockfileNode] of entries) {
6
6
  // workspace nodes and the project root node are already part of the
7
7
  // graph and it should not create new nodes if an existing one is there
8
8
  if (graph.nodes.has(id))
9
9
  continue;
10
- const [flags, name, integrity, resolved, location, manifest] = lockfileNode;
11
- const [type, , spec] = splitDepID(id);
10
+ const [flags, name, integrity, resolved, location, manifest, rawManifest,] = lockfileNode;
11
+ const [type, filepath, maybeExtra, lastExtra] = splitDepID(id);
12
+ const extra = type === 'registry' || type === 'git' ? lastExtra : maybeExtra;
13
+ const registrySpec = maybeExtra;
14
+ // The reference node is a node that matches the same id from the
15
+ // current iterating node in the provided `actual` graph, this allows
16
+ // for hydrating missing manifest, integrity, and resolved values
17
+ // that may be missing from the lockfile
18
+ const referenceNode = actual?.nodes.get(id);
19
+ const mani = manifest ?? referenceNode?.manifest;
12
20
  // if the lockfile has manifest data then it should just use that
13
21
  // otherwise tries to infer name / version value from the lockfile node
14
- const node = manifest ?
15
- graph.addNode(id, manifest)
16
- : graph.addNode(id, undefined, undefined, name ?? undefined, type === 'registry' && spec.indexOf('@') > 0 ?
17
- spec.split('@').slice(-1)[0]
22
+ const node = mani ?
23
+ graph.addNode(id, mani)
24
+ : graph.addNode(id, undefined, undefined, name ?? undefined, (type === 'registry' &&
25
+ registrySpec &&
26
+ registrySpec.indexOf('@') > 0) ?
27
+ registrySpec.split('@').slice(-1)[0]
18
28
  : undefined);
29
+ if (extra) {
30
+ node.modifier = extra;
31
+ }
19
32
  const { dev, optional } = getBooleanFlagsFromNum(flags);
20
33
  node.dev = dev;
21
34
  node.optional = optional;
22
- node.integrity = integrity ?? undefined;
23
- node.resolved = resolved ?? undefined;
35
+ node.integrity = integrity ?? referenceNode?.integrity;
36
+ node.resolved = resolved ?? referenceNode?.resolved;
24
37
  if (!node.resolved)
25
38
  node.setResolved();
26
- if (location)
39
+ if (location) {
27
40
  node.location = location;
41
+ }
42
+ else {
43
+ // set the location to file dependencies based on the id value
44
+ if (type === 'file') {
45
+ node.location = filepath;
46
+ }
47
+ }
48
+ if (mani && rawManifest) {
49
+ node.setConfusedManifest(mani, rawManifest);
50
+ }
28
51
  }
29
52
  };
30
53
  //# sourceMappingURL=load-nodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-nodes.js","sourceRoot":"","sources":["../../../src/lockfile/load-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAKnD,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,KAAgB,EAChB,KAA4B,EAC5B,EAAE;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAA4B,CAAA;IAChE,KAAK,MAAM,CAAC,EAAE,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE,CAAC;QACzC,oEAAoE;QACpE,uEAAuE;QACvE,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAQ;QAEjC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAC1D,YAAY,CAAA;QACd,MAAM,CAAC,IAAI,EAAE,AAAD,EAAG,IAAI,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAA;QAErC,iEAAiE;QACjE,uEAAuE;QACvE,MAAM,IAAI,GACR,QAAQ,CAAC,CAAC;YACR,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC;YAC7B,CAAC,CAAC,KAAK,CAAC,OAAO,CACX,EAAE,EACF,SAAS,EACT,SAAS,EACT,IAAI,IAAI,SAAS,EACjB,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9B,CAAC,CAAC,SAAS,CACZ,CAAA;QAEL,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;QACvD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,SAAS,CAAA;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,SAAS,CAAA;QACrC,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,WAAW,EAAE,CAAA;QACtC,IAAI,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IACxC,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { splitDepID } from '@vltpkg/dep-id/browser'\nimport { getBooleanFlagsFromNum } from './types.ts'\nimport type { LockfileData, LockfileNode } from './types.ts'\nimport type { DepID } from '@vltpkg/dep-id'\nimport type { GraphLike } from '../types.ts'\n\nexport const loadNodes = (\n graph: GraphLike,\n nodes: LockfileData['nodes'],\n) => {\n const entries = Object.entries(nodes) as [DepID, LockfileNode][]\n for (const [id, lockfileNode] of entries) {\n // workspace nodes and the project root node are already part of the\n // graph and it should not create new nodes if an existing one is there\n if (graph.nodes.has(id)) continue\n\n const [flags, name, integrity, resolved, location, manifest] =\n lockfileNode\n const [type, , spec] = splitDepID(id)\n\n // if the lockfile has manifest data then it should just use that\n // otherwise tries to infer name / version value from the lockfile node\n const node =\n manifest ?\n graph.addNode(id, manifest)\n : graph.addNode(\n id,\n undefined,\n undefined,\n name ?? undefined,\n type === 'registry' && spec.indexOf('@') > 0 ?\n spec.split('@').slice(-1)[0]\n : undefined,\n )\n\n const { dev, optional } = getBooleanFlagsFromNum(flags)\n node.dev = dev\n node.optional = optional\n node.integrity = integrity ?? undefined\n node.resolved = resolved ?? undefined\n if (!node.resolved) node.setResolved()\n if (location) node.location = location\n }\n}\n"]}
1
+ {"version":3,"file":"load-nodes.js","sourceRoot":"","sources":["../../../src/lockfile/load-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAKnD,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,KAAgB,EAChB,KAA4B,EAC5B,MAAkB,EAClB,EAAE;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAA4B,CAAA;IAChE,KAAK,MAAM,CAAC,EAAE,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE,CAAC;QACzC,oEAAoE;QACpE,uEAAuE;QACvE,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAQ;QAEjC,MAAM,CACJ,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACZ,GAAG,YAAY,CAAA;QAChB,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAA;QAC9D,MAAM,KAAK,GACT,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAA;QAChE,MAAM,YAAY,GAAG,UAAU,CAAA;QAE/B,iEAAiE;QACjE,qEAAqE;QACrE,iEAAiE;QACjE,wCAAwC;QACxC,MAAM,aAAa,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3C,MAAM,IAAI,GAAG,QAAQ,IAAI,aAAa,EAAE,QAAQ,CAAA;QAEhD,iEAAiE;QACjE,uEAAuE;QACvE,MAAM,IAAI,GACR,IAAI,CAAC,CAAC;YACJ,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC;YACzB,CAAC,CAAC,KAAK,CAAC,OAAO,CACX,EAAE,EACF,SAAS,EACT,SAAS,EACT,IAAI,IAAI,SAAS,EACjB,CACE,IAAI,KAAK,UAAU;gBACjB,YAAY;gBACZ,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAChC,CAAC,CAAC;gBACD,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtC,CAAC,CAAC,SAAS,CACZ,CAAA;QACL,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QACvB,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;QACvD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,aAAa,EAAE,SAAS,CAAA;QACtD,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,aAAa,EAAE,QAAQ,CAAA;QACnD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,WAAW,EAAE,CAAA;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,8DAA8D;YAC9D,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;YAC1B,CAAC;QACH,CAAC;QACD,IAAI,IAAI,IAAI,WAAW,EAAE,CAAC;YACxB,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { splitDepID } from '@vltpkg/dep-id/browser'\nimport { getBooleanFlagsFromNum } from './types.ts'\nimport type { LockfileData, LockfileNode } from './types.ts'\nimport type { DepID } from '@vltpkg/dep-id'\nimport type { GraphLike } from '../types.ts'\n\nexport const loadNodes = (\n graph: GraphLike,\n nodes: LockfileData['nodes'],\n actual?: GraphLike,\n) => {\n const entries = Object.entries(nodes) as [DepID, LockfileNode][]\n for (const [id, lockfileNode] of entries) {\n // workspace nodes and the project root node are already part of the\n // graph and it should not create new nodes if an existing one is there\n if (graph.nodes.has(id)) continue\n\n const [\n flags,\n name,\n integrity,\n resolved,\n location,\n manifest,\n rawManifest,\n ] = lockfileNode\n const [type, filepath, maybeExtra, lastExtra] = splitDepID(id)\n const extra =\n type === 'registry' || type === 'git' ? lastExtra : maybeExtra\n const registrySpec = maybeExtra\n\n // The reference node is a node that matches the same id from the\n // current iterating node in the provided `actual` graph, this allows\n // for hydrating missing manifest, integrity, and resolved values\n // that may be missing from the lockfile\n const referenceNode = actual?.nodes.get(id)\n const mani = manifest ?? referenceNode?.manifest\n\n // if the lockfile has manifest data then it should just use that\n // otherwise tries to infer name / version value from the lockfile node\n const node =\n mani ?\n graph.addNode(id, mani)\n : graph.addNode(\n id,\n undefined,\n undefined,\n name ?? undefined,\n (\n type === 'registry' &&\n registrySpec &&\n registrySpec.indexOf('@') > 0\n ) ?\n registrySpec.split('@').slice(-1)[0]\n : undefined,\n )\n if (extra) {\n node.modifier = extra\n }\n\n const { dev, optional } = getBooleanFlagsFromNum(flags)\n node.dev = dev\n node.optional = optional\n node.integrity = integrity ?? referenceNode?.integrity\n node.resolved = resolved ?? referenceNode?.resolved\n if (!node.resolved) node.setResolved()\n if (location) {\n node.location = location\n } else {\n // set the location to file dependencies based on the id value\n if (type === 'file') {\n node.location = filepath\n }\n }\n if (mani && rawManifest) {\n node.setConfusedManifest(mani, rawManifest)\n }\n }\n}\n"]}
@@ -1,11 +1,16 @@
1
1
  import { PackageJson } from '@vltpkg/package-json';
2
- import type { Manifest } from '@vltpkg/types';
3
2
  import { Monorepo } from '@vltpkg/workspaces';
4
- import type { SpecOptions } from '@vltpkg/spec';
5
- import type { PathScurry } from 'path-scurry';
6
3
  import { Graph } from '../graph.ts';
4
+ import type { PathScurry } from 'path-scurry';
5
+ import type { NormalizedManifest } from '@vltpkg/types';
6
+ import type { SpecOptions } from '@vltpkg/spec';
7
7
  import type { LockfileData } from './types.ts';
8
+ import type { GraphModifier } from '../modifiers.ts';
8
9
  export type LoadOptions = SpecOptions & {
10
+ /**
11
+ * An optional {@link Graph} object to hydrate extra data from.
12
+ */
13
+ actual?: Graph;
9
14
  /**
10
15
  * The project root dirname.
11
16
  */
@@ -13,7 +18,11 @@ export type LoadOptions = SpecOptions & {
13
18
  /**
14
19
  * The project root manifest.
15
20
  */
16
- mainManifest: Manifest;
21
+ mainManifest: NormalizedManifest;
22
+ /**
23
+ * The graph modifiers helper object.
24
+ */
25
+ modifiers?: GraphModifier;
17
26
  /**
18
27
  * A {@link Monorepo} object, for managing workspaces
19
28
  */
@@ -26,8 +35,12 @@ export type LoadOptions = SpecOptions & {
26
35
  * A {@link PathScurry} object, for use in globs
27
36
  */
28
37
  scurry?: PathScurry;
38
+ /**
39
+ * Load only importers into the graph if the modifiers have changed.
40
+ */
41
+ skipLoadingNodesOnModifiersChange?: boolean;
29
42
  };
30
43
  export declare const load: (options: LoadOptions) => Graph;
31
44
  export declare const loadHidden: (options: LoadOptions) => Graph;
32
- export declare const loadObject: (options: LoadOptions, lockfileData: LockfileData) => Graph;
45
+ export declare const loadObject: (options: LoadOptions, lockfileData: Omit<LockfileData, "options" | "lockfileVersion"> & Partial<Pick<LockfileData, "options" | "lockfileVersion">>) => Graph;
33
46
  //# sourceMappingURL=load.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/lockfile/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,EAAE,QAAQ,CAAA;IACtB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;CACpB,CAAA;AASD,eAAO,MAAM,IAAI,YAAa,WAAW,KAAG,KAM3C,CAAA;AAED,eAAO,MAAM,UAAU,YAAa,WAAW,KAAG,KAMjD,CAAA;AAED,eAAO,MAAM,UAAU,YACZ,WAAW,gBACN,YAAY,UA6C3B,CAAA"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/lockfile/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAK7C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAA;IACd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,EAAE,kBAAkB,CAAA;IAChC;;OAEG;IACH,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB;;OAEG;IACH,iCAAiC,CAAC,EAAE,OAAO,CAAA;CAC5C,CAAA;AASD,eAAO,MAAM,IAAI,YAAa,WAAW,KAAG,KAM3C,CAAA;AAED,eAAO,MAAM,UAAU,YAAa,WAAW,KAAG,KAMjD,CAAA;AAED,eAAO,MAAM,UAAU,YACZ,WAAW,gBACN,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,iBAAiB,CAAC,GAC7D,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,iBAAiB,CAAC,CAAC,UA4E7D,CAAA"}
@@ -17,15 +17,15 @@ export const loadHidden = (options) => {
17
17
  return loadObject(options, loadLockfile(projectRoot, 'node_modules/.vlt-lock.json'));
18
18
  };
19
19
  export const loadObject = (options, lockfileData) => {
20
- const { mainManifest, scurry } = options;
20
+ const { mainManifest, modifiers, scurry, skipLoadingNodesOnModifiersChange, } = options;
21
21
  const packageJson = options.packageJson ?? new PackageJson();
22
22
  const monorepo = options.monorepo ??
23
23
  Monorepo.maybeLoad(options.projectRoot, { packageJson, scurry });
24
- const { 'scope-registries': scopeRegistries, registry, registries, 'git-hosts': gitHosts, 'git-host-archives': gitHostArchives,
25
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
26
- } = lockfileData.options || {};
24
+ const { catalog = {}, catalogs = {}, modifiers: modifiersLockfileConfig, 'scope-registries': scopeRegistries, registry, registries, 'git-hosts': gitHosts, 'git-host-archives': gitHostArchives, } = lockfileData.options ?? {};
27
25
  const mergedOptions = {
28
26
  ...options,
27
+ catalog,
28
+ catalogs,
29
29
  'scope-registries': {
30
30
  ...options['scope-registries'],
31
31
  ...scopeRegistries,
@@ -49,8 +49,25 @@ export const loadObject = (options, lockfileData) => {
49
49
  mainManifest,
50
50
  monorepo,
51
51
  });
52
- loadNodes(graph, lockfileData.nodes);
53
- loadEdges(graph, lockfileData.edges, mergedOptions);
52
+ // When using the skipLoadingNodesOnModifiersChange option, we should skip loading
53
+ // dependencies in case the modifiers have changed since we'll need to
54
+ // recalculate the graph - useful for refreshing an ideal graph when
55
+ // modifiers are swapped.
56
+ const lockfileModifiers = JSON.stringify(modifiersLockfileConfig ?? {});
57
+ const optionsModifiers = JSON.stringify(modifiers?.config);
58
+ const modifiersChanged = lockfileModifiers !== optionsModifiers;
59
+ const shouldLoadDependencies = !(skipLoadingNodesOnModifiersChange && modifiersChanged);
60
+ if (shouldLoadDependencies) {
61
+ loadNodes(graph, lockfileData.nodes, options.actual);
62
+ loadEdges(graph, lockfileData.edges, mergedOptions);
63
+ }
64
+ // hydrate missing node-level registry data
65
+ for (const node of graph.nodes.values()) {
66
+ const [firstEdge] = node.edgesIn;
67
+ if (firstEdge?.spec.registry) {
68
+ node.registry = firstEdge.spec.registry;
69
+ }
70
+ }
54
71
  return graph;
55
72
  };
56
73
  //# sourceMappingURL=load.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/lockfile/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AA0BnC,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,YAAoB,EAAE,EAAE,CACjE,IAAI,CAAC,KAAK,CACR,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE;IAC/C,QAAQ,EAAE,MAAM;CACjB,CAAC,CACa,CAAA;AAEnB,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAoB,EAAS,EAAE;IAClD,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAC/B,OAAO,UAAU,CACf,OAAO,EACP,YAAY,CAAC,WAAW,EAAE,eAAe,CAAC,CAC3C,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAoB,EAAS,EAAE;IACxD,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAC/B,OAAO,UAAU,CACf,OAAO,EACP,YAAY,CAAC,WAAW,EAAE,6BAA6B,CAAC,CACzD,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAoB,EACpB,YAA0B,EAC1B,EAAE;IACF,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACxC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,WAAW,EAAE,CAAA;IAC5D,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;QAChB,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;IAClE,MAAM,EACJ,kBAAkB,EAAE,eAAe,EACnC,QAAQ,EACR,UAAU,EACV,WAAW,EAAE,QAAQ,EACrB,mBAAmB,EAAE,eAAe;IACpC,uEAAuE;MACxE,GAAG,YAAY,CAAC,OAAO,IAAI,EAAE,CAAA;IAC9B,MAAM,aAAa,GAAG;QACpB,GAAG,OAAO;QACV,kBAAkB,EAAE;YAClB,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAC9B,GAAG,eAAe;SACnB;QACD,QAAQ,EAAE,QAAQ,IAAI,OAAO,CAAC,QAAQ;QACtC,UAAU,EAAE;YACV,GAAG,OAAO,CAAC,UAAU;YACrB,GAAG,UAAU;SACd;QACD,WAAW,EAAE;YACX,GAAG,OAAO,CAAC,WAAW,CAAC;YACvB,GAAG,QAAQ;SACZ;QACD,mBAAmB,EAAE;YACnB,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAC/B,GAAG,eAAe;SACnB;KACF,CAAA;IACD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,GAAG,aAAa;QAChB,YAAY;QACZ,QAAQ;KACT,CAAC,CAAA;IAEF,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IACpC,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAA;IAEnD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA","sourcesContent":["import { PackageJson } from '@vltpkg/package-json'\nimport type { Manifest } from '@vltpkg/types'\nimport { Monorepo } from '@vltpkg/workspaces'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { PathScurry } from 'path-scurry'\nimport { loadEdges } from './load-edges.ts'\nimport { loadNodes } from './load-nodes.ts'\nimport { Graph } from '../graph.ts'\nimport type { LockfileData } from './types.ts'\n\nexport type LoadOptions = SpecOptions & {\n /**\n * The project root dirname.\n */\n projectRoot: string\n /**\n * The project root manifest.\n */\n mainManifest: Manifest\n /**\n * A {@link Monorepo} object, for managing workspaces\n */\n monorepo?: Monorepo\n /**\n * A {@link PackageJson} object, for sharing manifest caches\n */\n packageJson?: PackageJson\n /**\n * A {@link PathScurry} object, for use in globs\n */\n scurry?: PathScurry\n}\n\nconst loadLockfile = (projectRoot: string, lockfilePath: string) =>\n JSON.parse(\n readFileSync(resolve(projectRoot, lockfilePath), {\n encoding: 'utf8',\n }),\n ) as LockfileData\n\nexport const load = (options: LoadOptions): Graph => {\n const { projectRoot } = options\n return loadObject(\n options,\n loadLockfile(projectRoot, 'vlt-lock.json'),\n )\n}\n\nexport const loadHidden = (options: LoadOptions): Graph => {\n const { projectRoot } = options\n return loadObject(\n options,\n loadLockfile(projectRoot, 'node_modules/.vlt-lock.json'),\n )\n}\n\nexport const loadObject = (\n options: LoadOptions,\n lockfileData: LockfileData,\n) => {\n const { mainManifest, scurry } = options\n const packageJson = options.packageJson ?? new PackageJson()\n const monorepo =\n options.monorepo ??\n Monorepo.maybeLoad(options.projectRoot, { packageJson, scurry })\n const {\n 'scope-registries': scopeRegistries,\n registry,\n registries,\n 'git-hosts': gitHosts,\n 'git-host-archives': gitHostArchives,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n } = lockfileData.options || {}\n const mergedOptions = {\n ...options,\n 'scope-registries': {\n ...options['scope-registries'],\n ...scopeRegistries,\n },\n registry: registry ?? options.registry,\n registries: {\n ...options.registries,\n ...registries,\n },\n 'git-hosts': {\n ...options['git-hosts'],\n ...gitHosts,\n },\n 'git-host-archives': {\n ...options['git-host-archives'],\n ...gitHostArchives,\n },\n }\n const graph = new Graph({\n ...mergedOptions,\n mainManifest,\n monorepo,\n })\n\n loadNodes(graph, lockfileData.nodes)\n loadEdges(graph, lockfileData.edges, mergedOptions)\n\n return graph\n}\n"]}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/lockfile/load.ts"],"names":[],"mappings":"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","sourcesContent":["import { PackageJson } from '@vltpkg/package-json'\nimport { Monorepo } from '@vltpkg/workspaces'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { loadEdges } from './load-edges.ts'\nimport { loadNodes } from './load-nodes.ts'\nimport { Graph } from '../graph.ts'\nimport type { PathScurry } from 'path-scurry'\nimport type { NormalizedManifest } from '@vltpkg/types'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport type { LockfileData } from './types.ts'\nimport type { GraphModifier } from '../modifiers.ts'\n\nexport type LoadOptions = SpecOptions & {\n /**\n * An optional {@link Graph} object to hydrate extra data from.\n */\n actual?: Graph\n /**\n * The project root dirname.\n */\n projectRoot: string\n /**\n * The project root manifest.\n */\n mainManifest: NormalizedManifest\n /**\n * The graph modifiers helper object.\n */\n modifiers?: GraphModifier\n /**\n * A {@link Monorepo} object, for managing workspaces\n */\n monorepo?: Monorepo\n /**\n * A {@link PackageJson} object, for sharing manifest caches\n */\n packageJson?: PackageJson\n /**\n * A {@link PathScurry} object, for use in globs\n */\n scurry?: PathScurry\n /**\n * Load only importers into the graph if the modifiers have changed.\n */\n skipLoadingNodesOnModifiersChange?: boolean\n}\n\nconst loadLockfile = (projectRoot: string, lockfilePath: string) =>\n JSON.parse(\n readFileSync(resolve(projectRoot, lockfilePath), {\n encoding: 'utf8',\n }),\n ) as LockfileData\n\nexport const load = (options: LoadOptions): Graph => {\n const { projectRoot } = options\n return loadObject(\n options,\n loadLockfile(projectRoot, 'vlt-lock.json'),\n )\n}\n\nexport const loadHidden = (options: LoadOptions): Graph => {\n const { projectRoot } = options\n return loadObject(\n options,\n loadLockfile(projectRoot, 'node_modules/.vlt-lock.json'),\n )\n}\n\nexport const loadObject = (\n options: LoadOptions,\n lockfileData: Omit<LockfileData, 'options' | 'lockfileVersion'> &\n Partial<Pick<LockfileData, 'options' | 'lockfileVersion'>>,\n) => {\n const {\n mainManifest,\n modifiers,\n scurry,\n skipLoadingNodesOnModifiersChange,\n } = options\n const packageJson = options.packageJson ?? new PackageJson()\n const monorepo =\n options.monorepo ??\n Monorepo.maybeLoad(options.projectRoot, { packageJson, scurry })\n const {\n catalog = {},\n catalogs = {},\n modifiers: modifiersLockfileConfig,\n 'scope-registries': scopeRegistries,\n registry,\n registries,\n 'git-hosts': gitHosts,\n 'git-host-archives': gitHostArchives,\n } = lockfileData.options ?? {}\n const mergedOptions = {\n ...options,\n catalog,\n catalogs,\n 'scope-registries': {\n ...options['scope-registries'],\n ...scopeRegistries,\n },\n registry: registry ?? options.registry,\n registries: {\n ...options.registries,\n ...registries,\n },\n 'git-hosts': {\n ...options['git-hosts'],\n ...gitHosts,\n },\n 'git-host-archives': {\n ...options['git-host-archives'],\n ...gitHostArchives,\n },\n }\n const graph = new Graph({\n ...mergedOptions,\n mainManifest,\n monorepo,\n })\n\n // When using the skipLoadingNodesOnModifiersChange option, we should skip loading\n // dependencies in case the modifiers have changed since we'll need to\n // recalculate the graph - useful for refreshing an ideal graph when\n // modifiers are swapped.\n const lockfileModifiers = JSON.stringify(\n modifiersLockfileConfig ?? {},\n )\n const optionsModifiers = JSON.stringify(modifiers?.config)\n const modifiersChanged = lockfileModifiers !== optionsModifiers\n const shouldLoadDependencies = !(\n skipLoadingNodesOnModifiersChange && modifiersChanged\n )\n if (shouldLoadDependencies) {\n loadNodes(graph, lockfileData.nodes, options.actual)\n loadEdges(graph, lockfileData.edges, mergedOptions)\n }\n\n // hydrate missing node-level registry data\n for (const node of graph.nodes.values()) {\n const [firstEdge] = node.edgesIn\n if (firstEdge?.spec.registry) {\n node.registry = firstEdge.spec.registry\n }\n }\n\n return graph\n}\n"]}
@@ -1,18 +1,23 @@
1
1
  import type { SpecOptions } from '@vltpkg/spec';
2
2
  import type { Graph } from '../graph.ts';
3
3
  import type { LockfileData } from './types.ts';
4
+ import type { GraphModifier } from '../modifiers.ts';
4
5
  export type SaveOptions = SpecOptions & {
5
6
  /**
6
7
  * The graph to be stored in the lockfile.
7
8
  */
8
9
  graph: Graph;
10
+ /**
11
+ * The graph modifiers helper object.
12
+ */
13
+ modifiers?: GraphModifier;
9
14
  /**
10
15
  * Should it save manifest data in the lockfile?
11
16
  */
12
17
  saveManifests?: boolean;
13
18
  };
14
- export declare const lockfileData: ({ graph, "git-hosts": gitHosts, "git-host-archives": gitHostArchives, registry, registries, saveManifests, "scope-registries": scopeRegistries, }: SaveOptions) => LockfileData;
19
+ export declare const lockfileData: ({ graph, catalog, catalogs, "git-hosts": gitHosts, "git-host-archives": gitHostArchives, modifiers, registry, registries, saveManifests, "scope-registries": scopeRegistries, "jsr-registries": jsrRegistries, }: SaveOptions) => LockfileData;
15
20
  export declare const saveData: (data: LockfileData, fileName: string, saveManifests?: boolean) => void;
16
- export declare const save: (options: SaveOptions) => void;
17
- export declare const saveHidden: (options: SaveOptions) => void;
21
+ export declare const save: (options: Omit<SaveOptions, "saveManifests">) => void;
22
+ export declare const saveHidden: (options: Omit<SaveOptions, "saveManifests">) => void;
18
23
  //# sourceMappingURL=save.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../../src/lockfile/save.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAI/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAGxC,OAAO,KAAK,EACV,YAAY,EAKb,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IACZ;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAgGD,eAAO,MAAM,YAAY,sJAQtB,WAAW,KAAG,YAwChB,CAAA;AAeD,eAAO,MAAM,QAAQ,SACb,YAAY,YACR,MAAM,kCAMjB,CAAA;AAED,eAAO,MAAM,IAAI,YAAa,WAAW,SAKxC,CAAA;AAED,eAAO,MAAM,UAAU,YAAa,WAAW,SAS9C,CAAA"}
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../../src/lockfile/save.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,KAAK,EACV,YAAY,EAKb,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAyFD,eAAO,MAAM,YAAY,qNAYtB,WAAW,KAAG,YAyDhB,CAAA;AAeD,eAAO,MAAM,QAAQ,SACb,YAAY,YACR,MAAM,8BAEf,IAIF,CAAA;AAED,eAAO,MAAM,IAAI,YACN,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,KAC1C,IAKF,CAAA;AAED,eAAO,MAAM,UAAU,YACZ,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,KAC1C,IASF,CAAA"}
@@ -1,4 +1,5 @@
1
- import { defaultRegistry, defaultRegistries, defaultGitHosts, defaultGitHostArchives, defaultScopeRegistries, } from '@vltpkg/spec';
1
+ import { expandNormalizedManifestSymbols, isRecordStringString, } from '@vltpkg/types';
2
+ import { defaultGitHostArchives, defaultGitHosts, defaultJsrRegistries, defaultRegistries, defaultRegistry, defaultScopeRegistries, } from '@vltpkg/spec';
2
3
  import { mkdirSync, writeFileSync } from 'node:fs';
3
4
  import { dirname, resolve } from 'node:path';
4
5
  import { getFlagNumFromNode } from "./types.js";
@@ -13,11 +14,7 @@ const formatNodes = (nodes, saveManifests, registry) => {
13
14
  const customRegistry = node.resolved && registry && !node.resolved.startsWith(registry);
14
15
  const resolved = customRegistry ? node.resolved : undefined;
15
16
  // if it's in a location other than the default, stash that
16
- const location = (node.id.startsWith('file') ||
17
- node.location.endsWith('/node_modules/.vlt/' +
18
- node.id +
19
- '/node_modules/' +
20
- node.name)) ?
17
+ const location = node.id.startsWith('file') || node.inVltStore() ?
21
18
  undefined
22
19
  : node.location;
23
20
  const flags = getFlagNumFromNode(node);
@@ -31,8 +28,11 @@ const formatNodes = (nodes, saveManifests, registry) => {
31
28
  if (location) {
32
29
  lockfileNode[4] = location;
33
30
  }
34
- if (saveManifests) {
35
- lockfileNode[5] = node.manifest;
31
+ if (saveManifests && node.manifest) {
32
+ lockfileNode[5] = expandNormalizedManifestSymbols(node.manifest);
33
+ if (node.confused && node.rawManifest) {
34
+ lockfileNode[6] = expandNormalizedManifestSymbols(node.rawManifest);
35
+ }
36
36
  }
37
37
  res[node.id] = lockfileNode;
38
38
  }
@@ -51,7 +51,6 @@ Number(b.from.importer) - Number(a.from.importer) ||
51
51
  `${edge.from.id} ${edge.spec.name}`,
52
52
  `${edge.type} ${edge.spec.bareSpec || '*'} ${edge.to?.id ?? 'MISSING'}`,
53
53
  ]));
54
- const isRecordStringString = (registries) => !(!registries || typeof registries === 'string');
55
54
  const removeDefaultItems = (defaultItems, items) => {
56
55
  const res = {};
57
56
  for (const [key, value] of Object.entries(items)) {
@@ -61,25 +60,40 @@ const removeDefaultItems = (defaultItems, items) => {
61
60
  }
62
61
  return res;
63
62
  };
64
- export const lockfileData = ({ graph, 'git-hosts': gitHosts, 'git-host-archives': gitHostArchives, registry, registries, saveManifests, 'scope-registries': scopeRegistries, }) => {
63
+ export const lockfileData = ({ graph, catalog, catalogs, 'git-hosts': gitHosts, 'git-host-archives': gitHostArchives, modifiers, registry, registries, saveManifests, 'scope-registries': scopeRegistries, 'jsr-registries': jsrRegistries, }) => {
65
64
  const cleanGitHosts = isRecordStringString(gitHosts) ?
66
65
  removeDefaultItems(defaultGitHosts, gitHosts)
67
66
  : undefined;
68
67
  const cleanGitHostArchives = isRecordStringString(gitHostArchives) ?
69
68
  removeDefaultItems(defaultGitHostArchives, gitHostArchives)
70
69
  : undefined;
70
+ const cleanModifiers = modifiers && isRecordStringString(modifiers.config) ?
71
+ modifiers.config
72
+ : undefined;
71
73
  const cleanRegistries = isRecordStringString(registries) ?
72
74
  removeDefaultItems(defaultRegistries, registries)
73
75
  : undefined;
74
76
  const cleanScopeRegistries = isRecordStringString(scopeRegistries) ?
75
77
  removeDefaultItems(defaultScopeRegistries, scopeRegistries)
76
78
  : undefined;
79
+ const cleanJsrRegistries = isRecordStringString(jsrRegistries) ?
80
+ removeDefaultItems(defaultJsrRegistries, jsrRegistries)
81
+ : undefined;
77
82
  const hasItems = (clean) => clean && Object.keys(clean).length;
78
83
  return {
84
+ lockfileVersion: 0,
79
85
  options: {
86
+ ...(hasItems(cleanModifiers) ?
87
+ { modifiers: cleanModifiers }
88
+ : {}),
89
+ ...(hasItems(catalog) ? { catalog } : {}),
90
+ ...(hasItems(catalogs) ? { catalogs } : {}),
80
91
  ...(hasItems(cleanScopeRegistries) ?
81
92
  { 'scope-registries': cleanScopeRegistries }
82
93
  : undefined),
94
+ ...(hasItems(cleanJsrRegistries) ?
95
+ { 'jsr-registries': cleanJsrRegistries }
96
+ : undefined),
83
97
  ...(registry !== undefined && registry !== defaultRegistry ?
84
98
  { registry }
85
99
  : undefined),
@@ -116,13 +130,13 @@ export const save = (options) => {
116
130
  const { graph } = options;
117
131
  const data = lockfileData({ ...options, saveManifests: false });
118
132
  const fileName = resolve(graph.projectRoot, 'vlt-lock.json');
119
- return saveData(data, fileName, false);
133
+ saveData(data, fileName, false);
120
134
  };
121
135
  export const saveHidden = (options) => {
122
136
  const { graph } = options;
123
137
  const data = lockfileData({ ...options, saveManifests: true });
124
138
  const fileName = resolve(graph.projectRoot, 'node_modules/.vlt-lock.json');
125
139
  mkdirSync(dirname(fileName), { recursive: true });
126
- return saveData(data, fileName, true);
140
+ saveData(data, fileName, true);
127
141
  };
128
142
  //# sourceMappingURL=save.js.map