Skip to content

Commit e6673c1

Browse files
authored
handle case where additionalRef is a ref (fixes #345) (#383)
* handle case where additionalRef is a ref (fixes #345) * move isOpenAPI2Reference to utils, as build-script crashes when it is in /types
1 parent e8ba16f commit e6673c1

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/utils.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { OpenAPI2, OpenAPI3 } from "./types";
1+
import { OpenAPI2, OpenAPI2Reference, OpenAPI2SchemaObject, OpenAPI3 } from "./types";
22

33
export function comment(text: string): string {
44
return `/**
@@ -121,3 +121,9 @@ export function unrefComponent(components: any, ref: string): any {
121121
const [type, object] = ref.match(/(?<=\[")([^"]+)/g) as string[];
122122
return components[type][object];
123123
}
124+
125+
export function isOpenAPI2Reference(
126+
additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean
127+
): additionalProperties is OpenAPI2Reference {
128+
return (additionalProperties as OpenAPI2Reference).$ref !== undefined;
129+
}

src/v2.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import propertyMapper from "./property-mapper";
2-
import { OpenAPI2, OpenAPI2SchemaObject, OpenAPI2Schemas, SwaggerToTSOptions } from "./types";
3-
import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsUnionOf } from "./utils";
2+
import { OpenAPI2, OpenAPI2Reference, OpenAPI2SchemaObject, OpenAPI2Schemas, SwaggerToTSOptions } from "./types";
3+
import { comment, nodeType, transformRef, tsArrayOf, tsIntersectionOf, tsUnionOf, isOpenAPI2Reference } from "./utils";
44

55
export const PRIMITIVES: { [key: string]: "boolean" | "string" | "number" } = {
66
// boolean types
@@ -40,6 +40,14 @@ export default function generateTypesV2(input: OpenAPI2 | OpenAPI2Schemas, optio
4040
// propertyMapper
4141
const propertyMapped = options ? propertyMapper(definitions, options.propertyMapper) : definitions;
4242

43+
//this functionality could perhaps be added to the nodeType function, but I don't want to mess with that code
44+
function getAdditionalPropertiesType(additionalProperties: OpenAPI2SchemaObject | OpenAPI2Reference | boolean) {
45+
if (isOpenAPI2Reference(additionalProperties)) {
46+
return transformRef(additionalProperties.$ref, rawSchema ? "definitions/" : "");
47+
}
48+
return nodeType(additionalProperties);
49+
}
50+
4351
// type conversions
4452
function transform(node: OpenAPI2SchemaObject): string {
4553
switch (nodeType(node)) {
@@ -67,7 +75,7 @@ export default function generateTypesV2(input: OpenAPI2 | OpenAPI2Schemas, optio
6775

6876
// if additional properties, add to end of properties
6977
if (node.additionalProperties) {
70-
properties += `[key: string]: ${nodeType(node.additionalProperties) || "any"};\n`;
78+
properties += `[key: string]: ${getAdditionalPropertiesType(node.additionalProperties) || "any"};\n`;
7179
}
7280

7381
return tsIntersectionOf([

tests/v2/index.test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,38 @@ describe("transformation", () => {
255255
);
256256
});
257257

258+
it("additionalProperties 2 (issue #345)", () => {
259+
const schema: OpenAPI2 = {
260+
swagger: "2.0",
261+
definitions: {
262+
Messages: {
263+
type: "object",
264+
additionalProperties: {
265+
$ref: "#/definitions/Message",
266+
},
267+
},
268+
Message: {
269+
type: "object",
270+
properties: {
271+
code: {
272+
type: "integer",
273+
},
274+
text: {
275+
type: "string",
276+
},
277+
},
278+
},
279+
},
280+
};
281+
expect(swaggerToTS(schema)).toBe(
282+
format(`
283+
export interface definitions {
284+
Messages: { [key: string]: definitions["Message"] }
285+
Message: { code?: number; text?: string }
286+
}`)
287+
);
288+
});
289+
258290
it("allOf", () => {
259291
const schema: OpenAPI2 = {
260292
swagger: "2.0",

0 commit comments

Comments
 (0)