@atproto/common
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -0,1 +1,6 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import crypto from 'crypto'; | ||
import { Transform, TransformCallback } from 'stream'; | ||
import { CID } from 'multiformats/cid'; | ||
@@ -12,1 +17,13 @@ import * as Block from 'multiformats/block'; | ||
export declare const sha256RawToCid: (hash: Uint8Array) => CID; | ||
export declare class VerifyCidTransform extends Transform { | ||
cid: CID; | ||
hasher: crypto.Hash; | ||
constructor(cid: CID); | ||
_transform(chunk: Uint8Array, _enc: BufferEncoding, cb: TransformCallback): void; | ||
_flush(cb: TransformCallback): void; | ||
} | ||
export declare class VerifyCidError extends Error { | ||
expected: CID; | ||
actual: CID; | ||
constructor(expected: CID, actual: CID); | ||
} |
@@ -7,2 +7,4 @@ /// <reference types="node" /> | ||
export declare const streamSize: (stream: Readable) => Promise<number>; | ||
export declare const streamToBytes: (stream: Readable) => Promise<Uint8Array>; | ||
export declare const byteIterableToStream: (iter: AsyncIterable<Uint8Array>) => Readable; | ||
export declare const bytesToStream: (bytes: Uint8Array) => Readable; | ||
@@ -9,0 +11,0 @@ export declare class MaxSizeChecker extends Transform { |
@@ -8,3 +8,2 @@ import * as mf from 'multiformats/cid'; | ||
string: z.ZodString; | ||
array: z.ZodArray<z.ZodUnknown, "many">; | ||
record: z.ZodRecord<z.ZodString, z.ZodUnknown>; | ||
@@ -11,0 +10,0 @@ unknown: z.ZodUnknown; |
{ | ||
"name": "@atproto/common", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/bluesky-social/atproto.git", | ||
"directory": "packages/common" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"prettier": "prettier --check src/", | ||
"prettier:fix": "prettier --write src/", | ||
"prettier": "prettier --check src/ tests/", | ||
"prettier:fix": "prettier --write src/ tests/", | ||
"lint": "eslint . --ext .ts,.tsx", | ||
@@ -11,0 +16,0 @@ "lint:fix": "yarn lint --fix", |
@@ -0,1 +1,3 @@ | ||
import crypto from 'crypto' | ||
import { Transform, TransformCallback } from 'stream' | ||
import { check, schema } from '@atproto/common-web' | ||
@@ -53,1 +55,36 @@ import { CID } from 'multiformats/cid' | ||
} | ||
export class VerifyCidTransform extends Transform { | ||
hasher = crypto.createHash('sha256') | ||
constructor(public cid: CID) { | ||
super() | ||
} | ||
_transform(chunk: Uint8Array, _enc: BufferEncoding, cb: TransformCallback) { | ||
this.hasher.update(chunk) | ||
cb(null, chunk) | ||
} | ||
_flush(cb: TransformCallback) { | ||
try { | ||
const cid = sha256RawToCid(this.hasher.digest()) | ||
if (this.cid.equals(cid)) { | ||
return cb() | ||
} else { | ||
return cb(new VerifyCidError(this.cid, cid)) | ||
} | ||
} catch (_err) { | ||
const err = | ||
_err instanceof Error | ||
? _err | ||
: new Error('Unexpected error', { cause: _err }) | ||
return cb(err) | ||
} | ||
} | ||
} | ||
export class VerifyCidError extends Error { | ||
constructor(public expected: CID, public actual: CID) { | ||
super('Bad cid check') | ||
} | ||
} |
@@ -33,2 +33,16 @@ import { | ||
export const streamToBytes = async (stream: Readable): Promise<Uint8Array> => { | ||
const bufs: Buffer[] = [] | ||
for await (const bytes of stream) { | ||
bufs.push(bytes) | ||
} | ||
return new Uint8Array(Buffer.concat(bufs)) | ||
} | ||
export const byteIterableToStream = ( | ||
iter: AsyncIterable<Uint8Array>, | ||
): Readable => { | ||
return Readable.from(iter, { objectMode: false }) | ||
} | ||
export const bytesToStream = (bytes: Uint8Array): Readable => { | ||
@@ -35,0 +49,0 @@ const stream = new Readable() |
@@ -1,89 +0,29 @@ | ||
import { CID } from 'multiformats/cid' | ||
import * as ui8 from 'uint8arrays' | ||
import { ipldToJson, jsonToIpld } from '../src' | ||
import vectors from './ipld-vectors' | ||
import { | ||
cborDecode, | ||
cborEncode, | ||
cidForCbor, | ||
ipldEquals, | ||
ipldToJson, | ||
jsonToIpld, | ||
} from '../src' | ||
describe('ipld', () => { | ||
it('converts ipld to json', () => { | ||
const ipld = { | ||
one: 1, | ||
two: CID.parse( | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
), | ||
three: new Uint8Array([0, 1, 2, 3]), | ||
} | ||
const json = ipldToJson(ipld) | ||
expect(json).toEqual({ | ||
one: 1, | ||
two: { | ||
$link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
}, | ||
three: { | ||
$bytes: 'AAECAw', | ||
}, | ||
for (const vector of vectors) { | ||
it(`passes test vector: ${vector.name}`, async () => { | ||
const ipld = jsonToIpld(vector.json) | ||
const json = ipldToJson(ipld) | ||
const cbor = cborEncode(ipld) | ||
const ipldAgain = cborDecode(cbor) | ||
const jsonAgain = ipldToJson(ipldAgain) | ||
const cid = await cidForCbor(ipld) | ||
expect(json).toEqual(vector.json) | ||
expect(jsonAgain).toEqual(vector.json) | ||
expect(ipldEquals(ipld, vector.ipld)).toBeTruthy() | ||
expect(ipldEquals(ipldAgain, vector.ipld)).toBeTruthy() | ||
expect(ui8.equals(cbor, vector.cbor)).toBeTruthy() | ||
expect(cid.toString()).toEqual(vector.cid) | ||
}) | ||
}) | ||
it('converts json to ipld', () => { | ||
const json = { | ||
one: 1, | ||
two: { | ||
$link: 'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
}, | ||
three: { | ||
$bytes: 'AAECAw', | ||
}, | ||
} | ||
const expectedCid = CID.parse( | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
) | ||
const ipld = jsonToIpld(json) | ||
if (!ipld) { | ||
throw new Error() | ||
} | ||
expect(ipld['one']).toBe(1) | ||
expect(expectedCid.equals(ipld['two'])).toBeTruthy() | ||
expect(ui8.equals(ipld['three'], new Uint8Array([0, 1, 2, 3]))).toBeTruthy() | ||
}) | ||
it('converts nested ipld to json', () => { | ||
const ipld = { | ||
a: { | ||
b: [ | ||
CID.parse( | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
), | ||
], | ||
}, | ||
} | ||
const json = ipldToJson(ipld) | ||
expect(json).toEqual({ | ||
a: { | ||
b: [ | ||
{ | ||
$link: | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
}, | ||
], | ||
}, | ||
}) | ||
}) | ||
it('converts nested json to ipld', () => { | ||
const json = { | ||
a: { | ||
b: [ | ||
{ | ||
$link: | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
}, | ||
], | ||
}, | ||
} | ||
const ipld = jsonToIpld(json) | ||
const expectedCid = CID.parse( | ||
'bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a', | ||
) | ||
expect(ipld && expectedCid.equals(ipld['a']['b'])) | ||
}) | ||
} | ||
}) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
2664307
49
23346
23