@ai-matrx/vault 0.1.6 → 0.1.8
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/CHANGELOG.md +1 -1
- package/dist/index.cjs +47 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +45 -42
- package/dist/index.js.map +1 -1
- package/dist/io/bitwarden-json.worker.js +2 -2
- package/dist/io/bitwarden-json.worker.js.map +1 -1
- package/dist/io/onepux.worker.js +3 -3
- package/dist/io/onepux.worker.js.map +1 -1
- package/dist/io/proton-pass.worker.js +2 -2
- package/dist/io/proton-pass.worker.js.map +1 -1
- package/package.json +3 -3
|
@@ -616,7 +616,7 @@ function assertNoDuplicateKeys(text) {
|
|
|
616
616
|
i++;
|
|
617
617
|
}
|
|
618
618
|
}
|
|
619
|
-
var
|
|
619
|
+
var parseStrictJson = (text, ...rest) => {
|
|
620
620
|
assertNoDuplicateKeys(text);
|
|
621
621
|
return parse(text, ...rest);
|
|
622
622
|
};
|
|
@@ -747,7 +747,7 @@ function parseBitwardenExport(text, limits) {
|
|
|
747
747
|
if (bytes(text) > limits.maxFileBytes) throw new Error("The file exceeds this organization\u2019s import size limit.");
|
|
748
748
|
let root;
|
|
749
749
|
try {
|
|
750
|
-
root = object(
|
|
750
|
+
root = object(parseStrictJson(text)) ?? {};
|
|
751
751
|
} catch {
|
|
752
752
|
throw new Error("The JSON export has duplicate keys or could not be read safely.");
|
|
753
753
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/utils.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/LosslessNumber.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/numberParsers.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/revive.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/parse.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/stringify.ts","../../src/io/strict-json.ts","../../src/io/csv-import.ts","../../../kit/src/uuid.ts","../../src/io/bitwarden-json.ts","../../src/io/bitwarden-json.worker.ts"],"sourcesContent":["import type { NumberSplit } from './types'\n\n/**\n * Test whether a string contains an integer number\n */\nexport function isInteger(value: string): boolean {\n return INTEGER_REGEX.test(value)\n}\n\nconst INTEGER_REGEX = /^-?[0-9]+$/\n\n/**\n * Test whether a string contains a number\n * http://stackoverflow.com/questions/13340717/json-numbers-regular-expression\n */\nexport function isNumber(value: string): boolean {\n return NUMBER_REGEX.test(value)\n}\n\nconst NUMBER_REGEX = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$/\n\n/**\n * Test whether a string can be safely represented with a number\n * without information loss.\n *\n * When approx is true, floating point numbers that lose a few digits but\n * are still approximately equal in value are considered safe too.\n * Integer numbers must still be exactly equal.\n */\nexport function isSafeNumber(\n value: string,\n config?: {\n approx: boolean\n }\n): boolean {\n if (isInteger(value)) {\n return Number.isSafeInteger(Number.parseInt(value, 10))\n }\n\n const num = Number.parseFloat(value)\n const parsed = String(num)\n\n if (value === parsed) {\n return true\n }\n\n const valueDigits = extractSignificantDigits(value)\n const parsedDigits = extractSignificantDigits(parsed)\n\n if (valueDigits === parsedDigits) {\n return true\n }\n\n if (config?.approx === true) {\n // A value is approximately equal when:\n // 1. it is a floating point number, not an integer\n // 2. it has at least 14 digits\n // 3. the first 14 digits are equal\n const requiredDigits = 14\n if (\n !isInteger(value) &&\n parsedDigits.length >= requiredDigits &&\n valueDigits.startsWith(parsedDigits.substring(0, requiredDigits))\n ) {\n return true\n }\n }\n\n return false\n}\n\nexport enum UnsafeNumberReason {\n underflow = 'underflow',\n overflow = 'overflow',\n truncate_integer = 'truncate_integer',\n truncate_float = 'truncate_float'\n}\n\n/**\n * When the provided value is an unsafe number, describe what the reason is:\n * overflow, underflow, truncate_integer, or truncate_float.\n * Returns undefined when the value is safe.\n */\nexport function getUnsafeNumberReason(value: string): UnsafeNumberReason | undefined {\n if (isSafeNumber(value, { approx: false })) {\n return undefined\n }\n\n if (isInteger(value)) {\n return UnsafeNumberReason.truncate_integer\n }\n\n const num = Number.parseFloat(value)\n if (!Number.isFinite(num)) {\n return UnsafeNumberReason.overflow\n }\n\n if (num === 0) {\n return UnsafeNumberReason.underflow\n }\n\n return UnsafeNumberReason.truncate_float\n}\n\n/**\n * Convert a string into a number when it is safe to do so.\n * Throws an error otherwise, explaining the reason.\n */\nexport function toSafeNumberOrThrow(\n value: string,\n config?: {\n approx: boolean\n }\n): number {\n const number = Number.parseFloat(value)\n\n const unsafeReason = getUnsafeNumberReason(value)\n if (\n config?.approx === true\n ? unsafeReason && unsafeReason !== UnsafeNumberReason.truncate_float\n : unsafeReason\n ) {\n const unsafeReasonText = unsafeReason?.replace(/_\\w+$/, '')\n throw new Error(\n `Cannot safely convert to number: the value '${value}' would ${unsafeReasonText} and become ${number}`\n )\n }\n\n return number\n}\n\n/**\n * Split a number into sign, digits, and exponent.\n * Leading zeros and non-canonical zeros are normalized.\n *\n * The value can be constructed again from a split number by inserting a dot\n * at the second character of the digits if there is more than one digit,\n * prepending it with the sign, and appending an \"e\" and the exponent as follows:\n *\n * const reconstructed = `${sign}${digits[0]}.${digits.slice(1)}e${exponent}`\n *\n */\nexport function splitNumber(value: string): NumberSplit {\n const match = value.match(/^(-?)(\\d+\\.?\\d*)([eE]([+-]?\\d+))?$/)\n if (!match) {\n throw new SyntaxError(`Invalid number: ${value}`)\n }\n\n const sign = match[1] as '-' | ''\n const digitsStr = match[2]\n let exponent = match[4] !== undefined ? Number.parseInt(match[4], 10) : 0\n\n const dot = digitsStr.indexOf('.')\n exponent += dot !== -1 ? dot - 1 : digitsStr.length - 1\n\n const digits = digitsStr\n .replace('.', '') // remove the dot (must be removed before removing leading zeros)\n .replace(/^0*/, (zeros: string) => {\n // remove leading zeros, add their count to the exponent\n exponent -= zeros.length\n return ''\n })\n .replace(/0*$/, '') // remove trailing zeros\n\n // normalize zero, for example normalizes 0e5 or -0 into 0\n return digits.length > 0 ? { sign, digits, exponent } : { sign: '', digits: '0', exponent: 0 }\n}\n\n/**\n * Compare two strings containing a numeric value\n * Returns 1 when a is larger than b, 0 when they are equal,\n * and -1 when a is smaller than b.\n */\nexport function compareNumber(a: string, b: string): 1 | 0 | -1 {\n if (a === b) {\n return 0\n }\n\n const aa = splitNumber(a)\n const bb = splitNumber(b)\n\n type Sign = -1 | 1\n\n const sign: Sign = aa.sign === '-' ? -1 : 1\n\n if (aa.sign !== bb.sign) {\n return sign\n }\n\n if (aa.exponent !== bb.exponent) {\n return aa.exponent > bb.exponent ? sign : aa.exponent < bb.exponent ? (-sign as Sign) : 0\n }\n\n return aa.digits > bb.digits ? sign : aa.digits < bb.digits ? (-sign as Sign) : 0\n}\n\n/**\n * Count the significant digits of a number.\n *\n * For example:\n * '2.34' returns 3\n * '-77' returns 2\n * '0.003400' returns 2\n * '120.5e+30' returns 4\n **/\nexport function countSignificantDigits(value: string): number {\n const { start, end } = getSignificantDigitRange(value)\n\n const dot = value.indexOf('.')\n if (dot === -1 || dot < start || dot > end) {\n return end - start\n }\n\n return end - start - 1\n}\n\n/**\n * Get the significant digits of a number.\n *\n * For example:\n * '2.34' returns '234'\n * '-77' returns '77'\n * '0.003400' returns '34'\n * '120.5e+30' returns '1205'\n **/\nexport function extractSignificantDigits(value: string): string {\n const { start, end } = getSignificantDigitRange(value)\n\n const digits = value.substring(start, end)\n\n const dot = digits.indexOf('.')\n if (dot === -1) {\n return digits\n }\n\n return digits.substring(0, dot) + digits.substring(dot + 1)\n}\n\n/**\n * Returns the range (start to end) of the significant digits of a value.\n * Note that this range _may_ contain the decimal dot.\n *\n * For example:\n *\n * getSignificantDigitRange('0.0325900') // { start: 3, end: 7 }\n * getSignificantDigitRange('2.0300') // { start: 0, end: 3 }\n * getSignificantDigitRange('0.0') // { start: 3, end: 3 }\n *\n */\nfunction getSignificantDigitRange(value: string): { start: number; end: number } {\n let start = 0\n if (value[0] === '-') {\n start++\n }\n while (value[start] === '0' || value[start] === '.') {\n start++\n }\n\n let end = value.lastIndexOf('e')\n if (end === -1) {\n end = value.lastIndexOf('E')\n }\n if (end === -1) {\n end = value.length\n }\n while ((value[end - 1] === '0' || value[end - 1] === '.') && end > start) {\n end--\n }\n\n return { start, end }\n}\n","import {\n compareNumber,\n countSignificantDigits,\n getUnsafeNumberReason,\n isInteger,\n isNumber,\n UnsafeNumberReason\n} from './utils.js'\n\n/**\n * A lossless number. Stores its numeric value as string\n */\nexport class LosslessNumber {\n // numeric value as string\n value: string\n\n // type information\n isLosslessNumber = true\n\n constructor(value: string) {\n if (!isNumber(value)) {\n throw new Error(`Invalid number (value: \"${value}\")`)\n }\n\n this.value = value\n }\n\n /**\n * Get the value of the LosslessNumber as number or bigint.\n *\n * - a number is returned for safe numbers and decimal values that only lose some insignificant digits\n * - a bigint is returned for big integer numbers\n * - an Error is thrown for values that will overflow or underflow\n *\n * Note that you can implement your own strategy for conversion by just getting the value as string\n * via .toString(), and using util functions like isInteger, isSafeNumber, getUnsafeNumberReason,\n * and toSafeNumberOrThrow to convert it to a numeric value.\n */\n valueOf(): number | bigint {\n const unsafeReason = getUnsafeNumberReason(this.value)\n\n // safe or truncate_float\n if (unsafeReason === undefined || unsafeReason === UnsafeNumberReason.truncate_float) {\n return Number.parseFloat(this.value)\n }\n\n // truncate_integer\n if (isInteger(this.value)) {\n return BigInt(this.value)\n }\n\n // overflow or underflow\n throw new Error(\n `Cannot safely convert to number: the value '${this.value}' would ${unsafeReason} and become ${Number.parseFloat(this.value)}`\n )\n }\n\n /**\n * Get the value of the LosslessNumber as string.\n */\n toString(): string {\n return this.value\n }\n\n // Note: we do NOT implement a .toJSON() method, and you should not implement\n // or use that, it cannot safely turn the numeric value in the string into\n // stringified JSON since it has to be parsed into a number first.\n}\n\n/**\n * Test whether a value is a LosslessNumber\n */\nexport function isLosslessNumber(value: unknown): value is LosslessNumber {\n // @ts-expect-error\n return (value && typeof value === 'object' && value.isLosslessNumber) || false\n}\n\n/**\n * Convert a number into a LosslessNumber if this is possible in a safe way\n * If the value has too many digits, or is NaN or Infinity, an error will be thrown\n */\nexport function toLosslessNumber(value: number): LosslessNumber {\n const maxDigits = 15\n if (countSignificantDigits(String(value)) > maxDigits) {\n throw new Error(\n `Invalid number: contains more than 15 digits and is most likely truncated and unsafe by itself (value: ${value})`\n )\n }\n\n if (Number.isNaN(value)) {\n throw new Error('Invalid number: NaN')\n }\n\n if (!Number.isFinite(value)) {\n throw new Error(`Invalid number: ${value}`)\n }\n\n return new LosslessNumber(String(value))\n}\n\n/**\n * Compare two lossless numbers.\n * Returns 1 when a is larger than b, 0 when they are equal,\n * and -1 when a is smaller than b.\n */\nexport function compareLosslessNumber(a: LosslessNumber, b: LosslessNumber): 1 | 0 | -1 {\n return compareNumber(a.value, b.value)\n}\n","import { LosslessNumber } from './LosslessNumber.js'\nimport { isInteger } from './utils.js'\n\nexport function parseLosslessNumber(value: string): LosslessNumber {\n return new LosslessNumber(value)\n}\n\nexport function parseNumberAndBigInt(value: string): number | bigint {\n return isInteger(value) ? BigInt(value) : Number.parseFloat(value)\n}\n","import { isLosslessNumber } from './LosslessNumber.js'\nimport type { GenericObject, Reviver } from './types'\n\n/**\n * Revive a json object.\n * Applies the reviver function recursively on all values in the JSON object.\n * @param json A JSON Object, Array, or value\n * @param reviver\n * A reviver function invoked with arguments `key` and `value`,\n * which must return a replacement value. The function context\n * (`this`) is the Object or Array that contains the currently\n * handled value.\n */\nexport function revive(json: unknown, reviver: Reviver): unknown {\n return reviveValue({ '': json }, '', json, reviver)\n}\n\n/**\n * Revive a value\n */\nfunction reviveValue(\n context: GenericObject<unknown> | Array<unknown>,\n key: string,\n value: unknown,\n reviver: Reviver\n): unknown {\n if (Array.isArray(value)) {\n return reviver.call(context, key, reviveArray(value, reviver))\n }\n\n if (value && typeof value === 'object' && !isLosslessNumber(value)) {\n // note the special case for LosslessNumber,\n // we don't want to iterate over the internals of a LosslessNumber\n return reviver.call(context, key, reviveObject(value as GenericObject<unknown>, reviver))\n }\n\n return reviver.call(context, key, value)\n}\n\n/**\n * Revive the properties of an object\n */\nfunction reviveObject(object: GenericObject<unknown>, reviver: Reviver) {\n for (const key of Object.keys(object)) {\n const value = reviveValue(object, key, object[key], reviver)\n if (value !== undefined) {\n object[key] = value\n } else {\n delete object[key]\n }\n }\n\n return object\n}\n\n/**\n * Revive the properties of an Array\n */\nfunction reviveArray(array: Array<unknown>, reviver: Reviver): Array<unknown> {\n for (let i = 0; i < array.length; i++) {\n array[i] = reviveValue(array, String(i), array[i], reviver)\n }\n\n return array\n}\n","import { parseLosslessNumber } from './numberParsers.js'\nimport { revive } from './revive.js'\nimport type { DuplicateKeyInfo, GenericObject, NumberParser, ParseOptions, Reviver } from './types'\n\n/**\n * The LosslessJSON.parse() method parses a string as JSON, optionally transforming\n * the value produced by parsing.\n *\n * The parser is based on the parser of Tan Li Hou shared in\n * https://lihautan.com/json-parser-with-javascript/\n *\n * @param text\n * The string to parse as JSON. See the JSON object for a description of JSON syntax.\n *\n * @param [reviver]\n * If a function, prescribes how the value originally produced by parsing is\n * transformed, before being returned.\n *\n * @param [options=ParseOptions | NumberParserArgument]\n * Pass a custom number parser. Input is a string, and the output can be unknown\n * numeric value: number, bigint, LosslessNumber, or a custom BigNumber library.\n *\n * @returns Returns the Object corresponding to the given JSON text.\n *\n * @throws Throws a SyntaxError exception if the string to parse is not valid JSON.\n */\nexport function parse(\n text: string,\n reviver?: Reviver | null,\n options?: ParseOptions | NumberParser\n): unknown {\n const optionsObj = typeof options === 'function' ? { parseNumber: options } : options\n const parseNumber = optionsObj?.parseNumber ?? parseLosslessNumber\n const onDuplicateKey = optionsObj?.onDuplicateKey ?? throwDuplicateKey\n\n let i = 0\n const value = parseValue()\n expectValue(value)\n expectEndOfInput()\n\n return reviver ? revive(value, reviver) : value\n\n function parseObject(): GenericObject<unknown> | undefined {\n if (text.charCodeAt(i) === codeOpeningBrace) {\n i++\n skipWhitespace()\n\n const object: GenericObject<unknown> = {}\n let initial = true\n while (i < text.length && text.charCodeAt(i) !== codeClosingBrace) {\n if (!initial) {\n eatComma()\n skipWhitespace()\n } else {\n initial = false\n }\n\n const start = i\n\n const key = parseString()\n if (key === undefined) {\n throwObjectKeyExpected()\n return // To make TS happy\n }\n\n skipWhitespace()\n eatColon()\n const value = parseValue()\n\n if (value === undefined) {\n throwObjectValueExpected()\n return // To make TS happy\n }\n\n // handle duplicate keys\n // biome-ignore lint/suspicious/noPrototypeBuiltins: TODO: replace with hasOwn one day, when browser support is high enough\n if (Object.prototype.hasOwnProperty.call(object, key) && !isDeepEqual(value, object[key])) {\n // Note that we could also test `if(key in object) {...}`\n // or `if (object[key] !== 'undefined') {...}`, but that is slower.\n const returnedValue = onDuplicateKey({\n key,\n position: start + 1,\n oldValue: object[key],\n newValue: value\n })\n\n if (returnedValue !== undefined) {\n object[key] = returnedValue\n }\n } else {\n object[key] = value\n }\n }\n\n if (text.charCodeAt(i) !== codeClosingBrace) {\n throwObjectKeyOrEndExpected()\n }\n i++\n\n return object\n }\n }\n\n function parseArray(): Array<unknown> | unknown {\n if (text.charCodeAt(i) === codeOpeningBracket) {\n i++\n skipWhitespace()\n\n const array = []\n let initial = true\n while (i < text.length && text.charCodeAt(i) !== codeClosingBracket) {\n if (!initial) {\n eatComma()\n } else {\n initial = false\n }\n\n const value = parseValue()\n expectArrayItem(value)\n array.push(value)\n }\n\n if (text.charCodeAt(i) !== codeClosingBracket) {\n throwArrayItemOrEndExpected()\n }\n i++\n\n return array\n }\n }\n\n function parseValue(): unknown {\n skipWhitespace()\n\n const value =\n parseString() ??\n parseNumeric() ??\n parseObject() ??\n parseArray() ??\n parseKeyword('true', true) ??\n parseKeyword('false', false) ??\n parseKeyword('null', null)\n\n skipWhitespace()\n\n return value\n }\n\n function parseKeyword(name: string, value: unknown): unknown | undefined {\n if (text.slice(i, i + name.length) === name) {\n i += name.length\n return value\n }\n }\n\n function skipWhitespace() {\n while (isWhitespace(text.charCodeAt(i))) {\n i++\n }\n }\n\n function parseString() {\n if (text.charCodeAt(i) === codeDoubleQuote) {\n i++\n let result = ''\n while (i < text.length && text.charCodeAt(i) !== codeDoubleQuote) {\n if (text.charCodeAt(i) === codeBackslash) {\n const char = text[i + 1]\n const escapeChar = escapeCharacters[char]\n if (escapeChar !== undefined) {\n result += escapeChar\n i++\n } else if (char === 'u') {\n if (\n isHex(text.charCodeAt(i + 2)) &&\n isHex(text.charCodeAt(i + 3)) &&\n isHex(text.charCodeAt(i + 4)) &&\n isHex(text.charCodeAt(i + 5))\n ) {\n result += String.fromCharCode(Number.parseInt(text.slice(i + 2, i + 6), 16))\n i += 5\n } else {\n throwInvalidUnicodeCharacter(i)\n }\n } else {\n throwInvalidEscapeCharacter(i)\n }\n } else {\n if (isValidStringCharacter(text.charCodeAt(i))) {\n result += text[i]\n } else {\n throwInvalidCharacter(text[i])\n }\n }\n i++\n }\n expectEndOfString()\n i++\n return result\n }\n }\n\n function parseNumeric() {\n const start = i\n if (text.charCodeAt(i) === codeMinus) {\n i++\n expectDigit(start)\n }\n\n if (text.charCodeAt(i) === codeZero) {\n i++\n } else if (isNonZeroDigit(text.charCodeAt(i))) {\n i++\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (text.charCodeAt(i) === codeDot) {\n i++\n expectDigit(start)\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (text.charCodeAt(i) === codeLowercaseE || text.charCodeAt(i) === codeUppercaseE) {\n i++\n if (text.charCodeAt(i) === codeMinus || text.charCodeAt(i) === codePlus) {\n i++\n }\n expectDigit(start)\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (i > start) {\n return parseNumber(text.slice(start, i))\n }\n }\n\n function eatComma() {\n if (text.charCodeAt(i) !== codeComma) {\n throw new SyntaxError(`Comma ',' expected after value ${gotAt()}`)\n }\n i++\n }\n\n function eatColon() {\n if (text.charCodeAt(i) !== codeColon) {\n throw new SyntaxError(`Colon ':' expected after property name ${gotAt()}`)\n }\n i++\n }\n\n function expectValue(value: unknown) {\n if (value === undefined) {\n throw new SyntaxError(`JSON value expected ${gotAt()}`)\n }\n }\n\n function expectArrayItem(value: unknown) {\n if (value === undefined) {\n throw new SyntaxError(`Array item expected ${gotAt()}`)\n }\n }\n\n function expectEndOfInput() {\n if (i < text.length) {\n throw new SyntaxError(`Expected end of input ${gotAt()}`)\n }\n }\n\n function expectDigit(start: number) {\n if (!isDigit(text.charCodeAt(i))) {\n const numSoFar = text.slice(start, i)\n throw new SyntaxError(`Invalid number '${numSoFar}', expecting a digit ${gotAt()}`)\n }\n }\n\n function expectEndOfString() {\n if (text.charCodeAt(i) !== codeDoubleQuote) {\n throw new SyntaxError(`End of string '\"' expected ${gotAt()}`)\n }\n }\n\n function throwObjectKeyExpected() {\n throw new SyntaxError(`Quoted object key expected ${gotAt()}`)\n }\n\n function throwDuplicateKey({ key, position }: DuplicateKeyInfo) {\n throw new SyntaxError(`Duplicate key '${key}' encountered at position ${position}`)\n }\n\n function throwObjectKeyOrEndExpected() {\n throw new SyntaxError(`Quoted object key or end of object '}' expected ${gotAt()}`)\n }\n\n function throwArrayItemOrEndExpected() {\n throw new SyntaxError(`Array item or end of array ']' expected ${gotAt()}`)\n }\n\n function throwInvalidCharacter(char: string) {\n throw new SyntaxError(`Invalid character '${char}' ${pos()}`)\n }\n\n function throwInvalidEscapeCharacter(start: number) {\n const chars = text.slice(start, start + 2)\n throw new SyntaxError(`Invalid escape character '${chars}' ${pos()}`)\n }\n\n function throwObjectValueExpected() {\n throw new SyntaxError(`Object value expected after ':' ${pos()}`)\n }\n\n function throwInvalidUnicodeCharacter(start: number) {\n const chars = text.slice(start, start + 6)\n throw new SyntaxError(`Invalid unicode character '${chars}' ${pos()}`)\n }\n\n // zero based character position\n function pos(): string {\n return `at position ${i}`\n }\n\n function got(): string {\n return i < text.length ? `but got '${text[i]}'` : 'but reached end of input'\n }\n\n function gotAt(): string {\n return `${got()} ${pos()}`\n }\n}\n\nfunction isWhitespace(code: number): boolean {\n return code === codeSpace || code === codeNewline || code === codeTab || code === codeReturn\n}\n\nfunction isHex(code: number): boolean {\n return (\n (code >= codeZero && code <= codeNine) ||\n (code >= codeUppercaseA && code <= codeUppercaseF) ||\n (code >= codeLowercaseA && code <= codeLowercaseF)\n )\n}\n\nfunction isDigit(code: number): boolean {\n return code >= codeZero && code <= codeNine\n}\n\nfunction isNonZeroDigit(code: number): boolean {\n return code >= codeOne && code <= codeNine\n}\n\nexport function isValidStringCharacter(code: number): boolean {\n return code >= 0x20 && code <= 0x10ffff\n}\n\nexport function isDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, index) => isDeepEqual(item, b[index]))\n }\n\n if (isObject(a) && isObject(b)) {\n const keys = [...new Set([...Object.keys(a), ...Object.keys(b)])]\n return keys.every((key) => isDeepEqual(a[key], b[key]))\n }\n\n return false\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\n// map with all escape characters\nconst escapeCharacters: GenericObject<string> = {\n '\"': '\"',\n '\\\\': '\\\\',\n '/': '/',\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t'\n // note that \\u is handled separately in parseString()\n}\n\nconst codeBackslash = 0x5c // \"\\\"\nconst codeOpeningBrace = 0x7b // \"{\"\nconst codeClosingBrace = 0x7d // \"}\"\nconst codeOpeningBracket = 0x5b // \"[\"\nconst codeClosingBracket = 0x5d // \"]\"\nconst codeSpace = 0x20 // \" \"\nconst codeNewline = 0xa // \"\\n\"\nconst codeTab = 0x9 // \"\\t\"\nconst codeReturn = 0xd // \"\\r\"\nconst codeDoubleQuote = 0x0022 // \"\nconst codePlus = 0x2b // \"+\"\nconst codeMinus = 0x2d // \"-\"\nconst codeZero = 0x30\nconst codeOne = 0x31\nconst codeNine = 0x39\nconst codeComma = 0x2c // \",\"\nconst codeDot = 0x2e // \".\" (dot, period)\nconst codeColon = 0x3a // \":\"\nexport const codeUppercaseA = 0x41 // \"A\"\nexport const codeLowercaseA = 0x61 // \"a\"\nexport const codeUppercaseE = 0x45 // \"E\"\nexport const codeLowercaseE = 0x65 // \"e\"\nexport const codeUppercaseF = 0x46 // \"F\"\nexport const codeLowercaseF = 0x66 // \"f\"\n","import type { GenericObject, NumberStringifier, Replacer } from './types'\nimport { isNumber } from './utils.js'\n\n/**\n * The LosslessJSON.stringify() method converts a JavaScript value to a JSON string,\n * optionally replacing values if a replacer function is specified, or\n * optionally including only the specified properties if a replacer array is specified.\n *\n * @param value\n * The value to convert to a JSON string.\n *\n * @param [replacer]\n * A function that alters the behavior of the stringification process,\n * or an array of String and Number objects that serve as a whitelist for\n * selecting the properties of the value object to be included in the JSON string.\n * If this value is null or not provided, all properties of the object are\n * included in the resulting JSON string.\n *\n * @param [space]\n * A String or Number object that's used to insert white space into the output\n * JSON string for readability purposes. If this is a Number, it indicates the\n * number of space characters to use as white space; this number is capped at 10\n * if it's larger than that. Values less than 1 indicate that no space should be\n * used. If this is a String, the string (or the first 10 characters of the string,\n * if it's longer than that) is used as white space. If this parameter is not\n * provided (or is null), no white space is used.\n *\n * @param [numberStringifiers]\n * An optional list with additional number stringifiers, for example to serialize\n * a BigNumber. The output of the function must be valid stringified JSON.\n * When `undefined` is returned, the property will be deleted from the object.\n * The difference with using a `replacer` is that the output of a `replacer`\n * must be JSON and will be stringified afterwards, whereas the output of the\n * `numberStringifiers` is already stringified JSON.\n *\n * @returns Returns the string representation of the JSON object.\n */\nexport function stringify(\n value: unknown,\n replacer?: Replacer | null,\n space?: number | string,\n numberStringifiers?: NumberStringifier[]\n): string | undefined {\n const resolvedSpace = resolveSpace(space)\n\n const replacedValue =\n typeof replacer === 'function' ? replacer.call({ '': value }, '', value) : value\n\n return stringifyValue(replacedValue, '')\n\n /**\n * Stringify a value\n */\n function stringifyValue(value: unknown, indent: string | undefined): string | undefined {\n if (Array.isArray(numberStringifiers)) {\n const stringifier = numberStringifiers.find((item) => item.test(value))\n if (stringifier) {\n const str: unknown = stringifier.stringify(value)\n if (typeof str !== 'string' || !isNumber(str)) {\n throw new Error(\n `Invalid JSON number: output of a number stringifier must be a string containing a JSON number (output: ${str})`\n )\n }\n return str\n }\n }\n\n // boolean, null, number, string, or date\n if (\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string' ||\n value === null ||\n value instanceof Date ||\n value instanceof Boolean ||\n value instanceof Number ||\n value instanceof String\n ) {\n return JSON.stringify(value)\n }\n\n // lossless number, the secret ingredient :)\n // @ts-expect-error\n if (value?.isLosslessNumber) {\n return value.toString()\n }\n\n // BigInt\n if (typeof value === 'bigint') {\n return value.toString()\n }\n\n // Array\n if (Array.isArray(value)) {\n return stringifyArray(value, indent)\n }\n\n // Object (test lastly!)\n if (value && typeof value === 'object') {\n return stringifyObject(value as GenericObject<unknown>, indent)\n }\n\n return undefined\n }\n\n /**\n * Stringify an array\n */\n function stringifyArray(array: Array<unknown>, indent: string | undefined): string {\n if (array.length === 0) {\n return '[]'\n }\n\n const childIndent = resolvedSpace ? indent + resolvedSpace : undefined\n let str = resolvedSpace ? '[\\n' : '['\n\n for (let i = 0; i < array.length; i++) {\n const item =\n typeof replacer === 'function' ? replacer.call(array, String(i), array[i]) : array[i]\n\n if (resolvedSpace) {\n str += childIndent\n }\n\n if (typeof item !== 'undefined' && typeof item !== 'function') {\n str += stringifyValue(item, childIndent)\n } else {\n str += 'null'\n }\n\n if (i < array.length - 1) {\n str += resolvedSpace ? ',\\n' : ','\n }\n }\n\n str += resolvedSpace ? `\\n${indent}]` : ']'\n return str\n }\n\n /**\n * Stringify an object\n */\n function stringifyObject(\n object: GenericObject<unknown>,\n indent: string | undefined\n ): string | undefined {\n if (typeof object.toJSON === 'function') {\n return stringify(object.toJSON(), replacer, space, undefined)\n }\n\n const keys: string[] = Array.isArray(replacer) ? replacer.map(String) : Object.keys(object)\n\n if (keys.length === 0) {\n return '{}'\n }\n\n const childIndent = resolvedSpace ? indent + resolvedSpace : undefined\n let first = true\n let str = resolvedSpace ? '{\\n' : '{'\n\n for (const key of keys) {\n const value =\n typeof replacer === 'function' ? replacer.call(object, key, object[key]) : object[key]\n\n if (includeProperty(key, value)) {\n if (first) {\n first = false\n } else {\n str += resolvedSpace ? ',\\n' : ','\n }\n\n const keyStr = JSON.stringify(key)\n str += resolvedSpace ? `${childIndent + keyStr}: ` : `${keyStr}:`\n\n str += stringifyValue(value, childIndent)\n }\n }\n\n str += resolvedSpace ? `\\n${indent}}` : '}'\n return str\n }\n\n /**\n * Test whether to include a property in a stringified object or not.\n */\n function includeProperty(_key: string, value: unknown): boolean {\n return typeof value !== 'undefined' && typeof value !== 'function' && typeof value !== 'symbol'\n }\n}\n\n/**\n * Resolve a JSON stringify space:\n * replace a number with a string containing that number of spaces\n */\nfunction resolveSpace(space: number | string | undefined): string | undefined {\n if (typeof space === 'number') {\n return ' '.repeat(space)\n }\n\n if (typeof space === 'string' && space !== '') {\n return space\n }\n\n return undefined\n}\n","import { parse as losslessParse } from \"lossless-json\";\n\n/**\n * A JSON object that names the same key twice is refused — even when both values are equal. A\n * password-manager export with a repeated key is malformed or tampered with, and which copy wins\n * differs between readers. `lossless-json` only refuses a repeat with a DIFFERENT value (the web\n * app patched that in its own install; a patch cannot travel with this package), so every parse in\n * `io/` checks keys here first.\n */\nexport function assertNoDuplicateKeys(text: string): void {\n const stack: { keys: Set<string> | null; expectKey: boolean }[] = [];\n let i = 0;\n while (i < text.length) {\n const ch = text[i];\n if (ch === '\"') {\n const start = i;\n i++;\n while (i < text.length && text[i] !== '\"') i += text[i] === \"\\\\\" ? 2 : 1;\n const top = stack[stack.length - 1];\n if (top?.keys && top.expectKey) {\n const key = JSON.parse(text.slice(start, i + 1)) as string;\n if (top.keys.has(key)) throw new SyntaxError(`Duplicate key '${key}' encountered at position ${start + 1}`);\n top.keys.add(key);\n top.expectKey = false;\n }\n } else if (ch === \"{\") stack.push({ keys: new Set(), expectKey: true });\n else if (ch === \"[\") stack.push({ keys: null, expectKey: false });\n else if (ch === \"}\" || ch === \"]\") stack.pop();\n else if (ch === \",\") {\n const top = stack[stack.length - 1];\n if (top?.keys) top.expectKey = true;\n }\n i++;\n }\n}\n\n/** `lossless-json` `parse`, after the duplicate-key check. Every parse in `io/` uses this one. */\nexport const parse: typeof losslessParse = (text, ...rest) => {\n assertNoDuplicateKeys(text);\n return losslessParse(text, ...rest);\n};\n","/** Local-only CSV normalization for Vault's first password-manager import. */\nimport type { VaultItemCreateRequest } from \"@ai-matrx/api/account\";\nimport { parseDelimited } from \"@ai-matrx/kit/delimited\";\n\nimport { isLoopbackUrl } from \"./loopback\";\n\nexport type CsvImportLimits = {\n maxFileBytes: number;\n maxRecords: number;\n maxColumns: number;\n maxCellBytes: number;\n maxFields: number;\n maxPlaintextFieldBytes: number;\n maxRequestBodyBytes: number;\n maxJsonDepth?: number;\n jsonWorkerTimeoutMs?: number;\n};\nexport type CsvColumnRole =\n \"title\" | \"username\" | \"password\" | \"url\" | \"notes\" | \"otp\" | \"keep\";\nexport type CsvImportRow = {\n rowNumber: number;\n cells: string[];\n issue?: \"invalid\" | \"unsupported\" | undefined;\n};\nexport type CsvImportPreview = {\n headers: string[];\n rows: CsvImportRow[];\n issues: number;\n};\nexport type CsvImportCommand = {\n rowId: string;\n body: VaultItemCreateRequest;\n hasOtp: boolean;\n};\nexport type CsvImportPreparation =\n | { status: \"ready\"; command: CsvImportCommand }\n | {\n status: \"skipped\";\n reason:\n | \"invalid\"\n | \"unsupported\"\n | \"deleted\"\n | \"archived\"\n | \"possible_duplicate\";\n }\n | { status: \"invalid\"; diagnostic: string };\nexport type CsvImportOutcome = {\n imported: number;\n skipped: number;\n failed: number;\n cancelled: boolean;\n definitive: boolean;\n /** The first command that was not confirmed. Reuse it on a same-session retry. */\n progressCursor: number;\n};\n\nexport type CsvImportDispatch = \"committed\" | \"retryable\" | \"definitive\";\n\n/** The request's owner: an organization's vault, or the person's own. */\nexport function principalOf(organizationId: string | null): NonNullable<VaultItemCreateRequest[\"principal\"]> {\n return organizationId ? { type: \"organization\", organization_id: organizationId } : { type: \"user\" };\n}\n\nfunction utf8ByteLength(value: string): number {\n if (typeof TextEncoder !== \"undefined\")\n return new TextEncoder().encode(value).byteLength;\n return unescape(encodeURIComponent(value)).length;\n}\n\nfunction csvParserInput(text: string): string {\n // The parser emits an extra empty record for the final record terminator. Remove\n // exactly that terminator; interior/explicit blank rows retain their numbers.\n return text.replace(/^\\uFEFF/, \"\").replace(/(?:\\r\\n|\\r|\\n)$/, \"\");\n}\n\nexport function parseCsvText(\n text: string,\n limits: CsvImportLimits,\n): CsvImportPreview {\n if (utf8ByteLength(text) > limits.maxFileBytes)\n throw new Error(\"The file exceeds this organization’s import size limit.\");\n const parsed = parseDelimited(csvParserInput(text), {\n delimiter: \",\",\n skipEmptyLines: false,\n });\n if (\n parsed.errors.some(\n (error) =>\n error.code !== \"TooFewFields\" && error.code !== \"TooManyFields\",\n )\n )\n throw new Error(\"The CSV could not be read. Fix the file and try again.\");\n return validateParsedCsv(parsed.data, limits);\n}\n\nfunction validateParsedCsv(\n parsed: string[][],\n limits: CsvImportLimits,\n): CsvImportPreview {\n const [headers, ...data] = parsed;\n if (!headers?.length || headers.length > limits.maxColumns)\n throw new Error(\"The CSV has an unsupported number of columns.\");\n if (data.length > limits.maxRecords)\n throw new Error(\"The CSV has more records than this organization allows.\");\n const nonLoginTypeColumn = headers.findIndex((header) =>\n /^(item )?(type|kind|category)$/i.test(header.trim()),\n );\n const unsupportedValueColumns = headers\n .map((header, index) =>\n /(?:^|[\\s_-])(passkey|webauthn|fido|attachment|file)(?:$|[\\s_-])/i.test(\n header.trim(),\n )\n ? index\n : -1,\n )\n .filter((index) => index >= 0);\n let issues = 0;\n const rows = data.map((cells, index) => {\n const invalid =\n cells.length !== headers.length ||\n cells.some((cell) => utf8ByteLength(cell) > limits.maxCellBytes) ||\n cells.every((cell) => cell.trim().length === 0);\n const type =\n nonLoginTypeColumn >= 0\n ? (cells[nonLoginTypeColumn] ?? \"\").trim().toLowerCase()\n : \"\";\n const unsupported =\n !invalid &&\n (unsupportedValueColumns.some((column) =>\n Boolean(cells[column]?.trim()),\n ) ||\n (Boolean(type) &&\n !/^(login|website|web|password|credential)$/.test(type)));\n if (invalid || unsupported) issues += 1;\n return {\n rowNumber: index + 2,\n cells,\n issue: invalid\n ? (\"invalid\" as const)\n : unsupported\n ? (\"unsupported\" as const)\n : undefined,\n };\n });\n return { headers, rows, issues };\n}\n\nexport function safeDestination(raw: string): {\n metadata: string | null;\n host: string | null;\n} {\n try {\n const parsed = new URL(raw);\n if (!/^https?:$/.test(parsed.protocol))\n return { metadata: null, host: null };\n if (parsed.username || parsed.password)\n return { metadata: null, host: null };\n return { metadata: parsed.origin, host: parsed.host };\n } catch {\n return { metadata: null, host: null };\n }\n}\n\nexport function suggestedCsvMapping(\n headers: string[],\n source?: string,\n): CsvColumnRole[] {\n const aliases: Record<CsvColumnRole, ReadonlySet<string>> = {\n title: new Set([\"name\", \"title\", \"label\"]),\n username: new Set([\n \"username\",\n \"user\",\n \"login\",\n \"email\",\n \"loginusername\",\n \"loginemail\",\n ]),\n password: new Set([\"password\", \"pass\", \"pwd\", \"loginpassword\"]),\n url: new Set([\n \"url\",\n \"uri\",\n \"website\",\n \"websiteaddress\",\n \"loginurl\",\n \"loginuri\",\n ]),\n notes: new Set([\"note\", \"notes\", \"extra\"]),\n otp: new Set([\"otp\", \"totp\", \"otpauth\", \"onetimepassword\", \"onetimecode\"]),\n keep: new Set(),\n };\n let usernameAssigned = false;\n return headers.map((header) => {\n const key = header.trim().toLowerCase().replace(/[ _-]/g, \"\");\n if (source === \"nordpass\" && key === \"email\" && usernameAssigned)\n return \"keep\";\n const role =\n (Object.entries(aliases) as [CsvColumnRole, ReadonlySet<string>][]).find(\n ([, values]) => values.has(key),\n )?.[0] ?? \"keep\";\n if (role === \"username\") usernameAssigned = true;\n return role;\n });\n}\n\nfunction fieldKey(index: number, used: Set<string>): string {\n const base = `import_column_${index + 1}`;\n let key = base;\n let suffix = 2;\n while (used.has(key)) key = `${base}_${suffix++}`;\n used.add(key);\n return key;\n}\n\nfunction roleValue(\n row: CsvImportRow,\n mapping: CsvColumnRole[],\n role: CsvColumnRole,\n): string | null {\n const index = mapping.findIndex((entry) => entry === role);\n return index < 0 ? null : (row.cells[index] ?? \"\");\n}\n\nexport function hasAmbiguousCsvMapping(mapping: CsvColumnRole[]): boolean {\n return ([\"title\", \"username\", \"password\", \"notes\", \"otp\"] as const).some(\n (role) => mapping.filter((entry) => entry === role).length > 1,\n );\n}\n\nexport function isPossibleDuplicateRow(\n row: CsvImportRow,\n _preview: CsvImportPreview,\n mapping: CsvColumnRole[],\n existingItems: { displayName: string; loginUrls: string[] }[],\n): boolean {\n if (row.issue) return false;\n const title =\n roleValue(row, mapping, \"title\") || `Imported credential ${row.rowNumber}`;\n const urls = row.cells\n .filter((_, index) => mapping[index] === \"url\")\n .map(safeDestination)\n .flatMap((destination) =>\n destination.metadata ? [destination.metadata] : [],\n );\n return existingItems.some((item) => {\n if (item.displayName !== title) return false;\n const existingOrigins = item.loginUrls\n .map(safeDestination)\n .flatMap((destination) =>\n destination.metadata ? [destination.metadata] : [],\n );\n return urls.length > 0\n ? existingOrigins.some((origin) => urls.includes(origin))\n : existingOrigins.length === 0;\n });\n}\n\nexport function prepareCsvImportRow(input: {\n source: string;\n preview: CsvImportPreview;\n row: CsvImportRow;\n mapping: CsvColumnRole[];\n /** null = the person's own vault. */\n organizationId: string | null;\n rowId: string;\n limits: CsvImportLimits;\n browserFillEnabled?: boolean;\n existingItems?: { displayName: string; loginUrls: string[] }[];\n skipPossibleDuplicate?: boolean;\n}): CsvImportPreparation {\n if (input.row.issue === \"invalid\")\n return { status: \"skipped\", reason: \"invalid\" };\n if (input.row.issue === \"unsupported\")\n return { status: \"skipped\", reason: \"unsupported\" };\n if (\n input.skipPossibleDuplicate &&\n isPossibleDuplicateRow(\n input.row,\n input.preview,\n input.mapping,\n input.existingItems ?? [],\n )\n )\n return { status: \"skipped\", reason: \"possible_duplicate\" };\n const { headers } = input.preview;\n const { row, mapping } = input;\n const title =\n roleValue(row, mapping, \"title\") || `Imported credential ${row.rowNumber}`;\n const rawUrls = row.cells\n .filter((_, index) => mapping[index] === \"url\")\n .filter(Boolean);\n const urls = rawUrls\n .map(safeDestination)\n .flatMap((url) => (url.metadata ? [url.metadata] : []));\n const fields: NonNullable<VaultItemCreateRequest[\"fields\"]> = [];\n const used = new Set<string>();\n const add = (field_key: string, value: string, editable = true) => {\n if (!value) return;\n used.add(field_key);\n fields.push({\n field_key,\n value,\n handling: \"revealable\",\n editable,\n inject_into_sandbox: false,\n });\n };\n add(\"username\", roleValue(row, mapping, \"username\") ?? \"\");\n add(\"password\", roleValue(row, mapping, \"password\") ?? \"\");\n add(\"import_notes\", roleValue(row, mapping, \"notes\") ?? \"\");\n for (let index = 0; index < row.cells.length; index += 1) {\n if (mapping[index] === \"keep\")\n add(fieldKey(index, used), row.cells[index] ?? \"\");\n }\n // OTP stays only in the encrypted, revealable source representation until explicit enrollment.\n add(\n \"import_source_record\",\n JSON.stringify({\n source_vendor: input.source,\n format: \"csv\",\n cells: row.cells.map((value: string, column_index: number) => ({\n column_index,\n header: headers[column_index] ?? \"\",\n value,\n })),\n }),\n false,\n );\n if (\n fields.length > input.limits.maxFields ||\n fields.some(\n (field) =>\n utf8ByteLength(field.value) > input.limits.maxPlaintextFieldBytes,\n )\n )\n return {\n status: \"invalid\",\n diagnostic: `Row ${row.rowNumber} exceeds this organization’s encrypted field limit.`,\n };\n const command: CsvImportCommand = {\n rowId: input.rowId,\n hasOtp: Boolean(roleValue(row, mapping, \"otp\")),\n body: {\n principal: principalOf(input.organizationId),\n display_name: title,\n definition_key: \"website_login\",\n source: \"system_import\",\n login_urls: urls,\n uri_match_mode: \"never\",\n browser_fill_enabled:\n Boolean(input.browserFillEnabled) &&\n Boolean(roleValue(row, mapping, \"username\")) &&\n Boolean(roleValue(row, mapping, \"password\")) &&\n urls.length > 0 &&\n urls.every(\n (url) => new URL(url).protocol === \"https:\" || isLoopbackUrl(url),\n ),\n fields,\n },\n };\n // The browser matcher treats `never` as an absolute refusal. Keep this pair\n // coherent with the explicit, eligible bulk opt-in rather than advertising a\n // fill capability the canonical matcher will always reject.\n if (command.body.browser_fill_enabled) command.body.uri_match_mode = \"host\";\n if (\n utf8ByteLength(JSON.stringify(command.body)) >\n input.limits.maxRequestBodyBytes\n )\n return {\n status: \"invalid\",\n diagnostic: `Row ${row.rowNumber} exceeds this organization’s request size limit.`,\n };\n return { status: \"ready\", command };\n}\n\n/** Compatibility helper for callers that only need a command after preparation. */\nexport function toCsvImportCommand(\n input: Parameters<typeof prepareCsvImportRow>[0],\n): CsvImportCommand | null {\n const prepared = prepareCsvImportRow(input);\n return prepared.status === \"ready\" ? prepared.command : null;\n}\n\n/** Dispatch only one immutable command at a time; cancellation never rolls back a committed row. */\nexport async function runCsvImportCommands(\n commands: Array<CsvImportCommand | null>,\n dispatch: (command: CsvImportCommand) => Promise<CsvImportDispatch>,\n cancelled: () => boolean,\n progressCursor = 0,\n): Promise<CsvImportOutcome> {\n let imported = 0;\n let skipped = 0;\n let failed = 0;\n for (let index = progressCursor; index < commands.length; index += 1) {\n const command = commands[index];\n if (cancelled())\n return {\n imported,\n skipped,\n failed,\n cancelled: true,\n definitive: false,\n progressCursor: index,\n };\n if (!command) {\n skipped += 1;\n continue;\n }\n const result = await dispatch(command);\n if (result === \"committed\") {\n imported += 1;\n continue;\n }\n failed += 1;\n // A retryable or definitive outcome retains this exact command/UUID for review.\n return {\n imported,\n skipped,\n failed,\n cancelled: result === \"definitive\" || cancelled(),\n definitive: result === \"definitive\",\n progressCursor: index,\n };\n }\n return {\n imported,\n skipped,\n failed,\n cancelled: cancelled(),\n definitive: false,\n progressCursor: commands.length,\n };\n}\n","/**\n * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named\n * so that nobody can pick the wrong one by accident.\n *\n * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had\n * TWO different predicates both called `isUuid`, and the difference was\n * invisible at the call site:\n *\n * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).\n * Right for \"is this a database id or a slug?\", where a v7 id, a nil UUID\n * and a hand-made test fixture must all pass.\n * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally\n * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.\n * Right for a validation door on a public route, where the only ids that\n * should ever arrive are ones this system minted.\n *\n * They were never reconciled because there was no shared home; the census had\n * to allowlist two of them as \"provably a different capability\". Both now live\n * here, under names that say which is which, and `isUuid` is deliberately NOT\n * exported: a caller must choose.\n *\n * Note the strict predicate REJECTS values the lax one accepts, including the\n * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.\n * Never swap one for the other to make a test pass.\n *\n * TWO MORE CONTRACTS, 2026-09-30 (the UUID collapse census, 11 sites). Each is\n * its own export rather than an option on the two above, because an options\n * parameter breaks every `.every(isUuidShape)` / `.filter(isRfc4122Uuid)`\n * callback: the array passes its index as the second argument, which no longer\n * type-checks (proved with tsc before this was written).\n *\n * - `isRfc9562Uuid` — version 1–8 + variant, the current RFC 9562 set, so a\n * v6/v7/v8 id passes where `isRfc4122Uuid` (1–5) rejects it. A separate\n * name, not `isRfc4122Uuid(v, { versions })`, because the standard IS the\n * unit: a function named 4122 must not answer a 9562 question.\n * - `isLowercaseUuidShape` — any version, lower-case only. A real protocol\n * contract, not taste: the local-browser wire protocol identifies calls\n * and admissions by string equality, and both peers (matrx-local's\n * `str(uuid.UUID(v)) == v`, aidream's \"must be a canonical UUID\") reject\n * any other spelling, so the extension must too.\n *\n * A `string` argument gets a plain boolean, not a type predicate: `value is\n * string` on an input that is already a string narrows the FALSE branch to\n * `never`, so `if (isRfc4122Uuid(s)) return …; s.toLowerCase()` stopped\n * compiling (matrx-frontend linkOrganization, 2026-09-30). Any other input\n * keeps the `value is string` guard; that overload is last so `.every(…)` /\n * `.filter(…)` callbacks still narrow.\n */\n\n/**\n * 8-4-4-4-12 hex, any version, any variant, either case — the pattern\n * {@link isUuidShape} tests, EXPORTED (0.34.0) for schemas that must carry a\n * pattern rather than a predicate: `z.string().regex(UUID_SHAPE_PATTERN)`.\n * A zod schema that is codegen source (JSON Schema → Pydantic) keeps the\n * pattern; `.refine(isUuidShape)` would vanish from the generated contract.\n *\n * It spells the case out (`[0-9a-fA-F]`) and carries NO flags, on purpose:\n * a regex flag does not survive into a JSON Schema `pattern`, so an `i` flag\n * would make the Python side reject upper-case ids zod accepts. No `g` flag\n * either, so the shared object holds no `lastIndex` state.\n */\nexport const UUID_SHAPE_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\nconst UUID_SHAPE_RE = UUID_SHAPE_PATTERN;\n\n/** 8-4-4-4-12 hex with an RFC-4122 version (1–5) and variant (8/9/a/b). */\nconst RFC_4122_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 hex with an RFC-9562 version (1–8) and variant (8/9/a/b). */\nconst RFC_9562_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 LOWER-CASE hex, any version, any variant. No `i` flag. */\nconst LOWERCASE_UUID_SHAPE_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * True when `value` has UUID *shape* — the right question for \"did I get an\n * id or a slug?\". Accepts every UUID version plus the nil UUID.\n */\nexport function isUuidShape(value: string): boolean;\nexport function isUuidShape(value: unknown): value is string;\nexport function isUuidShape(value: unknown): boolean {\n return typeof value === \"string\" && UUID_SHAPE_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,\n * variant 8/9/a/b) — the right question for a validation door on a public\n * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.\n */\nexport function isRfc4122Uuid(value: string): boolean;\nexport function isRfc4122Uuid(value: unknown): value is string;\nexport function isRfc4122Uuid(value: unknown): boolean {\n return typeof value === \"string\" && RFC_4122_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid, VERSIONED RFC-9562 UUID\n * (version 1–8, variant 8/9/a/b), case-insensitive. The modern strict check:\n * accepts v6/v7/v8 ids that {@link isRfc4122Uuid} rejects. Like it, rejects the\n * special Nil (`0000…`) and Max (`ffff…`) UUIDs — neither is a minted id.\n */\nexport function isRfc9562Uuid(value: string): boolean;\nexport function isRfc9562Uuid(value: unknown): value is string;\nexport function isRfc9562Uuid(value: unknown): boolean {\n return typeof value === \"string\" && RFC_9562_RE.test(value);\n}\n\n/**\n * True when `value` has UUID shape AND is spelled in lower case — the\n * canonical text form a wire protocol compares by string equality. Any\n * version and the nil UUID pass; `3F25…` fails where {@link isUuidShape}\n * would accept it.\n */\nexport function isLowercaseUuidShape(value: string): boolean;\nexport function isLowercaseUuidShape(value: unknown): value is string;\nexport function isLowercaseUuidShape(value: unknown): boolean {\n return typeof value === \"string\" && LOWERCASE_UUID_SHAPE_RE.test(value);\n}\n","/** Bitwarden's plain JSON export adapter. Parsing is only invoked by its worker. */\nimport { LosslessNumber, stringify } from \"lossless-json\";\nimport { parse } from \"./strict-json\";\n\nimport { safeDestination, type CsvImportLimits } from \"./csv-import\";\nimport type { StructuredImportRecord } from \"./structured-import\";\nimport { isRfc4122Uuid } from \"@ai-matrx/kit/uuid\";\n\ntype JsonObject = Record<string, unknown>;\nconst rootKeys = new Set([\"encrypted\", \"folders\", \"items\"]);\nconst folderKeys = new Set([\"id\", \"name\"]);\nconst itemKeys = new Set([\"id\", \"name\", \"type\", \"folderId\", \"organizationId\", \"collectionIds\", \"notes\", \"login\", \"secureNote\", \"card\", \"identity\", \"sshKey\", \"favorite\", \"reprompt\", \"fields\", \"passwordHistory\", \"revisionDate\", \"creationDate\", \"deletedDate\", \"attachments\"]);\nconst loginKeys = new Set([\"username\", \"password\", \"totp\", \"uris\", \"fido2Credentials\"]);\nconst uriKeys = new Set([\"uri\", \"match\"]);\nconst sshKeys = new Set([\"privateKey\", \"publicKey\", \"keyFingerprint\"]);\nconst fieldKeys = new Set([\"name\", \"value\", \"type\", \"linkedId\"]);\nconst noteKeys = new Set([\"type\"]);\nconst cardKeys = new Set([\"cardholderName\", \"expMonth\", \"expYear\", \"code\", \"brand\", \"number\"]);\nconst identityKeys = new Set([\"title\", \"firstName\", \"middleName\", \"lastName\", \"address1\", \"address2\", \"address3\", \"city\", \"state\", \"postalCode\", \"country\", \"company\", \"email\", \"phone\", \"ssn\", \"username\", \"passportNumber\", \"licenseNumber\"]);\n\nfunction object(value: unknown): JsonObject | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as JsonObject : null;\n}\nfunction bytes(value: string): number {\n return typeof TextEncoder !== \"undefined\" ? new TextEncoder().encode(value).byteLength : unescape(encodeURIComponent(value)).length;\n}\nfunction only(value: JsonObject, allowed: Set<string>): boolean { return Object.keys(value).every((key) => allowed.has(key)); }\nfunction stringOrNull(value: unknown): value is string | null { return value === null || typeof value === \"string\"; }\nfunction exactInt(value: unknown, min: number, max: number): boolean {\n const text = value instanceof LosslessNumber ? value.value : \"\";\n return /^(0|[1-9][0-9]*)$/.test(text) && Number(text) >= min && Number(text) <= max;\n}\nfunction timestamp(value: unknown): boolean { return typeof value === \"string\" && /^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.\\d+)?(?:Z|[+-]\\d\\d:\\d\\d)$/.test(value); }\nexport function jsonDepthOk(value: unknown, maxDepth: number): boolean {\n const stack: Array<[unknown, number]> = [[value, 1]];\n while (stack.length) {\n const [node, depth] = stack.pop()!;\n if (depth > maxDepth) return false;\n const record = object(node);\n const children: unknown[] = Array.isArray(node)\n ? node\n : record\n ? Object.values(record)\n : [];\n for (const child of children) stack.push([child, depth + 1]);\n }\n return true;\n}\nfunction allStringsWithin(value: unknown, maxBytes: number): boolean {\n if (typeof value === \"string\") return bytes(value) <= maxBytes;\n if (Array.isArray(value)) return value.every((entry) => allStringsWithin(entry, maxBytes));\n const record = object(value);\n return !record || Object.values(record).every((entry) => allStringsWithin(entry, maxBytes));\n}\nfunction invalid(title: string, ordinal: number, reason: string): StructuredImportRecord { return { ordinal, title, status: \"invalid\", reason }; }\nfunction unsupported(title: string, ordinal: number, reason: string): StructuredImportRecord { return { ordinal, title, status: \"unsupported\", reason }; }\n\nfunction itemRecord(item: JsonObject, ordinal: number, maxCellBytes: number, maxJsonDepth: number, folders: JsonObject[]): StructuredImportRecord {\n const candidateTitle = typeof item.name === \"string\" ? item.name : `Item ${ordinal + 1}`;\n const title = bytes(candidateTitle) <= maxCellBytes ? candidateTitle : `Item ${ordinal + 1}`;\n if (!only(item, itemKeys)) return unsupported(title, ordinal, \"The item has an unsupported field.\");\n if (!isRfc4122Uuid(item.id) || typeof item.name !== \"string\" || !exactInt(item.type, 1, 5)) return exactInt(item.type, 0, Number.MAX_SAFE_INTEGER) ? unsupported(title, ordinal, \"The item type is unsupported.\") : invalid(title, ordinal, \"The item shape is not supported.\");\n if (![\"folderId\", \"organizationId\", \"notes\"].every((key) => item[key] === undefined || stringOrNull(item[key])) || [\"revisionDate\", \"creationDate\", \"deletedDate\"].some((key) => item[key] !== undefined && item[key] !== null && !timestamp(item[key])) || (item.folderId != null && !isRfc4122Uuid(item.folderId)) || (item.organizationId != null && !isRfc4122Uuid(item.organizationId)) || (item.collectionIds != null && (!Array.isArray(item.collectionIds) || !item.collectionIds.every(isRfc4122Uuid))) || (item.favorite != null && typeof item.favorite !== \"boolean\") || (item.reprompt != null && !exactInt(item.reprompt, 0, 1))) return invalid(title, ordinal, \"The item metadata is invalid.\");\n if (item.fields != null && (!Array.isArray(item.fields) || !item.fields.every((field) => { const row = object(field); return !!row && only(row, fieldKeys) && exactInt(row.type, 0, 3) && (row.name === undefined || stringOrNull(row.name)) && (row.value === undefined || stringOrNull(row.value)) && (row.linkedId === undefined || row.linkedId === null || exactInt(row.linkedId, 0, 4294967295)); }))) return invalid(title, ordinal, \"The custom fields are invalid.\");\n if (item.passwordHistory != null && (!Array.isArray(item.passwordHistory) || !item.passwordHistory.every((entry) => { const row = object(entry); return !!row && Object.keys(row).length === 2 && typeof row.password === \"string\" && timestamp(row.lastUsedDate); }))) return invalid(title, ordinal, \"The password history is invalid.\");\n if (item.attachments !== undefined && item.attachments !== null && !Array.isArray(item.attachments)) return invalid(title, ordinal, \"The attachment fields are invalid.\");\n if (!jsonDepthOk(item, maxJsonDepth) || !allStringsWithin(item, maxCellBytes)) return invalid(title, ordinal, \"The item exceeds the import limits.\");\n const type = Number((item.type as LosslessNumber).value);\n const matching = type === 1 ? \"login\" : type === 2 ? \"secureNote\" : type === 3 ? \"card\" : type === 4 ? \"identity\" : \"sshKey\";\n for (const component of [\"login\", \"secureNote\", \"card\", \"identity\", \"sshKey\"] as const) if (component !== matching && item[component] != null) return unsupported(title, ordinal, \"The item has an unclassified component.\");\n if (Array.isArray(item.attachments) && item.attachments.length) return unsupported(title, ordinal, \"Attachments require a later import path.\");\n const sourceRecord = (stringify({ source_vendor: \"bitwarden\", format: \"bitwarden-json-export-v1\", item, folders: typeof item.folderId === \"string\" ? folders.filter((folder) => folder.id === item.folderId) : [] }) ?? \"\");\n if (type === 1) {\n const login = object(item.login); if (!login) return invalid(title, ordinal, \"The login fields are invalid.\"); if (!only(login, loginKeys)) return unsupported(title, ordinal, \"The login has an unsupported field.\"); if (![\"username\", \"password\", \"totp\"].every((key) => login[key] === undefined || stringOrNull(login[key])) || (login.uris !== undefined && !Array.isArray(login.uris)) || (login.fido2Credentials !== undefined && !Array.isArray(login.fido2Credentials))) return invalid(title, ordinal, \"The login fields are invalid.\");\n if (Array.isArray(login.fido2Credentials) && login.fido2Credentials.length) return unsupported(title, ordinal, \"Passkeys require a later import path.\");\n const rawUrls: string[] = [];\n for (const uri of login.uris ?? []) { const row = object(uri); if (!row || !only(row, uriKeys)) return unsupported(title, ordinal, \"The login has an unsupported URL field.\"); if ((row.uri !== undefined && !stringOrNull(row.uri)) || (row.match !== undefined && row.match !== null && !exactInt(row.match, 0, 5))) return invalid(title, ordinal, \"The login URL fields are invalid.\"); if (typeof row.uri === \"string\") rawUrls.push(row.uri); }\n return { ordinal, title, kind: \"website_login\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, urls: rawUrls.map(safeDestination).flatMap((x) => x.metadata ? [x.metadata] : []), username: typeof login.username === \"string\" ? login.username : null, password: typeof login.password === \"string\" ? login.password : null, hasOtp: typeof login.totp === \"string\" && login.totp.length > 0 };\n }\n if (type === 5) { const key = object(item.sshKey); if (!key || !only(key, sshKeys) || typeof key.privateKey !== \"string\" || !key.privateKey || typeof key.publicKey !== \"string\" || typeof key.keyFingerprint !== \"string\") return invalid(title, ordinal, \"The SSH key fields are invalid.\"); return { ordinal, title, kind: \"ssh_key\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, hasOtp: false, privateKey: key.privateKey, publicKey: key.publicKey }; }\n const component = object(item[matching]); const allowed = type === 2 ? noteKeys : type === 3 ? cardKeys : identityKeys;\n if (!component) return invalid(title, ordinal, \"The item fields are invalid.\"); if (!only(component, allowed)) return unsupported(title, ordinal, \"The item has an unsupported field.\");\n if (type === 2 && !exactInt(component.type, 0, 0)) return invalid(title, ordinal, \"The secure note type is invalid.\");\n if (Object.entries(component).some(([key, value]) => key !== \"type\" && !stringOrNull(value))) return invalid(title, ordinal, \"The item fields are invalid.\");\n return { ordinal, title, kind: \"custom\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, hasOtp: false };\n}\n\nexport function parseBitwardenExport(text: string, limits: Pick<CsvImportLimits, \"maxFileBytes\" | \"maxRecords\" | \"maxCellBytes\"> & { maxJsonDepth: number }): StructuredImportRecord[] {\n if (bytes(text) > limits.maxFileBytes) throw new Error(\"The file exceeds this organization’s import size limit.\");\n // Our pinned lossless-json patch rejects every duplicate key, including equal values; keep its details out of UI.\n let root: JsonObject; try { root = object(parse(text)) ?? {}; } catch { throw new Error(\"The JSON export has duplicate keys or could not be read safely.\"); }\n if (!jsonDepthOk(root, limits.maxJsonDepth) || !only(root, rootKeys) || root.encrypted !== false || !Array.isArray(root.folders) || !Array.isArray(root.items)) throw new Error(root.encrypted === true ? \"Encrypted Bitwarden exports need local decryption support before they can be imported.\" : \"This is not a supported plain Bitwarden JSON export.\");\n if (root.items.length > limits.maxRecords) throw new Error(\"The export has more records than this organization allows.\");\n if (!root.folders.every((folder) => { const row = object(folder); return !!row && only(row, folderKeys) && isRfc4122Uuid(row.id) && typeof row.name === \"string\" && allStringsWithin(row, limits.maxCellBytes); })) throw new Error(\"The export folders are not supported.\");\n return root.items.map((item, ordinal) => object(item) ? itemRecord(item, ordinal, limits.maxCellBytes, limits.maxJsonDepth, root.folders as JsonObject[]) : invalid(`Item ${ordinal + 1}`, ordinal, \"The item is invalid.\"));\n}\n","import { parseBitwardenExport } from \"./bitwarden-json\";\nimport type {\n StructuredImportWorkerRequest,\n StructuredImportWorkerResponse,\n} from \"./structured-import-worker-protocol\";\n\nexport function createBitwardenJsonWorkerMessageHandler(\n post: (response: StructuredImportWorkerResponse) => void,\n) {\n let active: { requestId: string; controller: AbortController } | undefined;\n return async (request: StructuredImportWorkerRequest): Promise<void> => {\n if (request.type === \"cancel\") {\n if (active?.requestId === request.requestId) {\n active.controller.abort();\n active = undefined;\n }\n return;\n }\n active?.controller.abort();\n const operation = {\n requestId: request.requestId,\n controller: new AbortController(),\n };\n active = operation;\n try {\n if (request.file.size > request.limits.maxFileBytes)\n throw new Error(\n \"The file exceeds this organization’s import size limit.\",\n );\n const bytes = await request.file.arrayBuffer();\n if (operation.controller.signal.aborted) return;\n const text = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n const records = parseBitwardenExport(text, request.limits);\n if (active !== operation || operation.controller.signal.aborted) return;\n post({\n ok: true,\n requestId: request.requestId,\n records,\n fileNotices: [],\n });\n } catch {\n if (active !== operation || operation.controller.signal.aborted) return;\n post({\n ok: false,\n requestId: request.requestId,\n error: \"The JSON export could not be read.\",\n });\n } finally {\n if (active === operation) active = undefined;\n }\n };\n}\n\nif (typeof self !== \"undefined\") {\n const handle = createBitwardenJsonWorkerMessageHandler((response) =>\n self.postMessage(response),\n );\n self.onmessage = (event: MessageEvent<StructuredImportWorkerRequest>) => {\n void handle(event.data);\n };\n}\n"],"mappings":"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","names":["isInteger","value","INTEGER_REGEX","test","isNumber","NUMBER_REGEX","isSafeNumber","config","Number","isSafeInteger","parseInt","num","parseFloat","parsed","String","valueDigits","extractSignificantDigits","parsedDigits","approx","requiredDigits","length","startsWith","substring","UnsafeNumberReason","getUnsafeNumberReason","undefined","truncate_integer","isFinite","overflow","underflow","truncate_float","extractSignificantDigits","value","start","end","getSignificantDigitRange","digits","substring","dot","indexOf","lastIndexOf","length","LosslessNumber","isLosslessNumber","constructor","value","isNumber","Error","valueOf","unsafeReason","getUnsafeNumberReason","undefined","UnsafeNumberReason","truncate_float","Number","parseFloat","isInteger","BigInt","toString","parseLosslessNumber","value","LosslessNumber","revive","json","reviver","reviveValue","context","key","value","Array","isArray","call","reviveArray","isLosslessNumber","reviveObject","object","Object","keys","undefined","array","i","length","String","parse","text","reviver","options","optionsObj","parseNumber","parseLosslessNumber","onDuplicateKey","throwDuplicateKey","i","value","parseValue","expectValue","expectEndOfInput","revive","parseObject","charCodeAt","codeOpeningBrace","skipWhitespace","object","initial","length","codeClosingBrace","eatComma","start","key","parseString","undefined","throwObjectKeyExpected","eatColon","throwObjectValueExpected","Object","prototype","hasOwnProperty","call","isDeepEqual","returnedValue","position","oldValue","newValue","throwObjectKeyOrEndExpected","parseArray","codeOpeningBracket","array","codeClosingBracket","expectArrayItem","push","throwArrayItemOrEndExpected","parseNumeric","parseKeyword","name","slice","isWhitespace","codeDoubleQuote","result","codeBackslash","char","escapeChar","escapeCharacters","isHex","String","fromCharCode","Number","parseInt","throwInvalidUnicodeCharacter","throwInvalidEscapeCharacter","isValidStringCharacter","throwInvalidCharacter","expectEndOfString","codeMinus","expectDigit","codeZero","isNonZeroDigit","isDigit","codeDot","codeLowercaseE","codeUppercaseE","codePlus","codeComma","SyntaxError","gotAt","codeColon","numSoFar","_ref","pos","chars","got","code","codeSpace","codeNewline","codeTab","codeReturn","codeNine","codeUppercaseA","codeUppercaseF","codeLowercaseA","codeLowercaseF","codeOne","a","b","Array","isArray","every","item","index","isObject","keys","Set","f","n","r","t","stringify","value","replacer","space","numberStringifiers","resolvedSpace","resolveSpace","replacedValue","call","stringifyValue","indent","Array","isArray","stringifier","find","item","test","str","isNumber","Error","Date","Boolean","Number","String","JSON","isLosslessNumber","toString","stringifyArray","stringifyObject","undefined","array","length","childIndent","i","object","toJSON","keys","map","Object","first","key","includeProperty","keyStr","_key","repeat","parse","component","parse","bytes"]}
|
|
1
|
+
{"version":3,"sources":["../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/utils.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/LosslessNumber.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/numberParsers.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/revive.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/parse.ts","../../../../node_modules/.pnpm/lossless-json@4.3.1/node_modules/lossless-json/src/stringify.ts","../../src/io/strict-json.ts","../../src/io/csv-import.ts","../../../kit/src/uuid.ts","../../src/io/bitwarden-json.ts","../../src/io/bitwarden-json.worker.ts"],"sourcesContent":["import type { NumberSplit } from './types'\n\n/**\n * Test whether a string contains an integer number\n */\nexport function isInteger(value: string): boolean {\n return INTEGER_REGEX.test(value)\n}\n\nconst INTEGER_REGEX = /^-?[0-9]+$/\n\n/**\n * Test whether a string contains a number\n * http://stackoverflow.com/questions/13340717/json-numbers-regular-expression\n */\nexport function isNumber(value: string): boolean {\n return NUMBER_REGEX.test(value)\n}\n\nconst NUMBER_REGEX = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$/\n\n/**\n * Test whether a string can be safely represented with a number\n * without information loss.\n *\n * When approx is true, floating point numbers that lose a few digits but\n * are still approximately equal in value are considered safe too.\n * Integer numbers must still be exactly equal.\n */\nexport function isSafeNumber(\n value: string,\n config?: {\n approx: boolean\n }\n): boolean {\n if (isInteger(value)) {\n return Number.isSafeInteger(Number.parseInt(value, 10))\n }\n\n const num = Number.parseFloat(value)\n const parsed = String(num)\n\n if (value === parsed) {\n return true\n }\n\n const valueDigits = extractSignificantDigits(value)\n const parsedDigits = extractSignificantDigits(parsed)\n\n if (valueDigits === parsedDigits) {\n return true\n }\n\n if (config?.approx === true) {\n // A value is approximately equal when:\n // 1. it is a floating point number, not an integer\n // 2. it has at least 14 digits\n // 3. the first 14 digits are equal\n const requiredDigits = 14\n if (\n !isInteger(value) &&\n parsedDigits.length >= requiredDigits &&\n valueDigits.startsWith(parsedDigits.substring(0, requiredDigits))\n ) {\n return true\n }\n }\n\n return false\n}\n\nexport enum UnsafeNumberReason {\n underflow = 'underflow',\n overflow = 'overflow',\n truncate_integer = 'truncate_integer',\n truncate_float = 'truncate_float'\n}\n\n/**\n * When the provided value is an unsafe number, describe what the reason is:\n * overflow, underflow, truncate_integer, or truncate_float.\n * Returns undefined when the value is safe.\n */\nexport function getUnsafeNumberReason(value: string): UnsafeNumberReason | undefined {\n if (isSafeNumber(value, { approx: false })) {\n return undefined\n }\n\n if (isInteger(value)) {\n return UnsafeNumberReason.truncate_integer\n }\n\n const num = Number.parseFloat(value)\n if (!Number.isFinite(num)) {\n return UnsafeNumberReason.overflow\n }\n\n if (num === 0) {\n return UnsafeNumberReason.underflow\n }\n\n return UnsafeNumberReason.truncate_float\n}\n\n/**\n * Convert a string into a number when it is safe to do so.\n * Throws an error otherwise, explaining the reason.\n */\nexport function toSafeNumberOrThrow(\n value: string,\n config?: {\n approx: boolean\n }\n): number {\n const number = Number.parseFloat(value)\n\n const unsafeReason = getUnsafeNumberReason(value)\n if (\n config?.approx === true\n ? unsafeReason && unsafeReason !== UnsafeNumberReason.truncate_float\n : unsafeReason\n ) {\n const unsafeReasonText = unsafeReason?.replace(/_\\w+$/, '')\n throw new Error(\n `Cannot safely convert to number: the value '${value}' would ${unsafeReasonText} and become ${number}`\n )\n }\n\n return number\n}\n\n/**\n * Split a number into sign, digits, and exponent.\n * Leading zeros and non-canonical zeros are normalized.\n *\n * The value can be constructed again from a split number by inserting a dot\n * at the second character of the digits if there is more than one digit,\n * prepending it with the sign, and appending an \"e\" and the exponent as follows:\n *\n * const reconstructed = `${sign}${digits[0]}.${digits.slice(1)}e${exponent}`\n *\n */\nexport function splitNumber(value: string): NumberSplit {\n const match = value.match(/^(-?)(\\d+\\.?\\d*)([eE]([+-]?\\d+))?$/)\n if (!match) {\n throw new SyntaxError(`Invalid number: ${value}`)\n }\n\n const sign = match[1] as '-' | ''\n const digitsStr = match[2]\n let exponent = match[4] !== undefined ? Number.parseInt(match[4], 10) : 0\n\n const dot = digitsStr.indexOf('.')\n exponent += dot !== -1 ? dot - 1 : digitsStr.length - 1\n\n const digits = digitsStr\n .replace('.', '') // remove the dot (must be removed before removing leading zeros)\n .replace(/^0*/, (zeros: string) => {\n // remove leading zeros, add their count to the exponent\n exponent -= zeros.length\n return ''\n })\n .replace(/0*$/, '') // remove trailing zeros\n\n // normalize zero, for example normalizes 0e5 or -0 into 0\n return digits.length > 0 ? { sign, digits, exponent } : { sign: '', digits: '0', exponent: 0 }\n}\n\n/**\n * Compare two strings containing a numeric value\n * Returns 1 when a is larger than b, 0 when they are equal,\n * and -1 when a is smaller than b.\n */\nexport function compareNumber(a: string, b: string): 1 | 0 | -1 {\n if (a === b) {\n return 0\n }\n\n const aa = splitNumber(a)\n const bb = splitNumber(b)\n\n type Sign = -1 | 1\n\n const sign: Sign = aa.sign === '-' ? -1 : 1\n\n if (aa.sign !== bb.sign) {\n return sign\n }\n\n if (aa.exponent !== bb.exponent) {\n return aa.exponent > bb.exponent ? sign : aa.exponent < bb.exponent ? (-sign as Sign) : 0\n }\n\n return aa.digits > bb.digits ? sign : aa.digits < bb.digits ? (-sign as Sign) : 0\n}\n\n/**\n * Count the significant digits of a number.\n *\n * For example:\n * '2.34' returns 3\n * '-77' returns 2\n * '0.003400' returns 2\n * '120.5e+30' returns 4\n **/\nexport function countSignificantDigits(value: string): number {\n const { start, end } = getSignificantDigitRange(value)\n\n const dot = value.indexOf('.')\n if (dot === -1 || dot < start || dot > end) {\n return end - start\n }\n\n return end - start - 1\n}\n\n/**\n * Get the significant digits of a number.\n *\n * For example:\n * '2.34' returns '234'\n * '-77' returns '77'\n * '0.003400' returns '34'\n * '120.5e+30' returns '1205'\n **/\nexport function extractSignificantDigits(value: string): string {\n const { start, end } = getSignificantDigitRange(value)\n\n const digits = value.substring(start, end)\n\n const dot = digits.indexOf('.')\n if (dot === -1) {\n return digits\n }\n\n return digits.substring(0, dot) + digits.substring(dot + 1)\n}\n\n/**\n * Returns the range (start to end) of the significant digits of a value.\n * Note that this range _may_ contain the decimal dot.\n *\n * For example:\n *\n * getSignificantDigitRange('0.0325900') // { start: 3, end: 7 }\n * getSignificantDigitRange('2.0300') // { start: 0, end: 3 }\n * getSignificantDigitRange('0.0') // { start: 3, end: 3 }\n *\n */\nfunction getSignificantDigitRange(value: string): { start: number; end: number } {\n let start = 0\n if (value[0] === '-') {\n start++\n }\n while (value[start] === '0' || value[start] === '.') {\n start++\n }\n\n let end = value.lastIndexOf('e')\n if (end === -1) {\n end = value.lastIndexOf('E')\n }\n if (end === -1) {\n end = value.length\n }\n while ((value[end - 1] === '0' || value[end - 1] === '.') && end > start) {\n end--\n }\n\n return { start, end }\n}\n","import {\n compareNumber,\n countSignificantDigits,\n getUnsafeNumberReason,\n isInteger,\n isNumber,\n UnsafeNumberReason\n} from './utils.js'\n\n/**\n * A lossless number. Stores its numeric value as string\n */\nexport class LosslessNumber {\n // numeric value as string\n value: string\n\n // type information\n isLosslessNumber = true\n\n constructor(value: string) {\n if (!isNumber(value)) {\n throw new Error(`Invalid number (value: \"${value}\")`)\n }\n\n this.value = value\n }\n\n /**\n * Get the value of the LosslessNumber as number or bigint.\n *\n * - a number is returned for safe numbers and decimal values that only lose some insignificant digits\n * - a bigint is returned for big integer numbers\n * - an Error is thrown for values that will overflow or underflow\n *\n * Note that you can implement your own strategy for conversion by just getting the value as string\n * via .toString(), and using util functions like isInteger, isSafeNumber, getUnsafeNumberReason,\n * and toSafeNumberOrThrow to convert it to a numeric value.\n */\n valueOf(): number | bigint {\n const unsafeReason = getUnsafeNumberReason(this.value)\n\n // safe or truncate_float\n if (unsafeReason === undefined || unsafeReason === UnsafeNumberReason.truncate_float) {\n return Number.parseFloat(this.value)\n }\n\n // truncate_integer\n if (isInteger(this.value)) {\n return BigInt(this.value)\n }\n\n // overflow or underflow\n throw new Error(\n `Cannot safely convert to number: the value '${this.value}' would ${unsafeReason} and become ${Number.parseFloat(this.value)}`\n )\n }\n\n /**\n * Get the value of the LosslessNumber as string.\n */\n toString(): string {\n return this.value\n }\n\n // Note: we do NOT implement a .toJSON() method, and you should not implement\n // or use that, it cannot safely turn the numeric value in the string into\n // stringified JSON since it has to be parsed into a number first.\n}\n\n/**\n * Test whether a value is a LosslessNumber\n */\nexport function isLosslessNumber(value: unknown): value is LosslessNumber {\n // @ts-expect-error\n return (value && typeof value === 'object' && value.isLosslessNumber) || false\n}\n\n/**\n * Convert a number into a LosslessNumber if this is possible in a safe way\n * If the value has too many digits, or is NaN or Infinity, an error will be thrown\n */\nexport function toLosslessNumber(value: number): LosslessNumber {\n const maxDigits = 15\n if (countSignificantDigits(String(value)) > maxDigits) {\n throw new Error(\n `Invalid number: contains more than 15 digits and is most likely truncated and unsafe by itself (value: ${value})`\n )\n }\n\n if (Number.isNaN(value)) {\n throw new Error('Invalid number: NaN')\n }\n\n if (!Number.isFinite(value)) {\n throw new Error(`Invalid number: ${value}`)\n }\n\n return new LosslessNumber(String(value))\n}\n\n/**\n * Compare two lossless numbers.\n * Returns 1 when a is larger than b, 0 when they are equal,\n * and -1 when a is smaller than b.\n */\nexport function compareLosslessNumber(a: LosslessNumber, b: LosslessNumber): 1 | 0 | -1 {\n return compareNumber(a.value, b.value)\n}\n","import { LosslessNumber } from './LosslessNumber.js'\nimport { isInteger } from './utils.js'\n\nexport function parseLosslessNumber(value: string): LosslessNumber {\n return new LosslessNumber(value)\n}\n\nexport function parseNumberAndBigInt(value: string): number | bigint {\n return isInteger(value) ? BigInt(value) : Number.parseFloat(value)\n}\n","import { isLosslessNumber } from './LosslessNumber.js'\nimport type { GenericObject, Reviver } from './types'\n\n/**\n * Revive a json object.\n * Applies the reviver function recursively on all values in the JSON object.\n * @param json A JSON Object, Array, or value\n * @param reviver\n * A reviver function invoked with arguments `key` and `value`,\n * which must return a replacement value. The function context\n * (`this`) is the Object or Array that contains the currently\n * handled value.\n */\nexport function revive(json: unknown, reviver: Reviver): unknown {\n return reviveValue({ '': json }, '', json, reviver)\n}\n\n/**\n * Revive a value\n */\nfunction reviveValue(\n context: GenericObject<unknown> | Array<unknown>,\n key: string,\n value: unknown,\n reviver: Reviver\n): unknown {\n if (Array.isArray(value)) {\n return reviver.call(context, key, reviveArray(value, reviver))\n }\n\n if (value && typeof value === 'object' && !isLosslessNumber(value)) {\n // note the special case for LosslessNumber,\n // we don't want to iterate over the internals of a LosslessNumber\n return reviver.call(context, key, reviveObject(value as GenericObject<unknown>, reviver))\n }\n\n return reviver.call(context, key, value)\n}\n\n/**\n * Revive the properties of an object\n */\nfunction reviveObject(object: GenericObject<unknown>, reviver: Reviver) {\n for (const key of Object.keys(object)) {\n const value = reviveValue(object, key, object[key], reviver)\n if (value !== undefined) {\n object[key] = value\n } else {\n delete object[key]\n }\n }\n\n return object\n}\n\n/**\n * Revive the properties of an Array\n */\nfunction reviveArray(array: Array<unknown>, reviver: Reviver): Array<unknown> {\n for (let i = 0; i < array.length; i++) {\n array[i] = reviveValue(array, String(i), array[i], reviver)\n }\n\n return array\n}\n","import { parseLosslessNumber } from './numberParsers.js'\nimport { revive } from './revive.js'\nimport type { DuplicateKeyInfo, GenericObject, NumberParser, ParseOptions, Reviver } from './types'\n\n/**\n * The LosslessJSON.parse() method parses a string as JSON, optionally transforming\n * the value produced by parsing.\n *\n * The parser is based on the parser of Tan Li Hou shared in\n * https://lihautan.com/json-parser-with-javascript/\n *\n * @param text\n * The string to parse as JSON. See the JSON object for a description of JSON syntax.\n *\n * @param [reviver]\n * If a function, prescribes how the value originally produced by parsing is\n * transformed, before being returned.\n *\n * @param [options=ParseOptions | NumberParserArgument]\n * Pass a custom number parser. Input is a string, and the output can be unknown\n * numeric value: number, bigint, LosslessNumber, or a custom BigNumber library.\n *\n * @returns Returns the Object corresponding to the given JSON text.\n *\n * @throws Throws a SyntaxError exception if the string to parse is not valid JSON.\n */\nexport function parse(\n text: string,\n reviver?: Reviver | null,\n options?: ParseOptions | NumberParser\n): unknown {\n const optionsObj = typeof options === 'function' ? { parseNumber: options } : options\n const parseNumber = optionsObj?.parseNumber ?? parseLosslessNumber\n const onDuplicateKey = optionsObj?.onDuplicateKey ?? throwDuplicateKey\n\n let i = 0\n const value = parseValue()\n expectValue(value)\n expectEndOfInput()\n\n return reviver ? revive(value, reviver) : value\n\n function parseObject(): GenericObject<unknown> | undefined {\n if (text.charCodeAt(i) === codeOpeningBrace) {\n i++\n skipWhitespace()\n\n const object: GenericObject<unknown> = {}\n let initial = true\n while (i < text.length && text.charCodeAt(i) !== codeClosingBrace) {\n if (!initial) {\n eatComma()\n skipWhitespace()\n } else {\n initial = false\n }\n\n const start = i\n\n const key = parseString()\n if (key === undefined) {\n throwObjectKeyExpected()\n return // To make TS happy\n }\n\n skipWhitespace()\n eatColon()\n const value = parseValue()\n\n if (value === undefined) {\n throwObjectValueExpected()\n return // To make TS happy\n }\n\n // handle duplicate keys\n // biome-ignore lint/suspicious/noPrototypeBuiltins: TODO: replace with hasOwn one day, when browser support is high enough\n if (Object.prototype.hasOwnProperty.call(object, key) && !isDeepEqual(value, object[key])) {\n // Note that we could also test `if(key in object) {...}`\n // or `if (object[key] !== 'undefined') {...}`, but that is slower.\n const returnedValue = onDuplicateKey({\n key,\n position: start + 1,\n oldValue: object[key],\n newValue: value\n })\n\n if (returnedValue !== undefined) {\n object[key] = returnedValue\n }\n } else {\n object[key] = value\n }\n }\n\n if (text.charCodeAt(i) !== codeClosingBrace) {\n throwObjectKeyOrEndExpected()\n }\n i++\n\n return object\n }\n }\n\n function parseArray(): Array<unknown> | unknown {\n if (text.charCodeAt(i) === codeOpeningBracket) {\n i++\n skipWhitespace()\n\n const array = []\n let initial = true\n while (i < text.length && text.charCodeAt(i) !== codeClosingBracket) {\n if (!initial) {\n eatComma()\n } else {\n initial = false\n }\n\n const value = parseValue()\n expectArrayItem(value)\n array.push(value)\n }\n\n if (text.charCodeAt(i) !== codeClosingBracket) {\n throwArrayItemOrEndExpected()\n }\n i++\n\n return array\n }\n }\n\n function parseValue(): unknown {\n skipWhitespace()\n\n const value =\n parseString() ??\n parseNumeric() ??\n parseObject() ??\n parseArray() ??\n parseKeyword('true', true) ??\n parseKeyword('false', false) ??\n parseKeyword('null', null)\n\n skipWhitespace()\n\n return value\n }\n\n function parseKeyword(name: string, value: unknown): unknown | undefined {\n if (text.slice(i, i + name.length) === name) {\n i += name.length\n return value\n }\n }\n\n function skipWhitespace() {\n while (isWhitespace(text.charCodeAt(i))) {\n i++\n }\n }\n\n function parseString() {\n if (text.charCodeAt(i) === codeDoubleQuote) {\n i++\n let result = ''\n while (i < text.length && text.charCodeAt(i) !== codeDoubleQuote) {\n if (text.charCodeAt(i) === codeBackslash) {\n const char = text[i + 1]\n const escapeChar = escapeCharacters[char]\n if (escapeChar !== undefined) {\n result += escapeChar\n i++\n } else if (char === 'u') {\n if (\n isHex(text.charCodeAt(i + 2)) &&\n isHex(text.charCodeAt(i + 3)) &&\n isHex(text.charCodeAt(i + 4)) &&\n isHex(text.charCodeAt(i + 5))\n ) {\n result += String.fromCharCode(Number.parseInt(text.slice(i + 2, i + 6), 16))\n i += 5\n } else {\n throwInvalidUnicodeCharacter(i)\n }\n } else {\n throwInvalidEscapeCharacter(i)\n }\n } else {\n if (isValidStringCharacter(text.charCodeAt(i))) {\n result += text[i]\n } else {\n throwInvalidCharacter(text[i])\n }\n }\n i++\n }\n expectEndOfString()\n i++\n return result\n }\n }\n\n function parseNumeric() {\n const start = i\n if (text.charCodeAt(i) === codeMinus) {\n i++\n expectDigit(start)\n }\n\n if (text.charCodeAt(i) === codeZero) {\n i++\n } else if (isNonZeroDigit(text.charCodeAt(i))) {\n i++\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (text.charCodeAt(i) === codeDot) {\n i++\n expectDigit(start)\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (text.charCodeAt(i) === codeLowercaseE || text.charCodeAt(i) === codeUppercaseE) {\n i++\n if (text.charCodeAt(i) === codeMinus || text.charCodeAt(i) === codePlus) {\n i++\n }\n expectDigit(start)\n while (isDigit(text.charCodeAt(i))) {\n i++\n }\n }\n\n if (i > start) {\n return parseNumber(text.slice(start, i))\n }\n }\n\n function eatComma() {\n if (text.charCodeAt(i) !== codeComma) {\n throw new SyntaxError(`Comma ',' expected after value ${gotAt()}`)\n }\n i++\n }\n\n function eatColon() {\n if (text.charCodeAt(i) !== codeColon) {\n throw new SyntaxError(`Colon ':' expected after property name ${gotAt()}`)\n }\n i++\n }\n\n function expectValue(value: unknown) {\n if (value === undefined) {\n throw new SyntaxError(`JSON value expected ${gotAt()}`)\n }\n }\n\n function expectArrayItem(value: unknown) {\n if (value === undefined) {\n throw new SyntaxError(`Array item expected ${gotAt()}`)\n }\n }\n\n function expectEndOfInput() {\n if (i < text.length) {\n throw new SyntaxError(`Expected end of input ${gotAt()}`)\n }\n }\n\n function expectDigit(start: number) {\n if (!isDigit(text.charCodeAt(i))) {\n const numSoFar = text.slice(start, i)\n throw new SyntaxError(`Invalid number '${numSoFar}', expecting a digit ${gotAt()}`)\n }\n }\n\n function expectEndOfString() {\n if (text.charCodeAt(i) !== codeDoubleQuote) {\n throw new SyntaxError(`End of string '\"' expected ${gotAt()}`)\n }\n }\n\n function throwObjectKeyExpected() {\n throw new SyntaxError(`Quoted object key expected ${gotAt()}`)\n }\n\n function throwDuplicateKey({ key, position }: DuplicateKeyInfo) {\n throw new SyntaxError(`Duplicate key '${key}' encountered at position ${position}`)\n }\n\n function throwObjectKeyOrEndExpected() {\n throw new SyntaxError(`Quoted object key or end of object '}' expected ${gotAt()}`)\n }\n\n function throwArrayItemOrEndExpected() {\n throw new SyntaxError(`Array item or end of array ']' expected ${gotAt()}`)\n }\n\n function throwInvalidCharacter(char: string) {\n throw new SyntaxError(`Invalid character '${char}' ${pos()}`)\n }\n\n function throwInvalidEscapeCharacter(start: number) {\n const chars = text.slice(start, start + 2)\n throw new SyntaxError(`Invalid escape character '${chars}' ${pos()}`)\n }\n\n function throwObjectValueExpected() {\n throw new SyntaxError(`Object value expected after ':' ${pos()}`)\n }\n\n function throwInvalidUnicodeCharacter(start: number) {\n const chars = text.slice(start, start + 6)\n throw new SyntaxError(`Invalid unicode character '${chars}' ${pos()}`)\n }\n\n // zero based character position\n function pos(): string {\n return `at position ${i}`\n }\n\n function got(): string {\n return i < text.length ? `but got '${text[i]}'` : 'but reached end of input'\n }\n\n function gotAt(): string {\n return `${got()} ${pos()}`\n }\n}\n\nfunction isWhitespace(code: number): boolean {\n return code === codeSpace || code === codeNewline || code === codeTab || code === codeReturn\n}\n\nfunction isHex(code: number): boolean {\n return (\n (code >= codeZero && code <= codeNine) ||\n (code >= codeUppercaseA && code <= codeUppercaseF) ||\n (code >= codeLowercaseA && code <= codeLowercaseF)\n )\n}\n\nfunction isDigit(code: number): boolean {\n return code >= codeZero && code <= codeNine\n}\n\nfunction isNonZeroDigit(code: number): boolean {\n return code >= codeOne && code <= codeNine\n}\n\nexport function isValidStringCharacter(code: number): boolean {\n return code >= 0x20 && code <= 0x10ffff\n}\n\nexport function isDeepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, index) => isDeepEqual(item, b[index]))\n }\n\n if (isObject(a) && isObject(b)) {\n const keys = [...new Set([...Object.keys(a), ...Object.keys(b)])]\n return keys.every((key) => isDeepEqual(a[key], b[key]))\n }\n\n return false\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\n// map with all escape characters\nconst escapeCharacters: GenericObject<string> = {\n '\"': '\"',\n '\\\\': '\\\\',\n '/': '/',\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t'\n // note that \\u is handled separately in parseString()\n}\n\nconst codeBackslash = 0x5c // \"\\\"\nconst codeOpeningBrace = 0x7b // \"{\"\nconst codeClosingBrace = 0x7d // \"}\"\nconst codeOpeningBracket = 0x5b // \"[\"\nconst codeClosingBracket = 0x5d // \"]\"\nconst codeSpace = 0x20 // \" \"\nconst codeNewline = 0xa // \"\\n\"\nconst codeTab = 0x9 // \"\\t\"\nconst codeReturn = 0xd // \"\\r\"\nconst codeDoubleQuote = 0x0022 // \"\nconst codePlus = 0x2b // \"+\"\nconst codeMinus = 0x2d // \"-\"\nconst codeZero = 0x30\nconst codeOne = 0x31\nconst codeNine = 0x39\nconst codeComma = 0x2c // \",\"\nconst codeDot = 0x2e // \".\" (dot, period)\nconst codeColon = 0x3a // \":\"\nexport const codeUppercaseA = 0x41 // \"A\"\nexport const codeLowercaseA = 0x61 // \"a\"\nexport const codeUppercaseE = 0x45 // \"E\"\nexport const codeLowercaseE = 0x65 // \"e\"\nexport const codeUppercaseF = 0x46 // \"F\"\nexport const codeLowercaseF = 0x66 // \"f\"\n","import type { GenericObject, NumberStringifier, Replacer } from './types'\nimport { isNumber } from './utils.js'\n\n/**\n * The LosslessJSON.stringify() method converts a JavaScript value to a JSON string,\n * optionally replacing values if a replacer function is specified, or\n * optionally including only the specified properties if a replacer array is specified.\n *\n * @param value\n * The value to convert to a JSON string.\n *\n * @param [replacer]\n * A function that alters the behavior of the stringification process,\n * or an array of String and Number objects that serve as a whitelist for\n * selecting the properties of the value object to be included in the JSON string.\n * If this value is null or not provided, all properties of the object are\n * included in the resulting JSON string.\n *\n * @param [space]\n * A String or Number object that's used to insert white space into the output\n * JSON string for readability purposes. If this is a Number, it indicates the\n * number of space characters to use as white space; this number is capped at 10\n * if it's larger than that. Values less than 1 indicate that no space should be\n * used. If this is a String, the string (or the first 10 characters of the string,\n * if it's longer than that) is used as white space. If this parameter is not\n * provided (or is null), no white space is used.\n *\n * @param [numberStringifiers]\n * An optional list with additional number stringifiers, for example to serialize\n * a BigNumber. The output of the function must be valid stringified JSON.\n * When `undefined` is returned, the property will be deleted from the object.\n * The difference with using a `replacer` is that the output of a `replacer`\n * must be JSON and will be stringified afterwards, whereas the output of the\n * `numberStringifiers` is already stringified JSON.\n *\n * @returns Returns the string representation of the JSON object.\n */\nexport function stringify(\n value: unknown,\n replacer?: Replacer | null,\n space?: number | string,\n numberStringifiers?: NumberStringifier[]\n): string | undefined {\n const resolvedSpace = resolveSpace(space)\n\n const replacedValue =\n typeof replacer === 'function' ? replacer.call({ '': value }, '', value) : value\n\n return stringifyValue(replacedValue, '')\n\n /**\n * Stringify a value\n */\n function stringifyValue(value: unknown, indent: string | undefined): string | undefined {\n if (Array.isArray(numberStringifiers)) {\n const stringifier = numberStringifiers.find((item) => item.test(value))\n if (stringifier) {\n const str: unknown = stringifier.stringify(value)\n if (typeof str !== 'string' || !isNumber(str)) {\n throw new Error(\n `Invalid JSON number: output of a number stringifier must be a string containing a JSON number (output: ${str})`\n )\n }\n return str\n }\n }\n\n // boolean, null, number, string, or date\n if (\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string' ||\n value === null ||\n value instanceof Date ||\n value instanceof Boolean ||\n value instanceof Number ||\n value instanceof String\n ) {\n return JSON.stringify(value)\n }\n\n // lossless number, the secret ingredient :)\n // @ts-expect-error\n if (value?.isLosslessNumber) {\n return value.toString()\n }\n\n // BigInt\n if (typeof value === 'bigint') {\n return value.toString()\n }\n\n // Array\n if (Array.isArray(value)) {\n return stringifyArray(value, indent)\n }\n\n // Object (test lastly!)\n if (value && typeof value === 'object') {\n return stringifyObject(value as GenericObject<unknown>, indent)\n }\n\n return undefined\n }\n\n /**\n * Stringify an array\n */\n function stringifyArray(array: Array<unknown>, indent: string | undefined): string {\n if (array.length === 0) {\n return '[]'\n }\n\n const childIndent = resolvedSpace ? indent + resolvedSpace : undefined\n let str = resolvedSpace ? '[\\n' : '['\n\n for (let i = 0; i < array.length; i++) {\n const item =\n typeof replacer === 'function' ? replacer.call(array, String(i), array[i]) : array[i]\n\n if (resolvedSpace) {\n str += childIndent\n }\n\n if (typeof item !== 'undefined' && typeof item !== 'function') {\n str += stringifyValue(item, childIndent)\n } else {\n str += 'null'\n }\n\n if (i < array.length - 1) {\n str += resolvedSpace ? ',\\n' : ','\n }\n }\n\n str += resolvedSpace ? `\\n${indent}]` : ']'\n return str\n }\n\n /**\n * Stringify an object\n */\n function stringifyObject(\n object: GenericObject<unknown>,\n indent: string | undefined\n ): string | undefined {\n if (typeof object.toJSON === 'function') {\n return stringify(object.toJSON(), replacer, space, undefined)\n }\n\n const keys: string[] = Array.isArray(replacer) ? replacer.map(String) : Object.keys(object)\n\n if (keys.length === 0) {\n return '{}'\n }\n\n const childIndent = resolvedSpace ? indent + resolvedSpace : undefined\n let first = true\n let str = resolvedSpace ? '{\\n' : '{'\n\n for (const key of keys) {\n const value =\n typeof replacer === 'function' ? replacer.call(object, key, object[key]) : object[key]\n\n if (includeProperty(key, value)) {\n if (first) {\n first = false\n } else {\n str += resolvedSpace ? ',\\n' : ','\n }\n\n const keyStr = JSON.stringify(key)\n str += resolvedSpace ? `${childIndent + keyStr}: ` : `${keyStr}:`\n\n str += stringifyValue(value, childIndent)\n }\n }\n\n str += resolvedSpace ? `\\n${indent}}` : '}'\n return str\n }\n\n /**\n * Test whether to include a property in a stringified object or not.\n */\n function includeProperty(_key: string, value: unknown): boolean {\n return typeof value !== 'undefined' && typeof value !== 'function' && typeof value !== 'symbol'\n }\n}\n\n/**\n * Resolve a JSON stringify space:\n * replace a number with a string containing that number of spaces\n */\nfunction resolveSpace(space: number | string | undefined): string | undefined {\n if (typeof space === 'number') {\n return ' '.repeat(space)\n }\n\n if (typeof space === 'string' && space !== '') {\n return space\n }\n\n return undefined\n}\n","import { parse as losslessParse } from \"lossless-json\";\n\n/**\n * A JSON object that names the same key twice is refused — even when both values are equal. A\n * password-manager export with a repeated key is malformed or tampered with, and which copy wins\n * differs between readers. `lossless-json` only refuses a repeat with a DIFFERENT value (the web\n * app patched that in its own install; a patch cannot travel with this package), so every parse in\n * `io/` checks keys here first.\n */\nexport function assertNoDuplicateKeys(text: string): void {\n const stack: { keys: Set<string> | null; expectKey: boolean }[] = [];\n let i = 0;\n while (i < text.length) {\n const ch = text[i];\n if (ch === '\"') {\n const start = i;\n i++;\n while (i < text.length && text[i] !== '\"') i += text[i] === \"\\\\\" ? 2 : 1;\n const top = stack[stack.length - 1];\n if (top?.keys && top.expectKey) {\n const key = JSON.parse(text.slice(start, i + 1)) as string;\n if (top.keys.has(key)) throw new SyntaxError(`Duplicate key '${key}' encountered at position ${start + 1}`);\n top.keys.add(key);\n top.expectKey = false;\n }\n } else if (ch === \"{\") stack.push({ keys: new Set(), expectKey: true });\n else if (ch === \"[\") stack.push({ keys: null, expectKey: false });\n else if (ch === \"}\" || ch === \"]\") stack.pop();\n else if (ch === \",\") {\n const top = stack[stack.length - 1];\n if (top?.keys) top.expectKey = true;\n }\n i++;\n }\n}\n\n/** `lossless-json` `parse`, after the duplicate-key check. Every parse in `io/` uses this one. */\nexport const parseStrictJson: typeof losslessParse = (text, ...rest) => {\n assertNoDuplicateKeys(text);\n return losslessParse(text, ...rest);\n};\n","/** Local-only CSV normalization for Vault's first password-manager import. */\nimport type { VaultItemCreateRequest } from \"@ai-matrx/api/account\";\nimport { parseDelimited } from \"@ai-matrx/kit/delimited\";\n\nimport { isLoopbackUrl } from \"./loopback\";\n\nexport type CsvImportLimits = {\n maxFileBytes: number;\n maxRecords: number;\n maxColumns: number;\n maxCellBytes: number;\n maxFields: number;\n maxPlaintextFieldBytes: number;\n maxRequestBodyBytes: number;\n maxJsonDepth?: number;\n jsonWorkerTimeoutMs?: number;\n};\nexport type CsvColumnRole =\n \"title\" | \"username\" | \"password\" | \"url\" | \"notes\" | \"otp\" | \"keep\";\nexport type CsvImportRow = {\n rowNumber: number;\n cells: string[];\n issue?: \"invalid\" | \"unsupported\" | undefined;\n};\nexport type CsvImportPreview = {\n headers: string[];\n rows: CsvImportRow[];\n issues: number;\n};\nexport type CsvImportCommand = {\n rowId: string;\n body: VaultItemCreateRequest;\n hasOtp: boolean;\n};\nexport type CsvImportPreparation =\n | { status: \"ready\"; command: CsvImportCommand }\n | {\n status: \"skipped\";\n reason:\n | \"invalid\"\n | \"unsupported\"\n | \"deleted\"\n | \"archived\"\n | \"possible_duplicate\";\n }\n | { status: \"invalid\"; diagnostic: string };\nexport type CsvImportOutcome = {\n imported: number;\n skipped: number;\n failed: number;\n cancelled: boolean;\n definitive: boolean;\n /** The first command that was not confirmed. Reuse it on a same-session retry. */\n progressCursor: number;\n};\n\nexport type CsvImportDispatch = \"committed\" | \"retryable\" | \"definitive\";\n\n/** The request's owner: an organization's vault, or the person's own. */\nexport function principalOf(organizationId: string | null): NonNullable<VaultItemCreateRequest[\"principal\"]> {\n return organizationId ? { type: \"organization\", organization_id: organizationId } : { type: \"user\" };\n}\n\nfunction utf8ByteLength(value: string): number {\n if (typeof TextEncoder !== \"undefined\")\n return new TextEncoder().encode(value).byteLength;\n return unescape(encodeURIComponent(value)).length;\n}\n\nfunction csvParserInput(text: string): string {\n // The parser emits an extra empty record for the final record terminator. Remove\n // exactly that terminator; interior/explicit blank rows retain their numbers.\n return text.replace(/^\\uFEFF/, \"\").replace(/(?:\\r\\n|\\r|\\n)$/, \"\");\n}\n\nexport function parseCsvText(\n text: string,\n limits: CsvImportLimits,\n): CsvImportPreview {\n if (utf8ByteLength(text) > limits.maxFileBytes)\n throw new Error(\"The file exceeds this organization’s import size limit.\");\n const parsed = parseDelimited(csvParserInput(text), {\n delimiter: \",\",\n skipEmptyLines: false,\n });\n if (\n parsed.errors.some(\n (error) =>\n error.code !== \"TooFewFields\" && error.code !== \"TooManyFields\",\n )\n )\n throw new Error(\"The CSV could not be read. Fix the file and try again.\");\n return validateParsedCsv(parsed.data, limits);\n}\n\nfunction validateParsedCsv(\n parsed: string[][],\n limits: CsvImportLimits,\n): CsvImportPreview {\n const [headers, ...data] = parsed;\n if (!headers?.length || headers.length > limits.maxColumns)\n throw new Error(\"The CSV has an unsupported number of columns.\");\n if (data.length > limits.maxRecords)\n throw new Error(\"The CSV has more records than this organization allows.\");\n const nonLoginTypeColumn = headers.findIndex((header) =>\n /^(item )?(type|kind|category)$/i.test(header.trim()),\n );\n const unsupportedValueColumns = headers\n .map((header, index) =>\n /(?:^|[\\s_-])(passkey|webauthn|fido|attachment|file)(?:$|[\\s_-])/i.test(\n header.trim(),\n )\n ? index\n : -1,\n )\n .filter((index) => index >= 0);\n let issues = 0;\n const rows = data.map((cells, index) => {\n const invalid =\n cells.length !== headers.length ||\n cells.some((cell) => utf8ByteLength(cell) > limits.maxCellBytes) ||\n cells.every((cell) => cell.trim().length === 0);\n const type =\n nonLoginTypeColumn >= 0\n ? (cells[nonLoginTypeColumn] ?? \"\").trim().toLowerCase()\n : \"\";\n const unsupported =\n !invalid &&\n (unsupportedValueColumns.some((column) =>\n Boolean(cells[column]?.trim()),\n ) ||\n (Boolean(type) &&\n !/^(login|website|web|password|credential)$/.test(type)));\n if (invalid || unsupported) issues += 1;\n return {\n rowNumber: index + 2,\n cells,\n issue: invalid\n ? (\"invalid\" as const)\n : unsupported\n ? (\"unsupported\" as const)\n : undefined,\n };\n });\n return { headers, rows, issues };\n}\n\nexport function safeDestination(raw: string): {\n metadata: string | null;\n host: string | null;\n} {\n try {\n const parsed = new URL(raw);\n if (!/^https?:$/.test(parsed.protocol))\n return { metadata: null, host: null };\n if (parsed.username || parsed.password)\n return { metadata: null, host: null };\n return { metadata: parsed.origin, host: parsed.host };\n } catch {\n return { metadata: null, host: null };\n }\n}\n\nexport function suggestedCsvMapping(\n headers: string[],\n source?: string,\n): CsvColumnRole[] {\n const aliases: Record<CsvColumnRole, ReadonlySet<string>> = {\n title: new Set([\"name\", \"title\", \"label\"]),\n username: new Set([\n \"username\",\n \"user\",\n \"login\",\n \"email\",\n \"loginusername\",\n \"loginemail\",\n ]),\n password: new Set([\"password\", \"pass\", \"pwd\", \"loginpassword\"]),\n url: new Set([\n \"url\",\n \"uri\",\n \"website\",\n \"websiteaddress\",\n \"loginurl\",\n \"loginuri\",\n ]),\n notes: new Set([\"note\", \"notes\", \"extra\"]),\n otp: new Set([\"otp\", \"totp\", \"otpauth\", \"onetimepassword\", \"onetimecode\"]),\n keep: new Set(),\n };\n let usernameAssigned = false;\n return headers.map((header) => {\n const key = header.trim().toLowerCase().replace(/[ _-]/g, \"\");\n if (source === \"nordpass\" && key === \"email\" && usernameAssigned)\n return \"keep\";\n const role =\n (Object.entries(aliases) as [CsvColumnRole, ReadonlySet<string>][]).find(\n ([, values]) => values.has(key),\n )?.[0] ?? \"keep\";\n if (role === \"username\") usernameAssigned = true;\n return role;\n });\n}\n\nfunction fieldKey(index: number, used: Set<string>): string {\n const base = `import_column_${index + 1}`;\n let key = base;\n let suffix = 2;\n while (used.has(key)) key = `${base}_${suffix++}`;\n used.add(key);\n return key;\n}\n\nfunction roleValue(\n row: CsvImportRow,\n mapping: CsvColumnRole[],\n role: CsvColumnRole,\n): string | null {\n const index = mapping.findIndex((entry) => entry === role);\n return index < 0 ? null : (row.cells[index] ?? \"\");\n}\n\nexport function hasAmbiguousCsvMapping(mapping: CsvColumnRole[]): boolean {\n return ([\"title\", \"username\", \"password\", \"notes\", \"otp\"] as const).some(\n (role) => mapping.filter((entry) => entry === role).length > 1,\n );\n}\n\nexport function isPossibleDuplicateRow(\n row: CsvImportRow,\n _preview: CsvImportPreview,\n mapping: CsvColumnRole[],\n existingItems: { displayName: string; loginUrls: string[] }[],\n): boolean {\n if (row.issue) return false;\n const title =\n roleValue(row, mapping, \"title\") || `Imported credential ${row.rowNumber}`;\n const urls = row.cells\n .filter((_, index) => mapping[index] === \"url\")\n .map(safeDestination)\n .flatMap((destination) =>\n destination.metadata ? [destination.metadata] : [],\n );\n return existingItems.some((item) => {\n if (item.displayName !== title) return false;\n const existingOrigins = item.loginUrls\n .map(safeDestination)\n .flatMap((destination) =>\n destination.metadata ? [destination.metadata] : [],\n );\n return urls.length > 0\n ? existingOrigins.some((origin) => urls.includes(origin))\n : existingOrigins.length === 0;\n });\n}\n\nexport function prepareCsvImportRow(input: {\n source: string;\n preview: CsvImportPreview;\n row: CsvImportRow;\n mapping: CsvColumnRole[];\n /** null = the person's own vault. */\n organizationId: string | null;\n rowId: string;\n limits: CsvImportLimits;\n browserFillEnabled?: boolean;\n existingItems?: { displayName: string; loginUrls: string[] }[];\n skipPossibleDuplicate?: boolean;\n}): CsvImportPreparation {\n if (input.row.issue === \"invalid\")\n return { status: \"skipped\", reason: \"invalid\" };\n if (input.row.issue === \"unsupported\")\n return { status: \"skipped\", reason: \"unsupported\" };\n if (\n input.skipPossibleDuplicate &&\n isPossibleDuplicateRow(\n input.row,\n input.preview,\n input.mapping,\n input.existingItems ?? [],\n )\n )\n return { status: \"skipped\", reason: \"possible_duplicate\" };\n const { headers } = input.preview;\n const { row, mapping } = input;\n const title =\n roleValue(row, mapping, \"title\") || `Imported credential ${row.rowNumber}`;\n const rawUrls = row.cells\n .filter((_, index) => mapping[index] === \"url\")\n .filter(Boolean);\n const urls = rawUrls\n .map(safeDestination)\n .flatMap((url) => (url.metadata ? [url.metadata] : []));\n const fields: NonNullable<VaultItemCreateRequest[\"fields\"]> = [];\n const used = new Set<string>();\n const add = (field_key: string, value: string, editable = true) => {\n if (!value) return;\n used.add(field_key);\n fields.push({\n field_key,\n value,\n handling: \"revealable\",\n editable,\n inject_into_sandbox: false,\n });\n };\n add(\"username\", roleValue(row, mapping, \"username\") ?? \"\");\n add(\"password\", roleValue(row, mapping, \"password\") ?? \"\");\n add(\"import_notes\", roleValue(row, mapping, \"notes\") ?? \"\");\n for (let index = 0; index < row.cells.length; index += 1) {\n if (mapping[index] === \"keep\")\n add(fieldKey(index, used), row.cells[index] ?? \"\");\n }\n // OTP stays only in the encrypted, revealable source representation until explicit enrollment.\n add(\n \"import_source_record\",\n JSON.stringify({\n source_vendor: input.source,\n format: \"csv\",\n cells: row.cells.map((value: string, column_index: number) => ({\n column_index,\n header: headers[column_index] ?? \"\",\n value,\n })),\n }),\n false,\n );\n if (\n fields.length > input.limits.maxFields ||\n fields.some(\n (field) =>\n utf8ByteLength(field.value) > input.limits.maxPlaintextFieldBytes,\n )\n )\n return {\n status: \"invalid\",\n diagnostic: `Row ${row.rowNumber} exceeds this organization’s encrypted field limit.`,\n };\n const command: CsvImportCommand = {\n rowId: input.rowId,\n hasOtp: Boolean(roleValue(row, mapping, \"otp\")),\n body: {\n principal: principalOf(input.organizationId),\n display_name: title,\n definition_key: \"website_login\",\n source: \"system_import\",\n login_urls: urls,\n uri_match_mode: \"never\",\n browser_fill_enabled:\n Boolean(input.browserFillEnabled) &&\n Boolean(roleValue(row, mapping, \"username\")) &&\n Boolean(roleValue(row, mapping, \"password\")) &&\n urls.length > 0 &&\n urls.every(\n (url) => new URL(url).protocol === \"https:\" || isLoopbackUrl(url),\n ),\n fields,\n },\n };\n // The browser matcher treats `never` as an absolute refusal. Keep this pair\n // coherent with the explicit, eligible bulk opt-in rather than advertising a\n // fill capability the canonical matcher will always reject.\n if (command.body.browser_fill_enabled) command.body.uri_match_mode = \"host\";\n if (\n utf8ByteLength(JSON.stringify(command.body)) >\n input.limits.maxRequestBodyBytes\n )\n return {\n status: \"invalid\",\n diagnostic: `Row ${row.rowNumber} exceeds this organization’s request size limit.`,\n };\n return { status: \"ready\", command };\n}\n\n/** Compatibility helper for callers that only need a command after preparation. */\nexport function toCsvImportCommand(\n input: Parameters<typeof prepareCsvImportRow>[0],\n): CsvImportCommand | null {\n const prepared = prepareCsvImportRow(input);\n return prepared.status === \"ready\" ? prepared.command : null;\n}\n\n/** Dispatch only one immutable command at a time; cancellation never rolls back a committed row. */\nexport async function runCsvImportCommands(\n commands: Array<CsvImportCommand | null>,\n dispatch: (command: CsvImportCommand) => Promise<CsvImportDispatch>,\n cancelled: () => boolean,\n progressCursor = 0,\n): Promise<CsvImportOutcome> {\n let imported = 0;\n let skipped = 0;\n let failed = 0;\n for (let index = progressCursor; index < commands.length; index += 1) {\n const command = commands[index];\n if (cancelled())\n return {\n imported,\n skipped,\n failed,\n cancelled: true,\n definitive: false,\n progressCursor: index,\n };\n if (!command) {\n skipped += 1;\n continue;\n }\n const result = await dispatch(command);\n if (result === \"committed\") {\n imported += 1;\n continue;\n }\n failed += 1;\n // A retryable or definitive outcome retains this exact command/UUID for review.\n return {\n imported,\n skipped,\n failed,\n cancelled: result === \"definitive\" || cancelled(),\n definitive: result === \"definitive\",\n progressCursor: index,\n };\n }\n return {\n imported,\n skipped,\n failed,\n cancelled: cancelled(),\n definitive: false,\n progressCursor: commands.length,\n };\n}\n","/**\n * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named\n * so that nobody can pick the wrong one by accident.\n *\n * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had\n * TWO different predicates both called `isUuid`, and the difference was\n * invisible at the call site:\n *\n * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).\n * Right for \"is this a database id or a slug?\", where a v7 id, a nil UUID\n * and a hand-made test fixture must all pass.\n * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally\n * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.\n * Right for a validation door on a public route, where the only ids that\n * should ever arrive are ones this system minted.\n *\n * They were never reconciled because there was no shared home; the census had\n * to allowlist two of them as \"provably a different capability\". Both now live\n * here, under names that say which is which, and `isUuid` is deliberately NOT\n * exported: a caller must choose.\n *\n * Note the strict predicate REJECTS values the lax one accepts, including the\n * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.\n * Never swap one for the other to make a test pass.\n *\n * TWO MORE CONTRACTS, 2026-09-30 (the UUID collapse census, 11 sites). Each is\n * its own export rather than an option on the two above, because an options\n * parameter breaks every `.every(isUuidShape)` / `.filter(isRfc4122Uuid)`\n * callback: the array passes its index as the second argument, which no longer\n * type-checks (proved with tsc before this was written).\n *\n * - `isRfc9562Uuid` — version 1–8 + variant, the current RFC 9562 set, so a\n * v6/v7/v8 id passes where `isRfc4122Uuid` (1–5) rejects it. A separate\n * name, not `isRfc4122Uuid(v, { versions })`, because the standard IS the\n * unit: a function named 4122 must not answer a 9562 question.\n * - `isLowercaseUuidShape` — any version, lower-case only. A real protocol\n * contract, not taste: the local-browser wire protocol identifies calls\n * and admissions by string equality, and both peers (matrx-local's\n * `str(uuid.UUID(v)) == v`, aidream's \"must be a canonical UUID\") reject\n * any other spelling, so the extension must too.\n *\n * A `string` argument gets a plain boolean, not a type predicate: `value is\n * string` on an input that is already a string narrows the FALSE branch to\n * `never`, so `if (isRfc4122Uuid(s)) return …; s.toLowerCase()` stopped\n * compiling (matrx-frontend linkOrganization, 2026-09-30). Any other input\n * keeps the `value is string` guard; that overload is last so `.every(…)` /\n * `.filter(…)` callbacks still narrow.\n */\n\n/**\n * 8-4-4-4-12 hex, any version, any variant, either case — the pattern\n * {@link isUuidShape} tests, EXPORTED (0.34.0) for schemas that must carry a\n * pattern rather than a predicate: `z.string().regex(UUID_SHAPE_PATTERN)`.\n * A zod schema that is codegen source (JSON Schema → Pydantic) keeps the\n * pattern; `.refine(isUuidShape)` would vanish from the generated contract.\n *\n * It spells the case out (`[0-9a-fA-F]`) and carries NO flags, on purpose:\n * a regex flag does not survive into a JSON Schema `pattern`, so an `i` flag\n * would make the Python side reject upper-case ids zod accepts. No `g` flag\n * either, so the shared object holds no `lastIndex` state.\n */\nexport const UUID_SHAPE_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\nconst UUID_SHAPE_RE = UUID_SHAPE_PATTERN;\n\n/** 8-4-4-4-12 hex with an RFC-4122 version (1–5) and variant (8/9/a/b). */\nconst RFC_4122_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 hex with an RFC-9562 version (1–8) and variant (8/9/a/b). */\nconst RFC_9562_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 LOWER-CASE hex, any version, any variant. No `i` flag. */\nconst LOWERCASE_UUID_SHAPE_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * True when `value` has UUID *shape* — the right question for \"did I get an\n * id or a slug?\". Accepts every UUID version plus the nil UUID.\n */\nexport function isUuidShape(value: string): boolean;\nexport function isUuidShape(value: unknown): value is string;\nexport function isUuidShape(value: unknown): boolean {\n return typeof value === \"string\" && UUID_SHAPE_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,\n * variant 8/9/a/b) — the right question for a validation door on a public\n * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.\n */\nexport function isRfc4122Uuid(value: string): boolean;\nexport function isRfc4122Uuid(value: unknown): value is string;\nexport function isRfc4122Uuid(value: unknown): boolean {\n return typeof value === \"string\" && RFC_4122_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid, VERSIONED RFC-9562 UUID\n * (version 1–8, variant 8/9/a/b), case-insensitive. The modern strict check:\n * accepts v6/v7/v8 ids that {@link isRfc4122Uuid} rejects. Like it, rejects the\n * special Nil (`0000…`) and Max (`ffff…`) UUIDs — neither is a minted id.\n */\nexport function isRfc9562Uuid(value: string): boolean;\nexport function isRfc9562Uuid(value: unknown): value is string;\nexport function isRfc9562Uuid(value: unknown): boolean {\n return typeof value === \"string\" && RFC_9562_RE.test(value);\n}\n\n/**\n * True when `value` has UUID shape AND is spelled in lower case — the\n * canonical text form a wire protocol compares by string equality. Any\n * version and the nil UUID pass; `3F25…` fails where {@link isUuidShape}\n * would accept it.\n */\nexport function isLowercaseUuidShape(value: string): boolean;\nexport function isLowercaseUuidShape(value: unknown): value is string;\nexport function isLowercaseUuidShape(value: unknown): boolean {\n return typeof value === \"string\" && LOWERCASE_UUID_SHAPE_RE.test(value);\n}\n","/** Bitwarden's plain JSON export adapter. Parsing is only invoked by its worker. */\nimport { LosslessNumber, stringify } from \"lossless-json\";\nimport { parseStrictJson } from \"./strict-json\";\n\nimport { safeDestination, type CsvImportLimits } from \"./csv-import\";\nimport type { StructuredImportRecord } from \"./structured-import\";\nimport { isRfc4122Uuid } from \"@ai-matrx/kit/uuid\";\n\ntype JsonObject = Record<string, unknown>;\nconst rootKeys = new Set([\"encrypted\", \"folders\", \"items\"]);\nconst folderKeys = new Set([\"id\", \"name\"]);\nconst itemKeys = new Set([\"id\", \"name\", \"type\", \"folderId\", \"organizationId\", \"collectionIds\", \"notes\", \"login\", \"secureNote\", \"card\", \"identity\", \"sshKey\", \"favorite\", \"reprompt\", \"fields\", \"passwordHistory\", \"revisionDate\", \"creationDate\", \"deletedDate\", \"attachments\"]);\nconst loginKeys = new Set([\"username\", \"password\", \"totp\", \"uris\", \"fido2Credentials\"]);\nconst uriKeys = new Set([\"uri\", \"match\"]);\nconst sshKeys = new Set([\"privateKey\", \"publicKey\", \"keyFingerprint\"]);\nconst fieldKeys = new Set([\"name\", \"value\", \"type\", \"linkedId\"]);\nconst noteKeys = new Set([\"type\"]);\nconst cardKeys = new Set([\"cardholderName\", \"expMonth\", \"expYear\", \"code\", \"brand\", \"number\"]);\nconst identityKeys = new Set([\"title\", \"firstName\", \"middleName\", \"lastName\", \"address1\", \"address2\", \"address3\", \"city\", \"state\", \"postalCode\", \"country\", \"company\", \"email\", \"phone\", \"ssn\", \"username\", \"passportNumber\", \"licenseNumber\"]);\n\nfunction object(value: unknown): JsonObject | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as JsonObject : null;\n}\nfunction bytes(value: string): number {\n return typeof TextEncoder !== \"undefined\" ? new TextEncoder().encode(value).byteLength : unescape(encodeURIComponent(value)).length;\n}\nfunction only(value: JsonObject, allowed: Set<string>): boolean { return Object.keys(value).every((key) => allowed.has(key)); }\nfunction stringOrNull(value: unknown): value is string | null { return value === null || typeof value === \"string\"; }\nfunction exactInt(value: unknown, min: number, max: number): boolean {\n const text = value instanceof LosslessNumber ? value.value : \"\";\n return /^(0|[1-9][0-9]*)$/.test(text) && Number(text) >= min && Number(text) <= max;\n}\nfunction timestamp(value: unknown): boolean { return typeof value === \"string\" && /^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.\\d+)?(?:Z|[+-]\\d\\d:\\d\\d)$/.test(value); }\nexport function jsonDepthOk(value: unknown, maxDepth: number): boolean {\n const stack: Array<[unknown, number]> = [[value, 1]];\n while (stack.length) {\n const [node, depth] = stack.pop()!;\n if (depth > maxDepth) return false;\n const record = object(node);\n const children: unknown[] = Array.isArray(node)\n ? node\n : record\n ? Object.values(record)\n : [];\n for (const child of children) stack.push([child, depth + 1]);\n }\n return true;\n}\nfunction allStringsWithin(value: unknown, maxBytes: number): boolean {\n if (typeof value === \"string\") return bytes(value) <= maxBytes;\n if (Array.isArray(value)) return value.every((entry) => allStringsWithin(entry, maxBytes));\n const record = object(value);\n return !record || Object.values(record).every((entry) => allStringsWithin(entry, maxBytes));\n}\nfunction invalid(title: string, ordinal: number, reason: string): StructuredImportRecord { return { ordinal, title, status: \"invalid\", reason }; }\nfunction unsupported(title: string, ordinal: number, reason: string): StructuredImportRecord { return { ordinal, title, status: \"unsupported\", reason }; }\n\nfunction itemRecord(item: JsonObject, ordinal: number, maxCellBytes: number, maxJsonDepth: number, folders: JsonObject[]): StructuredImportRecord {\n const candidateTitle = typeof item.name === \"string\" ? item.name : `Item ${ordinal + 1}`;\n const title = bytes(candidateTitle) <= maxCellBytes ? candidateTitle : `Item ${ordinal + 1}`;\n if (!only(item, itemKeys)) return unsupported(title, ordinal, \"The item has an unsupported field.\");\n if (!isRfc4122Uuid(item.id) || typeof item.name !== \"string\" || !exactInt(item.type, 1, 5)) return exactInt(item.type, 0, Number.MAX_SAFE_INTEGER) ? unsupported(title, ordinal, \"The item type is unsupported.\") : invalid(title, ordinal, \"The item shape is not supported.\");\n if (![\"folderId\", \"organizationId\", \"notes\"].every((key) => item[key] === undefined || stringOrNull(item[key])) || [\"revisionDate\", \"creationDate\", \"deletedDate\"].some((key) => item[key] !== undefined && item[key] !== null && !timestamp(item[key])) || (item.folderId != null && !isRfc4122Uuid(item.folderId)) || (item.organizationId != null && !isRfc4122Uuid(item.organizationId)) || (item.collectionIds != null && (!Array.isArray(item.collectionIds) || !item.collectionIds.every(isRfc4122Uuid))) || (item.favorite != null && typeof item.favorite !== \"boolean\") || (item.reprompt != null && !exactInt(item.reprompt, 0, 1))) return invalid(title, ordinal, \"The item metadata is invalid.\");\n if (item.fields != null && (!Array.isArray(item.fields) || !item.fields.every((field) => { const row = object(field); return !!row && only(row, fieldKeys) && exactInt(row.type, 0, 3) && (row.name === undefined || stringOrNull(row.name)) && (row.value === undefined || stringOrNull(row.value)) && (row.linkedId === undefined || row.linkedId === null || exactInt(row.linkedId, 0, 4294967295)); }))) return invalid(title, ordinal, \"The custom fields are invalid.\");\n if (item.passwordHistory != null && (!Array.isArray(item.passwordHistory) || !item.passwordHistory.every((entry) => { const row = object(entry); return !!row && Object.keys(row).length === 2 && typeof row.password === \"string\" && timestamp(row.lastUsedDate); }))) return invalid(title, ordinal, \"The password history is invalid.\");\n if (item.attachments !== undefined && item.attachments !== null && !Array.isArray(item.attachments)) return invalid(title, ordinal, \"The attachment fields are invalid.\");\n if (!jsonDepthOk(item, maxJsonDepth) || !allStringsWithin(item, maxCellBytes)) return invalid(title, ordinal, \"The item exceeds the import limits.\");\n const type = Number((item.type as LosslessNumber).value);\n const matching = type === 1 ? \"login\" : type === 2 ? \"secureNote\" : type === 3 ? \"card\" : type === 4 ? \"identity\" : \"sshKey\";\n for (const component of [\"login\", \"secureNote\", \"card\", \"identity\", \"sshKey\"] as const) if (component !== matching && item[component] != null) return unsupported(title, ordinal, \"The item has an unclassified component.\");\n if (Array.isArray(item.attachments) && item.attachments.length) return unsupported(title, ordinal, \"Attachments require a later import path.\");\n const sourceRecord = (stringify({ source_vendor: \"bitwarden\", format: \"bitwarden-json-export-v1\", item, folders: typeof item.folderId === \"string\" ? folders.filter((folder) => folder.id === item.folderId) : [] }) ?? \"\");\n if (type === 1) {\n const login = object(item.login); if (!login) return invalid(title, ordinal, \"The login fields are invalid.\"); if (!only(login, loginKeys)) return unsupported(title, ordinal, \"The login has an unsupported field.\"); if (![\"username\", \"password\", \"totp\"].every((key) => login[key] === undefined || stringOrNull(login[key])) || (login.uris !== undefined && !Array.isArray(login.uris)) || (login.fido2Credentials !== undefined && !Array.isArray(login.fido2Credentials))) return invalid(title, ordinal, \"The login fields are invalid.\");\n if (Array.isArray(login.fido2Credentials) && login.fido2Credentials.length) return unsupported(title, ordinal, \"Passkeys require a later import path.\");\n const rawUrls: string[] = [];\n for (const uri of login.uris ?? []) { const row = object(uri); if (!row || !only(row, uriKeys)) return unsupported(title, ordinal, \"The login has an unsupported URL field.\"); if ((row.uri !== undefined && !stringOrNull(row.uri)) || (row.match !== undefined && row.match !== null && !exactInt(row.match, 0, 5))) return invalid(title, ordinal, \"The login URL fields are invalid.\"); if (typeof row.uri === \"string\") rawUrls.push(row.uri); }\n return { ordinal, title, kind: \"website_login\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, urls: rawUrls.map(safeDestination).flatMap((x) => x.metadata ? [x.metadata] : []), username: typeof login.username === \"string\" ? login.username : null, password: typeof login.password === \"string\" ? login.password : null, hasOtp: typeof login.totp === \"string\" && login.totp.length > 0 };\n }\n if (type === 5) { const key = object(item.sshKey); if (!key || !only(key, sshKeys) || typeof key.privateKey !== \"string\" || !key.privateKey || typeof key.publicKey !== \"string\" || typeof key.keyFingerprint !== \"string\") return invalid(title, ordinal, \"The SSH key fields are invalid.\"); return { ordinal, title, kind: \"ssh_key\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, hasOtp: false, privateKey: key.privateKey, publicKey: key.publicKey }; }\n const component = object(item[matching]); const allowed = type === 2 ? noteKeys : type === 3 ? cardKeys : identityKeys;\n if (!component) return invalid(title, ordinal, \"The item fields are invalid.\"); if (!only(component, allowed)) return unsupported(title, ordinal, \"The item has an unsupported field.\");\n if (type === 2 && !exactInt(component.type, 0, 0)) return invalid(title, ordinal, \"The secure note type is invalid.\");\n if (Object.entries(component).some(([key, value]) => key !== \"type\" && !stringOrNull(value))) return invalid(title, ordinal, \"The item fields are invalid.\");\n return { ordinal, title, kind: \"custom\", status: \"supported\", sourceState: item.deletedDate ? \"deleted\" : \"active\", sourceRecord, hasOtp: false };\n}\n\nexport function parseBitwardenExport(text: string, limits: Pick<CsvImportLimits, \"maxFileBytes\" | \"maxRecords\" | \"maxCellBytes\"> & { maxJsonDepth: number }): StructuredImportRecord[] {\n if (bytes(text) > limits.maxFileBytes) throw new Error(\"The file exceeds this organization’s import size limit.\");\n // Our pinned lossless-json patch rejects every duplicate key, including equal values; keep its details out of UI.\n let root: JsonObject; try { root = object(parseStrictJson(text)) ?? {}; } catch { throw new Error(\"The JSON export has duplicate keys or could not be read safely.\"); }\n if (!jsonDepthOk(root, limits.maxJsonDepth) || !only(root, rootKeys) || root.encrypted !== false || !Array.isArray(root.folders) || !Array.isArray(root.items)) throw new Error(root.encrypted === true ? \"Encrypted Bitwarden exports need local decryption support before they can be imported.\" : \"This is not a supported plain Bitwarden JSON export.\");\n if (root.items.length > limits.maxRecords) throw new Error(\"The export has more records than this organization allows.\");\n if (!root.folders.every((folder) => { const row = object(folder); return !!row && only(row, folderKeys) && isRfc4122Uuid(row.id) && typeof row.name === \"string\" && allStringsWithin(row, limits.maxCellBytes); })) throw new Error(\"The export folders are not supported.\");\n return root.items.map((item, ordinal) => object(item) ? itemRecord(item, ordinal, limits.maxCellBytes, limits.maxJsonDepth, root.folders as JsonObject[]) : invalid(`Item ${ordinal + 1}`, ordinal, \"The item is invalid.\"));\n}\n","import { parseBitwardenExport } from \"./bitwarden-json\";\nimport type {\n StructuredImportWorkerRequest,\n StructuredImportWorkerResponse,\n} from \"./structured-import-worker-protocol\";\n\nexport function createBitwardenJsonWorkerMessageHandler(\n post: (response: StructuredImportWorkerResponse) => void,\n) {\n let active: { requestId: string; controller: AbortController } | undefined;\n return async (request: StructuredImportWorkerRequest): Promise<void> => {\n if (request.type === \"cancel\") {\n if (active?.requestId === request.requestId) {\n active.controller.abort();\n active = undefined;\n }\n return;\n }\n active?.controller.abort();\n const operation = {\n requestId: request.requestId,\n controller: new AbortController(),\n };\n active = operation;\n try {\n if (request.file.size > request.limits.maxFileBytes)\n throw new Error(\n \"The file exceeds this organization’s import size limit.\",\n );\n const bytes = await request.file.arrayBuffer();\n if (operation.controller.signal.aborted) return;\n const text = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n const records = parseBitwardenExport(text, request.limits);\n if (active !== operation || operation.controller.signal.aborted) return;\n post({\n ok: true,\n requestId: request.requestId,\n records,\n fileNotices: [],\n });\n } catch {\n if (active !== operation || operation.controller.signal.aborted) return;\n post({\n ok: false,\n requestId: request.requestId,\n error: \"The JSON export could not be read.\",\n });\n } finally {\n if (active === operation) active = undefined;\n }\n };\n}\n\nif (typeof self !== \"undefined\") {\n const handle = createBitwardenJsonWorkerMessageHandler((response) =>\n self.postMessage(response),\n );\n self.onmessage = (event: MessageEvent<StructuredImportWorkerRequest>) => {\n void handle(event.data);\n };\n}\n"],"mappings":"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","names":["isInteger","value","INTEGER_REGEX","test","isNumber","NUMBER_REGEX","isSafeNumber","config","Number","isSafeInteger","parseInt","num","parseFloat","parsed","String","valueDigits","extractSignificantDigits","parsedDigits","approx","requiredDigits","length","startsWith","substring","UnsafeNumberReason","getUnsafeNumberReason","undefined","truncate_integer","isFinite","overflow","underflow","truncate_float","extractSignificantDigits","value","start","end","getSignificantDigitRange","digits","substring","dot","indexOf","lastIndexOf","length","LosslessNumber","isLosslessNumber","constructor","value","isNumber","Error","valueOf","unsafeReason","getUnsafeNumberReason","undefined","UnsafeNumberReason","truncate_float","Number","parseFloat","isInteger","BigInt","toString","parseLosslessNumber","value","LosslessNumber","revive","json","reviver","reviveValue","context","key","value","Array","isArray","call","reviveArray","isLosslessNumber","reviveObject","object","Object","keys","undefined","array","i","length","String","parse","text","reviver","options","optionsObj","parseNumber","parseLosslessNumber","onDuplicateKey","throwDuplicateKey","i","value","parseValue","expectValue","expectEndOfInput","revive","parseObject","charCodeAt","codeOpeningBrace","skipWhitespace","object","initial","length","codeClosingBrace","eatComma","start","key","parseString","undefined","throwObjectKeyExpected","eatColon","throwObjectValueExpected","Object","prototype","hasOwnProperty","call","isDeepEqual","returnedValue","position","oldValue","newValue","throwObjectKeyOrEndExpected","parseArray","codeOpeningBracket","array","codeClosingBracket","expectArrayItem","push","throwArrayItemOrEndExpected","parseNumeric","parseKeyword","name","slice","isWhitespace","codeDoubleQuote","result","codeBackslash","char","escapeChar","escapeCharacters","isHex","String","fromCharCode","Number","parseInt","throwInvalidUnicodeCharacter","throwInvalidEscapeCharacter","isValidStringCharacter","throwInvalidCharacter","expectEndOfString","codeMinus","expectDigit","codeZero","isNonZeroDigit","isDigit","codeDot","codeLowercaseE","codeUppercaseE","codePlus","codeComma","SyntaxError","gotAt","codeColon","numSoFar","_ref","pos","chars","got","code","codeSpace","codeNewline","codeTab","codeReturn","codeNine","codeUppercaseA","codeUppercaseF","codeLowercaseA","codeLowercaseF","codeOne","a","b","Array","isArray","every","item","index","isObject","keys","Set","f","n","r","t","stringify","value","replacer","space","numberStringifiers","resolvedSpace","resolveSpace","replacedValue","call","stringifyValue","indent","Array","isArray","stringifier","find","item","test","str","isNumber","Error","Date","Boolean","Number","String","JSON","isLosslessNumber","toString","stringifyArray","stringifyObject","undefined","array","length","childIndent","i","object","toJSON","keys","map","Object","first","key","includeProperty","keyStr","_key","repeat","component","bytes"]}
|
package/dist/io/onepux.worker.js
CHANGED
|
@@ -5054,7 +5054,7 @@ function assertNoDuplicateKeys(text) {
|
|
|
5054
5054
|
i++;
|
|
5055
5055
|
}
|
|
5056
5056
|
}
|
|
5057
|
-
var
|
|
5057
|
+
var parseStrictJson = (text, ...rest) => {
|
|
5058
5058
|
assertNoDuplicateKeys(text);
|
|
5059
5059
|
return parse(text, ...rest);
|
|
5060
5060
|
};
|
|
@@ -5211,7 +5211,7 @@ function parseOnePuxData(exportAttributesText, exportDataText, limits) {
|
|
|
5211
5211
|
if (bytes(exportAttributesText) + bytes(exportDataText) > limits.maxFileBytes) throw new Error("The 1Password export exceeds this organization\u2019s import size limit.");
|
|
5212
5212
|
let exportAttributes;
|
|
5213
5213
|
try {
|
|
5214
|
-
exportAttributes = object2(
|
|
5214
|
+
exportAttributes = object2(parseStrictJson(exportAttributesText)) ?? {};
|
|
5215
5215
|
} catch {
|
|
5216
5216
|
throw new Error("The 1Password export attributes could not be read safely.");
|
|
5217
5217
|
}
|
|
@@ -5219,7 +5219,7 @@ function parseOnePuxData(exportAttributesText, exportDataText, limits) {
|
|
|
5219
5219
|
if (!only(exportAttributes, ["version", "description", "createdAt"]) || !numericLexeme(exportAttributes.version)?.isThree || exportAttributes.description !== "1Password Unencrypted Export" || !integer(exportAttributes.createdAt)) throw new Error("This is not a supported unencrypted 1Password v3 export.");
|
|
5220
5220
|
let root;
|
|
5221
5221
|
try {
|
|
5222
|
-
root = object2(
|
|
5222
|
+
root = object2(parseStrictJson(exportDataText)) ?? {};
|
|
5223
5223
|
} catch {
|
|
5224
5224
|
throw new Error("The 1Password export could not be read safely.");
|
|
5225
5225
|
}
|