@technicity/openapi-sdk-generator 5.5.2 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/generate-remix.ts +90 -56
- package/src/generate.ts +2 -3
package/package.json
CHANGED
package/src/generate-remix.ts
CHANGED
|
@@ -12,15 +12,24 @@ import * as prettier from "prettier";
|
|
|
12
12
|
import del from "del";
|
|
13
13
|
|
|
14
14
|
type TEnv = "browser" | "node";
|
|
15
|
+
type TResult = {
|
|
16
|
+
operationId: string;
|
|
17
|
+
methodCode: string;
|
|
18
|
+
restCode: string;
|
|
19
|
+
reqBody: any;
|
|
20
|
+
reqBodySchemaName: string;
|
|
21
|
+
reqBodySchemas: string;
|
|
22
|
+
resBodyTypes: { name: string; status: string; type: string }[];
|
|
23
|
+
};
|
|
15
24
|
|
|
16
25
|
export async function generate(input: {
|
|
17
26
|
api: OpenAPI.Document;
|
|
18
27
|
doc: OpenAPI.Document;
|
|
19
28
|
outdir: string;
|
|
20
|
-
|
|
29
|
+
generateBrowser: boolean;
|
|
21
30
|
generateOrThrow: boolean;
|
|
22
31
|
}) {
|
|
23
|
-
const { api, outdir,
|
|
32
|
+
const { api, outdir, generateOrThrow } = input;
|
|
24
33
|
|
|
25
34
|
if (api.paths == null || Object.keys(api.paths).length === 0) {
|
|
26
35
|
throw new Error("No paths found.");
|
|
@@ -29,15 +38,7 @@ export async function generate(input: {
|
|
|
29
38
|
const produces = (api as OpenAPIV2.Document).produces;
|
|
30
39
|
const baseUrl = getBaseUrl(api);
|
|
31
40
|
|
|
32
|
-
let results:
|
|
33
|
-
operationId: string;
|
|
34
|
-
methodCode: string;
|
|
35
|
-
restCode: string;
|
|
36
|
-
reqBody: any;
|
|
37
|
-
reqBodySchemaName: string;
|
|
38
|
-
reqBodySchemas: string;
|
|
39
|
-
resBodyTypes: { name: string; status: string; type: string }[];
|
|
40
|
-
}[] = [];
|
|
41
|
+
let results: TResult[] = [];
|
|
41
42
|
|
|
42
43
|
// Sort
|
|
43
44
|
api.paths = Object.fromEntries(
|
|
@@ -57,7 +58,7 @@ export async function generate(input: {
|
|
|
57
58
|
|
|
58
59
|
results.push({
|
|
59
60
|
operationId,
|
|
60
|
-
...(await
|
|
61
|
+
...(await getMethodCode({
|
|
61
62
|
operationId,
|
|
62
63
|
path: p,
|
|
63
64
|
method,
|
|
@@ -76,19 +77,61 @@ export async function generate(input: {
|
|
|
76
77
|
|
|
77
78
|
await fs.writeFile(
|
|
78
79
|
path.join(outdir, `Sdk.ts`),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
getCode({ results, baseUrl, generateOrThrow, env: "node" })
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (input.generateBrowser) {
|
|
84
|
+
await fs.writeFile(
|
|
85
|
+
path.join(outdir, `Sdk.browser.ts`),
|
|
86
|
+
getCode({ results, baseUrl, generateOrThrow, env: "browser" })
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const reqBodySchemas = results.map((x) => x.reqBodySchemas);
|
|
91
|
+
|
|
92
|
+
if (reqBodySchemas.length > 0) {
|
|
93
|
+
await fs.writeFile(
|
|
94
|
+
path.join(outdir, `schemas.ts`),
|
|
95
|
+
prettier.format(reqBodySchemas.join("\n\n"), {
|
|
96
|
+
parser: "typescript",
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
await fs.writeFile(
|
|
102
|
+
path.join(outdir, "api.json"),
|
|
103
|
+
JSON.stringify(input.doc, null, 2)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getCode({
|
|
108
|
+
results,
|
|
109
|
+
baseUrl,
|
|
110
|
+
generateOrThrow,
|
|
111
|
+
env,
|
|
112
|
+
}: {
|
|
113
|
+
results: TResult[];
|
|
114
|
+
baseUrl: string | undefined;
|
|
115
|
+
generateOrThrow: boolean;
|
|
116
|
+
env: TEnv;
|
|
117
|
+
}) {
|
|
118
|
+
return prettier.format(
|
|
119
|
+
`${
|
|
120
|
+
env === "browser"
|
|
121
|
+
? ""
|
|
122
|
+
: `// TODO: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/60924
|
|
123
|
+
import {
|
|
124
|
+
fetch,
|
|
125
|
+
type RequestInit,
|
|
126
|
+
type HeadersInit,
|
|
127
|
+
type BodyInit,
|
|
128
|
+
Response,
|
|
129
|
+
Request,
|
|
130
|
+
Headers,
|
|
131
|
+
RetryAgent,
|
|
132
|
+
Agent,
|
|
133
|
+
} from "undici";`
|
|
134
|
+
}
|
|
92
135
|
|
|
93
136
|
export type Interceptors = { req?: (req: Request) => Promise<Request>, res?: (req: Request, res: Response) => Promise<Response> };
|
|
94
137
|
|
|
@@ -127,10 +170,8 @@ export async function generate(input: {
|
|
|
127
170
|
);
|
|
128
171
|
}${
|
|
129
172
|
env === "node"
|
|
130
|
-
? `const ReadableStream =
|
|
131
|
-
|
|
132
|
-
require("node:stream/web").ReadableStream`
|
|
133
|
-
: `const ReadableStream = globalThis.ReadableStream;`
|
|
173
|
+
? `const ReadableStream = await import("node:stream/web").then(({ReadableStream}) => ReadableStream)`
|
|
174
|
+
: ""
|
|
134
175
|
}
|
|
135
176
|
const _reqBody =
|
|
136
177
|
req.reqBody instanceof ReadableStream
|
|
@@ -243,12 +284,17 @@ export async function generate(input: {
|
|
|
243
284
|
req = await interceptors.req(req);
|
|
244
285
|
}
|
|
245
286
|
|
|
246
|
-
let
|
|
287
|
+
let reqOpts: RequestInit = {};
|
|
288
|
+
|
|
289
|
+
(reqOpts as any).dispatcher = new RetryAgent(new Agent(), {
|
|
290
|
+
methods: ["GET", "HEAD", "OPTIONS"],
|
|
291
|
+
});
|
|
292
|
+
|
|
247
293
|
if (typeof opts?.timeout === "number") {
|
|
248
|
-
|
|
294
|
+
reqOpts.signal = AbortSignal.timeout(opts.timeout);
|
|
249
295
|
}
|
|
250
296
|
|
|
251
|
-
let res = await this.#httpClient.fetch(req,
|
|
297
|
+
let res = await this.#httpClient.fetch(req, reqOpts);
|
|
252
298
|
|
|
253
299
|
if (interceptors?.res) {
|
|
254
300
|
res = await interceptors.res(req, res);
|
|
@@ -345,12 +391,17 @@ export async function generate(input: {
|
|
|
345
391
|
req = await interceptors.req(req);
|
|
346
392
|
}
|
|
347
393
|
|
|
348
|
-
let
|
|
394
|
+
let reqOpts: RequestInit = {};
|
|
395
|
+
|
|
396
|
+
(reqOpts as any).dispatcher = new RetryAgent(new Agent(), {
|
|
397
|
+
methods: ["GET", "HEAD", "OPTIONS"],
|
|
398
|
+
});
|
|
399
|
+
|
|
349
400
|
if (typeof opts?.timeout === "number") {
|
|
350
|
-
|
|
401
|
+
reqOpts.signal = AbortSignal.timeout(opts.timeout);
|
|
351
402
|
}
|
|
352
403
|
|
|
353
|
-
let res = await this.#httpClient.fetch(req,
|
|
404
|
+
let res = await this.#httpClient.fetch(req, reqOpts);
|
|
354
405
|
|
|
355
406
|
if (interceptors?.res) {
|
|
356
407
|
res = await interceptors.res(req, res);
|
|
@@ -413,34 +464,17 @@ export async function generate(input: {
|
|
|
413
464
|
return readable.text();
|
|
414
465
|
}
|
|
415
466
|
// Node
|
|
416
|
-
const consumers =
|
|
467
|
+
const consumers = await import("node:stream/consumers");
|
|
417
468
|
return consumers.text(readable);
|
|
418
469
|
}
|
|
419
470
|
|
|
420
471
|
${getHttpClientCode(env)}
|
|
421
472
|
`,
|
|
422
|
-
|
|
423
|
-
)
|
|
424
|
-
);
|
|
425
|
-
|
|
426
|
-
const reqBodySchemas = results.map((x) => x.reqBodySchemas);
|
|
427
|
-
|
|
428
|
-
if (reqBodySchemas.length > 0) {
|
|
429
|
-
await fs.writeFile(
|
|
430
|
-
path.join(outdir, `schemas.ts`),
|
|
431
|
-
prettier.format(reqBodySchemas.join("\n\n"), {
|
|
432
|
-
parser: "typescript",
|
|
433
|
-
})
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
await fs.writeFile(
|
|
438
|
-
path.join(outdir, "api.json"),
|
|
439
|
-
JSON.stringify(input.doc, null, 2)
|
|
473
|
+
{ parser: "typescript" }
|
|
440
474
|
);
|
|
441
475
|
}
|
|
442
476
|
|
|
443
|
-
async function
|
|
477
|
+
async function getMethodCode(input: {
|
|
444
478
|
operationId: string;
|
|
445
479
|
path: string;
|
|
446
480
|
method: string;
|
|
@@ -804,7 +838,7 @@ function getHttpClientCode(env: TEnv) {
|
|
|
804
838
|
? requestInfo
|
|
805
839
|
: requestInfo instanceof Request
|
|
806
840
|
? getURL(requestInfo.url)
|
|
807
|
-
: getURL(requestInfo);
|
|
841
|
+
: getURL(requestInfo as string);
|
|
808
842
|
const method =
|
|
809
843
|
init?.method?.toUpperCase() ??
|
|
810
844
|
(requestInfo instanceof Request ? requestInfo.method : "GET");
|
package/src/generate.ts
CHANGED
|
@@ -60,8 +60,7 @@ export const schema = {
|
|
|
60
60
|
description: "module type for generated SDK",
|
|
61
61
|
},
|
|
62
62
|
variant: { enum: ["default", "remix"], default: "default" },
|
|
63
|
-
|
|
64
|
-
env: { enum: ["browser", "node"], default: "browser" },
|
|
63
|
+
generateBrowser: { type: "boolean", default: false },
|
|
65
64
|
generateOrThrow: { type: "boolean", default: true },
|
|
66
65
|
},
|
|
67
66
|
additionalProperties: false,
|
|
@@ -115,7 +114,7 @@ export async function generate(opts) {
|
|
|
115
114
|
api,
|
|
116
115
|
outdir: path.resolve(opts.outdir),
|
|
117
116
|
doc: _doc,
|
|
118
|
-
|
|
117
|
+
generateBrowser: opts.generateBrowser,
|
|
119
118
|
generateOrThrow: opts.generateOrThrow,
|
|
120
119
|
});
|
|
121
120
|
}
|