From f9e2ab5e1d58b681b05dd8bb86c86d910c88f604 Mon Sep 17 00:00:00 2001 From: raveclassic Date: Fri, 8 Nov 2019 19:59:19 +0300 Subject: [PATCH] feat: oneOf support for typescript openapi 3 BREAKING CHANGE: OneOfSchemaObject type was added to SchemaObject --- .../3.0/serializers/schema-object.ts | 36 +++++++++++++------ src/schema/3.0/schema-object.ts | 26 ++++++++++++-- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/language/typescript/3.0/serializers/schema-object.ts b/src/language/typescript/3.0/serializers/schema-object.ts index cf4c634..ce36903 100644 --- a/src/language/typescript/3.0/serializers/schema-object.ts +++ b/src/language/typescript/3.0/serializers/schema-object.ts @@ -6,6 +6,7 @@ import { getSerializedPropertyType, getSerializedRecursiveType, getSerializedRefType, + getSerializedUnionType, intercalateSerializedTypes, SERIALIZED_BOOLEAN_TYPE, SERIALIZED_NUMERIC_TYPE, @@ -22,9 +23,10 @@ import { constFalse } from 'fp-ts/lib/function'; import { includes } from '../../../../utils/array'; import { sequenceEither } from '@devexperts/utils/dist/adt/either.utils'; import { fromString, Ref } from '../../../../utils/ref'; -import { AllOfSchemaObjectCodec, SchemaObject } from '../../../../schema/3.0/schema-object'; +import { AllOfSchemaObjectCodec, OneOfSchemaObjectCodec, SchemaObject } from '../../../../schema/3.0/schema-object'; import { ReferenceObject, ReferenceObjectCodec } from '../../../../schema/3.0/reference-object'; import { traverseNEAEither } from '../../../../utils/either'; +import { NonEmptyArray } from 'fp-ts/lib/NonEmptyArray'; type AdditionalProperties = boolean | ReferenceObject | SchemaObject; type AllowedAdditionalProperties = true | ReferenceObject | SchemaObject; @@ -41,18 +43,17 @@ export const serializeSchemaObject = ( const serializeSchemaObjectWithRecursion = (from: Ref, shouldTrackRecursion: boolean, name?: string) => ( schemaObject: SchemaObject, ): Either => { + if (OneOfSchemaObjectCodec.is(schemaObject)) { + return pipe( + serializeChildren(from, schemaObject.oneOf), + either.map(getSerializedUnionType), + either.map(getSerializedRecursiveType(from, shouldTrackRecursion)), + ); + } + if (AllOfSchemaObjectCodec.is(schemaObject)) { return pipe( - traverseNEAEither(schemaObject.allOf, item => { - if (ReferenceObjectCodec.is(item)) { - return pipe( - fromString(item.$ref), - either.map(getSerializedRefType(from)), - ); - } else { - return serializeSchemaObjectWithRecursion(from, false)(item); - } - }), + serializeChildren(from, schemaObject.allOf), either.map(getSerializedIntersectionType), either.map(getSerializedRecursiveType(from, shouldTrackRecursion)), ); @@ -166,3 +167,16 @@ const serializeSchemaObjectWithRecursion = (from: Ref, shouldTrackRecursion: boo } } }; + +const serializeChildren = ( + from: Ref, + children: NonEmptyArray, +): Either> => + traverseNEAEither(children, item => + ReferenceObjectCodec.is(item) + ? pipe( + fromString(item.$ref), + either.map(getSerializedRefType(from)), + ) + : serializeSchemaObjectWithRecursion(from, false)(item), + ); diff --git a/src/schema/3.0/schema-object.ts b/src/schema/3.0/schema-object.ts index 3202a82..790a5c1 100644 --- a/src/schema/3.0/schema-object.ts +++ b/src/schema/3.0/schema-object.ts @@ -69,8 +69,30 @@ export const AllOfSchemaObjectCodec: Codec = recursion('AllOf }), ); -export type SchemaObject = PrimitiveSchemaObject | ObjectSchemaObject | ArraySchemaObject | AllOfSchemaObject; +export interface OneOfSchemaObject extends BaseSchemaObject { + readonly oneOf: NonEmptyArray; +} + +export const OneOfSchemaObjectCodec: Codec = recursion('OneOfSchemaObject', () => + type({ + ...BaseSchemaObjectProps, + oneOf: nonEmptyArray(union([ReferenceObjectCodec, SchemaObjectCodec])), + }), +); + +export type SchemaObject = + | PrimitiveSchemaObject + | ObjectSchemaObject + | ArraySchemaObject + | AllOfSchemaObject + | OneOfSchemaObject; export const SchemaObjectCodec: Codec = recursion('SchemaObject', () => - union([PrimitiveSchemaObjectCodec, ObjectSchemaObjectCodec, ArraySchemaObjectCodec, AllOfSchemaObjectCodec]), + union([ + PrimitiveSchemaObjectCodec, + ObjectSchemaObjectCodec, + ArraySchemaObjectCodec, + AllOfSchemaObjectCodec, + OneOfSchemaObjectCodec, + ]), );