import path from "node:path"; function parseCoordinate(value, label) { let x; let z; if (Array.isArray(value) && value.length === 2) { [x, z] = value; } else if (value && typeof value === "object") { ({ x, z } = value); } else if (typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 0xffffffff) { x = value >>> 16; z = value & 0xffff; } else if (typeof value === "string") { const normalized = value.trim().replace(/^\[/, "").replace(/\]$/, ""); const match = /^(?:chunk-x)?(-?\d+)(?:-z|,)(-?\d+)$/i.exec(normalized); if (match) [, x, z] = match; } x = Number(x); z = Number(z); if (!Number.isInteger(x) || !Number.isInteger(z) || x < 0 || x > 0xffff || z < 0 || z > 0xffff) { throw new Error(`${label} must identify non-negative uint16 chunk coordinates.`); } return { x, z, key: ((x << 16) | z) >>> 0 }; } export function parseNativeWaterBuildArgs(argv) { const options = {}; const valueOptions = new Set([ "recipe", "source-root", "wdb-report", "output-root", "ground-manifest", "audit-cache-root", ]); for (let index = 0; index < argv.length; index += 1) { const token = argv[index]; if (token === "--help" || token === "-h") return { help: true }; if (!token.startsWith("--")) throw new Error(`Unexpected positional argument: ${token}`); const name = token.slice(2); if (!valueOptions.has(name)) throw new Error(`Unknown option --${name}.`); if (options[name] !== undefined) throw new Error(`Option --${name} may only be supplied once.`); const value = argv[index + 1]; if (!value || value.startsWith("--")) throw new Error(`Option --${name} requires a value.`); options[name] = value; index += 1; } return { help: false, ...options }; } export function chunkCoordinateFromManifestRow(row) { if (row?.coordinate !== undefined) return parseCoordinate(row.coordinate, "Ground-manifest chunk coordinate"); if (row?.key !== undefined) return parseCoordinate(row.key, "Ground-manifest chunk key"); if (row?.id !== undefined) return parseCoordinate(row.id, "Ground-manifest chunk id"); throw new Error("Ground-manifest chunk row has no coordinate, key, or id."); } export function selectNativeWaterChunkKeys({ wdbChunkKeys, groundManifest, sourceWdbSha256 }) { const available = new Set(wdbChunkKeys.map((key) => Number(key) >>> 0)); if (!groundManifest) return { selectedKeys: [...available].sort((a, b) => a - b), selection: { kind: "all-wdb-chunks" } }; const manifestSha = groundManifest.source?.wdbSha256 ?? groundManifest.sourceWdbSha256; if (typeof manifestSha !== "string" || !/^[a-f\d]{64}$/i.test(manifestSha)) { throw new Error("Ground manifest must include source.wdbSha256 or sourceWdbSha256 to bind it to its source WDB."); } if (manifestSha.toLowerCase() !== sourceWdbSha256.toLowerCase()) { throw new Error("Ground manifest source WDB SHA-256 does not match the water source WDB."); } if (!Array.isArray(groundManifest.chunks) || groundManifest.chunks.length === 0) { throw new Error("Ground manifest must contain a non-empty chunks array."); } const coordinates = groundManifest.chunks.map(chunkCoordinateFromManifestRow); const selectedKeys = new Set(); for (const coordinate of coordinates) { if (!available.has(coordinate.key)) { throw new Error(`Ground-manifest chunk [${coordinate.x},${coordinate.z}] is absent from the source WDB chunk table.`); } if (selectedKeys.has(coordinate.key)) { throw new Error(`Ground manifest repeats chunk [${coordinate.x},${coordinate.z}].`); } selectedKeys.add(coordinate.key); } return { selectedKeys: [...selectedKeys].sort((a, b) => a - b), selection: { kind: "ground-manifest-chunks", chunkCount: selectedKeys.size, coordinates: coordinates.map(({ x, z }) => ({ x, z })), }, }; } export function ensureWithinProject(projectRoot, outputPath) { const resolved = path.resolve(outputPath); const relative = path.relative(path.resolve(projectRoot), resolved); if (!relative || relative === ".") return resolved; if (path.isAbsolute(relative) || relative === ".." || relative.startsWith(`..${path.sep}`)) { throw new Error(`Output path must stay inside the project workspace: ${outputPath}`); } return resolved; }