@moccona/apicodegen 0.0.3 → 0.0.8
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/README.md +320 -25
- package/bin/cli.cjs +24 -0
- package/npm/index.cjs +2097 -2382
- package/npm/index.cjs.map +1 -1
- package/npm/index.d.cts +603 -408
- package/npm/index.d.cts.map +1 -0
- package/npm/index.d.mts +731 -0
- package/npm/index.d.mts.map +1 -0
- package/npm/index.mjs +2078 -0
- package/npm/index.mjs.map +1 -0
- package/npm/vite/index.d.mts +39 -0
- package/npm/vite/index.d.mts.map +1 -0
- package/npm/vite/index.mjs +1990 -0
- package/npm/vite/index.mjs.map +1 -0
- package/package.json +42 -25
- package/bin/cli.js +0 -2248
- package/npm/index.d.ts +0 -536
- package/npm/index.js +0 -2367
- package/npm/index.js.map +0 -1
- package/npm/vite/index.d.ts +0 -29
- package/npm/vite/index.js +0 -2276
- package/npm/vite/index.js.map +0 -1
package/npm/vite/index.js
DELETED
|
@@ -1,2276 +0,0 @@
|
|
|
1
|
-
// src/core/base/Adaptor.ts
|
|
2
|
-
var Adapter = class {
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
// src/core/constants/keywords.ts
|
|
6
|
-
var typescriptKeywords = /* @__PURE__ */ new Set([
|
|
7
|
-
"break",
|
|
8
|
-
"case",
|
|
9
|
-
"catch",
|
|
10
|
-
"class",
|
|
11
|
-
"const",
|
|
12
|
-
"continue",
|
|
13
|
-
"debugger",
|
|
14
|
-
"default",
|
|
15
|
-
"delete",
|
|
16
|
-
"do",
|
|
17
|
-
"else",
|
|
18
|
-
"enum",
|
|
19
|
-
"export",
|
|
20
|
-
"extends",
|
|
21
|
-
"false",
|
|
22
|
-
"finally",
|
|
23
|
-
"for",
|
|
24
|
-
"function",
|
|
25
|
-
"if",
|
|
26
|
-
"import",
|
|
27
|
-
"in",
|
|
28
|
-
"instanceof",
|
|
29
|
-
"new",
|
|
30
|
-
"null",
|
|
31
|
-
"return",
|
|
32
|
-
"super",
|
|
33
|
-
"switch",
|
|
34
|
-
"this",
|
|
35
|
-
"throw",
|
|
36
|
-
"true",
|
|
37
|
-
"try",
|
|
38
|
-
"typeof",
|
|
39
|
-
"var",
|
|
40
|
-
"void",
|
|
41
|
-
"while",
|
|
42
|
-
"with",
|
|
43
|
-
"as",
|
|
44
|
-
"implements",
|
|
45
|
-
"interface",
|
|
46
|
-
"let",
|
|
47
|
-
"package",
|
|
48
|
-
"private",
|
|
49
|
-
"protected",
|
|
50
|
-
"public",
|
|
51
|
-
"static",
|
|
52
|
-
"yield",
|
|
53
|
-
"abstract",
|
|
54
|
-
"any",
|
|
55
|
-
"async",
|
|
56
|
-
"await",
|
|
57
|
-
"constructor",
|
|
58
|
-
"declare",
|
|
59
|
-
"from",
|
|
60
|
-
"get",
|
|
61
|
-
"is",
|
|
62
|
-
"module",
|
|
63
|
-
"namespace",
|
|
64
|
-
"never",
|
|
65
|
-
"require",
|
|
66
|
-
"set",
|
|
67
|
-
"type",
|
|
68
|
-
"unknown",
|
|
69
|
-
"readonly",
|
|
70
|
-
"of",
|
|
71
|
-
"asserts",
|
|
72
|
-
"infer",
|
|
73
|
-
"keyof",
|
|
74
|
-
"boolean",
|
|
75
|
-
"number",
|
|
76
|
-
"string",
|
|
77
|
-
"symbol",
|
|
78
|
-
"object",
|
|
79
|
-
"undefined",
|
|
80
|
-
"bigint"
|
|
81
|
-
]);
|
|
82
|
-
|
|
83
|
-
// src/core/interface.ts
|
|
84
|
-
var MediaTypes = /* @__PURE__ */ ((MediaTypes2) => {
|
|
85
|
-
MediaTypes2["JSON"] = "application/json";
|
|
86
|
-
MediaTypes2["TEXT"] = "text";
|
|
87
|
-
MediaTypes2["IMAGE"] = "image";
|
|
88
|
-
MediaTypes2["AUDIO"] = "audio";
|
|
89
|
-
MediaTypes2["VIDEO"] = "video";
|
|
90
|
-
return MediaTypes2;
|
|
91
|
-
})(MediaTypes || {});
|
|
92
|
-
var HttpMethods = /* @__PURE__ */ ((HttpMethods2) => {
|
|
93
|
-
HttpMethods2["GET"] = "get";
|
|
94
|
-
HttpMethods2["PUT"] = "put";
|
|
95
|
-
HttpMethods2["POST"] = "post";
|
|
96
|
-
HttpMethods2["DELETE"] = "delete";
|
|
97
|
-
HttpMethods2["OPTIONS"] = "options";
|
|
98
|
-
HttpMethods2["HEAD"] = "head";
|
|
99
|
-
HttpMethods2["PATCH"] = "patch";
|
|
100
|
-
HttpMethods2["TRACE"] = "trace";
|
|
101
|
-
return HttpMethods2;
|
|
102
|
-
})(HttpMethods || {});
|
|
103
|
-
|
|
104
|
-
// src/core/base/Base.ts
|
|
105
|
-
import { Agent, request } from "undici";
|
|
106
|
-
var Base = class _Base {
|
|
107
|
-
constructor() {
|
|
108
|
-
if (new.target === _Base) {
|
|
109
|
-
throw new Error("Cannot instantiate abstract class");
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Converts a reference string to a meaningful name.
|
|
114
|
-
* @param ref - The reference string to process.
|
|
115
|
-
* @param [doc] - Optional document reference for context.
|
|
116
|
-
* @returns - The processed name.
|
|
117
|
-
*/
|
|
118
|
-
static ref2name(ref, doc) {
|
|
119
|
-
const paths = ref.replace(/^#/, "").split("/").filter(Boolean);
|
|
120
|
-
if (!doc) {
|
|
121
|
-
return paths.slice(-1)[0];
|
|
122
|
-
}
|
|
123
|
-
let temporary = doc;
|
|
124
|
-
let lastPath = "";
|
|
125
|
-
for (const path of paths) {
|
|
126
|
-
const adjustedPath = path.replaceAll("~1", "/");
|
|
127
|
-
temporary = temporary[adjustedPath];
|
|
128
|
-
lastPath = adjustedPath;
|
|
129
|
-
}
|
|
130
|
-
if (!temporary) {
|
|
131
|
-
return "unknown";
|
|
132
|
-
}
|
|
133
|
-
return temporary.$ref ? this.ref2name(temporary.$ref, doc) : lastPath;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Converts an API path to a function name.
|
|
137
|
-
* @param path - The API endpoint path.
|
|
138
|
-
* @param [method] - The HTTP method (e.g., GET, POST).
|
|
139
|
-
* @param [operationId] - Unique identifier for the operation.
|
|
140
|
-
* @returns - The generated function name.
|
|
141
|
-
*/
|
|
142
|
-
static pathToFnName(path, method, _operationId = "") {
|
|
143
|
-
const name = this.normalize(this.camelCase(this.normalize(path)));
|
|
144
|
-
const suffix = method ? this.capitalize(this.upperCamelCase(`using_${method}`)) : "";
|
|
145
|
-
return name + suffix;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Normalizes a string by replacing special characters and avoiding TypeScript keywords.
|
|
149
|
-
* @param text - Input text to normalize.
|
|
150
|
-
* @returns - The normalized string.
|
|
151
|
-
*/
|
|
152
|
-
static normalize(text) {
|
|
153
|
-
if (typescriptKeywords.has(text)) {
|
|
154
|
-
text += "_";
|
|
155
|
-
}
|
|
156
|
-
return text.replace(/[/\-_{}():\s`,*<>$#.]/gm, "_").replace(/^\d./gm, "").replaceAll("...", "");
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Capitalizes the first character of a string.
|
|
160
|
-
* @param text - Input string.
|
|
161
|
-
* @returns - Capitalized string.
|
|
162
|
-
*/
|
|
163
|
-
static capitalize(text) {
|
|
164
|
-
text = text.trim();
|
|
165
|
-
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Converts a string to camelCase.
|
|
169
|
-
* @param text - Input string.
|
|
170
|
-
* @returns - CamelCase string.
|
|
171
|
-
*/
|
|
172
|
-
static camelCase(text) {
|
|
173
|
-
text = text.trim();
|
|
174
|
-
return text.split("_").filter(Boolean).map((t4, index) => index === 0 ? t4 : this.capitalize(t4)).join("");
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Converts a string to UpperCamelCase.
|
|
178
|
-
* @param text - Input string.
|
|
179
|
-
* @returns - UpperCamelCase string.
|
|
180
|
-
*/
|
|
181
|
-
static upperCamelCase(text) {
|
|
182
|
-
return this.normalize(text).replaceAll("...", "").split("_").filter(Boolean).map(this.capitalize).join("");
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Fetches documentation from a given URL.
|
|
186
|
-
* @param url - The URL to fetch the documentation from.
|
|
187
|
-
* @param requestInit - Additional request parameters.
|
|
188
|
-
* @returns - A promise resolving to the fetched documentation data.
|
|
189
|
-
*/
|
|
190
|
-
static async fetchDoc(url, requestInit = {}) {
|
|
191
|
-
const agent = new Agent({
|
|
192
|
-
connect: { rejectUnauthorized: false }
|
|
193
|
-
});
|
|
194
|
-
const { body, statusCode } = await request(url, {
|
|
195
|
-
method: "GET",
|
|
196
|
-
dispatcher: agent,
|
|
197
|
-
...requestInit
|
|
198
|
-
});
|
|
199
|
-
if (statusCode >= 400) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Failed to fetch OpenAPI documentation from ${url}: HTTP ${statusCode}`
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
try {
|
|
205
|
-
return body.json();
|
|
206
|
-
} catch (error) {
|
|
207
|
-
throw new Error(
|
|
208
|
-
`Failed to parse JSON response from ${url}: ${error instanceof Error ? error.message : String(error)}`
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Determines the media type from a given media type string.
|
|
214
|
-
* @param mediaType - The media type string to evaluate.
|
|
215
|
-
* @returns - The matched MediaTypes or null.
|
|
216
|
-
*/
|
|
217
|
-
static getMediaType(mediaType) {
|
|
218
|
-
const mediaTypeValues = Object.values(MediaTypes);
|
|
219
|
-
const found = mediaTypeValues.find(
|
|
220
|
-
(type) => mediaType.includes(type)
|
|
221
|
-
);
|
|
222
|
-
return found;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Checks if a schema is a valid enum type that isn't boolean.
|
|
226
|
-
* @param a - The schema object to evaluate.
|
|
227
|
-
* @returns - True if the schema is a valid non-boolean enum.
|
|
228
|
-
*/
|
|
229
|
-
static isValidEnumType(a) {
|
|
230
|
-
return a.type !== "boolean" && !this.isBooleanEnum(a);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Checks if a schema represents a boolean enum.
|
|
234
|
-
* @param a - The schema object to evaluate.
|
|
235
|
-
* @returns - True if the schema is a boolean enum.
|
|
236
|
-
*/
|
|
237
|
-
static isBooleanEnum(a) {
|
|
238
|
-
return a.type === "boolean" || !!a.enum?.some(
|
|
239
|
-
(member) => typeof member === "boolean"
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Checks if two enum schemas are identical.
|
|
244
|
-
* @param a - First enum schema to compare.
|
|
245
|
-
* @param b - Second enum schema to compare.
|
|
246
|
-
* @returns - True if the enums are identical.
|
|
247
|
-
*/
|
|
248
|
-
static isSameEnum(a, b) {
|
|
249
|
-
return a.enum.length === b.enum.length && a.enum.sort().every((v, index) => v === b.enum.sort()[index]);
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Filters out duplicate enum schemas from an array.
|
|
253
|
-
* @param enums - Array of enum schemas to process.
|
|
254
|
-
* @returns - Array of unique enum schemas.
|
|
255
|
-
*/
|
|
256
|
-
static uniqueEnums(enums) {
|
|
257
|
-
const enumMap = /* @__PURE__ */ new Map();
|
|
258
|
-
for (const e of enums) {
|
|
259
|
-
const existing = enumMap.get(e.name);
|
|
260
|
-
if (existing) {
|
|
261
|
-
for (const value of e.enum) {
|
|
262
|
-
existing.add(value);
|
|
263
|
-
}
|
|
264
|
-
} else {
|
|
265
|
-
enumMap.set(e.name, new Set(e.enum));
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return Array.from(enumMap.entries()).map(([name, values]) => ({
|
|
269
|
-
name,
|
|
270
|
-
enum: Array.from(values)
|
|
271
|
-
}));
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Finds the first occurrence of a matching enum schema in an array.
|
|
275
|
-
* @param a - The enum schema to find.
|
|
276
|
-
* @param enums - Array of enum schemas to search.
|
|
277
|
-
* @returns - The found schema or undefined.
|
|
278
|
-
*/
|
|
279
|
-
static findSameSchema(a, enums) {
|
|
280
|
-
return enums.find((b) => this.isSameEnum(b, a));
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Checks if an object is a reference object.
|
|
284
|
-
* @param schema - The object to check.
|
|
285
|
-
* @returns - True if the object is a reference.
|
|
286
|
-
*/
|
|
287
|
-
static isRef(schema) {
|
|
288
|
-
return typeof schema === "object" && schema !== null && "$ref" in schema && typeof schema.$ref === "string";
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
// src/core/base/Provider.ts
|
|
293
|
-
var Provider = class {
|
|
294
|
-
/** collection of enum schemas */
|
|
295
|
-
enums = [];
|
|
296
|
-
/** collection of schemas indexed by name */
|
|
297
|
-
schemas = {};
|
|
298
|
-
/** collection of parameters indexed by name */
|
|
299
|
-
parameters = {};
|
|
300
|
-
/** collection of API responses indexed by name */
|
|
301
|
-
responses = {};
|
|
302
|
-
/** collection of request bodies indexed by name */
|
|
303
|
-
requestBodies = {};
|
|
304
|
-
/** collection of API endpoints (operations) indexed by path */
|
|
305
|
-
apis = {};
|
|
306
|
-
/** URL for fetching API documentation */
|
|
307
|
-
docURL;
|
|
308
|
-
/** base URL for API endpoints */
|
|
309
|
-
baseURL;
|
|
310
|
-
/** output directory for generated code */
|
|
311
|
-
output;
|
|
312
|
-
/** request options for API documentation fetch */
|
|
313
|
-
requestOptions;
|
|
314
|
-
/** source path for imported client */
|
|
315
|
-
importClientSource;
|
|
316
|
-
/**
|
|
317
|
-
* Provider Constructor.
|
|
318
|
-
* @param {ProviderInitOptions} initOptions - Initial configuration for the provider.
|
|
319
|
-
* @param {unknown} doc - Raw API documentation data to be parsed.
|
|
320
|
-
*/
|
|
321
|
-
constructor(initOptions, doc) {
|
|
322
|
-
this.docURL = initOptions.docURL;
|
|
323
|
-
this.baseURL = initOptions.baseURL ?? "";
|
|
324
|
-
this.output = initOptions.output ?? ".";
|
|
325
|
-
this.requestOptions = initOptions.requestOptions ?? {};
|
|
326
|
-
this.importClientSource = initOptions.importClientSource ?? "";
|
|
327
|
-
const { enums, schemas, requestBodies, responses, parameters, apis } = this.parse(doc);
|
|
328
|
-
this.enums = enums;
|
|
329
|
-
this.schemas = schemas;
|
|
330
|
-
this.responses = responses;
|
|
331
|
-
this.parameters = parameters;
|
|
332
|
-
this.requestBodies = requestBodies;
|
|
333
|
-
this.apis = apis;
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
// src/core/generator/index.ts
|
|
338
|
-
import { writeFile } from "fs/promises";
|
|
339
|
-
import { format } from "prettier";
|
|
340
|
-
import {
|
|
341
|
-
addSyntheticLeadingComment,
|
|
342
|
-
createPrinter,
|
|
343
|
-
factory as t,
|
|
344
|
-
NodeFlags,
|
|
345
|
-
SyntaxKind
|
|
346
|
-
} from "typescript";
|
|
347
|
-
var Generator = class _Generator {
|
|
348
|
-
/**
|
|
349
|
-
* Converts an array of TypeScript statements into a formatted string of code.
|
|
350
|
-
*
|
|
351
|
-
* @param statements - The array of TypeScript statement nodes.
|
|
352
|
-
* @returns Formatted code as a string.
|
|
353
|
-
* @throws {Error} If no valid statements are provided.
|
|
354
|
-
*/
|
|
355
|
-
static toCode(statements) {
|
|
356
|
-
if (statements.length === 0) {
|
|
357
|
-
return "// No api declaration found.";
|
|
358
|
-
}
|
|
359
|
-
const sourceFile = t.createSourceFile(
|
|
360
|
-
statements,
|
|
361
|
-
t.createToken(SyntaxKind.EndOfFileToken),
|
|
362
|
-
NodeFlags.None
|
|
363
|
-
);
|
|
364
|
-
return createPrinter().printFile(sourceFile);
|
|
365
|
-
}
|
|
366
|
-
static async write(code, filepath) {
|
|
367
|
-
try {
|
|
368
|
-
await writeFile(filepath, code);
|
|
369
|
-
} catch (error) {
|
|
370
|
-
console.error(error);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Converts a path string with parameters into a TypeScript template expression.
|
|
375
|
-
* Handles query parameters and path placeholders.
|
|
376
|
-
*
|
|
377
|
-
* @param path - The base path string containing placeholders.
|
|
378
|
-
* @param parameters - Array of parameter objects defining the parameters.
|
|
379
|
-
* @param basePath - Optional base path to prepend (default: "").
|
|
380
|
-
* @returns A TypeScript template expressi
|
|
381
|
-
*/
|
|
382
|
-
static toUrlTemplate(path, parameters, basePath = "") {
|
|
383
|
-
const queryParameters = parameters.filter(
|
|
384
|
-
(p) => p.in === "query" /* query */
|
|
385
|
-
);
|
|
386
|
-
if (queryParameters.length > 0) {
|
|
387
|
-
const queryString = queryParameters.map(
|
|
388
|
-
(qp, index) => `${index === 0 ? "?" : "&"}${encodeURIComponent(qp.name)}={${Base.camelCase(Base.normalize(qp.name))}}`
|
|
389
|
-
).join("");
|
|
390
|
-
path += queryString;
|
|
391
|
-
}
|
|
392
|
-
const pathSegments = path.replaceAll("{", "${").split("$").filter(Boolean);
|
|
393
|
-
if (pathSegments.length === 1) {
|
|
394
|
-
return t.createNoSubstitutionTemplateLiteral(basePath + path);
|
|
395
|
-
}
|
|
396
|
-
return t.createTemplateExpression(
|
|
397
|
-
t.createTemplateHead(basePath + pathSegments[0]),
|
|
398
|
-
pathSegments.slice(1).map((segment, index) => {
|
|
399
|
-
const match = /^{(.+)}(.+)?/gm.exec(segment);
|
|
400
|
-
const isLastSegment = index === pathSegments.length - 2;
|
|
401
|
-
if (!match) {
|
|
402
|
-
throw new Error(`Invalid path segment: ${segment}`);
|
|
403
|
-
}
|
|
404
|
-
return t.createTemplateSpan(
|
|
405
|
-
t.createIdentifier(match[1]),
|
|
406
|
-
!isLastSegment ? t.createTemplateMiddle(match[2]) : t.createTemplateTail(match[2] || "")
|
|
407
|
-
);
|
|
408
|
-
})
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Adds synthetic comments to a TypeScript AST node.
|
|
413
|
-
*
|
|
414
|
-
* @param node - The target AST node.
|
|
415
|
-
* @param comments - Array of comment objects to add.
|
|
416
|
-
*/
|
|
417
|
-
static addComments(node, comments) {
|
|
418
|
-
if (!Array.isArray(comments) || comments.filter(Boolean).length === 0)
|
|
419
|
-
return;
|
|
420
|
-
const formatComment = (comment) => {
|
|
421
|
-
return comment.tag ? ` @${comment.tag} ${comment.comment ?? ""}` : ` ${comment.comment}`;
|
|
422
|
-
};
|
|
423
|
-
const formattedComments = "*\n" + comments.map(formatComment).join("\n").trim() + "\n";
|
|
424
|
-
addSyntheticLeadingComment(
|
|
425
|
-
node,
|
|
426
|
-
SyntaxKind.MultiLineCommentTrivia,
|
|
427
|
-
formattedComments,
|
|
428
|
-
true
|
|
429
|
-
);
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Checks if a schema represents a binary type.
|
|
433
|
-
*
|
|
434
|
-
* @param schema - The schema object to check.
|
|
435
|
-
* @returns true if the schema is a binary type, false otherwise.
|
|
436
|
-
*/
|
|
437
|
-
static isBinarySchema(schema) {
|
|
438
|
-
if (schema.type === "array") {
|
|
439
|
-
const arraySchema = schema;
|
|
440
|
-
return this.isBinarySchema(arraySchema.items);
|
|
441
|
-
}
|
|
442
|
-
const nonArraySchema = schema;
|
|
443
|
-
return nonArraySchema.format === "blob" /* blob */ || nonArraySchema.format === "binary" /* binary */ || nonArraySchema.type === "file" /* file */;
|
|
444
|
-
}
|
|
445
|
-
static toRequestBodyTypeNode(schema) {
|
|
446
|
-
return t.createParameterDeclaration(
|
|
447
|
-
void 0,
|
|
448
|
-
void 0,
|
|
449
|
-
t.createIdentifier("req"),
|
|
450
|
-
void 0,
|
|
451
|
-
this.toTypeNode(schema)
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
static toTypeNode(schema) {
|
|
455
|
-
const { type, ref } = schema;
|
|
456
|
-
if (ref) {
|
|
457
|
-
const identify = Base.ref2name(ref);
|
|
458
|
-
return t.createTypeReferenceNode(
|
|
459
|
-
t.createIdentifier(
|
|
460
|
-
identify === "unknown" ? identify : Base.upperCamelCase(identify)
|
|
461
|
-
)
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
switch (type) {
|
|
465
|
-
case "array" /* array */:
|
|
466
|
-
const { items } = schema;
|
|
467
|
-
return t.createArrayTypeNode(this.toTypeNode(items));
|
|
468
|
-
case "object" /* object */:
|
|
469
|
-
const propsCount = Object.keys(schema.properties ?? {}).length;
|
|
470
|
-
if (!schema.properties || propsCount === 0) {
|
|
471
|
-
return t.createTypeReferenceNode(t.createIdentifier("Record"), [
|
|
472
|
-
t.createToken(SyntaxKind.StringKeyword),
|
|
473
|
-
t.createToken(SyntaxKind.UnknownKeyword)
|
|
474
|
-
]);
|
|
475
|
-
}
|
|
476
|
-
const props = Object.keys(schema.properties);
|
|
477
|
-
return t.createTypeLiteralNode(
|
|
478
|
-
props.map((propKey) => {
|
|
479
|
-
const propSchema = schema.properties[propKey];
|
|
480
|
-
return t.createPropertySignature(
|
|
481
|
-
void 0,
|
|
482
|
-
t.createStringLiteral(propKey),
|
|
483
|
-
// When field is required, a refrence or binary value, don't add question mark.
|
|
484
|
-
schema.required || schema.ref || this.isBinarySchema(schema) ? void 0 : t.createToken(SyntaxKind.QuestionToken),
|
|
485
|
-
this.toTypeNode(propSchema)
|
|
486
|
-
);
|
|
487
|
-
})
|
|
488
|
-
);
|
|
489
|
-
case "integer" /* integer */:
|
|
490
|
-
case "number" /* number */:
|
|
491
|
-
if (schema.enum) {
|
|
492
|
-
return t.createUnionTypeNode(
|
|
493
|
-
schema.enum.map(
|
|
494
|
-
(e) => t.createLiteralTypeNode(t.createNumericLiteral(e))
|
|
495
|
-
)
|
|
496
|
-
);
|
|
497
|
-
}
|
|
498
|
-
return t.createToken(SyntaxKind.NumberKeyword);
|
|
499
|
-
// case NonArraySchemaType.string:
|
|
500
|
-
case "boolean" /* boolean */:
|
|
501
|
-
return t.createToken(SyntaxKind.BooleanKeyword);
|
|
502
|
-
case "file" /* file */:
|
|
503
|
-
return t.createTypeReferenceNode(t.createIdentifier("Blob"));
|
|
504
|
-
default:
|
|
505
|
-
const {
|
|
506
|
-
format: format2,
|
|
507
|
-
oneOf,
|
|
508
|
-
allOf,
|
|
509
|
-
anyOf,
|
|
510
|
-
type: type2,
|
|
511
|
-
enum: enum_
|
|
512
|
-
} = schema;
|
|
513
|
-
switch (format2) {
|
|
514
|
-
case "number" /* number */:
|
|
515
|
-
return t.createToken(SyntaxKind.NumberKeyword);
|
|
516
|
-
case "string" /* string */:
|
|
517
|
-
return t.createToken(SyntaxKind.StringKeyword);
|
|
518
|
-
case "boolean" /* boolean */:
|
|
519
|
-
return t.createToken(SyntaxKind.BooleanKeyword);
|
|
520
|
-
case "blob" /* blob */:
|
|
521
|
-
case "binary" /* binary */:
|
|
522
|
-
return t.createTypeReferenceNode(t.createIdentifier("Blob"));
|
|
523
|
-
default:
|
|
524
|
-
}
|
|
525
|
-
if (enum_) {
|
|
526
|
-
return t.createUnionTypeNode(
|
|
527
|
-
enum_.map(
|
|
528
|
-
(e) => t.createLiteralTypeNode(t.createStringLiteral(e))
|
|
529
|
-
)
|
|
530
|
-
);
|
|
531
|
-
}
|
|
532
|
-
if (type2 === "string" /* string */) {
|
|
533
|
-
return t.createToken(SyntaxKind.StringKeyword);
|
|
534
|
-
}
|
|
535
|
-
if (oneOf) {
|
|
536
|
-
return t.createUnionTypeNode(
|
|
537
|
-
oneOf.map((schema2) => this.toTypeNode(schema2))
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
if (anyOf) {
|
|
541
|
-
return t.createUnionTypeNode(
|
|
542
|
-
anyOf.map((schema2) => this.toTypeNode(schema2))
|
|
543
|
-
);
|
|
544
|
-
}
|
|
545
|
-
if (allOf) {
|
|
546
|
-
return t.createIntersectionTypeNode(
|
|
547
|
-
allOf.map((schema2) => this.toTypeNode(schema2))
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
if (type2 && typeof type2 === "string") {
|
|
551
|
-
return t.createTypeReferenceNode(
|
|
552
|
-
type2 !== "unknown" && type2 !== "null" ? t.createIdentifier(Base.upperCamelCase(type2)) : type2
|
|
553
|
-
);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
return t.createToken(SyntaxKind.UnknownKeyword);
|
|
557
|
-
}
|
|
558
|
-
static toDeclarationNodes(parameters) {
|
|
559
|
-
const objectElements = [];
|
|
560
|
-
const typeObjectElements = [];
|
|
561
|
-
const refParameters = [];
|
|
562
|
-
for (const parameter of parameters) {
|
|
563
|
-
if (parameter.ref) {
|
|
564
|
-
const refName = Base.ref2name(parameter.ref);
|
|
565
|
-
refParameters.push(
|
|
566
|
-
t.createParameterDeclaration(
|
|
567
|
-
void 0,
|
|
568
|
-
void 0,
|
|
569
|
-
t.createIdentifier(Base.camelCase(Base.normalize(refName))),
|
|
570
|
-
void 0,
|
|
571
|
-
t.createTypeReferenceNode(
|
|
572
|
-
t.createIdentifier(Base.upperCamelCase(Base.normalize(refName)))
|
|
573
|
-
),
|
|
574
|
-
void 0
|
|
575
|
-
)
|
|
576
|
-
);
|
|
577
|
-
} else {
|
|
578
|
-
const { name, schema, required } = parameter;
|
|
579
|
-
objectElements.push(
|
|
580
|
-
t.createBindingElement(
|
|
581
|
-
void 0,
|
|
582
|
-
void 0,
|
|
583
|
-
t.createIdentifier(Base.camelCase(Base.normalize(name)))
|
|
584
|
-
)
|
|
585
|
-
);
|
|
586
|
-
typeObjectElements.push(
|
|
587
|
-
t.createPropertySignature(
|
|
588
|
-
[],
|
|
589
|
-
t.createIdentifier(Base.camelCase(Base.normalize(name))),
|
|
590
|
-
required ? void 0 : t.createToken(SyntaxKind.QuestionToken),
|
|
591
|
-
!schema ? t.createToken(SyntaxKind.UnknownKeyword) : this.toTypeNode(schema)
|
|
592
|
-
)
|
|
593
|
-
);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
if (objectElements.length > 0) {
|
|
597
|
-
const objectParam = t.createParameterDeclaration(
|
|
598
|
-
void 0,
|
|
599
|
-
void 0,
|
|
600
|
-
t.createObjectBindingPattern(objectElements),
|
|
601
|
-
void 0,
|
|
602
|
-
t.createTypeLiteralNode(typeObjectElements),
|
|
603
|
-
void 0
|
|
604
|
-
);
|
|
605
|
-
return [objectParam, ...refParameters];
|
|
606
|
-
}
|
|
607
|
-
return refParameters;
|
|
608
|
-
}
|
|
609
|
-
static toFormDataStatement(parameters, requestBody) {
|
|
610
|
-
const statements = [];
|
|
611
|
-
const fdDeclaration = t.createVariableStatement(
|
|
612
|
-
void 0,
|
|
613
|
-
t.createVariableDeclarationList(
|
|
614
|
-
[
|
|
615
|
-
t.createVariableDeclaration(
|
|
616
|
-
t.createIdentifier("fd"),
|
|
617
|
-
void 0,
|
|
618
|
-
void 0,
|
|
619
|
-
t.createNewExpression(
|
|
620
|
-
t.createIdentifier("FormData"),
|
|
621
|
-
void 0,
|
|
622
|
-
[]
|
|
623
|
-
)
|
|
624
|
-
)
|
|
625
|
-
],
|
|
626
|
-
NodeFlags.Const
|
|
627
|
-
)
|
|
628
|
-
);
|
|
629
|
-
statements.push(fdDeclaration);
|
|
630
|
-
parameters.forEach((parameter) => {
|
|
631
|
-
statements.push(
|
|
632
|
-
t.createExpressionStatement(
|
|
633
|
-
t.createBinaryExpression(
|
|
634
|
-
t.createIdentifier(parameter.name),
|
|
635
|
-
t.createToken(SyntaxKind.AmpersandAmpersandToken),
|
|
636
|
-
t.createCallExpression(
|
|
637
|
-
t.createPropertyAccessExpression(
|
|
638
|
-
t.createIdentifier("fd"),
|
|
639
|
-
t.createIdentifier("append")
|
|
640
|
-
),
|
|
641
|
-
void 0,
|
|
642
|
-
[
|
|
643
|
-
t.createStringLiteral(parameter.name),
|
|
644
|
-
t.createIdentifier(parameter.name)
|
|
645
|
-
]
|
|
646
|
-
)
|
|
647
|
-
)
|
|
648
|
-
)
|
|
649
|
-
);
|
|
650
|
-
});
|
|
651
|
-
if (requestBody && requestBody.type === "object" && requestBody.properties && Object.keys(requestBody.properties).length !== 0) {
|
|
652
|
-
Object.keys(requestBody.properties).forEach((key) => {
|
|
653
|
-
const schemaByKey = requestBody.properties[key];
|
|
654
|
-
if (schemaByKey.type === "array" /* array */ && this.isBinarySchema(schemaByKey)) {
|
|
655
|
-
statements.push(
|
|
656
|
-
t.createForOfStatement(
|
|
657
|
-
void 0,
|
|
658
|
-
t.createVariableDeclarationList(
|
|
659
|
-
[t.createVariableDeclaration("file")],
|
|
660
|
-
NodeFlags.Const
|
|
661
|
-
),
|
|
662
|
-
t.createElementAccessExpression(
|
|
663
|
-
t.createIdentifier("req"),
|
|
664
|
-
t.createStringLiteral(key)
|
|
665
|
-
),
|
|
666
|
-
t.createBlock([
|
|
667
|
-
t.createExpressionStatement(
|
|
668
|
-
t.createCallExpression(
|
|
669
|
-
t.createPropertyAccessExpression(
|
|
670
|
-
t.createIdentifier("fd"),
|
|
671
|
-
t.createIdentifier("append")
|
|
672
|
-
),
|
|
673
|
-
[],
|
|
674
|
-
[
|
|
675
|
-
t.createStringLiteral(key),
|
|
676
|
-
t.createIdentifier("file"),
|
|
677
|
-
t.createPropertyAccessExpression(
|
|
678
|
-
t.createAsExpression(
|
|
679
|
-
t.createIdentifier("file"),
|
|
680
|
-
t.createTypeReferenceNode(
|
|
681
|
-
t.createIdentifier("File"),
|
|
682
|
-
void 0
|
|
683
|
-
)
|
|
684
|
-
),
|
|
685
|
-
t.createIdentifier("name")
|
|
686
|
-
)
|
|
687
|
-
]
|
|
688
|
-
)
|
|
689
|
-
)
|
|
690
|
-
])
|
|
691
|
-
)
|
|
692
|
-
);
|
|
693
|
-
} else {
|
|
694
|
-
if (schemaByKey.required) {
|
|
695
|
-
statements.push(
|
|
696
|
-
t.createExpressionStatement(
|
|
697
|
-
t.createCallExpression(
|
|
698
|
-
t.createPropertyAccessExpression(
|
|
699
|
-
t.createIdentifier("fd"),
|
|
700
|
-
t.createIdentifier("append")
|
|
701
|
-
),
|
|
702
|
-
void 0,
|
|
703
|
-
[
|
|
704
|
-
t.createStringLiteral(key),
|
|
705
|
-
schemaByKey.type === "string" ? t.createElementAccessExpression(
|
|
706
|
-
t.createIdentifier("req"),
|
|
707
|
-
t.createStringLiteral(key)
|
|
708
|
-
) : t.createCallExpression(
|
|
709
|
-
t.createIdentifier("String"),
|
|
710
|
-
void 0,
|
|
711
|
-
[
|
|
712
|
-
t.createElementAccessExpression(
|
|
713
|
-
t.createIdentifier("req"),
|
|
714
|
-
t.createStringLiteral(key)
|
|
715
|
-
)
|
|
716
|
-
]
|
|
717
|
-
)
|
|
718
|
-
]
|
|
719
|
-
)
|
|
720
|
-
)
|
|
721
|
-
);
|
|
722
|
-
} else {
|
|
723
|
-
statements.push(
|
|
724
|
-
t.createExpressionStatement(
|
|
725
|
-
t.createBinaryExpression(
|
|
726
|
-
t.createElementAccessExpression(
|
|
727
|
-
t.createIdentifier("req"),
|
|
728
|
-
t.createStringLiteral(key)
|
|
729
|
-
),
|
|
730
|
-
t.createToken(SyntaxKind.AmpersandAmpersandToken),
|
|
731
|
-
t.createCallExpression(
|
|
732
|
-
t.createPropertyAccessExpression(
|
|
733
|
-
t.createIdentifier("fd"),
|
|
734
|
-
t.createIdentifier("append")
|
|
735
|
-
),
|
|
736
|
-
void 0,
|
|
737
|
-
[
|
|
738
|
-
t.createStringLiteral(key),
|
|
739
|
-
schemaByKey.type === "string" ? t.createElementAccessExpression(
|
|
740
|
-
t.createIdentifier("req"),
|
|
741
|
-
t.createStringLiteral(key)
|
|
742
|
-
) : t.createCallExpression(
|
|
743
|
-
t.createIdentifier("String"),
|
|
744
|
-
void 0,
|
|
745
|
-
[
|
|
746
|
-
t.createElementAccessExpression(
|
|
747
|
-
t.createIdentifier("req"),
|
|
748
|
-
t.createStringLiteral(key)
|
|
749
|
-
)
|
|
750
|
-
]
|
|
751
|
-
)
|
|
752
|
-
]
|
|
753
|
-
)
|
|
754
|
-
)
|
|
755
|
-
)
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
return statements;
|
|
762
|
-
}
|
|
763
|
-
static bodyBlock(uri, method, parameters, requestBody, response, adapter) {
|
|
764
|
-
const isFormDataRequest = requestBody && ["multipart/form-data", "application/x-www-form-urlencoded"].includes(
|
|
765
|
-
requestBody.type
|
|
766
|
-
);
|
|
767
|
-
const shouldParseResponseToJSON = "application/json" === response?.type;
|
|
768
|
-
const isRequestBodyBinary = requestBody?.schema && requestBody.schema.type === "array" /* array */ && this.isBinarySchema(requestBody.schema);
|
|
769
|
-
const parametersShouldPutInFormData = parameters.filter(
|
|
770
|
-
(p) => p.in === "formData" /* formData */ || p.schema && this.isBinarySchema(p.schema)
|
|
771
|
-
);
|
|
772
|
-
const parametersShouldNotPutInFormData = parameters.filter(
|
|
773
|
-
(p) => !parametersShouldPutInFormData.includes(p)
|
|
774
|
-
);
|
|
775
|
-
const isRequestBodyContainsBinary = requestBody?.schema && "properties" in requestBody.schema && Object.values(requestBody.schema?.properties ?? {}).some(
|
|
776
|
-
(p) => this.isBinarySchema(p)
|
|
777
|
-
);
|
|
778
|
-
const hasBinaryInParameters = parameters.some(
|
|
779
|
-
(p) => p?.schema && this.isBinarySchema(p.schema)
|
|
780
|
-
);
|
|
781
|
-
const shouldPutParametersOrBodyInFormData = isFormDataRequest || isRequestBodyBinary || hasBinaryInParameters || isRequestBodyContainsBinary || parametersShouldPutInFormData.length > 0;
|
|
782
|
-
return t.createBlock([
|
|
783
|
-
...shouldPutParametersOrBodyInFormData ? this.toFormDataStatement(
|
|
784
|
-
parametersShouldPutInFormData,
|
|
785
|
-
requestBody?.schema
|
|
786
|
-
) : [],
|
|
787
|
-
...adapter.client(
|
|
788
|
-
uri,
|
|
789
|
-
method,
|
|
790
|
-
parametersShouldNotPutInFormData,
|
|
791
|
-
requestBody,
|
|
792
|
-
response,
|
|
793
|
-
adapter,
|
|
794
|
-
shouldPutParametersOrBodyInFormData,
|
|
795
|
-
shouldParseResponseToJSON
|
|
796
|
-
)
|
|
797
|
-
]);
|
|
798
|
-
}
|
|
799
|
-
static schemaToStatemets(parsedDoc, adaptor, options) {
|
|
800
|
-
const statements = [];
|
|
801
|
-
const { apis, schemas = {}, enums } = parsedDoc;
|
|
802
|
-
const enumNames = [];
|
|
803
|
-
for (const enumObject of enums) {
|
|
804
|
-
enumNames.push(Base.capitalize(enumObject.name));
|
|
805
|
-
statements.push(
|
|
806
|
-
t.createEnumDeclaration(
|
|
807
|
-
[t.createToken(SyntaxKind.ExportKeyword)],
|
|
808
|
-
t.createIdentifier(Base.upperCamelCase(enumObject.name)),
|
|
809
|
-
enumObject.enum.map((member) => {
|
|
810
|
-
return t.createEnumMember(
|
|
811
|
-
t.createStringLiteral(
|
|
812
|
-
typeof member === "string" ? member : `${member}_`
|
|
813
|
-
),
|
|
814
|
-
typeof member === "string" ? t.createStringLiteral(member) : t.createNumericLiteral(member)
|
|
815
|
-
);
|
|
816
|
-
})
|
|
817
|
-
)
|
|
818
|
-
);
|
|
819
|
-
}
|
|
820
|
-
for (const schemaKey in schemas) {
|
|
821
|
-
if (Object.hasOwnProperty.call(schemas, schemaKey) && !enumNames.includes(Base.upperCamelCase(schemaKey))) {
|
|
822
|
-
const schema = schemas[schemaKey];
|
|
823
|
-
statements.push(
|
|
824
|
-
t.createTypeAliasDeclaration(
|
|
825
|
-
[t.createModifier(SyntaxKind.ExportKeyword)],
|
|
826
|
-
t.createIdentifier(Base.upperCamelCase(schemaKey)),
|
|
827
|
-
void 0,
|
|
828
|
-
this.toTypeNode(schema)
|
|
829
|
-
)
|
|
830
|
-
);
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
for (const uri in apis) {
|
|
834
|
-
const operations = apis[uri];
|
|
835
|
-
for (const operation of operations) {
|
|
836
|
-
const {
|
|
837
|
-
method,
|
|
838
|
-
operationId,
|
|
839
|
-
requestBody = [],
|
|
840
|
-
responses = [],
|
|
841
|
-
summary,
|
|
842
|
-
deprecated,
|
|
843
|
-
description
|
|
844
|
-
} = operation;
|
|
845
|
-
let { parameters = [] } = operation;
|
|
846
|
-
parameters = parameters.filter((p) => p.in !== "cookie");
|
|
847
|
-
if (requestBody.length === 0) {
|
|
848
|
-
requestBody.push({ type: "application/json" /* JSON */ });
|
|
849
|
-
}
|
|
850
|
-
const shouldAddExtraMethodNameSuffix = requestBody.length > 1;
|
|
851
|
-
for (const req of requestBody) {
|
|
852
|
-
const statement = t.createFunctionDeclaration(
|
|
853
|
-
[
|
|
854
|
-
t.createModifier(SyntaxKind.ExportKeyword),
|
|
855
|
-
t.createModifier(SyntaxKind.AsyncKeyword)
|
|
856
|
-
],
|
|
857
|
-
void 0,
|
|
858
|
-
Base.pathToFnName(uri, method, operationId) + (shouldAddExtraMethodNameSuffix ? Base.capitalize(req.type.split("/")[1]) : ""),
|
|
859
|
-
void 0,
|
|
860
|
-
[
|
|
861
|
-
...parameters.length > 0 ? _Generator.toDeclarationNodes(parameters) : [],
|
|
862
|
-
...req?.schema ? [_Generator.toRequestBodyTypeNode(req.schema)] : []
|
|
863
|
-
].filter(Boolean),
|
|
864
|
-
void 0,
|
|
865
|
-
this.bodyBlock(
|
|
866
|
-
options.baseURL + uri,
|
|
867
|
-
method,
|
|
868
|
-
parameters,
|
|
869
|
-
req,
|
|
870
|
-
responses[0],
|
|
871
|
-
adaptor
|
|
872
|
-
)
|
|
873
|
-
);
|
|
874
|
-
this.addComments(
|
|
875
|
-
statement,
|
|
876
|
-
[
|
|
877
|
-
description && {
|
|
878
|
-
comment: description
|
|
879
|
-
},
|
|
880
|
-
summary && {
|
|
881
|
-
comment: summary
|
|
882
|
-
},
|
|
883
|
-
deprecated && {
|
|
884
|
-
tag: "deprecated"
|
|
885
|
-
}
|
|
886
|
-
].filter(Boolean)
|
|
887
|
-
);
|
|
888
|
-
statements.push(statement);
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
return statements;
|
|
893
|
-
}
|
|
894
|
-
static async prettier(code) {
|
|
895
|
-
return await format(code, {
|
|
896
|
-
parser: "typescript"
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
|
-
static async genCode(schema, initOptions, adaptor) {
|
|
900
|
-
const { importClientSource } = initOptions;
|
|
901
|
-
const statements = this.schemaToStatemets(schema, adaptor, {
|
|
902
|
-
baseURL: initOptions.baseURL ?? ""
|
|
903
|
-
});
|
|
904
|
-
let code = this.toCode(statements);
|
|
905
|
-
if (importClientSource) {
|
|
906
|
-
code = importClientSource + "\n\n" + code;
|
|
907
|
-
}
|
|
908
|
-
return await this.prettier(code);
|
|
909
|
-
}
|
|
910
|
-
};
|
|
911
|
-
|
|
912
|
-
// src/core/client/axios.ts
|
|
913
|
-
import { factory as t2 } from "typescript";
|
|
914
|
-
var AxiosAdapter = class extends Adapter {
|
|
915
|
-
/**
|
|
916
|
-
* Name of the field used to specify the HTTP method in the request configuration.
|
|
917
|
-
*/
|
|
918
|
-
methodFieldName = "method";
|
|
919
|
-
/**
|
|
920
|
-
* Name of the field used to specify the request body (data) in the request configuration.
|
|
921
|
-
*/
|
|
922
|
-
bodyFieldName = "data";
|
|
923
|
-
/**
|
|
924
|
-
* Name of the field used to specify the request headers in the request configuration.
|
|
925
|
-
*/
|
|
926
|
-
headersFieldName = "headers";
|
|
927
|
-
/**
|
|
928
|
-
* Name of the field used to specify the query parameters in the request configuration.
|
|
929
|
-
*/
|
|
930
|
-
queryFieldName = "params";
|
|
931
|
-
/**
|
|
932
|
-
* The name of the client this adapter is configured for, which is 'axios' in this case.
|
|
933
|
-
*/
|
|
934
|
-
name = "axios";
|
|
935
|
-
/**
|
|
936
|
-
* Method that should generate and return the client-specific configuration statements.
|
|
937
|
-
*
|
|
938
|
-
* @returns {Statement[]} An array of TypeScript statements that define the client configuration.
|
|
939
|
-
*
|
|
940
|
-
* @throws {Error} Indicates that the method is not yet implemented and needs to be filled in.
|
|
941
|
-
*/
|
|
942
|
-
client(uri, method, parameters, requestBody, response, adapter, shouldUseFormData) {
|
|
943
|
-
const statements = [];
|
|
944
|
-
const inBody = parameters.filter((p) => !p.in || p.in === "body");
|
|
945
|
-
const inHeader = parameters.filter((p) => p.in === "header");
|
|
946
|
-
const toLiterlExpression = () => {
|
|
947
|
-
return t2.createObjectLiteralExpression(
|
|
948
|
-
[
|
|
949
|
-
// Set the HTTP method
|
|
950
|
-
t2.createPropertyAssignment(
|
|
951
|
-
t2.createIdentifier(adapter.methodFieldName),
|
|
952
|
-
t2.createStringLiteral(method.toUpperCase())
|
|
953
|
-
)
|
|
954
|
-
].concat(
|
|
955
|
-
// Add headers if there are any
|
|
956
|
-
inHeader.length > 0 ? t2.createPropertyAssignment(
|
|
957
|
-
t2.createIdentifier(adapter.headersFieldName),
|
|
958
|
-
t2.createObjectLiteralExpression(
|
|
959
|
-
inHeader.map(
|
|
960
|
-
(p) => t2.createPropertyAssignment(
|
|
961
|
-
t2.createStringLiteral(p.name),
|
|
962
|
-
t2.createCallExpression(
|
|
963
|
-
t2.createIdentifier("encodeURIComponent"),
|
|
964
|
-
void 0,
|
|
965
|
-
[
|
|
966
|
-
t2.createCallExpression(
|
|
967
|
-
t2.createIdentifier("String"),
|
|
968
|
-
void 0,
|
|
969
|
-
[
|
|
970
|
-
t2.createIdentifier(
|
|
971
|
-
Base.camelCase(Base.normalize(p.name))
|
|
972
|
-
)
|
|
973
|
-
]
|
|
974
|
-
)
|
|
975
|
-
]
|
|
976
|
-
)
|
|
977
|
-
)
|
|
978
|
-
)
|
|
979
|
-
)
|
|
980
|
-
) : []
|
|
981
|
-
).concat(
|
|
982
|
-
shouldUseFormData || inBody.length > 0 || requestBody?.schema ? t2.createPropertyAssignment(
|
|
983
|
-
t2.createIdentifier(adapter.bodyFieldName),
|
|
984
|
-
shouldUseFormData ? t2.createIdentifier("fd") : inBody.length > 0 || requestBody?.schema && !Generator.isBinarySchema(requestBody.schema) ? t2.createIdentifier("req") : t2.createIdentifier("req")
|
|
985
|
-
) : []
|
|
986
|
-
),
|
|
987
|
-
true
|
|
988
|
-
);
|
|
989
|
-
};
|
|
990
|
-
statements.push(
|
|
991
|
-
t2.createReturnStatement(
|
|
992
|
-
t2.createCallExpression(
|
|
993
|
-
t2.createIdentifier(adapter.name),
|
|
994
|
-
response?.schema ? [
|
|
995
|
-
Generator.toTypeNode(
|
|
996
|
-
response.schema
|
|
997
|
-
)
|
|
998
|
-
] : void 0,
|
|
999
|
-
[Generator.toUrlTemplate(uri, parameters), toLiterlExpression()]
|
|
1000
|
-
)
|
|
1001
|
-
)
|
|
1002
|
-
);
|
|
1003
|
-
return statements;
|
|
1004
|
-
}
|
|
1005
|
-
};
|
|
1006
|
-
|
|
1007
|
-
// src/core/client/fetch.ts
|
|
1008
|
-
import { factory as t3, SyntaxKind as SyntaxKind2 } from "typescript";
|
|
1009
|
-
var FetchAdapter = class extends Adapter {
|
|
1010
|
-
methodFieldName = "method";
|
|
1011
|
-
bodyFieldName = "body";
|
|
1012
|
-
headersFieldName = "headers";
|
|
1013
|
-
queryFieldName = "";
|
|
1014
|
-
name = "fetch";
|
|
1015
|
-
/**
|
|
1016
|
-
* Generates client code for making API requests using the Fetch API.
|
|
1017
|
-
* @param uri - The API endpoint URI
|
|
1018
|
-
* @param method - The HTTP method (GET, POST, etc.)
|
|
1019
|
-
* @param parameters - Array of parameters to include in the request
|
|
1020
|
-
* @param requestBody - The request body media type definition
|
|
1021
|
-
* @param response - The response media type definition
|
|
1022
|
-
* @param adapter - The adapter instance
|
|
1023
|
-
* @param shouldUseFormData - Flag to use FormData for the request body
|
|
1024
|
-
* @param shouldUseJSONResponse - Flag to use JSON parsing for the response
|
|
1025
|
-
* @return - An array of generated TypeScript statements
|
|
1026
|
-
*/
|
|
1027
|
-
client(uri, method, parameters, requestBody, response, adapter, shouldUseFormData, shouldUseJSONResponse) {
|
|
1028
|
-
const statements = [];
|
|
1029
|
-
const inBody = parameters.filter((p) => !p.in || p.in === "body");
|
|
1030
|
-
const inHeader = parameters.filter((p) => p.in === "header");
|
|
1031
|
-
const toLiterlExpression = () => {
|
|
1032
|
-
return t3.createObjectLiteralExpression(
|
|
1033
|
-
[
|
|
1034
|
-
// Set the HTTP method
|
|
1035
|
-
t3.createPropertyAssignment(
|
|
1036
|
-
t3.createIdentifier(adapter.methodFieldName),
|
|
1037
|
-
t3.createStringLiteral(method.toUpperCase())
|
|
1038
|
-
)
|
|
1039
|
-
].concat(
|
|
1040
|
-
// Add headers if there are any
|
|
1041
|
-
inHeader.length > 0 ? t3.createPropertyAssignment(
|
|
1042
|
-
t3.createIdentifier(adapter.headersFieldName),
|
|
1043
|
-
t3.createObjectLiteralExpression(
|
|
1044
|
-
inHeader.map(
|
|
1045
|
-
(p) => t3.createPropertyAssignment(
|
|
1046
|
-
t3.createStringLiteral(p.name),
|
|
1047
|
-
t3.createCallExpression(
|
|
1048
|
-
t3.createIdentifier("encodeURIComponent"),
|
|
1049
|
-
void 0,
|
|
1050
|
-
[
|
|
1051
|
-
t3.createCallExpression(
|
|
1052
|
-
t3.createIdentifier("String"),
|
|
1053
|
-
void 0,
|
|
1054
|
-
[
|
|
1055
|
-
t3.createIdentifier(
|
|
1056
|
-
Base.camelCase(Base.normalize(p.name))
|
|
1057
|
-
)
|
|
1058
|
-
]
|
|
1059
|
-
)
|
|
1060
|
-
]
|
|
1061
|
-
)
|
|
1062
|
-
)
|
|
1063
|
-
)
|
|
1064
|
-
)
|
|
1065
|
-
) : []
|
|
1066
|
-
).concat(
|
|
1067
|
-
shouldUseFormData || inBody.length > 0 || requestBody?.schema ? t3.createPropertyAssignment(
|
|
1068
|
-
t3.createIdentifier(adapter.bodyFieldName),
|
|
1069
|
-
shouldUseFormData ? t3.createIdentifier("fd") : inBody.length > 0 || requestBody?.schema && !Generator.isBinarySchema(requestBody.schema) ? t3.createCallExpression(
|
|
1070
|
-
t3.createPropertyAccessExpression(
|
|
1071
|
-
t3.createIdentifier("JSON"),
|
|
1072
|
-
t3.createIdentifier("stringify")
|
|
1073
|
-
),
|
|
1074
|
-
[],
|
|
1075
|
-
[
|
|
1076
|
-
requestBody ? t3.createIdentifier("req") : t3.createObjectLiteralExpression(
|
|
1077
|
-
inBody.map(
|
|
1078
|
-
(b) => t3.createShorthandPropertyAssignment(
|
|
1079
|
-
t3.createIdentifier(b.name)
|
|
1080
|
-
)
|
|
1081
|
-
),
|
|
1082
|
-
true
|
|
1083
|
-
)
|
|
1084
|
-
]
|
|
1085
|
-
) : (
|
|
1086
|
-
// One File parameter
|
|
1087
|
-
t3.createIdentifier("req")
|
|
1088
|
-
)
|
|
1089
|
-
) : []
|
|
1090
|
-
),
|
|
1091
|
-
true
|
|
1092
|
-
);
|
|
1093
|
-
};
|
|
1094
|
-
statements.push(
|
|
1095
|
-
t3.createReturnStatement(
|
|
1096
|
-
shouldUseJSONResponse ? (
|
|
1097
|
-
// Handle JSON response with proper type checking
|
|
1098
|
-
t3.createCallExpression(
|
|
1099
|
-
t3.createPropertyAccessExpression(
|
|
1100
|
-
t3.createCallExpression(
|
|
1101
|
-
t3.createIdentifier(adapter.name),
|
|
1102
|
-
void 0,
|
|
1103
|
-
[
|
|
1104
|
-
Generator.toUrlTemplate(uri, parameters),
|
|
1105
|
-
toLiterlExpression()
|
|
1106
|
-
]
|
|
1107
|
-
),
|
|
1108
|
-
t3.createIdentifier("then")
|
|
1109
|
-
),
|
|
1110
|
-
void 0,
|
|
1111
|
-
[
|
|
1112
|
-
t3.createArrowFunction(
|
|
1113
|
-
[t3.createModifier(SyntaxKind2.AsyncKeyword)],
|
|
1114
|
-
[],
|
|
1115
|
-
[
|
|
1116
|
-
t3.createParameterDeclaration(
|
|
1117
|
-
void 0,
|
|
1118
|
-
void 0,
|
|
1119
|
-
t3.createIdentifier("response")
|
|
1120
|
-
)
|
|
1121
|
-
],
|
|
1122
|
-
void 0,
|
|
1123
|
-
t3.createToken(SyntaxKind2.EqualsGreaterThanToken),
|
|
1124
|
-
response?.schema ? t3.createAsExpression(
|
|
1125
|
-
t3.createParenthesizedExpression(
|
|
1126
|
-
t3.createAwaitExpression(
|
|
1127
|
-
t3.createCallExpression(
|
|
1128
|
-
t3.createPropertyAccessExpression(
|
|
1129
|
-
t3.createIdentifier("response"),
|
|
1130
|
-
t3.createIdentifier("json")
|
|
1131
|
-
),
|
|
1132
|
-
void 0,
|
|
1133
|
-
[]
|
|
1134
|
-
)
|
|
1135
|
-
)
|
|
1136
|
-
),
|
|
1137
|
-
response?.schema ? Generator.toTypeNode(response.schema) : t3.createToken(SyntaxKind2.UnknownKeyword)
|
|
1138
|
-
) : t3.createParenthesizedExpression(
|
|
1139
|
-
t3.createAwaitExpression(
|
|
1140
|
-
t3.createCallExpression(
|
|
1141
|
-
t3.createPropertyAccessExpression(
|
|
1142
|
-
t3.createIdentifier("response"),
|
|
1143
|
-
t3.createIdentifier("json")
|
|
1144
|
-
),
|
|
1145
|
-
void 0,
|
|
1146
|
-
[]
|
|
1147
|
-
)
|
|
1148
|
-
)
|
|
1149
|
-
)
|
|
1150
|
-
)
|
|
1151
|
-
]
|
|
1152
|
-
)
|
|
1153
|
-
) : (
|
|
1154
|
-
// Simple fetch call without JSON parsing
|
|
1155
|
-
t3.createCallExpression(
|
|
1156
|
-
t3.createIdentifier(adapter.name),
|
|
1157
|
-
void 0,
|
|
1158
|
-
[Generator.toUrlTemplate(uri, parameters), toLiterlExpression()]
|
|
1159
|
-
)
|
|
1160
|
-
)
|
|
1161
|
-
)
|
|
1162
|
-
);
|
|
1163
|
-
return statements;
|
|
1164
|
-
}
|
|
1165
|
-
};
|
|
1166
|
-
|
|
1167
|
-
// src/openapi/index.ts
|
|
1168
|
-
import { createScopedLogger } from "@moccona/logger";
|
|
1169
|
-
|
|
1170
|
-
// src/openapi/V2.ts
|
|
1171
|
-
var V2 = class {
|
|
1172
|
-
doc;
|
|
1173
|
-
constructor(doc) {
|
|
1174
|
-
this.doc = doc;
|
|
1175
|
-
}
|
|
1176
|
-
/**
|
|
1177
|
-
* Is array schema.
|
|
1178
|
-
*/
|
|
1179
|
-
isOpenAPIArraySchema(schema) {
|
|
1180
|
-
return typeof schema === "object" && schema.type === "array";
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
* OpenAPI schema to base schema.
|
|
1184
|
-
*/
|
|
1185
|
-
getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
|
|
1186
|
-
let refName = "";
|
|
1187
|
-
if (Base.isRef(schema)) {
|
|
1188
|
-
refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
|
|
1189
|
-
if (reserveRef) {
|
|
1190
|
-
return {
|
|
1191
|
-
type: upLevelSchemaKey + refName
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
if (!this.doc.definitions) {
|
|
1195
|
-
this.doc.definitions = {};
|
|
1196
|
-
}
|
|
1197
|
-
schema = this.doc.definitions[Base.ref2name(schema.$ref, this.doc)];
|
|
1198
|
-
}
|
|
1199
|
-
return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Transform all OpenAPI schema to Base Schema
|
|
1203
|
-
*/
|
|
1204
|
-
toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
|
|
1205
|
-
if (!schema) {
|
|
1206
|
-
return {
|
|
1207
|
-
type: "unknown"
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
if (Base.isRef(schema)) {
|
|
1211
|
-
return this.getSchemaByRef(schema, true);
|
|
1212
|
-
}
|
|
1213
|
-
if (this.isOpenAPIArraySchema(schema)) {
|
|
1214
|
-
const { type, description, items, required } = schema;
|
|
1215
|
-
return {
|
|
1216
|
-
type,
|
|
1217
|
-
required: !!required,
|
|
1218
|
-
description,
|
|
1219
|
-
items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
|
|
1220
|
-
};
|
|
1221
|
-
} else {
|
|
1222
|
-
const {
|
|
1223
|
-
required = [],
|
|
1224
|
-
allOf,
|
|
1225
|
-
anyOf,
|
|
1226
|
-
description,
|
|
1227
|
-
enum: enum_,
|
|
1228
|
-
format: format2,
|
|
1229
|
-
oneOf,
|
|
1230
|
-
properties = {}
|
|
1231
|
-
} = schema;
|
|
1232
|
-
let { type } = schema;
|
|
1233
|
-
if (enum_ && type !== "boolean") {
|
|
1234
|
-
const name = Base.upperCamelCase(upLevelSchemaKey) + Base.upperCamelCase(schemaKey);
|
|
1235
|
-
const enumObject = {
|
|
1236
|
-
name,
|
|
1237
|
-
enum: [...new Set(enum_)]
|
|
1238
|
-
};
|
|
1239
|
-
const sameObject = Base.findSameSchema(enumObject, enums);
|
|
1240
|
-
if (!sameObject && Base.isValidEnumType(schema)) {
|
|
1241
|
-
enums.push(enumObject);
|
|
1242
|
-
}
|
|
1243
|
-
return {
|
|
1244
|
-
type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
|
|
1245
|
-
required,
|
|
1246
|
-
description
|
|
1247
|
-
};
|
|
1248
|
-
}
|
|
1249
|
-
if (type === void 0 && Object.keys(properties).length > 0) {
|
|
1250
|
-
type = "object" /* object */;
|
|
1251
|
-
}
|
|
1252
|
-
return {
|
|
1253
|
-
type,
|
|
1254
|
-
required,
|
|
1255
|
-
description,
|
|
1256
|
-
enum: enum_,
|
|
1257
|
-
format: format2,
|
|
1258
|
-
allOf: allOf?.map(
|
|
1259
|
-
(s) => Base.isRef(s) ? {
|
|
1260
|
-
...s,
|
|
1261
|
-
ref: s.$ref,
|
|
1262
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
1263
|
-
} : this.toBaseSchema(s, enums)
|
|
1264
|
-
),
|
|
1265
|
-
anyOf: anyOf?.map(
|
|
1266
|
-
(s) => Base.isRef(s) ? {
|
|
1267
|
-
...s,
|
|
1268
|
-
ref: s.$ref,
|
|
1269
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
1270
|
-
} : this.toBaseSchema(s, enums)
|
|
1271
|
-
),
|
|
1272
|
-
oneOf: oneOf?.map(
|
|
1273
|
-
(s) => Base.isRef(s) ? {
|
|
1274
|
-
...s,
|
|
1275
|
-
ref: s.$ref,
|
|
1276
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
1277
|
-
} : this.toBaseSchema(s, enums)
|
|
1278
|
-
),
|
|
1279
|
-
properties: Object.keys(properties).reduce((acc, p) => {
|
|
1280
|
-
const propSchema = properties[p];
|
|
1281
|
-
return {
|
|
1282
|
-
...acc,
|
|
1283
|
-
[p]: Base.isRef(propSchema) ? {
|
|
1284
|
-
type: Base.upperCamelCase(
|
|
1285
|
-
Base.ref2name(propSchema.$ref, this.doc)
|
|
1286
|
-
)
|
|
1287
|
-
} : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
|
|
1288
|
-
};
|
|
1289
|
-
}, {})
|
|
1290
|
-
};
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
/**
|
|
1294
|
-
* OpenAPI parameter to base parameter.
|
|
1295
|
-
*/
|
|
1296
|
-
getParameterByRef(parameter, enums = [], upLevelSchemaKey = "") {
|
|
1297
|
-
if (Base.isRef(parameter)) {
|
|
1298
|
-
parameter = this.doc.parameters[Base.ref2name(parameter.$ref, this.doc)];
|
|
1299
|
-
}
|
|
1300
|
-
const {
|
|
1301
|
-
name,
|
|
1302
|
-
required,
|
|
1303
|
-
description,
|
|
1304
|
-
type,
|
|
1305
|
-
items,
|
|
1306
|
-
enum: enum_,
|
|
1307
|
-
properties,
|
|
1308
|
-
schema
|
|
1309
|
-
} = parameter;
|
|
1310
|
-
if (enum_) {
|
|
1311
|
-
const type2 = Base.upperCamelCase(upLevelSchemaKey) + Base.upperCamelCase(name);
|
|
1312
|
-
const enumSchema = {
|
|
1313
|
-
name: type2,
|
|
1314
|
-
enum: [...new Set(enum_)]
|
|
1315
|
-
};
|
|
1316
|
-
const sameEnum = Base.findSameSchema(enumSchema, enums);
|
|
1317
|
-
if (!sameEnum && Base.isValidEnumType({ type: type2, enum: enums })) {
|
|
1318
|
-
enums.push(enumSchema);
|
|
1319
|
-
}
|
|
1320
|
-
return {
|
|
1321
|
-
name,
|
|
1322
|
-
required,
|
|
1323
|
-
description,
|
|
1324
|
-
in: parameter.in,
|
|
1325
|
-
schema: {
|
|
1326
|
-
type: sameEnum?.name ?? type2
|
|
1327
|
-
}
|
|
1328
|
-
};
|
|
1329
|
-
}
|
|
1330
|
-
if (items) {
|
|
1331
|
-
return {
|
|
1332
|
-
name,
|
|
1333
|
-
required,
|
|
1334
|
-
description,
|
|
1335
|
-
in: parameter.in,
|
|
1336
|
-
schema: {
|
|
1337
|
-
type,
|
|
1338
|
-
items
|
|
1339
|
-
}
|
|
1340
|
-
};
|
|
1341
|
-
}
|
|
1342
|
-
if (schema && Base.isRef(schema)) {
|
|
1343
|
-
return {
|
|
1344
|
-
name,
|
|
1345
|
-
required,
|
|
1346
|
-
description,
|
|
1347
|
-
in: parameter.in,
|
|
1348
|
-
schema: {
|
|
1349
|
-
type: Base.upperCamelCase(Base.ref2name(schema.$ref))
|
|
1350
|
-
}
|
|
1351
|
-
};
|
|
1352
|
-
}
|
|
1353
|
-
return {
|
|
1354
|
-
name,
|
|
1355
|
-
required,
|
|
1356
|
-
description,
|
|
1357
|
-
in: parameter.in,
|
|
1358
|
-
schema: {
|
|
1359
|
-
type,
|
|
1360
|
-
properties
|
|
1361
|
-
}
|
|
1362
|
-
};
|
|
1363
|
-
}
|
|
1364
|
-
/**
|
|
1365
|
-
* OpenAPI schema to base response
|
|
1366
|
-
*/
|
|
1367
|
-
getResponseByRef(schema) {
|
|
1368
|
-
if (Base.isRef(schema)) {
|
|
1369
|
-
schema = this.doc.responses[Base.ref2name(schema.$ref, this.doc)];
|
|
1370
|
-
}
|
|
1371
|
-
const { schema: responseSchema } = schema;
|
|
1372
|
-
return [
|
|
1373
|
-
{
|
|
1374
|
-
type: "application/json" /* JSON */,
|
|
1375
|
-
schema: responseSchema && this.getSchemaByRef(responseSchema, true)
|
|
1376
|
-
}
|
|
1377
|
-
];
|
|
1378
|
-
}
|
|
1379
|
-
init() {
|
|
1380
|
-
const { definitions = {}, responses = {}, paths = {} } = this.doc;
|
|
1381
|
-
const enums = [];
|
|
1382
|
-
const definitions_ = Object.keys(definitions).reduce((acc, key) => {
|
|
1383
|
-
const schema = definitions[key];
|
|
1384
|
-
return {
|
|
1385
|
-
...acc,
|
|
1386
|
-
[key]: this.getSchemaByRef(schema, false, enums, key)
|
|
1387
|
-
};
|
|
1388
|
-
}, {});
|
|
1389
|
-
const responses_ = Object.keys(responses).reduce((acc, key) => {
|
|
1390
|
-
const response = responses[key];
|
|
1391
|
-
return {
|
|
1392
|
-
...acc,
|
|
1393
|
-
[key]: this.getResponseByRef(response)
|
|
1394
|
-
};
|
|
1395
|
-
}, {});
|
|
1396
|
-
const apis = Object.keys(paths).reduce((acc, path) => {
|
|
1397
|
-
const pathObject = paths[path] ?? {};
|
|
1398
|
-
const { $ref } = pathObject;
|
|
1399
|
-
const methodApis = [];
|
|
1400
|
-
if ($ref) {
|
|
1401
|
-
} else {
|
|
1402
|
-
const { parameters = [] } = pathObject;
|
|
1403
|
-
Object.values(HttpMethods).forEach((method) => {
|
|
1404
|
-
const methodObject = pathObject[method];
|
|
1405
|
-
if (methodObject) {
|
|
1406
|
-
const {
|
|
1407
|
-
deprecated,
|
|
1408
|
-
operationId,
|
|
1409
|
-
summary: summary_,
|
|
1410
|
-
description: description_,
|
|
1411
|
-
responses: responses2 = {}
|
|
1412
|
-
} = methodObject;
|
|
1413
|
-
const { parameters: parameters_ = [] } = methodObject;
|
|
1414
|
-
const baseParameters = [...parameters, ...parameters_].map(
|
|
1415
|
-
(parameter) => this.getParameterByRef(parameter, enums)
|
|
1416
|
-
);
|
|
1417
|
-
const uniqueParameterName = [
|
|
1418
|
-
...new Set(baseParameters.map((p) => p.name))
|
|
1419
|
-
];
|
|
1420
|
-
if (Object.keys(responses2).length === 0) {
|
|
1421
|
-
Object.assign(responses2, {
|
|
1422
|
-
200: {
|
|
1423
|
-
description: "Successful response"
|
|
1424
|
-
}
|
|
1425
|
-
});
|
|
1426
|
-
}
|
|
1427
|
-
const inBody = baseParameters.filter(
|
|
1428
|
-
(p) => p.in === "body" || p.in === "formData"
|
|
1429
|
-
);
|
|
1430
|
-
const notInBody = baseParameters.filter(
|
|
1431
|
-
(p) => p.in !== "body" && p.in !== "formData"
|
|
1432
|
-
);
|
|
1433
|
-
const httpCodes = Object.keys(responses2);
|
|
1434
|
-
for (const code of httpCodes) {
|
|
1435
|
-
if (code in responses2) {
|
|
1436
|
-
const response = responses2[code];
|
|
1437
|
-
const responseSchema = this.getResponseByRef(response);
|
|
1438
|
-
const inBodyOnlyHasBody = inBody && inBody.length === 1 && inBody[0].in === "body" && inBody[0].name === "body";
|
|
1439
|
-
methodApis.push({
|
|
1440
|
-
method,
|
|
1441
|
-
operationId,
|
|
1442
|
-
summary: summary_,
|
|
1443
|
-
deprecated,
|
|
1444
|
-
description: description_,
|
|
1445
|
-
parameters: uniqueParameterName.map((name) => notInBody.find((p) => p.name === name)).filter(Boolean),
|
|
1446
|
-
responses: responseSchema,
|
|
1447
|
-
requestBody: inBody.length > 0 ? inBodyOnlyHasBody ? [
|
|
1448
|
-
{
|
|
1449
|
-
type: "application/json" /* JSON */,
|
|
1450
|
-
schema: inBody[0].schema
|
|
1451
|
-
}
|
|
1452
|
-
] : [
|
|
1453
|
-
{
|
|
1454
|
-
type: "application/json" /* JSON */,
|
|
1455
|
-
schema: {
|
|
1456
|
-
type: "object" /* object */,
|
|
1457
|
-
properties: inBody.reduce((a, p) => {
|
|
1458
|
-
return {
|
|
1459
|
-
...a,
|
|
1460
|
-
[p.name]: {
|
|
1461
|
-
type: p.schema?.type ?? "unknown",
|
|
1462
|
-
required: p.schema?.required,
|
|
1463
|
-
// @ts-expect-error items can be undefined
|
|
1464
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1465
|
-
items: p.schema?.items,
|
|
1466
|
-
description: p.schema?.description
|
|
1467
|
-
}
|
|
1468
|
-
};
|
|
1469
|
-
}, {})
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
] : void 0
|
|
1473
|
-
});
|
|
1474
|
-
break;
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
});
|
|
1479
|
-
}
|
|
1480
|
-
return {
|
|
1481
|
-
...acc,
|
|
1482
|
-
[path]: methodApis
|
|
1483
|
-
};
|
|
1484
|
-
}, {});
|
|
1485
|
-
return {
|
|
1486
|
-
enums: Base.uniqueEnums(enums),
|
|
1487
|
-
schemas: definitions_,
|
|
1488
|
-
responses: responses_,
|
|
1489
|
-
parameters: {},
|
|
1490
|
-
requestBodies: {},
|
|
1491
|
-
apis
|
|
1492
|
-
};
|
|
1493
|
-
}
|
|
1494
|
-
};
|
|
1495
|
-
|
|
1496
|
-
// src/openapi/V3.ts
|
|
1497
|
-
var V3 = class {
|
|
1498
|
-
doc;
|
|
1499
|
-
constructor(doc) {
|
|
1500
|
-
this.doc = doc;
|
|
1501
|
-
}
|
|
1502
|
-
/**
|
|
1503
|
-
* Is array schema.
|
|
1504
|
-
*/
|
|
1505
|
-
isOpenAPIArraySchema(schema) {
|
|
1506
|
-
return typeof schema === "object" && schema.type === "array";
|
|
1507
|
-
}
|
|
1508
|
-
/**
|
|
1509
|
-
* OpenAPI schema to base schema.
|
|
1510
|
-
*/
|
|
1511
|
-
getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
|
|
1512
|
-
let refName = "";
|
|
1513
|
-
if (Base.isRef(schema)) {
|
|
1514
|
-
refName = Base.capitalize(Base.ref2name(schema.$ref));
|
|
1515
|
-
if (reserveRef) {
|
|
1516
|
-
return {
|
|
1517
|
-
type: upLevelSchemaKey + refName
|
|
1518
|
-
};
|
|
1519
|
-
}
|
|
1520
|
-
const resolvedSchema = this.doc.components?.schemas?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1521
|
-
if (!resolvedSchema) {
|
|
1522
|
-
return { type: "unknown" };
|
|
1523
|
-
}
|
|
1524
|
-
schema = resolvedSchema;
|
|
1525
|
-
}
|
|
1526
|
-
return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
|
|
1527
|
-
}
|
|
1528
|
-
/**
|
|
1529
|
-
* OpenAPI parameter to base parameter.
|
|
1530
|
-
*/
|
|
1531
|
-
getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
|
|
1532
|
-
if (Base.isRef(schema)) {
|
|
1533
|
-
const resolvedSchema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1534
|
-
if (!resolvedSchema) {
|
|
1535
|
-
return {
|
|
1536
|
-
name: "unknown",
|
|
1537
|
-
in: "query"
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
schema = resolvedSchema;
|
|
1541
|
-
}
|
|
1542
|
-
const {
|
|
1543
|
-
name,
|
|
1544
|
-
required,
|
|
1545
|
-
deprecated,
|
|
1546
|
-
description,
|
|
1547
|
-
schema: parameterSchema
|
|
1548
|
-
} = schema;
|
|
1549
|
-
if (parameterSchema && !Base.isRef(parameterSchema) && parameterSchema.enum) {
|
|
1550
|
-
const type = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(name));
|
|
1551
|
-
const enumSchema = {
|
|
1552
|
-
name: type,
|
|
1553
|
-
enum: [...new Set(parameterSchema.enum)]
|
|
1554
|
-
};
|
|
1555
|
-
const sameEnum = Base.findSameSchema(enumSchema, enums);
|
|
1556
|
-
if (!sameEnum && Base.isValidEnumType(parameterSchema)) {
|
|
1557
|
-
enums.push(enumSchema);
|
|
1558
|
-
}
|
|
1559
|
-
return {
|
|
1560
|
-
name,
|
|
1561
|
-
required,
|
|
1562
|
-
description,
|
|
1563
|
-
deprecated,
|
|
1564
|
-
in: schema.in,
|
|
1565
|
-
schema: {
|
|
1566
|
-
type: sameEnum?.name ?? type
|
|
1567
|
-
}
|
|
1568
|
-
};
|
|
1569
|
-
}
|
|
1570
|
-
return {
|
|
1571
|
-
name,
|
|
1572
|
-
required,
|
|
1573
|
-
description,
|
|
1574
|
-
deprecated,
|
|
1575
|
-
in: schema.in,
|
|
1576
|
-
schema: schema.schema && this.getSchemaByRef(
|
|
1577
|
-
schema.schema,
|
|
1578
|
-
false,
|
|
1579
|
-
enums,
|
|
1580
|
-
upLevelSchemaKey + Base.capitalize(name)
|
|
1581
|
-
)
|
|
1582
|
-
};
|
|
1583
|
-
}
|
|
1584
|
-
/**
|
|
1585
|
-
* OpenAPI schema to base response
|
|
1586
|
-
*/
|
|
1587
|
-
getResponseByRef(schema) {
|
|
1588
|
-
if (Base.isRef(schema)) {
|
|
1589
|
-
const resolvedSchema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1590
|
-
if (!resolvedSchema) {
|
|
1591
|
-
return [];
|
|
1592
|
-
}
|
|
1593
|
-
schema = resolvedSchema;
|
|
1594
|
-
}
|
|
1595
|
-
const { content = {} } = schema;
|
|
1596
|
-
return Object.keys(content).map((c) => ({
|
|
1597
|
-
type: c,
|
|
1598
|
-
schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
|
|
1599
|
-
}));
|
|
1600
|
-
}
|
|
1601
|
-
/**
|
|
1602
|
-
* OpenAPI schema to requestBody.
|
|
1603
|
-
*/
|
|
1604
|
-
getRequestBodyByRef(schema, enums = []) {
|
|
1605
|
-
if (Base.isRef(schema)) {
|
|
1606
|
-
const resolvedSchema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1607
|
-
if (!resolvedSchema) {
|
|
1608
|
-
return [];
|
|
1609
|
-
}
|
|
1610
|
-
schema = resolvedSchema;
|
|
1611
|
-
}
|
|
1612
|
-
const { content = {} } = schema;
|
|
1613
|
-
return Object.keys(content).map((c) => ({
|
|
1614
|
-
type: c,
|
|
1615
|
-
schema: content[c].schema && this.getSchemaByRef(content[c].schema, false, enums)
|
|
1616
|
-
}));
|
|
1617
|
-
}
|
|
1618
|
-
/**
|
|
1619
|
-
* Transform all OpenAPI schema to Base Schema
|
|
1620
|
-
*/
|
|
1621
|
-
toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
|
|
1622
|
-
if (!schema) {
|
|
1623
|
-
return {
|
|
1624
|
-
type: "unknown"
|
|
1625
|
-
};
|
|
1626
|
-
}
|
|
1627
|
-
if (Base.isRef(schema)) {
|
|
1628
|
-
return this.getSchemaByRef(schema, true);
|
|
1629
|
-
}
|
|
1630
|
-
if (this.isOpenAPIArraySchema(schema)) {
|
|
1631
|
-
const { type, description, items, required } = schema;
|
|
1632
|
-
return {
|
|
1633
|
-
type,
|
|
1634
|
-
required: !!required,
|
|
1635
|
-
description,
|
|
1636
|
-
items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
|
|
1637
|
-
};
|
|
1638
|
-
} else {
|
|
1639
|
-
const {
|
|
1640
|
-
required = [],
|
|
1641
|
-
allOf,
|
|
1642
|
-
anyOf,
|
|
1643
|
-
description,
|
|
1644
|
-
deprecated,
|
|
1645
|
-
enum: enum_,
|
|
1646
|
-
format: format2,
|
|
1647
|
-
oneOf,
|
|
1648
|
-
properties = {}
|
|
1649
|
-
} = schema;
|
|
1650
|
-
let { type } = schema;
|
|
1651
|
-
if (enum_ && type !== "boolean") {
|
|
1652
|
-
const name = Base.upperCamelCase(Base.normalize(upLevelSchemaKey)) + Base.upperCamelCase(Base.normalize(schemaKey));
|
|
1653
|
-
const enumObject = {
|
|
1654
|
-
name,
|
|
1655
|
-
enum: [...new Set(enum_)]
|
|
1656
|
-
};
|
|
1657
|
-
const sameObject = Base.findSameSchema(enumObject, enums);
|
|
1658
|
-
if (!sameObject && Base.isValidEnumType(schema)) {
|
|
1659
|
-
enums.push(enumObject);
|
|
1660
|
-
}
|
|
1661
|
-
return {
|
|
1662
|
-
type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
|
|
1663
|
-
required,
|
|
1664
|
-
description,
|
|
1665
|
-
deprecated
|
|
1666
|
-
};
|
|
1667
|
-
}
|
|
1668
|
-
if (type === void 0 && Object.keys(properties).length > 0) {
|
|
1669
|
-
type = "object" /* object */;
|
|
1670
|
-
}
|
|
1671
|
-
return {
|
|
1672
|
-
type,
|
|
1673
|
-
required,
|
|
1674
|
-
description,
|
|
1675
|
-
deprecated,
|
|
1676
|
-
enum: enum_,
|
|
1677
|
-
format: format2,
|
|
1678
|
-
allOf: allOf?.map(
|
|
1679
|
-
(s) => Base.isRef(s) ? {
|
|
1680
|
-
...s,
|
|
1681
|
-
ref: s.$ref,
|
|
1682
|
-
type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
|
|
1683
|
-
} : this.toBaseSchema(s, enums)
|
|
1684
|
-
),
|
|
1685
|
-
anyOf: anyOf?.map(
|
|
1686
|
-
(s) => Base.isRef(s) ? {
|
|
1687
|
-
...s,
|
|
1688
|
-
ref: s.$ref,
|
|
1689
|
-
type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
|
|
1690
|
-
} : this.toBaseSchema(s, enums)
|
|
1691
|
-
),
|
|
1692
|
-
oneOf: oneOf?.map(
|
|
1693
|
-
(s) => Base.isRef(s) ? {
|
|
1694
|
-
...s,
|
|
1695
|
-
ref: s.$ref,
|
|
1696
|
-
type: Base.capitalize(Base.ref2name(s.$ref, this.doc))
|
|
1697
|
-
} : this.toBaseSchema(s, enums)
|
|
1698
|
-
),
|
|
1699
|
-
properties: Object.keys(properties).reduce((acc, p) => {
|
|
1700
|
-
const propSchema = properties[p];
|
|
1701
|
-
return {
|
|
1702
|
-
...acc,
|
|
1703
|
-
[p]: Base.isRef(propSchema) ? {
|
|
1704
|
-
type: Base.capitalize(
|
|
1705
|
-
Base.ref2name(propSchema.$ref, this.doc)
|
|
1706
|
-
)
|
|
1707
|
-
} : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
|
|
1708
|
-
};
|
|
1709
|
-
}, {})
|
|
1710
|
-
};
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
init() {
|
|
1714
|
-
const { components = {}, paths = {} } = this.doc;
|
|
1715
|
-
const enums = [];
|
|
1716
|
-
const {
|
|
1717
|
-
requestBodies = {},
|
|
1718
|
-
responses = {},
|
|
1719
|
-
parameters = {},
|
|
1720
|
-
schemas = {}
|
|
1721
|
-
} = components;
|
|
1722
|
-
const schemas_ = Object.keys(schemas).reduce((acc, key) => {
|
|
1723
|
-
const schema = schemas[key];
|
|
1724
|
-
return {
|
|
1725
|
-
...acc,
|
|
1726
|
-
[key]: this.getSchemaByRef(schema, false, enums, key)
|
|
1727
|
-
};
|
|
1728
|
-
}, {});
|
|
1729
|
-
const parameters_ = Object.keys(parameters).reduce((acc, key) => {
|
|
1730
|
-
const parameter = parameters[key];
|
|
1731
|
-
return {
|
|
1732
|
-
...acc,
|
|
1733
|
-
[key]: this.getParameterByRef(parameter, enums, key)
|
|
1734
|
-
};
|
|
1735
|
-
}, {});
|
|
1736
|
-
const responses_ = Object.keys(responses).reduce((acc, key) => {
|
|
1737
|
-
const response = responses[key];
|
|
1738
|
-
return {
|
|
1739
|
-
...acc,
|
|
1740
|
-
[key]: this.getResponseByRef(response)
|
|
1741
|
-
};
|
|
1742
|
-
}, {});
|
|
1743
|
-
const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
|
|
1744
|
-
const requestBody = requestBodies[key];
|
|
1745
|
-
return {
|
|
1746
|
-
...acc,
|
|
1747
|
-
[key]: this.getRequestBodyByRef(requestBody, enums)
|
|
1748
|
-
};
|
|
1749
|
-
}, {});
|
|
1750
|
-
const apis = Object.keys(paths).reduce((acc, path) => {
|
|
1751
|
-
const pathObject = paths[path] ?? {};
|
|
1752
|
-
const { $ref } = pathObject;
|
|
1753
|
-
const methodApis = [];
|
|
1754
|
-
if ($ref) {
|
|
1755
|
-
} else {
|
|
1756
|
-
const { parameters: parameters2 = [], description, summary } = pathObject;
|
|
1757
|
-
Object.values(HttpMethods).forEach((method) => {
|
|
1758
|
-
const methodObject = pathObject[method];
|
|
1759
|
-
if (methodObject) {
|
|
1760
|
-
const {
|
|
1761
|
-
deprecated,
|
|
1762
|
-
operationId,
|
|
1763
|
-
responses: responses2 = {},
|
|
1764
|
-
summary: summary_,
|
|
1765
|
-
description: description_,
|
|
1766
|
-
requestBody = { content: {} }
|
|
1767
|
-
} = methodObject;
|
|
1768
|
-
const { parameters: parameters_2 = [] } = methodObject;
|
|
1769
|
-
const baseParameters = [...parameters2, ...parameters_2].map(
|
|
1770
|
-
(parameter) => this.getParameterByRef(parameter, enums)
|
|
1771
|
-
);
|
|
1772
|
-
const baseRequestBody = this.getRequestBodyByRef(
|
|
1773
|
-
requestBody,
|
|
1774
|
-
enums
|
|
1775
|
-
);
|
|
1776
|
-
const uniqueParameterName = [
|
|
1777
|
-
...new Set(baseParameters.map((p) => p.name))
|
|
1778
|
-
];
|
|
1779
|
-
if (Object.keys(responses2).length === 0) {
|
|
1780
|
-
Object.assign(responses2, {
|
|
1781
|
-
200: {
|
|
1782
|
-
description: "Successful response"
|
|
1783
|
-
}
|
|
1784
|
-
});
|
|
1785
|
-
}
|
|
1786
|
-
const httpCodes = Object.keys(responses2);
|
|
1787
|
-
for (const code of httpCodes) {
|
|
1788
|
-
if (code in responses2) {
|
|
1789
|
-
const response = responses2[code];
|
|
1790
|
-
const responseSchema = this.getResponseByRef(response);
|
|
1791
|
-
methodApis.push({
|
|
1792
|
-
method,
|
|
1793
|
-
operationId,
|
|
1794
|
-
summary: summary_ ?? summary,
|
|
1795
|
-
description: description_ ?? description,
|
|
1796
|
-
deprecated,
|
|
1797
|
-
parameters: uniqueParameterName.map(
|
|
1798
|
-
(name) => baseParameters.find((p) => p.name === name)
|
|
1799
|
-
),
|
|
1800
|
-
responses: responseSchema,
|
|
1801
|
-
requestBody: baseRequestBody
|
|
1802
|
-
});
|
|
1803
|
-
break;
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
});
|
|
1808
|
-
}
|
|
1809
|
-
return {
|
|
1810
|
-
...acc,
|
|
1811
|
-
[path]: methodApis
|
|
1812
|
-
};
|
|
1813
|
-
}, {});
|
|
1814
|
-
return {
|
|
1815
|
-
enums: Base.uniqueEnums(enums),
|
|
1816
|
-
schemas: schemas_,
|
|
1817
|
-
responses: responses_,
|
|
1818
|
-
parameters: parameters_,
|
|
1819
|
-
requestBodies: requestBodies_,
|
|
1820
|
-
apis
|
|
1821
|
-
};
|
|
1822
|
-
}
|
|
1823
|
-
};
|
|
1824
|
-
|
|
1825
|
-
// src/openapi/V3_1.ts
|
|
1826
|
-
var V3_1 = class {
|
|
1827
|
-
doc;
|
|
1828
|
-
constructor(doc) {
|
|
1829
|
-
this.doc = doc;
|
|
1830
|
-
}
|
|
1831
|
-
/**
|
|
1832
|
-
* Is array schema.
|
|
1833
|
-
*/
|
|
1834
|
-
isOpenAPIArraySchema(schema) {
|
|
1835
|
-
return typeof schema === "object" && schema.type === "array";
|
|
1836
|
-
}
|
|
1837
|
-
/**
|
|
1838
|
-
* OpenAPI schema to base schema.
|
|
1839
|
-
*/
|
|
1840
|
-
getSchemaByRef(schema, reserveRef = false, enums = [], upLevelSchemaKey = "") {
|
|
1841
|
-
let refName = "";
|
|
1842
|
-
if (Base.isRef(schema)) {
|
|
1843
|
-
refName = Base.upperCamelCase(Base.ref2name(schema.$ref));
|
|
1844
|
-
if (reserveRef) {
|
|
1845
|
-
return {
|
|
1846
|
-
type: upLevelSchemaKey + refName
|
|
1847
|
-
};
|
|
1848
|
-
}
|
|
1849
|
-
if (!this.doc.components) {
|
|
1850
|
-
this.doc.components = {
|
|
1851
|
-
schemas: {}
|
|
1852
|
-
};
|
|
1853
|
-
}
|
|
1854
|
-
schema = this.doc.components.schemas[Base.ref2name(schema.$ref, this.doc)];
|
|
1855
|
-
}
|
|
1856
|
-
return this.toBaseSchema(schema, enums, "", upLevelSchemaKey + refName);
|
|
1857
|
-
}
|
|
1858
|
-
/**
|
|
1859
|
-
* OpenAPI parameter to base parameter.
|
|
1860
|
-
*/
|
|
1861
|
-
getParameterByRef(schema, enums = [], upLevelSchemaKey = "") {
|
|
1862
|
-
if (Base.isRef(schema)) {
|
|
1863
|
-
schema = this.doc.components?.parameters?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1864
|
-
}
|
|
1865
|
-
const {
|
|
1866
|
-
name,
|
|
1867
|
-
required,
|
|
1868
|
-
deprecated,
|
|
1869
|
-
description,
|
|
1870
|
-
schema: parameterSchema
|
|
1871
|
-
} = schema;
|
|
1872
|
-
if (parameterSchema && !Base.isRef(parameterSchema) && parameterSchema.enum) {
|
|
1873
|
-
const type = Base.upperCamelCase(upLevelSchemaKey) + Base.upperCamelCase(name);
|
|
1874
|
-
const enumSchema = {
|
|
1875
|
-
name: type,
|
|
1876
|
-
enum: [...new Set(parameterSchema.enum)]
|
|
1877
|
-
};
|
|
1878
|
-
const sameEnum = Base.findSameSchema(enumSchema, enums);
|
|
1879
|
-
if (!sameEnum && Base.isValidEnumType(parameterSchema)) {
|
|
1880
|
-
enums.push(enumSchema);
|
|
1881
|
-
}
|
|
1882
|
-
return {
|
|
1883
|
-
name,
|
|
1884
|
-
required,
|
|
1885
|
-
description,
|
|
1886
|
-
deprecated,
|
|
1887
|
-
in: schema.in,
|
|
1888
|
-
schema: {
|
|
1889
|
-
type: sameEnum?.name ?? type
|
|
1890
|
-
}
|
|
1891
|
-
};
|
|
1892
|
-
}
|
|
1893
|
-
return {
|
|
1894
|
-
name,
|
|
1895
|
-
required,
|
|
1896
|
-
description,
|
|
1897
|
-
deprecated,
|
|
1898
|
-
in: schema.in,
|
|
1899
|
-
schema: schema.schema && this.getSchemaByRef(
|
|
1900
|
-
schema.schema,
|
|
1901
|
-
false,
|
|
1902
|
-
enums,
|
|
1903
|
-
upLevelSchemaKey + Base.capitalize(name)
|
|
1904
|
-
)
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
|
-
/**
|
|
1908
|
-
* OpenAPI schema to base response
|
|
1909
|
-
*/
|
|
1910
|
-
getResponseByRef(schema) {
|
|
1911
|
-
if (Base.isRef(schema)) {
|
|
1912
|
-
schema = this.doc.components?.responses?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1913
|
-
}
|
|
1914
|
-
const { content = {} } = schema;
|
|
1915
|
-
return Object.keys(content).map((c) => ({
|
|
1916
|
-
type: c,
|
|
1917
|
-
schema: content[c].schema && this.getSchemaByRef(content[c].schema, true)
|
|
1918
|
-
}));
|
|
1919
|
-
}
|
|
1920
|
-
/**
|
|
1921
|
-
* OpenAPI schema to requestBody.
|
|
1922
|
-
*/
|
|
1923
|
-
getRequestBodyByRef(schema, enums = [], reserveRef = false) {
|
|
1924
|
-
if (Base.isRef(schema)) {
|
|
1925
|
-
schema = this.doc.components?.requestBodies?.[Base.ref2name(schema.$ref, this.doc)];
|
|
1926
|
-
}
|
|
1927
|
-
const { content = {} } = schema;
|
|
1928
|
-
return Object.keys(content).map((c) => ({
|
|
1929
|
-
type: c,
|
|
1930
|
-
schema: content[c].schema && this.getSchemaByRef(content[c].schema, reserveRef, enums)
|
|
1931
|
-
}));
|
|
1932
|
-
}
|
|
1933
|
-
/**
|
|
1934
|
-
* Transform all OpenAPI schema to Base Schema
|
|
1935
|
-
*/
|
|
1936
|
-
toBaseSchema(schema, enums = [], schemaKey = "", upLevelSchemaKey = "") {
|
|
1937
|
-
if (!schema) {
|
|
1938
|
-
return {
|
|
1939
|
-
type: "unknown"
|
|
1940
|
-
};
|
|
1941
|
-
}
|
|
1942
|
-
if (Base.isRef(schema)) {
|
|
1943
|
-
return this.getSchemaByRef(schema, true);
|
|
1944
|
-
}
|
|
1945
|
-
if (this.isOpenAPIArraySchema(schema)) {
|
|
1946
|
-
const { type, description, items, required } = schema;
|
|
1947
|
-
return {
|
|
1948
|
-
type,
|
|
1949
|
-
required: !!required,
|
|
1950
|
-
description,
|
|
1951
|
-
items: this.toBaseSchema(items, enums, schemaKey, upLevelSchemaKey)
|
|
1952
|
-
};
|
|
1953
|
-
} else {
|
|
1954
|
-
const {
|
|
1955
|
-
required = [],
|
|
1956
|
-
allOf,
|
|
1957
|
-
anyOf,
|
|
1958
|
-
description,
|
|
1959
|
-
deprecated,
|
|
1960
|
-
enum: enum_,
|
|
1961
|
-
format: format2,
|
|
1962
|
-
oneOf,
|
|
1963
|
-
properties = {}
|
|
1964
|
-
} = schema;
|
|
1965
|
-
let { type } = schema;
|
|
1966
|
-
if (enum_ && type !== "boolean") {
|
|
1967
|
-
const name = Base.upperCamelCase(upLevelSchemaKey) + Base.upperCamelCase(schemaKey);
|
|
1968
|
-
const enumObject = {
|
|
1969
|
-
name,
|
|
1970
|
-
enum: [...new Set(enum_)]
|
|
1971
|
-
};
|
|
1972
|
-
const sameObject = Base.findSameSchema(enumObject, enums);
|
|
1973
|
-
if (!sameObject && Base.isValidEnumType(schema)) {
|
|
1974
|
-
enums.push(enumObject);
|
|
1975
|
-
}
|
|
1976
|
-
return {
|
|
1977
|
-
type: sameObject ? sameObject.name : Base.isBooleanEnum(schema) ? "boolean" : enumObject.name,
|
|
1978
|
-
required,
|
|
1979
|
-
description,
|
|
1980
|
-
deprecated
|
|
1981
|
-
};
|
|
1982
|
-
}
|
|
1983
|
-
if (type === void 0 && Object.keys(properties).length > 0) {
|
|
1984
|
-
type = "object" /* object */;
|
|
1985
|
-
}
|
|
1986
|
-
return {
|
|
1987
|
-
type,
|
|
1988
|
-
required,
|
|
1989
|
-
description,
|
|
1990
|
-
deprecated,
|
|
1991
|
-
enum: enum_,
|
|
1992
|
-
format: format2,
|
|
1993
|
-
allOf: allOf?.map(
|
|
1994
|
-
(s) => Base.isRef(s) ? {
|
|
1995
|
-
...s,
|
|
1996
|
-
ref: s.$ref,
|
|
1997
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
1998
|
-
} : this.toBaseSchema(s, enums)
|
|
1999
|
-
),
|
|
2000
|
-
anyOf: anyOf?.map(
|
|
2001
|
-
(s) => Base.isRef(s) ? {
|
|
2002
|
-
...s,
|
|
2003
|
-
ref: s.$ref,
|
|
2004
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
2005
|
-
} : this.toBaseSchema(s, enums)
|
|
2006
|
-
),
|
|
2007
|
-
oneOf: oneOf?.map(
|
|
2008
|
-
(s) => Base.isRef(s) ? {
|
|
2009
|
-
...s,
|
|
2010
|
-
ref: s.$ref,
|
|
2011
|
-
type: Base.upperCamelCase(Base.ref2name(s.$ref, this.doc))
|
|
2012
|
-
} : this.toBaseSchema(s, enums)
|
|
2013
|
-
),
|
|
2014
|
-
properties: Object.keys(properties).reduce((acc, p) => {
|
|
2015
|
-
const propSchema = properties[p];
|
|
2016
|
-
return {
|
|
2017
|
-
...acc,
|
|
2018
|
-
[p]: Base.isRef(propSchema) ? {
|
|
2019
|
-
type: Base.upperCamelCase(
|
|
2020
|
-
Base.ref2name(propSchema.$ref, this.doc)
|
|
2021
|
-
)
|
|
2022
|
-
} : this.toBaseSchema(propSchema, enums, p, upLevelSchemaKey)
|
|
2023
|
-
};
|
|
2024
|
-
}, {})
|
|
2025
|
-
};
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
init() {
|
|
2029
|
-
const { components = {}, paths = {} } = this.doc;
|
|
2030
|
-
const enums = [];
|
|
2031
|
-
const {
|
|
2032
|
-
requestBodies = {},
|
|
2033
|
-
responses = {},
|
|
2034
|
-
parameters = {},
|
|
2035
|
-
schemas = {}
|
|
2036
|
-
} = components;
|
|
2037
|
-
const schemas_ = Object.keys(schemas).reduce((acc, key) => {
|
|
2038
|
-
const schema = schemas[key];
|
|
2039
|
-
return {
|
|
2040
|
-
...acc,
|
|
2041
|
-
[key]: this.getSchemaByRef(schema, false, enums, key)
|
|
2042
|
-
};
|
|
2043
|
-
}, {});
|
|
2044
|
-
const parameters_ = Object.keys(parameters).reduce((acc, key) => {
|
|
2045
|
-
const parameter = parameters[key];
|
|
2046
|
-
return {
|
|
2047
|
-
...acc,
|
|
2048
|
-
[key]: this.getParameterByRef(parameter, enums, key)
|
|
2049
|
-
};
|
|
2050
|
-
}, {});
|
|
2051
|
-
const responses_ = Object.keys(responses).reduce((acc, key) => {
|
|
2052
|
-
const response = responses[key];
|
|
2053
|
-
return {
|
|
2054
|
-
...acc,
|
|
2055
|
-
[key]: this.getResponseByRef(response)
|
|
2056
|
-
};
|
|
2057
|
-
}, {});
|
|
2058
|
-
const requestBodies_ = Object.keys(requestBodies).reduce((acc, key) => {
|
|
2059
|
-
const requestBody = requestBodies[key];
|
|
2060
|
-
return {
|
|
2061
|
-
...acc,
|
|
2062
|
-
[key]: this.getRequestBodyByRef(requestBody, enums)
|
|
2063
|
-
};
|
|
2064
|
-
}, {});
|
|
2065
|
-
const apis = Object.keys(paths).reduce((acc, path) => {
|
|
2066
|
-
const pathObject = paths[path] ?? {};
|
|
2067
|
-
const { $ref } = pathObject;
|
|
2068
|
-
const methodApis = [];
|
|
2069
|
-
if ($ref) {
|
|
2070
|
-
} else {
|
|
2071
|
-
const { parameters: parameters2 = [], description, summary } = pathObject;
|
|
2072
|
-
Object.values(HttpMethods).forEach((method) => {
|
|
2073
|
-
const methodObject = pathObject[method];
|
|
2074
|
-
if (methodObject) {
|
|
2075
|
-
const {
|
|
2076
|
-
deprecated,
|
|
2077
|
-
operationId,
|
|
2078
|
-
summary: summary_,
|
|
2079
|
-
description: description_,
|
|
2080
|
-
responses: responses2 = {},
|
|
2081
|
-
requestBody = { content: {} }
|
|
2082
|
-
} = methodObject;
|
|
2083
|
-
const { parameters: parameters_2 = [] } = methodObject;
|
|
2084
|
-
const baseParameters = [...parameters2, ...parameters_2].map(
|
|
2085
|
-
(parameter) => this.getParameterByRef(parameter, enums)
|
|
2086
|
-
);
|
|
2087
|
-
const baseRequestBody = this.getRequestBodyByRef(
|
|
2088
|
-
requestBody,
|
|
2089
|
-
enums,
|
|
2090
|
-
true
|
|
2091
|
-
);
|
|
2092
|
-
const uniqueParameterName = [
|
|
2093
|
-
...new Set(baseParameters.map((p) => p.name))
|
|
2094
|
-
];
|
|
2095
|
-
if (Object.keys(responses2).length === 0) {
|
|
2096
|
-
Object.assign(responses2, {
|
|
2097
|
-
200: {
|
|
2098
|
-
description: "Successful response"
|
|
2099
|
-
}
|
|
2100
|
-
});
|
|
2101
|
-
}
|
|
2102
|
-
const httpCodes = Object.keys(responses2);
|
|
2103
|
-
for (const code of httpCodes) {
|
|
2104
|
-
if (code in responses2) {
|
|
2105
|
-
const response = responses2[code];
|
|
2106
|
-
const responseSchema = this.getResponseByRef(response);
|
|
2107
|
-
methodApis.push({
|
|
2108
|
-
method,
|
|
2109
|
-
operationId,
|
|
2110
|
-
summary: summary_ ?? summary,
|
|
2111
|
-
description: description_ ?? description,
|
|
2112
|
-
deprecated,
|
|
2113
|
-
parameters: uniqueParameterName.map(
|
|
2114
|
-
(name) => baseParameters.find((p) => p.name === name)
|
|
2115
|
-
),
|
|
2116
|
-
responses: responseSchema,
|
|
2117
|
-
requestBody: baseRequestBody
|
|
2118
|
-
});
|
|
2119
|
-
break;
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
});
|
|
2124
|
-
}
|
|
2125
|
-
return {
|
|
2126
|
-
...acc,
|
|
2127
|
-
[path]: methodApis
|
|
2128
|
-
};
|
|
2129
|
-
}, {});
|
|
2130
|
-
return {
|
|
2131
|
-
enums: Base.uniqueEnums(enums),
|
|
2132
|
-
schemas: schemas_,
|
|
2133
|
-
responses: responses_,
|
|
2134
|
-
parameters: parameters_,
|
|
2135
|
-
requestBodies: requestBodies_,
|
|
2136
|
-
apis
|
|
2137
|
-
};
|
|
2138
|
-
}
|
|
2139
|
-
};
|
|
2140
|
-
|
|
2141
|
-
// src/openapi/index.ts
|
|
2142
|
-
var logger = createScopedLogger("OpenAPI");
|
|
2143
|
-
function getDocVersion(doc) {
|
|
2144
|
-
const version = (doc.openapi || doc.swagger).slice(0, 3);
|
|
2145
|
-
switch (version) {
|
|
2146
|
-
case "2.0":
|
|
2147
|
-
return "v2" /* v2 */;
|
|
2148
|
-
case "3.0":
|
|
2149
|
-
return "v3" /* v3 */;
|
|
2150
|
-
case "3.1":
|
|
2151
|
-
return "v3_1" /* v3_1 */;
|
|
2152
|
-
default:
|
|
2153
|
-
return "unknown" /* unknown */;
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
var OpenAPIProvider = class extends Provider {
|
|
2157
|
-
parse(doc) {
|
|
2158
|
-
const version = getDocVersion(doc);
|
|
2159
|
-
logger.debug(`openapi version ${version}`);
|
|
2160
|
-
let returnValue;
|
|
2161
|
-
switch (version) {
|
|
2162
|
-
case "v2" /* v2 */:
|
|
2163
|
-
returnValue = new V2(doc).init();
|
|
2164
|
-
break;
|
|
2165
|
-
case "v3" /* v3 */:
|
|
2166
|
-
returnValue = new V3(doc).init();
|
|
2167
|
-
break;
|
|
2168
|
-
case "v3_1" /* v3_1 */:
|
|
2169
|
-
returnValue = new V3_1(doc).init();
|
|
2170
|
-
break;
|
|
2171
|
-
default:
|
|
2172
|
-
logger.error(`Not a valid OpenAPI version ${version}`);
|
|
2173
|
-
process.exit(1);
|
|
2174
|
-
}
|
|
2175
|
-
return returnValue;
|
|
2176
|
-
}
|
|
2177
|
-
};
|
|
2178
|
-
function getAdaptor(type) {
|
|
2179
|
-
switch (type) {
|
|
2180
|
-
case "axios" /* axios */:
|
|
2181
|
-
return new AxiosAdapter();
|
|
2182
|
-
case "fetch" /* fetch */:
|
|
2183
|
-
return new FetchAdapter();
|
|
2184
|
-
default:
|
|
2185
|
-
throw TypeError(`Not Supported Adaptor ${type}`);
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
async function codeGen(initOptions) {
|
|
2189
|
-
const { verbose } = initOptions;
|
|
2190
|
-
if (verbose) {
|
|
2191
|
-
logger.setLevel("debug");
|
|
2192
|
-
} else {
|
|
2193
|
-
logger.setLevel("info");
|
|
2194
|
-
}
|
|
2195
|
-
logger.info(`Fech document from ${initOptions.docURL}`);
|
|
2196
|
-
const doc = await Base.fetchDoc(
|
|
2197
|
-
initOptions.docURL,
|
|
2198
|
-
initOptions.requestOptions
|
|
2199
|
-
);
|
|
2200
|
-
const provider = new OpenAPIProvider(initOptions, doc);
|
|
2201
|
-
const { enums, schemas, parameters, responses, requestBodies, apis } = provider;
|
|
2202
|
-
const adaptor = getAdaptor(initOptions.adaptor ?? "fetch" /* fetch */);
|
|
2203
|
-
const code = await Generator.genCode(
|
|
2204
|
-
{
|
|
2205
|
-
enums,
|
|
2206
|
-
schemas,
|
|
2207
|
-
parameters,
|
|
2208
|
-
responses,
|
|
2209
|
-
requestBodies,
|
|
2210
|
-
apis
|
|
2211
|
-
},
|
|
2212
|
-
initOptions,
|
|
2213
|
-
adaptor
|
|
2214
|
-
);
|
|
2215
|
-
if (process.env.NODE_ENV === "test") {
|
|
2216
|
-
await Generator.write(code, initOptions.output);
|
|
2217
|
-
}
|
|
2218
|
-
return code;
|
|
2219
|
-
}
|
|
2220
|
-
|
|
2221
|
-
// src/vite-plugin/index.ts
|
|
2222
|
-
import { createScopedLogger as createScopedLogger2 } from "@moccona/logger";
|
|
2223
|
-
import { execaCommand } from "execa";
|
|
2224
|
-
import fs from "fs-extra";
|
|
2225
|
-
var PLUGIN_NAME = "apiCodeGen";
|
|
2226
|
-
var logger2 = createScopedLogger2("api-codegen-vite-plugin");
|
|
2227
|
-
var tsc = async (path) => {
|
|
2228
|
-
await execaCommand(`npx tsc ${path} --noEmit`);
|
|
2229
|
-
};
|
|
2230
|
-
function apiCodeGenPlugin(options) {
|
|
2231
|
-
let firstRun = true;
|
|
2232
|
-
return {
|
|
2233
|
-
name: PLUGIN_NAME,
|
|
2234
|
-
async config(config) {
|
|
2235
|
-
if (!firstRun) return;
|
|
2236
|
-
firstRun = false;
|
|
2237
|
-
logger2.info("-------> api codegen start <--------");
|
|
2238
|
-
const proxies = await options.reduce(
|
|
2239
|
-
async (proxiesPromise_, option) => {
|
|
2240
|
-
const proxies_ = await proxiesPromise_;
|
|
2241
|
-
const { proxy = {}, name, ...codeGenInitOptions } = option;
|
|
2242
|
-
try {
|
|
2243
|
-
const code = await codeGen(codeGenInitOptions);
|
|
2244
|
-
await fs.createFile(codeGenInitOptions.output);
|
|
2245
|
-
await fs.writeFile(codeGenInitOptions.output, code);
|
|
2246
|
-
try {
|
|
2247
|
-
await tsc(codeGenInitOptions.output);
|
|
2248
|
-
} catch (error) {
|
|
2249
|
-
logger2.error(error);
|
|
2250
|
-
}
|
|
2251
|
-
} catch (error) {
|
|
2252
|
-
logger2.error(`Failed to generate api ${name}: ${error}`);
|
|
2253
|
-
}
|
|
2254
|
-
return {
|
|
2255
|
-
...proxies_,
|
|
2256
|
-
...proxy
|
|
2257
|
-
};
|
|
2258
|
-
},
|
|
2259
|
-
Promise.resolve({})
|
|
2260
|
-
);
|
|
2261
|
-
logger2.info("-------> api codegen finished <--------");
|
|
2262
|
-
return {
|
|
2263
|
-
...config,
|
|
2264
|
-
server: {
|
|
2265
|
-
...config.server ?? {},
|
|
2266
|
-
proxy: Object.assign({}, config.server?.proxy ?? {}, proxies)
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
}
|
|
2270
|
-
};
|
|
2271
|
-
}
|
|
2272
|
-
export {
|
|
2273
|
-
apiCodeGenPlugin,
|
|
2274
|
-
tsc
|
|
2275
|
-
};
|
|
2276
|
-
//# sourceMappingURL=index.js.map
|