Files
etcprs/src/routes/api/admin/replace-binary/+server.js
2026-03-18 03:06:27 -06:00

62 lines
1.9 KiB
JavaScript

import { json, error } from '@sveltejs/kit';
import { getPersonalityById, replacePersonalityBinary } from '$lib/server/db.js';
import { verifySession, SESSION_COOKIE } from '$lib/server/session.js';
import { FILE_SIZE } from '$lib/prs.js';
const NAME_OFFSET = 0x0e;
const NAME_LEN = 12;
const CH_COUNT_OFFSET = 0x0d;
function readPrsName(bytes) {
let name = '';
for (let i = 0; i < NAME_LEN; i++) {
if (bytes[NAME_OFFSET + i] === 0) break;
name += String.fromCharCode(bytes[NAME_OFFSET + i]);
}
return name.trim();
}
export async function POST({ request, cookies }) {
const session = verifySession(cookies.get(SESSION_COOKIE));
if (!session) throw error(401, 'Unauthorized');
const body = await request.json().catch(() => null);
if (!body?.id || !body?.data) throw error(400, 'Missing id or data');
const record = getPersonalityById(body.id);
if (!record) throw error(404, 'Personality not found');
if (record.deleted_at) throw error(400, 'Cannot replace binary of a deleted personality');
const bytes = new Uint8Array(body.data);
if (bytes.length !== FILE_SIZE) {
throw error(400, `Invalid file size: expected ${FILE_SIZE} bytes, got ${bytes.length}`);
}
const newPrsName = readPrsName(bytes);
const newChannelCount = bytes[CH_COUNT_OFFSET];
// Preview mode — return diff without saving
if (body.preview) {
return json({
preview: true,
current: {
prs_name: record.prs_name ?? '',
channel_count: record.channel_count
},
incoming: {
prs_name: newPrsName,
channel_count: newChannelCount
}
});
}
// Commit — replace the binary
replacePersonalityBinary(body.id, {
data: Buffer.from(bytes),
prs_name: newPrsName,
channel_count: newChannelCount
});
return json({ success: true, prs_name: newPrsName, channel_count: newChannelCount });
}