@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.
@@ -23,8 +23,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  ));
24
24
 
25
25
  // src/cli.ts
26
+ var import_path5 = __toESM(require("path"));
26
27
  var import_yargs = __toESM(require("yargs"));
27
- var import_path4 = __toESM(require("path"));
28
28
 
29
29
  // src/CliParser.ts
30
30
  var import_fs = __toESM(require("fs"));
@@ -77,6 +77,12 @@ var CliParser = class _CliParser {
77
77
  static isGenerateSnippetOnly = () => {
78
78
  return _CliParser.instance().argv.snippetOnly;
79
79
  };
80
+ static getWebSocketSchemaPath = () => {
81
+ return _CliParser.instance().argv.webSocketSchema;
82
+ };
83
+ static isGenerateWebSocket = () => {
84
+ return !!_CliParser.getWebSocketSchemaPath();
85
+ };
80
86
  };
81
87
 
82
88
  // src/CodeGenerator.ts
@@ -323,15 +329,15 @@ export enum Key_${classNameWithoutApi} {
323
329
  `;
324
330
  };
325
331
  function filterUsedImports(importArr, body) {
326
- return importArr.filter((path7) => {
327
- const start = path7.indexOf("{") + 1;
328
- const end = path7.indexOf("}");
332
+ return importArr.filter((path8) => {
333
+ const start = path8.indexOf("{") + 1;
334
+ const end = path8.indexOf("}");
329
335
  if (start > 0 && end > start) {
330
- const importName = path7.slice(start, end).trim();
336
+ const importName = path8.slice(start, end).trim();
331
337
  return body.includes(importName);
332
338
  }
333
339
  return false;
334
- }).map((path7) => path7).join("\n") + "\n";
340
+ }).map((path8) => path8).join("\n") + "\n";
335
341
  }
336
342
 
337
343
  // src/ParserUtils.ts
@@ -348,8 +354,8 @@ var REMOVED_KEYWORDS = [
348
354
  "/{namespace}/"
349
355
  ];
350
356
  var ParserUtils = class _ParserUtils {
351
- static getVersionSuffixFromPath(path7) {
352
- const version2_3_4_etc = path7.match(/\/v([2-9]|[1-9]\d+)\/+/);
357
+ static getVersionSuffixFromPath(path8) {
358
+ const version2_3_4_etc = path8.match(/\/v([2-9]|[1-9]\d+)\/+/);
353
359
  const methodSuffix = version2_3_4_etc ? `_v${version2_3_4_etc[1]}` : "";
354
360
  return methodSuffix;
355
361
  }
@@ -544,14 +550,14 @@ var ParserUtils = class _ParserUtils {
544
550
  * to this
545
551
  * `createGenerateByRequestIdByUserId`
546
552
  */
547
- static generateNaturalLangMethod = ({ servicePrefix, path: path7, httpMethod, isForm, existingMethods, permissionType }) => {
548
- let path_ = path7;
553
+ static generateNaturalLangMethod = ({ servicePrefix, path: path8, httpMethod, isForm, existingMethods, permissionType }) => {
554
+ let path_ = path8;
549
555
  path_ = path_.replace(`/${servicePrefix}/`, "/");
550
556
  REMOVED_KEYWORDS.forEach((prefix) => {
551
557
  path_ = path_.replace(prefix, "/");
552
558
  });
553
559
  path_ = path_.substring(1);
554
- const isPlural = httpMethod === "get" && !(path7.slice(-1) === "}");
560
+ const isPlural = httpMethod === "get" && !(path8.slice(-1) === "}");
555
561
  if (!isPlural) {
556
562
  path_ = _ParserUtils.replaceAll(path_, "ies/", "y/");
557
563
  path_ = _ParserUtils.replaceAll(path_, "s/", "/");
@@ -594,9 +600,9 @@ var ParserUtils = class _ParserUtils {
594
600
  const genPath = import_lodash.default.upperFirst(lastWords) + "/" + listBeforeLastWords.join("/") + listByParams.reverse().join("/");
595
601
  let generatedMethod = import_lodash.default.camelCase(mappedMethod(httpMethod, isForm, permissionType) + genPath);
596
602
  generatedMethod = _ParserUtils.replaceAll(generatedMethod, "Byword", "_By");
597
- const testedGeneratedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path7);
598
- generatedMethod = resolveConflicts({ path: path7, generatedMethod, testedGeneratedMethod, existingMethods });
599
- generatedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path7);
603
+ const testedGeneratedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path8);
604
+ generatedMethod = resolveConflicts({ path: path8, generatedMethod, testedGeneratedMethod, existingMethods });
605
+ generatedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path8);
600
606
  return generatedMethod;
601
607
  };
602
608
  static filterBodyParams(parameters) {
@@ -751,8 +757,8 @@ var ParserUtils = class _ParserUtils {
751
757
  */
752
758
  ${content}`;
753
759
  };
754
- static sortPathParamsByPath = (pathParams, path7) => {
755
- const params = path7.match(/{\w*}/g) || [];
760
+ static sortPathParamsByPath = (pathParams, path8) => {
761
+ const params = path8.match(/{\w*}/g) || [];
756
762
  const cleanParams = params.map((param) => param.replace("{", "").replace("}", ""));
757
763
  return pathParams.sort((a, b) => cleanParams.indexOf(a.name) - cleanParams.indexOf(b.name));
758
764
  };
@@ -776,30 +782,30 @@ var mappedMethod = (httpMethod, isForm, permissionType) => {
776
782
  return "delete";
777
783
  }
778
784
  };
779
- var resolveConflicts = ({ path: path7, generatedMethod, testedGeneratedMethod, existingMethods }) => {
785
+ var resolveConflicts = ({ path: path8, generatedMethod, testedGeneratedMethod, existingMethods }) => {
780
786
  let _testedGenMethod = testedGeneratedMethod;
781
787
  try {
782
- testConflict(path7, _testedGenMethod, existingMethods);
788
+ testConflict(path8, _testedGenMethod, existingMethods);
783
789
  } catch (e) {
784
- if (path7.indexOf("/namespaces/") >= 0) {
790
+ if (path8.indexOf("/namespaces/") >= 0) {
785
791
  generatedMethod += "_ByNS";
786
792
  _testedGenMethod += "_ByNS";
787
793
  }
788
794
  }
789
795
  try {
790
- testConflict(path7, _testedGenMethod, existingMethods);
796
+ testConflict(path8, _testedGenMethod, existingMethods);
791
797
  } catch (e) {
792
- if (path7.indexOf("/admin/") >= 0) {
798
+ if (path8.indexOf("/admin/") >= 0) {
793
799
  generatedMethod += "_admin";
794
800
  _testedGenMethod += "_admin";
795
801
  }
796
802
  }
797
- testConflict(path7, _testedGenMethod, existingMethods);
803
+ testConflict(path8, _testedGenMethod, existingMethods);
798
804
  return generatedMethod;
799
805
  };
800
- var testConflict = (path7, generatedMethod, existingMethods) => {
806
+ var testConflict = (path8, generatedMethod, existingMethods) => {
801
807
  if (existingMethods[generatedMethod]) {
802
- const conflictingMethod = { path: path7, generatedMethod };
808
+ const conflictingMethod = { path: path8, generatedMethod };
803
809
  throw Error(
804
810
  `Duplicate method conflict in ${JSON.stringify(conflictingMethod)},
805
811
  existingMethods: ${JSON.stringify(existingMethods, null, 2)}`
@@ -916,7 +922,7 @@ var OpenApiSpec = import_zod2.z.object({
916
922
  var templateApiMethod = ({
917
923
  classMethod,
918
924
  httpMethod,
919
- path: path7,
925
+ path: path8,
920
926
  pathParams,
921
927
  bodyParams,
922
928
  responseClasses,
@@ -925,12 +931,12 @@ var templateApiMethod = ({
925
931
  methodParamsNoTypes,
926
932
  xSecurity
927
933
  }) => {
928
- let newPath = `'${path7}'`;
934
+ let newPath = `'${path8}'`;
929
935
  let snippetMethod = "";
930
936
  for (const pathParam of pathParams) {
931
937
  const type = ParserUtils.parseType(pathParam);
932
938
  const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
933
- if (path7.match(`{${pathParam.name}}`)) {
939
+ if (path8.match(`{${pathParam.name}}`)) {
934
940
  if (type === "string") {
935
941
  newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
936
942
  } else {
@@ -938,9 +944,9 @@ var templateApiMethod = ({
938
944
  }
939
945
  }
940
946
  }
941
- const snippetShellArgs = ["--location --request", `${httpMethod} '__DOMAIN__${path7}'`, "--header 'accept: application/json'"];
947
+ const snippetShellArgs = ["--location --request", `${httpMethod} '__DOMAIN__${path8}'`, "--header 'accept: application/json'"];
942
948
  const snippetApiArgs = [];
943
- if (xSecurity !== void 0 || path7.includes("/admin")) {
949
+ if (xSecurity !== void 0 || path8.includes("/admin")) {
944
950
  snippetShellArgs.push("--header 'Authorization: Bearer {access_token}'");
945
951
  snippetApiArgs.push("{ axiosConfig: { request: { headers: { Authorization: 'Bearer {access_token}' } } } }".trim());
946
952
  }
@@ -978,7 +984,7 @@ var templateMethod = ({
978
984
  classMethod,
979
985
  description,
980
986
  httpMethod,
981
- path: path7,
987
+ path: path8,
982
988
  pathParams,
983
989
  bodyParams,
984
990
  queryParams,
@@ -988,9 +994,9 @@ var templateMethod = ({
988
994
  }) => {
989
995
  let methodParams = "";
990
996
  let methodParamsNoTypes = "";
991
- let newPath = `'${path7}'`;
997
+ let newPath = `'${path8}'`;
992
998
  let importStatements = [];
993
- const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path7);
999
+ const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path8);
994
1000
  for (const pathParam of sortedPathParams) {
995
1001
  const type = ParserUtils.parseType(pathParam);
996
1002
  if (pathParam.name !== "namespace") {
@@ -998,7 +1004,7 @@ var templateMethod = ({
998
1004
  methodParamsNoTypes += pathParam.name + ", ";
999
1005
  }
1000
1006
  const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
1001
- if (path7.match(`{${pathParam.name}}`)) {
1007
+ if (path8.match(`{${pathParam.name}}`)) {
1002
1008
  if (type === "string") {
1003
1009
  newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
1004
1010
  } else {
@@ -1063,7 +1069,7 @@ var POST_FETCH_INCLUDES_PATH = ["/table-query/"];
1063
1069
  var templateQueryMethod = ({
1064
1070
  classMethod,
1065
1071
  httpMethod,
1066
- path: path7,
1072
+ path: path8,
1067
1073
  pathParams,
1068
1074
  responseClasses,
1069
1075
  methodParams,
@@ -1071,14 +1077,14 @@ var templateQueryMethod = ({
1071
1077
  description,
1072
1078
  deprecated
1073
1079
  }) => {
1074
- const isPostFetch = httpMethod === "post" && (POST_FETCH_INCLUDES_PATH.some((p) => path7.includes(p)) || path7.endsWith("/list"));
1080
+ const isPostFetch = httpMethod === "post" && (POST_FETCH_INCLUDES_PATH.some((p) => path8.includes(p)) || path8.endsWith("/list"));
1075
1081
  const isFetch = classMethod.startsWith("fetch");
1076
1082
  const isGet = httpMethod === "get" || isPostFetch || isFetch;
1077
1083
  const queryMethod = isGet ? "useQuery" : "useMutation";
1078
1084
  let mParams = "";
1079
1085
  let mParamsNoTypes = "";
1080
- let newPath = `'${path7}'`;
1081
- const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path7);
1086
+ let newPath = `'${path8}'`;
1087
+ const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path8);
1082
1088
  for (const pathParam of sortedPathParams) {
1083
1089
  const type = ParserUtils.parseType(pathParam);
1084
1090
  if (pathParam.name !== "namespace") {
@@ -1086,7 +1092,7 @@ var templateQueryMethod = ({
1086
1092
  mParamsNoTypes += pathParam.name + ", ";
1087
1093
  }
1088
1094
  const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
1089
- if (path7.match(`{${pathParam.name}}`)) {
1095
+ if (path8.match(`{${pathParam.name}}`)) {
1090
1096
  if (type === "string") {
1091
1097
  newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
1092
1098
  } else {
@@ -1212,7 +1218,8 @@ var templateSdkSnippet = ({
1212
1218
  serviceNameTitle,
1213
1219
  apiName,
1214
1220
  snippetMethod,
1215
- snippetApiArgs: snippetApiArgsParam
1221
+ snippetApiArgs: snippetApiArgsParam,
1222
+ isUMD
1216
1223
  }) => {
1217
1224
  const methodArr = snippetMethod.split("//");
1218
1225
  const snippetApiArgs = ["sdk", ...snippetApiArgsParam];
@@ -1220,7 +1227,8 @@ var templateSdkSnippet = ({
1220
1227
  normMethod = normalizeMethodSnippet(normMethod, "queryParams:");
1221
1228
  normMethod = normalizeMethodSnippet(normMethod, "queryParams?:");
1222
1229
  normMethod += "\n\n//" + methodArr[1];
1223
- const sdkSnippet = `import { AccelByte } from '@accelbyte/sdk'
1230
+ const sdkAcronyms = ["Ams", "Gdpr", "Iam", "Ugc"];
1231
+ let sdkSnippet = `import { AccelByte } from '@accelbyte/sdk'
1224
1232
  import { ${serviceNameTitle} } from '@accelbyte/sdk-${serviceNameTitle.toLowerCase()}'
1225
1233
 
1226
1234
  const sdk = AccelByte.SDK({
@@ -1234,6 +1242,26 @@ const sdk = AccelByte.SDK({
1234
1242
 
1235
1243
  ${serviceNameTitle}.${apiName}(${snippetApiArgs.join(", ")})
1236
1244
  .${normMethod}`;
1245
+ if (isUMD) {
1246
+ sdkSnippet = `<script src="https://unpkg.com/@accelbyte/sdk/dist/global/index.global.js"></script>
1247
+ <script src="https://unpkg.com/@accelbyte/sdk-${serviceNameTitle.toLowerCase()}/dist/global/index.global.js"></script>
1248
+
1249
+ <script>
1250
+
1251
+ const sdk = AccelByteSDK.AccelByte.SDK({
1252
+ coreConfig: {
1253
+ baseURL: '__DOMAIN__',
1254
+ clientId: '77f88506b6174c3ea4d925f5b4096ce8',
1255
+ namespace: 'accelbyte',
1256
+ redirectURI: 'http://localhost:3030'
1257
+ }
1258
+ })
1259
+
1260
+ AccelByteSDK_${sdkAcronyms.includes(serviceNameTitle) ? serviceNameTitle.toUpperCase() : serviceNameTitle}.${apiName}(${snippetApiArgs.join(", ")})
1261
+ .${normMethod}
1262
+
1263
+ </script>`;
1264
+ }
1237
1265
  return sdkSnippet;
1238
1266
  };
1239
1267
  var normalizeMethodSnippet = (methodInput, splitWord) => {
@@ -1302,11 +1330,11 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
1302
1330
  admin: {},
1303
1331
  public: {}
1304
1332
  };
1305
- for (const [path7, operation] of sortedPathsByLength) {
1306
- if (path7.indexOf("/healthz") >= 0) {
1333
+ for (const [path8, operation] of sortedPathsByLength) {
1334
+ if (path8.indexOf("/healthz") >= 0) {
1307
1335
  continue;
1308
1336
  }
1309
- const isAdminEndpoint = path7.indexOf("/admin/") > -1;
1337
+ const isAdminEndpoint = path8.indexOf("/admin/") > -1;
1310
1338
  const picked = isAdminEndpoint ? result.admin : result.public;
1311
1339
  const {
1312
1340
  arrayDefinitions,
@@ -1324,25 +1352,25 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
1324
1352
  const httpMethods = Object.keys(operation);
1325
1353
  for (const httpMethod of httpMethods) {
1326
1354
  const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
1327
- console.error(JSON.stringify({ path: path7, httpMethod }, null, 2));
1355
+ console.error(JSON.stringify({ path: path8, httpMethod }, null, 2));
1328
1356
  throw error;
1329
1357
  });
1330
1358
  if (!endpoint.tags) continue;
1331
1359
  const [tag] = endpoint.tags;
1332
- const pathWithBase = `${api.basePath ?? ""}${path7}`;
1360
+ const pathWithBase = `${api.basePath ?? ""}${path8}`;
1333
1361
  const permissionType = getPermissionType(getPermission(endpoint));
1334
1362
  tagToClassMethodsMapByType[tag] = tagToClassMethodsMapByType[tag] ? tagToClassMethodsMapByType[tag] : {};
1335
1363
  const isForm = endpoint.consumes && endpoint.consumes[0] === "application/x-www-form-urlencoded";
1336
1364
  const classMethod = ParserUtils.generateNaturalLangMethod({
1337
1365
  servicePrefix,
1338
- path: path7,
1366
+ path: path8,
1339
1367
  httpMethod,
1340
1368
  isForm,
1341
1369
  existingMethods: tagToClassMethodsMapByType[tag],
1342
1370
  permissionType
1343
1371
  });
1344
- tagToClassMethodsMapByType[tag][classMethod] = `${path7} ${httpMethod}`;
1345
- generatedMethods[`${path7} ${httpMethod}`] = `${classMethod}`;
1372
+ tagToClassMethodsMapByType[tag][classMethod] = `${path8} ${httpMethod}`;
1373
+ generatedMethods[`${path8} ${httpMethod}`] = `${classMethod}`;
1346
1374
  if (!snippetMap[pathWithBase]) {
1347
1375
  snippetMap[pathWithBase] = {};
1348
1376
  }
@@ -1425,9 +1453,17 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
1425
1453
  snippetMethod,
1426
1454
  snippetApiArgs
1427
1455
  });
1456
+ const resultUMDSnippet = templateSdkSnippet({
1457
+ serviceNameTitle,
1458
+ apiName: apiGenName,
1459
+ snippetMethod,
1460
+ snippetApiArgs,
1461
+ isUMD: true
1462
+ });
1428
1463
  const currentSnippetMap = {};
1429
1464
  snippetMap[pathWithBase][httpMethod] = currentSnippetMap;
1430
1465
  currentSnippetMap.web = resultSnippet;
1466
+ currentSnippetMap.webUMD = resultUMDSnippet;
1431
1467
  const generatedDirName = isAdminEndpoint ? "generated-admin" : "generated-public";
1432
1468
  currentSnippetMap.webGit = GIT_URL + `/sdk-${sdkName}/src/${generatedDirName}/${apiGenName}.ts`;
1433
1469
  currentSnippetMap.shell = snippetShell;
@@ -1441,7 +1477,7 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
1441
1477
  };
1442
1478
 
1443
1479
  // src/templates/template-api-index.ts
1444
- var templateApiIndex = (serviceNameTitle, apiList) => {
1480
+ var templateApiIndex = (serviceNameTitle, apiList, isGenerateWebSocket = false) => {
1445
1481
  let imports = "";
1446
1482
  let returnStatement = "";
1447
1483
  for (const cl of apiList) {
@@ -1450,6 +1486,12 @@ var templateApiIndex = (serviceNameTitle, apiList) => {
1450
1486
  import { ${cl} } from './${dir}/${cl}.js'`;
1451
1487
  returnStatement += `
1452
1488
  ${cl}, `;
1489
+ }
1490
+ if (isGenerateWebSocket) {
1491
+ imports += `
1492
+ import { WebSocketClass } from './generated-websocket/WebSocketClass.js'`;
1493
+ returnStatement += `
1494
+ WebSocket: WebSocketClass, `;
1453
1495
  }
1454
1496
  return `/**
1455
1497
  * AUTO GENERATED
@@ -1872,7 +1914,8 @@ var CodeGenerator = class _CodeGenerator {
1872
1914
  };
1873
1915
  generatePublicOrAdmin(true);
1874
1916
  generatePublicOrAdmin(false);
1875
- const apiIndexBuff = templateApiIndex(serviceNameTitle, mainApiList);
1917
+ const isGenerateWebSocket = CliParser.isGenerateWebSocket();
1918
+ const apiIndexBuff = templateApiIndex(serviceNameTitle, mainApiList, isGenerateWebSocket);
1876
1919
  ParserUtils.writeApiMainFile(_CodeGenerator.srcFolder(), serviceNameTitle, apiIndexBuff);
1877
1920
  console.log("\nCOMPLETED\n----------\n\n");
1878
1921
  return { indexImports: indexImportsSet, queryImports: queryImportsSet };
@@ -1943,25 +1986,373 @@ var SwaggerDownloader = class _SwaggerDownloader {
1943
1986
  };
1944
1987
  };
1945
1988
 
1989
+ // src/WebsocketGenerator.ts
1990
+ var import_fs5 = __toESM(require("fs"));
1991
+ var import_path4 = __toESM(require("path"));
1992
+
1993
+ // src/templates/template-ws-class.ts
1994
+ var definitionToFunctionName = (type) => {
1995
+ if (type.endsWith("Request")) {
1996
+ return "send" + capitalize(type.slice(0, type.length - 7));
1997
+ }
1998
+ return type;
1999
+ };
2000
+ var renderSendFunction = (name, definition) => {
2001
+ const functionName = definitionToFunctionName(name);
2002
+ return `const ${functionName} = (data: Omit<Definitions.${capitalize(name)}, 'type'>) => {
2003
+ send({ type: '${name}', ...data })
2004
+ }`;
2005
+ };
2006
+ var templateWebsocketClass = (name, path8, definitions) => {
2007
+ const requestDefinitions = Object.keys(definitions).filter((key) => {
2008
+ const val = definitions[key];
2009
+ return val["x-type"] == "request";
2010
+ }).map((key) => [key, definitions[key]]);
2011
+ return `/* eslint-disable camelcase */
2012
+ /* eslint-disable no-inner-declarations */
2013
+ // @ts-ignore -> ts-expect-error TS6133
2014
+ import { AccelByteSDK, RefreshToken, SdkSetConfigParam } from '@accelbyte/sdk'
2015
+ import * as Definitions from './WebSocketDefinitions'
2016
+
2017
+ const messageParser = (data: string) => {
2018
+ const toVal = (str?: string) => {
2019
+ if (str) {
2020
+ if (str.startsWith('[') && str.endsWith(']')) {
2021
+ return str
2022
+ .slice(1, str.length - 1)
2023
+ .split(',')
2024
+ .filter(v => v !== '')
2025
+ }
2026
+ }
2027
+ return str
2028
+ }
2029
+
2030
+ const entries = data.split('\\n')
2031
+ .filter(line => line !== '')
2032
+ .map(line => {
2033
+ const [key, valStr] = line.split(': ')
2034
+ return [key, toVal(valStr)]
2035
+ })
2036
+
2037
+ return Object.fromEntries(entries)
2038
+ }
2039
+
2040
+ const messageSerializer = (data: Record<string, any>) => {
2041
+ return Object.keys(data)
2042
+ .map(key => {
2043
+ const toStr = (val: any) => {
2044
+ // array
2045
+ if (Array.isArray(val)) {
2046
+ return \`[\${String(val)}]\`
2047
+ }
2048
+ // null, undefined
2049
+ if (!val) {
2050
+ return ''
2051
+ }
2052
+ return String(val)
2053
+ }
2054
+ const val = data[key]
2055
+ const valStr = toStr(val)
2056
+
2057
+ return \`\${key}: \${valStr}\`
2058
+ })
2059
+ .join('\\n')
2060
+ }
2061
+
2062
+ export function WebSocketClass(sdk: AccelByteSDK, args?: SdkSetConfigParam) {
2063
+ const sdkAssembly = sdk.assembly()
2064
+ const baseURL = (args?.coreConfig?.baseURL ?? sdkAssembly.coreConfig.baseURL).replace('http', 'ws')
2065
+ const path = '${path8}'
2066
+ const url = baseURL + path
2067
+ let ws: WebSocket | null = null
2068
+ let isDisconnectManually = false
2069
+ const allowReconnect = sdkAssembly.webSocketConfig.allowReconnect ?? true
2070
+ const maxReconnectAttempts = sdkAssembly.webSocketConfig.maxReconnectAttempts ?? 0
2071
+ let reconnectAttempts = maxReconnectAttempts
2072
+
2073
+ const connect = () => {
2074
+ const token = sdk.getToken()
2075
+
2076
+ if (!token.accessToken) {
2077
+ console.warn('No access token, please login first')
2078
+ return
2079
+ }
2080
+
2081
+ if (!ws) {
2082
+ ws = new WebSocket(url, token.accessToken)
2083
+ }
2084
+ }
2085
+
2086
+ const refreshToken = async () => {
2087
+ const { refreshToken } = sdk.getToken()
2088
+ if (refreshToken) {
2089
+ const refresh = new RefreshToken({
2090
+ config: {
2091
+ axiosConfig: sdkAssembly.axiosConfig.request,
2092
+ clientId: sdkAssembly.coreConfig.clientId,
2093
+ refreshToken
2094
+ }
2095
+ })
2096
+ const result = await refresh.runWithLock()
2097
+ if (result) {
2098
+ sdk.setToken({
2099
+ accessToken: result.access_token,
2100
+ refreshToken: result.refresh_token
2101
+ })
2102
+ return true
2103
+ }
2104
+ }
2105
+ return false
2106
+ }
2107
+
2108
+ const handleReconnect = async (ev: CloseEvent) => {
2109
+ if (!allowReconnect || isDisconnectManually || !sdk.getToken().accessToken) return
2110
+ // token revoked
2111
+ if (ev.code === 4020) {
2112
+ await refreshToken()
2113
+ reconnectAttempts--
2114
+ connect()
2115
+ } else if (ev.code >= 1001 && ev.code <= 2999) {
2116
+ // Only reconnect if codes in range 1001-2999
2117
+ if (!ws || ws.readyState !== ws.OPEN) return
2118
+
2119
+ if (maxReconnectAttempts === 0) {
2120
+ setTimeout(() => {
2121
+ connect()
2122
+ }, 1000)
2123
+ } else if (reconnectAttempts !== 0) {
2124
+ setTimeout(() => {
2125
+ reconnectAttempts--
2126
+ connect()
2127
+ }, 1000)
2128
+ }
2129
+ }
2130
+ }
2131
+
2132
+ const disconnect = (code?: number, reason?: string) => {
2133
+ if (ws) {
2134
+ ws.close(code, reason)
2135
+ isDisconnectManually = true
2136
+ ws = null
2137
+ }
2138
+ }
2139
+
2140
+ const send = (message: Definitions.WebSocketRequest) => {
2141
+ if (ws) {
2142
+ ws.send(messageSerializer(message))
2143
+ }
2144
+ }
2145
+
2146
+ const sendRaw = (rawMessage: string) => {
2147
+ if (ws) {
2148
+ ws.send(rawMessage)
2149
+ }
2150
+ }
2151
+
2152
+ const onOpen = (cb: () => any) => {
2153
+ if (ws) {
2154
+ function listener(this: WebSocket, _ev: Event) {
2155
+ isDisconnectManually = false
2156
+ reconnectAttempts = maxReconnectAttempts
2157
+ cb()
2158
+ }
2159
+ ws.addEventListener('open', listener)
2160
+ return {
2161
+ removeEventListener: () => ws?.removeEventListener('open', listener)
2162
+ }
2163
+ }
2164
+ return {}
2165
+ }
2166
+
2167
+ const onClose = (cb: (ev: CloseEvent) => any) => {
2168
+ if (ws) {
2169
+ function listener(this: WebSocket, ev: CloseEvent) {
2170
+ handleReconnect(ev)
2171
+ cb(ev)
2172
+ }
2173
+ ws.addEventListener('close', listener)
2174
+ return {
2175
+ removeEventListener: () => ws?.removeEventListener('close', listener)
2176
+ }
2177
+ }
2178
+ return {}
2179
+ }
2180
+
2181
+ const onMessage = (cb: (message: Definitions.WebSocketResponseOrNotification | string) => any, raw: boolean = false) => {
2182
+ if (ws) {
2183
+ function listener(this: WebSocket, ev: MessageEvent<any>) {
2184
+ if (raw) {
2185
+ cb(ev.data)
2186
+ } else {
2187
+ const result = Definitions.WebSocketResponseOrNotification.parse(messageParser(ev.data))
2188
+ cb(result)
2189
+ }
2190
+ }
2191
+ ws.addEventListener('message', listener)
2192
+ return {
2193
+ removeEventListener: () => ws?.removeEventListener('message', listener)
2194
+ }
2195
+ }
2196
+ return {}
2197
+ }
2198
+
2199
+ const onError = (cb: (err: any) => any) => {
2200
+ if (ws) {
2201
+ function listener(this: WebSocket, err: any) {
2202
+ cb(err)
2203
+ }
2204
+ ws.addEventListener('error', listener)
2205
+ return {
2206
+ removeEventListener: () => ws?.removeEventListener('error', listener)
2207
+ }
2208
+ }
2209
+ return {}
2210
+ }
2211
+
2212
+ ${requestDefinitions.map(([name2, definition]) => renderSendFunction(name2, definition)).join(`
2213
+
2214
+ `)}
2215
+
2216
+ return {
2217
+ instance: ws,
2218
+ connect,
2219
+ disconnect,
2220
+ send,
2221
+ sendRaw,
2222
+ onOpen,
2223
+ onClose,
2224
+ onMessage,
2225
+ onError,
2226
+ ${requestDefinitions.map(([name2, _2]) => definitionToFunctionName(name2)).join(",\n ")}
2227
+ }
2228
+ }
2229
+
2230
+ `;
2231
+ };
2232
+
2233
+ // src/templates/template-ws-defintions.ts
2234
+ var renderZod = (property) => {
2235
+ switch (property.type) {
2236
+ case "string":
2237
+ return `z.coerce.string()`;
2238
+ case "integer":
2239
+ return `z.coerce.number()`;
2240
+ case "boolean":
2241
+ return `z.boolean()`;
2242
+ case "array":
2243
+ return `z.array(${renderZod(property.items)})`;
2244
+ default:
2245
+ return `z.any()`;
2246
+ }
2247
+ };
2248
+ var renderProperty = (name, type, property, required) => {
2249
+ const isRequired = required && required.includes(name);
2250
+ return `${name}: ${renderZod(property)}${isRequired || type != "request" ? "" : ".optional()"}`;
2251
+ };
2252
+ var renderDefinition = (name, definition) => {
2253
+ const capitalizedName = capitalize(name);
2254
+ if (definition.properties) {
2255
+ const properties = Object.entries(definition.properties);
2256
+ return `export const ${capitalizedName} = z.object({
2257
+ type: z.literal("${name}"),
2258
+ ${properties.map(([name2, property]) => renderProperty(name2, definition["x-type"], property, definition.required)).join(",\n ")}
2259
+ })
2260
+
2261
+ export type ${capitalizedName} = z.infer<typeof ${capitalizedName}>
2262
+ `;
2263
+ }
2264
+ return "";
2265
+ };
2266
+ var renderAllDefinitions = (definitions) => {
2267
+ if (definitions) {
2268
+ const definitionEntries = Object.entries(definitions);
2269
+ return definitionEntries.map(([name, definition]) => renderDefinition(name, definition)).join("\n\n");
2270
+ }
2271
+ return "";
2272
+ };
2273
+ var renderUnion = (type, definitions) => {
2274
+ if (definitions) {
2275
+ let capitalizedType = "";
2276
+ if (typeof type === "string") {
2277
+ capitalizedType = capitalize(type);
2278
+ } else {
2279
+ capitalizedType = type.map((t) => capitalize(t)).join("Or");
2280
+ }
2281
+ const filteredDefinitions = Object.entries(definitions).filter(([_2, def]) => {
2282
+ if (typeof type === "string") {
2283
+ return def["x-type"] === type;
2284
+ } else {
2285
+ return type.includes(def["x-type"]);
2286
+ }
2287
+ }).map(([name, _2]) => capitalize(name));
2288
+ return `export const WebSocket${capitalizedType} = z.discriminatedUnion("type", [
2289
+ ${filteredDefinitions.join(",\n ")}
2290
+ ])
2291
+
2292
+ export type WebSocket${capitalizedType} = z.infer<typeof WebSocket${capitalizedType}>`;
2293
+ }
2294
+ return "";
2295
+ };
2296
+ var templateWebsocketDefinitions = (definitions) => {
2297
+ return `/**
2298
+ * AUTO GENERATED
2299
+ */
2300
+
2301
+ import { z } from 'zod'
2302
+
2303
+ ${renderAllDefinitions(definitions)}
2304
+
2305
+ ${renderUnion("request", definitions)}
2306
+
2307
+ ${renderUnion(["response", "notification"], definitions)}
2308
+ `;
2309
+ };
2310
+
2311
+ // src/WebsocketGenerator.ts
2312
+ var WebsocketGenerator = class {
2313
+ static srcFolder = () => CliParser.getOutputPath();
2314
+ static outputFolder = () => import_path4.default.join(this.srcFolder(), "generated-websocket");
2315
+ static schemaContent = () => {
2316
+ const fileContent = JSON.parse(import_fs5.default.readFileSync(CliParser.getWebSocketSchemaPath(), "utf8"));
2317
+ return fileContent;
2318
+ };
2319
+ static prepareDirs = () => {
2320
+ ParserUtils.mkdirIfNotExist(this.outputFolder());
2321
+ };
2322
+ static main = () => {
2323
+ const { name, path: wsPath, definitions } = this.schemaContent();
2324
+ const templateDefinitions = templateWebsocketDefinitions(definitions);
2325
+ this.prepareDirs();
2326
+ const filePath = import_path4.default.join(this.outputFolder(), "WebSocketDefinitions.ts");
2327
+ import_fs5.default.writeFileSync(filePath, templateDefinitions, "utf8");
2328
+ const templateClass2 = templateWebsocketClass(name, wsPath, definitions);
2329
+ const filePathClass = import_path4.default.join(this.outputFolder(), "WebSocketClass.ts");
2330
+ import_fs5.default.writeFileSync(filePathClass, templateClass2, "utf8");
2331
+ };
2332
+ };
2333
+
1946
2334
  // src/cli.ts
1947
2335
  var generateSdk = async () => {
1948
2336
  const arrayOfSets = await Promise.all(CliParser.getConfigFile().map((config) => CodeGenerator.main(config)));
1949
2337
  if (CliParser.isGenerateSnippetOnly()) {
1950
2338
  return;
1951
2339
  }
2340
+ if (CliParser.isGenerateWebSocket()) {
2341
+ WebsocketGenerator.main();
2342
+ }
1952
2343
  const indexImportsSet = /* @__PURE__ */ new Set();
1953
2344
  const queryImportsSet = /* @__PURE__ */ new Set();
1954
2345
  const filenamesSet = /* @__PURE__ */ new Set();
1955
2346
  for (const set of arrayOfSets) {
1956
2347
  set.indexImports.forEach((value) => {
1957
- const fileName = import_path4.default.basename(value);
2348
+ const fileName = import_path5.default.basename(value);
1958
2349
  if (!filenamesSet.has(fileName)) {
1959
2350
  indexImportsSet.add(value);
1960
2351
  filenamesSet.add(fileName);
1961
2352
  }
1962
2353
  });
1963
2354
  set.queryImports.forEach((value) => {
1964
- const fileName = import_path4.default.basename(value);
2355
+ const fileName = import_path5.default.basename(value);
1965
2356
  if (!filenamesSet.has(fileName)) {
1966
2357
  queryImportsSet.add(value);
1967
2358
  }
@@ -2013,5 +2404,8 @@ import_yargs.default.command("download-swaggers", "Download swaggers JSON files"
2013
2404
  }).option("snippetOutput", {
2014
2405
  description: "Directory for the generated code snippets. Required when generating snippets.",
2015
2406
  type: "string"
2407
+ }).option("webSocketSchema", {
2408
+ description: "Path to the WebSocket schema file (schema.json). If provided, WebSocket methods will be generated based on the schema.",
2409
+ type: "string"
2016
2410
  }).demandCommand(1).help().argv;
2017
2411
  //# sourceMappingURL=accelbyte-codegen.js.map