@sonoransoftware/sonoran.js 1.0.34 → 1.0.35

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.
Files changed (38) hide show
  1. package/.github/workflows/auto-pr-on-branch-push.yml +89 -0
  2. package/.github/workflows/codex_instructions.md +24 -0
  3. package/.github/workflows/push-pr-nudge-codex.yml +50 -0
  4. package/dist/constants.d.ts +200 -1
  5. package/dist/constants.js +1 -0
  6. package/dist/index.d.ts +1 -1
  7. package/dist/instance/Instance.d.ts +6 -0
  8. package/dist/instance/Instance.js +27 -0
  9. package/dist/instance/instance.types.d.ts +3 -0
  10. package/dist/libs/rest/src/lib/REST.d.ts +2 -1
  11. package/dist/libs/rest/src/lib/REST.js +108 -0
  12. package/dist/libs/rest/src/lib/RequestManager.d.ts +2 -0
  13. package/dist/libs/rest/src/lib/RequestManager.js +201 -0
  14. package/dist/libs/rest/src/lib/errors/RateLimitError.js +19 -1
  15. package/dist/libs/rest/src/lib/utils/constants.d.ts +102 -22
  16. package/dist/libs/rest/src/lib/utils/constants.js +106 -2
  17. package/dist/managers/CADManager.d.ts +28 -0
  18. package/dist/managers/CADManager.js +90 -0
  19. package/dist/managers/CMSManager.d.ts +54 -0
  20. package/dist/managers/CMSManager.js +134 -0
  21. package/dist/managers/CMSServerManager.d.ts +3 -0
  22. package/dist/managers/CMSServerManager.js +36 -2
  23. package/dist/managers/RadioManager.d.ts +55 -0
  24. package/dist/managers/RadioManager.js +224 -0
  25. package/package.json +1 -1
  26. package/readme.md +170 -0
  27. package/src/constants.ts +232 -1
  28. package/src/index.ts +35 -1
  29. package/src/instance/Instance.ts +30 -1
  30. package/src/instance/instance.types.ts +4 -1
  31. package/src/libs/rest/src/lib/REST.ts +107 -1
  32. package/src/libs/rest/src/lib/RequestManager.ts +221 -10
  33. package/src/libs/rest/src/lib/errors/RateLimitError.ts +20 -2
  34. package/src/libs/rest/src/lib/utils/constants.ts +205 -24
  35. package/src/managers/CADManager.ts +86 -1
  36. package/src/managers/CMSManager.ts +121 -0
  37. package/src/managers/CMSServerManager.ts +39 -6
  38. package/src/managers/RadioManager.ts +187 -0
@@ -1,4 +1,4 @@
1
- import { productEnums } from '../../../../../constants';
1
+ import { productEnums, RadioSetUserChannelsOptions, RadioSpeakerLocation, CMSProfileFieldUpdate, CMSSetGameServerStruct } from '../../../../../constants';
2
2
  import type { RESTOptions } from '../REST';
3
3
 
4
4
  export const DefaultUserAgent = 'Sonoran.js NPM Module';
@@ -17,6 +17,13 @@ export const DefaultCMSRestOptions: Required<RESTOptions> = {
17
17
  rejectOnRateLimit: true
18
18
  };
19
19
 
20
+ export const DefaultRadioRestOptions: Required<RESTOptions> = {
21
+ agent: {},
22
+ api: 'https://api.sonoranradio.com',
23
+ headers: {},
24
+ rejectOnRateLimit: true
25
+ };
26
+
20
27
  /**
21
28
  * The events that the REST manager emits
22
29
  */
@@ -163,6 +170,24 @@ export const GeneralCADAPITypes: APITypeData[] = [
163
170
  path: 'general/send_photo',
164
171
  method: 'POST',
165
172
  minVersion: 4
173
+ },
174
+ {
175
+ type: 'SET_CLOCK',
176
+ path: 'general/set_clock',
177
+ method: 'POST',
178
+ minVersion: 3
179
+ },
180
+ {
181
+ type: 'JOIN_COMMUNITY',
182
+ path: 'sso/community',
183
+ method: 'POST',
184
+ minVersion: 0
185
+ },
186
+ {
187
+ type: 'LEAVE_COMMUNITY',
188
+ path: 'sso/community',
189
+ method: 'POST',
190
+ minVersion: 0
166
191
  }
167
192
  ];
168
193
 
@@ -347,6 +372,18 @@ export const GeneralCMSAPITypes: APITypeData[] = [
347
372
  method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
348
373
  minVersion: 3
349
374
  },
375
+ {
376
+ type: 'GET_CURRENT_CLOCK_IN',
377
+ path: 'general/get_current_clock_in',
378
+ method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
379
+ minVersion: 0
380
+ },
381
+ {
382
+ type: 'GET_ACCOUNTS',
383
+ path: 'general/get_accounts',
384
+ method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
385
+ minVersion: 0
386
+ },
350
387
  {
351
388
  type: 'GET_ACCOUNT_RANKS',
352
389
  path: 'general/get_account_ranks',
@@ -365,6 +402,12 @@ export const GeneralCMSAPITypes: APITypeData[] = [
365
402
  method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
366
403
  minVersion: 2,
367
404
  },
405
+ {
406
+ type: 'GET_PROFILE_FIELDS',
407
+ path: 'general/get_profile_fields',
408
+ method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
409
+ minVersion: 0
410
+ },
368
411
  {
369
412
  type: 'GET_SUB_VERSION',
370
413
  path: 'general/get_sub_version',
@@ -422,6 +465,12 @@ export const ServersCMSAPITypes: APITypeData[] = [
422
465
  method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
423
466
  minVersion: 2
424
467
  },
468
+ {
469
+ type: 'SET_GAME_SERVERS',
470
+ path: 'servers/set_game_servers',
471
+ method: 'POST',
472
+ minVersion: 2
473
+ },
425
474
  {
426
475
  type: 'VERIFY_WHITELIST',
427
476
  path: 'servers/verify_whitelist',
@@ -451,6 +500,12 @@ export const FormsCMSAPITypes: APITypeData[] = [
451
500
  path: 'forms/change/stage',
452
501
  method: 'POST',
453
502
  minVersion: 0
503
+ },
504
+ {
505
+ type: 'GET_FORM_TEMPLATE_SUBMISSIONS',
506
+ path: 'forms/get_template_submissions',
507
+ method: 'POST',
508
+ minVersion: 0
454
509
  }
455
510
  ];
456
511
 
@@ -484,6 +539,57 @@ export const ERLCMSAPITypes: APITypeData[] = [
484
539
  }
485
540
  ];
486
541
 
542
+ export const RadioAPITypes: APITypeData[] = [
543
+ {
544
+ type: 'RADIO_GET_COMMUNITY_CHANNELS',
545
+ path: 'api/radio/get-community-channels',
546
+ method: 'GET',
547
+ minVersion: 0
548
+ },
549
+ {
550
+ type: 'RADIO_GET_CONNECTED_USERS',
551
+ path: 'api/radio/get-connected-users',
552
+ method: 'GET',
553
+ minVersion: 0
554
+ },
555
+ {
556
+ type: 'RADIO_GET_CONNECTED_USER',
557
+ path: 'api/radio/get-connected-user',
558
+ method: 'GET',
559
+ minVersion: 0
560
+ },
561
+ {
562
+ type: 'RADIO_SET_USER_CHANNELS',
563
+ path: 'api/radio/set-user-channels',
564
+ method: 'POST',
565
+ minVersion: 0
566
+ },
567
+ {
568
+ type: 'RADIO_SET_USER_DISPLAY_NAME',
569
+ path: 'api/set-user-display-name',
570
+ method: 'POST',
571
+ minVersion: 0
572
+ },
573
+ {
574
+ type: 'RADIO_GET_SERVER_SUBSCRIPTION_FROM_IP',
575
+ path: 'radio/check-server-subscription',
576
+ method: 'GET',
577
+ minVersion: 0
578
+ },
579
+ {
580
+ type: 'RADIO_SET_SERVER_IP',
581
+ path: 'radio/set-server-ip',
582
+ method: 'POST',
583
+ minVersion: 0
584
+ },
585
+ {
586
+ type: 'RADIO_SET_IN_GAME_SPEAKER_LOCATIONS',
587
+ path: 'radio/set-server-speakers',
588
+ method: 'POST',
589
+ minVersion: 0
590
+ }
591
+ ];
592
+
487
593
  function formatForAll(array: APITypeData[], product: productEnums): AllAPITypeData[] {
488
594
  return array.map((val) => {
489
595
  return {
@@ -493,9 +599,9 @@ function formatForAll(array: APITypeData[], product: productEnums): AllAPITypeDa
493
599
  });
494
600
  }
495
601
 
496
- export const AllAPITypes: AllAPITypeData[] = [ ...formatForAll(GeneralCADAPITypes, productEnums.CAD), ...formatForAll(CivilianCADAPITypes, productEnums.CAD), ...formatForAll(EmergencyCADAPITypes, productEnums.CAD), ...formatForAll(GeneralCMSAPITypes, productEnums.CMS), ...formatForAll(ServersCMSAPITypes, productEnums.CMS), ...formatForAll(EventsCMSAPITypes, productEnums.CMS), ...formatForAll(FormsCMSAPITypes, productEnums.CMS), ...formatForAll(CommunitiesCMSAPITypes, productEnums.CMS), ...formatForAll(ERLCMSAPITypes, productEnums.CMS) ];
602
+ export const AllAPITypes: AllAPITypeData[] = [ ...formatForAll(GeneralCADAPITypes, productEnums.CAD), ...formatForAll(CivilianCADAPITypes, productEnums.CAD), ...formatForAll(EmergencyCADAPITypes, productEnums.CAD), ...formatForAll(GeneralCMSAPITypes, productEnums.CMS), ...formatForAll(ServersCMSAPITypes, productEnums.CMS), ...formatForAll(EventsCMSAPITypes, productEnums.CMS), ...formatForAll(FormsCMSAPITypes, productEnums.CMS), ...formatForAll(CommunitiesCMSAPITypes, productEnums.CMS), ...formatForAll(ERLCMSAPITypes, productEnums.CMS), ...formatForAll(RadioAPITypes, productEnums.RADIO) ];
497
603
 
498
- export type AllAPITypesType = 'GET_SERVERS' | 'SET_SERVERS' | 'GET_VERSION' | 'SET_PENAL_CODES' | 'SET_API_ID' | 'GET_TEMPLATES' | 'NEW_RECORD' | 'EDIT_RECORD' | 'REMOVE_RECORD' | 'LOOKUP_INT' | 'LOOKUP' | 'GET_ACCOUNT' | 'CHECK_APIID' | 'APPLY_PERMISSION_KEY' | 'SET_ACCOUNT_PERMISSIONS' | 'BAN_USER' | 'VERIFY_SECRET' | 'AUTH_STREETSIGNS' | 'SET_POSTALS' | 'SEND_PHOTO' | 'GET_CHARACTERS' | 'NEW_CHARACTER' | 'EDIT_CHARACTER' | 'REMOVE_CHARACTER' | 'GET_IDENTIFIERS' | 'MODIFY_IDENTIFIER' | 'SET_IDENTIFIER' | 'UNIT_PANIC' | 'UNIT_STATUS' | 'GET_BLIPS' | 'ADD_BLIP' | 'MODIFY_BLIP' | 'REMOVE_BLIP' | '911_CALL' | 'REMOVE_911' | 'GET_CALLS' | 'GET_ACTIVE_UNITS' | 'KICK_UNIT' | 'NEW_DISPATCH' | 'ATTACH_UNIT' | 'DETACH_UNIT' | 'SET_CALL_POSTAL' | 'SET_CALL_PRIMARY' | 'ADD_CALL_NOTE' | 'CLOSE_CALL' | 'UNIT_LOCATION' | 'SET_STREETSIGN_CONFIG' | 'UPDATE_STREETSIGN' | 'GET_COM_ACCOUNT' | 'GET_DEPARTMENTS' | 'GET_SUB_VERSION' | 'CHECK_COM_APIID' | 'VERIFY_WHITELIST' | 'CLOCK_IN_OUT' | 'FULL_WHITELIST' | 'GET_ACCOUNT_RANKS' | 'SET_ACCOUNT_RANKS' | 'RSVP' | 'CHANGE_FORM_STAGE' | 'KICK_ACCOUNT' | 'BAN_ACCOUNT' | 'LOOKUP' | 'EDIT_ACC_PROFLIE_FIELDS' | 'SET_ACCOUNT_NAME' | 'FORCE_SYNC' | "ERLC_GET_ONLINE_PLAYERS" | "ERLC_GET_PLAYER_QUEUE" | "ERLC_ADD_NEW_RECORD";
604
+ export type AllAPITypesType = 'GET_SERVERS' | 'SET_SERVERS' | 'GET_VERSION' | 'SET_PENAL_CODES' | 'SET_API_ID' | 'GET_TEMPLATES' | 'NEW_RECORD' | 'EDIT_RECORD' | 'REMOVE_RECORD' | 'LOOKUP_INT' | 'LOOKUP' | 'GET_ACCOUNT' | 'CHECK_APIID' | 'APPLY_PERMISSION_KEY' | 'SET_ACCOUNT_PERMISSIONS' | 'BAN_USER' | 'VERIFY_SECRET' | 'AUTH_STREETSIGNS' | 'SET_POSTALS' | 'SEND_PHOTO' | 'SET_CLOCK' | 'JOIN_COMMUNITY' | 'LEAVE_COMMUNITY' | 'GET_CHARACTERS' | 'NEW_CHARACTER' | 'EDIT_CHARACTER' | 'REMOVE_CHARACTER' | 'GET_IDENTIFIERS' | 'MODIFY_IDENTIFIER' | 'SET_IDENTIFIER' | 'UNIT_PANIC' | 'UNIT_STATUS' | 'GET_BLIPS' | 'ADD_BLIP' | 'MODIFY_BLIP' | 'REMOVE_BLIP' | '911_CALL' | 'REMOVE_911' | 'GET_CALLS' | 'GET_ACTIVE_UNITS' | 'KICK_UNIT' | 'NEW_DISPATCH' | 'ATTACH_UNIT' | 'DETACH_UNIT' | 'SET_CALL_POSTAL' | 'SET_CALL_PRIMARY' | 'ADD_CALL_NOTE' | 'CLOSE_CALL' | 'UNIT_LOCATION' | 'SET_STREETSIGN_CONFIG' | 'UPDATE_STREETSIGN' | 'GET_COM_ACCOUNT' | 'GET_DEPARTMENTS' | 'GET_SUB_VERSION' | 'GET_CURRENT_CLOCK_IN' | 'GET_ACCOUNTS' | 'GET_PROFILE_FIELDS' | 'CHECK_COM_APIID' | 'VERIFY_WHITELIST' | 'CLOCK_IN_OUT' | 'FULL_WHITELIST' | 'GET_ACCOUNT_RANKS' | 'SET_ACCOUNT_RANKS' | 'RSVP' | 'CHANGE_FORM_STAGE' | 'GET_FORM_TEMPLATE_SUBMISSIONS' | 'KICK_ACCOUNT' | 'BAN_ACCOUNT' | 'LOOKUP' | 'EDIT_ACC_PROFLIE_FIELDS' | 'SET_ACCOUNT_NAME' | 'FORCE_SYNC' | 'SET_GAME_SERVERS' | 'ERLC_GET_ONLINE_PLAYERS' | 'ERLC_GET_PLAYER_QUEUE' | 'ERLC_ADD_NEW_RECORD' | 'RADIO_GET_COMMUNITY_CHANNELS' | 'RADIO_GET_CONNECTED_USERS' | 'RADIO_GET_CONNECTED_USER' | 'RADIO_SET_USER_CHANNELS' | 'RADIO_SET_USER_DISPLAY_NAME' | 'RADIO_GET_SERVER_SUBSCRIPTION_FROM_IP' | 'RADIO_SET_SERVER_IP' | 'RADIO_SET_IN_GAME_SPEAKER_LOCATIONS';
499
605
 
500
606
  export interface CMSServerAPIStruct {
501
607
  id: number;
@@ -758,13 +864,9 @@ export interface CADStreetSignStruct {
758
864
 
759
865
  export interface CADUnitLocationStruct {
760
866
  apiId: string;
761
- location: string;
867
+ location: string;
762
868
  }
763
869
 
764
- export interface CMSProfileField {
765
- id: string;
766
- value: string;
767
- }
768
870
  export interface RESTTypedAPIDataStructs {
769
871
  // CAD - General
770
872
  GET_SERVERS: [];
@@ -787,7 +889,7 @@ export interface RESTTypedAPIDataStructs {
787
889
  ];
788
890
  CHECK_APIID: [apiId: string];
789
891
  APPLY_PERMISSION_KEY: [
790
- apiId: string,
892
+ apiId: string | undefined,
791
893
  permissionKey: string
792
894
  ];
793
895
  SET_ACCOUNT_PERMISSIONS: [data: CADModifyAccountPermsStruct];
@@ -796,9 +898,29 @@ export interface RESTTypedAPIDataStructs {
796
898
  AUTH_STREETSIGNS: [serverId: number];
797
899
  SET_POSTALS: [data: CADSetPostalStruct[]];
798
900
  SEND_PHOTO: [
799
- apiId: string,
901
+ apiId: string | undefined,
800
902
  url: string
801
903
  ];
904
+ SET_CLOCK: [
905
+ data: {
906
+ serverId: number,
907
+ currentUtc: string,
908
+ currentGame: string,
909
+ secondsPerHour: number
910
+ }
911
+ ];
912
+ JOIN_COMMUNITY: [
913
+ payload: {
914
+ internalKey: string,
915
+ accounts: Array<{ account: string }>
916
+ }
917
+ ];
918
+ LEAVE_COMMUNITY: [
919
+ payload: {
920
+ internalKey: string,
921
+ accounts: Array<{ account: string }>
922
+ }
923
+ ];
802
924
  // CAD - Civilian
803
925
  GET_CHARACTERS: [apiId: string];
804
926
  NEW_CHARACTER: [data: CADNewEditRecordOptionOneStruct | CADNewEditRecordOptionTwoStruct];
@@ -808,15 +930,15 @@ export interface RESTTypedAPIDataStructs {
808
930
  GET_IDENTIFIERS: [apiId: string];
809
931
  MODIFY_IDENTIFIER: [data: CADModifyIdentifierStruct];
810
932
  SET_IDENTIFIER: [
811
- apiId: string,
933
+ apiId: string | undefined,
812
934
  identId: number
813
935
  ];
814
936
  UNIT_PANIC: [
815
- apiId: string,
937
+ apiId: string | undefined,
816
938
  isPanic: boolean
817
939
  ];
818
940
  UNIT_STATUS: [
819
- apiId: string,
941
+ apiId: string | undefined,
820
942
  status: number,
821
943
  serverId: number
822
944
  ];
@@ -828,7 +950,7 @@ export interface RESTTypedAPIDataStructs {
828
950
  GET_CALLS: [data: CADGetCallsStruct];
829
951
  GET_ACTIVE_UNITS: [data: CADGetActiveUnitsStruct];
830
952
  KICK_UNIT: [
831
- apiId: string,
953
+ apiId: string | undefined,
832
954
  reason: string,
833
955
  serverId: number
834
956
  ];
@@ -893,6 +1015,24 @@ export interface RESTTypedAPIDataStructs {
893
1015
  uniqueId?: string
894
1016
  ];
895
1017
  GET_SUB_VERSION: [];
1018
+ GET_CURRENT_CLOCK_IN: [
1019
+ apiId?: string,
1020
+ username?: string,
1021
+ accId?: string,
1022
+ discord?: string,
1023
+ uniqueId?: string
1024
+ ];
1025
+ GET_ACCOUNTS: [
1026
+ options?: {
1027
+ skip?: number,
1028
+ take?: number,
1029
+ sysStatus?: boolean,
1030
+ comStatus?: boolean,
1031
+ banned?: boolean,
1032
+ archived?: boolean
1033
+ }
1034
+ ];
1035
+ GET_PROFILE_FIELDS: [];
896
1036
  CHECK_COM_APIID: [apiId: string];
897
1037
  CLOCK_IN_OUT: [
898
1038
  apiId?: string,
@@ -936,6 +1076,7 @@ export interface RESTTypedAPIDataStructs {
936
1076
  ],
937
1077
  // CMS - Servers
938
1078
  GET_GAME_SERVERS: [];
1079
+ SET_GAME_SERVERS: [servers: CMSSetGameServerStruct[]];
939
1080
  VERIFY_WHITELIST: [
940
1081
  apiId: string | undefined,
941
1082
  accId: string | undefined,
@@ -955,23 +1096,28 @@ export interface RESTTypedAPIDataStructs {
955
1096
  uniqueId: string | undefined
956
1097
  ],
957
1098
  EDIT_ACC_PROFLIE_FIELDS : [
958
- apiId: string,
959
- username: string,
960
- accId: string,
961
- discord: string,
962
- uniqueId: string,
963
- profileFields : CMSProfileField[]
1099
+ apiId: string | undefined,
1100
+ username: string | undefined,
1101
+ accId: string | undefined,
1102
+ discord: string | undefined,
1103
+ uniqueId: string | undefined,
1104
+ profileFields : CMSProfileFieldUpdate[]
964
1105
  ]
965
1106
  // CMS - Forms
966
1107
  CHANGE_FORM_STAGE: [
967
- accId: string,
1108
+ accId: string | undefined,
968
1109
  formId: number,
969
1110
  newStageId: string,
970
- apiId: string,
971
- username: string,
972
- discord: string,
1111
+ apiId: string | undefined,
1112
+ username: string | undefined,
1113
+ discord: string | undefined,
973
1114
  uniqueId: number,
974
1115
  ]
1116
+ GET_FORM_TEMPLATE_SUBMISSIONS: [
1117
+ templateId: number,
1118
+ skip?: number,
1119
+ take?: number,
1120
+ ]
975
1121
  BAN_ACCOUNT: [
976
1122
  apiId: string | undefined,
977
1123
  username: string | undefined,
@@ -1002,6 +1148,29 @@ export interface RESTTypedAPIDataStructs {
1002
1148
  playerRobloxId?: string | number,
1003
1149
  points?: number,
1004
1150
  ]
1151
+ // Radio
1152
+ RADIO_GET_COMMUNITY_CHANNELS: [];
1153
+ RADIO_GET_CONNECTED_USERS: [];
1154
+ RADIO_GET_CONNECTED_USER: [
1155
+ roomId: number,
1156
+ identity: string
1157
+ ];
1158
+ RADIO_SET_USER_CHANNELS: [
1159
+ identity: string,
1160
+ options?: RadioSetUserChannelsOptions
1161
+ ];
1162
+ RADIO_SET_USER_DISPLAY_NAME: [
1163
+ accId: string | undefined,
1164
+ displayName: string
1165
+ ];
1166
+ RADIO_GET_SERVER_SUBSCRIPTION_FROM_IP: [];
1167
+ RADIO_SET_SERVER_IP: [
1168
+ pushUrl: string
1169
+ ];
1170
+ RADIO_SET_IN_GAME_SPEAKER_LOCATIONS: [
1171
+ locations: RadioSpeakerLocation[],
1172
+ token?: string
1173
+ ];
1005
1174
  }
1006
1175
 
1007
1176
  export type PossibleRequestData =
@@ -1013,6 +1182,14 @@ export type PossibleRequestData =
1013
1182
  servers: CADServerAPIStruct[];
1014
1183
  deployMap: boolean;
1015
1184
  } |
1185
+ {
1186
+ data: {
1187
+ serverId: number;
1188
+ currentUtc: string;
1189
+ currentGame: string;
1190
+ secondsPerHour: number;
1191
+ }
1192
+ } |
1016
1193
  {
1017
1194
  id: number;
1018
1195
  } |
@@ -1109,6 +1286,10 @@ export type PossibleRequestData =
1109
1286
  text3: string;
1110
1287
  }
1111
1288
  } |
1289
+ {
1290
+ internalKey: string;
1291
+ accounts: { account: string }[];
1292
+ } |
1112
1293
  {
1113
1294
  apiId?: string;
1114
1295
  username?: string;
@@ -61,4 +61,89 @@ export class CADManager extends BaseManager {
61
61
  }
62
62
  });
63
63
  }
64
- }
64
+
65
+ /**
66
+ * Updates the CAD clock to match in-game time.
67
+ */
68
+ public async setClockTime(data: { serverId: number; currentUtc: string; currentGame: string; secondsPerHour: number }): Promise<globalTypes.CADSetClockTimePromiseResult> {
69
+ return new Promise(async (resolve, reject) => {
70
+ try {
71
+ const response: any = await this.rest?.request('SET_CLOCK', data);
72
+ resolve({ success: true, data: response });
73
+ } catch (err) {
74
+ if (err instanceof APIError) {
75
+ resolve({ success: false, reason: err.response });
76
+ } else {
77
+ reject(err);
78
+ }
79
+ }
80
+ });
81
+ }
82
+
83
+ /**
84
+ * Adds accounts to the community via the join community endpoint.
85
+ * NOTE: This endpoint is intended for internal CMS use and requires an internal key.
86
+ */
87
+ public async joinCommunity(internalKey: string, accounts: string | { account: string } | Array<string | { account: string }>): Promise<globalTypes.CADJoinCommunityPromiseResult> {
88
+ if (!internalKey) {
89
+ throw new Error('internalKey is required to join a community.');
90
+ }
91
+ const normalizedAccounts = this.normalizeAccountEntries(accounts);
92
+ if (normalizedAccounts.length === 0) {
93
+ throw new Error('At least one account must be provided to join the community.');
94
+ }
95
+ return new Promise(async (resolve, reject) => {
96
+ try {
97
+ const response: any = await this.rest?.request('JOIN_COMMUNITY', { internalKey, accounts: normalizedAccounts });
98
+ resolve({ success: true, data: response });
99
+ } catch (err) {
100
+ if (err instanceof APIError) {
101
+ resolve({ success: false, reason: err.response });
102
+ } else {
103
+ reject(err);
104
+ }
105
+ }
106
+ });
107
+ }
108
+
109
+ /**
110
+ * Removes accounts from the community via the leave community endpoint.
111
+ * NOTE: This endpoint is intended for internal CMS use and requires an internal key.
112
+ */
113
+ public async leaveCommunity(internalKey: string, accounts: string | { account: string } | Array<string | { account: string }>): Promise<globalTypes.CADLeaveCommunityPromiseResult> {
114
+ if (!internalKey) {
115
+ throw new Error('internalKey is required to leave a community.');
116
+ }
117
+ const normalizedAccounts = this.normalizeAccountEntries(accounts);
118
+ if (normalizedAccounts.length === 0) {
119
+ throw new Error('At least one account must be provided to leave the community.');
120
+ }
121
+ return new Promise(async (resolve, reject) => {
122
+ try {
123
+ const response: any = await this.rest?.request('LEAVE_COMMUNITY', { internalKey, accounts: normalizedAccounts });
124
+ resolve({ success: true, data: response });
125
+ } catch (err) {
126
+ if (err instanceof APIError) {
127
+ resolve({ success: false, reason: err.response });
128
+ } else {
129
+ reject(err);
130
+ }
131
+ }
132
+ });
133
+ }
134
+
135
+ private normalizeAccountEntries(input: string | { account: string } | Array<string | { account: string }>): { account: string }[] {
136
+ const entries = Array.isArray(input) ? input : [input];
137
+ return entries
138
+ .filter((entry): entry is string | { account: string } => entry !== undefined && entry !== null)
139
+ .map((entry) => {
140
+ if (typeof entry === 'string') {
141
+ return { account: entry };
142
+ }
143
+ if ('account' in entry) {
144
+ return { account: entry.account };
145
+ }
146
+ throw new Error('Invalid account entry provided.');
147
+ });
148
+ }
149
+ }
@@ -348,6 +348,127 @@ export class CMSManager extends BaseManager {
348
348
  });
349
349
  }
350
350
 
351
+ /**
352
+ * Toggles RSVP for the provided event and account.
353
+ */
354
+ public async rsvp(eventId: string, params: { apiId?: string, username?: string, accId?: string, discord?: string, uniqueId?: string } = {}): Promise<globalTypes.CMSRsvpPromiseResult> {
355
+ return new Promise(async (resolve, reject) => {
356
+ try {
357
+ const response: any = await this.rest?.request('RSVP', eventId, params.apiId, params.accId, params.discord, params.uniqueId);
358
+ if (typeof response === 'string') {
359
+ resolve({ success: true, status: response });
360
+ } else {
361
+ resolve({ success: true, data: response });
362
+ }
363
+ } catch (err) {
364
+ if (err instanceof APIError) {
365
+ resolve({ success: false, reason: err.response });
366
+ } else {
367
+ reject(err);
368
+ }
369
+ }
370
+ });
371
+ }
372
+
373
+ /**
374
+ * Retrieves submissions for a specific form template.
375
+ */
376
+ public async getFormSubmissions<T = unknown>(templateId: number, options: { skip?: number, take?: number } = {}): Promise<globalTypes.CMSGetFormSubmissionsPromiseResult<T>> {
377
+ return new Promise(async (resolve, reject) => {
378
+ try {
379
+ const response: any = await this.rest?.request('GET_FORM_TEMPLATE_SUBMISSIONS', templateId, options.skip, options.take);
380
+ resolve({ success: true, data: response });
381
+ } catch (err) {
382
+ if (err instanceof APIError) {
383
+ resolve({ success: false, reason: err.response });
384
+ } else {
385
+ reject(err);
386
+ }
387
+ }
388
+ });
389
+ }
390
+
391
+ /**
392
+ * Updates profile fields for the specified account.
393
+ */
394
+ public async editAccountProfileFields(params: { apiId?: string, username?: string, accId?: string, discord?: string, uniqueId?: string, profileFields: globalTypes.CMSProfileFieldUpdate[] }): Promise<globalTypes.CMSEditAccountProfileFieldsPromiseResult> {
395
+ if (!params.profileFields || params.profileFields.length === 0) {
396
+ throw new Error('profileFields array must include at least one value.');
397
+ }
398
+
399
+ return new Promise(async (resolve, reject) => {
400
+ try {
401
+ const response: any = await this.rest?.request('EDIT_ACC_PROFLIE_FIELDS', params.apiId, params.username, params.accId, params.discord, params.uniqueId, params.profileFields);
402
+ resolve({ success: true, data: response });
403
+ } catch (err) {
404
+ if (err instanceof APIError) {
405
+ resolve({ success: false, reason: err.response });
406
+ } else {
407
+ reject(err);
408
+ }
409
+ }
410
+ });
411
+ }
412
+
413
+ /**
414
+ * Gets the current clock in entry for a community member.
415
+ * @param {Object} params Identification parameters for the account.
416
+ */
417
+ public async getCurrentClockIn(params: { accId?: string, apiId?: string, username?: string, discord?: string, uniqueId?: string }): Promise<globalTypes.CMSGetCurrentClockInPromiseResult> {
418
+ return new Promise(async (resolve, reject) => {
419
+ try {
420
+ const response: any = await this.rest?.request('GET_CURRENT_CLOCK_IN', params.apiId, params.username, params.accId, params.discord, params.uniqueId);
421
+ if (typeof response === 'string') {
422
+ resolve({ success: true, reason: response, data: null });
423
+ } else {
424
+ resolve({ success: true, data: response });
425
+ }
426
+ } catch (err) {
427
+ if (err instanceof APIError) {
428
+ resolve({ success: false, reason: err.response });
429
+ } else {
430
+ reject(err);
431
+ }
432
+ }
433
+ });
434
+ }
435
+
436
+ /**
437
+ * Retrieves community accounts using optional pagination and status filters.
438
+ */
439
+ public async getAccounts(options: { skip?: number, take?: number, sysStatus?: boolean, comStatus?: boolean, banned?: boolean, archived?: boolean } = {}): Promise<globalTypes.CMSGetAccountsPromiseResult> {
440
+ return new Promise(async (resolve, reject) => {
441
+ try {
442
+ const response: any = await this.rest?.request('GET_ACCOUNTS', options);
443
+ resolve({ success: true, data: response });
444
+ } catch (err) {
445
+ if (err instanceof APIError) {
446
+ resolve({ success: false, reason: err.response });
447
+ } else {
448
+ reject(err);
449
+ }
450
+ }
451
+ });
452
+ }
453
+
454
+ /**
455
+ * Retrieves configured profile fields for the community.
456
+ */
457
+ public async getProfileFields(): Promise<globalTypes.CMSGetProfileFieldsPromiseResult> {
458
+ return new Promise(async (resolve, reject) => {
459
+ try {
460
+ const response: any = await this.rest?.request('GET_PROFILE_FIELDS');
461
+ resolve({ success: true, data: response });
462
+ } catch (err) {
463
+ if (err instanceof APIError) {
464
+ resolve({ success: false, reason: err.response });
465
+ } else {
466
+ reject(err);
467
+ }
468
+ }
469
+ });
470
+ }
471
+
351
472
  /**
352
473
  * Gets the current ERLC player queue count for the provided roblox join code.
353
474
  * @param {string} robloxJoinCode The roblox join code to get the player queue size for.
@@ -1,21 +1,22 @@
1
1
  import { Instance } from '../instance/Instance';
2
- import { CMSServerAPIStruct } from '../libs/rest/src';
2
+ import { APIError, CMSServerAPIStruct } from '../libs/rest/src';
3
+ import * as globalTypes from '../constants';
3
4
  import { CMSServer } from '../structures/CMSServer';
4
5
  import { CacheManager } from './CacheManager';
5
6
  import { CMSManager } from './CMSManager';
6
7
 
7
8
  export class CMSServerManager extends CacheManager<number, CMSServer, CMSServerAPIStruct> {
8
- constructor(instance: Instance, manager: CMSManager) {
9
+ constructor(instance: Instance, private readonly manager: CMSManager) {
9
10
  super(instance, CMSServer, []);
10
-
11
11
  (async () => {
12
- while(!manager.ready) {
12
+ const managerRef = this.manager;
13
+ while(!managerRef.ready) {
13
14
  await new Promise((resolve) => {
14
15
  setTimeout(resolve, 100);
15
16
  });
16
17
  }
17
18
  try {
18
- const serversRes: any = await manager.rest?.request('GET_GAME_SERVERS');
19
+ const serversRes: any = await managerRef.rest?.request('GET_GAME_SERVERS');
19
20
  const servers = serversRes.servers;
20
21
  servers.forEach((server: CMSServerAPIStruct) => {
21
22
  const serverStruct = {
@@ -30,4 +31,36 @@ export class CMSServerManager extends CacheManager<number, CMSServer, CMSServerA
30
31
  }
31
32
  })();
32
33
  }
33
- }
34
+
35
+ public async setGameServers(servers: globalTypes.CMSSetGameServerStruct[]): Promise<globalTypes.CMSSetGameServersPromiseResult> {
36
+ if (!Array.isArray(servers) || servers.length === 0) {
37
+ throw new Error('servers array must include at least one server configuration.');
38
+ }
39
+
40
+ return new Promise(async (resolve, reject) => {
41
+ try {
42
+ const response: any = await this.manager.rest?.request('SET_GAME_SERVERS', servers);
43
+ const updatedServers = (Array.isArray(response?.data) ? response.data : []) as CMSServerAPIStruct[];
44
+
45
+ if (updatedServers.length > 0) {
46
+ this.cache.clear();
47
+ updatedServers.forEach((server) => {
48
+ const serverStruct = {
49
+ id: server.id,
50
+ config: server
51
+ };
52
+ this._add(serverStruct, true, server.id);
53
+ });
54
+ }
55
+
56
+ resolve({ success: true, data: updatedServers as globalTypes.CMSSetGameServerStruct[] });
57
+ } catch (err) {
58
+ if (err instanceof APIError) {
59
+ resolve({ success: false, reason: err.response });
60
+ } else {
61
+ reject(err);
62
+ }
63
+ }
64
+ });
65
+ }
66
+ }