@idiolect-dev/schema
v0.7.0
Published
Runtime validators, types, and NSIDs for the dev.idiolect.* Lexicon family.
Downloads
1,468
Readme
@idiolect-dev/schema
TypeScript validators, record types, and NSID constants for the
dev.idiolect.* lexicon family.
Overview
The TypeScript twin of idiolect-records,
generated from the same lexicons under lexicons/dev/idiolect/. CI
rejects drift between the two packages. Three shipped surfaces:
- Types —
Encounter,Correction,Bounty, … per record kind, plus shared types fromdefs. - NSID constants —
NSID.encounter→"dev.idiolect.encounter", for switching on a record's collection at runtime. - Validators —
validateRecord,isRecord,classifyRecord,tagRecordfor runtime structural checks and typed unions.
Architecture
flowchart LR
LEX["lexicons/dev/idiolect/*.json"]
CG["idiolect-codegen<br/>(Rust binary)"]
subgraph pkg["@idiolect-dev/schema"]
GEN["src/generated/<br/>(types · validators · NSID)"]
API["isRecord · classifyRecord<br/>tagRecord · validateRecord"]
FIX["EXAMPLES (fixtures)"]
LEXDOCS["defaultLexicons()<br/>loadLexiconDocs()"]
end
ATLEX["@atproto/lexicon"]
CONS["TypeScript consumers<br/>(appviews · clients)"]
LEX --> CG --> GEN
GEN --> API
GEN --> FIX
LEX --> LEXDOCS
ATLEX --> API
API --> CONS
LEXDOCS --> CONSInstall
bun add @idiolect-dev/schema
# or
npm install @idiolect-dev/schemaUsage
import {
NSID,
isRecord,
classifyRecord,
type Encounter,
type AnyRecord,
} from "@idiolect-dev/schema";
// Narrow an unknown payload to a typed record.
const payload: unknown = await fetch(recordUrl).then(r => r.json());
if (isRecord(NSID.encounter, payload)) {
const e: Encounter = payload;
console.log(e.kind);
}
// Identify the nsid of an unknown record.
const nsid = classifyRecord(payload); // returns the matching nsid or null
// Wrap a strongly-typed record into a tagged AnyRecord for buffering.
import { tagRecord } from "@idiolect-dev/schema";
const tagged: AnyRecord = tagRecord(NSID.encounter, e);What ships
- Every record type (one per lexicon under
lexicons/dev/idiolect/) plus shared types fromdefs. NSID— a typed constants object with every shipped nsid.AnyRecord— discriminated union keyed on$nsid.isKind/ per-recordis<Kind>type guards.validateRecord(nsid, value)— atproto-level structural validation via@atproto/lexicon.classifyRecord(value)— returns the matching nsid ornull.tagRecord(nsid, record)— lift a typed record into the tagged union.EXAMPLESand per-record*_EXAMPLEconstants — bundled minimally-valid fixtures fromlexicons/dev/idiolect/examples/.loadLexiconDocs()/defaultLexicons()— re-exported lexicon JSON plus aLexiconsinstance for consumers that extend the validator set.
Design notes
- The generated TypeScript under
src/generated/is emitted byidiolect-codegen. CI runscargo run -p idiolect-codegen -- checkand fails the build if the committed output differs from what the current lexicons would produce. Hand-edits tosrc/generated/never merge.
Stability
idiolect is pre-1.0. Releases in the 0.x series may include
arbitrary breaking changes between minor versions — TypeScript
exports, lexicon shapes, wire formats, and the validator surface
are all in scope. Pin to an exact version if you depend on this
package, and read CHANGELOG.md before bumping.
Related
idiolect-records— Rust twin, generated from the same lexicons.idiolect-codegen— emits this package.
