Schema Derivation
JsonSchema.output derives a JSON Schema from a Spec or Plan without executing it. The schema reflects the output structure, including types, required fields, and nested objects.
Basic usage
Section titled “Basic usage”import { JsonSchema } from '@origints/core'
// From a Planconst schema = JsonSchema.output(plan)// { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] }import { extract } from '@origints/core'
// From a Specconst spec = extract($ => ({ name: $.get('name').string(), age: $.get('age').number(),}))const schema = JsonSchema.output(spec)Options
Section titled “Options”JsonSchema.output(plan, { draft: 'draft-07', id: 'https://example.com/user.schema.json', title: 'User', description: 'A user record', deduplicate: true,})| Option | Effect |
|---|---|
draft | JSON Schema dialect: 'draft-07', '2019-09', or '2020-12' (default). Draft-07 uses definitions; 2019-09 and 2020-12 use $defs. |
id | Sets $id on root schema |
title | Sets title on root schema |
description | Sets description on root schema |
deduplicate | Extracts repeated sub-schemas into $defs/definitions with $ref pointers |
Property metadata
Section titled “Property metadata”describe(path, meta) attaches annotations to an extraction. These appear in the derived JSON Schema.
.emit((out, $) => out .add('email', $.get('email').string()) .describe('email', { description: 'User email', format: 'email' }) .add('age', $.get('age').number()) .describe('age', { minimum: 0, maximum: 150 }))Supported OutputMeta fields: description, title, examples, deprecated, format, pattern, minimum, maximum, minLength, maxLength, enum.
Deduplication
Section titled “Deduplication”When deduplicate: true, repeated sub-schemas are extracted into $defs (or definitions for Draft-07) and replaced with $ref pointers.
Naming strategy:
- Property key — the parent property name (e.g., property
home→ defHome) - Singularized array items — array item schemas use a singularized form (e.g.,
addresses→Address) - Property-set fallback — object schemas with ≤4 properties use PascalCase property names joined (e.g.,
NameAge) - Counter fallback —
Schema1,Schema2, etc.
Manual override via $defName in OutputMeta:
.describe('addresses', { $defName: 'PostalAddress' })Spec kind mapping
Section titled “Spec kind mapping”| Spec | Schema |
|---|---|
extract (string/number/boolean/null/date/datetime) | { type: T } with optional default |
literal | { const: value } |
array | { type: 'array', items: ... } |
object | { type: 'object', properties: ..., required: [...] } |
match | Union of branch schemas via anyOf or type merge |
concat | { type: 'array', items: merged } |
try | Union of all fallback schemas |
map | Schema of the source spec |
guard | Schema of the source spec |
panic | {} (never produces output) |