@accelbyte/codegen 1.0.0-alpha.1 → 1.0.0-alpha.12
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/LICENSE +19 -0
- package/PATCHING.md +137 -0
- package/README.md +27 -131
- package/dist/accelbyte-codegen.js +354 -239
- package/dist/accelbyte-codegen.js.map +1 -1
- package/dist/accelbyte-codegen.mjs +321 -198
- package/dist/accelbyte-codegen.mjs.map +1 -1
- package/package.json +8 -6
- package/CHANGELOG.md +0 -40
|
@@ -11,10 +11,7 @@ var _ = require('lodash');
|
|
|
11
11
|
var fastJsonPatch = require('fast-json-patch');
|
|
12
12
|
var https = require('https');
|
|
13
13
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
function _interopNamespace(e) {
|
|
17
|
-
if (e && e.__esModule) return e;
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
18
15
|
var n = Object.create(null);
|
|
19
16
|
if (e) {
|
|
20
17
|
Object.keys(e).forEach(function (k) {
|
|
@@ -27,18 +24,13 @@ function _interopNamespace(e) {
|
|
|
27
24
|
}
|
|
28
25
|
});
|
|
29
26
|
}
|
|
30
|
-
n
|
|
27
|
+
n.default = e;
|
|
31
28
|
return Object.freeze(n);
|
|
32
29
|
}
|
|
33
30
|
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
38
|
-
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
39
|
-
var SwaggerParser__default = /*#__PURE__*/_interopDefaultLegacy(SwaggerParser);
|
|
40
|
-
var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
|
|
41
|
-
var https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
31
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
32
|
+
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
33
|
+
var https__namespace = /*#__PURE__*/_interopNamespaceDefault(https);
|
|
42
34
|
|
|
43
35
|
const SwaggersConfig = zod.z.array(zod.z.array(zod.z.string()));
|
|
44
36
|
class CliParser {
|
|
@@ -64,7 +56,7 @@ class CliParser {
|
|
|
64
56
|
const configPath = CliParser.getConfigPath();
|
|
65
57
|
if (!configPath)
|
|
66
58
|
throw new Error("Missing config file");
|
|
67
|
-
const config = JSON.parse(
|
|
59
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
68
60
|
if (!SwaggersConfig.safeParse(config).success) {
|
|
69
61
|
throw new Error("Wrong config file format");
|
|
70
62
|
}
|
|
@@ -109,15 +101,15 @@ const generateImports = (body, importStatements) => {
|
|
|
109
101
|
${importStatements.sort().join("\n")}`;
|
|
110
102
|
};
|
|
111
103
|
const templateClass = (className, body, importStatements) => `/**
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
* DON'T EDIT THIS FILE, it is AUTO GENERATED
|
|
105
|
+
*/
|
|
106
|
+
${generateImports(body, importStatements)}
|
|
115
107
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
export class ${className} {
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
constructor(private axiosInstance: AxiosInstance, private namespace: string, private cache = false) {}
|
|
119
111
|
${body}
|
|
120
|
-
|
|
112
|
+
}
|
|
121
113
|
`;
|
|
122
114
|
|
|
123
115
|
const templateJsdocFile = (apiName, body) => `
|
|
@@ -129,44 +121,34 @@ ${body}
|
|
|
129
121
|
`.replace(/, \)/g, ")").trim();
|
|
130
122
|
|
|
131
123
|
class ParserUtils {
|
|
132
|
-
static parseQueryParamAttributeDefault = (
|
|
133
|
-
const attrName = name.slice(name.lastIndexOf(".") + 1);
|
|
124
|
+
static parseQueryParamAttributeDefault = (definition) => {
|
|
125
|
+
const attrName = definition.name.slice(definition.name.lastIndexOf(".") + 1);
|
|
134
126
|
const defaultValue = definition.type === "string" ? `'${definition.default}'` : definition.default;
|
|
135
127
|
return `${attrName}: ${defaultValue}`;
|
|
136
128
|
};
|
|
137
|
-
static parseType = (
|
|
138
|
-
if (type === "integer")
|
|
129
|
+
static parseType = (pathParam) => {
|
|
130
|
+
if (pathParam.type === "int" || pathParam.type === "integer" || pathParam?.schema?.type === "integer")
|
|
139
131
|
return "number";
|
|
140
|
-
if (type === "array")
|
|
141
|
-
return "any[]
|
|
142
|
-
|
|
132
|
+
if (pathParam.type === "array")
|
|
133
|
+
return `${pathParam.items.type ?? "any"}[]`;
|
|
134
|
+
if (pathParam?.schema?.type === "array")
|
|
135
|
+
return `${pathParam.schema.items.type ?? "any"}[]`;
|
|
136
|
+
if (pathParam?.schema?.type)
|
|
137
|
+
return pathParam.schema.type;
|
|
138
|
+
return pathParam.type;
|
|
143
139
|
};
|
|
144
140
|
static parseQueryParamsType = (queryParams) => {
|
|
145
|
-
return queryParams.map((
|
|
141
|
+
return queryParams.map((queryParam) => ParserUtils.parseAttributeType(queryParam)).join(",");
|
|
146
142
|
};
|
|
147
143
|
static isAnyQueryParamRequired = (queryParams) => {
|
|
148
|
-
queryParams.
|
|
149
|
-
if (p.required) {
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
return false;
|
|
144
|
+
return queryParams.some((queryParam) => queryParam.required);
|
|
154
145
|
};
|
|
155
146
|
static parseQueryParamsDefault = (queryParams) => {
|
|
156
|
-
const result = queryParams.filter((
|
|
147
|
+
const result = queryParams.filter((queryParam) => !!queryParam.default && !queryParam.required).map(ParserUtils.parseQueryParamAttributeDefault).join(",");
|
|
157
148
|
return result ? `${result},` : "";
|
|
158
149
|
};
|
|
159
150
|
static parseBodyParamsImports = (bodyParams) => {
|
|
160
|
-
|
|
161
|
-
if (p?.schema?.$ref)
|
|
162
|
-
return ParserUtils.parseRefImport(p.schema.$ref, p);
|
|
163
|
-
if (p?.schema?.items?.$ref)
|
|
164
|
-
return ParserUtils.parseRefImport(p.schema.items.$ref, p);
|
|
165
|
-
if (p?.$ref)
|
|
166
|
-
return ParserUtils.parseRefImport(p.$ref, p);
|
|
167
|
-
return null;
|
|
168
|
-
}).filter((p) => !!p);
|
|
169
|
-
return ret;
|
|
151
|
+
return bodyParams.map(ParserUtils.parseRefImport).filter(Boolean);
|
|
170
152
|
};
|
|
171
153
|
static parseImportDir = ($ref) => {
|
|
172
154
|
let ref = $ref.replace(".", "/");
|
|
@@ -179,7 +161,11 @@ class ParserUtils {
|
|
|
179
161
|
return ref.slice(0, ref.lastIndexOf("/")).replace("#", ".");
|
|
180
162
|
}
|
|
181
163
|
};
|
|
182
|
-
static parseRefImport = (
|
|
164
|
+
static parseRefImport = (bodyParam) => {
|
|
165
|
+
const $ref = bodyParam?.schema?.$ref || bodyParam?.schema?.items?.$ref;
|
|
166
|
+
if (!$ref) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
183
169
|
const type = ParserUtils.parseRefType($ref);
|
|
184
170
|
return `import { ${type} } from './definitions/${type}'`;
|
|
185
171
|
};
|
|
@@ -189,60 +175,72 @@ class ParserUtils {
|
|
|
189
175
|
ref = ref.slice(0, -1);
|
|
190
176
|
}
|
|
191
177
|
const val = ref.slice(ref.lastIndexOf("/") + 1);
|
|
192
|
-
return
|
|
178
|
+
return _.upperFirst(_.camelCase(val)).replace(/( \w)/g, (group) => group.replace(" ", "").toUpperCase());
|
|
193
179
|
};
|
|
194
|
-
static parseAttributeType = (
|
|
180
|
+
static parseAttributeType = (definition) => {
|
|
195
181
|
const required = definition.required ? "" : "?";
|
|
196
|
-
const attrName = name.slice(name.lastIndexOf(".") + 1);
|
|
197
|
-
if (definition.
|
|
198
|
-
const enums = definition.
|
|
182
|
+
const attrName = definition.name.slice(definition.name.lastIndexOf(".") + 1);
|
|
183
|
+
if (definition.enum) {
|
|
184
|
+
const enums = definition.enum.map((enm) => definition.type === "string" ? `'${enm}'` : enm).join(" | ");
|
|
199
185
|
return `${attrName}${required}: ${enums}`;
|
|
200
186
|
}
|
|
201
|
-
if (definition.type && definition
|
|
187
|
+
if (definition.type && ParserUtils.parseType(definition) === "number") {
|
|
188
|
+
return `${attrName}${required}: number`;
|
|
189
|
+
}
|
|
190
|
+
if (definition?.schema?.type && ParserUtils.parseType(definition) === "number") {
|
|
202
191
|
return `${attrName}${required}: number`;
|
|
203
192
|
}
|
|
204
193
|
if (definition.type && definition.type === "array") {
|
|
205
194
|
return `${attrName}${required}: ${definition.items.type ?? "any"}[]`;
|
|
206
195
|
}
|
|
196
|
+
if (definition?.schema?.type && definition.schema.type === "array") {
|
|
197
|
+
return `${attrName}${required}: ${definition.schema.items.type ?? "any"}[]`;
|
|
198
|
+
}
|
|
207
199
|
if (definition.type && definition.type) {
|
|
208
200
|
return `${attrName}${required}: ${definition.type} | null`;
|
|
209
201
|
}
|
|
202
|
+
if (definition?.schema?.type && definition.schema.type) {
|
|
203
|
+
return `${attrName}${required}: ${definition.schema.type} | null`;
|
|
204
|
+
}
|
|
210
205
|
return `${attrName}${required}: any`;
|
|
211
206
|
};
|
|
212
207
|
static parseBodyParamsType = (bodyParams) => {
|
|
213
|
-
const [
|
|
214
|
-
if (!
|
|
208
|
+
const [bodyParam] = bodyParams;
|
|
209
|
+
if (!bodyParam)
|
|
215
210
|
return null;
|
|
216
|
-
if (bodyParams.length > 0 &&
|
|
217
|
-
let retBodyParams = `{${bodyParams.map((
|
|
211
|
+
if (bodyParams.length > 0 && bodyParam?.name !== "body" && !bodyParam?.schema) {
|
|
212
|
+
let retBodyParams = `{${bodyParams.map((bodyParam2) => ParserUtils.parseAttributeType(bodyParam2)).join(",")}}`;
|
|
218
213
|
retBodyParams = retBodyParams.replace("file?: file", "file?: File");
|
|
219
214
|
return retBodyParams;
|
|
220
215
|
}
|
|
221
|
-
if (
|
|
222
|
-
return `${
|
|
216
|
+
if (bodyParam?.schema?.type === "array" && !bodyParam?.schema?.items?.$ref) {
|
|
217
|
+
return `${bodyParam.schema.items.type ?? "any"}[]`;
|
|
223
218
|
}
|
|
224
|
-
if (
|
|
225
|
-
return `${ParserUtils.parseRefType(
|
|
219
|
+
if (bodyParam?.schema?.type === "array" && bodyParam?.schema?.items?.$ref) {
|
|
220
|
+
return `${ParserUtils.parseRefType(bodyParam.schema.items.$ref)}[]`;
|
|
226
221
|
}
|
|
227
|
-
if (
|
|
228
|
-
return ParserUtils.parseRefType(
|
|
222
|
+
if (bodyParam?.schema.$ref) {
|
|
223
|
+
return ParserUtils.parseRefType(bodyParam.schema.$ref);
|
|
229
224
|
}
|
|
230
|
-
if (
|
|
225
|
+
if (bodyParam?.schema?.additionalProperties?.type === "object") {
|
|
231
226
|
return "any";
|
|
232
227
|
}
|
|
233
228
|
return null;
|
|
234
229
|
};
|
|
235
|
-
static get2xxResponse(methodEntity
|
|
230
|
+
static get2xxResponse(methodEntity) {
|
|
236
231
|
const keys = Object.keys(methodEntity);
|
|
237
232
|
let responseClass = null;
|
|
238
233
|
keys.forEach((key) => {
|
|
239
234
|
if (String(key).startsWith("2")) {
|
|
240
235
|
const sch = methodEntity[key].schema;
|
|
236
|
+
const schV3 = methodEntity[key].content && methodEntity[key].content["application/json"].schema;
|
|
241
237
|
if (sch?.$ref) {
|
|
242
238
|
responseClass = ParserUtils.parseRefType(sch.$ref);
|
|
243
239
|
} else if (sch?.type === "array" && sch.items?.$ref) {
|
|
244
240
|
responseClass = ParserUtils.parseRefType(sch.items.$ref);
|
|
245
241
|
responseClass = `${responseClass}Array`;
|
|
242
|
+
} else if (schV3?.$ref) {
|
|
243
|
+
responseClass = ParserUtils.parseRefType(schV3.$ref);
|
|
246
244
|
} else ;
|
|
247
245
|
}
|
|
248
246
|
});
|
|
@@ -257,33 +255,32 @@ class ParserUtils {
|
|
|
257
255
|
}
|
|
258
256
|
return contentTypes.includes("application/x-www-form-urlencoded");
|
|
259
257
|
}
|
|
260
|
-
static
|
|
261
|
-
if (!
|
|
258
|
+
static filterPathParams(parameters) {
|
|
259
|
+
if (!parameters) {
|
|
262
260
|
return [];
|
|
263
261
|
}
|
|
264
|
-
|
|
265
|
-
for (const p of parametersArray) {
|
|
266
|
-
if (p.in === "path") {
|
|
267
|
-
res.push(p);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return res;
|
|
262
|
+
return parameters.filter((parameter) => parameter.in === "path");
|
|
271
263
|
}
|
|
272
|
-
static generateClassMethod(
|
|
264
|
+
static generateClassMethod({
|
|
265
|
+
path: path2,
|
|
266
|
+
endpoint,
|
|
267
|
+
httpMethod,
|
|
268
|
+
className
|
|
269
|
+
}) {
|
|
273
270
|
let replacedIdsPath = path2;
|
|
274
|
-
if (
|
|
275
|
-
for (const
|
|
276
|
-
if (
|
|
277
|
-
replacedIdsPath = replacedIdsPath.replace("{" +
|
|
271
|
+
if (endpoint.parameters) {
|
|
272
|
+
for (const parameter of endpoint.parameters) {
|
|
273
|
+
if (parameter.in === "path") {
|
|
274
|
+
replacedIdsPath = replacedIdsPath.replace("{" + parameter.name + "}", "By" + ParserUtils.toTitleCaseWord(parameter.name));
|
|
278
275
|
replacedIdsPath = replacedIdsPath.replace("/iam", "");
|
|
279
276
|
replacedIdsPath = replacedIdsPath.replace("/odin-config", "");
|
|
280
277
|
}
|
|
281
278
|
}
|
|
282
279
|
}
|
|
283
280
|
let classMethod = httpMethod + "/" + replacedIdsPath;
|
|
284
|
-
classMethod =
|
|
285
|
-
classMethod = classMethod.replace("PublicNamespacesByNamespace", "");
|
|
286
|
-
classMethod = classMethod.replace("AdminNamespacesByNamespace", "
|
|
281
|
+
classMethod = _.camelCase(classMethod);
|
|
282
|
+
classMethod = classMethod.replace("PublicNamespacesByNamespace", "Ns");
|
|
283
|
+
classMethod = classMethod.replace("AdminNamespacesByNamespace", "AdminNs");
|
|
287
284
|
const searchWord = "NamespacesByNamespace";
|
|
288
285
|
const nsExistInsideMethod = classMethod.indexOf(searchWord) > 0 && classMethod.indexOf(searchWord) + searchWord.length < classMethod.length;
|
|
289
286
|
const excludedClasses = ["Policies"];
|
|
@@ -292,45 +289,38 @@ class ParserUtils {
|
|
|
292
289
|
}
|
|
293
290
|
return classMethod;
|
|
294
291
|
}
|
|
295
|
-
static
|
|
296
|
-
if (
|
|
297
|
-
return
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return parametersArray.filter((p) => p.in === "body" || p.in === "formData");
|
|
292
|
+
static filterBodyParams(parameters) {
|
|
293
|
+
if (Array.isArray(parameters) && parameters.length > 0) {
|
|
294
|
+
return parameters.filter((parameter) => parameter.in === "body" || parameter.in === "formData");
|
|
295
|
+
}
|
|
296
|
+
return [];
|
|
301
297
|
}
|
|
302
|
-
static
|
|
303
|
-
if (!
|
|
298
|
+
static filterQueryParameters(parameters) {
|
|
299
|
+
if (!parameters) {
|
|
304
300
|
return [];
|
|
305
301
|
}
|
|
306
|
-
|
|
307
|
-
for (const p of parametersArray) {
|
|
308
|
-
if (p.in === "query") {
|
|
309
|
-
res.push(p);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return res;
|
|
302
|
+
return parameters.filter((parameter) => parameter.in === "query");
|
|
313
303
|
}
|
|
314
304
|
static mkdirIfNotExist(dirToCreate) {
|
|
315
|
-
if (!
|
|
316
|
-
|
|
305
|
+
if (!fs.existsSync(dirToCreate)) {
|
|
306
|
+
fs.mkdirSync(dirToCreate, { recursive: true });
|
|
317
307
|
}
|
|
318
308
|
}
|
|
319
309
|
static writeClassFile(distDir, apiName, apiBuffer, imports) {
|
|
320
310
|
const fileContent = templateClass(apiName, apiBuffer, imports);
|
|
321
|
-
|
|
311
|
+
fs.writeFileSync(`${distDir}/${apiName}.ts`, ParserUtils.prependCopyrightHeader(fileContent));
|
|
322
312
|
}
|
|
323
313
|
static writeJsdocFile(distDir, nameArray, apiBuffer) {
|
|
324
314
|
const jsdocFile = templateJsdocFile(nameArray[0], apiBuffer);
|
|
325
|
-
|
|
315
|
+
fs.writeFileSync(`${distDir}/docs/${nameArray[0]}.md`, jsdocFile);
|
|
326
316
|
}
|
|
327
317
|
static writeDefinitionFile(distDir, name, buffer) {
|
|
328
318
|
ParserUtils.mkdirIfNotExist(distDir);
|
|
329
|
-
|
|
319
|
+
fs.writeFileSync(path.join(distDir, `${name}.ts`), ParserUtils.prependCopyrightHeader(buffer));
|
|
330
320
|
}
|
|
331
321
|
static writeAllImportsFile(distDir, buffer, isAdminWebSdk) {
|
|
332
322
|
ParserUtils.mkdirIfNotExist(distDir);
|
|
333
|
-
|
|
323
|
+
fs.writeFileSync(path.join(distDir, `all-${isAdminWebSdk ? "admin" : "public"}-imports.ts`), ParserUtils.prependCopyrightHeader(buffer));
|
|
334
324
|
}
|
|
335
325
|
static toCamelCase(str) {
|
|
336
326
|
return str.split("/").map(function(word, index) {
|
|
@@ -356,24 +346,40 @@ class ParserUtils {
|
|
|
356
346
|
});
|
|
357
347
|
}
|
|
358
348
|
static applyPatchIfExists(swaggerFilePath, possibleSwaggerPatchFilePath, swaggerPatchedFilePath, swaggerPatchedDir) {
|
|
359
|
-
if (!
|
|
360
|
-
|
|
349
|
+
if (!fs.existsSync(swaggerPatchedDir)) {
|
|
350
|
+
fs.mkdirSync(swaggerPatchedDir, { recursive: true });
|
|
361
351
|
}
|
|
362
|
-
if (!
|
|
363
|
-
|
|
352
|
+
if (!fs.existsSync(possibleSwaggerPatchFilePath)) {
|
|
353
|
+
fs.copyFileSync(swaggerFilePath, swaggerPatchedFilePath);
|
|
364
354
|
return;
|
|
365
355
|
}
|
|
366
|
-
const swaggerContent = JSON.parse(
|
|
367
|
-
const swaggerPatchFileContent = JSON.parse(
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
356
|
+
const swaggerContent = JSON.parse(fs.readFileSync(swaggerFilePath, "utf8"));
|
|
357
|
+
const swaggerPatchFileContent = JSON.parse(fs.readFileSync(possibleSwaggerPatchFilePath, "utf8"));
|
|
358
|
+
for (const patchEntry of swaggerPatchFileContent) {
|
|
359
|
+
const segments = patchEntry.path.split("/").filter(Boolean);
|
|
360
|
+
let currentNode = swaggerContent;
|
|
361
|
+
let aggregatedPath = "";
|
|
362
|
+
for (let i = 0; i < segments.length; i++) {
|
|
363
|
+
const segment = segments[i];
|
|
364
|
+
aggregatedPath += `/${segment}`;
|
|
365
|
+
const effectiveSegment = segment.replace(/(~1)/g, "/").replace(/(~0)/g, "~");
|
|
366
|
+
if (!currentNode[effectiveSegment]) {
|
|
367
|
+
if (i + 1 === segments.length && patchEntry.op === "add") ; else {
|
|
368
|
+
throw new Error([
|
|
369
|
+
`JSON patch error: operation "${patchEntry.op}" on path "${aggregatedPath}" fails because the path doesn't exist in ${swaggerFilePath}. This may be caused by:
|
|
370
|
+
`,
|
|
371
|
+
"1. The related service has patched the service, so patch is no longer needed.",
|
|
372
|
+
"2. There is a breaking change on the service that causes the path to change.\n",
|
|
373
|
+
`In any case, revisit this file: "${possibleSwaggerPatchFilePath}", then try again.
|
|
374
|
+
`
|
|
375
|
+
].join("\n"));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
currentNode = currentNode[effectiveSegment];
|
|
379
|
+
}
|
|
375
380
|
}
|
|
376
|
-
|
|
381
|
+
const { newDocument } = fastJsonPatch.applyPatch(swaggerContent, swaggerPatchFileContent);
|
|
382
|
+
fs.writeFileSync(swaggerPatchedFilePath, JSON.stringify(newDocument, null, 2));
|
|
377
383
|
}
|
|
378
384
|
static getRelativePathToWebSdkSrcFolder(srcFolder, targetSrcFolder) {
|
|
379
385
|
const replaced = srcFolder.replace(/\\/g, "/");
|
|
@@ -390,7 +396,104 @@ ${content}`;
|
|
|
390
396
|
};
|
|
391
397
|
}
|
|
392
398
|
|
|
393
|
-
const
|
|
399
|
+
const Schema = zod.z.object({
|
|
400
|
+
$ref: zod.z.string().nullish(),
|
|
401
|
+
type: zod.z.union([zod.z.literal("array"), zod.z.literal("object"), zod.z.literal("file"), zod.z.literal("string"), zod.z.literal("boolean"), zod.z.literal("integer")]).nullish(),
|
|
402
|
+
items: zod.z.object({
|
|
403
|
+
$ref: zod.z.string().nullish(),
|
|
404
|
+
type: zod.z.string().nullish()
|
|
405
|
+
}).nullish(),
|
|
406
|
+
properties: zod.z.union([zod.z.array(zod.z.string()).nullish(), zod.z.record(zod.z.object({ type: zod.z.string() })).nullish()]),
|
|
407
|
+
description: zod.z.string().nullish(),
|
|
408
|
+
additionalProperties: zod.z.object({
|
|
409
|
+
type: zod.z.string().nullish()
|
|
410
|
+
}).nullish()
|
|
411
|
+
});
|
|
412
|
+
const Definition = zod.z.object({
|
|
413
|
+
required: zod.z.array(zod.z.string()).nullish(),
|
|
414
|
+
properties: zod.z.record(zod.z.object({
|
|
415
|
+
type: zod.z.string()
|
|
416
|
+
})).nullish()
|
|
417
|
+
});
|
|
418
|
+
const Definitions = zod.z.record(Definition);
|
|
419
|
+
const EndpointParametersType = zod.z.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
420
|
+
const EndpointParametersIn = zod.z.enum(["body", "formData", "header", "path", "query"]);
|
|
421
|
+
const EndpointParameters = zod.z.object({
|
|
422
|
+
type: EndpointParametersType.nullish(),
|
|
423
|
+
description: zod.z.string().nullish(),
|
|
424
|
+
name: zod.z.string(),
|
|
425
|
+
in: EndpointParametersIn,
|
|
426
|
+
required: zod.z.boolean().nullish(),
|
|
427
|
+
schema: Schema.nullish(),
|
|
428
|
+
default: zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number()]).nullish(),
|
|
429
|
+
enum: zod.z.array(zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number()])).nullish(),
|
|
430
|
+
items: zod.z.object({
|
|
431
|
+
type: zod.z.string()
|
|
432
|
+
}).nullish()
|
|
433
|
+
});
|
|
434
|
+
const Endpoint = zod.z.object({
|
|
435
|
+
description: zod.z.string().nullish(),
|
|
436
|
+
consumes: zod.z.array(zod.z.string()).nullish(),
|
|
437
|
+
produces: zod.z.array(zod.z.string()).nullish(),
|
|
438
|
+
tags: zod.z.array(zod.z.string()).nullish(),
|
|
439
|
+
summary: zod.z.string().nullish(),
|
|
440
|
+
operationId: zod.z.string(),
|
|
441
|
+
deprecated: zod.z.boolean().nullish(),
|
|
442
|
+
responses: zod.z.record(zod.z.object({
|
|
443
|
+
description: zod.z.string().nullish(),
|
|
444
|
+
schema: Schema.nullish(),
|
|
445
|
+
content: zod.z.object({
|
|
446
|
+
"application/json": zod.z.object({
|
|
447
|
+
schema: Schema.nullish()
|
|
448
|
+
})
|
|
449
|
+
}).nullish()
|
|
450
|
+
})),
|
|
451
|
+
parameters: zod.z.array(EndpointParameters).nullish(),
|
|
452
|
+
requestBody: zod.z.object({
|
|
453
|
+
required: zod.z.boolean(),
|
|
454
|
+
content: zod.z.object({
|
|
455
|
+
"application/json": zod.z.object({
|
|
456
|
+
schema: Schema.nullish()
|
|
457
|
+
})
|
|
458
|
+
}).nullish()
|
|
459
|
+
}).nullish()
|
|
460
|
+
});
|
|
461
|
+
const Operation = zod.z.object({
|
|
462
|
+
get: Endpoint.nullish(),
|
|
463
|
+
post: Endpoint.nullish(),
|
|
464
|
+
patch: Endpoint.nullish(),
|
|
465
|
+
delete: Endpoint.nullish(),
|
|
466
|
+
put: Endpoint.nullish()
|
|
467
|
+
});
|
|
468
|
+
const Paths = zod.z.record(Operation);
|
|
469
|
+
zod.z.object({
|
|
470
|
+
paths: Paths,
|
|
471
|
+
definitions: Definitions,
|
|
472
|
+
basePath: zod.z.string(),
|
|
473
|
+
info: zod.z.object({
|
|
474
|
+
description: zod.z.string(),
|
|
475
|
+
title: zod.z.string(),
|
|
476
|
+
contact: zod.z.object({
|
|
477
|
+
name: zod.z.string(),
|
|
478
|
+
url: zod.z.string(),
|
|
479
|
+
email: zod.z.string()
|
|
480
|
+
}),
|
|
481
|
+
version: zod.z.string()
|
|
482
|
+
}),
|
|
483
|
+
schemes: zod.z.array(zod.z.string()).nullish(),
|
|
484
|
+
components: zod.z.object({
|
|
485
|
+
schemas: Definitions
|
|
486
|
+
}).nullish()
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const templateJsdocMethod = ({
|
|
490
|
+
classMethod,
|
|
491
|
+
httpMethod,
|
|
492
|
+
path,
|
|
493
|
+
pathParams,
|
|
494
|
+
bodyParams,
|
|
495
|
+
queryParams
|
|
496
|
+
}) => {
|
|
394
497
|
let jsdoc = "";
|
|
395
498
|
let methodSignature = "";
|
|
396
499
|
let newPath = path;
|
|
@@ -427,21 +530,31 @@ const templateJsdocMethod = (classMethod, httpMethod, path, pathParams, bodyPara
|
|
|
427
530
|
`;
|
|
428
531
|
};
|
|
429
532
|
|
|
430
|
-
const templateMethod = (
|
|
533
|
+
const templateMethod = ({
|
|
534
|
+
classMethod,
|
|
535
|
+
description,
|
|
536
|
+
httpMethod,
|
|
537
|
+
path,
|
|
538
|
+
pathParams,
|
|
539
|
+
bodyParams,
|
|
540
|
+
queryParams,
|
|
541
|
+
isFormUrlEncoded,
|
|
542
|
+
responseClass
|
|
543
|
+
}) => {
|
|
431
544
|
let methodSignature = "";
|
|
432
545
|
let newPath = `'${path}'`;
|
|
433
546
|
let dependencies = [];
|
|
434
|
-
for (const
|
|
435
|
-
const type = ParserUtils.parseType(
|
|
436
|
-
if (
|
|
437
|
-
methodSignature +=
|
|
547
|
+
for (const pathParam of pathParams) {
|
|
548
|
+
const type = ParserUtils.parseType(pathParam);
|
|
549
|
+
if (pathParam.name !== "namespace") {
|
|
550
|
+
methodSignature += pathParam.name + `:${type}, `;
|
|
438
551
|
}
|
|
439
|
-
const pName =
|
|
440
|
-
if (path.match(`{${
|
|
552
|
+
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
553
|
+
if (path.match(`{${pathParam.name}}`)) {
|
|
441
554
|
if (type === "string") {
|
|
442
|
-
newPath = `${newPath}.replace('{${
|
|
555
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
443
556
|
} else {
|
|
444
|
-
newPath = `${newPath}.replace('{${
|
|
557
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', String(${pName}))`;
|
|
445
558
|
}
|
|
446
559
|
}
|
|
447
560
|
}
|
|
@@ -451,8 +564,8 @@ const templateMethod = (classMethod, description, httpMethod, path, pathParams,
|
|
|
451
564
|
dependencies = ParserUtils.parseBodyParamsImports(bodyParams);
|
|
452
565
|
methodSignature += dataType ? `data: ${dataType},` : "";
|
|
453
566
|
}
|
|
454
|
-
ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
455
|
-
const queryParamsType = queryParams.length ? `queryParams${"?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
567
|
+
const isAnyRequired = ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
568
|
+
const queryParamsType = queryParams.length ? `queryParams${isAnyRequired ? "" : "?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
456
569
|
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as SDKRequestConfig` : "const params = {} as SDKRequestConfig";
|
|
457
570
|
const isPostPutPatch = ["post", "put", "patch"].includes(httpMethod);
|
|
458
571
|
const isDelete = ["delete"].includes(httpMethod);
|
|
@@ -477,74 +590,30 @@ const templateMethod = (classMethod, description, httpMethod, path, pathParams,
|
|
|
477
590
|
const parameters = (queryParamsType ? `${methodSignature} ${queryParamsType}` : methodSignature).replace(/,\s*$/, "");
|
|
478
591
|
let methodImpl = "";
|
|
479
592
|
const isCacheFetch = ["get"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
480
|
-
const isCacheFetchUnknown = ["get"].includes(httpMethod) && resolvedResponseClass === "unknown";
|
|
481
593
|
const cachedFetchMethod = classMethod.replace("get", "fetch");
|
|
482
594
|
const deprecateTag = isCacheFetch ? `/**
|
|
483
595
|
* @deprecated Use "${cachedFetchMethod}()" instead.
|
|
484
596
|
*/` : "";
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
597
|
+
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
598
|
+
const methodName = httpMethod === "get" ? cachedFetchMethod : ["post", "put", "patch", "delete"].includes(httpMethod) ? classMethod : "";
|
|
599
|
+
const methodGenerics = resolvedResponseClass !== "unknown" ? `<T = ${resolvedResponseClass}>` : "";
|
|
600
|
+
const responseType = resolvedResponseClass !== "unknown" ? `T` : "unknown";
|
|
601
|
+
const responseSyncType = httpMethod === "get" ? "IResponseWithSync" : ["post", "put", "patch", "delete"].includes(httpMethod) ? "IResponse" : "";
|
|
602
|
+
methodImpl = `${descriptionText}
|
|
603
|
+
${methodName}${methodGenerics}(${parameters}): Promise<${responseSyncType}<${responseType}>> {
|
|
489
604
|
${queryParamsDefault}
|
|
490
605
|
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
491
606
|
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
492
|
-
|
|
493
|
-
const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
494
607
|
|
|
495
|
-
|
|
496
|
-
return SdkCache.withoutCache(res)
|
|
497
|
-
}
|
|
498
|
-
const key = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
499
|
-
return SdkCache.withCache(key, res)
|
|
500
|
-
}
|
|
501
|
-
`;
|
|
502
|
-
isGuardInvoked = true;
|
|
503
|
-
}
|
|
504
|
-
if (isCacheFetchUnknown) {
|
|
505
|
-
methodImpl = `${descriptionText}
|
|
506
|
-
${cachedFetchMethod}(${parameters}): Promise<IResponseWithSync<unknown>> {
|
|
507
|
-
${queryParamsDefault}
|
|
508
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
509
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
510
|
-
|
|
511
|
-
const res = () => Validate.responseType(() => resultPromise, z.unknown())
|
|
608
|
+
${httpMethod === "get" ? ` const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
512
609
|
|
|
513
610
|
if (!this.cache) {
|
|
514
611
|
return SdkCache.withoutCache(res)
|
|
515
612
|
}
|
|
516
|
-
const
|
|
517
|
-
return SdkCache.withCache(
|
|
613
|
+
const cacheKey = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
614
|
+
return SdkCache.withCache(cacheKey, res)` : ""}${["post", "put", "patch", "delete"].includes(httpMethod) ? ` return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})` : ""}
|
|
518
615
|
}
|
|
519
616
|
`;
|
|
520
|
-
isGuardInvoked = true;
|
|
521
|
-
}
|
|
522
|
-
const withTypeGuard = ["post", "put", "patch", "delete"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
523
|
-
if (withTypeGuard) {
|
|
524
|
-
methodImpl = `${descriptionText}
|
|
525
|
-
${classMethod}<T = ${resolvedResponseClass}>(${parameters}): Promise<IResponse<T>> {
|
|
526
|
-
${queryParamsDefault}
|
|
527
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
528
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
529
|
-
|
|
530
|
-
return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
531
|
-
}
|
|
532
|
-
`;
|
|
533
|
-
isGuardInvoked = true;
|
|
534
|
-
}
|
|
535
|
-
const withTypeGuardUnknown = ["post", "put", "patch", "delete"].includes(httpMethod) && resolvedResponseClass === "unknown";
|
|
536
|
-
if (withTypeGuardUnknown) {
|
|
537
|
-
methodImpl = `${descriptionText}
|
|
538
|
-
${classMethod}(${parameters}): Promise<IResponse<unknown>> {
|
|
539
|
-
${queryParamsDefault}
|
|
540
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
541
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
542
|
-
|
|
543
|
-
return Validate.responseType(() => resultPromise, z.unknown())
|
|
544
|
-
}
|
|
545
|
-
`;
|
|
546
|
-
isGuardInvoked = true;
|
|
547
|
-
}
|
|
548
617
|
if (!isGuardInvoked) {
|
|
549
618
|
methodImpl = `${descriptionText}
|
|
550
619
|
${deprecateTag}
|
|
@@ -562,41 +631,41 @@ class TemplateZod {
|
|
|
562
631
|
duplicates;
|
|
563
632
|
duplicateFound = false;
|
|
564
633
|
importClasses = /* @__PURE__ */ new Set();
|
|
565
|
-
render = (
|
|
634
|
+
render = (fileName, definition, duplicates) => {
|
|
566
635
|
this.duplicates = duplicates;
|
|
567
636
|
const content = this.parseToZodSchema(definition, definition.required || []);
|
|
568
|
-
const containsRecursiveType = this.importClasses.has(
|
|
637
|
+
const containsRecursiveType = this.importClasses.has(fileName);
|
|
569
638
|
if (containsRecursiveType) {
|
|
570
|
-
this.importClasses.delete(
|
|
639
|
+
this.importClasses.delete(fileName);
|
|
571
640
|
}
|
|
572
641
|
let imports = "";
|
|
573
642
|
for (const cl of Array.from(this.importClasses).sort()) {
|
|
574
|
-
imports += `
|
|
643
|
+
imports += `import { ${cl} } from './${cl}'
|
|
575
644
|
`;
|
|
576
645
|
}
|
|
577
646
|
let exportedVariableString;
|
|
578
647
|
let exportedTypeString;
|
|
579
648
|
if (containsRecursiveType) {
|
|
580
649
|
exportedVariableString = `
|
|
581
|
-
|
|
650
|
+
export const ${fileName}: z.ZodType<${fileName}> = z.lazy(() =>
|
|
582
651
|
${content.schemaString}
|
|
583
652
|
)
|
|
584
653
|
`;
|
|
585
654
|
exportedTypeString = `
|
|
586
|
-
|
|
655
|
+
export interface ${fileName} {
|
|
587
656
|
${content.typeString}
|
|
588
|
-
|
|
589
|
-
|
|
657
|
+
}
|
|
658
|
+
`;
|
|
590
659
|
} else {
|
|
591
|
-
exportedVariableString = `export const ${
|
|
592
|
-
exportedTypeString = `export
|
|
660
|
+
exportedVariableString = `export const ${fileName} = ${content.schemaString}`;
|
|
661
|
+
exportedTypeString = `export interface ${fileName} extends z.TypeOf<typeof ${fileName}> {}`;
|
|
593
662
|
}
|
|
594
663
|
const template = `import { z } from 'zod'
|
|
595
|
-
|
|
664
|
+
${imports}
|
|
596
665
|
|
|
597
|
-
|
|
666
|
+
${exportedVariableString}
|
|
598
667
|
|
|
599
|
-
|
|
668
|
+
${exportedTypeString}
|
|
600
669
|
`;
|
|
601
670
|
return { buffer: template, duplicateFound: this.duplicateFound };
|
|
602
671
|
};
|
|
@@ -604,13 +673,17 @@ class TemplateZod {
|
|
|
604
673
|
if (definition.additionalProperties) {
|
|
605
674
|
return this.parseToZodAttribute("", definition, []);
|
|
606
675
|
}
|
|
607
|
-
|
|
676
|
+
let properties;
|
|
677
|
+
if (definition.properties) {
|
|
678
|
+
properties = Object.entries(definition.properties);
|
|
679
|
+
} else if (definition.items?.properties) {
|
|
680
|
+
properties = Object.entries(definition.items.properties);
|
|
681
|
+
} else {
|
|
608
682
|
return {
|
|
609
683
|
schemaString: "z.any()",
|
|
610
684
|
typeString: "any"
|
|
611
685
|
};
|
|
612
686
|
}
|
|
613
|
-
const properties = Object.entries(definition.properties);
|
|
614
687
|
const schemaFields = [];
|
|
615
688
|
const typeFields = [];
|
|
616
689
|
for (const property of properties) {
|
|
@@ -619,6 +692,12 @@ class TemplateZod {
|
|
|
619
692
|
schemaFields.push(result.schemaString);
|
|
620
693
|
typeFields.push(result.typeString);
|
|
621
694
|
}
|
|
695
|
+
if (definition?.type === "array") {
|
|
696
|
+
return {
|
|
697
|
+
schemaString: `z.array(z.object({${schemaFields.join(",")}}))`,
|
|
698
|
+
typeString: typeFields.join(";")
|
|
699
|
+
};
|
|
700
|
+
}
|
|
622
701
|
return {
|
|
623
702
|
schemaString: `z.object({${schemaFields.join(",")}})`,
|
|
624
703
|
typeString: typeFields.join(";")
|
|
@@ -660,7 +739,8 @@ class TemplateZod {
|
|
|
660
739
|
};
|
|
661
740
|
}
|
|
662
741
|
if (type === "array") {
|
|
663
|
-
const
|
|
742
|
+
const items = definition.items;
|
|
743
|
+
const ref2 = items?.$ref;
|
|
664
744
|
let model2;
|
|
665
745
|
if (ref2) {
|
|
666
746
|
const refType = ParserUtils.parseRefType(ref2);
|
|
@@ -669,9 +749,13 @@ class TemplateZod {
|
|
|
669
749
|
schemaString: refType,
|
|
670
750
|
typeString: refType
|
|
671
751
|
};
|
|
672
|
-
} else {
|
|
673
|
-
const items = definition.items;
|
|
752
|
+
} else if (items) {
|
|
674
753
|
model2 = this.parseEnumItems(items);
|
|
754
|
+
} else {
|
|
755
|
+
return {
|
|
756
|
+
schemaString: `${schemaAttribute} z.array(z.any())${schemaRequired}`,
|
|
757
|
+
typeString: `${typeAttribute} any[]${typeNullishability}`
|
|
758
|
+
};
|
|
675
759
|
}
|
|
676
760
|
return {
|
|
677
761
|
schemaString: `${schemaAttribute} z.array(${model2.schemaString})${schemaRequired}`,
|
|
@@ -738,11 +822,11 @@ class TemplateZodArray {
|
|
|
738
822
|
render = (name) => {
|
|
739
823
|
const cls = name.replace("Array", "");
|
|
740
824
|
const template = `import { z } from 'zod'
|
|
741
|
-
|
|
825
|
+
import { ${cls} } from './${cls}'
|
|
742
826
|
|
|
743
|
-
|
|
827
|
+
export const ${name} = z.array(${cls})
|
|
744
828
|
|
|
745
|
-
|
|
829
|
+
export interface ${name} extends z.TypeOf<typeof ${name}> {}
|
|
746
830
|
`;
|
|
747
831
|
return template;
|
|
748
832
|
};
|
|
@@ -778,10 +862,10 @@ const extractEnumObject = (type, isRequired, enumArr) => {
|
|
|
778
862
|
};
|
|
779
863
|
|
|
780
864
|
class CodeGenerator {
|
|
781
|
-
static getPatchedDir = () =>
|
|
865
|
+
static getPatchedDir = () => path.join(CliParser.getSwaggersOutputPath(), "patched");
|
|
782
866
|
static getGeneratedPublicFolder = () => `${CliParser.getOutputPath()}/generated-public`;
|
|
783
867
|
static getGeneratedAdminFolder = () => `${CliParser.getOutputPath()}/generated-admin`;
|
|
784
|
-
static iterateApi = (api) => {
|
|
868
|
+
static iterateApi = async (api) => {
|
|
785
869
|
const apiBufferByTag = {};
|
|
786
870
|
const jsDocApiBufferByTag = {};
|
|
787
871
|
const dependenciesByTag = {};
|
|
@@ -794,15 +878,21 @@ class CodeGenerator {
|
|
|
794
878
|
} else if (!CliParser.isAdmin() && isAdminEndpoint) {
|
|
795
879
|
continue;
|
|
796
880
|
}
|
|
797
|
-
const
|
|
798
|
-
const
|
|
799
|
-
for (const httpMethod of
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
881
|
+
const operation = api.paths[path2];
|
|
882
|
+
const httpMethods = Object.keys(operation);
|
|
883
|
+
for (const httpMethod of httpMethods) {
|
|
884
|
+
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
885
|
+
console.error(JSON.stringify({ path: path2, httpMethod }, null, 2));
|
|
886
|
+
throw error;
|
|
887
|
+
});
|
|
888
|
+
if (!endpoint.tags) {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
const [tag] = endpoint.tags;
|
|
892
|
+
const description = endpoint.description;
|
|
893
|
+
const isDeprecated = endpoint.deprecated;
|
|
894
|
+
const responseClass = ParserUtils.get2xxResponse(endpoint.responses);
|
|
895
|
+
const className = _.upperFirst(_.camelCase(tag));
|
|
806
896
|
classImports[className] = classImports[className] ? classImports[className] : {};
|
|
807
897
|
if (!isDeprecated) {
|
|
808
898
|
if (responseClass) {
|
|
@@ -812,15 +902,39 @@ class CodeGenerator {
|
|
|
812
902
|
if (responseClass && responseClass.endsWith("Array")) {
|
|
813
903
|
arrayDefinitions.push(responseClass);
|
|
814
904
|
}
|
|
815
|
-
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod,
|
|
816
|
-
const queryParams = ParserUtils.
|
|
817
|
-
const pathParams = ParserUtils.
|
|
818
|
-
|
|
819
|
-
const classMethod = ParserUtils.generateClassMethod(
|
|
820
|
-
|
|
821
|
-
|
|
905
|
+
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod, endpoint.consumes);
|
|
906
|
+
const queryParams = ParserUtils.filterQueryParameters(endpoint.parameters);
|
|
907
|
+
const pathParams = ParserUtils.filterPathParams(endpoint.parameters);
|
|
908
|
+
let bodyParams = ParserUtils.filterBodyParams(endpoint.parameters);
|
|
909
|
+
const classMethod = ParserUtils.generateClassMethod({
|
|
910
|
+
path: path2,
|
|
911
|
+
endpoint,
|
|
912
|
+
httpMethod,
|
|
913
|
+
className
|
|
914
|
+
});
|
|
915
|
+
if (endpoint.requestBody) {
|
|
916
|
+
bodyParams = [
|
|
917
|
+
{
|
|
918
|
+
name: "body",
|
|
919
|
+
in: "body",
|
|
920
|
+
schema: endpoint.requestBody.content["application/json"].schema
|
|
921
|
+
}
|
|
922
|
+
];
|
|
923
|
+
}
|
|
924
|
+
const pathWithBase = `${api.basePath ?? ""}${path2}`;
|
|
925
|
+
const [generatedMethodString, importStatements] = templateMethod({
|
|
926
|
+
classMethod,
|
|
927
|
+
description,
|
|
928
|
+
httpMethod,
|
|
929
|
+
path: pathWithBase,
|
|
930
|
+
pathParams,
|
|
931
|
+
bodyParams,
|
|
932
|
+
queryParams,
|
|
933
|
+
isFormUrlEncoded,
|
|
934
|
+
responseClass
|
|
935
|
+
});
|
|
822
936
|
apiBufferByTag[tag] = (apiBufferByTag[tag] || "") + generatedMethodString;
|
|
823
|
-
jsDocApiBufferByTag[tag] = (jsDocApiBufferByTag[tag] || "") + templateJsdocMethod(classMethod, httpMethod, path2, pathParams, bodyParams, queryParams);
|
|
937
|
+
jsDocApiBufferByTag[tag] = (jsDocApiBufferByTag[tag] || "") + templateJsdocMethod({ classMethod, httpMethod, path: path2, pathParams, bodyParams, queryParams });
|
|
824
938
|
dependenciesByTag[tag] = dependenciesByTag[tag] ? [.../* @__PURE__ */ new Set([...importStatements, ...dependenciesByTag[tag]])] : [...new Set(importStatements)];
|
|
825
939
|
}
|
|
826
940
|
}
|
|
@@ -831,11 +945,11 @@ class CodeGenerator {
|
|
|
831
945
|
static main = async (nameArray) => {
|
|
832
946
|
const serviceName = nameArray[0];
|
|
833
947
|
const swaggerFile = nameArray[2];
|
|
834
|
-
const parser = new
|
|
948
|
+
const parser = new SwaggerParser();
|
|
835
949
|
const generatedFolder = CliParser.isAdmin() ? CodeGenerator.getGeneratedAdminFolder() : CodeGenerator.getGeneratedPublicFolder();
|
|
836
950
|
const DIST_DIR = `${generatedFolder}/${serviceName}`;
|
|
837
|
-
const DIST_DOCS_DIR =
|
|
838
|
-
const DIST_DEFINITION_DIR =
|
|
951
|
+
const DIST_DOCS_DIR = path.join(DIST_DIR, "docs");
|
|
952
|
+
const DIST_DEFINITION_DIR = path.join(DIST_DIR, "definitions");
|
|
839
953
|
const swaggerFilePath = `${CliParser.getSwaggersOutputPath()}/${swaggerFile}`;
|
|
840
954
|
const swaggerPatchedFilePath = `${CodeGenerator.getPatchedDir()}/${swaggerFile}`;
|
|
841
955
|
const swaggerPatchFilePath = `${swaggerFilePath}patch`;
|
|
@@ -846,42 +960,43 @@ class CodeGenerator {
|
|
|
846
960
|
ParserUtils.mkdirIfNotExist(DIST_DIR);
|
|
847
961
|
ParserUtils.mkdirIfNotExist(DIST_DOCS_DIR);
|
|
848
962
|
ParserUtils.mkdirIfNotExist(DIST_DEFINITION_DIR);
|
|
849
|
-
const { apiBufferByTag, dependenciesByTag, classImports, arrayDefinitions } = CodeGenerator.iterateApi(api);
|
|
963
|
+
const { apiBufferByTag, dependenciesByTag, classImports, arrayDefinitions } = await CodeGenerator.iterateApi(api);
|
|
850
964
|
const targetSrcFolder = `${CliParser.getOutputPath()}/`;
|
|
851
965
|
for (const tag in apiBufferByTag) {
|
|
852
|
-
const className =
|
|
966
|
+
const className = _.upperFirst(_.camelCase(tag));
|
|
853
967
|
const apiBuffer = apiBufferByTag[tag];
|
|
854
968
|
const imports = [.../* @__PURE__ */ new Set([...dependenciesByTag[tag], ...Object.values(classImports[className])])];
|
|
855
969
|
const classGenName = CliParser.isAdmin() ? className + "Admin$" : className + "$";
|
|
856
970
|
ParserUtils.writeClassFile(DIST_DIR, classGenName, apiBuffer, imports);
|
|
857
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
971
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_DIR, `${classGenName}`), targetSrcFolder));
|
|
858
972
|
}
|
|
859
973
|
const duplicates = /* @__PURE__ */ new Map();
|
|
860
|
-
|
|
861
|
-
|
|
974
|
+
const definitions = api?.components?.schemas || api.definitions;
|
|
975
|
+
for (const ref in definitions) {
|
|
976
|
+
const definition = definitions[ref];
|
|
862
977
|
let fileName = ParserUtils.parseRefType(ref);
|
|
863
|
-
const fileExist =
|
|
978
|
+
const fileExist = fs.existsSync(path.join(DIST_DEFINITION_DIR, `${fileName}.ts`));
|
|
864
979
|
if (fileExist) {
|
|
865
980
|
fileName = ParserUtils.toCamelCaseWord(ref).replace(".", "").replace(".", "");
|
|
866
981
|
duplicates.set(ref, fileName);
|
|
867
982
|
}
|
|
868
983
|
const { buffer } = new TemplateZod().render(fileName, definition, /* @__PURE__ */ new Map());
|
|
869
984
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, fileName, buffer);
|
|
870
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
985
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_DEFINITION_DIR, fileName), targetSrcFolder));
|
|
871
986
|
}
|
|
872
|
-
for (const ref in
|
|
873
|
-
const definition =
|
|
987
|
+
for (const ref in definitions) {
|
|
988
|
+
const definition = definitions[ref];
|
|
874
989
|
const fileName = ParserUtils.parseRefType(ref);
|
|
875
990
|
const { buffer, duplicateFound } = new TemplateZod().render(fileName, definition, duplicates);
|
|
876
991
|
if (duplicateFound) {
|
|
877
992
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, fileName, buffer);
|
|
878
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
993
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_DEFINITION_DIR, fileName), targetSrcFolder));
|
|
879
994
|
}
|
|
880
995
|
}
|
|
881
996
|
for (const arrayClass of arrayDefinitions) {
|
|
882
997
|
const buffer = new TemplateZodArray().render(arrayClass);
|
|
883
998
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, arrayClass, buffer);
|
|
884
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
999
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_DEFINITION_DIR, arrayClass), targetSrcFolder));
|
|
885
1000
|
}
|
|
886
1001
|
console.log("\n----------\nCOMPLETED.\n----------\n\n");
|
|
887
1002
|
return indexImportsSet;
|
|
@@ -924,7 +1039,7 @@ class SwaggerDownloader {
|
|
|
924
1039
|
};
|
|
925
1040
|
}
|
|
926
1041
|
|
|
927
|
-
|
|
1042
|
+
yargs.command("download-swaggers", "Download swaggers JSON files", (yargs2) => {
|
|
928
1043
|
CliParser.createInstance(yargs2);
|
|
929
1044
|
SwaggerDownloader.main();
|
|
930
1045
|
}).command("generate-code", "Generate code based on downloaded swagger files", async (yargs2) => {
|
|
@@ -940,7 +1055,7 @@ yargs__default["default"].command("download-swaggers", "Download swaggers JSON f
|
|
|
940
1055
|
const filenamesSet = /* @__PURE__ */ new Set();
|
|
941
1056
|
for (const set of arrayOfSets) {
|
|
942
1057
|
set.forEach((value) => {
|
|
943
|
-
const fileName =
|
|
1058
|
+
const fileName = path.basename(value);
|
|
944
1059
|
if (!filenamesSet.has(fileName)) {
|
|
945
1060
|
indexImportsSet.add(value);
|
|
946
1061
|
filenamesSet.add(fileName);
|