@atcute/cid 2.1.0 → 2.2.1

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/dist/codec.d.ts CHANGED
@@ -23,6 +23,7 @@ export interface Cid {
23
23
  bytes: Uint8Array;
24
24
  }
25
25
  export declare const create: (codec: 85 | 113, data: Uint8Array) => Promise<Cid>;
26
+ export declare const createEmpty: (codec: 85 | 113) => Cid;
26
27
  export declare const decodeFirst: (bytes: Uint8Array) => [decoded: Cid, remainder: Uint8Array];
27
28
  export declare const decode: (bytes: Uint8Array) => Cid;
28
29
  export declare const fromString: (input: string) => Cid;
package/dist/codec.js CHANGED
@@ -1,20 +1,36 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
2
  import { allocUnsafe, toSha256 } from '@atcute/uint8array';
3
- import * as varint from '@atcute/varint';
4
3
  export const CID_VERSION = 1;
5
4
  export const HASH_SHA256 = 0x12;
6
5
  export const CODEC_RAW = 0x55;
7
6
  export const CODEC_DCBOR = 0x71;
7
+ // a SHA-256 CIDv1 is always going to be 36 bytes, that's 4 bytes for the
8
+ // header, and 32 bytes for the digest itself.
8
9
  export const create = async (codec, data) => {
9
10
  const digest = await toSha256(data);
10
- const digestSize = digest.length;
11
- const digestLebSize = varint.encodingLength(digestSize);
12
- const bytes = allocUnsafe(3 + digestLebSize + digestSize);
11
+ if (digest.length !== 32) {
12
+ throw new RangeError(`invalid digest length`);
13
+ }
14
+ const bytes = allocUnsafe(4 + 32);
13
15
  bytes[0] = CID_VERSION;
14
16
  bytes[1] = codec;
15
17
  bytes[2] = HASH_SHA256;
16
- varint.encode(digestSize, bytes, 3);
17
- bytes.set(digest, 3 + digestLebSize);
18
+ bytes[3] = 32;
19
+ bytes.set(digest, 4);
20
+ const cid = {
21
+ version: CID_VERSION,
22
+ codec: codec,
23
+ digest: {
24
+ codec: HASH_SHA256,
25
+ contents: bytes.subarray(4, 36),
26
+ },
27
+ bytes: bytes,
28
+ };
29
+ return cid;
30
+ };
31
+ export const createEmpty = (codec) => {
32
+ const bytes = Uint8Array.from([CID_VERSION, codec, HASH_SHA256, 0]);
33
+ const digest = bytes.subarray(4);
18
34
  const cid = {
19
35
  version: CID_VERSION,
20
36
  codec: codec,
@@ -28,37 +44,38 @@ export const create = async (codec, data) => {
28
44
  };
29
45
  export const decodeFirst = (bytes) => {
30
46
  const length = bytes.length;
31
- if (length < 5) {
47
+ if (length < 4) {
32
48
  throw new RangeError(`cid too short`);
33
49
  }
34
50
  const version = bytes[0];
35
51
  const codec = bytes[1];
36
- const digestCodec = bytes[2];
52
+ const digestType = bytes[2];
53
+ const digestSize = bytes[3];
37
54
  if (version !== CID_VERSION) {
38
55
  throw new RangeError(`incorrect cid version (got v${version})`);
39
56
  }
40
57
  if (codec !== CODEC_DCBOR && codec !== CODEC_RAW) {
41
58
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
42
59
  }
43
- if (digestCodec !== HASH_SHA256) {
44
- throw new RangeError(`incorrect cid hash type (got 0x${digestCodec.toString(16)})`);
60
+ if (digestType !== HASH_SHA256) {
61
+ throw new RangeError(`incorrect cid digest codec (got 0x${digestType.toString(16)})`);
45
62
  }
46
- const [digestSize, digestLebSize] = varint.decode(bytes, 3);
47
- const digestOffset = 3 + digestLebSize;
48
- if (length - digestOffset < digestSize) {
49
- throw new RangeError(`digest too short (expected ${digestSize} bytes; got ${length - digestOffset})`);
63
+ if (digestSize !== 32 && digestSize !== 0) {
64
+ throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
65
+ }
66
+ if (length < 4 + digestSize) {
67
+ throw new RangeError(`cid too short`);
50
68
  }
51
- const remainder = bytes.subarray(digestOffset + digestSize);
52
69
  const cid = {
53
70
  version: CID_VERSION,
54
71
  codec: codec,
55
72
  digest: {
56
- codec: digestCodec,
57
- contents: bytes.subarray(digestOffset, digestOffset + digestSize),
73
+ codec: digestType,
74
+ contents: bytes.subarray(4, 4 + digestSize),
58
75
  },
59
- bytes: bytes.subarray(0, digestOffset + digestSize),
76
+ bytes: bytes.subarray(0, 4 + digestSize),
60
77
  };
61
- return [cid, remainder];
78
+ return [cid, bytes.subarray(4 + digestSize)];
62
79
  };
63
80
  export const decode = (bytes) => {
64
81
  const [cid, remainder] = decodeFirst(bytes);
@@ -71,6 +88,11 @@ export const fromString = (input) => {
71
88
  if (input.length < 2 || input[0] !== 'b') {
72
89
  throw new SyntaxError(`not a multibase base32 string`);
73
90
  }
91
+ // 4 bytes in base32 = 7 characters + 1 character for the prefix
92
+ // 36 bytes in base32 = 58 characters + 1 character for the prefix
93
+ if (input.length !== 59 && input.length !== 8) {
94
+ throw new RangeError(`cid too short`);
95
+ }
74
96
  const bytes = fromBase32(input.slice(1));
75
97
  return decode(bytes);
76
98
  };
@@ -79,7 +101,9 @@ export const toString = (cid) => {
79
101
  return `b${encoded}`;
80
102
  };
81
103
  export const fromBinary = (input) => {
82
- if (input.length < 2) {
104
+ // 4 bytes + 1 byte for the 0x00 prefix
105
+ // 36 bytes + 1 byte for the 0x00 prefix
106
+ if (input.length !== 37 && input.length !== 5) {
83
107
  throw new RangeError(`cid bytes too short`);
84
108
  }
85
109
  if (input[0] !== 0) {
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,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAEzC,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;AAuBhC,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,KAAkB,EAAE,IAAgB,EAAgB,EAAE;IAClF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEpC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAExD,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC;IAE1D,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IACvB,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACjB,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;IAEvB,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC;IAErC,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,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAE7B,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,WAAW,KAAK,WAAW,EAAE,CAAC;QACjC,MAAM,IAAI,UAAU,CAAC,kCAAkC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,CAAC,GAAG,aAAa,CAAC;IAEvC,IAAI,MAAM,GAAG,YAAY,GAAG,UAAU,EAAE,CAAC;QACxC,MAAM,IAAI,UAAU,CAAC,8BAA8B,UAAU,eAAe,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC;IACvG,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;IAE5D,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,YAAY,EAAE,YAAY,GAAG,UAAU,CAAC;SACjE;QACD,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;KACnD,CAAC;IAEF,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACzB,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,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAU,EAAE;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,IAAI,OAAO,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAiB,EAAO,EAAE;IACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,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"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"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"}
package/lib/codec.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
2
  import { allocUnsafe, toSha256 } from '@atcute/uint8array';
3
- import * as varint from '@atcute/varint';
4
3
 
5
4
  export const CID_VERSION = 1;
6
5
  export const HASH_SHA256 = 0x12;
@@ -29,20 +28,40 @@ export interface Cid {
29
28
  bytes: Uint8Array;
30
29
  }
31
30
 
31
+ // a SHA-256 CIDv1 is always going to be 36 bytes, that's 4 bytes for the
32
+ // header, and 32 bytes for the digest itself.
33
+
32
34
  export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid> => {
33
35
  const digest = await toSha256(data);
36
+ if (digest.length !== 32) {
37
+ throw new RangeError(`invalid digest length`);
38
+ }
34
39
 
35
- const digestSize = digest.length;
36
- const digestLebSize = varint.encodingLength(digestSize);
37
-
38
- const bytes = allocUnsafe(3 + digestLebSize + digestSize);
40
+ const bytes = allocUnsafe(4 + 32);
39
41
 
40
42
  bytes[0] = CID_VERSION;
41
43
  bytes[1] = codec;
42
44
  bytes[2] = HASH_SHA256;
45
+ bytes[3] = 32;
46
+
47
+ bytes.set(digest, 4);
48
+
49
+ const cid: Cid = {
50
+ version: CID_VERSION,
51
+ codec: codec,
52
+ digest: {
53
+ codec: HASH_SHA256,
54
+ contents: bytes.subarray(4, 36),
55
+ },
56
+ bytes: bytes,
57
+ };
58
+
59
+ return cid;
60
+ };
43
61
 
44
- varint.encode(digestSize, bytes, 3);
45
- bytes.set(digest, 3 + digestLebSize);
62
+ export const createEmpty = (codec: 0x55 | 0x71): Cid => {
63
+ const bytes = Uint8Array.from([CID_VERSION, codec, HASH_SHA256, 0]);
64
+ const digest = bytes.subarray(4);
46
65
 
47
66
  const cid: Cid = {
48
67
  version: CID_VERSION,
@@ -60,13 +79,14 @@ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid>
60
79
  export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8Array] => {
61
80
  const length = bytes.length;
62
81
 
63
- if (length < 5) {
82
+ if (length < 4) {
64
83
  throw new RangeError(`cid too short`);
65
84
  }
66
85
 
67
86
  const version = bytes[0];
68
87
  const codec = bytes[1];
69
- const digestCodec = bytes[2];
88
+ const digestType = bytes[2];
89
+ const digestSize = bytes[3];
70
90
 
71
91
  if (version !== CID_VERSION) {
72
92
  throw new RangeError(`incorrect cid version (got v${version})`);
@@ -76,30 +96,29 @@ export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8A
76
96
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
77
97
  }
78
98
 
79
- if (digestCodec !== HASH_SHA256) {
80
- throw new RangeError(`incorrect cid hash type (got 0x${digestCodec.toString(16)})`);
99
+ if (digestType !== HASH_SHA256) {
100
+ throw new RangeError(`incorrect cid digest codec (got 0x${digestType.toString(16)})`);
81
101
  }
82
102
 
83
- const [digestSize, digestLebSize] = varint.decode(bytes, 3);
84
- const digestOffset = 3 + digestLebSize;
85
-
86
- if (length - digestOffset < digestSize) {
87
- throw new RangeError(`digest too short (expected ${digestSize} bytes; got ${length - digestOffset})`);
103
+ if (digestSize !== 32 && digestSize !== 0) {
104
+ throw new RangeError(`incorrect cid digest size (got ${digestSize})`);
88
105
  }
89
106
 
90
- const remainder = bytes.subarray(digestOffset + digestSize);
107
+ if (length < 4 + digestSize) {
108
+ throw new RangeError(`cid too short`);
109
+ }
91
110
 
92
111
  const cid: Cid = {
93
112
  version: CID_VERSION,
94
113
  codec: codec,
95
114
  digest: {
96
- codec: digestCodec,
97
- contents: bytes.subarray(digestOffset, digestOffset + digestSize),
115
+ codec: digestType,
116
+ contents: bytes.subarray(4, 4 + digestSize),
98
117
  },
99
- bytes: bytes.subarray(0, digestOffset + digestSize),
118
+ bytes: bytes.subarray(0, 4 + digestSize),
100
119
  };
101
120
 
102
- return [cid, remainder];
121
+ return [cid, bytes.subarray(4 + digestSize)];
103
122
  };
104
123
 
105
124
  export const decode = (bytes: Uint8Array): Cid => {
@@ -117,6 +136,12 @@ export const fromString = (input: string): Cid => {
117
136
  throw new SyntaxError(`not a multibase base32 string`);
118
137
  }
119
138
 
139
+ // 4 bytes in base32 = 7 characters + 1 character for the prefix
140
+ // 36 bytes in base32 = 58 characters + 1 character for the prefix
141
+ if (input.length !== 59 && input.length !== 8) {
142
+ throw new RangeError(`cid too short`);
143
+ }
144
+
120
145
  const bytes = fromBase32(input.slice(1));
121
146
  return decode(bytes);
122
147
  };
@@ -127,7 +152,9 @@ export const toString = (cid: Cid): string => {
127
152
  };
128
153
 
129
154
  export const fromBinary = (input: Uint8Array): Cid => {
130
- if (input.length < 2) {
155
+ // 4 bytes + 1 byte for the 0x00 prefix
156
+ // 36 bytes + 1 byte for the 0x00 prefix
157
+ if (input.length !== 37 && input.length !== 5) {
131
158
  throw new RangeError(`cid bytes too short`);
132
159
  }
133
160
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@atcute/cid",
4
- "version": "2.1.0",
4
+ "version": "2.2.1",
5
5
  "description": "lightweight DASL CID codec library for AT Protocol",
6
6
  "keywords": [
7
7
  "atproto",
@@ -20,16 +20,16 @@
20
20
  "!lib/**/*.test.ts"
21
21
  ],
22
22
  "exports": {
23
- ".": "./dist/index.js"
23
+ ".": "./dist/index.js",
24
+ "./cid-link": "./dist/cid-link.js"
24
25
  },
25
26
  "sideEffects": false,
26
27
  "devDependencies": {
27
- "@types/bun": "^1.1.14"
28
+ "@types/bun": "^1.2.1"
28
29
  },
29
30
  "dependencies": {
30
- "@atcute/uint8array": "^1.0.0",
31
- "@atcute/varint": "^1.0.2",
32
- "@atcute/multibase": "^1.1.0"
31
+ "@atcute/multibase": "^1.1.3",
32
+ "@atcute/uint8array": "^1.0.1"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "tsc --project tsconfig.build.json",