chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { describe, expect, it } from 'vitest';
import { planInstall, resolveConfig, settingsSchema } from '../src/install.js';
const DEV = 'did:plc:developer';
const blob = (/** @type {string} */ cid, mimeType = 'text/html') => ({
$type: 'blob',
ref: { $link: cid },
mimeType,
size: 10,
});
function fixtures(overrides = {}) {
const site = {
uri: `at://${DEV}/dev.pdsjs.site.deploy/photos`,
cid: 'bafysite',
value: {
$type: 'dev.pdsjs.site.deploy',
files: [
{
path: 'index.html',
blob: blob('bafyindex'),
cacheControl: 'public, max-age=300',
},
],
fallback: 'index.html',
createdAt: '2026-08-11T00:00:00.000Z',
},
};
const manifest = {
uri: `at://${DEV}/dev.pdsjs.app.manifest/photos`,
cid: 'bafymanifest',
value: {
$type: 'dev.pdsjs.app.manifest',
name: 'Photos',
site: { uri: site.uri, cid: site.cid },
queries: [
{
name: 'grain-galleries',
collection: 'social.grain.gallery',
sort: { field: 'createdAt', direction: 'desc' },
},
],
settings: [
{
key: 'topo',
label: 'Terrain header',
type: 'boolean',
default: true,
},
{
key: 'rows',
type: 'select',
options: ['compact', 'roomy'],
default: 'roomy',
},
],
createdAt: '2026-08-11T00:00:00.000Z',
...overrides,
},
};
return { manifest, site };
}
describe('settingsSchema', () => {
it('keeps typed fields and drops what it cannot render', () => {
const schema = settingsSchema([
{ key: 'a', type: 'boolean' },
{ key: 'b', type: 'wat' },
{ type: 'string' },
{ key: 'c', type: 'select', options: ['x', 1, 'y'] },
]);
expect(schema.map((f) => f.key)).toEqual(['a', 'c']);
expect(schema[1].options).toEqual(['x', 'y']);
expect(settingsSchema('nope')).toEqual([]);
});
});
describe('resolveConfig', () => {
const schema = settingsSchema([
{ key: 'topo', type: 'boolean', default: true },
{ key: 'rows', type: 'select', options: ['compact', 'roomy'] },
]);
it('applies defaults and checked overrides', () => {
expect(resolveConfig(schema)).toEqual({ topo: true });
expect(resolveConfig(schema, { topo: false, rows: 'compact' })).toEqual({
topo: false,
rows: 'compact',
});
});
it('rejects unknown keys and wrong types', () => {
expect(() => resolveConfig(schema, { nope: 1 })).toThrow(/No such setting/);
expect(() => resolveConfig(schema, { topo: 'yes' })).toThrow(
/true or false/,
);
expect(() => resolveConfig(schema, { rows: 'wide' })).toThrow(/one of/);
});
});
describe('planInstall', () => {
it('plans copies, records, defs, and the settings snapshot', () => {
const { manifest, site } = fixtures();
const plan = planInstall({
manifest,
site,
overrides: { topo: false },
now: '2026-08-11T01:00:00.000Z',
});
expect(plan.localName).toBe('photos');
expect(plan.copies).toEqual([
{ path: 'index.html', cid: 'bafyindex', contentType: 'text/html' },
]);
expect(plan.siteRecord.fallback).toBe('index.html');
expect(
/** @type {Array<{cacheControl?: string}>} */ (plan.siteRecord.files)[0]
.cacheControl,
).toBe('public, max-age=300');
expect(plan.queryDefs).toHaveLength(1);
expect(plan.queryDefs[0].rkey).toBe('grain-galleries');
expect(plan.installRecord.manifest).toEqual({
uri: manifest.uri,
cid: 'bafymanifest',
});
expect(plan.installRecord.config).toEqual({ topo: false, rows: 'roomy' });
expect(plan.installRecord.name).toBe('Photos');
expect(
/** @type {Array<{key: string}>} */ (plan.installRecord.settings).map(
(f) => f.key,
),
).toEqual(['topo', 'rows']);
});
it('copies a declared icon into the install record', () => {
const { manifest, site } = fixtures({
icon: {
$type: 'blob',
ref: { $link: 'bafyicon' },
mimeType: 'image/svg+xml',
size: 400,
},
});
const plan = planInstall({ manifest, site });
expect(plan.icon).toEqual({
cid: 'bafyicon',
contentType: 'image/svg+xml',
});
expect(
/** @type {{ref: {$link: string}}} */ (plan.installRecord.icon).ref.$link,
).toBe('bafyicon');
expect(
planInstall({ manifest: fixtures().manifest, site }).icon,
).toBeNull();
});
it("carries a prior install's valid settings through an update", () => {
const { manifest, site } = fixtures();
const plan = planInstall({
manifest,
site,
existingConfig: {
rows: 'compact',
topo: false,
gone: 'stale',
rowsBad: 1,
},
overrides: { topo: true },
});
// kept: rows (still valid); dropped: unknown keys; override wins on topo
expect(plan.installRecord.config).toEqual({ topo: true, rows: 'compact' });
});
it('prefers the suggested site name over the artifact record key', () => {
const { manifest, site } = fixtures({ suggestedSite: 'pics' });
expect(planInstall({ manifest, site }).localName).toBe('pics');
expect(planInstall({ manifest, site, localName: 'mine' }).localName).toBe(
'mine',
);
});
it('rejects a drifted site pin and bad names', () => {
const { manifest, site } = fixtures();
expect(() =>
planInstall({ manifest, site: { ...site, cid: 'bafyother' } }),
).toThrow(/changed since this manifest/);
expect(() =>
planInstall({ manifest, site, localName: 'Not_A_Label' }),
).toThrow(/DNS label/);
});
it('rejects a site record that is not the pinned one or holds nothing', () => {
const { manifest, site } = fixtures();
expect(() =>
planInstall({
manifest,
site: { ...site, uri: `at://${DEV}/dev.pdsjs.site.deploy/other` },
}),
).toThrow(/not the one the manifest names/);
expect(() =>
planInstall({
manifest,
site: { ...site, value: { ...site.value, files: [] } },
}),
).toThrow(/no files/);
});
});