Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165import assert from 'node:assert/strict';import { readdirSync, readFileSync } from 'node:fs';import { join } from 'node:path';import { test } from 'node:test';import { ingest } from '../src/index/ingest.ts';import { IndexModel } from '../src/index/model.ts';import { memoryCache } from '../src/gateway/index.ts';import { handleRequest, type RouterEnv } from '../src/router.ts';import { ingestDeps, outbound } from '../src/services.ts';import { sqliteSql } from './sqlite-sql.ts';
const UA = 'nibling.dev/0.0.1 (+https://ops.example/contact)';const ALICE = 'did:plc:aaaaaaaaaaaaaaaaaaaaaaaa';const REPO = 'did:plc:rrrrrrrrrrrrrrrrrrrrrrrr';// A real TID: the card route only reads a record directly when the name parses as one.const PROJECT = `at://${ALICE}/dev.nibling.project/3la2bcdefghij`;const BLOB = 'bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku';
interface Seen { url: string; userAgent: string | null;}
/** Every service the worker talks to, answering just enough for each path to run to the end. */function world(request: Request): Response { const url = new URL(request.url); const at = `${url.host}${url.pathname}`; switch (at) { case 'slingshot.test/xrpc/blue.microcosm.identity.resolveMiniDoc': return Response.json({ did: ALICE, handle: 'alice.test', pds: 'https://pds.test' }); case 'slingshot.test/xrpc/blue.microcosm.repo.getRecordByUri': return Response.json({ uri: PROJECT, cid: 'bafy1', value: { $type: 'dev.nibling.project', name: 'p', files: [], createdAt: '2026-11-01T00:00:00.000Z' } }); case 'relay.test/xrpc/com.atproto.sync.listReposByCollection': return Response.json({ repos: [{ did: ALICE }] }); case `plc.directory/${ALICE}`: return Response.json({ id: ALICE, service: [{ id: '#atproto_pds', type: 'AtprotoPersonalDataServer', serviceEndpoint: 'https://pds.test' }] }); case `plc.directory/${REPO}`: return Response.json({ id: REPO, service: [{ id: '#tangled_knot', type: 'TangledKnot', serviceEndpoint: 'https://knot.test' }] }); case 'pds.test/xrpc/com.atproto.repo.listRecords': return Response.json({ records: [] }); case 'pds.test/xrpc/com.atproto.repo.getRecord': return Response.json({ uri: PROJECT, cid: 'bafy1', value: {} }); case 'pds.test/xrpc/com.atproto.sync.getBlob': return new Response('blob'); case 'constellation.test/xrpc/blue.microcosm.links.getBacklinksCount': return Response.json({ total: 1 }); case `knot.test/${REPO}/info/refs`: case `knot.test/${REPO}/git-upload-pack`: return new Response('0000'); case 'jetstream.test/xrpc/network.bsky.jetstream.subscribeEvents': { const listeners: Record<string, (() => void)[]> = {}; const webSocket = { accept() {}, addEventListener(type: string, listener: () => void) { (listeners[type] ??= []).push(listener); }, close() { for (const listener of listeners.close ?? []) listener(); }, }; return { status: 101, webSocket } as unknown as Response; } default: return new Response('{}', { status: 404 }); }}
/** Swaps the global fetch for a recorder for the length of `run`, so a path that skipped `upstream()` * still lands here, just without the header. */async function recording(run: () => Promise<unknown>): Promise<Seen[]> { const seen: Seen[] = []; const real = globalThis.fetch; globalThis.fetch = (async (input: string | URL | Request, init?: RequestInit) => { const request = new Request(input, init); seen.push({ url: `${new URL(request.url).host}${new URL(request.url).pathname}`, userAgent: request.headers.get('user-agent') }); return world(request); }) as typeof fetch; try { await run(); } finally { globalThis.fetch = real; } return seen;}
const env = { APP_ORIGIN: 'https://nibling.run', SLINGSHOT_URL: 'https://slingshot.test', CONSTELLATION_URL: 'https://constellation.test', JETSTREAM_URL: 'wss://jetstream.test', RELAY_URL: 'https://relay.test', CONTACT_URL: 'https://ops.example/contact',};
function routerEnv(): RouterEnv { const index = { getRecent: async () => ({ projects: [] }), getTrending: async () => ({ projects: [] }), getKnown: async () => [] }; return { ...env, INDEX: { getByName: () => index }, fetch: outbound(env), cache: memoryCache(Date.now), waitUntil: () => {} };}
test('link cards, backfill, and the Jetstream upgrade all send exactly the nibling User-Agent', async () => { const seen = await recording(async () => { const card = await handleRequest(new Request('https://api.nibling.run/alice.test/3la2bcdefghij'), routerEnv()); assert.equal(card.status, 200); const model = new IndexModel(sqliteSql()); await ingest({ ...ingestDeps(env, model, () => Date.now()), drainBudgetMs: 10 }); }); assert.deepEqual(seen, [ { url: 'slingshot.test/xrpc/blue.microcosm.identity.resolveMiniDoc', userAgent: UA }, { url: 'slingshot.test/xrpc/blue.microcosm.repo.getRecordByUri', userAgent: UA }, ...['dev.nibling.project', 'dev.nibling.feed.like', 'dev.nibling.graph.follow', 'dev.nibling.actor.profile'].flatMap(() => [ { url: 'relay.test/xrpc/com.atproto.sync.listReposByCollection', userAgent: UA }, { url: `plc.directory/${ALICE}`, userAgent: UA }, { url: 'pds.test/xrpc/com.atproto.repo.listRecords', userAgent: UA }, ]), { url: 'jetstream.test/xrpc/network.bsky.jetstream.subscribeEvents', userAgent: UA }, ]);});
test('every gateway read sends exactly the nibling User-Agent', async () => { let env: RouterEnv; const get = async (path: string, init?: RequestInit) => { const res = await handleRequest(new Request(`https://api.nibling.run${path}`, init), env); assert.equal(res.status, 200, path); await res.arrayBuffer(); }; const seen = await recording(async () => { env = routerEnv(); await get(`/xrpc/com.atproto.repo.getRecord?repo=${ALICE}&collection=dev.nibling.project&rkey=3la1`); await get(`/xrpc/com.atproto.sync.getBlob?did=${ALICE}&cid=${BLOB}`); await get(`/xrpc/blue.microcosm.links.getBacklinksCount?subject=${encodeURIComponent(PROJECT)}&source=dev.nibling.feed.like:subject.uri`); await get(`/xrpc/blue.microcosm.repo.getRecordByUri?at_uri=${encodeURIComponent(PROJECT)}`); await get(`/git/${REPO}/info/refs?service=git-upload-pack`); await get(`/git/${REPO}/git-upload-pack`, { method: 'POST', body: '0000' }); }); assert.deepEqual(seen, [ { url: 'slingshot.test/xrpc/blue.microcosm.identity.resolveMiniDoc', userAgent: UA }, { url: 'pds.test/xrpc/com.atproto.repo.getRecord', userAgent: UA }, { url: 'pds.test/xrpc/com.atproto.sync.getBlob', userAgent: UA }, { url: 'constellation.test/xrpc/blue.microcosm.links.getBacklinksCount', userAgent: UA }, { url: 'slingshot.test/xrpc/blue.microcosm.repo.getRecordByUri', userAgent: UA }, { url: `plc.directory/${REPO}`, userAgent: UA }, { url: `knot.test/${REPO}/info/refs`, userAgent: UA }, { url: `knot.test/${REPO}/git-upload-pack`, userAgent: UA }, ]);});
const src = new URL('../src/', import.meta.url).pathname;const sources = (dir: string): string[] => readdirSync(dir, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? sources(join(dir, entry.name)) : entry.name.endsWith('.ts') ? [join(dir, entry.name)] : [], );
test('only the composition root touches the global fetch, and nothing opens a bare WebSocket', () => { const offenders = sources(src).flatMap((file) => { const text = readFileSync(file, 'utf8').replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, ''); const name = file.slice(src.length); const hits: string[] = []; if (/(?:await|return|=>?|\(|,|&&|\|\||\?\?)\s*fetch\(/.test(text)) hits.push(`${name}: bare fetch(`); if (/new WebSocket\(/.test(text)) hits.push(`${name}: new WebSocket(`); if (/globalThis\.fetch/.test(text) && name !== 'services.ts') hits.push(`${name}: globalThis.fetch`); return hits; }); assert.deepEqual(offenders, []);});