@bcts/dcbor-parse 1.0.0-alpha.22 → 1.0.0-beta.0
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/dist/index.cjs +151 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +50 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +151 -37
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +151 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
- package/src/compose.ts +10 -2
- package/src/error.ts +139 -5
- package/src/index.ts +61 -16
- package/src/parse.ts +29 -11
- package/src/token.ts +127 -54
package/dist/index.iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.iife.js","names":["PE","DCborDate","UR","PE","KnownValue","KNOWN_VALUES","CborMap","CborMap"],"sources":["../src/error.ts","../src/token.ts","../src/parse.ts","../src/compose.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Error types\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust error.rs\n *\n * @module dcbor-parse/error\n */\n\nimport type { Token } from \"./token\";\n\n/**\n * Represents a span (range) in the source string.\n *\n * Corresponds to the Rust `logos::Span` type.\n */\nexport interface Span {\n readonly start: number;\n readonly end: number;\n}\n\n/**\n * Creates a span with the given start and end positions.\n */\nexport function span(start: number, end: number): Span {\n return { start, end };\n}\n\n/**\n * Creates a default (empty) span.\n */\nexport function defaultSpan(): Span {\n return { start: 0, end: 0 };\n}\n\n/**\n * Parse error types.\n *\n * Corresponds to the Rust `Error` enum in error.rs\n */\nexport type ParseError =\n | { readonly type: \"EmptyInput\" }\n | { readonly type: \"UnexpectedEndOfInput\" }\n | { readonly type: \"ExtraData\"; readonly span: Span }\n | { readonly type: \"UnexpectedToken\"; readonly token: Token; readonly span: Span }\n | { readonly type: \"UnrecognizedToken\"; readonly span: Span }\n | { readonly type: \"ExpectedComma\"; readonly span: Span }\n | { readonly type: \"ExpectedColon\"; readonly span: Span }\n | { readonly type: \"UnmatchedParentheses\"; readonly span: Span }\n | { readonly type: \"UnmatchedBraces\"; readonly span: Span }\n | { readonly type: \"ExpectedMapKey\"; readonly span: Span }\n | { readonly type: \"InvalidTagValue\"; readonly value: string; readonly span: Span }\n | { readonly type: \"UnknownTagName\"; readonly name: string; readonly span: Span }\n | { readonly type: \"InvalidHexString\"; readonly span: Span }\n | { readonly type: \"InvalidBase64String\"; readonly span: Span }\n | { readonly type: \"UnknownUrType\"; readonly urType: string; readonly span: Span }\n | { readonly type: \"InvalidUr\"; readonly message: string; readonly span: Span }\n | { readonly type: \"InvalidKnownValue\"; readonly value: string; readonly span: Span }\n | { readonly type: \"UnknownKnownValueName\"; readonly name: string; readonly span: Span }\n | { readonly type: \"InvalidDateString\"; readonly dateString: string; readonly span: Span }\n | { readonly type: \"DuplicateMapKey\"; readonly span: Span };\n\n// Error constructors (lowercase to differentiate from the type)\nexport const parseError = {\n emptyInput(): ParseError {\n return { type: \"EmptyInput\" };\n },\n\n unexpectedEndOfInput(): ParseError {\n return { type: \"UnexpectedEndOfInput\" };\n },\n\n extraData(span: Span): ParseError {\n return { type: \"ExtraData\", span };\n },\n\n unexpectedToken(token: Token, span: Span): ParseError {\n return { type: \"UnexpectedToken\", token, span };\n },\n\n unrecognizedToken(span: Span): ParseError {\n return { type: \"UnrecognizedToken\", span };\n },\n\n expectedComma(span: Span): ParseError {\n return { type: \"ExpectedComma\", span };\n },\n\n expectedColon(span: Span): ParseError {\n return { type: \"ExpectedColon\", span };\n },\n\n unmatchedParentheses(span: Span): ParseError {\n return { type: \"UnmatchedParentheses\", span };\n },\n\n unmatchedBraces(span: Span): ParseError {\n return { type: \"UnmatchedBraces\", span };\n },\n\n expectedMapKey(span: Span): ParseError {\n return { type: \"ExpectedMapKey\", span };\n },\n\n invalidTagValue(value: string, span: Span): ParseError {\n return { type: \"InvalidTagValue\", value, span };\n },\n\n unknownTagName(name: string, span: Span): ParseError {\n return { type: \"UnknownTagName\", name, span };\n },\n\n invalidHexString(span: Span): ParseError {\n return { type: \"InvalidHexString\", span };\n },\n\n invalidBase64String(span: Span): ParseError {\n return { type: \"InvalidBase64String\", span };\n },\n\n unknownUrType(urType: string, span: Span): ParseError {\n return { type: \"UnknownUrType\", urType, span };\n },\n\n invalidUr(message: string, span: Span): ParseError {\n return { type: \"InvalidUr\", message, span };\n },\n\n invalidKnownValue(value: string, span: Span): ParseError {\n return { type: \"InvalidKnownValue\", value, span };\n },\n\n unknownKnownValueName(name: string, span: Span): ParseError {\n return { type: \"UnknownKnownValueName\", name, span };\n },\n\n invalidDateString(dateString: string, span: Span): ParseError {\n return { type: \"InvalidDateString\", dateString, span };\n },\n\n duplicateMapKey(span: Span): ParseError {\n return { type: \"DuplicateMapKey\", span };\n },\n};\n\n/**\n * Checks if an error is the default unrecognized token error.\n *\n * Corresponds to Rust `Error::is_default()`\n */\nexport function isDefaultError(error: ParseError): boolean {\n return error.type === \"UnrecognizedToken\";\n}\n\n/**\n * Gets the error message for a parse error.\n *\n * Corresponds to Rust's `Display` implementation for `Error`\n */\nexport function errorMessage(error: ParseError): string {\n switch (error.type) {\n case \"EmptyInput\":\n return \"Empty input\";\n case \"UnexpectedEndOfInput\":\n return \"Unexpected end of input\";\n case \"ExtraData\":\n return \"Extra data at end of input\";\n case \"UnexpectedToken\":\n return `Unexpected token ${tokenDebugString(error.token)}`;\n case \"UnrecognizedToken\":\n return \"Unrecognized token\";\n case \"ExpectedComma\":\n return \"Expected comma\";\n case \"ExpectedColon\":\n return \"Expected colon\";\n case \"UnmatchedParentheses\":\n return \"Unmatched parentheses\";\n case \"UnmatchedBraces\":\n return \"Unmatched braces\";\n case \"ExpectedMapKey\":\n return \"Expected map key\";\n case \"InvalidTagValue\":\n return `Invalid tag value '${error.value}'`;\n case \"UnknownTagName\":\n return `Unknown tag name '${error.name}'`;\n case \"InvalidHexString\":\n return \"Invalid hex string\";\n case \"InvalidBase64String\":\n return \"Invalid base64 string\";\n case \"UnknownUrType\":\n return `Unknown UR type '${error.urType}'`;\n case \"InvalidUr\":\n return `Invalid UR '${error.message}'`;\n case \"InvalidKnownValue\":\n return `Invalid known value '${error.value}'`;\n case \"UnknownKnownValueName\":\n return `Unknown known value name '${error.name}'`;\n case \"InvalidDateString\":\n return `Invalid date string '${error.dateString}'`;\n case \"DuplicateMapKey\":\n return \"Duplicate map key\";\n }\n}\n\n/**\n * Gets the span for a parse error, if applicable.\n */\nexport function errorSpan(error: ParseError): Span | undefined {\n switch (error.type) {\n case \"EmptyInput\":\n case \"UnexpectedEndOfInput\":\n return undefined;\n case \"ExtraData\":\n case \"UnexpectedToken\":\n case \"UnrecognizedToken\":\n case \"ExpectedComma\":\n case \"ExpectedColon\":\n case \"UnmatchedParentheses\":\n case \"UnmatchedBraces\":\n case \"ExpectedMapKey\":\n case \"InvalidTagValue\":\n case \"UnknownTagName\":\n case \"InvalidHexString\":\n case \"InvalidBase64String\":\n case \"UnknownUrType\":\n case \"InvalidUr\":\n case \"InvalidKnownValue\":\n case \"UnknownKnownValueName\":\n case \"InvalidDateString\":\n case \"DuplicateMapKey\":\n return error.span;\n }\n}\n\n/**\n * Formats an error message with source context, line number, and caret.\n *\n * Corresponds to Rust `Error::format_message()`\n */\nfunction formatMessage(message: string, source: string, range: Span): string {\n const start = range.start;\n const end = range.end;\n\n // Walk through the characters up to `start` to find line number and line start offset\n let lineNumber = 1;\n let lineStart = 0;\n\n for (let idx = 0; idx < source.length && idx < start; idx++) {\n if (source[idx] === \"\\n\") {\n lineNumber++;\n lineStart = idx + 1;\n }\n }\n\n // Grab the exact line text (or empty if out of bounds)\n const lines = source.split(\"\\n\");\n const line = lines[lineNumber - 1] ?? \"\";\n\n // Column is byte-offset into that line\n const column = Math.max(0, start - lineStart);\n\n // Underline at least one caret, even for zero-width spans\n const underlineLen = Math.max(1, end - start);\n const caret = \" \".repeat(column) + \"^\".repeat(underlineLen);\n\n return `line ${lineNumber}: ${message}\\n${line}\\n${caret}`;\n}\n\n/**\n * Gets the full error message with source context.\n *\n * Corresponds to Rust `Error::full_message()`\n */\nexport function fullErrorMessage(error: ParseError, source: string): string {\n const message = errorMessage(error);\n\n switch (error.type) {\n case \"EmptyInput\":\n return formatMessage(message, source, defaultSpan());\n case \"UnexpectedEndOfInput\":\n return formatMessage(message, source, span(source.length, source.length));\n case \"ExtraData\":\n case \"UnexpectedToken\":\n case \"UnrecognizedToken\":\n case \"ExpectedComma\":\n case \"ExpectedColon\":\n case \"UnmatchedParentheses\":\n case \"UnmatchedBraces\":\n case \"ExpectedMapKey\":\n case \"InvalidTagValue\":\n case \"UnknownTagName\":\n case \"InvalidHexString\":\n case \"InvalidBase64String\":\n case \"UnknownUrType\":\n case \"InvalidUr\":\n case \"InvalidKnownValue\":\n case \"UnknownKnownValueName\":\n case \"InvalidDateString\":\n case \"DuplicateMapKey\":\n return formatMessage(message, source, error.span);\n }\n}\n\n/**\n * Creates a default parse error (UnrecognizedToken with empty span).\n *\n * Corresponds to Rust `Error::default()`\n */\nexport function defaultParseError(): ParseError {\n return parseError.unrecognizedToken(defaultSpan());\n}\n\n/**\n * Result type for parse operations.\n *\n * Corresponds to Rust `Result<T, Error>`\n */\nexport type ParseResult<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: ParseError };\n\n/**\n * Creates a successful result.\n */\nexport function ok<T>(value: T): ParseResult<T> {\n return { ok: true, value };\n}\n\n/**\n * Creates an error result.\n */\nexport function err<T>(error: ParseError): ParseResult<T> {\n return { ok: false, error };\n}\n\n/**\n * Checks if a result is successful.\n */\nexport function isOk<T>(result: ParseResult<T>): result is { ok: true; value: T } {\n return result.ok;\n}\n\n/**\n * Checks if a result is an error.\n */\nexport function isErr<T>(result: ParseResult<T>): result is { ok: false; error: ParseError } {\n return !result.ok;\n}\n\n/**\n * Unwraps a result, throwing if it's an error.\n */\nexport function unwrap<T>(result: ParseResult<T>): T {\n if (result.ok) {\n return result.value;\n }\n throw new Error(errorMessage(result.error));\n}\n\n/**\n * Unwraps a result error, throwing if it's successful.\n */\nexport function unwrapErr<T>(result: ParseResult<T>): ParseError {\n if (!result.ok) {\n return result.error;\n }\n throw new Error(\"Called unwrapErr on an Ok result\");\n}\n\n// Helper function to get debug string for a token (forward declaration resolved at runtime)\nfunction tokenDebugString(token: Token): string {\n // Simple debug representation\n return JSON.stringify(token);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Token types and Lexer\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust token.rs\n *\n * @module dcbor-parse/token\n */\n\nimport { type CborDate, CborDate as DCborDate } from \"@bcts/dcbor\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { type Span, span, parseError as PE, type ParseResult, ok, err } from \"./error\";\n\n/**\n * Token types produced by the lexer.\n *\n * Corresponds to the Rust `Token` enum in token.rs\n */\nexport type Token =\n | { readonly type: \"Bool\"; readonly value: boolean }\n | { readonly type: \"BraceOpen\" }\n | { readonly type: \"BraceClose\" }\n | { readonly type: \"BracketOpen\" }\n | { readonly type: \"BracketClose\" }\n | { readonly type: \"ParenthesisOpen\" }\n | { readonly type: \"ParenthesisClose\" }\n | { readonly type: \"Colon\" }\n | { readonly type: \"Comma\" }\n | { readonly type: \"Null\" }\n | { readonly type: \"NaN\" }\n | { readonly type: \"Infinity\" }\n | { readonly type: \"NegInfinity\" }\n | { readonly type: \"ByteStringHex\"; readonly value: Uint8Array }\n | { readonly type: \"ByteStringBase64\"; readonly value: Uint8Array }\n | { readonly type: \"DateLiteral\"; readonly value: CborDate }\n | { readonly type: \"Number\"; readonly value: number }\n | { readonly type: \"String\"; readonly value: string }\n | { readonly type: \"TagValue\"; readonly value: number }\n | { readonly type: \"TagName\"; readonly value: string }\n | { readonly type: \"KnownValueNumber\"; readonly value: number }\n | { readonly type: \"KnownValueName\"; readonly value: string }\n | { readonly type: \"Unit\" }\n | { readonly type: \"UR\"; readonly value: UR };\n\n// Token constructors (lowercase to differentiate from the type)\nexport const token = {\n bool(value: boolean): Token {\n return { type: \"Bool\", value };\n },\n braceOpen(): Token {\n return { type: \"BraceOpen\" };\n },\n braceClose(): Token {\n return { type: \"BraceClose\" };\n },\n bracketOpen(): Token {\n return { type: \"BracketOpen\" };\n },\n bracketClose(): Token {\n return { type: \"BracketClose\" };\n },\n parenthesisOpen(): Token {\n return { type: \"ParenthesisOpen\" };\n },\n parenthesisClose(): Token {\n return { type: \"ParenthesisClose\" };\n },\n colon(): Token {\n return { type: \"Colon\" };\n },\n comma(): Token {\n return { type: \"Comma\" };\n },\n null(): Token {\n return { type: \"Null\" };\n },\n nan(): Token {\n return { type: \"NaN\" };\n },\n infinity(): Token {\n return { type: \"Infinity\" };\n },\n negInfinity(): Token {\n return { type: \"NegInfinity\" };\n },\n byteStringHex(value: Uint8Array): Token {\n return { type: \"ByteStringHex\", value };\n },\n byteStringBase64(value: Uint8Array): Token {\n return { type: \"ByteStringBase64\", value };\n },\n dateLiteral(value: CborDate): Token {\n return { type: \"DateLiteral\", value };\n },\n number(value: number): Token {\n return { type: \"Number\", value };\n },\n string(value: string): Token {\n return { type: \"String\", value };\n },\n tagValue(value: number): Token {\n return { type: \"TagValue\", value };\n },\n tagName(value: string): Token {\n return { type: \"TagName\", value };\n },\n knownValueNumber(value: number): Token {\n return { type: \"KnownValueNumber\", value };\n },\n knownValueName(value: string): Token {\n return { type: \"KnownValueName\", value };\n },\n unit(): Token {\n return { type: \"Unit\" };\n },\n ur(value: UR): Token {\n return { type: \"UR\", value };\n },\n};\n\n/**\n * Lexer for dCBOR diagnostic notation.\n *\n * Corresponds to the Rust `logos::Lexer` used in parse.rs\n */\nexport class Lexer {\n private readonly _source: string;\n private _position: number;\n private _tokenStart: number;\n private _tokenEnd: number;\n\n constructor(source: string) {\n this._source = source;\n this._position = 0;\n this._tokenStart = 0;\n this._tokenEnd = 0;\n }\n\n /**\n * Gets the current span (position range of the last token).\n */\n span(): Span {\n return span(this._tokenStart, this._tokenEnd);\n }\n\n /**\n * Gets the slice of source corresponding to the last token.\n */\n slice(): string {\n return this._source.slice(this._tokenStart, this._tokenEnd);\n }\n\n /**\n * Gets the next token, or undefined if at end of input.\n * Returns a Result to handle lexing errors.\n */\n next(): ParseResult<Token> | undefined {\n this._skipWhitespaceAndComments();\n\n if (this._position >= this._source.length) {\n return undefined;\n }\n\n this._tokenStart = this._position;\n\n // Try to match tokens in order of specificity\n const result =\n this._tryMatchKeyword() ??\n this._tryMatchDateLiteral() ??\n this._tryMatchTagValueOrNumber() ??\n this._tryMatchTagName() ??\n this._tryMatchString() ??\n this._tryMatchByteStringHex() ??\n this._tryMatchByteStringBase64() ??\n this._tryMatchKnownValue() ??\n this._tryMatchUR() ??\n this._tryMatchPunctuation();\n\n if (result === undefined) {\n // Unrecognized token - consume one character\n this._position++;\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n return result;\n }\n\n private _skipWhitespaceAndComments(): void {\n while (this._position < this._source.length) {\n const ch = this._source[this._position];\n\n // Skip whitespace\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\r\" || ch === \"\\n\" || ch === \"\\f\") {\n this._position++;\n continue;\n }\n\n // Skip inline comments: /.../ (not preceded by another /)\n if (\n ch === \"/\" &&\n this._position + 1 < this._source.length &&\n this._source[this._position + 1] !== \"/\"\n ) {\n this._position++; // Skip opening /\n while (this._position < this._source.length && this._source[this._position] !== \"/\") {\n this._position++;\n }\n if (this._position < this._source.length) {\n this._position++; // Skip closing /\n }\n continue;\n }\n\n // Skip end-of-line comments: #...\n if (ch === \"#\") {\n while (this._position < this._source.length && this._source[this._position] !== \"\\n\") {\n this._position++;\n }\n continue;\n }\n\n break;\n }\n }\n\n private _tryMatchKeyword(): ParseResult<Token> | undefined {\n const keywords: [string, Token][] = [\n [\"true\", token.bool(true)],\n [\"false\", token.bool(false)],\n [\"null\", token.null()],\n [\"NaN\", token.nan()],\n [\"Infinity\", token.infinity()],\n [\"-Infinity\", token.negInfinity()],\n [\"Unit\", token.unit()],\n ];\n\n for (const [keyword, tok] of keywords) {\n if (this._matchLiteral(keyword)) {\n // Make sure it's not part of a longer identifier\n const nextChar = this._source[this._position];\n if (nextChar === undefined || !this._isIdentifierChar(nextChar)) {\n this._tokenEnd = this._position;\n return ok(tok);\n }\n // Reset position if it was a partial match\n this._position = this._tokenStart;\n }\n }\n\n return undefined;\n }\n\n private _tryMatchDateLiteral(): ParseResult<Token> | undefined {\n // ISO-8601 date: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS...\n const dateRegex = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})?)?/;\n const remaining = this._source.slice(this._position);\n const match = dateRegex.exec(remaining);\n\n if (match !== null) {\n const dateStr = match[0];\n this._position += dateStr.length;\n this._tokenEnd = this._position;\n\n // Validate date components before parsing to match Rust's strict behavior\n if (!isValidDateString(dateStr)) {\n return err(PE.invalidDateString(dateStr, this.span()));\n }\n\n try {\n const date = DCborDate.fromString(dateStr);\n return ok(token.dateLiteral(date));\n } catch {\n return err(PE.invalidDateString(dateStr, this.span()));\n }\n }\n\n return undefined;\n }\n\n private _tryMatchTagValueOrNumber(): ParseResult<Token> | undefined {\n // Check for tag value: integer followed by (\n // Or just a number\n const numberRegex = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/;\n const remaining = this._source.slice(this._position);\n const match = numberRegex.exec(remaining);\n\n if (match !== null) {\n const numStr = match[0];\n const nextChar = this._source[this._position + numStr.length];\n\n // Check if this is a tag value (integer followed by parenthesis)\n if (\n nextChar === \"(\" &&\n !numStr.includes(\".\") &&\n !numStr.includes(\"e\") &&\n !numStr.includes(\"E\") &&\n !numStr.startsWith(\"-\")\n ) {\n // It's a tag value\n this._position += numStr.length + 1; // Include the (\n this._tokenEnd = this._position;\n\n const tagValue = parseInt(numStr, 10);\n if (!Number.isSafeInteger(tagValue) || tagValue < 0) {\n return err(\n PE.invalidTagValue(numStr, span(this._tokenStart, this._tokenStart + numStr.length)),\n );\n }\n\n return ok(token.tagValue(tagValue));\n }\n\n // It's a regular number\n this._position += numStr.length;\n this._tokenEnd = this._position;\n\n const num = parseFloat(numStr);\n return ok(token.number(num));\n }\n\n return undefined;\n }\n\n private _tryMatchTagName(): ParseResult<Token> | undefined {\n // Tag name: identifier followed by (\n const tagNameRegex = /^[a-zA-Z_][a-zA-Z0-9_-]*\\(/;\n const remaining = this._source.slice(this._position);\n const match = tagNameRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const name = fullMatch.slice(0, -1); // Remove trailing (\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n return ok(token.tagName(name));\n }\n\n return undefined;\n }\n\n private _tryMatchString(): ParseResult<Token> | undefined {\n if (this._source[this._position] !== '\"') {\n return undefined;\n }\n\n // JavaScript-style string with escape sequences\n // eslint-disable-next-line no-control-regex\n const stringRegex = /^\"([^\"\\\\\\x00-\\x1F]|\\\\([\"\\\\bnfrt/]|u[a-fA-F0-9]{4}))*\"/;\n const remaining = this._source.slice(this._position);\n const match = stringRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n // Return the full string including quotes\n return ok(token.string(fullMatch));\n }\n\n // Invalid string - try to find where it ends for better error reporting\n this._position++;\n while (this._position < this._source.length) {\n const ch = this._source[this._position];\n if (ch === '\"' || ch === \"\\n\") {\n if (ch === '\"') this._position++;\n break;\n }\n if (ch === \"\\\\\") {\n this._position += 2;\n } else {\n this._position++;\n }\n }\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n private _tryMatchByteStringHex(): ParseResult<Token> | undefined {\n // h'...'\n if (!this._matchLiteral(\"h'\")) {\n return undefined;\n }\n\n const hexRegex = /^[0-9a-fA-F]*/;\n const remaining = this._source.slice(this._position);\n const match = hexRegex.exec(remaining);\n const hexPart = match !== null ? match[0] : \"\";\n\n this._position += hexPart.length;\n\n if (this._source[this._position] !== \"'\") {\n this._tokenEnd = this._position;\n return err(PE.invalidHexString(this.span()));\n }\n\n this._position++; // Skip closing '\n this._tokenEnd = this._position;\n\n // Check that hex string has even length\n if (hexPart.length % 2 !== 0) {\n return err(PE.invalidHexString(this.span()));\n }\n\n // Decode hex\n const bytes = hexToBytes(hexPart);\n return ok(token.byteStringHex(bytes));\n }\n\n private _tryMatchByteStringBase64(): ParseResult<Token> | undefined {\n // b64'...'\n if (!this._matchLiteral(\"b64'\")) {\n return undefined;\n }\n\n const base64Regex = /^[A-Za-z0-9+/=]*/;\n const remaining = this._source.slice(this._position);\n const match = base64Regex.exec(remaining);\n const base64Part = match !== null ? match[0] : \"\";\n\n this._position += base64Part.length;\n\n if (this._source[this._position] !== \"'\") {\n this._tokenEnd = this._position;\n return err(PE.invalidBase64String(this.span()));\n }\n\n this._position++; // Skip closing '\n this._tokenEnd = this._position;\n\n // Check minimum length requirement (2 characters)\n if (base64Part.length < 2) {\n return err(PE.invalidBase64String(this.span()));\n }\n\n // Decode base64\n try {\n const bytes = base64ToBytes(base64Part);\n return ok(token.byteStringBase64(bytes));\n } catch {\n return err(PE.invalidBase64String(this.span()));\n }\n }\n\n private _tryMatchKnownValue(): ParseResult<Token> | undefined {\n if (this._source[this._position] !== \"'\") {\n return undefined;\n }\n\n // Check for empty string '' (Unit)\n if (this._source[this._position + 1] === \"'\") {\n this._position += 2;\n this._tokenEnd = this._position;\n return ok(token.knownValueName(\"\"));\n }\n\n // Check for numeric known value: '0' or '[1-9][0-9]*'\n const numericRegex = /^'(0|[1-9][0-9]*)'/;\n const remaining = this._source.slice(this._position);\n let match = numericRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const numStr = match[1];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n const value = parseInt(numStr, 10);\n if (!Number.isSafeInteger(value) || value < 0) {\n return err(PE.invalidKnownValue(numStr, span(this._tokenStart + 1, this._tokenEnd - 1)));\n }\n\n return ok(token.knownValueNumber(value));\n }\n\n // Check for named known value: '[a-zA-Z_][a-zA-Z0-9_-]*'\n const nameRegex = /^'([a-zA-Z_][a-zA-Z0-9_-]*)'/;\n match = nameRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const name = match[1];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n return ok(token.knownValueName(name));\n }\n\n // Invalid known value\n this._position++;\n while (this._position < this._source.length && this._source[this._position] !== \"'\") {\n this._position++;\n }\n if (this._position < this._source.length) {\n this._position++;\n }\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n private _tryMatchUR(): ParseResult<Token> | undefined {\n // ur:type/data\n const urRegex = /^ur:([a-zA-Z0-9][a-zA-Z0-9-]*)\\/([a-zA-Z]{8,})/;\n const remaining = this._source.slice(this._position);\n const match = urRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n try {\n const ur = UR.fromURString(fullMatch);\n return ok(token.ur(ur));\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return err(PE.invalidUr(errorMsg, this.span()));\n }\n }\n\n return undefined;\n }\n\n private _tryMatchPunctuation(): ParseResult<Token> | undefined {\n const ch = this._source[this._position];\n\n const punctuation: Record<string, Token> = {\n \"{\": token.braceOpen(),\n \"}\": token.braceClose(),\n \"[\": token.bracketOpen(),\n \"]\": token.bracketClose(),\n \"(\": token.parenthesisOpen(),\n \")\": token.parenthesisClose(),\n \":\": token.colon(),\n \",\": token.comma(),\n };\n\n const matched = punctuation[ch];\n if (matched !== undefined) {\n this._position++;\n this._tokenEnd = this._position;\n return ok(matched);\n }\n\n return undefined;\n }\n\n private _matchLiteral(literal: string): boolean {\n if (this._source.slice(this._position, this._position + literal.length) === literal) {\n this._position += literal.length;\n return true;\n }\n return false;\n }\n\n private _isIdentifierChar(ch: string): boolean {\n return /[a-zA-Z0-9_-]/.test(ch);\n }\n}\n\n/**\n * Converts a hex string to bytes.\n */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Converts a base64 string to bytes with strict validation.\n * Rejects base64 strings with invalid padding (matches Rust's base64 crate behavior).\n */\nfunction base64ToBytes(base64: string): Uint8Array {\n // Validate base64 padding strictly (Rust's base64 crate requires proper padding)\n const expectedPadding = (4 - (base64.replace(/=/g, \"\").length % 4)) % 4;\n const paddingMatch = /=+$/.exec(base64);\n const actualPadding = paddingMatch !== null ? paddingMatch[0].length : 0;\n\n // If there should be padding but there isn't, or padding is wrong length\n if (expectedPadding !== actualPadding) {\n throw new Error(\"Invalid base64 padding\");\n }\n\n // Use built-in atob for base64 decoding\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Validates a date string has valid month/day values.\n * JavaScript Date is lenient and accepts invalid dates like 2023-02-30,\n * but Rust's Date::from_string rejects them.\n */\nfunction isValidDateString(dateStr: string): boolean {\n // Extract date components\n const dateMatch = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(dateStr);\n if (dateMatch === null) return false;\n\n const year = parseInt(dateMatch[1], 10);\n const month = parseInt(dateMatch[2], 10);\n const day = parseInt(dateMatch[3], 10);\n\n // Validate month (1-12)\n if (month < 1 || month > 12) return false;\n\n // Validate day (1-N where N depends on month)\n if (day < 1) return false;\n\n // Days in each month (non-leap year)\n const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n // Adjust for leap year\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n if (isLeapYear && month === 2) {\n if (day > 29) return false;\n } else {\n if (day > daysInMonth[month - 1]) return false;\n }\n\n // If there's a time component, validate it\n const timeMatch = /T(\\d{2}):(\\d{2}):(\\d{2})/.exec(dateStr);\n if (timeMatch !== null) {\n const hour = parseInt(timeMatch[1], 10);\n const minute = parseInt(timeMatch[2], 10);\n const second = parseInt(timeMatch[3], 10);\n\n if (hour < 0 || hour > 23) return false;\n if (minute < 0 || minute > 59) return false;\n if (second < 0 || second > 59) return false;\n }\n\n return true;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Parse module\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust parse.rs\n *\n * @module dcbor-parse/parse\n */\n\nimport { type Cbor, cbor, CborMap, getGlobalTagsStore } from \"@bcts/dcbor\";\nimport { KnownValue, KNOWN_VALUES } from \"@bcts/known-values\";\nimport type { UR } from \"@bcts/uniform-resources\";\nimport {\n type Span,\n span,\n parseError as PE,\n type ParseResult,\n ok,\n err,\n isDefaultError,\n} from \"./error\";\nimport { type Token, Lexer } from \"./token\";\n\n/**\n * Parses a dCBOR item from a string input.\n *\n * This function takes a string slice containing a dCBOR diagnostic notation\n * encoded value and attempts to parse it into a `Cbor` object. If the input\n * contains extra tokens after a valid item, an error is returned.\n *\n * @param src - A string containing the dCBOR-encoded data.\n * @returns `Ok(Cbor)` if parsing is successful and the input contains exactly one\n * valid dCBOR item, which itself might be an atomic value like a number or\n * string, or a complex value like an array or map.\n * `Err(ParseError)` if parsing fails or if extra tokens are found after the item.\n *\n * @example\n * ```typescript\n * const result = parseDcborItem(\"[1, 2, 3]\");\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"[1, 2, 3]\"\n * }\n * ```\n */\nexport function parseDcborItem(src: string): ParseResult<Cbor> {\n const lexer = new Lexer(src);\n const firstTokenResult = expectToken(lexer);\n\n if (!firstTokenResult.ok) {\n if (firstTokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.emptyInput());\n }\n return firstTokenResult;\n }\n\n const parseResult = parseItemToken(firstTokenResult.value, lexer);\n if (!parseResult.ok) {\n return parseResult;\n }\n\n // Check for extra data\n const nextToken = lexer.next();\n if (nextToken !== undefined) {\n return err(PE.extraData(lexer.span()));\n }\n\n return parseResult;\n}\n\n/**\n * Parses a dCBOR item from the beginning of a string and returns the parsed\n * `Cbor` along with the number of bytes consumed.\n *\n * Unlike `parseDcborItem`, this function succeeds even if additional\n * characters follow the first item. The returned index points to the first\n * unparsed character after skipping any trailing whitespace or comments.\n *\n * @param src - A string containing the dCBOR-encoded data.\n * @returns `Ok([Cbor, number])` with the parsed item and bytes consumed.\n *\n * @example\n * ```typescript\n * const result = parseDcborItemPartial(\"true )\");\n * if (result.ok) {\n * const [cbor, used] = result.value;\n * console.log(cbor.toDiagnostic()); // \"true\"\n * console.log(used); // 5\n * }\n * ```\n */\nexport function parseDcborItemPartial(src: string): ParseResult<[Cbor, number]> {\n const lexer = new Lexer(src);\n const firstTokenResult = expectToken(lexer);\n\n if (!firstTokenResult.ok) {\n if (firstTokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.emptyInput());\n }\n return firstTokenResult;\n }\n\n const parseResult = parseItemToken(firstTokenResult.value, lexer);\n if (!parseResult.ok) {\n return parseResult;\n }\n\n // Determine consumed bytes\n const nextToken = lexer.next();\n const consumed = nextToken !== undefined ? lexer.span().start : src.length;\n\n return ok([parseResult.value, consumed]);\n}\n\n// === Private Functions ===\n\nfunction parseItem(lexer: Lexer): ParseResult<Cbor> {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n return parseItemToken(tokenResult.value, lexer);\n}\n\nfunction expectToken(lexer: Lexer): ParseResult<Token> {\n const spanBefore = lexer.span();\n const result = lexer.next();\n\n if (result === undefined) {\n return err(PE.unexpectedEndOfInput());\n }\n\n if (!result.ok) {\n if (isDefaultError(result.error)) {\n return err(PE.unrecognizedToken(spanBefore));\n }\n return result;\n }\n\n return result;\n}\n\nfunction parseItemToken(token: Token, lexer: Lexer): ParseResult<Cbor> {\n switch (token.type) {\n case \"Bool\":\n return ok(cbor(token.value));\n\n case \"Null\":\n return ok(cbor(null));\n\n case \"ByteStringHex\":\n return ok(cbor(token.value));\n\n case \"ByteStringBase64\":\n return ok(cbor(token.value));\n\n case \"DateLiteral\":\n return ok(cbor(token.value));\n\n case \"Number\":\n return ok(cbor(token.value));\n\n case \"NaN\":\n return ok(cbor(Number.NaN));\n\n case \"Infinity\":\n return ok(cbor(Number.POSITIVE_INFINITY));\n\n case \"NegInfinity\":\n return ok(cbor(Number.NEGATIVE_INFINITY));\n\n case \"String\":\n return parseString(token.value, lexer.span());\n\n case \"UR\":\n return parseUr(token.value, lexer.span());\n\n case \"TagValue\":\n return parseNumberTag(token.value, lexer);\n\n case \"TagName\":\n return parseNameTag(token.value, lexer);\n\n case \"KnownValueNumber\":\n return ok(new KnownValue(token.value).taggedCbor());\n\n case \"KnownValueName\": {\n // Empty string means Unit (value 0)\n if (token.value === \"\") {\n return ok(new KnownValue(0).taggedCbor());\n }\n\n const knownValue = knownValueForName(token.value);\n if (knownValue !== undefined) {\n return ok(knownValue.taggedCbor());\n }\n const tokenSpan = lexer.span();\n return err(\n PE.unknownKnownValueName(token.value, span(tokenSpan.start + 1, tokenSpan.end - 1)),\n );\n }\n\n case \"Unit\":\n return ok(new KnownValue(0).taggedCbor());\n\n case \"BracketOpen\":\n return parseArray(lexer);\n\n case \"BraceOpen\":\n return parseMap(lexer);\n\n // Syntactic tokens that cannot start an item\n case \"BraceClose\":\n case \"BracketClose\":\n case \"ParenthesisOpen\":\n case \"ParenthesisClose\":\n case \"Colon\":\n case \"Comma\":\n return err(PE.unexpectedToken(token, lexer.span()));\n }\n}\n\nfunction parseString(s: string, tokenSpan: Span): ParseResult<Cbor> {\n if (s.startsWith('\"') && s.endsWith('\"')) {\n // Remove quotes and return the inner string\n const inner = s.slice(1, -1);\n return ok(cbor(inner));\n }\n return err(PE.unrecognizedToken(tokenSpan));\n}\n\nfunction tagForName(name: string): number | bigint | undefined {\n return getGlobalTagsStore().tagForName(name)?.value;\n}\n\nfunction knownValueForName(name: string): KnownValue | undefined {\n return KNOWN_VALUES.get().knownValueNamed(name);\n}\n\nfunction parseUr(ur: UR, tokenSpan: Span): ParseResult<Cbor> {\n const urType = ur.urTypeStr();\n const tag = tagForName(urType);\n\n if (tag !== undefined) {\n return ok(cbor({ tag, value: ur.cbor() }));\n }\n\n return err(\n PE.unknownUrType(urType, span(tokenSpan.start + 3, tokenSpan.start + 3 + urType.length)),\n );\n}\n\nfunction parseNumberTag(tagValue: number, lexer: Lexer): ParseResult<Cbor> {\n const itemResult = parseItem(lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n const closeResult = expectToken(lexer);\n if (!closeResult.ok) {\n if (closeResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.unmatchedParentheses(lexer.span()));\n }\n return closeResult;\n }\n\n if (closeResult.value.type === \"ParenthesisClose\") {\n return ok(cbor({ tag: tagValue, value: itemResult.value }));\n }\n\n return err(PE.unmatchedParentheses(lexer.span()));\n}\n\nfunction parseNameTag(name: string, lexer: Lexer): ParseResult<Cbor> {\n const tagSpan = span(lexer.span().start, lexer.span().end - 1);\n\n const itemResult = parseItem(lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n const closeResult = expectToken(lexer);\n if (!closeResult.ok) {\n return closeResult;\n }\n\n if (closeResult.value.type === \"ParenthesisClose\") {\n const tag = tagForName(name);\n if (tag !== undefined) {\n return ok(cbor({ tag, value: itemResult.value }));\n }\n return err(PE.unknownTagName(name, tagSpan));\n }\n\n return err(PE.unmatchedParentheses(lexer.span()));\n}\n\nfunction parseArray(lexer: Lexer): ParseResult<Cbor> {\n const items: Cbor[] = [];\n let awaitsComma = false;\n let awaitsItem = false;\n\n while (true) {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value;\n\n // Handle closing bracket\n if (token.type === \"BracketClose\" && !awaitsItem) {\n return ok(cbor(items));\n }\n\n // Handle comma\n if (token.type === \"Comma\" && awaitsComma) {\n awaitsItem = true;\n awaitsComma = false;\n continue;\n }\n\n // Expect an item when not awaiting comma\n if (awaitsComma) {\n return err(PE.expectedComma(lexer.span()));\n }\n\n // Parse the item\n const itemResult = parseItemToken(token, lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n items.push(itemResult.value);\n awaitsItem = false;\n awaitsComma = true;\n }\n}\n\nfunction parseMap(lexer: Lexer): ParseResult<Cbor> {\n const map = new CborMap();\n let awaitsComma = false;\n let awaitsKey = false;\n\n while (true) {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n if (tokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.unmatchedBraces(lexer.span()));\n }\n return tokenResult;\n }\n\n const token = tokenResult.value;\n\n // Handle closing brace\n if (token.type === \"BraceClose\" && !awaitsKey) {\n return ok(cbor(map));\n }\n\n // Handle comma\n if (token.type === \"Comma\" && awaitsComma) {\n awaitsKey = true;\n awaitsComma = false;\n continue;\n }\n\n // Expect a key when not awaiting comma\n if (awaitsComma) {\n return err(PE.expectedComma(lexer.span()));\n }\n\n // Parse the key\n const keyResult = parseItemToken(token, lexer);\n if (!keyResult.ok) {\n return keyResult;\n }\n\n const key = keyResult.value;\n const keySpan = lexer.span();\n\n // Check for duplicate key\n if (map.has(key)) {\n return err(PE.duplicateMapKey(keySpan));\n }\n\n // Expect colon\n const colonResult = expectToken(lexer);\n if (!colonResult.ok) {\n return colonResult;\n }\n\n if (colonResult.value.type !== \"Colon\") {\n return err(PE.expectedColon(lexer.span()));\n }\n\n // Parse the value\n const valueResult = parseItem(lexer);\n if (!valueResult.ok) {\n if (valueResult.error.type === \"UnexpectedToken\") {\n const unexpectedToken = (valueResult.error as { token: Token }).token;\n if (unexpectedToken.type === \"BraceClose\") {\n return err(PE.expectedMapKey(lexer.span()));\n }\n }\n return valueResult;\n }\n\n map.set(key, valueResult.value);\n awaitsKey = false;\n awaitsComma = true;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Compose module\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust compose.rs\n *\n * @module dcbor-parse/compose\n */\n\nimport { type Cbor, cbor, CborMap } from \"@bcts/dcbor\";\nimport type { ParseError } from \"./error\";\nimport { parseDcborItem } from \"./parse\";\n\n/**\n * Compose error types.\n *\n * Corresponds to the Rust `Error` enum in compose.rs\n */\nexport type ComposeError =\n | { readonly type: \"OddMapLength\" }\n | { readonly type: \"DuplicateMapKey\" }\n | { readonly type: \"ParseError\"; readonly error: ParseError };\n\n// ComposeError constructors (lowercase to differentiate from the type)\nexport const composeError = {\n oddMapLength(): ComposeError {\n return { type: \"OddMapLength\" };\n },\n\n duplicateMapKey(): ComposeError {\n return { type: \"DuplicateMapKey\" };\n },\n\n parseError(error: ParseError): ComposeError {\n return { type: \"ParseError\", error };\n },\n};\n\n/**\n * Gets the error message for a compose error.\n */\nexport function composeErrorMessage(error: ComposeError): string {\n switch (error.type) {\n case \"OddMapLength\":\n return \"Invalid odd map length\";\n case \"DuplicateMapKey\":\n return \"Duplicate map key\";\n case \"ParseError\":\n return `Invalid CBOR item: ${error.error.type}`;\n }\n}\n\n/**\n * Result type for compose operations.\n *\n * Corresponds to Rust `Result<T, Error>`\n */\nexport type ComposeResult<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: ComposeError };\n\n/**\n * Creates a successful compose result.\n */\nexport function composeOk<T>(value: T): ComposeResult<T> {\n return { ok: true, value };\n}\n\n/**\n * Creates an error compose result.\n */\nexport function composeErr<T>(error: ComposeError): ComposeResult<T> {\n return { ok: false, error };\n}\n\n/**\n * Composes a dCBOR array from a slice of string slices, and returns a CBOR\n * object representing the array.\n *\n * Each string slice is parsed as a dCBOR item.\n *\n * @param array - Array of strings, each representing a dCBOR item\n * @returns A CBOR array containing all parsed items\n *\n * @example\n * ```typescript\n * const result = composeDcborArray([\"1\", \"2\", \"3\"]);\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"[1, 2, 3]\"\n * }\n * ```\n */\nexport function composeDcborArray(array: readonly string[]): ComposeResult<Cbor> {\n const result: Cbor[] = [];\n\n for (const item of array) {\n const parseResult = parseDcborItem(item);\n if (!parseResult.ok) {\n return composeErr(composeError.parseError(parseResult.error));\n }\n result.push(parseResult.value);\n }\n\n return composeOk(cbor(result));\n}\n\n/**\n * Composes a dCBOR map from a slice of string slices, and returns a CBOR\n * object representing the map.\n *\n * The length of the slice must be even, as each key must have a corresponding\n * value.\n *\n * Each string slice is parsed as a dCBOR item.\n *\n * @param array - Array of strings representing key-value pairs in alternating order\n * @returns A CBOR map containing all parsed key-value pairs\n *\n * @example\n * ```typescript\n * const result = composeDcborMap([\"1\", \"2\", \"3\", \"4\"]);\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"{1: 2, 3: 4}\"\n * }\n * ```\n */\nexport function composeDcborMap(array: readonly string[]): ComposeResult<Cbor> {\n if (array.length % 2 !== 0) {\n return composeErr(composeError.oddMapLength());\n }\n\n const map = new CborMap();\n\n for (let i = 0; i < array.length; i += 2) {\n const keyStr = array[i];\n const valueStr = array[i + 1];\n\n const keyResult = parseDcborItem(keyStr);\n if (!keyResult.ok) {\n return composeErr(composeError.parseError(keyResult.error));\n }\n\n const valueResult = parseDcborItem(valueStr);\n if (!valueResult.ok) {\n return composeErr(composeError.parseError(valueResult.error));\n }\n\n // Check for duplicate key\n if (map.has(keyResult.value)) {\n return composeErr(composeError.duplicateMapKey());\n }\n\n map.set(keyResult.value, valueResult.value);\n }\n\n return composeOk(cbor(map));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.iife.js","names":["PE","DCborDate","UR","PE","KnownValue","KNOWN_VALUES","CborMap","CborMap"],"sources":["../src/error.ts","../src/token.ts","../src/parse.ts","../src/compose.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Error types\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust error.rs\n *\n * @module dcbor-parse/error\n */\n\nimport type { Token } from \"./token\";\n\n/**\n * Represents a span (range) in the source string.\n *\n * Corresponds to the Rust `logos::Span` type.\n *\n * **Encoding caveat (TS↔Rust)**: Rust spans are *byte* offsets into the\n * UTF-8 source. JavaScript strings are UTF-16 code-unit indexed, and\n * the TS lexer reports spans in those native code-unit units. The two\n * representations agree for ASCII input. For non-BMP / multi-byte\n * input (e.g. `\"🌎\"`, emoji, CJK characters) the indices diverge. If\n * you need byte-exact spans across implementations, transcode the\n * source to UTF-8 first or apply the equivalent `String.length` ↔\n * UTF-8 byte length conversion at the boundary.\n */\nexport interface Span {\n readonly start: number;\n readonly end: number;\n}\n\n/**\n * Creates a span with the given start and end positions.\n */\nexport function span(start: number, end: number): Span {\n return { start, end };\n}\n\n/**\n * Creates a default (empty) span.\n */\nexport function defaultSpan(): Span {\n return { start: 0, end: 0 };\n}\n\n/**\n * Parse error types.\n *\n * Corresponds to the Rust `Error` enum in error.rs\n */\nexport type ParseError =\n | { readonly type: \"EmptyInput\" }\n | { readonly type: \"UnexpectedEndOfInput\" }\n | { readonly type: \"ExtraData\"; readonly span: Span }\n | { readonly type: \"UnexpectedToken\"; readonly token: Token; readonly span: Span }\n | { readonly type: \"UnrecognizedToken\"; readonly span: Span }\n | { readonly type: \"ExpectedComma\"; readonly span: Span }\n | { readonly type: \"ExpectedColon\"; readonly span: Span }\n | { readonly type: \"UnmatchedParentheses\"; readonly span: Span }\n | { readonly type: \"UnmatchedBraces\"; readonly span: Span }\n | { readonly type: \"ExpectedMapKey\"; readonly span: Span }\n | { readonly type: \"InvalidTagValue\"; readonly value: string; readonly span: Span }\n | { readonly type: \"UnknownTagName\"; readonly name: string; readonly span: Span }\n | { readonly type: \"InvalidHexString\"; readonly span: Span }\n | { readonly type: \"InvalidBase64String\"; readonly span: Span }\n | { readonly type: \"UnknownUrType\"; readonly urType: string; readonly span: Span }\n | { readonly type: \"InvalidUr\"; readonly message: string; readonly span: Span }\n | { readonly type: \"InvalidKnownValue\"; readonly value: string; readonly span: Span }\n | { readonly type: \"UnknownKnownValueName\"; readonly name: string; readonly span: Span }\n | { readonly type: \"InvalidDateString\"; readonly dateString: string; readonly span: Span }\n | { readonly type: \"DuplicateMapKey\"; readonly span: Span };\n\n// Error constructors (lowercase to differentiate from the type)\nexport const parseError = {\n emptyInput(): ParseError {\n return { type: \"EmptyInput\" };\n },\n\n unexpectedEndOfInput(): ParseError {\n return { type: \"UnexpectedEndOfInput\" };\n },\n\n extraData(span: Span): ParseError {\n return { type: \"ExtraData\", span };\n },\n\n unexpectedToken(token: Token, span: Span): ParseError {\n return { type: \"UnexpectedToken\", token, span };\n },\n\n unrecognizedToken(span: Span): ParseError {\n return { type: \"UnrecognizedToken\", span };\n },\n\n expectedComma(span: Span): ParseError {\n return { type: \"ExpectedComma\", span };\n },\n\n expectedColon(span: Span): ParseError {\n return { type: \"ExpectedColon\", span };\n },\n\n unmatchedParentheses(span: Span): ParseError {\n return { type: \"UnmatchedParentheses\", span };\n },\n\n unmatchedBraces(span: Span): ParseError {\n return { type: \"UnmatchedBraces\", span };\n },\n\n expectedMapKey(span: Span): ParseError {\n return { type: \"ExpectedMapKey\", span };\n },\n\n invalidTagValue(value: string, span: Span): ParseError {\n return { type: \"InvalidTagValue\", value, span };\n },\n\n unknownTagName(name: string, span: Span): ParseError {\n return { type: \"UnknownTagName\", name, span };\n },\n\n invalidHexString(span: Span): ParseError {\n return { type: \"InvalidHexString\", span };\n },\n\n invalidBase64String(span: Span): ParseError {\n return { type: \"InvalidBase64String\", span };\n },\n\n unknownUrType(urType: string, span: Span): ParseError {\n return { type: \"UnknownUrType\", urType, span };\n },\n\n invalidUr(message: string, span: Span): ParseError {\n return { type: \"InvalidUr\", message, span };\n },\n\n invalidKnownValue(value: string, span: Span): ParseError {\n return { type: \"InvalidKnownValue\", value, span };\n },\n\n unknownKnownValueName(name: string, span: Span): ParseError {\n return { type: \"UnknownKnownValueName\", name, span };\n },\n\n invalidDateString(dateString: string, span: Span): ParseError {\n return { type: \"InvalidDateString\", dateString, span };\n },\n\n duplicateMapKey(span: Span): ParseError {\n return { type: \"DuplicateMapKey\", span };\n },\n};\n\n/**\n * Checks if an error is the default unrecognized token error.\n *\n * Corresponds to Rust `Error::is_default()`\n */\nexport function isDefaultError(error: ParseError): boolean {\n return error.type === \"UnrecognizedToken\";\n}\n\n/**\n * Gets the error message for a parse error.\n *\n * Corresponds to Rust's `Display` implementation for `Error`\n */\nexport function errorMessage(error: ParseError): string {\n switch (error.type) {\n case \"EmptyInput\":\n return \"Empty input\";\n case \"UnexpectedEndOfInput\":\n return \"Unexpected end of input\";\n case \"ExtraData\":\n return \"Extra data at end of input\";\n case \"UnexpectedToken\":\n return `Unexpected token ${tokenDebugString(error.token)}`;\n case \"UnrecognizedToken\":\n return \"Unrecognized token\";\n case \"ExpectedComma\":\n return \"Expected comma\";\n case \"ExpectedColon\":\n return \"Expected colon\";\n case \"UnmatchedParentheses\":\n return \"Unmatched parentheses\";\n case \"UnmatchedBraces\":\n return \"Unmatched braces\";\n case \"ExpectedMapKey\":\n return \"Expected map key\";\n case \"InvalidTagValue\":\n return `Invalid tag value '${error.value}'`;\n case \"UnknownTagName\":\n return `Unknown tag name '${error.name}'`;\n case \"InvalidHexString\":\n return \"Invalid hex string\";\n case \"InvalidBase64String\":\n return \"Invalid base64 string\";\n case \"UnknownUrType\":\n return `Unknown UR type '${error.urType}'`;\n case \"InvalidUr\":\n return `Invalid UR '${error.message}'`;\n case \"InvalidKnownValue\":\n return `Invalid known value '${error.value}'`;\n case \"UnknownKnownValueName\":\n return `Unknown known value name '${error.name}'`;\n case \"InvalidDateString\":\n return `Invalid date string '${error.dateString}'`;\n case \"DuplicateMapKey\":\n return \"Duplicate map key\";\n }\n}\n\n/**\n * Gets the span for a parse error, if applicable.\n */\nexport function errorSpan(error: ParseError): Span | undefined {\n switch (error.type) {\n case \"EmptyInput\":\n case \"UnexpectedEndOfInput\":\n return undefined;\n case \"ExtraData\":\n case \"UnexpectedToken\":\n case \"UnrecognizedToken\":\n case \"ExpectedComma\":\n case \"ExpectedColon\":\n case \"UnmatchedParentheses\":\n case \"UnmatchedBraces\":\n case \"ExpectedMapKey\":\n case \"InvalidTagValue\":\n case \"UnknownTagName\":\n case \"InvalidHexString\":\n case \"InvalidBase64String\":\n case \"UnknownUrType\":\n case \"InvalidUr\":\n case \"InvalidKnownValue\":\n case \"UnknownKnownValueName\":\n case \"InvalidDateString\":\n case \"DuplicateMapKey\":\n return error.span;\n }\n}\n\n/**\n * Formats an error message with source context, line number, and caret.\n *\n * Corresponds to Rust `Error::format_message()`\n */\nfunction formatMessage(message: string, source: string, range: Span): string {\n const start = range.start;\n const end = range.end;\n\n // Walk through the characters up to `start` to find line number and line start offset\n let lineNumber = 1;\n let lineStart = 0;\n\n for (let idx = 0; idx < source.length && idx < start; idx++) {\n if (source[idx] === \"\\n\") {\n lineNumber++;\n lineStart = idx + 1;\n }\n }\n\n // Grab the exact line text (or empty if out of bounds).\n //\n // Rust uses `source.lines()` here, which strips the trailing `\\r`\n // from `\\r\\n`-terminated lines (cf. `str::lines` docs). JS\n // `String#split(\"\\n\")` retains the `\\r`, so on Windows-style input we\n // would render an extra blank glyph at end-of-line and the caret\n // would shift. Strip a trailing `\\r` to match Rust's `lines()`.\n const lines = source.split(\"\\n\");\n let line = lines[lineNumber - 1] ?? \"\";\n if (line.endsWith(\"\\r\")) {\n line = line.slice(0, -1);\n }\n\n // Column is byte-offset into that line\n const column = Math.max(0, start - lineStart);\n\n // Underline at least one caret, even for zero-width spans\n const underlineLen = Math.max(1, end - start);\n const caret = \" \".repeat(column) + \"^\".repeat(underlineLen);\n\n return `line ${lineNumber}: ${message}\\n${line}\\n${caret}`;\n}\n\n/**\n * Gets the full error message with source context.\n *\n * Corresponds to Rust `Error::full_message()`\n */\nexport function fullErrorMessage(error: ParseError, source: string): string {\n const message = errorMessage(error);\n\n switch (error.type) {\n case \"EmptyInput\":\n return formatMessage(message, source, defaultSpan());\n case \"UnexpectedEndOfInput\":\n return formatMessage(message, source, span(source.length, source.length));\n case \"ExtraData\":\n case \"UnexpectedToken\":\n case \"UnrecognizedToken\":\n case \"ExpectedComma\":\n case \"ExpectedColon\":\n case \"UnmatchedParentheses\":\n case \"UnmatchedBraces\":\n case \"ExpectedMapKey\":\n case \"InvalidTagValue\":\n case \"UnknownTagName\":\n case \"InvalidHexString\":\n case \"InvalidBase64String\":\n case \"UnknownUrType\":\n case \"InvalidUr\":\n case \"InvalidKnownValue\":\n case \"UnknownKnownValueName\":\n case \"InvalidDateString\":\n case \"DuplicateMapKey\":\n return formatMessage(message, source, error.span);\n }\n}\n\n/**\n * Creates a default parse error (UnrecognizedToken with empty span).\n *\n * Corresponds to Rust `Error::default()`\n */\nexport function defaultParseError(): ParseError {\n return parseError.unrecognizedToken(defaultSpan());\n}\n\n/**\n * Result type for parse operations.\n *\n * Corresponds to Rust `Result<T, Error>`\n */\nexport type ParseResult<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: ParseError };\n\n/**\n * Creates a successful result.\n */\nexport function ok<T>(value: T): ParseResult<T> {\n return { ok: true, value };\n}\n\n/**\n * Creates an error result.\n */\nexport function err<T>(error: ParseError): ParseResult<T> {\n return { ok: false, error };\n}\n\n/**\n * Checks if a result is successful.\n */\nexport function isOk<T>(result: ParseResult<T>): result is { ok: true; value: T } {\n return result.ok;\n}\n\n/**\n * Checks if a result is an error.\n */\nexport function isErr<T>(result: ParseResult<T>): result is { ok: false; error: ParseError } {\n return !result.ok;\n}\n\n/**\n * Unwraps a result, throwing if it's an error.\n */\nexport function unwrap<T>(result: ParseResult<T>): T {\n if (result.ok) {\n return result.value;\n }\n throw new Error(errorMessage(result.error));\n}\n\n/**\n * Unwraps a result error, throwing if it's successful.\n */\nexport function unwrapErr<T>(result: ParseResult<T>): ParseError {\n if (!result.ok) {\n return result.error;\n }\n throw new Error(\"Called unwrapErr on an Ok result\");\n}\n\n/**\n * Renders a {@link Token} the way Rust's\n * `#[derive(Debug)]` on the corresponding enum variant would:\n *\n * - Variant-only tokens (`BraceOpen`, `Comma`, `Null`, `Unit`, `NaN`,\n * …) print as the bare variant name.\n * - Variant-with-value tokens print as `Variant(value)` where `value`\n * uses Rust's `Debug` form for the payload type:\n * `Bool(true)`, `Number(3.14)`, `String(\"foo\")` (with the inner\n * double quotes preserved — TS keeps them on the slice anyway),\n * `TagValue(1234)`, `KnownValueNumber(42)`, `TagName(\"date\")`,\n * `KnownValueName(\"isA\")`, `DateLiteral(2023-02-08T15:30:45.000Z)`,\n * etc.\n *\n * Mirrors Rust's `Error::UnexpectedToken(Box<Token>, Span)` formatter\n * `#[error(\"Unexpected token {0:?}\")]` so error messages stay\n * byte-identical to Rust.\n */\nfunction tokenDebugString(token: Token): string {\n switch (token.type) {\n case \"Bool\":\n return `Bool(${token.value ? \"true\" : \"false\"})`;\n case \"BraceOpen\":\n return \"BraceOpen\";\n case \"BraceClose\":\n return \"BraceClose\";\n case \"BracketOpen\":\n return \"BracketOpen\";\n case \"BracketClose\":\n return \"BracketClose\";\n case \"ParenthesisOpen\":\n return \"ParenthesisOpen\";\n case \"ParenthesisClose\":\n return \"ParenthesisClose\";\n case \"Colon\":\n return \"Colon\";\n case \"Comma\":\n return \"Comma\";\n case \"Null\":\n return \"Null\";\n case \"NaN\":\n return \"NaN\";\n case \"Infinity\":\n return \"Infinity\";\n case \"NegInfinity\":\n return \"NegInfinity\";\n case \"Unit\":\n return \"Unit\";\n case \"ByteStringHex\":\n // Rust `Token::ByteStringHex(Result<Vec<u8>>)` debug-formats the\n // `Ok(Vec<u8>)` payload as `Ok([0x68, 0x65, ...])`. We render the\n // bytes in the same `[0xNN, ...]` form so the text matches.\n return `ByteStringHex(Ok(${formatBytesDebug(token.value)}))`;\n case \"ByteStringBase64\":\n return `ByteStringBase64(Ok(${formatBytesDebug(token.value)}))`;\n case \"DateLiteral\":\n // The Rust `Date` `Debug` impl is opaque; we delegate to the\n // CborDate's own string rendering, which is the closest TS gets.\n return `DateLiteral(Ok(${String(token.value)}))`;\n case \"Number\":\n return `Number(${formatNumberDebug(token.value)})`;\n case \"String\":\n // The lexer stores the slice including the outer quotes\n // (matching Rust `Token::String(String)` which holds the raw\n // `lex.slice()`). Rust's `Debug` impl on `String` re-quotes the\n // contents — so a token whose value is `\"hello\"` prints as\n // `String(\"\\\"hello\\\"\")`. Since the inner already contains the\n // quotes, we can mirror Rust by `JSON.stringify`-ing.\n return `String(${JSON.stringify(token.value)})`;\n case \"TagValue\":\n return `TagValue(Ok(${tagOrKnownValueDebug(token.value)}))`;\n case \"TagName\":\n return `TagName(${JSON.stringify(token.value)})`;\n case \"KnownValueNumber\":\n return `KnownValueNumber(Ok(${tagOrKnownValueDebug(token.value)}))`;\n case \"KnownValueName\":\n return `KnownValueName(${JSON.stringify(token.value)})`;\n case \"UR\":\n // Rust `Token::UR(Result<UR>)` → `UR(Ok(<UR debug>))`. We don't\n // have access to the Rust `UR::Debug` shape, so we emit the UR\n // string form, which is stable and unambiguous.\n return `UR(Ok(${token.value.string()}))`;\n }\n}\n\n/**\n * Renders a `Vec<u8>` the way Rust's `Debug` does:\n * `[0x68, 0x65, 0x6c, 0x6c, 0x6f]`.\n */\nfunction formatBytesDebug(bytes: Uint8Array): string {\n const parts: string[] = [];\n for (const b of bytes) {\n parts.push(`0x${b.toString(16).padStart(2, \"0\")}`);\n }\n return `[${parts.join(\", \")}]`;\n}\n\n/**\n * Renders a JS `number` the way Rust's `f64::Debug` typically prints\n * it — using a decimal point even for integral values (e.g. `42.0`),\n * and `inf` / `-inf` / `NaN` for non-finite numbers. The dCBOR-parse\n * Rust source rarely produces a `Number` token in error messages\n * (numbers normally land in tagged-content contexts), but we still\n * mirror the convention so any error text is consistent with Rust.\n */\nfunction formatNumberDebug(n: number): string {\n if (Number.isNaN(n)) return \"NaN\";\n if (!Number.isFinite(n)) return n > 0 ? \"inf\" : \"-inf\";\n if (Number.isInteger(n)) return `${n}.0`;\n return String(n);\n}\n\n/**\n * Renders a `u64` payload the way Rust's `Debug` does — a bare digit\n * sequence without trailing `n` for `bigint` values. Mirrors\n * `<u64 as Debug>::fmt` and `<TagValue as Debug>::fmt` (TagValue is a\n * type alias for u64 in `bc-ur` / `dcbor`).\n */\nfunction tagOrKnownValueDebug(value: number | bigint): string {\n return typeof value === \"bigint\" ? value.toString() : String(value);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Token types and Lexer\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust token.rs\n *\n * @module dcbor-parse/token\n */\n\nimport { type CborDate, CborDate as DCborDate } from \"@bcts/dcbor\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { type Span, span, parseError as PE, type ParseResult, ok, err } from \"./error\";\n\n/**\n * Token types produced by the lexer.\n *\n * Corresponds to the Rust `Token` enum in token.rs.\n *\n * **u64 parity**: `TagValue` and `KnownValueNumber` are widened to\n * `number | bigint` because Rust accepts the full `u64` range\n * (`0..=2^64-1`). Values that fit in\n * {@link Number.MAX_SAFE_INTEGER} (`2^53-1`) come through as plain\n * `number`s; anything larger arrives as a `bigint` so callers don't\n * silently lose precision. This matches the way `@bcts/dcbor` already\n * stores large unsigned integers (`number | bigint`) and lets the\n * downstream `cbor({ tag, value })` builder serialize correctly.\n *\n * **String value field**: the lexer keeps the outer double quotes on\n * the slice (e.g. `\"\\\"hello\\\"\"`); the parser strips them in\n * `parseString`. Mirrors Rust `Token::String(String)` which holds the\n * raw `lex.slice()` including quotes (`token.rs:115-119`).\n */\nexport type Token =\n | { readonly type: \"Bool\"; readonly value: boolean }\n | { readonly type: \"BraceOpen\" }\n | { readonly type: \"BraceClose\" }\n | { readonly type: \"BracketOpen\" }\n | { readonly type: \"BracketClose\" }\n | { readonly type: \"ParenthesisOpen\" }\n | { readonly type: \"ParenthesisClose\" }\n | { readonly type: \"Colon\" }\n | { readonly type: \"Comma\" }\n | { readonly type: \"Null\" }\n | { readonly type: \"NaN\" }\n | { readonly type: \"Infinity\" }\n | { readonly type: \"NegInfinity\" }\n | { readonly type: \"ByteStringHex\"; readonly value: Uint8Array }\n | { readonly type: \"ByteStringBase64\"; readonly value: Uint8Array }\n | { readonly type: \"DateLiteral\"; readonly value: CborDate }\n | { readonly type: \"Number\"; readonly value: number }\n | { readonly type: \"String\"; readonly value: string }\n | { readonly type: \"TagValue\"; readonly value: number | bigint }\n | { readonly type: \"TagName\"; readonly value: string }\n | { readonly type: \"KnownValueNumber\"; readonly value: number | bigint }\n | { readonly type: \"KnownValueName\"; readonly value: string }\n | { readonly type: \"Unit\" }\n | { readonly type: \"UR\"; readonly value: UR };\n\n// Token constructors (lowercase to differentiate from the type)\nexport const token = {\n bool(value: boolean): Token {\n return { type: \"Bool\", value };\n },\n braceOpen(): Token {\n return { type: \"BraceOpen\" };\n },\n braceClose(): Token {\n return { type: \"BraceClose\" };\n },\n bracketOpen(): Token {\n return { type: \"BracketOpen\" };\n },\n bracketClose(): Token {\n return { type: \"BracketClose\" };\n },\n parenthesisOpen(): Token {\n return { type: \"ParenthesisOpen\" };\n },\n parenthesisClose(): Token {\n return { type: \"ParenthesisClose\" };\n },\n colon(): Token {\n return { type: \"Colon\" };\n },\n comma(): Token {\n return { type: \"Comma\" };\n },\n null(): Token {\n return { type: \"Null\" };\n },\n nan(): Token {\n return { type: \"NaN\" };\n },\n infinity(): Token {\n return { type: \"Infinity\" };\n },\n negInfinity(): Token {\n return { type: \"NegInfinity\" };\n },\n byteStringHex(value: Uint8Array): Token {\n return { type: \"ByteStringHex\", value };\n },\n byteStringBase64(value: Uint8Array): Token {\n return { type: \"ByteStringBase64\", value };\n },\n dateLiteral(value: CborDate): Token {\n return { type: \"DateLiteral\", value };\n },\n number(value: number): Token {\n return { type: \"Number\", value };\n },\n string(value: string): Token {\n return { type: \"String\", value };\n },\n tagValue(value: number | bigint): Token {\n return { type: \"TagValue\", value };\n },\n tagName(value: string): Token {\n return { type: \"TagName\", value };\n },\n knownValueNumber(value: number | bigint): Token {\n return { type: \"KnownValueNumber\", value };\n },\n knownValueName(value: string): Token {\n return { type: \"KnownValueName\", value };\n },\n unit(): Token {\n return { type: \"Unit\" };\n },\n ur(value: UR): Token {\n return { type: \"UR\", value };\n },\n};\n\n/**\n * Lexer for dCBOR diagnostic notation.\n *\n * Corresponds to the Rust `logos::Lexer` used in parse.rs\n */\nexport class Lexer {\n private readonly _source: string;\n private _position: number;\n private _tokenStart: number;\n private _tokenEnd: number;\n\n constructor(source: string) {\n this._source = source;\n this._position = 0;\n this._tokenStart = 0;\n this._tokenEnd = 0;\n }\n\n /**\n * Gets the current span (position range of the last token).\n */\n span(): Span {\n return span(this._tokenStart, this._tokenEnd);\n }\n\n /**\n * Gets the slice of source corresponding to the last token.\n */\n slice(): string {\n return this._source.slice(this._tokenStart, this._tokenEnd);\n }\n\n /**\n * Gets the next token, or undefined if at end of input.\n * Returns a Result to handle lexing errors.\n */\n next(): ParseResult<Token> | undefined {\n this._skipWhitespaceAndComments();\n\n if (this._position >= this._source.length) {\n return undefined;\n }\n\n this._tokenStart = this._position;\n\n // Try to match tokens in order of specificity\n const result =\n this._tryMatchKeyword() ??\n this._tryMatchDateLiteral() ??\n this._tryMatchTagValueOrNumber() ??\n this._tryMatchTagName() ??\n this._tryMatchString() ??\n this._tryMatchByteStringHex() ??\n this._tryMatchByteStringBase64() ??\n this._tryMatchKnownValue() ??\n this._tryMatchUR() ??\n this._tryMatchPunctuation();\n\n if (result === undefined) {\n // Unrecognized token - consume one character\n this._position++;\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n return result;\n }\n\n private _skipWhitespaceAndComments(): void {\n while (this._position < this._source.length) {\n const ch = this._source[this._position];\n\n // Skip whitespace\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\r\" || ch === \"\\n\" || ch === \"\\f\") {\n this._position++;\n continue;\n }\n\n // Skip inline comments: `/[^/]*/` (matches the Rust skip regex\n // `/[^/]*/`). Note that the Rust regex *does* match `//` (zero\n // non-slash characters between the two slashes), so an empty\n // comment is a valid no-op for the lexer. We accept that case too;\n // earlier revisions of this port required at least one non-slash\n // body character, which broke parity with Rust on inputs like\n // `// trailing thought`.\n if (ch === \"/\") {\n // Confirm there is a closing slash somewhere ahead. If not, fall\n // through and let the punctuation matcher report an\n // unrecognized token (Rust would equally fail to match the skip\n // regex and emit an `UnrecognizedToken`).\n let scan = this._position + 1;\n while (scan < this._source.length && this._source[scan] !== \"/\") {\n scan++;\n }\n if (scan < this._source.length) {\n this._position = scan + 1; // jump past the closing /\n continue;\n }\n // No closing /: not a comment — leave _position alone and break\n // out so the punctuation matcher can flag the unrecognized `/`.\n break;\n }\n\n // Skip end-of-line comments: #...\n if (ch === \"#\") {\n while (this._position < this._source.length && this._source[this._position] !== \"\\n\") {\n this._position++;\n }\n continue;\n }\n\n break;\n }\n }\n\n /**\n * Matches reserved keywords: `true`, `false`, `null`, `NaN`,\n * `Infinity`, `-Infinity`, `Unit`.\n *\n * Mirrors Rust's `Logos` `#[token(...)]` matcher\n * (`bc-dcbor-parse-rust/src/token.rs:12-50, 164`), which is greedy\n * and emits the keyword token *as soon as the literal matches* —\n * subsequent characters become a separate (likely unrecognized) token\n * stream. So input like `truex` lexes as `Bool(true)` followed by an\n * unrecognized run on `x`. Earlier revisions of this port enforced an\n * identifier boundary check (`!_isIdentifierChar(nextChar)`) and\n * rejected the whole prefix as a single `UnrecognizedToken`, which\n * broke span/variant parity with Rust.\n */\n private _tryMatchKeyword(): ParseResult<Token> | undefined {\n const keywords: [string, Token][] = [\n // Order matters: `-Infinity` must come before any other `-` based\n // matcher (we lex this before numbers, so the `-` doesn't get\n // siphoned off as a sign).\n [\"-Infinity\", token.negInfinity()],\n [\"true\", token.bool(true)],\n [\"false\", token.bool(false)],\n [\"null\", token.null()],\n [\"NaN\", token.nan()],\n [\"Infinity\", token.infinity()],\n [\"Unit\", token.unit()],\n ];\n\n for (const [keyword, tok] of keywords) {\n if (this._matchLiteral(keyword)) {\n this._tokenEnd = this._position;\n return ok(tok);\n }\n }\n\n return undefined;\n }\n\n private _tryMatchDateLiteral(): ParseResult<Token> | undefined {\n // ISO-8601 date: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS...\n const dateRegex = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})?)?/;\n const remaining = this._source.slice(this._position);\n const match = dateRegex.exec(remaining);\n\n if (match !== null) {\n const dateStr = match[0];\n this._position += dateStr.length;\n this._tokenEnd = this._position;\n\n // Validate date components before parsing to match Rust's strict behavior\n if (!isValidDateString(dateStr)) {\n return err(PE.invalidDateString(dateStr, this.span()));\n }\n\n try {\n const date = DCborDate.fromString(dateStr);\n return ok(token.dateLiteral(date));\n } catch {\n return err(PE.invalidDateString(dateStr, this.span()));\n }\n }\n\n return undefined;\n }\n\n private _tryMatchTagValueOrNumber(): ParseResult<Token> | undefined {\n // Check for tag value: integer followed by (\n // Or just a number\n const numberRegex = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/;\n const remaining = this._source.slice(this._position);\n const match = numberRegex.exec(remaining);\n\n if (match !== null) {\n const numStr = match[0];\n const nextChar = this._source[this._position + numStr.length];\n\n // Check if this is a tag value (integer followed by parenthesis)\n if (\n nextChar === \"(\" &&\n !numStr.includes(\".\") &&\n !numStr.includes(\"e\") &&\n !numStr.includes(\"E\") &&\n !numStr.startsWith(\"-\")\n ) {\n // It's a tag value. Mirrors Rust `token.rs:128-136`:\n // `stripped.parse::<TagValue>()` accepts the full `u64` range\n // (`0..=2^64-1`). We use `BigInt` to get exact-integer parsing,\n // then narrow to `number` when the value fits in\n // `Number.MAX_SAFE_INTEGER` so callers don't pay the bigint\n // tax for tag numbers in the common range. Anything outside\n // `[0, 2^64-1]` is reported as `InvalidTagValue` matching Rust.\n this._position += numStr.length + 1; // Include the (\n this._tokenEnd = this._position;\n\n const parsed = parseUsize64(numStr);\n if (parsed === undefined) {\n return err(\n PE.invalidTagValue(numStr, span(this._tokenStart, this._tokenStart + numStr.length)),\n );\n }\n\n return ok(token.tagValue(parsed));\n }\n\n // It's a regular number\n this._position += numStr.length;\n this._tokenEnd = this._position;\n\n const num = parseFloat(numStr);\n return ok(token.number(num));\n }\n\n return undefined;\n }\n\n private _tryMatchTagName(): ParseResult<Token> | undefined {\n // Tag name: identifier followed by (\n const tagNameRegex = /^[a-zA-Z_][a-zA-Z0-9_-]*\\(/;\n const remaining = this._source.slice(this._position);\n const match = tagNameRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const name = fullMatch.slice(0, -1); // Remove trailing (\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n return ok(token.tagName(name));\n }\n\n return undefined;\n }\n\n private _tryMatchString(): ParseResult<Token> | undefined {\n if (this._source[this._position] !== '\"') {\n return undefined;\n }\n\n // JavaScript-style string with escape sequences\n // eslint-disable-next-line no-control-regex\n const stringRegex = /^\"([^\"\\\\\\x00-\\x1F]|\\\\([\"\\\\bnfrt/]|u[a-fA-F0-9]{4}))*\"/;\n const remaining = this._source.slice(this._position);\n const match = stringRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n // Return the full string including quotes\n return ok(token.string(fullMatch));\n }\n\n // Invalid string: emit an unrecognized token covering just the\n // opening `\"` and let the next call to `next()` re-lex. Mirrors\n // Rust's Logos behaviour when the `String` regex fails to match —\n // the lexer emits `Error::default()` (which `expect_token` upgrades\n // to `UnrecognizedToken(span)` for the single character) and\n // recovers at the very next byte. Earlier revisions of this port\n // consumed through the next `\"` or `\\n`, which inflated the error\n // span beyond what Rust reports.\n this._position++;\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n private _tryMatchByteStringHex(): ParseResult<Token> | undefined {\n // h'...'\n if (!this._matchLiteral(\"h'\")) {\n return undefined;\n }\n\n const hexRegex = /^[0-9a-fA-F]*/;\n const remaining = this._source.slice(this._position);\n const match = hexRegex.exec(remaining);\n const hexPart = match !== null ? match[0] : \"\";\n\n this._position += hexPart.length;\n\n if (this._source[this._position] !== \"'\") {\n this._tokenEnd = this._position;\n return err(PE.invalidHexString(this.span()));\n }\n\n this._position++; // Skip closing '\n this._tokenEnd = this._position;\n\n // Check that hex string has even length\n if (hexPart.length % 2 !== 0) {\n return err(PE.invalidHexString(this.span()));\n }\n\n // Decode hex\n const bytes = hexToBytes(hexPart);\n return ok(token.byteStringHex(bytes));\n }\n\n private _tryMatchByteStringBase64(): ParseResult<Token> | undefined {\n // b64'...'\n if (!this._matchLiteral(\"b64'\")) {\n return undefined;\n }\n\n const base64Regex = /^[A-Za-z0-9+/=]*/;\n const remaining = this._source.slice(this._position);\n const match = base64Regex.exec(remaining);\n const base64Part = match !== null ? match[0] : \"\";\n\n this._position += base64Part.length;\n\n if (this._source[this._position] !== \"'\") {\n this._tokenEnd = this._position;\n return err(PE.invalidBase64String(this.span()));\n }\n\n this._position++; // Skip closing '\n this._tokenEnd = this._position;\n\n // Check minimum length requirement (2 characters)\n if (base64Part.length < 2) {\n return err(PE.invalidBase64String(this.span()));\n }\n\n // Decode base64\n try {\n const bytes = base64ToBytes(base64Part);\n return ok(token.byteStringBase64(bytes));\n } catch {\n return err(PE.invalidBase64String(this.span()));\n }\n }\n\n private _tryMatchKnownValue(): ParseResult<Token> | undefined {\n if (this._source[this._position] !== \"'\") {\n return undefined;\n }\n\n // Check for empty string '' (Unit)\n if (this._source[this._position + 1] === \"'\") {\n this._position += 2;\n this._tokenEnd = this._position;\n return ok(token.knownValueName(\"\"));\n }\n\n // Check for numeric known value: '0' or '[1-9][0-9]*'\n const numericRegex = /^'(0|[1-9][0-9]*)'/;\n const remaining = this._source.slice(this._position);\n let match = numericRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const numStr = match[1];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n // Mirrors Rust `token.rs:146-153`: `stripped.parse::<u64>()`\n // accepts the full `u64` range. We share the helper used for\n // `TagValue` to get the same narrow-when-safe-else-bigint path.\n const value = parseUsize64(numStr);\n if (value === undefined) {\n return err(PE.invalidKnownValue(numStr, span(this._tokenStart + 1, this._tokenEnd - 1)));\n }\n\n return ok(token.knownValueNumber(value));\n }\n\n // Check for named known value: '[a-zA-Z_][a-zA-Z0-9_-]*'\n const nameRegex = /^'([a-zA-Z_][a-zA-Z0-9_-]*)'/;\n match = nameRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n const name = match[1];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n return ok(token.knownValueName(name));\n }\n\n // Invalid known value: emit an unrecognized token covering just the\n // opening `'` and let the next call to `next()` re-lex. Mirrors\n // Rust's Logos behaviour when neither `KnownValueNumber` nor\n // `KnownValueName` regex matches — the lexer emits `Error::default()`\n // (single character span) and recovers at the next byte. Earlier\n // revisions of this port consumed through the closing `'`, which\n // inflated the error span beyond what Rust reports.\n this._position++;\n this._tokenEnd = this._position;\n return err(PE.unrecognizedToken(this.span()));\n }\n\n private _tryMatchUR(): ParseResult<Token> | undefined {\n // ur:type/data\n const urRegex = /^ur:([a-zA-Z0-9][a-zA-Z0-9-]*)\\/([a-zA-Z]{8,})/;\n const remaining = this._source.slice(this._position);\n const match = urRegex.exec(remaining);\n\n if (match !== null) {\n const fullMatch = match[0];\n this._position += fullMatch.length;\n this._tokenEnd = this._position;\n\n try {\n const ur = UR.fromURString(fullMatch);\n return ok(token.ur(ur));\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return err(PE.invalidUr(errorMsg, this.span()));\n }\n }\n\n return undefined;\n }\n\n private _tryMatchPunctuation(): ParseResult<Token> | undefined {\n const ch = this._source[this._position];\n\n const punctuation: Record<string, Token> = {\n \"{\": token.braceOpen(),\n \"}\": token.braceClose(),\n \"[\": token.bracketOpen(),\n \"]\": token.bracketClose(),\n \"(\": token.parenthesisOpen(),\n \")\": token.parenthesisClose(),\n \":\": token.colon(),\n \",\": token.comma(),\n };\n\n const matched = punctuation[ch];\n if (matched !== undefined) {\n this._position++;\n this._tokenEnd = this._position;\n return ok(matched);\n }\n\n return undefined;\n }\n\n private _matchLiteral(literal: string): boolean {\n if (this._source.slice(this._position, this._position + literal.length) === literal) {\n this._position += literal.length;\n return true;\n }\n return false;\n }\n}\n\n/**\n * Strictly parses a non-negative integer string in the range\n * `[0, 2^64 - 1]`, mirroring Rust `<u64 as FromStr>::from_str`.\n *\n * - Empty input or non-digit characters → `undefined`.\n * - Values that fit in `Number.MAX_SAFE_INTEGER` are returned as plain\n * `number`s, so callers in the common case (tag values like `40000`,\n * known values like `1`) never see a `bigint`.\n * - Values in `(2^53-1, 2^64-1]` are returned as `bigint`. dCBOR's\n * `cbor({ tag, value })` and `KnownValue` constructors both accept\n * `bigint` natively, so the bigint flows through to wire encoding\n * without precision loss.\n * - Values strictly greater than `2^64 - 1` (or negative) are rejected\n * so this parser never produces a tag/known-value outside the\n * `u64` domain — matches Rust which fails `parse::<u64>()` in that\n * case.\n */\nconst MAX_U64: bigint = (1n << 64n) - 1n;\nfunction parseUsize64(s: string): number | bigint | undefined {\n if (s.length === 0) return undefined;\n // The regex feeding this helper already rejects sign / leading\n // zeros / non-digits; this guard is defensive in case the helper is\n // reused elsewhere.\n if (!/^\\d+$/.test(s)) return undefined;\n let value: bigint;\n try {\n value = BigInt(s);\n } catch {\n return undefined;\n }\n if (value < 0n || value > MAX_U64) return undefined;\n // Narrow to plain `number` when safe so common-case callers never\n // see a `bigint`.\n if (value <= BigInt(Number.MAX_SAFE_INTEGER)) {\n return Number(value);\n }\n return value;\n}\n\n/**\n * Converts a hex string to bytes.\n */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Converts a base64 string to bytes with strict validation.\n * Rejects base64 strings with invalid padding (matches Rust's base64 crate behavior).\n */\nfunction base64ToBytes(base64: string): Uint8Array {\n // Validate base64 padding strictly (Rust's base64 crate requires proper padding)\n const expectedPadding = (4 - (base64.replace(/=/g, \"\").length % 4)) % 4;\n const paddingMatch = /=+$/.exec(base64);\n const actualPadding = paddingMatch !== null ? paddingMatch[0].length : 0;\n\n // If there should be padding but there isn't, or padding is wrong length\n if (expectedPadding !== actualPadding) {\n throw new Error(\"Invalid base64 padding\");\n }\n\n // Use built-in atob for base64 decoding\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Validates a date string has valid month/day values.\n * JavaScript Date is lenient and accepts invalid dates like 2023-02-30,\n * but Rust's Date::from_string rejects them.\n */\nfunction isValidDateString(dateStr: string): boolean {\n // Extract date components\n const dateMatch = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(dateStr);\n if (dateMatch === null) return false;\n\n const year = parseInt(dateMatch[1], 10);\n const month = parseInt(dateMatch[2], 10);\n const day = parseInt(dateMatch[3], 10);\n\n // Validate month (1-12)\n if (month < 1 || month > 12) return false;\n\n // Validate day (1-N where N depends on month)\n if (day < 1) return false;\n\n // Days in each month (non-leap year)\n const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n // Adjust for leap year\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n if (isLeapYear && month === 2) {\n if (day > 29) return false;\n } else {\n if (day > daysInMonth[month - 1]) return false;\n }\n\n // If there's a time component, validate it\n const timeMatch = /T(\\d{2}):(\\d{2}):(\\d{2})/.exec(dateStr);\n if (timeMatch !== null) {\n const hour = parseInt(timeMatch[1], 10);\n const minute = parseInt(timeMatch[2], 10);\n const second = parseInt(timeMatch[3], 10);\n\n if (hour < 0 || hour > 23) return false;\n if (minute < 0 || minute > 59) return false;\n if (second < 0 || second > 59) return false;\n }\n\n return true;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Parse module\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust parse.rs\n *\n * @module dcbor-parse/parse\n */\n\nimport { type Cbor, cbor, CborMap, getGlobalTagsStore } from \"@bcts/dcbor\";\nimport { KnownValue, KNOWN_VALUES } from \"@bcts/known-values\";\nimport type { UR } from \"@bcts/uniform-resources\";\nimport {\n type Span,\n span,\n parseError as PE,\n type ParseResult,\n ok,\n err,\n isDefaultError,\n} from \"./error\";\nimport { type Token, Lexer } from \"./token\";\n\n/**\n * Parses a dCBOR item from a string input.\n *\n * This function takes a string slice containing a dCBOR diagnostic notation\n * encoded value and attempts to parse it into a `Cbor` object. If the input\n * contains extra tokens after a valid item, an error is returned.\n *\n * @param src - A string containing the dCBOR-encoded data.\n * @returns `Ok(Cbor)` if parsing is successful and the input contains exactly one\n * valid dCBOR item, which itself might be an atomic value like a number or\n * string, or a complex value like an array or map.\n * `Err(ParseError)` if parsing fails or if extra tokens are found after the item.\n *\n * @example\n * ```typescript\n * const result = parseDcborItem(\"[1, 2, 3]\");\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"[1, 2, 3]\"\n * }\n * ```\n */\nexport function parseDcborItem(src: string): ParseResult<Cbor> {\n const lexer = new Lexer(src);\n const firstTokenResult = expectToken(lexer);\n\n if (!firstTokenResult.ok) {\n if (firstTokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.emptyInput());\n }\n return firstTokenResult;\n }\n\n const parseResult = parseItemToken(firstTokenResult.value, lexer);\n if (!parseResult.ok) {\n return parseResult;\n }\n\n // Check for extra data\n const nextToken = lexer.next();\n if (nextToken !== undefined) {\n return err(PE.extraData(lexer.span()));\n }\n\n return parseResult;\n}\n\n/**\n * Parses a dCBOR item from the beginning of a string and returns the parsed\n * `Cbor` along with the number of bytes consumed.\n *\n * Unlike `parseDcborItem`, this function succeeds even if additional\n * characters follow the first item. The returned index points to the first\n * unparsed character after skipping any trailing whitespace or comments.\n *\n * @param src - A string containing the dCBOR-encoded data.\n * @returns `Ok([Cbor, number])` with the parsed item and bytes consumed.\n *\n * @example\n * ```typescript\n * const result = parseDcborItemPartial(\"true )\");\n * if (result.ok) {\n * const [cbor, used] = result.value;\n * console.log(cbor.toDiagnostic()); // \"true\"\n * console.log(used); // 5\n * }\n * ```\n */\nexport function parseDcborItemPartial(src: string): ParseResult<[Cbor, number]> {\n const lexer = new Lexer(src);\n const firstTokenResult = expectToken(lexer);\n\n if (!firstTokenResult.ok) {\n if (firstTokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.emptyInput());\n }\n return firstTokenResult;\n }\n\n const parseResult = parseItemToken(firstTokenResult.value, lexer);\n if (!parseResult.ok) {\n return parseResult;\n }\n\n // Determine consumed bytes\n const nextToken = lexer.next();\n const consumed = nextToken !== undefined ? lexer.span().start : src.length;\n\n return ok([parseResult.value, consumed]);\n}\n\n// === Private Functions ===\n\nfunction parseItem(lexer: Lexer): ParseResult<Cbor> {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n return parseItemToken(tokenResult.value, lexer);\n}\n\nfunction expectToken(lexer: Lexer): ParseResult<Token> {\n const spanBefore = lexer.span();\n const result = lexer.next();\n\n if (result === undefined) {\n return err(PE.unexpectedEndOfInput());\n }\n\n if (!result.ok) {\n if (isDefaultError(result.error)) {\n return err(PE.unrecognizedToken(spanBefore));\n }\n return result;\n }\n\n return result;\n}\n\nfunction parseItemToken(token: Token, lexer: Lexer): ParseResult<Cbor> {\n switch (token.type) {\n case \"Bool\":\n return ok(cbor(token.value));\n\n case \"Null\":\n return ok(cbor(null));\n\n case \"ByteStringHex\":\n return ok(cbor(token.value));\n\n case \"ByteStringBase64\":\n return ok(cbor(token.value));\n\n case \"DateLiteral\":\n return ok(cbor(token.value));\n\n case \"Number\":\n return ok(cbor(token.value));\n\n case \"NaN\":\n return ok(cbor(Number.NaN));\n\n case \"Infinity\":\n return ok(cbor(Number.POSITIVE_INFINITY));\n\n case \"NegInfinity\":\n return ok(cbor(Number.NEGATIVE_INFINITY));\n\n case \"String\":\n return parseString(token.value, lexer.span());\n\n case \"UR\":\n return parseUr(token.value, lexer.span());\n\n case \"TagValue\":\n return parseNumberTag(token.value, lexer);\n\n case \"TagName\":\n return parseNameTag(token.value, lexer);\n\n case \"KnownValueNumber\":\n return ok(new KnownValue(token.value).taggedCbor());\n\n case \"KnownValueName\": {\n // Empty string means Unit (value 0)\n if (token.value === \"\") {\n return ok(new KnownValue(0).taggedCbor());\n }\n\n const knownValue = knownValueForName(token.value);\n if (knownValue !== undefined) {\n return ok(knownValue.taggedCbor());\n }\n const tokenSpan = lexer.span();\n return err(\n PE.unknownKnownValueName(token.value, span(tokenSpan.start + 1, tokenSpan.end - 1)),\n );\n }\n\n case \"Unit\":\n return ok(new KnownValue(0).taggedCbor());\n\n case \"BracketOpen\":\n return parseArray(lexer);\n\n case \"BraceOpen\":\n return parseMap(lexer);\n\n // Syntactic tokens that cannot start an item\n case \"BraceClose\":\n case \"BracketClose\":\n case \"ParenthesisOpen\":\n case \"ParenthesisClose\":\n case \"Colon\":\n case \"Comma\":\n return err(PE.unexpectedToken(token, lexer.span()));\n }\n}\n\nfunction parseString(s: string, tokenSpan: Span): ParseResult<Cbor> {\n if (s.startsWith('\"') && s.endsWith('\"')) {\n // Remove quotes and return the inner string\n const inner = s.slice(1, -1);\n return ok(cbor(inner));\n }\n return err(PE.unrecognizedToken(tokenSpan));\n}\n\nfunction tagForName(name: string): number | bigint | undefined {\n return getGlobalTagsStore().tagForName(name)?.value;\n}\n\nfunction knownValueForName(name: string): KnownValue | undefined {\n return KNOWN_VALUES.get().knownValueNamed(name);\n}\n\nfunction parseUr(ur: UR, tokenSpan: Span): ParseResult<Cbor> {\n const urType = ur.urTypeStr();\n const tag = tagForName(urType);\n\n if (tag !== undefined) {\n return ok(cbor({ tag, value: ur.cbor() }));\n }\n\n return err(\n PE.unknownUrType(urType, span(tokenSpan.start + 3, tokenSpan.start + 3 + urType.length)),\n );\n}\n\nfunction parseNumberTag(tagValue: number | bigint, lexer: Lexer): ParseResult<Cbor> {\n const itemResult = parseItem(lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n const closeResult = expectToken(lexer);\n if (!closeResult.ok) {\n if (closeResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.unmatchedParentheses(lexer.span()));\n }\n return closeResult;\n }\n\n if (closeResult.value.type === \"ParenthesisClose\") {\n // Pass the tag value through as-is: when it's a `bigint` (i.e. a\n // u64 outside the safe-integer range), dCBOR's `cbor({ tag, value })`\n // builder serialises it as a `bigint` tag — matching Rust which\n // accepts the full `0..=2^64-1` range natively.\n return ok(cbor({ tag: tagValue, value: itemResult.value }));\n }\n\n return err(PE.unmatchedParentheses(lexer.span()));\n}\n\nfunction parseNameTag(name: string, lexer: Lexer): ParseResult<Cbor> {\n const tagSpan = span(lexer.span().start, lexer.span().end - 1);\n\n const itemResult = parseItem(lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n const closeResult = expectToken(lexer);\n if (!closeResult.ok) {\n return closeResult;\n }\n\n if (closeResult.value.type === \"ParenthesisClose\") {\n const tag = tagForName(name);\n if (tag !== undefined) {\n return ok(cbor({ tag, value: itemResult.value }));\n }\n return err(PE.unknownTagName(name, tagSpan));\n }\n\n return err(PE.unmatchedParentheses(lexer.span()));\n}\n\nfunction parseArray(lexer: Lexer): ParseResult<Cbor> {\n const items: Cbor[] = [];\n let awaitsComma = false;\n let awaitsItem = false;\n\n while (true) {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value;\n\n // Handle closing bracket\n if (token.type === \"BracketClose\" && !awaitsItem) {\n return ok(cbor(items));\n }\n\n // Handle comma\n if (token.type === \"Comma\" && awaitsComma) {\n awaitsItem = true;\n awaitsComma = false;\n continue;\n }\n\n // Expect an item when not awaiting comma\n if (awaitsComma) {\n return err(PE.expectedComma(lexer.span()));\n }\n\n // Parse the item\n const itemResult = parseItemToken(token, lexer);\n if (!itemResult.ok) {\n return itemResult;\n }\n\n items.push(itemResult.value);\n awaitsItem = false;\n awaitsComma = true;\n }\n}\n\nfunction parseMap(lexer: Lexer): ParseResult<Cbor> {\n const map = new CborMap();\n let awaitsComma = false;\n let awaitsKey = false;\n\n while (true) {\n const tokenResult = expectToken(lexer);\n if (!tokenResult.ok) {\n if (tokenResult.error.type === \"UnexpectedEndOfInput\") {\n return err(PE.unmatchedBraces(lexer.span()));\n }\n return tokenResult;\n }\n\n const token = tokenResult.value;\n\n // Handle closing brace\n if (token.type === \"BraceClose\" && !awaitsKey) {\n return ok(cbor(map));\n }\n\n // Handle comma\n if (token.type === \"Comma\" && awaitsComma) {\n awaitsKey = true;\n awaitsComma = false;\n continue;\n }\n\n // Expect a key when not awaiting comma\n if (awaitsComma) {\n return err(PE.expectedComma(lexer.span()));\n }\n\n // Parse the key\n const keyResult = parseItemToken(token, lexer);\n if (!keyResult.ok) {\n return keyResult;\n }\n\n const key = keyResult.value;\n const keySpan = lexer.span();\n\n // Check for duplicate key\n if (map.has(key)) {\n return err(PE.duplicateMapKey(keySpan));\n }\n\n // Expect colon.\n //\n // Mirrors Rust `parse.rs:382-395`:\n // ```\n // if let Ok(Token::Colon) = expect_token(lexer) { … }\n // else { return Err(Error::ExpectedColon(lexer.span())); }\n // ```\n // Rust's pattern collapses *every* non-Colon outcome — including\n // `UnexpectedEndOfInput`, `UnrecognizedToken`, and any other error\n // — into `ExpectedColon`. Earlier revisions of this port forwarded\n // the inner error verbatim, so `{1` reported `UnexpectedEndOfInput`\n // instead of `ExpectedColon`.\n const colonResult = expectToken(lexer);\n if (!colonResult.ok || colonResult.value.type !== \"Colon\") {\n return err(PE.expectedColon(lexer.span()));\n }\n\n // Parse the value.\n //\n // Rust `parse.rs:383-389` uses the inner `UnexpectedToken`'s **own**\n // span when it converts to `ExpectedMapKey`. Earlier revisions of\n // this port called `lexer.span()` here, which can drift if the\n // lexer has stepped past the offending `}`. We now use the\n // captured span from `valueResult.error` to preserve Rust's exact\n // span semantics.\n const valueResult = parseItem(lexer);\n if (!valueResult.ok) {\n if (valueResult.error.type === \"UnexpectedToken\") {\n const unexpected = valueResult.error;\n if (unexpected.token.type === \"BraceClose\") {\n return err(PE.expectedMapKey(unexpected.span));\n }\n }\n return valueResult;\n }\n\n map.set(key, valueResult.value);\n awaitsKey = false;\n awaitsComma = true;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * @bcts/dcbor-parse - Compose module\n *\n * This is a 1:1 TypeScript port of bc-dcbor-parse-rust compose.rs\n *\n * @module dcbor-parse/compose\n */\n\nimport { type Cbor, cbor, CborMap } from \"@bcts/dcbor\";\nimport { type ParseError, errorMessage } from \"./error\";\nimport { parseDcborItem } from \"./parse\";\n\n/**\n * Compose error types.\n *\n * Corresponds to the Rust `Error` enum in compose.rs\n */\nexport type ComposeError =\n | { readonly type: \"OddMapLength\" }\n | { readonly type: \"DuplicateMapKey\" }\n | { readonly type: \"ParseError\"; readonly error: ParseError };\n\n// ComposeError constructors (lowercase to differentiate from the type)\nexport const composeError = {\n oddMapLength(): ComposeError {\n return { type: \"OddMapLength\" };\n },\n\n duplicateMapKey(): ComposeError {\n return { type: \"DuplicateMapKey\" };\n },\n\n parseError(error: ParseError): ComposeError {\n return { type: \"ParseError\", error };\n },\n};\n\n/**\n * Gets the error message for a compose error.\n *\n * Mirrors Rust `Error::Display` (`bc-dcbor-parse-rust/src/compose.rs`):\n * the `ParseError` arm uses `#[error(\"Invalid CBOR item: {0}\")]`, which\n * formats the inner error via its `Display` impl — *not* the variant\n * name. So `Error::ParseError(Error::EmptyInput)` formats as\n * `\"Invalid CBOR item: Empty input\"`, not\n * `\"Invalid CBOR item: EmptyInput\"`. We delegate to {@link errorMessage}\n * to get the same `Display`-style text.\n */\nexport function composeErrorMessage(error: ComposeError): string {\n switch (error.type) {\n case \"OddMapLength\":\n return \"Invalid odd map length\";\n case \"DuplicateMapKey\":\n return \"Duplicate map key\";\n case \"ParseError\":\n return `Invalid CBOR item: ${errorMessage(error.error)}`;\n }\n}\n\n/**\n * Result type for compose operations.\n *\n * Corresponds to Rust `Result<T, Error>`\n */\nexport type ComposeResult<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: ComposeError };\n\n/**\n * Creates a successful compose result.\n */\nexport function composeOk<T>(value: T): ComposeResult<T> {\n return { ok: true, value };\n}\n\n/**\n * Creates an error compose result.\n */\nexport function composeErr<T>(error: ComposeError): ComposeResult<T> {\n return { ok: false, error };\n}\n\n/**\n * Composes a dCBOR array from a slice of string slices, and returns a CBOR\n * object representing the array.\n *\n * Each string slice is parsed as a dCBOR item.\n *\n * @param array - Array of strings, each representing a dCBOR item\n * @returns A CBOR array containing all parsed items\n *\n * @example\n * ```typescript\n * const result = composeDcborArray([\"1\", \"2\", \"3\"]);\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"[1, 2, 3]\"\n * }\n * ```\n */\nexport function composeDcborArray(array: readonly string[]): ComposeResult<Cbor> {\n const result: Cbor[] = [];\n\n for (const item of array) {\n const parseResult = parseDcborItem(item);\n if (!parseResult.ok) {\n return composeErr(composeError.parseError(parseResult.error));\n }\n result.push(parseResult.value);\n }\n\n return composeOk(cbor(result));\n}\n\n/**\n * Composes a dCBOR map from a slice of string slices, and returns a CBOR\n * object representing the map.\n *\n * The length of the slice must be even, as each key must have a corresponding\n * value.\n *\n * Each string slice is parsed as a dCBOR item.\n *\n * @param array - Array of strings representing key-value pairs in alternating order\n * @returns A CBOR map containing all parsed key-value pairs\n *\n * @example\n * ```typescript\n * const result = composeDcborMap([\"1\", \"2\", \"3\", \"4\"]);\n * if (result.ok) {\n * console.log(result.value.toDiagnostic()); // \"{1: 2, 3: 4}\"\n * }\n * ```\n */\nexport function composeDcborMap(array: readonly string[]): ComposeResult<Cbor> {\n if (array.length % 2 !== 0) {\n return composeErr(composeError.oddMapLength());\n }\n\n const map = new CborMap();\n\n for (let i = 0; i < array.length; i += 2) {\n const keyStr = array[i];\n const valueStr = array[i + 1];\n\n const keyResult = parseDcborItem(keyStr);\n if (!keyResult.ok) {\n return composeErr(composeError.parseError(keyResult.error));\n }\n\n const valueResult = parseDcborItem(valueStr);\n if (!valueResult.ok) {\n return composeErr(composeError.parseError(valueResult.error));\n }\n\n // Check for duplicate key\n if (map.has(keyResult.value)) {\n return composeErr(composeError.duplicateMapKey());\n }\n\n map.set(keyResult.value, valueResult.value);\n }\n\n return composeOk(cbor(map));\n}\n"],"mappings":"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"}
|