diff --git a/encoding/jsonschema/generate.go b/encoding/jsonschema/generate.go index a434f9fe1..28ba2fbff 100644 --- a/encoding/jsonschema/generate.go +++ b/encoding/jsonschema/generate.go @@ -291,6 +291,12 @@ func (g *generator) makeItem0(v cue.Value, mode closedMode) item { if !pkg.Exists() { break } + // Check if this is a reference to a known validator function. + // For example, list.UniqueItems (without parens) should be treated + // the same as list.UniqueItems(). + if it := g.makeCallItem(v, []cue.Value{v}, mode); it != nil { + return it + } // It's a reference: generate a definition for it. // TODO Not all references need or should have a definition. if name := g.cfg.NameFunc(pkg, path); name != "" { @@ -422,7 +428,12 @@ func (g *generator) makeItem0(v cue.Value, mode closedMode) item { return &itemFalse{} } case cue.CallOp: - return g.makeCallItem(v, args, mode) + if it := g.makeCallItem(v, args, mode); it != nil { + return it + } + // For unknown functions, accept anything rather than fail. + // This allows for gradual implementation of more function types. + return &itemTrue{} } if !v.IsNull() { // We want to encode null as {type: "null"} not {const: null} @@ -864,9 +875,7 @@ func (g *generator) makeCallItem(v cue.Value, args []cue.Value, mode closedMode) } default: - // For unknown functions, accept anything rather than fail. - // This allows for gradual implementation of more function types - return &itemTrue{} + return nil } } diff --git a/encoding/jsonschema/testdata/generate/uniqueitems.txtar b/encoding/jsonschema/testdata/generate/uniqueitems.txtar index b31c848bb..2a6bfcc31 100644 --- a/encoding/jsonschema/testdata/generate/uniqueitems.txtar +++ b/encoding/jsonschema/testdata/generate/uniqueitems.txtar @@ -7,8 +7,6 @@ uniqueList?: list.UniqueItems() uniqueListNoCall?: list.UniqueItems -// TODO this doesn't work - the code currently just looks -// for call expressions but this isn't a call expression. uniqueBools?: list.UniqueItems() & [bool, bool] -- datatest/tests.cue -- @@ -27,8 +25,7 @@ badUnique: { badUniqueNoCall: { data: uniqueListNoCall: [1, 1, 2] - // TODO this should be an error. - //error: true + error: true } badUniqueBools: { @@ -38,12 +35,7 @@ badUniqueBools: { -- out/generate-v3/schema -- { $schema: "https://json-schema.org/draft/2020-12/schema" - $defs: { - UniqueItems: { - type: "array" - } - } - type: "object" + type: "object" properties: { uniqueBools: { type: "array" @@ -61,18 +53,22 @@ badUniqueBools: { uniqueItems: true } uniqueListNoCall: { - $ref: "#/$defs/UniqueItems" + type: "array" + uniqueItems: true } } } -- out/generate-v3/ok -- -- out/generate-v3/badUnique -- badUnique.data.uniqueList: invalid value [1,1,2] (does not satisfy list.UniqueItems): equal value (1) at position 0 and 1: - 1:289 + 1:248 ./datatest/tests.cue:10:20 -- out/generate-v3/badUniqueBools -- badUniqueBools.data.uniqueBools: invalid value [true,true] (does not satisfy list.UniqueItems): equal value (true) at position 0 and 1: - 1:240 - ./datatest/tests.cue:21:21 - 1:214 + 1:199 + ./datatest/tests.cue:20:21 + 1:173 -- out/generate-v3/badUniqueNoCall -- +badUniqueNoCall.data.uniqueListNoCall: invalid value [1,1,2] (does not satisfy list.UniqueItems): equal value (1) at position 0 and 1: + 1:303 + ./datatest/tests.cue:15:26