@accelbyte/codegen 4.0.2 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/accelbyte-codegen.js +446 -52
- package/dist/accelbyte-codegen.js.map +1 -1
- package/dist/accelbyte-codegen.mjs +446 -52
- package/dist/accelbyte-codegen.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
+
import path7 from "path";
|
|
4
5
|
import yargs from "yargs";
|
|
5
|
-
import path6 from "path";
|
|
6
6
|
|
|
7
7
|
// src/CliParser.ts
|
|
8
8
|
import fs from "fs";
|
|
@@ -55,6 +55,12 @@ var CliParser = class _CliParser {
|
|
|
55
55
|
static isGenerateSnippetOnly = () => {
|
|
56
56
|
return _CliParser.instance().argv.snippetOnly;
|
|
57
57
|
};
|
|
58
|
+
static getWebSocketSchemaPath = () => {
|
|
59
|
+
return _CliParser.instance().argv.webSocketSchema;
|
|
60
|
+
};
|
|
61
|
+
static isGenerateWebSocket = () => {
|
|
62
|
+
return !!_CliParser.getWebSocketSchemaPath();
|
|
63
|
+
};
|
|
58
64
|
};
|
|
59
65
|
|
|
60
66
|
// src/CodeGenerator.ts
|
|
@@ -301,15 +307,15 @@ export enum Key_${classNameWithoutApi} {
|
|
|
301
307
|
`;
|
|
302
308
|
};
|
|
303
309
|
function filterUsedImports(importArr, body) {
|
|
304
|
-
return importArr.filter((
|
|
305
|
-
const start =
|
|
306
|
-
const end =
|
|
310
|
+
return importArr.filter((path8) => {
|
|
311
|
+
const start = path8.indexOf("{") + 1;
|
|
312
|
+
const end = path8.indexOf("}");
|
|
307
313
|
if (start > 0 && end > start) {
|
|
308
|
-
const importName =
|
|
314
|
+
const importName = path8.slice(start, end).trim();
|
|
309
315
|
return body.includes(importName);
|
|
310
316
|
}
|
|
311
317
|
return false;
|
|
312
|
-
}).map((
|
|
318
|
+
}).map((path8) => path8).join("\n") + "\n";
|
|
313
319
|
}
|
|
314
320
|
|
|
315
321
|
// src/ParserUtils.ts
|
|
@@ -326,8 +332,8 @@ var REMOVED_KEYWORDS = [
|
|
|
326
332
|
"/{namespace}/"
|
|
327
333
|
];
|
|
328
334
|
var ParserUtils = class _ParserUtils {
|
|
329
|
-
static getVersionSuffixFromPath(
|
|
330
|
-
const version2_3_4_etc =
|
|
335
|
+
static getVersionSuffixFromPath(path8) {
|
|
336
|
+
const version2_3_4_etc = path8.match(/\/v([2-9]|[1-9]\d+)\/+/);
|
|
331
337
|
const methodSuffix = version2_3_4_etc ? `_v${version2_3_4_etc[1]}` : "";
|
|
332
338
|
return methodSuffix;
|
|
333
339
|
}
|
|
@@ -522,14 +528,14 @@ var ParserUtils = class _ParserUtils {
|
|
|
522
528
|
* to this
|
|
523
529
|
* `createGenerateByRequestIdByUserId`
|
|
524
530
|
*/
|
|
525
|
-
static generateNaturalLangMethod = ({ servicePrefix, path:
|
|
526
|
-
let path_ =
|
|
531
|
+
static generateNaturalLangMethod = ({ servicePrefix, path: path8, httpMethod, isForm, existingMethods, permissionType }) => {
|
|
532
|
+
let path_ = path8;
|
|
527
533
|
path_ = path_.replace(`/${servicePrefix}/`, "/");
|
|
528
534
|
REMOVED_KEYWORDS.forEach((prefix) => {
|
|
529
535
|
path_ = path_.replace(prefix, "/");
|
|
530
536
|
});
|
|
531
537
|
path_ = path_.substring(1);
|
|
532
|
-
const isPlural = httpMethod === "get" && !(
|
|
538
|
+
const isPlural = httpMethod === "get" && !(path8.slice(-1) === "}");
|
|
533
539
|
if (!isPlural) {
|
|
534
540
|
path_ = _ParserUtils.replaceAll(path_, "ies/", "y/");
|
|
535
541
|
path_ = _ParserUtils.replaceAll(path_, "s/", "/");
|
|
@@ -572,9 +578,9 @@ var ParserUtils = class _ParserUtils {
|
|
|
572
578
|
const genPath = _.upperFirst(lastWords) + "/" + listBeforeLastWords.join("/") + listByParams.reverse().join("/");
|
|
573
579
|
let generatedMethod = _.camelCase(mappedMethod(httpMethod, isForm, permissionType) + genPath);
|
|
574
580
|
generatedMethod = _ParserUtils.replaceAll(generatedMethod, "Byword", "_By");
|
|
575
|
-
const testedGeneratedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(
|
|
576
|
-
generatedMethod = resolveConflicts({ path:
|
|
577
|
-
generatedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(
|
|
581
|
+
const testedGeneratedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path8);
|
|
582
|
+
generatedMethod = resolveConflicts({ path: path8, generatedMethod, testedGeneratedMethod, existingMethods });
|
|
583
|
+
generatedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path8);
|
|
578
584
|
return generatedMethod;
|
|
579
585
|
};
|
|
580
586
|
static filterBodyParams(parameters) {
|
|
@@ -729,8 +735,8 @@ var ParserUtils = class _ParserUtils {
|
|
|
729
735
|
*/
|
|
730
736
|
${content}`;
|
|
731
737
|
};
|
|
732
|
-
static sortPathParamsByPath = (pathParams,
|
|
733
|
-
const params =
|
|
738
|
+
static sortPathParamsByPath = (pathParams, path8) => {
|
|
739
|
+
const params = path8.match(/{\w*}/g) || [];
|
|
734
740
|
const cleanParams = params.map((param) => param.replace("{", "").replace("}", ""));
|
|
735
741
|
return pathParams.sort((a, b) => cleanParams.indexOf(a.name) - cleanParams.indexOf(b.name));
|
|
736
742
|
};
|
|
@@ -754,30 +760,30 @@ var mappedMethod = (httpMethod, isForm, permissionType) => {
|
|
|
754
760
|
return "delete";
|
|
755
761
|
}
|
|
756
762
|
};
|
|
757
|
-
var resolveConflicts = ({ path:
|
|
763
|
+
var resolveConflicts = ({ path: path8, generatedMethod, testedGeneratedMethod, existingMethods }) => {
|
|
758
764
|
let _testedGenMethod = testedGeneratedMethod;
|
|
759
765
|
try {
|
|
760
|
-
testConflict(
|
|
766
|
+
testConflict(path8, _testedGenMethod, existingMethods);
|
|
761
767
|
} catch (e) {
|
|
762
|
-
if (
|
|
768
|
+
if (path8.indexOf("/namespaces/") >= 0) {
|
|
763
769
|
generatedMethod += "_ByNS";
|
|
764
770
|
_testedGenMethod += "_ByNS";
|
|
765
771
|
}
|
|
766
772
|
}
|
|
767
773
|
try {
|
|
768
|
-
testConflict(
|
|
774
|
+
testConflict(path8, _testedGenMethod, existingMethods);
|
|
769
775
|
} catch (e) {
|
|
770
|
-
if (
|
|
776
|
+
if (path8.indexOf("/admin/") >= 0) {
|
|
771
777
|
generatedMethod += "_admin";
|
|
772
778
|
_testedGenMethod += "_admin";
|
|
773
779
|
}
|
|
774
780
|
}
|
|
775
|
-
testConflict(
|
|
781
|
+
testConflict(path8, _testedGenMethod, existingMethods);
|
|
776
782
|
return generatedMethod;
|
|
777
783
|
};
|
|
778
|
-
var testConflict = (
|
|
784
|
+
var testConflict = (path8, generatedMethod, existingMethods) => {
|
|
779
785
|
if (existingMethods[generatedMethod]) {
|
|
780
|
-
const conflictingMethod = { path:
|
|
786
|
+
const conflictingMethod = { path: path8, generatedMethod };
|
|
781
787
|
throw Error(
|
|
782
788
|
`Duplicate method conflict in ${JSON.stringify(conflictingMethod)},
|
|
783
789
|
existingMethods: ${JSON.stringify(existingMethods, null, 2)}`
|
|
@@ -894,7 +900,7 @@ var OpenApiSpec = z2.object({
|
|
|
894
900
|
var templateApiMethod = ({
|
|
895
901
|
classMethod,
|
|
896
902
|
httpMethod,
|
|
897
|
-
path:
|
|
903
|
+
path: path8,
|
|
898
904
|
pathParams,
|
|
899
905
|
bodyParams,
|
|
900
906
|
responseClasses,
|
|
@@ -903,12 +909,12 @@ var templateApiMethod = ({
|
|
|
903
909
|
methodParamsNoTypes,
|
|
904
910
|
xSecurity
|
|
905
911
|
}) => {
|
|
906
|
-
let newPath = `'${
|
|
912
|
+
let newPath = `'${path8}'`;
|
|
907
913
|
let snippetMethod = "";
|
|
908
914
|
for (const pathParam of pathParams) {
|
|
909
915
|
const type = ParserUtils.parseType(pathParam);
|
|
910
916
|
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
911
|
-
if (
|
|
917
|
+
if (path8.match(`{${pathParam.name}}`)) {
|
|
912
918
|
if (type === "string") {
|
|
913
919
|
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
914
920
|
} else {
|
|
@@ -916,9 +922,9 @@ var templateApiMethod = ({
|
|
|
916
922
|
}
|
|
917
923
|
}
|
|
918
924
|
}
|
|
919
|
-
const snippetShellArgs = ["--location --request", `${httpMethod} '__DOMAIN__${
|
|
925
|
+
const snippetShellArgs = ["--location --request", `${httpMethod} '__DOMAIN__${path8}'`, "--header 'accept: application/json'"];
|
|
920
926
|
const snippetApiArgs = [];
|
|
921
|
-
if (xSecurity !== void 0 ||
|
|
927
|
+
if (xSecurity !== void 0 || path8.includes("/admin")) {
|
|
922
928
|
snippetShellArgs.push("--header 'Authorization: Bearer {access_token}'");
|
|
923
929
|
snippetApiArgs.push("{ axiosConfig: { request: { headers: { Authorization: 'Bearer {access_token}' } } } }".trim());
|
|
924
930
|
}
|
|
@@ -956,7 +962,7 @@ var templateMethod = ({
|
|
|
956
962
|
classMethod,
|
|
957
963
|
description,
|
|
958
964
|
httpMethod,
|
|
959
|
-
path:
|
|
965
|
+
path: path8,
|
|
960
966
|
pathParams,
|
|
961
967
|
bodyParams,
|
|
962
968
|
queryParams,
|
|
@@ -966,9 +972,9 @@ var templateMethod = ({
|
|
|
966
972
|
}) => {
|
|
967
973
|
let methodParams = "";
|
|
968
974
|
let methodParamsNoTypes = "";
|
|
969
|
-
let newPath = `'${
|
|
975
|
+
let newPath = `'${path8}'`;
|
|
970
976
|
let importStatements = [];
|
|
971
|
-
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams,
|
|
977
|
+
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path8);
|
|
972
978
|
for (const pathParam of sortedPathParams) {
|
|
973
979
|
const type = ParserUtils.parseType(pathParam);
|
|
974
980
|
if (pathParam.name !== "namespace") {
|
|
@@ -976,7 +982,7 @@ var templateMethod = ({
|
|
|
976
982
|
methodParamsNoTypes += pathParam.name + ", ";
|
|
977
983
|
}
|
|
978
984
|
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
979
|
-
if (
|
|
985
|
+
if (path8.match(`{${pathParam.name}}`)) {
|
|
980
986
|
if (type === "string") {
|
|
981
987
|
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
982
988
|
} else {
|
|
@@ -1041,7 +1047,7 @@ var POST_FETCH_INCLUDES_PATH = ["/table-query/"];
|
|
|
1041
1047
|
var templateQueryMethod = ({
|
|
1042
1048
|
classMethod,
|
|
1043
1049
|
httpMethod,
|
|
1044
|
-
path:
|
|
1050
|
+
path: path8,
|
|
1045
1051
|
pathParams,
|
|
1046
1052
|
responseClasses,
|
|
1047
1053
|
methodParams,
|
|
@@ -1049,14 +1055,14 @@ var templateQueryMethod = ({
|
|
|
1049
1055
|
description,
|
|
1050
1056
|
deprecated
|
|
1051
1057
|
}) => {
|
|
1052
|
-
const isPostFetch = httpMethod === "post" && (POST_FETCH_INCLUDES_PATH.some((p) =>
|
|
1058
|
+
const isPostFetch = httpMethod === "post" && (POST_FETCH_INCLUDES_PATH.some((p) => path8.includes(p)) || path8.endsWith("/list"));
|
|
1053
1059
|
const isFetch = classMethod.startsWith("fetch");
|
|
1054
1060
|
const isGet = httpMethod === "get" || isPostFetch || isFetch;
|
|
1055
1061
|
const queryMethod = isGet ? "useQuery" : "useMutation";
|
|
1056
1062
|
let mParams = "";
|
|
1057
1063
|
let mParamsNoTypes = "";
|
|
1058
|
-
let newPath = `'${
|
|
1059
|
-
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams,
|
|
1064
|
+
let newPath = `'${path8}'`;
|
|
1065
|
+
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path8);
|
|
1060
1066
|
for (const pathParam of sortedPathParams) {
|
|
1061
1067
|
const type = ParserUtils.parseType(pathParam);
|
|
1062
1068
|
if (pathParam.name !== "namespace") {
|
|
@@ -1064,7 +1070,7 @@ var templateQueryMethod = ({
|
|
|
1064
1070
|
mParamsNoTypes += pathParam.name + ", ";
|
|
1065
1071
|
}
|
|
1066
1072
|
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
1067
|
-
if (
|
|
1073
|
+
if (path8.match(`{${pathParam.name}}`)) {
|
|
1068
1074
|
if (type === "string") {
|
|
1069
1075
|
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
1070
1076
|
} else {
|
|
@@ -1190,7 +1196,8 @@ var templateSdkSnippet = ({
|
|
|
1190
1196
|
serviceNameTitle,
|
|
1191
1197
|
apiName,
|
|
1192
1198
|
snippetMethod,
|
|
1193
|
-
snippetApiArgs: snippetApiArgsParam
|
|
1199
|
+
snippetApiArgs: snippetApiArgsParam,
|
|
1200
|
+
isUMD
|
|
1194
1201
|
}) => {
|
|
1195
1202
|
const methodArr = snippetMethod.split("//");
|
|
1196
1203
|
const snippetApiArgs = ["sdk", ...snippetApiArgsParam];
|
|
@@ -1198,7 +1205,8 @@ var templateSdkSnippet = ({
|
|
|
1198
1205
|
normMethod = normalizeMethodSnippet(normMethod, "queryParams:");
|
|
1199
1206
|
normMethod = normalizeMethodSnippet(normMethod, "queryParams?:");
|
|
1200
1207
|
normMethod += "\n\n//" + methodArr[1];
|
|
1201
|
-
const
|
|
1208
|
+
const sdkAcronyms = ["Ams", "Gdpr", "Iam", "Ugc"];
|
|
1209
|
+
let sdkSnippet = `import { AccelByte } from '@accelbyte/sdk'
|
|
1202
1210
|
import { ${serviceNameTitle} } from '@accelbyte/sdk-${serviceNameTitle.toLowerCase()}'
|
|
1203
1211
|
|
|
1204
1212
|
const sdk = AccelByte.SDK({
|
|
@@ -1212,6 +1220,26 @@ const sdk = AccelByte.SDK({
|
|
|
1212
1220
|
|
|
1213
1221
|
${serviceNameTitle}.${apiName}(${snippetApiArgs.join(", ")})
|
|
1214
1222
|
.${normMethod}`;
|
|
1223
|
+
if (isUMD) {
|
|
1224
|
+
sdkSnippet = `<script src="https://unpkg.com/@accelbyte/sdk/dist/global/index.global.js"></script>
|
|
1225
|
+
<script src="https://unpkg.com/@accelbyte/sdk-${serviceNameTitle.toLowerCase()}/dist/global/index.global.js"></script>
|
|
1226
|
+
|
|
1227
|
+
<script>
|
|
1228
|
+
|
|
1229
|
+
const sdk = AccelByteSDK.AccelByte.SDK({
|
|
1230
|
+
coreConfig: {
|
|
1231
|
+
baseURL: '__DOMAIN__',
|
|
1232
|
+
clientId: '77f88506b6174c3ea4d925f5b4096ce8',
|
|
1233
|
+
namespace: 'accelbyte',
|
|
1234
|
+
redirectURI: 'http://localhost:3030'
|
|
1235
|
+
}
|
|
1236
|
+
})
|
|
1237
|
+
|
|
1238
|
+
AccelByteSDK_${sdkAcronyms.includes(serviceNameTitle) ? serviceNameTitle.toUpperCase() : serviceNameTitle}.${apiName}(${snippetApiArgs.join(", ")})
|
|
1239
|
+
.${normMethod}
|
|
1240
|
+
|
|
1241
|
+
</script>`;
|
|
1242
|
+
}
|
|
1215
1243
|
return sdkSnippet;
|
|
1216
1244
|
};
|
|
1217
1245
|
var normalizeMethodSnippet = (methodInput, splitWord) => {
|
|
@@ -1280,11 +1308,11 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
|
1280
1308
|
admin: {},
|
|
1281
1309
|
public: {}
|
|
1282
1310
|
};
|
|
1283
|
-
for (const [
|
|
1284
|
-
if (
|
|
1311
|
+
for (const [path8, operation] of sortedPathsByLength) {
|
|
1312
|
+
if (path8.indexOf("/healthz") >= 0) {
|
|
1285
1313
|
continue;
|
|
1286
1314
|
}
|
|
1287
|
-
const isAdminEndpoint =
|
|
1315
|
+
const isAdminEndpoint = path8.indexOf("/admin/") > -1;
|
|
1288
1316
|
const picked = isAdminEndpoint ? result.admin : result.public;
|
|
1289
1317
|
const {
|
|
1290
1318
|
arrayDefinitions,
|
|
@@ -1302,25 +1330,25 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
|
1302
1330
|
const httpMethods = Object.keys(operation);
|
|
1303
1331
|
for (const httpMethod of httpMethods) {
|
|
1304
1332
|
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
1305
|
-
console.error(JSON.stringify({ path:
|
|
1333
|
+
console.error(JSON.stringify({ path: path8, httpMethod }, null, 2));
|
|
1306
1334
|
throw error;
|
|
1307
1335
|
});
|
|
1308
1336
|
if (!endpoint.tags) continue;
|
|
1309
1337
|
const [tag] = endpoint.tags;
|
|
1310
|
-
const pathWithBase = `${api.basePath ?? ""}${
|
|
1338
|
+
const pathWithBase = `${api.basePath ?? ""}${path8}`;
|
|
1311
1339
|
const permissionType = getPermissionType(getPermission(endpoint));
|
|
1312
1340
|
tagToClassMethodsMapByType[tag] = tagToClassMethodsMapByType[tag] ? tagToClassMethodsMapByType[tag] : {};
|
|
1313
1341
|
const isForm = endpoint.consumes && endpoint.consumes[0] === "application/x-www-form-urlencoded";
|
|
1314
1342
|
const classMethod = ParserUtils.generateNaturalLangMethod({
|
|
1315
1343
|
servicePrefix,
|
|
1316
|
-
path:
|
|
1344
|
+
path: path8,
|
|
1317
1345
|
httpMethod,
|
|
1318
1346
|
isForm,
|
|
1319
1347
|
existingMethods: tagToClassMethodsMapByType[tag],
|
|
1320
1348
|
permissionType
|
|
1321
1349
|
});
|
|
1322
|
-
tagToClassMethodsMapByType[tag][classMethod] = `${
|
|
1323
|
-
generatedMethods[`${
|
|
1350
|
+
tagToClassMethodsMapByType[tag][classMethod] = `${path8} ${httpMethod}`;
|
|
1351
|
+
generatedMethods[`${path8} ${httpMethod}`] = `${classMethod}`;
|
|
1324
1352
|
if (!snippetMap[pathWithBase]) {
|
|
1325
1353
|
snippetMap[pathWithBase] = {};
|
|
1326
1354
|
}
|
|
@@ -1403,9 +1431,17 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
|
1403
1431
|
snippetMethod,
|
|
1404
1432
|
snippetApiArgs
|
|
1405
1433
|
});
|
|
1434
|
+
const resultUMDSnippet = templateSdkSnippet({
|
|
1435
|
+
serviceNameTitle,
|
|
1436
|
+
apiName: apiGenName,
|
|
1437
|
+
snippetMethod,
|
|
1438
|
+
snippetApiArgs,
|
|
1439
|
+
isUMD: true
|
|
1440
|
+
});
|
|
1406
1441
|
const currentSnippetMap = {};
|
|
1407
1442
|
snippetMap[pathWithBase][httpMethod] = currentSnippetMap;
|
|
1408
1443
|
currentSnippetMap.web = resultSnippet;
|
|
1444
|
+
currentSnippetMap.webUMD = resultUMDSnippet;
|
|
1409
1445
|
const generatedDirName = isAdminEndpoint ? "generated-admin" : "generated-public";
|
|
1410
1446
|
currentSnippetMap.webGit = GIT_URL + `/sdk-${sdkName}/src/${generatedDirName}/${apiGenName}.ts`;
|
|
1411
1447
|
currentSnippetMap.shell = snippetShell;
|
|
@@ -1419,7 +1455,7 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
|
1419
1455
|
};
|
|
1420
1456
|
|
|
1421
1457
|
// src/templates/template-api-index.ts
|
|
1422
|
-
var templateApiIndex = (serviceNameTitle, apiList) => {
|
|
1458
|
+
var templateApiIndex = (serviceNameTitle, apiList, isGenerateWebSocket = false) => {
|
|
1423
1459
|
let imports = "";
|
|
1424
1460
|
let returnStatement = "";
|
|
1425
1461
|
for (const cl of apiList) {
|
|
@@ -1428,6 +1464,12 @@ var templateApiIndex = (serviceNameTitle, apiList) => {
|
|
|
1428
1464
|
import { ${cl} } from './${dir}/${cl}.js'`;
|
|
1429
1465
|
returnStatement += `
|
|
1430
1466
|
${cl}, `;
|
|
1467
|
+
}
|
|
1468
|
+
if (isGenerateWebSocket) {
|
|
1469
|
+
imports += `
|
|
1470
|
+
import { WebSocketClass } from './generated-websocket/WebSocketClass.js'`;
|
|
1471
|
+
returnStatement += `
|
|
1472
|
+
WebSocket: WebSocketClass, `;
|
|
1431
1473
|
}
|
|
1432
1474
|
return `/**
|
|
1433
1475
|
* AUTO GENERATED
|
|
@@ -1850,7 +1892,8 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
1850
1892
|
};
|
|
1851
1893
|
generatePublicOrAdmin(true);
|
|
1852
1894
|
generatePublicOrAdmin(false);
|
|
1853
|
-
const
|
|
1895
|
+
const isGenerateWebSocket = CliParser.isGenerateWebSocket();
|
|
1896
|
+
const apiIndexBuff = templateApiIndex(serviceNameTitle, mainApiList, isGenerateWebSocket);
|
|
1854
1897
|
ParserUtils.writeApiMainFile(_CodeGenerator.srcFolder(), serviceNameTitle, apiIndexBuff);
|
|
1855
1898
|
console.log("\nCOMPLETED\n----------\n\n");
|
|
1856
1899
|
return { indexImports: indexImportsSet, queryImports: queryImportsSet };
|
|
@@ -1921,25 +1964,373 @@ var SwaggerDownloader = class _SwaggerDownloader {
|
|
|
1921
1964
|
};
|
|
1922
1965
|
};
|
|
1923
1966
|
|
|
1967
|
+
// src/WebsocketGenerator.ts
|
|
1968
|
+
import fs6 from "fs";
|
|
1969
|
+
import path6 from "path";
|
|
1970
|
+
|
|
1971
|
+
// src/templates/template-ws-class.ts
|
|
1972
|
+
var definitionToFunctionName = (type) => {
|
|
1973
|
+
if (type.endsWith("Request")) {
|
|
1974
|
+
return "send" + capitalize(type.slice(0, type.length - 7));
|
|
1975
|
+
}
|
|
1976
|
+
return type;
|
|
1977
|
+
};
|
|
1978
|
+
var renderSendFunction = (name, definition) => {
|
|
1979
|
+
const functionName = definitionToFunctionName(name);
|
|
1980
|
+
return `const ${functionName} = (data: Omit<Definitions.${capitalize(name)}, 'type'>) => {
|
|
1981
|
+
send({ type: '${name}', ...data })
|
|
1982
|
+
}`;
|
|
1983
|
+
};
|
|
1984
|
+
var templateWebsocketClass = (name, path8, definitions) => {
|
|
1985
|
+
const requestDefinitions = Object.keys(definitions).filter((key) => {
|
|
1986
|
+
const val = definitions[key];
|
|
1987
|
+
return val["x-type"] == "request";
|
|
1988
|
+
}).map((key) => [key, definitions[key]]);
|
|
1989
|
+
return `/* eslint-disable camelcase */
|
|
1990
|
+
/* eslint-disable no-inner-declarations */
|
|
1991
|
+
// @ts-ignore -> ts-expect-error TS6133
|
|
1992
|
+
import { AccelByteSDK, RefreshToken, SdkSetConfigParam } from '@accelbyte/sdk'
|
|
1993
|
+
import * as Definitions from './WebSocketDefinitions'
|
|
1994
|
+
|
|
1995
|
+
const messageParser = (data: string) => {
|
|
1996
|
+
const toVal = (str?: string) => {
|
|
1997
|
+
if (str) {
|
|
1998
|
+
if (str.startsWith('[') && str.endsWith(']')) {
|
|
1999
|
+
return str
|
|
2000
|
+
.slice(1, str.length - 1)
|
|
2001
|
+
.split(',')
|
|
2002
|
+
.filter(v => v !== '')
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
return str
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
const entries = data.split('\\n')
|
|
2009
|
+
.filter(line => line !== '')
|
|
2010
|
+
.map(line => {
|
|
2011
|
+
const [key, valStr] = line.split(': ')
|
|
2012
|
+
return [key, toVal(valStr)]
|
|
2013
|
+
})
|
|
2014
|
+
|
|
2015
|
+
return Object.fromEntries(entries)
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
const messageSerializer = (data: Record<string, any>) => {
|
|
2019
|
+
return Object.keys(data)
|
|
2020
|
+
.map(key => {
|
|
2021
|
+
const toStr = (val: any) => {
|
|
2022
|
+
// array
|
|
2023
|
+
if (Array.isArray(val)) {
|
|
2024
|
+
return \`[\${String(val)}]\`
|
|
2025
|
+
}
|
|
2026
|
+
// null, undefined
|
|
2027
|
+
if (!val) {
|
|
2028
|
+
return ''
|
|
2029
|
+
}
|
|
2030
|
+
return String(val)
|
|
2031
|
+
}
|
|
2032
|
+
const val = data[key]
|
|
2033
|
+
const valStr = toStr(val)
|
|
2034
|
+
|
|
2035
|
+
return \`\${key}: \${valStr}\`
|
|
2036
|
+
})
|
|
2037
|
+
.join('\\n')
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
export function WebSocketClass(sdk: AccelByteSDK, args?: SdkSetConfigParam) {
|
|
2041
|
+
const sdkAssembly = sdk.assembly()
|
|
2042
|
+
const baseURL = (args?.coreConfig?.baseURL ?? sdkAssembly.coreConfig.baseURL).replace('http', 'ws')
|
|
2043
|
+
const path = '${path8}'
|
|
2044
|
+
const url = baseURL + path
|
|
2045
|
+
let ws: WebSocket | null = null
|
|
2046
|
+
let isDisconnectManually = false
|
|
2047
|
+
const allowReconnect = sdkAssembly.webSocketConfig.allowReconnect ?? true
|
|
2048
|
+
const maxReconnectAttempts = sdkAssembly.webSocketConfig.maxReconnectAttempts ?? 0
|
|
2049
|
+
let reconnectAttempts = maxReconnectAttempts
|
|
2050
|
+
|
|
2051
|
+
const connect = () => {
|
|
2052
|
+
const token = sdk.getToken()
|
|
2053
|
+
|
|
2054
|
+
if (!token.accessToken) {
|
|
2055
|
+
console.warn('No access token, please login first')
|
|
2056
|
+
return
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
if (!ws) {
|
|
2060
|
+
ws = new WebSocket(url, token.accessToken)
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
const refreshToken = async () => {
|
|
2065
|
+
const { refreshToken } = sdk.getToken()
|
|
2066
|
+
if (refreshToken) {
|
|
2067
|
+
const refresh = new RefreshToken({
|
|
2068
|
+
config: {
|
|
2069
|
+
axiosConfig: sdkAssembly.axiosConfig.request,
|
|
2070
|
+
clientId: sdkAssembly.coreConfig.clientId,
|
|
2071
|
+
refreshToken
|
|
2072
|
+
}
|
|
2073
|
+
})
|
|
2074
|
+
const result = await refresh.runWithLock()
|
|
2075
|
+
if (result) {
|
|
2076
|
+
sdk.setToken({
|
|
2077
|
+
accessToken: result.access_token,
|
|
2078
|
+
refreshToken: result.refresh_token
|
|
2079
|
+
})
|
|
2080
|
+
return true
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
return false
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
const handleReconnect = async (ev: CloseEvent) => {
|
|
2087
|
+
if (!allowReconnect || isDisconnectManually || !sdk.getToken().accessToken) return
|
|
2088
|
+
// token revoked
|
|
2089
|
+
if (ev.code === 4020) {
|
|
2090
|
+
await refreshToken()
|
|
2091
|
+
reconnectAttempts--
|
|
2092
|
+
connect()
|
|
2093
|
+
} else if (ev.code >= 1001 && ev.code <= 2999) {
|
|
2094
|
+
// Only reconnect if codes in range 1001-2999
|
|
2095
|
+
if (!ws || ws.readyState !== ws.OPEN) return
|
|
2096
|
+
|
|
2097
|
+
if (maxReconnectAttempts === 0) {
|
|
2098
|
+
setTimeout(() => {
|
|
2099
|
+
connect()
|
|
2100
|
+
}, 1000)
|
|
2101
|
+
} else if (reconnectAttempts !== 0) {
|
|
2102
|
+
setTimeout(() => {
|
|
2103
|
+
reconnectAttempts--
|
|
2104
|
+
connect()
|
|
2105
|
+
}, 1000)
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
const disconnect = (code?: number, reason?: string) => {
|
|
2111
|
+
if (ws) {
|
|
2112
|
+
ws.close(code, reason)
|
|
2113
|
+
isDisconnectManually = true
|
|
2114
|
+
ws = null
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
const send = (message: Definitions.WebSocketRequest) => {
|
|
2119
|
+
if (ws) {
|
|
2120
|
+
ws.send(messageSerializer(message))
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
const sendRaw = (rawMessage: string) => {
|
|
2125
|
+
if (ws) {
|
|
2126
|
+
ws.send(rawMessage)
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
const onOpen = (cb: () => any) => {
|
|
2131
|
+
if (ws) {
|
|
2132
|
+
function listener(this: WebSocket, _ev: Event) {
|
|
2133
|
+
isDisconnectManually = false
|
|
2134
|
+
reconnectAttempts = maxReconnectAttempts
|
|
2135
|
+
cb()
|
|
2136
|
+
}
|
|
2137
|
+
ws.addEventListener('open', listener)
|
|
2138
|
+
return {
|
|
2139
|
+
removeEventListener: () => ws?.removeEventListener('open', listener)
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
return {}
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
const onClose = (cb: (ev: CloseEvent) => any) => {
|
|
2146
|
+
if (ws) {
|
|
2147
|
+
function listener(this: WebSocket, ev: CloseEvent) {
|
|
2148
|
+
handleReconnect(ev)
|
|
2149
|
+
cb(ev)
|
|
2150
|
+
}
|
|
2151
|
+
ws.addEventListener('close', listener)
|
|
2152
|
+
return {
|
|
2153
|
+
removeEventListener: () => ws?.removeEventListener('close', listener)
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
return {}
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
const onMessage = (cb: (message: Definitions.WebSocketResponseOrNotification | string) => any, raw: boolean = false) => {
|
|
2160
|
+
if (ws) {
|
|
2161
|
+
function listener(this: WebSocket, ev: MessageEvent<any>) {
|
|
2162
|
+
if (raw) {
|
|
2163
|
+
cb(ev.data)
|
|
2164
|
+
} else {
|
|
2165
|
+
const result = Definitions.WebSocketResponseOrNotification.parse(messageParser(ev.data))
|
|
2166
|
+
cb(result)
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
ws.addEventListener('message', listener)
|
|
2170
|
+
return {
|
|
2171
|
+
removeEventListener: () => ws?.removeEventListener('message', listener)
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
return {}
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
const onError = (cb: (err: any) => any) => {
|
|
2178
|
+
if (ws) {
|
|
2179
|
+
function listener(this: WebSocket, err: any) {
|
|
2180
|
+
cb(err)
|
|
2181
|
+
}
|
|
2182
|
+
ws.addEventListener('error', listener)
|
|
2183
|
+
return {
|
|
2184
|
+
removeEventListener: () => ws?.removeEventListener('error', listener)
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
return {}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
${requestDefinitions.map(([name2, definition]) => renderSendFunction(name2, definition)).join(`
|
|
2191
|
+
|
|
2192
|
+
`)}
|
|
2193
|
+
|
|
2194
|
+
return {
|
|
2195
|
+
instance: ws,
|
|
2196
|
+
connect,
|
|
2197
|
+
disconnect,
|
|
2198
|
+
send,
|
|
2199
|
+
sendRaw,
|
|
2200
|
+
onOpen,
|
|
2201
|
+
onClose,
|
|
2202
|
+
onMessage,
|
|
2203
|
+
onError,
|
|
2204
|
+
${requestDefinitions.map(([name2, _2]) => definitionToFunctionName(name2)).join(",\n ")}
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
`;
|
|
2209
|
+
};
|
|
2210
|
+
|
|
2211
|
+
// src/templates/template-ws-defintions.ts
|
|
2212
|
+
var renderZod = (property) => {
|
|
2213
|
+
switch (property.type) {
|
|
2214
|
+
case "string":
|
|
2215
|
+
return `z.coerce.string()`;
|
|
2216
|
+
case "integer":
|
|
2217
|
+
return `z.coerce.number()`;
|
|
2218
|
+
case "boolean":
|
|
2219
|
+
return `z.boolean()`;
|
|
2220
|
+
case "array":
|
|
2221
|
+
return `z.array(${renderZod(property.items)})`;
|
|
2222
|
+
default:
|
|
2223
|
+
return `z.any()`;
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
var renderProperty = (name, type, property, required) => {
|
|
2227
|
+
const isRequired = required && required.includes(name);
|
|
2228
|
+
return `${name}: ${renderZod(property)}${isRequired || type != "request" ? "" : ".optional()"}`;
|
|
2229
|
+
};
|
|
2230
|
+
var renderDefinition = (name, definition) => {
|
|
2231
|
+
const capitalizedName = capitalize(name);
|
|
2232
|
+
if (definition.properties) {
|
|
2233
|
+
const properties = Object.entries(definition.properties);
|
|
2234
|
+
return `export const ${capitalizedName} = z.object({
|
|
2235
|
+
type: z.literal("${name}"),
|
|
2236
|
+
${properties.map(([name2, property]) => renderProperty(name2, definition["x-type"], property, definition.required)).join(",\n ")}
|
|
2237
|
+
})
|
|
2238
|
+
|
|
2239
|
+
export type ${capitalizedName} = z.infer<typeof ${capitalizedName}>
|
|
2240
|
+
`;
|
|
2241
|
+
}
|
|
2242
|
+
return "";
|
|
2243
|
+
};
|
|
2244
|
+
var renderAllDefinitions = (definitions) => {
|
|
2245
|
+
if (definitions) {
|
|
2246
|
+
const definitionEntries = Object.entries(definitions);
|
|
2247
|
+
return definitionEntries.map(([name, definition]) => renderDefinition(name, definition)).join("\n\n");
|
|
2248
|
+
}
|
|
2249
|
+
return "";
|
|
2250
|
+
};
|
|
2251
|
+
var renderUnion = (type, definitions) => {
|
|
2252
|
+
if (definitions) {
|
|
2253
|
+
let capitalizedType = "";
|
|
2254
|
+
if (typeof type === "string") {
|
|
2255
|
+
capitalizedType = capitalize(type);
|
|
2256
|
+
} else {
|
|
2257
|
+
capitalizedType = type.map((t) => capitalize(t)).join("Or");
|
|
2258
|
+
}
|
|
2259
|
+
const filteredDefinitions = Object.entries(definitions).filter(([_2, def]) => {
|
|
2260
|
+
if (typeof type === "string") {
|
|
2261
|
+
return def["x-type"] === type;
|
|
2262
|
+
} else {
|
|
2263
|
+
return type.includes(def["x-type"]);
|
|
2264
|
+
}
|
|
2265
|
+
}).map(([name, _2]) => capitalize(name));
|
|
2266
|
+
return `export const WebSocket${capitalizedType} = z.discriminatedUnion("type", [
|
|
2267
|
+
${filteredDefinitions.join(",\n ")}
|
|
2268
|
+
])
|
|
2269
|
+
|
|
2270
|
+
export type WebSocket${capitalizedType} = z.infer<typeof WebSocket${capitalizedType}>`;
|
|
2271
|
+
}
|
|
2272
|
+
return "";
|
|
2273
|
+
};
|
|
2274
|
+
var templateWebsocketDefinitions = (definitions) => {
|
|
2275
|
+
return `/**
|
|
2276
|
+
* AUTO GENERATED
|
|
2277
|
+
*/
|
|
2278
|
+
|
|
2279
|
+
import { z } from 'zod'
|
|
2280
|
+
|
|
2281
|
+
${renderAllDefinitions(definitions)}
|
|
2282
|
+
|
|
2283
|
+
${renderUnion("request", definitions)}
|
|
2284
|
+
|
|
2285
|
+
${renderUnion(["response", "notification"], definitions)}
|
|
2286
|
+
`;
|
|
2287
|
+
};
|
|
2288
|
+
|
|
2289
|
+
// src/WebsocketGenerator.ts
|
|
2290
|
+
var WebsocketGenerator = class {
|
|
2291
|
+
static srcFolder = () => CliParser.getOutputPath();
|
|
2292
|
+
static outputFolder = () => path6.join(this.srcFolder(), "generated-websocket");
|
|
2293
|
+
static schemaContent = () => {
|
|
2294
|
+
const fileContent = JSON.parse(fs6.readFileSync(CliParser.getWebSocketSchemaPath(), "utf8"));
|
|
2295
|
+
return fileContent;
|
|
2296
|
+
};
|
|
2297
|
+
static prepareDirs = () => {
|
|
2298
|
+
ParserUtils.mkdirIfNotExist(this.outputFolder());
|
|
2299
|
+
};
|
|
2300
|
+
static main = () => {
|
|
2301
|
+
const { name, path: wsPath, definitions } = this.schemaContent();
|
|
2302
|
+
const templateDefinitions = templateWebsocketDefinitions(definitions);
|
|
2303
|
+
this.prepareDirs();
|
|
2304
|
+
const filePath = path6.join(this.outputFolder(), "WebSocketDefinitions.ts");
|
|
2305
|
+
fs6.writeFileSync(filePath, templateDefinitions, "utf8");
|
|
2306
|
+
const templateClass2 = templateWebsocketClass(name, wsPath, definitions);
|
|
2307
|
+
const filePathClass = path6.join(this.outputFolder(), "WebSocketClass.ts");
|
|
2308
|
+
fs6.writeFileSync(filePathClass, templateClass2, "utf8");
|
|
2309
|
+
};
|
|
2310
|
+
};
|
|
2311
|
+
|
|
1924
2312
|
// src/cli.ts
|
|
1925
2313
|
var generateSdk = async () => {
|
|
1926
2314
|
const arrayOfSets = await Promise.all(CliParser.getConfigFile().map((config) => CodeGenerator.main(config)));
|
|
1927
2315
|
if (CliParser.isGenerateSnippetOnly()) {
|
|
1928
2316
|
return;
|
|
1929
2317
|
}
|
|
2318
|
+
if (CliParser.isGenerateWebSocket()) {
|
|
2319
|
+
WebsocketGenerator.main();
|
|
2320
|
+
}
|
|
1930
2321
|
const indexImportsSet = /* @__PURE__ */ new Set();
|
|
1931
2322
|
const queryImportsSet = /* @__PURE__ */ new Set();
|
|
1932
2323
|
const filenamesSet = /* @__PURE__ */ new Set();
|
|
1933
2324
|
for (const set of arrayOfSets) {
|
|
1934
2325
|
set.indexImports.forEach((value) => {
|
|
1935
|
-
const fileName =
|
|
2326
|
+
const fileName = path7.basename(value);
|
|
1936
2327
|
if (!filenamesSet.has(fileName)) {
|
|
1937
2328
|
indexImportsSet.add(value);
|
|
1938
2329
|
filenamesSet.add(fileName);
|
|
1939
2330
|
}
|
|
1940
2331
|
});
|
|
1941
2332
|
set.queryImports.forEach((value) => {
|
|
1942
|
-
const fileName =
|
|
2333
|
+
const fileName = path7.basename(value);
|
|
1943
2334
|
if (!filenamesSet.has(fileName)) {
|
|
1944
2335
|
queryImportsSet.add(value);
|
|
1945
2336
|
}
|
|
@@ -1991,5 +2382,8 @@ yargs.command("download-swaggers", "Download swaggers JSON files", (yargs2) => {
|
|
|
1991
2382
|
}).option("snippetOutput", {
|
|
1992
2383
|
description: "Directory for the generated code snippets. Required when generating snippets.",
|
|
1993
2384
|
type: "string"
|
|
2385
|
+
}).option("webSocketSchema", {
|
|
2386
|
+
description: "Path to the WebSocket schema file (schema.json). If provided, WebSocket methods will be generated based on the schema.",
|
|
2387
|
+
type: "string"
|
|
1994
2388
|
}).demandCommand(1).help().argv;
|
|
1995
2389
|
//# sourceMappingURL=accelbyte-codegen.mjs.map
|