@atproto/lex-data 0.0.6 → 0.0.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/dist/cid.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cid.js","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":";;;AAuEA,sBAEC;AAED,4BAEC;AAED,8BAEC;AAED,8BAEC;AAED,sBAsBC;AAED,8CAEC;AAED,wCAMC;AAED,oDAIC;AA/HD,0CAAsC;AAwD7B,oFAxDA,SAAG,OAwDA;AAtDC,QAAA,mBAAmB,GAAG,IAAI,CAAA;AAC1B,QAAA,kBAAkB,GAAG,IAAI,CAAA;AAEzB,QAAA,uBAAuB,GAAG,IAAI,CAAA;AAkE3C,SAAgB,KAAK,CAAC,KAAc;IAClC,OAAO,SAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAa;IACpC,OAAO,SAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,SAAgB,SAAS,CAAC,KAAiB;IACzC,OAAO,SAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAgB,SAAS,CAAC,IAAY,EAAE,MAAuB;IAC7D,OAAO,SAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACnC,CAAC;AAED,SAAgB,KAAK,CACnB,KAAc,EACd,OAA8B;IAE9B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IACxB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,0BAAkB,IAAI,GAAG,CAAC,IAAI,KAAK,2BAAmB,EAAE,CAAC;YACxE,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,+BAAuB,EAAE,CAAC;YACnD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,OAAO,cAAc,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,KAAK,CAAA;AACpD,CAAC;AAED,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,KAAa;IAChD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;AACH,CAAC","sourcesContent":["import { CID } from 'multiformats/cid'\n\nexport const DAG_CBOR_MULTICODEC = 0x71\nexport const RAW_BIN_MULTICODEC = 0x55\n\nexport const SHA2_256_MULTIHASH_CODE = 0x12\n\nexport type MultihashDigest<Code extends number = number> = {\n code: Code\n digest: Uint8Array\n size: number\n bytes: Uint8Array\n}\n\ndeclare module 'multiformats/cid' {\n /**\n * @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and\n * related helpers ({@link asCid}, {@link parseCid}, {@link decodeCid},\n * {@link createCid}, {@link isCid}), instead.\n *\n * This is marked as deprecated because we want to discourage direct usage of\n * `multiformats/cid` in dependent packages, and instead have them rely on the\n * {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from\n * `multiformats` version <10 has compatibility issues with certain TypeScript\n * configuration, which can lead to type errors in dependent packages.\n *\n * We are stuck with version 9 because `@atproto` packages did not drop\n * CommonJS support yet, and multiformats version 10 only supports ES modules.\n *\n * In order to avoid compatibility issues, while preparing for future breaking\n * changes (CID in multiformats v10+ has a slightly different interface), as\n * we update or swap out `multiformats`, we provide our own stable {@link Cid}\n * interface.\n */\n interface CID {}\n}\n\n// multiformats' CID class is not very portable because:\n//\n// - In dependent packages that use \"moduleResolution\" set to \"node16\",\n// \"nodenext\" or \"bundler\", TypeScript fails to properly resolve the\n// multiformats package when importing CID from @atproto/lex-data. This causes\n// type errors in those packages. This is caused by the fact that the\n// multiformats version <10 (which is the last version that supports CommonJS)\n// uses \"exports\" field in package.json, which do not contain \"types\"\n// entrypoints.\n// https://www.npmjs.com/package/multiformats/v/9.9.0?activeTab=code\n// - By defining our own interface and helper functions, we can have more\n// control over the public API exposed by this package.\n// - It allow us to have a stable interface in case we need to swap out, or\n// eventually update multiformats (should we choose to drop CommonJS support)\n// in the future.\n\n// @NOTE Even though it is not portable, we still re-export CID here so that\n// dependent packages where it can be used, have access to it (instead of\n// importing directly from \"multiformats\" or\"multiformats/cid\").\nexport { CID }\n\n/**\n * Interface for working with decoded CID string, compatible with\n * {@link CID} implementation.\n */\nexport interface Cid {\n version: 0 | 1\n code: number\n multihash: MultihashDigest\n bytes: Uint8Array\n equals(other: unknown): boolean\n toString(): string\n}\n\nexport function asCid(value: unknown): Cid | null {\n return CID.asCID(value)\n}\n\nexport function parseCid(input: string): Cid {\n return CID.parse(input)\n}\n\nexport function decodeCid(bytes: Uint8Array): Cid {\n return CID.decode(bytes)\n}\n\nexport function createCid(code: number, digest: MultihashDigest): Cid {\n return CID.createV1(code, digest)\n}\n\nexport function isCid(\n value: unknown,\n options?: { strict?: boolean },\n): value is Cid {\n const cid = asCid(value)\n if (!cid) {\n return false\n }\n\n if (options?.strict) {\n if (cid.version !== 1) {\n return false\n }\n if (cid.code !== RAW_BIN_MULTICODEC && cid.code !== DAG_CBOR_MULTICODEC) {\n return false\n }\n if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) {\n return false\n }\n }\n\n return true\n}\n\nexport function validateCidString(input: string): boolean {\n return parseCidString(input)?.toString() === input\n}\n\nexport function parseCidString(input: string): Cid | undefined {\n try {\n return parseCid(input)\n } catch {\n return undefined\n }\n}\n\nexport function ensureValidCidString(input: string): void {\n if (!validateCidString(input)) {\n throw new Error(`Invalid CID string`)\n }\n}\n"]}
1
+ {"version":3,"file":"cid.js","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":"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","sourcesContent":["import { CID } from 'multiformats/cid'\nimport { create as createDigest } from 'multiformats/hashes/digest'\nimport { sha256, sha512 } from 'multiformats/hashes/sha2'\nimport { isObject } from './object.js'\nimport { ui8Equals } from './uint8array.js'\n\nexport const DAG_CBOR_MULTICODEC = 0x71 // DRISL conformant DAG-CBOR\nexport type DAG_CBOR_MULTICODEC = typeof DAG_CBOR_MULTICODEC\n\nexport const RAW_MULTICODEC = 0x55 // raw binary codec used in DASL CIDs\nexport type RAW_MULTICODEC = typeof RAW_MULTICODEC\n\nexport const SHA256_MULTIHASH = sha256.code\nexport type SHA256_MULTIHASH = typeof SHA256_MULTIHASH\n\nexport const SHA512_MULTIHASH = sha512.code\nexport type SHA512_MULTIHASH = typeof SHA512_MULTIHASH\n\nexport interface Multihash<TCode extends number = number> {\n /**\n * Code of the multihash\n */\n code: TCode\n\n /**\n * Raw digest\n */\n digest: Uint8Array\n}\n\nexport function multihashEquals(a: Multihash, b: Multihash): boolean {\n return a.code === b.code && ui8Equals(a.digest, b.digest)\n}\n\ndeclare module 'multiformats/cid' {\n /**\n * @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and\n * related helpers ({@link isCid}, {@link ifCid}, {@link asCid},\n * {@link parseCid}, {@link decodeCid}), instead.\n *\n * This is marked as deprecated because we want to discourage direct usage of\n * `multiformats/cid` in dependent packages, and instead have them rely on the\n * {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from\n * `multiformats` version <10 has compatibility issues with certain TypeScript\n * configuration, which can lead to type errors in dependent packages.\n *\n * We are stuck with version 9 because `@atproto` packages did not drop\n * CommonJS support yet, and multiformats version 10 only supports ES modules.\n *\n * In order to avoid compatibility issues, while preparing for future breaking\n * changes (CID in multiformats v10+ has a slightly different interface), as\n * we update or swap out `multiformats`, `@atproto/lex-data` provides its own\n * stable {@link Cid} interface.\n */\n interface CID {}\n}\n\n// multiformats' CID class is not very portable because:\n//\n// - In dependent packages that use \"moduleResolution\" set to \"node16\",\n// \"nodenext\" or \"bundler\", TypeScript fails to properly resolve the\n// multiformats package when importing CID from @atproto/lex-data. This causes\n// type errors in those packages. This is caused by the fact that the\n// multiformats version <10 (which is the last version that supports CommonJS)\n// uses \"exports\" field in package.json, which do not contain \"types\"\n// entrypoints.\n// https://www.npmjs.com/package/multiformats/v/9.9.0?activeTab=code\n// - By defining our own interface and helper functions, we can have more\n// control over the public API exposed by this package.\n// - It allow us to have a stable interface in case we need to swap out, or\n// eventually update multiformats (should we choose to drop CommonJS support)\n// in the future.\n\n// @NOTE Even though it is not portable, we still re-export CID here so that\n// dependent packages where it can be used, have access to it (instead of\n// importing directly from \"multiformats\" or \"multiformats/cid\").\nexport { /** @deprecated */ CID }\n\n/**\n * Converts a {@link Cid} to a multiformats {@link CID} instance.\n *\n * @deprecated Packages depending on `@atproto/lex-data` should use the\n * {@link Cid} interface instead of relying on `multiformats`'s {@link CID}\n * implementation directly. This is to avoid compatibility issues, and in order\n * to allow better portability, compatibility and future updates.\n */\nexport function asMultiformatsCID<\n TVersion extends 0 | 1 = 0 | 1,\n TCode extends number = number,\n TMultihashCode extends number = number,\n>(input: Cid<TVersion, TCode, TMultihashCode>) {\n const cid =\n // Already a multiformats CID instance\n CID.asCID(input) ??\n // Create a new multiformats CID instance\n CID.create(\n input.version,\n input.code,\n createDigest(input.multihash.code, input.multihash.digest),\n )\n\n // @NOTE: the \"satisfies\" operator is used here to ensure that the Cid\n // interface is indeed compatible with multiformats' CID implementation, which\n // allows us to safely rely on multiformats' CID implementation where Cid are\n // needed.\n return cid satisfies Cid as CID & Cid<TVersion, TCode, TMultihashCode>\n}\n\n/**\n * Interface for working with CIDs\n */\nexport interface Cid<\n TVersion extends 0 | 1 = 0 | 1,\n TCode extends number = number,\n TMultihashCode extends number = number,\n> {\n // @NOTE This interface is compatible with multiformats' CID implementation\n // which we are using under the hood.\n\n readonly version: TVersion\n readonly code: TCode\n readonly multihash: Multihash<TMultihashCode>\n\n /**\n * Binary representation of the whole CID.\n */\n readonly bytes: Uint8Array\n\n equals(other: Cid): boolean\n toString(): string\n}\n\n/**\n * Represents the cid of raw binary data (like media blobs).\n *\n * The use of {@link SHA256_MULTIHASH} is recommended but not required for raw CIDs.\n *\n * @see {@link https://atproto.com/specs/data-model#link-and-cid-formats ATproto Data Model - Link and CID Formats}\n */\nexport type RawCid = Cid<1, RAW_MULTICODEC>\n\nexport function isRawCid(cid: Cid): cid is RawCid {\n return cid.version === 1 && cid.code === RAW_MULTICODEC\n}\n\n/**\n * Represents a DASL compliant CID.\n * @see {@link https://dasl.ing/cid.html DASL-CIDs}\n */\nexport type DaslCid = Cid<\n 1,\n RAW_MULTICODEC | DAG_CBOR_MULTICODEC,\n SHA256_MULTIHASH\n>\n\nexport function isDaslCid(cid: Cid): cid is DaslCid {\n return (\n cid.version === 1 &&\n (cid.code === RAW_MULTICODEC || cid.code === DAG_CBOR_MULTICODEC) &&\n cid.multihash.code === SHA256_MULTIHASH &&\n cid.multihash.digest.byteLength === 32 // Should always be 32 bytes (256 bits) for SHA-256, but double-checking anyways\n )\n}\n\n/**\n * Represents the cid of ATProto DAG-CBOR data (like repository MST nodes).\n * @see {@link https://atproto.com/specs/data-model#link-and-cid-formats ATproto Data Model - Link and CID Formats}\n */\nexport type CborCid = Cid<1, DAG_CBOR_MULTICODEC, SHA256_MULTIHASH>\n\nexport function isCborCid(cid: Cid): cid is CborCid {\n return cid.code === DAG_CBOR_MULTICODEC && isDaslCid(cid)\n}\n\nexport type CheckCidOptions = {\n flavor?: 'raw' | 'cbor' | 'dasl'\n}\n\nexport type InferCheckedCid<TOptions> = TOptions extends { flavor: 'raw' }\n ? RawCid\n : TOptions extends { flavor: 'cbor' }\n ? CborCid\n : Cid\n\n/**\n * Type guard to check whether a {@link Cid} instance meets specific flavor\n * constraints.\n */\nexport function checkCid<TOptions extends CheckCidOptions>(\n cid: Cid,\n options: TOptions,\n): cid is InferCheckedCid<TOptions>\nexport function checkCid(cid: Cid, options?: CheckCidOptions): boolean\nexport function checkCid(cid: Cid, options?: CheckCidOptions): boolean {\n switch (options?.flavor) {\n case undefined:\n return true\n case 'cbor':\n return isCborCid(cid)\n case 'dasl':\n return isDaslCid(cid)\n case 'raw':\n return isRawCid(cid)\n default:\n throw new TypeError(`Unknown CID flavor: ${options?.flavor}`)\n }\n}\n\n/**\n * Type guard to check whether a value is a valid {@link Cid} instance,\n * optionally checking for specific flavor constraints.\n */\nexport function isCid<TOptions extends CheckCidOptions>(\n value: unknown,\n options: TOptions,\n): value is InferCheckedCid<TOptions>\nexport function isCid(value: unknown, options?: CheckCidOptions): value is Cid\nexport function isCid(value: unknown, options?: CheckCidOptions): value is Cid {\n return isCidImplementation(value) && checkCid(value, options)\n}\n\n/**\n * Returns the input value as a {@link Cid} if it is valid, or `null` otherwise.\n */\nexport function ifCid<TValue, TOptions extends CheckCidOptions>(\n value: unknown,\n options: TOptions,\n): (TValue & InferCheckedCid<TOptions>) | null\nexport function ifCid<TValue>(\n value: TValue,\n options?: CheckCidOptions,\n): (TValue & Cid) | null\nexport function ifCid(value: unknown, options?: CheckCidOptions): Cid | null {\n if (isCidImplementation(value) && checkCid(value, options)) return value\n return null\n}\n\n/**\n * Returns the input value as a {@link Cid} if it is valid.\n *\n * @throws if the input is not a valid {@link Cid}.\n */\nexport function asCid<TValue, TOptions extends CheckCidOptions>(\n value: TValue,\n options: TOptions,\n): TValue & InferCheckedCid<TOptions>\nexport function asCid<TValue>(\n value: TValue,\n options?: CheckCidOptions,\n): Cid & TValue\nexport function asCid(value: unknown, options?: CheckCidOptions): Cid {\n if (isCidImplementation(value) && checkCid(value, options)) return value\n throw new Error('Not a valid CID')\n}\n\n/**\n * Decodes a CID from its binary representation.\n *\n * @see {@link https://dasl.ing/cid.html DASL-CIDs}\n * @throws if the input do not represent a valid DASL {@link Cid}\n */\nexport function decodeCid<TOptions extends CheckCidOptions>(\n cidBytes: Uint8Array,\n options: TOptions,\n): InferCheckedCid<TOptions>\nexport function decodeCid(cidBytes: Uint8Array, options?: CheckCidOptions): Cid\nexport function decodeCid(\n cidBytes: Uint8Array,\n options?: CheckCidOptions,\n): Cid {\n const cid = CID.decode(cidBytes)\n return asCid(cid, options)\n}\n\n/**\n * Parses a CID string into a Cid object.\n *\n * @throws if the input is not a valid CID string.\n */\nexport function parseCid<TOptions extends CheckCidOptions>(\n input: string,\n options: TOptions,\n): InferCheckedCid<TOptions>\nexport function parseCid(input: string, options?: CheckCidOptions): Cid\nexport function parseCid(input: string, options?: CheckCidOptions): Cid {\n const cid = CID.parse(input)\n return asCid(cid, options)\n}\n\nexport function validateCidString(\n input: string,\n options?: CheckCidOptions,\n): boolean {\n return parseCidSafe(input, options)?.toString() === input\n}\n\nexport function parseCidSafe<TOptions extends CheckCidOptions>(\n input: string,\n options: TOptions,\n): InferCheckedCid<TOptions> | null\nexport function parseCidSafe(\n input: string,\n options?: CheckCidOptions,\n): Cid | null\nexport function parseCidSafe(\n input: string,\n options?: CheckCidOptions,\n): Cid | null {\n try {\n return parseCid(input, options)\n } catch {\n return null\n }\n}\n\nexport function ensureValidCidString(\n input: string,\n options?: CheckCidOptions,\n): void {\n if (!validateCidString(input, options)) {\n throw new Error(`Invalid CID string`)\n }\n}\n\n/**\n * Verifies whether the multihash of a given {@link cid} matches the hash of the provided {@link bytes}.\n * @params cid The CID to match against the bytes.\n * @params bytes The bytes to verify.\n * @returns true if the CID matches the bytes, false otherwise.\n */\nexport async function isCidForBytes(\n cid: Cid,\n bytes: Uint8Array,\n): Promise<boolean> {\n if (cid.multihash.code === sha256.code) {\n const multihash = await sha256.digest(bytes)\n return multihashEquals(multihash, cid.multihash)\n }\n\n if (cid.multihash.code === sha512.code) {\n const multihash = await sha512.digest(bytes)\n return multihashEquals(multihash, cid.multihash)\n }\n\n // Don't know how to verify other multihash codes\n throw new Error('Unsupported CID multihash')\n}\n\nexport function createCid<TCode extends number, TMultihashCode extends number>(\n code: TCode,\n multihashCode: TMultihashCode,\n digest: Uint8Array,\n) {\n const cid: Cid = CID.createV1(code, createDigest(multihashCode, digest))\n return cid as Cid<1, TCode, TMultihashCode>\n}\n\nexport async function cidForCbor(bytes: Uint8Array): Promise<CborCid> {\n const multihash = await sha256.digest(bytes)\n return CID.createV1(DAG_CBOR_MULTICODEC, multihash) as CborCid\n}\n\nexport async function cidForRawBytes(bytes: Uint8Array): Promise<RawCid> {\n const multihash = await sha256.digest(bytes)\n return CID.createV1(RAW_MULTICODEC, multihash) as RawCid\n}\n\nexport function cidForRawHash(digest: Uint8Array): RawCid {\n // Fool-proofing\n if (digest.length !== 32) {\n throw new Error(`Invalid SHA-256 hash length: ${digest.length}`)\n }\n return createCid(RAW_MULTICODEC, sha256.code, digest)\n}\n\n/**\n * @internal\n */\nfunction isCidImplementation(value: unknown): value is Cid {\n if (CID.asCID(value)) {\n // CIDs created using older multiformats versions did not have a \"bytes\"\n // property.\n return (value as { bytes?: Uint8Array }).bytes != null\n } else {\n // Unknown implementation, do a structural check\n try {\n if (!isObject(value)) return false\n\n const val = value as Record<string, unknown>\n if (val.version !== 0 && val.version !== 1) return false\n if (!isUint8(val.code)) return false\n\n if (!isObject(val.multihash)) return false\n const mh = val.multihash as Record<string, unknown>\n if (!isUint8(mh.code)) return false\n if (!(mh.digest instanceof Uint8Array)) return false\n\n // Ensure that the bytes array is consistent with other properties\n if (!(val.bytes instanceof Uint8Array)) return false\n if (val.bytes[0] !== val.version) return false\n if (val.bytes[1] !== val.code) return false\n if (val.bytes[2] !== mh.code) return false\n if (val.bytes[3] !== mh.digest.length) return false\n if (val.bytes.length !== 4 + mh.digest.length) return false\n if (!ui8Equals(val.bytes.subarray(4), mh.digest)) return false\n\n if (typeof val.equals !== 'function') return false\n if (val.equals(val) !== true) return false\n\n return true\n } catch {\n return false\n }\n }\n}\n\n/**\n * @internal\n */\nfunction isUint8(val: unknown): val is number {\n return Number.isInteger(val) && (val as number) >= 0 && (val as number) < 256\n}\n"]}
@@ -42,7 +42,7 @@ function lexEquals(a, b) {
42
42
  if ((0, cid_js_1.isCid)(a)) {
43
43
  // @NOTE CID.equals returns its argument when it is falsy (e.g. null or
44
44
  // undefined) so we need to explicitly check that the output is "true".
45
- return (0, cid_js_1.asCid)(a).equals((0, cid_js_1.asCid)(b)) === true;
45
+ return (0, cid_js_1.ifCid)(b)?.equals(a) === true;
46
46
  }
47
47
  else if ((0, cid_js_1.isCid)(b)) {
48
48
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"lex-equals.js","sourceRoot":"","sources":["../src/lex-equals.ts"],"names":[],"mappings":"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","sourcesContent":["import { asCid, isCid } from './cid.js'\nimport { LexValue } from './lex.js'\nimport { isPlainObject } from './object.js'\nimport { ui8Equals } from './uint8array.js'\n\nexport function lexEquals(a: LexValue, b: LexValue): boolean {\n if (Object.is(a, b)) {\n return true\n }\n\n if (\n a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object'\n ) {\n return false\n }\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b)) {\n return false\n }\n if (a.length !== b.length) {\n return false\n }\n for (let i = 0; i < a.length; i++) {\n if (!lexEquals(a[i], b[i])) {\n return false\n }\n }\n return true\n } else if (Array.isArray(b)) {\n return false\n }\n\n if (ArrayBuffer.isView(a)) {\n if (!ArrayBuffer.isView(b)) return false\n return ui8Equals(a, b)\n } else if (ArrayBuffer.isView(b)) {\n return false\n }\n\n if (isCid(a)) {\n // @NOTE CID.equals returns its argument when it is falsy (e.g. null or\n // undefined) so we need to explicitly check that the output is \"true\".\n return asCid(a)!.equals(asCid(b)) === true\n } else if (isCid(b)) {\n return false\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) {\n // Foolproof (should never happen)\n throw new TypeError(\n 'Invalid LexValue (expected CID, Uint8Array, or LexMap)',\n )\n }\n\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (aKeys.length !== bKeys.length) {\n return false\n }\n\n for (const key of aKeys) {\n const aVal = a[key]\n const bVal = b[key]\n\n // Needed because of the optional index signature in the Lex object type\n // though, in practice, aVal should never be undefined here.\n if (aVal === undefined) {\n if (bVal === undefined && bKeys.includes(key)) continue\n return false\n } else if (bVal === undefined) {\n return false\n }\n\n if (!lexEquals(aVal, bVal)) {\n return false\n }\n }\n\n return true\n}\n"]}
1
+ {"version":3,"file":"lex-equals.js","sourceRoot":"","sources":["../src/lex-equals.ts"],"names":[],"mappings":"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","sourcesContent":["import { ifCid, isCid } from './cid.js'\nimport { LexValue } from './lex.js'\nimport { isPlainObject } from './object.js'\nimport { ui8Equals } from './uint8array.js'\n\nexport function lexEquals(a: LexValue, b: LexValue): boolean {\n if (Object.is(a, b)) {\n return true\n }\n\n if (\n a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object'\n ) {\n return false\n }\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b)) {\n return false\n }\n if (a.length !== b.length) {\n return false\n }\n for (let i = 0; i < a.length; i++) {\n if (!lexEquals(a[i], b[i])) {\n return false\n }\n }\n return true\n } else if (Array.isArray(b)) {\n return false\n }\n\n if (ArrayBuffer.isView(a)) {\n if (!ArrayBuffer.isView(b)) return false\n return ui8Equals(a, b)\n } else if (ArrayBuffer.isView(b)) {\n return false\n }\n\n if (isCid(a)) {\n // @NOTE CID.equals returns its argument when it is falsy (e.g. null or\n // undefined) so we need to explicitly check that the output is \"true\".\n return ifCid(b)?.equals(a) === true\n } else if (isCid(b)) {\n return false\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) {\n // Foolproof (should never happen)\n throw new TypeError(\n 'Invalid LexValue (expected CID, Uint8Array, or LexMap)',\n )\n }\n\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (aKeys.length !== bKeys.length) {\n return false\n }\n\n for (const key of aKeys) {\n const aVal = a[key]\n const bVal = b[key]\n\n // Needed because of the optional index signature in the Lex object type\n // though, in practice, aVal should never be undefined here.\n if (aVal === undefined) {\n if (bVal === undefined && bKeys.includes(key)) continue\n return false\n } else if (bVal === undefined) {\n return false\n }\n\n if (!lexEquals(aVal, bVal)) {\n return false\n }\n }\n\n return true\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-data",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "license": "MIT",
5
5
  "description": "Core utilities for AT Lexicons",
6
6
  "keywords": [
package/src/blob.test.ts CHANGED
@@ -6,16 +6,19 @@ import {
6
6
  isBlobRef,
7
7
  isLegacyBlobRef,
8
8
  } from './blob.js'
9
- import { parseCid } from './cid.js'
9
+ import { RawCid, parseCid } from './cid.js'
10
10
  import { LexArray, LexMap, LexValue } from './lex.js'
11
11
 
12
12
  // await cidForRawBytes(Buffer.from('Hello, World!'))
13
13
  const validBlobCid = parseCid(
14
14
  'bafkreig77vqcdozl2wyk6z3cscaj5q5fggi53aoh64fewkdiri3cdauyn4',
15
+ { flavor: 'raw' },
15
16
  )
17
+
16
18
  // await cidForLex(Buffer.from('Hello, World!'))
17
19
  const invalidBlobCid = parseCid(
18
20
  'bafyreic52vzks7wdklat4evp3vimohl55i2unzqpshz2ytka5omzr7exdy',
21
+ { flavor: 'cbor' },
19
22
  )
20
23
 
21
24
  describe(isBlobRef, () => {
@@ -285,14 +288,14 @@ describe(isLegacyBlobRef, () => {
285
288
  })
286
289
 
287
290
  describe(enumBlobRefs, () => {
288
- const valid1: BlobRef = {
291
+ const valid1: BlobRef<RawCid> = {
289
292
  $type: 'blob',
290
293
  ref: validBlobCid,
291
294
  mimeType: 'image/png',
292
295
  size: 2048,
293
296
  }
294
297
 
295
- const valid2: BlobRef = {
298
+ const valid2: BlobRef<RawCid> = {
296
299
  $type: 'blob',
297
300
  ref: validBlobCid,
298
301
  mimeType: 'image/jpeg',
package/src/blob.ts CHANGED
@@ -1,24 +1,18 @@
1
- import {
2
- Cid,
3
- RAW_BIN_MULTICODEC,
4
- SHA2_256_MULTIHASH_CODE,
5
- asCid,
6
- parseCid,
7
- } from './cid.js'
1
+ import { Cid, RawCid, ifCid, validateCidString } from './cid.js'
8
2
  import { LexValue } from './lex.js'
9
3
  import { isPlainObject, isPlainProto } from './object.js'
10
4
 
11
5
  /**
12
6
  * @note {@link BlobRef} is just a {@link LexMap} with a specific shape.
13
7
  */
14
- export type BlobRef = {
8
+ export type BlobRef<Ref extends Cid = Cid> = {
15
9
  $type: 'blob'
16
10
  mimeType: string
17
- ref: Cid
11
+ ref: Ref
18
12
  size: number
19
13
  }
20
14
 
21
- export type BlobRefValidationOptions = {
15
+ export type BlobRefCheckOptions = {
22
16
  /**
23
17
  * If `false`, skips strict CID validation of {@link BlobRef.ref}, allowing
24
18
  * any valid CID. Otherwise, validates that the CID is v1, uses the raw
@@ -29,9 +23,25 @@ export type BlobRefValidationOptions = {
29
23
  strict?: boolean
30
24
  }
31
25
 
26
+ export type InferCheckedBlobRef<TOptions extends BlobRefCheckOptions> =
27
+ TOptions extends { strict: false }
28
+ ? BlobRef
29
+ : { strict: boolean } extends TOptions
30
+ ? BlobRef
31
+ : BlobRef<RawCid>
32
+
33
+ export function isBlobRef(input: unknown): input is BlobRef<RawCid>
34
+ export function isBlobRef<TOptions extends BlobRefCheckOptions>(
35
+ input: unknown,
36
+ options: TOptions,
37
+ ): input is InferCheckedBlobRef<TOptions>
38
+ export function isBlobRef(
39
+ input: unknown,
40
+ options?: BlobRefCheckOptions,
41
+ ): input is BlobRef
32
42
  export function isBlobRef(
33
43
  input: unknown,
34
- options?: BlobRefValidationOptions,
44
+ options?: BlobRefCheckOptions,
35
45
  ): input is BlobRef {
36
46
  if (!isPlainObject(input)) {
37
47
  return false
@@ -66,23 +76,15 @@ export function isBlobRef(
66
76
  }
67
77
  }
68
78
 
69
- const cid = asCid(ref)
79
+ const cid = ifCid(
80
+ ref,
81
+ // Strict unless explicitly disabled
82
+ options?.strict === false ? undefined : { flavor: 'raw' },
83
+ )
70
84
  if (!cid) {
71
85
  return false
72
86
  }
73
87
 
74
- if (options?.strict !== false) {
75
- if (cid.version !== 1) {
76
- return false
77
- }
78
- if (cid.code !== RAW_BIN_MULTICODEC) {
79
- return false
80
- }
81
- if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) {
82
- return false
83
- }
84
- }
85
-
86
88
  return true
87
89
  }
88
90
 
@@ -114,34 +116,38 @@ export function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {
114
116
  }
115
117
  }
116
118
 
117
- try {
118
- parseCid(cid)
119
- } catch {
119
+ if (!validateCidString(cid)) {
120
120
  return false
121
121
  }
122
122
 
123
123
  return true
124
124
  }
125
125
 
126
- export type EnumBlobRefsOptions = BlobRefValidationOptions & {
126
+ export type EnumBlobRefsOptions = BlobRefCheckOptions & {
127
127
  /**
128
128
  * @defaults to `false`
129
129
  */
130
130
  allowLegacy?: boolean
131
131
  }
132
132
 
133
+ export type InferEnumBlobRefs<TOptions extends EnumBlobRefsOptions> =
134
+ TOptions extends { allowLegacy: true }
135
+ ? InferCheckedBlobRef<TOptions> | LegacyBlobRef
136
+ : { allowLegacy: boolean } extends TOptions
137
+ ? InferCheckedBlobRef<TOptions> | LegacyBlobRef
138
+ : InferCheckedBlobRef<TOptions>
139
+
133
140
  /**
134
141
  * Enumerates all {@link BlobRef}s (and, optionally, {@link LegacyBlobRef}s)
135
142
  * found within a {@link LexValue}.
136
143
  */
137
144
  export function enumBlobRefs(
138
145
  input: LexValue,
139
- options: EnumBlobRefsOptions & { allowLegacy: true },
140
- ): Generator<BlobRef | LegacyBlobRef, void, unknown>
141
- export function enumBlobRefs(
146
+ ): Generator<BlobRef<RawCid>, void, unknown>
147
+ export function enumBlobRefs<TOptions extends EnumBlobRefsOptions>(
142
148
  input: LexValue,
143
- options?: EnumBlobRefsOptions & { allowLegacy?: false },
144
- ): Generator<BlobRef, void, unknown>
149
+ options: TOptions,
150
+ ): Generator<InferEnumBlobRefs<TOptions>, void, unknown>
145
151
  export function enumBlobRefs(
146
152
  input: LexValue,
147
153
  options?: EnumBlobRefsOptions,
@@ -150,6 +156,7 @@ export function* enumBlobRefs(
150
156
  input: LexValue,
151
157
  options?: EnumBlobRefsOptions,
152
158
  ): Generator<BlobRef | LegacyBlobRef, void, unknown> {
159
+ // LegacyBlobRef not included by default
153
160
  const includeLegacy = options?.allowLegacy === true
154
161
 
155
162
  // Using a stack to avoid recursion depth issues.
@@ -0,0 +1,137 @@
1
+ /* eslint-disable import/no-deprecated */
2
+
3
+ import { base32 } from 'multiformats/bases/base32'
4
+ import { CID } from 'multiformats/cid'
5
+ import { create as createDigest } from 'multiformats/hashes/digest'
6
+ import { assert, describe, expect, it } from 'vitest'
7
+ import { Cid } from './cid.js'
8
+ import { ui8Equals } from './uint8array.js'
9
+
10
+ export class BytesCid implements Cid {
11
+ constructor(readonly bytes: Uint8Array) {
12
+ if (this.bytes.length < 4) {
13
+ throw new Error('CID bytes are too short')
14
+ }
15
+ if (this.bytes[0] > 1) {
16
+ throw new Error('Unsupported CID version')
17
+ }
18
+ if (this.bytes.length !== 4 + this.bytes[3]) {
19
+ throw new Error('CID bytes length mismatch')
20
+ }
21
+ }
22
+
23
+ get version() {
24
+ return this.bytes[0] as 0 | 1
25
+ }
26
+
27
+ get code() {
28
+ return this.bytes[1]
29
+ }
30
+
31
+ get multihash() {
32
+ const code = this.bytes[2]
33
+ const digest = this.bytes.subarray(4)
34
+ return { code, digest }
35
+ }
36
+
37
+ equals(other: Cid): boolean {
38
+ return ui8Equals(this.bytes, other.bytes)
39
+ }
40
+
41
+ toString(): string {
42
+ return base32.encode(this.bytes)
43
+ }
44
+ }
45
+
46
+ describe(BytesCid, () => {
47
+ it('creates a BytesCid from valid bytes', () => {
48
+ const bytes = new Uint8Array([1, 0x55, 0x12, 3, 1, 2, 3])
49
+ const cid = new BytesCid(bytes)
50
+
51
+ assert(cid.version === 1)
52
+ assert(cid.code === 0x55)
53
+ assert(cid.multihash.code === 0x12)
54
+ assert(ui8Equals(cid.multihash.digest, new Uint8Array([1, 2, 3])))
55
+ assert(ui8Equals(cid.bytes, bytes))
56
+ assert(typeof cid.toString === 'function')
57
+ assert(typeof cid.equals === 'function')
58
+ })
59
+
60
+ it('throws an error for invalid CID bytes', () => {
61
+ expect(
62
+ () => new BytesCid(new Uint8Array([2, 0x55, 0x12, 3, 1, 2, 3])),
63
+ ).toThrowError('Unsupported CID version')
64
+ expect(() => new BytesCid(new Uint8Array([1, 0x55, 0x12]))).toThrowError(
65
+ 'CID bytes are too short',
66
+ )
67
+ expect(
68
+ () => new BytesCid(new Uint8Array([1, 0x55, 0x12, 4, 1, 2, 3])),
69
+ ).toThrowError('CID bytes length mismatch')
70
+ })
71
+ })
72
+
73
+ /**
74
+ * A minimal custom implementation of the `Cid` interface for testing purposes.
75
+ */
76
+ export function createCustomCid<
77
+ TVersion extends 0 | 1,
78
+ TCode extends number,
79
+ TMultihashCode extends number,
80
+ >(
81
+ version: TVersion,
82
+ code: TCode,
83
+ multihashCode: TMultihashCode,
84
+ digest: Uint8Array,
85
+ ): Cid<TVersion, TCode, TMultihashCode> {
86
+ return {
87
+ version,
88
+ code,
89
+ multihash: { code: multihashCode, digest },
90
+ bytes: new Uint8Array([
91
+ version,
92
+ code,
93
+ multihashCode,
94
+ digest.length,
95
+ ...digest,
96
+ ]),
97
+ toString,
98
+ equals,
99
+ }
100
+ }
101
+
102
+ function equals(this: Cid, other: Cid): boolean {
103
+ return (
104
+ this.version === other.version &&
105
+ this.code === other.code &&
106
+ this.multihash.code === other.multihash.code &&
107
+ ui8Equals(this.multihash.digest, other.multihash.digest)
108
+ )
109
+ }
110
+
111
+ function toString(this: Cid): string {
112
+ return CID.create(
113
+ this.version,
114
+ this.code,
115
+ createDigest(this.multihash.code, this.multihash.digest),
116
+ ).toString()
117
+ }
118
+
119
+ describe(createCustomCid, () => {
120
+ it('creates a CID with the specified properties', () => {
121
+ const digest = new Uint8Array([1, 2, 3, 4, 5])
122
+ const customCid = createCustomCid(1, 0x55, 0x12, digest)
123
+
124
+ assert(customCid.version === 1)
125
+ assert(customCid.code === 0x55)
126
+ assert(customCid.multihash.code === 0x12)
127
+ assert(ui8Equals(customCid.multihash.digest, digest))
128
+ assert(
129
+ ui8Equals(
130
+ customCid.bytes,
131
+ new Uint8Array([1, 0x55, 0x12, 5, 1, 2, 3, 4, 5]),
132
+ ),
133
+ )
134
+ assert(typeof customCid.toString === 'function')
135
+ assert(typeof customCid.equals === 'function')
136
+ })
137
+ })