chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { createHash, randomBytes } from 'node:crypto';
import { describe, expect, it } from 'vitest';
import { fromBase64, tarballHashes } from '../src/integrity.js';
import { isValidName, nameToRkey, rkeyToName } from '../src/lexicon.js';
import {
blobRef,
parsePackageRecord,
recordBlobCids,
serializePackageRecord,
} from '../src/record.js';
describe('names', () => {
it('accepts npm-shaped package names', () => {
for (const name of [
'lodash',
'my-pkg',
'a.b_c~d',
'@scope/name',
'@my-org/my.pkg',
]) {
expect(isValidName(name), name).toBe(true);
}
});
it('refuses names outside the grammar', () => {
for (const name of [
'',
'UPPER',
'.dot',
'_under',
'@scope',
'@scope/a/b',
'@/name',
'a b',
'a'.repeat(215),
]) {
expect(isValidName(name), name).toBe(false);
}
});
it('round-trips names through record keys', () => {
expect(nameToRkey('@scope/name')).toBe('scope:name');
expect(rkeyToName('scope:name')).toBe('@scope/name');
expect(nameToRkey('plain')).toBe('plain');
expect(rkeyToName('plain')).toBe('plain');
expect(rkeyToName(nameToRkey('@a/b.c'))).toBe('@a/b.c');
});
});
describe('integrity', () => {
it('matches what node crypto computes', async () => {
const bytes = new Uint8Array(randomBytes(4096));
const { integrity, shasum } = await tarballHashes(bytes);
expect(integrity).toBe(
`sha512-${createHash('sha512').update(bytes).digest('base64')}`,
);
expect(shasum).toBe(createHash('sha1').update(bytes).digest('hex'));
});
it('round-trips base64', () => {
const bytes = new Uint8Array(randomBytes(300));
expect(fromBase64(Buffer.from(bytes).toString('base64'))).toEqual(bytes);
});
});
describe('record', () => {
const record = {
name: '@scope/pkg',
distTags: [{ tag: 'latest', version: '1.2.0' }],
versions: [
{
version: '1.2.0',
tarball: blobRef('btarballcid', 'application/octet-stream', 900),
manifest: blobRef('bmanifestcid', 'application/json', 300),
integrity: 'sha512-abc',
shasum: 'deadbeef',
publishedAt: '2026-08-20T00:00:00.000Z',
},
],
createdAt: '2026-08-20T00:00:00.000Z',
};
it('round-trips through serialization', () => {
const parsed = parsePackageRecord(serializePackageRecord(record));
expect(parsed?.name).toBe('@scope/pkg');
expect(parsed?.distTags).toEqual(record.distTags);
expect(parsed?.versions).toEqual(record.versions);
});
it('collects every referenced blob CID once', () => {
expect(recordBlobCids(record).sort()).toEqual([
'bmanifestcid',
'btarballcid',
]);
});
it('parses nothing from a malformed value', () => {
expect(parsePackageRecord(null)).toBeNull();
expect(parsePackageRecord({ name: 5 })).toBeNull();
});
it('drops a version entry missing its blobs', () => {
const parsed = parsePackageRecord({
name: 'pkg',
distTags: [],
versions: [{ version: '1.0.0', integrity: 'sha512-x' }],
createdAt: record.createdAt,
});
expect(parsed?.versions).toEqual([]);
});
});