@atproto/lex-data 0.0.8 → 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.
- package/CHANGELOG.md +10 -0
- package/LICENSE.txt +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/uint8array.d.ts +1 -0
- package/dist/uint8array.d.ts.map +1 -1
- package/dist/uint8array.js +12 -6
- package/dist/uint8array.js.map +1 -1
- package/dist/utf8.d.ts.map +1 -1
- package/dist/utf8.js +4 -8
- package/dist/utf8.js.map +1 -1
- package/package.json +2 -3
- package/src/cid.test.ts +139 -32
- package/src/index.ts +0 -1
- package/src/uint8array.test.ts +24 -5
- package/src/uint8array.ts +13 -6
- package/src/utf8-len.test.ts +19 -28
- package/src/utf8.ts +4 -8
- package/dist/language.d.ts +0 -18
- package/dist/language.d.ts.map +0 -1
- package/dist/language.js +0 -30
- package/dist/language.js.map +0 -1
- package/src/language.test.ts +0 -88
- package/src/language.ts +0 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @atproto/lex-data
|
|
2
2
|
|
|
3
|
+
## 0.0.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4562](https://github.com/bluesky-social/atproto/pull/4562) [`7310b97`](https://github.com/bluesky-social/atproto/commit/7310b9704de678a3b389a741784d58bb7f79b10b) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `ifUint8Array` utility function
|
|
8
|
+
|
|
9
|
+
- [#4571](https://github.com/bluesky-social/atproto/pull/4571) [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Rename `isLanguageString` to `validateLanguage`
|
|
10
|
+
|
|
11
|
+
- [#4571](https://github.com/bluesky-social/atproto/pull/4571) [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Improve code coverage of tests
|
|
12
|
+
|
|
3
13
|
## 0.0.8
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Dual MIT/Apache-2.0 License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2022-
|
|
3
|
+
Copyright (c) 2022-2026 Bluesky Social PBC, and Contributors
|
|
4
4
|
|
|
5
5
|
Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
|
|
6
6
|
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./blob.js"), exports);
|
|
5
5
|
tslib_1.__exportStar(require("./cid.js"), exports);
|
|
6
|
-
tslib_1.__exportStar(require("./language.js"), exports);
|
|
7
6
|
tslib_1.__exportStar(require("./lex-equals.js"), exports);
|
|
8
7
|
tslib_1.__exportStar(require("./lex-error.js"), exports);
|
|
9
8
|
tslib_1.__exportStar(require("./lex.js"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,oDAAyB;AACzB,mDAAwB;AACxB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,oDAAyB;AACzB,mDAAwB;AACxB,0DAA+B;AAC/B,yDAA8B;AAC9B,mDAAwB;AACxB,sDAA2B;AAC3B,0DAA+B;AAC/B,oDAAyB","sourcesContent":["export * from './blob.js'\nexport * from './cid.js'\nexport * from './lex-equals.js'\nexport * from './lex-error.js'\nexport * from './lex.js'\nexport * from './object.js'\nexport * from './uint8array.js'\nexport * from './utf8.js'\n"]}
|
package/dist/uint8array.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const toBase64: (bytes: Uint8Array, alphabet?: Base64Alphabet) =>
|
|
|
14
14
|
* @throws If the input is not a valid base64 string
|
|
15
15
|
*/
|
|
16
16
|
export declare const fromBase64: (b64: string, alphabet?: Base64Alphabet) => Uint8Array;
|
|
17
|
+
export declare function ifUint8Array(input: unknown): Uint8Array | undefined;
|
|
17
18
|
/**
|
|
18
19
|
* Coerces various binary data representations into a Uint8Array.
|
|
19
20
|
*
|
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;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,CACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,KACtB,
|
|
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,MAGa,CAAA;AAElB;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,UAGe,CAAA;AAUpB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAMnE;AAED;;;;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,8CACgD,CAAA"}
|
package/dist/uint8array.js
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
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":";;;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"]}
|
package/dist/utf8.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
|
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.
|
|
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",
|
package/src/cid.test.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
decodeCid,
|
|
15
15
|
ensureValidCidString,
|
|
16
16
|
isCid,
|
|
17
|
+
isCidForBytes,
|
|
17
18
|
parseCid,
|
|
18
19
|
parseCidSafe,
|
|
19
20
|
} from './cid.js'
|
|
@@ -27,13 +28,13 @@ const cborCid = parseCid(cborCidStr, { flavor: 'cbor' })
|
|
|
27
28
|
const rawCidStr = 'bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4'
|
|
28
29
|
const rawCid = parseCid(rawCidStr, { flavor: 'raw' })
|
|
29
30
|
|
|
30
|
-
const
|
|
31
|
+
const rawCidLike: Cid = createCustomCid(
|
|
31
32
|
1,
|
|
32
33
|
RAW_MULTICODEC,
|
|
33
34
|
SHA256_MULTIHASH,
|
|
34
35
|
rawCid.multihash.digest,
|
|
35
36
|
)
|
|
36
|
-
const
|
|
37
|
+
const rawBytesCid = new BytesCid(rawCid.bytes)
|
|
37
38
|
|
|
38
39
|
describe(isCid, () => {
|
|
39
40
|
describe('non-strict mode', () => {
|
|
@@ -43,8 +44,8 @@ describe(isCid, () => {
|
|
|
43
44
|
})
|
|
44
45
|
|
|
45
46
|
it('returns true for custom compatible CID implementations', () => {
|
|
46
|
-
expect(isCid(
|
|
47
|
-
expect(isCid(
|
|
47
|
+
expect(isCid(rawCidLike)).toBe(true)
|
|
48
|
+
expect(isCid(rawBytesCid)).toBe(true)
|
|
48
49
|
})
|
|
49
50
|
|
|
50
51
|
it('returns true for CID v0 and v1', async () => {
|
|
@@ -118,50 +119,125 @@ describe(isCid, () => {
|
|
|
118
119
|
|
|
119
120
|
describe('alternative cid implementations', () => {
|
|
120
121
|
it('accepts compatible CID implementations', () => {
|
|
121
|
-
expect(isCid(
|
|
122
|
+
expect(isCid(rawCidLike)).toBe(true)
|
|
122
123
|
})
|
|
123
124
|
|
|
124
125
|
it('rejects non-matching version', () => {
|
|
125
|
-
expect(isCid({ ...
|
|
126
|
+
expect(isCid({ ...rawCidLike, version: 0 })).toBe(false)
|
|
126
127
|
})
|
|
127
128
|
|
|
128
129
|
it('rejects non-matching code', () => {
|
|
129
|
-
expect(isCid({ ...
|
|
130
|
+
expect(isCid({ ...rawCidLike, code: -1 })).toBe(false)
|
|
131
|
+
expect(isCid({ ...rawCidLike, code: 0 })).toBe(false)
|
|
132
|
+
expect(isCid({ ...rawCidLike, code: 256 })).toBe(false)
|
|
130
133
|
})
|
|
131
134
|
|
|
132
|
-
it('rejects
|
|
133
|
-
expect(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}),
|
|
138
|
-
).toBe(false)
|
|
139
|
-
})
|
|
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
140
|
|
|
141
|
-
it('rejects non-matching multihash digest', () => {
|
|
142
|
-
const differentDigest = new Uint8Array(32)
|
|
143
|
-
differentDigest[0] = 1
|
|
144
141
|
expect(
|
|
145
142
|
isCid({
|
|
146
|
-
...
|
|
147
|
-
|
|
143
|
+
...rawCidLike,
|
|
144
|
+
bytes: rawCidLike.bytes.subarray(0, rawCidLike.bytes.length - 1),
|
|
148
145
|
}),
|
|
149
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)
|
|
150
164
|
})
|
|
151
165
|
|
|
152
|
-
|
|
153
|
-
|
|
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
|
+
})
|
|
154
223
|
})
|
|
155
224
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
isCid({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
+
})
|
|
165
241
|
})
|
|
166
242
|
})
|
|
167
243
|
})
|
|
@@ -186,6 +262,37 @@ describe(parseCid, () => {
|
|
|
186
262
|
})
|
|
187
263
|
})
|
|
188
264
|
|
|
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
|
+
|
|
189
296
|
describe(parseCidSafe, () => {
|
|
190
297
|
it('parses valid CIDs', () => {
|
|
191
298
|
expect(parseCidSafe(cborCidStr)?.toString()).toBe(cborCidStr)
|
|
@@ -230,7 +337,7 @@ describe(cidForRawHash, () => {
|
|
|
230
337
|
|
|
231
338
|
describe(asMultiformatsCID, () => {
|
|
232
339
|
it('converts compatible CID to multiformats CID', () => {
|
|
233
|
-
for (const cid of [cborCid, rawCid,
|
|
340
|
+
for (const cid of [cborCid, rawCid, rawCidLike, rawBytesCid]) {
|
|
234
341
|
expect(asMultiformatsCID(cid)).toBeInstanceOf(CID)
|
|
235
342
|
expect(asMultiformatsCID(cid)).toMatchObject({
|
|
236
343
|
version: cid.version,
|
package/src/index.ts
CHANGED
package/src/uint8array.test.ts
CHANGED
|
@@ -5,12 +5,13 @@ import { describe, expect, it } from 'vitest'
|
|
|
5
5
|
import {
|
|
6
6
|
asUint8Array,
|
|
7
7
|
fromBase64,
|
|
8
|
+
ifUint8Array,
|
|
8
9
|
toBase64,
|
|
9
10
|
ui8Concat,
|
|
10
11
|
ui8Equals,
|
|
11
12
|
} from './uint8array.js'
|
|
12
13
|
|
|
13
|
-
describe(
|
|
14
|
+
describe(toBase64, () => {
|
|
14
15
|
it('encodes empty Uint8Array', () => {
|
|
15
16
|
const encoded = toBase64(new Uint8Array(0))
|
|
16
17
|
expect(typeof encoded).toBe('string')
|
|
@@ -49,7 +50,7 @@ describe('toBase64', () => {
|
|
|
49
50
|
})
|
|
50
51
|
})
|
|
51
52
|
|
|
52
|
-
describe(
|
|
53
|
+
describe(fromBase64, () => {
|
|
53
54
|
it('decodes empty string', () => {
|
|
54
55
|
const decoded = fromBase64('')
|
|
55
56
|
expect(decoded).toBeInstanceOf(Uint8Array)
|
|
@@ -133,7 +134,7 @@ describe('roundtrip toBase64 <-> fromBase64', () => {
|
|
|
133
134
|
})
|
|
134
135
|
})
|
|
135
136
|
|
|
136
|
-
describe(
|
|
137
|
+
describe(asUint8Array, () => {
|
|
137
138
|
describe('Uint8Array input', () => {
|
|
138
139
|
it('returns same Uint8Array instance', () => {
|
|
139
140
|
const input = new Uint8Array([1, 2, 3])
|
|
@@ -294,7 +295,7 @@ describe('asUint8Array', () => {
|
|
|
294
295
|
})
|
|
295
296
|
})
|
|
296
297
|
|
|
297
|
-
describe(
|
|
298
|
+
describe(ui8Equals, () => {
|
|
298
299
|
describe('equal arrays', () => {
|
|
299
300
|
it('returns true for identical arrays', () => {
|
|
300
301
|
const a = new Uint8Array([1, 2, 3])
|
|
@@ -434,7 +435,25 @@ describe('ui8Equals', () => {
|
|
|
434
435
|
})
|
|
435
436
|
})
|
|
436
437
|
|
|
437
|
-
describe(
|
|
438
|
+
describe(ifUint8Array, () => {
|
|
439
|
+
it('returns the input if it is a Uint8Array', () => {
|
|
440
|
+
const input = new Uint8Array([1, 2, 3])
|
|
441
|
+
const result = ifUint8Array(input)
|
|
442
|
+
expect(result).toBe(input)
|
|
443
|
+
})
|
|
444
|
+
|
|
445
|
+
it('returns undefined for non-Uint8Array inputs', () => {
|
|
446
|
+
expect(ifUint8Array(null)).toBeUndefined()
|
|
447
|
+
expect(ifUint8Array(undefined)).toBeUndefined()
|
|
448
|
+
expect(ifUint8Array({})).toBeUndefined()
|
|
449
|
+
expect(ifUint8Array([])).toBeUndefined()
|
|
450
|
+
expect(ifUint8Array('string')).toBeUndefined()
|
|
451
|
+
expect(ifUint8Array(123)).toBeUndefined()
|
|
452
|
+
expect(ifUint8Array(true)).toBeUndefined()
|
|
453
|
+
})
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
describe(ui8Concat, () => {
|
|
438
457
|
it('concatenates empty array', () => {
|
|
439
458
|
const result = ui8Concat([])
|
|
440
459
|
expect(result).toBeInstanceOf(Uint8Array)
|
package/src/uint8array.ts
CHANGED
|
@@ -28,8 +28,8 @@ export const toBase64: (
|
|
|
28
28
|
alphabet?: Base64Alphabet,
|
|
29
29
|
) => string =
|
|
30
30
|
/* v8 ignore next -- @preserve */ toBase64Native ??
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
toBase64Node ??
|
|
32
|
+
toBase64Ponyfill
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Decodes a base64 string into a Uint8Array. This function supports both padded
|
|
@@ -43,8 +43,8 @@ export const fromBase64: (
|
|
|
43
43
|
alphabet?: Base64Alphabet,
|
|
44
44
|
) => Uint8Array =
|
|
45
45
|
/* v8 ignore next -- @preserve */ fromBase64Native ??
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
fromBase64Node ??
|
|
47
|
+
fromBase64Ponyfill
|
|
48
48
|
|
|
49
49
|
/* v8 ignore next -- @preserve */
|
|
50
50
|
if (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {
|
|
@@ -54,6 +54,14 @@ if (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {
|
|
|
54
54
|
)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
export function ifUint8Array(input: unknown): Uint8Array | undefined {
|
|
58
|
+
if (input instanceof Uint8Array) {
|
|
59
|
+
return input
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
/**
|
|
58
66
|
* Coerces various binary data representations into a Uint8Array.
|
|
59
67
|
*
|
|
@@ -94,5 +102,4 @@ export function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {
|
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
export const ui8Concat =
|
|
97
|
-
/* v8 ignore next -- @preserve */ ui8ConcatNode ??
|
|
98
|
-
/* v8 ignore next -- @preserve */ ui8ConcatPonyfill
|
|
105
|
+
/* v8 ignore next -- @preserve */ ui8ConcatNode ?? ui8ConcatPonyfill
|
package/src/utf8-len.test.ts
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
import { utf8LenCompute, utf8LenNode } from './utf8-len.js'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
for (const utf8Len of [utf8LenNode!, utf8LenCompute!] as const) {
|
|
5
|
+
describe(utf8Len, () => {
|
|
6
|
+
it('computes utf8 string length', () => {
|
|
7
|
+
expect(utf8Len('a')).toBe(1)
|
|
8
|
+
expect(utf8Len('~')).toBe(1)
|
|
9
|
+
expect(utf8Len('ö')).toBe(2)
|
|
10
|
+
expect(utf8Len('ñ')).toBe(2)
|
|
11
|
+
expect(utf8Len('©')).toBe(2)
|
|
12
|
+
expect(utf8Len('⽘')).toBe(3)
|
|
13
|
+
expect(utf8Len('☎')).toBe(3)
|
|
14
|
+
expect(utf8Len('𓋓')).toBe(4)
|
|
15
|
+
expect(utf8Len('😀')).toBe(4)
|
|
16
|
+
expect(utf8Len('👨👩👧👧')).toBe(25)
|
|
17
|
+
// high surrogate with no low surrogate
|
|
18
|
+
expect(utf8Len('\uD83D')).toBe(3)
|
|
19
|
+
// low surrogate with no high surrogate
|
|
20
|
+
expect(utf8Len('\uDC00')).toBe(3)
|
|
21
|
+
})
|
|
16
22
|
})
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe(utf8LenCompute, () => {
|
|
20
|
-
it('computes utf8 string length', () => {
|
|
21
|
-
expect(utf8LenCompute('a')).toBe(1)
|
|
22
|
-
expect(utf8LenCompute('~')).toBe(1)
|
|
23
|
-
expect(utf8LenCompute('ö')).toBe(2)
|
|
24
|
-
expect(utf8LenCompute('ñ')).toBe(2)
|
|
25
|
-
expect(utf8LenCompute('©')).toBe(2)
|
|
26
|
-
expect(utf8LenCompute('⽘')).toBe(3)
|
|
27
|
-
expect(utf8LenCompute('☎')).toBe(3)
|
|
28
|
-
expect(utf8LenCompute('𓋓')).toBe(4)
|
|
29
|
-
expect(utf8LenCompute('😀')).toBe(4)
|
|
30
|
-
expect(utf8LenCompute('👨👩👧👧')).toBe(25)
|
|
31
|
-
})
|
|
32
|
-
})
|
|
23
|
+
}
|
package/src/utf8.ts
CHANGED
|
@@ -8,8 +8,7 @@ import { utf8LenCompute, utf8LenNode } from './utf8-len.js'
|
|
|
8
8
|
import { utf8ToBase64Node, utf8ToBase64Ponyfill } from './utf8-to-base64.js'
|
|
9
9
|
|
|
10
10
|
export const graphemeLen: (str: string) => number =
|
|
11
|
-
/* v8 ignore next -- @preserve */ graphemeLenNative ??
|
|
12
|
-
/* v8 ignore next -- @preserve */ graphemeLenPonyfill
|
|
11
|
+
/* v8 ignore next -- @preserve */ graphemeLenNative ?? graphemeLenPonyfill
|
|
13
12
|
|
|
14
13
|
/* v8 ignore next -- @preserve */
|
|
15
14
|
if (graphemeLen === graphemeLenPonyfill) {
|
|
@@ -20,16 +19,13 @@ if (graphemeLen === graphemeLenPonyfill) {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
export const utf8Len: (string: string) => number =
|
|
23
|
-
/* v8 ignore next -- @preserve */ utf8LenNode ??
|
|
24
|
-
/* v8 ignore next -- @preserve */ utf8LenCompute
|
|
22
|
+
/* v8 ignore next -- @preserve */ utf8LenNode ?? utf8LenCompute
|
|
25
23
|
|
|
26
24
|
export const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string =
|
|
27
|
-
/* v8 ignore next -- @preserve */ utf8ToBase64Node ??
|
|
28
|
-
/* v8 ignore next -- @preserve */ utf8ToBase64Ponyfill
|
|
25
|
+
/* v8 ignore next -- @preserve */ utf8ToBase64Node ?? utf8ToBase64Ponyfill
|
|
29
26
|
|
|
30
27
|
export const utf8FromBase64: (
|
|
31
28
|
b64: string,
|
|
32
29
|
alphabet?: Base64Alphabet,
|
|
33
30
|
) => string =
|
|
34
|
-
/* v8 ignore next -- @preserve */ utf8FromBase64Node ??
|
|
35
|
-
/* v8 ignore next -- @preserve */ utf8FromBase64Ponyfill
|
|
31
|
+
/* v8 ignore next -- @preserve */ utf8FromBase64Node ?? utf8FromBase64Ponyfill
|
package/dist/language.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type LanguageTag = {
|
|
2
|
-
grandfathered?: string;
|
|
3
|
-
language?: string;
|
|
4
|
-
extlang?: string;
|
|
5
|
-
script?: string;
|
|
6
|
-
region?: string;
|
|
7
|
-
variant?: string;
|
|
8
|
-
extension?: string;
|
|
9
|
-
privateUse?: string;
|
|
10
|
-
};
|
|
11
|
-
export declare function parseLanguageString(input: string): LanguageTag | null;
|
|
12
|
-
/**
|
|
13
|
-
* Validates well-formed BCP 47 syntax
|
|
14
|
-
*
|
|
15
|
-
* @see {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1}
|
|
16
|
-
*/
|
|
17
|
-
export declare function isLanguageString(input: string): boolean;
|
|
18
|
-
//# sourceMappingURL=language.d.ts.map
|
package/dist/language.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../src/language.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAerE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
package/dist/language.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseLanguageString = parseLanguageString;
|
|
4
|
-
exports.isLanguageString = isLanguageString;
|
|
5
|
-
const BCP47_REGEXP = /^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?<extension>[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?<privateUseA>x(-[A-Za-z0-9]{1,8})+))?)|(?<privateUseB>x(-[A-Za-z0-9]{1,8})+))$/;
|
|
6
|
-
function parseLanguageString(input) {
|
|
7
|
-
const parsed = input.match(BCP47_REGEXP);
|
|
8
|
-
if (!parsed?.groups)
|
|
9
|
-
return null;
|
|
10
|
-
const { groups } = parsed;
|
|
11
|
-
return {
|
|
12
|
-
grandfathered: groups.grandfathered,
|
|
13
|
-
language: groups.language,
|
|
14
|
-
extlang: groups.extlang,
|
|
15
|
-
script: groups.script,
|
|
16
|
-
region: groups.region,
|
|
17
|
-
variant: groups.variant,
|
|
18
|
-
extension: groups.extension,
|
|
19
|
-
privateUse: groups.privateUseA || groups.privateUseB,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Validates well-formed BCP 47 syntax
|
|
24
|
-
*
|
|
25
|
-
* @see {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1}
|
|
26
|
-
*/
|
|
27
|
-
function isLanguageString(input) {
|
|
28
|
-
return BCP47_REGEXP.test(input);
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=language.js.map
|
package/dist/language.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"language.js","sourceRoot":"","sources":["../src/language.ts"],"names":[],"mappings":";;AAcA,kDAeC;AAOD,4CAEC;AAtCD,MAAM,YAAY,GAChB,mlBAAmlB,CAAA;AAarlB,SAAgB,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACxC,IAAI,CAAC,MAAM,EAAE,MAAM;QAAE,OAAO,IAAI,CAAA;IAEhC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACzB,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW;KACrD,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC","sourcesContent":["const BCP47_REGEXP =\n /^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?<extension>[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?<privateUseA>x(-[A-Za-z0-9]{1,8})+))?)|(?<privateUseB>x(-[A-Za-z0-9]{1,8})+))$/\n\nexport type LanguageTag = {\n grandfathered?: string\n language?: string\n extlang?: string\n script?: string\n region?: string\n variant?: string\n extension?: string\n privateUse?: string\n}\n\nexport function parseLanguageString(input: string): LanguageTag | null {\n const parsed = input.match(BCP47_REGEXP)\n if (!parsed?.groups) return null\n\n const { groups } = parsed\n return {\n grandfathered: groups.grandfathered,\n language: groups.language,\n extlang: groups.extlang,\n script: groups.script,\n region: groups.region,\n variant: groups.variant,\n extension: groups.extension,\n privateUse: groups.privateUseA || groups.privateUseB,\n }\n}\n\n/**\n * Validates well-formed BCP 47 syntax\n *\n * @see {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1}\n */\nexport function isLanguageString(input: string): boolean {\n return BCP47_REGEXP.test(input)\n}\n"]}
|
package/src/language.test.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { isLanguageString, parseLanguageString } from './language'
|
|
3
|
-
|
|
4
|
-
describe('string', () => {
|
|
5
|
-
describe('languages', () => {
|
|
6
|
-
it('validates BCP 47', () => {
|
|
7
|
-
// valid
|
|
8
|
-
expect(isLanguageString('de')).toEqual(true)
|
|
9
|
-
expect(isLanguageString('de-CH')).toEqual(true)
|
|
10
|
-
expect(isLanguageString('de-DE-1901')).toEqual(true)
|
|
11
|
-
expect(isLanguageString('es-419')).toEqual(true)
|
|
12
|
-
expect(isLanguageString('sl-IT-nedis')).toEqual(true)
|
|
13
|
-
expect(isLanguageString('mn-Cyrl-MN')).toEqual(true)
|
|
14
|
-
expect(isLanguageString('x-fr-CH')).toEqual(true)
|
|
15
|
-
expect(
|
|
16
|
-
isLanguageString('en-GB-boont-r-extended-sequence-x-private'),
|
|
17
|
-
).toEqual(true)
|
|
18
|
-
expect(isLanguageString('sr-Cyrl')).toEqual(true)
|
|
19
|
-
expect(isLanguageString('hy-Latn-IT-arevela')).toEqual(true)
|
|
20
|
-
expect(isLanguageString('i-klingon')).toEqual(true)
|
|
21
|
-
// invalid
|
|
22
|
-
expect(isLanguageString('')).toEqual(false)
|
|
23
|
-
expect(isLanguageString('x')).toEqual(false)
|
|
24
|
-
expect(isLanguageString('de-CH-')).toEqual(false)
|
|
25
|
-
expect(isLanguageString('i-bad-grandfathered')).toEqual(false)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('parses BCP 47', () => {
|
|
29
|
-
// valid
|
|
30
|
-
expect(parseLanguageString('de')).toEqual({
|
|
31
|
-
language: 'de',
|
|
32
|
-
})
|
|
33
|
-
expect(parseLanguageString('de-CH')).toEqual({
|
|
34
|
-
language: 'de',
|
|
35
|
-
region: 'CH',
|
|
36
|
-
})
|
|
37
|
-
expect(parseLanguageString('de-DE-1901')).toEqual({
|
|
38
|
-
language: 'de',
|
|
39
|
-
region: 'DE',
|
|
40
|
-
variant: '1901',
|
|
41
|
-
})
|
|
42
|
-
expect(parseLanguageString('es-419')).toEqual({
|
|
43
|
-
language: 'es',
|
|
44
|
-
region: '419',
|
|
45
|
-
})
|
|
46
|
-
expect(parseLanguageString('sl-IT-nedis')).toEqual({
|
|
47
|
-
language: 'sl',
|
|
48
|
-
region: 'IT',
|
|
49
|
-
variant: 'nedis',
|
|
50
|
-
})
|
|
51
|
-
expect(parseLanguageString('mn-Cyrl-MN')).toEqual({
|
|
52
|
-
language: 'mn',
|
|
53
|
-
script: 'Cyrl',
|
|
54
|
-
region: 'MN',
|
|
55
|
-
})
|
|
56
|
-
expect(parseLanguageString('x-fr-CH')).toEqual({
|
|
57
|
-
privateUse: 'x-fr-CH',
|
|
58
|
-
})
|
|
59
|
-
expect(
|
|
60
|
-
parseLanguageString('en-GB-boont-r-extended-sequence-x-private'),
|
|
61
|
-
).toEqual({
|
|
62
|
-
language: 'en',
|
|
63
|
-
region: 'GB',
|
|
64
|
-
variant: 'boont',
|
|
65
|
-
extension: 'r-extended-sequence',
|
|
66
|
-
privateUse: 'x-private',
|
|
67
|
-
})
|
|
68
|
-
expect(parseLanguageString('sr-Cyrl')).toEqual({
|
|
69
|
-
language: 'sr',
|
|
70
|
-
script: 'Cyrl',
|
|
71
|
-
})
|
|
72
|
-
expect(parseLanguageString('hy-Latn-IT-arevela')).toEqual({
|
|
73
|
-
language: 'hy',
|
|
74
|
-
script: 'Latn',
|
|
75
|
-
region: 'IT',
|
|
76
|
-
variant: 'arevela',
|
|
77
|
-
})
|
|
78
|
-
expect(parseLanguageString('i-klingon')).toEqual({
|
|
79
|
-
grandfathered: 'i-klingon',
|
|
80
|
-
})
|
|
81
|
-
// invalid
|
|
82
|
-
expect(parseLanguageString('')).toEqual(null)
|
|
83
|
-
expect(parseLanguageString('x')).toEqual(null)
|
|
84
|
-
expect(parseLanguageString('de-CH-')).toEqual(null)
|
|
85
|
-
expect(parseLanguageString('i-bad-grandfathered')).toEqual(null)
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
})
|
package/src/language.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const BCP47_REGEXP =
|
|
2
|
-
/^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?<extension>[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?<privateUseA>x(-[A-Za-z0-9]{1,8})+))?)|(?<privateUseB>x(-[A-Za-z0-9]{1,8})+))$/
|
|
3
|
-
|
|
4
|
-
export type LanguageTag = {
|
|
5
|
-
grandfathered?: string
|
|
6
|
-
language?: string
|
|
7
|
-
extlang?: string
|
|
8
|
-
script?: string
|
|
9
|
-
region?: string
|
|
10
|
-
variant?: string
|
|
11
|
-
extension?: string
|
|
12
|
-
privateUse?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function parseLanguageString(input: string): LanguageTag | null {
|
|
16
|
-
const parsed = input.match(BCP47_REGEXP)
|
|
17
|
-
if (!parsed?.groups) return null
|
|
18
|
-
|
|
19
|
-
const { groups } = parsed
|
|
20
|
-
return {
|
|
21
|
-
grandfathered: groups.grandfathered,
|
|
22
|
-
language: groups.language,
|
|
23
|
-
extlang: groups.extlang,
|
|
24
|
-
script: groups.script,
|
|
25
|
-
region: groups.region,
|
|
26
|
-
variant: groups.variant,
|
|
27
|
-
extension: groups.extension,
|
|
28
|
-
privateUse: groups.privateUseA || groups.privateUseB,
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Validates well-formed BCP 47 syntax
|
|
34
|
-
*
|
|
35
|
-
* @see {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1}
|
|
36
|
-
*/
|
|
37
|
-
export function isLanguageString(input: string): boolean {
|
|
38
|
-
return BCP47_REGEXP.test(input)
|
|
39
|
-
}
|