import { z } from "@start9labs/start-sdk" import { matchVolume } from "./matchVolume" import { matchDockerProcedure } from "../../../Models/DockerProcedure" const matchJsProcedure = z.object({ type: z.literal("script"), args: z.array(z.unknown()).nullable().optional().default([]), }) const matchProcedure = z.union([matchDockerProcedure, matchJsProcedure]) export type Procedure = z.infer const healthCheckFields = { name: z.string(), "success-message": z.string().nullable().optional(), } const matchAction = z.object({ name: z.string(), description: z.string(), warning: z.string().nullable().optional(), implementation: matchProcedure, "allowed-statuses": z.array(z.enum(["running", "stopped"])), "input-spec": z.unknown().nullable().optional(), }) export const matchManifest = z.object({ id: z.string(), title: z.string(), version: z.string(), main: matchDockerProcedure, assets: z .object({ assets: z.string().nullable().optional(), scripts: z.string().nullable().optional(), }) .nullable() .optional(), "health-checks": z.record( z.string(), z.union([ matchDockerProcedure.extend(healthCheckFields), matchJsProcedure.extend(healthCheckFields), ]), ), config: z .object({ get: matchProcedure, set: matchProcedure, }) .nullable() .optional(), properties: matchProcedure.nullable().optional(), volumes: z.record(z.string(), matchVolume), interfaces: z.record( z.string(), z.object({ name: z.string(), description: z.string(), "tor-config": z .object({ "port-mapping": z.record(z.string(), z.string()), }) .nullable() .optional(), "lan-config": z .record( z.string(), z.object({ ssl: z.boolean(), internal: z.number(), }), ) .nullable() .optional(), ui: z.boolean(), protocols: z.array(z.string()), }), ), backup: z.object({ create: matchProcedure, restore: matchProcedure, }), migrations: z .object({ to: z.record(z.string(), matchProcedure), from: z.record(z.string(), matchProcedure), }) .nullable() .optional(), dependencies: z.record( z.string(), z .object({ version: z.string(), requirement: z.union([ z.object({ type: z.literal("opt-in"), how: z.string(), }), z.object({ type: z.literal("opt-out"), how: z.string(), }), z.object({ type: z.literal("required"), }), ]), description: z.string().nullable().optional(), config: z .object({ check: matchProcedure, "auto-configure": matchProcedure, }) .nullable() .optional(), }) .nullable() .optional(), ), actions: z.record(z.string(), matchAction), }) export type Manifest = z.infer