Skip to content

Commit 0c37ae3

Browse files
committed
Add tests for v3
1 parent 109b7fe commit 0c37ae3

File tree

21 files changed

+9702
-6629
lines changed

21 files changed

+9702
-6629
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.cache
22
.DS_Store
3-
./generated/*.ts
3+
**/generated/*.ts
44
coverage
55
pkg
66
node_modules

bin/cli.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ const timeStart = process.hrtime();
4545
// Write to file if specifying output
4646
if (cli.flags.output) {
4747
const outputFile = path.resolve(process.cwd(), cli.flags.output);
48+
49+
// recursively create parent directories if they don’t exist
50+
const parentDirs = cli.flags.output.split(path.sep);
51+
for (var i = 1; i < parentDirs.length; i++) {
52+
const dir = path.resolve(process.cwd(), ...parentDirs.slice(0, i));
53+
if (!fs.existsSync(dir)) {
54+
fs.mkdirSync(dir);
55+
}
56+
}
57+
4858
fs.writeFileSync(outputFile, result, "utf8");
4959

5060
const timeEnd = process.hrtime(timeStart);

src/types/OpenAPI3.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ export type OpenAPI3Type =
1919
| "object"
2020
| "string";
2121

22-
export type OpenAPI3Reference = { $ref: string };
22+
export type OpenAPI3Reference =
23+
| { $ref: string }
24+
| { anyOf: (OpenAPI3SchemaObject | OpenAPI3Reference)[] }
25+
| { oneOf: (OpenAPI3SchemaObject | OpenAPI3Reference)[] };
2326

2427
export interface OpenAPI3SchemaObject {
2528
additionalProperties?: OpenAPI3SchemaObject | OpenAPI3Reference | boolean;
2629
allOf?: (OpenAPI3SchemaObject | OpenAPI3Reference)[];
27-
anyOf?: (OpenAPI3SchemaObject | OpenAPI3Reference)[];
2830
description?: string;
2931
enum?: string[];
3032
items?: OpenAPI3SchemaObject | OpenAPI3Reference;

src/utils.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ export function isObjNode(node: any): boolean {
5050
);
5151
}
5252

53+
/**
54+
* Return ture if oneOf type
55+
*/
56+
export function isOneOfNode(node: any): boolean {
57+
if (!isSchemaObj(node)) {
58+
return false;
59+
}
60+
return Array.isArray(node.oneOf);
61+
}
62+
5363
/**
5464
* Return true if item is schema object
5565
*/
@@ -58,7 +68,12 @@ export function isSchemaObj(obj: any): boolean {
5868
return false;
5969
}
6070
return (
61-
!!obj.type || !!obj.properties || !!obj.allOf || !!obj.additionalProperties
71+
!!obj.additionalProperties ||
72+
!!obj.allOf ||
73+
!!obj.anyOf ||
74+
!!obj.oneOf ||
75+
!!obj.properties ||
76+
!!obj.type
6277
);
6378
}
6479

src/v2.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ export default function generateTypesV2(
4747
JSON.stringify(schema.definitions),
4848
(_, node) =>
4949
node && node["$ref"]
50-
? escape(`definitions['${node.$ref.replace("#/definitions/", "")}']`) // important: use single-quotes here for JSON (you can always change w/ Prettier at the end)
50+
? escape(
51+
`definitions['${node.$ref
52+
.replace("#/definitions/", "")
53+
.replace(/\//g, "']['")}']`
54+
) // important: use single-quotes here for JSON (you can always change w/ Prettier at the end)
5155
: node // return by default
5256
);
5357

src/v3.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
tsIntersectionOf,
1212
tsUnionOf,
1313
unescape,
14+
isOneOfNode,
1415
} from "./utils";
1516

1617
export const PRIMITIVES: { [key: string]: "boolean" | "string" | "number" } = {
@@ -35,26 +36,31 @@ export default function generateTypesV3(
3536
);
3637
}
3738

38-
// 1st pass: expand $refs first to reduce lookups & prevent circular refs
39-
const expandedRefs = JSON.parse(
39+
// 1st pass: convert anyOf to “any” since this is neither an “Intersection” nor “Union”
40+
const anyOf = JSON.parse(
4041
JSON.stringify(schema.components.schemas),
42+
(_, node) => (node && node.anyOf ? escape("any") : node)
43+
);
44+
45+
// 2nd pass: expand $refs first to reduce lookups & prevent circular refs
46+
const expandedRefs = JSON.parse(
47+
JSON.stringify(anyOf),
4148
(_, node) =>
4249
node && node["$ref"]
4350
? escape(
44-
`components['schemas']['${node.$ref.replace(
45-
"#/components/schemas/",
46-
""
47-
)}']`
51+
`components['${node.$ref
52+
.replace("#/components/", "")
53+
.replace(/\//g, "']['")}']`
4854
) // important: use single-quotes here for JSON (you can always change w/ Prettier at the end)
4955
: node // return by default
5056
);
5157

52-
// 2nd pass: propertyMapper
58+
// 3rd pass: propertyMapper
5359
const propertyMapped = options
5460
? propertyMapper(expandedRefs, options.propertyMapper)
5561
: expandedRefs;
5662

57-
// 3rd pass: primitives
63+
// 4th pass: primitives
5864
const primitives = JSON.parse(
5965
JSON.stringify(propertyMapped),
6066
(_, node: OpenAPI3SchemaObject) => {
@@ -70,7 +76,7 @@ export default function generateTypesV3(
7076
}
7177
);
7278

73-
// 4th pass: objects & arrays
79+
// 5th pass: objects & arrays
7480
const objectsAndArrays = JSON.parse(JSON.stringify(primitives), (_, node) => {
7581
// object
7682
if (isObjNode(node)) {
@@ -130,6 +136,11 @@ export default function generateTypesV3(
130136
return escape(tsArrayOf(node.items));
131137
}
132138

139+
// oneOf
140+
if (isOneOfNode(node)) {
141+
return escape(tsUnionOf(node.oneOf));
142+
}
143+
133144
return node; // return by default
134145
});
135146

tests/v2/expected/petstore.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* This file was auto-generated by swagger-to-ts.
3+
* Do not make direct changes to the file.
4+
*/
5+
6+
export interface definitions {
7+
Order: {
8+
id?: number;
9+
petId?: number;
10+
quantity?: number;
11+
shipDate?: string;
12+
status?: "placed" | "approved" | "delivered";
13+
complete?: boolean;
14+
};
15+
Category: { id?: number; name?: string };
16+
User: {
17+
id?: number;
18+
username?: string;
19+
firstName?: string;
20+
lastName?: string;
21+
email?: string;
22+
password?: string;
23+
phone?: string;
24+
userStatus?: number;
25+
};
26+
Tag: { id?: number; name?: string };
27+
Pet: {
28+
id?: number;
29+
category?: definitions["Category"];
30+
name: string;
31+
photoUrls: string[];
32+
tags?: definitions["Tag"][];
33+
status?: "available" | "pending" | "sold";
34+
};
35+
ApiResponse: { code?: number; type?: string; message?: string };
36+
}

0 commit comments

Comments
 (0)