@bcts/provenance-mark-cli 1.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +48 -0
- package/README.md +177 -0
- package/dist/cli.cjs +129 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +130 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.cjs +27 -0
- package/dist/index.d.cts +332 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +332 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/src-Bu1tG89l.mjs +705 -0
- package/dist/src-Bu1tG89l.mjs.map +1 -0
- package/dist/src-XNNUeTzh.cjs +889 -0
- package/dist/src-XNNUeTzh.cjs.map +1 -0
- package/package.json +88 -0
- package/src/cli.ts +243 -0
- package/src/cmd/index.ts +12 -0
- package/src/cmd/info.ts +147 -0
- package/src/cmd/new.ts +235 -0
- package/src/cmd/next.ts +119 -0
- package/src/cmd/print.ts +108 -0
- package/src/cmd/seed.ts +114 -0
- package/src/cmd/validate.ts +288 -0
- package/src/exec.ts +23 -0
- package/src/index.ts +55 -0
- package/src/utils.ts +130 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-Bu1tG89l.mjs","names":["effectivePath: string","ur: UR","e: unknown","generator: ProvenanceMarkGenerator","paragraphs: string[]","paragraphs: string[]","markInfos: ProvenanceMarkInfo[]","marks: ProvenanceMark[]","ur: UR","envelope: Envelope"],"sources":["../src/utils.ts","../src/cmd/info.ts","../src/cmd/seed.ts","../src/cmd/new.ts","../src/cmd/next.ts","../src/cmd/print.ts","../src/cmd/validate.ts","../src/index.ts"],"sourcesContent":["/**\n * Utilities module - 1:1 port of utils.rs\n *\n * Helper functions for CLI operations.\n */\n\n/* eslint-disable no-restricted-globals, no-undef */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Read a new path, supporting globbing, and resolving relative paths.\n *\n * Corresponds to Rust `read_new_path()`\n */\nexport function readNewPath(pathStr: string): string {\n // For TypeScript, we simplify glob handling - just resolve the path\n let effectivePath: string;\n\n if (path.isAbsolute(pathStr)) {\n effectivePath = pathStr;\n } else {\n const currentDir = process.cwd();\n effectivePath = path.join(currentDir, pathStr);\n }\n\n // Normalize the path (resolve . and ..)\n return path.normalize(effectivePath);\n}\n\n/**\n * Read an existing directory path, supporting globbing, and resolving relative paths.\n *\n * Corresponds to Rust `read_existing_directory_path()`\n */\nexport function readExistingDirectoryPath(pathStr: string): string {\n const effectivePath = readNewPath(pathStr);\n\n if (!fs.existsSync(effectivePath)) {\n throw new Error(`Path does not exist: ${effectivePath}`);\n }\n\n if (!fs.statSync(effectivePath).isDirectory()) {\n throw new Error(`Path is not a directory: ${effectivePath}`);\n }\n\n return effectivePath;\n}\n\n/**\n * Read an argument from command line or stdin.\n *\n * Corresponds to Rust `read_argument()`\n */\nexport function readArgument(argument?: string): string {\n if (argument !== undefined && argument !== \"\") {\n return argument;\n }\n\n // Read from stdin\n const input = readStdinSync();\n if (input.trim() === \"\") {\n throw new Error(\"No argument provided\");\n }\n return input.trim();\n}\n\n/**\n * Read all stdin synchronously.\n */\nexport function readStdinSync(): string {\n let input = \"\";\n const BUFSIZE = 256;\n const buf = Buffer.alloc(BUFSIZE);\n\n try {\n // Use process.stdin.fd (file descriptor 0) directly for reading\n const fd = process.stdin.fd;\n\n while (true) {\n try {\n const bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, null);\n if (bytesRead === 0) break;\n input += buf.toString(\"utf8\", 0, bytesRead);\n } catch {\n break;\n }\n }\n } catch {\n // Fallback: stdin might not be readable\n }\n\n return input;\n}\n\n/**\n * Convert bytes to hex string.\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Convert hex string to bytes.\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const cleanHex = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const bytes = new Uint8Array(cleanHex.length / 2);\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Convert bytes to base64 string.\n */\nexport function toBase64(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString(\"base64\");\n}\n\n/**\n * Convert base64 string to bytes.\n */\nexport function fromBase64(base64: string): Uint8Array {\n return new Uint8Array(Buffer.from(base64, \"base64\"));\n}\n","/**\n * Info args - 1:1 port of info.rs\n *\n * Shared arguments for supplying provenance mark `info` payloads.\n */\n\nimport { type Cbor, cbor, decodeCbor, isTagged, tagValue, getGlobalTagsStore } from \"@bcts/dcbor\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { hexToBytes } from \"../utils.js\";\n\n/**\n * Arguments for info payload.\n *\n * Corresponds to Rust `InfoArgs`\n */\nexport interface InfoArgs {\n /** Hex-encoded dCBOR or UR payload to embed in the mark's `info` field. */\n info?: string | undefined;\n /** CBOR tag value to associate with an unknown UR type. */\n infoTag?: number | undefined;\n}\n\n/**\n * Parse info args to CBOR.\n *\n * Corresponds to Rust `InfoArgs::to_cbor()`\n */\nexport function parseInfoArgs(args: InfoArgs): Cbor | undefined {\n if (args.info !== undefined) {\n return parseInfo(args.info, args.infoTag);\n }\n\n if (args.infoTag !== undefined) {\n throw new Error(\"--info-tag requires a UR payload\");\n }\n\n return undefined;\n}\n\n/**\n * Parse hex-encoded CBOR.\n *\n * Corresponds to Rust `parse_hex()`\n */\nfunction parseHex(input: string): Cbor {\n const trimmed = input.trim();\n const hexStr = trimmed.startsWith(\"0x\") ? trimmed.slice(2) : trimmed;\n\n try {\n const bytes = hexToBytes(hexStr);\n return decodeCbor(bytes);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`failed to decode hex info payload: ${message}`);\n }\n}\n\n/**\n * Parse info payload from raw string.\n *\n * Corresponds to Rust `parse_info()`\n */\nfunction parseInfo(raw: string, tagOverride?: number): Cbor {\n const trimmed = raw.trim();\n if (trimmed === \"\") {\n throw new Error(\"info payload must not be empty\");\n }\n\n // Check if it's a UR\n if (trimmed.length >= 3 && trimmed.slice(0, 3).toLowerCase() === \"ur:\") {\n return parseUrPayload(trimmed, tagOverride);\n }\n\n // Try hex first\n try {\n const cborResult = parseHex(trimmed);\n if (tagOverride !== undefined) {\n throw new Error(\"--info-tag is only valid when the payload is a UR\");\n }\n return cborResult;\n } catch (hexErr) {\n // Try as UR fallback\n try {\n return parseUrPayload(trimmed, tagOverride);\n } catch (urErr) {\n const hexMsg = hexErr instanceof Error ? hexErr.message : String(hexErr);\n const urMsg = urErr instanceof Error ? urErr.message : String(urErr);\n throw new Error(`failed to parse --info payload as hex (${hexMsg}) or UR (${urMsg})`);\n }\n }\n}\n\n/**\n * Parse UR payload.\n *\n * Corresponds to Rust `parse_ur_payload()`\n */\nfunction parseUrPayload(input: string, tagOverride?: number): Cbor {\n let ur: UR;\n try {\n ur = UR.fromURString(input.trim());\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`failed to parse UR info payload: ${message}`);\n }\n\n const typeStr = ur.urTypeStr();\n\n // Check if we have a registered tag for this UR type\n const registeredTag = getGlobalTagsStore().tagForName(typeStr);\n const registeredTagValue = registeredTag !== undefined ? Number(registeredTag.value) : undefined;\n\n if (registeredTagValue !== undefined && tagOverride !== undefined) {\n throw new Error(`UR type '${typeStr}' has a known CBOR tag; --info-tag must not be supplied`);\n }\n\n const expectedTag = registeredTagValue ?? tagOverride;\n if (expectedTag === undefined) {\n throw new Error(\n `UR type '${typeStr}' is not registered; supply --info-tag with the CBOR tag value`,\n );\n }\n\n const cborValue = ur.cbor();\n return ensureTag(cborValue, expectedTag, typeStr);\n}\n\n/**\n * Ensure CBOR has the expected tag.\n *\n * Corresponds to Rust `ensure_tag()`\n */\nfunction ensureTag(cborValue: Cbor, expectedTag: number, typeStr: string): Cbor {\n // Check if already tagged\n if (isTagged(cborValue)) {\n const tag = tagValue(cborValue);\n if (tag !== BigInt(expectedTag)) {\n throw new Error(\n `UR type '${typeStr}' encodes CBOR tag ${tag} but ${expectedTag} was expected`,\n );\n }\n // Return as-is if already properly tagged\n return cborValue;\n }\n // Not tagged, wrap it\n return cbor({ tag: expectedTag, value: cborValue });\n}\n","/**\n * Seed parsing - 1:1 port of seed.rs\n *\n * Functions for parsing provenance seeds from various formats.\n */\n\nimport { UR } from \"@bcts/uniform-resources\";\nimport { Seed } from \"@bcts/components\";\nimport { ProvenanceSeed, PROVENANCE_SEED_LENGTH } from \"@bcts/provenance-mark\";\nimport { fromBase64, hexToBytes } from \"../utils.js\";\n\n/**\n * Parse a seed from a string.\n *\n * Supports the following formats:\n * - `ur:seed/...` - UR-encoded seed\n * - `0x...` or hex string - Hex-encoded seed\n * - Base64 string - Base64-encoded seed\n *\n * Corresponds to Rust `parse_seed()`\n */\nexport function parseSeed(input: string): ProvenanceSeed {\n const trimmed = input.trim();\n if (trimmed === \"\") {\n throw new Error(\"seed string is empty\");\n }\n\n // Try UR format first\n if (trimmed.toLowerCase().startsWith(\"ur:\")) {\n return parseSeedUr(trimmed);\n }\n\n // Try hex format\n const hexResult = parseSeedHex(trimmed);\n if (hexResult !== undefined) {\n return hexResult;\n }\n\n // Fall back to base64\n return parseSeedBase64(trimmed);\n}\n\n/**\n * Parse a seed from a UR string.\n *\n * Corresponds to Rust `parse_seed_ur()`\n */\nfunction parseSeedUr(input: string): ProvenanceSeed {\n try {\n const ur = UR.fromURString(input);\n const seed = Seed.fromUR(ur);\n return seedFromExact(seed.toData());\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`failed to parse seed UR: ${message}`);\n }\n}\n\n/**\n * Parse a seed from a hex string.\n *\n * Returns undefined if the string is not valid hex format.\n *\n * Corresponds to Rust `parse_seed_hex()`\n */\nfunction parseSeedHex(input: string): ProvenanceSeed | undefined {\n const source = input.startsWith(\"0x\") ? input.slice(2) : input;\n if (source === \"\") {\n return undefined;\n }\n\n // Check if it's valid hex\n if (source.length % 2 !== 0) {\n return undefined;\n }\n if (!/^[0-9a-fA-F]+$/.test(source)) {\n return undefined;\n }\n\n try {\n const bytes = hexToBytes(source);\n return seedFromExact(bytes);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`failed to decode hex seed: ${message}`);\n }\n}\n\n/**\n * Parse a seed from a base64 string.\n *\n * Corresponds to Rust `parse_seed_base64()`\n */\nfunction parseSeedBase64(input: string): ProvenanceSeed {\n try {\n const bytes = fromBase64(input);\n return seedFromExact(bytes);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`failed to decode base64 seed: ${message}`);\n }\n}\n\n/**\n * Create a seed from exactly PROVENANCE_SEED_LENGTH bytes.\n *\n * Corresponds to Rust `seed_from_exact()`\n */\nfunction seedFromExact(bytes: Uint8Array): ProvenanceSeed {\n if (bytes.length !== PROVENANCE_SEED_LENGTH) {\n throw new Error(`seed must be ${PROVENANCE_SEED_LENGTH} bytes but found ${bytes.length}`);\n }\n return ProvenanceSeed.fromBytes(bytes);\n}\n","/**\n * New command - 1:1 port of new.rs\n *\n * Initialize a directory with a new provenance mark chain.\n */\n\n/* eslint-disable no-console, no-undef */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport {\n ProvenanceMarkGenerator,\n ProvenanceMarkInfo,\n ProvenanceMarkResolution,\n type ProvenanceSeed,\n} from \"@bcts/provenance-mark\";\n\nimport type { Exec } from \"../exec.js\";\nimport { readNewPath } from \"../utils.js\";\nimport { type InfoArgs, parseInfoArgs } from \"./info.js\";\n\n/**\n * Output format for the creation summary.\n *\n * Corresponds to Rust `OutputFormat`\n */\nexport enum OutputFormat {\n Markdown = \"markdown\",\n Ur = \"ur\",\n Json = \"json\",\n}\n\n/**\n * Resolution level for the provenance mark chain.\n *\n * Corresponds to Rust `Resolution`\n */\nexport enum Resolution {\n /** Good for physical works of art and applications requiring minimal mark size. */\n Low = \"low\",\n /** Good for digital works of art. */\n Medium = \"medium\",\n /** Good for general use. */\n Quartile = \"quartile\",\n /** Industrial strength, largest mark. */\n High = \"high\",\n}\n\n/**\n * Convert Resolution to ProvenanceMarkResolution.\n */\nfunction resolutionToProvenanceMarkResolution(res: Resolution): ProvenanceMarkResolution {\n switch (res) {\n case Resolution.Low:\n return ProvenanceMarkResolution.Low;\n case Resolution.Medium:\n return ProvenanceMarkResolution.Medium;\n case Resolution.Quartile:\n return ProvenanceMarkResolution.Quartile;\n case Resolution.High:\n return ProvenanceMarkResolution.High;\n }\n}\n\n/**\n * Parse a resolution string.\n */\nexport function parseResolution(value: string): Resolution {\n switch (value.toLowerCase()) {\n case \"low\":\n return Resolution.Low;\n case \"medium\":\n return Resolution.Medium;\n case \"quartile\":\n return Resolution.Quartile;\n case \"high\":\n return Resolution.High;\n default:\n throw new Error(`Invalid resolution: ${value}. Must be one of: low, medium, quartile, high`);\n }\n}\n\n/**\n * Parse an output format string.\n */\nexport function parseOutputFormat(value: string): OutputFormat {\n switch (value.toLowerCase()) {\n case \"markdown\":\n return OutputFormat.Markdown;\n case \"ur\":\n return OutputFormat.Ur;\n case \"json\":\n return OutputFormat.Json;\n default:\n throw new Error(`Invalid format: ${value}. Must be one of: markdown, ur, json`);\n }\n}\n\n/**\n * Arguments for the new command.\n *\n * Corresponds to Rust `CommandArgs`\n */\nexport interface NewCommandArgs {\n /** Path to directory to be created. Must not already exist. */\n path: string;\n /** A seed to use for the provenance mark chain, encoded as base64. */\n seed?: ProvenanceSeed;\n /** The resolution of the provenance mark chain. */\n resolution: Resolution;\n /** A comment to be included for the genesis mark. */\n comment: string;\n /** The date of the genesis mark. If not supplied, the current date is used. */\n date?: Date;\n /** Suppress informational status output on stderr/stdout. */\n quiet: boolean;\n /** Output format for the creation summary. */\n format: OutputFormat;\n /** Info args for the mark. */\n info: InfoArgs;\n}\n\n/**\n * Create default args for the new command.\n */\nexport function defaultNewCommandArgs(): NewCommandArgs {\n return {\n path: \"\",\n resolution: Resolution.Quartile,\n comment: \"Genesis mark.\",\n quiet: false,\n format: OutputFormat.Markdown,\n info: {},\n };\n}\n\n/**\n * New command implementation.\n *\n * Corresponds to Rust `impl Exec for CommandArgs`\n */\nexport class NewCommand implements Exec {\n private readonly args: NewCommandArgs;\n\n constructor(args: NewCommandArgs) {\n this.args = args;\n }\n\n exec(): string {\n // Create the directory, ensuring it doesn't already exist.\n const dirPath = this.createDir();\n\n // Create the `marks` subdirectory inside `path`.\n const marksPath = path.join(dirPath, \"marks\");\n fs.mkdirSync(marksPath);\n\n // Create the generator\n const resolution = resolutionToProvenanceMarkResolution(this.args.resolution);\n let generator: ProvenanceMarkGenerator;\n if (this.args.seed !== undefined) {\n generator = ProvenanceMarkGenerator.newWithSeed(resolution, this.args.seed);\n } else {\n generator = ProvenanceMarkGenerator.newRandom(resolution);\n }\n\n // Generate the genesis mark.\n const date = this.args.date ?? new Date();\n const info = parseInfoArgs(this.args.info);\n const mark = generator.next(date, info);\n const markInfo = ProvenanceMarkInfo.new(mark, this.args.comment);\n\n // Serialize the mark to JSON and write it as `mark-seq.json` to `path/marks`.\n const markJson = JSON.stringify(markInfo.toJSON(), null, 2);\n const markPath = path.join(marksPath, `mark-${mark.seq()}.json`);\n fs.writeFileSync(markPath, markJson);\n\n // Serialize `generator` to JSON and write it as `generator.json` to `path`.\n const generatorJson = JSON.stringify(generator.toJSON(), null, 2);\n const generatorPath = path.join(dirPath, \"generator.json\");\n fs.writeFileSync(generatorPath, generatorJson);\n\n // Return output based on format.\n const statusLines = [\n `Provenance mark chain created at: ${dirPath}`,\n `Mark ${mark.seq()} written to: ${markPath}`,\n ];\n\n switch (this.args.format) {\n case OutputFormat.Markdown: {\n const paragraphs: string[] = [];\n if (!this.args.quiet) {\n paragraphs.push(...statusLines);\n }\n paragraphs.push(markInfo.markdownSummary());\n return paragraphs.join(\"\\n\\n\");\n }\n case OutputFormat.Ur: {\n if (!this.args.quiet) {\n for (const line of statusLines) {\n console.error(line);\n }\n }\n return markInfo.ur().toString();\n }\n case OutputFormat.Json: {\n if (!this.args.quiet) {\n for (const line of statusLines) {\n console.error(line);\n }\n }\n return JSON.stringify(markInfo.toJSON(), null, 2);\n }\n }\n }\n\n private createDir(): string {\n const dirPath = readNewPath(this.args.path);\n\n // Ensure the directory doesn't already exist.\n if (fs.existsSync(dirPath)) {\n throw new Error(`Path already exists: ${dirPath}`);\n }\n\n // Ensure the parent directory exists.\n const parent = path.dirname(dirPath);\n if (!fs.existsSync(parent)) {\n throw new Error(`Parent directory does not exist: ${parent}`);\n }\n\n // Create the new directory.\n fs.mkdirSync(dirPath);\n\n return dirPath;\n }\n}\n","/**\n * Next command - 1:1 port of next.rs\n *\n * Generate the next provenance mark in a chain.\n */\n\n/* eslint-disable no-console, no-undef */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { ProvenanceMarkGenerator, ProvenanceMarkInfo } from \"@bcts/provenance-mark\";\n\nimport type { Exec } from \"../exec.js\";\nimport { readExistingDirectoryPath } from \"../utils.js\";\nimport { type InfoArgs, parseInfoArgs } from \"./info.js\";\nimport { OutputFormat, parseOutputFormat } from \"./new.js\";\n\n/**\n * Arguments for the next command.\n *\n * Corresponds to Rust `CommandArgs`\n */\nexport interface NextCommandArgs {\n /** Path to the chain's directory. Must already exist. */\n path: string;\n /** A comment to be included for the mark. */\n comment: string;\n /** The date of the next mark. If not supplied, the current date is used. */\n date?: Date;\n /** Suppress informational status output on stderr/stdout. */\n quiet: boolean;\n /** Output format for the mark. */\n format: OutputFormat;\n /** Info args for the mark. */\n info: InfoArgs;\n}\n\n/**\n * Create default args for the next command.\n */\nexport function defaultNextCommandArgs(): NextCommandArgs {\n return {\n path: \"\",\n comment: \"Blank.\",\n quiet: false,\n format: OutputFormat.Markdown,\n info: {},\n };\n}\n\n/**\n * Next command implementation.\n *\n * Corresponds to Rust `impl Exec for CommandArgs`\n */\nexport class NextCommand implements Exec {\n private readonly args: NextCommandArgs;\n\n constructor(args: NextCommandArgs) {\n this.args = args;\n }\n\n exec(): string {\n // Get the chain's directory path.\n const dirPath = readExistingDirectoryPath(this.args.path);\n\n // Read the generator from `path/generator.json`.\n const generatorPath = path.join(dirPath, \"generator.json\");\n const generatorJson = fs.readFileSync(generatorPath, \"utf-8\");\n const generator = ProvenanceMarkGenerator.fromJSON(\n JSON.parse(generatorJson) as Record<string, unknown>,\n );\n\n // Generate the next mark.\n const date = this.args.date ?? new Date();\n const info = parseInfoArgs(this.args.info);\n const mark = generator.next(date, info);\n const markInfo = ProvenanceMarkInfo.new(mark, this.args.comment);\n\n // Serialize the mark to JSON and write it as `mark-seq.json` to `path/marks`.\n const marksPath = path.join(dirPath, \"marks\");\n const markJson = JSON.stringify(markInfo.toJSON(), null, 2);\n const markPath = path.join(marksPath, `mark-${mark.seq()}.json`);\n fs.writeFileSync(markPath, markJson);\n\n // Serialize `generator` to JSON and write it back to `path/generator.json`.\n const newGeneratorJson = JSON.stringify(generator.toJSON(), null, 2);\n fs.writeFileSync(generatorPath, newGeneratorJson);\n\n // Return output based on format.\n const statusLine = `Mark ${mark.seq()} written to: ${markPath}`;\n\n switch (this.args.format) {\n case OutputFormat.Markdown: {\n const paragraphs: string[] = [];\n if (!this.args.quiet) {\n paragraphs.push(statusLine);\n }\n paragraphs.push(markInfo.markdownSummary());\n return paragraphs.join(\"\\n\\n\");\n }\n case OutputFormat.Ur: {\n if (!this.args.quiet) {\n console.error(statusLine);\n }\n return markInfo.ur().toString();\n }\n case OutputFormat.Json: {\n if (!this.args.quiet) {\n console.error(statusLine);\n }\n return JSON.stringify(markInfo.toJSON(), null, 2);\n }\n }\n }\n}\n\n// Re-export for convenience\nexport { OutputFormat, parseOutputFormat };\n","/**\n * Print command - 1:1 port of print.rs\n *\n * Prints provenance marks in a chain.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { ProvenanceMarkGenerator, ProvenanceMarkInfo } from \"@bcts/provenance-mark\";\n\nimport type { Exec } from \"../exec.js\";\nimport { readExistingDirectoryPath } from \"../utils.js\";\nimport { OutputFormat, parseOutputFormat } from \"./new.js\";\n\n/**\n * Arguments for the print command.\n *\n * Corresponds to Rust `CommandArgs`\n */\nexport interface PrintCommandArgs {\n /** Path to the chain's directory. Must already exist. */\n path: string;\n /** The sequence number of the first mark to print. */\n start: number;\n /** The sequence number of the last mark to print. */\n end?: number;\n /** Output format for the rendered marks. */\n format: OutputFormat;\n}\n\n/**\n * Create default args for the print command.\n */\nexport function defaultPrintCommandArgs(): PrintCommandArgs {\n return {\n path: \"\",\n start: 0,\n format: OutputFormat.Markdown,\n };\n}\n\n/**\n * Print command implementation.\n *\n * Corresponds to Rust `impl Exec for CommandArgs`\n */\nexport class PrintCommand implements Exec {\n private readonly args: PrintCommandArgs;\n\n constructor(args: PrintCommandArgs) {\n this.args = args;\n }\n\n exec(): string {\n // Get the chain's directory path.\n const dirPath = readExistingDirectoryPath(this.args.path);\n\n // Read the generator from `path/generator.json`.\n const generatorPath = path.join(dirPath, \"generator.json\");\n const generatorJson = fs.readFileSync(generatorPath, \"utf-8\");\n const generator = ProvenanceMarkGenerator.fromJSON(\n JSON.parse(generatorJson) as Record<string, unknown>,\n );\n\n // Validate the start and end sequence numbers.\n const lastValidSeq = generator.nextSeq() - 1;\n const startSeq = this.args.start;\n const endSeq = this.args.end ?? lastValidSeq;\n\n if (startSeq > endSeq) {\n throw new Error(\n \"The start sequence number must be less than or equal to the end sequence number.\",\n );\n }\n if (endSeq > lastValidSeq) {\n throw new Error(\n \"The end sequence number must be less than or equal to the last valid sequence number.\",\n );\n }\n\n // Collect the requested marks.\n const markInfos: ProvenanceMarkInfo[] = [];\n for (let seq = startSeq; seq <= endSeq; seq++) {\n const markPath = path.join(dirPath, \"marks\", `mark-${seq}.json`);\n const markJson = fs.readFileSync(markPath, \"utf-8\");\n const markInfo = ProvenanceMarkInfo.fromJSON(JSON.parse(markJson) as Record<string, unknown>);\n markInfos.push(markInfo);\n }\n\n switch (this.args.format) {\n case OutputFormat.Markdown: {\n const summaries = markInfos.map((info) => info.markdownSummary());\n return summaries.join(\"\\n\");\n }\n case OutputFormat.Ur: {\n const urs = markInfos.map((info) => info.ur().toString());\n return urs.join(\"\\n\");\n }\n case OutputFormat.Json: {\n const jsonArray = markInfos.map((info) => info.toJSON());\n return JSON.stringify(jsonArray, null, 2);\n }\n }\n }\n}\n\n// Re-export for convenience\nexport { OutputFormat, parseOutputFormat };\n","/**\n * Validate command - 1:1 port of validate.rs\n *\n * Validate one or more provenance marks.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { PROVENANCE } from \"@bcts/known-values\";\nimport {\n ProvenanceMark,\n ProvenanceMarkInfo,\n ValidationReportFormat,\n validate,\n hasIssues,\n formatReport,\n} from \"@bcts/provenance-mark\";\n\nimport type { Exec } from \"../exec.js\";\nimport { readExistingDirectoryPath } from \"../utils.js\";\n\n/**\n * Output format for the validation report.\n *\n * Corresponds to Rust `Format`\n */\nexport enum ValidateFormat {\n Text = \"text\",\n JsonCompact = \"json-compact\",\n JsonPretty = \"json-pretty\",\n}\n\n/**\n * Convert ValidateFormat to ValidationReportFormat.\n */\nfunction formatToValidationReportFormat(format: ValidateFormat): ValidationReportFormat {\n switch (format) {\n case ValidateFormat.Text:\n return ValidationReportFormat.Text;\n case ValidateFormat.JsonCompact:\n return ValidationReportFormat.JsonCompact;\n case ValidateFormat.JsonPretty:\n return ValidationReportFormat.JsonPretty;\n }\n}\n\n/**\n * Parse a format string.\n */\nexport function parseValidateFormat(value: string): ValidateFormat {\n switch (value.toLowerCase()) {\n case \"text\":\n return ValidateFormat.Text;\n case \"json-compact\":\n return ValidateFormat.JsonCompact;\n case \"json-pretty\":\n return ValidateFormat.JsonPretty;\n default:\n throw new Error(`Invalid format: ${value}. Must be one of: text, json-compact, json-pretty`);\n }\n}\n\n/**\n * Arguments for the validate command.\n *\n * Corresponds to Rust `CommandArgs`\n */\nexport interface ValidateCommandArgs {\n /** One or more provenance mark URs to validate. */\n marks: string[];\n /** Path to a chain directory containing marks to validate. */\n dir?: string;\n /** Report issues as warnings without failing. */\n warn: boolean;\n /** Output format for the validation report. */\n format: ValidateFormat;\n}\n\n/**\n * Create default args for the validate command.\n */\nexport function defaultValidateCommandArgs(): ValidateCommandArgs {\n return {\n marks: [],\n warn: false,\n format: ValidateFormat.Text,\n };\n}\n\n/**\n * Validate command implementation.\n *\n * Corresponds to Rust `impl Exec for CommandArgs`\n */\nexport class ValidateCommand implements Exec {\n private readonly args: ValidateCommandArgs;\n\n constructor(args: ValidateCommandArgs) {\n this.args = args;\n }\n\n exec(): string {\n // Collect marks from either URs or directory\n let marks: ProvenanceMark[];\n if (this.args.dir !== undefined) {\n marks = this.loadMarksFromDir(this.args.dir);\n } else {\n marks = this.parseMarksFromUrs(this.args.marks);\n }\n\n // Validate the marks\n const report = validate(marks);\n\n // Format the output\n const output = formatReport(report, formatToValidationReportFormat(this.args.format));\n\n // Determine if we should fail\n if (hasIssues(report) && !this.args.warn) {\n throw new Error(`Validation failed with issues:\\n${output}`);\n }\n\n return output;\n }\n\n /**\n * Parse marks from UR strings.\n *\n * Corresponds to Rust `parse_marks_from_urs()`\n */\n private parseMarksFromUrs(urStrings: string[]): ProvenanceMark[] {\n const marks: ProvenanceMark[] = [];\n for (const urString of urStrings) {\n const mark = this.extractProvenanceMark(urString.trim());\n marks.push(mark);\n }\n return marks;\n }\n\n /**\n * Extract a ProvenanceMark from a UR string.\n *\n * Supports three types of URs:\n * 1. `ur:provenance` - Direct provenance mark\n * 2. `ur:envelope` - Envelope with a 'provenance' assertion\n * 3. Any other UR type - Attempts to decode CBOR as an envelope\n *\n * Corresponds to Rust `extract_provenance_mark()`\n */\n private extractProvenanceMark(urString: string): ProvenanceMark {\n // Parse the UR to get its type and CBOR\n let ur: UR;\n try {\n ur = UR.fromURString(urString);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to parse UR '${urString}': ${message}`);\n }\n\n const urType = ur.urTypeStr();\n const cborValue = ur.cbor();\n\n // Case 1: Direct provenance mark\n // URs don't include the CBOR tag in their encoded format, so we use fromUntaggedCbor\n if (urType === \"provenance\") {\n try {\n return ProvenanceMark.fromUntaggedCbor(cborValue);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to decode provenance mark from '${urString}': ${message}`);\n }\n }\n\n // Case 2 & 3: Try to decode CBOR as an envelope\n let envelope: Envelope;\n try {\n envelope = Envelope.fromUntaggedCbor(cborValue);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `UR type '${urType}' is not 'provenance', and CBOR is not decodable as an envelope: ${message}`,\n );\n }\n\n // Extract the provenance mark from the envelope\n return this.extractProvenanceMarkFromEnvelope(envelope, urString);\n }\n\n /**\n * Extract a ProvenanceMark from an Envelope.\n *\n * The envelope must contain exactly one 'provenance' assertion,\n * and the object subject of that assertion must be a ProvenanceMark.\n *\n * Corresponds to Rust `extract_provenance_mark_from_envelope()`\n */\n private extractProvenanceMarkFromEnvelope(envelope: Envelope, urString: string): ProvenanceMark {\n // If the envelope is wrapped, unwrap it to get to the actual content\n let workingEnvelope = envelope;\n if (envelope.isWrapped()) {\n const innerEnvelope = envelope.unwrap();\n if (innerEnvelope !== undefined) {\n workingEnvelope = innerEnvelope;\n }\n }\n\n // Find all assertions with the 'provenance' predicate\n const provenancePredicate = Envelope.newWithKnownValue(PROVENANCE);\n const provenanceAssertions = workingEnvelope.assertionsWithPredicate(provenancePredicate);\n\n // Verify exactly one provenance assertion exists\n if (provenanceAssertions.length === 0) {\n throw new Error(`Envelope in '${urString}' does not contain a 'provenance' assertion`);\n }\n if (provenanceAssertions.length > 1) {\n throw new Error(\n `Envelope in '${urString}' contains ${provenanceAssertions.length} 'provenance' assertions, expected exactly one`,\n );\n }\n\n // Get the object of the provenance assertion\n const provenanceAssertion = provenanceAssertions[0];\n const objectEnvelope = provenanceAssertion.asObject();\n if (objectEnvelope === undefined) {\n throw new Error(`Failed to extract object from provenance assertion in '${urString}'`);\n }\n\n // The object should be decodable as a ProvenanceMark.\n // Extract the CBOR from the leaf envelope and parse it.\n try {\n const cborValue = objectEnvelope.asLeaf();\n if (cborValue === undefined) {\n throw new Error(\"Object envelope is not a leaf\");\n }\n return ProvenanceMark.fromTaggedCbor(cborValue);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(\n `Failed to decode ProvenanceMark from provenance assertion in '${urString}': ${message}`,\n );\n }\n }\n\n /**\n * Load marks from a directory.\n *\n * Corresponds to Rust `load_marks_from_dir()`\n */\n private loadMarksFromDir(dirPath: string): ProvenanceMark[] {\n // Get the chain's directory path\n const resolvedPath = readExistingDirectoryPath(dirPath);\n\n // Get the marks subdirectory\n const marksPath = path.join(resolvedPath, \"marks\");\n if (!fs.existsSync(marksPath) || !fs.statSync(marksPath).isDirectory()) {\n throw new Error(`Marks subdirectory not found: ${marksPath}`);\n }\n\n // Read all JSON files from the marks directory\n const entries = fs.readdirSync(marksPath);\n const markFiles = entries\n .map((entry) => path.join(marksPath, entry))\n .filter((p) => p.endsWith(\".json\"))\n .sort();\n\n if (markFiles.length === 0) {\n throw new Error(`No mark JSON files found in: ${marksPath}`);\n }\n\n // Parse each JSON file and extract the mark\n const marks: ProvenanceMark[] = [];\n for (const markFile of markFiles) {\n try {\n const jsonContent = fs.readFileSync(markFile, \"utf-8\");\n const markInfo = ProvenanceMarkInfo.fromJSON(\n JSON.parse(jsonContent) as Record<string, unknown>,\n );\n marks.push(markInfo.mark());\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to parse JSON from ${markFile}: ${message}`);\n }\n }\n\n return marks;\n }\n}\n","/**\n * @bcts/provenance-mark-cli - Command line tool for creating and managing Provenance Marks\n *\n * This is a 1:1 TypeScript port of provenance-mark-cli-rust.\n *\n * @packageDocumentation\n */\n\nexport const VERSION = \"1.0.0-alpha.13\";\n\n// Export exec interface\nexport type { Exec, ExecResult } from \"./exec.js\";\n\n// Export utilities\nexport {\n readNewPath,\n readExistingDirectoryPath,\n readArgument,\n readStdinSync,\n bytesToHex,\n hexToBytes,\n toBase64,\n fromBase64,\n} from \"./utils.js\";\n\n// Export command types and classes\nexport {\n // Info args\n type InfoArgs,\n parseInfoArgs,\n // Seed parsing\n parseSeed,\n // New command\n OutputFormat,\n Resolution,\n parseResolution,\n parseOutputFormat,\n type NewCommandArgs,\n defaultNewCommandArgs,\n NewCommand,\n // Next command\n type NextCommandArgs,\n defaultNextCommandArgs,\n NextCommand,\n // Print command\n type PrintCommandArgs,\n defaultPrintCommandArgs,\n PrintCommand,\n // Validate command\n ValidateFormat,\n parseValidateFormat,\n type ValidateCommandArgs,\n defaultValidateCommandArgs,\n ValidateCommand,\n} from \"./cmd/index.js\";\n"],"mappings":"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"}
|