~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
111 lines · 3.1 KB Raw History
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([]);
  });
});