@vltpkg/cli-sdk 0.0.0-3 → 0.0.0-31

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 (169) hide show
  1. package/README.md +3 -0
  2. package/dist/esm/commands/build.d.ts +25 -0
  3. package/dist/esm/commands/build.d.ts.map +1 -0
  4. package/dist/esm/commands/build.js +102 -0
  5. package/dist/esm/commands/build.js.map +1 -0
  6. package/dist/esm/commands/cache.d.ts +65 -0
  7. package/dist/esm/commands/cache.d.ts.map +1 -0
  8. package/dist/esm/commands/cache.js +257 -0
  9. package/dist/esm/commands/cache.js.map +1 -0
  10. package/dist/esm/commands/ci.d.ts +11 -0
  11. package/dist/esm/commands/ci.d.ts.map +1 -0
  12. package/dist/esm/commands/ci.js +32 -0
  13. package/dist/esm/commands/ci.js.map +1 -0
  14. package/dist/esm/commands/config.d.ts +3 -2
  15. package/dist/esm/commands/config.d.ts.map +1 -1
  16. package/dist/esm/commands/config.js +372 -101
  17. package/dist/esm/commands/config.js.map +1 -1
  18. package/dist/esm/commands/exec-cache.d.ts +49 -0
  19. package/dist/esm/commands/exec-cache.d.ts.map +1 -0
  20. package/dist/esm/commands/exec-cache.js +146 -0
  21. package/dist/esm/commands/exec-cache.js.map +1 -0
  22. package/dist/esm/commands/exec-local.d.ts +6 -0
  23. package/dist/esm/commands/exec-local.d.ts.map +1 -0
  24. package/dist/esm/commands/exec-local.js +24 -0
  25. package/dist/esm/commands/exec-local.js.map +1 -0
  26. package/dist/esm/commands/exec.d.ts +4 -0
  27. package/dist/esm/commands/exec.d.ts.map +1 -1
  28. package/dist/esm/commands/exec.js +75 -10
  29. package/dist/esm/commands/exec.js.map +1 -1
  30. package/dist/esm/commands/help.d.ts +1 -1
  31. package/dist/esm/commands/help.d.ts.map +1 -1
  32. package/dist/esm/commands/help.js +25 -3
  33. package/dist/esm/commands/help.js.map +1 -1
  34. package/dist/esm/commands/init.d.ts +4 -5
  35. package/dist/esm/commands/init.d.ts.map +1 -1
  36. package/dist/esm/commands/init.js +95 -9
  37. package/dist/esm/commands/init.js.map +1 -1
  38. package/dist/esm/commands/install/reporter.d.ts +3 -2
  39. package/dist/esm/commands/install/reporter.d.ts.map +1 -1
  40. package/dist/esm/commands/install/reporter.js +43 -15
  41. package/dist/esm/commands/install/reporter.js.map +1 -1
  42. package/dist/esm/commands/install.d.ts +24 -3
  43. package/dist/esm/commands/install.d.ts.map +1 -1
  44. package/dist/esm/commands/install.js +27 -3
  45. package/dist/esm/commands/install.js.map +1 -1
  46. package/dist/esm/commands/list.d.ts +1 -1
  47. package/dist/esm/commands/list.d.ts.map +1 -1
  48. package/dist/esm/commands/list.js +150 -42
  49. package/dist/esm/commands/list.js.map +1 -1
  50. package/dist/esm/commands/pack.d.ts +32 -0
  51. package/dist/esm/commands/pack.d.ts.map +1 -0
  52. package/dist/esm/commands/pack.js +147 -0
  53. package/dist/esm/commands/pack.js.map +1 -0
  54. package/dist/esm/commands/pkg.d.ts +2 -3
  55. package/dist/esm/commands/pkg.d.ts.map +1 -1
  56. package/dist/esm/commands/pkg.js +123 -38
  57. package/dist/esm/commands/pkg.js.map +1 -1
  58. package/dist/esm/commands/publish.d.ts +22 -0
  59. package/dist/esm/commands/publish.d.ts.map +1 -0
  60. package/dist/esm/commands/publish.js +239 -0
  61. package/dist/esm/commands/publish.js.map +1 -0
  62. package/dist/esm/commands/query.d.ts +1 -1
  63. package/dist/esm/commands/query.d.ts.map +1 -1
  64. package/dist/esm/commands/query.js +171 -32
  65. package/dist/esm/commands/query.js.map +1 -1
  66. package/dist/esm/commands/run-exec.d.ts +1 -0
  67. package/dist/esm/commands/run-exec.d.ts.map +1 -1
  68. package/dist/esm/commands/run-exec.js +1 -0
  69. package/dist/esm/commands/run-exec.js.map +1 -1
  70. package/dist/esm/commands/run.d.ts +1 -0
  71. package/dist/esm/commands/run.d.ts.map +1 -1
  72. package/dist/esm/commands/run.js +13 -16
  73. package/dist/esm/commands/run.js.map +1 -1
  74. package/dist/esm/commands/serve.d.ts +14 -0
  75. package/dist/esm/commands/serve.d.ts.map +1 -0
  76. package/dist/esm/commands/serve.js +103 -0
  77. package/dist/esm/commands/serve.js.map +1 -0
  78. package/dist/esm/commands/uninstall.d.ts +13 -1
  79. package/dist/esm/commands/uninstall.d.ts.map +1 -1
  80. package/dist/esm/commands/uninstall.js +12 -1
  81. package/dist/esm/commands/uninstall.js.map +1 -1
  82. package/dist/esm/commands/update.d.ts +14 -0
  83. package/dist/esm/commands/update.d.ts.map +1 -0
  84. package/dist/esm/commands/update.js +41 -0
  85. package/dist/esm/commands/update.js.map +1 -0
  86. package/dist/esm/commands/version.d.ts +26 -0
  87. package/dist/esm/commands/version.d.ts.map +1 -0
  88. package/dist/esm/commands/version.js +226 -0
  89. package/dist/esm/commands/version.js.map +1 -0
  90. package/dist/esm/commands/whoami.d.ts +4 -2
  91. package/dist/esm/commands/whoami.d.ts.map +1 -1
  92. package/dist/esm/commands/whoami.js +1 -1
  93. package/dist/esm/commands/whoami.js.map +1 -1
  94. package/dist/esm/config/definition.d.ts +117 -10
  95. package/dist/esm/config/definition.d.ts.map +1 -1
  96. package/dist/esm/config/definition.js +203 -31
  97. package/dist/esm/config/definition.js.map +1 -1
  98. package/dist/esm/config/index.d.ts +46 -40
  99. package/dist/esm/config/index.d.ts.map +1 -1
  100. package/dist/esm/config/index.js +126 -176
  101. package/dist/esm/config/index.js.map +1 -1
  102. package/dist/esm/config/merge.d.ts +3 -1
  103. package/dist/esm/config/merge.d.ts.map +1 -1
  104. package/dist/esm/config/merge.js +11 -6
  105. package/dist/esm/config/merge.js.map +1 -1
  106. package/dist/esm/config/usage.d.ts +3 -2
  107. package/dist/esm/config/usage.d.ts.map +1 -1
  108. package/dist/esm/config/usage.js.map +1 -1
  109. package/dist/esm/exec-command.d.ts +33 -14
  110. package/dist/esm/exec-command.d.ts.map +1 -1
  111. package/dist/esm/exec-command.js +214 -65
  112. package/dist/esm/exec-command.js.map +1 -1
  113. package/dist/esm/index.d.ts +1 -14
  114. package/dist/esm/index.d.ts.map +1 -1
  115. package/dist/esm/index.js +46 -20
  116. package/dist/esm/index.js.map +1 -1
  117. package/dist/esm/load-command.d.ts +16 -0
  118. package/dist/esm/load-command.d.ts.map +1 -0
  119. package/dist/esm/load-command.js +21 -0
  120. package/dist/esm/load-command.js.map +1 -0
  121. package/dist/esm/output.d.ts +6 -10
  122. package/dist/esm/output.d.ts.map +1 -1
  123. package/dist/esm/output.js +63 -33
  124. package/dist/esm/output.js.map +1 -1
  125. package/dist/esm/pack-tarball.d.ts +22 -0
  126. package/dist/esm/pack-tarball.d.ts.map +1 -0
  127. package/dist/esm/pack-tarball.js +247 -0
  128. package/dist/esm/pack-tarball.js.map +1 -0
  129. package/dist/esm/parse-add-remove-args.d.ts +1 -1
  130. package/dist/esm/parse-add-remove-args.d.ts.map +1 -1
  131. package/dist/esm/parse-add-remove-args.js +1 -1
  132. package/dist/esm/parse-add-remove-args.js.map +1 -1
  133. package/dist/esm/print-err.d.ts +12 -1
  134. package/dist/esm/print-err.d.ts.map +1 -1
  135. package/dist/esm/print-err.js +157 -26
  136. package/dist/esm/print-err.js.map +1 -1
  137. package/dist/esm/query-host-contexts.d.ts +16 -0
  138. package/dist/esm/query-host-contexts.d.ts.map +1 -0
  139. package/dist/esm/query-host-contexts.js +135 -0
  140. package/dist/esm/query-host-contexts.js.map +1 -0
  141. package/dist/esm/start-gui.d.ts +7 -33
  142. package/dist/esm/start-gui.d.ts.map +1 -1
  143. package/dist/esm/start-gui.js +51 -349
  144. package/dist/esm/start-gui.js.map +1 -1
  145. package/dist/esm/view.d.ts +2 -3
  146. package/dist/esm/view.d.ts.map +1 -1
  147. package/dist/esm/view.js +1 -1
  148. package/dist/esm/view.js.map +1 -1
  149. package/package.json +73 -45
  150. package/dist/esm/commands/gui.d.ts +0 -6
  151. package/dist/esm/commands/gui.d.ts.map +0 -1
  152. package/dist/esm/commands/gui.js +0 -14
  153. package/dist/esm/commands/gui.js.map +0 -1
  154. package/dist/esm/commands/install-exec.d.ts +0 -4
  155. package/dist/esm/commands/install-exec.d.ts.map +0 -1
  156. package/dist/esm/commands/install-exec.js +0 -13
  157. package/dist/esm/commands/install-exec.js.map +0 -1
  158. package/dist/esm/ignored-homedir-folder-names.d.ts +0 -7
  159. package/dist/esm/ignored-homedir-folder-names.d.ts.map +0 -1
  160. package/dist/esm/ignored-homedir-folder-names.js +0 -35
  161. package/dist/esm/ignored-homedir-folder-names.js.map +0 -1
  162. package/dist/esm/project-info.d.ts +0 -32
  163. package/dist/esm/project-info.d.ts.map +0 -1
  164. package/dist/esm/project-info.js +0 -90
  165. package/dist/esm/project-info.js.map +0 -1
  166. package/dist/esm/read-project-folders.d.ts +0 -27
  167. package/dist/esm/read-project-folders.d.ts.map +0 -1
  168. package/dist/esm/read-project-folders.js +0 -66
  169. package/dist/esm/read-project-folders.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-host-contexts.d.ts","sourceRoot":"","sources":["../../src/query-host-contexts.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAG1D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,QAAQ,EAAE,CAAA;IACxB,YAAY,EAAE,QAAQ,EAAE,CAAA;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,eAAe,EAAE,eAAe,CAAA;CACjC,CAAA;AA8CD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,SAC1B,YAAY,KACjB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAiH3D,CAAA"}
@@ -0,0 +1,135 @@
1
+ import { homedir } from 'node:os';
2
+ import { parse, posix } from 'node:path';
3
+ import { getProjectData, readProjectFolders, reloadConfig, } from '@vltpkg/server';
4
+ import { actual, createVirtualRoot } from '@vltpkg/graph';
5
+ import { SecurityArchive } from '@vltpkg/security-archive';
6
+ import { error } from '@vltpkg/error-cause';
7
+ // In restricted environments (like locked-down Codespaces),
8
+ // homedir() might fail. Fall back to parent directory.
9
+ let foundHome;
10
+ try {
11
+ foundHome = posix.format(parse(homedir()));
12
+ /* c8 ignore next 3 */
13
+ }
14
+ catch { }
15
+ const home = foundHome ?? posix.dirname(posix.format(parse(process.cwd())));
16
+ /**
17
+ * Generates possible project keys for a given folder.
18
+ */
19
+ const getPossibleProjectKeys = (folder, scurry) => {
20
+ const relativePath = posix.relative(scurry.cwd.fullpathPosix(), folder.fullpathPosix());
21
+ const absolutePath = folder.fullpathPosix();
22
+ const homeRelativePath = posix.relative(scurry.resolvePosix(home), folder.fullpathPosix());
23
+ const dotRelativeKey = relativePath === '' ? 'file:.' : `file:./${relativePath}`;
24
+ const relativeKey = `file:${relativePath}`;
25
+ const absoluteKey = `file:${absolutePath}`;
26
+ const homeRelativeKey = `file:~/${homeRelativePath}`;
27
+ const keys = [
28
+ relativeKey,
29
+ dotRelativeKey,
30
+ absoluteKey,
31
+ homeRelativeKey,
32
+ `${relativeKey}/`,
33
+ `${dotRelativeKey}/`,
34
+ `${absoluteKey}/`,
35
+ `${homeRelativeKey}/`,
36
+ ];
37
+ return new Set(keys);
38
+ };
39
+ /**
40
+ * Creates a Map of host context functions that can be used by the :host
41
+ * pseudo selector to dynamically load graphs from different sources.
42
+ */
43
+ export const createHostContextsMap = async (conf) => {
44
+ const hostContexts = new Map();
45
+ // Read all project folders from the configured paths
46
+ const { scurry } = conf.options;
47
+ const projectFolders = await readProjectFolders({
48
+ scurry,
49
+ userDefinedProjectPaths: conf.options['dashboard-root'] ?? [],
50
+ });
51
+ for (const folder of projectFolders) {
52
+ const retrieveProjectGraph = async () => {
53
+ const initialEdges = [];
54
+ const initialNodes = [];
55
+ const config = await reloadConfig(folder.fullpath());
56
+ // load each individual graph
57
+ const graph = actual.load({
58
+ ...config.options,
59
+ projectRoot: folder.fullpath(),
60
+ skipLoadingNodesOnModifiersChange: false,
61
+ });
62
+ initialEdges.push(...graph.edges);
63
+ initialNodes.push(...graph.nodes.values());
64
+ // Initialize security archive with all loaded nodes
65
+ const securityArchive = await SecurityArchive.start({
66
+ nodes: initialNodes,
67
+ });
68
+ return {
69
+ initialEdges,
70
+ initialNodes,
71
+ edges: [],
72
+ nodes: [graph.mainImporter],
73
+ securityArchive,
74
+ };
75
+ };
76
+ // add multiple keys for each project folder
77
+ for (const path of getPossibleProjectKeys(folder, scurry)) {
78
+ if (!hostContexts.has(path)) {
79
+ hostContexts.set(path, retrieveProjectGraph);
80
+ }
81
+ }
82
+ }
83
+ // Define local context - loads graphs from all projects in user's project paths
84
+ hostContexts.set('local', async () => {
85
+ // Load graphs from each project folder
86
+ const initialEdges = [];
87
+ const initialNodes = [];
88
+ const mainImporters = [];
89
+ for (const folder of projectFolders) {
90
+ try {
91
+ const config = await reloadConfig(folder.fullpath());
92
+ const projectInfo = getProjectData({
93
+ packageJson: config.options.packageJson,
94
+ scurry: config.options.scurry,
95
+ }, folder);
96
+ // only include projects that are vlt-installed
97
+ if (!projectInfo.vltInstalled) {
98
+ continue;
99
+ }
100
+ // load each individual graph
101
+ const graph = actual.load({
102
+ ...config.options,
103
+ projectRoot: folder.fullpath(),
104
+ skipLoadingNodesOnModifiersChange: false,
105
+ });
106
+ initialEdges.push(...graph.edges);
107
+ initialNodes.push(...graph.nodes.values());
108
+ mainImporters.push(graph.mainImporter);
109
+ }
110
+ catch (_error) {
111
+ // Skip projects that fail to load
112
+ // This might happen for projects without proper package.json
113
+ // or other loading issues
114
+ continue;
115
+ }
116
+ }
117
+ // Initialize security archive with all loaded nodes
118
+ const securityArchive = await SecurityArchive.start({
119
+ nodes: initialNodes,
120
+ });
121
+ const virtualRoot = createVirtualRoot('local', conf.options, mainImporters);
122
+ if (!virtualRoot) {
123
+ throw error('Failed to create virtual root for local context');
124
+ }
125
+ return {
126
+ initialEdges,
127
+ initialNodes,
128
+ edges: [],
129
+ nodes: [virtualRoot],
130
+ securityArchive,
131
+ };
132
+ });
133
+ return hostContexts;
134
+ };
135
+ //# sourceMappingURL=query-host-contexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-host-contexts.js","sourceRoot":"","sources":["../../src/query-host-contexts.ts"],"names":[],"mappings":"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","sourcesContent":["import { homedir } from 'node:os'\nimport { parse, posix } from 'node:path'\nimport {\n getProjectData,\n readProjectFolders,\n reloadConfig,\n} from '@vltpkg/server'\nimport { actual, createVirtualRoot } from '@vltpkg/graph'\nimport { SecurityArchive } from '@vltpkg/security-archive'\nimport { error } from '@vltpkg/error-cause'\nimport type { PathBase, PathScurry } from 'path-scurry'\nimport type { EdgeLike, NodeLike } from '@vltpkg/types'\nimport type { LoadedConfig } from './config/index.ts'\n\nexport type HostContextsMapResult = {\n initialEdges: EdgeLike[]\n initialNodes: NodeLike[]\n edges: EdgeLike[]\n nodes: NodeLike[]\n securityArchive: SecurityArchive\n}\n\n// In restricted environments (like locked-down Codespaces),\n// homedir() might fail. Fall back to parent directory.\nlet foundHome\ntry {\n foundHome = posix.format(parse(homedir()))\n /* c8 ignore next 3 */\n} catch {}\nconst home =\n foundHome ?? posix.dirname(posix.format(parse(process.cwd())))\n\n/**\n * Generates possible project keys for a given folder.\n */\nconst getPossibleProjectKeys = (\n folder: PathBase,\n scurry: PathScurry,\n): Set<string> => {\n const relativePath = posix.relative(\n scurry.cwd.fullpathPosix(),\n folder.fullpathPosix(),\n )\n const absolutePath = folder.fullpathPosix()\n const homeRelativePath = posix.relative(\n scurry.resolvePosix(home),\n folder.fullpathPosix(),\n )\n const dotRelativeKey =\n relativePath === '' ? 'file:.' : `file:./${relativePath}`\n const relativeKey = `file:${relativePath}`\n const absoluteKey = `file:${absolutePath}`\n const homeRelativeKey = `file:~/${homeRelativePath}`\n const keys = [\n relativeKey,\n dotRelativeKey,\n absoluteKey,\n homeRelativeKey,\n `${relativeKey}/`,\n `${dotRelativeKey}/`,\n `${absoluteKey}/`,\n `${homeRelativeKey}/`,\n ]\n return new Set(keys)\n}\n\n/**\n * Creates a Map of host context functions that can be used by the :host\n * pseudo selector to dynamically load graphs from different sources.\n */\nexport const createHostContextsMap = async (\n conf: LoadedConfig,\n): Promise<Map<string, () => Promise<HostContextsMapResult>>> => {\n const hostContexts = new Map<\n string,\n () => Promise<HostContextsMapResult>\n >()\n // Read all project folders from the configured paths\n const { scurry } = conf.options\n const projectFolders = await readProjectFolders({\n scurry,\n userDefinedProjectPaths: conf.options['dashboard-root'] ?? [],\n })\n\n for (const folder of projectFolders) {\n const retrieveProjectGraph = async () => {\n const initialEdges: EdgeLike[] = []\n const initialNodes: NodeLike[] = []\n const config = await reloadConfig(folder.fullpath())\n\n // load each individual graph\n const graph = actual.load({\n ...config.options,\n projectRoot: folder.fullpath(),\n skipLoadingNodesOnModifiersChange: false,\n })\n initialEdges.push(...graph.edges)\n initialNodes.push(...graph.nodes.values())\n\n // Initialize security archive with all loaded nodes\n const securityArchive = await SecurityArchive.start({\n nodes: initialNodes,\n })\n\n return {\n initialEdges,\n initialNodes,\n edges: [],\n nodes: [graph.mainImporter],\n securityArchive,\n }\n }\n\n // add multiple keys for each project folder\n for (const path of getPossibleProjectKeys(folder, scurry)) {\n if (!hostContexts.has(path)) {\n hostContexts.set(path, retrieveProjectGraph)\n }\n }\n }\n\n // Define local context - loads graphs from all projects in user's project paths\n hostContexts.set('local', async () => {\n // Load graphs from each project folder\n const initialEdges: EdgeLike[] = []\n const initialNodes: NodeLike[] = []\n const mainImporters: NodeLike[] = []\n for (const folder of projectFolders) {\n try {\n const config = await reloadConfig(folder.fullpath())\n const projectInfo = getProjectData(\n {\n packageJson: config.options.packageJson,\n scurry: config.options.scurry,\n },\n folder,\n )\n\n // only include projects that are vlt-installed\n if (!projectInfo.vltInstalled) {\n continue\n }\n\n // load each individual graph\n const graph = actual.load({\n ...config.options,\n projectRoot: folder.fullpath(),\n skipLoadingNodesOnModifiersChange: false,\n })\n initialEdges.push(...graph.edges)\n initialNodes.push(...graph.nodes.values())\n mainImporters.push(graph.mainImporter)\n } catch (_error) {\n // Skip projects that fail to load\n // This might happen for projects without proper package.json\n // or other loading issues\n continue\n }\n }\n\n // Initialize security archive with all loaded nodes\n const securityArchive = await SecurityArchive.start({\n nodes: initialNodes,\n })\n\n const virtualRoot = createVirtualRoot(\n 'local',\n conf.options,\n mainImporters,\n )\n\n if (!virtualRoot) {\n throw error('Failed to create virtual root for local context')\n }\n\n return {\n initialEdges,\n initialNodes,\n edges: [],\n nodes: [virtualRoot],\n securityArchive,\n }\n })\n\n return hostContexts\n}\n"]}
@@ -1,36 +1,10 @@
1
- import type { AddImportersDependenciesMap, InstallOptions, RemoveImportersDependenciesMap, UninstallOptions } from '@vltpkg/graph';
2
- import type { PackageJson } from '@vltpkg/package-json';
3
- import type { SpecOptions } from '@vltpkg/spec';
4
- import type { DependencyTypeShort } from '@vltpkg/types';
5
- import type { IncomingMessage, Server, ServerResponse } from 'node:http';
6
- import type { PathBase, PathScurry } from 'path-scurry';
1
+ import type { PathScurry } from 'path-scurry';
7
2
  import type { LoadedConfig } from './config/index.ts';
8
- import type { DashboardProjectData } from './project-info.ts';
9
- export type GUIInstallOptions = Record<string, Record<string, {
10
- version: string;
11
- type: DependencyTypeShort;
12
- }>>;
13
- export type GUIUninstallOptions = Record<string, Set<string>>;
14
- export type StartGUIOptions = {
15
- assetsDir?: string;
16
- conf: LoadedConfig;
17
- port?: number;
3
+ export declare const getDefaultStartingRoute: (options: {
4
+ queryString?: string;
18
5
  startingRoute?: string;
19
- tmpDir?: string;
20
- };
21
- export type DashboardLocation = {
22
- path: string;
23
- readablePath: string;
24
- };
25
- export type DashboardData = {
26
- cwd: string;
27
- buildVersion: string;
28
- dashboardProjectLocations: DashboardLocation[];
29
- defaultAuthor: string;
30
- projects: DashboardProjectData[];
31
- };
32
- export declare const parseInstallOptions: (options: InstallOptions & SpecOptions, args: GUIInstallOptions) => [InstallOptions, AddImportersDependenciesMap];
33
- export declare const parseUninstallOptions: (options: UninstallOptions, args: GUIUninstallOptions) => [UninstallOptions, RemoveImportersDependenciesMap];
34
- export declare const formatDashboardJson: (projectFolders: PathBase[], dashboardRoot: string[], scurry: PathScurry, packageJson: PackageJson) => Promise<DashboardData>;
35
- export declare const startGUI: ({ conf, assetsDir, port, startingRoute, tmpDir, }: StartGUIOptions) => Promise<Server<typeof IncomingMessage, typeof ServerResponse>>;
6
+ projectRoot: string;
7
+ scurry: PathScurry;
8
+ }) => Promise<string>;
9
+ export declare const startGUI: (conf: LoadedConfig, startingRoute?: string) => Promise<import("@vltpkg/server").VltServer>;
36
10
  //# sourceMappingURL=start-gui.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-gui.d.ts","sourceRoot":"","sources":["../../src/start-gui.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,2BAA2B,EAE3B,cAAc,EACd,8BAA8B,EAC9B,gBAAgB,EACjB,MAAM,eAAe,CAAA;AAQtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAUxD,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,cAAc,EACf,MAAM,WAAW,CAAA;AAMlB,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAkB7D,MAAM,MAAM,iBAAiB,GAAG,MAAM,CACpC,MAAM,EACN,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAC/D,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AAE7D,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,yBAAyB,EAAE,iBAAiB,EAAE,CAAA;IAC9C,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,oBAAoB,EAAE,CAAA;CACjC,CAAA;AAgBD,eAAO,MAAM,mBAAmB,YACrB,cAAc,GAAG,WAAW,QAC/B,iBAAiB,KACtB,CAAC,cAAc,EAAE,2BAA2B,CAiB9C,CAAA;AAED,eAAO,MAAM,qBAAqB,YACvB,gBAAgB,QACnB,mBAAmB,KACxB,CAAC,gBAAgB,EAAE,8BAA8B,CAWnD,CAAA;AAED,eAAO,MAAM,mBAAmB,mBACd,QAAQ,EAAE,iBACX,MAAM,EAAE,UACf,UAAU,eACL,WAAW,2BA6CzB,CAAA;AAqLD,eAAO,MAAM,QAAQ,sDAMlB,eAAe,mEAwLjB,CAAA"}
1
+ {"version":3,"file":"start-gui.d.ts","sourceRoot":"","sources":["../../src/start-gui.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,eAAO,MAAM,uBAAuB,YAAmB;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,UAAU,CAAA;CACnB,oBAYA,CAAA;AAaD,eAAO,MAAM,QAAQ,SACb,YAAY,kBACF,MAAM,gDA0CvB,CAAA"}
@@ -1,357 +1,59 @@
1
- import { asDepID } from '@vltpkg/dep-id';
2
- import { getUser } from '@vltpkg/git';
3
- import { actual, asDependency, install, uninstall, } from '@vltpkg/graph';
4
- import { getAuthorFromGitUser, init } from '@vltpkg/init';
5
- import { Spec } from '@vltpkg/spec';
1
+ import { resolve } from 'node:path';
2
+ import LZString from 'lz-string';
3
+ import { createServer } from '@vltpkg/server';
6
4
  import { urlOpen } from '@vltpkg/url-open';
7
- import assert from 'node:assert';
8
- import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
9
- import { createServer, request } from 'node:http';
10
- import { homedir, tmpdir } from 'node:os';
11
- import { dirname, relative, resolve } from 'node:path';
12
- import { fileURLToPath } from 'node:url';
13
- import { loadPackageJson } from 'package-json-from-dist';
14
- import handler from 'serve-handler';
15
- import { stderr, stdout } from "./output.js";
16
- import { getDashboardProjectData, getGraphProjectData, getReadablePath, } from "./project-info.js";
17
- import { readProjectFolders } from "./read-project-folders.js";
18
- const HOST = 'localhost';
19
- const PORT = 7017;
20
- const { version } = loadPackageJson(import.meta.filename, process.env.__VLT_INTERNAL_CLI_PACKAGE_JSON);
21
- class AddImportersDependenciesMapImpl extends Map {
22
- modifiedDependencies = false;
23
- }
24
- class RemoveImportersDependenciesMapImpl extends Map {
25
- modifiedDependencies = false;
26
- }
27
- export const parseInstallOptions = (options, args) => {
28
- const addArgs = new AddImportersDependenciesMapImpl();
29
- for (const [importerId, deps] of Object.entries(args)) {
30
- const depMap = new Map();
31
- for (const [name, { version, type }] of Object.entries(deps)) {
32
- depMap.set(name, asDependency({
33
- spec: Spec.parse(name, version, options),
34
- type,
35
- }));
36
- addArgs.modifiedDependencies = true;
37
- }
38
- addArgs.set(asDepID(importerId), depMap);
39
- }
40
- return [options, addArgs];
41
- };
42
- export const parseUninstallOptions = (options, args) => {
43
- const removeArgs = new RemoveImportersDependenciesMapImpl();
44
- for (const [importerId, deps] of Object.entries(args)) {
45
- const depMap = new Set();
46
- for (const name of deps) {
47
- depMap.add(name);
48
- }
49
- removeArgs.set(asDepID(importerId), depMap);
50
- removeArgs.modifiedDependencies = true;
51
- }
52
- return [options, removeArgs];
53
- };
54
- export const formatDashboardJson = async (projectFolders, dashboardRoot, scurry, packageJson) => {
55
- const userDefinedProjectPaths = (dashboardRoot.length ? dashboardRoot : [homedir()]).map(path => ({
56
- path,
57
- readablePath: getReadablePath(path),
58
- }));
59
- const result = {
60
- cwd: process.cwd(),
61
- buildVersion: version,
62
- dashboardProjectLocations: projectFolders
63
- .map((dir) => {
64
- const path = dirname(dir.fullpath());
65
- const res = {
66
- path,
67
- readablePath: getReadablePath(path),
68
- };
69
- return res;
70
- })
71
- .concat(userDefinedProjectPaths)
72
- .reduce((acc, curr) => {
73
- if (acc.every(obj => obj.path !== curr.path)) {
74
- acc.push(curr);
75
- }
76
- return acc;
77
- }, [])
78
- .sort((a, b) => a.readablePath.length - b.readablePath.length),
79
- defaultAuthor: getAuthorFromGitUser(await getUser().catch(() => undefined)),
80
- projects: [],
81
- };
82
- for (const folder of projectFolders) {
83
- const projectData = getDashboardProjectData(folder, {
84
- scurry,
85
- packageJson,
86
- });
87
- if (projectData) {
88
- result.projects.push(projectData);
89
- }
90
- }
91
- return result;
92
- };
93
- const updateGraphData = (tmp, options, hasDashboard) => {
94
- const { packageJson, projectRoot, scurry } = options;
95
- const mainManifest = packageJson.read(projectRoot);
96
- const graph = actual.load({
97
- ...options,
98
- mainManifest,
99
- loadManifests: true,
100
- });
101
- const importers = [...graph.importers];
102
- const folder = scurry.lstatSync(projectRoot);
103
- const graphJson = JSON.stringify({
104
- hasDashboard,
105
- importers,
106
- lockfile: graph,
107
- projectInfo: getGraphProjectData({ packageJson, scurry }, folder),
108
- }, null, 2);
109
- rmSync(resolve(tmp, 'graph.json'), { force: true });
110
- writeFileSync(resolve(tmp, 'graph.json'), graphJson);
111
- };
112
- const updateDashboardData = async (tmp, options) => {
113
- const { 'dashboard-root': userDefinedProjectPaths = [], scurry, packageJson, } = options;
114
- const dashboard = await formatDashboardJson(await readProjectFolders({
115
- scurry,
116
- userDefinedProjectPaths,
117
- }), userDefinedProjectPaths, scurry, packageJson);
118
- const dashboardJson = JSON.stringify(dashboard, null, 2);
119
- writeFileSync(resolve(tmp, 'dashboard.json'), dashboardJson);
120
- return dashboard.projects.length > 0;
121
- };
122
- const getDefaultStartingRoute = (options) => {
123
- const { projectRoot, scurry } = options;
124
- const stat = scurry.lstatSync(`${projectRoot}/package.json`);
5
+ import { stdout } from "./output.js";
6
+ export const getDefaultStartingRoute = async (options) => {
7
+ const { queryString = ':root', startingRoute, projectRoot, scurry, } = options;
8
+ if (startingRoute)
9
+ return startingRoute;
10
+ const stat = await scurry.lstat(`${projectRoot}/package.json`);
125
11
  return stat?.isFile() && !stat.isSymbolicLink() ?
126
- `/explore?query=${encodeURIComponent(':root')}`
127
- : '/dashboard';
128
- };
129
- /* c8 ignore start */
130
- const createStaticHandler = ({ assetsDir, publicDir, }) => {
131
- const opts = {
132
- cleanUrls: true,
133
- public: publicDir,
134
- rewrites: [
135
- { source: '/', destination: '/index.html' },
136
- { source: '/error', destination: '/index.html' },
137
- { source: '/explore', destination: '/index.html' },
138
- { source: '/dashboard', destination: '/index.html' },
139
- { source: '/queries', destination: '/index.html' },
140
- { source: '/labels', destination: '/index.html' },
141
- { source: '/new-project', destination: '/index.html' },
142
- ],
143
- };
144
- const errHandler = (err, res) => {
145
- stderr(err);
146
- res.statusCode = 500;
147
- res.end('Internal server error');
148
- };
149
- const staticHandler = (req, res) => handler(req, res, opts).catch((err) => errHandler(err, res));
150
- // It's important for this guard to check to not be destructured
151
- // because `infra/build` will replace the whole thing with `false`
152
- // causing it to be stripped entirely from production builds.
153
- if (process.env.__VLT_INTERNAL_LIVE_RELOAD) {
154
- // Generate a set of routes that should be proxied to the esbuild server
155
- const proxyRoutes = new Set([
156
- // `/esbuild` is an SSE endpoint served by esbuild
157
- 'esbuild',
158
- // Also proxy anything that currently exists in the assets dir
159
- ...readdirSync(assetsDir, {
160
- withFileTypes: true,
161
- recursive: true,
162
- })
163
- .filter(f => f.isFile())
164
- .map(f => relative(assetsDir, resolve(f.parentPath, f.name))),
165
- ].map(p => `/${p}`));
166
- return (req, res) => req.url && proxyRoutes.has(req.url) ?
167
- void req.pipe(request({
168
- hostname: HOST,
169
- port: 7018,
170
- path: req.url,
171
- method: req.method,
172
- headers: req.headers,
173
- }, proxy => {
174
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
175
- res.writeHead(proxy.statusCode, proxy.headers);
176
- proxy.pipe(res, { end: true });
177
- }).on('error', err => {
178
- // If we get an ECONNREFUSED error, fallback to the static handler
179
- // since the esbuild server is not running
180
- if (err instanceof Error &&
181
- 'code' in err &&
182
- err.code === 'ECONNREFUSED') {
183
- // In this case the /esbuild route is expected to fail so the
184
- // EventSource in the browser will be closed
185
- if (req.url === '/esbuild') {
186
- res.statusCode = 404;
187
- return res.end();
188
- }
189
- return staticHandler(req, res);
190
- }
191
- errHandler(err, res);
192
- }), { end: true })
193
- : staticHandler(req, res);
194
- }
195
- return staticHandler;
12
+ `/explore/${LZString.compressToEncodedURIComponent(queryString)}/overview`
13
+ : '/';
196
14
  };
197
- /* c8 ignore start */
198
15
  const getAssetsDir = () => {
199
- const fromEnv = process.env.__VLT_INTERNAL_GUI_ASSETS_DIR;
200
- // workaround for the import.meta.resolve issue not working with tap
201
- if (process.env.TAP) {
202
- assert(fromEnv, 'assets dir must be set from environment variable when running tests');
203
- }
204
- if (fromEnv) {
205
- return resolve(import.meta.dirname, fromEnv);
206
- }
207
- return fileURLToPath(import.meta.resolve('@vltpkg/gui'));
208
- };
209
- /* c8 ignore stop */
210
- export const startGUI = async ({ conf, assetsDir = getAssetsDir(), port = PORT, startingRoute = undefined, tmpDir = tmpdir(), }) => {
211
- const tmp = resolve(tmpDir, 'vltgui');
212
- rmSync(tmp, { recursive: true, force: true });
213
- mkdirSync(tmp, { recursive: true });
214
- // This is the same as `cpSync(assetsDir, tmp, { recursive: true })`
215
- // but that does not work in Deno yet (https://github.com/denoland/deno/issues/27494).
216
- for (const asset of readdirSync(assetsDir, {
217
- withFileTypes: true,
218
- recursive: true,
219
- })) {
220
- if (!asset.isFile())
221
- continue;
222
- const source = resolve(asset.parentPath, asset.name);
223
- const target = resolve(tmp, relative(assetsDir, source));
224
- mkdirSync(dirname(target), { recursive: true });
225
- writeFileSync(target, readFileSync(source));
226
- }
227
- // dashboard data is optional since the GUI might be started from a
228
- // project in order to just explore its graph data
229
- let hasDashboard = false;
230
- const { scurry, 'dashboard-root': dashboardRoot, packageJson, } = conf.options;
231
- const updateDashboard = async () => {
232
- try {
233
- hasDashboard = await updateDashboardData(tmp, {
234
- scurry,
235
- 'dashboard-root': dashboardRoot,
236
- packageJson,
237
- });
238
- /* c8 ignore next */
239
- }
240
- catch { }
241
- if (!hasDashboard) {
242
- rmSync(resolve(tmp, 'dashboard.json'), { force: true });
243
- }
244
- };
245
- await updateDashboard();
246
- // reading graph data is optional since the command might be run from a
247
- // parend directory of any given project root, in which case the GUI is
248
- // going to render only the dashboard to start with
249
- try {
250
- updateGraphData(tmp, conf.options, hasDashboard);
251
- }
252
- catch {
253
- rmSync(resolve(tmp, 'graph.json'), { force: true });
254
- }
255
- const staticHandler = createStaticHandler({
256
- publicDir: tmp,
257
- assetsDir,
258
- });
259
- const server = createServer(async (req, res) => {
260
- const json = () => new Promise(resolve => {
261
- req.setEncoding('utf8');
262
- let json = '';
263
- req.on('data', (d) => (json += d));
264
- req.on('end', () => resolve(JSON.parse(json)));
265
- });
266
- const jsonError = (errType, err, code) => {
267
- stderr(err);
268
- res.statusCode = code;
269
- res.end(JSON.stringify(`${errType}\n${err}`));
270
- };
271
- const jsonOk = (result) => {
272
- res.writeHead(200, { 'Content-Type': 'application/json' });
273
- res.end(JSON.stringify(result));
274
- };
275
- switch (`${req.method} ${req.url}`) {
276
- case 'POST /select-project': {
277
- const data = await json();
278
- conf.resetOptions(String(data.path));
279
- await updateDashboard();
280
- updateGraphData(tmp, conf.options, hasDashboard);
281
- return jsonOk('ok');
282
- }
283
- case 'POST /create-project': {
284
- const data = await json();
285
- if (typeof data.path !== 'string') {
286
- return jsonError('Bad request.', 'Project path must be a string', 400);
287
- }
288
- if (!/^[a-z0-9-]+$/.test(String(data.name)) ||
289
- String(data.name).length > 128) {
290
- return jsonError('Bad request.', 'Project name must be lowercase, alphanumeric, and may contain hyphens', 400);
291
- }
292
- const path = String(data.path);
293
- const name = String(data.name);
294
- const author = String(data.author);
295
- try {
296
- const cwd = resolve(path, name);
297
- mkdirSync(cwd, { recursive: true });
298
- await init({ cwd, author });
299
- conf.resetOptions(cwd);
300
- await install(conf.options);
301
- conf.resetOptions(conf.options.projectRoot);
302
- await updateDashboard();
303
- updateGraphData(tmp, conf.options, hasDashboard);
304
- }
305
- catch (err) {
306
- // eslint-disable-next-line no-console
307
- console.error(err);
308
- return jsonError('CLI Error', err.message, 500);
309
- }
310
- return jsonOk('ok');
311
- }
312
- case `POST /install`: {
313
- const { add } = await json();
314
- if (!add) {
315
- return jsonError('Bad request.', 'GUI install endpoint called without add argument', 400);
316
- }
317
- try {
318
- await install(...parseInstallOptions(conf.options, add));
319
- conf.resetOptions(conf.options.projectRoot);
320
- updateGraphData(tmp, conf.options, hasDashboard);
321
- return jsonOk('ok');
322
- }
323
- catch (err) {
324
- return jsonError('Install failed', err, 500);
325
- }
326
- }
327
- case `POST /uninstall`: {
328
- const { remove } = await json();
329
- if (!remove) {
330
- return jsonError('Bad request.', 'GUI uninstall endpoint called with no arguments', 400);
331
- }
332
- try {
333
- await uninstall(...parseUninstallOptions(conf.options, remove));
334
- conf.resetOptions(conf.options.projectRoot);
335
- updateGraphData(tmp, conf.options, hasDashboard);
336
- return jsonOk('ok');
337
- }
338
- catch (err) {
339
- return jsonError('Uninstall failed', err, 500);
340
- }
341
- }
342
- /* c8 ignore next 3 */
343
- default: {
344
- return staticHandler(req, res);
345
- }
346
- }
16
+ /* c8 ignore start */
17
+ if (process.env.__VLT_INTERNAL_GUI_ASSETS_DIR) {
18
+ return resolve(import.meta.dirname, process.env.__VLT_INTERNAL_GUI_ASSETS_DIR);
19
+ }
20
+ /* c8 ignore stop */
21
+ };
22
+ export const startGUI = async (conf, startingRoute) => {
23
+ /* c8 ignore start */
24
+ const allowScripts = conf.get('allow-scripts') ?
25
+ String(conf.get('allow-scripts'))
26
+ : ':not(*)';
27
+ /* c8 ignore stop */
28
+ const server = createServer({
29
+ ...conf.options,
30
+ assetsDir: getAssetsDir(),
31
+ loadedConfig: conf,
32
+ allowScripts,
347
33
  });
348
- return new Promise(res => {
349
- const route = startingRoute || getDefaultStartingRoute(conf.options);
350
- server.listen(port, 'localhost', () => {
351
- stdout(`⚡️ vlt GUI running at http://${HOST}:${port}`);
352
- void urlOpen(`http://${HOST}:${port}${route}`);
353
- res(server);
354
- });
34
+ server.on('needConfigUpdate', async (dir) => {
35
+ conf.resetOptions(dir);
36
+ const listeningServer = server;
37
+ listeningServer.updateOptions({ ...conf.options, allowScripts });
38
+ await conf
39
+ .reloadFromDisk()
40
+ .then(() => {
41
+ listeningServer.updateOptions({
42
+ ...conf.options,
43
+ allowScripts,
44
+ });
45
+ })
46
+ .catch(() => { });
355
47
  });
48
+ const { projectRoot, scurry } = conf.options;
49
+ await server.start();
50
+ stdout(`⚡️ vlt UI running at ${server.address()}`);
51
+ void urlOpen(server.address(await getDefaultStartingRoute({
52
+ queryString: conf.values.target,
53
+ startingRoute,
54
+ projectRoot,
55
+ scurry,
56
+ })));
57
+ return server;
356
58
  };
357
59
  //# sourceMappingURL=start-gui.js.map