@atproto/lex-data 0.0.5 → 0.0.7

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/blob.d.ts +39 -5
  3. package/dist/blob.d.ts.map +1 -1
  4. package/dist/blob.js +45 -16
  5. package/dist/blob.js.map +1 -1
  6. package/dist/cid.d.ts +83 -14
  7. package/dist/cid.d.ts.map +1 -1
  8. package/dist/cid.js +94 -35
  9. package/dist/cid.js.map +1 -1
  10. package/dist/lex-equals.js +1 -1
  11. package/dist/lex-equals.js.map +1 -1
  12. package/dist/uint8array-from-base64.d.ts.map +1 -1
  13. package/dist/uint8array-from-base64.js +1 -1
  14. package/dist/uint8array-from-base64.js.map +1 -1
  15. package/dist/uint8array-to-base64.d.ts.map +1 -1
  16. package/dist/uint8array-to-base64.js +2 -2
  17. package/dist/uint8array-to-base64.js.map +1 -1
  18. package/dist/utf8-from-base64.d.ts +4 -0
  19. package/dist/utf8-from-base64.d.ts.map +1 -0
  20. package/dist/utf8-from-base64.js +18 -0
  21. package/dist/utf8-from-base64.js.map +1 -0
  22. package/dist/utf8-to-base64.d.ts +4 -0
  23. package/dist/utf8-to-base64.d.ts.map +1 -0
  24. package/dist/utf8-to-base64.js +20 -0
  25. package/dist/utf8-to-base64.js.map +1 -0
  26. package/dist/utf8.d.ts +3 -0
  27. package/dist/utf8.d.ts.map +1 -1
  28. package/dist/utf8.js +16 -3
  29. package/dist/utf8.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/blob.test.ts +150 -25
  32. package/src/blob.ts +111 -27
  33. package/src/cid.test.ts +50 -33
  34. package/src/cid.ts +200 -35
  35. package/src/lex-equals.ts +2 -2
  36. package/src/uint8array-from-base64.ts +1 -1
  37. package/src/uint8array-to-base64.test.ts +2 -2
  38. package/src/uint8array-to-base64.ts +2 -2
  39. package/src/utf8-from-base64.test.ts +39 -0
  40. package/src/utf8-from-base64.ts +23 -0
  41. package/src/utf8-grapheme-len.test.ts +2 -2
  42. package/src/utf8-len.test.ts +2 -2
  43. package/src/utf8-to-base64.test.ts +35 -0
  44. package/src/utf8-to-base64.ts +22 -0
  45. package/src/utf8.ts +23 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @atproto/lex-data
2
2
 
3
+ ## 0.0.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4512](https://github.com/bluesky-social/atproto/pull/4512) [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe) Thanks [@matthieusieben](https://github.com/matthieusieben)! - **breaking**: replace `strict` options with `flavor` checking when parsing/decoding/validating `Cid` values
8
+
9
+ - [#4512](https://github.com/bluesky-social/atproto/pull/4512) [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose CID creation and validation utilities
10
+
11
+ - [#4512](https://github.com/bluesky-social/atproto/pull/4512) [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe) Thanks [@matthieusieben](https://github.com/matthieusieben)! - **breaking**: `asCid` now throws if the input cannot be cast into a `Cid`
12
+
13
+ ## 0.0.6
14
+
15
+ ### Patch Changes
16
+
17
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `enumBlobRefs` utility function
18
+
19
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Perform strict `BlobRef` validation by default
20
+
21
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `base64ToUtf8` and `utf8ToBase64` utilities
22
+
3
23
  ## 0.0.5
4
24
 
5
25
  ### Patch Changes
package/dist/blob.d.ts CHANGED
@@ -1,16 +1,32 @@
1
- import { Cid } from './cid.js';
1
+ import { Cid, RawCid } from './cid.js';
2
+ import { LexValue } from './lex.js';
2
3
  /**
3
4
  * @note {@link BlobRef} is just a {@link LexMap} with a specific shape.
4
5
  */
5
- export type BlobRef = {
6
+ export type BlobRef<Ref extends Cid = Cid> = {
6
7
  $type: 'blob';
7
8
  mimeType: string;
8
- ref: Cid;
9
+ ref: Ref;
9
10
  size: number;
10
11
  };
11
- export declare function isBlobRef(input: unknown, options?: {
12
+ export type BlobRefCheckOptions = {
13
+ /**
14
+ * If `false`, skips strict CID validation of {@link BlobRef.ref}, allowing
15
+ * any valid CID. Otherwise, validates that the CID is v1, uses the raw
16
+ * multicodec, and has a sha256 multihash.
17
+ *
18
+ * @defaults to `true`
19
+ */
12
20
  strict?: boolean;
13
- }): input is BlobRef;
21
+ };
22
+ export type InferCheckedBlobRef<TOptions extends BlobRefCheckOptions> = TOptions extends {
23
+ strict: false;
24
+ } ? BlobRef : {
25
+ strict: boolean;
26
+ } extends TOptions ? BlobRef : BlobRef<RawCid>;
27
+ export declare function isBlobRef(input: unknown): input is BlobRef<RawCid>;
28
+ export declare function isBlobRef<TOptions extends BlobRefCheckOptions>(input: unknown, options: TOptions): input is InferCheckedBlobRef<TOptions>;
29
+ export declare function isBlobRef(input: unknown, options?: BlobRefCheckOptions): input is BlobRef;
14
30
  /**
15
31
  * @note {@link LegacyBlobRef} is just a {@link LexMap} with a specific shape.
16
32
  */
@@ -19,4 +35,22 @@ export type LegacyBlobRef = {
19
35
  mimeType: string;
20
36
  };
21
37
  export declare function isLegacyBlobRef(input: unknown): input is LegacyBlobRef;
38
+ export type EnumBlobRefsOptions = BlobRefCheckOptions & {
39
+ /**
40
+ * @defaults to `false`
41
+ */
42
+ allowLegacy?: boolean;
43
+ };
44
+ export type InferEnumBlobRefs<TOptions extends EnumBlobRefsOptions> = TOptions extends {
45
+ allowLegacy: true;
46
+ } ? InferCheckedBlobRef<TOptions> | LegacyBlobRef : {
47
+ allowLegacy: boolean;
48
+ } extends TOptions ? InferCheckedBlobRef<TOptions> | LegacyBlobRef : InferCheckedBlobRef<TOptions>;
49
+ /**
50
+ * Enumerates all {@link BlobRef}s (and, optionally, {@link LegacyBlobRef}s)
51
+ * found within a {@link LexValue}.
52
+ */
53
+ export declare function enumBlobRefs(input: LexValue): Generator<BlobRef<RawCid>, void, unknown>;
54
+ export declare function enumBlobRefs<TOptions extends EnumBlobRefsOptions>(input: LexValue, options: TOptions): Generator<InferEnumBlobRefs<TOptions>, void, unknown>;
55
+ export declare function enumBlobRefs(input: LexValue, options?: EnumBlobRefsOptions): Generator<BlobRef | LegacyBlobRef, void, unknown>;
22
56
  //# sourceMappingURL=blob.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EAKJ,MAAM,UAAU,CAAA;AAGjB;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,KAAK,IAAI,OAAO,CAoDlB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CA2BtE"}
1
+ {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAA4B,MAAM,UAAU,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGnC;;GAEG;AACH,MAAM,MAAM,OAAO,CAAC,GAAG,SAAS,GAAG,GAAG,GAAG,IAAI;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,mBAAmB,IAClE,QAAQ,SAAS;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,GAC9B,OAAO,GACP;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,SAAS,QAAQ,GAClC,OAAO,GACP,OAAO,CAAC,MAAM,CAAC,CAAA;AAEvB,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;AACnE,wBAAgB,SAAS,CAAC,QAAQ,SAAS,mBAAmB,EAC5D,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,QAAQ,GAChB,KAAK,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;AACzC,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,KAAK,IAAI,OAAO,CAAA;AAkDnB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAyBtE;AAED,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG;IACtD;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,QAAQ,SAAS,mBAAmB,IAChE,QAAQ,SAAS;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,GAClC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,aAAa,GAC7C;IAAE,WAAW,EAAE,OAAO,CAAA;CAAE,SAAS,QAAQ,GACvC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,aAAa,GAC7C,mBAAmB,CAAC,QAAQ,CAAC,CAAA;AAErC;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,GACd,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AAC5C,wBAAgB,YAAY,CAAC,QAAQ,SAAS,mBAAmB,EAC/D,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,QAAQ,GAChB,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACxD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,SAAS,CAAC,OAAO,GAAG,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA"}
package/dist/blob.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isBlobRef = isBlobRef;
4
4
  exports.isLegacyBlobRef = isLegacyBlobRef;
5
+ exports.enumBlobRefs = enumBlobRefs;
5
6
  const cid_js_1 = require("./cid.js");
6
7
  const object_js_1 = require("./object.js");
7
8
  function isBlobRef(input, options) {
@@ -30,21 +31,12 @@ function isBlobRef(input, options) {
30
31
  return false;
31
32
  }
32
33
  }
33
- const cid = (0, cid_js_1.asCid)(ref);
34
+ const cid = (0, cid_js_1.ifCid)(ref,
35
+ // Strict unless explicitly disabled
36
+ options?.strict === false ? undefined : { flavor: 'raw' });
34
37
  if (!cid) {
35
38
  return false;
36
39
  }
37
- if (options?.strict) {
38
- if (cid.version !== 1) {
39
- return false;
40
- }
41
- if (cid.code !== cid_js_1.RAW_BIN_MULTICODEC) {
42
- return false;
43
- }
44
- if (cid.multihash.code !== cid_js_1.SHA2_256_MULTIHASH_CODE) {
45
- return false;
46
- }
47
- }
48
40
  return true;
49
41
  }
50
42
  function isLegacyBlobRef(input) {
@@ -63,12 +55,49 @@ function isLegacyBlobRef(input) {
63
55
  return false;
64
56
  }
65
57
  }
66
- try {
67
- (0, cid_js_1.parseCid)(cid);
68
- }
69
- catch {
58
+ if (!(0, cid_js_1.validateCidString)(cid)) {
70
59
  return false;
71
60
  }
72
61
  return true;
73
62
  }
63
+ function* enumBlobRefs(input, options) {
64
+ // LegacyBlobRef not included by default
65
+ const includeLegacy = options?.allowLegacy === true;
66
+ // Using a stack to avoid recursion depth issues.
67
+ const stack = [input];
68
+ // Since we are using a stack, we could end-up in an infinite loop with cyclic
69
+ // structures. Cyclic structures are not valid LexValues and should, thus,
70
+ // never occur, but let's be safe.
71
+ const visited = new Set();
72
+ do {
73
+ const value = stack.pop();
74
+ if (value != null && typeof value === 'object') {
75
+ if (Array.isArray(value)) {
76
+ if (visited.has(value))
77
+ continue;
78
+ visited.add(value);
79
+ stack.push(...value);
80
+ }
81
+ else if ((0, object_js_1.isPlainProto)(value)) {
82
+ if (visited.has(value))
83
+ continue;
84
+ visited.add(value);
85
+ if (isBlobRef(value, options)) {
86
+ yield value;
87
+ }
88
+ else if (includeLegacy && isLegacyBlobRef(value)) {
89
+ yield value;
90
+ }
91
+ else {
92
+ for (const v of Object.values(value)) {
93
+ if (v != null)
94
+ stack.push(v);
95
+ }
96
+ }
97
+ }
98
+ }
99
+ } while (stack.length > 0);
100
+ // Optimization: ease GC's work
101
+ visited.clear();
102
+ }
74
103
  //# sourceMappingURL=blob.js.map
package/dist/blob.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":";;AAmBA,8BAuDC;AAUD,0CA2BC;AA/GD,qCAMiB;AACjB,2CAA2C;AAY3C,SAAgB,SAAS,CACvB,KAAc,EACd,OAA8B;IAE9B,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,KAAK,EAAE,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IACrC,mCAAmC;IACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IACE,GAAG,KAAK,OAAO;YACf,GAAG,KAAK,UAAU;YAClB,GAAG,KAAK,KAAK;YACb,GAAG,KAAK,MAAM,EACd,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,cAAK,EAAC,GAAG,CAAC,CAAA;IACtB,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,2BAAkB,EAAE,CAAC;YACpC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,gCAAuB,EAAE,CAAC;YACnD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAUD,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,IAAA,iBAAQ,EAAC,GAAG,CAAC,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import {\n Cid,\n RAW_BIN_MULTICODEC,\n SHA2_256_MULTIHASH_CODE,\n asCid,\n parseCid,\n} from './cid.js'\nimport { isPlainObject } from './object.js'\n\n/**\n * @note {@link BlobRef} is just a {@link LexMap} with a specific shape.\n */\nexport type BlobRef = {\n $type: 'blob'\n mimeType: string\n ref: Cid\n size: number\n}\n\nexport function isBlobRef(\n input: unknown,\n options?: { strict?: boolean },\n): input is BlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n if (input?.$type !== 'blob') {\n return false\n }\n\n const { mimeType, size, ref } = input\n // @NOTE Very basic mime validation\n if (typeof mimeType !== 'string' || !mimeType.includes('/')) {\n return false\n }\n\n if (typeof size !== 'number' || size < 0 || !Number.isSafeInteger(size)) {\n return false\n }\n\n if (typeof ref !== 'object' || ref === null) {\n return false\n }\n\n for (const key in input) {\n if (\n key !== '$type' &&\n key !== 'mimeType' &&\n key !== 'ref' &&\n key !== 'size'\n ) {\n return false\n }\n }\n\n const cid = asCid(ref)\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) {\n return false\n }\n if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * @note {@link LegacyBlobRef} is just a {@link LexMap} with a specific shape.\n */\nexport type LegacyBlobRef = {\n cid: string\n mimeType: string\n}\n\nexport function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n const { cid, mimeType } = input\n if (typeof cid !== 'string') {\n return false\n }\n\n if (typeof mimeType !== 'string' || mimeType.length === 0) {\n return false\n }\n\n for (const key in input) {\n if (key !== 'cid' && key !== 'mimeType') {\n return false\n }\n }\n\n try {\n parseCid(cid)\n } catch {\n return false\n }\n\n return true\n}\n"]}
1
+ {"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":";;AAyCA,8BA+CC;AAUD,0CAyBC;AA+BD,oCAyCC;AAnMD,qCAAgE;AAEhE,2CAAyD;AAuCzD,SAAgB,SAAS,CACvB,KAAc,EACd,OAA6B;IAE7B,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,KAAK,EAAE,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IACrC,mCAAmC;IACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IACE,GAAG,KAAK,OAAO;YACf,GAAG,KAAK,UAAU;YAClB,GAAG,KAAK,KAAK;YACb,GAAG,KAAK,MAAM,EACd,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,cAAK,EACf,GAAG;IACH,oCAAoC;IACpC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAC1D,CAAA;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAUD,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAA,0BAAiB,EAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AA+BD,QAAe,CAAC,CAAC,YAAY,CAC3B,KAAe,EACf,OAA6B;IAE7B,wCAAwC;IACxC,MAAM,aAAa,GAAG,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAEnD,iDAAiD;IACjD,MAAM,KAAK,GAAe,CAAC,KAAK,CAAC,CAAA;IAEjC,8EAA8E;IAC9E,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IAEjC,GAAG,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QAE1B,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAQ;gBAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;YACtB,CAAC;iBAAM,IAAI,IAAA,wBAAY,EAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAQ;gBAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;oBAC9B,MAAM,KAAK,CAAA;gBACb,CAAC;qBAAM,IAAI,aAAa,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnD,MAAM,KAAK,CAAA;gBACb,CAAC;qBAAM,CAAC;oBACN,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;wBACrC,IAAI,CAAC,IAAI,IAAI;4BAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBAC9B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,QAAQ,KAAK,CAAC,MAAM,GAAG,CAAC,EAAC;IAE1B,+BAA+B;IAC/B,OAAO,CAAC,KAAK,EAAE,CAAA;AACjB,CAAC","sourcesContent":["import { Cid, RawCid, ifCid, validateCidString } from './cid.js'\nimport { LexValue } from './lex.js'\nimport { isPlainObject, isPlainProto } from './object.js'\n\n/**\n * @note {@link BlobRef} is just a {@link LexMap} with a specific shape.\n */\nexport type BlobRef<Ref extends Cid = Cid> = {\n $type: 'blob'\n mimeType: string\n ref: Ref\n size: number\n}\n\nexport type BlobRefCheckOptions = {\n /**\n * If `false`, skips strict CID validation of {@link BlobRef.ref}, allowing\n * any valid CID. Otherwise, validates that the CID is v1, uses the raw\n * multicodec, and has a sha256 multihash.\n *\n * @defaults to `true`\n */\n strict?: boolean\n}\n\nexport type InferCheckedBlobRef<TOptions extends BlobRefCheckOptions> =\n TOptions extends { strict: false }\n ? BlobRef\n : { strict: boolean } extends TOptions\n ? BlobRef\n : BlobRef<RawCid>\n\nexport function isBlobRef(input: unknown): input is BlobRef<RawCid>\nexport function isBlobRef<TOptions extends BlobRefCheckOptions>(\n input: unknown,\n options: TOptions,\n): input is InferCheckedBlobRef<TOptions>\nexport function isBlobRef(\n input: unknown,\n options?: BlobRefCheckOptions,\n): input is BlobRef\nexport function isBlobRef(\n input: unknown,\n options?: BlobRefCheckOptions,\n): input is BlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n if (input?.$type !== 'blob') {\n return false\n }\n\n const { mimeType, size, ref } = input\n // @NOTE Very basic mime validation\n if (typeof mimeType !== 'string' || !mimeType.includes('/')) {\n return false\n }\n\n if (typeof size !== 'number' || size < 0 || !Number.isSafeInteger(size)) {\n return false\n }\n\n if (typeof ref !== 'object' || ref === null) {\n return false\n }\n\n for (const key in input) {\n if (\n key !== '$type' &&\n key !== 'mimeType' &&\n key !== 'ref' &&\n key !== 'size'\n ) {\n return false\n }\n }\n\n const cid = ifCid(\n ref,\n // Strict unless explicitly disabled\n options?.strict === false ? undefined : { flavor: 'raw' },\n )\n if (!cid) {\n return false\n }\n\n return true\n}\n\n/**\n * @note {@link LegacyBlobRef} is just a {@link LexMap} with a specific shape.\n */\nexport type LegacyBlobRef = {\n cid: string\n mimeType: string\n}\n\nexport function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n const { cid, mimeType } = input\n if (typeof cid !== 'string') {\n return false\n }\n\n if (typeof mimeType !== 'string' || mimeType.length === 0) {\n return false\n }\n\n for (const key in input) {\n if (key !== 'cid' && key !== 'mimeType') {\n return false\n }\n }\n\n if (!validateCidString(cid)) {\n return false\n }\n\n return true\n}\n\nexport type EnumBlobRefsOptions = BlobRefCheckOptions & {\n /**\n * @defaults to `false`\n */\n allowLegacy?: boolean\n}\n\nexport type InferEnumBlobRefs<TOptions extends EnumBlobRefsOptions> =\n TOptions extends { allowLegacy: true }\n ? InferCheckedBlobRef<TOptions> | LegacyBlobRef\n : { allowLegacy: boolean } extends TOptions\n ? InferCheckedBlobRef<TOptions> | LegacyBlobRef\n : InferCheckedBlobRef<TOptions>\n\n/**\n * Enumerates all {@link BlobRef}s (and, optionally, {@link LegacyBlobRef}s)\n * found within a {@link LexValue}.\n */\nexport function enumBlobRefs(\n input: LexValue,\n): Generator<BlobRef<RawCid>, void, unknown>\nexport function enumBlobRefs<TOptions extends EnumBlobRefsOptions>(\n input: LexValue,\n options: TOptions,\n): Generator<InferEnumBlobRefs<TOptions>, void, unknown>\nexport function enumBlobRefs(\n input: LexValue,\n options?: EnumBlobRefsOptions,\n): Generator<BlobRef | LegacyBlobRef, void, unknown>\nexport function* enumBlobRefs(\n input: LexValue,\n options?: EnumBlobRefsOptions,\n): Generator<BlobRef | LegacyBlobRef, void, unknown> {\n // LegacyBlobRef not included by default\n const includeLegacy = options?.allowLegacy === true\n\n // Using a stack to avoid recursion depth issues.\n const stack: LexValue[] = [input]\n\n // Since we are using a stack, we could end-up in an infinite loop with cyclic\n // structures. Cyclic structures are not valid LexValues and should, thus,\n // never occur, but let's be safe.\n const visited = new Set<object>()\n\n do {\n const value = stack.pop()!\n\n if (value != null && typeof value === 'object') {\n if (Array.isArray(value)) {\n if (visited.has(value)) continue\n visited.add(value)\n stack.push(...value)\n } else if (isPlainProto(value)) {\n if (visited.has(value)) continue\n visited.add(value)\n if (isBlobRef(value, options)) {\n yield value\n } else if (includeLegacy && isLegacyBlobRef(value)) {\n yield value\n } else {\n for (const v of Object.values(value)) {\n if (v != null) stack.push(v)\n }\n }\n }\n }\n } while (stack.length > 0)\n\n // Optimization: ease GC's work\n visited.clear()\n}\n"]}
package/dist/cid.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { CID } from 'multiformats/cid';
2
2
  export declare const DAG_CBOR_MULTICODEC = 113;
3
- export declare const RAW_BIN_MULTICODEC = 85;
4
- export declare const SHA2_256_MULTIHASH_CODE = 18;
3
+ export type DAG_CBOR_MULTICODEC = typeof DAG_CBOR_MULTICODEC;
4
+ export declare const RAW_MULTICODEC = 85;
5
+ export type RAW_MULTICODEC = typeof RAW_MULTICODEC;
6
+ export declare const SHA256_MULTIHASH: 18;
7
+ export type SHA256_MULTIHASH = typeof SHA256_MULTIHASH;
5
8
  export type MultihashDigest<Code extends number = number> = {
6
9
  code: Code;
7
10
  digest: Uint8Array;
@@ -11,8 +14,8 @@ export type MultihashDigest<Code extends number = number> = {
11
14
  declare module 'multiformats/cid' {
12
15
  /**
13
16
  * @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and
14
- * related helpers ({@link asCid}, {@link parseCid}, {@link decodeCid},
15
- * {@link createCid}, {@link isCid}), instead.
17
+ * related helpers ({@link isCid}, {@link ifCid}, {@link asCid},
18
+ * {@link parseCid}, {@link decodeCid}), instead.
16
19
  *
17
20
  * This is marked as deprecated because we want to discourage direct usage of
18
21
  * `multiformats/cid` in dependent packages, and instead have them rely on the
@@ -44,14 +47,80 @@ export interface Cid {
44
47
  equals(other: unknown): boolean;
45
48
  toString(): string;
46
49
  }
47
- export declare function asCid(value: unknown): Cid | null;
48
- export declare function parseCid(input: string): Cid;
49
- export declare function decodeCid(bytes: Uint8Array): Cid;
50
- export declare function createCid(code: number, digest: MultihashDigest): Cid;
51
- export declare function isCid(value: unknown, options?: {
52
- strict?: boolean;
53
- }): value is Cid;
54
- export declare function validateCidString(input: string): boolean;
55
- export declare function parseCidString(input: string): Cid | undefined;
56
- export declare function ensureValidCidString(input: string): void;
50
+ /**
51
+ * Represents the cid of raw binary data (like media blobs).
52
+ * @see {@link https://atproto.com/specs/data-model#link-and-cid-formats ATproto Data Model - Link and CID Formats}
53
+ */
54
+ export interface RawCid extends Cid {
55
+ version: 1;
56
+ code: RAW_MULTICODEC;
57
+ }
58
+ export declare function isRawCid(cid: Cid): cid is RawCid;
59
+ /**
60
+ * Represents a DASL compliant CID.
61
+ * @see {@link https://dasl.ing/cid.html DASL-CIDs}
62
+ */
63
+ export interface DaslCid extends Cid {
64
+ version: 1;
65
+ code: RAW_MULTICODEC | DAG_CBOR_MULTICODEC;
66
+ multihash: MultihashDigest<SHA256_MULTIHASH>;
67
+ }
68
+ export declare function isDaslCid(cid: Cid): cid is DaslCid;
69
+ /**
70
+ * Represents the cid of ATProto DAG-CBOR data (like repository MST nodes).
71
+ * @see {@link https://atproto.com/specs/data-model#link-and-cid-formats ATproto Data Model - Link and CID Formats}
72
+ */
73
+ export interface CborCid extends DaslCid {
74
+ code: DAG_CBOR_MULTICODEC;
75
+ }
76
+ export declare function isCborCid(cid: Cid): cid is CborCid;
77
+ export type CidCheckOptions = {
78
+ flavor?: 'raw' | 'cbor' | 'dasl';
79
+ };
80
+ export type InferCheckedCid<TOptions> = TOptions extends {
81
+ flavor: 'raw';
82
+ } ? RawCid : TOptions extends {
83
+ flavor: 'cbor';
84
+ } ? CborCid : Cid;
85
+ /**
86
+ * Coerces the input value to a Cid, or returns null if not possible.
87
+ */
88
+ export declare function ifCid<TOptions extends CidCheckOptions>(value: unknown, options: TOptions): InferCheckedCid<TOptions> | null;
89
+ export declare function ifCid(value: unknown, options?: CidCheckOptions): Cid | null;
90
+ export declare function isCid<TOptions extends CidCheckOptions>(value: unknown, options: TOptions): value is InferCheckedCid<TOptions>;
91
+ export declare function isCid(value: unknown, options?: CidCheckOptions): value is Cid;
92
+ /**
93
+ * Coerces the input value to a Cid, or throws if not possible.
94
+ */
95
+ export declare function asCid<TOptions extends CidCheckOptions>(value: unknown, options: TOptions): InferCheckedCid<TOptions>;
96
+ export declare function asCid(value: unknown, options?: CidCheckOptions): Cid;
97
+ /**
98
+ * Parses a CID string into a Cid object.
99
+ *
100
+ * @throws if the input is not a valid CID string.
101
+ */
102
+ export declare function parseCid<TOptions extends CidCheckOptions>(input: string, options: TOptions): InferCheckedCid<TOptions>;
103
+ export declare function parseCid(input: string, options?: CidCheckOptions): Cid;
104
+ /**
105
+ * Decodes a CID from its binary representation.
106
+ *
107
+ * @see {@link https://dasl.ing/cid.html DASL-CIDs}
108
+ * @throws if the input do not represent a valid DASL {@link Cid}
109
+ */
110
+ export declare function decodeCid<TOptions extends CidCheckOptions>(cidBytes: Uint8Array, options: TOptions): InferCheckedCid<TOptions>;
111
+ export declare function decodeCid(cidBytes: Uint8Array, options?: CidCheckOptions): Cid;
112
+ export declare function validateCidString(input: string, options?: CidCheckOptions): boolean;
113
+ export declare function parseCidString<TOptions extends CidCheckOptions>(input: string, options: TOptions): InferCheckedCid<TOptions> | undefined;
114
+ export declare function parseCidString(input: string, options?: CidCheckOptions): Cid | undefined;
115
+ export declare function ensureValidCidString(input: string, options?: CidCheckOptions): void;
116
+ /**
117
+ * Verifies whether the multihash of a given {@link cid} matches the hash of the provided {@link bytes}.
118
+ * @params cid The CID to match against the bytes.
119
+ * @params bytes The bytes to verify.
120
+ * @returns true if the CID matches the bytes, false otherwise.
121
+ */
122
+ export declare function isCidForBytes(cid: Cid, bytes: Uint8Array): Promise<boolean>;
123
+ export declare function cidForCbor(bytes: Uint8Array): Promise<CborCid>;
124
+ export declare function cidForRawBytes(bytes: Uint8Array): Promise<RawCid>;
125
+ export declare function cidForRawHash(hash: Uint8Array): RawCid;
57
126
  //# sourceMappingURL=cid.d.ts.map
package/dist/cid.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAEtC,eAAO,MAAM,mBAAmB,MAAO,CAAA;AACvC,eAAO,MAAM,kBAAkB,KAAO,CAAA;AAEtC,eAAO,MAAM,uBAAuB,KAAO,CAAA;AAE3C,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1D,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,CAAA;CAClB,CAAA;AAED,OAAO,QAAQ,kBAAkB,CAAC;IAChC;;;;;;;;;;;;;;;;;;OAkBG;IACH,UAAU,GAAG;KAAG;CACjB;AAqBD,OAAO,EAAE,GAAG,EAAE,CAAA;AAEd;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,eAAe,CAAA;IAC1B,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;IAC/B,QAAQ,IAAI,MAAM,CAAA;CACnB;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,GAAG,IAAI,CAEhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAE3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAEhD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,GAAG,CAEpE;AAED,wBAAgB,KAAK,CACnB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,KAAK,IAAI,GAAG,CAmBd;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAM7D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxD"}
1
+ {"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":"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"}
package/dist/cid.js CHANGED
@@ -1,63 +1,122 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CID = exports.SHA2_256_MULTIHASH_CODE = exports.RAW_BIN_MULTICODEC = exports.DAG_CBOR_MULTICODEC = void 0;
3
+ exports.CID = exports.SHA256_MULTIHASH = exports.RAW_MULTICODEC = exports.DAG_CBOR_MULTICODEC = void 0;
4
+ exports.isRawCid = isRawCid;
5
+ exports.isDaslCid = isDaslCid;
6
+ exports.isCborCid = isCborCid;
7
+ exports.ifCid = ifCid;
8
+ exports.isCid = isCid;
4
9
  exports.asCid = asCid;
5
10
  exports.parseCid = parseCid;
6
11
  exports.decodeCid = decodeCid;
7
- exports.createCid = createCid;
8
- exports.isCid = isCid;
9
12
  exports.validateCidString = validateCidString;
10
13
  exports.parseCidString = parseCidString;
11
14
  exports.ensureValidCidString = ensureValidCidString;
15
+ exports.isCidForBytes = isCidForBytes;
16
+ exports.cidForCbor = cidForCbor;
17
+ exports.cidForRawBytes = cidForRawBytes;
18
+ exports.cidForRawHash = cidForRawHash;
12
19
  const cid_1 = require("multiformats/cid");
13
20
  Object.defineProperty(exports, "CID", { enumerable: true, get: function () { return cid_1.CID; } });
14
- exports.DAG_CBOR_MULTICODEC = 0x71;
15
- exports.RAW_BIN_MULTICODEC = 0x55;
16
- exports.SHA2_256_MULTIHASH_CODE = 0x12;
17
- function asCid(value) {
18
- return cid_1.CID.asCID(value);
21
+ const digest_1 = require("multiformats/hashes/digest");
22
+ const sha2_1 = require("multiformats/hashes/sha2");
23
+ exports.DAG_CBOR_MULTICODEC = 0x71; // DRISL conformant DAG-CBOR
24
+ exports.RAW_MULTICODEC = 0x55; // raw binary codec used in DASL CIDs
25
+ exports.SHA256_MULTIHASH = sha2_1.sha256.code;
26
+ function isRawCid(cid) {
27
+ return cid.version === 1 && cid.code === exports.RAW_MULTICODEC;
19
28
  }
20
- function parseCid(input) {
21
- return cid_1.CID.parse(input);
29
+ function isDaslCid(cid) {
30
+ return (cid.version === 1 &&
31
+ (cid.code === exports.RAW_MULTICODEC || cid.code === exports.DAG_CBOR_MULTICODEC) &&
32
+ cid.multihash.code === exports.SHA256_MULTIHASH &&
33
+ cid.multihash.size === 32 // Should always be 32 bytes (256 bits) for SHA-256
34
+ );
22
35
  }
23
- function decodeCid(bytes) {
24
- return cid_1.CID.decode(bytes);
36
+ function isCborCid(cid) {
37
+ return cid.code === exports.DAG_CBOR_MULTICODEC && isDaslCid(cid);
25
38
  }
26
- function createCid(code, digest) {
27
- return cid_1.CID.createV1(code, digest);
28
- }
29
- function isCid(value, options) {
30
- const cid = asCid(value);
39
+ function ifCid(value, options) {
40
+ const cid = cid_1.CID.asCID(value);
31
41
  if (!cid) {
32
- return false;
42
+ return null;
33
43
  }
34
- if (options?.strict) {
35
- if (cid.version !== 1) {
36
- return false;
37
- }
38
- if (cid.code !== exports.RAW_BIN_MULTICODEC && cid.code !== exports.DAG_CBOR_MULTICODEC) {
39
- return false;
40
- }
41
- if (cid.multihash.code !== exports.SHA2_256_MULTIHASH_CODE) {
42
- return false;
43
- }
44
+ switch (options?.flavor) {
45
+ case 'cbor':
46
+ return isCborCid(cid) ? cid : null;
47
+ case 'raw':
48
+ return isRawCid(cid) ? cid : null;
49
+ case 'dasl':
50
+ return isDaslCid(cid) ? cid : null;
51
+ default:
52
+ return cid;
44
53
  }
45
- return true;
46
54
  }
47
- function validateCidString(input) {
48
- return parseCidString(input)?.toString() === input;
55
+ function isCid(value, options) {
56
+ return ifCid(value, options) !== null;
57
+ }
58
+ function asCid(value, options) {
59
+ const cid = ifCid(value, options);
60
+ if (cid)
61
+ return cid;
62
+ throw new Error('Not a valid CID');
63
+ }
64
+ function parseCid(input, options) {
65
+ const cid = cid_1.CID.parse(input);
66
+ return asCid(cid, options);
67
+ }
68
+ function decodeCid(cidBytes, options) {
69
+ const cid = cid_1.CID.decode(cidBytes);
70
+ return asCid(cid, options);
49
71
  }
50
- function parseCidString(input) {
72
+ function validateCidString(input, options) {
73
+ return parseCidString(input, options)?.toString() === input;
74
+ }
75
+ function parseCidString(input, options) {
51
76
  try {
52
- return parseCid(input);
77
+ return parseCid(input, options);
53
78
  }
54
79
  catch {
55
80
  return undefined;
56
81
  }
57
82
  }
58
- function ensureValidCidString(input) {
59
- if (!validateCidString(input)) {
83
+ function ensureValidCidString(input, options) {
84
+ if (!validateCidString(input, options)) {
60
85
  throw new Error(`Invalid CID string`);
61
86
  }
62
87
  }
88
+ /**
89
+ * Verifies whether the multihash of a given {@link cid} matches the hash of the provided {@link bytes}.
90
+ * @params cid The CID to match against the bytes.
91
+ * @params bytes The bytes to verify.
92
+ * @returns true if the CID matches the bytes, false otherwise.
93
+ */
94
+ async function isCidForBytes(cid, bytes) {
95
+ if (cid.multihash.code === sha2_1.sha256.code) {
96
+ const digest = await sha2_1.sha256.digest(bytes);
97
+ return (0, digest_1.equals)(cid.multihash, digest);
98
+ }
99
+ if (cid.multihash.code === sha2_1.sha512.code) {
100
+ const digest = await sha2_1.sha512.digest(bytes);
101
+ return (0, digest_1.equals)(cid.multihash, digest);
102
+ }
103
+ // Don't know how to verify other multihash codes
104
+ throw new Error('Unsupported CID multihash');
105
+ }
106
+ async function cidForCbor(bytes) {
107
+ const digest = await sha2_1.sha256.digest(bytes);
108
+ return cid_1.CID.createV1(exports.DAG_CBOR_MULTICODEC, digest);
109
+ }
110
+ async function cidForRawBytes(bytes) {
111
+ const digest = await sha2_1.sha256.digest(bytes);
112
+ return cid_1.CID.createV1(exports.RAW_MULTICODEC, digest);
113
+ }
114
+ function cidForRawHash(hash) {
115
+ // Fool-proofing
116
+ if (hash.length !== 32) {
117
+ throw new Error(`Invalid SHA-256 hash length: ${hash.length}`);
118
+ }
119
+ const digest = (0, digest_1.create)(sha2_1.sha256.code, hash);
120
+ return cid_1.CID.createV1(exports.RAW_MULTICODEC, digest);
121
+ }
63
122
  //# sourceMappingURL=cid.js.map
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 {\n create as createDigest,\n equals as digestEquals,\n} from 'multiformats/hashes/digest'\nimport { sha256, sha512 } from 'multiformats/hashes/sha2'\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 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 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`, 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\n/**\n * Represents the cid of raw binary data (like media blobs).\n * @see {@link https://atproto.com/specs/data-model#link-and-cid-formats ATproto Data Model - Link and CID Formats}\n */\nexport interface RawCid extends Cid {\n version: 1\n code: RAW_MULTICODEC\n}\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 interface DaslCid extends Cid {\n version: 1\n code: RAW_MULTICODEC | DAG_CBOR_MULTICODEC\n multihash: MultihashDigest<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.size === 32 // Should always be 32 bytes (256 bits) for SHA-256\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 interface CborCid extends DaslCid {\n code: DAG_CBOR_MULTICODEC\n}\n\nexport function isCborCid(cid: Cid): cid is CborCid {\n return cid.code === DAG_CBOR_MULTICODEC && isDaslCid(cid)\n}\n\nexport type CidCheckOptions = {\n flavor?: 'raw' | 'cbor' | 'dasl'\n}\nexport type InferCheckedCid<TOptions> = TOptions extends { flavor: 'raw' }\n ? RawCid\n : TOptions extends { flavor: 'cbor' }\n ? CborCid\n : Cid\n\n/**\n * Coerces the input value to a Cid, or returns null if not possible.\n */\nexport function ifCid<TOptions extends CidCheckOptions>(\n value: unknown,\n options: TOptions,\n): InferCheckedCid<TOptions> | null\nexport function ifCid(value: unknown, options?: CidCheckOptions): Cid | null\nexport function ifCid(value: unknown, options?: CidCheckOptions): Cid | null {\n const cid = CID.asCID(value)\n if (!cid) {\n return null\n }\n\n switch (options?.flavor) {\n case 'cbor':\n return isCborCid(cid) ? cid : null\n case 'raw':\n return isRawCid(cid) ? cid : null\n case 'dasl':\n return isDaslCid(cid) ? cid : null\n default:\n return cid\n }\n}\n\nexport function isCid<TOptions extends CidCheckOptions>(\n value: unknown,\n options: TOptions,\n): value is InferCheckedCid<TOptions>\nexport function isCid(value: unknown, options?: CidCheckOptions): value is Cid\nexport function isCid(value: unknown, options?: CidCheckOptions): value is Cid {\n return ifCid(value, options) !== null\n}\n\n/**\n * Coerces the input value to a Cid, or throws if not possible.\n */\nexport function asCid<TOptions extends CidCheckOptions>(\n value: unknown,\n options: TOptions,\n): InferCheckedCid<TOptions>\nexport function asCid(value: unknown, options?: CidCheckOptions): Cid\nexport function asCid(value: unknown, options?: CidCheckOptions): Cid {\n const cid = ifCid(value, options)\n if (cid) return cid\n throw new Error('Not a valid CID')\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 CidCheckOptions>(\n input: string,\n options: TOptions,\n): InferCheckedCid<TOptions>\nexport function parseCid(input: string, options?: CidCheckOptions): Cid\nexport function parseCid(input: string, options?: CidCheckOptions): Cid {\n const cid = CID.parse(input)\n return asCid(cid, options)\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 CidCheckOptions>(\n cidBytes: Uint8Array,\n options: TOptions,\n): InferCheckedCid<TOptions>\nexport function decodeCid(cidBytes: Uint8Array, options?: CidCheckOptions): Cid\nexport function decodeCid(\n cidBytes: Uint8Array,\n options?: CidCheckOptions,\n): Cid {\n const cid = CID.decode(cidBytes)\n return asCid(cid, options)\n}\n\nexport function validateCidString(\n input: string,\n options?: CidCheckOptions,\n): boolean {\n return parseCidString(input, options)?.toString() === input\n}\n\nexport function parseCidString<TOptions extends CidCheckOptions>(\n input: string,\n options: TOptions,\n): InferCheckedCid<TOptions> | undefined\nexport function parseCidString(\n input: string,\n options?: CidCheckOptions,\n): Cid | undefined\nexport function parseCidString(\n input: string,\n options?: CidCheckOptions,\n): Cid | undefined {\n try {\n return parseCid(input, options)\n } catch {\n return undefined\n }\n}\n\nexport function ensureValidCidString(\n input: string,\n options?: CidCheckOptions,\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 digest = await sha256.digest(bytes)\n return digestEquals(cid.multihash, digest)\n }\n\n if (cid.multihash.code === sha512.code) {\n const digest = await sha512.digest(bytes)\n return digestEquals(cid.multihash, digest)\n }\n\n // Don't know how to verify other multihash codes\n throw new Error('Unsupported CID multihash')\n}\n\nexport async function cidForCbor(bytes: Uint8Array): Promise<CborCid> {\n const digest = await sha256.digest(bytes)\n return CID.createV1(DAG_CBOR_MULTICODEC, digest) as CborCid\n}\n\nexport async function cidForRawBytes(bytes: Uint8Array): Promise<RawCid> {\n const digest = await sha256.digest(bytes)\n return CID.createV1(RAW_MULTICODEC, digest) as RawCid\n}\n\nexport function cidForRawHash(hash: Uint8Array): RawCid {\n // Fool-proofing\n if (hash.length !== 32) {\n throw new Error(`Invalid SHA-256 hash length: ${hash.length}`)\n }\n const digest = createDigest(sha256.code, hash)\n return CID.createV1(RAW_MULTICODEC, digest) as RawCid\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"uint8array-from-base64.d.ts","sourceRoot":"","sources":["../src/uint8array-from-base64.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAIvD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B;;WAEG;QACH,UAAU,CAAC,EAAE,CACX,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;YACR,wBAAwB;YACxB,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAA;YACjC,iBAAiB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,qBAAqB,CAAA;SAC/D,KACE,UAAU,CAAA;KAChB;CACF;AAED,eAAO,MAAM,gBAAgB,SAGhB,MAAM,aACD,cAAc,KACvB,UAAU,QAMT,CAAA;AAEV,eAAO,MAAM,cAAc,SAEhB,MAAM,aACD,cAAc,KACvB,UAAU,QAQyB,CAAA;AAE1C,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,cAAyB,GAClC,UAAU,CAIZ"}
1
+ {"version":3,"file":"uint8array-from-base64.d.ts","sourceRoot":"","sources":["../src/uint8array-from-base64.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAIvD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B;;WAEG;QACH,UAAU,CAAC,EAAE,CACX,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;YACR,wBAAwB;YACxB,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAA;YACjC,iBAAiB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,qBAAqB,CAAA;SAC/D,KACE,UAAU,CAAA;KAChB;CACF;AAED,eAAO,MAAM,gBAAgB,SAGhB,MAAM,aACD,cAAc,KACvB,UAAU,QAMyB,CAAA;AAE5C,eAAO,MAAM,cAAc,SAEhB,MAAM,aACD,cAAc,KACvB,UAAU,QAQyB,CAAA;AAE1C,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,cAAyB,GAClC,UAAU,CAIZ"}
@@ -12,7 +12,7 @@ exports.fromBase64Native = typeof Uint8Array.fromBase64 === 'function'
12
12
  lastChunkHandling: 'loose',
13
13
  });
14
14
  }
15
- : null;
15
+ : /* v8 ignore next -- @preserve */ null;
16
16
  exports.fromBase64Node = Buffer
17
17
  ? function fromBase64Node(b64, alphabet = 'base64') {
18
18
  const bytes = Buffer.from(b64, alphabet);