47 lines
3.4 KiB
TypeScript
47 lines
3.4 KiB
TypeScript
import { db } from '../db/index.js';
|
|
import type { ArtifactKind, ScriptRow, ScriptVersionRow } from './scripts.js';
|
|
|
|
/** Fixed query count regardless of the number of artifacts or retained versions. */
|
|
export function scriptCatalog(kind?: ArtifactKind) {
|
|
const version = (alias: string) => `CASE WHEN ${alias}.id IS NOT NULL THEN json_object(
|
|
'id',${alias}.id,'version',${alias}.version,'release_version',${alias}.release_version,
|
|
'sha256',${alias}.sha256,'size',${alias}.size,'state',${alias}.state,'uploaded_at',${alias}.uploaded_at) END`;
|
|
const rows = db().prepare(`SELECT s.*, ${version('c')} current_json, ${version('v')} latest_json,
|
|
COALESCE(counts.n,0) versionCount, active.beta_id runningBetaId
|
|
FROM scripts s
|
|
LEFT JOIN (SELECT script_id, COUNT(*) n, MAX(version) latest FROM script_versions GROUP BY script_id) counts ON counts.script_id=s.id
|
|
LEFT JOIN script_versions v ON v.script_id=s.id AND v.version=counts.latest
|
|
LEFT JOIN script_versions c ON c.id=s.current_version_id
|
|
LEFT JOIN (SELECT bs.script_id, MIN(b.id) beta_id FROM beta_scripts bs JOIN betas b ON b.id=bs.beta_id
|
|
WHERE b.state IN ('running','ready-promote') GROUP BY bs.script_id) active ON active.script_id=s.id
|
|
${kind ? 'WHERE s.kind=?' : ''} ORDER BY s.name`).all(...(kind ? [kind] : [])) as Array<ScriptRow & {
|
|
current_json: string | null; latest_json: string | null; versionCount: number; runningBetaId: number | null;
|
|
}>;
|
|
const servers = db().prepare('SELECT name, game, map FROM servers ORDER BY name').all() as { name: string; game: string | null; map: string | null }[];
|
|
return rows.map(({ current_json, latest_json, ...row }) => ({ ...row,
|
|
currentVersion: current_json ? JSON.parse(current_json) as ScriptVersionRow : null,
|
|
latestVersion: latest_json ? JSON.parse(latest_json) as ScriptVersionRow : null,
|
|
servers: row.scope_type && row.scope_value ? servers.filter(server => server[row.scope_type!] === row.scope_value).map(server => server.name) : []
|
|
}));
|
|
}
|
|
|
|
export function betaScriptMetadata(ids: number[]) {
|
|
const rows = db().prepare(`SELECT bs.beta_id, bs.script_id id, COALESCE(s.name,'(deleted)') name,
|
|
COALESCE(s.target_rel_path,'') target_rel_path, COALESCE(s.kind,bs.kind,'script') kind,
|
|
v.id version_id, v.version, v.release_version, v.sha256
|
|
FROM beta_scripts bs LEFT JOIN scripts s ON s.id=bs.script_id
|
|
LEFT JOIN script_versions v ON v.id=bs.script_version_id
|
|
WHERE bs.beta_id IN (SELECT value FROM json_each(?)) ORDER BY bs.script_id`).all(JSON.stringify(ids)) as Array<{
|
|
beta_id: number; id: number; name: string; target_rel_path: string; kind: ArtifactKind;
|
|
version_id: number | null; version: number; release_version: string | null; sha256: string;
|
|
}>;
|
|
const grouped = new Map<number, Array<{ id: number; name: string; target_rel_path: string; kind: ArtifactKind;
|
|
version: { id: number; version: number; release_version: string | null; sha256: string } | null }>>();
|
|
for (const { beta_id, version_id, version, release_version, sha256, ...script } of rows) {
|
|
const group = grouped.get(beta_id) ?? [];
|
|
group.push({ ...script, version: version_id === null ? null : { id: version_id, version, release_version, sha256 } });
|
|
grouped.set(beta_id, group);
|
|
}
|
|
return grouped;
|
|
}
|