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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
79 lines · 2.6 KB Raw History
/**
 * Regenerate packages/lexicon-resolver/src/schemas/published.js.
 *
 * Walks the network resolution chain from every NSID in knownRecords, follows
 * each schema's refs, and writes the closure to disk. Run it when Bluesky
 * publishes a lexicon change worth shipping early:
 *
 *   node scripts/gen-bundled-lexicons.mjs
 *
 * The resolver refreshes these from the network on its own TTL, so the file is
 * a warm start rather than the authority.
 */

import { execFileSync } from 'node:child_process';
import { writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { LexiconResolver } from '../packages/lexicon-resolver/src/resolver.js';
import { coreSchemas } from '../packages/lexicon-resolver/src/schemas/com-atproto.js';
import { knownRecords } from '../packages/lexicon-resolver/src/schemas/known-records.js';

const OUT = join(
  dirname(fileURLToPath(import.meta.url)),
  '../packages/lexicon-resolver/src/schemas/published.js',
);

const resolver = new LexiconResolver({
  fetch: (url, init) => fetch(url, init),
});

/** @type {string[]} */
const missing = [];
for (const nsid of knownRecords) {
  const unresolved = new Set();
  await resolver.ensureSchemaWithRefs(nsid, unresolved);
  missing.push(...unresolved);
}

if (missing.length) {
  console.error(`unresolved: ${[...new Set(missing)].join(', ')}`);
  process.exit(1);
}

const bundled = new Set(coreSchemas.map((s) => s.id));
const ids = [...resolver.schemas.keys()]
  .filter((id) => !bundled.has(id))
  .sort();

const header = `/**
 * Lexicons for the record types this PDS enforces, and every schema they
 * reference. Generated by scripts/gen-bundled-lexicons.mjs.
 *
 * The resolver preloads these so the common write path costs no network calls.
 * Each one carries the resolver's TTL like any other cache entry, so the
 * network answer replaces it once the entry goes stale. Enforcement comes from
 * known-records.js, not from this file.
 *
 * Do not edit by hand.
 */

/** @type {import('@bigmoves/lexicon').Lexicon[]} */
export const publishedSchemas = ${JSON.stringify(
  // An authority publishes its lexicon as a record, so the document arrives
  // carrying the collection it was stored in. That is not part of a Lexicon.
  ids.map((id) => {
    const { $type, ...schema } = /** @type {Record<string, unknown>} */ (
      resolver.schemas.get(id)
    );
    return schema;
  }),
  null,
  2,
)};
`;

writeFileSync(OUT, header);
// JSON.stringify does not produce the house style, and `npm run ci` checks it.
execFileSync('npx', ['biome', 'format', '--write', OUT], { stdio: 'inherit' });
console.log(`wrote ${ids.length} schemas to ${OUT}`);