@vltpkg/cli-sdk 1.0.0-rc.3 → 1.0.0-rc.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/access.d.ts +22 -0
- package/dist/commands/access.js +246 -0
- package/dist/commands/bugs.d.ts +17 -0
- package/dist/commands/bugs.js +163 -0
- package/dist/{esm/commands → commands}/build.d.ts +0 -1
- package/dist/{esm/commands → commands}/build.js +0 -1
- package/dist/{esm/commands → commands}/cache.d.ts +0 -1
- package/dist/{esm/commands → commands}/cache.js +0 -1
- package/dist/{esm/commands → commands}/ci.d.ts +0 -1
- package/dist/{esm/commands → commands}/ci.js +11 -3
- package/dist/{esm/commands → commands}/config.d.ts +0 -1
- package/dist/{esm/commands → commands}/config.js +6 -1
- package/dist/commands/create.d.ts +8 -0
- package/dist/commands/create.js +102 -0
- package/dist/commands/deprecate.d.ts +13 -0
- package/dist/commands/deprecate.js +139 -0
- package/dist/commands/dist-tag.d.ts +21 -0
- package/dist/commands/dist-tag.js +177 -0
- package/dist/{esm/commands → commands}/docs.d.ts +0 -1
- package/dist/{esm/commands → commands}/docs.js +2 -3
- package/dist/{esm/commands → commands}/exec-cache.d.ts +0 -1
- package/dist/{esm/commands → commands}/exec-cache.js +0 -1
- package/dist/{esm/commands → commands}/exec-local.d.ts +0 -1
- package/dist/{esm/commands → commands}/exec-local.js +23 -1
- package/dist/{esm/commands → commands}/exec.d.ts +0 -1
- package/dist/{esm/commands → commands}/exec.js +84 -10
- package/dist/{esm/commands → commands}/help.d.ts +0 -1
- package/dist/{esm/commands → commands}/help.js +5 -1
- package/dist/{esm/commands → commands}/init.d.ts +0 -1
- package/dist/{esm/commands → commands}/init.js +31 -10
- package/dist/{esm/commands → commands}/install/reporter.d.ts +0 -1
- package/dist/{esm/commands → commands}/install/reporter.js +0 -1
- package/dist/{esm/commands → commands}/install.d.ts +21 -3
- package/dist/commands/install.js +140 -0
- package/dist/{esm/commands → commands}/list.d.ts +4 -2
- package/dist/{esm/commands → commands}/list.js +8 -10
- package/dist/{esm/commands → commands}/login.d.ts +0 -1
- package/dist/{esm/commands → commands}/login.js +10 -1
- package/dist/{esm/commands/token.d.ts → commands/logout.d.ts} +0 -1
- package/dist/{esm/commands → commands}/logout.js +10 -1
- package/dist/{esm/commands → commands}/pack.d.ts +0 -1
- package/dist/{esm/commands → commands}/pack.js +90 -32
- package/dist/commands/ping.d.ts +17 -0
- package/dist/commands/ping.js +114 -0
- package/dist/{esm/commands → commands}/pkg.d.ts +0 -1
- package/dist/{esm/commands → commands}/pkg.js +27 -1
- package/dist/commands/profile.d.ts +13 -0
- package/dist/commands/profile.js +104 -0
- package/dist/{esm/commands → commands}/publish.d.ts +1 -2
- package/dist/{esm/commands → commands}/publish.js +63 -12
- package/dist/{esm/commands → commands}/query.d.ts +4 -2
- package/dist/{esm/commands → commands}/query.js +12 -10
- package/dist/commands/repo.d.ts +17 -0
- package/dist/commands/repo.js +157 -0
- package/dist/{esm/commands → commands}/run-exec.d.ts +0 -1
- package/dist/commands/run-exec.js +40 -0
- package/dist/{esm/commands → commands}/run.d.ts +0 -1
- package/dist/{esm/commands → commands}/run.js +27 -1
- package/dist/commands/token.d.ts +31 -0
- package/dist/commands/token.js +186 -0
- package/dist/{esm/commands → commands}/uninstall.d.ts +0 -1
- package/dist/{esm/commands → commands}/uninstall.js +16 -3
- package/dist/commands/unpublish.d.ts +15 -0
- package/dist/commands/unpublish.js +200 -0
- package/dist/{esm/commands → commands}/update.d.ts +0 -1
- package/dist/{esm/commands → commands}/update.js +6 -1
- package/dist/{esm/commands → commands}/version.d.ts +0 -1
- package/dist/{esm/commands → commands}/version.js +27 -1
- package/dist/commands/view.d.ts +22 -0
- package/dist/commands/view.js +334 -0
- package/dist/{esm/commands → commands}/whoami.d.ts +0 -1
- package/dist/{esm/commands → commands}/whoami.js +10 -1
- package/dist/{esm/config → config}/definition.d.ts +39 -19
- package/dist/{esm/config → config}/definition.js +74 -39
- package/dist/{esm/config → config}/index.d.ts +0 -1
- package/dist/{esm/config → config}/index.js +37 -2
- package/dist/{esm/config → config}/merge.d.ts +0 -1
- package/dist/{esm/config → config}/merge.js +0 -1
- package/dist/{esm/config → config}/usage.d.ts +0 -1
- package/dist/{esm/config → config}/usage.js +0 -1
- package/dist/{esm/custom-help.d.ts → custom-help.d.ts} +0 -1
- package/dist/{esm/custom-help.js → custom-help.js} +35 -9
- package/dist/{esm/exec-command.d.ts → exec-command.d.ts} +0 -1
- package/dist/{esm/exec-command.js → exec-command.js} +14 -8
- package/dist/{esm/index.d.ts → index.d.ts} +0 -1
- package/dist/{esm/index.js → index.js} +1 -2
- package/dist/{esm/load-command.d.ts → load-command.d.ts} +0 -1
- package/dist/{esm/load-command.js → load-command.js} +0 -1
- package/dist/mermaid-image-view.d.ts +18 -0
- package/dist/mermaid-image-view.js +36 -0
- package/dist/{esm/output.d.ts → output.d.ts} +2 -2
- package/dist/{esm/output.js → output.js} +55 -2
- package/dist/{esm/pack-tarball.d.ts → pack-tarball.d.ts} +15 -1
- package/dist/{esm/pack-tarball.js → pack-tarball.js} +133 -91
- package/dist/{esm/parse-add-remove-args.d.ts → parse-add-remove-args.d.ts} +9 -3
- package/dist/{esm/parse-add-remove-args.js → parse-add-remove-args.js} +43 -11
- package/dist/{esm/print-err.d.ts → print-err.d.ts} +0 -1
- package/dist/{esm/print-err.js → print-err.js} +18 -3
- package/dist/query-diff-files.d.ts +17 -0
- package/dist/query-diff-files.js +63 -0
- package/dist/{esm/query-host-contexts.d.ts → query-host-contexts.d.ts} +0 -1
- package/dist/{esm/query-host-contexts.js → query-host-contexts.js} +8 -7
- package/dist/{esm/read-password.d.ts → read-password.d.ts} +0 -1
- package/dist/{esm/read-password.js → read-password.js} +0 -1
- package/dist/read-project-folders.d.ts +17 -0
- package/dist/read-project-folders.js +100 -0
- package/dist/reload-config.d.ts +2 -0
- package/dist/reload-config.js +11 -0
- package/dist/render-mermaid.d.ts +22 -0
- package/dist/render-mermaid.js +68 -0
- package/dist/telemetry.d.ts +58 -0
- package/dist/telemetry.js +170 -0
- package/dist/{esm/view.d.ts → view.d.ts} +0 -1
- package/dist/{esm/view.js → view.js} +1 -2
- package/package.json +69 -83
- package/dist/esm/commands/build.d.ts.map +0 -1
- package/dist/esm/commands/build.js.map +0 -1
- package/dist/esm/commands/cache.d.ts.map +0 -1
- package/dist/esm/commands/cache.js.map +0 -1
- package/dist/esm/commands/ci.d.ts.map +0 -1
- package/dist/esm/commands/ci.js.map +0 -1
- package/dist/esm/commands/config.d.ts.map +0 -1
- package/dist/esm/commands/config.js.map +0 -1
- package/dist/esm/commands/docs.d.ts.map +0 -1
- package/dist/esm/commands/docs.js.map +0 -1
- package/dist/esm/commands/exec-cache.d.ts.map +0 -1
- package/dist/esm/commands/exec-cache.js.map +0 -1
- package/dist/esm/commands/exec-local.d.ts.map +0 -1
- package/dist/esm/commands/exec-local.js.map +0 -1
- package/dist/esm/commands/exec.d.ts.map +0 -1
- package/dist/esm/commands/exec.js.map +0 -1
- package/dist/esm/commands/help.d.ts.map +0 -1
- package/dist/esm/commands/help.js.map +0 -1
- package/dist/esm/commands/init.d.ts.map +0 -1
- package/dist/esm/commands/init.js.map +0 -1
- package/dist/esm/commands/install/reporter.d.ts.map +0 -1
- package/dist/esm/commands/install/reporter.js.map +0 -1
- package/dist/esm/commands/install.d.ts.map +0 -1
- package/dist/esm/commands/install.js +0 -45
- package/dist/esm/commands/install.js.map +0 -1
- package/dist/esm/commands/list.d.ts.map +0 -1
- package/dist/esm/commands/list.js.map +0 -1
- package/dist/esm/commands/login.d.ts.map +0 -1
- package/dist/esm/commands/login.js.map +0 -1
- package/dist/esm/commands/logout.d.ts +0 -4
- package/dist/esm/commands/logout.d.ts.map +0 -1
- package/dist/esm/commands/logout.js.map +0 -1
- package/dist/esm/commands/pack.d.ts.map +0 -1
- package/dist/esm/commands/pack.js.map +0 -1
- package/dist/esm/commands/pkg.d.ts.map +0 -1
- package/dist/esm/commands/pkg.js.map +0 -1
- package/dist/esm/commands/publish.d.ts.map +0 -1
- package/dist/esm/commands/publish.js.map +0 -1
- package/dist/esm/commands/query.d.ts.map +0 -1
- package/dist/esm/commands/query.js.map +0 -1
- package/dist/esm/commands/run-exec.d.ts.map +0 -1
- package/dist/esm/commands/run-exec.js +0 -14
- package/dist/esm/commands/run-exec.js.map +0 -1
- package/dist/esm/commands/run.d.ts.map +0 -1
- package/dist/esm/commands/run.js.map +0 -1
- package/dist/esm/commands/serve.d.ts +0 -14
- package/dist/esm/commands/serve.d.ts.map +0 -1
- package/dist/esm/commands/serve.js +0 -103
- package/dist/esm/commands/serve.js.map +0 -1
- package/dist/esm/commands/token.d.ts.map +0 -1
- package/dist/esm/commands/token.js +0 -30
- package/dist/esm/commands/token.js.map +0 -1
- package/dist/esm/commands/uninstall.d.ts.map +0 -1
- package/dist/esm/commands/uninstall.js.map +0 -1
- package/dist/esm/commands/update.d.ts.map +0 -1
- package/dist/esm/commands/update.js.map +0 -1
- package/dist/esm/commands/version.d.ts.map +0 -1
- package/dist/esm/commands/version.js.map +0 -1
- package/dist/esm/commands/whoami.d.ts.map +0 -1
- package/dist/esm/commands/whoami.js.map +0 -1
- package/dist/esm/config/definition.d.ts.map +0 -1
- package/dist/esm/config/definition.js.map +0 -1
- package/dist/esm/config/index.d.ts.map +0 -1
- package/dist/esm/config/index.js.map +0 -1
- package/dist/esm/config/merge.d.ts.map +0 -1
- package/dist/esm/config/merge.js.map +0 -1
- package/dist/esm/config/usage.d.ts.map +0 -1
- package/dist/esm/config/usage.js.map +0 -1
- package/dist/esm/custom-help.d.ts.map +0 -1
- package/dist/esm/custom-help.js.map +0 -1
- package/dist/esm/exec-command.d.ts.map +0 -1
- package/dist/esm/exec-command.js.map +0 -1
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/load-command.d.ts.map +0 -1
- package/dist/esm/load-command.js.map +0 -1
- package/dist/esm/output.d.ts.map +0 -1
- package/dist/esm/output.js.map +0 -1
- package/dist/esm/pack-tarball.d.ts.map +0 -1
- package/dist/esm/pack-tarball.js.map +0 -1
- package/dist/esm/package.json +0 -3
- package/dist/esm/parse-add-remove-args.d.ts.map +0 -1
- package/dist/esm/parse-add-remove-args.js.map +0 -1
- package/dist/esm/print-err.d.ts.map +0 -1
- package/dist/esm/print-err.js.map +0 -1
- package/dist/esm/query-host-contexts.d.ts.map +0 -1
- package/dist/esm/query-host-contexts.js.map +0 -1
- package/dist/esm/read-password.d.ts.map +0 -1
- package/dist/esm/read-password.js.map +0 -1
- package/dist/esm/start-gui.d.ts +0 -10
- package/dist/esm/start-gui.d.ts.map +0 -1
- package/dist/esm/start-gui.js +0 -60
- package/dist/esm/start-gui.js.map +0 -1
- package/dist/esm/view.d.ts.map +0 -1
- package/dist/esm/view.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { parse, posix } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { readProjectFolders } from "./read-project-folders.js";
|
|
4
|
+
import { reloadConfig } from "./reload-config.js";
|
|
4
5
|
import { actual, createVirtualRoot } from '@vltpkg/graph';
|
|
5
6
|
import { SecurityArchive } from '@vltpkg/security-archive';
|
|
6
7
|
import { error } from '@vltpkg/error-cause';
|
|
@@ -13,6 +14,11 @@ try {
|
|
|
13
14
|
}
|
|
14
15
|
catch { }
|
|
15
16
|
const home = foundHome ?? posix.dirname(posix.format(parse(process.cwd())));
|
|
17
|
+
const isVltInstalled = (folder) => !!folder.resolve('node_modules/.vlt').lstatSync()?.isDirectory() ||
|
|
18
|
+
!!folder
|
|
19
|
+
.resolve('node_modules/.vlt-lock.json')
|
|
20
|
+
.lstatSync()
|
|
21
|
+
?.isFile();
|
|
16
22
|
/**
|
|
17
23
|
* Generates possible project keys for a given folder.
|
|
18
24
|
*/
|
|
@@ -89,12 +95,8 @@ export const createHostContextsMap = async (conf) => {
|
|
|
89
95
|
for (const folder of projectFolders) {
|
|
90
96
|
try {
|
|
91
97
|
const config = await reloadConfig(folder.fullpath());
|
|
92
|
-
const projectInfo = getProjectData({
|
|
93
|
-
packageJson: config.options.packageJson,
|
|
94
|
-
scurry: config.options.scurry,
|
|
95
|
-
}, folder);
|
|
96
98
|
// only include projects that are vlt-installed
|
|
97
|
-
if (!
|
|
99
|
+
if (!isVltInstalled(folder)) {
|
|
98
100
|
continue;
|
|
99
101
|
}
|
|
100
102
|
// load each individual graph
|
|
@@ -132,4 +134,3 @@ export const createHostContextsMap = async (conf) => {
|
|
|
132
134
|
});
|
|
133
135
|
return hostContexts;
|
|
134
136
|
};
|
|
135
|
-
//# sourceMappingURL=query-host-contexts.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PathBase, PathScurry } from 'path-scurry';
|
|
2
|
+
type ProjectFolderOptions = {
|
|
3
|
+
path?: string;
|
|
4
|
+
scurry: PathScurry;
|
|
5
|
+
userDefinedProjectPaths: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Retrieves folders from a given directory, if that directory is
|
|
9
|
+
* recognized to be the current cli project root folder then we
|
|
10
|
+
* proceed to read its siblings.
|
|
11
|
+
*
|
|
12
|
+
* Traverses nested directory recursively until project folders can
|
|
13
|
+
* be find, always stopping at the first level where a package.json
|
|
14
|
+
* is present.
|
|
15
|
+
*/
|
|
16
|
+
export declare const readProjectFolders: ({ path, scurry, userDefinedProjectPaths, }: ProjectFolderOptions, maxDepth?: number) => Promise<PathBase[]>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { availableParallelism, homedir } from 'node:os';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { callLimit } from 'promise-call-limit';
|
|
4
|
+
const limit = Math.max(availableParallelism() - 1, 1) * 8;
|
|
5
|
+
let home;
|
|
6
|
+
try {
|
|
7
|
+
home = homedir();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
home = dirname(process.cwd());
|
|
11
|
+
}
|
|
12
|
+
const ignoredHomedirFolderNames = [
|
|
13
|
+
'downloads',
|
|
14
|
+
'movies',
|
|
15
|
+
'music',
|
|
16
|
+
'pictures',
|
|
17
|
+
'private',
|
|
18
|
+
'library',
|
|
19
|
+
'dropbox',
|
|
20
|
+
].concat(process.platform === 'darwin' ?
|
|
21
|
+
[
|
|
22
|
+
'public',
|
|
23
|
+
'private',
|
|
24
|
+
'applications',
|
|
25
|
+
'applications (parallels)',
|
|
26
|
+
'sites',
|
|
27
|
+
'sync',
|
|
28
|
+
]
|
|
29
|
+
: process.platform === 'win32' ?
|
|
30
|
+
[
|
|
31
|
+
'appdata',
|
|
32
|
+
'application data',
|
|
33
|
+
'favorites',
|
|
34
|
+
'links',
|
|
35
|
+
'videos',
|
|
36
|
+
'contacts',
|
|
37
|
+
'searches',
|
|
38
|
+
]
|
|
39
|
+
: ['videos', 'public']);
|
|
40
|
+
/**
|
|
41
|
+
* Retrieves folders from a given directory, if that directory is
|
|
42
|
+
* recognized to be the current cli project root folder then we
|
|
43
|
+
* proceed to read its siblings.
|
|
44
|
+
*
|
|
45
|
+
* Traverses nested directory recursively until project folders can
|
|
46
|
+
* be find, always stopping at the first level where a package.json
|
|
47
|
+
* is present.
|
|
48
|
+
*/
|
|
49
|
+
export const readProjectFolders = async ({ path = home, scurry, userDefinedProjectPaths, }, maxDepth = 7) => {
|
|
50
|
+
const result = [];
|
|
51
|
+
const homeEntry = scurry.cwd.resolve(home);
|
|
52
|
+
const paths = userDefinedProjectPaths.length ? userDefinedProjectPaths : [path];
|
|
53
|
+
const step = (entry, depth) => async () => {
|
|
54
|
+
try {
|
|
55
|
+
for (const child of await entry.readdir()) {
|
|
56
|
+
if (await collectResult(child, result, scurry, entry === homeEntry, depth, maxDepth)) {
|
|
57
|
+
traverse.push(step(child, depth + 1));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/* c8 ignore next 4 */
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Ignore directories that can't be read.
|
|
64
|
+
// This commonly happens in restricted environments.
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
let traverse = (await Promise.all(paths.map(path => scurry.lstat(path))))
|
|
68
|
+
.filter(p => !!p)
|
|
69
|
+
.map(p => step(p, 0));
|
|
70
|
+
// have to do it in phases this way because pushing into the queue
|
|
71
|
+
// during the promise-call-limit confuses its tracking.
|
|
72
|
+
let t;
|
|
73
|
+
do {
|
|
74
|
+
t = traverse;
|
|
75
|
+
traverse = [];
|
|
76
|
+
await callLimit(t, { limit });
|
|
77
|
+
} while (traverse.length);
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
const collectResult = async (entry, result, scurry, fromHome, depth, maxDepth) => {
|
|
81
|
+
if (!entry.isDirectory() ||
|
|
82
|
+
entry.isSymbolicLink() ||
|
|
83
|
+
entry.name === 'node_modules' ||
|
|
84
|
+
(fromHome &&
|
|
85
|
+
ignoredHomedirFolderNames.includes(entry.name.toLowerCase())) ||
|
|
86
|
+
entry.name.startsWith('.') ||
|
|
87
|
+
depth > maxDepth) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
const resolved = entry.fullpath();
|
|
91
|
+
const statPackageJson = await scurry
|
|
92
|
+
.lstat(`${resolved}/package.json`)
|
|
93
|
+
.catch(() => { });
|
|
94
|
+
const hasValidPackageJson = statPackageJson &&
|
|
95
|
+
statPackageJson.isFile() &&
|
|
96
|
+
!statPackageJson.isSymbolicLink();
|
|
97
|
+
if (hasValidPackageJson)
|
|
98
|
+
result.push(entry);
|
|
99
|
+
return !hasValidPackageJson;
|
|
100
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const reloadConfig = async (folder) => {
|
|
2
|
+
try {
|
|
3
|
+
const { unload } = (await import('@vltpkg/vlt-json'));
|
|
4
|
+
unload('user');
|
|
5
|
+
unload('project');
|
|
6
|
+
/* c8 ignore next */
|
|
7
|
+
}
|
|
8
|
+
catch { }
|
|
9
|
+
const { Config } = await import("./config/index.js");
|
|
10
|
+
return Config.load(folder, process.argv, true);
|
|
11
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type OutputFormat = 'svg' | 'png';
|
|
2
|
+
/**
|
|
3
|
+
* Renders mermaid diagram text to an SVG string using
|
|
4
|
+
* the `beautiful-mermaid` library. No external process
|
|
5
|
+
* is spawned — everything runs in-process.
|
|
6
|
+
* @returns {string} The SVG markup as a string.
|
|
7
|
+
*/
|
|
8
|
+
export declare const renderMermaidSvg: (mermaidText: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Renders mermaid diagram text to an SVG file.
|
|
11
|
+
* Uses `beautiful-mermaid` in-process, then writes
|
|
12
|
+
* the result to a temp directory.
|
|
13
|
+
* @returns {Promise<string>} The file path of the generated SVG.
|
|
14
|
+
*/
|
|
15
|
+
export declare const renderMermaidToFile: (mermaidText: string) => Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Renders mermaid diagram text to a PNG file.
|
|
18
|
+
* Uses `beautiful-mermaid` for SVG, then `@resvg/resvg-wasm`
|
|
19
|
+
* to convert SVG to PNG. Writes to a temp directory.
|
|
20
|
+
* @returns {Promise<string>} The file path of the generated PNG.
|
|
21
|
+
*/
|
|
22
|
+
export declare const renderMermaidToPng: (mermaidText: string) => Promise<string>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { writeFile, mkdtemp } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { error } from '@vltpkg/error-cause';
|
|
5
|
+
import { renderMermaidSVG } from 'beautiful-mermaid';
|
|
6
|
+
/**
|
|
7
|
+
* Replace `#64;` with `@` for display rendering.
|
|
8
|
+
* Mermaid text uses `#64;` to avoid issues with `@` in
|
|
9
|
+
* GitHub/markdown parsers, but SVG/PNG should show `@`.
|
|
10
|
+
*/
|
|
11
|
+
const decodeForDisplay = (mermaidText) => mermaidText.replace(/#64;/g, '@');
|
|
12
|
+
/**
|
|
13
|
+
* Renders mermaid diagram text to an SVG string using
|
|
14
|
+
* the `beautiful-mermaid` library. No external process
|
|
15
|
+
* is spawned — everything runs in-process.
|
|
16
|
+
* @returns {string} The SVG markup as a string.
|
|
17
|
+
*/
|
|
18
|
+
export const renderMermaidSvg = (mermaidText) => {
|
|
19
|
+
try {
|
|
20
|
+
return renderMermaidSVG(decodeForDisplay(mermaidText), {
|
|
21
|
+
bg: '#FFFFFF',
|
|
22
|
+
fg: '#27272A',
|
|
23
|
+
padding: 40,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (cause) {
|
|
27
|
+
throw error('Error rendering SVG', { cause });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Renders mermaid diagram text to an SVG file.
|
|
32
|
+
* Uses `beautiful-mermaid` in-process, then writes
|
|
33
|
+
* the result to a temp directory.
|
|
34
|
+
* @returns {Promise<string>} The file path of the generated SVG.
|
|
35
|
+
*/
|
|
36
|
+
export const renderMermaidToFile = async (mermaidText) => {
|
|
37
|
+
const svg = renderMermaidSvg(mermaidText);
|
|
38
|
+
const dir = await mkdtemp(join(tmpdir(), 'vlt-mermaid-'));
|
|
39
|
+
const outputFile = join(dir, 'graph.svg');
|
|
40
|
+
await writeFile(outputFile, svg);
|
|
41
|
+
return outputFile;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Renders mermaid diagram text to a PNG file.
|
|
45
|
+
* Uses `beautiful-mermaid` for SVG, then `@resvg/resvg-wasm`
|
|
46
|
+
* to convert SVG to PNG. Writes to a temp directory.
|
|
47
|
+
* @returns {Promise<string>} The file path of the generated PNG.
|
|
48
|
+
*/
|
|
49
|
+
export const renderMermaidToPng = async (mermaidText) => {
|
|
50
|
+
const svg = renderMermaidSvg(mermaidText);
|
|
51
|
+
const { Resvg, initWasm } = await import('@resvg/resvg-wasm');
|
|
52
|
+
const { readFile: rf } = await import('node:fs/promises');
|
|
53
|
+
const { createRequire: cr } = await import('node:module');
|
|
54
|
+
const wasmPath = cr(import.meta.url).resolve('@resvg/resvg-wasm/index_bg.wasm');
|
|
55
|
+
try {
|
|
56
|
+
await initWasm(await rf(wasmPath));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// WASM may already be initialized — ignore
|
|
60
|
+
}
|
|
61
|
+
const resvg = new Resvg(svg);
|
|
62
|
+
const pngData = resvg.render();
|
|
63
|
+
const pngBuffer = pngData.asPng();
|
|
64
|
+
const dir = await mkdtemp(join(tmpdir(), 'vlt-mermaid-'));
|
|
65
|
+
const outputFile = join(dir, 'graph.png');
|
|
66
|
+
await writeFile(outputFile, pngBuffer);
|
|
67
|
+
return outputFile;
|
|
68
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anonymized telemetry for the vlt CLI.
|
|
3
|
+
*
|
|
4
|
+
* - Sends anonymous, non-PII events to PostHog.
|
|
5
|
+
* - Generates a random UUID on first run, stored in XDG data dir.
|
|
6
|
+
* - Respects opt-out via `DO_NOT_TRACK=1`, `VLT_TELEMETRY=0`,
|
|
7
|
+
* or the `--telemetry=false` config flag.
|
|
8
|
+
* - Flush is awaited with a timeout cap so it never blocks CLI exit for long.
|
|
9
|
+
* - Fails silently on any network or runtime error.
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Check whether telemetry is disabled via environment variables.
|
|
14
|
+
*
|
|
15
|
+
* - `DO_NOT_TRACK=1` — https://consoledonottrack.com/
|
|
16
|
+
* - `VLT_TELEMETRY=0`
|
|
17
|
+
*/
|
|
18
|
+
export declare const isOptedOut: () => boolean;
|
|
19
|
+
export interface CommandEvent {
|
|
20
|
+
command: string;
|
|
21
|
+
duration_ms: number;
|
|
22
|
+
success: boolean;
|
|
23
|
+
node_version: string;
|
|
24
|
+
vlt_version: string;
|
|
25
|
+
os: string;
|
|
26
|
+
arch: string;
|
|
27
|
+
ci: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface InstallEvent {
|
|
30
|
+
dependency_count: number;
|
|
31
|
+
duration_ms: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ErrorEvent {
|
|
34
|
+
command: string;
|
|
35
|
+
error_code?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Capture a `cli_command` event.
|
|
39
|
+
*/
|
|
40
|
+
export declare const trackCommand: (ev: CommandEvent, telemetryFlag?: boolean) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Capture a `cli_install` event.
|
|
43
|
+
*/
|
|
44
|
+
export declare const trackInstall: (ev: InstallEvent, telemetryFlag?: boolean) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Capture a `cli_error` event.
|
|
47
|
+
*/
|
|
48
|
+
export declare const trackError: (ev: ErrorEvent, telemetryFlag?: boolean) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Flush pending events. Returns a promise that resolves once flushing
|
|
51
|
+
* completes **or** when `SHUTDOWN_TIMEOUT_MS` elapses — whichever
|
|
52
|
+
* comes first. Never rejects.
|
|
53
|
+
*
|
|
54
|
+
* The safety-net timer is unreffed so it cannot keep the process alive
|
|
55
|
+
* on its own — if the caller does not `await` this, Node will still
|
|
56
|
+
* exit promptly once all other handles are drained.
|
|
57
|
+
*/
|
|
58
|
+
export declare const flush: () => Promise<void>;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anonymized telemetry for the vlt CLI.
|
|
3
|
+
*
|
|
4
|
+
* - Sends anonymous, non-PII events to PostHog.
|
|
5
|
+
* - Generates a random UUID on first run, stored in XDG data dir.
|
|
6
|
+
* - Respects opt-out via `DO_NOT_TRACK=1`, `VLT_TELEMETRY=0`,
|
|
7
|
+
* or the `--telemetry=false` config flag.
|
|
8
|
+
* - Flush is awaited with a timeout cap so it never blocks CLI exit for long.
|
|
9
|
+
* - Fails silently on any network or runtime error.
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { randomUUID } from 'node:crypto';
|
|
13
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
import { XDG } from '@vltpkg/xdg';
|
|
16
|
+
const POSTHOG_API_KEY = 'phc_k9xCAgC6sPIBLb5UhjhnGWpt1mos0hLV4mmEhZTGPpO';
|
|
17
|
+
const POSTHOG_HOST = 'https://us.i.posthog.com';
|
|
18
|
+
/** Timeout (ms) we wait for PostHog to flush before giving up. */
|
|
19
|
+
const SHUTDOWN_TIMEOUT_MS = 2_000;
|
|
20
|
+
const xdg = new XDG('vlt');
|
|
21
|
+
/**
|
|
22
|
+
* Check whether telemetry is disabled via environment variables.
|
|
23
|
+
*
|
|
24
|
+
* - `DO_NOT_TRACK=1` — https://consoledonottrack.com/
|
|
25
|
+
* - `VLT_TELEMETRY=0`
|
|
26
|
+
*/
|
|
27
|
+
export const isOptedOut = () => process.env.DO_NOT_TRACK === '1' ||
|
|
28
|
+
process.env.VLT_TELEMETRY === '0';
|
|
29
|
+
/**
|
|
30
|
+
* Return (or create) a stable anonymous distinct ID.
|
|
31
|
+
* Stored at `<XDG_DATA_HOME>/vlt/telemetry-id`.
|
|
32
|
+
*/
|
|
33
|
+
const getAnonymousId = () => {
|
|
34
|
+
const dir = xdg.data();
|
|
35
|
+
const file = xdg.data('telemetry-id');
|
|
36
|
+
try {
|
|
37
|
+
const existing = readFileSync(file, 'utf8').trim();
|
|
38
|
+
if (existing)
|
|
39
|
+
return existing;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// file doesn't exist yet — create it below
|
|
43
|
+
}
|
|
44
|
+
const id = randomUUID();
|
|
45
|
+
try {
|
|
46
|
+
mkdirSync(dir, { recursive: true });
|
|
47
|
+
writeFileSync(file, id + '\n');
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// best-effort — if we can't persist, just use a transient id
|
|
51
|
+
}
|
|
52
|
+
return id;
|
|
53
|
+
};
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// PostHog client — lazily initialised
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
let _posthog;
|
|
58
|
+
let _initFailed = false;
|
|
59
|
+
const getClient = () => {
|
|
60
|
+
if (_posthog)
|
|
61
|
+
return _posthog;
|
|
62
|
+
if (_initFailed)
|
|
63
|
+
return undefined;
|
|
64
|
+
try {
|
|
65
|
+
// Dynamic import would be async; posthog-node also ships a
|
|
66
|
+
// synchronous constructor, so we use createRequire to keep
|
|
67
|
+
// the hot-path synchronous in this ESM package.
|
|
68
|
+
const req = createRequire(import.meta.url);
|
|
69
|
+
const { PostHog } = req('posthog-node');
|
|
70
|
+
_posthog = new PostHog(POSTHOG_API_KEY, {
|
|
71
|
+
host: POSTHOG_HOST,
|
|
72
|
+
// Buffer up to 20 events and flush every 10 s — but we always
|
|
73
|
+
// call shutdown at the end so this is just a safety net.
|
|
74
|
+
flushAt: 20,
|
|
75
|
+
flushInterval: 10_000,
|
|
76
|
+
});
|
|
77
|
+
return _posthog;
|
|
78
|
+
/* c8 ignore next 4 */
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
_initFailed = true;
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Capture a `cli_command` event.
|
|
87
|
+
*/
|
|
88
|
+
export const trackCommand = (ev, telemetryFlag) => {
|
|
89
|
+
if (telemetryFlag === false || isOptedOut())
|
|
90
|
+
return;
|
|
91
|
+
const ph = getClient();
|
|
92
|
+
if (!ph)
|
|
93
|
+
return;
|
|
94
|
+
try {
|
|
95
|
+
ph.capture({
|
|
96
|
+
distinctId: getAnonymousId(),
|
|
97
|
+
event: 'cli_command',
|
|
98
|
+
properties: { ...ev },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// fail silently
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Capture a `cli_install` event.
|
|
107
|
+
*/
|
|
108
|
+
export const trackInstall = (ev, telemetryFlag) => {
|
|
109
|
+
if (telemetryFlag === false || isOptedOut())
|
|
110
|
+
return;
|
|
111
|
+
const ph = getClient();
|
|
112
|
+
if (!ph)
|
|
113
|
+
return;
|
|
114
|
+
try {
|
|
115
|
+
ph.capture({
|
|
116
|
+
distinctId: getAnonymousId(),
|
|
117
|
+
event: 'cli_install',
|
|
118
|
+
properties: { ...ev },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// fail silently
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Capture a `cli_error` event.
|
|
127
|
+
*/
|
|
128
|
+
export const trackError = (ev, telemetryFlag) => {
|
|
129
|
+
if (telemetryFlag === false || isOptedOut())
|
|
130
|
+
return;
|
|
131
|
+
const ph = getClient();
|
|
132
|
+
if (!ph)
|
|
133
|
+
return;
|
|
134
|
+
try {
|
|
135
|
+
ph.capture({
|
|
136
|
+
distinctId: getAnonymousId(),
|
|
137
|
+
event: 'cli_error',
|
|
138
|
+
properties: { ...ev },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// fail silently
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Flush pending events. Returns a promise that resolves once flushing
|
|
147
|
+
* completes **or** when `SHUTDOWN_TIMEOUT_MS` elapses — whichever
|
|
148
|
+
* comes first. Never rejects.
|
|
149
|
+
*
|
|
150
|
+
* The safety-net timer is unreffed so it cannot keep the process alive
|
|
151
|
+
* on its own — if the caller does not `await` this, Node will still
|
|
152
|
+
* exit promptly once all other handles are drained.
|
|
153
|
+
*/
|
|
154
|
+
export const flush = () => {
|
|
155
|
+
const ph = _posthog;
|
|
156
|
+
if (!ph)
|
|
157
|
+
return Promise.resolve();
|
|
158
|
+
// Clear the reference so no further events are captured and
|
|
159
|
+
// PostHog's internal timers can be garbage-collected.
|
|
160
|
+
_posthog = undefined;
|
|
161
|
+
return Promise.race([
|
|
162
|
+
ph.shutdown().catch(() => { }),
|
|
163
|
+
new Promise(r => {
|
|
164
|
+
const t = setTimeout(r, SHUTDOWN_TIMEOUT_MS);
|
|
165
|
+
// Unref so this timer alone won't keep the process alive.
|
|
166
|
+
if (typeof t === 'object' && 'unref' in t)
|
|
167
|
+
t.unref();
|
|
168
|
+
}),
|
|
169
|
+
]);
|
|
170
|
+
};
|
|
@@ -27,4 +27,3 @@ export type ViewFn<T = unknown> = (result: T, options: ViewOptions, conf: Loaded
|
|
|
27
27
|
export type View<T = unknown> = ViewFn<T> | typeof ViewClass<T>;
|
|
28
28
|
export declare const isViewClass: <T = unknown>(view: View<T>) => view is typeof ViewClass<T>;
|
|
29
29
|
export type Views<T = unknown> = View<T> | Record<string, View<T>>;
|
|
30
|
-
//# sourceMappingURL=view.d.ts.map
|
|
@@ -17,7 +17,7 @@ export class ViewClass {
|
|
|
17
17
|
this.config = config;
|
|
18
18
|
}
|
|
19
19
|
// TODO: maybe have start() return a flag to say "i got this, do not
|
|
20
|
-
// run the command", for example to
|
|
20
|
+
// run the command", for example to just open a web browser
|
|
21
21
|
// to the page relevant to a given thing, rather than computing it twice
|
|
22
22
|
start() { }
|
|
23
23
|
async done(_result, _opts) {
|
|
@@ -28,4 +28,3 @@ export class ViewClass {
|
|
|
28
28
|
export const isViewClass = (view) => typeof view === 'function' &&
|
|
29
29
|
'prototype' in view &&
|
|
30
30
|
view.prototype instanceof ViewClass;
|
|
31
|
-
//# sourceMappingURL=view.js.map
|