From f8fde443f52d067e2b7391ff8b89bbaf971d0f8d Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Mon, 26 Oct 2026 17:25:10 +0800 Subject: [PATCH] Preflight API capabilities before publishing content data --- scripts/publish-layout-reference.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/publish-layout-reference.mjs b/scripts/publish-layout-reference.mjs index 5b3745c..80956ed 100644 --- a/scripts/publish-layout-reference.mjs +++ b/scripts/publish-layout-reference.mjs @@ -25,6 +25,8 @@ for(const name of [...assetNames].sort()){ if(!state.assets[hash]&&!pending.some(a=>a.hash===hash))pending.push({name,bytes,hash}); } if(!dryRun){ + const capabilities=await Promise.all(['/api/upload?agent_mode=True','/api/posts?agent_mode=True'].map(async url=>{const r=await fetch(base+url,{signal:AbortSignal.timeout(30000)});if(!r.ok)throw Error('无法读取 API 能力说明');return r.text()})); + if(!capabilities[0].includes('assetOnly')||!capabilities[1].includes('publicId'))throw Error('目标站点尚未部署所需通用 API,停止发布'); for(let offset=0;offsetx.id===l.id).elements)for(const key of ['asset','mask','underlay'])if(e[key])extra.add(e[key].slice('asset:'.length)); posts.push({key:l.id,publicId:ids[l.id],slug:'layout-reference-'+l.id,title:l.id+' · '+l.name,description:`${l.id} 原图一一对应:${text.length} 组文字、${images.length} 组图位、${decor.length} 组装饰;含图像、坐标及 HTML/React/Next.js 示例。`,markdown,main:[`${l.id}/source.png`,`${l.id}/annotated.png`,`${l.id}/text-map.png`,`${l.id}/image-map.png`,`${l.id}/decoration-map.png`],extra:[...extra]}); } -for(const p of posts){if(p.markdown.length>100000)throw Error('正文超长 '+p.key);if(p.markdown.includes('/layout-reference/'))throw Error('正文仍有专用静态路径 '+p.key)} +for(const p of posts){p.markdown=p.markdown.trim();if(p.markdown.length>100000)throw Error('正文超长 '+p.key);if(p.markdown.includes('/layout-reference/'))throw Error('正文仍有专用静态路径 '+p.key)} if(dryRun){console.log(JSON.stringify({posts:posts.length,uniqueFiles:assetNames.size,uniqueHashes:new Set(Object.values(byFile).map(a=>a.hash)).size,maxText:Math.max(...posts.map(p=>p.markdown.length)),cover:'router-cover.png'}));process.exit(0)} const tag=await api('/api/tags',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:'高级感排版',slug:'premium-layout'})}); for(const p of [...posts.slice(1),posts[0]]){