@accelbyte/codegen 2.0.0-beta.1 → 2.0.0-beta.10
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.
|
@@ -78,6 +78,9 @@ class CliParser {
|
|
|
78
78
|
static getSnippetOutputPath = () => {
|
|
79
79
|
return CliParser.instance().argv.snippetOutput;
|
|
80
80
|
};
|
|
81
|
+
static skipVersionSync = () => {
|
|
82
|
+
return CliParser.instance().argv.skipVersionSync;
|
|
83
|
+
};
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
const getImportableVarMap$1 = () => ({
|
|
@@ -146,15 +149,25 @@ export function ${className}(sdk: AccelbyteSDK, args?: ApiArgs) {
|
|
|
146
149
|
`;
|
|
147
150
|
};
|
|
148
151
|
|
|
152
|
+
const VersionBumpType = zod.z.enum(["CUTOFF", "RELEASE", "HOTFIX"]);
|
|
149
153
|
class VersionHelpers {
|
|
150
154
|
static getNextVersion = ({
|
|
151
155
|
codegenVersion,
|
|
152
156
|
serviceVersion,
|
|
153
157
|
predefinedMajorVersion,
|
|
154
|
-
|
|
158
|
+
versionBumpType,
|
|
155
159
|
sdkVersion,
|
|
156
160
|
nextPrereleaseId
|
|
157
161
|
}) => {
|
|
162
|
+
if (versionBumpType !== void 0) {
|
|
163
|
+
const parsed = VersionBumpType.safeParse(versionBumpType);
|
|
164
|
+
if (!parsed.success) {
|
|
165
|
+
throw new Error(`Invalid process.env.VERSION_BUMP_TYPE: ${versionBumpType}`);
|
|
166
|
+
}
|
|
167
|
+
if ((parsed.data === "HOTFIX" || parsed.data === "RELEASE") && nextPrereleaseId) {
|
|
168
|
+
throw new Error(`process.env.PRERELEASE_ID should be empty when process.env.VERSION_BUMP_TYPE is "HOTFIX" or "PRELEASE".`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
158
171
|
const codegenSemvers = semver.parse(codegenVersion);
|
|
159
172
|
const serviceSemvers = semver.parse(serviceVersion);
|
|
160
173
|
const sdkSemvers = semver.parse(sdkVersion);
|
|
@@ -167,20 +180,39 @@ class VersionHelpers {
|
|
|
167
180
|
if (sdkSemvers === null) {
|
|
168
181
|
throw new Error(`Invalid sdk version: ${sdkVersion}`);
|
|
169
182
|
}
|
|
170
|
-
const
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
|
|
183
|
+
const { major: currentMajor, minor: currentMinor, patch: currentPatch, prerelease: currentPrerelease } = sdkSemvers;
|
|
184
|
+
const nextMajor = codegenSemvers.major + predefinedMajorVersion;
|
|
185
|
+
const shouldResetVersion = nextMajor !== currentMajor;
|
|
186
|
+
let nextMinor = currentMinor;
|
|
187
|
+
let nextPatch = currentPatch;
|
|
188
|
+
switch (versionBumpType) {
|
|
189
|
+
case VersionBumpType.Enum.CUTOFF: {
|
|
190
|
+
nextMinor++;
|
|
191
|
+
nextPatch = 0;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case VersionBumpType.Enum.RELEASE:
|
|
195
|
+
break;
|
|
196
|
+
case VersionBumpType.Enum.HOTFIX: {
|
|
197
|
+
nextPatch++;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (shouldResetVersion) {
|
|
202
|
+
nextMinor = 0;
|
|
203
|
+
nextPatch = 0;
|
|
204
|
+
}
|
|
174
205
|
let nextVersion = [
|
|
175
206
|
codegenSemvers.major + predefinedMajorVersion,
|
|
176
207
|
nextMinor,
|
|
177
208
|
nextPatch
|
|
178
209
|
].join(".");
|
|
179
210
|
if (nextPrereleaseId) {
|
|
180
|
-
if (nextMinor !== currentMinor ||
|
|
211
|
+
if (nextMinor !== currentMinor || nextMajor !== currentMajor) {
|
|
181
212
|
nextVersion += `-${nextPrereleaseId}.0`;
|
|
182
213
|
} else {
|
|
183
|
-
|
|
214
|
+
if (currentPrerelease.length)
|
|
215
|
+
nextVersion += `-${currentPrerelease.join(".")}`;
|
|
184
216
|
nextVersion = semver.inc(nextVersion, "prerelease", void 0, nextPrereleaseId);
|
|
185
217
|
}
|
|
186
218
|
}
|
|
@@ -207,14 +239,14 @@ class ParserUtils {
|
|
|
207
239
|
static replaceAll = (string, search, replace) => {
|
|
208
240
|
return string.split(search).join(replace);
|
|
209
241
|
};
|
|
210
|
-
static generateClassName = (tag) => {
|
|
242
|
+
static generateClassName = (tag, isAdmin) => {
|
|
211
243
|
const className = _.upperFirst(_.camelCase(tag));
|
|
212
|
-
const classGenName =
|
|
244
|
+
const classGenName = isAdmin ? className + "Admin$" : className + "$";
|
|
213
245
|
return { className, classGenName };
|
|
214
246
|
};
|
|
215
|
-
static generateApiName = (tag) => {
|
|
247
|
+
static generateApiName = (tag, isAdmin) => {
|
|
216
248
|
const apiName = _.upperFirst(_.camelCase(tag));
|
|
217
|
-
const apiGenName =
|
|
249
|
+
const apiGenName = isAdmin ? apiName + "AdminApi" : apiName + "Api";
|
|
218
250
|
return { apiName, apiGenName };
|
|
219
251
|
};
|
|
220
252
|
static parseQueryParamAttributeDefault = (definition) => {
|
|
@@ -314,6 +346,12 @@ class ParserUtils {
|
|
|
314
346
|
if (definition?.schema?.type && definition.schema.type === "array") {
|
|
315
347
|
return `${attrName}${required}: ${definition.schema.items.type ?? "any"}[]`;
|
|
316
348
|
}
|
|
349
|
+
if (definition.type && definition.type === "file") {
|
|
350
|
+
return `${attrName}${required}: File`;
|
|
351
|
+
}
|
|
352
|
+
if (definition?.schema?.type && definition.schema.type === "file") {
|
|
353
|
+
return `${attrName}${required}: File`;
|
|
354
|
+
}
|
|
317
355
|
if (definition.type && definition.type) {
|
|
318
356
|
return `${attrName}${required}: ${definition.type} | null`;
|
|
319
357
|
}
|
|
@@ -493,17 +531,16 @@ class ParserUtils {
|
|
|
493
531
|
ParserUtils.mkdirIfNotExist(distDir);
|
|
494
532
|
fs.writeFileSync(path.join(distDir, `all-${isAdminWebSdk ? "admin" : "public"}-imports.ts`), ParserUtils.prependCopyrightHeader(buffer));
|
|
495
533
|
}
|
|
496
|
-
static syncPackageVersion(apiInfo,
|
|
497
|
-
if (
|
|
534
|
+
static syncPackageVersion(apiInfo, skipVersionSync, prereleaseId) {
|
|
535
|
+
if (skipVersionSync)
|
|
498
536
|
return;
|
|
499
|
-
}
|
|
500
537
|
const currDir = process.cwd();
|
|
501
538
|
const { packageJSON, pathToPackageJSON } = ParserUtils.getPackageJSONInfo(currDir);
|
|
502
539
|
const nextSemver = VersionHelpers.getNextVersion({
|
|
503
540
|
codegenVersion: codegenPackageJSON.version,
|
|
504
541
|
serviceVersion: apiInfo["x-version"] || apiInfo.version || UNDEFINED_SWAGGER_SEMVER,
|
|
505
|
-
predefinedMajorVersion: packageJSON.predefinedMajorVersion,
|
|
506
|
-
|
|
542
|
+
predefinedMajorVersion: packageJSON.predefinedMajorVersion || 0,
|
|
543
|
+
versionBumpType: process.env.VERSION_BUMP_TYPE,
|
|
507
544
|
sdkVersion: packageJSON.version,
|
|
508
545
|
nextPrereleaseId: prereleaseId
|
|
509
546
|
});
|
|
@@ -587,7 +624,9 @@ class ParserUtils {
|
|
|
587
624
|
${content}`;
|
|
588
625
|
};
|
|
589
626
|
static sortPathParamsByPath = (pathParams, path2) => {
|
|
590
|
-
|
|
627
|
+
const params = path2.match(/{\w*}/g) || [];
|
|
628
|
+
const cleanParams = params.map((param) => param.replace("{", "").replace("}", ""));
|
|
629
|
+
return pathParams.sort((a, b) => cleanParams.indexOf(a.name) - cleanParams.indexOf(b.name));
|
|
591
630
|
};
|
|
592
631
|
}
|
|
593
632
|
const mappedMethod = (httpMethod, isForm) => {
|
|
@@ -655,205 +694,6 @@ const isSwaggerIntegerType = (type) => {
|
|
|
655
694
|
return type === "integer" || type === "int";
|
|
656
695
|
};
|
|
657
696
|
|
|
658
|
-
const Schema = zod.z.object({
|
|
659
|
-
$ref: zod.z.string().nullish(),
|
|
660
|
-
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(),
|
|
661
|
-
items: zod.z.object({
|
|
662
|
-
$ref: zod.z.string().nullish(),
|
|
663
|
-
type: zod.z.string().nullish()
|
|
664
|
-
}).nullish(),
|
|
665
|
-
properties: zod.z.union([zod.z.array(zod.z.string()).nullish(), zod.z.record(zod.z.object({ type: zod.z.string() })).nullish()]),
|
|
666
|
-
description: zod.z.string().nullish(),
|
|
667
|
-
additionalProperties: zod.z.object({
|
|
668
|
-
type: zod.z.string().nullish()
|
|
669
|
-
}).nullish()
|
|
670
|
-
});
|
|
671
|
-
const Definition = zod.z.object({
|
|
672
|
-
required: zod.z.array(zod.z.string()).nullish(),
|
|
673
|
-
properties: zod.z.record(zod.z.object({
|
|
674
|
-
type: zod.z.string()
|
|
675
|
-
})).nullish()
|
|
676
|
-
});
|
|
677
|
-
const Definitions = zod.z.record(Definition);
|
|
678
|
-
const EndpointParametersType = zod.z.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
679
|
-
const EndpointParametersIn = zod.z.enum(["body", "formData", "header", "path", "query"]);
|
|
680
|
-
const EndpointParameters = zod.z.object({
|
|
681
|
-
type: EndpointParametersType.nullish(),
|
|
682
|
-
description: zod.z.string().nullish(),
|
|
683
|
-
name: zod.z.string(),
|
|
684
|
-
in: EndpointParametersIn,
|
|
685
|
-
required: zod.z.boolean().nullish(),
|
|
686
|
-
schema: Schema.nullish(),
|
|
687
|
-
default: zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number(), zod.z.array(zod.z.any())]).nullish(),
|
|
688
|
-
enum: zod.z.array(zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number()])).nullish(),
|
|
689
|
-
items: zod.z.object({
|
|
690
|
-
type: zod.z.string(),
|
|
691
|
-
enum: zod.z.array(zod.z.any()).nullish()
|
|
692
|
-
}).nullish()
|
|
693
|
-
});
|
|
694
|
-
const Endpoint = zod.z.object({
|
|
695
|
-
description: zod.z.string().nullish(),
|
|
696
|
-
consumes: zod.z.array(zod.z.string()).nullish(),
|
|
697
|
-
produces: zod.z.array(zod.z.string()).nullish(),
|
|
698
|
-
tags: zod.z.array(zod.z.string()).nullish(),
|
|
699
|
-
summary: zod.z.string().nullish(),
|
|
700
|
-
operationId: zod.z.string(),
|
|
701
|
-
deprecated: zod.z.boolean().nullish(),
|
|
702
|
-
responses: zod.z.record(zod.z.object({
|
|
703
|
-
description: zod.z.string().nullish(),
|
|
704
|
-
schema: Schema.nullish(),
|
|
705
|
-
content: zod.z.object({
|
|
706
|
-
"application/json": zod.z.object({
|
|
707
|
-
schema: Schema.nullish()
|
|
708
|
-
})
|
|
709
|
-
}).nullish()
|
|
710
|
-
})),
|
|
711
|
-
parameters: zod.z.array(EndpointParameters).nullish(),
|
|
712
|
-
requestBody: zod.z.object({
|
|
713
|
-
required: zod.z.boolean(),
|
|
714
|
-
content: zod.z.object({
|
|
715
|
-
"application/json": zod.z.object({
|
|
716
|
-
schema: Schema.nullish()
|
|
717
|
-
})
|
|
718
|
-
}).nullish()
|
|
719
|
-
}).nullish()
|
|
720
|
-
});
|
|
721
|
-
const Operation = zod.z.object({
|
|
722
|
-
get: Endpoint.nullish(),
|
|
723
|
-
post: Endpoint.nullish(),
|
|
724
|
-
patch: Endpoint.nullish(),
|
|
725
|
-
delete: Endpoint.nullish(),
|
|
726
|
-
put: Endpoint.nullish()
|
|
727
|
-
});
|
|
728
|
-
const Paths = zod.z.record(Operation);
|
|
729
|
-
zod.z.object({
|
|
730
|
-
paths: Paths,
|
|
731
|
-
definitions: Definitions,
|
|
732
|
-
basePath: zod.z.string(),
|
|
733
|
-
info: zod.z.object({
|
|
734
|
-
description: zod.z.string(),
|
|
735
|
-
title: zod.z.string(),
|
|
736
|
-
contact: zod.z.object({
|
|
737
|
-
name: zod.z.string(),
|
|
738
|
-
url: zod.z.string(),
|
|
739
|
-
email: zod.z.string()
|
|
740
|
-
}),
|
|
741
|
-
version: zod.z.string()
|
|
742
|
-
}),
|
|
743
|
-
schemes: zod.z.array(zod.z.string()).nullish(),
|
|
744
|
-
components: zod.z.object({
|
|
745
|
-
schemas: Definitions
|
|
746
|
-
}).nullish()
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
const templateMethod = ({
|
|
750
|
-
classMethod,
|
|
751
|
-
description,
|
|
752
|
-
httpMethod,
|
|
753
|
-
path,
|
|
754
|
-
pathParams,
|
|
755
|
-
bodyParams,
|
|
756
|
-
queryParams,
|
|
757
|
-
isFormUrlEncoded,
|
|
758
|
-
responseClass
|
|
759
|
-
}) => {
|
|
760
|
-
let methodParams = "";
|
|
761
|
-
let methodParamsNoTypes = "";
|
|
762
|
-
let newPath = `'${path}'`;
|
|
763
|
-
let importStatements = [];
|
|
764
|
-
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path);
|
|
765
|
-
for (const pathParam of sortedPathParams) {
|
|
766
|
-
const type = ParserUtils.parseType(pathParam);
|
|
767
|
-
if (pathParam.name !== "namespace") {
|
|
768
|
-
methodParams += pathParam.name + `:${type}, `;
|
|
769
|
-
methodParamsNoTypes += pathParam.name + ", ";
|
|
770
|
-
}
|
|
771
|
-
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
772
|
-
if (path.match(`{${pathParam.name}}`)) {
|
|
773
|
-
if (type === "string") {
|
|
774
|
-
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
775
|
-
} else {
|
|
776
|
-
newPath = `${newPath}.replace('{${pathParam.name}}', String(${pName}))`;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
let dataType = null;
|
|
781
|
-
if (httpMethod !== "get") {
|
|
782
|
-
dataType = ParserUtils.parseBodyParamsType(bodyParams);
|
|
783
|
-
importStatements = ParserUtils.parseBodyParamsImports(bodyParams);
|
|
784
|
-
methodParams += dataType ? `data: ${dataType},` : "";
|
|
785
|
-
methodParamsNoTypes += dataType ? `data,` : "";
|
|
786
|
-
}
|
|
787
|
-
const isAnyRequired = ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
788
|
-
const queryParamsType = queryParams.length ? `queryParams${isAnyRequired ? "" : "?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
789
|
-
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as SDKRequestConfig` : "const params = {} as SDKRequestConfig";
|
|
790
|
-
const isPostPutPatch = ["post", "put", "patch"].includes(httpMethod);
|
|
791
|
-
const isDelete = ["delete"].includes(httpMethod);
|
|
792
|
-
let dataPayload = "{params}";
|
|
793
|
-
const descriptionText = description ? `
|
|
794
|
-
/**
|
|
795
|
-
* ${description.replace(/\n/g, "\n * ")}
|
|
796
|
-
*/` : "";
|
|
797
|
-
let formPayloadString = "";
|
|
798
|
-
if (isFormUrlEncoded) {
|
|
799
|
-
formPayloadString = ``;
|
|
800
|
-
const params = "{ ...params, headers: { ...params.headers, 'content-type': 'application/x-www-form-urlencoded' } }";
|
|
801
|
-
dataPayload = dataType ? `CodeGenUtil.getFormUrlEncodedData(data), ${params}` : `null, ${params}`;
|
|
802
|
-
} else if (isPostPutPatch) {
|
|
803
|
-
dataPayload = dataType ? `data, {params}` : "null, {params}";
|
|
804
|
-
} else if (isDelete) {
|
|
805
|
-
dataPayload = dataType ? `{data, params}` : "{params}";
|
|
806
|
-
}
|
|
807
|
-
const isFileUpload = methodParams.indexOf("data: {file") > -1;
|
|
808
|
-
const resolvedResponseClass = responseClass || "unknown";
|
|
809
|
-
const resolvedResponseClassValidated = responseClass || "z.unknown()";
|
|
810
|
-
methodParams = (queryParamsType ? `${methodParams} ${queryParamsType}` : methodParams).replace(/,\s*$/, "");
|
|
811
|
-
methodParamsNoTypes = queryParamsType ? `${methodParamsNoTypes} queryParams` : methodParamsNoTypes;
|
|
812
|
-
let methodImpl = "";
|
|
813
|
-
const isCacheFetch = ["get"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
814
|
-
const cachedFetchMethod = classMethod;
|
|
815
|
-
const deprecateTag = isCacheFetch ? `/**
|
|
816
|
-
* @deprecated Use "${classMethod}()" instead.
|
|
817
|
-
*/` : "";
|
|
818
|
-
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
819
|
-
const methodName = httpMethod === "get" ? cachedFetchMethod : ["post", "put", "patch", "delete"].includes(httpMethod) ? classMethod : "";
|
|
820
|
-
const responseType = resolvedResponseClass !== "unknown" ? `${resolvedResponseClass}` : "unknown";
|
|
821
|
-
const generateMethodName = () => `${methodName}(${methodParams}): Promise<${responseSyncType}<${responseType}>>`;
|
|
822
|
-
const responseSyncType = httpMethod === "get" ? "IResponseWithSync" : ["post", "put", "patch", "delete"].includes(httpMethod) ? "IResponse" : "";
|
|
823
|
-
methodImpl = `${descriptionText}
|
|
824
|
-
${generateMethodName()} {
|
|
825
|
-
${queryParamsDefault}
|
|
826
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
827
|
-
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
828
|
-
|
|
829
|
-
${httpMethod === "get" ? ` const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated}, '${resolvedResponseClassValidated}')
|
|
830
|
-
|
|
831
|
-
if (!this.cache) {
|
|
832
|
-
return SdkCache.withoutCache(res)
|
|
833
|
-
}
|
|
834
|
-
const cacheKey = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
835
|
-
return SdkCache.withCache(cacheKey, res)` : ""}${["post", "put", "patch", "delete"].includes(httpMethod) ? ` return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated}, '${resolvedResponseClassValidated}')` : ""}
|
|
836
|
-
}
|
|
837
|
-
`;
|
|
838
|
-
if (!isGuardInvoked) {
|
|
839
|
-
methodImpl = `${descriptionText}
|
|
840
|
-
${deprecateTag}
|
|
841
|
-
TODO_${classMethod}(${methodParams}): Promise<AxiosResponse<${resolvedResponseClass}>> {
|
|
842
|
-
${queryParamsDefault}
|
|
843
|
-
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
844
|
-
return this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
845
|
-
}
|
|
846
|
-
`;
|
|
847
|
-
}
|
|
848
|
-
const res = {
|
|
849
|
-
methodImpl,
|
|
850
|
-
methodParams,
|
|
851
|
-
methodParamsNoTypes,
|
|
852
|
-
importStatements
|
|
853
|
-
};
|
|
854
|
-
return res;
|
|
855
|
-
};
|
|
856
|
-
|
|
857
697
|
class TemplateZod {
|
|
858
698
|
duplicates;
|
|
859
699
|
duplicateFound = false;
|
|
@@ -938,7 +778,13 @@ ${exportedTypeString}
|
|
|
938
778
|
const schemaAttribute = name ? `'${name}':` : "";
|
|
939
779
|
const typeAttribute = name ? `'${name}'${typeRequired}:` : "";
|
|
940
780
|
const type = definition?.type;
|
|
941
|
-
if (
|
|
781
|
+
if (definition.properties) {
|
|
782
|
+
const result = this.parseToZodSchema(definition, requiredAttrs);
|
|
783
|
+
return {
|
|
784
|
+
schemaString: `${schemaAttribute} ${result.schemaString}${schemaRequired}`,
|
|
785
|
+
typeString: `${typeAttribute} ${result.typeString}${typeNullishability}`
|
|
786
|
+
};
|
|
787
|
+
} else if (type) {
|
|
942
788
|
if (type === "object" && definition.additionalProperties) {
|
|
943
789
|
const zodAttribute = this.parseToZodAttribute("", definition.additionalProperties, [""]);
|
|
944
790
|
return {
|
|
@@ -1014,12 +860,6 @@ ${exportedTypeString}
|
|
|
1014
860
|
typeString: `${typeAttribute} ${result.typeString}`
|
|
1015
861
|
};
|
|
1016
862
|
}
|
|
1017
|
-
} else if (definition.properties) {
|
|
1018
|
-
const result = this.parseToZodSchema(definition, requiredAttrs);
|
|
1019
|
-
return {
|
|
1020
|
-
schemaString: `${schemaAttribute} ${result.schemaString}${schemaRequired}`,
|
|
1021
|
-
typeString: `${typeAttribute} ${result.typeString}${typeNullishability}`
|
|
1022
|
-
};
|
|
1023
863
|
}
|
|
1024
864
|
const ref = definition.$ref;
|
|
1025
865
|
let model = `z.record(z.any())`;
|
|
@@ -1106,6 +946,227 @@ const extractEnumObject = (type, isRequired, enumArr) => {
|
|
|
1106
946
|
};
|
|
1107
947
|
};
|
|
1108
948
|
|
|
949
|
+
const templateApiIndex = (serviceName, serviceNameTitle, apiList) => {
|
|
950
|
+
let imports = "";
|
|
951
|
+
let returnStatement = "";
|
|
952
|
+
for (const cl of apiList) {
|
|
953
|
+
imports += `
|
|
954
|
+
import { ${cl} } from './${serviceName}/${cl}.js'`;
|
|
955
|
+
returnStatement += `
|
|
956
|
+
${cl}, `;
|
|
957
|
+
}
|
|
958
|
+
return `/**
|
|
959
|
+
* AUTO GENERATED
|
|
960
|
+
*/
|
|
961
|
+
${imports}
|
|
962
|
+
|
|
963
|
+
const apis = {
|
|
964
|
+
${returnStatement}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
export const ${ParserUtils.convertDashesToTitleCase(serviceNameTitle)} = apis
|
|
968
|
+
`;
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
const Schema = zod.z.object({
|
|
972
|
+
$ref: zod.z.string().nullish(),
|
|
973
|
+
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(),
|
|
974
|
+
items: zod.z.object({
|
|
975
|
+
$ref: zod.z.string().nullish(),
|
|
976
|
+
type: zod.z.string().nullish()
|
|
977
|
+
}).nullish(),
|
|
978
|
+
properties: zod.z.union([zod.z.array(zod.z.string()).nullish(), zod.z.record(zod.z.object({ type: zod.z.string() })).nullish()]),
|
|
979
|
+
description: zod.z.string().nullish(),
|
|
980
|
+
additionalProperties: zod.z.object({
|
|
981
|
+
type: zod.z.string().nullish()
|
|
982
|
+
}).nullish()
|
|
983
|
+
});
|
|
984
|
+
const Definition = zod.z.object({
|
|
985
|
+
required: zod.z.array(zod.z.string()).nullish(),
|
|
986
|
+
properties: zod.z.record(zod.z.object({
|
|
987
|
+
type: zod.z.string()
|
|
988
|
+
})).nullish()
|
|
989
|
+
});
|
|
990
|
+
const Definitions = zod.z.record(Definition);
|
|
991
|
+
const EndpointParametersType = zod.z.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
992
|
+
const EndpointParametersIn = zod.z.enum(["body", "formData", "header", "path", "query"]);
|
|
993
|
+
const EndpointParameters = zod.z.object({
|
|
994
|
+
type: EndpointParametersType.nullish(),
|
|
995
|
+
description: zod.z.string().nullish(),
|
|
996
|
+
name: zod.z.string(),
|
|
997
|
+
in: EndpointParametersIn,
|
|
998
|
+
required: zod.z.boolean().nullish(),
|
|
999
|
+
schema: Schema.nullish(),
|
|
1000
|
+
default: zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number(), zod.z.array(zod.z.any())]).nullish(),
|
|
1001
|
+
enum: zod.z.array(zod.z.union([zod.z.boolean(), zod.z.string(), zod.z.number()])).nullish(),
|
|
1002
|
+
items: zod.z.object({
|
|
1003
|
+
type: zod.z.string(),
|
|
1004
|
+
enum: zod.z.array(zod.z.any()).nullish()
|
|
1005
|
+
}).nullish()
|
|
1006
|
+
});
|
|
1007
|
+
const Endpoint = zod.z.object({
|
|
1008
|
+
description: zod.z.string().nullish(),
|
|
1009
|
+
consumes: zod.z.array(zod.z.string()).nullish(),
|
|
1010
|
+
produces: zod.z.array(zod.z.string()).nullish(),
|
|
1011
|
+
tags: zod.z.array(zod.z.string()).nullish(),
|
|
1012
|
+
summary: zod.z.string().nullish(),
|
|
1013
|
+
operationId: zod.z.string(),
|
|
1014
|
+
deprecated: zod.z.boolean().nullish(),
|
|
1015
|
+
responses: zod.z.record(zod.z.object({
|
|
1016
|
+
description: zod.z.string().nullish(),
|
|
1017
|
+
schema: Schema.nullish(),
|
|
1018
|
+
content: zod.z.object({
|
|
1019
|
+
"application/json": zod.z.object({
|
|
1020
|
+
schema: Schema.nullish()
|
|
1021
|
+
})
|
|
1022
|
+
}).nullish()
|
|
1023
|
+
})),
|
|
1024
|
+
parameters: zod.z.array(EndpointParameters).nullish(),
|
|
1025
|
+
requestBody: zod.z.object({
|
|
1026
|
+
required: zod.z.boolean(),
|
|
1027
|
+
content: zod.z.object({
|
|
1028
|
+
"application/json": zod.z.object({
|
|
1029
|
+
schema: Schema.nullish()
|
|
1030
|
+
})
|
|
1031
|
+
}).nullish()
|
|
1032
|
+
}).nullish()
|
|
1033
|
+
});
|
|
1034
|
+
const Operation = zod.z.object({
|
|
1035
|
+
get: Endpoint.nullish(),
|
|
1036
|
+
post: Endpoint.nullish(),
|
|
1037
|
+
patch: Endpoint.nullish(),
|
|
1038
|
+
delete: Endpoint.nullish(),
|
|
1039
|
+
put: Endpoint.nullish()
|
|
1040
|
+
});
|
|
1041
|
+
const Paths = zod.z.record(Operation);
|
|
1042
|
+
zod.z.object({
|
|
1043
|
+
paths: Paths,
|
|
1044
|
+
definitions: Definitions,
|
|
1045
|
+
basePath: zod.z.string(),
|
|
1046
|
+
info: zod.z.object({
|
|
1047
|
+
description: zod.z.string(),
|
|
1048
|
+
title: zod.z.string(),
|
|
1049
|
+
contact: zod.z.object({
|
|
1050
|
+
name: zod.z.string(),
|
|
1051
|
+
url: zod.z.string(),
|
|
1052
|
+
email: zod.z.string()
|
|
1053
|
+
}),
|
|
1054
|
+
version: zod.z.string()
|
|
1055
|
+
}),
|
|
1056
|
+
schemes: zod.z.array(zod.z.string()).nullish(),
|
|
1057
|
+
components: zod.z.object({
|
|
1058
|
+
schemas: Definitions
|
|
1059
|
+
}).nullish()
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
const templateMethod = ({
|
|
1063
|
+
classMethod,
|
|
1064
|
+
description,
|
|
1065
|
+
httpMethod,
|
|
1066
|
+
path,
|
|
1067
|
+
pathParams,
|
|
1068
|
+
bodyParams,
|
|
1069
|
+
queryParams,
|
|
1070
|
+
isFormUrlEncoded,
|
|
1071
|
+
responseClass
|
|
1072
|
+
}) => {
|
|
1073
|
+
let methodParams = "";
|
|
1074
|
+
let methodParamsNoTypes = "";
|
|
1075
|
+
let newPath = `'${path}'`;
|
|
1076
|
+
let importStatements = [];
|
|
1077
|
+
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path);
|
|
1078
|
+
for (const pathParam of sortedPathParams) {
|
|
1079
|
+
const type = ParserUtils.parseType(pathParam);
|
|
1080
|
+
if (pathParam.name !== "namespace") {
|
|
1081
|
+
methodParams += pathParam.name + `:${type}, `;
|
|
1082
|
+
methodParamsNoTypes += pathParam.name + ", ";
|
|
1083
|
+
}
|
|
1084
|
+
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
1085
|
+
if (path.match(`{${pathParam.name}}`)) {
|
|
1086
|
+
if (type === "string") {
|
|
1087
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
1088
|
+
} else {
|
|
1089
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', String(${pName}))`;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
let dataType = null;
|
|
1094
|
+
if (httpMethod !== "get") {
|
|
1095
|
+
dataType = ParserUtils.parseBodyParamsType(bodyParams);
|
|
1096
|
+
importStatements = ParserUtils.parseBodyParamsImports(bodyParams);
|
|
1097
|
+
methodParams += dataType ? `data: ${dataType},` : "";
|
|
1098
|
+
methodParamsNoTypes += dataType ? `data,` : "";
|
|
1099
|
+
}
|
|
1100
|
+
const isAnyRequired = ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
1101
|
+
const queryParamsType = queryParams.length ? `queryParams${isAnyRequired ? "" : "?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
1102
|
+
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as SDKRequestConfig` : "const params = {} as SDKRequestConfig";
|
|
1103
|
+
const isPostPutPatch = ["post", "put", "patch"].includes(httpMethod);
|
|
1104
|
+
const isDelete = ["delete"].includes(httpMethod);
|
|
1105
|
+
let dataPayload = "{params}";
|
|
1106
|
+
const descriptionText = description ? `
|
|
1107
|
+
/**
|
|
1108
|
+
* ${description.replace(/\n/g, "\n * ")}
|
|
1109
|
+
*/` : "";
|
|
1110
|
+
let formPayloadString = "";
|
|
1111
|
+
if (isFormUrlEncoded) {
|
|
1112
|
+
formPayloadString = ``;
|
|
1113
|
+
const params = "{ ...params, headers: { ...params.headers, 'content-type': 'application/x-www-form-urlencoded' } }";
|
|
1114
|
+
dataPayload = dataType ? `CodeGenUtil.getFormUrlEncodedData(data), ${params}` : `null, ${params}`;
|
|
1115
|
+
} else if (isPostPutPatch) {
|
|
1116
|
+
dataPayload = dataType ? `data, {params}` : "null, {params}";
|
|
1117
|
+
} else if (isDelete) {
|
|
1118
|
+
dataPayload = dataType ? `{data, params}` : "{params}";
|
|
1119
|
+
}
|
|
1120
|
+
const isFileUpload = methodParams.indexOf("data: {file") > -1;
|
|
1121
|
+
const resolvedResponseClass = responseClass || "unknown";
|
|
1122
|
+
const resolvedResponseClassValidated = responseClass || "z.unknown()";
|
|
1123
|
+
methodParams = (queryParamsType ? `${methodParams} ${queryParamsType}` : methodParams).replace(/,\s*$/, "");
|
|
1124
|
+
methodParamsNoTypes = queryParamsType ? `${methodParamsNoTypes} queryParams` : methodParamsNoTypes;
|
|
1125
|
+
let methodImpl = "";
|
|
1126
|
+
const isCacheFetch = ["get"].includes(httpMethod) && resolvedResponseClass !== "unknown";
|
|
1127
|
+
const cachedFetchMethod = classMethod;
|
|
1128
|
+
const deprecateTag = isCacheFetch ? `/**
|
|
1129
|
+
* @deprecated Use "${classMethod}()" instead.
|
|
1130
|
+
*/` : "";
|
|
1131
|
+
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
1132
|
+
const methodName = httpMethod === "get" ? cachedFetchMethod : ["post", "put", "patch", "delete"].includes(httpMethod) ? classMethod : "";
|
|
1133
|
+
const responseType = resolvedResponseClass !== "unknown" ? `${resolvedResponseClass}` : "unknown";
|
|
1134
|
+
const generateMethodName = () => `${methodName}(${methodParams}): Promise<${responseSyncType}<${responseType}>>`;
|
|
1135
|
+
const responseSyncType = httpMethod === "get" ? "IResponseWithSync" : ["post", "put", "patch", "delete"].includes(httpMethod) ? "IResponse" : "";
|
|
1136
|
+
methodImpl = `${descriptionText}
|
|
1137
|
+
${generateMethodName()} {
|
|
1138
|
+
${queryParamsDefault}
|
|
1139
|
+
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
1140
|
+
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
1141
|
+
|
|
1142
|
+
${httpMethod === "get" ? ` const res = () => Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated}, '${resolvedResponseClassValidated}')
|
|
1143
|
+
|
|
1144
|
+
if (!this.cache) {
|
|
1145
|
+
return SdkCache.withoutCache(res)
|
|
1146
|
+
}
|
|
1147
|
+
const cacheKey = url + CodeGenUtil.hashCode(JSON.stringify({ params }))
|
|
1148
|
+
return SdkCache.withCache(cacheKey, res)` : ""}${["post", "put", "patch", "delete"].includes(httpMethod) ? ` return Validate.responseType(() => resultPromise, ${resolvedResponseClassValidated}, '${resolvedResponseClassValidated}')` : ""}
|
|
1149
|
+
}
|
|
1150
|
+
`;
|
|
1151
|
+
if (!isGuardInvoked) {
|
|
1152
|
+
methodImpl = `${descriptionText}
|
|
1153
|
+
${deprecateTag}
|
|
1154
|
+
TODO_${classMethod}(${methodParams}): Promise<AxiosResponse<${resolvedResponseClass}>> {
|
|
1155
|
+
${queryParamsDefault}
|
|
1156
|
+
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
1157
|
+
return this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
1158
|
+
}
|
|
1159
|
+
`;
|
|
1160
|
+
}
|
|
1161
|
+
const res = {
|
|
1162
|
+
methodImpl,
|
|
1163
|
+
methodParams,
|
|
1164
|
+
methodParamsNoTypes,
|
|
1165
|
+
importStatements
|
|
1166
|
+
};
|
|
1167
|
+
return res;
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1109
1170
|
const templateApiMethod = ({
|
|
1110
1171
|
classMethod,
|
|
1111
1172
|
description,
|
|
@@ -1167,28 +1228,6 @@ const templateApiMethod = ({
|
|
|
1167
1228
|
return [methodImpl, snippetSdk, snippetShell];
|
|
1168
1229
|
};
|
|
1169
1230
|
|
|
1170
|
-
const templateApiIndex = (serviceName, serviceNameTitle, apiList) => {
|
|
1171
|
-
let imports = "";
|
|
1172
|
-
let returnStatement = "";
|
|
1173
|
-
for (const cl of apiList) {
|
|
1174
|
-
imports += `
|
|
1175
|
-
import { ${cl} } from './${serviceName}/${cl}.js'`;
|
|
1176
|
-
returnStatement += `
|
|
1177
|
-
${cl}, `;
|
|
1178
|
-
}
|
|
1179
|
-
return `/**
|
|
1180
|
-
* AUTO GENERATED
|
|
1181
|
-
*/
|
|
1182
|
-
${imports}
|
|
1183
|
-
|
|
1184
|
-
const apis = {
|
|
1185
|
-
${returnStatement}
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
export const ${ParserUtils.convertDashesToTitleCase(serviceNameTitle)} = apis
|
|
1189
|
-
`;
|
|
1190
|
-
};
|
|
1191
|
-
|
|
1192
1231
|
const templateSdkSnippet = (serviceNameTitle, apiName, methodSnippet) => {
|
|
1193
1232
|
const methodArr = methodSnippet.split("//");
|
|
1194
1233
|
let normMethod = normalizeMethodSnippet(methodArr[0].trim(), "data:");
|
|
@@ -1228,21 +1267,33 @@ const normalizeMethodSnippet = (methodInput, splitWord) => {
|
|
|
1228
1267
|
};
|
|
1229
1268
|
|
|
1230
1269
|
const GIT_URL = "https://github.com/AccelByte/accelbyte-web-sdk/blob/main/packages";
|
|
1231
|
-
class
|
|
1232
|
-
static getPatchedDir = () => path.join(CliParser.getSwaggersOutputPath(), "patched");
|
|
1233
|
-
static getGeneratedPublicFolder = () => `${CliParser.getOutputPath()}/generated-public`;
|
|
1234
|
-
static getGeneratedAdminFolder = () => `${CliParser.getOutputPath()}/generated-admin`;
|
|
1235
|
-
static getGeneratedSnippetsFolder = () => `${CliParser.getSnippetOutputPath()}/generated-snippets`;
|
|
1270
|
+
class SwaggerReaderHelpers {
|
|
1236
1271
|
static getServicePrefix = (servicePaths) => servicePaths[servicePaths.length - 1].split("/")[1];
|
|
1237
|
-
static
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1272
|
+
static parseAllEndpoints = async ({
|
|
1273
|
+
api,
|
|
1274
|
+
sdkName,
|
|
1275
|
+
serviceName
|
|
1276
|
+
}) => {
|
|
1277
|
+
const result = {
|
|
1278
|
+
admin: {
|
|
1279
|
+
arrayDefinitions: [],
|
|
1280
|
+
snippetMap: {},
|
|
1281
|
+
tagToClassImportsRecord: {},
|
|
1282
|
+
tagToEndpointClassesRecord: {},
|
|
1283
|
+
tagToSdkClientRecord: {},
|
|
1284
|
+
tagToSdkFunctionNamesRecord: {},
|
|
1285
|
+
tagToSdkImportsRecord: {}
|
|
1286
|
+
},
|
|
1287
|
+
public: {
|
|
1288
|
+
arrayDefinitions: [],
|
|
1289
|
+
snippetMap: {},
|
|
1290
|
+
tagToClassImportsRecord: {},
|
|
1291
|
+
tagToEndpointClassesRecord: {},
|
|
1292
|
+
tagToSdkClientRecord: {},
|
|
1293
|
+
tagToSdkFunctionNamesRecord: {},
|
|
1294
|
+
tagToSdkImportsRecord: {}
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1246
1297
|
const sortedPathsByLength = new Map(Object.entries(api.paths).sort((a, b) => {
|
|
1247
1298
|
if (a[0].length === b[0].length) {
|
|
1248
1299
|
return a[0].localeCompare(b[0]);
|
|
@@ -1251,55 +1302,62 @@ class CodeGenerator {
|
|
|
1251
1302
|
}
|
|
1252
1303
|
}));
|
|
1253
1304
|
const sortedKeys = Array.from(sortedPathsByLength.keys());
|
|
1254
|
-
const servicePrefix =
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
} else if (path2.indexOf("/healthz") >= 0) {
|
|
1305
|
+
const servicePrefix = SwaggerReaderHelpers.getServicePrefix(sortedKeys);
|
|
1306
|
+
const tagToClassMethodsMap = {
|
|
1307
|
+
admin: {},
|
|
1308
|
+
public: {}
|
|
1309
|
+
};
|
|
1310
|
+
for (const [path, operation] of sortedPathsByLength) {
|
|
1311
|
+
if (path.indexOf("/healthz") >= 0) {
|
|
1262
1312
|
continue;
|
|
1263
1313
|
}
|
|
1314
|
+
const isAdminEndpoint = path.indexOf("/admin/") > -1;
|
|
1315
|
+
const picked = isAdminEndpoint ? result.admin : result.public;
|
|
1316
|
+
const {
|
|
1317
|
+
arrayDefinitions,
|
|
1318
|
+
snippetMap,
|
|
1319
|
+
tagToClassImportsRecord,
|
|
1320
|
+
tagToEndpointClassesRecord,
|
|
1321
|
+
tagToSdkClientRecord,
|
|
1322
|
+
tagToSdkFunctionNamesRecord,
|
|
1323
|
+
tagToSdkImportsRecord
|
|
1324
|
+
} = picked;
|
|
1325
|
+
const tagToClassMethodsMapByType = isAdminEndpoint ? tagToClassMethodsMap.admin : tagToClassMethodsMap.public;
|
|
1264
1326
|
const httpMethods = Object.keys(operation);
|
|
1265
1327
|
for (const httpMethod of httpMethods) {
|
|
1266
1328
|
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
1267
|
-
console.error(JSON.stringify({ path
|
|
1329
|
+
console.error(JSON.stringify({ path, httpMethod }, null, 2));
|
|
1268
1330
|
throw error;
|
|
1269
1331
|
});
|
|
1270
|
-
if (!endpoint.tags)
|
|
1271
|
-
continue;
|
|
1272
|
-
}
|
|
1273
|
-
if (endpoint.deprecated) {
|
|
1332
|
+
if (!endpoint.tags || endpoint.deprecated)
|
|
1274
1333
|
continue;
|
|
1275
|
-
}
|
|
1276
1334
|
const [tag] = endpoint.tags;
|
|
1277
|
-
|
|
1335
|
+
const pathWithBase = `${api.basePath ?? ""}${path}`;
|
|
1336
|
+
tagToClassMethodsMapByType[tag] = tagToClassMethodsMapByType[tag] ? tagToClassMethodsMapByType[tag] : {};
|
|
1278
1337
|
const isForm = endpoint.consumes && endpoint.consumes[0] === "application/x-www-form-urlencoded";
|
|
1279
1338
|
const classMethod = ParserUtils.generateNaturalLangMethod({
|
|
1280
1339
|
servicePrefix,
|
|
1281
|
-
path
|
|
1340
|
+
path,
|
|
1282
1341
|
httpMethod,
|
|
1283
1342
|
isForm,
|
|
1284
|
-
existingMethods:
|
|
1343
|
+
existingMethods: tagToClassMethodsMapByType[tag]
|
|
1285
1344
|
});
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
description = description
|
|
1345
|
+
tagToClassMethodsMapByType[tag][classMethod] = `${path} ${httpMethod}`;
|
|
1346
|
+
if (!snippetMap[pathWithBase]) {
|
|
1347
|
+
snippetMap[pathWithBase] = {};
|
|
1348
|
+
}
|
|
1349
|
+
const description = endpoint.description?.replace(/\s+/g, " ") || "";
|
|
1291
1350
|
const responseClass = ParserUtils.get2xxResponse(endpoint.responses);
|
|
1292
|
-
const { className, classGenName } = ParserUtils.generateClassName(tag);
|
|
1293
|
-
|
|
1351
|
+
const { className, classGenName } = ParserUtils.generateClassName(tag, isAdminEndpoint);
|
|
1352
|
+
tagToClassImportsRecord[className] = tagToClassImportsRecord[className] ? tagToClassImportsRecord[className] : {};
|
|
1294
1353
|
if (responseClass) {
|
|
1295
1354
|
const importTypeClass = ParserUtils.parseRefType(responseClass);
|
|
1296
|
-
|
|
1355
|
+
tagToClassImportsRecord[className][importTypeClass] = `import { ${importTypeClass} } from '../definitions/${importTypeClass}.js'`;
|
|
1297
1356
|
}
|
|
1298
1357
|
if (responseClass && responseClass.endsWith("Array")) {
|
|
1299
1358
|
arrayDefinitions.push(responseClass);
|
|
1300
1359
|
}
|
|
1301
1360
|
const queryParams = ParserUtils.filterQueryParameters(endpoint.parameters);
|
|
1302
|
-
const pathWithBase = `${api.basePath ?? ""}${path2}`;
|
|
1303
1361
|
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod, endpoint.consumes);
|
|
1304
1362
|
const pathParams = ParserUtils.filterPathParams(endpoint.parameters);
|
|
1305
1363
|
let bodyParams = ParserUtils.filterBodyParams(endpoint.parameters);
|
|
@@ -1323,8 +1381,8 @@ class CodeGenerator {
|
|
|
1323
1381
|
isFormUrlEncoded,
|
|
1324
1382
|
responseClass
|
|
1325
1383
|
});
|
|
1326
|
-
|
|
1327
|
-
const [
|
|
1384
|
+
tagToEndpointClassesRecord[tag] = (tagToEndpointClassesRecord[tag] || "") + methodImpl;
|
|
1385
|
+
const [generatedMethodString, snippetMethod, snippetShell] = templateApiMethod({
|
|
1328
1386
|
classMethod,
|
|
1329
1387
|
description,
|
|
1330
1388
|
httpMethod,
|
|
@@ -1336,32 +1394,37 @@ class CodeGenerator {
|
|
|
1336
1394
|
methodParams,
|
|
1337
1395
|
methodParamsNoTypes
|
|
1338
1396
|
});
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1397
|
+
tagToSdkClientRecord[tag] = (tagToSdkClientRecord[tag] || "") + generatedMethodString;
|
|
1398
|
+
tagToSdkFunctionNamesRecord[tag] = (tagToSdkFunctionNamesRecord[tag] || "") + classMethod + ",";
|
|
1399
|
+
tagToSdkImportsRecord[tag] = tagToSdkImportsRecord[tag] ? [.../* @__PURE__ */ new Set([...importStatements, ...tagToSdkImportsRecord[tag]])] : [...new Set(importStatements)];
|
|
1342
1400
|
const serviceNameTitle = ParserUtils.convertDashesToTitleCase(serviceName);
|
|
1343
|
-
const { apiGenName } = ParserUtils.generateApiName(tag);
|
|
1401
|
+
const { apiGenName } = ParserUtils.generateApiName(tag, isAdminEndpoint);
|
|
1344
1402
|
const resultSnippet = templateSdkSnippet(serviceNameTitle, apiGenName, snippetMethod);
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1403
|
+
const currentSnippetMap = {};
|
|
1404
|
+
snippetMap[pathWithBase][httpMethod] = currentSnippetMap;
|
|
1405
|
+
if (!isAdminEndpoint) {
|
|
1406
|
+
currentSnippetMap.web = !isAdminEndpoint ? resultSnippet : "";
|
|
1407
|
+
currentSnippetMap.webGit = !isAdminEndpoint ? GIT_URL + `/sdk-${sdkName}/src/generated-public/${serviceName}/${apiGenName}.ts` : "";
|
|
1408
|
+
}
|
|
1409
|
+
currentSnippetMap.shell = snippetShell;
|
|
1350
1410
|
}
|
|
1351
1411
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
classBufferByTag,
|
|
1357
|
-
dependenciesByTag,
|
|
1358
|
-
classImports,
|
|
1359
|
-
arrayDefinitions,
|
|
1360
|
-
snippetMap
|
|
1361
|
-
};
|
|
1412
|
+
for (const key in result) {
|
|
1413
|
+
result[key].arrayDefinitions = Array.from(new Set(result[key].arrayDefinitions));
|
|
1414
|
+
}
|
|
1415
|
+
return result;
|
|
1362
1416
|
};
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
class CodeGenerator {
|
|
1420
|
+
static getPatchedDir = () => path.join(CliParser.getSwaggersOutputPath(), "patched");
|
|
1421
|
+
static getGeneratedPublicFolder = () => `${CliParser.getOutputPath()}/generated-public`;
|
|
1422
|
+
static getGeneratedAdminFolder = () => `${CliParser.getOutputPath()}/generated-admin`;
|
|
1423
|
+
static getGeneratedSnippetsFolder = () => `${CliParser.getSnippetOutputPath()}/generated-snippets`;
|
|
1424
|
+
static getServicePrefix = (servicePaths) => servicePaths[servicePaths.length - 1].split("/")[1];
|
|
1363
1425
|
static main = async (nameArray) => {
|
|
1364
1426
|
const serviceName = nameArray[0];
|
|
1427
|
+
const sdkName = nameArray[1];
|
|
1365
1428
|
const swaggerFile = nameArray[2];
|
|
1366
1429
|
const parser = new SwaggerParser();
|
|
1367
1430
|
const generatedFolder = CliParser.isAdmin() ? CodeGenerator.getGeneratedAdminFolder() : CodeGenerator.getGeneratedPublicFolder();
|
|
@@ -1376,27 +1439,39 @@ class CodeGenerator {
|
|
|
1376
1439
|
ParserUtils.mkdirIfNotExist(DIST_DIR);
|
|
1377
1440
|
ParserUtils.mkdirIfNotExist(DIST_DEFINITION_DIR);
|
|
1378
1441
|
ParserUtils.mkdirIfNotExist(DIST_ENDPOINTS_DIR);
|
|
1379
|
-
ParserUtils.syncPackageVersion(apiInfo, CliParser.
|
|
1380
|
-
const
|
|
1442
|
+
ParserUtils.syncPackageVersion(apiInfo, CliParser.skipVersionSync(), process.env.PRERELEASE_ID);
|
|
1443
|
+
const parsedInformation = await SwaggerReaderHelpers.parseAllEndpoints({ api, sdkName, serviceName });
|
|
1444
|
+
const parsedInformationByType = CliParser.isAdmin() ? parsedInformation.admin : parsedInformation.public;
|
|
1445
|
+
const {
|
|
1446
|
+
arrayDefinitions,
|
|
1447
|
+
tagToClassImportsRecord,
|
|
1448
|
+
tagToEndpointClassesRecord,
|
|
1449
|
+
tagToSdkClientRecord,
|
|
1450
|
+
tagToSdkFunctionNamesRecord,
|
|
1451
|
+
tagToSdkImportsRecord
|
|
1452
|
+
} = parsedInformationByType;
|
|
1381
1453
|
if (CliParser.getSnippetOutputPath()) {
|
|
1382
1454
|
try {
|
|
1383
|
-
ParserUtils.writeSnippetFile(CodeGenerator.getGeneratedSnippetsFolder(), api.info.title, JSON.stringify(
|
|
1455
|
+
ParserUtils.writeSnippetFile(CodeGenerator.getGeneratedSnippetsFolder(), api.info.title, JSON.stringify({
|
|
1456
|
+
...parsedInformation.public.snippetMap,
|
|
1457
|
+
...parsedInformation.admin.snippetMap
|
|
1458
|
+
}, null, 2));
|
|
1384
1459
|
} catch (err) {
|
|
1385
1460
|
console.log("Generating snippets", err);
|
|
1386
1461
|
}
|
|
1387
1462
|
}
|
|
1388
1463
|
const targetSrcFolder = `${CliParser.getOutputPath()}/`;
|
|
1389
1464
|
const apiList = [];
|
|
1390
|
-
for (const tag in
|
|
1391
|
-
const { className, classGenName } = ParserUtils.generateClassName(tag);
|
|
1392
|
-
const classBuffer =
|
|
1393
|
-
const imports = [.../* @__PURE__ */ new Set([...
|
|
1394
|
-
const apiImports = [.../* @__PURE__ */ new Set([...
|
|
1465
|
+
for (const tag in tagToEndpointClassesRecord) {
|
|
1466
|
+
const { className, classGenName } = ParserUtils.generateClassName(tag, CliParser.isAdmin());
|
|
1467
|
+
const classBuffer = tagToEndpointClassesRecord[tag];
|
|
1468
|
+
const imports = [.../* @__PURE__ */ new Set([...tagToSdkImportsRecord[tag], ...Object.values(tagToClassImportsRecord[className])])];
|
|
1469
|
+
const apiImports = [.../* @__PURE__ */ new Set([...tagToSdkImportsRecord[tag], ...Object.values(tagToClassImportsRecord[className])])];
|
|
1395
1470
|
apiImports.push(`import { ${classGenName} } from './endpoints/${classGenName}.js'`);
|
|
1396
1471
|
ParserUtils.writeClassFile(DIST_ENDPOINTS_DIR, classGenName, classBuffer, imports);
|
|
1397
|
-
const apiBuffer =
|
|
1398
|
-
const { apiGenName } = ParserUtils.generateApiName(tag);
|
|
1399
|
-
ParserUtils.writeApiFile(DIST_DIR, apiGenName, apiBuffer, apiImports,
|
|
1472
|
+
const apiBuffer = tagToSdkClientRecord[tag];
|
|
1473
|
+
const { apiGenName } = ParserUtils.generateApiName(tag, CliParser.isAdmin());
|
|
1474
|
+
ParserUtils.writeApiFile(DIST_DIR, apiGenName, apiBuffer, apiImports, tagToSdkFunctionNamesRecord[tag]);
|
|
1400
1475
|
apiList.push(apiGenName);
|
|
1401
1476
|
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_ENDPOINTS_DIR, `${classGenName}`), targetSrcFolder));
|
|
1402
1477
|
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path.join(DIST_DIR, `${apiGenName}`), targetSrcFolder));
|