1import { SERVER_VERSION } from "../version.ts";
2import { SERVICE_LAUNCHER_PROTOCOL } from "./serviceProtocol.ts";
3
4export type ServicePreflightResult =
5 | {
6 readonly status: "ready";
7 readonly version: string;
8 readonly launcherProtocol: typeof SERVICE_LAUNCHER_PROTOCOL;
9 }
10 | {
11 readonly status: "blocked";
12 readonly version: string;
13 readonly reason: string;
14 };
15
16export function runServicePreflight(input: {
17 /** Older servers always pass this flag when invoking a staged preflight. */
18 readonly databasePath: string;
19 readonly launcherProtocol: number;
20 readonly version?: string;
21}): ServicePreflightResult {
22 const version = input.version ?? SERVER_VERSION;
23 if (input.launcherProtocol !== SERVICE_LAUNCHER_PROTOCOL) {
24 return {
25 status: "blocked",
26 version,
27 reason:
28 "This release requires a newer T3 Code service launcher. Update it on the server machine.",
29 };
30 }
31
32 return { status: "ready", version, launcherProtocol: SERVICE_LAUNCHER_PROTOCOL };
33}
34
35export function decodeServicePreflightResult(value: unknown): ServicePreflightResult | undefined {
36 if (typeof value !== "object" || value === null) {
37 return undefined;
38 }
39 const record = value as Record<string, unknown>;
40 if (
41 record.status === "ready" &&
42 record.launcherProtocol === SERVICE_LAUNCHER_PROTOCOL &&
43 typeof record.version === "string"
44 ) {
45 return {
46 status: "ready",
47 version: record.version,
48 launcherProtocol: SERVICE_LAUNCHER_PROTOCOL,
49 };
50 }
51 if (
52 record.status === "blocked" &&
53 typeof record.version === "string" &&
54 typeof record.reason === "string"
55 ) {
56 return { status: "blocked", version: record.version, reason: record.reason };
57 }
58 return undefined;
59}