[@kbn/config-schema] add discriminatedUnion schema type#246095
[@kbn/config-schema] add discriminatedUnion schema type#246095nickofthyme merged 10 commits intoelastic:mainfrom
discriminatedUnion schema type#246095Conversation
- remove `DiscriminatorType`, not really needed - fix return type of `oneOfKind` to return correct resolved type - add type tests
This reverts commit 9f0525d.
src/platform/packages/shared/kbn-config-schema/src/types/discriminated_union_type.ts
Outdated
Show resolved
Hide resolved
src/platform/packages/shared/kbn-config-schema/src/types/discriminated_union_type.ts
Outdated
Show resolved
Hide resolved
src/platform/packages/shared/kbn-config-schema/src/types/discriminated_union_type.ts
Outdated
Show resolved
Hide resolved
- allow fallback or catch-all schema - validate 0 or 1 fallback schema - validate unique discriminators
oneOfKind schema typediscriminatedUnion schema type
jloleysens
left a comment
There was a problem hiding this comment.
Great work @nickofthyme , this looks like a solid version of discriminated union with solid DX.
💛 Build succeeded, but was flaky
Failed CI StepsMetrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
History
|
## Summary
Adds `discriminatedUnion` method to `@kbn/config-schema` for
discriminated union of object schemas.
```ts
const exampleType = schema.discriminatedUnion('type', [
schema.object({ type: schema.literal('str'), string: schema.string() }),
schema.object({ type: schema.literal('num'), number: schema.number() }),
schema.object({ type: schema.literal('bool'), boolean: schema.boolean() }),
]);
```
Order of Errors:
1) missing `discriminator` property.
1) `discriminator` property has wrong type (only strings via
`schema.literal` and one `schema.string` are permitted)
1) `discriminator` is a string but not one of the expected
discriminators.
1) validation errors from the respective schema based on
`discriminator`, only the matching schema is validated.
Also allows for fallback schema. Limit of one fallback, position in
array does not matter.
```ts
const exampleType = schema.discriminatedUnion('type', [
schema.object({ type: schema.literal('str'), string: schema.string() }),
schema.object({ type: schema.literal('num'), number: schema.number() }),
schema.object({ type: schema.string }, { unknowns: 'allow' }), // allows any other type other than 'str' and 'num'
]);
```
## Error Example
```
{ type: 'str', string: 123 } // "string" property is a number instead of a string
[string]: expected value of type [string] but got [number]
```
closes #84264
### Checklist
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.
## Summary Close #181994 Support generating OAS for `@kbn/config-schema`'s using our new `schema.discriminatedUnion` type #246095 ## Notes * Force developers to define a `{ meta: { id: '...' } }` for the objects inside a `schema.discriminatedUnion` so that we can generate the correct OAS. Guidance for name is as follows: `<your-id>-<your-team-or-area>`. The intention is that IDs are globally unique while remaining somewhat user readable as they will be surfaced in our docs. * Tackled a few unrelated OAS/schema chores in this PR ## Conversion Given a schema like: ```ts schema.discriminatedUnion('type', [ schema.object( { type: schema.literal('str'), value: schema.string() }, { meta: { id: 'my-str-my-team' } } ), schema.object( { type: schema.literal('num'), value: schema.number() }, { meta: { id: 'my-num-team' } } ), ]), ``` Produce OAS like: ```js { oneOf: [ { $ref: '#/components/schemas/my-str-my-team', }, { $ref: '#/components/schemas/my-num-team', }, ], discriminator: { propertyName: 'type', } } ... components: { schemas: { 'my-str-my-team': { type: 'object', properties: { type: { type: 'string', enum: ['str'] }, }, }, 'my-num-team': { type: 'object', properties: { type: { type: 'string', enum: ['num'] }, }, }, }, } ```
Summary
Adds
discriminatedUnionmethod to@kbn/config-schemafor discriminated union of object schemas.Order of Errors:
discriminatorproperty.discriminatorproperty has wrong type (only strings viaschema.literaland oneschema.stringare permitted)discriminatoris a string but not one of the expected discriminators.discriminator, only the matching schema is validated.Also allows for fallback schema. Limit of one fallback, position in array does not matter.
Error Example
closes #84264
Checklist
release_note:breakinglabel should be applied in these situations.release_note:*label is applied per the guidelinesbackport:*labels.