@vantaloom/cli 0.1.2 → 0.1.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/README.md +1 -1
- package/package.json +1 -1
- package/src/cli.mjs +236 -121
package/README.md
CHANGED
|
@@ -9,4 +9,4 @@ vantaloom status
|
|
|
9
9
|
vantaloom update
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
The CLI downloads platform
|
|
12
|
+
The CLI downloads the current platform runtime from public npm packages such as `@vantaloom/runtime-win32-x64`, `@vantaloom/runtime-linux-x64`, and `@vantaloom/runtime-darwin-arm64`. No GitHub token is required for install or update.
|
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -2,12 +2,10 @@ import { execFileSync, spawnSync } from "node:child_process"
|
|
|
2
2
|
import {
|
|
3
3
|
chmodSync,
|
|
4
4
|
existsSync,
|
|
5
|
-
lstatSync,
|
|
6
5
|
mkdirSync,
|
|
7
6
|
mkdtempSync,
|
|
8
7
|
readdirSync,
|
|
9
8
|
readFileSync,
|
|
10
|
-
readlinkSync,
|
|
11
9
|
rmSync,
|
|
12
10
|
writeFileSync,
|
|
13
11
|
} from "node:fs"
|
|
@@ -21,19 +19,7 @@ const repoCandidate = path.resolve(cliRoot, "..", "..")
|
|
|
21
19
|
const installedConfigPath = path.join(cliRoot, "config.json")
|
|
22
20
|
const defaultReleaseTag = "runtime-latest"
|
|
23
21
|
const defaultRepo = "Timefiles404/Vantaloom-next"
|
|
24
|
-
|
|
25
|
-
const runtimePackages = [
|
|
26
|
-
"@next/env",
|
|
27
|
-
"@swc/helpers",
|
|
28
|
-
"baseline-browser-mapping",
|
|
29
|
-
"caniuse-lite",
|
|
30
|
-
"client-only",
|
|
31
|
-
"postcss",
|
|
32
|
-
"react",
|
|
33
|
-
"react-dom",
|
|
34
|
-
"scheduler",
|
|
35
|
-
"styled-jsx",
|
|
36
|
-
]
|
|
22
|
+
const defaultNpmRegistry = "https://registry.npmjs.org"
|
|
37
23
|
|
|
38
24
|
export async function main(argv) {
|
|
39
25
|
const command = argv[0] ?? "help"
|
|
@@ -43,19 +29,23 @@ export async function main(argv) {
|
|
|
43
29
|
case "install":
|
|
44
30
|
if (options.package) {
|
|
45
31
|
await installFromPackage({ ...options, update: false })
|
|
46
|
-
} else if (
|
|
32
|
+
} else if (shouldUseSourceInstall(options)) {
|
|
33
|
+
await installFromSource(options)
|
|
34
|
+
} else if (shouldUseReleaseSync(options)) {
|
|
47
35
|
await syncFromRelease(options, "install")
|
|
48
36
|
} else {
|
|
49
|
-
await
|
|
37
|
+
await syncFromNpmRegistry(options, "install")
|
|
50
38
|
}
|
|
51
39
|
return
|
|
52
40
|
case "update":
|
|
53
41
|
if (options.package) {
|
|
54
42
|
await installFromPackage({ ...options, update: true })
|
|
55
|
-
} else if (
|
|
43
|
+
} else if (shouldUseSourceInstall(options)) {
|
|
44
|
+
await installFromSource({ ...options, update: true })
|
|
45
|
+
} else if (shouldUseReleaseSync(options)) {
|
|
56
46
|
await syncFromRelease(options, "update")
|
|
57
47
|
} else {
|
|
58
|
-
await
|
|
48
|
+
await syncFromNpmRegistry(options, "update")
|
|
59
49
|
}
|
|
60
50
|
return
|
|
61
51
|
case "package":
|
|
@@ -126,6 +116,10 @@ async function packageRuntime(options) {
|
|
|
126
116
|
buildWeb: options.buildWeb,
|
|
127
117
|
})
|
|
128
118
|
|
|
119
|
+
if (options.npmPackage) {
|
|
120
|
+
writeRuntimePackageMetadata(packageRoot, sourceRoot, builtPlatform)
|
|
121
|
+
}
|
|
122
|
+
|
|
129
123
|
if (options.archive) {
|
|
130
124
|
const archivePath = `${packageRoot}.tar.gz`
|
|
131
125
|
removeKnownPath(archivePath, path.dirname(archivePath))
|
|
@@ -161,7 +155,7 @@ async function buildRuntimePackage(sourceRoot, packageRoot, options) {
|
|
|
161
155
|
runPnpm(["--filter", "vantaloom-app", "build"], { cwd: sourceRoot })
|
|
162
156
|
}
|
|
163
157
|
|
|
164
|
-
await
|
|
158
|
+
await copyStaticWeb(sourceRoot, buildWeb)
|
|
165
159
|
await copyCliDirectory(path.join(packageRoot, "cli"), sourceRoot, runtimeConfigFromSource(sourceRoot))
|
|
166
160
|
writeBuildManifest(packageRoot, version, platform)
|
|
167
161
|
|
|
@@ -219,6 +213,46 @@ async function applyPackage(packageRoot, prefix, options) {
|
|
|
219
213
|
return version
|
|
220
214
|
}
|
|
221
215
|
|
|
216
|
+
async function syncFromNpmRegistry(options, action) {
|
|
217
|
+
const prefix = safeDirectory(options.prefix ?? defaultPrefix())
|
|
218
|
+
const installedConfig = readInstalledConfig(prefix)
|
|
219
|
+
const runtimePackage = options.runtimePackage || installedConfig.runtimePackage || runtimePackageName(platformId())
|
|
220
|
+
const runtimeVersion = options.runtimeVersion || installedConfig.runtimeVersion || "latest"
|
|
221
|
+
const registry = normalizeRegistry(options.npmRegistry || installedConfig.npmRegistry || defaultNpmRegistry)
|
|
222
|
+
const tempRoot = mkdtempSync(path.join(os.tmpdir(), "vantaloom-npm-"))
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
const extractRoot = path.join(tempRoot, "extract")
|
|
226
|
+
const archive = path.join(tempRoot, `${packageBasename(runtimePackage)}-${runtimeVersion}.tgz`)
|
|
227
|
+
mkdirSync(extractRoot, { recursive: true })
|
|
228
|
+
|
|
229
|
+
const resolved = await resolveNpmPackage({ registry, name: runtimePackage, version: runtimeVersion })
|
|
230
|
+
await downloadNpmTarball({
|
|
231
|
+
tarballUrl: resolved.tarball,
|
|
232
|
+
target: archive,
|
|
233
|
+
packageName: runtimePackage,
|
|
234
|
+
version: resolved.version,
|
|
235
|
+
})
|
|
236
|
+
run("tar", ["-xzf", archive, "-C", extractRoot])
|
|
237
|
+
|
|
238
|
+
const packageRoot = findExtractedNpmPackage(extractRoot)
|
|
239
|
+
const version = await applyPackage(packageRoot, prefix, {
|
|
240
|
+
noStart: options.noStart,
|
|
241
|
+
runtimePackage,
|
|
242
|
+
runtimeVersion: options.runtimeVersion ? resolved.version : "latest",
|
|
243
|
+
npmRegistry: registry,
|
|
244
|
+
update: action === "update",
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
console.log(`${action === "update" ? "updated" : "installed"} Vantaloom: ${prefix}`)
|
|
248
|
+
console.log(`version: ${version}`)
|
|
249
|
+
console.log(`source: ${runtimePackage}@${resolved.version}`)
|
|
250
|
+
console.log(`run: ${displayCommand(prefix)} status`)
|
|
251
|
+
} finally {
|
|
252
|
+
removeKnownPath(tempRoot, os.tmpdir())
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
222
256
|
async function syncFromRelease(options, action) {
|
|
223
257
|
const prefix = safeDirectory(options.prefix ?? defaultPrefix())
|
|
224
258
|
const installedConfig = readInstalledConfig(prefix)
|
|
@@ -261,7 +295,7 @@ async function syncFromRelease(options, action) {
|
|
|
261
295
|
}
|
|
262
296
|
|
|
263
297
|
async function downloadReleaseAsset({ repo, releaseTag, assetName, target, token }) {
|
|
264
|
-
const
|
|
298
|
+
const releaseUrl = `https://api.github.com/repos/${repo}/releases/tags/${releaseTag}`
|
|
265
299
|
const headers = {
|
|
266
300
|
"User-Agent": "vantaloom-cli",
|
|
267
301
|
}
|
|
@@ -270,7 +304,28 @@ async function downloadReleaseAsset({ repo, releaseTag, assetName, target, token
|
|
|
270
304
|
headers.Authorization = `Bearer ${githubToken}`
|
|
271
305
|
}
|
|
272
306
|
|
|
273
|
-
const
|
|
307
|
+
const releaseResponse = await fetch(releaseUrl, { headers })
|
|
308
|
+
if (!releaseResponse.ok) {
|
|
309
|
+
const detail = await releaseResponse.text().catch(() => "")
|
|
310
|
+
const authHint = releaseResponse.status === 404 || releaseResponse.status === 403
|
|
311
|
+
? " If the repository is private, set VANTALOOM_GITHUB_TOKEN to a GitHub token that can read releases."
|
|
312
|
+
: ""
|
|
313
|
+
throw new Error(`failed to inspect ${repo}@${releaseTag}: HTTP ${releaseResponse.status}.${authHint}${detail ? ` ${detail.slice(0, 200)}` : ""}`)
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const release = await releaseResponse.json()
|
|
317
|
+
const asset = release.assets?.find((asset) => asset.name === assetName)
|
|
318
|
+
if (!asset) {
|
|
319
|
+
const names = release.assets?.map((asset) => asset.name).join(", ") || "none"
|
|
320
|
+
throw new Error(`missing release asset ${assetName} in ${repo}@${releaseTag}; available assets: ${names}`)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const response = await fetch(asset.url, {
|
|
324
|
+
headers: {
|
|
325
|
+
...headers,
|
|
326
|
+
Accept: "application/octet-stream",
|
|
327
|
+
},
|
|
328
|
+
})
|
|
274
329
|
if (!response.ok) {
|
|
275
330
|
const detail = await response.text().catch(() => "")
|
|
276
331
|
const authHint = response.status === 404 || response.status === 403
|
|
@@ -283,8 +338,53 @@ async function downloadReleaseAsset({ repo, releaseTag, assetName, target, token
|
|
|
283
338
|
await writeFile(target, buffer)
|
|
284
339
|
}
|
|
285
340
|
|
|
286
|
-
function
|
|
287
|
-
|
|
341
|
+
async function resolveNpmPackage({ registry, name, version }) {
|
|
342
|
+
const metadataUrl = `${registry}/${encodeURIComponent(name).replace("%2F", "%2f")}`
|
|
343
|
+
const response = await fetch(metadataUrl, {
|
|
344
|
+
headers: {
|
|
345
|
+
Accept: "application/vnd.npm.install-v1+json",
|
|
346
|
+
"User-Agent": "vantaloom-cli",
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
if (!response.ok) {
|
|
350
|
+
const detail = await response.text().catch(() => "")
|
|
351
|
+
throw new Error(`failed to inspect npm package ${name}: HTTP ${response.status}${detail ? ` ${detail.slice(0, 200)}` : ""}`)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const metadata = await response.json()
|
|
355
|
+
const selectedVersion = metadata["dist-tags"]?.[version] ?? version
|
|
356
|
+
const packageVersion = metadata.versions?.[selectedVersion]
|
|
357
|
+
if (!packageVersion?.dist?.tarball) {
|
|
358
|
+
const available = Object.keys(metadata.versions ?? {}).slice(-8).join(", ") || "none"
|
|
359
|
+
throw new Error(`missing npm package ${name}@${version}; available versions: ${available}`)
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
version: selectedVersion,
|
|
363
|
+
tarball: packageVersion.dist.tarball,
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function downloadNpmTarball({ tarballUrl, target, packageName, version }) {
|
|
368
|
+
const response = await fetch(tarballUrl, {
|
|
369
|
+
headers: {
|
|
370
|
+
"User-Agent": "vantaloom-cli",
|
|
371
|
+
},
|
|
372
|
+
})
|
|
373
|
+
if (!response.ok) {
|
|
374
|
+
const detail = await response.text().catch(() => "")
|
|
375
|
+
throw new Error(`failed to download ${packageName}@${version}: HTTP ${response.status}${detail ? ` ${detail.slice(0, 200)}` : ""}`)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const buffer = Buffer.from(await response.arrayBuffer())
|
|
379
|
+
await writeFile(target, buffer)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function shouldUseSourceInstall(options) {
|
|
383
|
+
return Boolean(options.local || options.source || options.buildWeb)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function shouldUseReleaseSync(options) {
|
|
387
|
+
return Boolean(options.repo || options.remote || options.releaseTag || options.githubToken)
|
|
288
388
|
}
|
|
289
389
|
|
|
290
390
|
function assertRuntimePackage(packageRoot) {
|
|
@@ -317,7 +417,7 @@ function readJSONIfExists(filePath) {
|
|
|
317
417
|
|
|
318
418
|
function mergeRuntimeConfig(packageConfig, existingConfig, overrides) {
|
|
319
419
|
const merged = { ...packageConfig }
|
|
320
|
-
for (const key of ["sourceRoot", "remote", "repo", "releaseTag"]) {
|
|
420
|
+
for (const key of ["sourceRoot", "remote", "repo", "releaseTag", "runtimePackage", "runtimeVersion", "npmRegistry"]) {
|
|
321
421
|
if (!merged[key] && existingConfig[key]) {
|
|
322
422
|
merged[key] = existingConfig[key]
|
|
323
423
|
}
|
|
@@ -325,12 +425,30 @@ function mergeRuntimeConfig(packageConfig, existingConfig, overrides) {
|
|
|
325
425
|
if (overrides.sourceRoot) {
|
|
326
426
|
merged.sourceRoot = overrides.sourceRoot
|
|
327
427
|
}
|
|
428
|
+
if (overrides.runtimePackage) {
|
|
429
|
+
merged.runtimePackage = overrides.runtimePackage
|
|
430
|
+
}
|
|
431
|
+
if (overrides.runtimeVersion) {
|
|
432
|
+
merged.runtimeVersion = overrides.runtimeVersion
|
|
433
|
+
}
|
|
434
|
+
if (overrides.npmRegistry) {
|
|
435
|
+
merged.npmRegistry = overrides.npmRegistry
|
|
436
|
+
}
|
|
328
437
|
if (!merged.repo) {
|
|
329
438
|
merged.repo = defaultRepo
|
|
330
439
|
}
|
|
331
440
|
if (!merged.releaseTag) {
|
|
332
441
|
merged.releaseTag = defaultReleaseTag
|
|
333
442
|
}
|
|
443
|
+
if (!merged.runtimePackage) {
|
|
444
|
+
merged.runtimePackage = runtimePackageName(platformId())
|
|
445
|
+
}
|
|
446
|
+
if (!merged.runtimeVersion) {
|
|
447
|
+
merged.runtimeVersion = "latest"
|
|
448
|
+
}
|
|
449
|
+
if (!merged.npmRegistry) {
|
|
450
|
+
merged.npmRegistry = defaultNpmRegistry
|
|
451
|
+
}
|
|
334
452
|
return merged
|
|
335
453
|
}
|
|
336
454
|
|
|
@@ -342,6 +460,9 @@ function runtimeConfigFromSource(sourceRoot) {
|
|
|
342
460
|
...(remote ? { remote } : {}),
|
|
343
461
|
repo,
|
|
344
462
|
releaseTag: defaultReleaseTag,
|
|
463
|
+
runtimePackage: runtimePackageName(platformId()),
|
|
464
|
+
runtimeVersion: "latest",
|
|
465
|
+
npmRegistry: defaultNpmRegistry,
|
|
345
466
|
}
|
|
346
467
|
}
|
|
347
468
|
|
|
@@ -361,6 +482,22 @@ function findExtractedPackage(extractRoot, platform) {
|
|
|
361
482
|
throw new Error(`could not find extracted Vantaloom package in ${extractRoot}`)
|
|
362
483
|
}
|
|
363
484
|
|
|
485
|
+
function findExtractedNpmPackage(extractRoot) {
|
|
486
|
+
const expected = path.join(extractRoot, "package")
|
|
487
|
+
if (existsSync(expected)) {
|
|
488
|
+
return expected
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const directories = readdirSync(extractRoot, { withFileTypes: true })
|
|
492
|
+
.filter((entry) => entry.isDirectory())
|
|
493
|
+
.map((entry) => path.join(extractRoot, entry.name))
|
|
494
|
+
if (directories.length === 1) {
|
|
495
|
+
return directories[0]
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
throw new Error(`could not find extracted npm package in ${extractRoot}`)
|
|
499
|
+
}
|
|
500
|
+
|
|
364
501
|
function tryFindSourceRoot() {
|
|
365
502
|
try {
|
|
366
503
|
return findSourceRoot()
|
|
@@ -401,29 +538,16 @@ function inferGitHubRepo(remote) {
|
|
|
401
538
|
return sshMatch?.[1] ?? ""
|
|
402
539
|
}
|
|
403
540
|
|
|
404
|
-
async function
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
const publicSource = path.join(sourceRoot, "apps", "vantaloom", "public")
|
|
408
|
-
if (!existsSync(standalone)) {
|
|
541
|
+
async function copyStaticWeb(sourceRoot, buildWeb) {
|
|
542
|
+
const exportRoot = path.join(sourceRoot, "apps", "vantaloom", "out")
|
|
543
|
+
if (!existsSync(exportRoot)) {
|
|
409
544
|
throw new Error(
|
|
410
|
-
"missing Next
|
|
545
|
+
"missing Next static export output; let GitHub CI run production build, or pass --build-web for a local one-off build"
|
|
411
546
|
)
|
|
412
547
|
}
|
|
413
548
|
|
|
414
549
|
removeKnownPath(buildWeb, path.dirname(buildWeb))
|
|
415
|
-
|
|
416
|
-
await copyDir(standalone, buildWeb, { dereference: !preserveStandaloneLinks })
|
|
417
|
-
if (preserveStandaloneLinks) {
|
|
418
|
-
await copyStandaloneHoistedTargets(sourceRoot, buildWeb)
|
|
419
|
-
}
|
|
420
|
-
await copyDir(staticSource, path.join(buildWeb, "apps", "vantaloom", ".next", "static"))
|
|
421
|
-
await copyDir(publicSource, path.join(buildWeb, "apps", "vantaloom", "public"))
|
|
422
|
-
|
|
423
|
-
const appNodeModules = path.join(buildWeb, "apps", "vantaloom", "node_modules")
|
|
424
|
-
for (const packageName of runtimePackages) {
|
|
425
|
-
await copyPnpmRuntimePackage(sourceRoot, packageName, appNodeModules)
|
|
426
|
-
}
|
|
550
|
+
await copyDir(exportRoot, buildWeb)
|
|
427
551
|
}
|
|
428
552
|
|
|
429
553
|
async function copyCliDirectory(target, sourceRoot, config) {
|
|
@@ -483,81 +607,6 @@ function buildGo(sourceRoot, buildBin, name) {
|
|
|
483
607
|
], { cwd: sourceRoot })
|
|
484
608
|
}
|
|
485
609
|
|
|
486
|
-
async function copyPnpmRuntimePackage(sourceRoot, packageName, destinationNodeModules) {
|
|
487
|
-
const pnpmRoot = path.join(sourceRoot, "node_modules", ".pnpm")
|
|
488
|
-
const storeName = packageName.replace("/", "+")
|
|
489
|
-
const packageRoot = readdirSync(pnpmRoot, { withFileTypes: true })
|
|
490
|
-
.filter((entry) => entry.isDirectory() && entry.name.startsWith(`${storeName}@`))
|
|
491
|
-
.map((entry) => path.join(pnpmRoot, entry.name))
|
|
492
|
-
.sort()
|
|
493
|
-
.reverse()[0]
|
|
494
|
-
if (!packageRoot) {
|
|
495
|
-
throw new Error(`missing pnpm runtime package: ${packageName}`)
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const source = path.join(packageRoot, "node_modules", ...packageName.split("/"))
|
|
499
|
-
if (!existsSync(source)) {
|
|
500
|
-
throw new Error(`missing pnpm runtime package source: ${source}`)
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
await copyDir(source, path.join(destinationNodeModules, ...packageName.split("/")))
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
async function copyStandaloneHoistedTargets(sourceRoot, buildWeb) {
|
|
507
|
-
const sourceHoisted = path.join(sourceRoot, "node_modules", ".pnpm", "node_modules")
|
|
508
|
-
const buildHoisted = path.join(buildWeb, "node_modules", ".pnpm", "node_modules")
|
|
509
|
-
const packageNames = findHoistedSymlinkPackages(path.join(buildWeb, "node_modules"))
|
|
510
|
-
|
|
511
|
-
for (const packageName of packageNames) {
|
|
512
|
-
const source = path.join(sourceHoisted, ...packageName.split("/"))
|
|
513
|
-
if (existsSync(source)) {
|
|
514
|
-
await copyDir(source, path.join(buildHoisted, ...packageName.split("/")))
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
function findHoistedSymlinkPackages(nodeModules) {
|
|
520
|
-
const packages = new Set()
|
|
521
|
-
if (!existsSync(nodeModules)) {
|
|
522
|
-
return packages
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
for (const entry of readdirSync(nodeModules, { withFileTypes: true })) {
|
|
526
|
-
if (entry.name === ".pnpm" || entry.name.startsWith(".")) {
|
|
527
|
-
continue
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const entryPath = path.join(nodeModules, entry.name)
|
|
531
|
-
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
532
|
-
for (const scopedEntry of readdirSync(entryPath, { withFileTypes: true })) {
|
|
533
|
-
addHoistedSymlinkPackage(packages, path.join(entryPath, scopedEntry.name), `${entry.name}/${scopedEntry.name}`)
|
|
534
|
-
}
|
|
535
|
-
continue
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
addHoistedSymlinkPackage(packages, entryPath, entry.name)
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
return packages
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function addHoistedSymlinkPackage(packages, packagePath, packageName) {
|
|
545
|
-
let stat
|
|
546
|
-
try {
|
|
547
|
-
stat = lstatSync(packagePath)
|
|
548
|
-
} catch {
|
|
549
|
-
return
|
|
550
|
-
}
|
|
551
|
-
if (!stat.isSymbolicLink()) {
|
|
552
|
-
return
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
const target = readlinkSync(packagePath).replaceAll("\\", "/")
|
|
556
|
-
if (target.includes(".pnpm/node_modules/")) {
|
|
557
|
-
packages.add(packageName)
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
610
|
async function copyDir(source, destination, options = {}) {
|
|
562
611
|
if (!existsSync(source)) {
|
|
563
612
|
throw new Error(`missing source directory: ${source}`)
|
|
@@ -589,6 +638,39 @@ function writeBuildManifest(buildRoot, version, platform) {
|
|
|
589
638
|
)
|
|
590
639
|
}
|
|
591
640
|
|
|
641
|
+
function writeRuntimePackageMetadata(packageRoot, sourceRoot, platform) {
|
|
642
|
+
const version = npmPackageVersion(sourceRoot)
|
|
643
|
+
const { os: runtimeOS, cpu } = parsePlatformId(platform)
|
|
644
|
+
const name = runtimePackageName(platform)
|
|
645
|
+
writeFileSync(
|
|
646
|
+
path.join(packageRoot, "package.json"),
|
|
647
|
+
`${JSON.stringify(
|
|
648
|
+
{
|
|
649
|
+
name,
|
|
650
|
+
version,
|
|
651
|
+
private: false,
|
|
652
|
+
description: `Vantaloom local runtime for ${platform}.`,
|
|
653
|
+
type: "module",
|
|
654
|
+
os: [runtimeOS],
|
|
655
|
+
cpu: [cpu],
|
|
656
|
+
files: ["bin", "web", "cli", "manifest.json", "VERSION", "README.md"],
|
|
657
|
+
publishConfig: {
|
|
658
|
+
access: "public",
|
|
659
|
+
},
|
|
660
|
+
engines: {
|
|
661
|
+
node: ">=20",
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
null,
|
|
665
|
+
2
|
|
666
|
+
)}\n`
|
|
667
|
+
)
|
|
668
|
+
writeFileSync(
|
|
669
|
+
path.join(packageRoot, "README.md"),
|
|
670
|
+
`# ${name}\n\nPlatform runtime package for Vantaloom ${platform}. Install @vantaloom/cli instead of this package directly.\n`
|
|
671
|
+
)
|
|
672
|
+
}
|
|
673
|
+
|
|
592
674
|
function findSourceRoot(sourceOption) {
|
|
593
675
|
if (sourceOption) {
|
|
594
676
|
return assertSourceRoot(path.resolve(sourceOption))
|
|
@@ -605,6 +687,11 @@ function findSourceRoot(sourceOption) {
|
|
|
605
687
|
return assertSourceRoot(repoCandidate)
|
|
606
688
|
}
|
|
607
689
|
|
|
690
|
+
function npmPackageVersion(sourceRoot) {
|
|
691
|
+
const packageJSON = readJSONIfExists(path.join(sourceRoot, "packages", "cli", "package.json"))
|
|
692
|
+
return packageJSON.version ?? "0.0.0"
|
|
693
|
+
}
|
|
694
|
+
|
|
608
695
|
function assertSourceRoot(sourceRoot) {
|
|
609
696
|
if (!existsSync(path.join(sourceRoot, "apps", "api", "go.mod"))) {
|
|
610
697
|
throw new Error(`not a Vantaloom source root: ${sourceRoot}`)
|
|
@@ -641,6 +728,9 @@ function parseOptions(args) {
|
|
|
641
728
|
case "remote":
|
|
642
729
|
case "release-tag":
|
|
643
730
|
case "github-token":
|
|
731
|
+
case "runtime-package":
|
|
732
|
+
case "runtime-version":
|
|
733
|
+
case "npm-registry":
|
|
644
734
|
options[toCamel(key)] = inlineValue ?? args[++index]
|
|
645
735
|
if (!options[toCamel(key)]) {
|
|
646
736
|
throw new Error(`missing value for --${key}`)
|
|
@@ -655,6 +745,9 @@ function parseOptions(args) {
|
|
|
655
745
|
case "archive":
|
|
656
746
|
options.archive = true
|
|
657
747
|
break
|
|
748
|
+
case "npm-package":
|
|
749
|
+
options.npmPackage = true
|
|
750
|
+
break
|
|
658
751
|
case "local":
|
|
659
752
|
options.local = true
|
|
660
753
|
break
|
|
@@ -714,6 +807,28 @@ function platformId() {
|
|
|
714
807
|
return `${process.platform}-${process.arch}`
|
|
715
808
|
}
|
|
716
809
|
|
|
810
|
+
function runtimePackageName(platform) {
|
|
811
|
+
return `@vantaloom/runtime-${platform}`
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
function parsePlatformId(platform) {
|
|
815
|
+
const parts = platform.split("-")
|
|
816
|
+
const cpu = parts.pop()
|
|
817
|
+
const runtimeOS = parts.join("-")
|
|
818
|
+
if (!runtimeOS || !cpu) {
|
|
819
|
+
throw new Error(`invalid platform id: ${platform}`)
|
|
820
|
+
}
|
|
821
|
+
return { os: runtimeOS, cpu }
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function packageBasename(name) {
|
|
825
|
+
return name.split("/").pop() ?? name
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
function normalizeRegistry(value) {
|
|
829
|
+
return value.replace(/\/+$/, "")
|
|
830
|
+
}
|
|
831
|
+
|
|
717
832
|
function defaultPrefix() {
|
|
718
833
|
if (process.env.VANTALOOM_HOME) {
|
|
719
834
|
return process.env.VANTALOOM_HOME
|
|
@@ -747,11 +862,11 @@ function printHelp() {
|
|
|
747
862
|
console.log(`Vantaloom CLI
|
|
748
863
|
|
|
749
864
|
Usage:
|
|
750
|
-
vantaloom install [--prefix <dir>] [--
|
|
865
|
+
vantaloom install [--prefix <dir>] [--runtime-version <version>] [--npm-registry <url>] [--package <dir>] [--no-start]
|
|
751
866
|
vantaloom install --local [--prefix <dir>] [--source <repo>] [--build-web] [--no-start]
|
|
752
|
-
vantaloom update [--prefix <dir>] [--
|
|
867
|
+
vantaloom update [--prefix <dir>] [--runtime-version <version>] [--npm-registry <url>] [--no-start]
|
|
753
868
|
vantaloom update --local [--prefix <dir>] [--source <repo>] [--build-web] [--no-start]
|
|
754
|
-
vantaloom package [--source <repo>] [--output <dir>] [--build-web] [--archive]
|
|
869
|
+
vantaloom package [--source <repo>] [--output <dir>] [--build-web] [--archive] [--npm-package]
|
|
755
870
|
vantaloom start [--prefix <dir>] [--component all|api|agent|web]
|
|
756
871
|
vantaloom stop [--prefix <dir>] [--component all|api|agent|web]
|
|
757
872
|
vantaloom restart [--prefix <dir>] [--component all|api|agent|web]
|