import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const sourcePath = path.join(root, "tests/files/web/m12_stl_capability_v1/capability-binary.stl"); const outputRoot = path.join(root, "tests/files/web/m12_stl_edges_v1"); const reportPath = path.join(root, "tests/golden/M12-07E/edge-fixtures.json"); const sha256 = (bytes) => crypto.createHash("sha256").update(bytes).digest("hex"); fs.mkdirSync(outputRoot, { recursive: true }); fs.mkdirSync(path.dirname(reportPath), { recursive: true }); const source = fs.readFileSync(sourcePath); if (source.length !== 184 || source.readUInt32LE(80) !== 2) throw new Error("M12-07D binary parent fixture drifted"); fs.writeFileSync(path.join(outputRoot, "capability-binary.stl"), source); const degenerate = Buffer.from(source); const firstVertex = Buffer.from(degenerate.subarray(84 + 12, 84 + 24)); firstVertex.copy(degenerate, 84 + 24); firstVertex.copy(degenerate, 84 + 36); const trailing = Buffer.concat([source, Buffer.from([0xde, 0xad, 0xbe, 0xef])]); const outputs = [ { id: "DEGENERATE_TRIANGLE", name: "degenerate-binary.stl", bytes: degenerate, expectedCode: "STL_DEGENERATE_TRIANGLE" }, { id: "TRAILING_BYTES", name: "trailing-binary.stl", bytes: trailing, expectedCode: "STL_TRAILING_BYTES" }, ]; for (const output of outputs) fs.writeFileSync(path.join(outputRoot, output.name), output.bytes); const report = { schemaVersion: 1, task: "M12-07E", operation: "STL_EDGE_FIXTURE_GENERATION", parent: { path: "tests/files/web/m12_stl_capability_v1/capability-binary.stl", byteLength: source.length, sha256: sha256(source) }, fixtures: outputs.map((output) => ({ id: output.id, file: output.name, byteLength: output.bytes.length, sha256: sha256(output.bytes), expectedCode: output.expectedCode })), nextTask: "M12-07F", }; fs.writeFileSync(reportPath, JSON.stringify(report, null, 2) + "\n"); process.stdout.write(`stl-edge-fixtures-generated cases=${outputs.length} next=${report.nextTask}\n`);