chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
/**
* What a settings form offers to link: every package this account publishes,
* read from the two registry collections. The write itself goes through OAuth
* and a live PDS, which the browser exercises.
*/
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { account } from '../src/lib/git.js';
import { packageKey, publishedPackages } from '../src/lib/settings.js';
const original = globalThis.fetch;
beforeEach(() => {
account.did = 'did:plc:owner';
account.pds = 'https://pds.example.com';
account.handle = 'owner.example.com';
});
afterEach(() => {
globalThis.fetch = original;
});
/** @param {string} name */
const record = (name) => ({ value: { name } });
/**
* Answer each collection with the pages it holds, and a cursor while pages
* remain.
* @param {Record<string, Array<Array<{value: {name: string}}>>>} pages
*/
function serve(pages) {
/** @type {string[]} */
const asked = [];
globalThis.fetch = async (/** @type {string|URL|Request} */ input) => {
const url = new URL(String(input));
asked.push(url.searchParams.get('cursor') ?? '');
const collection = url.searchParams.get('collection') ?? '';
const held = pages[collection] ?? [[]];
const page = Number(url.searchParams.get('cursor') ?? '0');
return Response.json({
records: held[page] ?? [],
...(page + 1 < held.length ? { cursor: String(page + 1) } : {}),
});
};
return asked;
}
describe('packageKey', () => {
it('names a package by the pair, since a name repeats across registries', () => {
expect(packageKey({ registry: 'npm', name: 'app' })).not.toBe(
packageKey({ registry: 'oci', name: 'app' }),
);
});
});
describe('publishedPackages', () => {
it('reads both registries and says which one holds each name', async () => {
serve({
'dev.pdsjs.npm.package': [[record('@scope/lib')]],
'dev.pdsjs.oci.repo': [[record('app/server')]],
});
expect(await publishedPackages()).toEqual([
{ registry: 'npm', name: '@scope/lib' },
{ registry: 'oci', name: 'app/server' },
]);
});
it('follows the cursor to the end of a collection', async () => {
const asked = serve({
'dev.pdsjs.npm.package': [[record('one')], [record('two')]],
});
const packages = await publishedPackages();
expect(packages.map((entry) => entry.name)).toEqual(['one', 'two']);
expect(asked).toContain('1');
});
it('leaves out a record naming nothing', async () => {
serve({ 'dev.pdsjs.npm.package': [[{ value: {} }, record('lib')]] });
expect(await publishedPackages()).toEqual([
{ registry: 'npm', name: 'lib' },
]);
});
it('reads a registry the server does not serve as nothing published', async () => {
globalThis.fetch = async () => new Response('no', { status: 404 });
expect(await publishedPackages()).toEqual([]);
});
it('reads an unreachable PDS as nothing published', async () => {
globalThis.fetch = async () => {
throw new Error('offline');
};
expect(await publishedPackages()).toEqual([]);
});
});