jsonschema

package
v0.17.1 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: Apache-2.0 Imports: 31 Imported by: 12

Documentation

Overview

Package jsonschema converts JSON Schema to CUE

JSON Schema data is presented in CUE, so any of the supported encodings that can represent JSON Schema data can be used as a source.

Package jsonschema implements the JSON schema standard.

Mapping and Linking

JSON Schema are often defined in a single file. CUE, on the other hand idiomatically defines schema as a definition.

CUE:

$schema: which schema is used for validation.
$id: which validation does this schema provide.

Foo: _ @jsonschema(sc)
@source(https://...) // What schema is used to validate.

NOTE: JSON Schema is a draft standard and may undergo backwards incompatible changes.

Index

Constants

View Source
const (
	// DefaultRootID is used as the absolute base URI for a schema
	// when no value is provided in [Config.ID].
	DefaultRootID     = "https://" + DefaultRootIDHost
	DefaultRootIDHost = "cue.jsonschema.invalid"
)
View Source
const DefaultVersion = VersionDraft2020_12

DefaultVersion defines the default schema version used when there is no $schema field and no explicit Config.DefaultVersion.

Variables

This section is empty.

Functions

func DefaultMapRef added in v0.12.0

func DefaultMapRef(loc SchemaLoc) (importPath string, path cue.Path, err error)

DefaultMapRef implements the default logic for mapping a schema location to CUE. It uses a heuristic to map the URL host and path to an import path, and maps the fragment part according to the following:

#                    <empty path>
#/definitions/foo   #foo or #."foo"
#/$defs/foo   #foo or #."foo"

func DefaultMapURL deprecated added in v0.10.0

func DefaultMapURL(u *url.URL) (string, cue.Path, error)

DefaultMapURL implements the default schema ID to import path mapping. It trims off any ".json" suffix and uses the package name "schema" if the final component of the path isn't a valid CUE identifier.

Deprecated: The Config.MapURL API is superceded in factor of Config.MapRef.

func DefaultNameFunc deprecated added in v0.15.0

func DefaultNameFunc(inst cue.Value, ref cue.Path) string

DefaultNameFunc holds the default function used by Generate to generate a JSON Schema definition name from a reference path within the value inst, where inst is usually a CUE package value.

Deprecated: use DefaultNamesFunc instead.

func DefaultNamesFunc added in v0.17.0

func DefaultNamesFunc(refs []*CUERef)

DefaultNamesFunc holds the default function used by Generate to generate JSON Schema definition names from references. See GenerateConfig.NamesFunc for more information.

It uses the shortest unique suffix of each reference path, stripping '#' from definition selectors where possible. When stripping '#' would cause a clash (e.g. both #Foo and Foo are referenced), the '#' is preserved for the definition.

func Extract

func Extract(data cue.InstanceOrValue, cfg *Config) (*ast.File, error)

Extract converts JSON Schema data into an equivalent CUE representation.

The generated CUE schema is guaranteed to deem valid any value that is a valid instance of the source JSON schema.

The result can be converted to a cue.Value via cue.Context.BuildFile.

func Generate added in v0.15.0

func Generate(v cue.Value, cfg *GenerateConfig) (ast.Expr, error)

Generate generates a JSON Schema for the given CUE value, with the returned AST representing the generated JSON result.

The result is typically encoded as JSON, for example by obtaining a value via cue.Context.BuildExpr and then encoding it via encoding/json.Marshal.

Note: this functionality is currently experimental. The form of the generated schema may, and probably will, change from release to release.

Types

type CRDConfig added in v0.14.0

type CRDConfig struct{}

CRDConfig holds configuration for ExtractCRDs. Although this empty currently, it allows configuration to be added in the future without breaking the API.

type CRDSpec added in v0.14.0

type CRDSpec struct {
	ApiVersion string `json:"apiVersion"`

	Kind string `json:"kind"`

	Spec struct {
		Group string `json:"group"`

		Names struct {
			Kind string `json:"kind"`

			Plural string `json:"plural"`

			Singular string `json:"singular"`
		} `json:"names"`

		Scope string `json:"scope"`

		Versions []struct {
			Name string `json:"name"`

			Schema struct {
				OpenAPIV3Schema cue.Value `json:"openAPIV3Schema"`
			} `json:"schema"`
		} `json:"versions"`
	} `json:"spec"`
}

CRDSpec defines a subset of the CRD schema, suitable for filtering CRDs based on common criteria like group and name.

type CUERef added in v0.17.0

type CUERef struct {
	// Inst holds the package where the reference is.
	Inst cue.Value

	// Path holds the path within Inst.
	Path cue.Path

	// Name holds the name to use for the reference within
	// the generated JSON Schema. It is the responsibility
	// of the [GenerateConfig.NamesFunc] to set this.
	Name string
}

CUERef represents a reference within CUE source.

type Config

type Config struct {
	PkgName string

	// ID sets the URL of the original source, corresponding to the $id field.
	ID string

	// JSON reference of location containing schemas. The empty string indicates
	// that there is a single schema at the root. If this is non-empty,
	// the referred-to location should be an object, and each member
	// is taken to be a schema (by default: see [Config.SingleRoot])
	//
	// Examples:
	//  "#/" or "#"                    top-level fields are schemas.
	//  "#/components/schemas"   the canonical OpenAPI location.
	//
	// Note: #/ should technically _not_ refer to the root of the
	// schema: this behavior is preserved for backwards compatibility
	// only. Just `#` is preferred.
	Root string

	// SingleRoot is consulted only when Root is non-empty.
	// If Root is non-empty and SingleRoot is true, then
	// Root should specify the location of a single schema to extract.
	SingleRoot bool

	// AllowNonExistentRoot prevents an error when there is no value at
	// the above Root path. Such an error can be useful to signal that
	// the data may not be a JSON Schema, but is not always a good idea.
	AllowNonExistentRoot bool

	// Map maps the locations of schemas and definitions to a new location.
	// References are updated accordingly. A returned label must be
	// an identifier or string literal.
	//
	// The default mapping is
	//    {}                     {}
	//    {"definitions", foo}   {#foo} or {#, foo}
	//    {"$defs", foo}         {#foo} or {#, foo}
	//
	// Deprecated: use [Config.MapRef].
	Map func(pos token.Pos, path []string) ([]ast.Label, error)

	// MapURL maps a URL reference as found in $ref to
	// an import path for a CUE package and a path within that package.
	// If this is nil, [DefaultMapURL] will be used.
	//
	// Deprecated: use [Config.MapRef].
	MapURL func(u *url.URL) (importPath string, path cue.Path, err error)

	// NOTE: this method is currently experimental. Its usage and type
	// signature may change.
	//
	// MapRef is used to determine how a JSON schema location maps to
	// CUE. It is used for both explicit references and for named
	// schemas inside $defs and definitions.
	//
	// For example, given this schema:
	//
	// 	{
	// 	    "$schema": "https://json-schema.org/draft/2020-12/schema",
	// 	    "$id": "https://my.schema.org/hello",
	// 	    "$defs": {
	// 	        "foo": {
	// 	            "$id": "https://other.org",
	// 	            "type": "object",
	// 	            "properties": {
	// 	                "a": {
	// 	                    "type": "string"
	// 	                },
	// 	                "b": {
	// 	                    "$ref": "#/properties/a"
	// 	                }
	// 	            }
	// 	        }
	// 	    },
	// 	    "allOf": [{
	// 	        "$ref": "#/$defs/foo"
	// 	    }, {
	// 	        "$ref": "https://my.schema.org/hello#/$defs/foo"
	// 	    }, {
	// 	        "$ref": "https://other.org"
	// 	    }, {
	// 	        "$ref": "https://external.ref"
	//	    }]
	// 	}
	//
	// ... MapRef will be called with the following locations for the
	// $ref keywords in order of appearance (no guarantees are made
	// about the actual order or number of calls to MapRef):
	//
	//	ID                                      RootRel
	//	https://other.org/properties/a          https://my.schema.org/hello#/$defs/foo/properties/a
	//	https://my.schema.org/hello#/$defs/foo  https://my.schema.org/hello#/$defs/foo
	//	https://other.org                       https://my.schema.org/hello#/$defs/foo
	//	https://external.ref                    <nil>
	//
	// It will also be called for the named schema in #/$defs/foo with these arguments:
	//
	//	https://other.org                       https://my.schema.org/hello#/$defs/foo
	//
	// MapRef should return the desired CUE location for the schema with
	// the provided IDs, consisting of the import path of the package
	// containing the schema, and a path within that package. If the
	// returned import path is empty, the path will be interpreted
	// relative to the root of the generated JSON schema.
	//
	// Note that MapRef is general enough to subsume use of [Config.Map] and
	// [Config.MapURL], which are both now deprecated. If all three fields are
	// nil, [DefaultMapRef] will be used.
	MapRef func(loc SchemaLoc) (importPath string, relPath cue.Path, err error)

	// NOTE: this method is currently experimental. Its usage and type
	// signature may change.
	//
	// DefineSchema is called, if not nil, for any schema that is defined
	// within the json schema being converted but is mapped somewhere
	// external via [Config.MapRef]. The invoker of [Extract] is
	// responsible for defining the schema in the correct place as described
	// by the import path and its relative CUE path.
	//
	// The importPath and path are exactly as returned by [Config.MapRef].
	// If this or [Config.MapRef] is nil this function will never be called.
	// Note that importPath will never be empty, because if MapRef
	// returns an empty importPath, it's specifying an internal schema
	// which will be defined accordingly.
	DefineSchema func(importPath string, path cue.Path, e ast.Expr, docComment *ast.CommentGroup)

	// Strict reports an error for unsupported features and keywords,
	// rather than ignoring them. When true, this is equivalent to
	// setting both StrictFeatures and StrictKeywords to true.
	Strict bool

	// StrictFeatures reports an error for features that are known
	// to be unsupported.
	StrictFeatures bool

	// StrictKeywords reports an error when unknown keywords
	// are encountered.
	StrictKeywords bool

	// OpenOnlyWhenExplicit requires a schema to be explicitly opened before a
	// `...` will be added to a struct. A schema is considered
	// explicitly opened when `additionalProperties` is present (unless
	// its value is false) or, when the version is
	// [VersionKubernetesCRD], when
	// `x-kubernetes-preserve-unknown-fields` is set.
	//
	// Set to true when you'd like non-explicitly specified fields
	// to be disallowed by default.
	//
	// This is useful for Kubernetes schemas and CRDs which never
	// use additionalProperties: false but are nonetheless desired
	// to be treated as closed.
	//
	// Implied true when the version is [VersionKubernetesCRD] or
	// [VersionKubernetesAPI].
	OpenOnlyWhenExplicit bool

	// DefaultVersion holds the default schema version to use
	// when no $schema field is present. If it is zero, [DefaultVersion]
	// will be used.
	DefaultVersion Version
	// contains filtered or unexported fields
}

A Config configures a JSON Schema encoding or decoding.

type ExtractedCRD added in v0.14.0

type ExtractedCRD struct {
	// Versions holds the CUE schemas extracted from the CRD: one per
	// version.
	Versions map[string]*ast.File

	// VersionToPath maps each version to the path
	// within Source containing the schema for that version.
	VersionToPath map[string]cue.Path

	// Data holds chosen fields extracted from the source CRD document.
	Data *CRDSpec

	// Source holds the raw CRD document from which Data is derived.
	Source cue.Value
}

ExtractedCRD holds an extracted Kubernetes CRD and the data it was derived from.

func ExtractCRDs added in v0.14.0

func ExtractCRDs(data cue.Value, cfg *CRDConfig) ([]*ExtractedCRD, error)

ExtractCRDs extracts Kubernetes custom resource definitions (CRDs) from the given data. If data holds an array, each element of the array might itself be a Kubernetes resource.

While the data must hold Kubernetes resources, those resources need not all be CRDs: resources with a kind that's not "CustomResourceDefinition" will be ignored.

If cfg is nil, it's equivalent to passing a pointer to the zero-valued CRDConfig.

type GenerateConfig added in v0.15.0

type GenerateConfig struct {
	// Version specifies the version of JSON Schema to generate.
	// Currently only [VersionDraft2020_12] is supported.
	Version Version

	// NameFunc is used to determine how a reference maps to a JSON Schema
	// definition name. It is passed the root value (usually a package)
	// and the path to that value within it, as returned by [cue.Value.ReferencePath].
	//
	// If both NameFunc and NamesFunc are nil, [DefaultNamesFunc] will be used.
	//
	// Deprecated: use [GenerateConfig.NamesFunc] instead, which
	// allows all references to be named with full knowledge of all
	// the other references.
	NameFunc func(root cue.Value, path cue.Path) string

	// NamesFunc is used to determine how references map to JSON Schema
	// definition names. It is passed all the distinct references made
	// by the schema being generated. It is the responsibility of the
	// function to set a different [CUERef.Name] for each reference.
	//
	// If this is nil and [GenerateConfig.NameFunc] is also nil,
	// [DefaultNamesFunc] will be used.
	NamesFunc func(refs []*CUERef)

	// ExplicitOpen, when true, will never close a schema with `additionalProperties: false`
	// (but _will_ explicitly open a schema with `additionalProperties: true`
	// when there is an explicit `...` or universal pattern in a struct).
	//
	// By default (when ExplicitOpen is false), all structs that are closed will
	// have an `additionalProperties: false` added.
	ExplicitOpen bool
}

GenerateConfig configures JSON Schema generation from CUE values.

type SchemaLoc added in v0.12.0

type SchemaLoc struct {
	// ID holds the canonical URI of the schema, as declared
	// by the schema or one of its parents.
	ID *url.URL

	// IsLocal holds whether the schema has been defined locally.
	// If true, then [SchemaLoc.Path] holds the path from the root
	// value, as passed to [Extract], to the schema definition.
	IsLocal bool
	Path    cue.Path
}

SchemaLoc defines the location of schema, both in absolute terms as its canonical ID and, optionally, relative to the root of the value passed to Extract.

func (SchemaLoc) String added in v0.12.0

func (loc SchemaLoc) String() string

type Version added in v0.11.0

type Version int
const (
	VersionUnknown Version = iota // unknown
	VersionDraft4                 // http://json-schema.org/draft-04/schema#
	// Note: draft 5 never existed and should not be used.
	VersionDraft6       // http://json-schema.org/draft-06/schema#
	VersionDraft7       // http://json-schema.org/draft-07/schema#
	VersionDraft2019_09 // https://json-schema.org/draft/2019-09/schema
	VersionDraft2020_12 // https://json-schema.org/draft/2020-12/schema

	// Note: The following versions stand alone: they're not in the regular JSON Schema lineage.
	VersionOpenAPI       // OpenAPI 3.0
	VersionKubernetesAPI // Kubernetes API
	VersionKubernetesCRD // Kubernetes CRD
)

func ParseVersion added in v0.11.0

func ParseVersion(sv string) (Version, error)

ParseVersion parses a version URI that defines a JSON Schema version.

func (Version) String added in v0.11.0

func (i Version) String() string

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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