62 lines
1.9 KiB
JavaScript
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 });
|
|
}
|