From 0da326f5d457b1096e5dcc07a0cd994a4c1c1008 Mon Sep 17 00:00:00 2001 From: Michael M Date: Fri, 27 Oct 2023 20:11:55 +0200 Subject: [PATCH] feat: add support for explicit discriminators --- .../ng-openapi-gen/src/lib/utils/open-api.ts | 46 +++++++++++++++++++ .../ng-openapi-gen/src/lib/utils/string.ts | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/ng-openapi-gen/src/lib/utils/open-api.ts b/packages/ng-openapi-gen/src/lib/utils/open-api.ts index a63e38b..7cf3a4e 100644 --- a/packages/ng-openapi-gen/src/lib/utils/open-api.ts +++ b/packages/ng-openapi-gen/src/lib/utils/open-api.ts @@ -105,6 +105,14 @@ export function tsTypeVal( let result = '{\n'; const properties = schema.properties || {}; const required = schema.required; + + for (const baseSchema of allOf) { + const discriminator = tryGetDiscriminator(baseSchema, schema, openApi); + if (discriminator) { + result += `'${discriminator.propName}': '${discriminator.value}';\n`; + } + } + for (const [propName, property] of Object.entries(properties)) { if (!property) { continue; @@ -178,3 +186,41 @@ export function resolveRef(openApi: OpenAPIObject, ref: string): unknown { } return current; } + +/** Tries to get a discriminator info from a base schema and for a derived one */ +function tryGetDiscriminator( + baseSchemaOrRef: SchemaObject | ReferenceObject, + derivedSchema: SchemaObject, + openApi: OpenAPIObject, +) { + const baseSchema = ( + baseSchemaOrRef.$ref ? resolveRef(openApi, baseSchemaOrRef.$ref) : baseSchemaOrRef + ) as SchemaObject; + const discriminatorProp = baseSchema.discriminator?.propertyName; + if (discriminatorProp) { + const discriminatorValue = tryGetDiscriminatorValue(baseSchema, derivedSchema, openApi); + if (discriminatorValue) { + return { + propName: discriminatorProp, + value: discriminatorValue, + }; + } + } + return; +} + +/** Tries to get a discriminator value from a base schema and for a derived one */ +function tryGetDiscriminatorValue( + baseSchema: SchemaObject, + derivedSchema: SchemaObject, + openApi: OpenAPIObject, +): string | null { + const mapping = baseSchema.discriminator?.mapping; + + if (mapping) { + const mappingIndex = Object.values(mapping).findIndex((ref) => resolveRef(openApi, ref) === derivedSchema); + return Object.keys(mapping)[mappingIndex] ?? null; + } + + return null; +} diff --git a/packages/ng-openapi-gen/src/lib/utils/string.ts b/packages/ng-openapi-gen/src/lib/utils/string.ts index 2e15750..819ab61 100644 --- a/packages/ng-openapi-gen/src/lib/utils/string.ts +++ b/packages/ng-openapi-gen/src/lib/utils/string.ts @@ -66,7 +66,7 @@ export function escapeId(name: string) { /** Returns the TypeScript comments for the given schema description, in a given indentation level */ export function tsComments(description: string | undefined, level: number, deprecated?: boolean): string { const indent = ' '.repeat(level); - if (description == undefined || description.length === 0) { + if (description === undefined || description.length === 0) { return indent + (deprecated ? '/** @deprecated */' : ''); } const lines = description.trim().split('\n');