a tiny atproto lexicon validator
0

Configure Feed

Select the types of activity you want to include in your feed.

LexiconCatalog -> TinyLex

+11 -11
+4 -4
README.md
··· 8 8 9 9 ## Usage 10 10 11 - A `LexiconCatalog` holds your lexicon documents and resolves cross-references between them. You can handwrite or copy/paste lexicons inline or [fetch them by NSID](#fetching-lexicons) — either way, add them to the catalog, then call `schema(nsid)` to get a Standard Schema validator: 11 + A `TinyLex` instance holds your lexicon documents and resolves cross-references between them. You can handwrite or copy/paste lexicons inline or [fetch them by NSID](#fetching-lexicons) — either way, add them to the catalog, then call `schema(nsid)` to get a Standard Schema validator: 12 12 13 13 ```js 14 - import { LexiconCatalog } from "./tinylex.js"; 14 + import TinyLex from "./tinylex.js"; 15 15 16 - const lexicons = new LexiconCatalog().add({ 16 + const lexicons = new TinyLex().add({ 17 17 lexicon: 1, 18 18 id: "com.example.follow", 19 19 defs: { ··· 53 53 ./tinylex-install app.bsky.feed.post --js 54 54 ``` 55 55 56 - Output defaults to `./lexicons/<nsid>.json`. Pass `--js` to emit `.js` files wrapped in `export default /** @type {const} */ ({...})` so imports keep literal types (otherwise TypeScript widens the JSON and `LexiconCatalog.add()` can't infer narrow types for `result.value`). 56 + Output defaults to `./lexicons/<nsid>.json`. Pass `--js` to emit `.js` files wrapped in `export default /** @type {const} */ ({...})` so imports keep literal types (otherwise TypeScript widens the JSON and `TinyLex.add()` can't infer narrow types for `result.value`). 57 57 58 58 The script is a polyglot shell/JS file that picks the first available runtime among Node, Deno and Bun. 59 59
+5 -5
test.js
··· 1 1 import { test } from "node:test"; 2 2 import assert from "node:assert/strict"; 3 - import { LexiconCatalog } from "./tinylex.js"; 3 + import TinyLex from "./tinylex.js"; 4 4 5 5 /** @returns {(v: unknown) => boolean} */ 6 6 const validator = (/** @type {any} */ def) => { 7 - const schema = new LexiconCatalog() 7 + const schema = new TinyLex() 8 8 .add({ lexicon: 1, id: "test.x", defs: { main: def } }) 9 9 .schema("test.x"); 10 10 return (v) => !schema["~standard"].validate(v).issues; ··· 245 245 // --------------------------------------------------------------------------- 246 246 247 247 test("ref resolves through catalog", () => { 248 - const catalog = new LexiconCatalog().add({ 248 + const catalog = new TinyLex().add({ 249 249 lexicon: 1, 250 250 id: "test.ref", 251 251 defs: { ··· 259 259 }); 260 260 261 261 test("union: open accepts unknown $type", () => { 262 - const catalog = new LexiconCatalog().add({ 262 + const catalog = new TinyLex().add({ 263 263 lexicon: 1, 264 264 id: "test.u", 265 265 defs: { ··· 274 274 }); 275 275 276 276 test("union: closed rejects unknown $type", () => { 277 - const catalog = new LexiconCatalog().add({ 277 + const catalog = new TinyLex().add({ 278 278 lexicon: 1, 279 279 id: "test.cu", 280 280 defs: {
+2 -2
tinylex.js
··· 290 290 /** 291 291 * @template {CatalogMap} [Catalog={}] 292 292 */ 293 - export class LexiconCatalog { 293 + export default class TinyLex { 294 294 #files = new Map(); 295 295 296 296 /** 297 297 * @template {string} const Nsid 298 298 * @template {Record<string, unknown>} const Defs 299 299 * @param {{ readonly id: Nsid; readonly defs: Defs; readonly [k: string]: unknown }} file 300 - * @returns {LexiconCatalog<Catalog & FlattenDefs<Nsid, Defs, Catalog & FlattenDefs<Nsid, Defs, Catalog>>>} 300 + * @returns {TinyLex<Catalog & FlattenDefs<Nsid, Defs, Catalog & FlattenDefs<Nsid, Defs, Catalog>>>} 301 301 */ 302 302 add(file) { 303 303 this.#files.set(file.id, file);