From 1317ed0dcf7e3845370923179914568be8b9f3a9 Mon Sep 17 00:00:00 2001 From: Michael Nahkies Date: Sun, 12 Nov 2023 12:26:19 +0000 Subject: [PATCH] feat: basic support for openapi 3.1 this adds basic support for openapi 3.1 definitions, based on the mgiration blog post from openapis.org. the primary change is allowing `null` as a `type`, and that `type` can be an array. the other changes listed relating to file uploads, and `exclusiveMinimum` aren't applicable as these aren't really supported at all yet (https://github.com/mnahkies/openapi-code-generator/issues/51, https://github.com/mnahkies/openapi-code-generator/issues/53) there's probably a bunch of other gaps in general JSON schema support, such as the `if` / `else` things mentioned, but there's relatively few examples of complex `3.1.0` definitions to test against. I stumbled across https://github.com/APIs-guru/openapi-directory looking for samples and I've tested these changes against these definitions: - https://github.com/APIs-guru/openapi-directory/blob/dec74da7a6785d5d5b83bc6a4cebc07336d67ec9/APIs/vercel.com/0.0.1/openapi.yaml - https://github.com/APIs-guru/openapi-directory/blob/dec74da7a6785d5d5b83bc6a4cebc07336d67ec9/APIs/discourse.local/latest/openapi.yaml - https://github.com/APIs-guru/openapi-directory/blob/dec74da7a6785d5d5b83bc6a4cebc07336d67ec9/APIs/adyen.com/CheckoutService/70/openapi.yaml It appears to be giving reasonable output - no compile errors at least, and nothing obviously wrong doing a quick scan of output. ref: https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0 --- .../openapi-code-generator/src/core/input.ts | 35 ++++++++++++++----- .../src/core/openapi-types.ts | 2 +- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/openapi-code-generator/src/core/input.ts b/packages/openapi-code-generator/src/core/input.ts index c7d1252a..0459783f 100644 --- a/packages/openapi-code-generator/src/core/input.ts +++ b/packages/openapi-code-generator/src/core/input.ts @@ -168,14 +168,14 @@ function normalizeMediaType(mediaTypes: {[contentType: string]: MediaType} = {}) // Sometimes people pass `{}` as the MediaType for 204 responses, filter these out .filter(([, mediaType]) => Boolean(mediaType.schema)) .map(([contentType, mediaType]) => { - return [ - contentType, - { - schema: normalizeSchemaObject(mediaType.schema), - encoding: mediaType.encoding, - }, - ] - })) + return [ + contentType, + { + schema: normalizeSchemaObject(mediaType.schema), + encoding: mediaType.encoding, + }, + ] + })) } function normalizeParameterObject(parameterObject: Parameter): IRParameter { @@ -195,6 +195,22 @@ function normalizeSchemaObject(schemaObject: Schema | Reference): MaybeIRModel { return schemaObject satisfies IRRef } + // TODO: HACK: translates a type array into a a oneOf - unsure if this makes sense, + // or is the cleanest way to do it. I'm fairly sure this will work fine + // for most things though. + if (Array.isArray(schemaObject.type)) { + const nullable = Boolean(schemaObject.type.find(it => it === "null")) + return normalizeSchemaObject({ + oneOf: schemaObject.type + .filter(it => it !== "null") + .map(it => normalizeSchemaObject({ + ...schemaObject, + type: it, + nullable, + })), + }) + } + const base: IRModelBase = { nullable: schemaObject.nullable || false, readOnly: schemaObject.readOnly || false, @@ -202,6 +218,7 @@ function normalizeSchemaObject(schemaObject: Schema | Reference): MaybeIRModel { switch (schemaObject.type) { case undefined: + case "null": // TODO: HACK case "object": { const properties = normalizeProperties(schemaObject.properties) const allOf = normalizeAllOf(schemaObject.allOf) @@ -222,6 +239,8 @@ function normalizeSchemaObject(schemaObject: Schema | Reference): MaybeIRModel { return { ...base, + // TODO: HACK + nullable: base.nullable || schemaObject.type === "null", type: "object", allOf, oneOf, diff --git a/packages/openapi-code-generator/src/core/openapi-types.ts b/packages/openapi-code-generator/src/core/openapi-types.ts index d704c3ff..8fdabd0f 100644 --- a/packages/openapi-code-generator/src/core/openapi-types.ts +++ b/packages/openapi-code-generator/src/core/openapi-types.ts @@ -209,7 +209,7 @@ export interface Schema { minProperties?: number required?: string[] /* [] */ enum?: string[] | number[] - type?: "integer" | "number" | "string" | "boolean" | "object" | "array" /* object */ + type?: "null" | "integer" | "number" | "string" | "boolean" | "object" | "array" /* object */ not?: Schema | Reference allOf?: (Schema | Reference)[] oneOf?: (Schema | Reference)[]