blob: 09e41738171501da4873be2a7c36ac4a0c945fcc [file] [log] [blame]
Marcel van Lohuizen47d98702020-01-17 21:51:39 +01001// Copyright 2020 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package jsonschema implements the JSON schema standard.
16//
17// Mapping and Linking
18//
19// JSON Schema are often defined in a single file. CUE, on the other hand
20// idomatically defines schema as a definition.
21//
22// CUE:
23// $schema: which schema is used for validation.
24// $id: which validation does this schema provide.
25//
26// Foo: _ @jsonschema(sc)
27// @source(https://...) // What schema is used to validate.
28//
29// NOTE: JSON Schema is a draft standard and may undergo backwards incompatible
30// changes.
31package jsonschema
32
33import (
34 "cuelang.org/go/cue"
35 "cuelang.org/go/cue/ast"
Marcel van Lohuizen671b9562020-03-10 12:42:45 +010036 "cuelang.org/go/cue/token"
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010037)
38
39// Extract converts JSON Schema data into an equivalent CUE representation.
40//
41// The generated CUE schema is guaranteed to deem valid any value that is
42// a valid instance of the source JSON schema.
Marcel van Lohuizen671b9562020-03-10 12:42:45 +010043func Extract(data *cue.Instance, cfg *Config) (f *ast.File, err error) {
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010044 d := &decoder{
45 cfg: cfg,
46 imports: map[string]*ast.Ident{},
47 }
Marcel van Lohuizen671b9562020-03-10 12:42:45 +010048
49 f = d.decode(data.Value())
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010050 if d.errs != nil {
51 return nil, d.errs
52 }
Marcel van Lohuizen671b9562020-03-10 12:42:45 +010053 return f, nil
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010054}
55
56// A Config configures a JSON Schema encoding or decoding.
57type Config struct {
Marcel van Lohuizenbd98b132020-03-05 15:38:21 +010058 PkgName string
59
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010060 ID string // URL of the original source, corresponding to the $id field.
61
Marcel van Lohuizen671b9562020-03-10 12:42:45 +010062 // JSON reference of location containing schema. The empty string indicates
63 // that there is a single schema at the root.
64 //
65 // Examples:
66 // "#/" top-level fields are schemas.
67 // "#/components/schemas" the canonical OpenAPI location.
68 Root string
69
70 // Map maps the locations of schemas and definitions to a new location.
71 // References are updated accordingly.
72 //
73 // The default mapping is
74 // {} {"Schema"}
75 // {"definitions", foo} {"Defs", strings.Title(foo)}
76 // {"$defs", foo} {"Defs", strings.Title(foo)}
77 Map func(pos token.Pos, path []string) ([]string, error)
78
Marcel van Lohuizen47d98702020-01-17 21:51:39 +010079 // TODO: configurability to make it compatible with OpenAPI, such as
80 // - locations of definitions: #/components/schemas, for instance.
81 // - selection and definition of formats
82 // - documentation hooks.
83
84 _ struct{} // prohibit casting from different type.
85}