| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- import fs from 'node:fs';
- import path from 'node:path';
- import crypto from 'node:crypto';
- import {fileURLToPath} from 'node:url';
- const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
- const manifest=JSON.parse(fs.readFileSync(path.join(root,'deploy/industry-ui-files.json')));
- const args=process.argv.slice(2);
- if(args.length&&!(args.length===2&&args[0]==='--origin'))throw Error('USAGE: --origin https://kangshifu.fmode.cn');
- const base=new URL(args[1]||'https://kangshifu.fmode.cn');
- if(!['https:','http:'].includes(base.protocol)||base.username||base.password||base.pathname!=='/')throw Error('INVALID_ORIGIN');
- const sha=b=>crypto.createHash('sha256').update(b).digest('hex');
- const normal=b=>Buffer.from(b.toString('utf8').replaceAll('\r\n','\n'));
- const result={ok:false,release:manifest.release,checkedAt:new Date().toISOString(),origin:base.origin,modules:[],checks:[],productionWrites:0,paidCalls:0};
- const check=(name,ok)=>{result.checks.push({name,ok:!!ok});};
- const post=async(endpoint,body)=>{
- const res=await fetch(new URL(endpoint,base),{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(body),signal:AbortSignal.timeout(30000)});
- const data=await res.json();if(!res.ok||!data.ok)throw Error('API_READ_FAILED:'+endpoint+':'+body.op);
- check(endpoint+':'+body.op+':readOnly',data.readOnly===true&&data.databaseWrites===0);return data;
- };
- try{
- for(const file of manifest.files){
- const url=new URL(file.path,base);url.searchParams.set('r14verify',String(Date.now()));
- const res=await fetch(url,{headers:{'cache-control':'no-cache'},signal:AbortSignal.timeout(30000)});const bytes=Buffer.from(await res.arrayBuffer());
- const row={path:file.path,status:res.status,contentType:res.headers.get('content-type'),bytes:bytes.length,sha256:sha(bytes),normalizedSha256:sha(normal(bytes)),cacheControl:res.headers.get('cache-control'),etag:res.headers.get('etag')};
- row.matches=res.ok&&row.contentType?.includes('javascript')&&row.normalizedSha256===file.sha256;result.modules.push(row);
- }
- check('all-11-public-modules',result.modules.length===11&&result.modules.every(m=>m.matches));
- const home=await fetch(new URL('index.html',base),{headers:{'cache-control':'no-cache'},signal:AbortSignal.timeout(30000)});
- result.homepageSha256=sha(Buffer.from(await home.arrayBuffer()));check('homepage-unchanged',home.ok&&result.homepageSha256===manifest.homepageSha256);
- const s=await post('api/library',{op:'summary'}),c=await post('api/industry',{op:'contract'}),w=await post('api/industry',{op:'workshop',filters:{category:'banmian'}});
- result.generation=s.generation;result.counts=s.counts;result.analysisCounts=s.analysisCounts;result.defaultScope=w.scope;
- check('generation-consistent',s.generation===c.generation&&s.generation===w.generation);
- check('8-groups-52-options',Object.keys(w.dimensions).length===8&&Object.values(w.dimensions).flat().length===52);
- const iBrand=await post('api/industry',{op:'workshop',filters:{platform:'jd',brand:'tongyi'}});
- const iShop=await post('api/industry',{op:'workshop',filters:{platform:'jd',shopId:'1000084104'}});
- check('industry-brand-limits-shops',!iBrand.rangeFacets.shopId.some(r=>r.value==='1000084104'&&r.products>0));
- check('industry-shop-limits-brands',iShop.rangeFacets.brand.some(r=>r.value==='ksf'&&r.products>0)&&iShop.rangeFacets.brand.every(r=>r.value!=='tongyi'||!r.products));
- const lBrand=await post('api/library',{op:'browse',entity:'products',quality:'audit',filters:{platform:'jd',brand:'tongyi'},limit:1});
- const lShop=await post('api/library',{op:'browse',entity:'products',quality:'audit',filters:{platform:'jd',shopId:'1000084104'},limit:1});
- check('library-brand-limits-shops',!lBrand.facets.shopId.rows.some(r=>r.shop_id==='1000084104'&&r.recordCount>0));
- check('library-shop-limits-brands',lShop.facets.brand.rows.some(r=>r.brand==='ksf'&&r.recordCount>0)&&lShop.facets.brand.rows.every(r=>r.brand!=='tongyi'||!r.recordCount));
- const p=await post('api/industry',{op:'policies'});const review=p.applications.reviewedEvidence;
- result.policy={verified:review.verifiedClauses,pending:review.pendingClauses,originals:review.originalDocuments};
- check('policy-review-remains-12-19-13',result.policy.verified===12&&result.policy.pending===19&&result.policy.originals===13);
- result.ok=result.checks.every(c=>c.ok);
- }catch(e){result.error=e.message;}
- console.log(JSON.stringify(result,null,2));if(!result.ok)process.exitCode=1;
|