28 lines
2.3 KiB
TypeScript
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'}}};
|