Files
probably-rendering-one-more…/apps/waterfall-wiki/src/lib/studio-series.ts
T
codex-bot 174a3ef266
studio CI and deployment / verify-and-deploy (pull_request) Failing after 3m51s
waterfall-wiki CI and deployment / verify-and-deploy (pull_request) Failing after 2m58s
Add versioned multi-page Studio artwork documents and native exports
2026-10-28 23:36:54 +08:00

26 lines
2.0 KiB
TypeScript

import {randomUUID} from 'node:crypto';
import {z} from 'zod';
import {db,transaction} from './db';
import {series,pageParameters} from './series';
import layouts from '../content/studio-layouts.json';
import standard from '../content/standard-layout.json';
import {validateDesign,designOutput,DesignConflict} from './studio-designs';
import {ensureDesignPost} from './studio-design-posts';
const all=[...layouts,standard];
export const seriesInput=z.object({schemaVersion:z.literal(2),name:z.string().trim().min(1).max(120),document:z.unknown()}).strict();
export const seriesUpdate=seriesInput.extend({revision:z.number().int().positive()});
export async function saveSeries(input:z.infer<typeof seriesInput>,id?:string,revision?:number){
const document=series(input.document,all);
return transaction(async client=>{
const old=id?(await client.query('SELECT * FROM studio_designs WHERE id=$1 FOR UPDATE',[id])).rows[0]:null;
if(id&&!old)return null;
if(old&&(!old.document||old.archived||old.revision!==revision))throw new DesignConflict('作品类型、归档状态或修订号冲突');
for(const page of document.pages)await validateDesign(page.layoutId,page.parameters,client);
const cover=document.pages[0],layout=all.find(l=>l.id===cover.layoutId)!;
const p=pageParameters(document,cover,layout);
const row=id?(await client.query('UPDATE studio_designs SET name=$2,layout_id=$3,parameters=$4,document=$5,revision=revision+1,updated_at=now() WHERE id=$1 RETURNING *',[id,input.name,cover.layoutId,JSON.stringify(p),JSON.stringify(document)])).rows[0]:(await client.query('INSERT INTO studio_designs(id,name,layout_id,parameters,document) VALUES($1,$2,$3,$4,$5) RETURNING *',[randomUUID(),input.name,cover.layoutId,JSON.stringify(p),JSON.stringify(document)])).rows[0];
return designOutput(await ensureDesignPost(client,row));
});
}
export async function readSeries(id:string){const row=(await db().query('SELECT * FROM studio_designs WHERE id=$1 AND document IS NOT NULL',[id])).rows[0];return row?designOutput(row):null}