From d60d260342ff3013c2e228151e9b897224eb89cc Mon Sep 17 00:00:00 2001 From: Lubos Date: Sun, 10 Nov 2024 06:23:36 +0800 Subject: [PATCH] fix: correctly generate array when items are a oneOf array with length 1 --- .changeset/big-trees-hide.md | 5 +++ .../src/openApi/3.0.x/parser/schema.ts | 7 ++--- .../src/openApi/3.1.x/parser/schema.ts | 11 ++++--- packages/openapi-ts/test/3.0.x.spec.ts | 8 +++++ packages/openapi-ts/test/3.1.x.spec.ts | 8 +++++ .../array-items-one-of-length-1/index.ts | 2 ++ .../array-items-one-of-length-1/types.gen.ts | 7 +++++ .../array-items-one-of-length-1/index.ts | 2 ++ .../array-items-one-of-length-1/types.gen.ts | 7 +++++ packages/openapi-ts/test/sample.cjs | 4 +-- .../3.0.x/array-items-one-of-length-1.json | 31 +++++++++++++++++++ .../3.1.x/array-items-one-of-length-1.json | 31 +++++++++++++++++++ 12 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 .changeset/big-trees-hide.md create mode 100644 packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/index.ts create mode 100644 packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/types.gen.ts create mode 100644 packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/index.ts create mode 100644 packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/types.gen.ts create mode 100644 packages/openapi-ts/test/spec/3.0.x/array-items-one-of-length-1.json create mode 100644 packages/openapi-ts/test/spec/3.1.x/array-items-one-of-length-1.json diff --git a/.changeset/big-trees-hide.md b/.changeset/big-trees-hide.md new file mode 100644 index 000000000..aef5d436e --- /dev/null +++ b/.changeset/big-trees-hide.md @@ -0,0 +1,5 @@ +--- +'@hey-api/openapi-ts': patch +--- + +fix: correctly generate array when items are a oneOf array with length 1 diff --git a/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts b/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts index 5049d4811..0fb81cbc2 100644 --- a/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts +++ b/packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts @@ -81,10 +81,9 @@ const parseArray = ({ if ('$ref' in schema.items) { schemaItems.push(irItemsSchema); } else { - const isComposedSchema = Boolean( - schema.items.allOf || schema.items.anyOf || schema.items.oneOf, - ); - if (isComposedSchema) { + const ofArray = + schema.items.allOf || schema.items.anyOf || schema.items.oneOf; + if (ofArray && ofArray.length > 1 && !schema.items.nullable) { // bring composition up to avoid incorrectly nested arrays irSchema = { ...irSchema, diff --git a/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts b/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts index cdc124915..d42a2bf6c 100644 --- a/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts +++ b/packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts @@ -120,10 +120,13 @@ const parseArray = ({ ) { schemaItems = Array(schema.maxItems).fill(irItemsSchema); } else { - const isComposedSchema = Boolean( - schema.items.allOf || schema.items.anyOf || schema.items.oneOf, - ); - if (isComposedSchema) { + const ofArray = + schema.items.allOf || schema.items.anyOf || schema.items.oneOf; + if ( + ofArray && + ofArray.length > 1 && + !getSchemaTypes({ schema: schema.items }).includes('null') + ) { // bring composition up to avoid incorrectly nested arrays irSchema = { ...irSchema, diff --git a/packages/openapi-ts/test/3.0.x.spec.ts b/packages/openapi-ts/test/3.0.x.spec.ts index 418a7766a..6d7583786 100644 --- a/packages/openapi-ts/test/3.0.x.spec.ts +++ b/packages/openapi-ts/test/3.0.x.spec.ts @@ -48,6 +48,14 @@ describe(`OpenAPI ${VERSION}`, () => { }), description: 'allows arbitrary properties on objects', }, + { + config: createConfig({ + input: 'array-items-one-of-length-1.json', + output: 'array-items-one-of-length-1', + }), + description: + 'generates correct array when items are oneOf array with single item', + }, { config: createConfig({ input: 'enum-escape.json', diff --git a/packages/openapi-ts/test/3.1.x.spec.ts b/packages/openapi-ts/test/3.1.x.spec.ts index 0665abd46..ab11ad5f8 100644 --- a/packages/openapi-ts/test/3.1.x.spec.ts +++ b/packages/openapi-ts/test/3.1.x.spec.ts @@ -48,6 +48,14 @@ describe(`OpenAPI ${VERSION}`, () => { }), description: 'allows arbitrary properties on objects', }, + { + config: createConfig({ + input: 'array-items-one-of-length-1.json', + output: 'array-items-one-of-length-1', + }), + description: + 'generates correct array when items are oneOf array with single item', + }, { config: createConfig({ input: 'duplicate-null.json', diff --git a/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/index.ts b/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/index.ts new file mode 100644 index 000000000..56bade120 --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/index.ts @@ -0,0 +1,2 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './types.gen'; \ No newline at end of file diff --git a/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/types.gen.ts b/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/types.gen.ts new file mode 100644 index 000000000..d17a3c928 --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/3.0.x/array-items-one-of-length-1/types.gen.ts @@ -0,0 +1,7 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type Foo = { + foo?: Array; +}; + +export type Bar = string; \ No newline at end of file diff --git a/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/index.ts b/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/index.ts new file mode 100644 index 000000000..56bade120 --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/index.ts @@ -0,0 +1,2 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './types.gen'; \ No newline at end of file diff --git a/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/types.gen.ts b/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/types.gen.ts new file mode 100644 index 000000000..d17a3c928 --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/3.1.x/array-items-one-of-length-1/types.gen.ts @@ -0,0 +1,7 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type Foo = { + foo?: Array; +}; + +export type Bar = string; \ No newline at end of file diff --git a/packages/openapi-ts/test/sample.cjs b/packages/openapi-ts/test/sample.cjs index 0db06fb5d..2b69ea7ea 100644 --- a/packages/openapi-ts/test/sample.cjs +++ b/packages/openapi-ts/test/sample.cjs @@ -13,7 +13,7 @@ const main = async () => { input: { // include: // '^(#/components/schemas/import|#/paths/api/v{api-version}/simple/options)$', - path: './test/spec/3.0.x/parameter-explode-false.json', + path: './test/spec/3.1.x/array-items-one-of-length-1.json', // path: 'https://mongodb-mms-prod-build-server.s3.amazonaws.com/openapi/2caffd88277a4e27c95dcefc7e3b6a63a3b03297-v2-2023-11-15.json', }, // name: 'foo', @@ -30,7 +30,7 @@ const main = async () => { { // asClass: true, // include... - name: '@hey-api/services', + // name: '@hey-api/services', // serviceNameBuilder: '^Parameters', }, { diff --git a/packages/openapi-ts/test/spec/3.0.x/array-items-one-of-length-1.json b/packages/openapi-ts/test/spec/3.0.x/array-items-one-of-length-1.json new file mode 100644 index 000000000..d0613678c --- /dev/null +++ b/packages/openapi-ts/test/spec/3.0.x/array-items-one-of-length-1.json @@ -0,0 +1,31 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "OpenAPI 3.0.2 array items oneOf length 1 example", + "version": "1" + }, + "components": { + "schemas": { + "Foo": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/Bar" + } + ] + }, + "maxItems": 2147483647, + "minItems": 1 + } + } + }, + "Bar": { + "type": "string" + } + } + } +} diff --git a/packages/openapi-ts/test/spec/3.1.x/array-items-one-of-length-1.json b/packages/openapi-ts/test/spec/3.1.x/array-items-one-of-length-1.json new file mode 100644 index 000000000..78a852bce --- /dev/null +++ b/packages/openapi-ts/test/spec/3.1.x/array-items-one-of-length-1.json @@ -0,0 +1,31 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI 3.1.0 array items oneOf length 1 example", + "version": "1" + }, + "components": { + "schemas": { + "Foo": { + "type": "object", + "properties": { + "foo": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/Bar" + } + ] + }, + "maxItems": 2147483647, + "minItems": 1 + } + } + }, + "Bar": { + "type": "string" + } + } + } +}