From 89fc1d0ba1fb3ae0f7df49270eaee06141029fac Mon Sep 17 00:00:00 2001 From: Atle Frenvik Sveen Date: Tue, 24 Nov 2020 08:53:53 +0100 Subject: [PATCH 1/2] handle case where additionalRef is a ref (fixes #345) --- src/types/OpenAPI2.ts | 6 ++++++ src/v2.ts | 19 +++++++++++++++++-- tests/v2/index.test.ts | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/types/OpenAPI2.ts b/src/types/OpenAPI2.ts index 009762e6a..1255118b4 100644 --- a/src/types/OpenAPI2.ts +++ b/src/types/OpenAPI2.ts @@ -32,6 +32,12 @@ export type OpenAPI2Type = export type OpenAPI2Reference = { $ref: string }; +export function isOpenAPI2Reference( + additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean +): additionalProperties is OpenAPI2Reference { + return (additionalProperties as OpenAPI2Reference).$ref !== undefined; +} + export interface OpenAPI2SchemaObject { additionalProperties?: OpenAPI2SchemaObject | OpenAPI2Reference | boolean; allOf?: OpenAPI2SchemaObject[]; diff --git a/src/v2.ts b/src/v2.ts index 6bbec80f1..df1e8bf28 100644 --- a/src/v2.ts +++ b/src/v2.ts @@ -1,5 +1,12 @@ import propertyMapper from "./property-mapper"; -import { OpenAPI2, OpenAPI2SchemaObject, OpenAPI2Schemas, SwaggerToTSOptions } from "./types"; +import { + OpenAPI2, + OpenAPI2Reference, + OpenAPI2SchemaObject, + OpenAPI2Schemas, + SwaggerToTSOptions, + isOpenAPI2Reference, +} from "./types"; import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsUnionOf } from "./utils"; export const PRIMITIVES: { [key: string]: "boolean" | "string" | "number" } = { @@ -40,6 +47,14 @@ export default function generateTypesV2(input: OpenAPI2 | OpenAPI2Schemas, optio // propertyMapper const propertyMapped = options ? propertyMapper(definitions, options.propertyMapper) : definitions; + //this functionality could perhaps be added to the nodeType function, but I don't want to mess with that code + function getAdditionalPropertiesType(additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean) { + if (isOpenAPI2Reference(additionalProperties)) { + return transformRef(additionalProperties.$ref, rawSchema ? "definitions/" : ""); + } + return nodeType(additionalProperties); + } + // type conversions function transform(node: OpenAPI2SchemaObject): string { switch (nodeType(node)) { @@ -67,7 +82,7 @@ export default function generateTypesV2(input: OpenAPI2 | OpenAPI2Schemas, optio // if additional properties, add to end of properties if (node.additionalProperties) { - properties += `[key: string]: ${nodeType(node.additionalProperties) || "any"};\n`; + properties += `[key: string]: ${getAdditionalPropertiesType(node.additionalProperties) || "any"};\n`; } return tsIntersectionOf([ diff --git a/tests/v2/index.test.ts b/tests/v2/index.test.ts index 972fbeb4c..a2fc36039 100644 --- a/tests/v2/index.test.ts +++ b/tests/v2/index.test.ts @@ -255,6 +255,38 @@ describe("transformation", () => { ); }); + it("additionalProperties 2 (issue #345)", () => { + const schema: OpenAPI2 = { + swagger: "2.0", + definitions: { + Messages: { + type: "object", + additionalProperties: { + $ref: "#/definitions/Message", + }, + }, + Message: { + type: "object", + properties: { + code: { + type: "integer", + }, + text: { + type: "string", + }, + }, + }, + }, + }; + expect(swaggerToTS(schema)).toBe( + format(` + export interface definitions { + Messages: { [key: string]: definitions["Message"] } + Message: { code?: number; text?: string } + }`) + ); + }); + it("allOf", () => { const schema: OpenAPI2 = { swagger: "2.0", From 3d247c5a2cec51df3a679fd9bafa3e809751f184 Mon Sep 17 00:00:00 2001 From: Atle Frenvik Sveen Date: Tue, 24 Nov 2020 09:39:37 +0100 Subject: [PATCH 2/2] move isOpenAPI2Reference to utils, as build-script crashes when it is in /types --- src/types/OpenAPI2.ts | 6 ------ src/utils.ts | 8 +++++++- src/v2.ts | 11 ++--------- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/types/OpenAPI2.ts b/src/types/OpenAPI2.ts index 1255118b4..009762e6a 100644 --- a/src/types/OpenAPI2.ts +++ b/src/types/OpenAPI2.ts @@ -32,12 +32,6 @@ export type OpenAPI2Type = export type OpenAPI2Reference = { $ref: string }; -export function isOpenAPI2Reference( - additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean -): additionalProperties is OpenAPI2Reference { - return (additionalProperties as OpenAPI2Reference).$ref !== undefined; -} - export interface OpenAPI2SchemaObject { additionalProperties?: OpenAPI2SchemaObject | OpenAPI2Reference | boolean; allOf?: OpenAPI2SchemaObject[]; diff --git a/src/utils.ts b/src/utils.ts index e17f938fd..01ad9248f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { OpenAPI2, OpenAPI3 } from "./types"; +import { OpenAPI2, OpenAPI2Reference, OpenAPI2SchemaObject, OpenAPI3 } from "./types"; export function comment(text: string): string { return `/** @@ -121,3 +121,9 @@ export function unrefComponent(components: any, ref: string): any { const [type, object] = ref.match(/(?<=\[")([^"]+)/g) as string[]; return components[type][object]; } + +export function isOpenAPI2Reference( + additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean +): additionalProperties is OpenAPI2Reference { + return (additionalProperties as OpenAPI2Reference).$ref !== undefined; +} diff --git a/src/v2.ts b/src/v2.ts index df1e8bf28..12af30f36 100644 --- a/src/v2.ts +++ b/src/v2.ts @@ -1,13 +1,6 @@ import propertyMapper from "./property-mapper"; -import { - OpenAPI2, - OpenAPI2Reference, - OpenAPI2SchemaObject, - OpenAPI2Schemas, - SwaggerToTSOptions, - isOpenAPI2Reference, -} from "./types"; -import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsUnionOf } from "./utils"; +import { OpenAPI2, OpenAPI2Reference, OpenAPI2SchemaObject, OpenAPI2Schemas, SwaggerToTSOptions } from "./types"; +import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsUnionOf, isOpenAPI2Reference } from "./utils"; export const PRIMITIVES: { [key: string]: "boolean" | "string" | "number" } = { // boolean types