@supatype/cli 0.1.0-alpha.6 → 0.1.0-alpha.7
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +203 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/dist/app-config.d.ts +7 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +113 -0
- package/dist/app-config.js.map +1 -0
- package/dist/augmentation-generator.d.ts +2 -0
- package/dist/augmentation-generator.d.ts.map +1 -0
- package/dist/augmentation-generator.js +111 -0
- package/dist/augmentation-generator.js.map +1 -0
- package/dist/binary-cache.d.ts +89 -0
- package/dist/binary-cache.d.ts.map +1 -0
- package/dist/binary-cache.js +656 -0
- package/dist/binary-cache.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +4 -3
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +56 -209
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +105 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/cloud.d.ts +12 -0
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +36 -46
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +47 -54
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts +2 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +92 -51
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +11 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +751 -384
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +20 -15
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/engine.d.ts +1 -3
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +13 -85
- package/dist/commands/engine.js.map +1 -1
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +92 -105
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +22 -12
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +124 -410
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate-from-v1.d.ts +5 -0
- package/dist/commands/migrate-from-v1.d.ts.map +1 -0
- package/dist/commands/migrate-from-v1.js +125 -0
- package/dist/commands/migrate-from-v1.js.map +1 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +27 -23
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/pg.d.ts +8 -0
- package/dist/commands/pg.d.ts.map +1 -0
- package/dist/commands/pg.js +102 -0
- package/dist/commands/pg.js.map +1 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +5 -66
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +99 -39
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/seed.d.ts +2 -0
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +44 -11
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/self-host.d.ts +7 -1
- package/dist/commands/self-host.d.ts.map +1 -1
- package/dist/commands/self-host.js +272 -758
- package/dist/commands/self-host.js.map +1 -1
- package/dist/commands/self-update.d.ts +9 -0
- package/dist/commands/self-update.d.ts.map +1 -0
- package/dist/commands/self-update.js +33 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +4 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/types.d.ts +3 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +62 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +77 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/components.d.ts +5 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +3 -0
- package/dist/components.js.map +1 -0
- package/dist/config.d.ts +10 -51
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +101 -33
- package/dist/config.js.map +1 -1
- package/dist/docker-postgres.d.ts +39 -0
- package/dist/docker-postgres.d.ts.map +1 -0
- package/dist/docker-postgres.js +96 -0
- package/dist/docker-postgres.js.map +1 -0
- package/dist/engine-client.d.ts +67 -0
- package/dist/engine-client.d.ts.map +1 -0
- package/dist/engine-client.js +156 -0
- package/dist/engine-client.js.map +1 -0
- package/dist/ensure-binary.d.ts +7 -0
- package/dist/ensure-binary.d.ts.map +1 -0
- package/dist/ensure-binary.js +17 -0
- package/dist/ensure-binary.js.map +1 -0
- package/dist/functions-router-gen.d.ts +14 -0
- package/dist/functions-router-gen.d.ts.map +1 -0
- package/dist/functions-router-gen.js +199 -0
- package/dist/functions-router-gen.js.map +1 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/kong-config.d.ts +21 -0
- package/dist/kong-config.d.ts.map +1 -0
- package/dist/kong-config.js +60 -0
- package/dist/kong-config.js.map +1 -0
- package/dist/local-gateway.d.ts +7 -0
- package/dist/local-gateway.d.ts.map +1 -0
- package/dist/local-gateway.js +9 -0
- package/dist/local-gateway.js.map +1 -0
- package/dist/local-storage.d.ts +8 -0
- package/dist/local-storage.d.ts.map +1 -0
- package/dist/local-storage.js +14 -0
- package/dist/local-storage.js.map +1 -0
- package/dist/pgbouncer-userlist.d.ts +5 -0
- package/dist/pgbouncer-userlist.d.ts.map +1 -0
- package/dist/pgbouncer-userlist.js +14 -0
- package/dist/pgbouncer-userlist.js.map +1 -0
- package/dist/postgres-ctl.d.ts +44 -0
- package/dist/postgres-ctl.d.ts.map +1 -0
- package/dist/postgres-ctl.js +137 -0
- package/dist/postgres-ctl.js.map +1 -0
- package/dist/process-manager.d.ts +41 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +120 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/project-config.d.ts +215 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +145 -0
- package/dist/project-config.js.map +1 -0
- package/dist/pull-utils.d.ts +15 -0
- package/dist/pull-utils.d.ts.map +1 -1
- package/dist/pull-utils.js +12 -0
- package/dist/pull-utils.js.map +1 -1
- package/dist/release-pins.d.ts +7 -0
- package/dist/release-pins.d.ts.map +1 -0
- package/dist/release-pins.js +27 -0
- package/dist/release-pins.js.map +1 -0
- package/dist/release-public-key.d.ts +8 -0
- package/dist/release-public-key.d.ts.map +1 -0
- package/dist/release-public-key.js +13 -0
- package/dist/release-public-key.js.map +1 -0
- package/dist/runtime-routes.d.ts +25 -0
- package/dist/runtime-routes.d.ts.map +1 -0
- package/dist/runtime-routes.js +189 -0
- package/dist/runtime-routes.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +5 -6
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +36 -20
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/self-host-compose.d.ts +14 -0
- package/dist/self-host-compose.d.ts.map +1 -0
- package/dist/self-host-compose.js +236 -0
- package/dist/self-host-compose.js.map +1 -0
- package/dist/storage-provision.d.ts +24 -0
- package/dist/storage-provision.d.ts.map +1 -0
- package/dist/storage-provision.js +44 -0
- package/dist/storage-provision.js.map +1 -0
- package/dist/systemd.d.ts +26 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +102 -0
- package/dist/systemd.js.map +1 -0
- package/dist/tsx-runner.d.ts.map +1 -1
- package/dist/tsx-runner.js +9 -2
- package/dist/tsx-runner.js.map +1 -1
- package/dist/type-extractor.d.ts +31 -0
- package/dist/type-extractor.d.ts.map +1 -0
- package/dist/type-extractor.js +876 -0
- package/dist/type-extractor.js.map +1 -0
- package/package.json +4 -3
- package/releases/deno/VERSION +1 -0
- package/scripts/mirror-deno-release.sh +76 -0
- package/src/app-config.ts +128 -0
- package/src/augmentation-generator.ts +126 -0
- package/src/binary-cache.ts +802 -0
- package/src/cli.ts +13 -8
- package/src/commands/admin.ts +4 -3
- package/src/commands/app.ts +67 -231
- package/src/commands/cache.ts +117 -0
- package/src/commands/cloud.ts +46 -57
- package/src/commands/db.ts +54 -63
- package/src/commands/deploy.ts +110 -61
- package/src/commands/dev.ts +930 -405
- package/src/commands/diff.ts +21 -29
- package/src/commands/engine.ts +13 -116
- package/src/commands/functions.ts +97 -115
- package/src/commands/generate.ts +23 -10
- package/src/commands/init.ts +136 -414
- package/src/commands/migrate-from-v1.ts +131 -0
- package/src/commands/migrate.ts +27 -23
- package/src/commands/pg.ts +133 -0
- package/src/commands/pull.ts +6 -85
- package/src/commands/push.ts +128 -59
- package/src/commands/seed.ts +54 -12
- package/src/commands/self-host.ts +312 -880
- package/src/commands/self-update.ts +45 -0
- package/src/commands/status.ts +4 -3
- package/src/commands/types.ts +76 -0
- package/src/commands/update.ts +92 -0
- package/src/components.ts +6 -0
- package/src/config.ts +127 -94
- package/src/docker-postgres.ts +138 -0
- package/src/engine-client.ts +231 -0
- package/src/ensure-binary.ts +28 -0
- package/src/functions-router-gen.ts +224 -0
- package/src/index.ts +4 -12
- package/src/kong-config.ts +78 -0
- package/src/local-gateway.ts +9 -0
- package/src/local-storage.ts +14 -0
- package/src/pgbouncer-userlist.ts +15 -0
- package/src/postgres-ctl.ts +171 -0
- package/src/process-manager.ts +151 -0
- package/src/project-config.ts +353 -0
- package/src/pull-utils.ts +24 -0
- package/src/release-pins.ts +31 -0
- package/src/release-public-key.ts +12 -0
- package/src/runtime-routes.ts +216 -0
- package/src/scripts/postinstall.ts +36 -25
- package/src/self-host-compose.ts +257 -0
- package/src/storage-provision.ts +58 -0
- package/src/systemd.ts +137 -0
- package/src/tsx-runner.ts +11 -1
- package/src/type-extractor.ts +1016 -0
- package/tests/app-command.test.ts +54 -0
- package/tests/augmentation-generator.test.ts +59 -0
- package/tests/binary-cache-cloud-overrides.test.ts +123 -0
- package/tests/cached-artifact-format.test.ts +84 -0
- package/tests/cli-help.test.ts +40 -14
- package/tests/config.test.ts +140 -37
- package/tests/engine-distribution.test.ts +3 -3
- package/tests/ensure-binary.test.ts +59 -0
- package/tests/init.test.ts +28 -86
- package/tests/migrate-from-v1.test.ts +29 -0
- package/tests/pg-spawn-env.test.ts +18 -0
- package/tests/postgres-archive-tag.test.ts +9 -0
- package/tests/pull-utils.test.ts +36 -1
- package/tests/release-pins.test.ts +28 -0
- package/tests/runtime-contract.test.ts +236 -0
- package/tests/seed-discover.test.ts +31 -0
- package/tests/tsconfig.json +9 -0
- package/tests/type-extractor.test.ts +401 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +12 -0
- package/dist/engine/cache.d.ts +0 -37
- package/dist/engine/cache.d.ts.map +0 -1
- package/dist/engine/cache.js +0 -121
- package/dist/engine/cache.js.map +0 -1
- package/dist/engine/download.d.ts +0 -19
- package/dist/engine/download.d.ts.map +0 -1
- package/dist/engine/download.js +0 -108
- package/dist/engine/download.js.map +0 -1
- package/dist/engine/platform.d.ts +0 -24
- package/dist/engine/platform.d.ts.map +0 -1
- package/dist/engine/platform.js +0 -50
- package/dist/engine/platform.js.map +0 -1
- package/dist/engine/resolve.d.ts +0 -37
- package/dist/engine/resolve.d.ts.map +0 -1
- package/dist/engine/resolve.js +0 -133
- package/dist/engine/resolve.js.map +0 -1
- package/dist/engine/update-notify.d.ts +0 -11
- package/dist/engine/update-notify.d.ts.map +0 -1
- package/dist/engine/update-notify.js +0 -43
- package/dist/engine/update-notify.js.map +0 -1
- package/dist/engine/verify.d.ts +0 -50
- package/dist/engine/verify.d.ts.map +0 -1
- package/dist/engine/verify.js +0 -161
- package/dist/engine/verify.js.map +0 -1
- package/dist/engine-version.d.ts +0 -35
- package/dist/engine-version.d.ts.map +0 -1
- package/dist/engine-version.js +0 -35
- package/dist/engine-version.js.map +0 -1
- package/dist/engine.d.ts +0 -34
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js +0 -76
- package/dist/engine.js.map +0 -1
- package/src/engine/cache.ts +0 -135
- package/src/engine/download.ts +0 -143
- package/src/engine/platform.ts +0 -66
- package/src/engine/resolve.ts +0 -197
- package/src/engine/update-notify.ts +0 -50
- package/src/engine/verify.ts +0 -206
- package/src/engine-version.ts +0 -39
- package/src/engine.ts +0 -99
package/dist/engine.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Locates the engine binary (from cache) and provides a helper to invoke it.
|
|
3
|
-
*
|
|
4
|
-
* The engine binary is cached at ~/.supatype/engine/{version}/supatype-engine[.exe].
|
|
5
|
-
* On first use, it's automatically downloaded, verified, and cached.
|
|
6
|
-
*/
|
|
7
|
-
export interface EngineResult {
|
|
8
|
-
stdout: string;
|
|
9
|
-
stderr: string;
|
|
10
|
-
exitCode: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Get the path to the engine binary, downloading if needed.
|
|
14
|
-
* This is the async version — use when you can await.
|
|
15
|
-
*/
|
|
16
|
-
export declare function getEnginePathAsync(): Promise<string>;
|
|
17
|
-
/**
|
|
18
|
-
* Get the path to the engine binary (sync).
|
|
19
|
-
* Throws if the binary is not cached — caller must ensure it's downloaded first.
|
|
20
|
-
*/
|
|
21
|
-
export declare function getEnginePath(): string;
|
|
22
|
-
/**
|
|
23
|
-
* Ensure the engine binary is available, downloading if necessary.
|
|
24
|
-
* Call this before invokeEngine() in command handlers.
|
|
25
|
-
*/
|
|
26
|
-
export declare function ensureEngine(): Promise<string>;
|
|
27
|
-
/**
|
|
28
|
-
* Invoke the engine binary with the given arguments.
|
|
29
|
-
* Input JSON is passed via stdin.
|
|
30
|
-
*
|
|
31
|
-
* The caller must call ensureEngine() first to guarantee the binary exists.
|
|
32
|
-
*/
|
|
33
|
-
export declare function invokeEngine(args: string[], input?: string): EngineResult;
|
|
34
|
-
//# sourceMappingURL=engine.d.ts.map
|
package/dist/engine.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAW1D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CActC;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAepD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,CAAC,EAAE,MAAM,GACb,YAAY,CAYd"}
|
package/dist/engine.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Locates the engine binary (from cache) and provides a helper to invoke it.
|
|
3
|
-
*
|
|
4
|
-
* The engine binary is cached at ~/.supatype/engine/{version}/supatype-engine[.exe].
|
|
5
|
-
* On first use, it's automatically downloaded, verified, and cached.
|
|
6
|
-
*/
|
|
7
|
-
import { spawnSync } from "node:child_process";
|
|
8
|
-
import { ENGINE_VERSION } from "./engine-version.js";
|
|
9
|
-
import { detectPlatform } from "./engine/platform.js";
|
|
10
|
-
import { getCachedBinaryPath, hasCachedBinary } from "./engine/cache.js";
|
|
11
|
-
import { resolveEngine, checkVersionCompatibility } from "./engine/resolve.js";
|
|
12
|
-
/**
|
|
13
|
-
* Get the path to the engine binary, downloading if needed.
|
|
14
|
-
* This is the async version — use when you can await.
|
|
15
|
-
*/
|
|
16
|
-
export async function getEnginePathAsync() {
|
|
17
|
-
const platform = detectPlatform();
|
|
18
|
-
// Fast path: binary already cached
|
|
19
|
-
if (hasCachedBinary(ENGINE_VERSION, platform)) {
|
|
20
|
-
return getCachedBinaryPath(ENGINE_VERSION, platform);
|
|
21
|
-
}
|
|
22
|
-
// Need to download
|
|
23
|
-
const result = await resolveEngine(ENGINE_VERSION);
|
|
24
|
-
return result.binaryPath;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Get the path to the engine binary (sync).
|
|
28
|
-
* Throws if the binary is not cached — caller must ensure it's downloaded first.
|
|
29
|
-
*/
|
|
30
|
-
export function getEnginePath() {
|
|
31
|
-
const platform = detectPlatform();
|
|
32
|
-
const path = getCachedBinaryPath(ENGINE_VERSION, platform);
|
|
33
|
-
if (!hasCachedBinary(ENGINE_VERSION, platform)) {
|
|
34
|
-
throw new Error(`Supatype engine binary not found in cache.\n` +
|
|
35
|
-
`Expected: ${path}\n` +
|
|
36
|
-
`Run any supatype command to trigger automatic download,\n` +
|
|
37
|
-
`or run: npx supatype engine version`);
|
|
38
|
-
}
|
|
39
|
-
return path;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Ensure the engine binary is available, downloading if necessary.
|
|
43
|
-
* Call this before invokeEngine() in command handlers.
|
|
44
|
-
*/
|
|
45
|
-
export async function ensureEngine() {
|
|
46
|
-
const result = await resolveEngine(ENGINE_VERSION);
|
|
47
|
-
if (!result.fromCache) {
|
|
48
|
-
// Just downloaded — version is correct
|
|
49
|
-
return result.binaryPath;
|
|
50
|
-
}
|
|
51
|
-
// Cached — check compatibility
|
|
52
|
-
const compat = checkVersionCompatibility(ENGINE_VERSION, ENGINE_VERSION);
|
|
53
|
-
if (!compat.compatible) {
|
|
54
|
-
throw new Error(compat.message);
|
|
55
|
-
}
|
|
56
|
-
return result.binaryPath;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Invoke the engine binary with the given arguments.
|
|
60
|
-
* Input JSON is passed via stdin.
|
|
61
|
-
*
|
|
62
|
-
* The caller must call ensureEngine() first to guarantee the binary exists.
|
|
63
|
-
*/
|
|
64
|
-
export function invokeEngine(args, input) {
|
|
65
|
-
const enginePath = getEnginePath();
|
|
66
|
-
const result = spawnSync(enginePath, args, {
|
|
67
|
-
input: input ? Buffer.from(input, "utf8") : undefined,
|
|
68
|
-
maxBuffer: 50 * 1024 * 1024, // 50MB
|
|
69
|
-
});
|
|
70
|
-
return {
|
|
71
|
-
stdout: result.stdout?.toString("utf8") ?? "",
|
|
72
|
-
stderr: result.stderr?.toString("utf8") ?? "",
|
|
73
|
-
exitCode: result.status ?? 1,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=engine.js.map
|
package/dist/engine.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,oBAAoB,CAAA;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAQ9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;IAEjC,mCAAmC;IACnC,IAAI,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC9C,OAAO,mBAAmB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;IACtD,CAAC;IAED,mBAAmB;IACnB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAA;IAClD,OAAO,MAAM,CAAC,UAAU,CAAA;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;IACjC,MAAM,IAAI,GAAG,mBAAmB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;IAE1D,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,8CAA8C;YAC9C,aAAa,IAAI,IAAI;YACrB,2DAA2D;YAC3D,qCAAqC,CACtC,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAA;IAElD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,uCAAuC;QACvC,OAAO,MAAM,CAAC,UAAU,CAAA;IAC1B,CAAC;IAED,+BAA+B;IAC/B,MAAM,MAAM,GAAG,yBAAyB,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;IACxE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,OAAO,MAAM,CAAC,UAAU,CAAA;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAc,EACd,KAAc;IAEd,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,MAAM,GAA6B,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE;QACnE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACrD,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO;KACrC,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;QAC7C,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC;KAC7B,CAAA;AACH,CAAC"}
|
package/src/engine/cache.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Local cache management for engine binaries.
|
|
3
|
-
* Binaries are stored at ~/.supatype/engine/{version}/supatype-engine[.exe]
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from "node:fs"
|
|
7
|
-
import { readFile, writeFile } from "node:fs/promises"
|
|
8
|
-
import { join } from "node:path"
|
|
9
|
-
import { homedir } from "node:os"
|
|
10
|
-
import type { PlatformInfo } from "./platform.js"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Root cache directory: ~/.supatype/engine/
|
|
14
|
-
*/
|
|
15
|
-
export function getCacheDir(): string {
|
|
16
|
-
return join(homedir(), ".supatype", "engine")
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Full path to a cached engine binary for a specific version.
|
|
21
|
-
*/
|
|
22
|
-
export function getCachedBinaryPath(version: string, platform: PlatformInfo): string {
|
|
23
|
-
return join(getCacheDir(), version, platform.binaryName)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Check if a valid cached binary exists for the given version.
|
|
28
|
-
*/
|
|
29
|
-
export function hasCachedBinary(version: string, platform: PlatformInfo): boolean {
|
|
30
|
-
const path = getCachedBinaryPath(version, platform)
|
|
31
|
-
return existsSync(path)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Ensure the cache directory for a version exists.
|
|
36
|
-
*/
|
|
37
|
-
export function ensureCacheDir(version: string): string {
|
|
38
|
-
const dir = join(getCacheDir(), version)
|
|
39
|
-
mkdirSync(dir, { recursive: true })
|
|
40
|
-
return dir
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* List all cached engine versions.
|
|
45
|
-
*/
|
|
46
|
-
export function listCachedVersions(): string[] {
|
|
47
|
-
const cacheDir = getCacheDir()
|
|
48
|
-
if (!existsSync(cacheDir)) return []
|
|
49
|
-
|
|
50
|
-
return readdirSync(cacheDir, { withFileTypes: true })
|
|
51
|
-
.filter((d) => d.isDirectory())
|
|
52
|
-
.map((d) => d.name)
|
|
53
|
-
.sort()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Remove all cached versions except the specified one.
|
|
58
|
-
* Returns the total bytes freed.
|
|
59
|
-
*/
|
|
60
|
-
export function pruneCacheExcept(keepVersion: string): { removed: string[]; bytesFreed: number } {
|
|
61
|
-
const versions = listCachedVersions()
|
|
62
|
-
const removed: string[] = []
|
|
63
|
-
let bytesFreed = 0
|
|
64
|
-
|
|
65
|
-
for (const version of versions) {
|
|
66
|
-
if (version === keepVersion) continue
|
|
67
|
-
const versionDir = join(getCacheDir(), version)
|
|
68
|
-
bytesFreed += getDirSize(versionDir)
|
|
69
|
-
rmSync(versionDir, { recursive: true, force: true })
|
|
70
|
-
removed.push(version)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return { removed, bytesFreed }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function getDirSize(dir: string): number {
|
|
77
|
-
let size = 0
|
|
78
|
-
if (!existsSync(dir)) return size
|
|
79
|
-
|
|
80
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
81
|
-
const path = join(dir, entry.name)
|
|
82
|
-
if (entry.isFile()) {
|
|
83
|
-
size += statSync(path).size
|
|
84
|
-
} else if (entry.isDirectory()) {
|
|
85
|
-
size += getDirSize(path)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return size
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Update check throttling.
|
|
93
|
-
* Stores last check timestamp in ~/.supatype/update-check.json
|
|
94
|
-
*/
|
|
95
|
-
const UPDATE_CHECK_FILE = join(homedir(), ".supatype", "update-check.json")
|
|
96
|
-
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000 // 24 hours
|
|
97
|
-
|
|
98
|
-
interface UpdateCheckData {
|
|
99
|
-
lastCheck: number
|
|
100
|
-
latestVersion?: string
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export async function shouldCheckForUpdates(): Promise<boolean> {
|
|
104
|
-
// Skip in CI environments
|
|
105
|
-
if (process.env.CI === "true" || process.env.CI === "1") return false
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
if (!existsSync(UPDATE_CHECK_FILE)) return true
|
|
109
|
-
const data: UpdateCheckData = JSON.parse(await readFile(UPDATE_CHECK_FILE, "utf8"))
|
|
110
|
-
return Date.now() - data.lastCheck > CHECK_INTERVAL_MS
|
|
111
|
-
} catch {
|
|
112
|
-
return true
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export async function saveUpdateCheck(latestVersion: string): Promise<void> {
|
|
117
|
-
const dir = join(homedir(), ".supatype")
|
|
118
|
-
mkdirSync(dir, { recursive: true })
|
|
119
|
-
|
|
120
|
-
const data: UpdateCheckData = {
|
|
121
|
-
lastCheck: Date.now(),
|
|
122
|
-
latestVersion,
|
|
123
|
-
}
|
|
124
|
-
await writeFile(UPDATE_CHECK_FILE, JSON.stringify(data, null, 2))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export async function getLastKnownLatestVersion(): Promise<string | undefined> {
|
|
128
|
-
try {
|
|
129
|
-
if (!existsSync(UPDATE_CHECK_FILE)) return undefined
|
|
130
|
-
const data: UpdateCheckData = JSON.parse(await readFile(UPDATE_CHECK_FILE, "utf8"))
|
|
131
|
-
return data.latestVersion
|
|
132
|
-
} catch {
|
|
133
|
-
return undefined
|
|
134
|
-
}
|
|
135
|
-
}
|
package/src/engine/download.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Engine binary download with progress bar, retry, and proxy support.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createWriteStream } from "node:fs"
|
|
6
|
-
import { Readable } from "node:stream"
|
|
7
|
-
import { pipeline } from "node:stream/promises"
|
|
8
|
-
|
|
9
|
-
export interface DownloadOptions {
|
|
10
|
-
url: string
|
|
11
|
-
dest: string
|
|
12
|
-
showProgress?: boolean
|
|
13
|
-
label?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const MAX_RETRIES = 3
|
|
17
|
-
const RETRY_DELAYS = [1000, 3000, 10000]
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Download a file with retry and optional progress bar.
|
|
21
|
-
* Respects HTTP_PROXY / HTTPS_PROXY environment variables.
|
|
22
|
-
*/
|
|
23
|
-
export async function downloadFile(options: DownloadOptions): Promise<void> {
|
|
24
|
-
const { url, dest, showProgress = false, label } = options
|
|
25
|
-
let lastError: Error | undefined
|
|
26
|
-
|
|
27
|
-
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
28
|
-
try {
|
|
29
|
-
await doDownload(url, dest, showProgress, label)
|
|
30
|
-
return
|
|
31
|
-
} catch (err) {
|
|
32
|
-
lastError = err instanceof Error ? err : new Error(String(err))
|
|
33
|
-
if (attempt < MAX_RETRIES - 1) {
|
|
34
|
-
const delay = RETRY_DELAYS[attempt]!
|
|
35
|
-
process.stderr.write(
|
|
36
|
-
`Download failed. Retrying (${attempt + 2}/${MAX_RETRIES})...\n`,
|
|
37
|
-
)
|
|
38
|
-
await sleep(delay)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Failed to download after ${MAX_RETRIES} attempts: ${lastError?.message}`,
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function doDownload(
|
|
49
|
-
url: string,
|
|
50
|
-
dest: string,
|
|
51
|
-
showProgress: boolean,
|
|
52
|
-
label?: string,
|
|
53
|
-
): Promise<void> {
|
|
54
|
-
const fetchOptions = buildFetchOptions(url)
|
|
55
|
-
const res = await fetch(url, fetchOptions)
|
|
56
|
-
|
|
57
|
-
if (!res.ok) {
|
|
58
|
-
throw new Error(`HTTP ${res.status} ${res.statusText}: ${url}`)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!res.body) {
|
|
62
|
-
throw new Error(`No response body: ${url}`)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const contentLength = Number(res.headers.get("content-length") || 0)
|
|
66
|
-
const out = createWriteStream(dest)
|
|
67
|
-
|
|
68
|
-
if (showProgress && contentLength > 0 && process.stderr.isTTY) {
|
|
69
|
-
const progressStream = createProgressStream(contentLength, label)
|
|
70
|
-
await pipeline(Readable.fromWeb(res.body as any), progressStream, out)
|
|
71
|
-
// Clear the progress line
|
|
72
|
-
process.stderr.write("\n")
|
|
73
|
-
} else {
|
|
74
|
-
if (showProgress && label) {
|
|
75
|
-
process.stderr.write(`${label}...\n`)
|
|
76
|
-
}
|
|
77
|
-
await pipeline(Readable.fromWeb(res.body as any), out)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Build fetch options respecting proxy env vars.
|
|
83
|
-
*/
|
|
84
|
-
function buildFetchOptions(url: string): RequestInit {
|
|
85
|
-
const opts: RequestInit = {}
|
|
86
|
-
|
|
87
|
-
// Node.js 18+ fetch supports the proxy via undici dispatcher.
|
|
88
|
-
// For simplicity, we rely on the global-agent or undici proxy support.
|
|
89
|
-
// The user should set HTTPS_PROXY or HTTP_PROXY env vars.
|
|
90
|
-
// Node.js 22+ automatically respects these in fetch().
|
|
91
|
-
//
|
|
92
|
-
// For older Node.js, users can install global-agent or similar.
|
|
93
|
-
|
|
94
|
-
return opts
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Creates a Transform stream that logs download progress to stderr.
|
|
99
|
-
*/
|
|
100
|
-
function createProgressStream(
|
|
101
|
-
totalBytes: number,
|
|
102
|
-
label?: string,
|
|
103
|
-
): import("node:stream").Transform {
|
|
104
|
-
const { Transform } = require("node:stream") as typeof import("node:stream")
|
|
105
|
-
let downloaded = 0
|
|
106
|
-
|
|
107
|
-
return new Transform({
|
|
108
|
-
transform(chunk: Buffer, _encoding, callback) {
|
|
109
|
-
downloaded += chunk.length
|
|
110
|
-
const percent = Math.round((downloaded / totalBytes) * 100)
|
|
111
|
-
const mb = (downloaded / (1024 * 1024)).toFixed(1)
|
|
112
|
-
const totalMb = (totalBytes / (1024 * 1024)).toFixed(1)
|
|
113
|
-
const barWidth = 30
|
|
114
|
-
const filled = Math.round((percent / 100) * barWidth)
|
|
115
|
-
const bar = "=".repeat(filled) + " ".repeat(barWidth - filled)
|
|
116
|
-
|
|
117
|
-
const prefix = label || "Downloading"
|
|
118
|
-
process.stderr.write(
|
|
119
|
-
`\r${prefix} ${mb}MB/${totalMb}MB [${bar}] ${percent}%`,
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
this.push(chunk)
|
|
123
|
-
callback()
|
|
124
|
-
},
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function sleep(ms: number): Promise<void> {
|
|
129
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Fetch a JSON file from a URL. Returns undefined on failure.
|
|
134
|
-
*/
|
|
135
|
-
export async function fetchJson<T>(url: string): Promise<T | undefined> {
|
|
136
|
-
try {
|
|
137
|
-
const res = await fetch(url)
|
|
138
|
-
if (!res.ok) return undefined
|
|
139
|
-
return (await res.json()) as T
|
|
140
|
-
} catch {
|
|
141
|
-
return undefined
|
|
142
|
-
}
|
|
143
|
-
}
|
package/src/engine/platform.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Platform detection for engine binary downloads.
|
|
3
|
-
* Maps Node.js platform/arch to the binary naming convention.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface PlatformInfo {
|
|
7
|
-
os: "linux" | "darwin" | "win"
|
|
8
|
-
arch: "x64" | "arm64"
|
|
9
|
-
binaryName: string
|
|
10
|
-
ext: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const PLATFORM_MAP: Record<string, { os: PlatformInfo["os"]; arch: PlatformInfo["arch"] }> = {
|
|
14
|
-
"darwin-arm64": { os: "darwin", arch: "arm64" },
|
|
15
|
-
"darwin-x64": { os: "darwin", arch: "x64" },
|
|
16
|
-
"linux-arm64": { os: "linux", arch: "arm64" },
|
|
17
|
-
"linux-x64": { os: "linux", arch: "x64" },
|
|
18
|
-
"win32-x64": { os: "win", arch: "x64" },
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const SUPPORTED_PLATFORMS = [
|
|
22
|
-
"linux-x64",
|
|
23
|
-
"linux-arm64",
|
|
24
|
-
"darwin-x64",
|
|
25
|
-
"darwin-arm64",
|
|
26
|
-
"win-x64",
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Detect the current platform and return the binary info.
|
|
31
|
-
* Throws on unsupported platforms with a helpful message.
|
|
32
|
-
*/
|
|
33
|
-
export function detectPlatform(): PlatformInfo {
|
|
34
|
-
const key = `${process.platform}-${process.arch}`
|
|
35
|
-
const mapped = PLATFORM_MAP[key]
|
|
36
|
-
|
|
37
|
-
if (!mapped) {
|
|
38
|
-
throw new Error(
|
|
39
|
-
`Supatype engine is not available for ${process.platform}-${process.arch}.\n` +
|
|
40
|
-
`Supported platforms: ${SUPPORTED_PLATFORMS.join(", ")}`,
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const ext = mapped.os === "win" ? ".exe" : ""
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
os: mapped.os,
|
|
48
|
-
arch: mapped.arch,
|
|
49
|
-
binaryName: `supatype-engine${ext}`,
|
|
50
|
-
ext,
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Build the artifact filename for a given version and platform.
|
|
56
|
-
*/
|
|
57
|
-
export function getArtifactName(version: string, platform: PlatformInfo): string {
|
|
58
|
-
return `supatype-engine-${version}-${platform.os}-${platform.arch}${platform.ext}`
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Build the CDN download URL for a given version and artifact.
|
|
63
|
-
*/
|
|
64
|
-
export function getCdnUrl(baseUrl: string, version: string, filename: string): string {
|
|
65
|
-
return `${baseUrl}/v${version}/${filename}`
|
|
66
|
-
}
|
package/src/engine/resolve.ts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Engine resolver — orchestrates binary download, verification, and caching.
|
|
3
|
-
*
|
|
4
|
-
* Resolution flow:
|
|
5
|
-
* 1. Check local cache for the pinned version
|
|
6
|
-
* 2. If cached and valid, return cached path
|
|
7
|
-
* 3. If not cached, download from CDN (with GitHub Releases fallback)
|
|
8
|
-
* 4. Verify signature + checksum
|
|
9
|
-
* 5. Cache the verified binary
|
|
10
|
-
* 6. Return the cached path
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { chmodSync, existsSync } from "node:fs"
|
|
14
|
-
import { rename, unlink, copyFile } from "node:fs/promises"
|
|
15
|
-
import { join } from "node:path"
|
|
16
|
-
import { detectPlatform, getArtifactName, getCdnUrl } from "./platform.js"
|
|
17
|
-
import { getCachedBinaryPath, hasCachedBinary, ensureCacheDir } from "./cache.js"
|
|
18
|
-
import { downloadFile, fetchJson } from "./download.js"
|
|
19
|
-
import { verifyBinary, verifyChecksumOnly } from "./verify.js"
|
|
20
|
-
import {
|
|
21
|
-
ENGINE_VERSION,
|
|
22
|
-
CDN_BASE_URL,
|
|
23
|
-
GITHUB_RELEASES_FALLBACK_URL,
|
|
24
|
-
} from "../engine-version.js"
|
|
25
|
-
|
|
26
|
-
export interface ResolveResult {
|
|
27
|
-
binaryPath: string
|
|
28
|
-
version: string
|
|
29
|
-
fromCache: boolean
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Resolve the engine binary path, downloading if necessary.
|
|
34
|
-
*/
|
|
35
|
-
export async function resolveEngine(
|
|
36
|
-
version: string = ENGINE_VERSION,
|
|
37
|
-
): Promise<ResolveResult> {
|
|
38
|
-
const platform = detectPlatform()
|
|
39
|
-
|
|
40
|
-
// Check cache first
|
|
41
|
-
if (hasCachedBinary(version, platform)) {
|
|
42
|
-
return {
|
|
43
|
-
binaryPath: getCachedBinaryPath(version, platform),
|
|
44
|
-
version,
|
|
45
|
-
fromCache: true,
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Not cached — need to download
|
|
50
|
-
const artifactName = getArtifactName(version, platform)
|
|
51
|
-
const cacheDir = ensureCacheDir(version)
|
|
52
|
-
const binaryDest = getCachedBinaryPath(version, platform)
|
|
53
|
-
const tempBinary = `${binaryDest}.tmp`
|
|
54
|
-
const checksumDest = join(cacheDir, "checksums.sha256")
|
|
55
|
-
const signatureDest = join(cacheDir, "checksums.sha256.minisig")
|
|
56
|
-
|
|
57
|
-
// Try CDN first, then GitHub Releases fallback
|
|
58
|
-
let downloaded = false
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
downloaded = await downloadFromSource(
|
|
62
|
-
CDN_BASE_URL,
|
|
63
|
-
version,
|
|
64
|
-
artifactName,
|
|
65
|
-
tempBinary,
|
|
66
|
-
checksumDest,
|
|
67
|
-
signatureDest,
|
|
68
|
-
)
|
|
69
|
-
} catch {
|
|
70
|
-
// CDN failed, try fallback
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!downloaded) {
|
|
74
|
-
try {
|
|
75
|
-
downloaded = await downloadFromSource(
|
|
76
|
-
GITHUB_RELEASES_FALLBACK_URL,
|
|
77
|
-
version,
|
|
78
|
-
artifactName,
|
|
79
|
-
tempBinary,
|
|
80
|
-
checksumDest,
|
|
81
|
-
signatureDest,
|
|
82
|
-
)
|
|
83
|
-
} catch {
|
|
84
|
-
// Fallback also failed
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!downloaded) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
"Cannot download Supatype engine. Check your internet connection.\n" +
|
|
91
|
-
"If this persists, report at https://github.com/supatype/supatype/issues",
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Verify the downloaded binary
|
|
96
|
-
if (existsSync(signatureDest)) {
|
|
97
|
-
// Full two-step verification: signature + checksum
|
|
98
|
-
await verifyBinary(tempBinary, checksumDest, signatureDest, artifactName)
|
|
99
|
-
} else {
|
|
100
|
-
// Checksum-only verification (GitHub Releases may not have .minisig)
|
|
101
|
-
await verifyChecksumOnly(tempBinary, checksumDest, artifactName)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Move verified binary to final location
|
|
105
|
-
await rename(tempBinary, binaryDest)
|
|
106
|
-
|
|
107
|
-
// Set executable permission on Unix
|
|
108
|
-
if (process.platform !== "win32") {
|
|
109
|
-
chmodSync(binaryDest, 0o755)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
binaryPath: binaryDest,
|
|
114
|
-
version,
|
|
115
|
-
fromCache: false,
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async function downloadFromSource(
|
|
120
|
-
baseUrl: string,
|
|
121
|
-
version: string,
|
|
122
|
-
artifactName: string,
|
|
123
|
-
binaryDest: string,
|
|
124
|
-
checksumDest: string,
|
|
125
|
-
signatureDest: string,
|
|
126
|
-
): Promise<boolean> {
|
|
127
|
-
const binaryUrl = getCdnUrl(baseUrl, version, artifactName)
|
|
128
|
-
const checksumUrl = getCdnUrl(baseUrl, version, "checksums.sha256")
|
|
129
|
-
const signatureUrl = getCdnUrl(baseUrl, version, "checksums.sha256.minisig")
|
|
130
|
-
|
|
131
|
-
// Download binary with progress
|
|
132
|
-
await downloadFile({
|
|
133
|
-
url: binaryUrl,
|
|
134
|
-
dest: binaryDest,
|
|
135
|
-
showProgress: true,
|
|
136
|
-
label: `Downloading Supatype engine v${version} for ${detectPlatform().os}-${detectPlatform().arch}`,
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
// Download checksum file
|
|
140
|
-
await downloadFile({
|
|
141
|
-
url: checksumUrl,
|
|
142
|
-
dest: checksumDest,
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
// Try to download signature file (may not exist for GitHub Releases)
|
|
146
|
-
try {
|
|
147
|
-
await downloadFile({
|
|
148
|
-
url: signatureUrl,
|
|
149
|
-
dest: signatureDest,
|
|
150
|
-
})
|
|
151
|
-
} catch {
|
|
152
|
-
// Signature file optional for fallback sources
|
|
153
|
-
// But for CDN, we require it — verifyBinary will enforce this
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return true
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Check for the latest engine version from CDN.
|
|
161
|
-
*/
|
|
162
|
-
export interface LatestVersionInfo {
|
|
163
|
-
version: string
|
|
164
|
-
date: string
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export async function checkLatestVersion(): Promise<LatestVersionInfo | undefined> {
|
|
168
|
-
return fetchJson<LatestVersionInfo>(`${CDN_BASE_URL}/latest.json`)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Check version compatibility.
|
|
173
|
-
* Engine and CLI must share the same major version.
|
|
174
|
-
*/
|
|
175
|
-
export function checkVersionCompatibility(
|
|
176
|
-
engineVersion: string,
|
|
177
|
-
expectedVersion: string,
|
|
178
|
-
): { compatible: boolean; message?: string } {
|
|
179
|
-
const engineMajor = parseMajor(engineVersion)
|
|
180
|
-
const expectedMajor = parseMajor(expectedVersion)
|
|
181
|
-
|
|
182
|
-
if (engineMajor !== expectedMajor) {
|
|
183
|
-
return {
|
|
184
|
-
compatible: false,
|
|
185
|
-
message:
|
|
186
|
-
`Engine version ${engineVersion} is not compatible with CLI version ${expectedVersion}.\n` +
|
|
187
|
-
`Run: npm update @supatype/cli`,
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return { compatible: true }
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function parseMajor(version: string): number {
|
|
195
|
-
const match = version.match(/^(\d+)/)
|
|
196
|
-
return match ? parseInt(match[1]!, 10) : 0
|
|
197
|
-
}
|