const [origin,environment]=process.argv.slice(2); if(!origin||!['test','production'].includes(environment))throw new Error('Usage: node scripts/check-health.mjs test|production'); async function read(path) { const response=await fetch(new URL(path,origin),{signal:AbortSignal.timeout(5000),redirect:'error',cache:'no-store'}); if(response.status!==200)throw new Error(`${path} HTTP ${response.status}`); let text='',size=0; const decoder=new TextDecoder(); for await(const part of response.body) { size+=part.length;if(size>1048576)throw new Error(`${path} 响应超过检查上限`); text+=decoder.decode(part,{stream:true}); if(path==='/'&&text.includes('/_next/'))break; } return {text,type:response.headers.get('content-type')||''}; } let healthy=false; for(let attempt=1;attempt<=5;attempt++) { try { const health=await read('/healthz'),status=JSON.parse(health.text); if(status.status!=='ok'||status.environment!==environment||status.application!=='jha-1049-sgdj-web')throw new Error('/healthz 未命中本站对应环境'); const home=await read('/'); if(!/^text\/html(?:;|$)/i.test(home.type)||!home.text.includes('/_next/'))throw new Error('首页不是 Next HTML'); healthy=true;console.log('/healthz 与 Next 首页检查通过');break; }catch(error) { console.error(`健康检查 ${attempt}/5 失败:${error.message}`); if(attempt<5)await new Promise(resolve=>setTimeout(resolve,1000)); } } process.exitCode=healthy?0:1;