@vltpkg/graph 1.0.0-rc.23 → 1.0.0-rc.24

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 (109) hide show
  1. package/dist/actual/load.d.ts +107 -0
  2. package/dist/actual/load.js +336 -0
  3. package/dist/browser.d.ts +14 -0
  4. package/dist/browser.js +16 -0
  5. package/dist/build.d.ts +28 -0
  6. package/dist/build.js +78 -0
  7. package/dist/dependencies.d.ts +65 -0
  8. package/dist/dependencies.js +111 -0
  9. package/dist/diff.d.ts +119 -0
  10. package/dist/diff.js +151 -0
  11. package/dist/edge.d.ts +46 -0
  12. package/dist/edge.js +77 -0
  13. package/dist/fixup-added-names.d.ts +18 -0
  14. package/dist/fixup-added-names.js +46 -0
  15. package/dist/graph.d.ts +153 -0
  16. package/dist/graph.js +444 -0
  17. package/dist/ideal/append-nodes.d.ts +31 -0
  18. package/dist/ideal/append-nodes.js +560 -0
  19. package/dist/ideal/build-ideal-from-starting-graph.d.ts +14 -0
  20. package/dist/ideal/build-ideal-from-starting-graph.js +69 -0
  21. package/dist/ideal/build.d.ts +40 -0
  22. package/dist/ideal/build.js +84 -0
  23. package/dist/ideal/get-importer-specs.d.ts +20 -0
  24. package/dist/ideal/get-importer-specs.js +180 -0
  25. package/dist/ideal/peers.d.ts +160 -0
  26. package/dist/ideal/peers.js +696 -0
  27. package/dist/ideal/refresh-ideal-graph.d.ts +43 -0
  28. package/dist/ideal/refresh-ideal-graph.js +62 -0
  29. package/dist/ideal/remove-satisfied-specs.d.ts +7 -0
  30. package/dist/ideal/remove-satisfied-specs.js +34 -0
  31. package/dist/ideal/sorting.d.ts +45 -0
  32. package/dist/ideal/sorting.js +70 -0
  33. package/dist/ideal/types.d.ts +107 -0
  34. package/dist/ideal/types.js +1 -0
  35. package/dist/index.d.ts +38 -0
  36. package/dist/index.js +32 -0
  37. package/dist/install.d.ts +19 -0
  38. package/dist/install.js +208 -0
  39. package/dist/lockfile/load-edges.d.ts +11 -0
  40. package/dist/lockfile/load-edges.js +105 -0
  41. package/dist/lockfile/load-nodes.d.ts +4 -0
  42. package/dist/lockfile/load-nodes.js +101 -0
  43. package/dist/lockfile/load.d.ts +45 -0
  44. package/dist/lockfile/load.js +84 -0
  45. package/dist/lockfile/save.d.ts +30 -0
  46. package/dist/lockfile/save.js +174 -0
  47. package/dist/lockfile/types.d.ts +95 -0
  48. package/dist/lockfile/types.js +49 -0
  49. package/dist/modifiers.d.ts +188 -0
  50. package/dist/modifiers.js +329 -0
  51. package/dist/node.d.ts +234 -0
  52. package/dist/node.js +388 -0
  53. package/dist/non-empty-list.d.ts +2 -0
  54. package/dist/non-empty-list.js +2 -0
  55. package/dist/reify/add-edge.d.ts +9 -0
  56. package/dist/reify/add-edge.js +71 -0
  57. package/dist/reify/add-edges.d.ts +4 -0
  58. package/dist/reify/add-edges.js +12 -0
  59. package/dist/reify/add-nodes.d.ts +6 -0
  60. package/dist/reify/add-nodes.js +16 -0
  61. package/dist/reify/bin-chmod.d.ts +10 -0
  62. package/dist/reify/bin-chmod.js +38 -0
  63. package/dist/reify/build.d.ts +13 -0
  64. package/dist/reify/build.js +111 -0
  65. package/dist/reify/calculate-save-value.d.ts +2 -0
  66. package/dist/reify/calculate-save-value.js +50 -0
  67. package/dist/reify/check-needed-build.d.ts +34 -0
  68. package/dist/reify/check-needed-build.js +71 -0
  69. package/dist/reify/delete-edge.d.ts +4 -0
  70. package/dist/reify/delete-edge.js +27 -0
  71. package/dist/reify/delete-edges.d.ts +4 -0
  72. package/dist/reify/delete-edges.js +13 -0
  73. package/dist/reify/delete-nodes.d.ts +4 -0
  74. package/dist/reify/delete-nodes.js +15 -0
  75. package/dist/reify/extract-node.d.ts +23 -0
  76. package/dist/reify/extract-node.js +83 -0
  77. package/dist/reify/index.d.ts +34 -0
  78. package/dist/reify/index.js +161 -0
  79. package/dist/reify/internal-hoist.d.ts +8 -0
  80. package/dist/reify/internal-hoist.js +133 -0
  81. package/dist/reify/optional-fail.d.ts +15 -0
  82. package/dist/reify/optional-fail.js +15 -0
  83. package/dist/reify/rollback.d.ts +4 -0
  84. package/dist/reify/rollback.js +23 -0
  85. package/dist/reify/update-importers-package-json.d.ts +35 -0
  86. package/dist/reify/update-importers-package-json.js +122 -0
  87. package/dist/remove-optional-subgraph.d.ts +33 -0
  88. package/dist/remove-optional-subgraph.js +47 -0
  89. package/dist/resolve-save-type.d.ts +5 -0
  90. package/dist/resolve-save-type.js +4 -0
  91. package/dist/stringify-node.d.ts +2 -0
  92. package/dist/stringify-node.js +32 -0
  93. package/dist/transfer-data/load.d.ts +43 -0
  94. package/dist/transfer-data/load.js +175 -0
  95. package/dist/uninstall.d.ts +14 -0
  96. package/dist/uninstall.js +75 -0
  97. package/dist/update.d.ts +12 -0
  98. package/dist/update.js +73 -0
  99. package/dist/virtual-root.d.ts +15 -0
  100. package/dist/virtual-root.js +78 -0
  101. package/dist/visualization/human-readable-output.d.ts +26 -0
  102. package/dist/visualization/human-readable-output.js +163 -0
  103. package/dist/visualization/json-output.d.ts +41 -0
  104. package/dist/visualization/json-output.js +50 -0
  105. package/dist/visualization/mermaid-output.d.ts +17 -0
  106. package/dist/visualization/mermaid-output.js +170 -0
  107. package/dist/visualization/object-like-output.d.ts +2 -0
  108. package/dist/visualization/object-like-output.js +47 -0
  109. package/package.json +22 -22
@@ -0,0 +1,32 @@
1
+ import { splitDepID } from '@vltpkg/dep-id/browser';
2
+ import { defaultRegistryName } from '@vltpkg/spec/browser';
3
+ export const stringifyNode = (node) => {
4
+ if (!node)
5
+ return '';
6
+ const version = node.version ? `@${node.version}` : '';
7
+ const [type, ref, nameVersion] = splitDepID(node.id);
8
+ if (type === 'registry') {
9
+ let prefix = `${defaultRegistryName}:`;
10
+ if (ref) {
11
+ if (/^https?:\/\//.test(ref)) {
12
+ prefix = `registry:${ref}#`;
13
+ }
14
+ else {
15
+ prefix = `${ref}:`;
16
+ }
17
+ }
18
+ return `${prefix}${nameVersion}`;
19
+ }
20
+ else if (type === 'workspace') {
21
+ return `workspace:${node.name}`;
22
+ }
23
+ else if (type === 'file' && node.mainImporter) {
24
+ return `root:${node.name}`;
25
+ }
26
+ else {
27
+ // node.name getter will return the id if the package has no name
28
+ // property so here we check for that in order to return `type(ref)` only
29
+ const nameVersion = node.name !== node.id ? `:${node.name}${version}` : '';
30
+ return `${type}(${ref})${nameVersion}`;
31
+ }
32
+ };
@@ -0,0 +1,43 @@
1
+ import { SecurityArchive } from '@vltpkg/security-archive/browser';
2
+ import type { GraphLike, NormalizedManifest } from '@vltpkg/types';
3
+ import type { LockfileData } from '../lockfile/types.ts';
4
+ import type { SpecOptionsFilled } from '@vltpkg/spec/browser';
5
+ /**
6
+ * The returned object when loading a graph from a transfer data structure,
7
+ * including the graph itself, the spec options used to create it, and
8
+ * the security archive (if any).
9
+ */
10
+ export type LoadResult = {
11
+ graph: GraphLike;
12
+ specOptions: SpecOptionsFilled;
13
+ securityArchive: SecurityArchive | undefined;
14
+ };
15
+ /**
16
+ * A data structure defining a complete graph to be transfered, including
17
+ * extra information to the lockfile such as project info and importers.
18
+ */
19
+ export type TransferData = {
20
+ importers: {
21
+ importer: boolean;
22
+ mainImporter: boolean;
23
+ id: string;
24
+ name: string;
25
+ version: string;
26
+ location: string;
27
+ manifest: NormalizedManifest;
28
+ projectRoot?: string;
29
+ integrity?: string;
30
+ resolved?: string;
31
+ dev?: boolean;
32
+ optional?: boolean;
33
+ }[];
34
+ lockfile: LockfileData;
35
+ projectInfo: {
36
+ root: string;
37
+ homedirRelativeRoot: string;
38
+ tools?: string[];
39
+ vltInstalled?: boolean;
40
+ };
41
+ securityArchive?: any;
42
+ };
43
+ export declare const load: (transfered: TransferData) => LoadResult;
@@ -0,0 +1,175 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { SecurityArchive } from '@vltpkg/security-archive/browser';
3
+ import { defaultGitHostArchives, defaultGitHosts, defaultRegistries, defaultRegistry, defaultScopeRegistries, } from '@vltpkg/spec/browser';
4
+ import { stringifyNode } from "../stringify-node.js";
5
+ import { loadEdges } from "../lockfile/load-edges.js";
6
+ import { loadNodes } from "../lockfile/load-nodes.js";
7
+ const loadSpecOptions = (lockfile) => {
8
+ const { catalog = {}, catalogs = {}, registries, registry, 'git-hosts': gitHosts, 'git-host-archives': gitHostArchives, 'scope-registries': scopeRegistries, 'jsr-registries': jsrRegistries, } = lockfile.options;
9
+ return {
10
+ catalog,
11
+ catalogs,
12
+ registries: { ...defaultRegistries, ...registries },
13
+ registry: registry || defaultRegistry,
14
+ 'jsr-registries': { ...jsrRegistries },
15
+ 'git-hosts': { ...defaultGitHosts, ...gitHosts },
16
+ 'git-host-archives': {
17
+ ...defaultGitHostArchives,
18
+ ...gitHostArchives,
19
+ },
20
+ 'scope-registries': {
21
+ ...defaultScopeRegistries,
22
+ ...scopeRegistries,
23
+ },
24
+ };
25
+ };
26
+ export const load = (transfered) => {
27
+ const [mainImporter] = transfered.importers;
28
+ const maybeGraph = {
29
+ importers: new Set(),
30
+ edges: new Set(),
31
+ nodes: new Map(),
32
+ nodesByName: new Map(),
33
+ projectRoot: transfered.projectInfo.root,
34
+ addEdge(type, spec, from, to) {
35
+ const existing = from.edgesOut.get(spec.name);
36
+ if (existing) {
37
+ const edge = existing;
38
+ if (edge.type === type &&
39
+ edge.spec.bareSpec === spec.bareSpec) {
40
+ if (to && to !== edge.to) {
41
+ edge.to = to;
42
+ edge.to.edgesIn.add(edge);
43
+ }
44
+ return edge;
45
+ }
46
+ this.edges.delete(edge);
47
+ }
48
+ const edge = {
49
+ from,
50
+ name: spec.name,
51
+ spec,
52
+ to,
53
+ type,
54
+ };
55
+ from.edgesOut.set(spec.name, edge);
56
+ to?.edgesIn.add(edge);
57
+ this.edges.add(edge);
58
+ return edge;
59
+ },
60
+ addNode(id, manifest) {
61
+ const graph = this;
62
+ if (!id)
63
+ throw error('id is required', { manifest });
64
+ if (!manifest)
65
+ throw error('manifest is required');
66
+ const node = {
67
+ id,
68
+ name: manifest.name,
69
+ version: manifest.version,
70
+ manifest,
71
+ edgesIn: new Set(),
72
+ edgesOut: new Map(),
73
+ workspaces: undefined,
74
+ graph,
75
+ importer: false,
76
+ mainImporter: false,
77
+ projectRoot: graph.projectRoot,
78
+ dev: false,
79
+ optional: false,
80
+ options: transfered.lockfile.options,
81
+ confused: false,
82
+ setResolved() { },
83
+ setConfusedManifest(fixed, confused) {
84
+ this.manifest = fixed;
85
+ this.rawManifest = confused;
86
+ this.confused = true;
87
+ },
88
+ maybeSetConfusedManifest() { },
89
+ toJSON() {
90
+ return {
91
+ id: this.id,
92
+ name: this.name,
93
+ version: this.version,
94
+ location: this.location,
95
+ importer: this.importer,
96
+ manifest: this.manifest,
97
+ projectRoot: this.projectRoot,
98
+ integrity: this.integrity,
99
+ resolved: this.resolved,
100
+ dev: this.dev,
101
+ optional: this.optional,
102
+ confused: this.confused,
103
+ ...(this.confused ?
104
+ { rawManifest: this.rawManifest }
105
+ : undefined),
106
+ };
107
+ },
108
+ toString() {
109
+ return stringifyNode(this);
110
+ },
111
+ };
112
+ this.nodes.set(node.id, node);
113
+ if (node.name) {
114
+ const allNodesWithThisName = this.nodesByName.get(node.name) ?? new Set();
115
+ allNodesWithThisName.add(node);
116
+ this.nodesByName.set(node.name, allNodesWithThisName);
117
+ }
118
+ return node;
119
+ },
120
+ };
121
+ // configure importer nodes
122
+ for (const importer of transfered.importers) {
123
+ const id = importer.id;
124
+ const graph = maybeGraph;
125
+ const node = graph.addNode(id, importer.manifest);
126
+ node.importer = true;
127
+ node.mainImporter = importer.id === mainImporter?.id;
128
+ node.location = importer.location;
129
+ node.integrity = importer.integrity;
130
+ node.resolved = importer.resolved;
131
+ /* c8 ignore next 2 */
132
+ node.dev = importer.dev ?? false;
133
+ node.optional = importer.optional ?? false;
134
+ node.confused = false;
135
+ node.toJSON = () => ({
136
+ id: node.id,
137
+ name: node.name,
138
+ version: node.version,
139
+ location: node.location,
140
+ importer: node.importer,
141
+ manifest: node.manifest,
142
+ projectRoot: node.projectRoot,
143
+ integrity: node.integrity,
144
+ resolved: node.resolved,
145
+ dev: node.dev,
146
+ optional: node.optional,
147
+ confused: node.confused,
148
+ });
149
+ node.toString = () => stringifyNode(node);
150
+ // should set the main importer in the first iteration
151
+ graph.mainImporter ??= node;
152
+ graph.importers.add(node);
153
+ }
154
+ // populate nodes and edges from loaded data
155
+ const graph = maybeGraph;
156
+ const specOptions = loadSpecOptions(transfered.lockfile);
157
+ loadNodes(graph, transfered.lockfile.nodes, specOptions, graph);
158
+ loadEdges(graph, transfered.lockfile.edges, specOptions);
159
+ const securityArchive = SecurityArchive.load(transfered.securityArchive);
160
+ // validates that all nodes have a security archive entry
161
+ if (securityArchive) {
162
+ securityArchive.ok = true;
163
+ for (const node of graph.nodes.values()) {
164
+ if (!securityArchive.has(node.id)) {
165
+ securityArchive.ok = false;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ return {
171
+ graph,
172
+ specOptions,
173
+ securityArchive,
174
+ };
175
+ };
@@ -0,0 +1,14 @@
1
+ import type { PackageInfoClient } from '@vltpkg/package-info';
2
+ import type { LoadOptions } from './actual/load.ts';
3
+ import type { RemoveImportersDependenciesMap } from './dependencies.ts';
4
+ export type UninstallOptions = LoadOptions & {
5
+ packageInfo: PackageInfoClient;
6
+ allowScripts: string;
7
+ };
8
+ export declare const uninstall: (options: UninstallOptions, remove?: RemoveImportersDependenciesMap) => Promise<{
9
+ graph: import("./graph.ts").Graph;
10
+ diff: undefined;
11
+ } | {
12
+ graph: import("./graph.ts").Graph;
13
+ diff: import("./reify/index.ts").ReifyResult;
14
+ }>;
@@ -0,0 +1,75 @@
1
+ import { load as actualLoad } from "./actual/load.js";
2
+ import { GraphModifier } from "./modifiers.js";
3
+ import { build as idealBuild } from "./ideal/build.js";
4
+ import { reify } from "./reify/index.js";
5
+ import { lockfile } from "./index.js";
6
+ import { updatePackageJson } from "./reify/update-importers-package-json.js";
7
+ import { RollbackRemove } from '@vltpkg/rollback-remove';
8
+ import { existsSync, rmSync } from 'node:fs';
9
+ import { resolve } from 'node:path';
10
+ export const uninstall = async (options, remove) => {
11
+ const mainManifest = options.packageJson.read(options.projectRoot);
12
+ const modifiers = GraphModifier.maybeLoad(options);
13
+ const remover = new RollbackRemove();
14
+ try {
15
+ // Load the actual graph before building the ideal graph so that
16
+ // manifest data from installed packages can be used to hydrate
17
+ // nodes loaded from the lockfile. Without this, nodes loaded from
18
+ // vlt-lock.json (which does not store manifests) will be missing
19
+ // manifest data, causing the hidden lockfile save to silently fail
20
+ // due to throwOnMissingManifest and leaving stale entries behind.
21
+ const act = actualLoad({
22
+ ...options,
23
+ modifiers: undefined,
24
+ mainManifest,
25
+ loadManifests: true,
26
+ });
27
+ const graph = await idealBuild({
28
+ ...options,
29
+ actual: act,
30
+ remove,
31
+ mainManifest,
32
+ loadManifests: true,
33
+ remover,
34
+ });
35
+ // If lockfileOnly is enabled, skip reify and only save the lockfile
36
+ if (options.lockfileOnly) {
37
+ // Save only the main lockfile, skip all filesystem operations
38
+ lockfile.save({ graph, modifiers });
39
+ const saveImportersPackageJson =
40
+ /* c8 ignore next */
41
+ remove?.modifiedDependencies ?
42
+ updatePackageJson({
43
+ ...options,
44
+ remove,
45
+ graph,
46
+ })
47
+ : undefined;
48
+ saveImportersPackageJson?.();
49
+ return { graph, diff: undefined };
50
+ }
51
+ const diff = await reify({
52
+ ...options,
53
+ remove,
54
+ actual: act,
55
+ graph,
56
+ loadManifests: true,
57
+ remover,
58
+ });
59
+ return { graph, diff };
60
+ /* c8 ignore start */
61
+ }
62
+ catch (err) {
63
+ await remover.rollback().catch(() => { });
64
+ // Remove hidden lockfile on failure
65
+ try {
66
+ const hiddenLockfile = resolve(options.projectRoot, 'node_modules/.vlt-lock.json');
67
+ if (existsSync(hiddenLockfile)) {
68
+ rmSync(hiddenLockfile, { force: true });
69
+ }
70
+ }
71
+ catch { }
72
+ throw err;
73
+ }
74
+ /* c8 ignore stop */
75
+ };
@@ -0,0 +1,12 @@
1
+ import type { PackageInfoClient } from '@vltpkg/package-info';
2
+ import type { LoadOptions } from './actual/load.ts';
3
+ import { Graph } from './graph.ts';
4
+ export type UpdateOptions = LoadOptions & {
5
+ packageInfo: PackageInfoClient;
6
+ allowScripts: string;
7
+ };
8
+ export declare const update: (options: UpdateOptions) => Promise<{
9
+ buildQueue: import("@vltpkg/dep-id").DepID[] | undefined;
10
+ graph: Graph;
11
+ diff: import("./diff.ts").Diff;
12
+ }>;
package/dist/update.js ADDED
@@ -0,0 +1,73 @@
1
+ import { load as actualLoad } from "./actual/load.js";
2
+ import { buildIdealFromStartingGraph } from "./ideal/build-ideal-from-starting-graph.js";
3
+ import { reify } from "./reify/index.js";
4
+ import { GraphModifier } from "./modifiers.js";
5
+ import { init } from '@vltpkg/init';
6
+ import { asError } from '@vltpkg/types';
7
+ import { Graph } from "./graph.js";
8
+ import { graphStep } from '@vltpkg/output';
9
+ import { RollbackRemove } from '@vltpkg/rollback-remove';
10
+ import { existsSync, rmSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+ export const update = async (options) => {
13
+ let mainManifest = undefined;
14
+ try {
15
+ mainManifest = options.packageJson.read(options.projectRoot);
16
+ }
17
+ catch (err) {
18
+ if (asError(err).message === 'Could not read package.json file') {
19
+ await init({ cwd: options.projectRoot });
20
+ mainManifest = options.packageJson.read(options.projectRoot, {
21
+ reload: true,
22
+ });
23
+ }
24
+ else {
25
+ throw err;
26
+ }
27
+ }
28
+ const modifiers = GraphModifier.maybeLoad(options);
29
+ const remover = new RollbackRemove();
30
+ try {
31
+ const done = graphStep('build');
32
+ const graph = await buildIdealFromStartingGraph({
33
+ ...options,
34
+ add: Object.assign(new Map(), { modifiedDependencies: false }),
35
+ remove: Object.assign(new Map(), {
36
+ modifiedDependencies: false,
37
+ }),
38
+ graph: new Graph({ ...options, mainManifest }),
39
+ modifiers,
40
+ remover,
41
+ });
42
+ done();
43
+ const act = actualLoad({
44
+ ...options,
45
+ mainManifest,
46
+ loadManifests: true,
47
+ });
48
+ const { buildQueue, diff } = await reify({
49
+ ...options,
50
+ actual: act,
51
+ graph,
52
+ loadManifests: true,
53
+ modifiers,
54
+ remover,
55
+ update: true,
56
+ });
57
+ return { buildQueue, graph, diff };
58
+ /* c8 ignore start */
59
+ }
60
+ catch (err) {
61
+ await remover.rollback().catch(() => { });
62
+ // Remove hidden lockfile on failure
63
+ try {
64
+ const hiddenLockfile = resolve(options.projectRoot, 'node_modules/.vlt-lock.json');
65
+ if (existsSync(hiddenLockfile)) {
66
+ rmSync(hiddenLockfile, { force: true });
67
+ }
68
+ }
69
+ catch { }
70
+ throw err;
71
+ }
72
+ /* c8 ignore stop */
73
+ };
@@ -0,0 +1,15 @@
1
+ import type { SpecOptions } from '@vltpkg/spec/browser';
2
+ import type { NodeLike } from '@vltpkg/types';
3
+ /**
4
+ * An unique DepID to identify the virtual root node.
5
+ */
6
+ export declare const VIRTUAL_ROOT_ID: import("@vltpkg/dep-id/browser").DepID;
7
+ /**
8
+ * A virtual root used to aggregate multiple importers into a single graph.
9
+ *
10
+ * This is meant to be used with visual tools that want a single root node
11
+ * starting point to represent the graph.
12
+ *
13
+ * Returns undefined if a virtual root is not needed.
14
+ */
15
+ export declare const createVirtualRoot: (name: string | undefined, options: SpecOptions, mainImporters: NodeLike[]) => NodeLike | undefined;
@@ -0,0 +1,78 @@
1
+ import { Spec } from '@vltpkg/spec/browser';
2
+ import { joinDepIDTuple } from '@vltpkg/dep-id/browser';
3
+ /**
4
+ * An unique DepID to identify the virtual root node.
5
+ */
6
+ export const VIRTUAL_ROOT_ID = joinDepIDTuple([
7
+ 'file',
8
+ '__virtual%root__',
9
+ ]);
10
+ /**
11
+ * A virtual root used to aggregate multiple importers into a single graph.
12
+ *
13
+ * This is meant to be used with visual tools that want a single root node
14
+ * starting point to represent the graph.
15
+ *
16
+ * Returns undefined if a virtual root is not needed.
17
+ */
18
+ export const createVirtualRoot = (name = 'virtual-root', options, mainImporters) => {
19
+ const res = {
20
+ id: VIRTUAL_ROOT_ID,
21
+ name,
22
+ version: '1.0.0',
23
+ manifest: {
24
+ name,
25
+ version: '1.0.0',
26
+ },
27
+ edgesIn: new Set(),
28
+ edgesOut: new Map([]),
29
+ confused: false,
30
+ importer: true,
31
+ mainImporter: true,
32
+ location: '.',
33
+ graph: { importers: new Set() },
34
+ projectRoot: '',
35
+ dev: false,
36
+ optional: false,
37
+ options,
38
+ setConfusedManifest() { },
39
+ setResolved() { },
40
+ maybeSetConfusedManifest() { },
41
+ workspaces: undefined,
42
+ toJSON() {
43
+ return {
44
+ id: this.id,
45
+ name: this.name,
46
+ version: this.version,
47
+ location: this.location,
48
+ importer: this.importer,
49
+ manifest: this.manifest,
50
+ projectRoot: this.projectRoot,
51
+ integrity: this.integrity,
52
+ resolved: this.resolved,
53
+ dev: this.dev,
54
+ optional: this.optional,
55
+ confused: false,
56
+ };
57
+ },
58
+ };
59
+ // @ts-expect-error
60
+ res[Symbol.toStringTag] = '@vltpkg/graph.Node';
61
+ // link all mainImporters to the virtual root
62
+ for (const importer of mainImporters) {
63
+ const name = importer.name || '(unknown)';
64
+ if (importer.mainImporter) {
65
+ const spec = Spec.parse(name, 'file:.', options);
66
+ const edge = {
67
+ name: spec.name,
68
+ from: res,
69
+ to: importer,
70
+ spec,
71
+ type: 'prod',
72
+ };
73
+ res.edgesOut.set(name, edge);
74
+ importer.edgesIn.add(edge);
75
+ }
76
+ }
77
+ return res;
78
+ };
@@ -0,0 +1,26 @@
1
+ import type { EdgeLike, NodeLike } from '@vltpkg/types';
2
+ export type TreeItem = {
3
+ name?: string | null;
4
+ edge: EdgeLike | undefined;
5
+ node: NodeLike | undefined;
6
+ prefix: string;
7
+ padding: string;
8
+ hasSibling: boolean;
9
+ seen: boolean;
10
+ include: boolean;
11
+ parent: TreeItem | undefined;
12
+ };
13
+ export type HumanReadableOutputGraph = {
14
+ edges: EdgeLike[];
15
+ importers: Set<NodeLike>;
16
+ nodes: NodeLike[];
17
+ highlightSelection?: boolean;
18
+ };
19
+ export type EdgeMap = Map<NodeLike | undefined, TreeItem>;
20
+ export type TreeMap = Map<EdgeLike | undefined, EdgeMap>;
21
+ /**
22
+ * Returns a human-readable output of the graph.
23
+ */
24
+ export declare function humanReadableOutput(options: HumanReadableOutputGraph, { colors }: {
25
+ colors?: boolean;
26
+ }): string;