@devframes/hub-ui-onboard 1.3.2 → 1.3.5
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/index.d.mts +6 -0
- package/dist/index.mjs +44 -4
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -53,6 +53,12 @@ interface CreateOnboardingOptions {
|
|
|
53
53
|
stateDir?: string;
|
|
54
54
|
/** Install as a devDependency. Default: `true`. */
|
|
55
55
|
dev?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Stop the install when it runs longer than this many milliseconds, and
|
|
58
|
+
* show an error that asks the user to run the command in a terminal.
|
|
59
|
+
* Default: `300_000` (5 minutes).
|
|
60
|
+
*/
|
|
61
|
+
installTimeout?: number;
|
|
56
62
|
branding?: OnboardingBranding;
|
|
57
63
|
messages?: Partial<OnboardingMessages>;
|
|
58
64
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -54,6 +54,10 @@ const diagnostics = defineDiagnostics({
|
|
|
54
54
|
DF9008: {
|
|
55
55
|
why: (p) => `Nobody allowed \`${p.command}\` within ${p.minutes} minutes. The install was refused.`,
|
|
56
56
|
fix: "Click Install again and answer in the terminal that runs the dev server. If the answer does not arrive, another program reads that terminal: pass an `onConfirm` function to `createOnboarding()`."
|
|
57
|
+
},
|
|
58
|
+
DF9009: {
|
|
59
|
+
why: (p) => `\`${p.command}\` did not finish within ${p.seconds} seconds, so it was stopped.`,
|
|
60
|
+
fix: "Run the command in a terminal to see where the package manager stops, then click Install again. If the install is only slow, raise `installTimeout`."
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
});
|
|
@@ -66,18 +70,35 @@ async function resolveInstallCommand(plan) {
|
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
68
72
|
* Run the install and make sure that each named package landed in
|
|
69
|
-
* `<cwd>/node_modules`. Throws a `DF9001` / `DF9002` diagnostic on failure.
|
|
73
|
+
* `<cwd>/node_modules`. Throws a `DF9001` / `DF9002` / `DF9009` diagnostic on failure.
|
|
70
74
|
*/
|
|
71
75
|
async function runInstall(plan, command) {
|
|
72
|
-
const
|
|
76
|
+
const commandLine = [command.command, ...command.args].join(" ");
|
|
77
|
+
const child = exec(command.command, command.args, { nodeOptions: {
|
|
73
78
|
cwd: plan.cwd,
|
|
74
79
|
env: {
|
|
75
80
|
...process.env,
|
|
76
81
|
CI: "1"
|
|
77
82
|
}
|
|
78
83
|
} });
|
|
84
|
+
let timer;
|
|
85
|
+
let killed;
|
|
86
|
+
const timedOut = new Promise((resolve) => {
|
|
87
|
+
timer = setTimeout(() => {
|
|
88
|
+
killed = killTree(child);
|
|
89
|
+
killed.then(() => resolve(void 0));
|
|
90
|
+
}, plan.timeout);
|
|
91
|
+
});
|
|
92
|
+
const result = await Promise.race([child, timedOut]).finally(() => clearTimeout(timer));
|
|
93
|
+
if (killed || !result) {
|
|
94
|
+
await killed;
|
|
95
|
+
throw diagnostics.DF9009({
|
|
96
|
+
command: commandLine,
|
|
97
|
+
seconds: Math.round(plan.timeout / 1e3)
|
|
98
|
+
});
|
|
99
|
+
}
|
|
79
100
|
if (result.exitCode !== 0) throw diagnostics.DF9001({
|
|
80
|
-
command:
|
|
101
|
+
command: commandLine,
|
|
81
102
|
exitCode: result.exitCode,
|
|
82
103
|
stderr: result.stderr.trim().slice(-2048)
|
|
83
104
|
});
|
|
@@ -87,6 +108,23 @@ async function runInstall(plan, command) {
|
|
|
87
108
|
});
|
|
88
109
|
}
|
|
89
110
|
/**
|
|
111
|
+
* Kill the install with everything it started. On Windows, tinyexec runs a
|
|
112
|
+
* package manager's `.cmd` shim through `cmd.exe`, and a kill does not reach
|
|
113
|
+
* child processes, so `taskkill /T /F` ends the whole tree.
|
|
114
|
+
*/
|
|
115
|
+
async function killTree(child) {
|
|
116
|
+
const pid = child.process?.pid;
|
|
117
|
+
if (process.platform === "win32" && pid !== void 0) {
|
|
118
|
+
if ((await exec("taskkill", [
|
|
119
|
+
"/pid",
|
|
120
|
+
String(pid),
|
|
121
|
+
"/T",
|
|
122
|
+
"/F"
|
|
123
|
+
]).then((r) => r, () => void 0))?.exitCode === 0) return;
|
|
124
|
+
}
|
|
125
|
+
child.kill();
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
90
128
|
* `true` when every named package is already in `<cwd>/node_modules`, so the
|
|
91
129
|
* onboarding has nothing to install. Path, URL and alias specs cannot be
|
|
92
130
|
* checked by name, so a plan made only of those is never "already installed".
|
|
@@ -149,6 +187,7 @@ function confirmInTerminal(command, input = process.stdin) {
|
|
|
149
187
|
}
|
|
150
188
|
// src/index.ts
|
|
151
189
|
const STATE_FILE = "hub-ui-onboard.json";
|
|
190
|
+
const DEFAULT_INSTALL_TIMEOUT = 3e5;
|
|
152
191
|
/** `devframes` → `/devframes/`, same rule as `normalizeHubBase` in `@devframes/hub`. */
|
|
153
192
|
function normalizeBase(base) {
|
|
154
193
|
return `/${base}/`.replace(/\/{2,}/g, "/");
|
|
@@ -242,7 +281,8 @@ function createOnboarding(options) {
|
|
|
242
281
|
const plan = {
|
|
243
282
|
cwd,
|
|
244
283
|
packages: options.packages,
|
|
245
|
-
dev: options.dev ?? true
|
|
284
|
+
dev: options.dev ?? true,
|
|
285
|
+
timeout: options.installTimeout ?? DEFAULT_INSTALL_TIMEOUT
|
|
246
286
|
};
|
|
247
287
|
const branding = options.branding ?? {};
|
|
248
288
|
const messages = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devframes/hub-ui-onboard",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.5",
|
|
5
5
|
"description": "A tiny stand-in for the devframe hub UI: a floating button that installs it on demand.",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^26.6.6",
|
|
37
|
-
"tsdown": "^0.23.
|
|
37
|
+
"tsdown": "^0.23.7",
|
|
38
38
|
"tsx": "^4.23.15",
|
|
39
|
-
"unocss": "^66.
|
|
40
|
-
"vite": "^8.3.
|
|
41
|
-
"vitest": "^5.0
|
|
39
|
+
"unocss": "^66.13.0",
|
|
40
|
+
"vite": "^8.3.8",
|
|
41
|
+
"vitest": "^5.1.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "pnpm run build:css && tsdown && vite build --config vite.client.config.ts",
|