@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 +17 -0
- package/README.md +14 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -0
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
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|