@willbooster/shared-lib 10.19.0 → 10.19.2
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/appEnv.cjs.map +1 -1
- package/dist/appEnv.js.map +1 -1
- package/dist/array.cjs.map +1 -1
- package/dist/array.js.map +1 -1
- package/dist/assert.cjs.map +1 -1
- package/dist/assert.js.map +1 -1
- package/dist/concurrency.cjs.map +1 -1
- package/dist/concurrency.js.map +1 -1
- package/dist/crypto.cjs.map +1 -1
- package/dist/crypto.js.map +1 -1
- package/dist/error.cjs.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/filePath.cjs.map +1 -1
- package/dist/filePath.js.map +1 -1
- package/dist/foreignCjk.cjs.map +1 -1
- package/dist/foreignCjk.js.map +1 -1
- package/dist/formatIsoDate.cjs.map +1 -1
- package/dist/formatIsoDate.js.map +1 -1
- package/dist/github.cjs.map +1 -1
- package/dist/github.js.map +1 -1
- package/dist/githubTemplates.cjs.map +1 -1
- package/dist/githubTemplates.js.map +1 -1
- package/dist/http.cjs.map +1 -1
- package/dist/http.js.map +1 -1
- package/dist/humanize.cjs.map +1 -1
- package/dist/humanize.js.map +1 -1
- package/dist/mail.cjs.map +1 -1
- package/dist/mail.js.map +1 -1
- package/dist/markdown.cjs.map +1 -1
- package/dist/markdown.js.map +1 -1
- package/dist/number.cjs.map +1 -1
- package/dist/number.js.map +1 -1
- package/dist/object.cjs.map +1 -1
- package/dist/object.js.map +1 -1
- package/dist/parseCommandLineArgs.cjs.map +1 -1
- package/dist/parseCommandLineArgs.js.map +1 -1
- package/dist/parseIsoDate.cjs.map +1 -1
- package/dist/parseIsoDate.js.map +1 -1
- package/dist/prompt.cjs +8 -8
- package/dist/prompt.cjs.map +1 -1
- package/dist/prompt.js +8 -8
- package/dist/prompt.js.map +1 -1
- package/dist/promptFormatters.cjs.map +1 -1
- package/dist/promptFormatters.js.map +1 -1
- package/dist/recoverJson.cjs +2 -2
- package/dist/recoverJson.cjs.map +1 -1
- package/dist/recoverJson.js +1 -1
- package/dist/recoverJson.js.map +1 -1
- package/dist/shuffle.cjs.map +1 -1
- package/dist/shuffle.js.map +1 -1
- package/dist/sleep.cjs.map +1 -1
- package/dist/sleep.js.map +1 -1
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.js.map +1 -1
- package/dist/testingRules.js.map +1 -1
- package/dist/text.cjs.map +1 -1
- package/dist/text.js.map +1 -1
- package/dist/throttledFetch.cjs.map +1 -1
- package/dist/throttledFetch.js.map +1 -1
- package/dist/timeout.cjs.map +1 -1
- package/dist/timeout.js.map +1 -1
- package/dist/url.cjs.map +1 -1
- package/dist/url.js.map +1 -1
- package/dist/yaml.cjs.map +1 -1
- package/dist/yaml.js.map +1 -1
- package/dist/zenkaku.cjs.map +1 -1
- package/dist/zenkaku.js.map +1 -1
- package/package.json +7 -7
package/dist/recoverJson.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recoverJson.js","names":[],"sources":["../src/recoverJson.ts"],"sourcesContent":["/*! JSON recovery informed by jsonrepair, Copyright (c) 2020-2026 Jos de Jong (ISC). See NOTICE. */\n\nimport { getErrorMessage } from './error.js';\n\nexport interface JsonRepair {\n /** UTF-16 offset in the original response. */\n offset: number;\n kind: 'syntax' | 'incomplete' | 'ambiguous';\n reason: string;\n}\n\nexport interface RecoveredJson {\n value: unknown;\n json: string;\n start: number;\n end: number;\n repairs: JsonRepair[];\n /** Missing content or an ambiguous interpretation requires confirmation before acting on this value. */\n requiresConfirmation: boolean;\n}\n\nexport interface JsonRecovery {\n candidates: RecoveredJson[];\n errors: { offset: number; message: string }[];\n}\n\nconst MAX_INPUT_LENGTH = 1_000_000;\nconst MAX_DEPTH = 128;\nconst MAX_CANDIDATES = 32;\nconst MAX_ERRORS = 32;\nconst MAX_DIAGNOSTIC_EXCERPT = 256;\nconst QUOTES: Record<string, string> = { '\"': '\"', \"'\": \"'\", '“': '”', '”': '”', '‘': '’', '’': '’' };\nconst KEYWORDS: Record<string, string> = {\n true: 'true',\n false: 'false',\n null: 'null',\n True: 'true',\n False: 'false',\n None: 'null',\n};\n\n/**\n * Extracts JSON values from a response, repairing common LLM syntax and retaining repair provenance.\n * Offsets refer to the original string. All candidates are returned: choosing among multiple answers,\n * schema validation, and provider truncation signals belong to the caller. No schema values are coerced.\n * Bounded to one million UTF-16 code units, 128 nesting levels, and 32 candidates/errors each.\n * A region is abandoned after 32 failed starts; later Markdown regions can still yield candidates.\n */\nexport function recoverJson(text: string): JsonRecovery {\n const result: JsonRecovery = { candidates: [], errors: [] };\n if (text.length > MAX_INPUT_LENGTH) {\n result.errors.push({ offset: MAX_INPUT_LENGTH, message: 'JSON recovery input exceeds one million characters' });\n return result;\n }\n const fences = [...text.matchAll(/^(?: {0,3})(`{3,}|~{3,})[^\\r\\n]*(?:\\r\\n|[\\r\\n]|$)/gm)].flatMap((fence) => {\n const marker = fence[1]!;\n const markerEnd = fence.index + fence[0].indexOf(marker) + marker.length;\n const lineEnd = fence.index + fence[0].length;\n const info = text.slice(markerEnd, lineEnd);\n const inlinePrefix = /^[ \\t]*json(?=[ \\t{[\"'“”‘’])[ \\t]*/i.exec(info);\n const inlineStart = inlinePrefix === null ? lineEnd : markerEnd + inlinePrefix[0].length;\n const start =\n text[inlineStart] === '{' || text[inlineStart] === '[' || scalarStart(text, inlineStart, lineEnd)\n ? inlineStart\n : lineEnd;\n return marker[0] === '`' && start === lineEnd && info.includes('`') ? [] : [{ index: fence.index, marker, start }];\n });\n if (fences.length > 0) {\n let consumed = 0;\n for (const fence of fences) {\n if (fence.index < consumed) continue;\n extractRegion(text, consumed, fence.index, result);\n const parsedThrough = result.candidates.at(-1)?.end ?? consumed;\n if (parsedThrough > fence.index) {\n consumed = parsedThrough;\n continue;\n }\n const { marker, start } = fence;\n const close = new RegExp(`^ {0,3}${marker[0]}{${marker.length},}[ \\\\t]*$`, 'gm');\n close.lastIndex = start;\n const match = close.exec(text);\n const end = match?.index ?? text.length;\n extractRegion(text, start, end, result);\n const extendedEnd = result.candidates.at(-1)?.end ?? start;\n if (extendedEnd > end) {\n close.lastIndex = extendedEnd;\n const outerClose = close.exec(text);\n if (outerClose !== null && !fences.some((next) => next.index >= extendedEnd && next.index < outerClose.index)) {\n extractRegion(text, extendedEnd, outerClose.index, result);\n consumed = outerClose.index + outerClose[0].length;\n continue;\n }\n }\n consumed = Math.max(\n result.candidates.at(-1)?.end ?? start,\n match === null ? text.length : match.index + match[0].length\n );\n }\n extractRegion(text, consumed, text.length, result);\n } else {\n extractRegion(text, 0, text.length, result);\n }\n if (result.candidates.length === MAX_CANDIDATES) {\n const error = {\n offset: result.candidates.at(-1)!.end,\n message: 'JSON candidate limit reached; extraction may be incomplete',\n };\n if (result.errors.length === MAX_ERRORS) result.errors[MAX_ERRORS - 1] = error;\n else result.errors.push(error);\n }\n return result;\n}\n\nfunction extractRegion(text: string, start: number, end: number, result: JsonRecovery, commentFragment = false): void {\n if (result.candidates.length >= MAX_CANDIDATES) return;\n let index = start;\n let failures = 0;\n let ambiguousScalarTail = false;\n let scalarBoundary = true;\n let uriBoundaryEnd = start;\n let uriTokenEnd = start;\n let uriContainerStart = start;\n while (index < end && /\\s/.test(text[index]!)) index++;\n const firstIndex = index;\n const initialParser = new RecoveryParser(text, index, end);\n if (!commentFragment) initialParser.space();\n const initialValueStart = initialParser.index;\n if (initialValueStart >= end) {\n if (initialParser.repairs.some((repair) => repair.kind === 'incomplete') && result.errors.length < MAX_ERRORS)\n result.errors.push({ offset: index, message: 'Incomplete leading JSON comment' });\n return;\n }\n const first = text[initialValueStart];\n // Within prose, scalar starts need a line boundary; containers may appear inline.\n const rootValue = scalarStart(text, initialValueStart, end);\n const initialValue = rootValue || first === '{' || first === '[';\n if (!initialValue) index = initialValueStart;\n while (index < end && result.candidates.length < MAX_CANDIDATES && failures < MAX_ERRORS) {\n if (!initialValue || index !== firstIndex) {\n while (index < end && text[index] !== '{' && text[index] !== '[') {\n if (scalarBoundary && scalarStart(text, index, end)) break;\n const uriEnd =\n index === start || !/[\\w+.-]/.test(text[index - 1]!) ? unquotedUriEnd(text, index, end) : undefined;\n if (uriEnd !== undefined) {\n if (index >= uriTokenEnd) {\n const whitespace = text.slice(index, end).search(/\\s/);\n uriTokenEnd = whitespace === -1 ? end : index + whitespace;\n uriContainerStart = index;\n }\n if (index >= uriContainerStart) {\n const container = text.slice(index, uriTokenEnd).search(/[{[]/);\n uriContainerStart = container === -1 ? uriTokenEnd : index + container;\n }\n if (uriContainerStart < uriTokenEnd) uriBoundaryEnd = Math.max(uriBoundaryEnd, uriTokenEnd);\n index = Math.min(uriEnd, uriContainerStart);\n scalarBoundary = false;\n continue;\n }\n if (!commentFragment && text[index] === '/') {\n const trivia = new RecoveryParser(text, index, end);\n trivia.space();\n if (trivia.index > index) {\n if (trivia.repairs.some((repair) => repair.kind === 'incomplete') && result.errors.length < MAX_ERRORS)\n result.errors.push({ offset: index, message: 'Possibly unterminated comment-like span in prose' });\n extractRegion(text, index + 2, trivia.index, result, true);\n scalarBoundary ||= /[\\r\\n]/.test(text.slice(index, trivia.index));\n index = trivia.index;\n continue;\n }\n }\n if (/[\\r\\n]/.test(text[index]!)) scalarBoundary = true;\n else if (!/[\\s,]/.test(text[index]!)) scalarBoundary = false;\n index++;\n }\n }\n if (index >= end || result.candidates.length >= MAX_CANDIDATES) break;\n let parser = initialValue && index === firstIndex ? initialParser : new RecoveryParser(text, index, end);\n const valueStart = parser.index;\n try {\n let json = parser.value(0);\n if (\n !commentFragment &&\n (text[valueStart] === '{' || text[valueStart] === '[') &&\n parser.index === end &&\n end < text.length\n ) {\n const extended = new RecoveryParser(text, index, text.length);\n try {\n const extendedJson = extended.value(0);\n if (\n extended.index > end &&\n extended.repairs.every((repair) => repair.reason === 'unescaped-control-character')\n ) {\n extended.repairs.push({ offset: end, kind: 'ambiguous', reason: 'literal-fence-in-string' });\n parser = extended;\n json = extendedJson;\n }\n } catch {\n // Keep the bounded interpretation when extending it is not a complete JSON document.\n }\n }\n const valueEnd = parser.index;\n if (text[valueStart] !== '{' && text[valueStart] !== '[' && !parser.finishScalar(end, valueStart)) {\n scalarBoundary = false;\n index = valueEnd;\n continue;\n }\n parser.space();\n if (!commentFragment && failures === 0 && parser.index < end && /[}\\]]/.test(text[parser.index]!)) {\n const surplusStart = parser.index;\n while (parser.index < end && /[}\\]]/.test(text[parser.index]!)) {\n parser.repairs.push({ offset: parser.index, kind: 'ambiguous', reason: 'surplus-closing-bracket' });\n parser.index++;\n parser.space();\n }\n if (result.errors.length < MAX_ERRORS) {\n const excerptEnd = Math.min(end, surplusStart + MAX_DIAGNOSTIC_EXCERPT);\n result.errors.push({\n offset: surplusStart,\n message: `Surplus closing brackets and possible continuation (${excerptEnd < end ? 'truncated excerpt' : 'excerpt'}): ${JSON.stringify(text.slice(surplusStart, excerptEnd))}`,\n });\n }\n }\n if (\n text[valueStart]! in QUOTES &&\n parser.repairs.some((repair) => repair.reason === 'trailing-scalar-content') &&\n result.errors.length < MAX_ERRORS\n ) {\n const excerptEnd = Math.min(end, valueEnd + MAX_DIAGNOSTIC_EXCERPT);\n result.errors.push({\n offset: valueEnd,\n message: `Ambiguous quoted-scalar tail (${excerptEnd < end ? 'truncated excerpt' : 'excerpt'}): ${JSON.stringify(text.slice(valueEnd, excerptEnd))}`,\n });\n }\n if (commentFragment)\n parser.repairs.unshift({ offset: index, kind: 'ambiguous', reason: 'fragment-in-comment-like-prose' });\n if (failures > 0)\n parser.repairs.unshift({ offset: index, kind: 'ambiguous', reason: 'fragment-after-rejected-document' });\n if (ambiguousScalarTail)\n parser.repairs.unshift({ offset: index, kind: 'ambiguous', reason: 'fragment-after-ambiguous-scalar' });\n if (index < uriBoundaryEnd)\n parser.repairs.unshift({ offset: index, kind: 'ambiguous', reason: 'ambiguous-uri-boundary' });\n ambiguousScalarTail ||= parser.repairs.some((repair) => repair.reason === 'trailing-scalar-content');\n result.candidates.push({\n value: JSON.parse(json),\n json,\n start: index,\n end: parser.index,\n repairs: parser.repairs,\n requiresConfirmation: parser.repairs.some((repair) => repair.kind !== 'syntax'),\n });\n } catch (error) {\n if (result.errors.length < MAX_ERRORS)\n result.errors.push({ offset: parser.index, message: getErrorMessage(error) });\n failures++;\n index = valueStart + 1;\n scalarBoundary = false;\n continue;\n }\n index = Math.max(index + 1, parser.index);\n scalarBoundary = true;\n }\n}\n\nfunction scalarStart(text: string, start: number, end: number): boolean {\n const first = text[start];\n if (first === undefined) return false;\n const keyword = /^([A-Za-z]+)/.exec(text.slice(start, end))?.[1];\n return (\n first in QUOTES ||\n /[-\\d]/.test(first) ||\n (keyword !== undefined &&\n (Object.hasOwn(KEYWORDS, keyword) ||\n (Object.keys(KEYWORDS).some((word) => word.startsWith(keyword)) &&\n /^[^\\S\\r\\n]*(?:[\\r\\n]|$)/.test(text.slice(start + keyword.length, end)))))\n );\n}\n\nclass RecoveryParser {\n readonly repairs: JsonRepair[] = [];\n readonly text: string;\n readonly end: number;\n index: number;\n\n constructor(text: string, index: number, end: number) {\n this.text = text;\n this.index = index;\n this.end = end;\n }\n\n finishScalar(regionEnd: number, start: number): boolean {\n const valueEnd = this.index;\n const atom = this.text.slice(start, valueEnd);\n const bullet = atom === '-' && /\\s/.test(this.text[valueEnd] ?? '');\n const retainLiteral =\n this.text[start]! in QUOTES || this.repairs.some((repair) => repair.reason === 'unquoted-value');\n this.space();\n if (bullet) return false;\n if (this.index >= regionEnd) return true;\n if (/[\\r\\n]/.test(this.text.slice(valueEnd, this.index))) {\n this.repair('ambiguous', 'scalar-before-prose', valueEnd);\n return true;\n }\n if (/^\\d+[.)]$/.test(atom) && /[ \\t]/.test(this.text[valueEnd] ?? '')) return false;\n if (retainLiteral || /^[\\p{P}\\p{S}]/u.test(this.text.slice(this.index, regionEnd))) {\n this.repair('ambiguous', 'trailing-scalar-content', valueEnd);\n return true;\n }\n return false;\n }\n\n value(depth: number): string {\n if (depth > MAX_DEPTH) throw new Error('JSON nesting exceeds 128 levels');\n this.space();\n const char = this.text[this.index];\n if (this.index >= this.end || char === ',' || char === '}' || char === ']') {\n this.repair('incomplete', 'missing-value');\n return 'null';\n }\n if (char === '{' || char === '[') {\n if (depth >= MAX_DEPTH) throw new Error('JSON nesting exceeds 128 levels');\n return this.container(depth, char === '{');\n }\n if (char !== undefined && char in QUOTES) return this.string(depth > 0 ? 'value' : 'root');\n const start = this.index;\n const uriEnd = unquotedUriEnd(this.text, start, this.end);\n if (uriEnd !== undefined) this.index = uriEnd;\n else\n while (\n this.index < this.end &&\n !/[\\s,}\\]]/.test(this.text[this.index]!) &&\n !(depth === 0 && /[{[]/.test(this.text[this.index]!)) &&\n !this.comment()\n )\n this.index++;\n if (this.index === start) throw new Error('Expected a JSON value');\n const token = this.text.slice(start, this.index);\n if (/^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$/.test(token)) return token;\n if (Object.hasOwn(KEYWORDS, token)) {\n const canonical = KEYWORDS[token]!;\n if (canonical !== token) this.repair('syntax', 'python-keyword', start);\n return canonical;\n }\n this.repair(this.index >= this.end ? 'incomplete' : 'ambiguous', 'unquoted-value', start);\n return JSON.stringify(token);\n }\n\n private container(depth: number, object: boolean): string {\n this.index++;\n const close = object ? '}' : ']';\n const items: string[] = [];\n const keys = new Set<string>();\n let afterComma = false;\n let commaOffset = this.index;\n for (;;) {\n this.space();\n if (this.index >= this.end || this.text[this.index] === close) {\n if (this.index >= this.end) this.repair('incomplete', `missing-${close}`);\n else this.index++;\n if (afterComma) this.repair('syntax', 'trailing-comma', commaOffset);\n return (object ? '{' : '[') + items.join(',') + close;\n }\n if (this.text[this.index] === '}' || this.text[this.index] === ']') throw new Error('Mismatched closing bracket');\n if (this.text[this.index] === ',') {\n if (object) this.repair('ambiguous', 'extra-comma');\n else {\n items.push('null');\n this.repair('incomplete', 'missing-value');\n }\n commaOffset = this.index;\n afterComma = true;\n this.index++;\n continue;\n }\n let key: string | undefined;\n if (object) {\n const start = this.index;\n if (this.text[this.index]! in QUOTES) key = this.string();\n else {\n while (this.index < this.end && !/[\\s:,{}[\\]]/.test(this.text[this.index]!) && !this.comment()) this.index++;\n if (this.index === start) throw new Error('Expected an object key');\n const rawKey = this.text.slice(start, this.index);\n key = JSON.stringify(rawKey);\n this.repair(/[\"'“”‘’]/.test(rawKey) ? 'ambiguous' : 'syntax', 'unquoted-key', start);\n }\n const decoded: string = JSON.parse(key);\n if (keys.has(decoded)) this.repair('ambiguous', 'duplicate-key', start);\n keys.add(decoded);\n this.space();\n if (this.text[this.index] === ':') this.index++;\n else this.repair('ambiguous', 'missing-colon');\n }\n const value = this.value(depth + 1);\n items.push(key === undefined ? value : `${key}:${value}`);\n this.space();\n afterComma = this.text[this.index] === ',';\n if (afterComma) {\n commaOffset = this.index;\n this.index++;\n } else if (this.index < this.end && this.text[this.index] !== close) this.repair('syntax', 'missing-comma');\n }\n }\n\n private string(context: 'root' | 'key' | 'value' = 'key'): string {\n const start = this.index;\n const open = this.text[this.index++]!;\n const close = QUOTES[open]!;\n if (open !== '\"') this.repair('syntax', 'non-json-quote', start);\n let value = '';\n let tail = '';\n const append = (text: string): void => {\n value += text;\n tail = (tail + text).slice(-2);\n };\n let embeddedQuote = false;\n const family = '\"“”'.includes(open) ? '\"“”' : \"'‘’\";\n let alternative: { end: number; value: string; repairCount: number } | undefined;\n while (this.index < this.end) {\n const char = this.text[this.index++]!;\n if (\n \"'‘’\".includes(open) &&\n \"'’\".includes(char) &&\n /[\\p{L}\\p{N}]$/u.test(tail) &&\n /^[\\p{L}\\p{N}]/u.test(this.text.slice(this.index, this.end))\n ) {\n this.repair('ambiguous', 'literal-apostrophe', this.index - 1);\n append(char);\n continue;\n }\n if (family.includes(char)) {\n const after = this.text.slice(this.index, this.end).trimStart()[0];\n const delimited = after === undefined || /[,}\\]:\"']/.test(after);\n if (char === close) {\n if (embeddedQuote) {\n embeddedQuote = false;\n this.repair('ambiguous', 'unescaped-quote', this.index - 1);\n append(char);\n continue;\n }\n if (context !== 'root' && alternative !== undefined && !delimited) {\n this.index = alternative.end;\n this.repairs.length = alternative.repairCount;\n this.repair('ambiguous', 'mismatched-quote', this.index - 1);\n return JSON.stringify(alternative.value);\n }\n const nextClose = this.text.indexOf(close, this.index);\n const afterNext = this.text.slice(nextClose + 1, this.end).trimStart()[0];\n if (\n context === 'value' &&\n !delimited &&\n !/\\s/.test(this.text[this.index] ?? '') &&\n nextClose > this.index &&\n nextClose < this.end &&\n afterNext !== undefined &&\n (!/[,}:\\]]/.test(afterNext) ||\n (afterNext === ',' && this.continuesStringAfterComma(nextClose + 1, close))) &&\n !/[\\\\*:,{}[\\]\\r\\n]|\\/\\//.test(this.text.slice(this.index, nextClose)) &&\n !this.startsKey(nextClose)\n ) {\n embeddedQuote = true;\n this.repair('ambiguous', 'unescaped-quote', this.index - 1);\n append(char);\n continue;\n }\n return JSON.stringify(value);\n }\n if (delimited) alternative ??= { end: this.index, value, repairCount: this.repairs.length };\n }\n if (char !== '\\\\') {\n if (char.codePointAt(0)! < 32) this.repair('syntax', 'unescaped-control-character', this.index - 1);\n append(char);\n continue;\n }\n const escapeOffset = this.index - 1;\n if (this.index >= this.end) {\n append('\\\\');\n this.repair('incomplete', 'truncated-escape', escapeOffset);\n break;\n }\n const escape = this.text[this.index++]!;\n if (escape === 'u') {\n const hex = this.text.slice(this.index, Math.min(this.index + 4, this.end));\n if (/^[\\da-fA-F]{4}$/.test(hex)) {\n append(String.fromCodePoint(Number.parseInt(hex, 16)));\n this.index += 4;\n } else {\n append(String.raw`\\u`);\n this.repair(\n /^[\\da-fA-F]{0,3}$/.test(hex) ? 'incomplete' : 'ambiguous',\n 'invalid-unicode-escape',\n escapeOffset\n );\n }\n } else if (String.raw`\"\\/bfnrt`.includes(escape)) {\n append(JSON.parse(`\"\\\\${escape}\"`) as string);\n } else if (escape === \"'\" && open === \"'\") append(\"'\");\n else {\n append(`\\\\${escape}`);\n this.repair('ambiguous', 'invalid-escape', escapeOffset);\n }\n }\n this.repair('incomplete', 'unterminated-string', start);\n return JSON.stringify(value);\n }\n\n private continuesStringAfterComma(start: number, quote: string): boolean {\n const parser = new RecoveryParser(this.text, start - 1, this.end);\n parser.string();\n const end = parser.index - 1;\n if (\n this.text[end] !== quote ||\n parser.repairs.some(\n (repair) => !['non-json-quote', 'literal-apostrophe', 'unescaped-control-character'].includes(repair.reason)\n )\n )\n return false;\n const continuation = this.text.slice(start, end);\n const after = this.text.slice(end + 1, this.end).trimStart()[0];\n return (\n /^\\s*,\\s*[\\p{L}\\p{N}]/u.test(continuation) &&\n !/[\\\\:{}[\\]]/.test(continuation) &&\n (after === undefined || /[,}\\]]/.test(after))\n );\n }\n\n private startsKey(index: number): boolean {\n const parser = new RecoveryParser(this.text, index, this.end);\n parser.string();\n parser.space();\n return this.text[parser.index] === ':';\n }\n\n space(): void {\n while (this.index < this.end) {\n if (/\\s/.test(this.text[this.index]!)) {\n if (!/[ \\t\\r\\n]/.test(this.text[this.index]!)) this.repair('syntax', 'non-json-whitespace');\n this.index++;\n } else if (this.text.startsWith('//', this.index)) {\n this.repair('syntax', 'line-comment');\n while (this.index < this.end && !/[\\r\\n]/.test(this.text[this.index]!)) this.index++;\n } else if (this.text.startsWith('/*', this.index)) {\n const end = this.text.indexOf('*/', this.index + 2);\n this.repair(end === -1 || end >= this.end ? 'incomplete' : 'syntax', 'block-comment');\n this.index = end === -1 || end >= this.end ? this.end : end + 2;\n } else break;\n }\n }\n\n private repair(kind: JsonRepair['kind'], reason: string, offset = this.index): void {\n this.repairs.push({ offset, kind, reason });\n }\n\n private comment(): boolean {\n return this.text.startsWith('//', this.index) || this.text.startsWith('/*', this.index);\n }\n}\n\nfunction unquotedUriEnd(text: string, start: number, end: number): number | undefined {\n const match = /^[A-Za-z][A-Za-z\\d+.-]*:\\/\\//.exec(text.slice(start, end));\n if (match === null) return;\n let index = start + match[0].length;\n let brackets = 0;\n while (index < end && !/[\\s}]/.test(text[index]!)) {\n if (text[index] === ',' && brackets === 0) break;\n if (text[index] === '[') brackets++;\n else if (text[index] === ']') {\n if (brackets === 0) break;\n brackets--;\n }\n index++;\n }\n return index;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"recoverJson.js","names":["MAX_INPUT_LENGTH","QUOTES","CLOSERS","KEYWORDS","recoverJson","result","text","fences","findFences","consumed","fence","extractThroughFence","extractRegion","error","marker","markerEnd","lineEnd","info","inlinePrefix","inlineStart","start","isContainerStart","scalarStart","parsedThrough","close","match","end","extendedEnd","outerClose","next","RegionExtractor","commentFragment","firstIndex","initialParser","RecoveryParser","initialValueStart","repair","initialValue","atInitialValue","index","uriEnd","unquotedUriEnd","whitespace","container","trivia","valueStart","bounded","parser","boundedJson","extended","json","valueEnd","getErrorMessage","surplusStart","mark","excerptEnd","offset","excerpt","summary","char","first","keyword","word","atom","bullet","retainLiteral","regionEnd","depth","token","canonical","object","open","items","keys","afterComma","commaOffset","key","decoded","seen","rawKey","value","tail","append","embeddedQuote","family","alternative","after","delimited","context","nextClose","afterNext","escapeOffset","escape","hex","quote","continuation","reason","brackets"],"sources":["../src/recoverJson.ts"],"sourcesContent":["/*! JSON recovery informed by jsonrepair, Copyright (c) 2020-2026 Jos de Jong (ISC). See NOTICE. */\n\nimport { getErrorMessage } from './error.js';\n\nexport interface JsonRepair {\n /** UTF-16 offset in the original response. */\n offset: number;\n kind: 'syntax' | 'incomplete' | 'ambiguous';\n reason: string;\n}\n\nexport interface RecoveredJson {\n value: unknown;\n json: string;\n start: number;\n end: number;\n repairs: JsonRepair[];\n /** Missing content or an ambiguous interpretation requires confirmation before acting on this value. */\n requiresConfirmation: boolean;\n}\n\nexport interface JsonRecovery {\n candidates: RecoveredJson[];\n errors: { offset: number; message: string }[];\n}\n\nconst MAX_INPUT_LENGTH = 1_000_000;\nconst MAX_DEPTH = 128;\nconst MAX_CANDIDATES = 32;\nconst MAX_ERRORS = 32;\nconst MAX_DIAGNOSTIC_EXCERPT = 256;\nconst QUOTES: Record<string, string> = { '\"': '\"', \"'\": \"'\", '“': '”', '”': '”', '‘': '’', '’': '’' };\nconst CLOSERS = { '{': '}', '[': ']' } as const;\nconst KEYWORDS: Record<string, string> = {\n true: 'true',\n false: 'false',\n null: 'null',\n True: 'true',\n False: 'false',\n None: 'null',\n};\n\n/**\n * Extracts JSON values from a response, repairing common LLM syntax and retaining repair provenance.\n * Offsets refer to the original string. All candidates are returned: choosing among multiple answers,\n * schema validation, and provider truncation signals belong to the caller. No schema values are coerced.\n * Bounded to one million UTF-16 code units, 128 nesting levels, and 32 candidates/errors each.\n * A region is abandoned after 32 failed starts; later Markdown regions can still yield candidates.\n */\nexport function recoverJson(text: string): JsonRecovery {\n const result: JsonRecovery = { candidates: [], errors: [] };\n if (text.length > MAX_INPUT_LENGTH) {\n result.errors.push({ offset: MAX_INPUT_LENGTH, message: 'JSON recovery input exceeds one million characters' });\n return result;\n }\n const fences = findFences(text);\n let consumed = 0;\n for (const fence of fences) {\n if (fence.index >= consumed) consumed = extractThroughFence(text, fences, fence, consumed, result);\n }\n extractRegion(text, consumed, text.length, result);\n if (result.candidates.length === MAX_CANDIDATES) {\n const error = {\n offset: result.candidates.at(-1)!.end,\n message: 'JSON candidate limit reached; extraction may be incomplete',\n };\n if (result.errors.length === MAX_ERRORS) result.errors[MAX_ERRORS - 1] = error;\n else result.errors.push(error);\n }\n return result;\n}\n\ninterface Fence {\n index: number;\n marker: string;\n /** Where the fenced content starts: after the opening line, or within it when JSON follows the info string. */\n start: number;\n}\n\nfunction findFences(text: string): Fence[] {\n return [...text.matchAll(/^(?: {0,3})(`{3,}|~{3,})[^\\r\\n]*(?:\\r\\n|[\\r\\n]|$)/gm)].flatMap((fence) => {\n const marker = fence[1]!;\n const markerEnd = fence.index + fence[0].indexOf(marker) + marker.length;\n const lineEnd = fence.index + fence[0].length;\n const info = text.slice(markerEnd, lineEnd);\n const inlinePrefix = /^[ \\t]*json(?=[ \\t{[\"'“”‘’])[ \\t]*/i.exec(info);\n const inlineStart = inlinePrefix === null ? lineEnd : markerEnd + inlinePrefix[0].length;\n const start =\n isContainerStart(text[inlineStart]) || scalarStart(text, inlineStart, lineEnd) ? inlineStart : lineEnd;\n return marker[0] === '`' && start === lineEnd && info.includes('`') ? [] : [{ index: fence.index, marker, start }];\n });\n}\n\n/** Extracts the prose before `fence` and then its content, returning the offset up to which the text is consumed. */\nfunction extractThroughFence(\n text: string,\n fences: Fence[],\n fence: Fence,\n consumed: number,\n result: JsonRecovery\n): number {\n extractRegion(text, consumed, fence.index, result);\n const parsedThrough = result.candidates.at(-1)?.end ?? consumed;\n if (parsedThrough > fence.index) return parsedThrough;\n const { marker, start } = fence;\n const close = new RegExp(`^ {0,3}${marker[0]}{${marker.length},}[ \\\\t]*$`, 'gm');\n close.lastIndex = start;\n const match = close.exec(text);\n const end = match?.index ?? text.length;\n extractRegion(text, start, end, result);\n const extendedEnd = result.candidates.at(-1)?.end ?? start;\n if (extendedEnd > end) {\n close.lastIndex = extendedEnd;\n const outerClose = close.exec(text);\n if (outerClose !== null && !fences.some((next) => next.index >= extendedEnd && next.index < outerClose.index)) {\n extractRegion(text, extendedEnd, outerClose.index, result);\n return outerClose.index + outerClose[0].length;\n }\n }\n return Math.max(result.candidates.at(-1)?.end ?? start, match === null ? text.length : match.index + match[0].length);\n}\n\nfunction extractRegion(text: string, start: number, end: number, result: JsonRecovery, commentFragment = false): void {\n if (result.candidates.length < MAX_CANDIDATES) new RegionExtractor(text, start, end, result, commentFragment).run();\n}\n\nclass RegionExtractor {\n private readonly text: string;\n private readonly start: number;\n private readonly end: number;\n private readonly result: JsonRecovery;\n private readonly commentFragment: boolean;\n private index: number;\n private failures = 0;\n private ambiguousScalarTail = false;\n private scalarBoundary = true;\n private uriBoundaryEnd: number;\n private uriTokenEnd: number;\n private uriContainerStart: number;\n\n constructor(text: string, start: number, end: number, result: JsonRecovery, commentFragment: boolean) {\n this.text = text;\n this.start = start;\n this.end = end;\n this.result = result;\n this.commentFragment = commentFragment;\n this.index = start;\n this.uriBoundaryEnd = start;\n this.uriTokenEnd = start;\n this.uriContainerStart = start;\n }\n\n run(): void {\n const { text, end, result } = this;\n while (this.index < end && /\\s/.test(text[this.index]!)) this.index++;\n const firstIndex = this.index;\n const initialParser = new RecoveryParser(text, this.index, end);\n if (!this.commentFragment) initialParser.space();\n const initialValueStart = initialParser.index;\n if (initialValueStart >= end) {\n if (initialParser.repairs.some((repair) => repair.kind === 'incomplete'))\n this.reportError(this.index, 'Incomplete leading JSON comment');\n return;\n }\n // Within prose, scalar starts need a line boundary; containers may appear inline.\n const initialValue = scalarStart(text, initialValueStart, end) || isContainerStart(text[initialValueStart]);\n if (!initialValue) this.index = initialValueStart;\n while (this.index < end && result.candidates.length < MAX_CANDIDATES && this.failures < MAX_ERRORS) {\n const atInitialValue = initialValue && this.index === firstIndex;\n if (!atInitialValue) this.skipProse();\n if (this.index >= end || result.candidates.length >= MAX_CANDIDATES) break;\n this.extractCandidate(atInitialValue ? initialParser : new RecoveryParser(text, this.index, end));\n }\n }\n\n /** Advances to the next position where a JSON value may start. */\n private skipProse(): void {\n const { text, end } = this;\n while (this.index < end && !isContainerStart(text[this.index])) {\n if (this.scalarBoundary && scalarStart(text, this.index, end)) break;\n if (this.skipUri() || this.skipCommentLikeSpan()) continue;\n if (/[\\r\\n]/.test(text[this.index]!)) this.scalarBoundary = true;\n else if (!/[\\s,]/.test(text[this.index]!)) this.scalarBoundary = false;\n this.index++;\n }\n }\n\n private skipUri(): boolean {\n const { text, end, index } = this;\n if (index !== this.start && /[\\w+.-]/.test(text[index - 1]!)) return false;\n const uriEnd = unquotedUriEnd(text, index, end);\n if (uriEnd === undefined) return false;\n if (index >= this.uriTokenEnd) {\n const whitespace = text.slice(index, end).search(/\\s/);\n this.uriTokenEnd = whitespace === -1 ? end : index + whitespace;\n this.uriContainerStart = index;\n }\n if (index >= this.uriContainerStart) {\n const container = text.slice(index, this.uriTokenEnd).search(/[{[]/);\n this.uriContainerStart = container === -1 ? this.uriTokenEnd : index + container;\n }\n if (this.uriContainerStart < this.uriTokenEnd)\n this.uriBoundaryEnd = Math.max(this.uriBoundaryEnd, this.uriTokenEnd);\n this.index = Math.min(uriEnd, this.uriContainerStart);\n this.scalarBoundary = false;\n return true;\n }\n\n private skipCommentLikeSpan(): boolean {\n const { text, end, index } = this;\n if (this.commentFragment || text[index] !== '/') return false;\n const trivia = new RecoveryParser(text, index, end);\n trivia.space();\n if (trivia.index <= index) return false;\n if (trivia.repairs.some((repair) => repair.kind === 'incomplete'))\n this.reportError(index, 'Possibly unterminated comment-like span in prose');\n extractRegion(text, index + 2, trivia.index, this.result, true);\n this.scalarBoundary ||= /[\\r\\n]/.test(text.slice(index, trivia.index));\n this.index = trivia.index;\n return true;\n }\n\n private extractCandidate(bounded: RecoveryParser): void {\n const { text, end, index } = this;\n const valueStart = bounded.index;\n let parser = bounded;\n try {\n const boundedJson = bounded.value(0);\n const extended = this.parsePastRegionEnd(bounded, valueStart);\n parser = extended?.parser ?? bounded;\n const json = extended?.json ?? boundedJson;\n const valueEnd = parser.index;\n if (!isContainerStart(text[valueStart]) && !parser.finishScalar(end, valueStart)) {\n this.scalarBoundary = false;\n this.index = valueEnd;\n return;\n }\n parser.space();\n this.consumeSurplusClosers(parser);\n if (text[valueStart]! in QUOTES && parser.hasRepair('trailing-scalar-content'))\n this.reportExcerpt(valueEnd, 'Ambiguous quoted-scalar tail');\n this.markFragmentProvenance(parser);\n this.ambiguousScalarTail ||= parser.hasRepair('trailing-scalar-content');\n this.result.candidates.push({\n value: JSON.parse(json),\n json,\n start: index,\n end: parser.index,\n repairs: parser.repairs,\n requiresConfirmation: parser.repairs.some((repair) => repair.kind !== 'syntax'),\n });\n } catch (error) {\n this.reportError(parser.index, getErrorMessage(error));\n this.failures++;\n this.index = valueStart + 1;\n this.scalarBoundary = false;\n return;\n }\n this.index = Math.max(index + 1, parser.index);\n this.scalarBoundary = true;\n }\n\n /**\n * Reparses a container that `bounded` ended exactly at the region end against the rest of the text,\n * as the fence that bounds the region may be literal text inside one of its strings.\n */\n private parsePastRegionEnd(\n bounded: RecoveryParser,\n valueStart: number\n ): { parser: RecoveryParser; json: string } | undefined {\n const { text, end } = this;\n if (this.commentFragment || !isContainerStart(text[valueStart]) || bounded.index !== end || end >= text.length)\n return undefined;\n const parser = new RecoveryParser(text, this.index, text.length);\n try {\n const json = parser.value(0);\n if (parser.index > end && parser.repairs.every((repair) => repair.reason === 'unescaped-control-character')) {\n parser.repairs.push({ offset: end, kind: 'ambiguous', reason: 'literal-fence-in-string' });\n return { parser, json };\n }\n } catch {\n // Keep the bounded interpretation when extending it is not a complete JSON document.\n }\n return undefined;\n }\n\n private consumeSurplusClosers(parser: RecoveryParser): void {\n if (this.commentFragment || this.failures > 0) return;\n const surplusStart = parser.index;\n while (parser.index < this.end && /[}\\]]/.test(this.text[parser.index]!)) {\n parser.repairs.push({ offset: parser.index, kind: 'ambiguous', reason: 'surplus-closing-bracket' });\n parser.index++;\n parser.space();\n }\n if (parser.index > surplusStart)\n this.reportExcerpt(surplusStart, 'Surplus closing brackets and possible continuation');\n }\n\n private markFragmentProvenance(parser: RecoveryParser): void {\n const mark = (reason: string): void => {\n parser.repairs.unshift({ offset: this.index, kind: 'ambiguous', reason });\n };\n if (this.commentFragment) mark('fragment-in-comment-like-prose');\n if (this.failures > 0) mark('fragment-after-rejected-document');\n if (this.ambiguousScalarTail) mark('fragment-after-ambiguous-scalar');\n if (this.index < this.uriBoundaryEnd) mark('ambiguous-uri-boundary');\n }\n\n private reportExcerpt(offset: number, summary: string): void {\n const excerptEnd = Math.min(this.end, offset + MAX_DIAGNOSTIC_EXCERPT);\n const excerpt = JSON.stringify(this.text.slice(offset, excerptEnd));\n this.reportError(offset, `${summary} (${excerptEnd < this.end ? 'truncated excerpt' : 'excerpt'}): ${excerpt}`);\n }\n\n private reportError(offset: number, message: string): void {\n if (this.result.errors.length < MAX_ERRORS) this.result.errors.push({ offset, message });\n }\n}\n\nfunction isContainerStart(char: string | undefined): char is keyof typeof CLOSERS {\n return char === '{' || char === '[';\n}\n\nfunction scalarStart(text: string, start: number, end: number): boolean {\n const first = text[start];\n if (first === undefined) return false;\n const keyword = /^([A-Za-z]+)/.exec(text.slice(start, end))?.[1];\n return (\n first in QUOTES ||\n /[-\\d]/.test(first) ||\n (keyword !== undefined &&\n (Object.hasOwn(KEYWORDS, keyword) ||\n (Object.keys(KEYWORDS).some((word) => word.startsWith(keyword)) &&\n /^[^\\S\\r\\n]*(?:[\\r\\n]|$)/.test(text.slice(start + keyword.length, end)))))\n );\n}\n\nclass RecoveryParser {\n readonly repairs: JsonRepair[] = [];\n readonly text: string;\n readonly end: number;\n index: number;\n\n constructor(text: string, index: number, end: number) {\n this.text = text;\n this.index = index;\n this.end = end;\n }\n\n finishScalar(regionEnd: number, start: number): boolean {\n const valueEnd = this.index;\n const atom = this.text.slice(start, valueEnd);\n const bullet = atom === '-' && /\\s/.test(this.text[valueEnd] ?? '');\n const retainLiteral = this.text[start]! in QUOTES || this.hasRepair('unquoted-value');\n this.space();\n if (bullet) return false;\n if (this.index >= regionEnd) return true;\n if (/[\\r\\n]/.test(this.text.slice(valueEnd, this.index))) {\n this.repair('ambiguous', 'scalar-before-prose', valueEnd);\n return true;\n }\n if (/^\\d+[.)]$/.test(atom) && /[ \\t]/.test(this.text[valueEnd] ?? '')) return false;\n if (retainLiteral || /^[\\p{P}\\p{S}]/u.test(this.text.slice(this.index, regionEnd))) {\n this.repair('ambiguous', 'trailing-scalar-content', valueEnd);\n return true;\n }\n return false;\n }\n\n value(depth: number): string {\n if (depth > MAX_DEPTH) throw new Error('JSON nesting exceeds 128 levels');\n this.space();\n const char = this.text[this.index];\n if (this.index >= this.end || char === ',' || char === '}' || char === ']') {\n this.repair('incomplete', 'missing-value');\n return 'null';\n }\n if (isContainerStart(char)) {\n if (depth >= MAX_DEPTH) throw new Error('JSON nesting exceeds 128 levels');\n return this.container(depth, char);\n }\n if (char !== undefined && char in QUOTES) return this.string(depth > 0 ? 'value' : 'root');\n const start = this.index;\n const uriEnd = unquotedUriEnd(this.text, start, this.end);\n if (uriEnd !== undefined) this.index = uriEnd;\n else\n while (\n this.index < this.end &&\n !/[\\s,}\\]]/.test(this.text[this.index]!) &&\n !(depth === 0 && /[{[]/.test(this.text[this.index]!)) &&\n !this.comment()\n )\n this.index++;\n if (this.index === start) throw new Error('Expected a JSON value');\n const token = this.text.slice(start, this.index);\n if (/^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$/.test(token)) return token;\n if (Object.hasOwn(KEYWORDS, token)) {\n const canonical = KEYWORDS[token]!;\n if (canonical !== token) this.repair('syntax', 'python-keyword', start);\n return canonical;\n }\n this.repair(this.index >= this.end ? 'incomplete' : 'ambiguous', 'unquoted-value', start);\n return JSON.stringify(token);\n }\n\n private container(depth: number, open: keyof typeof CLOSERS): string {\n this.index++;\n const object = open === '{';\n const close = CLOSERS[open];\n const items: string[] = [];\n const keys = new Set<string>();\n let afterComma = false;\n let commaOffset = this.index;\n for (;;) {\n this.space();\n if (this.index >= this.end || this.text[this.index] === close) {\n if (this.index >= this.end) this.repair('incomplete', `missing-${close}`);\n else this.index++;\n if (afterComma) this.repair('syntax', 'trailing-comma', commaOffset);\n return open + items.join(',') + close;\n }\n if (this.text[this.index] === '}' || this.text[this.index] === ']') throw new Error('Mismatched closing bracket');\n if (this.text[this.index] === ',') {\n if (object) this.repair('ambiguous', 'extra-comma');\n else {\n items.push('null');\n this.repair('incomplete', 'missing-value');\n }\n commaOffset = this.index;\n afterComma = true;\n this.index++;\n continue;\n }\n items.push(object ? `${this.key(keys)}:${this.value(depth + 1)}` : this.value(depth + 1));\n this.space();\n afterComma = this.text[this.index] === ',';\n if (afterComma) {\n commaOffset = this.index;\n this.index++;\n } else if (this.index < this.end && this.text[this.index] !== close) this.repair('syntax', 'missing-comma');\n }\n }\n\n /** Parses an object key and the colon after it, returning the key as JSON. */\n private key(seen: Set<string>): string {\n const start = this.index;\n const key = this.text[start]! in QUOTES ? this.string() : this.unquotedKey();\n const decoded: string = JSON.parse(key);\n if (seen.has(decoded)) this.repair('ambiguous', 'duplicate-key', start);\n seen.add(decoded);\n this.space();\n if (this.text[this.index] === ':') this.index++;\n else this.repair('ambiguous', 'missing-colon');\n return key;\n }\n\n private unquotedKey(): string {\n const start = this.index;\n while (this.index < this.end && !/[\\s:,{}[\\]]/.test(this.text[this.index]!) && !this.comment()) this.index++;\n if (this.index === start) throw new Error('Expected an object key');\n const rawKey = this.text.slice(start, this.index);\n this.repair(/[\"'“”‘’]/.test(rawKey) ? 'ambiguous' : 'syntax', 'unquoted-key', start);\n return JSON.stringify(rawKey);\n }\n\n private string(context: 'root' | 'key' | 'value' = 'key'): string {\n const start = this.index;\n const open = this.text[this.index++]!;\n const close = QUOTES[open]!;\n if (open !== '\"') this.repair('syntax', 'non-json-quote', start);\n let value = '';\n let tail = '';\n const append = (text: string): void => {\n value += text;\n tail = (tail + text).slice(-2);\n };\n let embeddedQuote = false;\n const family = '\"“”'.includes(open) ? '\"“”' : \"'‘’\";\n let alternative: { end: number; value: string; repairCount: number } | undefined;\n while (this.index < this.end) {\n const char = this.text[this.index++]!;\n if (\n \"'‘’\".includes(open) &&\n \"'’\".includes(char) &&\n /[\\p{L}\\p{N}]$/u.test(tail) &&\n /^[\\p{L}\\p{N}]/u.test(this.text.slice(this.index, this.end))\n ) {\n this.repair('ambiguous', 'literal-apostrophe', this.index - 1);\n append(char);\n continue;\n }\n if (family.includes(char)) {\n const after = this.charAfterSpace(this.index);\n const delimited = after === undefined || /[,}\\]:\"']/.test(after);\n if (char !== close) {\n if (delimited) alternative ??= { end: this.index, value, repairCount: this.repairs.length };\n } else if (!embeddedQuote && context !== 'root' && alternative !== undefined && !delimited) {\n this.index = alternative.end;\n this.repairs.length = alternative.repairCount;\n this.repair('ambiguous', 'mismatched-quote', this.index - 1);\n return JSON.stringify(alternative.value);\n } else if (embeddedQuote || (context === 'value' && !delimited && this.opensEmbeddedQuote(close))) {\n embeddedQuote = !embeddedQuote;\n this.repair('ambiguous', 'unescaped-quote', this.index - 1);\n } else return JSON.stringify(value);\n }\n if (char === '\\\\') append(this.escapeSequence(open));\n else {\n if (char.codePointAt(0)! < 32) this.repair('syntax', 'unescaped-control-character', this.index - 1);\n append(char);\n }\n }\n this.repair('incomplete', 'unterminated-string', start);\n return JSON.stringify(value);\n }\n\n /** Whether the closing quote just consumed and the next one more plausibly enclose a phrase quoted within the string. */\n private opensEmbeddedQuote(close: string): boolean {\n const nextClose = this.text.indexOf(close, this.index);\n const afterNext = this.charAfterSpace(nextClose + 1);\n return (\n !/\\s/.test(this.text[this.index] ?? '') &&\n nextClose > this.index &&\n nextClose < this.end &&\n afterNext !== undefined &&\n (!/[,}:\\]]/.test(afterNext) || (afterNext === ',' && this.continuesStringAfterComma(nextClose + 1, close))) &&\n !/[\\\\*:,{}[\\]\\r\\n]|\\/\\//.test(this.text.slice(this.index, nextClose)) &&\n !this.startsKey(nextClose)\n );\n }\n\n /** Decodes the escape sequence whose backslash was just consumed. */\n private escapeSequence(open: string): string {\n const escapeOffset = this.index - 1;\n if (this.index >= this.end) {\n this.repair('incomplete', 'truncated-escape', escapeOffset);\n return '\\\\';\n }\n const escape = this.text[this.index++]!;\n if (escape === 'u') {\n const hex = this.text.slice(this.index, Math.min(this.index + 4, this.end));\n if (/^[\\da-fA-F]{4}$/.test(hex)) {\n this.index += 4;\n return String.fromCodePoint(Number.parseInt(hex, 16));\n }\n this.repair(/^[\\da-fA-F]{0,3}$/.test(hex) ? 'incomplete' : 'ambiguous', 'invalid-unicode-escape', escapeOffset);\n return String.raw`\\u`;\n }\n if (String.raw`\"\\/bfnrt`.includes(escape)) return JSON.parse(`\"\\\\${escape}\"`) as string;\n if (escape === \"'\" && open === \"'\") return \"'\";\n this.repair('ambiguous', 'invalid-escape', escapeOffset);\n return `\\\\${escape}`;\n }\n\n private continuesStringAfterComma(start: number, quote: string): boolean {\n const parser = new RecoveryParser(this.text, start - 1, this.end);\n parser.string();\n const end = parser.index - 1;\n if (\n this.text[end] !== quote ||\n parser.repairs.some(\n (repair) => !['non-json-quote', 'literal-apostrophe', 'unescaped-control-character'].includes(repair.reason)\n )\n )\n return false;\n const continuation = this.text.slice(start, end);\n const after = this.charAfterSpace(end + 1);\n return (\n /^\\s*,\\s*[\\p{L}\\p{N}]/u.test(continuation) &&\n !/[\\\\:{}[\\]]/.test(continuation) &&\n (after === undefined || /[,}\\]]/.test(after))\n );\n }\n\n private startsKey(index: number): boolean {\n const parser = new RecoveryParser(this.text, index, this.end);\n parser.string();\n parser.space();\n return this.text[parser.index] === ':';\n }\n\n space(): void {\n while (this.index < this.end) {\n if (/\\s/.test(this.text[this.index]!)) {\n if (!/[ \\t\\r\\n]/.test(this.text[this.index]!)) this.repair('syntax', 'non-json-whitespace');\n this.index++;\n } else if (this.text.startsWith('//', this.index)) {\n this.repair('syntax', 'line-comment');\n while (this.index < this.end && !/[\\r\\n]/.test(this.text[this.index]!)) this.index++;\n } else if (this.text.startsWith('/*', this.index)) {\n const end = this.text.indexOf('*/', this.index + 2);\n this.repair(end === -1 || end >= this.end ? 'incomplete' : 'syntax', 'block-comment');\n this.index = end === -1 || end >= this.end ? this.end : end + 2;\n } else break;\n }\n }\n\n hasRepair(reason: string): boolean {\n return this.repairs.some((repair) => repair.reason === reason);\n }\n\n private charAfterSpace(index: number): string | undefined {\n return this.text.slice(index, this.end).trimStart()[0];\n }\n\n private repair(kind: JsonRepair['kind'], reason: string, offset = this.index): void {\n this.repairs.push({ offset, kind, reason });\n }\n\n private comment(): boolean {\n return this.text.startsWith('//', this.index) || this.text.startsWith('/*', this.index);\n }\n}\n\nfunction unquotedUriEnd(text: string, start: number, end: number): number | undefined {\n const match = /^[A-Za-z][A-Za-z\\d+.-]*:\\/\\//.exec(text.slice(start, end));\n if (match === null) return;\n let index = start + match[0].length;\n let brackets = 0;\n while (index < end && !/[\\s}]/.test(text[index]!)) {\n if (text[index] === ',' && brackets === 0) break;\n if (text[index] === '[') brackets++;\n else if (text[index] === ']') {\n if (brackets === 0) break;\n brackets--;\n }\n index++;\n }\n return index;\n}\n"],"mappings":"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"}
|
package/dist/shuffle.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shuffle.cjs","names":[],"sources":["../src/shuffle.ts"],"sourcesContent":["export function shuffle<T>(array: T[]): T[] {\n return shuffleWithRandom(array, Math.random);\n}\n\n/** Shuffles an array in place, returning the same array. Equal string seeds produce equal permutations. */\nexport function shuffleWithSeed<T>(array: T[], seed: string): T[] {\n let state = 1_779_033_703 ^ seed.length;\n for (const character of seed) {\n state = Math.imul(state ^ character.codePointAt(0)!, 3_432_918_353);\n state = (state << 13) | (state >>> 19);\n }\n state = Math.imul(state ^ (state >>> 16), 2_246_822_507);\n state = Math.imul(state ^ (state >>> 13), 3_266_489_909);\n state ^= state >>> 16;\n\n return shuffleWithRandom(array, () => {\n state += 1_831_565_813;\n let value = Math.imul(state ^ (state >>> 15), state | 1);\n value ^= value + Math.imul(value ^ (value >>> 7), value | 61);\n return ((value ^ (value >>> 14)) >>> 0) / 4_294_967_296;\n });\n}\n\nfunction shuffleWithRandom<T>(array: T[], random: () => number): T[] {\n for (let index = array.length - 1; index > 0; index--) {\n const index_ = Math.floor(random() * (index + 1));\n [array[index], array[index_]] = [array[index_], array[index]] as [T, T];\n }\n return array;\n}\n"],"mappings":"aAAA,
|
|
1
|
+
{"version":3,"file":"shuffle.cjs","names":["shuffle","shuffleWithRandom","array","shuffleWithSeed","state","seed","character","value","index","index_","random"],"sources":["../src/shuffle.ts"],"sourcesContent":["export function shuffle<T>(array: T[]): T[] {\n return shuffleWithRandom(array, Math.random);\n}\n\n/** Shuffles an array in place, returning the same array. Equal string seeds produce equal permutations. */\nexport function shuffleWithSeed<T>(array: T[], seed: string): T[] {\n let state = 1_779_033_703 ^ seed.length;\n for (const character of seed) {\n state = Math.imul(state ^ character.codePointAt(0)!, 3_432_918_353);\n state = (state << 13) | (state >>> 19);\n }\n state = Math.imul(state ^ (state >>> 16), 2_246_822_507);\n state = Math.imul(state ^ (state >>> 13), 3_266_489_909);\n state ^= state >>> 16;\n\n return shuffleWithRandom(array, () => {\n state += 1_831_565_813;\n let value = Math.imul(state ^ (state >>> 15), state | 1);\n value ^= value + Math.imul(value ^ (value >>> 7), value | 61);\n return ((value ^ (value >>> 14)) >>> 0) / 4_294_967_296;\n });\n}\n\nfunction shuffleWithRandom<T>(array: T[], random: () => number): T[] {\n for (let index = array.length - 1; index > 0; index--) {\n const index_ = Math.floor(random() * (index + 1));\n [array[index], array[index_]] = [array[index_], array[index]] as [T, T];\n }\n return array;\n}\n"],"mappings":"aAAA,SAAgBA,EAAW,EAAiB,CAC1C,OAAOC,EAAkBC,EAAO,KAAK,MAAM,CAC7C,CAGA,SAAgBC,EAAmB,EAAY,EAAmB,CAChE,IAAIC,EAAQ,WAAgBC,EAAK,OACjC,IAAK,IAAMC,KAAaD,EACtB,EAAQ,KAAK,KAAKD,EAAQE,EAAU,YAAY,CAAC,EAAI,UAAa,EAClE,EAASF,GAAS,GAAOA,IAAU,GAMrC,MAJA,GAAQ,KAAK,KAAKA,EAASA,IAAU,GAAK,UAAa,EACvD,EAAQ,KAAK,KAAKA,EAASA,IAAU,GAAK,UAAa,EACvD,GAASA,IAAU,GAEZH,EAAkBC,MAAa,CACpC,GAAS,WACT,IAAIK,EAAQ,KAAK,KAAKH,EAASA,IAAU,GAAKA,EAAQ,CAAC,EAEvD,MADA,IAASG,EAAQ,KAAK,KAAKA,EAASA,IAAU,EAAIA,EAAQ,EAAE,IACnDA,EAASA,IAAU,MAAS,GAAK,UAC5C,CAAC,CACH,CAEA,SAASN,EAAqB,EAAY,EAA2B,CACnE,IAAK,IAAIO,EAAQN,EAAM,OAAS,EAAGM,EAAQ,EAAG,IAAS,CACrD,IAAMC,EAAS,KAAK,MAAMC,EAAO,GAAKF,EAAQ,EAAE,EAChD,CAACN,EAAMM,GAAQN,EAAMO,IAAW,CAACP,EAAMO,GAASP,EAAMM,EAAM,CAC9D,CACA,OAAON,CACT"}
|
package/dist/shuffle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shuffle.js","names":[],"sources":["../src/shuffle.ts"],"sourcesContent":["export function shuffle<T>(array: T[]): T[] {\n return shuffleWithRandom(array, Math.random);\n}\n\n/** Shuffles an array in place, returning the same array. Equal string seeds produce equal permutations. */\nexport function shuffleWithSeed<T>(array: T[], seed: string): T[] {\n let state = 1_779_033_703 ^ seed.length;\n for (const character of seed) {\n state = Math.imul(state ^ character.codePointAt(0)!, 3_432_918_353);\n state = (state << 13) | (state >>> 19);\n }\n state = Math.imul(state ^ (state >>> 16), 2_246_822_507);\n state = Math.imul(state ^ (state >>> 13), 3_266_489_909);\n state ^= state >>> 16;\n\n return shuffleWithRandom(array, () => {\n state += 1_831_565_813;\n let value = Math.imul(state ^ (state >>> 15), state | 1);\n value ^= value + Math.imul(value ^ (value >>> 7), value | 61);\n return ((value ^ (value >>> 14)) >>> 0) / 4_294_967_296;\n });\n}\n\nfunction shuffleWithRandom<T>(array: T[], random: () => number): T[] {\n for (let index = array.length - 1; index > 0; index--) {\n const index_ = Math.floor(random() * (index + 1));\n [array[index], array[index_]] = [array[index_], array[index]] as [T, T];\n }\n return array;\n}\n"],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"shuffle.js","names":["shuffle","shuffleWithRandom","array","shuffleWithSeed","state","seed","character","value","index","index_","random"],"sources":["../src/shuffle.ts"],"sourcesContent":["export function shuffle<T>(array: T[]): T[] {\n return shuffleWithRandom(array, Math.random);\n}\n\n/** Shuffles an array in place, returning the same array. Equal string seeds produce equal permutations. */\nexport function shuffleWithSeed<T>(array: T[], seed: string): T[] {\n let state = 1_779_033_703 ^ seed.length;\n for (const character of seed) {\n state = Math.imul(state ^ character.codePointAt(0)!, 3_432_918_353);\n state = (state << 13) | (state >>> 19);\n }\n state = Math.imul(state ^ (state >>> 16), 2_246_822_507);\n state = Math.imul(state ^ (state >>> 13), 3_266_489_909);\n state ^= state >>> 16;\n\n return shuffleWithRandom(array, () => {\n state += 1_831_565_813;\n let value = Math.imul(state ^ (state >>> 15), state | 1);\n value ^= value + Math.imul(value ^ (value >>> 7), value | 61);\n return ((value ^ (value >>> 14)) >>> 0) / 4_294_967_296;\n });\n}\n\nfunction shuffleWithRandom<T>(array: T[], random: () => number): T[] {\n for (let index = array.length - 1; index > 0; index--) {\n const index_ = Math.floor(random() * (index + 1));\n [array[index], array[index_]] = [array[index_], array[index]] as [T, T];\n }\n return array;\n}\n"],"mappings":"AAAA,SAAgBA,EAAW,EAAiB,CAC1C,OAAOC,EAAkBC,EAAO,KAAK,MAAM,CAC7C,CAGA,SAAgBC,EAAmB,EAAY,EAAmB,CAChE,IAAIC,EAAQ,WAAgBC,EAAK,OACjC,IAAK,IAAMC,KAAaD,EACtB,EAAQ,KAAK,KAAKD,EAAQE,EAAU,YAAY,CAAC,EAAI,UAAa,EAClE,EAASF,GAAS,GAAOA,IAAU,GAMrC,MAJA,GAAQ,KAAK,KAAKA,EAASA,IAAU,GAAK,UAAa,EACvD,EAAQ,KAAK,KAAKA,EAASA,IAAU,GAAK,UAAa,EACvD,GAASA,IAAU,GAEZH,EAAkBC,MAAa,CACpC,GAAS,WACT,IAAIK,EAAQ,KAAK,KAAKH,EAASA,IAAU,GAAKA,EAAQ,CAAC,EAEvD,MADA,IAASG,EAAQ,KAAK,KAAKA,EAASA,IAAU,EAAIA,EAAQ,EAAE,IACnDA,EAASA,IAAU,MAAS,GAAK,UAC5C,CAAC,CACH,CAEA,SAASN,EAAqB,EAAY,EAA2B,CACnE,IAAK,IAAIO,EAAQN,EAAM,OAAS,EAAGM,EAAQ,EAAG,IAAS,CACrD,IAAMC,EAAS,KAAK,MAAMC,EAAO,GAAKF,EAAQ,EAAE,EAChD,CAACN,EAAMM,GAAQN,EAAMO,IAAW,CAACP,EAAMO,GAASP,EAAMM,EAAM,CAC9D,CACA,OAAON,CACT"}
|
package/dist/sleep.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.cjs","names":[],"sources":["../src/sleep.ts"],"sourcesContent":["export async function sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"mappings":"aAAA,
|
|
1
|
+
{"version":3,"file":"sleep.cjs","names":["sleep","resolve","milliseconds"],"sources":["../src/sleep.ts"],"sourcesContent":["export async function sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"mappings":"aAAA,eAAsBA,EAAM,EAAqC,CAC/D,OAAO,IAAI,QAAS,GAAY,WAAWC,EAASC,CAAY,CAAC,CACnE"}
|
package/dist/sleep.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.js","names":[],"sources":["../src/sleep.ts"],"sourcesContent":["export async function sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"sleep.js","names":["sleep","resolve","milliseconds"],"sources":["../src/sleep.ts"],"sourcesContent":["export async function sleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n"],"mappings":"AAAA,eAAsBA,EAAM,EAAqC,CAC/D,OAAO,IAAI,QAAS,GAAY,WAAWC,EAASC,CAAY,CAAC,CACnE"}
|
package/dist/sqlite.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.cjs","names":[],"sources":["../src/sqlite.ts"],"sourcesContent":["export function getConnectionLevelSqlitePragmas(): string {\n // cf. https://github.com/benbjohnson/litestream/issues/724#issue-3367254318\n // cf. https://github.com/benbjohnson/litestream/blob/9bd72348b7e7b1b3b8cf1e8befbee3b2c17444f7/.claude/agents/performance-optimizer.md?plain=1#L225-L232\n return 'PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000; PRAGMA cache_size = -16000; PRAGMA synchronous = NORMAL; PRAGMA wal_autocheckpoint = 10000;';\n}\n\nexport function getPersistentSqlitePragmas(): string {\n return 'PRAGMA journal_mode = WAL;';\n}\n\n/**\n * Escapes `%`, `_`, and `\\` so that `LIKE` does not read them as wildcards or escapes. SQLite's `LIKE` still matches\n * ASCII letters case-insensitively unless `PRAGMA case_sensitive_like = ON`; use `=` when case must match exactly.\n * The query must declare the escape character, e.g. `WHERE name LIKE ? ESCAPE '\\'` in SQL, which is `ESCAPE '\\\\'`\n * inside a JavaScript string literal.\n */\nexport function escapeLikePattern(text: string): string {\n return text.replaceAll(/[%\\\\_]/gu, String.raw`\\$&`);\n}\n"],"mappings":"aAAA,
|
|
1
|
+
{"version":3,"file":"sqlite.cjs","names":["getConnectionLevelSqlitePragmas","getPersistentSqlitePragmas","escapeLikePattern","text"],"sources":["../src/sqlite.ts"],"sourcesContent":["export function getConnectionLevelSqlitePragmas(): string {\n // cf. https://github.com/benbjohnson/litestream/issues/724#issue-3367254318\n // cf. https://github.com/benbjohnson/litestream/blob/9bd72348b7e7b1b3b8cf1e8befbee3b2c17444f7/.claude/agents/performance-optimizer.md?plain=1#L225-L232\n return 'PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000; PRAGMA cache_size = -16000; PRAGMA synchronous = NORMAL; PRAGMA wal_autocheckpoint = 10000;';\n}\n\nexport function getPersistentSqlitePragmas(): string {\n return 'PRAGMA journal_mode = WAL;';\n}\n\n/**\n * Escapes `%`, `_`, and `\\` so that `LIKE` does not read them as wildcards or escapes. SQLite's `LIKE` still matches\n * ASCII letters case-insensitively unless `PRAGMA case_sensitive_like = ON`; use `=` when case must match exactly.\n * The query must declare the escape character, e.g. `WHERE name LIKE ? ESCAPE '\\'` in SQL, which is `ESCAPE '\\\\'`\n * inside a JavaScript string literal.\n */\nexport function escapeLikePattern(text: string): string {\n return text.replaceAll(/[%\\\\_]/gu, String.raw`\\$&`);\n}\n"],"mappings":"aAAA,SAAgBA,GAA0C,CAGxD,MAAO,mJACT,CAEA,SAAgBC,GAAqC,CACnD,MAAO,4BACT,CAQA,SAAgBC,EAAkB,EAAsB,CACtD,OAAOC,EAAK,WAAW,WAAY,OAAO,GAAG,KAAK,CACpD"}
|
package/dist/sqlite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","names":[],"sources":["../src/sqlite.ts"],"sourcesContent":["export function getConnectionLevelSqlitePragmas(): string {\n // cf. https://github.com/benbjohnson/litestream/issues/724#issue-3367254318\n // cf. https://github.com/benbjohnson/litestream/blob/9bd72348b7e7b1b3b8cf1e8befbee3b2c17444f7/.claude/agents/performance-optimizer.md?plain=1#L225-L232\n return 'PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000; PRAGMA cache_size = -16000; PRAGMA synchronous = NORMAL; PRAGMA wal_autocheckpoint = 10000;';\n}\n\nexport function getPersistentSqlitePragmas(): string {\n return 'PRAGMA journal_mode = WAL;';\n}\n\n/**\n * Escapes `%`, `_`, and `\\` so that `LIKE` does not read them as wildcards or escapes. SQLite's `LIKE` still matches\n * ASCII letters case-insensitively unless `PRAGMA case_sensitive_like = ON`; use `=` when case must match exactly.\n * The query must declare the escape character, e.g. `WHERE name LIKE ? ESCAPE '\\'` in SQL, which is `ESCAPE '\\\\'`\n * inside a JavaScript string literal.\n */\nexport function escapeLikePattern(text: string): string {\n return text.replaceAll(/[%\\\\_]/gu, String.raw`\\$&`);\n}\n"],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"sqlite.js","names":["getConnectionLevelSqlitePragmas","getPersistentSqlitePragmas","escapeLikePattern","text"],"sources":["../src/sqlite.ts"],"sourcesContent":["export function getConnectionLevelSqlitePragmas(): string {\n // cf. https://github.com/benbjohnson/litestream/issues/724#issue-3367254318\n // cf. https://github.com/benbjohnson/litestream/blob/9bd72348b7e7b1b3b8cf1e8befbee3b2c17444f7/.claude/agents/performance-optimizer.md?plain=1#L225-L232\n return 'PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 5000; PRAGMA cache_size = -16000; PRAGMA synchronous = NORMAL; PRAGMA wal_autocheckpoint = 10000;';\n}\n\nexport function getPersistentSqlitePragmas(): string {\n return 'PRAGMA journal_mode = WAL;';\n}\n\n/**\n * Escapes `%`, `_`, and `\\` so that `LIKE` does not read them as wildcards or escapes. SQLite's `LIKE` still matches\n * ASCII letters case-insensitively unless `PRAGMA case_sensitive_like = ON`; use `=` when case must match exactly.\n * The query must declare the escape character, e.g. `WHERE name LIKE ? ESCAPE '\\'` in SQL, which is `ESCAPE '\\\\'`\n * inside a JavaScript string literal.\n */\nexport function escapeLikePattern(text: string): string {\n return text.replaceAll(/[%\\\\_]/gu, String.raw`\\$&`);\n}\n"],"mappings":"AAAA,SAAgBA,GAA0C,CAGxD,MAAO,mJACT,CAEA,SAAgBC,GAAqC,CACnD,MAAO,4BACT,CAQA,SAAgBC,EAAkB,EAAsB,CACtD,OAAOC,EAAK,WAAW,WAAY,OAAO,GAAG,KAAK,CACpD"}
|
package/dist/testingRules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testingRules.js","names":[],"sources":["../src/testingRules.ts"],"sourcesContent":["/**\n * When to write a test and what a test may assert, as markdown bullets for an agent's instructions.\n * Stated once here and rendered by the generated agent instructions and the testing skill so the\n * two cannot drift apart.\n */\nexport const TEST_WRITING_RULES = `- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.\n- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.\n- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.\n- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.\n- Avoid fixed waits in E2E tests; wait for conditions instead.`;\n"],"mappings":"AAKA,
|
|
1
|
+
{"version":3,"file":"testingRules.js","names":["TEST_WRITING_RULES"],"sources":["../src/testingRules.ts"],"sourcesContent":["/**\n * When to write a test and what a test may assert, as markdown bullets for an agent's instructions.\n * Stated once here and rendered by the generated agent instructions and the testing skill so the\n * two cannot drift apart.\n */\nexport const TEST_WRITING_RULES = `- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.\n- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.\n- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.\n- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.\n- Avoid fixed waits in E2E tests; wait for conditions instead.`;\n"],"mappings":"AAKA,MAAaA,EAAqB"}
|
package/dist/text.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.cjs","names":[],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n\n/**\n * Wraps text in a Markdown code block fenced with tildes, which are rarer than backticks in Markdown content.\n * The fence is longer than any run of tildes in the text so that the text cannot close it.\n */\nexport function toTildeCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('~', text, language);\n}\n\n/**\n * Wraps text in a Markdown code block fenced with backticks.\n * The fence is longer than any run of backticks in the text so that the text cannot close it.\n */\nexport function toCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('`', text, language);\n}\n\nfunction toFencedCodeBlock(fenceChar: string, text: string, language: string): string {\n const shortestFence = fenceChar.repeat(3);\n let longestRun = 2;\n let start = text.indexOf(shortestFence);\n while (start !== -1) {\n let end = start + 3;\n while (text[end] === fenceChar) end++;\n longestRun = Math.max(longestRun, end - start);\n start = text.indexOf(shortestFence, end);\n }\n let languageStart = 0;\n while (language[languageStart] === fenceChar) languageStart++;\n const fence = fenceChar.repeat(longestRun + 1 + languageStart);\n return `${fence}${language.slice(languageStart)}\\n${text}${text.endsWith('\\n') ? '' : '\\n'}${fence}`;\n}\n\n/**\n * Shortens text to at most `maxLength` UTF-16 code units, including the `ellipsis` that marks the cut.\n * Throws a `RangeError` when `maxLength` cannot hold the ellipsis.\n */\nexport function truncate(text: string, maxLength: number, ellipsis = '…'): string {\n if (text.length <= maxLength) return text;\n if (maxLength < ellipsis.length) {\n throw new RangeError(`maxLength (${maxLength}) must be at least the ellipsis length (${ellipsis.length})`);\n }\n return `${sliceWithoutSplittingSurrogates(text, maxLength - ellipsis.length)}${ellipsis}`;\n}\n\n/**\n * Returns the first `end` code units of `text`, one fewer when the last kept unit is a high surrogate, whose low half\n * is either cut off or absent from `text`, because an unpaired surrogate is replaced with U+FFFD by encoders.\n */\nexport function sliceWithoutSplittingSurrogates(text: string, end: number): string {\n // oxlint-disable-next-line unicorn/prefer-code-point -- the check is on a single UTF-16 code unit\n const lastKeptUnit = text.charCodeAt(end - 1);\n return text.slice(0, lastKeptUnit >= 0xD8_00 && lastKeptUnit <= 0xDB_FF ? end - 1 : end);\n}\n\nconst htmlEntities: Readonly<Record<string, string>> = {\n '\"': '"',\n '&': '&',\n \"'\": ''',\n '<': '<',\n '>': '>',\n};\n\nconst htmlSpecialCharactersPattern = /[\"&'<>]/gu;\n\n/** Escapes `&`, `<`, `>`, `\"`, and `'`, so the result is safe in HTML text and in quoted attribute values. */\nexport function escapeHtml(text: string): string {\n // Measured in V8 and JavaScriptCore: a native `search` first is faster than `replaceAll` alone for text without these\n // characters, and one native `replaceAll` beats a per-code-unit loop for text where they are rare.\n return text.search(htmlSpecialCharactersPattern) === -1\n ? text\n : text.replaceAll(htmlSpecialCharactersPattern, (character) => htmlEntities[character] as string);\n}\n"],"mappings":"aACA,
|
|
1
|
+
{"version":3,"file":"text.cjs","names":["escapeRegExp","text","quoteForShell","value","toTildeCodeBlock","toFencedCodeBlock","language","toCodeBlock","shortestFence","fenceChar","longestRun","start","end","languageStart","fence","truncate","maxLength","ellipsis","sliceWithoutSplittingSurrogates","lastKeptUnit","htmlEntities","htmlSpecialCharactersPattern","escapeHtml","character"],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n\n/**\n * Wraps text in a Markdown code block fenced with tildes, which are rarer than backticks in Markdown content.\n * The fence is longer than any run of tildes in the text so that the text cannot close it.\n */\nexport function toTildeCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('~', text, language);\n}\n\n/**\n * Wraps text in a Markdown code block fenced with backticks.\n * The fence is longer than any run of backticks in the text so that the text cannot close it.\n */\nexport function toCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('`', text, language);\n}\n\nfunction toFencedCodeBlock(fenceChar: string, text: string, language: string): string {\n const shortestFence = fenceChar.repeat(3);\n let longestRun = 2;\n let start = text.indexOf(shortestFence);\n while (start !== -1) {\n let end = start + 3;\n while (text[end] === fenceChar) end++;\n longestRun = Math.max(longestRun, end - start);\n start = text.indexOf(shortestFence, end);\n }\n let languageStart = 0;\n while (language[languageStart] === fenceChar) languageStart++;\n const fence = fenceChar.repeat(longestRun + 1 + languageStart);\n return `${fence}${language.slice(languageStart)}\\n${text}${text.endsWith('\\n') ? '' : '\\n'}${fence}`;\n}\n\n/**\n * Shortens text to at most `maxLength` UTF-16 code units, including the `ellipsis` that marks the cut.\n * Throws a `RangeError` when `maxLength` cannot hold the ellipsis.\n */\nexport function truncate(text: string, maxLength: number, ellipsis = '…'): string {\n if (text.length <= maxLength) return text;\n if (maxLength < ellipsis.length) {\n throw new RangeError(`maxLength (${maxLength}) must be at least the ellipsis length (${ellipsis.length})`);\n }\n return `${sliceWithoutSplittingSurrogates(text, maxLength - ellipsis.length)}${ellipsis}`;\n}\n\n/**\n * Returns the first `end` code units of `text`, one fewer when the last kept unit is a high surrogate, whose low half\n * is either cut off or absent from `text`, because an unpaired surrogate is replaced with U+FFFD by encoders.\n */\nexport function sliceWithoutSplittingSurrogates(text: string, end: number): string {\n // oxlint-disable-next-line unicorn/prefer-code-point -- the check is on a single UTF-16 code unit\n const lastKeptUnit = text.charCodeAt(end - 1);\n return text.slice(0, lastKeptUnit >= 0xD8_00 && lastKeptUnit <= 0xDB_FF ? end - 1 : end);\n}\n\nconst htmlEntities: Readonly<Record<string, string>> = {\n '\"': '"',\n '&': '&',\n \"'\": ''',\n '<': '<',\n '>': '>',\n};\n\nconst htmlSpecialCharactersPattern = /[\"&'<>]/gu;\n\n/** Escapes `&`, `<`, `>`, `\"`, and `'`, so the result is safe in HTML text and in quoted attribute values. */\nexport function escapeHtml(text: string): string {\n // Measured in V8 and JavaScriptCore: a native `search` first is faster than `replaceAll` alone for text without these\n // characters, and one native `replaceAll` beats a per-code-unit loop for text where they are rare.\n return text.search(htmlSpecialCharactersPattern) === -1\n ? text\n : text.replaceAll(htmlSpecialCharactersPattern, (character) => htmlEntities[character] as string);\n}\n"],"mappings":"aACA,SAAgBA,EAAa,EAAsB,CACjD,OAAOC,EAAK,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAChE,CAGA,SAAgBC,EAAc,EAAuB,CACnD,MAAO,cAAc,KAAKC,CAAK,EAAIA,EAAQ,IAAIA,EAAM,WAAW,IAAK,OAAO,GAAG,MAAM,EAAE,EACzF,CAMA,SAAgBC,EAAiB,EAAc,EAAW,GAAY,CACpE,OAAOC,EAAkB,IAAKJ,EAAMK,CAAQ,CAC9C,CAMA,SAAgBC,EAAY,EAAc,EAAW,GAAY,CAC/D,OAAOF,EAAkB,IAAKJ,EAAMK,CAAQ,CAC9C,CAEA,SAASD,EAAkB,EAAmB,EAAc,EAA0B,CACpF,IAAMG,EAAgBC,EAAU,OAAO,CAAC,EACpCC,EAAa,EACbC,EAAQV,EAAK,QAAQO,CAAa,EACtC,KAAOG,IAAU,IAAI,CACnB,IAAIC,EAAMD,EAAQ,EAClB,KAAOV,EAAKW,KAASH,GAAW,IAChC,EAAa,KAAK,IAAIC,EAAYE,EAAMD,CAAK,EAC7C,EAAQV,EAAK,QAAQO,EAAeI,CAAG,CACzC,CACA,IAAIC,EAAgB,EACpB,KAAOP,EAASO,KAAmBJ,GAAW,IAC9C,IAAMK,EAAQL,EAAU,OAAOC,EAAa,EAAIG,CAAa,EAC7D,MAAO,GAAGC,IAAQR,EAAS,MAAMO,CAAa,EAAE,IAAIZ,IAAOA,EAAK,SAAS;CAAI,EAAI,GAAK;IAAOa,GAC/F,CAMA,SAAgBC,EAAS,EAAc,EAAmB,EAAW,IAAa,CAChF,GAAId,EAAK,QAAUe,EAAW,OAAOf,EACrC,GAAIe,EAAYC,EAAS,OACvB,MAAU,WAAW,cAAcD,EAAU,0CAA0CC,EAAS,OAAO,EAAE,EAE3G,MAAO,GAAGC,EAAgCjB,EAAMe,EAAYC,EAAS,MAAM,IAAIA,GACjF,CAMA,SAAgBC,EAAgC,EAAc,EAAqB,CAEjF,IAAMC,EAAelB,EAAK,WAAWW,EAAM,CAAC,EAC5C,OAAOX,EAAK,MAAM,EAAGkB,GAAgB,OAAWA,GAAgB,MAAUP,EAAM,EAAIA,CAAG,CACzF,CAEA,MAAMQ,EAAiD,CACrD,IAAK,SACL,IAAK,QACL,IAAK,QACL,IAAK,OACL,IAAK,MACP,EAEMC,EAA+B,YAGrC,SAAgBC,EAAW,EAAsB,CAG/C,OAAOrB,EAAK,OAAOoB,CAA4B,IAAM,GACjDpB,EACAA,EAAK,WAAWoB,EAA+B,GAAcD,EAAaG,EAAoB,CACpG"}
|
package/dist/text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n\n/**\n * Wraps text in a Markdown code block fenced with tildes, which are rarer than backticks in Markdown content.\n * The fence is longer than any run of tildes in the text so that the text cannot close it.\n */\nexport function toTildeCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('~', text, language);\n}\n\n/**\n * Wraps text in a Markdown code block fenced with backticks.\n * The fence is longer than any run of backticks in the text so that the text cannot close it.\n */\nexport function toCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('`', text, language);\n}\n\nfunction toFencedCodeBlock(fenceChar: string, text: string, language: string): string {\n const shortestFence = fenceChar.repeat(3);\n let longestRun = 2;\n let start = text.indexOf(shortestFence);\n while (start !== -1) {\n let end = start + 3;\n while (text[end] === fenceChar) end++;\n longestRun = Math.max(longestRun, end - start);\n start = text.indexOf(shortestFence, end);\n }\n let languageStart = 0;\n while (language[languageStart] === fenceChar) languageStart++;\n const fence = fenceChar.repeat(longestRun + 1 + languageStart);\n return `${fence}${language.slice(languageStart)}\\n${text}${text.endsWith('\\n') ? '' : '\\n'}${fence}`;\n}\n\n/**\n * Shortens text to at most `maxLength` UTF-16 code units, including the `ellipsis` that marks the cut.\n * Throws a `RangeError` when `maxLength` cannot hold the ellipsis.\n */\nexport function truncate(text: string, maxLength: number, ellipsis = '…'): string {\n if (text.length <= maxLength) return text;\n if (maxLength < ellipsis.length) {\n throw new RangeError(`maxLength (${maxLength}) must be at least the ellipsis length (${ellipsis.length})`);\n }\n return `${sliceWithoutSplittingSurrogates(text, maxLength - ellipsis.length)}${ellipsis}`;\n}\n\n/**\n * Returns the first `end` code units of `text`, one fewer when the last kept unit is a high surrogate, whose low half\n * is either cut off or absent from `text`, because an unpaired surrogate is replaced with U+FFFD by encoders.\n */\nexport function sliceWithoutSplittingSurrogates(text: string, end: number): string {\n // oxlint-disable-next-line unicorn/prefer-code-point -- the check is on a single UTF-16 code unit\n const lastKeptUnit = text.charCodeAt(end - 1);\n return text.slice(0, lastKeptUnit >= 0xD8_00 && lastKeptUnit <= 0xDB_FF ? end - 1 : end);\n}\n\nconst htmlEntities: Readonly<Record<string, string>> = {\n '\"': '"',\n '&': '&',\n \"'\": ''',\n '<': '<',\n '>': '>',\n};\n\nconst htmlSpecialCharactersPattern = /[\"&'<>]/gu;\n\n/** Escapes `&`, `<`, `>`, `\"`, and `'`, so the result is safe in HTML text and in quoted attribute values. */\nexport function escapeHtml(text: string): string {\n // Measured in V8 and JavaScriptCore: a native `search` first is faster than `replaceAll` alone for text without these\n // characters, and one native `replaceAll` beats a per-code-unit loop for text where they are rare.\n return text.search(htmlSpecialCharactersPattern) === -1\n ? text\n : text.replaceAll(htmlSpecialCharactersPattern, (character) => htmlEntities[character] as string);\n}\n"],"mappings":"AACA,
|
|
1
|
+
{"version":3,"file":"text.js","names":["escapeRegExp","text","quoteForShell","value","toTildeCodeBlock","toFencedCodeBlock","language","toCodeBlock","shortestFence","fenceChar","longestRun","start","end","languageStart","fence","truncate","maxLength","ellipsis","sliceWithoutSplittingSurrogates","lastKeptUnit","htmlEntities","htmlSpecialCharactersPattern","escapeHtml","character"],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n\n/**\n * Wraps text in a Markdown code block fenced with tildes, which are rarer than backticks in Markdown content.\n * The fence is longer than any run of tildes in the text so that the text cannot close it.\n */\nexport function toTildeCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('~', text, language);\n}\n\n/**\n * Wraps text in a Markdown code block fenced with backticks.\n * The fence is longer than any run of backticks in the text so that the text cannot close it.\n */\nexport function toCodeBlock(text: string, language = ''): string {\n return toFencedCodeBlock('`', text, language);\n}\n\nfunction toFencedCodeBlock(fenceChar: string, text: string, language: string): string {\n const shortestFence = fenceChar.repeat(3);\n let longestRun = 2;\n let start = text.indexOf(shortestFence);\n while (start !== -1) {\n let end = start + 3;\n while (text[end] === fenceChar) end++;\n longestRun = Math.max(longestRun, end - start);\n start = text.indexOf(shortestFence, end);\n }\n let languageStart = 0;\n while (language[languageStart] === fenceChar) languageStart++;\n const fence = fenceChar.repeat(longestRun + 1 + languageStart);\n return `${fence}${language.slice(languageStart)}\\n${text}${text.endsWith('\\n') ? '' : '\\n'}${fence}`;\n}\n\n/**\n * Shortens text to at most `maxLength` UTF-16 code units, including the `ellipsis` that marks the cut.\n * Throws a `RangeError` when `maxLength` cannot hold the ellipsis.\n */\nexport function truncate(text: string, maxLength: number, ellipsis = '…'): string {\n if (text.length <= maxLength) return text;\n if (maxLength < ellipsis.length) {\n throw new RangeError(`maxLength (${maxLength}) must be at least the ellipsis length (${ellipsis.length})`);\n }\n return `${sliceWithoutSplittingSurrogates(text, maxLength - ellipsis.length)}${ellipsis}`;\n}\n\n/**\n * Returns the first `end` code units of `text`, one fewer when the last kept unit is a high surrogate, whose low half\n * is either cut off or absent from `text`, because an unpaired surrogate is replaced with U+FFFD by encoders.\n */\nexport function sliceWithoutSplittingSurrogates(text: string, end: number): string {\n // oxlint-disable-next-line unicorn/prefer-code-point -- the check is on a single UTF-16 code unit\n const lastKeptUnit = text.charCodeAt(end - 1);\n return text.slice(0, lastKeptUnit >= 0xD8_00 && lastKeptUnit <= 0xDB_FF ? end - 1 : end);\n}\n\nconst htmlEntities: Readonly<Record<string, string>> = {\n '\"': '"',\n '&': '&',\n \"'\": ''',\n '<': '<',\n '>': '>',\n};\n\nconst htmlSpecialCharactersPattern = /[\"&'<>]/gu;\n\n/** Escapes `&`, `<`, `>`, `\"`, and `'`, so the result is safe in HTML text and in quoted attribute values. */\nexport function escapeHtml(text: string): string {\n // Measured in V8 and JavaScriptCore: a native `search` first is faster than `replaceAll` alone for text without these\n // characters, and one native `replaceAll` beats a per-code-unit loop for text where they are rare.\n return text.search(htmlSpecialCharactersPattern) === -1\n ? text\n : text.replaceAll(htmlSpecialCharactersPattern, (character) => htmlEntities[character] as string);\n}\n"],"mappings":"AACA,SAAgBA,EAAa,EAAsB,CACjD,OAAOC,EAAK,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAChE,CAGA,SAAgBC,EAAc,EAAuB,CACnD,MAAO,cAAc,KAAKC,CAAK,EAAIA,EAAQ,IAAIA,EAAM,WAAW,IAAK,OAAO,GAAG,MAAM,EAAE,EACzF,CAMA,SAAgBC,EAAiB,EAAc,EAAW,GAAY,CACpE,OAAOC,EAAkB,IAAKJ,EAAMK,CAAQ,CAC9C,CAMA,SAAgBC,EAAY,EAAc,EAAW,GAAY,CAC/D,OAAOF,EAAkB,IAAKJ,EAAMK,CAAQ,CAC9C,CAEA,SAASD,EAAkB,EAAmB,EAAc,EAA0B,CACpF,IAAMG,EAAgBC,EAAU,OAAO,CAAC,EACpCC,EAAa,EACbC,EAAQV,EAAK,QAAQO,CAAa,EACtC,KAAOG,IAAU,IAAI,CACnB,IAAIC,EAAMD,EAAQ,EAClB,KAAOV,EAAKW,KAASH,GAAW,IAChC,EAAa,KAAK,IAAIC,EAAYE,EAAMD,CAAK,EAC7C,EAAQV,EAAK,QAAQO,EAAeI,CAAG,CACzC,CACA,IAAIC,EAAgB,EACpB,KAAOP,EAASO,KAAmBJ,GAAW,IAC9C,IAAMK,EAAQL,EAAU,OAAOC,EAAa,EAAIG,CAAa,EAC7D,MAAO,GAAGC,IAAQR,EAAS,MAAMO,CAAa,EAAE,IAAIZ,IAAOA,EAAK,SAAS;CAAI,EAAI,GAAK;IAAOa,GAC/F,CAMA,SAAgBC,EAAS,EAAc,EAAmB,EAAW,IAAa,CAChF,GAAId,EAAK,QAAUe,EAAW,OAAOf,EACrC,GAAIe,EAAYC,EAAS,OACvB,MAAU,WAAW,cAAcD,EAAU,0CAA0CC,EAAS,OAAO,EAAE,EAE3G,MAAO,GAAGC,EAAgCjB,EAAMe,EAAYC,EAAS,MAAM,IAAIA,GACjF,CAMA,SAAgBC,EAAgC,EAAc,EAAqB,CAEjF,IAAMC,EAAelB,EAAK,WAAWW,EAAM,CAAC,EAC5C,OAAOX,EAAK,MAAM,EAAGkB,GAAgB,OAAWA,GAAgB,MAAUP,EAAM,EAAIA,CAAG,CACzF,CAEA,MAAMQ,EAAiD,CACrD,IAAK,SACL,IAAK,QACL,IAAK,QACL,IAAK,OACL,IAAK,MACP,EAEMC,EAA+B,YAGrC,SAAgBC,EAAW,EAAsB,CAG/C,OAAOrB,EAAK,OAAOoB,CAA4B,IAAM,GACjDpB,EACAA,EAAK,WAAWoB,EAA+B,GAAcD,EAAaG,EAAoB,CACpG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttledFetch.cjs","names":["sleep"],"sources":["../src/throttledFetch.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n// `setTimeout` fires after 1 ms for longer delays, which would turn a long `Retry-After` hold into a busy loop.\nconst MAX_TIMER_MILLISECONDS = 2_147_483_647;\n\nexport interface ThrottledFetchOptions {\n /** The minimum interval between the starts of consecutive requests. */\n intervalMilliseconds: number;\n /** How long to hold later requests after a 429 response without `Retry-After` in delay seconds or IMF-fixdate. */\n rateLimitFallbackMilliseconds: number;\n}\n\n/**\n * Creates a `fetch` for a rate-limited API that starts requests in call order, at least `intervalMilliseconds` apart.\n * A 429 response holds every later request until its `Retry-After` (delay seconds or an IMF-fixdate) elapses, including\n * requests already waiting; the 429 response itself is returned to the caller, not retried. An abort signal takes effect\n * only once its request starts, not while it waits in the queue.\n */\nexport function createThrottledFetch({\n intervalMilliseconds,\n rateLimitFallbackMilliseconds,\n}: ThrottledFetchOptions): (input: string | URL | Request, init?: RequestInit) => Promise<Response> {\n let nextRequestAt = 0;\n let admission = Promise.resolve();\n\n return async (input, init) => {\n const previousAdmission = admission;\n const ready = (async () => {\n await previousAdmission;\n // A response to an earlier request can push `nextRequestAt` back while this request sleeps.\n while (nextRequestAt > performance.now()) {\n await sleep(Math.min(nextRequestAt - performance.now(), MAX_TIMER_MILLISECONDS));\n }\n nextRequestAt = performance.now() + intervalMilliseconds;\n })();\n admission = ready;\n await ready;\n\n const response = await fetch(input, init);\n if (response.status === 429) {\n const waitMilliseconds = parseRetryAfterMilliseconds(response.headers.get('retry-after'));\n nextRequestAt = Math.max(nextRequestAt, performance.now() + (waitMilliseconds ?? rateLimitFallbackMilliseconds));\n }\n return response;\n };\n}\n\n// RFC 9110 requires senders to generate HTTP dates in this IMF-fixdate form, e.g. `Sun, 06 Nov 1994 08:49:37 GMT`.\n// `Date.parse` alone would also accept malformed values such as `1.5`.\nconst IMF_FIXDATE = /^[A-Z][a-z]{2}, \\d{2} [A-Z][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/u;\n\n/** Parses `Retry-After` in delay seconds or IMF-fixdate; the obsolete RFC 850 and asctime dates yield `undefined`. */\nfunction parseRetryAfterMilliseconds(value: string | null): number | undefined {\n const trimmed = value?.trim() ?? '';\n const milliseconds = /^\\d+$/u.test(trimmed)\n ? Number(trimmed) * 1000\n : IMF_FIXDATE.test(trimmed)\n ? Date.parse(trimmed) - Date.now()\n : Number.NaN;\n return Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : undefined;\n}\n"],"mappings":"4CAkBA,
|
|
1
|
+
{"version":3,"file":"throttledFetch.cjs","names":["sleep","require_sleep","createThrottledFetch","nextRequestAt","admission","previousAdmission","ready","intervalMilliseconds","response","input","init","waitMilliseconds","parseRetryAfterMilliseconds","rateLimitFallbackMilliseconds","IMF_FIXDATE","trimmed","value","milliseconds"],"sources":["../src/throttledFetch.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n// `setTimeout` fires after 1 ms for longer delays, which would turn a long `Retry-After` hold into a busy loop.\nconst MAX_TIMER_MILLISECONDS = 2_147_483_647;\n\nexport interface ThrottledFetchOptions {\n /** The minimum interval between the starts of consecutive requests. */\n intervalMilliseconds: number;\n /** How long to hold later requests after a 429 response without `Retry-After` in delay seconds or IMF-fixdate. */\n rateLimitFallbackMilliseconds: number;\n}\n\n/**\n * Creates a `fetch` for a rate-limited API that starts requests in call order, at least `intervalMilliseconds` apart.\n * A 429 response holds every later request until its `Retry-After` (delay seconds or an IMF-fixdate) elapses, including\n * requests already waiting; the 429 response itself is returned to the caller, not retried. An abort signal takes effect\n * only once its request starts, not while it waits in the queue.\n */\nexport function createThrottledFetch({\n intervalMilliseconds,\n rateLimitFallbackMilliseconds,\n}: ThrottledFetchOptions): (input: string | URL | Request, init?: RequestInit) => Promise<Response> {\n let nextRequestAt = 0;\n let admission = Promise.resolve();\n\n return async (input, init) => {\n const previousAdmission = admission;\n const ready = (async () => {\n await previousAdmission;\n // A response to an earlier request can push `nextRequestAt` back while this request sleeps.\n while (nextRequestAt > performance.now()) {\n await sleep(Math.min(nextRequestAt - performance.now(), MAX_TIMER_MILLISECONDS));\n }\n nextRequestAt = performance.now() + intervalMilliseconds;\n })();\n admission = ready;\n await ready;\n\n const response = await fetch(input, init);\n if (response.status === 429) {\n const waitMilliseconds = parseRetryAfterMilliseconds(response.headers.get('retry-after'));\n nextRequestAt = Math.max(nextRequestAt, performance.now() + (waitMilliseconds ?? rateLimitFallbackMilliseconds));\n }\n return response;\n };\n}\n\n// RFC 9110 requires senders to generate HTTP dates in this IMF-fixdate form, e.g. `Sun, 06 Nov 1994 08:49:37 GMT`.\n// `Date.parse` alone would also accept malformed values such as `1.5`.\nconst IMF_FIXDATE = /^[A-Z][a-z]{2}, \\d{2} [A-Z][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/u;\n\n/** Parses `Retry-After` in delay seconds or IMF-fixdate; the obsolete RFC 850 and asctime dates yield `undefined`. */\nfunction parseRetryAfterMilliseconds(value: string | null): number | undefined {\n const trimmed = value?.trim() ?? '';\n const milliseconds = /^\\d+$/u.test(trimmed)\n ? Number(trimmed) * 1000\n : IMF_FIXDATE.test(trimmed)\n ? Date.parse(trimmed) - Date.now()\n : Number.NaN;\n return Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : undefined;\n}\n"],"mappings":"4CAkBA,SAAgBE,EAAqB,CACnC,uBACA,iCACkG,CAClG,IAAIC,EAAgB,EAChBC,EAAY,QAAQ,QAAQ,EAEhC,OAAO,MAAO,EAAO,IAAS,CAC5B,IAAMC,EAAoBD,EACpBE,GAAS,SAAY,CAGzB,IAFA,MAAMD,EAECF,EAAgB,YAAY,IAAI,GACrC,MAAMH,EAAAA,MAAM,KAAK,IAAIG,EAAgB,YAAY,IAAI,EAAG,UAAsB,CAAC,EAEjF,EAAgB,YAAY,IAAI,EAAII,CACtC,EAAA,CAAG,EACH,EAAYD,EACZ,MAAMA,EAEN,IAAME,EAAW,MAAM,MAAMC,EAAOC,CAAI,EACxC,GAAIF,EAAS,SAAW,IAAK,CAC3B,IAAMG,EAAmBC,EAA4BJ,EAAS,QAAQ,IAAI,aAAa,CAAC,EACxF,EAAgB,KAAK,IAAIL,EAAe,YAAY,IAAI,GAAKQ,GAAoBE,EAA8B,CACjH,CACA,OAAOL,CACT,CACF,CAIA,MAAMM,EAAc,oEAGpB,SAASF,EAA4B,EAA0C,CAC7E,IAAMG,EAAUC,GAAO,KAAK,GAAK,GAC3BC,EAAe,SAAS,KAAKF,CAAO,EACtC,OAAOA,CAAO,EAAI,IAClBD,EAAY,KAAKC,CAAO,EACtB,KAAK,MAAMA,CAAO,EAAI,KAAK,IAAI,EAC/B,IACN,OAAO,OAAO,SAASE,CAAY,EAAI,KAAK,IAAI,EAAGA,CAAY,EAAI,IAAA,EACrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttledFetch.js","names":[],"sources":["../src/throttledFetch.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n// `setTimeout` fires after 1 ms for longer delays, which would turn a long `Retry-After` hold into a busy loop.\nconst MAX_TIMER_MILLISECONDS = 2_147_483_647;\n\nexport interface ThrottledFetchOptions {\n /** The minimum interval between the starts of consecutive requests. */\n intervalMilliseconds: number;\n /** How long to hold later requests after a 429 response without `Retry-After` in delay seconds or IMF-fixdate. */\n rateLimitFallbackMilliseconds: number;\n}\n\n/**\n * Creates a `fetch` for a rate-limited API that starts requests in call order, at least `intervalMilliseconds` apart.\n * A 429 response holds every later request until its `Retry-After` (delay seconds or an IMF-fixdate) elapses, including\n * requests already waiting; the 429 response itself is returned to the caller, not retried. An abort signal takes effect\n * only once its request starts, not while it waits in the queue.\n */\nexport function createThrottledFetch({\n intervalMilliseconds,\n rateLimitFallbackMilliseconds,\n}: ThrottledFetchOptions): (input: string | URL | Request, init?: RequestInit) => Promise<Response> {\n let nextRequestAt = 0;\n let admission = Promise.resolve();\n\n return async (input, init) => {\n const previousAdmission = admission;\n const ready = (async () => {\n await previousAdmission;\n // A response to an earlier request can push `nextRequestAt` back while this request sleeps.\n while (nextRequestAt > performance.now()) {\n await sleep(Math.min(nextRequestAt - performance.now(), MAX_TIMER_MILLISECONDS));\n }\n nextRequestAt = performance.now() + intervalMilliseconds;\n })();\n admission = ready;\n await ready;\n\n const response = await fetch(input, init);\n if (response.status === 429) {\n const waitMilliseconds = parseRetryAfterMilliseconds(response.headers.get('retry-after'));\n nextRequestAt = Math.max(nextRequestAt, performance.now() + (waitMilliseconds ?? rateLimitFallbackMilliseconds));\n }\n return response;\n };\n}\n\n// RFC 9110 requires senders to generate HTTP dates in this IMF-fixdate form, e.g. `Sun, 06 Nov 1994 08:49:37 GMT`.\n// `Date.parse` alone would also accept malformed values such as `1.5`.\nconst IMF_FIXDATE = /^[A-Z][a-z]{2}, \\d{2} [A-Z][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/u;\n\n/** Parses `Retry-After` in delay seconds or IMF-fixdate; the obsolete RFC 850 and asctime dates yield `undefined`. */\nfunction parseRetryAfterMilliseconds(value: string | null): number | undefined {\n const trimmed = value?.trim() ?? '';\n const milliseconds = /^\\d+$/u.test(trimmed)\n ? Number(trimmed) * 1000\n : IMF_FIXDATE.test(trimmed)\n ? Date.parse(trimmed) - Date.now()\n : Number.NaN;\n return Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : undefined;\n}\n"],"mappings":"mCAkBA,
|
|
1
|
+
{"version":3,"file":"throttledFetch.js","names":["createThrottledFetch","nextRequestAt","admission","previousAdmission","ready","sleep","intervalMilliseconds","response","input","init","waitMilliseconds","parseRetryAfterMilliseconds","rateLimitFallbackMilliseconds","IMF_FIXDATE","trimmed","value","milliseconds"],"sources":["../src/throttledFetch.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n// `setTimeout` fires after 1 ms for longer delays, which would turn a long `Retry-After` hold into a busy loop.\nconst MAX_TIMER_MILLISECONDS = 2_147_483_647;\n\nexport interface ThrottledFetchOptions {\n /** The minimum interval between the starts of consecutive requests. */\n intervalMilliseconds: number;\n /** How long to hold later requests after a 429 response without `Retry-After` in delay seconds or IMF-fixdate. */\n rateLimitFallbackMilliseconds: number;\n}\n\n/**\n * Creates a `fetch` for a rate-limited API that starts requests in call order, at least `intervalMilliseconds` apart.\n * A 429 response holds every later request until its `Retry-After` (delay seconds or an IMF-fixdate) elapses, including\n * requests already waiting; the 429 response itself is returned to the caller, not retried. An abort signal takes effect\n * only once its request starts, not while it waits in the queue.\n */\nexport function createThrottledFetch({\n intervalMilliseconds,\n rateLimitFallbackMilliseconds,\n}: ThrottledFetchOptions): (input: string | URL | Request, init?: RequestInit) => Promise<Response> {\n let nextRequestAt = 0;\n let admission = Promise.resolve();\n\n return async (input, init) => {\n const previousAdmission = admission;\n const ready = (async () => {\n await previousAdmission;\n // A response to an earlier request can push `nextRequestAt` back while this request sleeps.\n while (nextRequestAt > performance.now()) {\n await sleep(Math.min(nextRequestAt - performance.now(), MAX_TIMER_MILLISECONDS));\n }\n nextRequestAt = performance.now() + intervalMilliseconds;\n })();\n admission = ready;\n await ready;\n\n const response = await fetch(input, init);\n if (response.status === 429) {\n const waitMilliseconds = parseRetryAfterMilliseconds(response.headers.get('retry-after'));\n nextRequestAt = Math.max(nextRequestAt, performance.now() + (waitMilliseconds ?? rateLimitFallbackMilliseconds));\n }\n return response;\n };\n}\n\n// RFC 9110 requires senders to generate HTTP dates in this IMF-fixdate form, e.g. `Sun, 06 Nov 1994 08:49:37 GMT`.\n// `Date.parse` alone would also accept malformed values such as `1.5`.\nconst IMF_FIXDATE = /^[A-Z][a-z]{2}, \\d{2} [A-Z][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/u;\n\n/** Parses `Retry-After` in delay seconds or IMF-fixdate; the obsolete RFC 850 and asctime dates yield `undefined`. */\nfunction parseRetryAfterMilliseconds(value: string | null): number | undefined {\n const trimmed = value?.trim() ?? '';\n const milliseconds = /^\\d+$/u.test(trimmed)\n ? Number(trimmed) * 1000\n : IMF_FIXDATE.test(trimmed)\n ? Date.parse(trimmed) - Date.now()\n : Number.NaN;\n return Number.isFinite(milliseconds) ? Math.max(0, milliseconds) : undefined;\n}\n"],"mappings":"mCAkBA,SAAgBA,EAAqB,CACnC,uBACA,iCACkG,CAClG,IAAIC,EAAgB,EAChBC,EAAY,QAAQ,QAAQ,EAEhC,OAAO,MAAO,EAAO,IAAS,CAC5B,IAAMC,EAAoBD,EACpBE,GAAS,SAAY,CAGzB,IAFA,MAAMD,EAECF,EAAgB,YAAY,IAAI,GACrC,MAAMI,EAAM,KAAK,IAAIJ,EAAgB,YAAY,IAAI,EAAG,UAAsB,CAAC,EAEjF,EAAgB,YAAY,IAAI,EAAIK,CACtC,EAAA,CAAG,EACH,EAAYF,EACZ,MAAMA,EAEN,IAAMG,EAAW,MAAM,MAAMC,EAAOC,CAAI,EACxC,GAAIF,EAAS,SAAW,IAAK,CAC3B,IAAMG,EAAmBC,EAA4BJ,EAAS,QAAQ,IAAI,aAAa,CAAC,EACxF,EAAgB,KAAK,IAAIN,EAAe,YAAY,IAAI,GAAKS,GAAoBE,EAA8B,CACjH,CACA,OAAOL,CACT,CACF,CAIA,MAAMM,EAAc,oEAGpB,SAASF,EAA4B,EAA0C,CAC7E,IAAMG,EAAUC,GAAO,KAAK,GAAK,GAC3BC,EAAe,SAAS,KAAKF,CAAO,EACtC,OAAOA,CAAO,EAAI,IAClBD,EAAY,KAAKC,CAAO,EACtB,KAAK,MAAMA,CAAO,EAAI,KAAK,IAAI,EAC/B,IACN,OAAO,OAAO,SAASE,CAAY,EAAI,KAAK,IAAI,EAAGA,CAAY,EAAI,IAAA,EACrE"}
|
package/dist/timeout.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.cjs","names":[],"sources":["../src/timeout.ts"],"sourcesContent":["export type RaceWithTimeoutResult<T> = { timedOut: false; value: T } | { timedOut: true };\n\n/**\n * Waits for `promise` for at most `timeoutMilliseconds`. A rejection of `promise` within the limit propagates.\n * The timer is cleared as soon as either side settles, so it never keeps a process alive after the race.\n * `promise` itself is not canceled on timeout; pass an `AbortSignal` to the underlying work for that.\n */\nexport async function raceWithTimeout<T>(\n promise: Promise<T>,\n timeoutMilliseconds: number\n): Promise<RaceWithTimeoutResult<T>> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise.then((value) => ({ timedOut: false as const, value })),\n new Promise<{ timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ timedOut: true }), timeoutMilliseconds);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"aAOA,
|
|
1
|
+
{"version":3,"file":"timeout.cjs","names":["raceWithTimeout","timer","promise","resolve","timeoutMilliseconds"],"sources":["../src/timeout.ts"],"sourcesContent":["export type RaceWithTimeoutResult<T> = { timedOut: false; value: T } | { timedOut: true };\n\n/**\n * Waits for `promise` for at most `timeoutMilliseconds`. A rejection of `promise` within the limit propagates.\n * The timer is cleared as soon as either side settles, so it never keeps a process alive after the race.\n * `promise` itself is not canceled on timeout; pass an `AbortSignal` to the underlying work for that.\n */\nexport async function raceWithTimeout<T>(\n promise: Promise<T>,\n timeoutMilliseconds: number\n): Promise<RaceWithTimeoutResult<T>> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise.then((value) => ({ timedOut: false as const, value })),\n new Promise<{ timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ timedOut: true }), timeoutMilliseconds);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"aAOA,eAAsBA,EACpB,EACA,EACmC,CACnC,IAAIC,EACJ,GAAI,CACF,OAAO,MAAM,QAAQ,KAAK,CACxBC,EAAQ,KAAM,IAAW,CAAE,SAAU,GAAgB,OAAM,EAAE,EAC7D,IAAI,QAA6B,GAAY,CAC3C,EAAQ,eAAiBC,EAAQ,CAAE,SAAU,EAAK,CAAC,EAAGC,CAAmB,CAC3E,CAAC,CACH,CAAC,CACH,QAAU,CACR,aAAaH,CAAK,CACpB,CACF"}
|
package/dist/timeout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.js","names":[],"sources":["../src/timeout.ts"],"sourcesContent":["export type RaceWithTimeoutResult<T> = { timedOut: false; value: T } | { timedOut: true };\n\n/**\n * Waits for `promise` for at most `timeoutMilliseconds`. A rejection of `promise` within the limit propagates.\n * The timer is cleared as soon as either side settles, so it never keeps a process alive after the race.\n * `promise` itself is not canceled on timeout; pass an `AbortSignal` to the underlying work for that.\n */\nexport async function raceWithTimeout<T>(\n promise: Promise<T>,\n timeoutMilliseconds: number\n): Promise<RaceWithTimeoutResult<T>> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise.then((value) => ({ timedOut: false as const, value })),\n new Promise<{ timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ timedOut: true }), timeoutMilliseconds);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"AAOA,
|
|
1
|
+
{"version":3,"file":"timeout.js","names":["raceWithTimeout","timer","promise","resolve","timeoutMilliseconds"],"sources":["../src/timeout.ts"],"sourcesContent":["export type RaceWithTimeoutResult<T> = { timedOut: false; value: T } | { timedOut: true };\n\n/**\n * Waits for `promise` for at most `timeoutMilliseconds`. A rejection of `promise` within the limit propagates.\n * The timer is cleared as soon as either side settles, so it never keeps a process alive after the race.\n * `promise` itself is not canceled on timeout; pass an `AbortSignal` to the underlying work for that.\n */\nexport async function raceWithTimeout<T>(\n promise: Promise<T>,\n timeoutMilliseconds: number\n): Promise<RaceWithTimeoutResult<T>> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise.then((value) => ({ timedOut: false as const, value })),\n new Promise<{ timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ timedOut: true }), timeoutMilliseconds);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"AAOA,eAAsBA,EACpB,EACA,EACmC,CACnC,IAAIC,EACJ,GAAI,CACF,OAAO,MAAM,QAAQ,KAAK,CACxBC,EAAQ,KAAM,IAAW,CAAE,SAAU,GAAgB,OAAM,EAAE,EAC7D,IAAI,QAA6B,GAAY,CAC3C,EAAQ,eAAiBC,EAAQ,CAAE,SAAU,EAAK,CAAC,EAAGC,CAAmB,CAC3E,CAAC,CACH,CAAC,CACH,QAAU,CACR,aAAaH,CAAK,CACpB,CACF"}
|
package/dist/url.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.cjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["export interface SafeRedirectPathOptions {\n /** The app's own origin, e.g. `https://example.com`; an unparsable origin throws a `TypeError`. */\n origin: string;\n /** Returned when `value` does not point to a page on `origin`. */\n fallback?: string;\n}\n\n/**\n * Returns the path, query, and fragment of `value` when it points to a page on the app's own origin, and `fallback`\n * (`/` by default) otherwise, so that redirecting to a user-supplied callback URL cannot lead to another site.\n * `value` is resolved against `origin` the way browsers resolve links, so relative paths and absolute URLs on\n * `origin` are accepted, while `//evil.example`, `/\\evil.example`, and `/\\t/evil.example` are rejected. For an array,\n * such as a repeated query parameter, the first element is used.\n */\nexport function getSafeRedirectPath(\n value: string | readonly string[] | null | undefined,\n { origin, fallback = '/' }: SafeRedirectPathOptions\n): string {\n // Parsed outside the per-value `try` so that a misconfigured origin fails loudly instead of rejecting every value.\n const baseUrl = new URL(origin);\n const rawValue = (typeof value === 'string' ? value : value?.[0])?.trim();\n if (!rawValue) return fallback;\n\n let url: URL;\n try {\n url = new URL(rawValue, baseUrl);\n } catch {\n return fallback;\n }\n // A `blob:` URL shares its inner URL's origin but has that URL as its pathname, hence the protocol check.\n // Dot segments can leave a pathname such as `//evil.example`, which is protocol-relative once returned as a path.\n if (url.protocol !== baseUrl.protocol || url.origin !== baseUrl.origin || url.pathname.startsWith('//')) {\n return fallback;\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n"],"mappings":"aAcA,
|
|
1
|
+
{"version":3,"file":"url.cjs","names":["getSafeRedirectPath","baseUrl","origin","rawValue","value","fallback","url"],"sources":["../src/url.ts"],"sourcesContent":["export interface SafeRedirectPathOptions {\n /** The app's own origin, e.g. `https://example.com`; an unparsable origin throws a `TypeError`. */\n origin: string;\n /** Returned when `value` does not point to a page on `origin`. */\n fallback?: string;\n}\n\n/**\n * Returns the path, query, and fragment of `value` when it points to a page on the app's own origin, and `fallback`\n * (`/` by default) otherwise, so that redirecting to a user-supplied callback URL cannot lead to another site.\n * `value` is resolved against `origin` the way browsers resolve links, so relative paths and absolute URLs on\n * `origin` are accepted, while `//evil.example`, `/\\evil.example`, and `/\\t/evil.example` are rejected. For an array,\n * such as a repeated query parameter, the first element is used.\n */\nexport function getSafeRedirectPath(\n value: string | readonly string[] | null | undefined,\n { origin, fallback = '/' }: SafeRedirectPathOptions\n): string {\n // Parsed outside the per-value `try` so that a misconfigured origin fails loudly instead of rejecting every value.\n const baseUrl = new URL(origin);\n const rawValue = (typeof value === 'string' ? value : value?.[0])?.trim();\n if (!rawValue) return fallback;\n\n let url: URL;\n try {\n url = new URL(rawValue, baseUrl);\n } catch {\n return fallback;\n }\n // A `blob:` URL shares its inner URL's origin but has that URL as its pathname, hence the protocol check.\n // Dot segments can leave a pathname such as `//evil.example`, which is protocol-relative once returned as a path.\n if (url.protocol !== baseUrl.protocol || url.origin !== baseUrl.origin || url.pathname.startsWith('//')) {\n return fallback;\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n"],"mappings":"aAcA,SAAgBA,EACd,EACA,CAAE,SAAQ,WAAW,KACb,CAER,IAAMC,EAAU,IAAI,IAAIC,CAAM,EACxBC,GAAY,OAAOC,GAAU,SAAWA,EAAQA,IAAQ,GAAA,EAAK,KAAK,EACxE,GAAI,CAACD,EAAU,OAAOE,EAEtB,IAAIC,EACJ,GAAI,CACF,EAAM,IAAI,IAAIH,EAAUF,CAAO,CACjC,MAAQ,CACN,OAAOI,CACT,CAMA,OAHIC,EAAI,WAAaL,EAAQ,UAAYK,EAAI,SAAWL,EAAQ,QAAUK,EAAI,SAAS,WAAW,IAAI,EAC7FD,EAEF,GAAGC,EAAI,WAAWA,EAAI,SAASA,EAAI,MAC5C"}
|
package/dist/url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["export interface SafeRedirectPathOptions {\n /** The app's own origin, e.g. `https://example.com`; an unparsable origin throws a `TypeError`. */\n origin: string;\n /** Returned when `value` does not point to a page on `origin`. */\n fallback?: string;\n}\n\n/**\n * Returns the path, query, and fragment of `value` when it points to a page on the app's own origin, and `fallback`\n * (`/` by default) otherwise, so that redirecting to a user-supplied callback URL cannot lead to another site.\n * `value` is resolved against `origin` the way browsers resolve links, so relative paths and absolute URLs on\n * `origin` are accepted, while `//evil.example`, `/\\evil.example`, and `/\\t/evil.example` are rejected. For an array,\n * such as a repeated query parameter, the first element is used.\n */\nexport function getSafeRedirectPath(\n value: string | readonly string[] | null | undefined,\n { origin, fallback = '/' }: SafeRedirectPathOptions\n): string {\n // Parsed outside the per-value `try` so that a misconfigured origin fails loudly instead of rejecting every value.\n const baseUrl = new URL(origin);\n const rawValue = (typeof value === 'string' ? value : value?.[0])?.trim();\n if (!rawValue) return fallback;\n\n let url: URL;\n try {\n url = new URL(rawValue, baseUrl);\n } catch {\n return fallback;\n }\n // A `blob:` URL shares its inner URL's origin but has that URL as its pathname, hence the protocol check.\n // Dot segments can leave a pathname such as `//evil.example`, which is protocol-relative once returned as a path.\n if (url.protocol !== baseUrl.protocol || url.origin !== baseUrl.origin || url.pathname.startsWith('//')) {\n return fallback;\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n"],"mappings":"AAcA,
|
|
1
|
+
{"version":3,"file":"url.js","names":["getSafeRedirectPath","baseUrl","origin","rawValue","value","fallback","url"],"sources":["../src/url.ts"],"sourcesContent":["export interface SafeRedirectPathOptions {\n /** The app's own origin, e.g. `https://example.com`; an unparsable origin throws a `TypeError`. */\n origin: string;\n /** Returned when `value` does not point to a page on `origin`. */\n fallback?: string;\n}\n\n/**\n * Returns the path, query, and fragment of `value` when it points to a page on the app's own origin, and `fallback`\n * (`/` by default) otherwise, so that redirecting to a user-supplied callback URL cannot lead to another site.\n * `value` is resolved against `origin` the way browsers resolve links, so relative paths and absolute URLs on\n * `origin` are accepted, while `//evil.example`, `/\\evil.example`, and `/\\t/evil.example` are rejected. For an array,\n * such as a repeated query parameter, the first element is used.\n */\nexport function getSafeRedirectPath(\n value: string | readonly string[] | null | undefined,\n { origin, fallback = '/' }: SafeRedirectPathOptions\n): string {\n // Parsed outside the per-value `try` so that a misconfigured origin fails loudly instead of rejecting every value.\n const baseUrl = new URL(origin);\n const rawValue = (typeof value === 'string' ? value : value?.[0])?.trim();\n if (!rawValue) return fallback;\n\n let url: URL;\n try {\n url = new URL(rawValue, baseUrl);\n } catch {\n return fallback;\n }\n // A `blob:` URL shares its inner URL's origin but has that URL as its pathname, hence the protocol check.\n // Dot segments can leave a pathname such as `//evil.example`, which is protocol-relative once returned as a path.\n if (url.protocol !== baseUrl.protocol || url.origin !== baseUrl.origin || url.pathname.startsWith('//')) {\n return fallback;\n }\n return `${url.pathname}${url.search}${url.hash}`;\n}\n"],"mappings":"AAcA,SAAgBA,EACd,EACA,CAAE,SAAQ,WAAW,KACb,CAER,IAAMC,EAAU,IAAI,IAAIC,CAAM,EACxBC,GAAY,OAAOC,GAAU,SAAWA,EAAQA,IAAQ,GAAA,EAAK,KAAK,EACxE,GAAI,CAACD,EAAU,OAAOE,EAEtB,IAAIC,EACJ,GAAI,CACF,EAAM,IAAI,IAAIH,EAAUF,CAAO,CACjC,MAAQ,CACN,OAAOI,CACT,CAMA,OAHIC,EAAI,WAAaL,EAAQ,UAAYK,EAAI,SAAWL,EAAQ,QAAUK,EAAI,SAAS,WAAW,IAAI,EAC7FD,EAEF,GAAGC,EAAI,WAAWA,EAAI,SAASA,EAAI,MAC5C"}
|
package/dist/yaml.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml.cjs","names":[],"sources":["../src/yaml.ts"],"sourcesContent":["/**\n * Options for `stringify` of the `yaml` package that keep multiline strings readable: `blockQuote: 'literal'` writes\n * them as `key: |` blocks, and `lineWidth: 0` disables line wrapping.\n */\nexport const yamlStringifyOptions = { blockQuote: 'literal', lineWidth: 0 } as const;\n"],"mappings":"aAIA,
|
|
1
|
+
{"version":3,"file":"yaml.cjs","names":["yamlStringifyOptions"],"sources":["../src/yaml.ts"],"sourcesContent":["/**\n * Options for `stringify` of the `yaml` package that keep multiline strings readable: `blockQuote: 'literal'` writes\n * them as `key: |` blocks, and `lineWidth: 0` disables line wrapping.\n */\nexport const yamlStringifyOptions = { blockQuote: 'literal', lineWidth: 0 } as const;\n"],"mappings":"aAIA,MAAaA,EAAuB,CAAE,WAAY,UAAW,UAAW,CAAE"}
|
package/dist/yaml.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml.js","names":[],"sources":["../src/yaml.ts"],"sourcesContent":["/**\n * Options for `stringify` of the `yaml` package that keep multiline strings readable: `blockQuote: 'literal'` writes\n * them as `key: |` blocks, and `lineWidth: 0` disables line wrapping.\n */\nexport const yamlStringifyOptions = { blockQuote: 'literal', lineWidth: 0 } as const;\n"],"mappings":"AAIA,
|
|
1
|
+
{"version":3,"file":"yaml.js","names":["yamlStringifyOptions"],"sources":["../src/yaml.ts"],"sourcesContent":["/**\n * Options for `stringify` of the `yaml` package that keep multiline strings readable: `blockQuote: 'literal'` writes\n * them as `key: |` blocks, and `lineWidth: 0` disables line wrapping.\n */\nexport const yamlStringifyOptions = { blockQuote: 'literal', lineWidth: 0 } as const;\n"],"mappings":"AAIA,MAAaA,EAAuB,CAAE,WAAY,UAAW,UAAW,CAAE"}
|
package/dist/zenkaku.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zenkaku.cjs","names":[],"sources":["../src/zenkaku.ts"],"sourcesContent":["export function zenkakuAlphanumericalsToHankaku(str: string): string {\n return str.replaceAll(/[0-9A-Za-z]/g, (s: string) => {\n return String.fromCodePoint((s.codePointAt(0) ?? 0) - 0xFE_E0);\n });\n}\n"],"mappings":"aAAA,
|
|
1
|
+
{"version":3,"file":"zenkaku.cjs","names":["zenkakuAlphanumericalsToHankaku","str","s"],"sources":["../src/zenkaku.ts"],"sourcesContent":["export function zenkakuAlphanumericalsToHankaku(str: string): string {\n return str.replaceAll(/[0-9A-Za-z]/g, (s: string) => {\n return String.fromCodePoint((s.codePointAt(0) ?? 0) - 0xFE_E0);\n });\n}\n"],"mappings":"aAAA,SAAgBA,EAAgC,EAAqB,CACnE,OAAOC,EAAI,WAAW,eAAiB,GAC9B,OAAO,eAAeC,EAAE,YAAY,CAAC,GAAK,GAAK,KAAO,CAC9D,CACH"}
|
package/dist/zenkaku.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zenkaku.js","names":[],"sources":["../src/zenkaku.ts"],"sourcesContent":["export function zenkakuAlphanumericalsToHankaku(str: string): string {\n return str.replaceAll(/[0-9A-Za-z]/g, (s: string) => {\n return String.fromCodePoint((s.codePointAt(0) ?? 0) - 0xFE_E0);\n });\n}\n"],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"zenkaku.js","names":["zenkakuAlphanumericalsToHankaku","str","s"],"sources":["../src/zenkaku.ts"],"sourcesContent":["export function zenkakuAlphanumericalsToHankaku(str: string): string {\n return str.replaceAll(/[0-9A-Za-z]/g, (s: string) => {\n return String.fromCodePoint((s.codePointAt(0) ?? 0) - 0xFE_E0);\n });\n}\n"],"mappings":"AAAA,SAAgBA,EAAgC,EAAqB,CACnE,OAAOC,EAAI,WAAW,eAAiB,GAC9B,OAAO,eAAeC,EAAE,YAAY,CAAC,GAAK,GAAK,KAAO,CAC9D,CACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willbooster/shared-lib",
|
|
3
|
-
"version": "10.19.
|
|
3
|
+
"version": "10.19.2",
|
|
4
4
|
"description": "Shared library for WillBooster projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"@tsconfig/node-lts": "24.0.1",
|
|
48
48
|
"@tsconfig/node-ts": "23.6.4",
|
|
49
49
|
"@types/bun": "1.4.2",
|
|
50
|
-
"@types/node": "26.6.
|
|
50
|
+
"@types/node": "26.6.4",
|
|
51
51
|
"@willbooster/oxfmt-config": "1.2.2",
|
|
52
52
|
"@willbooster/oxlint-config": "1.4.8",
|
|
53
|
-
"@willbooster/wb": "22.
|
|
54
|
-
"build-ts": "21.0.
|
|
55
|
-
"oxfmt": "0.
|
|
56
|
-
"oxlint": "1.
|
|
57
|
-
"oxlint-tsgolint": "7.0.
|
|
53
|
+
"@willbooster/wb": "22.23.1",
|
|
54
|
+
"build-ts": "21.0.20",
|
|
55
|
+
"oxfmt": "0.71.0",
|
|
56
|
+
"oxlint": "1.86.0",
|
|
57
|
+
"oxlint-tsgolint": "7.0.2003",
|
|
58
58
|
"sort-package-json": "4.0.0",
|
|
59
59
|
"typescript": "7.0.2",
|
|
60
60
|
"yaml": "2.9.1"
|