jsonschema

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2024 License: Apache-2.0 Imports: 24 Imported by: 0

README

jsonschema v6.0.1

License GoDoc Go Report Card Build Status codecov

see godoc for examples

Library Features

  • pass JSON-Schema-Test-Suite excluding optional(compare with other impls at bowtie)
    • draft-04
    • draft-06
    • draft-07
    • draft/2019-09
    • draft/2020-12
  • detect infinite loop traps
    • $schema cycle
    • validation cycle
  • custom $schema url
  • vocabulary based validation
  • custom regex engine
  • format assertions
    • flag to enable in draft >= 2019-09
    • custom format registration
    • built-in formats
      • regex, uuid
      • ipv4, ipv6
      • hostname, email
      • date, time, date-time, duration
      • json-pointer, relative-json-pointer
      • uri, uri-reference, uri-template
      • iri, iri-reference
      • period, semver
  • content assertions
    • flag to enable in draft >= 7
    • contentEncoding
      • base64
      • custom
    • contentMediaType
      • application/json
      • custom
    • contentSchema
  • errors
    • introspectable
    • hierarchy
      • alternative display with #
    • output
      • flag
      • basic
      • detailed
  • custom vocabulary
    • enable via $vocabulary for draft >=2019-19
    • enable via flag for draft <= 7
  • mixed dialect support

CLI v0.7.0

to install: go install github.com/santhosh-tekuri/jsonschema/cmd/jv@latest

Note that the cli is versioned independently. you can see it in git tags cmd/jv/v0.7.0

Usage: jv [OPTIONS] SCHEMA [INSTANCE...]

Options:
  -c, --assert-content    Enable content assertions with draft >= 7
  -f, --assert-format     Enable format assertions with draft >= 2019
      --cacert pem-file   Use the specified pem-file to verify the peer. The file may contain multiple CA certificates
  -d, --draft version     Draft version used when '$schema' is missing. Valid values 4, 6, 7, 2019, 2020 (default 2020)
  -h, --help              Print help information
  -k, --insecure          Use insecure TLS connection
  -o, --output format     Output format. Valid values simple, alt, flag, basic, detailed (default "simple")
  -q, --quiet             Do not print errors
  -v, --version           Print build information
  • exit code 1 for validation errors, 2 for usage errors
  • validate both schema and multiple instances
  • support both json and yaml files
  • support standard input, use -
  • quite mode with parsable output
  • http(s) url support
    • custom certs for validation, use --cacert
    • flag to skip certificate verification, use --insecure

Documentation

Overview

Example (CustomContentEndocing)

Example_customContentEncoding shows how to define "hex" contentEncoding.

package main

import (
	"encoding/hex"
	"fmt"

	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"strings"
)

func main() {
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{"type": "string", "contentEncoding": "hex"}`))
	if err != nil {
		log.Fatal(err)
	}
	inst := "abcxyz"

	c := jsonschema.NewCompiler()
	c.RegisterContentEncoding(&jsonschema.Decoder{
		Name:   "hex",
		Decode: hex.DecodeString,
	})
	c.AssertContent()
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}
	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: false
Example (CustomContentMediaType)

Example_customContentMediaType shows how to define "application/xml" contentMediaType.

package main

import (
	"encoding/xml"
	"fmt"

	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"strings"
)

func main() {
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{"type": "string", "contentMediaType": "application/xml"}`))
	if err != nil {
		log.Fatal(err)
	}
	inst := "<abc></def>"

	c := jsonschema.NewCompiler()
	c.RegisterContentMediaType(&jsonschema.MediaType{
		Name: "application/xml",
		Validate: func(b []byte) error {
			return xml.Unmarshal(b, new(any))
		},
		UnmarshalJSON: nil, // xml is not json-compatible format
	})
	c.AssertContent()
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}
	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: false
Example (CustomFormat)
package main

import (
	"fmt"

	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"strings"
)

func main() {
	validatePalindrome := func(v any) error {
		s, ok := v.(string)
		if !ok {
			return nil
		}
		var runes []rune
		for _, r := range s {
			runes = append(runes, r)
		}
		for i, j := 0, len(runes)-1; i <= j; i, j = i+1, j-1 {
			if runes[i] != runes[j] {
				return fmt.Errorf("no match for rune at %d", i)
			}
		}
		return nil
	}

	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{"type": "string", "format": "palindrome"}`))
	if err != nil {
		log.Fatal(err)
	}
	inst := "hello world"

	c := jsonschema.NewCompiler()
	c.RegisterFormat(&jsonschema.Format{
		Name:     "palindrome",
		Validate: validatePalindrome,
	})
	c.AssertFormat()
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}
	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: false
Example (CustomRegexpEngine)

Example_customRegexpEngine shows how to use dlclark/regexp2 instead of regexp from standard library.

package main

import (
	"fmt"
	jsonschema "gitee.com/jack1995/jsonschema"
	"github.com/dlclark/regexp2"
	"log"
	"strings"
)

type dlclarkRegexp regexp2.Regexp

func (re *dlclarkRegexp) MatchString(s string) bool {
	matched, err := (*regexp2.Regexp)(re).MatchString(s)
	return err == nil && matched
}

func (re *dlclarkRegexp) String() string {
	return (*regexp2.Regexp)(re).String()
}

func dlclarkCompile(s string) (jsonschema.Regexp, error) {
	re, err := regexp2.Compile(s, regexp2.ECMAScript)
	if err != nil {
		return nil, err
	}
	return (*dlclarkRegexp)(re), nil
}

// Example_customRegexpEngine shows how to use dlclark/regexp2
// instead of regexp from standard library.
func main() {
	// golang regexp does not support escape sequence: `\c`
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"type": "string",
		"pattern": "^\\cc$"
	}`))
	if err != nil {
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(strings.NewReader(`"\u0003"`))
	if err != nil {
		log.Fatal(err)
	}

	c := jsonschema.NewCompiler()
	c.UseRegexpEngine(dlclarkCompile)
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}

	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}
	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: true
Example (FromFiles)
package main

import (
	"fmt"

	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"os"
)

func main() {
	schemaFile := "./testdata/examples/schema.json"
	instanceFile := "./testdata/examples/instance.json"

	c := jsonschema.NewCompiler()
	sch, err := c.Compile(schemaFile)
	if err != nil {
		log.Fatal(err)
	}

	f, err := os.Open(instanceFile)
	if err != nil {
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(f)
	if err != nil {
		log.Fatal(err)
	}

	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: true
Example (FromHTTPS)
package main

import (
	"crypto/tls"
	"fmt"
	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"net/http"
	"os"
	"time"
)

type HTTPURLLoader http.Client

func (l *HTTPURLLoader) Load(url string) (any, error) {
	client := (*http.Client)(l)
	resp, err := client.Get(url)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		_ = resp.Body.Close()
		return nil, fmt.Errorf("%s returned status code %d", url, resp.StatusCode)
	}
	defer resp.Body.Close()

	return jsonschema.UnmarshalJSON(resp.Body)
}

func newHTTPURLLoader(insecure bool) *HTTPURLLoader {
	httpLoader := HTTPURLLoader(http.Client{
		Timeout: 15 * time.Second,
	})
	if insecure {
		httpLoader.Transport = &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
	}
	return &httpLoader
}

func main() {
	schemaURL := "https://raw.githubusercontent.com/santhosh-tekuri/boon/main/tests/examples/schema.json"
	instanceFile := "./testdata/examples/instance.json"

	loader := jsonschema.SchemeURLLoader{
		"file":  jsonschema.FileLoader{},
		"http":  newHTTPURLLoader(false),
		"https": newHTTPURLLoader(false),
	}

	c := jsonschema.NewCompiler()
	c.UseLoader(loader)
	sch, err := c.Compile(schemaURL)
	if err != nil {
		log.Fatal(err)
	}

	f, err := os.Open(instanceFile)
	if err != nil {
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(f)
	if err != nil {
		log.Fatal(err)
	}

	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: true
Example (FromStrings)
package main

import (
	"fmt"

	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"strings"
)

func main() {
	catSchema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
        "type": "object",
        "properties": {
            "speak": { "const": "meow" }
        },
        "required": ["speak"]
    }`))
	if err != nil {
		log.Fatal(err)
	}
	// note that dog.json is loaded from file ./testdata/examples/dog.json
	petSchema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
        "oneOf": [
            { "$ref": "dog.json" },
            { "$ref": "cat.json" }
        ]
    }`))
	if err != nil {
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(strings.NewReader(`{"speak": "bow"}`))
	if err != nil {
		log.Fatal(err)
	}

	c := jsonschema.NewCompiler()
	if err := c.AddResource("./testdata/examples/cat.json", catSchema); err != nil {
		log.Fatal(err)
	}
	if err := c.AddResource("./testdata/examples/pet.json", petSchema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("./testdata/examples/pet.json")
	if err != nil {
		log.Fatal(err)
	}
	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: true
Example (Vocab_discriminator)
package main

import (
	"fmt"
	jsonschema "gitee.com/jack1995/jsonschema"
	"log"
	"strings"
)

// SchemaExt --

type discriminator struct {
	pname  string
	values map[string]*jsonschema.Schema
}

func (d *discriminator) Validate(ctx *jsonschema.ValidatorContext, v any) {
	obj, ok := v.(map[string]any)
	if !ok {
		return
	}
	pvalue, ok := obj[d.pname]
	if !ok {
		return
	}
	value, ok := pvalue.(string)
	if !ok {
		return
	}
	sch := d.values[value]
	if sch == nil {
		return
	}
	if err := ctx.Validate(sch, v, nil); err != nil {
		ctx.AddErr(err)
	} else {
		ctx.EvaluatedProp(d.pname)
	}
}

// Vocab --

func discriminatorVocab() *jsonschema.Vocabulary {
	url := "http://example.com/meta/discriminator"
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"discriminator": {
			"type": "object",
			"minProperties": 1,
			"maxProperties": 1,
			"patternProperties": {
				".*": {
					"type": "object",
					"patternProperties": {
						".*": {
							"$ref": "https://json-schema.org/draft/2020-12/schema"
						}
					}
				}
			}
		}
	}`))
	if err != nil {
		log.Fatal(err)
	}

	c := jsonschema.NewCompiler()
	if err := c.AddResource(url, schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile(url)
	if err != nil {
		log.Fatal(err)
	}

	return &jsonschema.Vocabulary{
		URL:    url,
		Schema: sch,
		Subschemas: []jsonschema.SchemaPath{
			{jsonschema.Prop("discriminator"), jsonschema.AllProp{}, jsonschema.AllProp{}},
		},
		Compile: compileDiscriminator,
	}
}

func compileDiscriminator(ctx *jsonschema.CompilerContext, obj map[string]any) (jsonschema.SchemaExt, error) {
	v, ok := obj["discriminator"]
	if !ok {
		return nil, nil
	}
	d, ok := v.(map[string]any)
	if !ok {
		return nil, nil
	}
	var pname string
	var pvalue any
	for key, value := range d {
		pname = key
		pvalue = value
		break
	}
	values := map[string]*jsonschema.Schema{}
	vm, ok := pvalue.(map[string]any)
	if !ok {
		return nil, nil
	}
	for value := range vm {
		values[value] = ctx.Enqueue([]string{"discriminator", pname, value})
	}
	return &discriminator{pname, values}, nil
}

// Example --

func main() {
	// if kind is fish, swimmingSpeed is required
	// if kind is dog, runningSpeed is required
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"type": "object",
		"properties": {
			"kind": { "type": "string" }
		},
		"required": ["kind"],
		"discriminator": {
			"kind": {
				"fish": {
					"type": "object",
					"properties": {
						"swimmingSpeed": { "type": "number" }
					},
					"required": ["swimmingSpeed"]
				},
				"dog": {
					"type": "object",
					"properties": {
						"runningSpeed": { "type": "number" }
					},
					"required": ["runningSpeed"]
				}
			}
		}
	}`))
	if err != nil {
		fmt.Println("xxx", err)
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"kind": "fish",
		"runningSpeed": 5
	}`))
	if err != nil {
		log.Fatal(err)
	}
	c := jsonschema.NewCompiler()
	c.AssertVocabs()
	c.RegisterVocabulary(discriminatorVocab())
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}

	err = sch.Validate(inst)
	fmt.Println("valid:", err == nil)
}
Output:

valid: false
Example (Vocab_uniquekeys)
package main

import (
	"fmt"
	jsonschema "gitee.com/jack1995/jsonschema"
	"golang.org/x/text/message"
	"log"
	"strings"
)

// SchemaExt --

type uniqueKeys struct {
	pname string
}

func (s *uniqueKeys) Validate(ctx *jsonschema.ValidatorContext, v any) {
	arr, ok := v.([]any)
	if !ok {
		return
	}
	var keys []any
	for _, item := range arr {
		obj, ok := item.(map[string]any)
		if !ok {
			continue
		}
		key, ok := obj[s.pname]
		if ok {
			keys = append(keys, key)
		}
	}

	i, j, err := ctx.Duplicates(keys)
	if err != nil {
		ctx.AddErr(err)
		return
	}
	if i != -1 {
		ctx.AddError(&UniqueKeys{Key: s.pname, Duplicates: []int{i, j}})
	}
}

// Vocab --

func uniqueKeysVocab() *jsonschema.Vocabulary {
	url := "http://example.com/meta/unique-keys"
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"properties": {
			"uniqueKeys": { "type": "string" }
		}
	}`))
	if err != nil {
		log.Fatal(err)
	}

	c := jsonschema.NewCompiler()
	if err := c.AddResource(url, schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile(url)
	if err != nil {
		log.Fatal(err)
	}

	return &jsonschema.Vocabulary{
		URL:     url,
		Schema:  sch,
		Compile: compileUniqueKeys,
	}
}

func compileUniqueKeys(ctx *jsonschema.CompilerContext, obj map[string]any) (jsonschema.SchemaExt, error) {
	v, ok := obj["uniqueKeys"]
	if !ok {
		return nil, nil
	}
	s, ok := v.(string)
	if !ok {
		return nil, nil
	}
	return &uniqueKeys{pname: s}, nil
}

// ErrorKind --

type UniqueKeys struct {
	Key        string
	Duplicates []int
}

func (*UniqueKeys) KeywordPath() []string {
	return []string{"uniqueKeys"}
}

func (k *UniqueKeys) LocalizedString(p *message.Printer) string {
	return p.Sprintf("items at %d and %d have same %s", k.Duplicates[0], k.Duplicates[1], k.Key)
}

// Example --

func main() {
	schema, err := jsonschema.UnmarshalJSON(strings.NewReader(`{
		"uniqueKeys": "id"
	}`))
	if err != nil {
		log.Fatal(err)
	}
	inst, err := jsonschema.UnmarshalJSON(strings.NewReader(`[
		{ "id": 1, "name": "alice" },
		{ "id": 2, "name": "bob" },
		{ "id": 1, "name": "scott" }
	]`))
	if err != nil {
		log.Fatal(err)
	}

	c := jsonschema.NewCompiler()
	c.AssertVocabs()
	c.RegisterVocabulary(uniqueKeysVocab())
	if err := c.AddResource("schema.json", schema); err != nil {
		log.Fatal(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		log.Fatal(err)
	}

	var aa = make(map[string]any)
	aa["111"] = "456"
	aa["222"] = "789"
	aa["333"] = "101112"

	err = sch.ValidateAndExt(inst, aa)
	fmt.Println("valid:", err == nil)
}
Output:

valid: false

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	Draft4 = &Draft{
		version: 4,
		url:     "http://json-schema.org/draft-04/schema",
		id:      "id",
		subschemas: []SchemaPath{

			schemaPath("definitions/*"),
			schemaPath("not"),
			schemaPath("allOf/[]"),
			schemaPath("anyOf/[]"),
			schemaPath("oneOf/[]"),

			schemaPath("properties/*"),
			schemaPath("additionalProperties"),
			schemaPath("patternProperties/*"),

			schemaPath("items"),
			schemaPath("items/[]"),
			schemaPath("additionalItems"),
			schemaPath("dependencies/*"),
		},
		vocabPrefix:   "",
		allVocabs:     map[string]*Schema{},
		defaultVocabs: []string{},
	}

	Draft6 = &Draft{
		version: 6,
		url:     "http://json-schema.org/draft-06/schema",
		id:      "$id",
		subschemas: joinSubschemas(Draft4.subschemas,
			schemaPath("propertyNames"),
			schemaPath("contains"),
		),
		vocabPrefix:   "",
		allVocabs:     map[string]*Schema{},
		defaultVocabs: []string{},
	}

	Draft7 = &Draft{
		version: 7,
		url:     "http://json-schema.org/draft-07/schema",
		id:      "$id",
		subschemas: joinSubschemas(Draft6.subschemas,
			schemaPath("if"),
			schemaPath("then"),
			schemaPath("else"),
		),
		vocabPrefix:   "",
		allVocabs:     map[string]*Schema{},
		defaultVocabs: []string{},
	}

	Draft2019 = &Draft{
		version: 2019,
		url:     "https://json-schema.org/draft/2019-09/schema",
		id:      "$id",
		subschemas: joinSubschemas(Draft7.subschemas,
			schemaPath("$defs/*"),
			schemaPath("dependentSchemas/*"),
			schemaPath("unevaluatedProperties"),
			schemaPath("unevaluatedItems"),
			schemaPath("contentSchema"),
		),
		vocabPrefix: "https://json-schema.org/draft/2019-09/vocab/",
		allVocabs: map[string]*Schema{
			"core":       nil,
			"applicator": nil,
			"validation": nil,
			"meta-data":  nil,
			"format":     nil,
			"content":    nil,
		},
		defaultVocabs: []string{"core", "applicator", "validation"},
	}

	Draft2020 = &Draft{
		version: 2020,
		url:     "https://json-schema.org/draft/2020-12/schema",
		id:      "$id",
		subschemas: joinSubschemas(Draft2019.subschemas,
			schemaPath("prefixItems/[]"),
		),
		vocabPrefix: "https://json-schema.org/draft/2020-12/vocab/",
		allVocabs: map[string]*Schema{
			"core":              nil,
			"applicator":        nil,
			"unevaluated":       nil,
			"validation":        nil,
			"meta-data":         nil,
			"format-annotation": nil,
			"format-assertion":  nil,
			"content":           nil,
		},
		defaultVocabs: []string{"core", "applicator", "unevaluated", "validation"},
	}
)

Functions

func BuildRef

func BuildRef(objectRefs *ObjectRef, keyword string, instanceMap map[string]any)

func ExtractValueByPath

func ExtractValueByPath(data map[string]any, path []string, keyword string) any

func LocalizableError

func LocalizableError(format string, args ...any) error

LocalizableError is an error whose message is localizable.

func UnmarshalJSON

func UnmarshalJSON(r io.Reader) (any, error)

UnmarshalJSON unmarshals into [any] without losing number precision using json.Number.

Types

type AllItem

type AllItem struct{}

type AllProp

type AllProp struct{}

type AnchorNotFoundError

type AnchorNotFoundError struct {
	URL       string
	Reference string
}

func (*AnchorNotFoundError) Error

func (e *AnchorNotFoundError) Error() string

type Compiler

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

Compiler compiles json schema into *Schema.

func NewCompiler

func NewCompiler() *Compiler

NewCompiler create Compiler Object.

func (*Compiler) AddResource

func (c *Compiler) AddResource(url string, doc any) error

AddResource adds schema resource which gets used later in reference resolution.

The argument url can be file path or url. Any fragment in url is ignored. The argument doc must be valid json value.

func (*Compiler) ApplyResource

func (c *Compiler) ApplyResource(url string, doc any) (bool, error)

func (*Compiler) AssertContent

func (c *Compiler) AssertContent()

AssertContent enables content assertions.

Content assertions include keywords:

  • contentEncoding
  • contentMediaType
  • contentSchema

Default behavior is always disabled.

func (*Compiler) AssertFormat

func (c *Compiler) AssertFormat()

AssertFormat always enables format assertions.

Default Behavior: for draft-07: enabled. for draft/2019-09: disabled unless metaschema says `format` vocabulary is required. for draft/2020-12: disabled unless metaschema says `format-assertion` vocabulary is required.

func (*Compiler) AssertVocabs

func (c *Compiler) AssertVocabs()

AssertVocabs always enables user-defined vocabularies assertions.

Default Behavior: for draft-07: enabled. for draft/2019-09: disabled unless metaschema enables a vocabulary. for draft/2020-12: disabled unless metaschema enables a vocabulary.

func (*Compiler) Compile

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

Compile compiles json-schema at given loc.

func (*Compiler) DefaultDraft

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

DefaultDraft overrides the draft used to compile schemas without `$schema` field.

By default, this library uses the latest draft supported.

The use of this option is HIGHLY encouraged to ensure continued correct operation of your schema. The current default value will not stay the same overtime.

func (*Compiler) MustCompile

func (c *Compiler) MustCompile(loc string) *Schema

MustCompile is like [Compile] but panics if compilation fails. It simplifies safe initialization of global variables holding compiled schema.

func (*Compiler) RegisterContentEncoding

func (c *Compiler) RegisterContentEncoding(d *Decoder)

RegisterContentEncoding registers custom contentEncoding.

NOTE: content assertions are disabled by default. see Compiler.AssertContent.

func (*Compiler) RegisterContentMediaType

func (c *Compiler) RegisterContentMediaType(mt *MediaType)

RegisterContentMediaType registers custom contentMediaType.

NOTE: content assertions are disabled by default. see Compiler.AssertContent.

func (*Compiler) RegisterFormat

func (c *Compiler) RegisterFormat(f *Format)

RegisterFormat registers custom format.

NOTE:

  • "regex" format can not be overridden
  • format assertions are disabled for draft >= 2019-09 see Compiler.AssertFormat

func (*Compiler) RegisterVocabulary

func (c *Compiler) RegisterVocabulary(vocab *Vocabulary)

RegisterVocabulary registers custom vocabulary.

NOTE:

func (*Compiler) UseLoader

func (c *Compiler) UseLoader(loader URLLoader)

UseLoader overrides the default URLLoader used to load schema resources.

func (*Compiler) UseRegexpEngine

func (c *Compiler) UseRegexpEngine(engine RegexpEngine)

UseRegexpEngine changes the regexp-engine used. By default it uses regexp package from go standard library.

NOTE: must be called before compiling any schemas.

type CompilerContext

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

CompilerContext provides helpers for compiling a Vocabulary.

func (*CompilerContext) Enqueue

func (ctx *CompilerContext) Enqueue(schPath []string) *Schema

type Decoder

type Decoder struct {
	// Name of contentEncoding.
	Name string
	// Decode given string to byte array.
	Decode func(string) ([]byte, error)
}

Decoder specifies how to decode specific contentEncoding.

type Draft

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

A Draft represents json-schema specification.

func (*Draft) String

func (d *Draft) String() string

String returns the specification url.

type DuplicateAnchorError

type DuplicateAnchorError struct {
	Anchor string
	URL    string
	Ptr1   string
	Ptr2   string
}

func (*DuplicateAnchorError) Error

func (e *DuplicateAnchorError) Error() string

type DuplicateIDError

type DuplicateIDError struct {
	ID   string
	URL  string
	Ptr1 string
	Ptr2 string
}

func (*DuplicateIDError) Error

func (e *DuplicateIDError) Error() string

type DynamicRef

type DynamicRef struct {
	Ref    *Schema
	Anchor string // "" if not specified
}

type Enum

type Enum struct {
	Values []any
	// contains filtered or unexported fields
}

type ErrorKind

type ErrorKind interface {
	KeywordPath() []string
	LocalizedString(*message.Printer) string
}

type FileLoader

type FileLoader struct{}

FileLoader loads json file url.

func (FileLoader) Load

func (l FileLoader) Load(url string) (any, error)

func (FileLoader) ToFile

func (l FileLoader) ToFile(url string) (string, error)

ToFile is helper method to convert file url to file path.

type FlagOutput

type FlagOutput struct {
	Valid bool `json:"valid"`
}

Flag is output format with simple boolean property valid.

type Format

type Format struct {
	// Name of format.
	Name string

	// Validate checks if given value is of this format.
	Validate func(v any) error
}

Format defined specific format.

type InvalidJsonPointerError

type InvalidJsonPointerError struct {
	URL string
}

func (*InvalidJsonPointerError) Error

func (e *InvalidJsonPointerError) Error() string

type InvalidMetaSchemaURLError

type InvalidMetaSchemaURLError struct {
	URL string
	Err error
}

func (*InvalidMetaSchemaURLError) Error

func (e *InvalidMetaSchemaURLError) Error() string

type InvalidRegexError

type InvalidRegexError struct {
	URL   string
	Regex string
	Err   error
}

func (*InvalidRegexError) Error

func (e *InvalidRegexError) Error() string

type Item

type Item int

type JSONPointerNotFoundError

type JSONPointerNotFoundError struct {
	URL string
}

func (*JSONPointerNotFoundError) Error

func (e *JSONPointerNotFoundError) Error() string

type LoadURLError

type LoadURLError struct {
	URL string
	Err error
}

func (*LoadURLError) Error

func (e *LoadURLError) Error() string

type MediaType

type MediaType struct {
	// Name of contentMediaType.
	Name string

	// Validate checks whether bytes conform to this mediatype.
	Validate func([]byte) error

	// UnmarshalJSON unmarshals bytes into json value.
	// This must be nil if this mediatype is not compatible
	// with json.
	UnmarshalJSON func([]byte) (any, error)
}

MediaType specified how to validate bytes against specific contentMediaType.

type MetaSchemaCycleError

type MetaSchemaCycleError struct {
	URL string
}

func (*MetaSchemaCycleError) Error

func (e *MetaSchemaCycleError) Error() string

type MetaSchemaMismatchError

type MetaSchemaMismatchError struct {
	URL string
}

func (*MetaSchemaMismatchError) Error

func (e *MetaSchemaMismatchError) Error() string

type ObjectRef

type ObjectRef struct {
	Path  []string
	Value any
	Obj   any
}

func ExtractObjectRefs

func ExtractObjectRefs(data any, basePath []string, keyword string) []ObjectRef

type OutputError

type OutputError struct {
	Kind ErrorKind
	// contains filtered or unexported fields
}

func (OutputError) MarshalJSON

func (k OutputError) MarshalJSON() ([]byte, error)

type OutputUnit

type OutputUnit struct {
	Valid                   bool         `json:"valid"`
	KeywordLocation         string       `json:"keywordLocation"`
	AbsoluteKeywordLocation string       `json:"AbsoluteKeywordLocation,omitempty"`
	InstanceLocation        string       `json:"instanceLocation"`
	Error                   *OutputError `json:"error,omitempty"`
	Errors                  []OutputUnit `json:"errors,omitempty"`
}

type ParseAnchorError

type ParseAnchorError struct {
	URL string
}

func (*ParseAnchorError) Error

func (e *ParseAnchorError) Error() string

type ParseIDError

type ParseIDError struct {
	URL string
}

func (*ParseIDError) Error

func (e *ParseIDError) Error() string

type ParseURLError

type ParseURLError struct {
	URL string
	Err error
}

func (*ParseURLError) Error

func (e *ParseURLError) Error() string

type Position

type Position interface {
	// contains filtered or unexported methods
}

Position tells possible tokens in json.

type Prop

type Prop string

type Regexp

type Regexp interface {
	fmt.Stringer

	// MatchString reports whether the string s contains
	// any match of the regular expression.
	MatchString(string) bool
}

Regexp is the representation of compiled regular expression.

type RegexpEngine

type RegexpEngine func(string) (Regexp, error)

RegexpEngine parses a regular expression and returns, if successful, a Regexp object that can be used to match against text.

type ResourceExistsError

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

func (*ResourceExistsError) Error

func (e *ResourceExistsError) Error() string

type Schema

type Schema struct {
	DraftVersion int
	Location     string

	// type agnostic --
	Bool            *bool // boolean schema
	ID              string
	Ref             *Schema
	Anchor          string
	RecursiveRef    *Schema
	RecursiveAnchor bool
	DynamicRef      *DynamicRef
	DynamicAnchor   string // "" if not specified
	Types           *Types
	Enum            *Enum
	Const           *any
	Not             *Schema
	AllOf           []*Schema
	AnyOf           []*Schema
	OneOf           []*Schema
	If              *Schema
	Then            *Schema
	Else            *Schema
	Format          *Format

	// object --
	MaxProperties         *int
	MinProperties         *int
	Required              []string
	PropertyNames         *Schema
	Properties            map[string]*Schema
	PatternProperties     map[Regexp]*Schema
	AdditionalProperties  any            // nil or bool or *Schema
	Dependencies          map[string]any // value is []string or *Schema
	DependentRequired     map[string][]string
	DependentSchemas      map[string]*Schema
	UnevaluatedProperties *Schema

	// array --
	MinItems         *int
	MaxItems         *int
	UniqueItems      bool
	Contains         *Schema
	MinContains      *int
	MaxContains      *int
	Items            any // nil or []*Schema or *Schema
	AdditionalItems  any // nil or bool or *Schema
	PrefixItems      []*Schema
	Items2020        *Schema
	UnevaluatedItems *Schema

	// string --
	MinLength        *int
	MaxLength        *int
	Pattern          Regexp
	ContentEncoding  *Decoder
	ContentMediaType *MediaType
	ContentSchema    *Schema

	// number --
	Maximum          *big.Rat
	Minimum          *big.Rat
	ExclusiveMaximum *big.Rat
	ExclusiveMinimum *big.Rat
	MultipleOf       *big.Rat

	Extensions []SchemaExt

	// annotations --
	Title       string
	Description string
	Default     *any
	Comment     string
	ReadOnly    bool
	WriteOnly   bool
	Examples    []any
	Deprecated  bool
	// contains filtered or unexported fields
}

Schema is the regpresentation of a compiled jsonschema.

func (*Schema) Validate

func (sch *Schema) Validate(v any) error

func (*Schema) ValidateAndExt

func (sch *Schema) ValidateAndExt(v any, extMap map[string]any) error

type SchemaExt

type SchemaExt interface {
	// Validate validates v against and errors if any are reported
	// to ctx.
	Validate(ctx *ValidatorContext, v any)
}

SchemaExt is compled form of vocabulary.

type SchemaPath

type SchemaPath []Position

SchemaPath tells where to look for subschema inside keyword.

func (SchemaPath) String

func (sp SchemaPath) String() string

type SchemaValidationError

type SchemaValidationError struct {
	URL string
	Err error
}

func (*SchemaValidationError) Error

func (e *SchemaValidationError) Error() string

type SchemeURLLoader

type SchemeURLLoader map[string]URLLoader

SchemeURLLoader delegates to other [URLLoaders] based on url scheme.

func (SchemeURLLoader) Load

func (l SchemeURLLoader) Load(url string) (any, error)

type Types

type Types int

Types encapsulates list of json value types.

func (Types) IsEmpty

func (tt Types) IsEmpty() bool

func (Types) String

func (tt Types) String() string

func (Types) ToStrings

func (tt Types) ToStrings() []string

type URLLoader

type URLLoader interface {
	// Load loads json from given absolute url.
	Load(url string) (any, error)
}

URLLoader knows how to load json from given url.

type UnsupportedDraftError

type UnsupportedDraftError struct {
	URL string
}

func (*UnsupportedDraftError) Error

func (e *UnsupportedDraftError) Error() string

type UnsupportedURLSchemeError

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

func (*UnsupportedURLSchemeError) Error

func (e *UnsupportedURLSchemeError) Error() string

type UnsupportedVocabularyError

type UnsupportedVocabularyError struct {
	URL        string
	Vocabulary string
}

func (*UnsupportedVocabularyError) Error

type ValidationError

type ValidationError struct {
	// absolute, dereferenced schema location.
	SchemaURL string

	// location of the JSON value within the instance being validated.
	InstanceLocation []string

	// kind of error
	ErrorKind ErrorKind

	// holds nested errors
	Causes []*ValidationError
}

func (*ValidationError) BasicOutput

func (e *ValidationError) BasicOutput() *OutputUnit

The `Basic` structure, a flat list of output units.

func (*ValidationError) DetailedOutput

func (e *ValidationError) DetailedOutput() *OutputUnit

The `Detailed` structure, based on the schema.

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) FlagOutput

func (e *ValidationError) FlagOutput() *FlagOutput

The `Flag` output format, merely the boolean result.

func (*ValidationError) GoString

func (e *ValidationError) GoString() string

func (*ValidationError) LocalizedBasicOutput

func (e *ValidationError) LocalizedBasicOutput(p *message.Printer) *OutputUnit

func (*ValidationError) LocalizedDetailedOutput

func (e *ValidationError) LocalizedDetailedOutput(p *message.Printer) *OutputUnit

func (*ValidationError) LocalizedError

func (e *ValidationError) LocalizedError(p *message.Printer) string

func (*ValidationError) LocalizedGoString

func (e *ValidationError) LocalizedGoString(p *message.Printer) string

type ValidatorContext

type ValidatorContext struct {
	ExtMap map[string]interface{}
	// contains filtered or unexported fields
}

ValidatorContext provides helpers for validating with SchemaExt.

func (*ValidatorContext) AddErr

func (ctx *ValidatorContext) AddErr(err error)

AddErr reports the given err. This is typically used to report the error created by subschema validation.

NOTE that err must be of type *ValidationError.

func (*ValidatorContext) AddError

func (ctx *ValidatorContext) AddError(k ErrorKind)

AddError reports validation-error of given kind.

func (*ValidatorContext) AddErrors

func (ctx *ValidatorContext) AddErrors(errors []*ValidationError, k ErrorKind)

AddErrors reports validation-errors of given kind.

func (*ValidatorContext) Duplicates

func (ctx *ValidatorContext) Duplicates(arr []any) (int, int, error)

func (*ValidatorContext) Equals

func (ctx *ValidatorContext) Equals(v1, v2 any) (bool, error)

func (*ValidatorContext) EvaluatedItem

func (ctx *ValidatorContext) EvaluatedItem(index int)

EvaluatedItem marks items at given index of current array as evaluated.

func (*ValidatorContext) EvaluatedProp

func (ctx *ValidatorContext) EvaluatedProp(pname string)

EvaluatedProp marks given property of current object as evaluated.

func (*ValidatorContext) GetCtxVloc

func (ctx *ValidatorContext) GetCtxVloc() ([]string, error)

func (*ValidatorContext) Validate

func (ctx *ValidatorContext) Validate(sch *Schema, v any, vpath []string) error

Validate validates v with sch. vpath gives path of v from current context value.

type Vocabulary

type Vocabulary struct {
	// URL identifier for this Vocabulary.
	URL string

	// Schema that is used to validate the keywords that is introduced by this
	// vocabulary.
	Schema *Schema

	// Subschemas lists the possible locations of subschemas introduced by
	// this vocabulary.
	Subschemas []SchemaPath

	// Compile compiles the keywords(introduced by this vocabulary) in obj into [SchemaExt].
	// If obj does not contain any keywords introduced by this vocabulary, nil SchemaExt must
	// be returned.
	Compile func(ctx *CompilerContext, obj map[string]any) (SchemaExt, error)
}

Vocabulary defines a set of keywords, their syntax and their semantics.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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