@atcute/cid 1.0.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/LICENSE ADDED
@@ -0,0 +1,17 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining a copy
2
+ of this software and associated documentation files (the "Software"), to deal
3
+ in the Software without restriction, including without limitation the rights
4
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5
+ copies of the Software, and to permit persons to whom the Software is
6
+ furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all
9
+ copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # @atcute/cid
2
+
3
+ create and parse AT Protocol-blessed CIDv1 format
4
+
5
+ ```ts
6
+ const parsed = parse('bafyreihffx5a2e7k5uwrmmgofbvzujc5cmw5h4espouwuxt3liqoflx3ee');
7
+ // ^? { version: 1, code: 113, digest: { ... }, bytes: Uint8Array(36) }
8
+
9
+ // Creating a CID containing CBOR data
10
+ const cid = await create(0x71, buffer);
11
+
12
+ // Serializing CID into string
13
+ format(cid); // -> bafyrei...
14
+ ```
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @module
3
+ * Bare minimum implementation for creating, parsing, and formatting
4
+ * AT Protocol-blessed CIDv1 format.
5
+ *
6
+ * As specified by AT Protocol, the blessed format is:
7
+ * - Multibase: `base32` (b)
8
+ * - Multicodec: `dag-cbor` (0x71) for record, `raw` (0x55) for blobs
9
+ * - Multihash: `sha-256` (0x12)
10
+ */
11
+ /**
12
+ * Raw digest information
13
+ */
14
+ export interface Digest {
15
+ code: number;
16
+ size: number;
17
+ digest: Uint8Array;
18
+ bytes: Uint8Array;
19
+ }
20
+ /**
21
+ * CID information
22
+ */
23
+ export interface CID {
24
+ version: number;
25
+ code: number;
26
+ digest: Digest;
27
+ bytes: Uint8Array;
28
+ }
29
+ /**
30
+ * Information regarding CID buffer being inspected
31
+ */
32
+ export interface InspectedCID {
33
+ version: number;
34
+ codec: number;
35
+ multihashCode: number;
36
+ digestSize: number;
37
+ multihashSize: number;
38
+ size: number;
39
+ }
40
+ /**
41
+ * Parse a CID string
42
+ */
43
+ export declare const parse: (cid: string) => CID;
44
+ /**
45
+ * Provides information regarding the CID buffer
46
+ */
47
+ export declare const inspect: (initialBytes: Uint8Array) => InspectedCID;
48
+ /**
49
+ * Decode the first CID contained, and return the remainder.
50
+ * @param bytes Buffer to decode
51
+ * @returns A tuple containing the first CID in the buffer, and the remainder
52
+ */
53
+ export declare const decodeFirst: (bytes: Uint8Array) => [cid: CID, remainder: Uint8Array];
54
+ /**
55
+ * Decodes a CID buffer
56
+ */
57
+ export declare const decode: (bytes: Uint8Array) => CID;
58
+ /**
59
+ * Creates a CID
60
+ */
61
+ export declare const create: (code: number, input: Uint8Array) => Promise<CID>;
62
+ /**
63
+ * Serialize CID into a string
64
+ */
65
+ export declare const format: (cid: CID) => string;
package/dist/index.js ADDED
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @module
3
+ * Bare minimum implementation for creating, parsing, and formatting
4
+ * AT Protocol-blessed CIDv1 format.
5
+ *
6
+ * As specified by AT Protocol, the blessed format is:
7
+ * - Multibase: `base32` (b)
8
+ * - Multicodec: `dag-cbor` (0x71) for record, `raw` (0x55) for blobs
9
+ * - Multihash: `sha-256` (0x12)
10
+ */
11
+ import * as base32 from '@atcute/base32';
12
+ import * as varint from '@atcute/varint';
13
+ /**
14
+ * Parse a CID string
15
+ */
16
+ export const parse = (cid) => {
17
+ if (cid[0] !== 'b') {
18
+ throw new Error(`only base32 cidv1 is supported`);
19
+ }
20
+ const bytes = base32.decode(cid.slice(1));
21
+ return decode(bytes);
22
+ };
23
+ /**
24
+ * Provides information regarding the CID buffer
25
+ */
26
+ export const inspect = (initialBytes) => {
27
+ let offset = 0;
28
+ const next = () => {
29
+ const [i, length] = varint.decode(initialBytes.subarray(offset));
30
+ offset += length;
31
+ return i;
32
+ };
33
+ let version = next();
34
+ let codec = 0x70; // dag-pb
35
+ if (version === 18) {
36
+ // CIDv0
37
+ version = 0;
38
+ offset = 0;
39
+ }
40
+ else {
41
+ codec = next();
42
+ }
43
+ if (version !== 1) {
44
+ throw new RangeError(`only cidv1 is supported`);
45
+ }
46
+ const prefixSize = offset;
47
+ const multihashCode = next();
48
+ const digestSize = next();
49
+ const size = offset + digestSize;
50
+ const multihashSize = size - prefixSize;
51
+ return { version, codec, multihashCode, digestSize, multihashSize, size };
52
+ };
53
+ /**
54
+ * Decode the first CID contained, and return the remainder.
55
+ * @param bytes Buffer to decode
56
+ * @returns A tuple containing the first CID in the buffer, and the remainder
57
+ */
58
+ export const decodeFirst = (bytes) => {
59
+ const specs = inspect(bytes);
60
+ const prefixSize = specs.size - specs.multihashSize;
61
+ const multihashBytes = bytes.subarray(prefixSize, prefixSize + specs.multihashSize);
62
+ if (multihashBytes.byteLength !== specs.multihashSize) {
63
+ throw new RangeError('incorrect cid length');
64
+ }
65
+ const digestBytes = multihashBytes.subarray(specs.multihashSize - specs.digestSize);
66
+ const digest = {
67
+ code: specs.multihashCode,
68
+ size: specs.multihashSize,
69
+ digest: digestBytes,
70
+ bytes: multihashBytes,
71
+ };
72
+ const cid = {
73
+ version: 1,
74
+ code: specs.codec,
75
+ digest: digest,
76
+ bytes: encodeCID(1, specs.codec, digest.bytes),
77
+ };
78
+ return [cid, bytes.subarray(specs.size)];
79
+ };
80
+ /**
81
+ * Decodes a CID buffer
82
+ */
83
+ export const decode = (bytes) => {
84
+ const [cid, remainder] = decodeFirst(bytes);
85
+ if (remainder.length !== 0) {
86
+ throw new Error(`incorrect cid length`);
87
+ }
88
+ return cid;
89
+ };
90
+ /**
91
+ * Creates a CID
92
+ */
93
+ export const create = async (code, input) => {
94
+ const digest = createDigest(0x12, new Uint8Array(await crypto.subtle.digest('sha-256', input)));
95
+ const bytes = encodeCID(1, code, digest.bytes);
96
+ return {
97
+ version: 1,
98
+ code: code,
99
+ digest: digest,
100
+ bytes: bytes,
101
+ };
102
+ };
103
+ /**
104
+ * Serialize CID into a string
105
+ */
106
+ export const format = (cid) => {
107
+ return 'b' + base32.encode(cid.bytes);
108
+ };
109
+ const createDigest = (code, digest) => {
110
+ const size = digest.byteLength;
111
+ const sizeOffset = varint.encodingLength(code);
112
+ const digestOffset = sizeOffset + varint.encodingLength(size);
113
+ const bytes = new Uint8Array(digestOffset + size);
114
+ varint.encode(code, bytes, 0);
115
+ varint.encode(size, bytes, sizeOffset);
116
+ bytes.set(digest, digestOffset);
117
+ return {
118
+ code: code,
119
+ size: size,
120
+ digest: digest,
121
+ bytes: bytes,
122
+ };
123
+ };
124
+ const encodeCID = (version, code, multihash) => {
125
+ const codeOffset = varint.encodingLength(version);
126
+ const hashOffset = codeOffset + varint.encodingLength(code);
127
+ const bytes = new Uint8Array(hashOffset + multihash.byteLength);
128
+ varint.encode(version, bytes, 0);
129
+ varint.encode(code, bytes, codeOffset);
130
+ bytes.set(multihash, hashOffset);
131
+ return bytes;
132
+ };
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "type": "module",
3
+ "name": "@atcute/cid",
4
+ "version": "1.0.0",
5
+ "description": "create and parse AT Protocol-blessed CIDv1 format",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "url": "https://codeberg.org/mary-ext/atcute"
9
+ },
10
+ "files": [
11
+ "dist/"
12
+ ],
13
+ "exports": {
14
+ ".": "./dist/index.js"
15
+ },
16
+ "sideEffects": false,
17
+ "devDependencies": {
18
+ "@types/bun": "^1.1.6"
19
+ },
20
+ "dependencies": {
21
+ "@atcute/base32": "^1.0.0",
22
+ "@atcute/varint": "^1.0.0"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc --project tsconfig.build.json",
26
+ "test": "bun test --coverage",
27
+ "prepublish": "rm -rf dist; pnpm run build"
28
+ }
29
+ }