@accelbyte/codegen 1.0.0-alpha.3 → 1.0.0-alpha.7
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/dist/accelbyte-codegen.js +280 -221
- package/dist/accelbyte-codegen.js.map +1 -1
- package/dist/accelbyte-codegen.mjs +246 -177
- package/dist/accelbyte-codegen.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -98,44 +98,30 @@ ${body}
|
|
|
98
98
|
`.replace(/, \)/g, ")").trim();
|
|
99
99
|
|
|
100
100
|
class ParserUtils {
|
|
101
|
-
static parseQueryParamAttributeDefault = (
|
|
102
|
-
const attrName = name.slice(name.lastIndexOf(".") + 1);
|
|
101
|
+
static parseQueryParamAttributeDefault = (definition) => {
|
|
102
|
+
const attrName = definition.name.slice(definition.name.lastIndexOf(".") + 1);
|
|
103
103
|
const defaultValue = definition.type === "string" ? `'${definition.default}'` : definition.default;
|
|
104
104
|
return `${attrName}: ${defaultValue}`;
|
|
105
105
|
};
|
|
106
|
-
static parseType = (
|
|
107
|
-
if (type === "integer")
|
|
106
|
+
static parseType = (pathParam) => {
|
|
107
|
+
if (pathParam.type === "int" || pathParam.type === "integer")
|
|
108
108
|
return "number";
|
|
109
|
-
if (type === "array")
|
|
110
|
-
return "any[]
|
|
111
|
-
return type;
|
|
109
|
+
if (pathParam.type === "array")
|
|
110
|
+
return `${pathParam.items.type ?? "any"}[]`;
|
|
111
|
+
return pathParam.type;
|
|
112
112
|
};
|
|
113
113
|
static parseQueryParamsType = (queryParams) => {
|
|
114
|
-
return queryParams.map((
|
|
114
|
+
return queryParams.map((queryParam) => ParserUtils.parseAttributeType(queryParam)).join(",");
|
|
115
115
|
};
|
|
116
116
|
static isAnyQueryParamRequired = (queryParams) => {
|
|
117
|
-
queryParams.
|
|
118
|
-
if (p.required) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
return false;
|
|
117
|
+
return queryParams.some((queryParam) => queryParam.required);
|
|
123
118
|
};
|
|
124
119
|
static parseQueryParamsDefault = (queryParams) => {
|
|
125
|
-
const result = queryParams.filter((
|
|
120
|
+
const result = queryParams.filter((queryParam) => !!queryParam.default && !queryParam.required).map(ParserUtils.parseQueryParamAttributeDefault).join(",");
|
|
126
121
|
return result ? `${result},` : "";
|
|
127
122
|
};
|
|
128
123
|
static parseBodyParamsImports = (bodyParams) => {
|
|
129
|
-
|
|
130
|
-
if (p?.schema?.$ref)
|
|
131
|
-
return ParserUtils.parseRefImport(p.schema.$ref, p);
|
|
132
|
-
if (p?.schema?.items?.$ref)
|
|
133
|
-
return ParserUtils.parseRefImport(p.schema.items.$ref, p);
|
|
134
|
-
if (p?.$ref)
|
|
135
|
-
return ParserUtils.parseRefImport(p.$ref, p);
|
|
136
|
-
return null;
|
|
137
|
-
}).filter((p) => !!p);
|
|
138
|
-
return ret;
|
|
124
|
+
return bodyParams.map(ParserUtils.parseRefImport).filter(Boolean);
|
|
139
125
|
};
|
|
140
126
|
static parseImportDir = ($ref) => {
|
|
141
127
|
let ref = $ref.replace(".", "/");
|
|
@@ -148,7 +134,11 @@ class ParserUtils {
|
|
|
148
134
|
return ref.slice(0, ref.lastIndexOf("/")).replace("#", ".");
|
|
149
135
|
}
|
|
150
136
|
};
|
|
151
|
-
static parseRefImport = (
|
|
137
|
+
static parseRefImport = (bodyParam) => {
|
|
138
|
+
const $ref = bodyParam?.schema?.$ref || bodyParam?.schema?.items?.$ref;
|
|
139
|
+
if (!$ref) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
152
142
|
const type = ParserUtils.parseRefType($ref);
|
|
153
143
|
return `import { ${type} } from './definitions/${type}'`;
|
|
154
144
|
};
|
|
@@ -158,60 +148,72 @@ class ParserUtils {
|
|
|
158
148
|
ref = ref.slice(0, -1);
|
|
159
149
|
}
|
|
160
150
|
const val = ref.slice(ref.lastIndexOf("/") + 1);
|
|
161
|
-
return _.upperFirst(_.camelCase(val));
|
|
151
|
+
return _.upperFirst(_.camelCase(val)).replace(/( \w)/g, (group) => group.replace(" ", "").toUpperCase());
|
|
162
152
|
};
|
|
163
|
-
static parseAttributeType = (
|
|
153
|
+
static parseAttributeType = (definition) => {
|
|
164
154
|
const required = definition.required ? "" : "?";
|
|
165
|
-
const attrName = name.slice(name.lastIndexOf(".") + 1);
|
|
166
|
-
if (definition.
|
|
167
|
-
const enums = definition.
|
|
155
|
+
const attrName = definition.name.slice(definition.name.lastIndexOf(".") + 1);
|
|
156
|
+
if (definition.enum) {
|
|
157
|
+
const enums = definition.enum.map((enm) => definition.type === "string" ? `'${enm}'` : enm).join(" | ");
|
|
168
158
|
return `${attrName}${required}: ${enums}`;
|
|
169
159
|
}
|
|
170
|
-
if (definition.type && definition
|
|
160
|
+
if (definition.type && ParserUtils.parseType(definition) === "number") {
|
|
161
|
+
return `${attrName}${required}: number`;
|
|
162
|
+
}
|
|
163
|
+
if (definition?.schema?.type && ParserUtils.parseType(definition.schema) === "number") {
|
|
171
164
|
return `${attrName}${required}: number`;
|
|
172
165
|
}
|
|
173
166
|
if (definition.type && definition.type === "array") {
|
|
174
167
|
return `${attrName}${required}: ${definition.items.type ?? "any"}[]`;
|
|
175
168
|
}
|
|
169
|
+
if (definition?.schema?.type && definition.schema.type === "array") {
|
|
170
|
+
return `${attrName}${required}: ${definition.schema.items.type ?? "any"}[]`;
|
|
171
|
+
}
|
|
176
172
|
if (definition.type && definition.type) {
|
|
177
173
|
return `${attrName}${required}: ${definition.type} | null`;
|
|
178
174
|
}
|
|
175
|
+
if (definition?.schema?.type && definition.schema.type) {
|
|
176
|
+
return `${attrName}${required}: ${definition.schema.type} | null`;
|
|
177
|
+
}
|
|
179
178
|
return `${attrName}${required}: any`;
|
|
180
179
|
};
|
|
181
180
|
static parseBodyParamsType = (bodyParams) => {
|
|
182
|
-
const [
|
|
183
|
-
if (!
|
|
181
|
+
const [bodyParam] = bodyParams;
|
|
182
|
+
if (!bodyParam)
|
|
184
183
|
return null;
|
|
185
|
-
if (bodyParams.length > 0 &&
|
|
186
|
-
let retBodyParams = `{${bodyParams.map((
|
|
184
|
+
if (bodyParams.length > 0 && bodyParam?.name !== "body" && !bodyParam?.schema) {
|
|
185
|
+
let retBodyParams = `{${bodyParams.map((bodyParam2) => ParserUtils.parseAttributeType(bodyParam2)).join(",")}}`;
|
|
187
186
|
retBodyParams = retBodyParams.replace("file?: file", "file?: File");
|
|
188
187
|
return retBodyParams;
|
|
189
188
|
}
|
|
190
|
-
if (
|
|
191
|
-
return `${
|
|
189
|
+
if (bodyParam?.schema?.type === "array" && !bodyParam?.schema?.items?.$ref) {
|
|
190
|
+
return `${bodyParam.schema.items.type ?? "any"}[]`;
|
|
192
191
|
}
|
|
193
|
-
if (
|
|
194
|
-
return `${ParserUtils.parseRefType(
|
|
192
|
+
if (bodyParam?.schema?.type === "array" && bodyParam?.schema?.items?.$ref) {
|
|
193
|
+
return `${ParserUtils.parseRefType(bodyParam.schema.items.$ref)}[]`;
|
|
195
194
|
}
|
|
196
|
-
if (
|
|
197
|
-
return ParserUtils.parseRefType(
|
|
195
|
+
if (bodyParam?.schema.$ref) {
|
|
196
|
+
return ParserUtils.parseRefType(bodyParam.schema.$ref);
|
|
198
197
|
}
|
|
199
|
-
if (
|
|
198
|
+
if (bodyParam?.schema?.additionalProperties?.type === "object") {
|
|
200
199
|
return "any";
|
|
201
200
|
}
|
|
202
201
|
return null;
|
|
203
202
|
};
|
|
204
|
-
static get2xxResponse(methodEntity
|
|
203
|
+
static get2xxResponse(methodEntity) {
|
|
205
204
|
const keys = Object.keys(methodEntity);
|
|
206
205
|
let responseClass = null;
|
|
207
206
|
keys.forEach((key) => {
|
|
208
207
|
if (String(key).startsWith("2")) {
|
|
209
208
|
const sch = methodEntity[key].schema;
|
|
209
|
+
const schV3 = methodEntity[key].content && methodEntity[key].content["application/json"].schema;
|
|
210
210
|
if (sch?.$ref) {
|
|
211
211
|
responseClass = ParserUtils.parseRefType(sch.$ref);
|
|
212
212
|
} else if (sch?.type === "array" && sch.items?.$ref) {
|
|
213
213
|
responseClass = ParserUtils.parseRefType(sch.items.$ref);
|
|
214
214
|
responseClass = `${responseClass}Array`;
|
|
215
|
+
} else if (schV3?.$ref) {
|
|
216
|
+
responseClass = ParserUtils.parseRefType(schV3.$ref);
|
|
215
217
|
} else ;
|
|
216
218
|
}
|
|
217
219
|
});
|
|
@@ -226,24 +228,23 @@ class ParserUtils {
|
|
|
226
228
|
}
|
|
227
229
|
return contentTypes.includes("application/x-www-form-urlencoded");
|
|
228
230
|
}
|
|
229
|
-
static
|
|
230
|
-
if (!
|
|
231
|
+
static filterPathParams(parameters) {
|
|
232
|
+
if (!parameters) {
|
|
231
233
|
return [];
|
|
232
234
|
}
|
|
233
|
-
|
|
234
|
-
for (const p of parametersArray) {
|
|
235
|
-
if (p.in === "path") {
|
|
236
|
-
res.push(p);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return res;
|
|
235
|
+
return parameters.filter((parameter) => parameter.in === "path");
|
|
240
236
|
}
|
|
241
|
-
static generateClassMethod(
|
|
237
|
+
static generateClassMethod({
|
|
238
|
+
path: path2,
|
|
239
|
+
endpoint,
|
|
240
|
+
httpMethod,
|
|
241
|
+
className
|
|
242
|
+
}) {
|
|
242
243
|
let replacedIdsPath = path2;
|
|
243
|
-
if (
|
|
244
|
-
for (const
|
|
245
|
-
if (
|
|
246
|
-
replacedIdsPath = replacedIdsPath.replace("{" +
|
|
244
|
+
if (endpoint.parameters) {
|
|
245
|
+
for (const parameter of endpoint.parameters) {
|
|
246
|
+
if (parameter.in === "path") {
|
|
247
|
+
replacedIdsPath = replacedIdsPath.replace("{" + parameter.name + "}", "By" + ParserUtils.toTitleCaseWord(parameter.name));
|
|
247
248
|
replacedIdsPath = replacedIdsPath.replace("/iam", "");
|
|
248
249
|
replacedIdsPath = replacedIdsPath.replace("/odin-config", "");
|
|
249
250
|
}
|
|
@@ -261,24 +262,17 @@ class ParserUtils {
|
|
|
261
262
|
}
|
|
262
263
|
return classMethod;
|
|
263
264
|
}
|
|
264
|
-
static
|
|
265
|
-
if (
|
|
266
|
-
return
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return parametersArray.filter((p) => p.in === "body" || p.in === "formData");
|
|
265
|
+
static filterBodyParams(parameters) {
|
|
266
|
+
if (Array.isArray(parameters) && parameters.length > 0) {
|
|
267
|
+
return parameters.filter((parameter) => parameter.in === "body" || parameter.in === "formData");
|
|
268
|
+
}
|
|
269
|
+
return [];
|
|
270
270
|
}
|
|
271
|
-
static
|
|
272
|
-
if (!
|
|
271
|
+
static filterQueryParameters(parameters) {
|
|
272
|
+
if (!parameters) {
|
|
273
273
|
return [];
|
|
274
274
|
}
|
|
275
|
-
|
|
276
|
-
for (const p of parametersArray) {
|
|
277
|
-
if (p.in === "query") {
|
|
278
|
-
res.push(p);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return res;
|
|
275
|
+
return parameters.filter((parameter) => parameter.in === "query");
|
|
282
276
|
}
|
|
283
277
|
static mkdirIfNotExist(dirToCreate) {
|
|
284
278
|
if (!fs__default.existsSync(dirToCreate)) {
|
|
@@ -337,13 +331,6 @@ class ParserUtils {
|
|
|
337
331
|
const { newDocument } = applyPatch(swaggerContent, swaggerPatchFileContent);
|
|
338
332
|
fs__default.writeFileSync(swaggerPatchedFilePath, JSON.stringify(newDocument, null, 2));
|
|
339
333
|
}
|
|
340
|
-
static mapKeys(map_) {
|
|
341
|
-
const methods_ = [];
|
|
342
|
-
for (const m in map_) {
|
|
343
|
-
methods_.push(m);
|
|
344
|
-
}
|
|
345
|
-
return methods_;
|
|
346
|
-
}
|
|
347
334
|
static getRelativePathToWebSdkSrcFolder(srcFolder, targetSrcFolder) {
|
|
348
335
|
const replaced = srcFolder.replace(/\\/g, "/");
|
|
349
336
|
return replaced.replace(/\\/g, "/").replace(targetSrcFolder, "./");
|
|
@@ -359,7 +346,96 @@ ${content}`;
|
|
|
359
346
|
};
|
|
360
347
|
}
|
|
361
348
|
|
|
362
|
-
const
|
|
349
|
+
const Schema = z.object({
|
|
350
|
+
$ref: z.string().nullish(),
|
|
351
|
+
type: z.union([z.literal("array"), z.literal("object"), z.literal("file"), z.literal("string"), z.literal("boolean"), z.literal("integer")]).nullish(),
|
|
352
|
+
items: z.object({
|
|
353
|
+
$ref: z.string().nullish(),
|
|
354
|
+
type: z.string().nullish()
|
|
355
|
+
}).nullish(),
|
|
356
|
+
properties: z.array(z.string()).nullish(),
|
|
357
|
+
description: z.string().nullish(),
|
|
358
|
+
additionalProperties: z.object({
|
|
359
|
+
type: z.string().nullish()
|
|
360
|
+
}).nullish()
|
|
361
|
+
});
|
|
362
|
+
const Definition = z.object({
|
|
363
|
+
required: z.array(z.string()).nullish(),
|
|
364
|
+
properties: z.record(z.object({
|
|
365
|
+
type: z.string()
|
|
366
|
+
})).nullish()
|
|
367
|
+
});
|
|
368
|
+
const Definitions = z.record(Definition);
|
|
369
|
+
const EndpointParametersType = z.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
370
|
+
const EndpointParametersIn = z.enum(["body", "formData", "header", "path", "query"]);
|
|
371
|
+
const EndpointParameters = z.object({
|
|
372
|
+
type: EndpointParametersType.nullish(),
|
|
373
|
+
description: z.string().nullish(),
|
|
374
|
+
name: z.string(),
|
|
375
|
+
in: EndpointParametersIn,
|
|
376
|
+
required: z.boolean().nullish(),
|
|
377
|
+
schema: Schema.nullish(),
|
|
378
|
+
default: z.union([z.boolean(), z.string(), z.number()]).nullish(),
|
|
379
|
+
enum: z.array(z.union([z.boolean(), z.string(), z.number()])).nullish(),
|
|
380
|
+
items: z.object({
|
|
381
|
+
type: z.string()
|
|
382
|
+
}).nullish()
|
|
383
|
+
});
|
|
384
|
+
const Endpoint = z.object({
|
|
385
|
+
description: z.string().nullish(),
|
|
386
|
+
consumes: z.array(z.string()).nullish(),
|
|
387
|
+
produces: z.array(z.string()).nullish(),
|
|
388
|
+
tags: z.array(z.string()).nullish(),
|
|
389
|
+
summary: z.string().nullish(),
|
|
390
|
+
operationId: z.string(),
|
|
391
|
+
deprecated: z.boolean().nullish(),
|
|
392
|
+
responses: z.record(z.object({
|
|
393
|
+
description: z.string().nullish(),
|
|
394
|
+
schema: Schema.nullish(),
|
|
395
|
+
content: z.object({
|
|
396
|
+
"application/json": z.object({
|
|
397
|
+
schema: Schema.nullish()
|
|
398
|
+
})
|
|
399
|
+
}).nullish()
|
|
400
|
+
})),
|
|
401
|
+
parameters: z.array(EndpointParameters).nullish()
|
|
402
|
+
});
|
|
403
|
+
const Operation = z.object({
|
|
404
|
+
get: Endpoint.nullish(),
|
|
405
|
+
post: Endpoint.nullish(),
|
|
406
|
+
patch: Endpoint.nullish(),
|
|
407
|
+
delete: Endpoint.nullish(),
|
|
408
|
+
put: Endpoint.nullish()
|
|
409
|
+
});
|
|
410
|
+
const Paths = z.record(Operation);
|
|
411
|
+
z.object({
|
|
412
|
+
paths: Paths,
|
|
413
|
+
definitions: Definitions,
|
|
414
|
+
basePath: z.string(),
|
|
415
|
+
info: z.object({
|
|
416
|
+
description: z.string(),
|
|
417
|
+
title: z.string(),
|
|
418
|
+
contact: z.object({
|
|
419
|
+
name: z.string(),
|
|
420
|
+
url: z.string(),
|
|
421
|
+
email: z.string()
|
|
422
|
+
}),
|
|
423
|
+
version: z.string()
|
|
424
|
+
}),
|
|
425
|
+
schemes: z.array(z.string()).nullish(),
|
|
426
|
+
components: z.object({
|
|
427
|
+
schemas: Definitions
|
|
428
|
+
}).nullish()
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
const templateJsdocMethod = ({
|
|
432
|
+
classMethod,
|
|
433
|
+
httpMethod,
|
|
434
|
+
path,
|
|
435
|
+
pathParams,
|
|
436
|
+
bodyParams,
|
|
437
|
+
queryParams
|
|
438
|
+
}) => {
|
|
363
439
|
let jsdoc = "";
|
|
364
440
|
let methodSignature = "";
|
|
365
441
|
let newPath = path;
|
|
@@ -396,21 +472,31 @@ const templateJsdocMethod = (classMethod, httpMethod, path, pathParams, bodyPara
|
|
|
396
472
|
`;
|
|
397
473
|
};
|
|
398
474
|
|
|
399
|
-
const templateMethod = (
|
|
475
|
+
const templateMethod = ({
|
|
476
|
+
classMethod,
|
|
477
|
+
description,
|
|
478
|
+
httpMethod,
|
|
479
|
+
path,
|
|
480
|
+
pathParams,
|
|
481
|
+
bodyParams,
|
|
482
|
+
queryParams,
|
|
483
|
+
isFormUrlEncoded,
|
|
484
|
+
responseClass
|
|
485
|
+
}) => {
|
|
400
486
|
let methodSignature = "";
|
|
401
487
|
let newPath = `'${path}'`;
|
|
402
488
|
let dependencies = [];
|
|
403
|
-
for (const
|
|
404
|
-
const type = ParserUtils.parseType(
|
|
405
|
-
if (
|
|
406
|
-
methodSignature +=
|
|
489
|
+
for (const pathParam of pathParams) {
|
|
490
|
+
const type = ParserUtils.parseType(pathParam);
|
|
491
|
+
if (pathParam.name !== "namespace") {
|
|
492
|
+
methodSignature += pathParam.name + `:${type}, `;
|
|
407
493
|
}
|
|
408
|
-
const pName =
|
|
409
|
-
if (path.match(`{${
|
|
494
|
+
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
495
|
+
if (path.match(`{${pathParam.name}}`)) {
|
|
410
496
|
if (type === "string") {
|
|
411
|
-
newPath = `${newPath}.replace('{${
|
|
497
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
412
498
|
} else {
|
|
413
|
-
newPath = `${newPath}.replace('{${
|
|
499
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', String(${pName}))`;
|
|
414
500
|
}
|
|
415
501
|
}
|
|
416
502
|
}
|
|
@@ -420,8 +506,8 @@ const templateMethod = (classMethod, description, httpMethod, path, pathParams,
|
|
|
420
506
|
dependencies = ParserUtils.parseBodyParamsImports(bodyParams);
|
|
421
507
|
methodSignature += dataType ? `data: ${dataType},` : "";
|
|
422
508
|
}
|
|
423
|
-
ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
424
|
-
const queryParamsType = queryParams.length ? `queryParams${"?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
509
|
+
const isAnyRequired = ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
510
|
+
const queryParamsType = queryParams.length ? `queryParams${isAnyRequired ? "" : "?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
425
511
|
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as SDKRequestConfig` : "const params = {} as SDKRequestConfig";
|
|
426
512
|
const isPostPutPatch = ["post", "put", "patch"].includes(httpMethod);
|
|
427
513
|
const isDelete = ["delete"].includes(httpMethod);
|
|
@@ -446,74 +532,30 @@ const templateMethod = (classMethod, description, httpMethod, path, pathParams,
|
|
|
446
532
|
const parameters = (queryParamsType ? `${methodSignature} ${queryParamsType}` : methodSignature).replace(/,\s*$/, "");
|
|
447
533
|
let methodImpl = "";
|
|
448
534
|
const isCacheFetch = ["get"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
449
|
-
const isCacheFetchUnknown = ["get"].includes(httpMethod) && resolvedResponseClass === "unknown";
|
|
450
535
|
const cachedFetchMethod = classMethod.replace("get", "fetch");
|
|
451
536
|
const deprecateTag = isCacheFetch ? `/**
|
|
452
537
|
* @deprecated Use "${cachedFetchMethod}()" instead.
|
|
453
538
|
*/` : "";
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
539
|
+
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
540
|
+
const methodName = httpMethod === "get" ? cachedFetchMethod : ["post", "put", "patch", "delete"].includes(httpMethod) ? classMethod : "";
|
|
541
|
+
const methodGenerics = resolvedResponseClass !== "unknown" ? `<T = ${resolvedResponseClass}>` : "";
|
|
542
|
+
const responseType = resolvedResponseClass !== "unknown" ? `T` : "unknown";
|
|
543
|
+
const responseSyncType = httpMethod === "get" ? "IResponseWithSync" : ["post", "put", "patch", "delete"].includes(httpMethod) ? "IResponse" : "";
|
|
544
|
+
methodImpl = `${descriptionText}
|
|
545
|
+
${methodName}${methodGenerics}(${parameters}): Promise<${responseSyncType}<${responseType}>> {
|
|
458
546
|
${queryParamsDefault}
|
|
459
547
|
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
460
548
|
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
461
|
-
|
|
462
|
-
const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
463
549
|
|
|
464
|
-
|
|
465
|
-
return SdkCache.withoutCache(res)
|
|
466
|
-
}
|
|
467
|
-
const cacheKey = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
468
|
-
return SdkCache.withCache(cacheKey, res)
|
|
469
|
-
}
|
|
470
|
-
`;
|
|
471
|
-
isGuardInvoked = true;
|
|
472
|
-
}
|
|
473
|
-
if (isCacheFetchUnknown) {
|
|
474
|
-
methodImpl = `${descriptionText}
|
|
475
|
-
${cachedFetchMethod}(${parameters}): Promise<IResponseWithSync<unknown>> {
|
|
476
|
-
${queryParamsDefault}
|
|
477
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
478
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
479
|
-
|
|
480
|
-
const res = () => Validate.responseType(() => resultPromise, z.unknown())
|
|
550
|
+
${httpMethod === "get" ? `const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
481
551
|
|
|
482
552
|
if (!this.cache) {
|
|
483
553
|
return SdkCache.withoutCache(res)
|
|
484
554
|
}
|
|
485
555
|
const cacheKey = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
486
|
-
return SdkCache.withCache(cacheKey, res)
|
|
487
|
-
}
|
|
488
|
-
`;
|
|
489
|
-
isGuardInvoked = true;
|
|
490
|
-
}
|
|
491
|
-
const withTypeGuard = ["post", "put", "patch", "delete"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
492
|
-
if (withTypeGuard) {
|
|
493
|
-
methodImpl = `${descriptionText}
|
|
494
|
-
${classMethod}<T = ${resolvedResponseClass}>(${parameters}): Promise<IResponse<T>> {
|
|
495
|
-
${queryParamsDefault}
|
|
496
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
497
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
498
|
-
|
|
499
|
-
return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})
|
|
500
|
-
}
|
|
501
|
-
`;
|
|
502
|
-
isGuardInvoked = true;
|
|
503
|
-
}
|
|
504
|
-
const withTypeGuardUnknown = ["post", "put", "patch", "delete"].includes(httpMethod) && resolvedResponseClass === "unknown";
|
|
505
|
-
if (withTypeGuardUnknown) {
|
|
506
|
-
methodImpl = `${descriptionText}
|
|
507
|
-
${classMethod}(${parameters}): Promise<IResponse<unknown>> {
|
|
508
|
-
${queryParamsDefault}
|
|
509
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
510
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
511
|
-
|
|
512
|
-
return Validate.responseType(() => resultPromise, z.unknown())
|
|
556
|
+
return SdkCache.withCache(cacheKey, res)` : ""}${["post", "put", "patch", "delete"].includes(httpMethod) ? `return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated})` : ""}
|
|
513
557
|
}
|
|
514
558
|
`;
|
|
515
|
-
isGuardInvoked = true;
|
|
516
|
-
}
|
|
517
559
|
if (!isGuardInvoked) {
|
|
518
560
|
methodImpl = `${descriptionText}
|
|
519
561
|
${deprecateTag}
|
|
@@ -531,12 +573,12 @@ class TemplateZod {
|
|
|
531
573
|
duplicates;
|
|
532
574
|
duplicateFound = false;
|
|
533
575
|
importClasses = /* @__PURE__ */ new Set();
|
|
534
|
-
render = (
|
|
576
|
+
render = (fileName, definition, duplicates) => {
|
|
535
577
|
this.duplicates = duplicates;
|
|
536
578
|
const content = this.parseToZodSchema(definition, definition.required || []);
|
|
537
|
-
const containsRecursiveType = this.importClasses.has(
|
|
579
|
+
const containsRecursiveType = this.importClasses.has(fileName);
|
|
538
580
|
if (containsRecursiveType) {
|
|
539
|
-
this.importClasses.delete(
|
|
581
|
+
this.importClasses.delete(fileName);
|
|
540
582
|
}
|
|
541
583
|
let imports = "";
|
|
542
584
|
for (const cl of Array.from(this.importClasses).sort()) {
|
|
@@ -547,18 +589,18 @@ class TemplateZod {
|
|
|
547
589
|
let exportedTypeString;
|
|
548
590
|
if (containsRecursiveType) {
|
|
549
591
|
exportedVariableString = `
|
|
550
|
-
export const ${
|
|
592
|
+
export const ${fileName}: z.ZodType<${fileName}> = z.lazy(() =>
|
|
551
593
|
${content.schemaString}
|
|
552
594
|
)
|
|
553
595
|
`;
|
|
554
596
|
exportedTypeString = `
|
|
555
|
-
export type ${
|
|
597
|
+
export type ${fileName} = {
|
|
556
598
|
${content.typeString}
|
|
557
599
|
}
|
|
558
600
|
`;
|
|
559
601
|
} else {
|
|
560
|
-
exportedVariableString = `export const ${
|
|
561
|
-
exportedTypeString = `export type ${
|
|
602
|
+
exportedVariableString = `export const ${fileName} = ${content.schemaString}`;
|
|
603
|
+
exportedTypeString = `export type ${fileName} = z.TypeOf<typeof ${fileName}>`;
|
|
562
604
|
}
|
|
563
605
|
const template = `import { z } from 'zod'
|
|
564
606
|
${imports}
|
|
@@ -629,7 +671,8 @@ class TemplateZod {
|
|
|
629
671
|
};
|
|
630
672
|
}
|
|
631
673
|
if (type === "array") {
|
|
632
|
-
const
|
|
674
|
+
const items = definition.items;
|
|
675
|
+
const ref2 = items?.$ref;
|
|
633
676
|
let model2;
|
|
634
677
|
if (ref2) {
|
|
635
678
|
const refType = ParserUtils.parseRefType(ref2);
|
|
@@ -638,9 +681,13 @@ class TemplateZod {
|
|
|
638
681
|
schemaString: refType,
|
|
639
682
|
typeString: refType
|
|
640
683
|
};
|
|
641
|
-
} else {
|
|
642
|
-
const items = definition.items;
|
|
684
|
+
} else if (items) {
|
|
643
685
|
model2 = this.parseEnumItems(items);
|
|
686
|
+
} else {
|
|
687
|
+
return {
|
|
688
|
+
schemaString: `${schemaAttribute} z.array(z.unknown())${schemaRequired}`,
|
|
689
|
+
typeString: `${typeAttribute} z.unknown()[]${typeNullishability}`
|
|
690
|
+
};
|
|
644
691
|
}
|
|
645
692
|
return {
|
|
646
693
|
schemaString: `${schemaAttribute} z.array(${model2.schemaString})${schemaRequired}`,
|
|
@@ -750,7 +797,7 @@ class CodeGenerator {
|
|
|
750
797
|
static getPatchedDir = () => path__default.join(CliParser.getSwaggersOutputPath(), "patched");
|
|
751
798
|
static getGeneratedPublicFolder = () => `${CliParser.getOutputPath()}/generated-public`;
|
|
752
799
|
static getGeneratedAdminFolder = () => `${CliParser.getOutputPath()}/generated-admin`;
|
|
753
|
-
static iterateApi = (api) => {
|
|
800
|
+
static iterateApi = async (api) => {
|
|
754
801
|
const apiBufferByTag = {};
|
|
755
802
|
const jsDocApiBufferByTag = {};
|
|
756
803
|
const dependenciesByTag = {};
|
|
@@ -763,14 +810,20 @@ class CodeGenerator {
|
|
|
763
810
|
} else if (!CliParser.isAdmin() && isAdminEndpoint) {
|
|
764
811
|
continue;
|
|
765
812
|
}
|
|
766
|
-
const
|
|
767
|
-
const
|
|
768
|
-
for (const httpMethod of
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
813
|
+
const operation = api.paths[path2];
|
|
814
|
+
const httpMethods = Object.keys(operation);
|
|
815
|
+
for (const httpMethod of httpMethods) {
|
|
816
|
+
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
817
|
+
console.error(JSON.stringify({ path: path2, httpMethod }, null, 2));
|
|
818
|
+
throw error;
|
|
819
|
+
});
|
|
820
|
+
if (!endpoint.tags) {
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
const [tag] = endpoint.tags;
|
|
824
|
+
const description = endpoint.description;
|
|
825
|
+
const isDeprecated = endpoint.deprecated;
|
|
826
|
+
const responseClass = ParserUtils.get2xxResponse(endpoint.responses);
|
|
774
827
|
const className = _.upperFirst(_.camelCase(tag));
|
|
775
828
|
classImports[className] = classImports[className] ? classImports[className] : {};
|
|
776
829
|
if (!isDeprecated) {
|
|
@@ -781,15 +834,30 @@ class CodeGenerator {
|
|
|
781
834
|
if (responseClass && responseClass.endsWith("Array")) {
|
|
782
835
|
arrayDefinitions.push(responseClass);
|
|
783
836
|
}
|
|
784
|
-
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod,
|
|
785
|
-
const queryParams = ParserUtils.
|
|
786
|
-
const pathParams = ParserUtils.
|
|
787
|
-
const bodyParams = ParserUtils.
|
|
788
|
-
const classMethod = ParserUtils.generateClassMethod(
|
|
789
|
-
|
|
790
|
-
|
|
837
|
+
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod, endpoint.consumes);
|
|
838
|
+
const queryParams = ParserUtils.filterQueryParameters(endpoint.parameters);
|
|
839
|
+
const pathParams = ParserUtils.filterPathParams(endpoint.parameters);
|
|
840
|
+
const bodyParams = ParserUtils.filterBodyParams(endpoint.parameters);
|
|
841
|
+
const classMethod = ParserUtils.generateClassMethod({
|
|
842
|
+
path: path2,
|
|
843
|
+
endpoint,
|
|
844
|
+
httpMethod,
|
|
845
|
+
className
|
|
846
|
+
});
|
|
847
|
+
const pathWithBase = `${api.basePath ?? ""}${path2}`;
|
|
848
|
+
const [generatedMethodString, importStatements] = templateMethod({
|
|
849
|
+
classMethod,
|
|
850
|
+
description,
|
|
851
|
+
httpMethod,
|
|
852
|
+
path: pathWithBase,
|
|
853
|
+
pathParams,
|
|
854
|
+
bodyParams,
|
|
855
|
+
queryParams,
|
|
856
|
+
isFormUrlEncoded,
|
|
857
|
+
responseClass
|
|
858
|
+
});
|
|
791
859
|
apiBufferByTag[tag] = (apiBufferByTag[tag] || "") + generatedMethodString;
|
|
792
|
-
jsDocApiBufferByTag[tag] = (jsDocApiBufferByTag[tag] || "") + templateJsdocMethod(classMethod, httpMethod, path2, pathParams, bodyParams, queryParams);
|
|
860
|
+
jsDocApiBufferByTag[tag] = (jsDocApiBufferByTag[tag] || "") + templateJsdocMethod({ classMethod, httpMethod, path: path2, pathParams, bodyParams, queryParams });
|
|
793
861
|
dependenciesByTag[tag] = dependenciesByTag[tag] ? [.../* @__PURE__ */ new Set([...importStatements, ...dependenciesByTag[tag]])] : [...new Set(importStatements)];
|
|
794
862
|
}
|
|
795
863
|
}
|
|
@@ -815,7 +883,7 @@ class CodeGenerator {
|
|
|
815
883
|
ParserUtils.mkdirIfNotExist(DIST_DIR);
|
|
816
884
|
ParserUtils.mkdirIfNotExist(DIST_DOCS_DIR);
|
|
817
885
|
ParserUtils.mkdirIfNotExist(DIST_DEFINITION_DIR);
|
|
818
|
-
const { apiBufferByTag, dependenciesByTag, classImports, arrayDefinitions } = CodeGenerator.iterateApi(api);
|
|
886
|
+
const { apiBufferByTag, dependenciesByTag, classImports, arrayDefinitions } = await CodeGenerator.iterateApi(api);
|
|
819
887
|
const targetSrcFolder = `${CliParser.getOutputPath()}/`;
|
|
820
888
|
for (const tag in apiBufferByTag) {
|
|
821
889
|
const className = _.upperFirst(_.camelCase(tag));
|
|
@@ -826,8 +894,9 @@ class CodeGenerator {
|
|
|
826
894
|
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path__default.join(DIST_DIR, `${classGenName}`), targetSrcFolder));
|
|
827
895
|
}
|
|
828
896
|
const duplicates = /* @__PURE__ */ new Map();
|
|
829
|
-
|
|
830
|
-
|
|
897
|
+
const definitions = api?.components?.schemas || api.definitions;
|
|
898
|
+
for (const ref in definitions) {
|
|
899
|
+
const definition = definitions[ref];
|
|
831
900
|
let fileName = ParserUtils.parseRefType(ref);
|
|
832
901
|
const fileExist = fs__default.existsSync(path__default.join(DIST_DEFINITION_DIR, `${fileName}.ts`));
|
|
833
902
|
if (fileExist) {
|
|
@@ -838,8 +907,8 @@ class CodeGenerator {
|
|
|
838
907
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, fileName, buffer);
|
|
839
908
|
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path__default.join(DIST_DEFINITION_DIR, fileName), targetSrcFolder));
|
|
840
909
|
}
|
|
841
|
-
for (const ref in
|
|
842
|
-
const definition =
|
|
910
|
+
for (const ref in definitions) {
|
|
911
|
+
const definition = definitions[ref];
|
|
843
912
|
const fileName = ParserUtils.parseRefType(ref);
|
|
844
913
|
const { buffer, duplicateFound } = new TemplateZod().render(fileName, definition, duplicates);
|
|
845
914
|
if (duplicateFound) {
|