Add GitHub plugin release imports and update discovery

This commit is contained in:
2026-09-18 01:29:38 -04:00
parent a718efc9e7
commit 3c49437bf9
16 changed files with 847 additions and 2 deletions
@@ -0,0 +1,20 @@
import { json } from '@sveltejs/kit';
import { importPluginRelease } from '$lib/server/fleet/plugin-releases.js';
import { GithubReleaseError } from '$lib/server/integrations/github-releases.js';
import { ScriptError } from '$lib/server/fleet/scripts.js';
export async function POST({ request }: { request: Request }) {
let input;
try { input = await request.json(); } catch { return json({ error: 'Invalid JSON body.' }, { status: 400 }); }
if (!input || typeof input !== 'object' || Array.isArray(input)) return json({ error: 'Import details are required.' }, { status: 400 });
if ((input.scopeType != null && input.scopeType !== 'game' && input.scopeType !== 'map') ||
(input.scopeValue != null && typeof input.scopeValue !== 'string')) {
return json({ error: 'Invalid plugin scope.' }, { status: 400 });
}
try { return json({ ok: true, ...await importPluginRelease(input) }); }
catch (error) {
if (error instanceof GithubReleaseError) return json({ error: error.message }, { status: error.status });
if (error instanceof ScriptError) return json({ error: error.message }, { status: 409 });
throw error;
}
}
@@ -0,0 +1,10 @@
import { json } from '@sveltejs/kit';
import { getGithubRelease, GithubReleaseError } from '$lib/server/integrations/github-releases.js';
export async function GET({ url }: { url: URL }) {
try { return json({ release: await getGithubRelease(url.searchParams.get('url') ?? '') }); }
catch (error) {
if (error instanceof GithubReleaseError) return json({ error: error.message }, { status: error.status });
throw error;
}
}
+25
View File
@@ -0,0 +1,25 @@
import { json } from '@sveltejs/kit';
import { listScripts } from '$lib/server/fleet/scripts.js';
import { checkPluginUpdate } from '$lib/server/fleet/plugin-releases.js';
import { GithubReleaseError } from '$lib/server/integrations/github-releases.js';
import type { PluginUpdate } from '$lib/plugin-github.js';
export async function GET({ url }: { url: URL }) {
const raw = url.searchParams.get('pluginId');
if (raw !== null) {
const id = Number(raw);
if (!Number.isSafeInteger(id) || id < 1) return json({ error: 'Invalid plugin id.' }, { status: 400 });
try { return json({ updates: [await checkPluginUpdate(id)] }); }
catch (error) {
if (error instanceof GithubReleaseError) return json({ error: error.message }, { status: error.status });
throw error;
}
}
const plugins = listScripts('plugin');
const updates: PluginUpdate[] = [];
// Bound outbound concurrency for large fleets; repository requests share a five-minute cache.
for (let i = 0; i < plugins.length; i += 4) {
updates.push(...await Promise.all(plugins.slice(i, i + 4).map(p => checkPluginUpdate(p.id))));
}
return json({ updates });
}
+5
View File
@@ -8,6 +8,8 @@ import {
type ScopeType
} from '$lib/server/fleet/scripts.js';
import { findRunningBetaForScript } from '$lib/server/fleet/beta.js';
import { db } from '$lib/server/db/index.js';
import type { PluginSource } from '$lib/plugin-github.js';
function parseId(idRaw: string): number | null {
const n = Number.parseInt(idRaw, 10);
@@ -27,6 +29,9 @@ export async function GET({ params }: { params: { id: string } }) {
sha256: v.sha256,
size: v.size,
notes: v.notes,
source: script.kind === 'plugin'
? db().prepare('SELECT * FROM plugin_imports WHERE version_id = ?').get(v.id) as PluginSource | undefined ?? null
: null,
state: v.state,
uploaded_at: v.uploaded_at
}));