@atproto/common 0.2.0 → 0.3.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/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/README.md +9 -2
- package/build.js +0 -8
- package/dist/buffers.d.ts +3 -0
- package/dist/dates.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +10382 -681
- package/dist/index.js.map +4 -4
- package/dist/ipld.d.ts +18 -0
- package/dist/streams.d.ts +2 -0
- package/package.json +24 -20
- package/src/buffers.ts +10 -0
- package/src/dates.ts +16 -0
- package/src/fs.ts +2 -1
- package/src/index.ts +2 -0
- package/src/ipld.ts +46 -0
- package/src/streams.ts +14 -0
- package/tests/ipld-vectors.ts +279 -0
- package/tests/ipld.test.ts +24 -84
- package/tests/streams.test.ts +136 -0
- package/tsconfig.build.json +1 -1
- package/tsconfig.json +3 -5
- package/dist/async.d.ts +0 -24
- package/dist/blocks.d.ts +0 -8
- package/dist/check.d.ts +0 -18
- package/dist/strings.d.ts +0 -2
- package/dist/tid.d.ts +0 -20
- package/dist/times.d.ts +0 -4
- package/dist/types.d.ts +0 -19
- package/dist/util.d.ts +0 -15
- package/tsconfig.build.tsbuildinfo +0 -1
- package/update-pkg.js +0 -14
package/dist/ipld.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
import { Transform, TransformCallback } from 'stream';
|
|
1
6
|
import { CID } from 'multiformats/cid';
|
|
2
7
|
import * as Block from 'multiformats/block';
|
|
3
8
|
import * as cborCodec from '@ipld/dag-cbor';
|
|
@@ -5,7 +10,20 @@ export declare const cborEncode: typeof cborCodec.encode;
|
|
|
5
10
|
export declare const cborDecode: typeof cborCodec.decode;
|
|
6
11
|
export declare const dataToCborBlock: (data: unknown) => Promise<Block.Block<unknown>>;
|
|
7
12
|
export declare const cidForCbor: (data: unknown) => Promise<CID>;
|
|
13
|
+
export declare const isValidCid: (cidStr: string) => Promise<boolean>;
|
|
8
14
|
export declare const cborBytesToRecord: (bytes: Uint8Array) => Record<string, unknown>;
|
|
9
15
|
export declare const verifyCidForBytes: (cid: CID, bytes: Uint8Array) => Promise<void>;
|
|
10
16
|
export declare const sha256ToCid: (hash: Uint8Array, codec: number) => CID;
|
|
11
17
|
export declare const sha256RawToCid: (hash: Uint8Array) => CID;
|
|
18
|
+
export declare class VerifyCidTransform extends Transform {
|
|
19
|
+
cid: CID;
|
|
20
|
+
hasher: crypto.Hash;
|
|
21
|
+
constructor(cid: CID);
|
|
22
|
+
_transform(chunk: Uint8Array, _enc: BufferEncoding, cb: TransformCallback): void;
|
|
23
|
+
_flush(cb: TransformCallback): void;
|
|
24
|
+
}
|
|
25
|
+
export declare class VerifyCidError extends Error {
|
|
26
|
+
expected: CID;
|
|
27
|
+
actual: CID;
|
|
28
|
+
constructor(expected: CID, actual: CID);
|
|
29
|
+
}
|
package/dist/streams.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { Stream, Readable, Transform, TransformCallback } from 'stream';
|
|
|
4
4
|
export declare const forwardStreamErrors: (...streams: Stream[]) => void;
|
|
5
5
|
export declare const cloneStream: (stream: Readable) => Readable;
|
|
6
6
|
export declare const streamSize: (stream: Readable) => Promise<number>;
|
|
7
|
+
export declare const streamToBytes: (stream: Readable) => Promise<Uint8Array>;
|
|
8
|
+
export declare const byteIterableToStream: (iter: AsyncIterable<Uint8Array>) => Readable;
|
|
7
9
|
export declare const bytesToStream: (bytes: Uint8Array) => Readable;
|
|
8
10
|
export declare class MaxSizeChecker extends Transform {
|
|
9
11
|
maxSize: number;
|
package/package.json
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/common",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"main": "dist/index.js",
|
|
3
|
+
"version": "0.3.1",
|
|
5
4
|
"license": "MIT",
|
|
5
|
+
"description": "Shared web-platform-friendly code for atproto libraries",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"atproto"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://atproto.com",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/bluesky-social/atproto",
|
|
13
|
+
"directory": "packages/common"
|
|
14
|
+
},
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@ipld/dag-cbor": "^7.0.3",
|
|
18
|
+
"cbor-x": "^1.5.1",
|
|
19
|
+
"iso-datestring-validator": "^2.2.2",
|
|
20
|
+
"multiformats": "^9.9.0",
|
|
21
|
+
"pino": "^8.15.0",
|
|
22
|
+
"zod": "3.21.4",
|
|
23
|
+
"@atproto/common-web": "^0.2.1"
|
|
24
|
+
},
|
|
6
25
|
"scripts": {
|
|
7
26
|
"test": "jest",
|
|
8
|
-
"prettier": "prettier --check src/",
|
|
9
|
-
"prettier:fix": "prettier --write src/",
|
|
10
|
-
"lint": "eslint . --ext .ts,.tsx",
|
|
11
|
-
"lint:fix": "yarn lint --fix",
|
|
12
|
-
"verify": "run-p prettier lint",
|
|
13
|
-
"verify:fix": "yarn prettier:fix && yarn lint:fix",
|
|
14
27
|
"build": "node ./build.js",
|
|
15
28
|
"postbuild": "tsc --build tsconfig.build.json",
|
|
16
|
-
"update-main-to-dist": "node
|
|
17
|
-
"update-main-to-src": "node ./update-pkg.js --update-main-to-src",
|
|
18
|
-
"prepublish": "npm run update-main-to-dist",
|
|
19
|
-
"postpublish": "npm run update-main-to-src"
|
|
29
|
+
"update-main-to-dist": "node ../../update-main-to-dist.js packages/common"
|
|
20
30
|
},
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"@ipld/dag-cbor": "^7.0.3",
|
|
24
|
-
"cbor-x": "^1.5.1",
|
|
25
|
-
"multiformats": "^9.6.4",
|
|
26
|
-
"pino": "^8.6.1"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
31
|
+
"types": "dist/index.d.ts"
|
|
32
|
+
}
|
package/src/buffers.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function ui8ToBuffer(bytes: Uint8Array): Buffer {
|
|
2
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function ui8ToArrayBuffer(bytes: Uint8Array): ArrayBuffer {
|
|
6
|
+
return bytes.buffer.slice(
|
|
7
|
+
bytes.byteOffset,
|
|
8
|
+
bytes.byteLength + bytes.byteOffset,
|
|
9
|
+
)
|
|
10
|
+
}
|
package/src/dates.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { isValidISODateString } from 'iso-datestring-validator'
|
|
2
|
+
|
|
3
|
+
// Normalize date strings to simplified ISO so that the lexical sort preserves temporal sort.
|
|
4
|
+
// Rather than failing on an invalid date format, returns valid unix epoch.
|
|
5
|
+
export function toSimplifiedISOSafe(dateStr: string) {
|
|
6
|
+
const date = new Date(dateStr)
|
|
7
|
+
if (isNaN(date.getTime())) {
|
|
8
|
+
return new Date(0).toISOString()
|
|
9
|
+
}
|
|
10
|
+
const iso = date.toISOString()
|
|
11
|
+
if (!isValidISODateString(iso)) {
|
|
12
|
+
// Occurs in rare cases, e.g. where resulting UTC year is negative. These also don't preserve lexical sort.
|
|
13
|
+
return new Date(0).toISOString()
|
|
14
|
+
}
|
|
15
|
+
return iso // YYYY-MM-DDTHH:mm:ss.sssZ
|
|
16
|
+
}
|
package/src/fs.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { isErrnoException } from '@atproto/common-web'
|
|
2
|
+
import { constants } from 'fs'
|
|
2
3
|
import fs from 'fs/promises'
|
|
3
4
|
|
|
4
5
|
export const fileExists = async (location: string): Promise<boolean> => {
|
|
5
6
|
try {
|
|
6
|
-
await fs.access(location,
|
|
7
|
+
await fs.access(location, constants.F_OK)
|
|
7
8
|
return true
|
|
8
9
|
} catch (err) {
|
|
9
10
|
if (isErrnoException(err) && err.code === 'ENOENT') {
|
package/src/index.ts
CHANGED
package/src/ipld.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import { Transform, TransformCallback } from 'stream'
|
|
1
3
|
import { check, schema } from '@atproto/common-web'
|
|
2
4
|
import { CID } from 'multiformats/cid'
|
|
3
5
|
import * as Block from 'multiformats/block'
|
|
@@ -22,6 +24,15 @@ export const cidForCbor = async (data: unknown): Promise<CID> => {
|
|
|
22
24
|
return block.cid
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
export const isValidCid = async (cidStr: string): Promise<boolean> => {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = CID.parse(cidStr)
|
|
30
|
+
return parsed.toString() === cidStr
|
|
31
|
+
} catch (err) {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
export const cborBytesToRecord = (
|
|
26
37
|
bytes: Uint8Array,
|
|
27
38
|
): Record<string, unknown> => {
|
|
@@ -50,3 +61,38 @@ export const sha256ToCid = (hash: Uint8Array, codec: number): CID => {
|
|
|
50
61
|
export const sha256RawToCid = (hash: Uint8Array): CID => {
|
|
51
62
|
return sha256ToCid(hash, rawCodec.code)
|
|
52
63
|
}
|
|
64
|
+
|
|
65
|
+
export class VerifyCidTransform extends Transform {
|
|
66
|
+
hasher = crypto.createHash('sha256')
|
|
67
|
+
constructor(public cid: CID) {
|
|
68
|
+
super()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_transform(chunk: Uint8Array, _enc: BufferEncoding, cb: TransformCallback) {
|
|
72
|
+
this.hasher.update(chunk)
|
|
73
|
+
cb(null, chunk)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_flush(cb: TransformCallback) {
|
|
77
|
+
try {
|
|
78
|
+
const cid = sha256RawToCid(this.hasher.digest())
|
|
79
|
+
if (this.cid.equals(cid)) {
|
|
80
|
+
return cb()
|
|
81
|
+
} else {
|
|
82
|
+
return cb(new VerifyCidError(this.cid, cid))
|
|
83
|
+
}
|
|
84
|
+
} catch (_err) {
|
|
85
|
+
const err =
|
|
86
|
+
_err instanceof Error
|
|
87
|
+
? _err
|
|
88
|
+
: new Error('Unexpected error', { cause: _err })
|
|
89
|
+
return cb(err)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export class VerifyCidError extends Error {
|
|
95
|
+
constructor(public expected: CID, public actual: CID) {
|
|
96
|
+
super('Bad cid check')
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/streams.ts
CHANGED
|
@@ -30,6 +30,20 @@ export const streamSize = async (stream: Readable): Promise<number> => {
|
|
|
30
30
|
return size
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export const streamToBytes = async (stream: Readable): Promise<Uint8Array> => {
|
|
34
|
+
const bufs: Buffer[] = []
|
|
35
|
+
for await (const bytes of stream) {
|
|
36
|
+
bufs.push(bytes)
|
|
37
|
+
}
|
|
38
|
+
return new Uint8Array(Buffer.concat(bufs))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const byteIterableToStream = (
|
|
42
|
+
iter: AsyncIterable<Uint8Array>,
|
|
43
|
+
): Readable => {
|
|
44
|
+
return Readable.from(iter, { objectMode: false })
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
export const bytesToStream = (bytes: Uint8Array): Readable => {
|
|
34
48
|
const stream = new Readable()
|
|
35
49
|
stream.push(bytes)
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid'
|
|
2
|
+
|
|
3
|
+
export const vectors = [
|
|
4
|
+
{
|
|
5
|
+
name: 'basic',
|
|
6
|
+
json: {
|
|
7
|
+
string: 'abc',
|
|
8
|
+
unicode: 'a~öñ©⽘☎𓋓😀👨👩👧👧',
|
|
9
|
+
integer: 123,
|
|
10
|
+
bool: true,
|
|
11
|
+
null: null,
|
|
12
|
+
array: ['abc', 'def', 'ghi'],
|
|
13
|
+
object: {
|
|
14
|
+
string: 'abc',
|
|
15
|
+
number: 123,
|
|
16
|
+
bool: true,
|
|
17
|
+
arr: ['abc', 'def', 'ghi'],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
ipld: {
|
|
21
|
+
string: 'abc',
|
|
22
|
+
unicode: 'a~öñ©⽘☎𓋓😀👨👩👧👧',
|
|
23
|
+
integer: 123,
|
|
24
|
+
bool: true,
|
|
25
|
+
null: null,
|
|
26
|
+
array: ['abc', 'def', 'ghi'],
|
|
27
|
+
object: {
|
|
28
|
+
string: 'abc',
|
|
29
|
+
number: 123,
|
|
30
|
+
bool: true,
|
|
31
|
+
arr: ['abc', 'def', 'ghi'],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
cbor: new Uint8Array([
|
|
35
|
+
167, 100, 98, 111, 111, 108, 245, 100, 110, 117, 108, 108, 246, 101, 97,
|
|
36
|
+
114, 114, 97, 121, 131, 99, 97, 98, 99, 99, 100, 101, 102, 99, 103, 104,
|
|
37
|
+
105, 102, 111, 98, 106, 101, 99, 116, 164, 99, 97, 114, 114, 131, 99, 97,
|
|
38
|
+
98, 99, 99, 100, 101, 102, 99, 103, 104, 105, 100, 98, 111, 111, 108, 245,
|
|
39
|
+
102, 110, 117, 109, 98, 101, 114, 24, 123, 102, 115, 116, 114, 105, 110,
|
|
40
|
+
103, 99, 97, 98, 99, 102, 115, 116, 114, 105, 110, 103, 99, 97, 98, 99,
|
|
41
|
+
103, 105, 110, 116, 101, 103, 101, 114, 24, 123, 103, 117, 110, 105, 99,
|
|
42
|
+
111, 100, 101, 120, 47, 97, 126, 195, 182, 195, 177, 194, 169, 226, 189,
|
|
43
|
+
152, 226, 152, 142, 240, 147, 139, 147, 240, 159, 152, 128, 240, 159, 145,
|
|
44
|
+
168, 226, 128, 141, 240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 167,
|
|
45
|
+
226, 128, 141, 240, 159, 145, 167,
|
|
46
|
+
]),
|
|
47
|
+
cid: 'bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'ipld',
|
|
51
|
+
json: {
|
|
52
|
+
a: {
|
|
53
|
+
$link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
54
|
+
},
|
|
55
|
+
b: {
|
|
56
|
+
$bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
57
|
+
},
|
|
58
|
+
c: {
|
|
59
|
+
$type: 'blob',
|
|
60
|
+
ref: {
|
|
61
|
+
$link: 'bafkreiccldh766hwcnuxnf2wh6jgzepf2nlu2lvcllt63eww5p6chi4ity',
|
|
62
|
+
},
|
|
63
|
+
mimeType: 'image/jpeg',
|
|
64
|
+
size: 10000,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
ipld: {
|
|
68
|
+
a: CID.parse(
|
|
69
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
70
|
+
),
|
|
71
|
+
b: new Uint8Array([
|
|
72
|
+
156, 81, 17, 142, 242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253,
|
|
73
|
+
65, 60, 242, 11, 98, 238, 213, 118, 248, 157, 238, 190, 176, 26, 194,
|
|
74
|
+
204, 141,
|
|
75
|
+
]),
|
|
76
|
+
c: {
|
|
77
|
+
$type: 'blob',
|
|
78
|
+
ref: CID.parse(
|
|
79
|
+
'bafkreiccldh766hwcnuxnf2wh6jgzepf2nlu2lvcllt63eww5p6chi4ity',
|
|
80
|
+
),
|
|
81
|
+
mimeType: 'image/jpeg',
|
|
82
|
+
size: 10000,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
cbor: new Uint8Array([
|
|
86
|
+
163, 97, 97, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0,
|
|
87
|
+
252, 22, 215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72,
|
|
88
|
+
147, 54, 137, 29, 9, 23, 65, 162, 57, 208, 97, 98, 88, 32, 156, 81, 17,
|
|
89
|
+
142, 242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253, 65, 60, 242, 11,
|
|
90
|
+
98, 238, 213, 118, 248, 157, 238, 190, 176, 26, 194, 204, 141, 97, 99,
|
|
91
|
+
164, 99, 114, 101, 102, 216, 42, 88, 37, 0, 1, 85, 18, 32, 66, 88, 207,
|
|
92
|
+
255, 120, 246, 19, 105, 118, 151, 86, 63, 146, 108, 145, 229, 211, 87, 77,
|
|
93
|
+
46, 162, 90, 231, 237, 146, 214, 235, 252, 35, 163, 136, 158, 100, 115,
|
|
94
|
+
105, 122, 101, 25, 39, 16, 101, 36, 116, 121, 112, 101, 100, 98, 108, 111,
|
|
95
|
+
98, 104, 109, 105, 109, 101, 84, 121, 112, 101, 106, 105, 109, 97, 103,
|
|
96
|
+
101, 47, 106, 112, 101, 103,
|
|
97
|
+
]),
|
|
98
|
+
cid: 'bafyreihldkhcwijkde7gx4rpkkuw7pl6lbyu5gieunyc7ihactn5bkd2nm',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'ipldArray',
|
|
102
|
+
json: [
|
|
103
|
+
{
|
|
104
|
+
$link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
$link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
$link: 'bafyreiaizynclnqiolq7byfpjjtgqzn4sfrsgn7z2hhf6bo4utdwkin7ke',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
$link: 'bafyreifd4w4tcr5tluxz7osjtnofffvtsmgdqcfrfi6evjde4pl27lrjpy',
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
ipld: [
|
|
117
|
+
CID.parse('bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a'),
|
|
118
|
+
CID.parse('bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q'),
|
|
119
|
+
CID.parse('bafyreiaizynclnqiolq7byfpjjtgqzn4sfrsgn7z2hhf6bo4utdwkin7ke'),
|
|
120
|
+
CID.parse('bafyreifd4w4tcr5tluxz7osjtnofffvtsmgdqcfrfi6evjde4pl27lrjpy'),
|
|
121
|
+
],
|
|
122
|
+
cbor: new Uint8Array([
|
|
123
|
+
132, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22,
|
|
124
|
+
215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72, 147, 54,
|
|
125
|
+
137, 29, 9, 23, 65, 162, 57, 208, 216, 42, 88, 37, 0, 1, 113, 18, 32, 206,
|
|
126
|
+
188, 253, 200, 24, 248, 158, 85, 31, 33, 95, 133, 103, 145, 125, 120, 196,
|
|
127
|
+
209, 14, 220, 33, 139, 148, 27, 165, 214, 150, 172, 255, 213, 142, 244,
|
|
128
|
+
216, 42, 88, 37, 0, 1, 113, 18, 32, 8, 206, 26, 37, 182, 8, 114, 225, 240,
|
|
129
|
+
224, 175, 74, 102, 104, 101, 188, 145, 99, 35, 55, 249, 209, 206, 95, 5,
|
|
130
|
+
220, 164, 199, 101, 33, 191, 81, 216, 42, 88, 37, 0, 1, 113, 18, 32, 163,
|
|
131
|
+
229, 185, 49, 71, 179, 93, 47, 159, 186, 73, 155, 92, 82, 150, 179, 147,
|
|
132
|
+
12, 56, 8, 177, 42, 60, 74, 164, 100, 227, 215, 175, 174, 41, 126,
|
|
133
|
+
]),
|
|
134
|
+
cid: 'bafyreiaj3udmqlqrcbjxjayzuxwp64gt64olcbjfrkldzoqponpru6gq4m',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'ipldNested',
|
|
138
|
+
json: {
|
|
139
|
+
a: {
|
|
140
|
+
b: [
|
|
141
|
+
{
|
|
142
|
+
d: [
|
|
143
|
+
{
|
|
144
|
+
$link:
|
|
145
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
$link:
|
|
149
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
e: [
|
|
153
|
+
{
|
|
154
|
+
$bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
$bytes: 'iE+sPoHobU9tSIqGI+309LLCcWQIRmEXwxcoDt19tas',
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
ipld: {
|
|
165
|
+
a: {
|
|
166
|
+
b: [
|
|
167
|
+
{
|
|
168
|
+
d: [
|
|
169
|
+
CID.parse(
|
|
170
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
171
|
+
),
|
|
172
|
+
CID.parse(
|
|
173
|
+
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
174
|
+
),
|
|
175
|
+
],
|
|
176
|
+
e: [
|
|
177
|
+
new Uint8Array([
|
|
178
|
+
156, 81, 17, 142, 242, 203, 139, 15, 106, 155, 142, 73, 174,
|
|
179
|
+
161, 253, 65, 60, 242, 11, 98, 238, 213, 118, 248, 157, 238,
|
|
180
|
+
190, 176, 26, 194, 204, 141,
|
|
181
|
+
]),
|
|
182
|
+
new Uint8Array([
|
|
183
|
+
136, 79, 172, 62, 129, 232, 109, 79, 109, 72, 138, 134, 35, 237,
|
|
184
|
+
244, 244, 178, 194, 113, 100, 8, 70, 97, 23, 195, 23, 40, 14,
|
|
185
|
+
221, 125, 181, 171,
|
|
186
|
+
]),
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
cbor: new Uint8Array([
|
|
193
|
+
161, 97, 97, 161, 97, 98, 129, 162, 97, 100, 130, 216, 42, 88, 37, 0, 1,
|
|
194
|
+
113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22, 215, 60, 105, 68, 35, 124,
|
|
195
|
+
203, 193, 91, 28, 74, 114, 52, 72, 147, 54, 137, 29, 9, 23, 65, 162, 57,
|
|
196
|
+
208, 216, 42, 88, 37, 0, 1, 113, 18, 32, 101, 6, 42, 90, 90, 0, 252, 22,
|
|
197
|
+
215, 60, 105, 68, 35, 124, 203, 193, 91, 28, 74, 114, 52, 72, 147, 54,
|
|
198
|
+
137, 29, 9, 23, 65, 162, 57, 208, 97, 101, 130, 88, 32, 156, 81, 17, 142,
|
|
199
|
+
242, 203, 139, 15, 106, 155, 142, 73, 174, 161, 253, 65, 60, 242, 11, 98,
|
|
200
|
+
238, 213, 118, 248, 157, 238, 190, 176, 26, 194, 204, 141, 88, 32, 136,
|
|
201
|
+
79, 172, 62, 129, 232, 109, 79, 109, 72, 138, 134, 35, 237, 244, 244, 178,
|
|
202
|
+
194, 113, 100, 8, 70, 97, 23, 195, 23, 40, 14, 221, 125, 181, 171,
|
|
203
|
+
]),
|
|
204
|
+
cid: 'bafyreid3imdulnhgeytpf6uk7zahjvrsqlofkmm5b5ub2maw4kqus6jp4i',
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: 'poorlyFormatted',
|
|
208
|
+
json: {
|
|
209
|
+
a: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
210
|
+
b: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
211
|
+
c: {
|
|
212
|
+
$link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
|
|
213
|
+
another: 'bad value',
|
|
214
|
+
},
|
|
215
|
+
d: {
|
|
216
|
+
$bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
217
|
+
another: 'bad value',
|
|
218
|
+
},
|
|
219
|
+
e: {
|
|
220
|
+
'/': 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
|
|
221
|
+
},
|
|
222
|
+
f: {
|
|
223
|
+
'/': {
|
|
224
|
+
bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
ipld: {
|
|
229
|
+
a: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
230
|
+
b: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
231
|
+
c: {
|
|
232
|
+
$link: 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
|
|
233
|
+
another: 'bad value',
|
|
234
|
+
},
|
|
235
|
+
d: {
|
|
236
|
+
$bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
237
|
+
another: 'bad value',
|
|
238
|
+
},
|
|
239
|
+
e: {
|
|
240
|
+
'/': 'bafyreigoxt64qghytzkr6ik7qvtzc7lyytiq5xbbrokbxjows2wp7vmo6q',
|
|
241
|
+
},
|
|
242
|
+
f: {
|
|
243
|
+
'/': {
|
|
244
|
+
bytes: 'nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
cbor: new Uint8Array([
|
|
249
|
+
166, 97, 97, 120, 59, 98, 97, 102, 121, 114, 101, 105, 100, 102, 97, 121,
|
|
250
|
+
118, 102, 117, 119, 113, 97, 55, 113, 108, 110, 111, 112, 100, 106, 105,
|
|
251
|
+
113, 114, 120, 122, 115, 54, 98, 108, 109, 111, 101, 117, 52, 114, 117,
|
|
252
|
+
106, 99, 106, 116, 110, 99, 105, 53, 98, 101, 108, 117, 100, 105, 114,
|
|
253
|
+
122, 50, 97, 97, 98, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119,
|
|
254
|
+
57, 113, 109, 52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76,
|
|
255
|
+
117, 49, 88, 98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48, 97,
|
|
256
|
+
99, 162, 101, 36, 108, 105, 110, 107, 120, 59, 98, 97, 102, 121, 114, 101,
|
|
257
|
+
105, 103, 111, 120, 116, 54, 52, 113, 103, 104, 121, 116, 122, 107, 114,
|
|
258
|
+
54, 105, 107, 55, 113, 118, 116, 122, 99, 55, 108, 121, 121, 116, 105,
|
|
259
|
+
113, 53, 120, 98, 98, 114, 111, 107, 98, 120, 106, 111, 119, 115, 50, 119,
|
|
260
|
+
112, 55, 118, 109, 111, 54, 113, 103, 97, 110, 111, 116, 104, 101, 114,
|
|
261
|
+
105, 98, 97, 100, 32, 118, 97, 108, 117, 101, 97, 100, 162, 102, 36, 98,
|
|
262
|
+
121, 116, 101, 115, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119,
|
|
263
|
+
57, 113, 109, 52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76,
|
|
264
|
+
117, 49, 88, 98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48, 103,
|
|
265
|
+
97, 110, 111, 116, 104, 101, 114, 105, 98, 97, 100, 32, 118, 97, 108, 117,
|
|
266
|
+
101, 97, 101, 161, 97, 47, 120, 59, 98, 97, 102, 121, 114, 101, 105, 103,
|
|
267
|
+
111, 120, 116, 54, 52, 113, 103, 104, 121, 116, 122, 107, 114, 54, 105,
|
|
268
|
+
107, 55, 113, 118, 116, 122, 99, 55, 108, 121, 121, 116, 105, 113, 53,
|
|
269
|
+
120, 98, 98, 114, 111, 107, 98, 120, 106, 111, 119, 115, 50, 119, 112, 55,
|
|
270
|
+
118, 109, 111, 54, 113, 97, 102, 161, 97, 47, 161, 101, 98, 121, 116, 101,
|
|
271
|
+
115, 120, 43, 110, 70, 69, 82, 106, 118, 76, 76, 105, 119, 57, 113, 109,
|
|
272
|
+
52, 53, 74, 114, 113, 72, 57, 81, 84, 122, 121, 67, 50, 76, 117, 49, 88,
|
|
273
|
+
98, 52, 110, 101, 54, 43, 115, 66, 114, 67, 122, 73, 48,
|
|
274
|
+
]),
|
|
275
|
+
cid: 'bafyreico7wgbbfe6dpfsuednrtrlh6t2yjl6xq5rf32gl3pgwhwxk77cn4',
|
|
276
|
+
},
|
|
277
|
+
]
|
|
278
|
+
|
|
279
|
+
export default vectors
|
package/tests/ipld.test.ts
CHANGED
|
@@ -1,89 +1,29 @@
|
|
|
1
|
-
import { CID } from 'multiformats/cid'
|
|
2
1
|
import * as ui8 from 'uint8arrays'
|
|
3
|
-
import
|
|
2
|
+
import vectors from './ipld-vectors'
|
|
3
|
+
import {
|
|
4
|
+
cborDecode,
|
|
5
|
+
cborEncode,
|
|
6
|
+
cidForCbor,
|
|
7
|
+
ipldEquals,
|
|
8
|
+
ipldToJson,
|
|
9
|
+
jsonToIpld,
|
|
10
|
+
} from '../src'
|
|
4
11
|
|
|
5
12
|
describe('ipld', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
three: {
|
|
21
|
-
$bytes: 'AAECAw',
|
|
22
|
-
},
|
|
13
|
+
for (const vector of vectors) {
|
|
14
|
+
it(`passes test vector: ${vector.name}`, async () => {
|
|
15
|
+
const ipld = jsonToIpld(vector.json)
|
|
16
|
+
const json = ipldToJson(ipld)
|
|
17
|
+
const cbor = cborEncode(ipld)
|
|
18
|
+
const ipldAgain = cborDecode(cbor)
|
|
19
|
+
const jsonAgain = ipldToJson(ipldAgain)
|
|
20
|
+
const cid = await cidForCbor(ipld)
|
|
21
|
+
expect(json).toEqual(vector.json)
|
|
22
|
+
expect(jsonAgain).toEqual(vector.json)
|
|
23
|
+
expect(ipldEquals(ipld, vector.ipld)).toBeTruthy()
|
|
24
|
+
expect(ipldEquals(ipldAgain, vector.ipld)).toBeTruthy()
|
|
25
|
+
expect(ui8.equals(cbor, vector.cbor)).toBeTruthy()
|
|
26
|
+
expect(cid.toString()).toEqual(vector.cid)
|
|
23
27
|
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
it('converts json to ipld', () => {
|
|
27
|
-
const json = {
|
|
28
|
-
one: 1,
|
|
29
|
-
two: {
|
|
30
|
-
$link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
31
|
-
},
|
|
32
|
-
three: {
|
|
33
|
-
$bytes: 'AAECAw',
|
|
34
|
-
},
|
|
35
|
-
}
|
|
36
|
-
const expectedCid = CID.parse(
|
|
37
|
-
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
const ipld = jsonToIpld(json)
|
|
41
|
-
if (!ipld) {
|
|
42
|
-
throw new Error()
|
|
43
|
-
}
|
|
44
|
-
expect(ipld['one']).toBe(1)
|
|
45
|
-
expect(expectedCid.equals(ipld['two'])).toBeTruthy()
|
|
46
|
-
expect(ui8.equals(ipld['three'], new Uint8Array([0, 1, 2, 3]))).toBeTruthy()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('converts nested ipld to json', () => {
|
|
50
|
-
const ipld = {
|
|
51
|
-
a: {
|
|
52
|
-
b: [
|
|
53
|
-
CID.parse(
|
|
54
|
-
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
55
|
-
),
|
|
56
|
-
],
|
|
57
|
-
},
|
|
58
|
-
}
|
|
59
|
-
const json = ipldToJson(ipld)
|
|
60
|
-
expect(json).toEqual({
|
|
61
|
-
a: {
|
|
62
|
-
b: [
|
|
63
|
-
{
|
|
64
|
-
$link:
|
|
65
|
-
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
},
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('converts nested json to ipld', () => {
|
|
73
|
-
const json = {
|
|
74
|
-
a: {
|
|
75
|
-
b: [
|
|
76
|
-
{
|
|
77
|
-
$link:
|
|
78
|
-
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
const ipld = jsonToIpld(json)
|
|
84
|
-
const expectedCid = CID.parse(
|
|
85
|
-
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a',
|
|
86
|
-
)
|
|
87
|
-
expect(ipld && expectedCid.equals(ipld['a']['b']))
|
|
88
|
-
})
|
|
28
|
+
}
|
|
89
29
|
})
|