@atproto/lex-data 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/blob.d.ts +6 -0
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js +2 -2
- package/dist/blob.js.map +1 -1
- package/dist/cid.d.ts +2 -3
- package/dist/cid.d.ts.map +1 -1
- package/dist/cid.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/language.d.ts +2 -2
- package/dist/language.d.ts.map +1 -1
- package/dist/language.js +4 -4
- package/dist/language.js.map +1 -1
- package/dist/lex-error.d.ts +17 -0
- package/dist/lex-error.d.ts.map +1 -0
- package/dist/lex-error.js +26 -0
- package/dist/lex-error.js.map +1 -0
- package/dist/lex.d.ts.map +1 -1
- package/dist/lex.js +49 -48
- package/dist/lex.js.map +1 -1
- package/dist/lib/nodejs-buffer.d.ts +1 -0
- package/dist/lib/nodejs-buffer.d.ts.map +1 -1
- package/dist/lib/nodejs-buffer.js +1 -1
- package/dist/lib/nodejs-buffer.js.map +1 -1
- package/dist/object.d.ts +13 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +15 -2
- package/dist/object.js.map +1 -1
- package/dist/uint8array-concat.d.ts +3 -0
- package/dist/uint8array-concat.d.ts.map +1 -0
- package/dist/uint8array-concat.js +24 -0
- package/dist/uint8array-concat.js.map +1 -0
- package/dist/uint8array-from-base64.d.ts.map +1 -1
- package/dist/uint8array-from-base64.js +1 -1
- package/dist/uint8array-from-base64.js.map +1 -1
- package/dist/uint8array.d.ts +1 -0
- package/dist/uint8array.d.ts.map +1 -1
- package/dist/uint8array.js +14 -3
- package/dist/uint8array.js.map +1 -1
- package/dist/utf8-grapheme-len.d.ts.map +1 -1
- package/dist/utf8-grapheme-len.js +2 -2
- package/dist/utf8-grapheme-len.js.map +1 -1
- package/dist/utf8-len.d.ts.map +1 -1
- package/dist/utf8-len.js +1 -1
- package/dist/utf8-len.js.map +1 -1
- package/package.json +5 -5
- package/src/blob.test.ts +83 -2
- package/src/blob.ts +8 -2
- package/src/cid.test.ts +126 -0
- package/src/cid.ts +7 -7
- package/src/index.ts +1 -0
- package/src/language.test.ts +34 -33
- package/src/language.ts +2 -2
- package/src/lex-equals.test.ts +30 -0
- package/src/lex-error.ts +34 -0
- package/src/lex.test.ts +156 -1
- package/src/lex.ts +50 -43
- package/src/lib/nodejs-buffer.ts +2 -1
- package/src/object.test.ts +2 -0
- package/src/object.ts +16 -4
- package/src/uint8array-concat.test.ts +197 -0
- package/src/uint8array-concat.ts +21 -0
- package/src/uint8array-from-base64.test.ts +4 -1
- package/src/uint8array-from-base64.ts +1 -1
- package/src/uint8array-to-base64.test.ts +1 -1
- package/src/uint8array.test.ts +484 -0
- package/src/uint8array.ts +14 -2
- package/src/utf8-grapheme-len.test.ts +1 -0
- package/src/utf8-grapheme-len.ts +2 -2
- package/src/utf8-len.test.ts +1 -0
- package/src/utf8-len.ts +1 -1
- package/tsconfig.tests.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uint8array-concat.js","sourceRoot":"","sources":["../src/uint8array-concat.ts"],"names":[],"mappings":";;;AAUA,8CAUC;AApBD,6DAAqD;AAErD,MAAM,MAAM,GAAG,+BAAY,CAAA;AAEd,QAAA,aAAa,GAAG,MAAM;IACjC,CAAC,CAAC,SAAS,aAAa,CAAC,KAA4B;QACjD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;IACH,CAAC,CAAC,iCAAiC,CAAC,IAAI,CAAA;AAE1C,SAAgB,iBAAiB,CAAC,KAA4B;IAC5D,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,KAAK,MAAM,GAAG,IAAI,KAAK;QAAE,WAAW,IAAI,GAAG,CAAC,MAAM,CAAA;IAClD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAA;IAC1C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACvB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAA;IACtB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import { NodeJSBuffer } from './lib/nodejs-buffer.js'\n\nconst Buffer = NodeJSBuffer\n\nexport const ui8ConcatNode = Buffer\n ? function ui8ConcatNode(array: readonly Uint8Array[]): Uint8Array {\n return Buffer.concat(array)\n }\n : /* v8 ignore next -- @preserve */ null\n\nexport function ui8ConcatPonyfill(array: readonly Uint8Array[]): Uint8Array {\n let totalLength = 0\n for (const arr of array) totalLength += arr.length\n const result = new Uint8Array(totalLength)\n let offset = 0\n for (const arr of array) {\n result.set(arr, offset)\n offset += arr.length\n }\n return result\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,
|
|
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"}
|
|
@@ -22,7 +22,7 @@ exports.fromBase64Node = Buffer
|
|
|
22
22
|
// results in unexpected behavior downstream (e.g. in tests)
|
|
23
23
|
return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
24
24
|
}
|
|
25
|
-
: null;
|
|
25
|
+
: /* v8 ignore next -- @preserve */ null;
|
|
26
26
|
function fromBase64Ponyfill(b64, alphabet = 'base64') {
|
|
27
27
|
const bytes = (0, from_string_1.fromString)(b64, b64.endsWith('=') ? `${alphabet}pad` : alphabet);
|
|
28
28
|
verifyBase64ForBytes(b64, bytes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uint8array-from-base64.js","sourceRoot":"","sources":["../src/uint8array-from-base64.ts"],"names":[],"mappings":";;;AAiDA,gDAOC;AAxDD,yDAAoD;AACpD,6DAAqD;AAGrD,MAAM,MAAM,GAAG,+BAAY,CAAA;AAkBd,QAAA,gBAAgB,GAC3B,OAAO,UAAU,CAAC,UAAU,KAAK,UAAU;IACzC,CAAC,CAAC,SAAS,gBAAgB,CACvB,GAAW,EACX,WAA2B,QAAQ;QAEnC,OAAO,UAAU,CAAC,UAAW,CAAC,GAAG,EAAE;YACjC,QAAQ;YACR,iBAAiB,EAAE,OAAO;SAC3B,CAAC,CAAA;IACJ,CAAC;IACH,CAAC,CAAC,IAAI,CAAA;AAEG,QAAA,cAAc,GAAG,MAAM;IAClC,CAAC,CAAC,SAAS,cAAc,CACrB,GAAW,EACX,WAA2B,QAAQ;QAEnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QACxC,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,qEAAqE;QACrE,yEAAyE;QACzE,4DAA4D;QAC5D,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IACzE,CAAC;IACH,CAAC,CAAC,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"uint8array-from-base64.js","sourceRoot":"","sources":["../src/uint8array-from-base64.ts"],"names":[],"mappings":";;;AAiDA,gDAOC;AAxDD,yDAAoD;AACpD,6DAAqD;AAGrD,MAAM,MAAM,GAAG,+BAAY,CAAA;AAkBd,QAAA,gBAAgB,GAC3B,OAAO,UAAU,CAAC,UAAU,KAAK,UAAU;IACzC,CAAC,CAAC,SAAS,gBAAgB,CACvB,GAAW,EACX,WAA2B,QAAQ;QAEnC,OAAO,UAAU,CAAC,UAAW,CAAC,GAAG,EAAE;YACjC,QAAQ;YACR,iBAAiB,EAAE,OAAO;SAC3B,CAAC,CAAA;IACJ,CAAC;IACH,CAAC,CAAC,IAAI,CAAA;AAEG,QAAA,cAAc,GAAG,MAAM;IAClC,CAAC,CAAC,SAAS,cAAc,CACrB,GAAW,EACX,WAA2B,QAAQ;QAEnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QACxC,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,qEAAqE;QACrE,yEAAyE;QACzE,4DAA4D;QAC5D,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IACzE,CAAC;IACH,CAAC,CAAC,iCAAiC,CAAC,IAAI,CAAA;AAE1C,SAAgB,kBAAkB,CAChC,GAAW,EACX,WAA2B,QAAQ;IAEnC,MAAM,KAAK,GAAG,IAAA,wBAAU,EAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IAC9E,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAChC,OAAO,KAAK,CAAA;AACd,CAAC;AAED,2EAA2E;AAC3E,wEAAwE;AACxE,+EAA+E;AAC/E,0EAA0E;AAC1E,0CAA0C;AAC1C,SAAS,oBAAoB,CAAC,GAAW,EAAE,KAAiB;IAC1D,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvE,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,GAAG,YAAY,CAAA;IAC/C,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9D,IAAI,KAAK,CAAC,MAAM,KAAK,kBAAkB,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;IAChD,MAAM,oBAAoB,GACxB,iBAAiB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAA;IAC/D,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,oBAAoB,CAAA;IACtE,IAAI,GAAG,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,qEAAqE;IACrE,qBAAqB;IACrB,KACE,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,EACpC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,YAAY,EAC7B,CAAC,EAAE,EACH,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAC9B,IACE,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM;YACrC,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM;YACtC,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,IAAI,MAAM;YACrC,IAAI,KAAK,EAAE,IAAI,IAAI;YACnB,IAAI,KAAK,EAAE,CAAC,IAAI;UAChB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { fromString } from 'uint8arrays/from-string'\nimport { NodeJSBuffer } from './lib/nodejs-buffer.js'\nimport { Base64Alphabet } from './uint8array-base64.js'\n\nconst Buffer = NodeJSBuffer\n\ndeclare global {\n interface Uint8ArrayConstructor {\n /**\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64 Uint8Array.fromBase64()}\n */\n fromBase64?: (\n b64: string,\n options?: {\n /** @default 'base64' */\n alphabet?: 'base64' | 'base64url'\n lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial'\n },\n ) => Uint8Array\n }\n}\n\nexport const fromBase64Native =\n typeof Uint8Array.fromBase64 === 'function'\n ? function fromBase64Native(\n b64: string,\n alphabet: Base64Alphabet = 'base64',\n ): Uint8Array {\n return Uint8Array.fromBase64!(b64, {\n alphabet,\n lastChunkHandling: 'loose',\n })\n }\n : null\n\nexport const fromBase64Node = Buffer\n ? function fromBase64Node(\n b64: string,\n alphabet: Base64Alphabet = 'base64',\n ): Uint8Array {\n const bytes = Buffer.from(b64, alphabet)\n verifyBase64ForBytes(b64, bytes)\n // Convert to Uint8Array because even though Buffer is a sub class of\n // Uint8Array, it serializes differently to Uint8Array (e.g. in JSON) and\n // results in unexpected behavior downstream (e.g. in tests)\n return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n }\n : /* v8 ignore next -- @preserve */ null\n\nexport function fromBase64Ponyfill(\n b64: string,\n alphabet: Base64Alphabet = 'base64',\n): Uint8Array {\n const bytes = fromString(b64, b64.endsWith('=') ? `${alphabet}pad` : alphabet)\n verifyBase64ForBytes(b64, bytes)\n return bytes\n}\n\n// @NOTE NodeJS will silently stop decoding at the first invalid character,\n// while \"uint8arrays/from-string\" will not validate that the padding is\n// correct. The following function performs basic validation to ensure that the\n// input was a valid base64 string. The availability of the \"bytes\" allows\n// to perform checks with O[1] complexity.\nfunction verifyBase64ForBytes(b64: string, bytes: Uint8Array): void {\n const paddingCount = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0\n const trimmedLength = b64.length - paddingCount\n const expectedByteLength = Math.floor((trimmedLength * 3) / 4)\n if (bytes.length !== expectedByteLength) {\n throw new Error('Invalid base64 string')\n }\n\n const expectedB64Length = (bytes.length / 3) * 4\n const expectedPaddingCount =\n expectedB64Length % 4 === 0 ? 0 : 4 - (expectedB64Length % 4)\n const expectedFullB64Length = expectedB64Length + expectedPaddingCount\n if (b64.length > expectedFullB64Length) {\n throw new Error('Invalid base64 string')\n }\n\n // The previous might still allow false positive if only the last few\n // chars are invalid.\n for (\n let i = Math.ceil(expectedB64Length);\n i < b64.length - paddingCount;\n i++\n ) {\n const code = b64.charCodeAt(i)\n if (\n !(code >= 65 && code <= 90) && // A-Z\n !(code >= 97 && code <= 122) && // a-z\n !(code >= 48 && code <= 57) && // 0-9\n code !== 43 && // +\n code !== 47 // /\n ) {\n throw new Error('Invalid base64 string')\n }\n }\n}\n"]}
|
package/dist/uint8array.d.ts
CHANGED
|
@@ -21,4 +21,5 @@ export declare const fromBase64: (b64: string, alphabet?: Base64Alphabet) => Uin
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function asUint8Array(input: unknown): Uint8Array | undefined;
|
|
23
23
|
export declare function ui8Equals(a: Uint8Array, b: Uint8Array): boolean;
|
|
24
|
+
export declare const ui8Concat: (array: readonly Uint8Array[]) => Uint8Array;
|
|
24
25
|
//# sourceMappingURL=uint8array.d.ts.map
|
package/dist/uint8array.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,CACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,KACtB,MAG+C,CAAA;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,UAGiD,CAAA;AAUtD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAkBnE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAY/D;AAED,eAAO,MAAM,SAAS,8CAE+B,CAAA"}
|
package/dist/uint8array.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fromBase64 = exports.toBase64 = void 0;
|
|
3
|
+
exports.ui8Concat = exports.fromBase64 = exports.toBase64 = void 0;
|
|
4
4
|
exports.asUint8Array = asUint8Array;
|
|
5
5
|
exports.ui8Equals = ui8Equals;
|
|
6
|
+
const uint8array_concat_js_1 = require("./uint8array-concat.js");
|
|
6
7
|
const uint8array_from_base64_js_1 = require("./uint8array-from-base64.js");
|
|
7
8
|
const uint8array_to_base64_js_1 = require("./uint8array-to-base64.js");
|
|
8
9
|
// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /
|
|
@@ -14,7 +15,10 @@ const uint8array_to_base64_js_1 = require("./uint8array-to-base64.js");
|
|
|
14
15
|
*
|
|
15
16
|
* @returns The base64 encoded string
|
|
16
17
|
*/
|
|
17
|
-
exports.toBase64 =
|
|
18
|
+
exports.toBase64 =
|
|
19
|
+
/* 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;
|
|
18
22
|
/**
|
|
19
23
|
* Decodes a base64 string into a Uint8Array. This function supports both padded
|
|
20
24
|
* and unpadded base64 strings.
|
|
@@ -22,7 +26,11 @@ exports.toBase64 = uint8array_to_base64_js_1.toBase64Native ?? uint8array_to_bas
|
|
|
22
26
|
* @returns The decoded {@link Uint8Array}
|
|
23
27
|
* @throws If the input is not a valid base64 string
|
|
24
28
|
*/
|
|
25
|
-
exports.fromBase64 =
|
|
29
|
+
exports.fromBase64 =
|
|
30
|
+
/* 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;
|
|
33
|
+
/* v8 ignore next -- @preserve */
|
|
26
34
|
if (exports.toBase64 === uint8array_to_base64_js_1.toBase64Ponyfill || exports.fromBase64 === uint8array_from_base64_js_1.fromBase64Ponyfill) {
|
|
27
35
|
/*#__PURE__*/
|
|
28
36
|
console.warn('[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.');
|
|
@@ -55,4 +63,7 @@ function ui8Equals(a, b) {
|
|
|
55
63
|
}
|
|
56
64
|
return true;
|
|
57
65
|
}
|
|
66
|
+
exports.ui8Concat =
|
|
67
|
+
/* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatNode ??
|
|
68
|
+
/* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatPonyfill;
|
|
58
69
|
//# sourceMappingURL=uint8array.js.map
|
package/dist/uint8array.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uint8array.js","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":";;;
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utf8-grapheme-len.d.ts","sourceRoot":"","sources":["../src/utf8-grapheme-len.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB,SACM,MAAM,KAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"utf8-grapheme-len.d.ts","sourceRoot":"","sources":["../src/utf8-grapheme-len.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB,SACM,MAAM,KAAG,MAAM,QAKT,CAAA;AAE1C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
|
@@ -8,7 +8,7 @@ const grapheme_1 = require("unicode-segmenter/grapheme");
|
|
|
8
8
|
// https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter
|
|
9
9
|
const segmenter = 'Segmenter' in Intl && typeof Intl.Segmenter === 'function'
|
|
10
10
|
? /*#__PURE__*/ new Intl.Segmenter()
|
|
11
|
-
: null;
|
|
11
|
+
: /* v8 ignore next -- @preserve */ null;
|
|
12
12
|
exports.graphemeLenNative = segmenter
|
|
13
13
|
? function graphemeLenNative(str) {
|
|
14
14
|
let length = 0;
|
|
@@ -16,7 +16,7 @@ exports.graphemeLenNative = segmenter
|
|
|
16
16
|
length++;
|
|
17
17
|
return length;
|
|
18
18
|
}
|
|
19
|
-
: null;
|
|
19
|
+
: /* v8 ignore next -- @preserve */ null;
|
|
20
20
|
function graphemeLenPonyfill(str) {
|
|
21
21
|
return (0, grapheme_1.countGraphemes)(str);
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utf8-grapheme-len.js","sourceRoot":"","sources":["../src/utf8-grapheme-len.ts"],"names":[],"mappings":";;;AAkBA,kDAEC;AApBD,yDAA2D;AAE3D,0EAA0E;AAC1E,oBAAoB;AACpB,+FAA+F;AAC/F,MAAM,SAAS,GACb,WAAW,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU;IACzD,CAAC,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;IACpC,CAAC,CAAC,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"utf8-grapheme-len.js","sourceRoot":"","sources":["../src/utf8-grapheme-len.ts"],"names":[],"mappings":";;;AAkBA,kDAEC;AApBD,yDAA2D;AAE3D,0EAA0E;AAC1E,oBAAoB;AACpB,+FAA+F;AAC/F,MAAM,SAAS,GACb,WAAW,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU;IACzD,CAAC,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;IACpC,CAAC,CAAC,iCAAiC,CAAC,IAAI,CAAA;AAE/B,QAAA,iBAAiB,GAAG,SAAS;IACxC,CAAC,CAAC,SAAS,iBAAiB,CAAC,GAAW;QACpC,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,MAAM,EAAE,CAAA;QAChD,OAAO,MAAM,CAAA;IACf,CAAC;IACH,CAAC,CAAC,iCAAiC,CAAC,IAAI,CAAA;AAE1C,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,OAAO,IAAA,yBAAc,EAAC,GAAG,CAAC,CAAA;AAC5B,CAAC","sourcesContent":["import { countGraphemes } from 'unicode-segmenter/grapheme'\n\n// @TODO: Drop usage of \"unicode-segmenter\" package when Intl.Segmenter is\n// widely supported.\n// https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter\nconst segmenter =\n 'Segmenter' in Intl && typeof Intl.Segmenter === 'function'\n ? /*#__PURE__*/ new Intl.Segmenter()\n : /* v8 ignore next -- @preserve */ null\n\nexport const graphemeLenNative = segmenter\n ? function graphemeLenNative(str: string): number {\n let length = 0\n for (const _ of segmenter.segment(str)) length++\n return length\n }\n : /* v8 ignore next -- @preserve */ null\n\nexport function graphemeLenPonyfill(str: string): number {\n return countGraphemes(str)\n}\n"]}
|
package/dist/utf8-len.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utf8-len.d.ts","sourceRoot":"","sources":["../src/utf8-len.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,YACS,MAAM,KAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"utf8-len.d.ts","sourceRoot":"","sources":["../src/utf8-len.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,YACS,MAAM,KAAG,MAAM,QAGN,CAAA;AAE1C,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAsCrD"}
|
package/dist/utf8-len.js
CHANGED
|
@@ -10,7 +10,7 @@ exports.utf8LenNode = nodejs_buffer_js_1.NodeJSBuffer
|
|
|
10
10
|
? function utf8LenNode(string) {
|
|
11
11
|
return nodejs_buffer_js_1.NodeJSBuffer.byteLength(string, 'utf8');
|
|
12
12
|
}
|
|
13
|
-
: null;
|
|
13
|
+
: /* v8 ignore next -- @preserve */ null;
|
|
14
14
|
function utf8LenCompute(string) {
|
|
15
15
|
// The code below is similar to TextEncoder's implementation of UTF-8
|
|
16
16
|
// encoding. However, using TextEncoder to get the byte length is slower
|
package/dist/utf8-len.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utf8-len.js","sourceRoot":"","sources":["../src/utf8-len.ts"],"names":[],"mappings":";;;AAYA,wCAsCC;AAlDD,6DAAqD;AAErD,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAEjE,QAAA,WAAW,GAAG,+BAAY;IACrC,CAAC,CAAC,SAAS,WAAW,CAAC,MAAc;QACjC,OAAO,+BAAa,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjD,CAAC;IACH,CAAC,CAAC,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"utf8-len.js","sourceRoot":"","sources":["../src/utf8-len.ts"],"names":[],"mappings":";;;AAYA,wCAsCC;AAlDD,6DAAqD;AAErD,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAEjE,QAAA,WAAW,GAAG,+BAAY;IACrC,CAAC,CAAC,SAAS,WAAW,CAAC,MAAc;QACjC,OAAO,+BAAa,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjD,CAAC;IACH,CAAC,CAAC,iCAAiC,CAAC,IAAI,CAAA;AAE1C,SAAgB,cAAc,CAAC,MAAc;IAC3C,qEAAqE;IACrE,wEAAwE;IACxE,+DAA+D;IAE/D,qDAAqD;IAErD,mDAAmD;IACnD,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,CAAA;IACvB,IAAI,IAAY,CAAA;IAEhB,gEAAgE;IAChE,uBAAuB;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAE3B,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,gBAAgB;QAClB,CAAC;aAAM,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,eAAe;YACf,GAAG,IAAI,CAAC,CAAA;QACV,CAAC;aAAM,CAAC;YACN,eAAe;YACf,GAAG,IAAI,CAAC,CAAA;YACR,sEAAsE;YACtE,+DAA+D;YAC/D,wEAAwE;YACxE,OAAO;YACP,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACrC,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;gBAC/B,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACrC,CAAC,EAAE,CAAA;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["import { NodeJSBuffer } from './lib/nodejs-buffer.js'\n\n// @NOTE This file is not meant to be exported directly. Instead, we re-export\n// public functions from ./utf8.ts. The reason for this separation is that this\n// file allows to test both the NodeJS-optimized and ponyfill implementations.\n\nexport const utf8LenNode = NodeJSBuffer\n ? function utf8LenNode(string: string): number {\n return NodeJSBuffer!.byteLength(string, 'utf8')\n }\n : /* v8 ignore next -- @preserve */ null\n\nexport function utf8LenCompute(string: string): number {\n // The code below is similar to TextEncoder's implementation of UTF-8\n // encoding. However, using TextEncoder to get the byte length is slower\n // as it requires allocating a new Uint8Array and copying data:\n\n // return new TextEncoder().encode(string).byteLength\n\n // The base length is the string length (all ASCII)\n let len = string.length\n let code: number\n\n // The loop calculates the number of additional bytes needed for\n // non-ASCII characters\n for (let i = 0; i < string.length; i += 1) {\n code = string.charCodeAt(i)\n\n if (code <= 0x7f) {\n // ASCII, 1 byte\n } else if (code <= 0x7ff) {\n // 2 bytes char\n len += 1\n } else {\n // 3 bytes char\n len += 2\n // If the current char is a high surrogate, and the next char is a low\n // surrogate, skip the next char as the total is a 4 bytes char\n // (represented as a surrogate pair in UTF-16) and was already accounted\n // for.\n if (code >= 0xd800 && code <= 0xdbff) {\n code = string.charCodeAt(i + 1)\n if (code >= 0xdc00 && code <= 0xdfff) {\n i++\n }\n }\n }\n }\n\n return len\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/lex-data",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Core utilities for AT Lexicons",
|
|
6
6
|
"keywords": [
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"types": "./dist/index.d.ts",
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
31
32
|
"browser": "./dist/index.js",
|
|
32
33
|
"import": "./dist/index.js",
|
|
33
|
-
"require": "./dist/index.js"
|
|
34
|
-
"types": "./dist/index.d.ts"
|
|
34
|
+
"require": "./dist/index.js"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"core-js": "^3",
|
|
46
|
-
"
|
|
46
|
+
"vitest": "^4.0.16"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsc --build tsconfig.build.json",
|
|
50
|
-
"test": "
|
|
50
|
+
"test": "vitest run"
|
|
51
51
|
}
|
|
52
52
|
}
|
package/src/blob.test.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
1
2
|
import { isBlobRef, isLegacyBlobRef } from './blob.js'
|
|
2
3
|
import { parseCid } from './cid.js'
|
|
3
4
|
|
|
@@ -10,7 +11,7 @@ const lexCid = parseCid(
|
|
|
10
11
|
'bafyreic52vzks7wdklat4evp3vimohl55i2unzqpshz2ytka5omzr7exdy',
|
|
11
12
|
)
|
|
12
13
|
|
|
13
|
-
describe(
|
|
14
|
+
describe(isBlobRef, () => {
|
|
14
15
|
it('tests valid blobCid and lexCid', () => {
|
|
15
16
|
expect(blobCid.code).toBe(0x55) // raw
|
|
16
17
|
expect(blobCid.multihash.code).toBe(0x12) // sha2-256
|
|
@@ -51,6 +52,25 @@ describe('isBlobRef', () => {
|
|
|
51
52
|
size: '10000',
|
|
52
53
|
}),
|
|
53
54
|
).toBe(false)
|
|
55
|
+
|
|
56
|
+
expect(
|
|
57
|
+
isBlobRef({
|
|
58
|
+
// $type: 'blob',
|
|
59
|
+
ref: blobCid,
|
|
60
|
+
mimeType: 'image/jpeg',
|
|
61
|
+
size: 10000,
|
|
62
|
+
}),
|
|
63
|
+
).toBe(false)
|
|
64
|
+
|
|
65
|
+
expect(
|
|
66
|
+
isBlobRef({
|
|
67
|
+
$type: 'blob',
|
|
68
|
+
ref: blobCid,
|
|
69
|
+
mimeType: { toString: () => 'image/jpeg' },
|
|
70
|
+
size: 10000,
|
|
71
|
+
}),
|
|
72
|
+
).toBe(false)
|
|
73
|
+
|
|
54
74
|
expect(
|
|
55
75
|
isBlobRef(
|
|
56
76
|
{
|
|
@@ -81,6 +101,22 @@ describe('isBlobRef', () => {
|
|
|
81
101
|
{ strict: true },
|
|
82
102
|
),
|
|
83
103
|
).toBe(false)
|
|
104
|
+
|
|
105
|
+
expect(isBlobRef('not an object')).toBe(false)
|
|
106
|
+
expect(isBlobRef([])).toBe(false)
|
|
107
|
+
expect(isBlobRef(new Date())).toBe(false)
|
|
108
|
+
expect(isBlobRef(new Map())).toBe(false)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('rejects non-integer size', () => {
|
|
112
|
+
expect(
|
|
113
|
+
isBlobRef({
|
|
114
|
+
$type: 'blob',
|
|
115
|
+
ref: blobCid,
|
|
116
|
+
mimeType: 'image/jpeg',
|
|
117
|
+
size: 10000.5,
|
|
118
|
+
}),
|
|
119
|
+
).toBe(false)
|
|
84
120
|
})
|
|
85
121
|
|
|
86
122
|
it('rejects invalid CID/multihash code', () => {
|
|
@@ -133,9 +169,28 @@ describe('isBlobRef', () => {
|
|
|
133
169
|
),
|
|
134
170
|
).toBe(false)
|
|
135
171
|
})
|
|
172
|
+
|
|
173
|
+
describe('strict mode', () => {
|
|
174
|
+
it('rejects invalid CID version', () => {
|
|
175
|
+
const cidV0 = parseCid(
|
|
176
|
+
'QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG', // CID v0
|
|
177
|
+
)
|
|
178
|
+
expect(
|
|
179
|
+
isBlobRef(
|
|
180
|
+
{
|
|
181
|
+
$type: 'blob',
|
|
182
|
+
ref: cidV0,
|
|
183
|
+
mimeType: 'image/jpeg',
|
|
184
|
+
size: 10000,
|
|
185
|
+
},
|
|
186
|
+
{ strict: true },
|
|
187
|
+
),
|
|
188
|
+
).toBe(false)
|
|
189
|
+
})
|
|
190
|
+
})
|
|
136
191
|
})
|
|
137
192
|
|
|
138
|
-
describe(
|
|
193
|
+
describe(isLegacyBlobRef, () => {
|
|
139
194
|
it('parses valid legacy blob', () => {
|
|
140
195
|
expect(
|
|
141
196
|
isLegacyBlobRef({
|
|
@@ -172,6 +227,32 @@ describe('isLegacyBlobRef', () => {
|
|
|
172
227
|
mimeType: 'image/jpeg',
|
|
173
228
|
}),
|
|
174
229
|
).toBe(false)
|
|
230
|
+
|
|
231
|
+
expect(
|
|
232
|
+
isLegacyBlobRef({
|
|
233
|
+
cid: lexCid.toString(),
|
|
234
|
+
mimeType: { toString: () => 'image/jpeg' },
|
|
235
|
+
}),
|
|
236
|
+
).toBe(false)
|
|
237
|
+
|
|
238
|
+
expect(
|
|
239
|
+
isLegacyBlobRef({
|
|
240
|
+
cid: lexCid.toString(),
|
|
241
|
+
mimeType: 3,
|
|
242
|
+
}),
|
|
243
|
+
).toBe(false)
|
|
244
|
+
|
|
245
|
+
expect(
|
|
246
|
+
isLegacyBlobRef({
|
|
247
|
+
cid: lexCid.toString(),
|
|
248
|
+
mimeType: '',
|
|
249
|
+
}),
|
|
250
|
+
).toBe(false)
|
|
251
|
+
|
|
252
|
+
expect(isLegacyBlobRef([])).toBe(false)
|
|
253
|
+
expect(isLegacyBlobRef('not an object')).toBe(false)
|
|
254
|
+
expect(isLegacyBlobRef(new Date())).toBe(false)
|
|
255
|
+
expect(isLegacyBlobRef(new Map())).toBe(false)
|
|
175
256
|
})
|
|
176
257
|
|
|
177
258
|
it('rejects extra keys', () => {
|
package/src/blob.ts
CHANGED
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
} from './cid.js'
|
|
8
8
|
import { isPlainObject } from './object.js'
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @note {@link BlobRef} is just a {@link LexMap} with a specific shape.
|
|
12
|
+
*/
|
|
10
13
|
export type BlobRef = {
|
|
11
14
|
$type: 'blob'
|
|
12
15
|
mimeType: string
|
|
@@ -32,7 +35,7 @@ export function isBlobRef(
|
|
|
32
35
|
return false
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
if (typeof size !== 'number' || size < 0 || !Number.
|
|
38
|
+
if (typeof size !== 'number' || size < 0 || !Number.isSafeInteger(size)) {
|
|
36
39
|
return false
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -71,6 +74,9 @@ export function isBlobRef(
|
|
|
71
74
|
return true
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
/**
|
|
78
|
+
* @note {@link LegacyBlobRef} is just a {@link LexMap} with a specific shape.
|
|
79
|
+
*/
|
|
74
80
|
export type LegacyBlobRef = {
|
|
75
81
|
cid: string
|
|
76
82
|
mimeType: string
|
|
@@ -86,7 +92,7 @@ export function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {
|
|
|
86
92
|
return false
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
if (typeof mimeType !== 'string') {
|
|
95
|
+
if (typeof mimeType !== 'string' || mimeType.length === 0) {
|
|
90
96
|
return false
|
|
91
97
|
}
|
|
92
98
|
|
package/src/cid.test.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid'
|
|
2
|
+
import { sha256, sha512 } from 'multiformats/hashes/sha2'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import {
|
|
5
|
+
RAW_BIN_MULTICODEC,
|
|
6
|
+
createCid,
|
|
7
|
+
decodeCid,
|
|
8
|
+
ensureValidCidString,
|
|
9
|
+
isCid,
|
|
10
|
+
parseCid,
|
|
11
|
+
parseCidString,
|
|
12
|
+
} from './cid.js'
|
|
13
|
+
|
|
14
|
+
describe(isCid, () => {
|
|
15
|
+
describe('non-strict mode', () => {
|
|
16
|
+
it('returns true for parsed CIDs', () => {
|
|
17
|
+
const cid = parseCid(
|
|
18
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
19
|
+
)
|
|
20
|
+
expect(isCid(cid)).toBe(true)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('returns true for CID v0 and v1', async () => {
|
|
24
|
+
const digest = await sha256.digest(Buffer.from('hello world'))
|
|
25
|
+
const cidV0 = CID.createV0(digest)
|
|
26
|
+
const cidV1 = CID.createV1(RAW_BIN_MULTICODEC, digest)
|
|
27
|
+
expect(isCid(cidV0)).toBe(true)
|
|
28
|
+
expect(isCid(cidV1)).toBe(true)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('returns false for invalid CIDs', () => {
|
|
32
|
+
expect(isCid(new Date())).toBe(false)
|
|
33
|
+
expect(isCid({})).toBe(false)
|
|
34
|
+
expect(isCid('not a cid')).toBe(false)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('strict mode', () => {
|
|
39
|
+
it('returns true for valid CIDs in strict mode', async () => {
|
|
40
|
+
const digest = await sha256.digest(Buffer.from('hello world'))
|
|
41
|
+
const cid = CID.createV1(RAW_BIN_MULTICODEC, digest)
|
|
42
|
+
expect(isCid(cid, { strict: true })).toBe(true)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('rejects CID v0 when strict option is set', async () => {
|
|
46
|
+
const digest = await sha256.digest(Buffer.from('hello world'))
|
|
47
|
+
const cid = CID.createV0(digest)
|
|
48
|
+
expect(isCid(cid, { strict: true })).toBe(false)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('rejects CIDs with invalid hash algorithm', async () => {
|
|
52
|
+
const digest = await sha512.digest(Buffer.from('hello world'))
|
|
53
|
+
const cid = CID.createV1(RAW_BIN_MULTICODEC, digest)
|
|
54
|
+
expect(isCid(cid, { strict: true })).toBe(false)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('rejects CIDs with invalid code', async () => {
|
|
58
|
+
const digest = await sha256.digest(Buffer.from('hello world'))
|
|
59
|
+
const cid = CID.createV1(3333, digest)
|
|
60
|
+
expect(isCid(cid, { strict: true })).toBe(false)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe(createCid, () => {
|
|
66
|
+
it('creates a valid CID v1', async () => {
|
|
67
|
+
const digest = await sha256.digest(Buffer.from('hello world'))
|
|
68
|
+
const cid = createCid(RAW_BIN_MULTICODEC, digest)
|
|
69
|
+
expect(cid.version).toBe(1)
|
|
70
|
+
expect(cid.code).toBe(RAW_BIN_MULTICODEC)
|
|
71
|
+
expect(cid.multihash.code).toBe(sha256.code)
|
|
72
|
+
expect(cid.multihash.digest).toEqual(digest.digest)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe(decodeCid, () => {
|
|
77
|
+
it('decodes CID from bytes', () => {
|
|
78
|
+
const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
|
|
79
|
+
const cid = parseCid(cidStr)
|
|
80
|
+
const bytes = cid.bytes
|
|
81
|
+
const decodedCid = decodeCid(bytes)
|
|
82
|
+
expect(decodedCid.toString()).toBe(cidStr)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
describe(parseCid, () => {
|
|
87
|
+
it('parses valid CIDs', () => {
|
|
88
|
+
const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
|
|
89
|
+
const cid = parseCid(cidStr)
|
|
90
|
+
expect(cid.toString()).toBe(cidStr)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('throws for invalid CIDs', () => {
|
|
94
|
+
const invalidCidStr = 'invalidcidstring'
|
|
95
|
+
expect(() => parseCid(invalidCidStr)).toThrow()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe(parseCidString, () => {
|
|
100
|
+
it('parses valid CIDs', () => {
|
|
101
|
+
const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
|
|
102
|
+
const cid = parseCidString(cidStr)
|
|
103
|
+
expect(cid).toBeDefined()
|
|
104
|
+
expect(cid!.toString()).toBe(cidStr)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('returns undefined for invalid CIDs', () => {
|
|
108
|
+
const invalidCidStr = 'invalidcidstring'
|
|
109
|
+
const cid = parseCidString(invalidCidStr)
|
|
110
|
+
expect(cid).toBeUndefined()
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
describe(ensureValidCidString, () => {
|
|
115
|
+
it('does not throw for valid CIDs', () => {
|
|
116
|
+
const cidStr = 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'
|
|
117
|
+
expect(() => ensureValidCidString(cidStr)).not.toThrow()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('throws for invalid CIDs', () => {
|
|
121
|
+
const invalidCidStr = 'invalidcidstring'
|
|
122
|
+
expect(() => ensureValidCidString(invalidCidStr)).toThrow(
|
|
123
|
+
'Invalid CID string',
|
|
124
|
+
)
|
|
125
|
+
})
|
|
126
|
+
})
|
package/src/cid.ts
CHANGED
|
@@ -22,21 +22,20 @@ declare module 'multiformats/cid' {
|
|
|
22
22
|
* `multiformats/cid` in dependent packages, and instead have them rely on the
|
|
23
23
|
* {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from
|
|
24
24
|
* `multiformats` version <10 has compatibility issues with certain TypeScript
|
|
25
|
-
*
|
|
26
|
-
* packages.
|
|
25
|
+
* configuration, which can lead to type errors in dependent packages.
|
|
27
26
|
*
|
|
28
27
|
* We are stuck with version 9 because `@atproto` packages did not drop
|
|
29
28
|
* CommonJS support yet, and multiformats version 10 only supports ES modules.
|
|
30
29
|
*
|
|
31
30
|
* In order to avoid compatibility issues, while preparing for future breaking
|
|
32
31
|
* changes (CID in multiformats v10+ has a slightly different interface), as
|
|
33
|
-
* we update or swap out `multiformats`, we provide our own stable
|
|
32
|
+
* we update or swap out `multiformats`, we provide our own stable {@link Cid}
|
|
34
33
|
* interface.
|
|
35
34
|
*/
|
|
36
35
|
interface CID {}
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
// CID
|
|
38
|
+
// multiformats' CID class is not very portable because:
|
|
40
39
|
//
|
|
41
40
|
// - In dependent packages that use "moduleResolution" set to "node16",
|
|
42
41
|
// "nodenext" or "bundler", TypeScript fails to properly resolve the
|
|
@@ -46,14 +45,15 @@ declare module 'multiformats/cid' {
|
|
|
46
45
|
// uses "exports" field in package.json, which do not contain "types"
|
|
47
46
|
// entrypoints.
|
|
48
47
|
// https://www.npmjs.com/package/multiformats/v/9.9.0?activeTab=code
|
|
49
|
-
// - By defining our own
|
|
50
|
-
// control over the API
|
|
48
|
+
// - By defining our own interface and helper functions, we can have more
|
|
49
|
+
// control over the public API exposed by this package.
|
|
51
50
|
// - It allow us to have a stable interface in case we need to swap out, or
|
|
52
51
|
// eventually update multiformats (should we choose to drop CommonJS support)
|
|
53
52
|
// in the future.
|
|
54
53
|
|
|
55
54
|
// @NOTE Even though it is not portable, we still re-export CID here so that
|
|
56
|
-
// dependent packages where it can be used, have access to it
|
|
55
|
+
// dependent packages where it can be used, have access to it (instead of
|
|
56
|
+
// importing directly from "multiformats" or"multiformats/cid").
|
|
57
57
|
export { CID }
|
|
58
58
|
|
|
59
59
|
/**
|
package/src/index.ts
CHANGED