@atcute/cid 2.0.1 → 2.2.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/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,19 +1,36 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
- import * as varint from '@atcute/varint';
2
+ import { allocUnsafe, toSha256 } from '@atcute/uint8array';
3
3
  export const CID_VERSION = 1;
4
4
  export const HASH_SHA256 = 0x12;
5
5
  export const CODEC_RAW = 0x55;
6
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.
7
9
  export const create = async (codec, data) => {
8
- const digest = new Uint8Array(await crypto.subtle.digest('sha-256', data));
9
- const digestSize = digest.length;
10
- const digestLebSize = varint.encodingLength(digestSize);
11
- const bytes = new Uint8Array(3 + digestLebSize + digestSize);
10
+ const digest = await toSha256(data);
11
+ if (digest.length !== 32) {
12
+ throw new RangeError(`invalid digest length`);
13
+ }
14
+ const bytes = allocUnsafe(4 + 32);
12
15
  bytes[0] = CID_VERSION;
13
16
  bytes[1] = codec;
14
17
  bytes[2] = HASH_SHA256;
15
- varint.encode(digestSize, bytes, 3);
16
- 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);
17
34
  const cid = {
18
35
  version: CID_VERSION,
19
36
  codec: codec,
@@ -27,37 +44,38 @@ export const create = async (codec, data) => {
27
44
  };
28
45
  export const decodeFirst = (bytes) => {
29
46
  const length = bytes.length;
30
- if (length < 5) {
47
+ if (length < 4) {
31
48
  throw new RangeError(`cid too short`);
32
49
  }
33
50
  const version = bytes[0];
34
51
  const codec = bytes[1];
35
- const digestCodec = bytes[2];
52
+ const digestType = bytes[2];
53
+ const digestSize = bytes[3];
36
54
  if (version !== CID_VERSION) {
37
55
  throw new RangeError(`incorrect cid version (got v${version})`);
38
56
  }
39
57
  if (codec !== CODEC_DCBOR && codec !== CODEC_RAW) {
40
58
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
41
59
  }
42
- if (digestCodec !== HASH_SHA256) {
43
- 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)})`);
44
62
  }
45
- const [digestSize, digestLebSize] = varint.decode(bytes, 3);
46
- const digestOffset = 3 + digestLebSize;
47
- if (length - digestOffset < digestSize) {
48
- 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`);
49
68
  }
50
- const remainder = bytes.subarray(digestOffset + digestSize);
51
69
  const cid = {
52
70
  version: CID_VERSION,
53
71
  codec: codec,
54
72
  digest: {
55
- codec: digestCodec,
56
- contents: bytes.subarray(digestOffset, digestOffset + digestSize),
73
+ codec: digestType,
74
+ contents: bytes.subarray(4, 4 + digestSize),
57
75
  },
58
- bytes: bytes.subarray(0, digestOffset + digestSize),
76
+ bytes: bytes.subarray(0, 4 + digestSize),
59
77
  };
60
- return [cid, remainder];
78
+ return [cid, bytes.subarray(4 + digestSize)];
61
79
  };
62
80
  export const decode = (bytes) => {
63
81
  const [cid, remainder] = decodeFirst(bytes);
@@ -70,6 +88,11 @@ export const fromString = (input) => {
70
88
  if (input.length < 2 || input[0] !== 'b') {
71
89
  throw new SyntaxError(`not a multibase base32 string`);
72
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
+ }
73
96
  const bytes = fromBase32(input.slice(1));
74
97
  return decode(bytes);
75
98
  };
@@ -78,7 +101,9 @@ export const toString = (cid) => {
78
101
  return `b${encoded}`;
79
102
  };
80
103
  export const fromBinary = (input) => {
81
- 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) {
82
107
  throw new RangeError(`cid bytes too short`);
83
108
  }
84
109
  if (input[0] !== 0) {
@@ -88,7 +113,8 @@ export const fromBinary = (input) => {
88
113
  return decode(bytes);
89
114
  };
90
115
  export const toBinary = (cid) => {
91
- const bytes = new Uint8Array(1 + cid.bytes.length);
116
+ const bytes = allocUnsafe(1 + cid.bytes.length);
117
+ bytes[0] = 0;
92
118
  bytes.set(cid.bytes, 1);
93
119
  return bytes;
94
120
  };
package/dist/codec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"codec.js","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../lib/codec.ts"],"names":[],"mappings":"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"}
package/lib/codec.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { fromBase32, toBase32 } from '@atcute/multibase';
2
- import * as varint from '@atcute/varint';
2
+ import { allocUnsafe, toSha256 } from '@atcute/uint8array';
3
3
 
4
4
  export const CID_VERSION = 1;
5
5
  export const HASH_SHA256 = 0x12;
@@ -28,20 +28,40 @@ export interface Cid {
28
28
  bytes: Uint8Array;
29
29
  }
30
30
 
31
- export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid> => {
32
- const digest = new Uint8Array(await crypto.subtle.digest('sha-256', data));
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
33
 
34
- const digestSize = digest.length;
35
- const digestLebSize = varint.encodingLength(digestSize);
34
+ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid> => {
35
+ const digest = await toSha256(data);
36
+ if (digest.length !== 32) {
37
+ throw new RangeError(`invalid digest length`);
38
+ }
36
39
 
37
- const bytes = new Uint8Array(3 + digestLebSize + digestSize);
40
+ const bytes = allocUnsafe(4 + 32);
38
41
 
39
42
  bytes[0] = CID_VERSION;
40
43
  bytes[1] = codec;
41
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
+ };
42
61
 
43
- varint.encode(digestSize, bytes, 3);
44
- 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);
45
65
 
46
66
  const cid: Cid = {
47
67
  version: CID_VERSION,
@@ -59,13 +79,14 @@ export const create = async (codec: 0x55 | 0x71, data: Uint8Array): Promise<Cid>
59
79
  export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8Array] => {
60
80
  const length = bytes.length;
61
81
 
62
- if (length < 5) {
82
+ if (length < 4) {
63
83
  throw new RangeError(`cid too short`);
64
84
  }
65
85
 
66
86
  const version = bytes[0];
67
87
  const codec = bytes[1];
68
- const digestCodec = bytes[2];
88
+ const digestType = bytes[2];
89
+ const digestSize = bytes[3];
69
90
 
70
91
  if (version !== CID_VERSION) {
71
92
  throw new RangeError(`incorrect cid version (got v${version})`);
@@ -75,30 +96,29 @@ export const decodeFirst = (bytes: Uint8Array): [decoded: Cid, remainder: Uint8A
75
96
  throw new RangeError(`incorrect cid codec (got 0x${codec.toString(16)})`);
76
97
  }
77
98
 
78
- if (digestCodec !== HASH_SHA256) {
79
- 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)})`);
80
101
  }
81
102
 
82
- const [digestSize, digestLebSize] = varint.decode(bytes, 3);
83
- const digestOffset = 3 + digestLebSize;
84
-
85
- if (length - digestOffset < digestSize) {
86
- 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})`);
87
105
  }
88
106
 
89
- const remainder = bytes.subarray(digestOffset + digestSize);
107
+ if (length < 4 + digestSize) {
108
+ throw new RangeError(`cid too short`);
109
+ }
90
110
 
91
111
  const cid: Cid = {
92
112
  version: CID_VERSION,
93
113
  codec: codec,
94
114
  digest: {
95
- codec: digestCodec,
96
- contents: bytes.subarray(digestOffset, digestOffset + digestSize),
115
+ codec: digestType,
116
+ contents: bytes.subarray(4, 4 + digestSize),
97
117
  },
98
- bytes: bytes.subarray(0, digestOffset + digestSize),
118
+ bytes: bytes.subarray(0, 4 + digestSize),
99
119
  };
100
120
 
101
- return [cid, remainder];
121
+ return [cid, bytes.subarray(4 + digestSize)];
102
122
  };
103
123
 
104
124
  export const decode = (bytes: Uint8Array): Cid => {
@@ -116,6 +136,12 @@ export const fromString = (input: string): Cid => {
116
136
  throw new SyntaxError(`not a multibase base32 string`);
117
137
  }
118
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
+
119
145
  const bytes = fromBase32(input.slice(1));
120
146
  return decode(bytes);
121
147
  };
@@ -126,7 +152,9 @@ export const toString = (cid: Cid): string => {
126
152
  };
127
153
 
128
154
  export const fromBinary = (input: Uint8Array): Cid => {
129
- 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) {
130
158
  throw new RangeError(`cid bytes too short`);
131
159
  }
132
160
 
@@ -139,7 +167,8 @@ export const fromBinary = (input: Uint8Array): Cid => {
139
167
  };
140
168
 
141
169
  export const toBinary = (cid: Cid): Uint8Array => {
142
- const bytes = new Uint8Array(1 + cid.bytes.length);
170
+ const bytes = allocUnsafe(1 + cid.bytes.length);
171
+ bytes[0] = 0;
143
172
  bytes.set(cid.bytes, 1);
144
173
 
145
174
  return bytes;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@atcute/cid",
4
- "version": "2.0.1",
4
+ "version": "2.2.0",
5
5
  "description": "lightweight DASL CID codec library for AT Protocol",
6
6
  "keywords": [
7
7
  "atproto",
@@ -20,15 +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/multibase": "^1.0.1",
31
- "@atcute/varint": "^1.0.2"
31
+ "@atcute/multibase": "^1.1.2",
32
+ "@atcute/uint8array": "^1.0.1"
32
33
  },
33
34
  "scripts": {
34
35
  "build": "tsc --project tsconfig.build.json",