@atcute/cid 2.2.6 → 2.4.0

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/README.md CHANGED
@@ -1,18 +1,87 @@
1
1
  # @atcute/cid
2
2
 
3
- lightweight [DASL CID][dasl-cid] codec library for AT Protocol.
3
+ content identifier (CID) codec for AT Protocol.
4
+
5
+ ```sh
6
+ npm install @atcute/cid
7
+ ```
8
+
9
+ this library implements DASL's [CID][dasl-cid] format used by AT Protocol to address resources by
10
+ their contents.
4
11
 
5
12
  [dasl-cid]: https://dasl.ing/cid.html
6
13
 
14
+ ## usage
15
+
16
+ ### creating CIDs
17
+
7
18
  ```ts
8
19
  import * as CID from '@atcute/cid';
9
20
 
21
+ // create a CID from DAG-CBOR data
22
+ const cid = await CID.create(0x71, cborBytes);
23
+ // -> { version: 1, codec: 113, digest: { ... }, bytes: Uint8Array(36) }
24
+
25
+ // create from raw data
26
+ const rawCid = await CID.create(0x55, rawBytes);
27
+
28
+ // create an empty CID (zero-length digest)
29
+ const empty = CID.createEmpty(0x71);
30
+ ```
31
+
32
+ ### parsing CIDs
33
+
34
+ ```ts
35
+ import * as CID from '@atcute/cid';
36
+
37
+ // parse from base32 string
10
38
  const cid = CID.fromString('bafyreihffx5a2e7k5uwrmmgofbvzujc5cmw5h4espouwuxt3liqoflx3ee');
11
- // ^? { version: 1, codec: 113, digest: { ... }, bytes: Uint8Array(36) }
12
39
 
13
- // Creating a CID containing CBOR data
14
- const cid = await CID.create(0x71, buffer);
40
+ // parse from binary (with 0x00 prefix)
41
+ const cid = CID.fromBinary(bytes);
42
+
43
+ // parse from raw CID bytes
44
+ const cid = CID.decode(cidBytes);
45
+ ```
46
+
47
+ ### serializing CIDs
48
+
49
+ ```ts
50
+ import * as CID from '@atcute/cid';
51
+
52
+ // to base32 string
53
+ CID.toString(cid);
54
+ // -> "bafyreihffx5a2e7k5uwrmmgofbvzujc5cmw5h4espouwuxt3liqoflx3ee"
55
+
56
+ // to binary (with 0x00 prefix)
57
+ CID.toBinary(cid);
58
+ // -> Uint8Array(37)
59
+ ```
60
+
61
+ ### comparing CIDs
62
+
63
+ ```ts
64
+ import * as CID from '@atcute/cid';
65
+
66
+ CID.equals(cidA, cidB); // true if same content hash
67
+ ```
68
+
69
+ ### CidLink wrapper
70
+
71
+ for JSON serialization compatible with atproto's data model:
72
+
73
+ ```ts
74
+ import { toCidLink, fromCidLink, isCidLink } from '@atcute/cid';
75
+
76
+ // convert Cid to CidLink (has $link property)
77
+ const link = toCidLink(cid);
78
+ // -> { $link: "bafyrei..." }
79
+
80
+ // convert back to Cid
81
+ const cid = fromCidLink(link);
15
82
 
16
- // Serializing CID into string
17
- CID.toString(cid); // -> bafyrei...
83
+ // type guard
84
+ if (isCidLink(value)) {
85
+ console.log(value.$link);
86
+ }
18
87
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"cid-link.d.ts","sourceRoot":"","sources":["../lib/cid-link.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2C,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAO/E,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,cAAe,YAAW,OAAO;IAI7C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;gBAEf,KAAK,EAAE,UAAU;IAI7B,IAAI,KAAK,IAAI,MAAM,CASlB;IAED,MAAM,IAAI,OAAO;CAGjB;AAED,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,OAOnD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,GAAG,KAAG,OASpC,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,MAAM,OAAO,KAAG,GAM3C,CAAC"}
1
+ {"version":3,"file":"cid-link.d.ts","sourceRoot":"","sources":["../lib/cid-link.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2C,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAO/E,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,cAAe,YAAW,OAAO;IAI7C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAE3B,YAAY,KAAK,EAAE,UAAU,EAE5B;IAED,IAAI,KAAK,IAAI,MAAM,CASlB;IAED,MAAM,IAAI,OAAO,CAEhB;CACD;AAED,eAAO,MAAM,SAAS,sCAOrB,CAAC;AAEF,eAAO,MAAM,SAAS,uBASrB,CAAC;AAEF,eAAO,MAAM,WAAW,wBAMvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cid-link.js","sourceRoot":"","sources":["../lib/cid-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAE/E,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;AAE/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA0B,CAAC;AAM7E,MAAM,OAAO,cAAc;IAC1B,gBAAgB;IACP,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;IAEzB,KAAK,CAAa;IAE3B,YAAY,KAAiB;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,KAAK;QACR,IAAI,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvB,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAEjC,uBAAuB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,MAAM;QACL,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;CACD;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAc,EAAoB,EAAE;IAC7D,MAAM,GAAG,GAAG,KAAY,CAAC;IAEzB,OAAO,CACN,GAAG,YAAY,cAAc;QAC7B,CAAC,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAC1E,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAW,EAAE;IAC9C,MAAM,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEzC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,uBAAuB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAa,EAAO,EAAE;IACjD,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC"}
1
+ {"version":3,"file":"cid-link.js","sourceRoot":"","sources":["../lib/cid-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAE/E,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;AAE/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA0B,CAAC;AAM7E,MAAM,OAAO,cAAc;IAC1B,gBAAgB;IACP,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;IAEzB,KAAK,CAAa;IAE3B,YAAY,KAAiB,EAAE;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAAA,CACnB;IAED,IAAI,KAAK,GAAW;QACnB,IAAI,GAAG,GAAG,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvB,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAEjC,uBAAuB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,GAAG,CAAC;IAAA,CACX;IAED,MAAM,GAAY;QACjB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAAA,CAC7B;CACD;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAc,EAAoB,EAAE,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAY,CAAC;IAEzB,OAAO,CACN,GAAG,YAAY,cAAc;QAC7B,CAAC,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAC1E,CAAC;AAAA,CACF,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEzC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,uBAAuB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AAAA,CACZ,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAa,EAAO,EAAE,CAAC;IAClD,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAAA,CAC9B,CAAC"}
package/dist/codec.d.ts CHANGED
@@ -1,9 +1,13 @@
1
+ /** CID version, always `1` for CIDv1 */
1
2
  export declare const CID_VERSION = 1;
3
+ /** multicodec for SHA-256 hash */
2
4
  export declare const HASH_SHA256 = 18;
5
+ /** multicodec for raw binary data */
3
6
  export declare const CODEC_RAW = 85;
7
+ /** multicodec for DAG-CBOR encoded data */
4
8
  export declare const CODEC_DCBOR = 113;
5
9
  /**
6
- * Represents a Content Identifier (CID), in particular, a limited subset of
10
+ * represents a Content Identifier (CID), in particular, a limited subset of
7
11
  * CIDv1 as described by DASL specifications.
8
12
  * https://dasl.ing/cid.html
9
13
  */
@@ -22,13 +26,67 @@ export interface Cid {
22
26
  /** Raw CID bytes */
23
27
  readonly bytes: Uint8Array;
24
28
  }
25
- export declare const create: (codec: 85 | 113, data: Uint8Array) => Promise<Cid>;
26
- export declare const createEmpty: (codec: 85 | 113) => Cid;
27
- export declare const decodeFirst: (bytes: Uint8Array) => [decoded: Cid, remainder: Uint8Array];
28
- export declare const decode: (bytes: Uint8Array) => Cid;
29
+ /**
30
+ * creates a CID from a pre-computed SHA-256 digest
31
+ * @param codec multicodec type for the data
32
+ * @param digest raw SHA-256 hash bytes (must be 32 bytes)
33
+ * @returns CID object
34
+ */
35
+ export declare const fromDigest: (codec: 85 | 113, digest: Uint8Array<ArrayBufferLike>) => Cid;
36
+ /**
37
+ * creates a CID by hashing the provided data with SHA-256
38
+ * @param codec multicodec type for the data
39
+ * @param data raw data to hash
40
+ * @returns CID object
41
+ */
42
+ export declare const create: (codec: 85 | 113, data: Uint8Array<ArrayBufferLike>) => Promise<Cid>;
43
+ /**
44
+ * decodes a CID from bytes, returning the CID and any remaining bytes
45
+ * @param bytes raw CID bytes
46
+ * @returns tuple of decoded CID and remainder bytes
47
+ * @throws {RangeError} if the bytes are too short or contain invalid values
48
+ */
49
+ export declare const decodeFirst: (bytes: Uint8Array<ArrayBufferLike>) => [decoded: Cid, remainder: Uint8Array<ArrayBufferLike>];
50
+ /**
51
+ * decodes a CID from bytes, expecting no remainder
52
+ * @param bytes raw CID bytes
53
+ * @returns decoded CID
54
+ * @throws {RangeError} if the bytes are invalid or contain extra data
55
+ */
56
+ export declare const decode: (bytes: Uint8Array<ArrayBufferLike>) => Cid;
57
+ /**
58
+ * parses a CID from a multibase base32 string
59
+ * @param input base32-encoded CID string (with 'b' prefix)
60
+ * @returns decoded CID
61
+ * @throws {SyntaxError} if the string is not a valid multibase base32 string
62
+ * @throws {RangeError} if the string length is invalid
63
+ */
29
64
  export declare const fromString: (input: string) => Cid;
65
+ /**
66
+ * encodes a CID to a multibase base32 string
67
+ * @param cid CID to encode
68
+ * @returns base32-encoded string with 'b' prefix
69
+ */
30
70
  export declare const toString: (cid: Cid) => string;
31
- export declare const fromBinary: (input: Uint8Array) => Cid;
32
- export declare const toBinary: (cid: Cid) => Uint8Array;
71
+ /**
72
+ * parses a CID from binary format (with 0x00 prefix)
73
+ * @param input binary CID bytes with 0x00 prefix
74
+ * @returns decoded CID
75
+ * @throws {RangeError} if the byte length is invalid
76
+ * @throws {SyntaxError} if the prefix byte is not 0x00
77
+ */
78
+ export declare const fromBinary: (input: Uint8Array<ArrayBufferLike>) => Cid;
79
+ /**
80
+ * encodes a CID to binary format (with 0x00 prefix)
81
+ * @param cid CID to encode
82
+ * @returns binary CID bytes with 0x00 prefix
83
+ */
84
+ export declare const toBinary: (cid: Cid) => Uint8Array<ArrayBufferLike>;
85
+ /**
86
+ * checks if two CIDs are equal
87
+ * @param a first CID
88
+ * @param b second CID
89
+ * @returns true if the CIDs have identical bytes
90
+ */
33
91
  export declare const equals: (a: Cid, b: Cid) => boolean;
34
92
  //# sourceMappingURL=codec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,WAAW,KAAO,CAAC;AAEhC,eAAO,MAAM,SAAS,KAAO,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAO,CAAC;AAKhC;;;;GAIG;AACH,MAAM,WAAW,GAAG;IACnB,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,QAAQ,CAAC,MAAM,EAAE;QAChB,wEAAwE;QACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,qBAAqB;QACrB,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;KAC9B,CAAC;IACF,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC3B;AAKD,eAAO,MAAM,MAAM,GAAU,OAAO,EAAI,GAAG,GAAI,EAAE,MAAM,UAAU,KAAG,OAAO,CAAC,GAAG,CA0B9E,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,EAAI,GAAG,GAAI,KAAG,GAehD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,UAAU,KAAG,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CA2CnF,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,GAQ1C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,GAgB1C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,GAAG,KAAG,MASnC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,UAAU,KAAG,GAa9C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,GAAG,KAAG,UAMnC,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,GAAG,GAAG,EAAE,GAAG,GAAG,KAAG,OAEvC,CAAC"}
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"AAGA,wCAAwC;AACxC,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,kCAAkC;AAClC,eAAO,MAAM,WAAW,KAAO,CAAC;AAEhC,qCAAqC;AACrC,eAAO,MAAM,SAAS,KAAO,CAAC;AAC9B,2CAA2C;AAC3C,eAAO,MAAM,WAAW,MAAO,CAAC;AAKhC;;;;GAIG;AACH,MAAM,WAAW,GAAG;IACnB,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,QAAQ,CAAC,MAAM,EAAE;QAChB,wEAAwE;QACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,qBAAqB;QACrB,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;KAC9B,CAAC;IACF,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC3B;AAKD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,+DAuBtB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,MAAM,sEAGlB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,gGAqCvB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,MAAM,6CAQlB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,wBAWtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sBASpB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,6CAOtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2CAMpB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,MAAM,6BAElB,CAAC"}
package/dist/codec.js CHANGED
@@ -1,15 +1,24 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
2
  import { allocUnsafe, toSha256, equals as isBufferEqual } from '@atcute/uint8array';
3
+ /** CID version, always `1` for CIDv1 */
3
4
  export const CID_VERSION = 1;
5
+ /** multicodec for SHA-256 hash */
4
6
  export const HASH_SHA256 = 0x12;
7
+ /** multicodec for raw binary data */
5
8
  export const CODEC_RAW = 0x55;
9
+ /** multicodec for DAG-CBOR encoded data */
6
10
  export const CODEC_DCBOR = 0x71;
7
11
  /** @internal */
8
12
  export const CID_STRINGIFY_CACHE = new WeakMap();
9
13
  // a SHA-256 CIDv1 is always going to be 36 bytes, that's 4 bytes for the
10
14
  // header, and 32 bytes for the digest itself.
11
- export const create = async (codec, data) => {
12
- const digest = await toSha256(data);
15
+ /**
16
+ * creates a CID from a pre-computed SHA-256 digest
17
+ * @param codec multicodec type for the data
18
+ * @param digest raw SHA-256 hash bytes (must be 32 bytes)
19
+ * @returns CID object
20
+ */
21
+ export const fromDigest = (codec, digest) => {
13
22
  if (digest.length !== 32) {
14
23
  throw new RangeError(`invalid digest length`);
15
24
  }
@@ -19,7 +28,7 @@ export const create = async (codec, data) => {
19
28
  bytes[2] = HASH_SHA256;
20
29
  bytes[3] = 32;
21
30
  bytes.set(digest, 4);
22
- const cid = {
31
+ return {
23
32
  version: CID_VERSION,
24
33
  codec: codec,
25
34
  digest: {
@@ -28,25 +37,25 @@ export const create = async (codec, data) => {
28
37
  },
29
38
  bytes: bytes,
30
39
  };
31
- return cid;
32
40
  };
33
- export const createEmpty = (codec) => {
34
- const bytes = Uint8Array.from([CID_VERSION, codec, HASH_SHA256, 0]);
35
- const digest = bytes.subarray(4);
36
- const cid = {
37
- version: CID_VERSION,
38
- codec: codec,
39
- digest: {
40
- codec: HASH_SHA256,
41
- contents: digest,
42
- },
43
- bytes: bytes,
44
- };
45
- return cid;
41
+ /**
42
+ * creates a CID by hashing the provided data with SHA-256
43
+ * @param codec multicodec type for the data
44
+ * @param data raw data to hash
45
+ * @returns CID object
46
+ */
47
+ export const create = async (codec, data) => {
48
+ const digest = await toSha256(data);
49
+ return fromDigest(codec, digest);
46
50
  };
51
+ /**
52
+ * decodes a CID from bytes, returning the CID and any remaining bytes
53
+ * @param bytes raw CID bytes
54
+ * @returns tuple of decoded CID and remainder bytes
55
+ * @throws {RangeError} if the bytes are too short or contain invalid values
56
+ */
47
57
  export const decodeFirst = (bytes) => {
48
- const length = bytes.length;
49
- if (length < 4) {
58
+ if (bytes.length < 36) {
50
59
  throw new RangeError(`cid too short`);
51
60
  }
52
61
  const version = bytes[0];
@@ -62,23 +71,26 @@ export const decodeFirst = (bytes) => {
62
71
  if (digestType !== HASH_SHA256) {
63
72
  throw new RangeError(`incorrect cid digest codec (got 0x${digestType.toString(16)})`);
64
73
  }
65
- if (digestSize !== 32 && digestSize !== 0) {
74
+ if (digestSize !== 32) {
66
75
  throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
67
76
  }
68
- if (length < 4 + digestSize) {
69
- throw new RangeError(`cid too short`);
70
- }
71
77
  const cid = {
72
78
  version: CID_VERSION,
73
79
  codec: codec,
74
80
  digest: {
75
81
  codec: digestType,
76
- contents: bytes.subarray(4, 4 + digestSize),
82
+ contents: bytes.subarray(4, 36),
77
83
  },
78
- bytes: bytes.subarray(0, 4 + digestSize),
84
+ bytes: bytes.subarray(0, 36),
79
85
  };
80
- return [cid, bytes.subarray(4 + digestSize)];
86
+ return [cid, bytes.subarray(36)];
81
87
  };
88
+ /**
89
+ * decodes a CID from bytes, expecting no remainder
90
+ * @param bytes raw CID bytes
91
+ * @returns decoded CID
92
+ * @throws {RangeError} if the bytes are invalid or contain extra data
93
+ */
82
94
  export const decode = (bytes) => {
83
95
  const [cid, remainder] = decodeFirst(bytes);
84
96
  if (remainder.length !== 0) {
@@ -86,20 +98,28 @@ export const decode = (bytes) => {
86
98
  }
87
99
  return cid;
88
100
  };
101
+ /**
102
+ * parses a CID from a multibase base32 string
103
+ * @param input base32-encoded CID string (with 'b' prefix)
104
+ * @returns decoded CID
105
+ * @throws {SyntaxError} if the string is not a valid multibase base32 string
106
+ * @throws {RangeError} if the string length is invalid
107
+ */
89
108
  export const fromString = (input) => {
90
- if (input.length < 2 || input[0] !== 'b') {
91
- throw new SyntaxError(`not a multibase base32 string`);
92
- }
93
- // 4 bytes in base32 = 7 characters + 1 character for the prefix
94
109
  // 36 bytes in base32 = 58 characters + 1 character for the prefix
95
- if (input.length !== 59 && input.length !== 8) {
96
- throw new RangeError(`cid too short`);
110
+ if (input.length !== 59 || input[0] !== 'b') {
111
+ throw new SyntaxError(`not a valid cid string`);
97
112
  }
98
113
  const bytes = fromBase32(input.slice(1));
99
114
  const cid = decode(bytes);
100
115
  CID_STRINGIFY_CACHE.set(cid, input);
101
116
  return cid;
102
117
  };
118
+ /**
119
+ * encodes a CID to a multibase base32 string
120
+ * @param cid CID to encode
121
+ * @returns base32-encoded string with 'b' prefix
122
+ */
103
123
  export const toString = (cid) => {
104
124
  let str = CID_STRINGIFY_CACHE.get(cid);
105
125
  if (str === undefined) {
@@ -108,24 +128,37 @@ export const toString = (cid) => {
108
128
  }
109
129
  return str;
110
130
  };
131
+ /**
132
+ * parses a CID from binary format (with 0x00 prefix)
133
+ * @param input binary CID bytes with 0x00 prefix
134
+ * @returns decoded CID
135
+ * @throws {RangeError} if the byte length is invalid
136
+ * @throws {SyntaxError} if the prefix byte is not 0x00
137
+ */
111
138
  export const fromBinary = (input) => {
112
- // 4 bytes + 1 byte for the 0x00 prefix
113
139
  // 36 bytes + 1 byte for the 0x00 prefix
114
- if (input.length !== 37 && input.length !== 5) {
115
- throw new RangeError(`cid bytes too short`);
116
- }
117
- if (input[0] !== 0) {
118
- throw new SyntaxError(`incorrect binary cid`);
140
+ if (input.length !== 37 || input[0] !== 0) {
141
+ throw new SyntaxError(`invalid binary cid`);
119
142
  }
120
- const bytes = input.subarray(1);
121
- return decode(bytes);
143
+ return decode(input.subarray(1));
122
144
  };
145
+ /**
146
+ * encodes a CID to binary format (with 0x00 prefix)
147
+ * @param cid CID to encode
148
+ * @returns binary CID bytes with 0x00 prefix
149
+ */
123
150
  export const toBinary = (cid) => {
124
151
  const bytes = allocUnsafe(1 + cid.bytes.length);
125
152
  bytes[0] = 0;
126
153
  bytes.set(cid.bytes, 1);
127
154
  return bytes;
128
155
  };
156
+ /**
157
+ * checks if two CIDs are equal
158
+ * @param a first CID
159
+ * @param b second CID
160
+ * @returns true if the CIDs have identical bytes
161
+ */
129
162
  export const equals = (a, b) => {
130
163
  return isBufferEqual(a.bytes, b.bytes);
131
164
  };
package/dist/codec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"codec.js","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEhC,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAEhC,gBAAgB;AAChB,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,OAAO,EAAe,CAAC;AAuB9D,yEAAyE;AACzE,8CAA8C;AAE9C,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,KAAkB,EAAE,IAAgB,EAAgB,EAAE;IAClF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAElC,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IACvB,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACjB,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IACvB,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAErB,MAAM,GAAG,GAAQ;QAChB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE;YACP,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;SAC/B;QACD,KAAK,EAAE,KAAK;KACZ,CAAC;IAEF,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAkB,EAAO,EAAE;IACtD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEjC,MAAM,GAAG,GAAQ;QAChB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE;YACP,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,MAAM;SAChB;QACD,KAAK,EAAE,KAAK;KACZ,CAAC;IAEF,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAyC,EAAE;IACvF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE5B,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAE5B,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,+BAA+B,OAAO,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAClD,MAAM,IAAI,UAAU,CAAC,8BAA8B,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,UAAU,CAAC,qCAAqC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,UAAU,KAAK,EAAE,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,UAAU,CAAC,kCAAkC,UAAU,GAAG,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,GAAG,GAAQ;QAChB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE;YACP,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC;SAC3C;QACD,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC;KACxC,CAAC;IAEF,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAiB,EAAO,EAAE;IAChD,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAE5C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,8BAA8B,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAO,EAAE;IAChD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1C,MAAM,IAAI,WAAW,CAAC,+BAA+B,CAAC,CAAC;IACxD,CAAC;IAED,gEAAgE;IAChE,kEAAkE;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1B,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAU,EAAE;IAC5C,IAAI,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,GAAG,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAEhC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAiB,EAAO,EAAE;IACpD,uCAAuC;IACvC,wCAAwC;IACxC,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAc,EAAE;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAExB,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAM,EAAE,CAAM,EAAW,EAAE;IACjD,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC,CAAC"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAEA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // implements github:darobin/dasl.ing@cc66c35 (2025-10-20)
1
2
  export * from './cid-link.js';
2
3
  export * from './codec.js';
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
package/lib/codec.ts CHANGED
@@ -1,17 +1,21 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
2
  import { allocUnsafe, toSha256, equals as isBufferEqual } from '@atcute/uint8array';
3
3
 
4
+ /** CID version, always `1` for CIDv1 */
4
5
  export const CID_VERSION = 1;
6
+ /** multicodec for SHA-256 hash */
5
7
  export const HASH_SHA256 = 0x12;
6
8
 
9
+ /** multicodec for raw binary data */
7
10
  export const CODEC_RAW = 0x55;
11
+ /** multicodec for DAG-CBOR encoded data */
8
12
  export const CODEC_DCBOR = 0x71;
9
13
 
10
14
  /** @internal */
11
15
  export const CID_STRINGIFY_CACHE = new WeakMap<Cid, string>();
12
16
 
13
17
  /**
14
- * Represents a Content Identifier (CID), in particular, a limited subset of
18
+ * represents a Content Identifier (CID), in particular, a limited subset of
15
19
  * CIDv1 as described by DASL specifications.
16
20
  * https://dasl.ing/cid.html
17
21
  */
@@ -34,8 +38,13 @@ export interface Cid {
34
38
  // a SHA-256 CIDv1 is always going to be 36 bytes, that's 4 bytes for the
35
39
  // header, and 32 bytes for the digest itself.
36
40
 
37
- export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid> => {
38
- const digest = await toSha256(data);
41
+ /**
42
+ * creates a CID from a pre-computed SHA-256 digest
43
+ * @param codec multicodec type for the data
44
+ * @param digest raw SHA-256 hash bytes (must be 32 bytes)
45
+ * @returns CID object
46
+ */
47
+ export const fromDigest = (codec: 0x55 | 0x71, digest: Uint8Array): Cid => {
39
48
  if (digest.length !== 32) {
40
49
  throw new RangeError(`invalid digest length`);
41
50
  }
@@ -49,7 +58,7 @@ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid>
49
58
 
50
59
  bytes.set(digest, 4);
51
60
 
52
- const cid: Cid = {
61
+ return {
53
62
  version: CID_VERSION,
54
63
  codec: codec,
55
64
  digest: {
@@ -58,31 +67,27 @@ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid>
58
67
  },
59
68
  bytes: bytes,
60
69
  };
61
-
62
- return cid;
63
70
  };
64
71
 
65
- export const createEmpty = (codec: 0x55 | 0x71): Cid => {
66
- const bytes = Uint8Array.from([CID_VERSION, codec, HASH_SHA256, 0]);
67
- const digest = bytes.subarray(4);
68
-
69
- const cid: Cid = {
70
- version: CID_VERSION,
71
- codec: codec,
72
- digest: {
73
- codec: HASH_SHA256,
74
- contents: digest,
75
- },
76
- bytes: bytes,
77
- };
78
-
79
- return cid;
72
+ /**
73
+ * creates a CID by hashing the provided data with SHA-256
74
+ * @param codec multicodec type for the data
75
+ * @param data raw data to hash
76
+ * @returns CID object
77
+ */
78
+ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid> => {
79
+ const digest = await toSha256(data);
80
+ return fromDigest(codec, digest);
80
81
  };
81
82
 
83
+ /**
84
+ * decodes a CID from bytes, returning the CID and any remaining bytes
85
+ * @param bytes raw CID bytes
86
+ * @returns tuple of decoded CID and remainder bytes
87
+ * @throws {RangeError} if the bytes are too short or contain invalid values
88
+ */
82
89
  export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8Array] => {
83
- const length = bytes.length;
84
-
85
- if (length < 4) {
90
+ if (bytes.length < 36) {
86
91
  throw new RangeError(`cid too short`);
87
92
  }
88
93
 
@@ -103,27 +108,29 @@ export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8A
103
108
  throw new RangeError(`incorrect cid digest codec (got 0x${digestType.toString(16)})`);
104
109
  }
105
110
 
106
- if (digestSize !== 32 && digestSize !== 0) {
111
+ if (digestSize !== 32) {
107
112
  throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
108
113
  }
109
114
 
110
- if (length < 4 + digestSize) {
111
- throw new RangeError(`cid too short`);
112
- }
113
-
114
115
  const cid: Cid = {
115
116
  version: CID_VERSION,
116
117
  codec: codec,
117
118
  digest: {
118
119
  codec: digestType,
119
- contents: bytes.subarray(4, 4 + digestSize),
120
+ contents: bytes.subarray(4, 36),
120
121
  },
121
- bytes: bytes.subarray(0, 4 + digestSize),
122
+ bytes: bytes.subarray(0, 36),
122
123
  };
123
124
 
124
- return [cid, bytes.subarray(4 + digestSize)];
125
+ return [cid, bytes.subarray(36)];
125
126
  };
126
127
 
128
+ /**
129
+ * decodes a CID from bytes, expecting no remainder
130
+ * @param bytes raw CID bytes
131
+ * @returns decoded CID
132
+ * @throws {RangeError} if the bytes are invalid or contain extra data
133
+ */
127
134
  export const decode = (bytes: Uint8Array): Cid => {
128
135
  const [cid, remainder] = decodeFirst(bytes);
129
136
 
@@ -134,15 +141,17 @@ export const decode = (bytes: Uint8Array): Cid => {
134
141
  return cid;
135
142
  };
136
143
 
144
+ /**
145
+ * parses a CID from a multibase base32 string
146
+ * @param input base32-encoded CID string (with 'b' prefix)
147
+ * @returns decoded CID
148
+ * @throws {SyntaxError} if the string is not a valid multibase base32 string
149
+ * @throws {RangeError} if the string length is invalid
150
+ */
137
151
  export const fromString = (input: string): Cid => {
138
- if (input.length < 2 || input[0] !== 'b') {
139
- throw new SyntaxError(`not a multibase base32 string`);
140
- }
141
-
142
- // 4 bytes in base32 = 7 characters + 1 character for the prefix
143
152
  // 36 bytes in base32 = 58 characters + 1 character for the prefix
144
- if (input.length !== 59 && input.length !== 8) {
145
- throw new RangeError(`cid too short`);
153
+ if (input.length !== 59 || input[0] !== 'b') {
154
+ throw new SyntaxError(`not a valid cid string`);
146
155
  }
147
156
 
148
157
  const bytes = fromBase32(input.slice(1));
@@ -152,6 +161,11 @@ export const fromString = (input: string): Cid => {
152
161
  return cid;
153
162
  };
154
163
 
164
+ /**
165
+ * encodes a CID to a multibase base32 string
166
+ * @param cid CID to encode
167
+ * @returns base32-encoded string with 'b' prefix
168
+ */
155
169
  export const toString = (cid: Cid): string => {
156
170
  let str = CID_STRINGIFY_CACHE.get(cid);
157
171
  if (str === undefined) {
@@ -163,21 +177,27 @@ export const toString = (cid: Cid): string => {
163
177
  return str;
164
178
  };
165
179
 
180
+ /**
181
+ * parses a CID from binary format (with 0x00 prefix)
182
+ * @param input binary CID bytes with 0x00 prefix
183
+ * @returns decoded CID
184
+ * @throws {RangeError} if the byte length is invalid
185
+ * @throws {SyntaxError} if the prefix byte is not 0x00
186
+ */
166
187
  export const fromBinary = (input: Uint8Array): Cid => {
167
- // 4 bytes + 1 byte for the 0x00 prefix
168
188
  // 36 bytes + 1 byte for the 0x00 prefix
169
- if (input.length !== 37 && input.length !== 5) {
170
- throw new RangeError(`cid bytes too short`);
189
+ if (input.length !== 37 || input[0] !== 0) {
190
+ throw new SyntaxError(`invalid binary cid`);
171
191
  }
172
192
 
173
- if (input[0] !== 0) {
174
- throw new SyntaxError(`incorrect binary cid`);
175
- }
176
-
177
- const bytes = input.subarray(1);
178
- return decode(bytes);
193
+ return decode(input.subarray(1));
179
194
  };
180
195
 
196
+ /**
197
+ * encodes a CID to binary format (with 0x00 prefix)
198
+ * @param cid CID to encode
199
+ * @returns binary CID bytes with 0x00 prefix
200
+ */
181
201
  export const toBinary = (cid: Cid): Uint8Array => {
182
202
  const bytes = allocUnsafe(1 + cid.bytes.length);
183
203
  bytes[0] = 0;
@@ -186,6 +206,12 @@ export const toBinary = (cid: Cid): Uint8Array => {
186
206
  return bytes;
187
207
  };
188
208
 
209
+ /**
210
+ * checks if two CIDs are equal
211
+ * @param a first CID
212
+ * @param b second CID
213
+ * @returns true if the CIDs have identical bytes
214
+ */
189
215
  export const equals = (a: Cid, b: Cid): boolean => {
190
216
  return isBufferEqual(a.bytes, b.bytes);
191
217
  };
package/lib/index.ts CHANGED
@@ -1,2 +1,4 @@
1
+ // implements github:darobin/dasl.ing@cc66c35 (2025-10-20)
2
+
1
3
  export * from './cid-link.js';
2
4
  export * from './codec.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@atcute/cid",
4
- "version": "2.2.6",
4
+ "version": "2.4.0",
5
5
  "description": "lightweight DASL CID codec library for AT Protocol",
6
6
  "keywords": [
7
7
  "atproto",
@@ -13,6 +13,9 @@
13
13
  "url": "https://github.com/mary-ext/atcute",
14
14
  "directory": "packages/utilities/cid"
15
15
  },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
16
19
  "files": [
17
20
  "dist/",
18
21
  "lib/",
@@ -25,15 +28,16 @@
25
28
  },
26
29
  "sideEffects": false,
27
30
  "devDependencies": {
28
- "@types/bun": "^1.2.21"
31
+ "@vitest/coverage-v8": "^4.0.16",
32
+ "vitest": "^4.0.16"
29
33
  },
30
34
  "dependencies": {
31
35
  "@atcute/multibase": "^1.1.6",
32
- "@atcute/uint8array": "^1.0.5"
36
+ "@atcute/uint8array": "^1.0.6"
33
37
  },
34
38
  "scripts": {
35
- "build": "tsc --project tsconfig.build.json",
36
- "test": "bun test --coverage",
39
+ "build": "tsgo --project tsconfig.build.json",
40
+ "test": "vitest",
37
41
  "prepublish": "rm -rf dist; pnpm run build"
38
42
  }
39
43
  }