Skip to content

Commit 4619f9d

Browse files
authored
Add the "es_quirk" annotation to capture snowflakes in ES behavior (#1674) (#1678)
1 parent 900d4a7 commit 4619f9d

File tree

9 files changed

+94
-51
lines changed

9 files changed

+94
-51
lines changed

compiler/src/model/metamodel.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ export class Property {
139139
aliases?: string[]
140140
/** If the enclosing class is a variants container, is this a property of the container and not a variant? */
141141
containerProperty?: boolean
142+
/** If this property has a quirk that needs special attention, give a short explanation about it */
143+
esQuirk?: string
142144
}
143145

144146
// ------------------------------------------------------------------------------------------------
@@ -158,6 +160,8 @@ export abstract class BaseType {
158160
docUrl?: string
159161
docId?: string
160162
deprecation?: Deprecation
163+
/** If this endpoint has a quirk that needs special attention, give a short explanation about it */
164+
esQuirk?: string
161165
kind: string
162166
/** Variant name for externally tagged variants */
163167
variantName?: string

compiler/src/model/utils.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ export function modelEnumDeclaration (declaration: EnumDeclaration): model.Enum
439439
type.isOpen = true
440440
}
441441

442+
if (typeof tags.es_quirk === 'string') {
443+
type.esQuirk = tags.es_quirk
444+
}
445+
442446
return type
443447
}
444448

@@ -639,7 +643,8 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
639643
// We want to enforce a single jsDoc block.
640644
assert(jsDocs, jsDocs.length < 2, 'Use a single multiline jsDoc block instead of multiple single line blocks')
641645

642-
const validTags = ['class_serializer', 'doc_url', 'doc_id', 'behavior', 'variants', 'variant', 'shortcut_property', 'codegen_names', 'non_exhaustive']
646+
const validTags = ['class_serializer', 'doc_url', 'doc_id', 'behavior', 'variants', 'variant', 'shortcut_property',
647+
'codegen_names', 'non_exhaustive', 'es_quirk']
643648
const tags = parseJsDocTags(jsDocs)
644649
if (jsDocs.length === 1) {
645650
const description = jsDocs[0].getDescription()
@@ -671,6 +676,8 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
671676
type.kind === 'type_alias' && type.type.kind === 'union_of' && type.type.items.length === type.codegenNames.length,
672677
'@codegen_names must have the number of items as the union definition'
673678
)
679+
} else if (tag === 'es_quirk') {
680+
type.esQuirk = value
674681
} else {
675682
assert(jsDocs, false, `Unhandled tag: '${tag}' with value: '${value}' on type ${type.name.name}`)
676683
}
@@ -684,7 +691,8 @@ function hoistPropertyAnnotations (property: model.Property, jsDocs: JSDoc[]): v
684691
// We want to enforce a single jsDoc block.
685692
assert(jsDocs, jsDocs.length < 2, 'Use a single multiline jsDoc block instead of multiple single line blocks')
686693

687-
const validTags = ['stability', 'prop_serializer', 'doc_url', 'aliases', 'codegen_name', 'since', 'server_default', 'variant', 'doc_id']
694+
const validTags = ['stability', 'prop_serializer', 'doc_url', 'aliases', 'codegen_name', 'since', 'server_default',
695+
'variant', 'doc_id', 'es_quirk']
688696
const tags = parseJsDocTags(jsDocs)
689697
if (jsDocs.length === 1) {
690698
const description = jsDocs[0].getDescription()
@@ -764,6 +772,8 @@ function hoistPropertyAnnotations (property: model.Property, jsDocs: JSDoc[]): v
764772
} else if (tag === 'variant') {
765773
assert(jsDocs, value === 'container_property', `Unknown 'variant' value '${value}' on property ${property.name}`)
766774
property.containerProperty = true
775+
} else if (tag === 'es_quirk') {
776+
property.esQuirk = value
767777
} else {
768778
assert(jsDocs, false, `Unhandled tag: '${tag}' with value: '${value}' on property ${property.name}`)
769779
}

docs/modeling-guide.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,20 @@ export class TermQuery extends QueryBase {
397397
}
398398
```
399399

400+
### Tracking Elasticsearch quirks
401+
402+
There are a few places where Elasticsearch has an uncommon behavior that does not deserve a specific feature in the API specification metamodel. These quirks still have to be captured so that code generators can act on them. The `eq_quirk` jsdoc tag is meant for that, and can be used on type definitions and properties.
403+
404+
```ts
405+
/**
406+
* @es_quirk This enum is a boolean that evolved into a tri-state enum. True and False have
407+
* to be (de)serialized as JSON booleans.
408+
*/
409+
enum Foo { true, false, bar }
410+
```
411+
412+
Code generators should track the `es_quirk` they implement and fail if a new unhandled quirk is present on a type or a property. This behavior allows code generators to be updated whenever a new quirk is identified in the API specification.
413+
400414
### Additional information
401415

402416
If needed, you can specify additional information on each type with the approariate JSDoc tag.

0 commit comments

Comments
 (0)