Skip to content

Commit

Permalink
feat: improve oneOf schema handling
Browse files Browse the repository at this point in the history
This introduces an enhancement to better handle the oneOf schema in OpenAPI definitions.

- Added a new OpenAPI test fixture - oneOfMerge.yaml
- Updated logic in the codegen script where oneOf schemas are encountered. The properties of the schema are now deeply merged to accommodate different variations.
- Added a new test case to confirm the improved handling of oneOf schemas.

more details: #503 (comment)

fix: #495

--

Signed-off-by: kahiro okina <kahiro.okina@craftsman-software.com>
  • Loading branch information
kahirokunn committed Nov 28, 2023
1 parent ee62a62 commit d97fc2e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
36 changes: 36 additions & 0 deletions src/codegen/__fixtures__/oneOfMerge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
openapi: 3.0.3
info:
title: OneOfMerge
version: 0.1.0
paths:
/mix:
get:
description: stats
parameters:
- name: param1
in: query
schema:
oneOf:
- required:
- c
properties:
a:
type: string
- required:
- b
properties:
b:
type: string
required:
- d
properties:
c:
type: string
d:
enum:
- enum1
- enum2
type: string
responses:
"200":
description: ok
9 changes: 8 additions & 1 deletion src/codegen/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { OpenAPIV3 } from "openapi-types";
import * as cg from "./tscodegen";
import generateServers, { defaultBaseUrl } from "./generateServers";
import { Opts } from ".";
import merge from "deepmerge";

export const verbs = [
"GET",
Expand Down Expand Up @@ -574,8 +575,14 @@ export default class ApiGenerator {
}

if (schema.oneOf) {
const clone = { ...schema };
delete clone.oneOf;
// oneOf -> union
return this.getUnionType(schema.oneOf, schema.discriminator, onlyMode);
return this.getUnionType(
schema.oneOf.map((variant) => merge(variant as any, clone as any)),
schema.discriminator,
onlyMode,
);
}
if (schema.anyOf) {
// anyOf -> union
Expand Down
7 changes: 7 additions & 0 deletions src/codegen/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ describe("generateSource", () => {
expect(src).toContain("PathsFilterGetParameters0SchemaOneOf0");
});

it("should merge properties within oneOf schema variations", async () => {
const src = await generate("/__fixtures__/oneOfMerge.yaml");
expect(src).toContain(
'{ param1?: { a?: string; c: string; d: "enum1" | "enum2"; } | { b: string; c?: string; d: "enum1" | "enum2"; }'
);
});

it("should support parameters specified with content", async () => {
const src = await generate("/__fixtures__/contentParams.json");
expect(src).toContain(
Expand Down

0 comments on commit d97fc2e

Please sign in to comment.