#!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; import {createRequire} from 'node:module'; import {pathToFileURL} from 'node:url'; const root='/home/mes123456/FreeCADWasmDev/working/FreeCAD'; const build=path.resolve(process.argv[2]??path.join(root,'freecad-source/build-web/configure/bin')); const batch=JSON.parse(fs.readFileSync(path.join(root,'docs/current/module-batch-manifest.json'),'utf8')); if(batch.status!=='ready'||batch.batchId!=='d1559c9c02b8a5787800e864'||batch.selected.module!=='TechDraw'||batch.selected.tier!=='tier-2-pure'||batch.selected.family!=='geometry-value') throw new Error('unexpected batch'); const records=batch.records.map(([apiId,name,disposition,sourcePath])=>({apiId,name,family:batch.selected.family,kind:'method',sourcePath,disposition})); const out='/tmp/freecad-techdraw-geometry-gate'; fs.mkdirSync(out,{recursive:true}); const {execFileSync}=await import('node:child_process'); execFileSync(path.join(root,'web/node_modules/.bin/tsc'),['--target','ES2022','--module','ESNext','--moduleResolution','Bundler','--strict','--skipLibCheck','--outDir',out,'--declaration','false','--noEmit','false',path.join(root,'web/src/facade-envelope.ts'),path.join(root,'web/src/techdraw-python-family-facade.ts')],{cwd:root,stdio:'inherit'}); const facade=await import(pathToFileURL(path.join(out,'techdraw-python-family-facade.js'))); const env=await import(pathToFileURL(path.join(out,'facade-envelope.js'))); globalThis.__dirname=build; globalThis.require=createRequire(import.meta.url); const workerJs=path.join(build,'FreeCADWebTechDrawRuntimeProbe.worker.js'); const workerCjs=path.join(build,'FreeCADWebTechDrawRuntimeProbe.worker.cjs'); if(!fs.existsSync(workerCjs)&&fs.existsSync(workerJs)) fs.copyFileSync(workerJs,workerCjs); const mod=await import(pathToFileURL(path.join(build,'FreeCADWebTechDrawRuntimeProbe.js'))); const kernel=await mod.default({wasmBinary:fs.readFileSync(path.join(build,'FreeCADWebTechDrawRuntimeProbe.wasm')),locateFile:file=>file.endsWith('.worker.js')&&fs.existsSync(workerCjs)?workerCjs:path.join(build,file),print:()=>{},printErr:()=>{}}); const q=new env.FacadeSerialQueue(); const req=facade.createTechDrawPythonFamilyRequest('techdraw-geometry-value',records,'tier-2-pure'); const response=await facade.dispatchTechDrawPythonFamily(q,req,kernel); if(response.kind!=='result') throw new Error(`native dispatch failed: ${JSON.stringify(response)}`); const result=response.result; const repeated=await facade.dispatchTechDrawPythonFamily(q,facade.createTechDrawPythonFamilyRequest('repeat',records,'tier-2-pure'),kernel); if(repeated.kind!=='result'||result.count!==4||result.resourcesReleased!==true||JSON.stringify(result)!==JSON.stringify(repeated.result)||result.records.some(record=>record.status!=='exposed'||record.code!=='native_method_fixture')) throw new Error('invalid native method result'); const hash=v=>crypto.createHash('sha256').update(JSON.stringify(v)).digest('hex'); const fileHash=f=>crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex'); const evidence=`docs/p6/techdraw-geometry-value-module-batch-${batch.batchId}-runtime.json`; const report={schema:'freecad-web-techdraw-geometry-value-module-batch-runtime/v1',taskId:'FW-P6-FPA-Y',batchId:batch.batchId,module:'TechDraw',tier:'tier-2-pure',family:'geometry-value',status:'pass',route:{command:'techdraw.pythonFamilyBatch',native:'freecad-source/src/WebAssembly/FreeCADCoreProbe/TechDrawRuntimeProbe.cpp:fc_web_dispatch_json',facade:'web/src/techdraw-python-family-facade.ts',worker:'web/src/techdraw-python.worker.ts'},input:{cmd:'techdraw.pythonFamilyBatch',args:{tier:'tier-2-pure',records}},result,resultSha256:hash(result),replay:{equal:true,resultSha256:hash(repeated.result)},records:result.records.map(r=>({apiId:r.apiId,name:r.name,status:r.status,code:r.code,message:r.message,parameterSchema:r.parameterSchema,returnSchema:r.returnSchema,result:r.result,sourceEntry:r.sourceEntry,sourceRevision:r.sourceRevision,evidenceSha256:hash(r)})),resources:{resourcesReleased:true,documentMutation:'temporary-native-document-released'},artifacts:{module:'TechDraw',worker:'techdraw-python.worker.ts',revision:result.records[0]?.sourceRevision,runtimeUrl:'/modules/TechDraw/FreeCADWebTechDrawRuntimeProbe.js',wasmUrl:'/modules/TechDraw/FreeCADWebTechDrawRuntimeProbe.wasm',dataUrl:null,assetBaseUrl:'/modules/TechDraw/',runtimeSha256:fileHash(path.join(build,'FreeCADWebTechDrawRuntimeProbe.js')),wasmSha256:fileHash(path.join(build,'FreeCADWebTechDrawRuntimeProbe.wasm')),buildProfile:'fast-dev'},boundaries:['The fixture exercises deterministic native DrawViewPart method contracts; it does not claim desktop TechDrawGui resources.','All values and hashes derive from compiled FreeCAD through fc_web_dispatch_json; no JavaScript method result is substituted.']}; fs.writeFileSync(path.join(root,evidence),JSON.stringify(report,null,2)+'\n'); fs.writeFileSync(path.join(root,`docs/freecad-p6-techdraw-geometry-value-module-batch-${batch.batchId}.log`),JSON.stringify({status:report.status,count:4,resultSha256:report.resultSha256})+'\n'); console.log(JSON.stringify({status:report.status,count:4,resultSha256:report.resultSha256})); process.exit(0);