Skip to content

Commit 2ac5d55

Browse files
authored
Merge pull request #12 from moznion/export_schema_types
Export schema types from the generated client
2 parents 2784e7a + 6878728 commit 2ac5d55

File tree

4 files changed

+140
-1
lines changed

4 files changed

+140
-1
lines changed

src/index.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ export function generateClient(schemaFilePath: string): string {
2828
if (!pathsInterface) {
2929
throw new Error(`Interface "paths" not found in ${schemaFilePath}`);
3030
}
31+
const componentsInterface = findInterface(schemaFile, "components");
3132

32-
return generateClientCode(pathsInterface, path.basename(schemaFilePath));
33+
return generateClientCode(
34+
pathsInterface,
35+
componentsInterface,
36+
path.basename(schemaFilePath),
37+
);
3338
}
3439

3540
function findInterface(
@@ -51,6 +56,7 @@ interface EndpointInfo {
5156

5257
function generateClientCode(
5358
pathsInterface: InterfaceDeclaration,
59+
componentsInterface: InterfaceDeclaration | undefined,
5460
schemaFileName: string,
5561
): string {
5662
const endpoints = extractEndpointsInfo(pathsInterface);
@@ -65,6 +71,8 @@ function generateClientCode(
6571
`import type { paths } from "./${schemaFileName}"; // generated by openapi-typescript`,
6672
"",
6773
clientClass,
74+
"",
75+
...generateSchemaTypes(componentsInterface),
6876
].join("\n");
6977

7078
const tempFile = tmp.fileSync({ postfix: ".ts" }).name;
@@ -73,6 +81,27 @@ function generateClientCode(
7381
return fs.readFileSync(tempFile, "utf-8");
7482
}
7583

84+
function generateSchemaTypes(
85+
componentsInterface: InterfaceDeclaration | undefined,
86+
): string[] {
87+
const schemasProperty = componentsInterface?.getProperty("schemas");
88+
89+
const types = [];
90+
if (schemasProperty) {
91+
const schemasType = schemasProperty.getType();
92+
for (const schema of schemasType.getProperties()) {
93+
const schemaType = schema.getValueDeclaration()?.getType();
94+
if (schemaType) {
95+
const schemaName =
96+
schema.getName() === "Client" ? "ClientSchema" : schema.getName();
97+
types.push(`export type ${schemaName} = ${schemaType.getText()};`);
98+
}
99+
}
100+
}
101+
102+
return types;
103+
}
104+
76105
function extractEndpointsInfo(
77106
pathsInterface: InterfaceDeclaration,
78107
): EndpointInfo[] {

src/test_resources/expected_client.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,102 @@ export class Client<HT extends Record<string, string>> {
236236
});
237237
}
238238
}
239+
240+
export type Error = { code: number; message: string };
241+
export type User = {
242+
id: string;
243+
name: string;
244+
email: string;
245+
membershipType: "REGULAR" | "PREMIUM" | "STUDENT";
246+
registeredAt: string;
247+
address?: {
248+
postalCode?: string;
249+
street: string;
250+
city: string;
251+
country: string;
252+
};
253+
};
254+
export type Address = {
255+
postalCode?: string;
256+
street: string;
257+
city: string;
258+
country: string;
259+
};
260+
export type UserCreate = {
261+
name: string;
262+
email: string;
263+
membershipType: "REGULAR" | "PREMIUM" | "STUDENT";
264+
address?: {
265+
postalCode?: string;
266+
street: string;
267+
city: string;
268+
country: string;
269+
};
270+
};
271+
export type UserUpdate = {
272+
name: string;
273+
email: string;
274+
membershipType: "REGULAR" | "PREMIUM" | "STUDENT";
275+
address?: {
276+
postalCode?: string;
277+
street: string;
278+
city: string;
279+
country: string;
280+
};
281+
} & { id: string };
282+
export type UserPatch = {
283+
name?: string;
284+
email?: string;
285+
membershipType?: "REGULAR" | "PREMIUM" | "STUDENT";
286+
address?: {
287+
postalCode?: string;
288+
street: string;
289+
city: string;
290+
country: string;
291+
};
292+
};
293+
export type UserList = {
294+
id: string;
295+
name: string;
296+
email: string;
297+
membershipType: "REGULAR" | "PREMIUM" | "STUDENT";
298+
registeredAt: string;
299+
address?: {
300+
postalCode?: string;
301+
street: string;
302+
city: string;
303+
country: string;
304+
};
305+
}[];
306+
export type UserPage = {
307+
total: number;
308+
page: number;
309+
pageSize: number;
310+
items: {
311+
id: string;
312+
name: string;
313+
email: string;
314+
membershipType: "REGULAR" | "PREMIUM" | "STUDENT";
315+
registeredAt: string;
316+
address?: {
317+
postalCode?: string;
318+
street: string;
319+
city: string;
320+
country: string;
321+
};
322+
}[];
323+
};
324+
export type Loan = {
325+
loanId: string;
326+
book: { isbn: string; title: string; author: string };
327+
borrowedAt: string;
328+
dueAt: string;
329+
};
330+
export type Book = { isbn: string; title: string; author: string };
331+
export type BulkJobStatus = {
332+
jobId: string;
333+
status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED";
334+
processed: number;
335+
total: number;
336+
};
337+
export type ClientSchema = { id?: string };

src/test_resources/schema.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,9 @@ export interface components {
528528
processed: number;
529529
total: number;
530530
};
531+
Client: {
532+
id?: string;
533+
};
531534
};
532535
responses: {
533536
/** @description Bad request due to invalid input */

src/test_resources/schema.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,3 +522,11 @@ components:
522522
- status
523523
- processed
524524
- total
525+
526+
# this is dummy schema to check name confliction
527+
Client:
528+
type: object
529+
properties:
530+
id:
531+
type: string
532+

0 commit comments

Comments
 (0)