@atproto/lex-data 0.0.7 → 0.0.9

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ui8Concat = exports.fromBase64 = exports.toBase64 = void 0;
4
+ exports.ifUint8Array = ifUint8Array;
4
5
  exports.asUint8Array = asUint8Array;
5
6
  exports.ui8Equals = ui8Equals;
6
7
  const uint8array_concat_js_1 = require("./uint8array-concat.js");
@@ -17,8 +18,8 @@ const uint8array_to_base64_js_1 = require("./uint8array-to-base64.js");
17
18
  */
18
19
  exports.toBase64 =
19
20
  /* v8 ignore next -- @preserve */ uint8array_to_base64_js_1.toBase64Native ??
20
- /* v8 ignore next -- @preserve */ uint8array_to_base64_js_1.toBase64Node ??
21
- /* v8 ignore next -- @preserve */ uint8array_to_base64_js_1.toBase64Ponyfill;
21
+ uint8array_to_base64_js_1.toBase64Node ??
22
+ uint8array_to_base64_js_1.toBase64Ponyfill;
22
23
  /**
23
24
  * Decodes a base64 string into a Uint8Array. This function supports both padded
24
25
  * and unpadded base64 strings.
@@ -28,13 +29,19 @@ exports.toBase64 =
28
29
  */
29
30
  exports.fromBase64 =
30
31
  /* v8 ignore next -- @preserve */ uint8array_from_base64_js_1.fromBase64Native ??
31
- /* v8 ignore next -- @preserve */ uint8array_from_base64_js_1.fromBase64Node ??
32
- /* v8 ignore next -- @preserve */ uint8array_from_base64_js_1.fromBase64Ponyfill;
32
+ uint8array_from_base64_js_1.fromBase64Node ??
33
+ uint8array_from_base64_js_1.fromBase64Ponyfill;
33
34
  /* v8 ignore next -- @preserve */
34
35
  if (exports.toBase64 === uint8array_to_base64_js_1.toBase64Ponyfill || exports.fromBase64 === uint8array_from_base64_js_1.fromBase64Ponyfill) {
35
36
  /*#__PURE__*/
36
37
  console.warn('[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.');
37
38
  }
39
+ function ifUint8Array(input) {
40
+ if (input instanceof Uint8Array) {
41
+ return input;
42
+ }
43
+ return undefined;
44
+ }
38
45
  /**
39
46
  * Coerces various binary data representations into a Uint8Array.
40
47
  *
@@ -64,6 +71,5 @@ function ui8Equals(a, b) {
64
71
  return true;
65
72
  }
66
73
  exports.ui8Concat =
67
- /* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatNode ??
68
- /* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatPonyfill;
74
+ /* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatNode ?? uint8array_concat_js_1.ui8ConcatPonyfill;
69
75
  //# sourceMappingURL=uint8array.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uint8array.js","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":";;;AA6DA,oCAkBC;AAED,8BAYC;AA5FD,iEAAyE;AACzE,2EAIoC;AACpC,uEAIkC;AAIlC,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAE1C;;;;GAIG;AACU,QAAA,QAAQ;AAInB,iCAAiC,CAAC,wCAAc;IAChD,iCAAiC,CAAC,sCAAY;IAC9C,iCAAiC,CAAC,0CAAgB,CAAA;AAEpD;;;;;;GAMG;AACU,QAAA,UAAU;AAIrB,iCAAiC,CAAC,4CAAgB;IAClD,iCAAiC,CAAC,0CAAc;IAChD,iCAAiC,CAAC,8CAAkB,CAAA;AAEtD,iCAAiC;AACjC,IAAI,gBAAQ,KAAK,0CAAgB,IAAI,kBAAU,KAAK,8CAAkB,EAAE,CAAC;IACvE,aAAa;IACb,OAAO,CAAC,IAAI,CACV,wJAAwJ,CACzJ,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,UAAU,CACnB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAChD,CAAA;IACH,CAAC;IAED,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAEY,QAAA,SAAS;AACpB,iCAAiC,CAAC,oCAAa;IAC/C,iCAAiC,CAAC,wCAAiB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array-base64.js'\nimport { ui8ConcatNode, ui8ConcatPonyfill } from './uint8array-concat.js'\nimport {\n fromBase64Native,\n fromBase64Node,\n fromBase64Ponyfill,\n} from './uint8array-from-base64.js'\nimport {\n toBase64Native,\n toBase64Node,\n toBase64Ponyfill,\n} from './uint8array-to-base64.js'\n\nexport type { Base64Alphabet }\n\n// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /\n// Uint8Array.prototype.toBase64 is widely supported, and mark fromBase64 /\n// toBase64 as deprecated. We can also drop NodeJS specific implementations\n// once NodeJS <24 is no longer supported.\n\n/**\n * Encodes a Uint8Array into a base64 string.\n *\n * @returns The base64 encoded string\n */\nexport const toBase64: (\n bytes: Uint8Array,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ toBase64Native ??\n /* v8 ignore next -- @preserve */ toBase64Node ??\n /* v8 ignore next -- @preserve */ toBase64Ponyfill\n\n/**\n * Decodes a base64 string into a Uint8Array. This function supports both padded\n * and unpadded base64 strings.\n *\n * @returns The decoded {@link Uint8Array}\n * @throws If the input is not a valid base64 string\n */\nexport const fromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => Uint8Array =\n /* v8 ignore next -- @preserve */ fromBase64Native ??\n /* v8 ignore next -- @preserve */ fromBase64Node ??\n /* v8 ignore next -- @preserve */ fromBase64Ponyfill\n\n/* v8 ignore next -- @preserve */\nif (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\n/**\n * Coerces various binary data representations into a Uint8Array.\n *\n * @return `undefined` if the input could not be coerced into a {@link Uint8Array}.\n */\nexport function asUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n if (ArrayBuffer.isView(input)) {\n return new Uint8Array(\n input.buffer,\n input.byteOffset,\n input.byteLength / Uint8Array.BYTES_PER_ELEMENT,\n )\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input)\n }\n\n return undefined\n}\n\nexport function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {\n if (a.byteLength !== b.byteLength) {\n return false\n }\n\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n\nexport const ui8Concat =\n /* v8 ignore next -- @preserve */ ui8ConcatNode ??\n /* v8 ignore next -- @preserve */ ui8ConcatPonyfill\n"]}
1
+ {"version":3,"file":"uint8array.js","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":";;;AAwDA,oCAMC;AAOD,oCAkBC;AAED,8BAYC;AApGD,iEAAyE;AACzE,2EAIoC;AACpC,uEAIkC;AAIlC,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAE1C;;;;GAIG;AACU,QAAA,QAAQ;AAInB,iCAAiC,CAAC,wCAAc;IAChD,sCAAY;IACZ,0CAAgB,CAAA;AAElB;;;;;;GAMG;AACU,QAAA,UAAU;AAIrB,iCAAiC,CAAC,4CAAgB;IAClD,0CAAc;IACd,8CAAkB,CAAA;AAEpB,iCAAiC;AACjC,IAAI,gBAAQ,KAAK,0CAAgB,IAAI,kBAAU,KAAK,8CAAkB,EAAE,CAAC;IACvE,aAAa;IACb,OAAO,CAAC,IAAI,CACV,wJAAwJ,CACzJ,CAAA;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,UAAU,CACnB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAChD,CAAA;IACH,CAAC;IAED,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAEY,QAAA,SAAS;AACpB,iCAAiC,CAAC,oCAAa,IAAI,wCAAiB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array-base64.js'\nimport { ui8ConcatNode, ui8ConcatPonyfill } from './uint8array-concat.js'\nimport {\n fromBase64Native,\n fromBase64Node,\n fromBase64Ponyfill,\n} from './uint8array-from-base64.js'\nimport {\n toBase64Native,\n toBase64Node,\n toBase64Ponyfill,\n} from './uint8array-to-base64.js'\n\nexport type { Base64Alphabet }\n\n// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /\n// Uint8Array.prototype.toBase64 is widely supported, and mark fromBase64 /\n// toBase64 as deprecated. We can also drop NodeJS specific implementations\n// once NodeJS <24 is no longer supported.\n\n/**\n * Encodes a Uint8Array into a base64 string.\n *\n * @returns The base64 encoded string\n */\nexport const toBase64: (\n bytes: Uint8Array,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ toBase64Native ??\n toBase64Node ??\n toBase64Ponyfill\n\n/**\n * Decodes a base64 string into a Uint8Array. This function supports both padded\n * and unpadded base64 strings.\n *\n * @returns The decoded {@link Uint8Array}\n * @throws If the input is not a valid base64 string\n */\nexport const fromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => Uint8Array =\n /* v8 ignore next -- @preserve */ fromBase64Native ??\n fromBase64Node ??\n fromBase64Ponyfill\n\n/* v8 ignore next -- @preserve */\nif (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\nexport function ifUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n return undefined\n}\n\n/**\n * Coerces various binary data representations into a Uint8Array.\n *\n * @return `undefined` if the input could not be coerced into a {@link Uint8Array}.\n */\nexport function asUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n if (ArrayBuffer.isView(input)) {\n return new Uint8Array(\n input.buffer,\n input.byteOffset,\n input.byteLength / Uint8Array.BYTES_PER_ELEMENT,\n )\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input)\n }\n\n return undefined\n}\n\nexport function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {\n if (a.byteLength !== b.byteLength) {\n return false\n }\n\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n\nexport const ui8Concat =\n /* v8 ignore next -- @preserve */ ui8ConcatNode ?? ui8ConcatPonyfill\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"utf8.d.ts","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAShD,eAAO,MAAM,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAEY,CAAA;AAUvD,eAAO,MAAM,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAEQ,CAAA;AAElD,eAAO,MAAM,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,MAEf,CAAA;AAExD,eAAO,MAAM,cAAc,EAAE,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,MAEqD,CAAA"}
1
+ {"version":3,"file":"utf8.d.ts","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAShD,eAAO,MAAM,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MACiC,CAAA;AAU5E,eAAO,MAAM,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MACuB,CAAA;AAEjE,eAAO,MAAM,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,MACK,CAAA;AAE5E,eAAO,MAAM,cAAc,EAAE,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,MAC2E,CAAA"}
package/dist/utf8.js CHANGED
@@ -6,20 +6,16 @@ const utf8_grapheme_len_js_1 = require("./utf8-grapheme-len.js");
6
6
  const utf8_len_js_1 = require("./utf8-len.js");
7
7
  const utf8_to_base64_js_1 = require("./utf8-to-base64.js");
8
8
  exports.graphemeLen =
9
- /* v8 ignore next -- @preserve */ utf8_grapheme_len_js_1.graphemeLenNative ??
10
- /* v8 ignore next -- @preserve */ utf8_grapheme_len_js_1.graphemeLenPonyfill;
9
+ /* v8 ignore next -- @preserve */ utf8_grapheme_len_js_1.graphemeLenNative ?? utf8_grapheme_len_js_1.graphemeLenPonyfill;
11
10
  /* v8 ignore next -- @preserve */
12
11
  if (exports.graphemeLen === utf8_grapheme_len_js_1.graphemeLenPonyfill) {
13
12
  /*#__PURE__*/
14
13
  console.warn('[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.');
15
14
  }
16
15
  exports.utf8Len =
17
- /* v8 ignore next -- @preserve */ utf8_len_js_1.utf8LenNode ??
18
- /* v8 ignore next -- @preserve */ utf8_len_js_1.utf8LenCompute;
16
+ /* v8 ignore next -- @preserve */ utf8_len_js_1.utf8LenNode ?? utf8_len_js_1.utf8LenCompute;
19
17
  exports.utf8ToBase64 =
20
- /* v8 ignore next -- @preserve */ utf8_to_base64_js_1.utf8ToBase64Node ??
21
- /* v8 ignore next -- @preserve */ utf8_to_base64_js_1.utf8ToBase64Ponyfill;
18
+ /* v8 ignore next -- @preserve */ utf8_to_base64_js_1.utf8ToBase64Node ?? utf8_to_base64_js_1.utf8ToBase64Ponyfill;
22
19
  exports.utf8FromBase64 =
23
- /* v8 ignore next -- @preserve */ utf8_from_base64_js_1.utf8FromBase64Node ??
24
- /* v8 ignore next -- @preserve */ utf8_from_base64_js_1.utf8FromBase64Ponyfill;
20
+ /* v8 ignore next -- @preserve */ utf8_from_base64_js_1.utf8FromBase64Node ?? utf8_from_base64_js_1.utf8FromBase64Ponyfill;
25
21
  //# sourceMappingURL=utf8.js.map
package/dist/utf8.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utf8.js","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":";;;AACA,+DAG8B;AAC9B,iEAA+E;AAC/E,+CAA2D;AAC3D,2DAA4E;AAE/D,QAAA,WAAW;AACtB,iCAAiC,CAAC,wCAAiB;IACnD,iCAAiC,CAAC,0CAAmB,CAAA;AAEvD,iCAAiC;AACjC,IAAI,mBAAW,KAAK,0CAAmB,EAAE,CAAC;IACxC,aAAa;IACb,OAAO,CAAC,IAAI,CACV,oHAAoH,CACrH,CAAA;AACH,CAAC;AAEY,QAAA,OAAO;AAClB,iCAAiC,CAAC,yBAAW;IAC7C,iCAAiC,CAAC,4BAAc,CAAA;AAErC,QAAA,YAAY;AACvB,iCAAiC,CAAC,oCAAgB;IAClD,iCAAiC,CAAC,wCAAoB,CAAA;AAE3C,QAAA,cAAc;AAIzB,iCAAiC,CAAC,wCAAkB;IACpD,iCAAiC,CAAC,4CAAsB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array.js'\nimport {\n utf8FromBase64Node,\n utf8FromBase64Ponyfill,\n} from './utf8-from-base64.js'\nimport { graphemeLenNative, graphemeLenPonyfill } from './utf8-grapheme-len.js'\nimport { utf8LenCompute, utf8LenNode } from './utf8-len.js'\nimport { utf8ToBase64Node, utf8ToBase64Ponyfill } from './utf8-to-base64.js'\n\nexport const graphemeLen: (str: string) => number =\n /* v8 ignore next -- @preserve */ graphemeLenNative ??\n /* v8 ignore next -- @preserve */ graphemeLenPonyfill\n\n/* v8 ignore next -- @preserve */\nif (graphemeLen === graphemeLenPonyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\nexport const utf8Len: (string: string) => number =\n /* v8 ignore next -- @preserve */ utf8LenNode ??\n /* v8 ignore next -- @preserve */ utf8LenCompute\n\nexport const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string =\n /* v8 ignore next -- @preserve */ utf8ToBase64Node ??\n /* v8 ignore next -- @preserve */ utf8ToBase64Ponyfill\n\nexport const utf8FromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ utf8FromBase64Node ??\n /* v8 ignore next -- @preserve */ utf8FromBase64Ponyfill\n"]}
1
+ {"version":3,"file":"utf8.js","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":";;;AACA,+DAG8B;AAC9B,iEAA+E;AAC/E,+CAA2D;AAC3D,2DAA4E;AAE/D,QAAA,WAAW;AACtB,iCAAiC,CAAC,wCAAiB,IAAI,0CAAmB,CAAA;AAE5E,iCAAiC;AACjC,IAAI,mBAAW,KAAK,0CAAmB,EAAE,CAAC;IACxC,aAAa;IACb,OAAO,CAAC,IAAI,CACV,oHAAoH,CACrH,CAAA;AACH,CAAC;AAEY,QAAA,OAAO;AAClB,iCAAiC,CAAC,yBAAW,IAAI,4BAAc,CAAA;AAEpD,QAAA,YAAY;AACvB,iCAAiC,CAAC,oCAAgB,IAAI,wCAAoB,CAAA;AAE/D,QAAA,cAAc;AAIzB,iCAAiC,CAAC,wCAAkB,IAAI,4CAAsB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array.js'\nimport {\n utf8FromBase64Node,\n utf8FromBase64Ponyfill,\n} from './utf8-from-base64.js'\nimport { graphemeLenNative, graphemeLenPonyfill } from './utf8-grapheme-len.js'\nimport { utf8LenCompute, utf8LenNode } from './utf8-len.js'\nimport { utf8ToBase64Node, utf8ToBase64Ponyfill } from './utf8-to-base64.js'\n\nexport const graphemeLen: (str: string) => number =\n /* v8 ignore next -- @preserve */ graphemeLenNative ?? graphemeLenPonyfill\n\n/* v8 ignore next -- @preserve */\nif (graphemeLen === graphemeLenPonyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\nexport const utf8Len: (string: string) => number =\n /* v8 ignore next -- @preserve */ utf8LenNode ?? utf8LenCompute\n\nexport const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string =\n /* v8 ignore next -- @preserve */ utf8ToBase64Node ?? utf8ToBase64Ponyfill\n\nexport const utf8FromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ utf8FromBase64Node ?? utf8FromBase64Ponyfill\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-data",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "license": "MIT",
5
5
  "description": "Core utilities for AT Lexicons",
6
6
  "keywords": [
@@ -38,8 +38,7 @@
38
38
  "multiformats": "^9.9.0",
39
39
  "tslib": "^2.8.1",
40
40
  "uint8arrays": "3.0.0",
41
- "unicode-segmenter": "^0.14.0",
42
- "@atproto/syntax": "0.4.2"
41
+ "unicode-segmenter": "^0.14.0"
43
42
  },
44
43
  "devDependencies": {
45
44
  "core-js": "^3",
@@ -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
+ })
package/src/cid.test.ts CHANGED
@@ -1,23 +1,51 @@
1
+ /* eslint-disable import/no-deprecated */
2
+
1
3
  import { CID } from 'multiformats/cid'
2
4
  import { sha256, sha512 } from 'multiformats/hashes/sha2'
3
5
  import { describe, expect, it } from 'vitest'
6
+ import { BytesCid, createCustomCid } from './cid-implementation.test.js'
4
7
  import {
8
+ Cid,
5
9
  DAG_CBOR_MULTICODEC,
6
10
  RAW_MULTICODEC,
11
+ SHA256_MULTIHASH,
12
+ asMultiformatsCID,
13
+ cidForRawHash,
7
14
  decodeCid,
8
15
  ensureValidCidString,
9
16
  isCid,
17
+ isCidForBytes,
10
18
  parseCid,
11
- parseCidString,
19
+ parseCidSafe,
12
20
  } from './cid.js'
21
+ import { ui8Equals } from './uint8array.js'
22
+
23
+ const invalidCidStr = 'invalidcidstring'
24
+
25
+ const cborCidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
26
+ const cborCid = parseCid(cborCidStr, { flavor: 'cbor' })
27
+
28
+ const rawCidStr = 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4'
29
+ const rawCid = parseCid(rawCidStr, { flavor: 'raw' })
30
+
31
+ const rawCidLike: Cid = createCustomCid(
32
+ 1,
33
+ RAW_MULTICODEC,
34
+ SHA256_MULTIHASH,
35
+ rawCid.multihash.digest,
36
+ )
37
+ const rawBytesCid = new BytesCid(rawCid.bytes)
13
38
 
14
39
  describe(isCid, () => {
15
40
  describe('non-strict mode', () => {
16
41
  it('returns true for parsed CIDs', () => {
17
- const cid = parseCid(
18
- 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
19
- )
20
- expect(isCid(cid)).toBe(true)
42
+ expect(isCid(cborCid)).toBe(true)
43
+ expect(isCid(rawCid)).toBe(true)
44
+ })
45
+
46
+ it('returns true for custom compatible CID implementations', () => {
47
+ expect(isCid(rawCidLike)).toBe(true)
48
+ expect(isCid(rawBytesCid)).toBe(true)
21
49
  })
22
50
 
23
51
  it('returns true for CID v0 and v1', async () => {
@@ -88,56 +116,237 @@ describe(isCid, () => {
88
116
  })
89
117
  })
90
118
  })
119
+
120
+ describe('alternative cid implementations', () => {
121
+ it('accepts compatible CID implementations', () => {
122
+ expect(isCid(rawCidLike)).toBe(true)
123
+ })
124
+
125
+ it('rejects non-matching version', () => {
126
+ expect(isCid({ ...rawCidLike, version: 0 })).toBe(false)
127
+ })
128
+
129
+ it('rejects non-matching code', () => {
130
+ expect(isCid({ ...rawCidLike, code: -1 })).toBe(false)
131
+ expect(isCid({ ...rawCidLike, code: 0 })).toBe(false)
132
+ expect(isCid({ ...rawCidLike, code: 256 })).toBe(false)
133
+ })
134
+
135
+ it('rejects invalid bytes property', () => {
136
+ expect(isCid({ ...rawCidLike, bytes: undefined })).toBe(false)
137
+ expect(isCid({ ...rawCidLike, bytes: 12 })).toBe(false)
138
+ expect(isCid({ ...rawCidLike, bytes: {} })).toBe(false)
139
+ expect(isCid({ ...rawCidLike, bytes: [] })).toBe(false)
140
+
141
+ expect(
142
+ isCid({
143
+ ...rawCidLike,
144
+ bytes: rawCidLike.bytes.subarray(0, rawCidLike.bytes.length - 1),
145
+ }),
146
+ ).toBe(false)
147
+
148
+ const bytes = new Uint8Array(rawCidLike.bytes.length)
149
+
150
+ bytes.set(rawCidLike.bytes)
151
+ expect(isCid({ ...rawCidLike, bytes })).toBe(true)
152
+
153
+ bytes[0] = bytes[0] ^ 0xff
154
+ expect(isCid({ ...rawCidLike, bytes })).toBe(false)
155
+ bytes.set(rawCidLike.bytes)
156
+
157
+ bytes[3] = bytes[3] ^ 0xff
158
+ expect(isCid({ ...rawCidLike, bytes })).toBe(false)
159
+ bytes.set(rawCidLike.bytes)
160
+
161
+ bytes[6] = bytes[6] ^ 0xff
162
+ expect(isCid({ ...rawCidLike, bytes })).toBe(false)
163
+ bytes.set(rawCidLike.bytes)
164
+ })
165
+
166
+ describe('multihash property', () => {
167
+ it('rejects non-matching object', () => {
168
+ expect(isCid({ ...rawCidLike, multihash: undefined })).toBe(false)
169
+ expect(isCid({ ...rawCidLike, multihash: 12 })).toBe(false)
170
+ expect(isCid({ ...rawCidLike, multihash: {} })).toBe(false)
171
+ expect(isCid({ ...rawCidLike, multihash: [] })).toBe(false)
172
+ })
173
+
174
+ it('rejects non-matching code', () => {
175
+ expect(
176
+ isCid({
177
+ ...rawCidLike,
178
+ multihash: { ...rawCidLike.multihash, code: -1 },
179
+ }),
180
+ ).toBe(false)
181
+ expect(
182
+ isCid({
183
+ ...rawCidLike,
184
+ multihash: { ...rawCidLike.multihash, code: 0 },
185
+ }),
186
+ ).toBe(false)
187
+ expect(
188
+ isCid({
189
+ ...rawCidLike,
190
+ multihash: { ...rawCidLike.multihash, code: 256 },
191
+ }),
192
+ ).toBe(false)
193
+ })
194
+
195
+ it('rejects non Uint8Array digest', () => {
196
+ expect(
197
+ isCid({
198
+ ...rawCidLike,
199
+ multihash: { ...rawCidLike.multihash, digest: new Array(32) },
200
+ }),
201
+ ).toBe(false)
202
+ })
203
+
204
+ it('rejects non Uint8Array digest', () => {
205
+ expect(
206
+ isCid({
207
+ ...rawCidLike,
208
+ multihash: { ...rawCidLike.multihash, digest: new Array(32) },
209
+ }),
210
+ ).toBe(false)
211
+ })
212
+
213
+ it('rejects non-matching digest', () => {
214
+ const differentDigest = new Uint8Array(32)
215
+ differentDigest[0] = 1
216
+ expect(
217
+ isCid({
218
+ ...rawCidLike,
219
+ multihash: { ...rawCidLike.multihash, digest: differentDigest },
220
+ }),
221
+ ).toBe(false)
222
+ })
223
+ })
224
+
225
+ describe('equals() method', () => {
226
+ it('rejects objects without equals method', () => {
227
+ expect(isCid({ ...rawCidLike, equals: undefined })).toBe(false)
228
+ expect(isCid({ ...rawCidLike, equals: () => false })).toBe(false)
229
+ })
230
+
231
+ it('rejects object with throwing equals method', () => {
232
+ expect(
233
+ isCid({
234
+ ...rawCidLike,
235
+ equals: () => {
236
+ throw new Error('fail')
237
+ },
238
+ }),
239
+ ).toBe(false)
240
+ })
241
+ })
242
+ })
91
243
  })
92
244
 
93
245
  describe(decodeCid, () => {
94
246
  it('decodes CID from bytes', () => {
95
- const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
96
- const cid = parseCid(cidStr)
247
+ const cid = parseCid(cborCidStr)
97
248
  const bytes = cid.bytes
98
249
  const decodedCid = decodeCid(bytes)
99
- expect(decodedCid.toString()).toBe(cidStr)
250
+ expect(decodedCid.toString()).toBe(cborCidStr)
100
251
  })
101
252
  })
102
253
 
103
254
  describe(parseCid, () => {
104
255
  it('parses valid CIDs', () => {
105
- const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
106
- const cid = parseCid(cidStr)
107
- expect(cid.toString()).toBe(cidStr)
256
+ expect(parseCid(cborCidStr).toString()).toBe(cborCidStr)
257
+ expect(parseCid(rawCidStr).toString()).toBe(rawCidStr)
108
258
  })
109
259
 
110
260
  it('throws for invalid CIDs', () => {
111
- const invalidCidStr = 'invalidcidstring'
112
261
  expect(() => parseCid(invalidCidStr)).toThrow()
113
262
  })
114
263
  })
115
264
 
116
- describe(parseCidString, () => {
265
+ describe(isCidForBytes, () => {
266
+ describe('raw', () => {
267
+ it('returns true for valid raw CID bytes', async () => {
268
+ for (const hasher of [sha256, sha512]) {
269
+ const data = new TextEncoder().encode('hello world')
270
+ const digest = await hasher.digest(data)
271
+ const cid = CID.createV1(RAW_MULTICODEC, digest)
272
+ expect(await isCidForBytes(cid, data)).toBe(true)
273
+
274
+ data[0] = data[0] ^ 0xff
275
+ expect(await isCidForBytes(cid, data)).toBe(false)
276
+ }
277
+ })
278
+ })
279
+
280
+ describe('cbor', () => {
281
+ it('returns true for valid cbor CID bytes', async () => {
282
+ for (const hasher of [sha256, sha512]) {
283
+ // @NOTE this is not valid CBOR, but sufficient for testing the hash
284
+ const data = new TextEncoder().encode('hello world')
285
+ const digest = await hasher.digest(data)
286
+ const cid = CID.createV1(DAG_CBOR_MULTICODEC, digest)
287
+ expect(await isCidForBytes(cid, data)).toBe(true)
288
+
289
+ data[0] = data[0] ^ 0xff
290
+ expect(await isCidForBytes(cid, data)).toBe(false)
291
+ }
292
+ })
293
+ })
294
+ })
295
+
296
+ describe(parseCidSafe, () => {
117
297
  it('parses valid CIDs', () => {
118
- const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
119
- const cid = parseCidString(cidStr)
120
- expect(cid).toBeDefined()
121
- expect(cid!.toString()).toBe(cidStr)
298
+ expect(parseCidSafe(cborCidStr)?.toString()).toBe(cborCidStr)
299
+ expect(parseCidSafe(rawCidStr)?.toString()).toBe(rawCidStr)
122
300
  })
123
301
 
124
302
  it('returns undefined for invalid CIDs', () => {
125
- const invalidCidStr = 'invalidcidstring'
126
- const cid = parseCidString(invalidCidStr)
127
- expect(cid).toBeUndefined()
303
+ expect(parseCidSafe(invalidCidStr)).toBeNull()
128
304
  })
129
305
  })
130
306
 
131
307
  describe(ensureValidCidString, () => {
132
308
  it('does not throw for valid CIDs', () => {
133
- const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
134
- expect(() => ensureValidCidString(cidStr)).not.toThrow()
309
+ expect(() => ensureValidCidString(cborCidStr)).not.toThrow()
135
310
  })
136
311
 
137
312
  it('throws for invalid CIDs', () => {
138
- const invalidCidStr = 'invalidcidstring'
139
313
  expect(() => ensureValidCidString(invalidCidStr)).toThrow(
140
314
  'Invalid CID string',
141
315
  )
142
316
  })
143
317
  })
318
+
319
+ describe(cidForRawHash, () => {
320
+ it('creates a RawCid from a SHA-256 hash', () => {
321
+ const hash = new Uint8Array(32)
322
+ const cid = cidForRawHash(hash)
323
+ expect(cid.code).toBe(RAW_MULTICODEC)
324
+ expect(cid.multihash.code).toBe(SHA256_MULTIHASH)
325
+ expect(ui8Equals(cid.multihash.digest, hash)).toBe(true)
326
+ })
327
+
328
+ it('rejects hashes on invalid lengths', () => {
329
+ expect(() => cidForRawHash(new Uint8Array(31))).toThrow(
330
+ 'Invalid SHA-256 hash length',
331
+ )
332
+ expect(() => cidForRawHash(new Uint8Array(33))).toThrow(
333
+ 'Invalid SHA-256 hash length',
334
+ )
335
+ })
336
+ })
337
+
338
+ describe(asMultiformatsCID, () => {
339
+ it('converts compatible CID to multiformats CID', () => {
340
+ for (const cid of [cborCid, rawCid, rawCidLike, rawBytesCid]) {
341
+ expect(asMultiformatsCID(cid)).toBeInstanceOf(CID)
342
+ expect(asMultiformatsCID(cid)).toMatchObject({
343
+ version: cid.version,
344
+ code: cid.code,
345
+ multihash: {
346
+ code: cid.multihash.code,
347
+ digest: cid.multihash.digest,
348
+ },
349
+ })
350
+ }
351
+ })
352
+ })