Skip to content

Commit

Permalink
encoding/jsonschema: add OpenAPI version support
Browse files Browse the repository at this point in the history
WIP

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: I0070f8c02a9b403e2018b84919b886b0bc5f29d8
Dispatch-Trailer: {"type":"trybot","CL":1200578,"patchset":1,"ref":"refs/changes/78/1200578/1","targetBranch":"master"}
  • Loading branch information
rogpeppe authored and cueckoo committed Sep 3, 2024
1 parent 6051c74 commit cd3fb45
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
10 changes: 7 additions & 3 deletions encoding/jsonschema/constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,18 @@ var constraints = []*constraint{
p2("dependencies", constraintDependencies),
todo("dependentRequired", vfrom(VersionDraft2019_09)),
todo("dependentSchemas", vfrom(VersionDraft2019_09)),
p2("deprecated", constraintDeprecated),
p2d("deprecated", constraintDeprecated, vfrom(VersionDraft2019_09)),
p2("description", constraintDescription),
todo("discriminator", vset(VersionOpenAPI3_0)),
todo("else", vfrom(VersionDraft7)),
p2("enum", constraintEnum),
todo("example", vset(VersionOpenAPI3_0)),
p2d("examples", constraintExamples, vfrom(VersionDraft6)),
p2("exclusiveMaximum", constraintExclusiveMaximum),
p2("exclusiveMinimum", constraintExclusiveMinimum),
todo("externalDocs", vset(VersionOpenAPI3_0)),
todo("format", allVersions),
p1d("id", constraintID, vto(VersionDraft4)),
p1d("id", constraintID, vto(VersionDraft4)&^openAPI3_0),
todo("if", vfrom(VersionDraft7)),
p2("items", constraintItems),
p1d("maxContains", constraintMaxContains, vfrom(VersionDraft2019_09)),
Expand All @@ -107,7 +110,7 @@ var constraints = []*constraint{
p3("minimum", constraintMinimum),
p2("multipleOf", constraintMultipleOf),
p3("not", constraintNot),
p2("nullable", constraintNullable),
p2d("nullable", constraintNullable, vset(VersionOpenAPI3_0)),
p3("oneOf", constraintOneOf),
p2("pattern", constraintPattern),
p3("patternProperties", constraintPatternProperties),
Expand All @@ -123,6 +126,7 @@ var constraints = []*constraint{
todo("unevaluatedProperties", vfrom(VersionDraft2019_09)),
p2("uniqueItems", constraintUniqueItems),
todo("writeOnly", vfrom(VersionDraft7)),
todo("xml", vset(VersionOpenAPI3_0)),
}

func todo(name string, versions versionSet) *constraint {
Expand Down
14 changes: 12 additions & 2 deletions encoding/jsonschema/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,21 @@ const (
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
VersionOpenAPI3_0 // OpenAPI 3.0

numVersions // unknown
)

var (
openAPI3_0 = vset(VersionOpenAPI3_0)
notOpenAPI3_0 = allVersions &^ vset(VersionOpenAPI3_0)
)

type versionSet int

const allVersions = versionSet(1<<numVersions-1) &^ (1 << VersionUnknown)
// allVersions includes all regular versions of JSON Schema.
// It does not include OpenAPI v3.0
const allVersions = versionSet(1<<numVersions-1) &^ (1 << VersionUnknown) &^ (1 << VersionOpenAPI3_0)

// contains reports whether m contains the version v.
func (m versionSet) contains(v Version) bool {
Expand Down Expand Up @@ -70,7 +78,9 @@ func ParseVersion(sv string) (Version, error) {
// If this linear search is ever a performance issue, we could
// build a map, but it doesn't seem worthwhile for now.
for i := Version(1); i < numVersions; i++ {
if sv == i.String() {
// Note: OpenAPI doesn't have a schema URI in the
// same way as the other schema versions.
if i != VersionOpenAPI3_0 && sv == i.String() {
return i, nil
}
}
Expand Down
7 changes: 4 additions & 3 deletions encoding/jsonschema/version_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 25 additions & 7 deletions encoding/openapi/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package openapi

import (
"fmt"
"strings"

"cuelang.org/go/cue"
Expand All @@ -41,15 +42,24 @@ func Extract(data cue.InstanceOrValue, c *Config) (*ast.File, error) {
}
}

js, err := jsonschema.Extract(data, &jsonschema.Config{
Root: oapiSchemas,
Map: openAPIMapping,
})
v := data.Value()
versionValue := v.LookupPath(cue.MakePath(cue.Str("openapi")))
if versionValue.Err() != nil {
return nil, fmt.Errorf("openapi field is required but not found")
}
version, err := versionValue.String()
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid openapi field (must be string): %v", err)
}
var schemaVersion jsonschema.Version
switch {
case strings.HasPrefix(version, "v3.0."):
schemaVersion = jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: jsonschema.OpenAPI3_0

Check failure on line 57 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: jsonschema.OpenAPI3_0
case strings.HasPrefix(version, "v3.1."):
schemaVersion = VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, ubuntu-22.04)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, macos-14)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.23.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: VersionDraft2020_12

Check failure on line 59 in encoding/openapi/decode.go

View workflow job for this annotation

GitHub Actions / test (1.22.x, windows-2022)

undefined: VersionDraft2020_12
default:
return nil, fmt.Errorf("unknown OpenAPI version %q", version)
}

v := data.Value()

doc, _ := v.LookupPath(cue.MakePath(cue.Str("info"), cue.Str("title"))).String() // Required
if s, _ := v.LookupPath(cue.MakePath(cue.Str("info"), cue.Str("description"))).String(); s != "" {
Expand All @@ -65,6 +75,14 @@ func Extract(data cue.InstanceOrValue, c *Config) (*ast.File, error) {
add(cg)
}

js, err := jsonschema.Extract(data, &jsonschema.Config{
Root: oapiSchemas,
Map: openAPIMapping,
DefaultVersion: schemaVersion,
})
if err != nil {
return nil, err
}
preamble := js.Preamble()
body := js.Decls[len(preamble):]
for _, d := range preamble {
Expand Down

0 comments on commit cd3fb45

Please sign in to comment.