Files
probably-rendering-one-more…/apps/studio/src/pages/api/export/[slug].ts
T

28 lines
2.3 KiB
TypeScript

import {embedSvgMedia} from '../../../lib/layout-images';
import {renderToStaticMarkup} from 'react-dom/server';
import {serveApiDocumentation} from '../../../lib/api-documentation';
import type {NextApiRequest,NextApiResponse} from 'next';
import {ideas,ideaMarkdown} from '../../../content/ideas';
import {selections} from '../../../components/SourceCover';
import {renderCover} from '../../../lib/render-cover';
import {tutorialPost} from '../../../content/tool-links';
export default async function handler(req:NextApiRequest,res:NextApiResponse){
if(serveApiDocumentation(req,res,'/studio/api/export/{slug}'))return;
if(!['GET','POST'].includes(req.method||'')){res.setHeader('Allow','GET, POST');return res.status(405).end();}
const slug=String(req.query.slug||''),idea=ideas.find(i=>i.slug===slug);if(!idea)return res.status(404).end();
if(req.method==='POST'||req.query.format==='svg'){
if(req.query.format!==undefined&&!['svg','json'].includes(String(req.query.format)))return res.status(400).json({error:'渲染格式必须为 svg 或 json'});
try{
const raw=req.query.slide??'0';if(req.method==='GET'&&(typeof raw!=='string'||!/^\d+$/.test(raw)))throw Error('无效 slide');
const input=req.method==='POST'?req.body:idea.tool?{layoutId:req.query.layoutId??selections[0].id}:{slide:Number(raw)};
const result=renderCover(slug,input);res.setHeader('Cache-Control','no-store');
res.setHeader('Content-Disposition',`attachment; filename="${slug}.${req.query.format==='json'?'json':'svg'}"`);
if(req.query.format==='json')return res.json(result.data);
res.setHeader('Content-Type','image/svg+xml; charset=utf-8');return res.send(await embedSvgMedia(req,renderToStaticMarkup(result.node)));
}catch(error){return res.status(400).json({error:error instanceof Error?error.message:'无效参数'});}
}
if(req.query.format==='markdown'){res.setHeader('Content-Type','text/markdown; charset=utf-8');return res.send(ideaMarkdown(idea)+'\n\n使用教程:'+tutorialPost+(idea.tool?'\n\n```json\n'+JSON.stringify(selections,null,2)+'\n```':''));}
res.setHeader('Content-Disposition',`attachment; filename="${idea.slug}.json"`);return res.json({version:idea.tool?3:idea.template?2:1,...idea,...(idea.tool?{layouts:selections}:{}),tutorialPost});
}
export const config={api:{bodyParser:{sizeLimit:'32kb'}}};