Skip to content

Commit 5ccb4e4

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-query-parameters
2 parents bbe5d70 + 9dd5b47 commit 5ccb4e4

File tree

2 files changed

+18
-68
lines changed

2 files changed

+18
-68
lines changed

compiler/src/steps/validate-model.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
149149

150150
// Register builtin types
151151
for (const name of [
152-
'string', 'boolean', 'number', 'null'
152+
'string', 'boolean', 'number', 'null', 'void', 'binary'
153153
]) {
154154
const typeName = {
155155
namespace: '_builtins',
@@ -541,33 +541,29 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
541541
}
542542

543543
function validateTypeAlias (typeDef: model.TypeAlias): void {
544-
const openGenerics = new Set(typeDef.generics?.map(t => t.name))
544+
const openGenerics = openGenericSet(typeDef)
545545

546546
if (typeDef.variants != null) {
547-
if (typeDef.generics != null && typeDef.generics.length !== 0) {
548-
modelError('A tagged union should not have generic parameters')
549-
}
550-
551547
if (typeDef.type.kind !== 'union_of') {
552548
modelError('The "variants" tag only applies to unions')
553549
} else {
554-
validateTaggedUnion(typeDef.name, typeDef.type, typeDef.variants)
550+
validateTaggedUnion(typeDef.name, typeDef.type, typeDef.variants, openGenerics)
555551
}
556552
} else {
557553
validateValueOf(typeDef.type, openGenerics)
558554
}
559555
}
560556

561-
function validateTaggedUnion (parentName: TypeName, valueOf: model.UnionOf, variants: model.InternalTag | model.ExternalTag | model.Untagged): void {
557+
function validateTaggedUnion (parentName: TypeName, valueOf: model.UnionOf, variants: model.InternalTag | model.ExternalTag | model.Untagged, openGenerics: Set<string>): void {
562558
if (variants.kind === 'external_tag') {
563559
// All items must have a 'variant' attribute
564-
const items = flattenUnionMembers(valueOf)
560+
const items = flattenUnionMembers(valueOf, openGenerics)
565561

566562
for (const item of items) {
567563
if (item.kind !== 'instance_of') {
568564
modelError('Items of externally tagged unions must be types with a "variant_tag" annotation')
569565
} else {
570-
validateTypeRef(item.type, undefined, new Set<string>())
566+
validateTypeRef(item.type, item.generics, openGenerics)
571567
const type = getTypeDef(item.type)
572568
if (type == null) {
573569
modelError(`Type ${fqn(item.type)} not found`)
@@ -582,13 +578,13 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
582578
}
583579
} else if (variants.kind === 'internal_tag') {
584580
const tagName = variants.tag
585-
const items = flattenUnionMembers(valueOf)
581+
const items = flattenUnionMembers(valueOf, openGenerics)
586582

587583
for (const item of items) {
588584
if (item.kind !== 'instance_of') {
589585
modelError('Items of internally tagged unions must be type references')
590586
} else {
591-
validateTypeRef(item.type, undefined, new Set<string>())
587+
validateTypeRef(item.type, item.generics, openGenerics)
592588
const type = getTypeDef(item.type)
593589
if (type == null) {
594590
modelError(`Type ${fqn(item.type)} not found`)
@@ -601,7 +597,7 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
601597
}
602598
}
603599

604-
validateValueOf(valueOf, new Set())
600+
validateValueOf(valueOf, openGenerics)
605601
} else if (variants.kind === 'untagged') {
606602
if (fqn(parentName) !== '_types.query_dsl:DecayFunction' &&
607603
fqn(parentName) !== '_types.query_dsl:DistanceFeatureQuery' &&
@@ -614,15 +610,15 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
614610
modelError(`Type ${fqn(variants.untypedVariant)} not found`)
615611
}
616612

617-
const items = flattenUnionMembers(valueOf)
613+
const items = flattenUnionMembers(valueOf, openGenerics)
618614
const baseTypes = new Set<string>()
619615
let foundUntyped = false
620616

621617
for (const item of items) {
622618
if (item.kind !== 'instance_of') {
623619
modelError('Items of type untagged unions must be type references')
624620
} else {
625-
validateTypeRef(item.type, undefined, new Set<string>())
621+
validateTypeRef(item.type, item.generics, openGenerics)
626622
const type = getTypeDef(item.type)
627623
if (type == null) {
628624
modelError(`Type ${fqn(item.type)} not found`)
@@ -674,7 +670,7 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
674670
// -----------------------------------------------------------------------------------------------
675671
// Constituents of type definitions
676672

677-
function openGenericSet (typeDef: model.Request | model.Response | model.Interface): Set<string> {
673+
function openGenericSet (typeDef: model.Request | model.Response | model.Interface | model.TypeAlias): Set<string> {
678674
return new Set((typeDef.generics ?? []).map(name => fqn(name)))
679675
}
680676

@@ -879,7 +875,7 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
879875
} else {
880876
// tagged union: the discriminant tells us what to look for, check each member in isolation
881877
assert(typeDef.type.kind === 'union_of', 'Variants are only allowed on union_of type aliases')
882-
for (const item of flattenUnionMembers(typeDef.type)) {
878+
for (const item of flattenUnionMembers(typeDef.type, new Set())) {
883879
validateValueOfJsonEvents(item)
884880
}
885881

@@ -894,13 +890,13 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
894890
}
895891

896892
/** Build the flattened item list of potentially nested unions (this is used for large unions) */
897-
function flattenUnionMembers (union: model.UnionOf): model.ValueOf[] {
893+
function flattenUnionMembers (union: model.UnionOf, openGenerics: Set<string>): model.ValueOf[] {
898894
const allItems = new Array<model.ValueOf>()
899895

900896
function collectItems (items: model.ValueOf[]): void {
901897
for (const item of items) {
902898
if (item.kind !== 'instance_of') {
903-
validateValueOf(item, new Set<string>())
899+
validateValueOf(item, openGenerics)
904900
allItems.push(item)
905901
} else {
906902
const itemType = getTypeDef(item.type)
@@ -910,7 +906,7 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
910906
// Recurse in nested union
911907
collectItems(itemType.type.items)
912908
} else {
913-
validateValueOf(item, new Set<string>())
909+
validateValueOf(item, openGenerics)
914910
allItems.push(item)
915911
}
916912
}

output/schema/validation-errors.json

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,9 @@
3636
],
3737
"response": []
3838
},
39-
"async_search.get": {
40-
"request": [],
41-
"response": [
42-
"type_alias definition _types:EpochTime / instance_of - No type definition for '_types.EpochTime:Unit'",
43-
"type_alias definition _types.aggregations:Buckets / union_of / dictionary_of / instance_of - No type definition for '_types.aggregations.Buckets:TBucket'",
44-
"type_alias definition _types.aggregations:Buckets / union_of / array_of / instance_of - No type definition for '_types.aggregations.Buckets:TBucket'",
45-
"type_alias definition _spec_utils:Void / instance_of - No type definition for '_builtins:void'",
46-
"type_alias definition _types:DurationValue / instance_of - No type definition for '_types.DurationValue:Unit'",
47-
"type_alias definition _global.search._types:Suggest - A tagged union should not have generic parameters",
48-
"type_alias definition _global.search._types:Suggest / instance_of / Generics / instance_of - No type definition for '_global.search._types.Suggest:TDocument'",
49-
"type_alias definition _global.search._types:Suggest - Expected 1 generic parameters but got 0"
50-
]
51-
},
5239
"async_search.submit": {
5340
"request": [
54-
"interface definition _types:QueryVectorBuilder - Property text_embedding is a single-variant and must be required",
55-
"type_alias definition _spec_utils:PipeSeparatedFlags / union_of / instance_of - No type definition for '_spec_utils.PipeSeparatedFlags:T'"
41+
"interface definition _types:QueryVectorBuilder - Property text_embedding is a single-variant and must be required"
5642
],
5743
"response": []
5844
},
@@ -62,12 +48,6 @@
6248
],
6349
"response": []
6450
},
65-
"cat.allocation": {
66-
"request": [],
67-
"response": [
68-
"type_alias definition _spec_utils:Stringified / union_of / instance_of - No type definition for '_spec_utils.Stringified:T'"
69-
]
70-
},
7151
"cat.help": {
7252
"request": [
7353
"Request: missing json spec query parameter 'help'",
@@ -170,12 +150,6 @@
170150
],
171151
"response": []
172152
},
173-
"connector.update_error": {
174-
"request": [
175-
"type_alias definition _spec_utils:WithNullValue / union_of / instance_of - No type definition for '_spec_utils.WithNullValue:T'"
176-
],
177-
"response": []
178-
},
179153
"connector.update_features": {
180154
"request": [
181155
"Missing request & response"
@@ -202,12 +176,6 @@
202176
],
203177
"response": []
204178
},
205-
"esql.query": {
206-
"request": [],
207-
"response": [
208-
"type_alias definition _types:EsqlColumns / instance_of - No type definition for '_builtins:binary'"
209-
]
210-
},
211179
"fleet.delete_secret": {
212180
"request": [
213181
"Missing request & response"
@@ -220,12 +188,6 @@
220188
],
221189
"response": []
222190
},
223-
"fleet.msearch": {
224-
"request": [],
225-
"response": [
226-
"type_alias definition _global.msearch:ResponseItem / union_of / instance_of / Generics / instance_of - No type definition for '_global.msearch.ResponseItem:TDocument'"
227-
]
228-
},
229191
"fleet.post_secret": {
230192
"request": [
231193
"Missing request & response"
@@ -338,12 +300,6 @@
338300
],
339301
"response": []
340302
},
341-
"mget": {
342-
"request": [],
343-
"response": [
344-
"type_alias definition _global.mget:ResponseItem / union_of / instance_of / Generics / instance_of - No type definition for '_global.mget.ResponseItem:TDocument'"
345-
]
346-
},
347303
"ml.stop_datafeed": {
348304
"request": [
349305
"Request: missing json spec query parameter 'allow_no_datafeeds'"
@@ -421,9 +377,7 @@
421377
"Request: query parameter 'grid_agg' does not exist in the json spec",
422378
"Request: missing json spec query parameter 'track_total_hits'"
423379
],
424-
"response": [
425-
"type_alias definition _types:MapboxVectorTiles / instance_of - No type definition for '_builtins:binary'"
426-
]
380+
"response": []
427381
},
428382
"searchable_snapshots.clear_cache": {
429383
"request": [

0 commit comments

Comments
 (0)