import { json } from '@sveltejs/kit'; import { createScript, listScripts, listVersions, serversMatchingScope, ScriptError, type ScopeType } from '$lib/server/fleet/scripts.js'; import { findRunningBetaForScript } from '$lib/server/fleet/beta.js'; function scopeTypeOrNull(v: FormDataEntryValue | null): ScopeType | null { if (v === null) return null; const s = String(v); if (s === '' || s === 'none') return null; if (s === 'game' || s === 'map') return s; throw new ScriptError(`invalid scope_type: ${s}`, 'invalid-scope'); } export async function GET() { const scripts = listScripts().map((s) => { const versions = listVersions(s.id); const matched = s.scope_type && s.scope_value ? serversMatchingScope(s.scope_type as ScopeType, s.scope_value) : []; const runningBeta = findRunningBetaForScript(s.id); return { ...s, latestVersion: versions[0] ? { id: versions[0].id, version: versions[0].version, sha256: versions[0].sha256, size: versions[0].size, uploaded_at: versions[0].uploaded_at } : null, versionCount: versions.length, servers: matched, runningBetaId: runningBeta?.id ?? null }; }); return json({ scripts }); } // Multipart POST — creates a script + version 1 from a single file upload. // Fields: name (text), scopeType (optional: 'game'|'map'), scopeValue // (optional string), notes (optional), content (file). The target rel path // defaults to the uploaded filename — T5 servers keep all scripts in a flat // sp/ directory, so there's no sub-path to specify. export async function POST({ request }: { request: Request }) { const form = await request.formData(); const name = String(form.get('name') ?? '').trim(); const notes = form.get('notes') ? String(form.get('notes')) : undefined; let scopeType: ScopeType | null; try { scopeType = scopeTypeOrNull(form.get('scopeType')); } catch (err) { return json({ ok: false, error: (err as Error).message }, { status: 400 }); } const scopeValueRaw = form.get('scopeValue'); const scopeValue = scopeValueRaw ? String(scopeValueRaw).trim() : null; const file = form.get('content'); if (!(file instanceof File)) return json({ ok: false, error: 'content file is required' }, { status: 400 }); const targetRelPath = file.name; const content = Buffer.from(await file.arrayBuffer()); try { const { script, version } = createScript({ name, targetRelPath, scopeType, scopeValue, content, notes }); return json({ ok: true, script, versionId: version.id }); } catch (err) { if (err instanceof ScriptError) { return json({ ok: false, error: err.message, kind: err.kind }, { status: 409 }); } throw err; } }