Skip to content

Commit 6b87085

Browse files
authored
Add the "es_quirk" annotation to capture snowflakes in ES behavior (#1674)
1 parent ec4d4b4 commit 6b87085

File tree

10 files changed

+101
-58
lines changed

10 files changed

+101
-58
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
@@ -444,6 +444,10 @@ export function modelEnumDeclaration (declaration: EnumDeclaration): model.Enum
444444
type.isOpen = true
445445
}
446446

447+
if (typeof tags.es_quirk === 'string') {
448+
type.esQuirk = tags.es_quirk
449+
}
450+
447451
return type
448452
}
449453

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

650-
const validTags = ['class_serializer', 'doc_url', 'doc_id', 'behavior', 'variants', 'variant', 'shortcut_property', 'codegen_names', 'non_exhaustive']
654+
const validTags = ['class_serializer', 'doc_url', 'doc_id', 'behavior', 'variants', 'variant', 'shortcut_property',
655+
'codegen_names', 'non_exhaustive', 'es_quirk']
651656
const tags = parseJsDocTags(jsDocs)
652657
if (jsDocs.length === 1) {
653658
const description = jsDocs[0].getDescription()
@@ -682,6 +687,8 @@ export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[
682687
type.kind === 'type_alias' && type.type.kind === 'union_of' && type.type.items.length === type.codegenNames.length,
683688
'@codegen_names must have the number of items as the union definition'
684689
)
690+
} else if (tag === 'es_quirk') {
691+
type.esQuirk = value
685692
} else {
686693
assert(jsDocs, false, `Unhandled tag: '${tag}' with value: '${value}' on type ${type.name.name}`)
687694
}
@@ -695,7 +702,8 @@ function hoistPropertyAnnotations (property: model.Property, jsDocs: JSDoc[]): v
695702
// We want to enforce a single jsDoc block.
696703
assert(jsDocs, jsDocs.length < 2, 'Use a single multiline jsDoc block instead of multiple single line blocks')
697704

698-
const validTags = ['stability', 'prop_serializer', 'doc_url', 'aliases', 'codegen_name', 'since', 'server_default', 'variant', 'doc_id']
705+
const validTags = ['stability', 'prop_serializer', 'doc_url', 'aliases', 'codegen_name', 'since', 'server_default',
706+
'variant', 'doc_id', 'es_quirk']
699707
const tags = parseJsDocTags(jsDocs)
700708
if (jsDocs.length === 1) {
701709
const description = jsDocs[0].getDescription()
@@ -787,6 +795,8 @@ function hoistPropertyAnnotations (property: model.Property, jsDocs: JSDoc[]): v
787795
} else if (tag === 'variant') {
788796
assert(jsDocs, value === 'container_property', `Unknown 'variant' value '${value}' on property ${property.name}`)
789797
property.containerProperty = true
798+
} else if (tag === 'es_quirk') {
799+
property.esQuirk = value
790800
} else {
791801
assert(jsDocs, false, `Unhandled tag: '${tag}' with value: '${value}' on property ${property.name}`)
792802
}

docs/known-issues.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ There is nothing that can be done here, it's a security limitation imposed by Gi
3434

3535
#### Current solution
3636

37-
Eitgher performa cherry-pick once merged or create a branch directly in this repository.
37+
Either perform a cherry-pick once merged or create a branch directly in this repository.
3838
Nit: if you do the latter, name the branch like this: `{username}/{feature_name}`
3939

4040
## Boolean in specific enum shouldn't be sent as string
@@ -45,4 +45,4 @@ Nit: if you do the latter, name the branch like this: `{username}/{feature_name}
4545

4646
#### Current solution
4747

48-
Handle the enum `true` and `false` to be serialized as booleans and not string.
48+
Handle the enum `true` and `false` to be serialized as booleans and not string. These enums have an `es_quirk` annotation.

docs/modeling-guide.md

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

402+
### Tracking Elasticsearch quirks
403+
404+
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.
405+
406+
```ts
407+
/**
408+
* @es_quirk This enum is a boolean that evolved into a tri-state enum. True and False have
409+
* to be (de)serialized as JSON booleans.
410+
*/
411+
enum Foo { true, false, bar }
412+
```
413+
414+
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.
415+
402416
### Additional information
403417

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

0 commit comments

Comments
 (0)