60 lines
3.0 KiB
JavaScript
60 lines
3.0 KiB
JavaScript
import { createHash } from "node:crypto";
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { dirname, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const packageRoot = resolve(root, "node_modules/@rerun-io/web-viewer");
|
|
const vendorRoot = resolve(root, "vendor/rerun-web-viewer-0.36.3");
|
|
const manifest = JSON.parse(readFileSync(resolve(vendorRoot, "navigation-build.json"), "utf8"));
|
|
const installed = JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8"));
|
|
const sha = bytes => createHash("sha256").update(bytes).digest("hex");
|
|
if (installed.version !== "0.36.3" || manifest.upstreamVersion !== installed.version) {
|
|
throw new Error("Rerun navigation requires the audited 0.36.3 package; rebase before upgrading");
|
|
}
|
|
if (sha(readFileSync(resolve(vendorRoot, "NODEDC_NAVIGATION.patch"))) !== manifest.patchSha256) {
|
|
throw new Error("Rerun navigation source patch identity mismatch");
|
|
}
|
|
|
|
const eyeType = "{ position: [number, number, number]; lookTarget: [number, number, number]; eyeUp: [number, number, number] } | null";
|
|
const additions = {
|
|
"index.js": {
|
|
marker: " get_active_recording_id() {",
|
|
code: ` get_camera_eye() {\n if (!this.#handle) throw new Error("Rerun viewer is stopped");\n return JSON.parse(this.#handle.nodedc_camera_eye() ?? "null");\n }\n`,
|
|
},
|
|
"index.ts": {
|
|
marker: " get_active_recording_id(): string | null {",
|
|
code: ` get_camera_eye(): ${eyeType} {\n if (!this.#handle) throw new Error("Rerun viewer is stopped");\n return JSON.parse(this.#handle.nodedc_camera_eye() ?? "null");\n }\n`,
|
|
},
|
|
"index.d.ts": {
|
|
marker: " get_active_recording_id(): string | null;",
|
|
code: ` get_camera_eye(): ${eyeType};\n`,
|
|
},
|
|
};
|
|
|
|
// Validate the complete set before changing any installed file. A package
|
|
// upgrade, corrupt artifact or independently modified wrapper fails closed.
|
|
const writes = [];
|
|
for (const [name, identity] of Object.entries(manifest.files)) {
|
|
const current = readFileSync(resolve(packageRoot, name));
|
|
let output;
|
|
if (additions[name]) {
|
|
const { marker, code } = additions[name];
|
|
const source = current.toString("utf8");
|
|
const original = source.includes(code) ? source.replace(code, "") : source;
|
|
if (sha(original) !== identity.upstreamSha256 || original.split(marker).length !== 2) {
|
|
throw new Error(`Unexpected upstream wrapper: ${name}`);
|
|
}
|
|
output = Buffer.from(original.replace(marker, code + marker));
|
|
} else {
|
|
output = readFileSync(resolve(vendorRoot, identity.artifact));
|
|
if (sha(output) !== identity.sha256) throw new Error(`Corrupt navigation artifact: ${name}`);
|
|
if (![identity.upstreamSha256, identity.sha256].includes(sha(current))) {
|
|
throw new Error(`Unexpected installed runtime: ${name}`);
|
|
}
|
|
}
|
|
writes.push([resolve(packageRoot, name), output]);
|
|
}
|
|
for (const [path, output] of writes) writeFileSync(path, output);
|
|
console.log("Installed NODE.DC Rerun 0.36.3 navigation/v1 (native camera, one renderer).");
|