vercel-vm-factory 0.2.8 → 0.5.8
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/README.md +1 -1
- package/deploy-vm.mjs +46 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vercel VM Factory
|
|
2
2
|
|
|
3
|
-
Create a tiny Vercel Container deployment: copy `wsterm` from `ghcr.io/v1xingyue/ws-shell:v1.
|
|
3
|
+
Create a tiny Vercel Container deployment: copy `wsterm` from `ghcr.io/v1xingyue/ws-shell:v1.8.alpine` into a selected base image, then deploy with Vercel CLI.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npx vercel-vm-factory create \
|
package/deploy-vm.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { createInterface } from "node:readline/promises";
|
|
5
5
|
import { stdin as input, stdout as output } from "node:process";
|
|
@@ -20,8 +20,13 @@ const workspaceRoot = process.cwd();
|
|
|
20
20
|
const stateRoot = path.join(homedir(), ".vercel-vm-factory");
|
|
21
21
|
const defaultsPath = path.join(stateRoot, "defaults.json");
|
|
22
22
|
const legacyDefaultsPath = path.join(scriptRoot, ".defaults.json");
|
|
23
|
-
const
|
|
23
|
+
const codeDefaults = { base: "alpine", from: defaultWsShellImage };
|
|
24
|
+
const packagedDefaults = {
|
|
24
25
|
...(await readDefaults(legacyDefaultsPath)),
|
|
26
|
+
...codeDefaults,
|
|
27
|
+
};
|
|
28
|
+
let defaults = {
|
|
29
|
+
...packagedDefaults,
|
|
25
30
|
...(await readDefaults(defaultsPath)),
|
|
26
31
|
};
|
|
27
32
|
const colorEnabled = output.isTTY && !process.env.NO_COLOR;
|
|
@@ -57,6 +62,7 @@ try {
|
|
|
57
62
|
|
|
58
63
|
async function main() {
|
|
59
64
|
printHeader();
|
|
65
|
+
defaults = await syncDefaults();
|
|
60
66
|
await ensureVercelInstalled();
|
|
61
67
|
await ensureVercelLogin();
|
|
62
68
|
|
|
@@ -310,10 +316,7 @@ async function doctor() {
|
|
|
310
316
|
printKeyValue("base", defaults.base || "not set");
|
|
311
317
|
printKeyValue("project", defaults.project || "not set");
|
|
312
318
|
printKeyValue("scope", defaults.scope || "not set");
|
|
313
|
-
printKeyValue(
|
|
314
|
-
"source image",
|
|
315
|
-
defaults.from || "ghcr.io/v1xingyue/ws-shell:v1.1.alpine",
|
|
316
|
-
);
|
|
319
|
+
printKeyValue("source image", defaults.from || defaultWsShellImage);
|
|
317
320
|
printKeyValue("auth mode", defaults["auth-mode"] || "not set");
|
|
318
321
|
printKeyValue(
|
|
319
322
|
"auth user",
|
|
@@ -479,12 +482,47 @@ async function readDefaults(file) {
|
|
|
479
482
|
}
|
|
480
483
|
}
|
|
481
484
|
|
|
485
|
+
async function syncDefaults() {
|
|
486
|
+
const current = await readDefaults(defaultsPath);
|
|
487
|
+
const codeMtime = Math.max(
|
|
488
|
+
await readMtime(import.meta.filename),
|
|
489
|
+
await readMtime(legacyDefaultsPath),
|
|
490
|
+
);
|
|
491
|
+
const homeMtime = await readMtime(defaultsPath);
|
|
492
|
+
const latest =
|
|
493
|
+
homeMtime > codeMtime
|
|
494
|
+
? { ...packagedDefaults, ...current }
|
|
495
|
+
: { ...current, ...packagedDefaults };
|
|
496
|
+
|
|
497
|
+
if (
|
|
498
|
+
JSON.stringify(cleanDefaults(current)) !==
|
|
499
|
+
JSON.stringify(cleanDefaults(latest))
|
|
500
|
+
)
|
|
501
|
+
await writeDefaults(defaultsPath, latest);
|
|
502
|
+
return cleanDefaults(latest);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
async function readMtime(file) {
|
|
506
|
+
try {
|
|
507
|
+
return (await stat(file)).mtimeMs;
|
|
508
|
+
} catch {
|
|
509
|
+
return 0;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
482
513
|
async function writeDefaults(file, data) {
|
|
514
|
+
const clean = cleanDefaults(data);
|
|
515
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
516
|
+
await writeFile(file, `${JSON.stringify(clean, null, 2)}\n`);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function cleanDefaults(data) {
|
|
483
520
|
const clean = Object.fromEntries(
|
|
484
521
|
Object.entries(data).filter(([, value]) => value),
|
|
485
522
|
);
|
|
486
|
-
|
|
487
|
-
|
|
523
|
+
return Object.fromEntries(
|
|
524
|
+
Object.entries(clean).sort(([a], [b]) => a.localeCompare(b)),
|
|
525
|
+
);
|
|
488
526
|
}
|
|
489
527
|
|
|
490
528
|
function mask(value) {
|