Skip to content

Commit 2300c9b

Browse files
committed
Fixed openapi 3 spec to default additionalProperties to true
Signed-off-by: Micah Halter <[email protected]>
1 parent 4c51afc commit 2300c9b

26 files changed

+8361
-6942
lines changed

src/transform/headers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { transformSchemaObj } from "./schema";
44

55
export function transformHeaderObjMap(
66
headerMap: Record<string, HeaderObject>,
7-
options: { formatter?: SchemaFormatter; immutableTypes: boolean }
7+
options: { formatter?: SchemaFormatter; immutableTypes: boolean; version: number }
88
): string {
99
let output = "";
1010

src/transform/index.ts

+10
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
2828
formatter,
2929
immutableTypes,
3030
required: Object.keys(schema),
31+
version,
3132
})}\n}`;
3233
}
3334
case 3: {
3435
return `export interface schemas {\n ${transformSchemaObjMap(schema, {
3536
formatter,
3637
immutableTypes,
3738
required: Object.keys(schema),
39+
version,
3840
})}\n }\n\n`;
3941
}
4042
}
@@ -60,6 +62,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
6062
formatter,
6163
immutableTypes,
6264
required: Object.keys(schema.definitions),
65+
version,
6366
})}\n}\n\n`;
6467
}
6568

@@ -70,6 +73,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
7073
formatter,
7174
immutableTypes,
7275
required,
76+
version,
7377
})}\n }\n\n`;
7478
}
7579

@@ -78,6 +82,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
7882
output += `export interface responses {\n ${transformResponsesObj(schema.responses, {
7983
formatter,
8084
immutableTypes,
85+
version,
8186
})}\n }\n\n`;
8287
}
8388
break;
@@ -94,6 +99,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
9499
formatter,
95100
immutableTypes,
96101
required,
102+
version,
97103
})}\n }\n`;
98104
}
99105

@@ -102,6 +108,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
102108
output += ` ${readonly}responses: {\n ${transformResponsesObj(schema.components.responses, {
103109
formatter,
104110
immutableTypes,
111+
version,
105112
})}\n }\n`;
106113
}
107114

@@ -112,6 +119,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
112119
formatter,
113120
immutableTypes,
114121
required,
122+
version,
115123
})}\n }\n`;
116124
}
117125

@@ -120,6 +128,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
120128
output += ` ${readonly}requestBodies: {\n ${transformRequestBodies(schema.components.requestBodies, {
121129
formatter,
122130
immutableTypes,
131+
version,
123132
})}\n }\n`;
124133
}
125134

@@ -128,6 +137,7 @@ export function transformAll(schema: any, { formatter, immutableTypes, rawSchema
128137
output += ` ${readonly}headers: {\n ${transformHeaderObjMap(schema.components.headers, {
129138
formatter,
130139
immutableTypes,
140+
version,
131141
})} }\n`;
132142
}
133143
}

src/transform/operation.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function transformOperationObj(
3434
if (operation.responses) {
3535
output += ` ${readonly}responses: {\n ${transformResponsesObj(operation.responses, {
3636
immutableTypes,
37+
version,
3738
})}\n }\n`;
3839
}
3940

@@ -44,7 +45,7 @@ export function transformOperationObj(
4445
if (operation.requestBody.description) output += comment(operation.requestBody.description);
4546

4647
output += ` ${readonly}requestBody: {\n`; // open requestBody
47-
output += ` ${transformRequestBodyObj(operation.requestBody, { immutableTypes })}`;
48+
output += ` ${transformRequestBodyObj(operation.requestBody, { immutableTypes, version })}`;
4849
output += ` }\n`; // close requestBody
4950
}
5051
}
@@ -54,7 +55,7 @@ export function transformOperationObj(
5455

5556
export function transformRequestBodyObj(
5657
requestBody: RequestBody,
57-
{ immutableTypes }: { immutableTypes: boolean }
58+
{ immutableTypes, version }: { immutableTypes: boolean; version: number }
5859
): string {
5960
const readonly = tsReadonly(immutableTypes);
6061

@@ -66,7 +67,7 @@ export function transformRequestBodyObj(
6667
output += ` ${readonly}content: {\n`; // open content
6768

6869
Object.entries(content).forEach(([k, v]) => {
69-
output += ` ${readonly}"${k}": ${transformSchemaObj(v.schema, { immutableTypes })};\n`;
70+
output += ` ${readonly}"${k}": ${transformSchemaObj(v.schema, { immutableTypes, version })};\n`;
7071
});
7172
output += ` }\n`; // close content
7273
} else {

src/transform/parameters.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ export function transformParametersArray(
5959
let paramType = ``;
6060
if (version === 2) {
6161
if (paramObj.in === "body" && paramObj.schema) {
62-
paramType = transformSchemaObj(paramObj.schema, { immutableTypes });
62+
paramType = transformSchemaObj(paramObj.schema, { immutableTypes, version });
6363
} else if (paramObj.type) {
64-
paramType = transformSchemaObj(paramObj, { immutableTypes });
64+
paramType = transformSchemaObj(paramObj, { immutableTypes, version });
6565
} else {
6666
paramType = "unknown";
6767
}
6868
} else if (version === 3) {
69-
paramType = paramObj.schema ? transformSchemaObj(paramObj.schema, { immutableTypes }) : "unknown";
69+
paramType = paramObj.schema ? transformSchemaObj(paramObj.schema, { immutableTypes, version }) : "unknown";
7070
}
7171
output += ` ${readonly}"${paramName}"${required}: ${paramType};\n`;
7272
});

src/transform/responses.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const resType = (res: string | number) => (res === 204 || (res >= 300 && res < 4
99
interface Options {
1010
formatter?: SchemaFormatter;
1111
immutableTypes: boolean;
12+
version: number;
1213
}
1314

1415
export function transformResponsesObj(responsesObj: Record<string, any>, options: Options): string {

src/transform/schema.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface TransformSchemaObjMapOptions {
1414
formatter?: SchemaFormatter;
1515
immutableTypes: boolean;
1616
required?: string[];
17+
version: number;
1718
}
1819

1920
/** Take object keys and convert to TypeScript interface */
@@ -34,6 +35,7 @@ export function transformSchemaObjMap(obj: Record<string, any>, options: Transfo
3435
output += transformSchemaObj(value.schema || value, {
3536
formatter: options.formatter,
3637
immutableTypes: options.immutableTypes,
38+
version: options.version,
3739
});
3840

3941
// 4. close
@@ -46,6 +48,7 @@ export function transformSchemaObjMap(obj: Record<string, any>, options: Transfo
4648
interface Options {
4749
formatter?: SchemaFormatter;
4850
immutableTypes: boolean;
51+
version: number;
4952
}
5053

5154
/** transform anyOf */
@@ -112,13 +115,14 @@ export function transformSchemaObj(node: any, options: Options): string {
112115
let properties = transformSchemaObjMap(node.properties || {}, {
113116
immutableTypes: options.immutableTypes,
114117
required: node.required,
118+
version: options.version,
115119
});
116120

117121
// if additional properties, add an intersection with a generic map type
118122
let additionalProperties: string | undefined;
119-
if (node.additionalProperties) {
120-
if (node.additionalProperties === true || Object.keys(node.additionalProperties).length === 0) {
121-
additionalProperties = `{ [key: string]: any }`;
123+
if (node.additionalProperties || (node.additionalProperties === undefined && options.version === 3)) {
124+
if ((node.additionalProperties ?? true) === true || Object.keys(node.additionalProperties).length === 0) {
125+
additionalProperties = `{ ${readonly}[key: string]: any }`;
122126
} else if (typeof node.additionalProperties === "object") {
123127
const oneOf: any[] | undefined = (node.additionalProperties as any).oneOf || undefined; // TypeScript does a really bad job at inference here, so we enforce a type
124128
const anyOf: any[] | undefined = (node.additionalProperties as any).anyOf || undefined; // "

tests/bin/expected/prettier-js.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ export interface components {
7373
/** Order Status */
7474
status?: 'placed' | 'approved' | 'delivered'
7575
complete?: boolean
76-
}
76+
} & { [key: string]: any }
7777
Category: {
7878
id?: number
7979
name?: string
80-
}
80+
} & { [key: string]: any }
8181
User: {
8282
id?: number
8383
username?: string
@@ -88,11 +88,11 @@ export interface components {
8888
phone?: string
8989
/** User Status */
9090
userStatus?: number
91-
}
91+
} & { [key: string]: any }
9292
Tag: {
9393
id?: number
9494
name?: string
95-
}
95+
} & { [key: string]: any }
9696
Pet: {
9797
id?: number
9898
category?: components['schemas']['Category']
@@ -101,12 +101,12 @@ export interface components {
101101
tags?: components['schemas']['Tag'][]
102102
/** pet status in the store */
103103
status?: 'available' | 'pending' | 'sold'
104-
}
104+
} & { [key: string]: any }
105105
ApiResponse: {
106106
code?: number
107107
type?: string
108108
message?: string
109-
}
109+
} & { [key: string]: any }
110110
}
111111
}
112112

@@ -221,7 +221,7 @@ export interface operations {
221221
name?: string
222222
/** Updated status of the pet */
223223
status?: string
224-
}
224+
} & { [key: string]: any }
225225
}
226226
}
227227
}
@@ -264,7 +264,7 @@ export interface operations {
264264
additionalMetadata?: string
265265
/** file to upload */
266266
file?: string
267-
}
267+
} & { [key: string]: any }
268268
}
269269
}
270270
}

tests/bin/expected/prettier-json.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ export interface components {
7373
/** Order Status */
7474
status?: 'placed' | 'approved' | 'delivered'
7575
complete?: boolean
76-
}
76+
} & { [key: string]: any }
7777
Category: {
7878
id?: number
7979
name?: string
80-
}
80+
} & { [key: string]: any }
8181
User: {
8282
id?: number
8383
username?: string
@@ -88,11 +88,11 @@ export interface components {
8888
phone?: string
8989
/** User Status */
9090
userStatus?: number
91-
}
91+
} & { [key: string]: any }
9292
Tag: {
9393
id?: number
9494
name?: string
95-
}
95+
} & { [key: string]: any }
9696
Pet: {
9797
id?: number
9898
category?: components['schemas']['Category']
@@ -101,12 +101,12 @@ export interface components {
101101
tags?: components['schemas']['Tag'][]
102102
/** pet status in the store */
103103
status?: 'available' | 'pending' | 'sold'
104-
}
104+
} & { [key: string]: any }
105105
ApiResponse: {
106106
code?: number
107107
type?: string
108108
message?: string
109-
}
109+
} & { [key: string]: any }
110110
}
111111
}
112112

@@ -221,7 +221,7 @@ export interface operations {
221221
name?: string
222222
/** Updated status of the pet */
223223
status?: string
224-
}
224+
} & { [key: string]: any }
225225
}
226226
}
227227
}
@@ -264,7 +264,7 @@ export interface operations {
264264
additionalMetadata?: string
265265
/** file to upload */
266266
file?: string
267-
}
267+
} & { [key: string]: any }
268268
}
269269
}
270270
}

tests/bin/expected/stdout.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ export interface components {
7373
/** Order Status */
7474
status?: "placed" | "approved" | "delivered";
7575
complete?: boolean;
76-
};
76+
} & { [key: string]: any };
7777
Category: {
7878
id?: number;
7979
name?: string;
80-
};
80+
} & { [key: string]: any };
8181
User: {
8282
id?: number;
8383
username?: string;
@@ -88,11 +88,11 @@ export interface components {
8888
phone?: string;
8989
/** User Status */
9090
userStatus?: number;
91-
};
91+
} & { [key: string]: any };
9292
Tag: {
9393
id?: number;
9494
name?: string;
95-
};
95+
} & { [key: string]: any };
9696
Pet: {
9797
id?: number;
9898
category?: components["schemas"]["Category"];
@@ -101,12 +101,12 @@ export interface components {
101101
tags?: components["schemas"]["Tag"][];
102102
/** pet status in the store */
103103
status?: "available" | "pending" | "sold";
104-
};
104+
} & { [key: string]: any };
105105
ApiResponse: {
106106
code?: number;
107107
type?: string;
108108
message?: string;
109-
};
109+
} & { [key: string]: any };
110110
};
111111
}
112112

@@ -221,7 +221,7 @@ export interface operations {
221221
name?: string;
222222
/** Updated status of the pet */
223223
status?: string;
224-
};
224+
} & { [key: string]: any };
225225
};
226226
};
227227
};
@@ -264,7 +264,7 @@ export interface operations {
264264
additionalMetadata?: string;
265265
/** file to upload */
266266
file?: string;
267-
};
267+
} & { [key: string]: any };
268268
};
269269
};
270270
};

0 commit comments

Comments
 (0)