@atproto/lex-data 0.0.0 → 0.0.2
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 +20 -0
- package/LICENSE.txt +7 -0
- package/dist/blob.d.ts +2 -2
- package/dist/blob.d.ts.map +1 -1
- package/dist/blob.js +4 -3
- package/dist/blob.js.map +1 -1
- package/dist/cid.d.ts +48 -2
- package/dist/cid.d.ts.map +1 -1
- package/dist/cid.js +18 -2
- package/dist/cid.js.map +1 -1
- package/dist/lex-equals.js +1 -1
- package/dist/lex-equals.js.map +1 -1
- package/dist/lex.d.ts +2 -2
- package/dist/lex.js.map +1 -1
- package/package.json +6 -5
- package/src/blob.test.ts +3 -3
- package/src/blob.ts +12 -5
- package/src/cid.ts +82 -4
- package/src/lex-equals.test.ts +8 -8
- package/src/lex-equals.ts +2 -2
- package/src/lex.ts +2 -2
- package/src/object.test.ts +3 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @atproto/lex-data
|
|
2
|
+
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4390](https://github.com/bluesky-social/atproto/pull/4390) [`1d445af`](https://github.com/bluesky-social/atproto/commit/1d445af2a7fc27eca5a45869b29266e6a2a7f3ba) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use `Cid` interface instead of `CID` class to represent parsed CID data.
|
|
8
|
+
|
|
9
|
+
- [#4390](https://github.com/bluesky-social/atproto/pull/4390) [`1d445af`](https://github.com/bluesky-social/atproto/commit/1d445af2a7fc27eca5a45869b29266e6a2a7f3ba) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Replace use of `CID` with `Cid`
|
|
10
|
+
|
|
11
|
+
- [#4397](https://github.com/bluesky-social/atproto/pull/4397) [`688f9d6`](https://github.com/bluesky-social/atproto/commit/688f9d67597ba96d6e9c4a4aec4d394d42f4cbf4) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `CHANGELOG.md` to npm package
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`bcae2b7`](https://github.com/bluesky-social/atproto/commit/bcae2b77b68da6dc2ec202651c8bf41fd5769f69)]:
|
|
14
|
+
- @atproto/syntax@0.4.2
|
|
15
|
+
|
|
16
|
+
## 0.0.1
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- [#4371](https://github.com/bluesky-social/atproto/pull/4371) [`46550d6`](https://github.com/bluesky-social/atproto/commit/46550d6c1ffb298f57d54eb1904067b2df5a40af) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Release
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Dual MIT/Apache-2.0 License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2025 Bluesky Social PBC, and Contributors
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
Downstream projects and end users may chose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.
|
package/dist/blob.d.ts
CHANGED
package/dist/blob.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EAKJ,MAAM,UAAU,CAAA;AAGjB,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,GAAG,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,KAAK,IAAI,OAAO,CAoDlB;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CA2BtE"}
|
package/dist/blob.js
CHANGED
|
@@ -12,7 +12,8 @@ function isBlobRef(input, options) {
|
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
const { mimeType, size, ref } = input;
|
|
15
|
-
|
|
15
|
+
// @NOTE Very basic mime validation
|
|
16
|
+
if (typeof mimeType !== 'string' || !mimeType.includes('/')) {
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
19
|
if (typeof size !== 'number' || size < 0 || !Number.isInteger(size)) {
|
|
@@ -29,7 +30,7 @@ function isBlobRef(input, options) {
|
|
|
29
30
|
return false;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
const cid = cid_js_1.
|
|
33
|
+
const cid = (0, cid_js_1.asCid)(ref);
|
|
33
34
|
if (!cid) {
|
|
34
35
|
return false;
|
|
35
36
|
}
|
|
@@ -63,7 +64,7 @@ function isLegacyBlobRef(input) {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
try {
|
|
66
|
-
cid_js_1.
|
|
67
|
+
(0, cid_js_1.parseCid)(cid);
|
|
67
68
|
}
|
|
68
69
|
catch {
|
|
69
70
|
return false;
|
package/dist/blob.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"blob.js","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":";;AAgBA,8BAuDC;AAOD,0CA2BC;AAzGD,qCAMiB;AACjB,2CAA2C;AAS3C,SAAgB,SAAS,CACvB,KAAc,EACd,OAA8B;IAE9B,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,KAAK,EAAE,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IACrC,mCAAmC;IACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IACE,GAAG,KAAK,OAAO;YACf,GAAG,KAAK,UAAU;YAClB,GAAG,KAAK,KAAK;YACb,GAAG,KAAK,MAAM,EACd,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,cAAK,EAAC,GAAG,CAAC,CAAA;IACtB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,2BAAkB,EAAE,CAAC;YACpC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,gCAAuB,EAAE,CAAC;YACnD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAOD,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACxC,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,IAAA,iBAAQ,EAAC,GAAG,CAAC,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import {\n Cid,\n RAW_BIN_MULTICODEC,\n SHA2_256_MULTIHASH_CODE,\n asCid,\n parseCid,\n} from './cid.js'\nimport { isPlainObject } from './object.js'\n\nexport type BlobRef = {\n $type: 'blob'\n mimeType: string\n ref: Cid\n size: number\n}\n\nexport function isBlobRef(\n input: unknown,\n options?: { strict?: boolean },\n): input is BlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n if (input?.$type !== 'blob') {\n return false\n }\n\n const { mimeType, size, ref } = input\n // @NOTE Very basic mime validation\n if (typeof mimeType !== 'string' || !mimeType.includes('/')) {\n return false\n }\n\n if (typeof size !== 'number' || size < 0 || !Number.isInteger(size)) {\n return false\n }\n\n if (typeof ref !== 'object' || ref === null) {\n return false\n }\n\n for (const key in input) {\n if (\n key !== '$type' &&\n key !== 'mimeType' &&\n key !== 'ref' &&\n key !== 'size'\n ) {\n return false\n }\n }\n\n const cid = asCid(ref)\n if (!cid) {\n return false\n }\n\n if (options?.strict) {\n if (cid.version !== 1) {\n return false\n }\n if (cid.code !== RAW_BIN_MULTICODEC) {\n return false\n }\n if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) {\n return false\n }\n }\n\n return true\n}\n\nexport type LegacyBlobRef = {\n cid: string\n mimeType: string\n}\n\nexport function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {\n if (!isPlainObject(input)) {\n return false\n }\n\n const { cid, mimeType } = input\n if (typeof cid !== 'string') {\n return false\n }\n\n if (typeof mimeType !== 'string') {\n return false\n }\n\n for (const key in input) {\n if (key !== 'cid' && key !== 'mimeType') {\n return false\n }\n }\n\n try {\n parseCid(cid)\n } catch {\n return false\n }\n\n return true\n}\n"]}
|
package/dist/cid.d.ts
CHANGED
|
@@ -2,11 +2,57 @@ import { CID } from 'multiformats/cid';
|
|
|
2
2
|
export declare const DAG_CBOR_MULTICODEC = 113;
|
|
3
3
|
export declare const RAW_BIN_MULTICODEC = 85;
|
|
4
4
|
export declare const SHA2_256_MULTIHASH_CODE = 18;
|
|
5
|
+
export type MultihashDigest<Code extends number = number> = {
|
|
6
|
+
code: Code;
|
|
7
|
+
digest: Uint8Array;
|
|
8
|
+
size: number;
|
|
9
|
+
bytes: Uint8Array;
|
|
10
|
+
};
|
|
11
|
+
declare module 'multiformats/cid' {
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and
|
|
14
|
+
* related helpers ({@link asCid}, {@link parseCid}, {@link decodeCid},
|
|
15
|
+
* {@link createCid}, {@link isCid}), instead.
|
|
16
|
+
*
|
|
17
|
+
* This is marked as deprecated because we want to discourage direct usage of
|
|
18
|
+
* `multiformats/cid` in dependent packages, and instead have them rely on the
|
|
19
|
+
* {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from
|
|
20
|
+
* `multiformats` version <10 has compatibility issues with certain TypeScript
|
|
21
|
+
* module resolution strategies, which can lead to type errors in dependent
|
|
22
|
+
* packages.
|
|
23
|
+
*
|
|
24
|
+
* We are stuck with version 9 because `@atproto` packages did not drop
|
|
25
|
+
* CommonJS support yet, and multiformats version 10 only supports ES modules.
|
|
26
|
+
*
|
|
27
|
+
* In order to avoid compatibility issues, while preparing for future breaking
|
|
28
|
+
* changes (CID in multiformats v10+ has a slightly different interface), as
|
|
29
|
+
* we update or swap out `multiformats`, we provide our own stable `Cid`
|
|
30
|
+
* interface.
|
|
31
|
+
*/
|
|
32
|
+
interface CID {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
5
35
|
export { CID };
|
|
36
|
+
/**
|
|
37
|
+
* Interface for working with decoded CID string, compatible with
|
|
38
|
+
* {@link CID} implementation.
|
|
39
|
+
*/
|
|
40
|
+
export interface Cid {
|
|
41
|
+
version: 0 | 1;
|
|
42
|
+
code: number;
|
|
43
|
+
multihash: MultihashDigest;
|
|
44
|
+
bytes: Uint8Array;
|
|
45
|
+
equals(other: unknown): boolean;
|
|
46
|
+
toString(): string;
|
|
47
|
+
}
|
|
48
|
+
export declare function asCid(value: unknown): Cid | null;
|
|
49
|
+
export declare function parseCid(input: string): Cid;
|
|
50
|
+
export declare function decodeCid(bytes: Uint8Array): Cid;
|
|
51
|
+
export declare function createCid(code: number, digest: MultihashDigest): Cid;
|
|
6
52
|
export declare function isCid(value: unknown, options?: {
|
|
7
53
|
strict?: boolean;
|
|
8
|
-
}): value is
|
|
54
|
+
}): value is Cid;
|
|
9
55
|
export declare function validateCidString(input: string): boolean;
|
|
10
|
-
export declare function parseCidString(input: string):
|
|
56
|
+
export declare function parseCidString(input: string): Cid | undefined;
|
|
11
57
|
export declare function ensureValidCidString(input: string): void;
|
|
12
58
|
//# sourceMappingURL=cid.d.ts.map
|
package/dist/cid.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAEtC,eAAO,MAAM,mBAAmB,MAAO,CAAA;AACvC,eAAO,MAAM,kBAAkB,KAAO,CAAA;AAEtC,eAAO,MAAM,uBAAuB,KAAO,CAAA;AAE3C,OAAO,EAAE,GAAG,EAAE,CAAA;AAEd,wBAAgB,KAAK,CACnB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,KAAK,IAAI,GAAG,CAmBd;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAM7D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxD"}
|
|
1
|
+
{"version":3,"file":"cid.d.ts","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAEtC,eAAO,MAAM,mBAAmB,MAAO,CAAA;AACvC,eAAO,MAAM,kBAAkB,KAAO,CAAA;AAEtC,eAAO,MAAM,uBAAuB,KAAO,CAAA;AAE3C,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1D,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,CAAA;CAClB,CAAA;AAED,OAAO,QAAQ,kBAAkB,CAAC;IAChC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,UAAU,GAAG;KAAG;CACjB;AAoBD,OAAO,EAAE,GAAG,EAAE,CAAA;AAEd;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,eAAe,CAAA;IAC1B,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;IAC/B,QAAQ,IAAI,MAAM,CAAA;CACnB;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,GAAG,IAAI,CAEhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAE3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAEhD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,GAAG,CAEpE;AAED,wBAAgB,KAAK,CACnB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,KAAK,IAAI,GAAG,CAmBd;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAM7D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxD"}
|
package/dist/cid.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CID = exports.SHA2_256_MULTIHASH_CODE = exports.RAW_BIN_MULTICODEC = exports.DAG_CBOR_MULTICODEC = void 0;
|
|
4
|
+
exports.asCid = asCid;
|
|
5
|
+
exports.parseCid = parseCid;
|
|
6
|
+
exports.decodeCid = decodeCid;
|
|
7
|
+
exports.createCid = createCid;
|
|
4
8
|
exports.isCid = isCid;
|
|
5
9
|
exports.validateCidString = validateCidString;
|
|
6
10
|
exports.parseCidString = parseCidString;
|
|
@@ -10,8 +14,20 @@ Object.defineProperty(exports, "CID", { enumerable: true, get: function () { ret
|
|
|
10
14
|
exports.DAG_CBOR_MULTICODEC = 0x71;
|
|
11
15
|
exports.RAW_BIN_MULTICODEC = 0x55;
|
|
12
16
|
exports.SHA2_256_MULTIHASH_CODE = 0x12;
|
|
17
|
+
function asCid(value) {
|
|
18
|
+
return cid_1.CID.asCID(value);
|
|
19
|
+
}
|
|
20
|
+
function parseCid(input) {
|
|
21
|
+
return cid_1.CID.parse(input);
|
|
22
|
+
}
|
|
23
|
+
function decodeCid(bytes) {
|
|
24
|
+
return cid_1.CID.decode(bytes);
|
|
25
|
+
}
|
|
26
|
+
function createCid(code, digest) {
|
|
27
|
+
return cid_1.CID.createV1(code, digest);
|
|
28
|
+
}
|
|
13
29
|
function isCid(value, options) {
|
|
14
|
-
const cid =
|
|
30
|
+
const cid = asCid(value);
|
|
15
31
|
if (!cid) {
|
|
16
32
|
return false;
|
|
17
33
|
}
|
|
@@ -33,7 +49,7 @@ function validateCidString(input) {
|
|
|
33
49
|
}
|
|
34
50
|
function parseCidString(input) {
|
|
35
51
|
try {
|
|
36
|
-
return
|
|
52
|
+
return parseCid(input);
|
|
37
53
|
}
|
|
38
54
|
catch {
|
|
39
55
|
return undefined;
|
package/dist/cid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cid.js","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"cid.js","sourceRoot":"","sources":["../src/cid.ts"],"names":[],"mappings":";;;AAuEA,sBAEC;AAED,4BAEC;AAED,8BAEC;AAED,8BAEC;AAED,sBAsBC;AAED,8CAEC;AAED,wCAMC;AAED,oDAIC;AA/HD,0CAAsC;AAwD7B,oFAxDA,SAAG,OAwDA;AAtDC,QAAA,mBAAmB,GAAG,IAAI,CAAA;AAC1B,QAAA,kBAAkB,GAAG,IAAI,CAAA;AAEzB,QAAA,uBAAuB,GAAG,IAAI,CAAA;AAkE3C,SAAgB,KAAK,CAAC,KAAc;IAClC,OAAO,SAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAa;IACpC,OAAO,SAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,SAAgB,SAAS,CAAC,KAAiB;IACzC,OAAO,SAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAgB,SAAS,CAAC,IAAY,EAAE,MAAuB;IAC7D,OAAO,SAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACnC,CAAC;AAED,SAAgB,KAAK,CACnB,KAAc,EACd,OAA8B;IAE9B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;IACxB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,0BAAkB,IAAI,GAAG,CAAC,IAAI,KAAK,2BAAmB,EAAE,CAAC;YACxE,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,+BAAuB,EAAE,CAAC;YACnD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,OAAO,cAAc,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,KAAK,CAAA;AACpD,CAAC;AAED,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,KAAa;IAChD,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACvC,CAAC;AACH,CAAC","sourcesContent":["import { CID } from 'multiformats/cid'\n\nexport const DAG_CBOR_MULTICODEC = 0x71\nexport const RAW_BIN_MULTICODEC = 0x55\n\nexport const SHA2_256_MULTIHASH_CODE = 0x12\n\nexport type MultihashDigest<Code extends number = number> = {\n code: Code\n digest: Uint8Array\n size: number\n bytes: Uint8Array\n}\n\ndeclare module 'multiformats/cid' {\n /**\n * @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and\n * related helpers ({@link asCid}, {@link parseCid}, {@link decodeCid},\n * {@link createCid}, {@link isCid}), instead.\n *\n * This is marked as deprecated because we want to discourage direct usage of\n * `multiformats/cid` in dependent packages, and instead have them rely on the\n * {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from\n * `multiformats` version <10 has compatibility issues with certain TypeScript\n * module resolution strategies, which can lead to type errors in dependent\n * packages.\n *\n * We are stuck with version 9 because `@atproto` packages did not drop\n * CommonJS support yet, and multiformats version 10 only supports ES modules.\n *\n * In order to avoid compatibility issues, while preparing for future breaking\n * changes (CID in multiformats v10+ has a slightly different interface), as\n * we update or swap out `multiformats`, we provide our own stable `Cid`\n * interface.\n */\n interface CID {}\n}\n\n// CID form \"multiformats\" is not very portable because:\n//\n// - In dependent packages that use \"moduleResolution\" set to \"node16\",\n// \"nodenext\" or \"bundler\", TypeScript fails to properly resolve the\n// multiformats package when importing CID from @atproto/lex-data. This causes\n// type errors in those packages. This is caused by the fact that the\n// multiformats version <10 (which is the last version that supports CommonJS)\n// uses \"exports\" field in package.json, which do not contain \"types\"\n// entrypoints.\n// https://www.npmjs.com/package/multiformats/v/9.9.0?activeTab=code\n// - By defining our own Cid interface and related functions, we can have more\n// control over the API we expose to dependent packages.\n// - It allow us to have a stable interface in case we need to swap out, or\n// eventually update multiformats (should we choose to drop CommonJS support)\n// in the future.\n\n// @NOTE Even though it is not portable, we still re-export CID here so that\n// dependent packages where it can be used, have access to it.\nexport { CID }\n\n/**\n * Interface for working with decoded CID string, compatible with\n * {@link CID} implementation.\n */\nexport interface Cid {\n version: 0 | 1\n code: number\n multihash: MultihashDigest\n bytes: Uint8Array\n equals(other: unknown): boolean\n toString(): string\n}\n\nexport function asCid(value: unknown): Cid | null {\n return CID.asCID(value)\n}\n\nexport function parseCid(input: string): Cid {\n return CID.parse(input)\n}\n\nexport function decodeCid(bytes: Uint8Array): Cid {\n return CID.decode(bytes)\n}\n\nexport function createCid(code: number, digest: MultihashDigest): Cid {\n return CID.createV1(code, digest)\n}\n\nexport function isCid(\n value: unknown,\n options?: { strict?: boolean },\n): value is Cid {\n const cid = asCid(value)\n if (!cid) {\n return false\n }\n\n if (options?.strict) {\n if (cid.version !== 1) {\n return false\n }\n if (cid.code !== RAW_BIN_MULTICODEC && cid.code !== DAG_CBOR_MULTICODEC) {\n return false\n }\n if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) {\n return false\n }\n }\n\n return true\n}\n\nexport function validateCidString(input: string): boolean {\n return parseCidString(input)?.toString() === input\n}\n\nexport function parseCidString(input: string): Cid | undefined {\n try {\n return parseCid(input)\n } catch {\n return undefined\n }\n}\n\nexport function ensureValidCidString(input: string): void {\n if (!validateCidString(input)) {\n throw new Error(`Invalid CID string`)\n }\n}\n"]}
|
package/dist/lex-equals.js
CHANGED
|
@@ -42,7 +42,7 @@ function lexEquals(a, b) {
|
|
|
42
42
|
if ((0, cid_js_1.isCid)(a)) {
|
|
43
43
|
// @NOTE CID.equals returns its argument when it is falsy (e.g. null or
|
|
44
44
|
// undefined) so we need to explicitly check that the output is "true".
|
|
45
|
-
return cid_js_1.
|
|
45
|
+
return (0, cid_js_1.asCid)(a).equals((0, cid_js_1.asCid)(b)) === true;
|
|
46
46
|
}
|
|
47
47
|
else if ((0, cid_js_1.isCid)(b)) {
|
|
48
48
|
return false;
|
package/dist/lex-equals.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex-equals.js","sourceRoot":"","sources":["../src/lex-equals.ts"],"names":[],"mappings":";;AAKA,8BA+EC;AApFD,
|
|
1
|
+
{"version":3,"file":"lex-equals.js","sourceRoot":"","sources":["../src/lex-equals.ts"],"names":[],"mappings":"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","sourcesContent":["import { asCid, isCid } from './cid.js'\nimport { LexValue } from './lex.js'\nimport { isPlainObject } from './object.js'\nimport { ui8Equals } from './uint8array.js'\n\nexport function lexEquals(a: LexValue, b: LexValue): boolean {\n if (Object.is(a, b)) {\n return true\n }\n\n if (\n a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object'\n ) {\n return false\n }\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b)) {\n return false\n }\n if (a.length !== b.length) {\n return false\n }\n for (let i = 0; i < a.length; i++) {\n if (!lexEquals(a[i], b[i])) {\n return false\n }\n }\n return true\n } else if (Array.isArray(b)) {\n return false\n }\n\n if (ArrayBuffer.isView(a)) {\n if (!ArrayBuffer.isView(b)) return false\n return ui8Equals(a, b)\n } else if (ArrayBuffer.isView(b)) {\n return false\n }\n\n if (isCid(a)) {\n // @NOTE CID.equals returns its argument when it is falsy (e.g. null or\n // undefined) so we need to explicitly check that the output is \"true\".\n return asCid(a)!.equals(asCid(b)) === true\n } else if (isCid(b)) {\n return false\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) {\n // Foolproof (should never happen)\n throw new TypeError(\n 'Invalid LexValue (expected CID, Uint8Array, or LexMap)',\n )\n }\n\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (aKeys.length !== bKeys.length) {\n return false\n }\n\n for (const key of aKeys) {\n const aVal = a[key]\n const bVal = b[key]\n\n // Needed because of the optional index signature in the Lex object type\n // though, in practice, aVal should never be undefined here.\n if (aVal === undefined) {\n if (bVal === undefined && bKeys.includes(key)) continue\n return false\n } else if (bVal === undefined) {\n return false\n }\n\n if (!lexEquals(aVal, bVal)) {\n return false\n }\n }\n\n return true\n}\n"]}
|
package/dist/lex.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type LexScalar = number | string | boolean | null |
|
|
1
|
+
import { Cid } from './cid.js';
|
|
2
|
+
export type LexScalar = number | string | boolean | null | Cid | Uint8Array;
|
|
3
3
|
export type LexValue = LexScalar | LexValue[] | {
|
|
4
4
|
[_ in string]?: LexValue;
|
|
5
5
|
};
|
package/dist/lex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex.js","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":";;AAUA,4BAMC;AAED,gCAMC;AAED,kCAcC;AAED,gCA4BC;AAGD,sCAIC;AA7ED,qCAAqC;AACrC,2CAA2C;AAS3C,SAAgB,QAAQ,CAAC,KAAc;IACrC,IAAI,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACvC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAC3C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,UAAU,CAAC,KAAc;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IACzC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,WAAW,CAAC,KAAc;IACxC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;YAC/B,OAAO,KAAK,YAAY,UAAU,IAAI,IAAA,cAAK,EAAC,KAAK,CAAC,CAAA;QACpD,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,IAAI,CAAA;QACb,KAAK,QAAQ;YACX,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;YACxC,MAAM,IAAI,SAAS,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAA;QACpD;YACE,MAAM,IAAI,SAAS,CAAC,sBAAsB,OAAO,KAAK,EAAE,CAAC,CAAA;IAC7D,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,KAAc;IACvC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;QAC5C,cAAc;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,IAAI,CAAA;QACb,KAAK,QAAQ;YACX,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAAE,OAAO,KAAK,CAAA;gBACzC,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;oBACxB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBAAE,OAAO,KAAK,CAAA;gBAC3C,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,KAAK,YAAY,UAAU;gBAAE,OAAO,IAAI,CAAA;YAC5C,IAAI,IAAA,cAAK,EAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAA;QAC/B,cAAc;QACd;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC;AAGD,SAAgB,aAAa,CAAC,KAAe;IAC3C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAC7E,CAAA;AACH,CAAC","sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"lex.js","sourceRoot":"","sources":["../src/lex.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cid, isCid } from './cid.js'\nimport { isPlainObject } from './object.js'\n\n// @NOTE BlobRef is just a special case of LexMap.\n\nexport type LexScalar = number | string | boolean | null | Cid | Uint8Array\nexport type LexValue = LexScalar | LexValue[] | { [_ in string]?: LexValue }\nexport type LexMap = { [_ in string]?: LexValue }\nexport type LexArray = LexValue[]\n\nexport function isLexMap(value: unknown): value is LexMap {\n if (!isPlainObject(value)) return false\n for (const key in value) {\n if (!isLexValue(value[key])) return false\n }\n return true\n}\n\nexport function isLexArray(value: unknown): value is LexArray {\n if (!Array.isArray(value)) return false\n for (let i = 0; i < value.length; i++) {\n if (!isLexValue(value[i])) return false\n }\n return true\n}\n\nexport function isLexScalar(value: unknown): value is LexScalar {\n switch (typeof value) {\n case 'object':\n if (value === null) return true\n return value instanceof Uint8Array || isCid(value)\n case 'string':\n case 'boolean':\n return true\n case 'number':\n if (Number.isInteger(value)) return true\n throw new TypeError(`Invalid Lex value: ${value}`)\n default:\n throw new TypeError(`Invalid Lex value: ${typeof value}`)\n }\n}\n\nexport function isLexValue(value: unknown): value is LexValue {\n switch (typeof value) {\n case 'number':\n if (!Number.isInteger(value)) return false\n // fallthrough\n case 'string':\n case 'boolean':\n return true\n case 'object':\n if (value === null) return true\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n if (!isLexValue(value[i])) return false\n }\n return true\n }\n if (isPlainObject(value)) {\n for (const key in value) {\n if (!isLexValue(value[key])) return false\n }\n return true\n }\n if (value instanceof Uint8Array) return true\n if (isCid(value)) return true\n // fallthrough\n default:\n return false\n }\n}\n\nexport type TypedLexMap = LexMap & { $type: string }\nexport function isTypedLexMap(value: LexValue): value is TypedLexMap {\n return (\n isLexMap(value) && typeof value.$type === 'string' && value.$type.length > 0\n )\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.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Core utilities for AT Lexicons",
|
|
6
6
|
"keywords": [
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"./tsconfig.build.json",
|
|
20
20
|
"./tsconfig.tests.json",
|
|
21
21
|
"./tsconfig.json",
|
|
22
|
-
"./dist"
|
|
22
|
+
"./dist",
|
|
23
|
+
"./CHANGELOG.md"
|
|
23
24
|
],
|
|
24
25
|
"sideEffects": false,
|
|
25
26
|
"type": "commonjs",
|
|
@@ -34,11 +35,11 @@
|
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@atproto/syntax": "workspace:*",
|
|
38
38
|
"multiformats": "^9.9.0",
|
|
39
39
|
"tslib": "^2.8.1",
|
|
40
40
|
"uint8arrays": "3.0.0",
|
|
41
|
-
"unicode-segmenter": "^0.14.0"
|
|
41
|
+
"unicode-segmenter": "^0.14.0",
|
|
42
|
+
"@atproto/syntax": "0.4.2"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"core-js": "^3",
|
|
@@ -48,4 +49,4 @@
|
|
|
48
49
|
"build": "tsc --build tsconfig.build.json",
|
|
49
50
|
"test": "jest"
|
|
50
51
|
}
|
|
51
|
-
}
|
|
52
|
+
}
|
package/src/blob.test.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isBlobRef, isLegacyBlobRef } from './blob.js'
|
|
2
|
-
import {
|
|
2
|
+
import { parseCid } from './cid.js'
|
|
3
3
|
|
|
4
4
|
// await cidForRawBytes(Buffer.from('Hello, World!'))
|
|
5
|
-
const blobCid =
|
|
5
|
+
const blobCid = parseCid(
|
|
6
6
|
'bafkreig77vqcdozl2wyk6z3cscaj5q5fggi53aoh64fewkdiri3cdauyn4',
|
|
7
7
|
)
|
|
8
8
|
// await cidForLex(Buffer.from('Hello, World!'))
|
|
9
|
-
const lexCid =
|
|
9
|
+
const lexCid = parseCid(
|
|
10
10
|
'bafyreic52vzks7wdklat4evp3vimohl55i2unzqpshz2ytka5omzr7exdy',
|
|
11
11
|
)
|
|
12
12
|
|
package/src/blob.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Cid,
|
|
3
|
+
RAW_BIN_MULTICODEC,
|
|
4
|
+
SHA2_256_MULTIHASH_CODE,
|
|
5
|
+
asCid,
|
|
6
|
+
parseCid,
|
|
7
|
+
} from './cid.js'
|
|
2
8
|
import { isPlainObject } from './object.js'
|
|
3
9
|
|
|
4
10
|
export type BlobRef = {
|
|
5
11
|
$type: 'blob'
|
|
6
12
|
mimeType: string
|
|
7
|
-
ref:
|
|
13
|
+
ref: Cid
|
|
8
14
|
size: number
|
|
9
15
|
}
|
|
10
16
|
|
|
@@ -21,7 +27,8 @@ export function isBlobRef(
|
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
const { mimeType, size, ref } = input
|
|
24
|
-
|
|
30
|
+
// @NOTE Very basic mime validation
|
|
31
|
+
if (typeof mimeType !== 'string' || !mimeType.includes('/')) {
|
|
25
32
|
return false
|
|
26
33
|
}
|
|
27
34
|
|
|
@@ -44,7 +51,7 @@ export function isBlobRef(
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
|
|
47
|
-
const cid =
|
|
54
|
+
const cid = asCid(ref)
|
|
48
55
|
if (!cid) {
|
|
49
56
|
return false
|
|
50
57
|
}
|
|
@@ -90,7 +97,7 @@ export function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {
|
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
try {
|
|
93
|
-
|
|
100
|
+
parseCid(cid)
|
|
94
101
|
} catch {
|
|
95
102
|
return false
|
|
96
103
|
}
|
package/src/cid.ts
CHANGED
|
@@ -5,13 +5,91 @@ export const RAW_BIN_MULTICODEC = 0x55
|
|
|
5
5
|
|
|
6
6
|
export const SHA2_256_MULTIHASH_CODE = 0x12
|
|
7
7
|
|
|
8
|
+
export type MultihashDigest<Code extends number = number> = {
|
|
9
|
+
code: Code
|
|
10
|
+
digest: Uint8Array
|
|
11
|
+
size: number
|
|
12
|
+
bytes: Uint8Array
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare module 'multiformats/cid' {
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated use the {@link Cid} interface from `@atproto/lex-data`, and
|
|
18
|
+
* related helpers ({@link asCid}, {@link parseCid}, {@link decodeCid},
|
|
19
|
+
* {@link createCid}, {@link isCid}), instead.
|
|
20
|
+
*
|
|
21
|
+
* This is marked as deprecated because we want to discourage direct usage of
|
|
22
|
+
* `multiformats/cid` in dependent packages, and instead have them rely on the
|
|
23
|
+
* {@link Cid} interface from `@atproto/lex-data`. The {@link CID} class from
|
|
24
|
+
* `multiformats` version <10 has compatibility issues with certain TypeScript
|
|
25
|
+
* module resolution strategies, which can lead to type errors in dependent
|
|
26
|
+
* packages.
|
|
27
|
+
*
|
|
28
|
+
* We are stuck with version 9 because `@atproto` packages did not drop
|
|
29
|
+
* CommonJS support yet, and multiformats version 10 only supports ES modules.
|
|
30
|
+
*
|
|
31
|
+
* In order to avoid compatibility issues, while preparing for future breaking
|
|
32
|
+
* changes (CID in multiformats v10+ has a slightly different interface), as
|
|
33
|
+
* we update or swap out `multiformats`, we provide our own stable `Cid`
|
|
34
|
+
* interface.
|
|
35
|
+
*/
|
|
36
|
+
interface CID {}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// CID form "multiformats" is not very portable because:
|
|
40
|
+
//
|
|
41
|
+
// - In dependent packages that use "moduleResolution" set to "node16",
|
|
42
|
+
// "nodenext" or "bundler", TypeScript fails to properly resolve the
|
|
43
|
+
// multiformats package when importing CID from @atproto/lex-data. This causes
|
|
44
|
+
// type errors in those packages. This is caused by the fact that the
|
|
45
|
+
// multiformats version <10 (which is the last version that supports CommonJS)
|
|
46
|
+
// uses "exports" field in package.json, which do not contain "types"
|
|
47
|
+
// entrypoints.
|
|
48
|
+
// https://www.npmjs.com/package/multiformats/v/9.9.0?activeTab=code
|
|
49
|
+
// - By defining our own Cid interface and related functions, we can have more
|
|
50
|
+
// control over the API we expose to dependent packages.
|
|
51
|
+
// - It allow us to have a stable interface in case we need to swap out, or
|
|
52
|
+
// eventually update multiformats (should we choose to drop CommonJS support)
|
|
53
|
+
// in the future.
|
|
54
|
+
|
|
55
|
+
// @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.
|
|
8
57
|
export { CID }
|
|
9
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Interface for working with decoded CID string, compatible with
|
|
61
|
+
* {@link CID} implementation.
|
|
62
|
+
*/
|
|
63
|
+
export interface Cid {
|
|
64
|
+
version: 0 | 1
|
|
65
|
+
code: number
|
|
66
|
+
multihash: MultihashDigest
|
|
67
|
+
bytes: Uint8Array
|
|
68
|
+
equals(other: unknown): boolean
|
|
69
|
+
toString(): string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function asCid(value: unknown): Cid | null {
|
|
73
|
+
return CID.asCID(value)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function parseCid(input: string): Cid {
|
|
77
|
+
return CID.parse(input)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function decodeCid(bytes: Uint8Array): Cid {
|
|
81
|
+
return CID.decode(bytes)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function createCid(code: number, digest: MultihashDigest): Cid {
|
|
85
|
+
return CID.createV1(code, digest)
|
|
86
|
+
}
|
|
87
|
+
|
|
10
88
|
export function isCid(
|
|
11
89
|
value: unknown,
|
|
12
90
|
options?: { strict?: boolean },
|
|
13
|
-
): value is
|
|
14
|
-
const cid =
|
|
91
|
+
): value is Cid {
|
|
92
|
+
const cid = asCid(value)
|
|
15
93
|
if (!cid) {
|
|
16
94
|
return false
|
|
17
95
|
}
|
|
@@ -35,9 +113,9 @@ export function validateCidString(input: string): boolean {
|
|
|
35
113
|
return parseCidString(input)?.toString() === input
|
|
36
114
|
}
|
|
37
115
|
|
|
38
|
-
export function parseCidString(input: string):
|
|
116
|
+
export function parseCidString(input: string): Cid | undefined {
|
|
39
117
|
try {
|
|
40
|
-
return
|
|
118
|
+
return parseCid(input)
|
|
41
119
|
} catch {
|
|
42
120
|
return undefined
|
|
43
121
|
}
|
package/src/lex-equals.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseCid } from './cid.js'
|
|
2
2
|
import { lexEquals } from './lex-equals.js'
|
|
3
3
|
import { LexValue } from './lex.js'
|
|
4
4
|
|
|
@@ -48,11 +48,11 @@ describe('lexEquals', () => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
it('compares CIDs', () => {
|
|
51
|
-
const cid1 =
|
|
51
|
+
const cid1 = parseCid(
|
|
52
52
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
53
53
|
)
|
|
54
|
-
const cid2 =
|
|
55
|
-
const cid3 =
|
|
54
|
+
const cid2 = parseCid(cid1.toString())
|
|
55
|
+
const cid3 = parseCid(cid1.toString())
|
|
56
56
|
|
|
57
57
|
expectLexEqual(cid1, cid2, true)
|
|
58
58
|
expectLexEqual(cid1, cid3, true)
|
|
@@ -78,19 +78,19 @@ describe('lexEquals', () => {
|
|
|
78
78
|
it('compares nested structures', () => {
|
|
79
79
|
const lex1 = {
|
|
80
80
|
foo: [1, 2, { bar: new Uint8Array([3, 4, 5]) }],
|
|
81
|
-
baz:
|
|
81
|
+
baz: parseCid(
|
|
82
82
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
83
83
|
),
|
|
84
84
|
}
|
|
85
85
|
const lex2 = {
|
|
86
86
|
foo: [1, 2, { bar: new Uint8Array([3, 4, 5]) }],
|
|
87
|
-
baz:
|
|
87
|
+
baz: parseCid(
|
|
88
88
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
89
89
|
),
|
|
90
90
|
}
|
|
91
91
|
const lex3 = {
|
|
92
92
|
foo: [1, 2, { bar: new Uint8Array([3, 4, 5 + 1]) }],
|
|
93
|
-
baz:
|
|
93
|
+
baz: parseCid(
|
|
94
94
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
95
95
|
),
|
|
96
96
|
}
|
|
@@ -127,7 +127,7 @@ describe('lexEquals', () => {
|
|
|
127
127
|
const u8 = new Uint8Array([1, 2, 3])
|
|
128
128
|
expectLexEqual(u8, u8, true)
|
|
129
129
|
|
|
130
|
-
const cid =
|
|
130
|
+
const cid = parseCid(
|
|
131
131
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
132
132
|
)
|
|
133
133
|
expectLexEqual(cid, cid, true)
|
package/src/lex-equals.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { asCid, isCid } from './cid.js'
|
|
2
2
|
import { LexValue } from './lex.js'
|
|
3
3
|
import { isPlainObject } from './object.js'
|
|
4
4
|
import { ui8Equals } from './uint8array.js'
|
|
@@ -44,7 +44,7 @@ export function lexEquals(a: LexValue, b: LexValue): boolean {
|
|
|
44
44
|
if (isCid(a)) {
|
|
45
45
|
// @NOTE CID.equals returns its argument when it is falsy (e.g. null or
|
|
46
46
|
// undefined) so we need to explicitly check that the output is "true".
|
|
47
|
-
return
|
|
47
|
+
return asCid(a)!.equals(asCid(b)) === true
|
|
48
48
|
} else if (isCid(b)) {
|
|
49
49
|
return false
|
|
50
50
|
}
|
package/src/lex.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cid, isCid } from './cid.js'
|
|
2
2
|
import { isPlainObject } from './object.js'
|
|
3
3
|
|
|
4
4
|
// @NOTE BlobRef is just a special case of LexMap.
|
|
5
5
|
|
|
6
|
-
export type LexScalar = number | string | boolean | null |
|
|
6
|
+
export type LexScalar = number | string | boolean | null | Cid | Uint8Array
|
|
7
7
|
export type LexValue = LexScalar | LexValue[] | { [_ in string]?: LexValue }
|
|
8
8
|
export type LexMap = { [_ in string]?: LexValue }
|
|
9
9
|
export type LexArray = LexValue[]
|
package/src/object.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseCid } from './cid.js'
|
|
2
2
|
import { isObject, isPlainObject } from './object.js'
|
|
3
3
|
describe('isObject', () => {
|
|
4
4
|
it('returns true for plain objects', () => {
|
|
@@ -7,7 +7,7 @@ describe('isObject', () => {
|
|
|
7
7
|
})
|
|
8
8
|
|
|
9
9
|
it('returns true for CIDs', () => {
|
|
10
|
-
const cid =
|
|
10
|
+
const cid = parseCid(
|
|
11
11
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
12
12
|
)
|
|
13
13
|
expect(isObject(cid)).toBe(true)
|
|
@@ -54,7 +54,7 @@ describe('isPlainObject', () => {
|
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
it('returns false for CIDs', () => {
|
|
57
|
-
const cid =
|
|
57
|
+
const cid = parseCid(
|
|
58
58
|
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
59
59
|
)
|
|
60
60
|
expect(isPlainObject(cid)).toBe(false)
|