From 3f5c8469587f0578b224341e748e171d5e45553a Mon Sep 17 00:00:00 2001 From: Florian Bernd Date: Fri, 28 Jun 2024 13:55:17 +0200 Subject: [PATCH] Improve declaration of untagged unions to allow for generator optimizations (#2548) --- compiler-rs/clients_schema/src/lib.rs | 9 + .../clients_schema_to_openapi/src/main.rs | 6 +- .../clients_schema_to_openapi/src/schemas.rs | 2 + .../openapi_to_clients_schema/src/types.rs | 2 +- compiler/src/model/metamodel.ts | 14 +- compiler/src/model/utils.ts | 39 +- compiler/src/steps/validate-model.ts | 70 +- docs/modeling-guide.md | 35 +- .../elasticsearch-serverless-openapi.json | 104 +- output/schema/schema.json | 951 +++++++++--------- output/typescript/types.ts | 50 +- specification/_types/query_dsl/compound.ts | 46 +- specification/_types/query_dsl/specialized.ts | 11 +- specification/_types/query_dsl/term.ts | 75 +- typescript-generator/src/index.ts | 36 +- typescript-generator/src/metamodel.ts | 14 +- 16 files changed, 839 insertions(+), 625 deletions(-) diff --git a/compiler-rs/clients_schema/src/lib.rs b/compiler-rs/clients_schema/src/lib.rs index 4ec7dd66d9..caba0d491f 100644 --- a/compiler-rs/clients_schema/src/lib.rs +++ b/compiler-rs/clients_schema/src/lib.rs @@ -380,6 +380,7 @@ pub enum ServerDefault { pub enum Variants { ExternalTag(ExternalTag), InternalTag(InternalTag), + Untagged(Untagged), Container(Container), } @@ -404,6 +405,13 @@ pub struct InternalTag { pub default_tag: Option, } +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Untagged { + #[serde(default)] + pub non_exhaustive: bool, +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Container { @@ -799,6 +807,7 @@ impl TypeAlias { pub enum TypeAliasVariants { ExternalTag(ExternalTag), InternalTag(InternalTag), + Untagged(Untagged), } //------------------------------------------------------------------------------------------------------------ diff --git a/compiler-rs/clients_schema_to_openapi/src/main.rs b/compiler-rs/clients_schema_to_openapi/src/main.rs index 8601c79e75..4fe74a7589 100644 --- a/compiler-rs/clients_schema_to_openapi/src/main.rs +++ b/compiler-rs/clients_schema_to_openapi/src/main.rs @@ -16,6 +16,7 @@ // under the License. use std::path::{Path, PathBuf}; +use anyhow::bail; use clap::{Parser, ValueEnum}; use clients_schema::{Availabilities, Visibility}; @@ -71,7 +72,10 @@ impl Cli { std::fs::read_to_string(self.schema)? }; - let mut model: clients_schema::IndexedModel = serde_json::from_str(&json)?; + let mut model: clients_schema::IndexedModel = match serde_json::from_str(&json) { + Ok(indexed_model) => indexed_model, + Err(e) => bail!("cannot parse schema json: {}", e) + }; if let Some(flavor) = self.flavor { if flavor != SchemaFlavor::All { diff --git a/compiler-rs/clients_schema_to_openapi/src/schemas.rs b/compiler-rs/clients_schema_to_openapi/src/schemas.rs index 52176f6b2d..7c5a9d09a9 100644 --- a/compiler-rs/clients_schema_to_openapi/src/schemas.rs +++ b/compiler-rs/clients_schema_to_openapi/src/schemas.rs @@ -395,6 +395,8 @@ impl<'a> TypesAndComponents<'a> { extensions: Default::default(), }); } + Some(TypeAliasVariants::Untagged(_tag)) => { + } }; Ok(schema) diff --git a/compiler-rs/openapi_to_clients_schema/src/types.rs b/compiler-rs/openapi_to_clients_schema/src/types.rs index 89b5ea7615..47425510de 100644 --- a/compiler-rs/openapi_to_clients_schema/src/types.rs +++ b/compiler-rs/openapi_to_clients_schema/src/types.rs @@ -323,7 +323,7 @@ fn generate_schema_kind_one_of( let mut variants: Option = None; // TODO: do we want to allow untagged unions (those that are disambiguated by inspecting property names)? - + if let Some(discriminator) = discriminator { variants = Some(TypeAliasVariants::InternalTag(InternalTag { default_tag: None, diff --git a/compiler/src/model/metamodel.ts b/compiler/src/model/metamodel.ts index f40110c6af..5e7d01e23c 100644 --- a/compiler/src/model/metamodel.ts +++ b/compiler/src/model/metamodel.ts @@ -180,7 +180,7 @@ export abstract class BaseType { specLocation: string } -export type Variants = ExternalTag | InternalTag | Container +export type Variants = ExternalTag | InternalTag | Container | Untagged export class VariantBase { /** @@ -207,6 +207,11 @@ export class Container extends VariantBase { kind: 'container' } +export class Untagged extends VariantBase { + kind: 'untagged' + untypedVariant: Inherits +} + /** * Inherits clause (aka extends or implements) for an interface or request */ @@ -364,8 +369,11 @@ export class TypeAlias extends BaseType { type: ValueOf /** generic parameters: either concrete types or open parameters from the enclosing type */ generics?: TypeName[] - /** Only applicable to `union_of` aliases: identify typed_key unions (external) and variant inventories (internal) */ - variants?: InternalTag | ExternalTag + /** + * Only applicable to `union_of` aliases: identify typed_key unions (external), variant inventories (internal) + * and untagged variants + */ + variants?: InternalTag | ExternalTag | Untagged } // ------------------------------------------------------------------------------------------------ diff --git a/compiler/src/model/utils.ts b/compiler/src/model/utils.ts index 22ab709047..e798a34e53 100644 --- a/compiler/src/model/utils.ts +++ b/compiler/src/model/utils.ts @@ -536,8 +536,8 @@ export function modelTypeAlias (declaration: TypeAliasDeclaration): model.TypeAl if (variants != null) { assert( declaration.getJsDocs(), - variants.kind === 'internal_tag' || variants.kind === 'external_tag', - 'Type Aliases can only have internal or external variants' + variants.kind === 'internal_tag' || variants.kind === 'external_tag' || variants.kind === 'untagged', + 'Type Aliases can only have internal, external or untagged variants' ) typeAlias.variants = variants } @@ -1110,17 +1110,34 @@ export function parseVariantsTag (jsDoc: JSDoc[]): model.Variants | undefined { } } - assert(jsDoc, type === 'internal', `Bad variant type: ${type}`) - - const pairs = parseKeyValues(jsDoc, values, 'tag', 'default') - assert(jsDoc, typeof pairs.tag === 'string', 'Internal variant requires a tag definition') + if (type === 'internal') { + const pairs = parseKeyValues(jsDoc, values, 'tag', 'default') + assert(jsDoc, typeof pairs.tag === 'string', 'Internal variant requires a tag definition') + return { + kind: 'internal_tag', + nonExhaustive: nonExhaustive, + tag: pairs.tag, + defaultTag: pairs.default + } + } - return { - kind: 'internal_tag', - nonExhaustive: nonExhaustive, - tag: pairs.tag, - defaultTag: pairs.default + if (type === 'untagged') { + const pairs = parseKeyValues(jsDoc, values, 'untyped') + assert(jsDoc, typeof pairs.untyped === 'string', 'Untagged variant requires an untyped definition') + const fqn = pairs.untyped.split('.') + return { + kind: 'untagged', + nonExhaustive: nonExhaustive, + untypedVariant: { + type: { + namespace: fqn.slice(0, fqn.length - 1).join('.'), + name: fqn[fqn.length - 1] + } + } + } } + + assert(jsDoc, false, `Bad variant type: ${type}`) } /** diff --git a/compiler/src/steps/validate-model.ts b/compiler/src/steps/validate-model.ts index be4500271f..95ba7db7ea 100644 --- a/compiler/src/steps/validate-model.ts +++ b/compiler/src/steps/validate-model.ts @@ -559,14 +559,14 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma if (typeDef.type.kind !== 'union_of') { modelError('The "variants" tag only applies to unions') } else { - validateTaggedUnion(typeDef.type, typeDef.variants) + validateTaggedUnion(typeDef.name, typeDef.type, typeDef.variants) } } else { validateValueOf(typeDef.type, openGenerics) } } - function validateTaggedUnion (valueOf: model.UnionOf, variants: model.InternalTag | model.ExternalTag): void { + function validateTaggedUnion (parentName: TypeName, valueOf: model.UnionOf, variants: model.InternalTag | model.ExternalTag | model.Untagged): void { if (variants.kind === 'external_tag') { // All items must have a 'variant' attribute const items = flattenUnionMembers(valueOf) @@ -610,6 +610,72 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma } validateValueOf(valueOf, new Set()) + } else if (variants.kind === 'untagged') { + if (fqn(parentName) !== '_types.query_dsl:DecayFunction' && + fqn(parentName) !== '_types.query_dsl:DistanceFeatureQuery' && + fqn(parentName) !== '_types.query_dsl:RangeQuery') { + throw new Error(`Please contact the devtools team before adding new untagged variant ${fqn(parentName)}`) + } + + const untypedVariant = getTypeDef(variants.untypedVariant.type) + if (untypedVariant == null) { + modelError(`Type ${fqn(variants.untypedVariant.type)} not found`) + } + + const items = flattenUnionMembers(valueOf) + const baseTypes = new Set() + let foundUntyped = false + + for (const item of items) { + if (item.kind !== 'instance_of') { + modelError('Items of type untagged unions must be type references') + } else { + validateTypeRef(item.type, undefined, new Set()) + const type = getTypeDef(item.type) + if (type == null) { + modelError(`Type ${fqn(item.type)} not found`) + } else { + if (type.kind !== 'interface') { + modelError(`Type ${fqn(item.type)} must be an interface to be used in an untagged union`) + continue + } + + if (untypedVariant != null && fqn(item.type) === fqn(untypedVariant.name)) { + foundUntyped = true + } + + if (type.inherits == null) { + modelError(`Type ${fqn(item.type)} must derive from a base type to be used in an untagged union`) + continue + } + + baseTypes.add(fqn(type.inherits.type)) + + const baseType = getTypeDef(type.inherits.type) + if (baseType == null) { + modelError(`Type ${fqn(type.inherits.type)} not found`) + continue + } + + if (baseType.kind !== 'interface') { + modelError(`Type ${fqn(type.inherits.type)} must be an interface to be used as the base class of another interface`) + continue + } + + if (baseType.generics == null || baseType.generics.length === 0) { + modelError('The common base type of an untagged union must accept at least one generic type argument') + } + } + } + } + + if (baseTypes.size !== 1) { + modelError('All items of an untagged union must derive from the same common base type') + } + + if (!foundUntyped) { + modelError('The untyped variant of an untagged variant must be contained in the union items') + } } } diff --git a/docs/modeling-guide.md b/docs/modeling-guide.md index d2a1b78b94..123a844acb 100644 --- a/docs/modeling-guide.md +++ b/docs/modeling-guide.md @@ -418,7 +418,7 @@ An annotation allows distinguishing these properties from container variants: For example: -``` +```ts /** * @variants container */ @@ -435,6 +435,39 @@ class AggregationContainer { ... ``` +#### Untagged + +The untagged variant is used for unions that can only be distinguished by the type of one or more fields. + +> [!WARNING] +> This variant should only be used for legacy types and should otherwise be avoided as far as possible, as it leads to less optimal code generation in the client libraries. + +The syntax is: + +```ts +/** @variants untagged */ +``` + +Untagged variants must exactly follow a defined pattern. + +For example: + +```ts +export class MyTypeBase { ... } + +export class MyTypeUntyped extends MyTypeBase {} +export class MyTypeSpecialized1 extends MyTypeBase {} +export class MyTypeSpecialized2 extends MyTypeBase {} +export class MyTypeSpecialized3 extends MyTypeBase {} + +/** + * @codegen_names untyped, mytype1, mytypet2, mytype3 + * @variant untagged untyped=_types.MyTypeUntyped + */ +// Note: deserialization depends on value types +export type MyType = MyTypeUntyped | MyTypeSpecialized1 | MyTypeSpecialized2 | MyTypeSpecialized3 +``` + ### Shortcut properties In many places Elasticsearch accepts a property value to be either a complete data structure or a single value, that value being a shortcut for a property in the data structure. diff --git a/output/openapi/elasticsearch-serverless-openapi.json b/output/openapi/elasticsearch-serverless-openapi.json index d5390aac36..03a2ba47c8 100644 --- a/output/openapi/elasticsearch-serverless-openapi.json +++ b/output/openapi/elasticsearch-serverless-openapi.json @@ -35094,14 +35094,14 @@ "_types.query_dsl:DateDecayFunction": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBase" + "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBaseDateMathDuration" }, { "type": "object" } ] }, - "_types.query_dsl:DecayFunctionBase": { + "_types.query_dsl:DecayFunctionBaseDateMathDuration": { "type": "object", "properties": { "multi_value_mode": { @@ -35121,23 +35121,39 @@ "_types.query_dsl:NumericDecayFunction": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBase" + "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBasedoubledouble" }, { "type": "object" } ] }, + "_types.query_dsl:DecayFunctionBasedoubledouble": { + "type": "object", + "properties": { + "multi_value_mode": { + "$ref": "#/components/schemas/_types.query_dsl:MultiValueMode" + } + } + }, "_types.query_dsl:GeoDecayFunction": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBase" + "$ref": "#/components/schemas/_types.query_dsl:DecayFunctionBaseGeoLocationDistance" }, { "type": "object" } ] }, + "_types.query_dsl:DecayFunctionBaseGeoLocationDistance": { + "type": "object", + "properties": { + "multi_value_mode": { + "$ref": "#/components/schemas/_types.query_dsl:MultiValueMode" + } + } + }, "_types.query_dsl:FieldValueFactorScoreFunction": { "type": "object", "properties": { @@ -37685,18 +37701,31 @@ "$ref": "#/components/schemas/_types.query_dsl:NumberRangeQuery" }, { - "$ref": "#/components/schemas/_types.query_dsl:TermsRangeQuery" + "$ref": "#/components/schemas/_types.query_dsl:TermRangeQuery" } ] }, "_types.query_dsl:DateRangeQuery": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBase" + "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBaseDateMath" + }, + { + "type": "object" + } + ] + }, + "_types.query_dsl:RangeQueryBaseDateMath": { + "allOf": [ + { + "$ref": "#/components/schemas/_types.query_dsl:QueryBase" }, { "type": "object", "properties": { + "relation": { + "$ref": "#/components/schemas/_types.query_dsl:RangeRelation" + }, "gt": { "$ref": "#/components/schemas/_types:DateMath" }, @@ -37741,43 +37770,41 @@ } ] }, + "_types.query_dsl:RangeRelation": { + "type": "string", + "enum": [ + "within", + "contains", + "intersects" + ] + }, "_types:DateFormat": { "externalDocs": { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html" }, "type": "string" }, - "_types.query_dsl:RangeQueryBase": { + "_types.query_dsl:NumberRangeQuery": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:QueryBase" + "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBasedouble" }, { - "type": "object", - "properties": { - "relation": { - "$ref": "#/components/schemas/_types.query_dsl:RangeRelation" - } - } + "type": "object" } ] }, - "_types.query_dsl:RangeRelation": { - "type": "string", - "enum": [ - "within", - "contains", - "intersects" - ] - }, - "_types.query_dsl:NumberRangeQuery": { + "_types.query_dsl:RangeQueryBasedouble": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBase" + "$ref": "#/components/schemas/_types.query_dsl:QueryBase" }, { "type": "object", "properties": { + "relation": { + "$ref": "#/components/schemas/_types.query_dsl:RangeRelation" + }, "gt": { "description": "Greater than.", "type": "number" @@ -37815,19 +37842,38 @@ "type": "string" } ] + }, + "format": { + "$ref": "#/components/schemas/_types:DateFormat" + }, + "time_zone": { + "$ref": "#/components/schemas/_types:TimeZone" } } } ] }, - "_types.query_dsl:TermsRangeQuery": { + "_types.query_dsl:TermRangeQuery": { + "allOf": [ + { + "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBasestring" + }, + { + "type": "object" + } + ] + }, + "_types.query_dsl:RangeQueryBasestring": { "allOf": [ { - "$ref": "#/components/schemas/_types.query_dsl:RangeQueryBase" + "$ref": "#/components/schemas/_types.query_dsl:QueryBase" }, { "type": "object", "properties": { + "relation": { + "$ref": "#/components/schemas/_types.query_dsl:RangeRelation" + }, "gt": { "description": "Greater than.", "type": "string" @@ -37865,6 +37911,12 @@ "type": "string" } ] + }, + "format": { + "$ref": "#/components/schemas/_types:DateFormat" + }, + "time_zone": { + "$ref": "#/components/schemas/_types:TimeZone" } } } diff --git a/output/schema/schema.json b/output/schema/schema.json index 6a7ea111e5..5973cefdcf 100644 --- a/output/schema/schema.json +++ b/output/schema/schema.json @@ -75116,7 +75116,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L28-L52" + "specLocation": "_types/query_dsl/compound.ts#L29-L53" }, { "inherits": { @@ -75168,7 +75168,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L54-L67" + "specLocation": "_types/query_dsl/compound.ts#L55-L68" }, { "kind": "enum", @@ -75434,57 +75434,45 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L69-L76" + "specLocation": "_types/query_dsl/compound.ts#L70-L77" }, { "attachedBehaviors": [ "AdditionalProperty" ], - "behaviors": [ - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "Field", - "namespace": "_types" - } - }, - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - }, - { - "kind": "instance_of", - "type": { - "name": "Duration", - "namespace": "_types" - } + "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "Field", + "namespace": "_types" + } + }, + { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "DateMath", + "namespace": "_types" + } + }, + { + "kind": "instance_of", + "type": { + "name": "Duration", + "namespace": "_types" } - ], - "kind": "instance_of", - "type": { - "name": "DecayPlacement", - "namespace": "_types.query_dsl" } + ], + "kind": "instance_of", + "type": { + "name": "DecayPlacement", + "namespace": "_types.query_dsl" } - ], - "meta": { - "key": "field", - "value": "placement" - }, - "type": { - "name": "AdditionalProperty", - "namespace": "_spec_utils" } - } - ], - "inherits": { + ], "type": { "name": "DecayFunctionBase", "namespace": "_types.query_dsl" @@ -75496,7 +75484,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/compound.ts#L189-L194" + "specLocation": "_types/query_dsl/compound.ts#L196-L199" }, { "inherits": { @@ -75527,10 +75515,19 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/specialized.ts#L67-L70" + "specLocation": "_types/query_dsl/specialized.ts#L72-L75" }, { "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "DateMath", + "namespace": "_types" + } + } + ], "type": { "name": "RangeQueryBase", "namespace": "_types.query_dsl" @@ -75542,100 +75539,6 @@ "namespace": "_types.query_dsl" }, "properties": [ - { - "description": "Greater than.", - "name": "gt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - } - }, - { - "description": "Greater than or equal to.", - "name": "gte", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - } - }, - { - "description": "Less than.", - "name": "lt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - } - }, - { - "description": "Less than or equal to.", - "name": "lte", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - } - }, - { - "name": "from", - "required": false, - "type": { - "items": [ - { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } - } - ], - "kind": "union_of" - } - }, - { - "name": "to", - "required": false, - "type": { - "items": [ - { - "kind": "instance_of", - "type": { - "name": "DateMath", - "namespace": "_types" - } - }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } - } - ], - "kind": "union_of" - } - }, { "description": "Date format used to convert `date` values in the query.", "name": "format", @@ -75661,10 +75564,11 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L116-L143" + "specLocation": "_types/query_dsl/term.ts#L146-L155" }, { "codegenNames": [ + "untyped", "date", "numeric", "geo" @@ -75674,9 +75578,16 @@ "name": "DecayFunction", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/compound.ts#L203-L208", + "specLocation": "_types/query_dsl/compound.ts#L205-L214", "type": { "items": [ + { + "kind": "instance_of", + "type": { + "name": "UntypedDecayFunction", + "namespace": "_types.query_dsl" + } + }, { "kind": "instance_of", "type": { @@ -75700,9 +75611,59 @@ } ], "kind": "union_of" + }, + "variants": { + "kind": "untagged", + "untypedVariant": { + "type": { + "name": "UntypedDecayFunction", + "namespace": "_types.query_dsl" + } + } } }, { + "attachedBehaviors": [ + "AdditionalProperty" + ], + "behaviors": [ + { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "TOrigin", + "namespace": "_types.query_dsl.DecayFunctionBase" + } + }, + { + "kind": "instance_of", + "type": { + "name": "TScale", + "namespace": "_types.query_dsl.DecayFunctionBase" + } + } + ], + "meta": { + "key": "field", + "value": "placement" + }, + "type": { + "name": "AdditionalProperty", + "namespace": "_spec_utils" + } + } + ], + "generics": [ + { + "name": "TOrigin", + "namespace": "_types.query_dsl.DecayFunctionBase" + }, + { + "name": "TScale", + "namespace": "_types.query_dsl.DecayFunctionBase" + } + ], "kind": "interface", "name": { "name": "DecayFunctionBase", @@ -75723,7 +75684,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L174-L180" + "specLocation": "_types/query_dsl/compound.ts#L175-L186" }, { "generics": [ @@ -75793,7 +75754,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L153-L172" + "specLocation": "_types/query_dsl/compound.ts#L154-L173" }, { "inherits": { @@ -75837,10 +75798,11 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L78-L90" + "specLocation": "_types/query_dsl/compound.ts#L79-L91" }, { "codegenNames": [ + "untyped", "geo", "date" ], @@ -75849,9 +75811,16 @@ "name": "DistanceFeatureQuery", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/specialized.ts#L72-L76", + "specLocation": "_types/query_dsl/specialized.ts#L77-L85", "type": { "items": [ + { + "kind": "instance_of", + "type": { + "name": "UntypedDistanceFeatureQuery", + "namespace": "_types.query_dsl" + } + }, { "kind": "instance_of", "type": { @@ -75868,6 +75837,15 @@ } ], "kind": "union_of" + }, + "variants": { + "kind": "untagged", + "untypedVariant": { + "type": { + "name": "UntypedDistanceFeatureQuery", + "namespace": "_types.query_dsl" + } + } } }, { @@ -75958,7 +75936,7 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L36-L41" + "specLocation": "_types/query_dsl/term.ts#L37-L42" }, { "description": "A reference to a field with formatting instructions on how to return the value", @@ -76113,7 +76091,7 @@ "name": "FieldValueFactorModifier", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/compound.ts#L307-L350" + "specLocation": "_types/query_dsl/compound.ts#L313-L356" }, { "kind": "interface", @@ -76172,7 +76150,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L132-L151" + "specLocation": "_types/query_dsl/compound.ts#L133-L152" }, { "kind": "enum", @@ -76206,7 +76184,7 @@ "name": "FunctionBoostMode", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/compound.ts#L279-L305" + "specLocation": "_types/query_dsl/compound.ts#L285-L311" }, { "esQuirk": "this container is valid without a variant. Despite being documented as a function, 'weight'\nis actually a container property that can be combined with a function. Comment in the ES code\n(SearchModule#registerScoreFunctions) says: Weight doesn't have its own parser, so every function\nsupports it out of the box. Can be a single function too when not associated to any other function,\nwhich is why it needs to be registered manually here.", @@ -76313,7 +76291,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L210-L250", + "specLocation": "_types/query_dsl/compound.ts#L216-L256", "variants": { "kind": "container" } @@ -76350,7 +76328,7 @@ "name": "FunctionScoreMode", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/compound.ts#L252-L277" + "specLocation": "_types/query_dsl/compound.ts#L258-L283" }, { "inherits": { @@ -76443,7 +76421,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L92-L118" + "specLocation": "_types/query_dsl/compound.ts#L93-L119" }, { "inherits": { @@ -76559,7 +76537,7 @@ } ], "shortcutProperty": "value", - "specLocation": "_types/query_dsl/term.ts#L43-L78" + "specLocation": "_types/query_dsl/term.ts#L44-L79" }, { "attachedBehaviors": [ @@ -76653,51 +76631,39 @@ "attachedBehaviors": [ "AdditionalProperty" ], - "behaviors": [ - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "Field", - "namespace": "_types" - } - }, - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "GeoLocation", - "namespace": "_types" - } - }, - { - "kind": "instance_of", - "type": { - "name": "Distance", - "namespace": "_types" - } + "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "Field", + "namespace": "_types" + } + }, + { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "GeoLocation", + "namespace": "_types" + } + }, + { + "kind": "instance_of", + "type": { + "name": "Distance", + "namespace": "_types" } - ], - "kind": "instance_of", - "type": { - "name": "DecayPlacement", - "namespace": "_types.query_dsl" } + ], + "kind": "instance_of", + "type": { + "name": "DecayPlacement", + "namespace": "_types.query_dsl" } - ], - "meta": { - "key": "field", - "value": "placement" - }, - "type": { - "name": "AdditionalProperty", - "namespace": "_spec_utils" } - } - ], - "inherits": { + ], "type": { "name": "DecayFunctionBase", "namespace": "_types.query_dsl" @@ -76709,7 +76675,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/compound.ts#L196-L201" + "specLocation": "_types/query_dsl/compound.ts#L200-L203" }, { "inherits": { @@ -76740,7 +76706,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/specialized.ts#L62-L65" + "specLocation": "_types/query_dsl/specialized.ts#L67-L70" }, { "attachedBehaviors": [ @@ -77293,7 +77259,7 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L80-L85" + "specLocation": "_types/query_dsl/term.ts#L81-L86" }, { "kind": "interface", @@ -77974,7 +77940,7 @@ "name": "Like", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/specialized.ts#L186-L191", + "specLocation": "_types/query_dsl/specialized.ts#L195-L200", "type": { "items": [ { @@ -78106,7 +78072,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L162-L184" + "specLocation": "_types/query_dsl/specialized.ts#L171-L193" }, { "inherits": { @@ -78909,7 +78875,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L78-L160" + "specLocation": "_types/query_dsl/specialized.ts#L87-L169" }, { "inherits": { @@ -79176,7 +79142,7 @@ "name": "MultiValueMode", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/compound.ts#L352-L369" + "specLocation": "_types/query_dsl/compound.ts#L358-L375" }, { "inherits": { @@ -79260,6 +79226,15 @@ }, { "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "double", + "namespace": "_types" + } + } + ], "type": { "name": "RangeQueryBase", "namespace": "_types.query_dsl" @@ -79270,60 +79245,24 @@ "name": "NumberRangeQuery", "namespace": "_types.query_dsl" }, - "properties": [ - { - "description": "Greater than.", - "name": "gt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "double", - "namespace": "_types" - } - } - }, - { - "description": "Greater than or equal to.", - "name": "gte", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "double", - "namespace": "_types" - } - } - }, - { - "description": "Less than.", - "name": "lt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "double", - "namespace": "_types" - } - } - }, - { - "description": "Less than or equal to.", - "name": "lte", - "required": false, - "type": { + "properties": [], + "specLocation": "_types/query_dsl/term.ts#L157-L157" + }, + { + "attachedBehaviors": [ + "AdditionalProperty" + ], + "inherits": { + "generics": [ + { "kind": "instance_of", "type": { - "name": "double", + "name": "Field", "namespace": "_types" } - } - }, - { - "name": "from", - "required": false, - "type": { - "items": [ + }, + { + "generics": [ { "kind": "instance_of", "type": { @@ -79331,92 +79270,21 @@ "namespace": "_types" } }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } - } - ], - "kind": "union_of" - } - }, - { - "name": "to", - "required": false, - "type": { - "items": [ { "kind": "instance_of", "type": { "name": "double", "namespace": "_types" } - }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } } ], - "kind": "union_of" - } - } - ], - "specLocation": "_types/query_dsl/term.ts#L145-L164" - }, - { - "attachedBehaviors": [ - "AdditionalProperty" - ], - "behaviors": [ - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "Field", - "namespace": "_types" - } - }, - { - "generics": [ - { - "kind": "instance_of", - "type": { - "name": "double", - "namespace": "_types" - } - }, - { - "kind": "instance_of", - "type": { - "name": "double", - "namespace": "_types" - } - } - ], - "kind": "instance_of", - "type": { - "name": "DecayPlacement", - "namespace": "_types.query_dsl" - } + "kind": "instance_of", + "type": { + "name": "DecayPlacement", + "namespace": "_types.query_dsl" } - ], - "meta": { - "key": "field", - "value": "placement" - }, - "type": { - "name": "AdditionalProperty", - "namespace": "_spec_utils" } - } - ], - "inherits": { + ], "type": { "name": "DecayFunctionBase", "namespace": "_types.query_dsl" @@ -79428,7 +79296,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/compound.ts#L182-L187" + "specLocation": "_types/query_dsl/compound.ts#L192-L195" }, { "kind": "enum", @@ -79622,7 +79490,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L193-L230" + "specLocation": "_types/query_dsl/specialized.ts#L202-L239" }, { "kind": "interface", @@ -79656,7 +79524,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L253-L262" + "specLocation": "_types/query_dsl/specialized.ts#L262-L271" }, { "inherits": { @@ -79715,7 +79583,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L232-L251", + "specLocation": "_types/query_dsl/specialized.ts#L241-L260", "variants": { "kind": "container" } @@ -79781,7 +79649,7 @@ } ], "shortcutProperty": "value", - "specLocation": "_types/query_dsl/term.ts#L87-L106" + "specLocation": "_types/query_dsl/term.ts#L88-L107" }, { "kind": "interface", @@ -81272,22 +81140,30 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L127-L130" + "specLocation": "_types/query_dsl/compound.ts#L128-L131" }, { "codegenNames": [ + "untyped", "date", "number", - "terms" + "term" ], "kind": "type_alias", "name": { "name": "RangeQuery", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/term.ts#L187-L189", + "specLocation": "_types/query_dsl/term.ts#L161-L170", "type": { "items": [ + { + "kind": "instance_of", + "type": { + "name": "UntypedRangeQuery", + "namespace": "_types.query_dsl" + } + }, { "kind": "instance_of", "type": { @@ -81305,15 +81181,30 @@ { "kind": "instance_of", "type": { - "name": "TermsRangeQuery", + "name": "TermRangeQuery", "namespace": "_types.query_dsl" } } ], "kind": "union_of" + }, + "variants": { + "kind": "untagged", + "untypedVariant": { + "type": { + "name": "UntypedRangeQuery", + "namespace": "_types.query_dsl" + } + } } }, { + "generics": [ + { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + ], "inherits": { "type": { "name": "QueryBase", @@ -81327,20 +81218,114 @@ }, "properties": [ { - "description": "Indicates how the range query matches values for `range` fields.", - "name": "relation", + "description": "Indicates how the range query matches values for `range` fields.", + "name": "relation", + "required": false, + "serverDefault": "intersects", + "type": { + "kind": "instance_of", + "type": { + "name": "RangeRelation", + "namespace": "_types.query_dsl" + } + } + }, + { + "description": "Greater than.", + "name": "gt", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + } + }, + { + "description": "Greater than or equal to.", + "name": "gte", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + } + }, + { + "description": "Less than.", + "name": "lt", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + } + }, + { + "description": "Less than or equal to.", + "name": "lte", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + } + }, + { + "name": "from", + "required": false, + "type": { + "items": [ + { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + }, + { + "kind": "instance_of", + "type": { + "name": "null", + "namespace": "_builtins" + } + } + ], + "kind": "union_of" + } + }, + { + "name": "to", "required": false, - "serverDefault": "intersects", "type": { - "kind": "instance_of", - "type": { - "name": "RangeRelation", - "namespace": "_types.query_dsl" - } + "items": [ + { + "kind": "instance_of", + "type": { + "name": "T", + "namespace": "_types.query_dsl.RangeQueryBase" + } + }, + { + "kind": "instance_of", + "type": { + "name": "null", + "namespace": "_builtins" + } + } + ], + "kind": "union_of" } } ], - "specLocation": "_types/query_dsl/term.ts#L108-L114" + "specLocation": "_types/query_dsl/term.ts#L109-L133" }, { "kind": "enum", @@ -81362,7 +81347,7 @@ "name": "RangeRelation", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/term.ts#L191-L204" + "specLocation": "_types/query_dsl/term.ts#L172-L185" }, { "kind": "interface", @@ -81371,7 +81356,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/specialized.ts#L264-L264" + "specLocation": "_types/query_dsl/specialized.ts#L273-L273" }, { "inherits": { @@ -81386,7 +81371,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/specialized.ts#L266-L266" + "specLocation": "_types/query_dsl/specialized.ts#L275-L275" }, { "inherits": { @@ -81414,7 +81399,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L268-L273" + "specLocation": "_types/query_dsl/specialized.ts#L277-L282" }, { "inherits": { @@ -81442,7 +81427,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L275-L280" + "specLocation": "_types/query_dsl/specialized.ts#L284-L289" }, { "inherits": { @@ -81482,7 +81467,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L282-L291" + "specLocation": "_types/query_dsl/specialized.ts#L291-L300" }, { "inherits": { @@ -81558,7 +81543,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L293-L316" + "specLocation": "_types/query_dsl/specialized.ts#L302-L325" }, { "inherits": { @@ -81650,7 +81635,7 @@ } ], "shortcutProperty": "value", - "specLocation": "_types/query_dsl/term.ts#L206-L236" + "specLocation": "_types/query_dsl/term.ts#L187-L217" }, { "inherits": { @@ -81698,7 +81683,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L372-L376" + "specLocation": "_types/query_dsl/specialized.ts#L381-L385" }, { "inherits": { @@ -81726,7 +81711,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L318-L324" + "specLocation": "_types/query_dsl/specialized.ts#L327-L333" }, { "kind": "interface", @@ -81748,7 +81733,7 @@ } } ], - "specLocation": "_types/query_dsl/compound.ts#L120-L125" + "specLocation": "_types/query_dsl/compound.ts#L121-L126" }, { "inherits": { @@ -81800,7 +81785,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L326-L340" + "specLocation": "_types/query_dsl/specialized.ts#L335-L349" }, { "inherits": { @@ -81886,7 +81871,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L357-L370" + "specLocation": "_types/query_dsl/specialized.ts#L366-L379" }, { "attachedBehaviors": [ @@ -81945,7 +81930,7 @@ } } ], - "specLocation": "_types/query_dsl/specialized.ts#L342-L355" + "specLocation": "_types/query_dsl/specialized.ts#L351-L364" }, { "kind": "enum", @@ -82946,7 +82931,31 @@ } ], "shortcutProperty": "value", - "specLocation": "_types/query_dsl/term.ts#L238-L252" + "specLocation": "_types/query_dsl/term.ts#L219-L233" + }, + { + "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "string", + "namespace": "_builtins" + } + } + ], + "type": { + "name": "RangeQueryBase", + "namespace": "_types.query_dsl" + } + }, + "kind": "interface", + "name": { + "name": "TermRangeQuery", + "namespace": "_types.query_dsl" + }, + "properties": [], + "specLocation": "_types/query_dsl/term.ts#L159-L159" }, { "kind": "interface", @@ -83000,7 +83009,7 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L266-L271" + "specLocation": "_types/query_dsl/term.ts#L247-L252" }, { "attachedBehaviors": [ @@ -83046,7 +83055,7 @@ "namespace": "_types.query_dsl" }, "properties": [], - "specLocation": "_types/query_dsl/term.ts#L254-L259" + "specLocation": "_types/query_dsl/term.ts#L235-L240" }, { "codegenNames": [ @@ -83058,7 +83067,7 @@ "name": "TermsQueryField", "namespace": "_types.query_dsl" }, - "specLocation": "_types/query_dsl/term.ts#L261-L264", + "specLocation": "_types/query_dsl/term.ts#L242-L245", "type": { "items": [ { @@ -83082,116 +83091,6 @@ "kind": "union_of" } }, - { - "inherits": { - "type": { - "name": "RangeQueryBase", - "namespace": "_types.query_dsl" - } - }, - "kind": "interface", - "name": { - "name": "TermsRangeQuery", - "namespace": "_types.query_dsl" - }, - "properties": [ - { - "description": "Greater than.", - "name": "gt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - } - }, - { - "description": "Greater than or equal to.", - "name": "gte", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - } - }, - { - "description": "Less than.", - "name": "lt", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - } - }, - { - "description": "Less than or equal to.", - "name": "lte", - "required": false, - "type": { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - } - }, - { - "name": "from", - "required": false, - "type": { - "items": [ - { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } - } - ], - "kind": "union_of" - } - }, - { - "name": "to", - "required": false, - "type": { - "items": [ - { - "kind": "instance_of", - "type": { - "name": "string", - "namespace": "_builtins" - } - }, - { - "kind": "instance_of", - "type": { - "name": "null", - "namespace": "_builtins" - } - } - ], - "kind": "union_of" - } - } - ], - "specLocation": "_types/query_dsl/term.ts#L166-L185" - }, { "inherits": { "type": { @@ -83245,7 +83144,7 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L273-L286" + "specLocation": "_types/query_dsl/term.ts#L254-L267" }, { "inherits": { @@ -83418,7 +83317,105 @@ } } ], - "specLocation": "_types/query_dsl/term.ts#L288-L290" + "specLocation": "_types/query_dsl/term.ts#L269-L271" + }, + { + "attachedBehaviors": [ + "AdditionalProperty" + ], + "inherits": { + "generics": [ + { + "kind": "instance_of", + "type": { + "name": "Field", + "namespace": "_types" + } + }, + { + "kind": "user_defined_value" + } + ], + "type": { + "name": "DecayFunctionBase", + "namespace": "_types.query_dsl" + } + }, + "kind": "interface", + "name": { + "name": "UntypedDecayFunction", + "namespace": "_types.query_dsl" + }, + "properties": [], + "specLocation": "_types/query_dsl/compound.ts#L188-L191" + }, + { + "inherits": { + "generics": [ + { + "kind": "user_defined_value" + }, + { + "kind": "user_defined_value" + } + ], + "type": { + "name": "DistanceFeatureQueryBase", + "namespace": "_types.query_dsl" + } + }, + "kind": "interface", + "name": { + "name": "UntypedDistanceFeatureQuery", + "namespace": "_types.query_dsl" + }, + "properties": [], + "specLocation": "_types/query_dsl/specialized.ts#L62-L65" + }, + { + "inherits": { + "generics": [ + { + "kind": "user_defined_value" + } + ], + "type": { + "name": "RangeQueryBase", + "namespace": "_types.query_dsl" + } + }, + "kind": "interface", + "name": { + "name": "UntypedRangeQuery", + "namespace": "_types.query_dsl" + }, + "properties": [ + { + "description": "Date format used to convert `date` values in the query.", + "name": "format", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "DateFormat", + "namespace": "_types" + } + } + }, + { + "description": "Coordinated Universal Time (UTC) offset or IANA time zone used to convert `date` values in the query to UTC.", + "name": "time_zone", + "required": false, + "type": { + "kind": "instance_of", + "type": { + "name": "TimeZone", + "namespace": "_types" + } + } + } + ], + "specLocation": "_types/query_dsl/term.ts#L135-L144" }, { "inherits": { @@ -83543,7 +83540,7 @@ } ], "shortcutProperty": "value", - "specLocation": "_types/query_dsl/term.ts#L292-L309" + "specLocation": "_types/query_dsl/term.ts#L273-L290" }, { "inherits": { diff --git a/output/typescript/types.ts b/output/typescript/types.ts index cb598f9b5b..4d78da010e 100644 --- a/output/typescript/types.ts +++ b/output/typescript/types.ts @@ -5492,7 +5492,7 @@ export interface QueryDslConstantScoreQuery extends QueryDslQueryBase { filter: QueryDslQueryContainer } -export interface QueryDslDateDecayFunctionKeys extends QueryDslDecayFunctionBase { +export interface QueryDslDateDecayFunctionKeys extends QueryDslDecayFunctionBase { } export type QueryDslDateDecayFunction = QueryDslDateDecayFunctionKeys & { [property: string]: QueryDslDecayPlacement | QueryDslMultiValueMode } @@ -5500,20 +5500,12 @@ export type QueryDslDateDecayFunction = QueryDslDateDecayFunctionKeys export interface QueryDslDateDistanceFeatureQuery extends QueryDslDistanceFeatureQueryBase { } -export interface QueryDslDateRangeQuery extends QueryDslRangeQueryBase { - gt?: DateMath - gte?: DateMath - lt?: DateMath - lte?: DateMath - from?: DateMath | null - to?: DateMath | null - format?: DateFormat - time_zone?: TimeZone +export interface QueryDslDateRangeQuery extends QueryDslRangeQueryBase { } export type QueryDslDecayFunction = QueryDslDateDecayFunction | QueryDslNumericDecayFunction | QueryDslGeoDecayFunction -export interface QueryDslDecayFunctionBase { +export interface QueryDslDecayFunctionBase { multi_value_mode?: QueryDslMultiValueMode } @@ -5604,7 +5596,7 @@ export interface QueryDslGeoBoundingBoxQueryKeys extends QueryDslQueryBase { export type QueryDslGeoBoundingBoxQuery = QueryDslGeoBoundingBoxQueryKeys & { [property: string]: GeoBounds | QueryDslGeoExecution | QueryDslGeoValidationMethod | boolean | float | string } -export interface QueryDslGeoDecayFunctionKeys extends QueryDslDecayFunctionBase { +export interface QueryDslGeoDecayFunctionKeys extends QueryDslDecayFunctionBase { } export type QueryDslGeoDecayFunction = QueryDslGeoDecayFunctionKeys & { [property: string]: QueryDslDecayPlacement | QueryDslMultiValueMode } @@ -5855,16 +5847,10 @@ export interface QueryDslNestedQuery extends QueryDslQueryBase { score_mode?: QueryDslChildScoreMode } -export interface QueryDslNumberRangeQuery extends QueryDslRangeQueryBase { - gt?: double - gte?: double - lt?: double - lte?: double - from?: double | null - to?: double | null +export interface QueryDslNumberRangeQuery extends QueryDslRangeQueryBase { } -export interface QueryDslNumericDecayFunctionKeys extends QueryDslDecayFunctionBase { +export interface QueryDslNumericDecayFunctionKeys extends QueryDslDecayFunctionBase { } export type QueryDslNumericDecayFunction = QueryDslNumericDecayFunctionKeys & { [property: string]: QueryDslDecayPlacement | QueryDslMultiValueMode } @@ -6007,10 +5993,18 @@ export interface QueryDslRandomScoreFunction { seed?: long | string } -export type QueryDslRangeQuery = QueryDslDateRangeQuery | QueryDslNumberRangeQuery | QueryDslTermsRangeQuery +export type QueryDslRangeQuery = QueryDslDateRangeQuery | QueryDslNumberRangeQuery | QueryDslTermRangeQuery -export interface QueryDslRangeQueryBase extends QueryDslQueryBase { +export interface QueryDslRangeQueryBase extends QueryDslQueryBase { relation?: QueryDslRangeRelation + gt?: T + gte?: T + lt?: T + lte?: T + from?: T | null + to?: T | null + format?: DateFormat + time_zone?: TimeZone } export type QueryDslRangeRelation = 'within' | 'contains' | 'intersects' @@ -6184,6 +6178,9 @@ export interface QueryDslTermQuery extends QueryDslQueryBase { case_insensitive?: boolean } +export interface QueryDslTermRangeQuery extends QueryDslRangeQueryBase { +} + export interface QueryDslTermsLookup { index: IndexName id: Id @@ -6198,15 +6195,6 @@ export type QueryDslTermsQuery = QueryDslTermsQueryKeys export type QueryDslTermsQueryField = FieldValue[] | QueryDslTermsLookup -export interface QueryDslTermsRangeQuery extends QueryDslRangeQueryBase { - gt?: string - gte?: string - lt?: string - lte?: string - from?: string | null - to?: string | null -} - export interface QueryDslTermsSetQuery extends QueryDslQueryBase { minimum_should_match_field?: Field minimum_should_match_script?: Script diff --git a/specification/_types/query_dsl/compound.ts b/specification/_types/query_dsl/compound.ts index d613b08a76..662eb434d9 100644 --- a/specification/_types/query_dsl/compound.ts +++ b/specification/_types/query_dsl/compound.ts @@ -24,6 +24,7 @@ import { double, float, long } from '@_types/Numeric' import { Script } from '@_types/Scripting' import { DateMath, Duration } from '@_types/Time' import { QueryBase, QueryContainer } from './abstractions' +import { UserDefinedValue } from '@spec_utils/UserDefinedValue' export class BoolQuery extends QueryBase { /** @@ -171,7 +172,12 @@ export class DecayPlacement { origin?: TOrigin } -export class DecayFunctionBase { +/** + * @behavior_meta AdditionalProperty key=field value=placement + */ +export class DecayFunctionBase + implements AdditionalProperty +{ /** * Determines how the distance is calculated when a field used for computing the decay contains multiple values. * @server_default min @@ -179,30 +185,30 @@ export class DecayFunctionBase { multi_value_mode?: MultiValueMode } -/** - * @behavior_meta AdditionalProperty key=field value=placement - */ -export class NumericDecayFunction - extends DecayFunctionBase - implements AdditionalProperty> {} - -/** - * @behavior_meta AdditionalProperty key=field value=placement - */ -export class DateDecayFunction - extends DecayFunctionBase - implements AdditionalProperty> {} +export class UntypedDecayFunction extends DecayFunctionBase< + Field, + UserDefinedValue +> {} +export class NumericDecayFunction extends DecayFunctionBase< + Field, + DecayPlacement +> {} +export class DateDecayFunction extends DecayFunctionBase< + Field, + DecayPlacement +> {} +export class GeoDecayFunction extends DecayFunctionBase< + Field, + DecayPlacement +> {} /** - * @behavior_meta AdditionalProperty key=field value=placement + * @codegen_names untyped, date, numeric, geo + * @variants untagged untyped=_types.query_dsl.UntypedDecayFunction */ -export class GeoDecayFunction - extends DecayFunctionBase - implements AdditionalProperty> {} - -/** @codegen_names date, numeric, geo */ // Note: deserialization depends on value types export type DecayFunction = + | UntypedDecayFunction | DateDecayFunction | NumericDecayFunction | GeoDecayFunction diff --git a/specification/_types/query_dsl/specialized.ts b/specification/_types/query_dsl/specialized.ts index 6dcf67901e..5d9997f5fd 100644 --- a/specification/_types/query_dsl/specialized.ts +++ b/specification/_types/query_dsl/specialized.ts @@ -59,6 +59,11 @@ export class DistanceFeatureQueryBase extends QueryBase { field: Field } +export class UntypedDistanceFeatureQuery extends DistanceFeatureQueryBase< + UserDefinedValue, + UserDefinedValue +> {} + export class GeoDistanceFeatureQuery extends DistanceFeatureQueryBase< GeoLocation, Distance @@ -69,9 +74,13 @@ export class DateDistanceFeatureQuery extends DistanceFeatureQueryBase< Duration > {} -/** @codegen_names geo, date */ +/** + * @codegen_names untyped, geo, date + * @variants untagged untyped=_types.query_dsl.UntypedDistanceFeatureQuery + */ // Note: deserialization depends on value types export type DistanceFeatureQuery = + | UntypedDistanceFeatureQuery | GeoDistanceFeatureQuery | DateDistanceFeatureQuery diff --git a/specification/_types/query_dsl/term.ts b/specification/_types/query_dsl/term.ts index c43d09e156..30367453c8 100644 --- a/specification/_types/query_dsl/term.ts +++ b/specification/_types/query_dsl/term.ts @@ -32,6 +32,7 @@ import { Script } from '@_types/Scripting' import { DateFormat, DateMath, TimeZone } from '@_types/Time' import { QueryBase } from './abstractions' import { AdditionalProperty } from '@spec_utils/behaviors' +import { UserDefinedValue } from '@spec_utils/UserDefinedValue' export class ExistsQuery extends QueryBase { /** @@ -105,33 +106,33 @@ export class PrefixQuery extends QueryBase { case_insensitive?: boolean } -export class RangeQueryBase extends QueryBase { +export class RangeQueryBase extends QueryBase { /** * Indicates how the range query matches values for `range` fields. * @server_default intersects */ relation?: RangeRelation -} - -export class DateRangeQuery extends RangeQueryBase { /** * Greater than. */ - gt?: DateMath + gt?: T /** * Greater than or equal to. */ - gte?: DateMath + gte?: T /** * Less than. */ - lt?: DateMath + lt?: T /** * Less than or equal to. */ - lte?: DateMath - from?: DateMath | null - to?: DateMath | null + lte?: T + from?: T | null + to?: T | null +} + +export class UntypedRangeQuery extends RangeQueryBase { /** * Date format used to convert `date` values in the query. */ @@ -142,51 +143,31 @@ export class DateRangeQuery extends RangeQueryBase { time_zone?: TimeZone } -export class NumberRangeQuery extends RangeQueryBase { - /** - * Greater than. - */ - gt?: double - /** - * Greater than or equal to. - */ - gte?: double +export class DateRangeQuery extends RangeQueryBase { /** - * Less than. + * Date format used to convert `date` values in the query. */ - lt?: double + format?: DateFormat /** - * Less than or equal to. + * Coordinated Universal Time (UTC) offset or IANA time zone used to convert `date` values in the query to UTC. */ - lte?: double - from?: double | null - to?: double | null + time_zone?: TimeZone } -export class TermsRangeQuery extends RangeQueryBase { - /** - * Greater than. - */ - gt?: string - /** - * Greater than or equal to. - */ - gte?: string - /** - * Less than. - */ - lt?: string - /** - * Less than or equal to. - */ - lte?: string - from?: string | null - to?: string | null -} +export class NumberRangeQuery extends RangeQueryBase {} + +export class TermRangeQuery extends RangeQueryBase {} -/** @codegen_names date, number, terms */ +/** + * @codegen_names untyped, date, number, term + * @variants untagged untyped=_types.query_dsl.UntypedRangeQuery + */ // Note: deserialization depends on value types -export type RangeQuery = DateRangeQuery | NumberRangeQuery | TermsRangeQuery +export type RangeQuery = + | UntypedRangeQuery + | DateRangeQuery + | NumberRangeQuery + | TermRangeQuery export enum RangeRelation { /** diff --git a/typescript-generator/src/index.ts b/typescript-generator/src/index.ts index 1e6aa55eb8..d7064db7c9 100644 --- a/typescript-generator/src/index.ts +++ b/typescript-generator/src/index.ts @@ -283,8 +283,21 @@ function buildBehaviorInterface (type: M.Interface): string { // The main difference with this approaches comes when you are actually using the types. 1 and 2 are good when // you are reading an object of that type, while 3 is good when you are writing an object of that type. function serializeAdditionalPropertiesType (type: M.Interface): string { - const dictionaryOf = lookupBehavior(type, 'AdditionalProperties') ?? lookupBehavior(type, 'AdditionalProperty') + let dictionaryOf = lookupBehavior(type, 'AdditionalProperties') ?? lookupBehavior(type, 'AdditionalProperty') if (dictionaryOf == null) throw new Error(`Unknown implements ${type.name.name}`) + + const parent = model.types.find(t => t.name.name === type.inherits?.type.name) + if (parent != null && parent.kind === 'interface' && parent.generics != null && parent.generics.length === type.inherits?.generics?.length) { + const map = new Map() + for (let i = 0; i < parent.generics.length; i++) { + map.set(parent.generics[i], type.inherits.generics[i]) + } + dictionaryOf = { + type: dictionaryOf.type, + generics: dictionaryOf.generics?.map(x => replaceGenerics(x, map)) + } + } + const extendedPropertyTypes = getAllExtendedPropertyTypes(type.inherits) const openGenerics = type.generics?.map(t => t.name) ?? [] let code = `export interface ${createName(type.name)}Keys${buildGenerics(type.generics)}${buildInherits(type)} {\n` @@ -325,6 +338,27 @@ function serializeAdditionalPropertiesType (type: M.Interface): string { } } +function replaceGenerics (value: M.ValueOf, map: Map): M.ValueOf { + if (value.kind !== 'instance_of') { + return value + } + + if (value.generics == null || value.generics.length === 0) { + for (const entry of map) { + if (entry[0].namespace === value.type.namespace && entry[0].name === value.type.name) { + return entry[1] + } + } + return value + } + + return { + kind: 'instance_of', + type: value.type, + generics: value.generics.map(x => replaceGenerics(x, map)) + } +} + function lookupBehavior (type: M.Interface, name: string): M.Inherits | null { if (!type.attachedBehaviors?.includes(name)) return null // eslint-disable-line if (Array.isArray(type.behaviors)) { diff --git a/typescript-generator/src/metamodel.ts b/typescript-generator/src/metamodel.ts index f40110c6af..5e7d01e23c 100644 --- a/typescript-generator/src/metamodel.ts +++ b/typescript-generator/src/metamodel.ts @@ -180,7 +180,7 @@ export abstract class BaseType { specLocation: string } -export type Variants = ExternalTag | InternalTag | Container +export type Variants = ExternalTag | InternalTag | Container | Untagged export class VariantBase { /** @@ -207,6 +207,11 @@ export class Container extends VariantBase { kind: 'container' } +export class Untagged extends VariantBase { + kind: 'untagged' + untypedVariant: Inherits +} + /** * Inherits clause (aka extends or implements) for an interface or request */ @@ -364,8 +369,11 @@ export class TypeAlias extends BaseType { type: ValueOf /** generic parameters: either concrete types or open parameters from the enclosing type */ generics?: TypeName[] - /** Only applicable to `union_of` aliases: identify typed_key unions (external) and variant inventories (internal) */ - variants?: InternalTag | ExternalTag + /** + * Only applicable to `union_of` aliases: identify typed_key unions (external), variant inventories (internal) + * and untagged variants + */ + variants?: InternalTag | ExternalTag | Untagged } // ------------------------------------------------------------------------------------------------