jsonschema

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 14 Imported by: 0

README

jsonschema

CI

If you consume or produce JSON that has a schema, jsonschema gives you two things the Go ecosystem has been missing at once: a validator that actually implements the whole spec — 100% of the official JSON Schema Test Suite's required set for draft 2020-12, 2019-09, and draft-07, including $ref/$dynamicRef, oneOf, if/then/else, unevaluated*, and vocabularies (details and the one inherent gap) — and a code generator that turns a schema into idiomatic Go types whose UnmarshalJSON and Validate enforce that schema for you. Point it at a schema and get structs, enums, discriminated-union interfaces, embedded compositions, and typed constraints, with no reflection, no hand-written validation, and no third-party runtime dependency in the code it emits. Reach for the validator when you work with dynamic data, the generator when you want compile-time types — or both, over the same schema, backed by the same engine so they never disagree.

Contents

Install

# the library (validator + generator API)
go get github.com/ChristopherDavenport/jsonschema

# the generator CLI
go install github.com/ChristopherDavenport/jsonschema/cmd/jsonschema-gen@latest

Runtime validation

Compile a schema once, validate many decoded values. Instances are the shapes encoding/json produces (nil, bool, float64/json.Number, string, []any, map[string]any); decode with UseNumber so numbers compare exactly.

import (
	"bytes"
	"encoding/json"

	"github.com/ChristopherDavenport/jsonschema"
)

sch, err := jsonschema.Compile(schemaBytes)
if err != nil {
	return err
}

dec := json.NewDecoder(bytes.NewReader(dataBytes))
dec.UseNumber()
var v any
if err := dec.Decode(&v); err != nil {
	return err
}

if err := sch.Validate(v); err != nil {
	// err describes every failure, with JSON-Pointer instance locations.
}

For multi-document schemas, remote references, or format assertion, use a Compiler:

c := jsonschema.NewCompiler().AssertFormat(true)
_ = c.AddResource("https://example.com/root.json", rootBytes)
_ = c.AddResource("https://example.com/defs.json", defsBytes) // resolves a $ref
sch, err := c.Compile("https://example.com/root.json")

format is annotation-only by default (per spec); AssertFormat(true) turns it into an assertion. RegisterMetaSchemas() bundles the official meta-schemas so a document can validate itself against its $schema.

Code generation, from simple to complex

Each example below is the generated output of jsonschema-gen (lightly trimmed — repeated UnmarshalJSON boilerplate is elided where a prior example already shows it, along with the godoc comment on each declaration). Every generated type, method, and constant carries a godoc comment — the schema's description (or title) when present, a sensible default otherwise — so go doc and pkg.go.dev render usefully. Wire the generator into your build with go:generate:

//go:generate jsonschema-gen -package user -root User -o user.gen.go user.schema.json
1. Objects and required fields

The foundation: an object becomes a struct; optional fields become pointers with omitzero; required fields are enforced at decode time by a generated UnmarshalJSON (since encoding/json cannot otherwise tell absent from zero). omitzero (Go 1.24) omits only the zero value, so an empty-but-present array or map round-trips instead of being erased.

{
  "type": "object",
  "required": ["id", "email"],
  "properties": {
    "id":     { "type": "integer" },
    "email":  { "type": "string" },
    "active": { "type": "boolean" }
  }
}
type User struct {
	Active *bool  `json:"active,omitzero"`
	Email  string `json:"email"`
	ID     int64  `json:"id"`
}

func (x *User) UnmarshalJSON(data []byte) error {
	var raw map[string]json.RawMessage
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	for _, k := range []string{"email", "id"} {
		if _, ok := raw[k]; !ok {
			return fmt.Errorf("missing required property %q", k)
		}
	}
	type shadow struct {
		Active *bool  `json:"active,omitzero"`
		Email  string `json:"email"`
		ID     int64  `json:"id"`
	}
	var sh shadow
	if err := json.Unmarshal(data, &sh); err != nil {
		return err
	}
	x.Active, x.Email, x.ID = sh.Active, sh.Email, sh.ID
	return nil
}

func (x *User) Validate() error { return nil }
2. Constraints, formats, and enums

Assertions become inline checks in Validate; an enum becomes a named type with typed constants and its own Validate. -assert-format emits format checks that call the dependency-free xvalid helpers.

{
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id":   { "type": "string", "format": "uuid" },
    "name": { "type": "string", "minLength": 1, "maxLength": 80 },
    "age":  { "type": "integer", "minimum": 0, "maximum": 130 },
    "role": { "enum": ["admin", "user", "guest"] }
  }
}
type Account struct {
	Age  *int64       `json:"age,omitzero"`
	ID   string       `json:"id"`
	Name string       `json:"name"`
	Role *AccountRole `json:"role,omitzero"`
}

// (UnmarshalJSON enforces the required id and name, as in example 1.)

func (x *Account) Validate() error {
	if x.Age != nil {
		if *x.Age < int64(0) {
			return fmt.Errorf("age: below minimum")
		}
		if *x.Age > int64(130) {
			return fmt.Errorf("age: above maximum")
		}
	}
	if ok, _ := xvalid.CheckFormat("uuid", x.ID); !ok {
		return fmt.Errorf("id: invalid uuid")
	}
	if utf8.RuneCountInString(x.Name) < 1 {
		return fmt.Errorf("name: too short")
	}
	if utf8.RuneCountInString(x.Name) > 80 {
		return fmt.Errorf("name: too long")
	}
	if x.Role != nil {
		if err := x.Role.Validate(); err != nil {
			return err
		}
	}
	return nil
}

type AccountRole string

const (
	AccountRoleAdmin AccountRole = "admin"
	AccountRoleUser  AccountRole = "user"
	AccountRoleGuest AccountRole = "guest"
)

func (x AccountRole) Validate() error {
	switch x {
	case AccountRoleAdmin, AccountRoleUser, AccountRoleGuest:
		return nil
	}
	return fmt.Errorf("AccountRole: invalid value %v", x)
}
3. Arrays, maps, and references

items → a slice; uniqueItems → a dedup check; additionalProperties of a type → a map[string]T dictionary; a $ref → the named type it points at, whose Validate is called through the parent. A pattern compiles once into a package-level variable.

{
  "type": "object",
  "properties": {
    "tags":    { "type": "array", "items": {"type": "string"}, "uniqueItems": true },
    "labels":  { "type": "object", "additionalProperties": {"type": "string"} },
    "address": { "$ref": "#/$defs/address" }
  },
  "$defs": {
    "address": {
      "type": "object",
      "required": ["street"],
      "properties": {
        "street": {"type": "string"},
        "zip":    {"type": "string", "pattern": "^[0-9]{5}$"}
      }
    }
  }
}
type Resource struct {
	Address *Address          `json:"address,omitzero"`
	Labels  map[string]string `json:"labels,omitzero"`
	Tags    []string          `json:"tags,omitzero"`
}

func (x *Resource) Validate() error {
	if x.Address != nil {
		if err := x.Address.Validate(); err != nil {
			return err
		}
	}
	{
		arr := x.Tags
		for i := 0; i < len(arr); i++ {
			for j := i + 1; j < len(arr); j++ {
				if reflect.DeepEqual(arr[i], arr[j]) {
					return fmt.Errorf("tags: items are not unique")
				}
			}
		}
	}
	return nil
}

// Address is generated too, with its own required-enforcing UnmarshalJSON and:
func (x *Address) Validate() error {
	if x.Zip != nil {
		if !pattern0.MatchString(*x.Zip) {
			return fmt.Errorf("zip: does not match pattern")
		}
	}
	return nil
}

var pattern0 = xvalid.MustCompilePattern("^[0-9]{5}$")
4. oneOf — discriminated unions as interfaces

oneOf/anyOf become a sealed marker interface with a generated variant type per branch and an Unmarshal<Name> that selects the matching one (and enforces oneOf's exactly-one rule). The parent decodes the field as raw JSON and routes it through that dispatcher — so encoding/json, which cannot populate an interface on its own, just works.

{
  "type": "object",
  "required": ["payment"],
  "properties": {
    "payment": { "oneOf": [ {"$ref": "#/$defs/card"}, {"$ref": "#/$defs/bank"} ] }
  },
  "$defs": {
    "card": {"type": "object", "required": ["cardNumber"], "properties": {"cardNumber": {"type": "string"}}},
    "bank": {"type": "object", "required": ["iban"], "properties": {"iban": {"type": "string"}}}
  }
}
type Order struct {
	Payment OrderPayment `json:"payment"`
}

type OrderPayment interface{ isOrderPayment() }

type Card struct {
	CardNumber string `json:"cardNumber"`
}
type Bank struct {
	Iban string `json:"iban"`
}

func (_ Card) isOrderPayment() {}
func (_ Bank) isOrderPayment() {}

func UnmarshalOrderPayment(data []byte) (OrderPayment, error) {
	var matches []OrderPayment
	{
		var v0 Card
		if err := json.Unmarshal(data, &v0); err == nil {
			if val, ok := any(&v0).(interface{ Validate() error }); !ok || val.Validate() == nil {
				matches = append(matches, &v0)
			}
		}
	}
	{
		var v1 Bank
		if err := json.Unmarshal(data, &v1); err == nil {
			if val, ok := any(&v1).(interface{ Validate() error }); !ok || val.Validate() == nil {
				matches = append(matches, &v1)
			}
		}
	}
	switch len(matches) {
	case 1:
		return matches[0], nil
	case 0:
		return nil, fmt.Errorf("OrderPayment: value matches no variant")
	default:
		return nil, fmt.Errorf("OrderPayment: value matches %d variants, want exactly one", len(matches))
	}
}

func (x *Order) UnmarshalJSON(data []byte) error {
	// ... required check ...
	type shadow struct {
		Payment json.RawMessage `json:"payment"`
	}
	var sh shadow
	if err := json.Unmarshal(data, &sh); err != nil {
		return err
	}
	if len(sh.Payment) > 0 {
		v, err := UnmarshalOrderPayment(sh.Payment)
		if err != nil {
			return err
		}
		x.Payment = v
	}
	return nil
}

Consuming it is a type switch:

var o Order
_ = json.Unmarshal(data, &o)
switch p := o.Payment.(type) {
case *Card:
	useCard(p)
case *Bank:
	useBank(p)
}
5. allOf — composition as struct embedding

An allOf whose every member is an object schema — directly or through a $ref — becomes Go struct embedding. Each part decodes from the full object (so it enforces its own required), the composite Validate delegates to each part, and a generated MarshalJSON merges the parts back into one flat object.

{
  "allOf": [ {"$ref": "#/$defs/base"}, {"$ref": "#/$defs/audit"} ],
  "$defs": {
    "base":  {"type": "object", "required": ["id"], "properties": {"id": {"type": "string"}}},
    "audit": {"type": "object", "required": ["createdBy"], "properties": {"createdBy": {"type": "string"}}}
  }
}
type Record struct {
	Base
	Audit
}

func (x *Record) UnmarshalJSON(data []byte) error {
	var raw map[string]json.RawMessage
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	if err := json.Unmarshal(data, &x.Base); err != nil { // enforces Base's required id
		return err
	}
	if err := json.Unmarshal(data, &x.Audit); err != nil { // enforces Audit's required createdBy
		return err
	}
	return nil
}

func (x *Record) Validate() error {
	if err := x.Base.Validate(); err != nil {
		return err
	}
	if err := x.Audit.Validate(); err != nil {
		return err
	}
	return nil
}

x.ID and x.CreatedBy are promoted, so Record reads like one flat struct.

Marshaling merges the parts rather than relying on Go's promotion rules, which cannot express two of the compositions the schema allows: a property declared by two members would be an ambiguous promoted field and get dropped from the output entirely, and a free-form additionalProperties member is a map that would nest under its own type name. Merging emits one flat object either way, with the earlier part winning a shared key:

allOf: [Base{id,name}, Audit{id,createdBy}, Extras{additionalProperties}]
{"id":"1","name":"n","createdBy":"me","extra":"e"}   // in, and back out again

Members that are not object schemas — a scalar, an array, a union — have no properties to contribute, so those compositions fall to one of the two modes below.

6. if/then/else — conditional requirements

When the if is a string-value discriminator and the branches add required, the condition becomes a plain Go conditional (matching the spec's rule that properties alone does not require presence).

{
  "type": "object",
  "properties": {
    "kind":   {"type": "string"},
    "secret": {"type": "string"}
  },
  "if":   {"properties": {"kind": {"const": "private"}}},
  "then": {"required": ["secret"]}
}
func (x *Item) Validate() error {
	if x.Kind == nil || *x.Kind == "private" {
		if x.Secret == nil {
			return fmt.Errorf("\"secret\" is required here")
		}
	}
	return nil
}

The recognized shape is deliberately narrow: the tag is matched by a plain-string const/enum and nothing else, its field's Go type is string, and the branches carry only required naming declared properties. Anything outside that — a numeric tag, an enum-typed field, a then with its own constraints — is refused rather than half-mirrored, and falls to one of the two modes below, where the generated NOTE names the rule it missed.

Using the generated code

Generate into a package inside your module and import it like any other. The -package flag names the package; the output file goes wherever you point -o:

//go:generate jsonschema-gen -package schema -root Order -o schema/order.gen.go order.schema.json
import "example.com/app/schema"

Decode and validate. The generated UnmarshalJSON enforces required properties as it decodes; call Validate for everything else. The two are separate on purpose — decoding tells you the shape is right, Validate tells you the values are.

var u schema.User
if err := json.Unmarshal(data, &u); err != nil {
	// e.g. missing required "email"
}
if err := u.Validate(); err != nil {
	// e.g. a constraint violation
}

Construct values yourself. The types are ordinary structs — build them with literals. Optional fields are pointers, enums are typed constants, and Validate / json.Marshal work on values you make, not just ones you decode.

name := "Ada"
role := schema.AccountRoleAdmin // typed enum constant
acct := schema.Account{
	ID:   "550e8400-e29b-41d4-a716-446655440000",
	Name: name,
	Role: &role, // optional field -> pointer
}
_ = acct.Validate() // <nil>
b, _ := json.Marshal(acct)
// {"id":"550e8400-e29b-41d4-a716-446655440000","name":"Ada","role":"admin"}

Set a oneOf field. Assign a concrete variant to the interface field — that is all the marker interface asks of you. It marshals as its underlying object and decodes back to the same concrete type, which you recover with a type switch. (If you already hold the raw JSON for just that field, UnmarshalOrderPayment(raw) returns the variant directly.)

order := schema.Order{Payment: &schema.Card{CardNumber: "4111111111111111"}}
b, _ := json.Marshal(order)
// {"payment":{"cardNumber":"4111111111111111"}}

var back schema.Order
_ = json.Unmarshal(b, &back)
switch p := back.Payment.(type) {
case *schema.Card:
	useCard(p)
case *schema.Bank:
	useBank(p)
}

Fill an allOf composition. Embedded parts promote their fields, so you set them directly and marshal to one flat object.

var rec schema.Record
rec.ID = "r-1"        // promoted from Base
rec.CreatedBy = "ada" // promoted from Audit
_ = rec.Validate()
b, _ := json.Marshal(rec)
// {"id":"r-1","createdBy":"ada"}

All output comments above are the real results of running this code against the generated types.

The x-go extension

Steer generation per-schema, without leaving the document:

{
  "type": "object",
  "properties": {
    "createdAt": { "type": "string", "format": "date-time", "x-go": {"type": "time.Time", "import": "time"} }
  }
}

x-go fields: type (Go type used verbatim), import (its package path), name (override the generated identifier), pointer (force or forbid a pointer), and extraTags (extra key:value struct tags, e.g. for another library).

Conditional and combinator keywords

allOf (example 5) and string-discriminator if/then/else (example 6) are generated as idiomatic Go. The remaining in-place keywords — general if/then/else, dependentSchemas, and not — would require emitting an arbitrary subschema as a boolean predicate, which amounts to re-implementing the validator as generated code. For those there are two modes:

  • Default: the type and a Validate are still generated, the keyword is not enforced, and a NOTE comment names exactly what was skipped — on the Validate method for a struct, on the type declaration for an alias, enum, or union interface. Output depends only on the standard library and xvalid.

    // Validate reports whether x satisfies the constraints this type mirrors inline.
    //
    // NOTE: it does not enforce:
    //   - if/then/else: then requires "value", which is not a declared property
    //
    // Regenerate with -engine-fallback, or validate with the jsonschema engine.
    

    It lists only what is actually unenforced: a schema whose discriminator if is mirrored but that also uses not gets a NOTE naming not alone. The last line also says whether -engine-fallback would resolve the item — it cannot when the keyword constrains a property the Go type does not declare, since the delegating Validate sees only the marshaled value:

    // -engine-fallback cannot enforce "not" here: it validates the marshaled value
    // of this type, which never carries "ghost". Validate the original document
    // with the jsonschema engine instead.
    
  • -engine-fallback: Validate for such a type delegates to the embedded schema evaluated by the runtime engine — engine-grade conformance, at the cost of a dependency on the jsonschema package and a marshal round-trip. Where the round trip cannot carry what the keyword constrains, the delegating Validate carries a NOTE saying so instead of claiming conformance it cannot deliver.

The generator never half-mirrors a keyword: a schema that falls outside a recognized shape gets the NOTE, not a Validate that quietly skips part of it. Two limits are worth knowing before you rely on this: the fallback only rewrites Validate on struct types, and it validates the marshaled Go value rather than the original document. If you use either mode — or if a conditional you expected to be enforced isn't — read docs/conditionals.md: it gives the exact shapes each inline path recognizes, the near misses, the two remaining gaps, and recipes for working around them. Either way, the runtime engine is always available for complete coverage.

You do not have to read the generated source to find these: jsonschema-gen prints the same information to stderr as it generates, so it lands in your go generate log.

$ jsonschema-gen -package demo -root Item -o item.gen.go item.schema.json
wrote item.gen.go

3 constraints in 2 types not enforced by the generated code:

  Item
    - not
      fix: validate the document with the jsonschema engine — -engine-fallback
      cannot enforce this: it validates the marshaled value of this type, which
      never carries the properties this keyword constrains ("ghost")
    - dependentSchemas ("kind")
      fix: regenerate with -engine-fallback, or validate the document with the
      jsonschema engine

  Meta (no Validate method: not a struct or enum)
    - allOf: member 1 is not an object schema
      fix: validate the document with the jsonschema engine — -engine-fallback
      cannot enforce this: it rewrites Validate methods, and this type has none

Regenerating with -engine-fallback would enforce 1 constraint.

A schema the generator mirrors completely prints nothing. Regenerating the same schema with -engine-fallback drops the dependentSchemas line — the engine enforces it now — and keeps the other two, which it genuinely cannot. Pass -strict to exit non-zero while anything remains unenforced, for a CI gate; the report prints either way. Programmatically, gen.GenerateWithReport returns the same thing as a *gen.Report.

The CLI takes these values as flags or from a YAML config (-config gen.yaml, with flags overriding it):

package: person
rootName: Person
assertFormat: true
strict: true
input: person.schema.json
output: person.gen.go

Conformance

The validator passes the official JSON Schema Test Suite required set at 100%, enforced as a CI gate:

Draft Passing
2020-12 1299 / 1299 (100%)
2019-09 1259 / 1259 (100%)
draft-07 927 / 927 (100%)

This includes full $dynamicRef/$recursiveRef dynamic-scope resolution, offline meta-schema self-validation, and vocabulary-aware keyword gating. See CONFORMANCE.md for details and the one remaining limitation: Go's RE2 has no lookaround or backreferences, so pattern needs a different regexp engine for those — supply one with xvalid.UseRegexpEngine.

Coverage vs. omissis/go-jsonschema

The two columns below describe generated code. The runtime validator implements every keyword in this table — the distinction only matters for the generator.

Legend: ✅ validated & generated · 🔶 validated by the engine; the generator reports it as unenforced (a NOTE, the report, and a -strict failure) · ⚙️ typed only · ❌ ignored/absent.

Feature jsonschema (this) omissis/go-jsonschema
type, properties, required, enum
const, numeric, string constraints
uniqueItems, dependentRequired
oneOf (interface + variants)
anyOf partial
allOf (struct embedding) ✅ (embedding inline; rest via fallback) partial
not ✅ (validate; generate via fallback) partial
if / then / else ✅ (discriminator inline; rest via fallback)
dependentSchemas ✅ (validate; generate via fallback)
contains / min/maxContains ✅ (validate; generate via fallback)
unevaluatedItems ✅ (validate; generate via fallback)
min/maxProperties 🔶
patternProperties, propertyNames 🔶
unevaluatedProperties 🔶
prefixItems / tuples
Boolean subschemas (true/false) partial
format assertion (uuid/email/uri/…) ✅ (opt-in)
nested $ref, remote refs, recursion partial
$dynamicRef / $recursiveRef
meta-schema self-validation (bundled)

The 🔶 rows are the keywords a generated struct cannot enforce even with -engine-fallback: the engine validates the marshaled value, which carries only the properties the Go type declares, so a count or a name test over its key set would answer a different question than the schema asked. They are announced rather than silently dropped — see docs/conditionals.md §5.3.

Package layout

Package Purpose
jsonschema Compile a schema and validate decoded any (the runtime validator + conformance target).
jsonschema/ir Internal schema model — a Bool | Object sum type carrying every 2020-12 keyword.
jsonschema/dialect Detect $schema and normalize 2019-09 / draft-07 onto the canonical model.
jsonschema/loader Load JSON, resolve $id/$ref/$anchor/$defs, remote refs, cycles.
jsonschema/gotype Map the model to a Go type model.
jsonschema/gen Emit Go source: types + Validate + custom (un)marshalers.
jsonschema/xvalid Zero-dependency runtime helpers the generated code calls.
jsonschema/metaschema The bundled official meta-schemas.
cmd/jsonschema-gen The command-line generator.

License

MIT — see LICENSE. Bundled third-party content is attributed in NOTICE.

Documentation

Overview

Package jsonschema compiles JSON Schema documents and validates decoded JSON values against them. It accepts draft 2020-12, 2019-09 and draft-07 (all normalized to a canonical 2020-12 model) and is the conformance-anchored core that the code generator mirrors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Compiler

type Compiler struct {
	// contains filtered or unexported fields
}

Compiler accumulates schema resources and compiles them into validators.

func NewCompiler

func NewCompiler() *Compiler

NewCompiler returns an empty Compiler.

func (*Compiler) AddAndCompile

func (c *Compiler) AddAndCompile(uri string, data []byte) (*Schema, error)

AddAndCompile parses data, registers it under uri, and returns a validator for its root — even if a top-level $id relocated the root's canonical URI.

func (*Compiler) AddResource

func (c *Compiler) AddResource(uri string, data []byte) error

AddResource parses a JSON schema document and registers it (and its subschemas) under the given canonical URI, so later references can resolve to it. Call this for the root schema and for any remote documents it references.

func (*Compiler) AssertFormat

func (c *Compiler) AssertFormat(on bool) *Compiler

AssertFormat controls whether the `format` keyword is enforced as an assertion (true) or collected as an annotation only (false, the spec default). It returns the compiler for chaining.

func (*Compiler) Compile

func (c *Compiler) Compile(uri string) (*Schema, error)

Compile returns a validator for a previously added resource URI.

func (*Compiler) DefaultDraft

func (c *Compiler) DefaultDraft(d dialect.Draft) *Compiler

DefaultDraft sets the draft assumed for documents without a $schema keyword. It returns the compiler for chaining.

func (*Compiler) RegisterMetaSchemas

func (c *Compiler) RegisterMetaSchemas() (*Compiler, error)

RegisterMetaSchemas registers the bundled official meta-schemas so that a document referencing one (e.g. for self-validation) resolves offline. It returns the compiler for chaining.

type Schema

type Schema struct {
	// contains filtered or unexported fields
}

Schema is a compiled schema ready to validate instances.

func Compile

func Compile(data []byte) (*Schema, error)

Compile is a convenience that compiles a single self-contained schema document with no external references.

func (*Schema) Validate

func (s *Schema) Validate(instance any) error

Validate reports whether instance (a value decoded by encoding/json into an any: nil, bool, float64, string, []any, map[string]any) satisfies the schema. A non-nil error describes every failure.

Directories

Path Synopsis
cmd
jsonschema-gen command
Command jsonschema-gen generates Go types with inline validation from a JSON Schema document.
Command jsonschema-gen generates Go types with inline validation from a JSON Schema document.
Package dialect detects which JSON Schema draft a document targets and normalizes older drafts onto the canonical 2020-12 ir model, so the rest of the toolchain only ever sees one dialect.
Package dialect detects which JSON Schema draft a document targets and normalizes older drafts onto the canonical 2020-12 ir model, so the rest of the toolchain only ever sees one dialect.
Package gen turns a JSON Schema document into Go source: named types plus Validate methods whose inline checks mirror the jsonschema validation engine, so the generated code enforces the schema with no third-party runtime dependency (only the first-party xvalid helpers).
Package gen turns a JSON Schema document into Go source: named types plus Validate methods whose inline checks mirror the jsonschema validation engine, so the generated code enforces the schema with no third-party runtime dependency (only the first-party xvalid helpers).
Package gotype maps a compiled ir schema graph onto a model of named Go types.
Package gotype maps a compiled ir schema graph onto a model of named Go types.
Package ir defines the internal representation of a JSON Schema: a single canonical model, aligned with draft 2020-12, onto which every supported dialect is normalized.
Package ir defines the internal representation of a JSON Schema: a single canonical model, aligned with draft 2020-12, onto which every supported dialect is normalized.
Package loader parses JSON Schema documents into the ir model and resolves the referencing layer: $id/base-URI resolution, $ref/$anchor/$defs, remote documents, and cycle-safe indexing of every schema resource by canonical URI.
Package loader parses JSON Schema documents into the ir model and resolves the referencing layer: $id/base-URI resolution, $ref/$anchor/$defs, remote documents, and cycle-safe indexing of every schema resource by canonical URI.
Package metaschema bundles the official JSON Schema meta-schemas so that documents which reference them (for self-validation) resolve offline.
Package metaschema bundles the official JSON Schema meta-schemas so that documents which reference them (for self-validation) resolve offline.
Package xvalid provides the small, dependency-free runtime that both the validation engine and generated code rely on: JSON value-equality, semantic format checks, and a structured validation error type.
Package xvalid provides the small, dependency-free runtime that both the validation engine and generated code rely on: JSON value-equality, semantic format checks, and a structured validation error type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL