mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 16:02:55 +00:00
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import { z } from 'zod'
|
|
import { ORCA_VM_RECIPE_ID_PATTERN, ORCA_VM_RECIPE_ID_RULE } from '../orca-yaml'
|
|
import type { OrcaVmRecipe } from '../types'
|
|
|
|
const recipeCommandSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1)
|
|
.max(32 * 1024)
|
|
.refine((value) => !value.includes('\0'), 'must not contain NUL bytes')
|
|
|
|
const pluginVmRecipeArtifactSchema = z
|
|
.object({
|
|
schemaVersion: z.literal(1),
|
|
id: z.string().regex(ORCA_VM_RECIPE_ID_PATTERN, ORCA_VM_RECIPE_ID_RULE),
|
|
name: z.string().trim().min(1).max(128),
|
|
description: z.string().trim().min(1).max(1024).optional(),
|
|
create: recipeCommandSchema,
|
|
suspend: recipeCommandSchema.optional(),
|
|
resume: recipeCommandSchema.optional(),
|
|
destroy: z.union([recipeCommandSchema, z.literal('none')]).optional()
|
|
})
|
|
.strict()
|
|
.superRefine((recipe, ctx) => {
|
|
if (Boolean(recipe.suspend) !== Boolean(recipe.resume)) {
|
|
ctx.addIssue({
|
|
code: 'custom',
|
|
path: recipe.suspend ? ['resume'] : ['suspend'],
|
|
message: 'suspend and resume must be declared together'
|
|
})
|
|
}
|
|
})
|
|
|
|
export type PluginVmRecipeCommand = {
|
|
phase: 'create' | 'suspend' | 'resume' | 'destroy'
|
|
command: string
|
|
}
|
|
|
|
export function parsePluginVmRecipeArtifact(raw: string): OrcaVmRecipe {
|
|
const parsed = pluginVmRecipeArtifactSchema.parse(JSON.parse(raw))
|
|
const destroyDisabled = parsed.destroy === 'none'
|
|
return {
|
|
id: parsed.id,
|
|
name: parsed.name,
|
|
create: parsed.create,
|
|
...(parsed.description ? { description: parsed.description } : {}),
|
|
...(parsed.suspend ? { suspend: parsed.suspend } : {}),
|
|
...(parsed.resume ? { resume: parsed.resume } : {}),
|
|
...(parsed.destroy && !destroyDisabled ? { destroy: parsed.destroy } : {}),
|
|
...(destroyDisabled ? { destroyDisabled: true } : {})
|
|
}
|
|
}
|
|
|
|
export function listPluginVmRecipeCommands(recipe: OrcaVmRecipe): PluginVmRecipeCommand[] {
|
|
return [
|
|
{ phase: 'create', command: recipe.create },
|
|
...(recipe.suspend ? [{ phase: 'suspend' as const, command: recipe.suspend }] : []),
|
|
...(recipe.resume ? [{ phase: 'resume' as const, command: recipe.resume }] : []),
|
|
...(recipe.destroy
|
|
? [{ phase: 'destroy' as const, command: recipe.destroy }]
|
|
: recipe.destroyDisabled
|
|
? [{ phase: 'destroy' as const, command: 'none' }]
|
|
: [])
|
|
]
|
|
}
|