@sonoransoftware/sonoran.js 1.0.50 → 1.0.52

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.
@@ -148,6 +148,7 @@ export interface CMSClockInOutParams {
148
148
  accId?: string;
149
149
  apiId?: string;
150
150
  forceClockIn?: boolean;
151
+ forceClockOut?: boolean;
151
152
  discord?: string;
152
153
  uniqueId?: string;
153
154
  type?: string;
@@ -362,6 +363,49 @@ export interface CMSChangeFormStagePromiseResult {
362
363
  reason?: string;
363
364
  data?: unknown;
364
365
  }
366
+ export interface CMSGetFormLockStatusPromiseResult {
367
+ success: boolean;
368
+ reason?: string;
369
+ locked?: boolean;
370
+ }
371
+ export interface CMSSetFormLockStatusPromiseResult {
372
+ success: boolean;
373
+ reason?: string;
374
+ data?: unknown;
375
+ }
376
+ export interface CMSCurrentSession {
377
+ id: string;
378
+ sysStatus: boolean;
379
+ community: string;
380
+ serverId: number;
381
+ startedBy: string;
382
+ startedAt: string;
383
+ endedBy: string | null;
384
+ endedAt: string | null;
385
+ cancelledBy: string | null;
386
+ stats: Record<string, unknown>;
387
+ metadata: Record<string, unknown>;
388
+ }
389
+ export interface CMSGetCurrentSessionPromiseResult {
390
+ success: boolean;
391
+ reason?: string;
392
+ data?: CMSCurrentSession | null;
393
+ }
394
+ export interface CMSStartSessionPromiseResult {
395
+ success: boolean;
396
+ reason?: string;
397
+ data?: CMSCurrentSession | null;
398
+ }
399
+ export interface CMSStopSessionPromiseResult {
400
+ success: boolean;
401
+ reason?: string;
402
+ data?: CMSCurrentSession | null;
403
+ }
404
+ export interface CMSCancelSessionPromiseResult {
405
+ success: boolean;
406
+ reason?: string;
407
+ data?: CMSCurrentSession | null;
408
+ }
365
409
  export interface CMSSetGameServerStruct {
366
410
  id?: number;
367
411
  name: string;
@@ -79,6 +79,29 @@ class REST extends events_1.EventEmitter {
79
79
  serverId: args[0]
80
80
  };
81
81
  }
82
+ case 'GET_CURRENT_SESSION': {
83
+ return {
84
+ serverId: args[0]
85
+ };
86
+ }
87
+ case 'START_SESSION': {
88
+ return {
89
+ serverId: args[0],
90
+ accId: args[1],
91
+ };
92
+ }
93
+ case 'STOP_SESSION': {
94
+ return {
95
+ serverId: args[0],
96
+ accId: args[1],
97
+ };
98
+ }
99
+ case 'CANCEL_SESSION': {
100
+ return {
101
+ serverId: args[0],
102
+ accId: args[1],
103
+ };
104
+ }
82
105
  case 'SET_GAME_SERVERS': {
83
106
  return (_a = args[0]) !== null && _a !== void 0 ? _a : [];
84
107
  }
@@ -199,7 +222,8 @@ class REST extends events_1.EventEmitter {
199
222
  forceClockIn: args[2],
200
223
  discord: args[3],
201
224
  uniqueId: args[4],
202
- type: args[5]
225
+ type: args[5],
226
+ forceClockOut: args[6]
203
227
  };
204
228
  }
205
229
  case 'ADD_CALL_NOTE': {
@@ -295,6 +319,17 @@ class REST extends events_1.EventEmitter {
295
319
  take: args[2],
296
320
  };
297
321
  }
322
+ case 'GET_FORM_LOCK_STATUS': {
323
+ return {
324
+ templateId: args[0],
325
+ };
326
+ }
327
+ case 'SET_FORM_LOCK_STATUS': {
328
+ return {
329
+ templateId: args[0],
330
+ state: args[1],
331
+ };
332
+ }
298
333
  case 'CHANGE_FORM_STAGE': {
299
334
  return {
300
335
  accId: args[0],
@@ -38,7 +38,7 @@ export declare const CommunitiesCMSAPITypes: APITypeData[];
38
38
  export declare const ERLCMSAPITypes: APITypeData[];
39
39
  export declare const RadioAPITypes: APITypeData[];
40
40
  export declare const AllAPITypes: AllAPITypeData[];
41
- 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_MY_CALL' | '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_CLOCKIN_TYPES' | 'GET_LATEST_ACTIVITY' | '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' | 'TRIGGER_PROMOTION_FLOWS' | 'GET_PROMOTION_FLOWS' | 'SET_GAME_SERVERS' | 'ERLC_GET_ONLINE_PLAYERS' | 'ERLC_GET_PLAYER_QUEUE' | 'ERLC_ADD_NEW_RECORD' | 'ERLC_EXECUTE_COMMAND' | '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' | 'PLAY_TONE';
41
+ 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_MY_CALL' | '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_CLOCKIN_TYPES' | 'GET_LATEST_ACTIVITY' | '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' | 'GET_FORM_LOCK_STATUS' | 'SET_FORM_LOCK_STATUS' | 'GET_CURRENT_SESSION' | 'START_SESSION' | 'STOP_SESSION' | 'CANCEL_SESSION' | 'KICK_ACCOUNT' | 'BAN_ACCOUNT' | 'LOOKUP' | 'EDIT_ACC_PROFLIE_FIELDS' | 'SET_ACCOUNT_NAME' | 'FORCE_SYNC' | 'TRIGGER_PROMOTION_FLOWS' | 'GET_PROMOTION_FLOWS' | 'SET_GAME_SERVERS' | 'ERLC_GET_ONLINE_PLAYERS' | 'ERLC_GET_PLAYER_QUEUE' | 'ERLC_ADD_NEW_RECORD' | 'ERLC_EXECUTE_COMMAND' | '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' | 'PLAY_TONE';
42
42
  export interface CMSServerAPIStruct {
43
43
  id: number;
44
44
  name: string;
@@ -504,7 +504,8 @@ export interface RESTTypedAPIDataStructs {
504
504
  forceClockIn?: boolean,
505
505
  discord?: string,
506
506
  uniqueId?: string,
507
- type?: string
507
+ type?: string,
508
+ forceClockOut?: boolean
508
509
  ];
509
510
  GET_DEPARTMENTS: [];
510
511
  GET_ACCOUNT_RANKS: [
@@ -556,6 +557,21 @@ export interface RESTTypedAPIDataStructs {
556
557
  FULL_WHITELIST: [
557
558
  serverId?: number
558
559
  ];
560
+ GET_CURRENT_SESSION: [
561
+ serverId: number
562
+ ];
563
+ STOP_SESSION: [
564
+ serverId: number,
565
+ accId?: string
566
+ ];
567
+ START_SESSION: [
568
+ serverId: number,
569
+ accId?: string
570
+ ];
571
+ CANCEL_SESSION: [
572
+ serverId: number,
573
+ accId?: string
574
+ ];
559
575
  RSVP: [
560
576
  eventId: string,
561
577
  apiId: string | undefined,
@@ -585,6 +601,13 @@ export interface RESTTypedAPIDataStructs {
585
601
  skip?: number,
586
602
  take?: number
587
603
  ];
604
+ GET_FORM_LOCK_STATUS: [
605
+ templateId: number
606
+ ];
607
+ SET_FORM_LOCK_STATUS: [
608
+ templateId: number,
609
+ state: boolean
610
+ ];
588
611
  BAN_ACCOUNT: [
589
612
  apiId: string | undefined,
590
613
  username: string | undefined,
@@ -662,6 +685,11 @@ export type PossibleRequestData = undefined | {
662
685
  id: number;
663
686
  } | {
664
687
  recordTypeId?: number;
688
+ } | {
689
+ templateId: number;
690
+ } | {
691
+ templateId: number;
692
+ state: boolean;
665
693
  } | {
666
694
  apiId?: string;
667
695
  username?: string;
@@ -757,6 +785,7 @@ export type PossibleRequestData = undefined | {
757
785
  apiId?: string;
758
786
  accId?: string;
759
787
  forceClockIn?: boolean;
788
+ forceClockOut?: boolean;
760
789
  discord?: string;
761
790
  uniqueId?: string;
762
791
  type?: string;
@@ -479,6 +479,30 @@ exports.ServersCMSAPITypes = [
479
479
  path: 'servers/full_whitelist',
480
480
  method: 'POST',
481
481
  minVersion: 3
482
+ },
483
+ {
484
+ type: 'GET_CURRENT_SESSION',
485
+ path: 'servers/get_current_session',
486
+ method: 'POST',
487
+ minVersion: 0
488
+ },
489
+ {
490
+ type: 'START_SESSION',
491
+ path: 'servers/start_session',
492
+ method: 'POST',
493
+ minVersion: 0
494
+ },
495
+ {
496
+ type: 'STOP_SESSION',
497
+ path: 'servers/stop_session',
498
+ method: 'POST',
499
+ minVersion: 0
500
+ },
501
+ {
502
+ type: 'CANCEL_SESSION',
503
+ path: 'servers/cancel_session',
504
+ method: 'POST',
505
+ minVersion: 0
482
506
  }
483
507
  ];
484
508
  exports.EventsCMSAPITypes = [
@@ -501,6 +525,18 @@ exports.FormsCMSAPITypes = [
501
525
  path: 'forms/get_template_submissions',
502
526
  method: 'POST',
503
527
  minVersion: 0
528
+ },
529
+ {
530
+ type: 'GET_FORM_LOCK_STATUS',
531
+ path: 'forms/get_form_lock_status',
532
+ method: 'POST',
533
+ minVersion: 0
534
+ },
535
+ {
536
+ type: 'SET_FORM_LOCK_STATUS',
537
+ path: 'forms/set_form_lock_status',
538
+ method: 'POST',
539
+ minVersion: 0
504
540
  }
505
541
  ];
506
542
  exports.CommunitiesCMSAPITypes = [
@@ -77,6 +77,7 @@ export declare class CMSManager extends BaseManager {
77
77
  * @param {string} [data.accId] (Optional) The account id to clock in or out.
78
78
  * @param {string} [data.apiId] (Optional) The api id to clock in or out.
79
79
  * @param {boolean} [data.forceClockIn] If true, it will override any current clock in with a new clock in at the time of the request.
80
+ * @param {boolean} [data.forceClockOut] If true, it will force a clock out regardless of current status.
80
81
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
81
82
  * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
82
83
  * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
@@ -210,6 +211,14 @@ export declare class CMSManager extends BaseManager {
210
211
  discord?: string;
211
212
  uniqueId: number;
212
213
  }): Promise<globalTypes.CMSChangeFormStagePromiseResult>;
214
+ /**
215
+ * Retrieves the lock status for a form template.
216
+ */
217
+ getFormLockStatus(templateId: number): Promise<globalTypes.CMSGetFormLockStatusPromiseResult>;
218
+ /**
219
+ * Sets the lock status for a form template.
220
+ */
221
+ setFormLockStatus(templateId: number, state: boolean): Promise<globalTypes.CMSSetFormLockStatusPromiseResult>;
213
222
  /**
214
223
  * Retrieves submissions for a specific form template.
215
224
  */
@@ -263,6 +272,22 @@ export declare class CMSManager extends BaseManager {
263
272
  * Retrieves configured profile fields for the community.
264
273
  */
265
274
  getProfileFields(): Promise<globalTypes.CMSGetProfileFieldsPromiseResult>;
275
+ /**
276
+ * Retrieves the current active session for the specified server, if present.
277
+ */
278
+ getCurrentSession(serverId?: number): Promise<globalTypes.CMSGetCurrentSessionPromiseResult>;
279
+ /**
280
+ * Starts a new CMS session for the specified server.
281
+ */
282
+ startSession(serverId?: number, accId?: string): Promise<globalTypes.CMSStartSessionPromiseResult>;
283
+ /**
284
+ * Stops the current CMS session for the specified server.
285
+ */
286
+ stopSession(serverId?: number, accId?: string): Promise<globalTypes.CMSStopSessionPromiseResult>;
287
+ /**
288
+ * Cancels the current CMS session for the specified server.
289
+ */
290
+ cancelSession(serverId?: number, accId?: string): Promise<globalTypes.CMSCancelSessionPromiseResult>;
266
291
  /**
267
292
  * Gets the current ERLC player queue count for the provided roblox join code.
268
293
  * @param {string} robloxJoinCode The roblox join code to get the player queue size for.
@@ -176,6 +176,7 @@ class CMSManager extends BaseManager_1.BaseManager {
176
176
  * @param {string} [data.accId] (Optional) The account id to clock in or out.
177
177
  * @param {string} [data.apiId] (Optional) The api id to clock in or out.
178
178
  * @param {boolean} [data.forceClockIn] If true, it will override any current clock in with a new clock in at the time of the request.
179
+ * @param {boolean} [data.forceClockOut] If true, it will force a clock out regardless of current status.
179
180
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
180
181
  * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
181
182
  * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
@@ -185,7 +186,7 @@ class CMSManager extends BaseManager_1.BaseManager {
185
186
  return new Promise(async (resolve, reject) => {
186
187
  var _a;
187
188
  try {
188
- const clockInOutRequest = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId, data.type));
189
+ const clockInOutRequest = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId, data.type, !!data.forceClockOut));
189
190
  const clockInOutResponse = clockInOutRequest;
190
191
  if (!clockInOutResponse)
191
192
  resolve({ success: false, reason: clockInOutRequest });
@@ -518,6 +519,80 @@ class CMSManager extends BaseManager_1.BaseManager {
518
519
  }
519
520
  });
520
521
  }
522
+ /**
523
+ * Retrieves the lock status for a form template.
524
+ */
525
+ async getFormLockStatus(templateId) {
526
+ if (templateId === undefined || Number.isNaN(Number(templateId))) {
527
+ throw new Error('templateId is required to get form lock status.');
528
+ }
529
+ return new Promise(async (resolve, reject) => {
530
+ var _a;
531
+ try {
532
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('GET_FORM_LOCK_STATUS', templateId));
533
+ if (typeof response === 'boolean') {
534
+ resolve({ success: true, locked: response });
535
+ return;
536
+ }
537
+ if (typeof response === 'string') {
538
+ const normalized = response.toLowerCase();
539
+ if (normalized === 'locked') {
540
+ resolve({ success: true, locked: true });
541
+ return;
542
+ }
543
+ if (normalized === 'unlocked') {
544
+ resolve({ success: true, locked: false });
545
+ return;
546
+ }
547
+ }
548
+ if (response && typeof response === 'object') {
549
+ if ('locked' in response) {
550
+ resolve({ success: true, locked: Boolean(response.locked) });
551
+ return;
552
+ }
553
+ if ('isLocked' in response) {
554
+ resolve({ success: true, locked: Boolean(response.isLocked) });
555
+ return;
556
+ }
557
+ }
558
+ resolve({ success: false, reason: response });
559
+ }
560
+ catch (err) {
561
+ if (err instanceof src_1.APIError) {
562
+ resolve({ success: false, reason: err.response });
563
+ }
564
+ else {
565
+ reject(err);
566
+ }
567
+ }
568
+ });
569
+ }
570
+ /**
571
+ * Sets the lock status for a form template.
572
+ */
573
+ async setFormLockStatus(templateId, state) {
574
+ if (templateId === undefined || Number.isNaN(Number(templateId))) {
575
+ throw new Error('templateId is required to set form lock status.');
576
+ }
577
+ if (typeof state !== 'boolean') {
578
+ throw new Error('state must be a boolean to set form lock status.');
579
+ }
580
+ return new Promise(async (resolve, reject) => {
581
+ var _a;
582
+ try {
583
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('SET_FORM_LOCK_STATUS', templateId, state));
584
+ resolve({ success: true, data: response });
585
+ }
586
+ catch (err) {
587
+ if (err instanceof src_1.APIError) {
588
+ resolve({ success: false, reason: err.response });
589
+ }
590
+ else {
591
+ reject(err);
592
+ }
593
+ }
594
+ });
595
+ }
521
596
  /**
522
597
  * Retrieves submissions for a specific form template.
523
598
  */
@@ -657,6 +732,111 @@ class CMSManager extends BaseManager_1.BaseManager {
657
732
  }
658
733
  });
659
734
  }
735
+ /**
736
+ * Retrieves the current active session for the specified server, if present.
737
+ */
738
+ async getCurrentSession(serverId) {
739
+ const resolvedServerId = serverId !== null && serverId !== void 0 ? serverId : this.instance.cmsDefaultServerId;
740
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
741
+ throw new Error('serverId is required to get current session.');
742
+ }
743
+ return new Promise(async (resolve, reject) => {
744
+ var _a;
745
+ try {
746
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('GET_CURRENT_SESSION', resolvedServerId));
747
+ resolve({ success: true, data: response !== null && response !== void 0 ? response : null });
748
+ }
749
+ catch (err) {
750
+ if (err instanceof src_1.APIError) {
751
+ resolve({ success: false, reason: err.response });
752
+ }
753
+ else {
754
+ reject(err);
755
+ }
756
+ }
757
+ });
758
+ }
759
+ /**
760
+ * Starts a new CMS session for the specified server.
761
+ */
762
+ async startSession(serverId, accId) {
763
+ const resolvedServerId = serverId !== null && serverId !== void 0 ? serverId : this.instance.cmsDefaultServerId;
764
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
765
+ throw new Error('serverId is required to start a session.');
766
+ }
767
+ if (!accId) {
768
+ throw new Error('accId is required to start a session.');
769
+ }
770
+ return new Promise(async (resolve, reject) => {
771
+ var _a;
772
+ try {
773
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('START_SESSION', resolvedServerId, accId));
774
+ resolve({ success: true, data: response !== null && response !== void 0 ? response : null });
775
+ }
776
+ catch (err) {
777
+ if (err instanceof src_1.APIError) {
778
+ resolve({ success: false, reason: err.response });
779
+ }
780
+ else {
781
+ reject(err);
782
+ }
783
+ }
784
+ });
785
+ }
786
+ /**
787
+ * Stops the current CMS session for the specified server.
788
+ */
789
+ async stopSession(serverId, accId) {
790
+ const resolvedServerId = serverId !== null && serverId !== void 0 ? serverId : this.instance.cmsDefaultServerId;
791
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
792
+ throw new Error('serverId is required to stop a session.');
793
+ }
794
+ if (!accId) {
795
+ throw new Error('accId is required to stop a session.');
796
+ }
797
+ return new Promise(async (resolve, reject) => {
798
+ var _a;
799
+ try {
800
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('STOP_SESSION', resolvedServerId, accId));
801
+ resolve({ success: true, data: response !== null && response !== void 0 ? response : null });
802
+ }
803
+ catch (err) {
804
+ if (err instanceof src_1.APIError) {
805
+ resolve({ success: false, reason: err.response });
806
+ }
807
+ else {
808
+ reject(err);
809
+ }
810
+ }
811
+ });
812
+ }
813
+ /**
814
+ * Cancels the current CMS session for the specified server.
815
+ */
816
+ async cancelSession(serverId, accId) {
817
+ const resolvedServerId = serverId !== null && serverId !== void 0 ? serverId : this.instance.cmsDefaultServerId;
818
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
819
+ throw new Error('serverId is required to cancel a session.');
820
+ }
821
+ if (!accId) {
822
+ throw new Error('accId is required to cancel a session.');
823
+ }
824
+ return new Promise(async (resolve, reject) => {
825
+ var _a;
826
+ try {
827
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('CANCEL_SESSION', resolvedServerId, accId));
828
+ resolve({ success: true, data: response !== null && response !== void 0 ? response : null });
829
+ }
830
+ catch (err) {
831
+ if (err instanceof src_1.APIError) {
832
+ resolve({ success: false, reason: err.response });
833
+ }
834
+ else {
835
+ reject(err);
836
+ }
837
+ }
838
+ });
839
+ }
660
840
  /**
661
841
  * Gets the current ERLC player queue count for the provided roblox join code.
662
842
  * @param {string} robloxJoinCode The roblox join code to get the player queue size for.
@@ -139,6 +139,7 @@ if (comAccount.success) {
139
139
  | data.apiId | Yes | String | Must have at least apiId or accId |
140
140
  | data.accId | Yes | String | Must have at least apiId or accId |
141
141
  | data.forceClockIn | Yes | Boolean | Will start a new clock in and overrite any current clock in |
142
+ | data.forceClockOut | Yes | Boolean | Forces a clock out regardless of the current status |
142
143
 
143
144
  Returns *clockResult*;
144
145
  | Property | Optional | Type | Note |
@@ -162,6 +163,12 @@ const clockResult = await instance.cms.clockInOut({
162
163
  forceClockIn: true
163
164
  });
164
165
  // OR
166
+ // This will force a clock out on the community account found by the specified API ID if found.
167
+ const clockResult = await instance.cms.clockInOut({
168
+ apiId: '235947056630333440',
169
+ forceClockOut: true
170
+ });
171
+ // OR
165
172
  // This will either clock in or out the community account found by the specified API ID if found.
166
173
  // Will determine to clock in or out depending on what is pending.
167
174
  const clockResult = await instance.cms.clockInOut({
@@ -209,4 +216,4 @@ if (checkResult.success) {
209
216
  } else {
210
217
  console.log('Unsuccessful', checkResult.reason);
211
218
  }
212
- ```
219
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonoransoftware/sonoran.js",
3
- "version": "1.0.50",
3
+ "version": "1.0.52",
4
4
  "description": "Sonoran.js is a library that allows you to interact with the Sonoran CAD and Sonoran CMS API. Based off of and utilizes several Discord.js library techniques for ease of use.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -267,12 +267,13 @@ const getRanks = await instance.cms.getAccountRanks(params);
267
267
  ### clockInOut(obj)
268
268
  Clock a user in or out in the CMS system
269
269
  #### Arugment `obj`
270
- ##### Type `object` `{accId?: string, apiId?: string, forceClockIn?: boolean, discord?: string, uniqueId?: string, type?: string}`
270
+ ##### Type `object` `{accId?: string, apiId?: string, forceClockIn?: boolean, forceClockOut?: boolean, discord?: string, uniqueId?: string, type?: string}`
271
271
  ```js
272
272
  const params = {
273
273
  accId: '',
274
274
  apiId: '',
275
275
  forceClockIn: true,
276
+ forceClockOut: false,
276
277
  discord: '',
277
278
  uniqueId: '1234',
278
279
  type: 'clockin-type-uuid'
@@ -404,6 +405,19 @@ Retrieves form submissions with optional pagination.
404
405
  const submissions = await instance.cms.getFormSubmissions(42, { skip: 0, take: 25 });
405
406
  ```
406
407
 
408
+ ### getFormLockStatus(templateId)
409
+ Returns whether a form template is locked.
410
+ ```js
411
+ const lockStatus = await instance.cms.getFormLockStatus(42);
412
+ // lockStatus => { success: true, locked: true } when locked
413
+ ```
414
+
415
+ ### setFormLockStatus(templateId, state)
416
+ Sets the lock state for a form template.
417
+ ```js
418
+ const result = await instance.cms.setFormLockStatus(42, true); // lock form
419
+ ```
420
+
407
421
  ### changeFormStage(params)
408
422
  Moves a form to the specified stage for an account.
409
423
  ```js
@@ -464,6 +478,30 @@ await instance.cms.servers?.setGameServers([
464
478
  ]);
465
479
  ```
466
480
 
481
+ ### getCurrentSession(serverId?)
482
+ Retrieves the active CMS session for a server (if one exists).
483
+ ```js
484
+ const session = await instance.cms.getCurrentSession(1);
485
+ ```
486
+
487
+ ### startSession(serverId?, accId)
488
+ Starts a CMS session for the given server using the provided account.
489
+ ```js
490
+ const session = await instance.cms.startSession(1, 'account-uuid');
491
+ ```
492
+
493
+ ### stopSession(serverId?, accId)
494
+ Stops the active CMS session for the given server using the provided account.
495
+ ```js
496
+ const session = await instance.cms.stopSession(1, 'account-uuid');
497
+ ```
498
+
499
+ ### cancelSession(serverId?, accId)
500
+ Cancels the active CMS session for the given server using the provided account.
501
+ ```js
502
+ const session = await instance.cms.cancelSession(1, 'account-uuid');
503
+ ```
504
+
467
505
  ## Radio Functions
468
506
  ### getCommunityChannels()
469
507
  Retrieves configured community channel groups and channels.
package/src/constants.ts CHANGED
@@ -168,6 +168,7 @@ export interface CMSClockInOutParams {
168
168
  accId?: string;
169
169
  apiId?: string;
170
170
  forceClockIn?: boolean;
171
+ forceClockOut?: boolean;
171
172
  discord?: string;
172
173
  uniqueId?: string;
173
174
  type?: string;
@@ -405,6 +406,56 @@ export interface CMSChangeFormStagePromiseResult {
405
406
  data?: unknown;
406
407
  }
407
408
 
409
+ export interface CMSGetFormLockStatusPromiseResult {
410
+ success: boolean;
411
+ reason?: string;
412
+ locked?: boolean;
413
+ }
414
+
415
+ export interface CMSSetFormLockStatusPromiseResult {
416
+ success: boolean;
417
+ reason?: string;
418
+ data?: unknown;
419
+ }
420
+
421
+ export interface CMSCurrentSession {
422
+ id: string;
423
+ sysStatus: boolean;
424
+ community: string;
425
+ serverId: number;
426
+ startedBy: string;
427
+ startedAt: string;
428
+ endedBy: string | null;
429
+ endedAt: string | null;
430
+ cancelledBy: string | null;
431
+ stats: Record<string, unknown>;
432
+ metadata: Record<string, unknown>;
433
+ }
434
+
435
+ export interface CMSGetCurrentSessionPromiseResult {
436
+ success: boolean;
437
+ reason?: string;
438
+ data?: CMSCurrentSession | null;
439
+ }
440
+
441
+ export interface CMSStartSessionPromiseResult {
442
+ success: boolean;
443
+ reason?: string;
444
+ data?: CMSCurrentSession | null;
445
+ }
446
+
447
+ export interface CMSStopSessionPromiseResult {
448
+ success: boolean;
449
+ reason?: string;
450
+ data?: CMSCurrentSession | null;
451
+ }
452
+
453
+ export interface CMSCancelSessionPromiseResult {
454
+ success: boolean;
455
+ reason?: string;
456
+ data?: CMSCurrentSession | null;
457
+ }
458
+
408
459
  export interface CMSSetGameServerStruct {
409
460
  id?: number;
410
461
  name: string;
@@ -185,6 +185,29 @@ export class REST extends EventEmitter {
185
185
  serverId: args[0]
186
186
  }
187
187
  }
188
+ case 'GET_CURRENT_SESSION': {
189
+ return {
190
+ serverId: args[0]
191
+ }
192
+ }
193
+ case 'START_SESSION': {
194
+ return {
195
+ serverId: args[0],
196
+ accId: args[1],
197
+ }
198
+ }
199
+ case 'STOP_SESSION': {
200
+ return {
201
+ serverId: args[0],
202
+ accId: args[1],
203
+ }
204
+ }
205
+ case 'CANCEL_SESSION': {
206
+ return {
207
+ serverId: args[0],
208
+ accId: args[1],
209
+ }
210
+ }
188
211
  case 'SET_GAME_SERVERS': {
189
212
  return args[0] ?? [];
190
213
  }
@@ -303,7 +326,8 @@ export class REST extends EventEmitter {
303
326
  forceClockIn: args[2],
304
327
  discord: args[3],
305
328
  uniqueId: args[4],
306
- type: args[5]
329
+ type: args[5],
330
+ forceClockOut: args[6]
307
331
  };
308
332
  }
309
333
  case 'ADD_CALL_NOTE': {
@@ -404,6 +428,17 @@ export class REST extends EventEmitter {
404
428
  take: args[2],
405
429
  };
406
430
  }
431
+ case 'GET_FORM_LOCK_STATUS': {
432
+ return {
433
+ templateId: args[0],
434
+ };
435
+ }
436
+ case 'SET_FORM_LOCK_STATUS': {
437
+ return {
438
+ templateId: args[0],
439
+ state: args[1],
440
+ };
441
+ }
407
442
  case 'CHANGE_FORM_STAGE': {
408
443
  return {
409
444
  accId: args[0],
@@ -512,6 +512,30 @@ export const ServersCMSAPITypes: APITypeData[] = [
512
512
  path: 'servers/full_whitelist',
513
513
  method: 'POST',
514
514
  minVersion: 3
515
+ },
516
+ {
517
+ type: 'GET_CURRENT_SESSION',
518
+ path: 'servers/get_current_session',
519
+ method: 'POST',
520
+ minVersion: 0
521
+ },
522
+ {
523
+ type: 'START_SESSION',
524
+ path: 'servers/start_session',
525
+ method: 'POST',
526
+ minVersion: 0
527
+ },
528
+ {
529
+ type: 'STOP_SESSION',
530
+ path: 'servers/stop_session',
531
+ method: 'POST',
532
+ minVersion: 0
533
+ },
534
+ {
535
+ type: 'CANCEL_SESSION',
536
+ path: 'servers/cancel_session',
537
+ method: 'POST',
538
+ minVersion: 0
515
539
  }
516
540
  ];
517
541
 
@@ -536,6 +560,18 @@ export const FormsCMSAPITypes: APITypeData[] = [
536
560
  path: 'forms/get_template_submissions',
537
561
  method: 'POST',
538
562
  minVersion: 0
563
+ },
564
+ {
565
+ type: 'GET_FORM_LOCK_STATUS',
566
+ path: 'forms/get_form_lock_status',
567
+ method: 'POST',
568
+ minVersion: 0
569
+ },
570
+ {
571
+ type: 'SET_FORM_LOCK_STATUS',
572
+ path: 'forms/set_form_lock_status',
573
+ method: 'POST',
574
+ minVersion: 0
539
575
  }
540
576
  ];
541
577
 
@@ -643,7 +679,7 @@ function formatForAll(array: APITypeData[], product: productEnums): AllAPITypeDa
643
679
 
644
680
  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) ];
645
681
 
646
- 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_MY_CALL' | '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_CLOCKIN_TYPES' | 'GET_LATEST_ACTIVITY' | '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' | 'TRIGGER_PROMOTION_FLOWS' | 'GET_PROMOTION_FLOWS' | 'SET_GAME_SERVERS' | 'ERLC_GET_ONLINE_PLAYERS' | 'ERLC_GET_PLAYER_QUEUE' | 'ERLC_ADD_NEW_RECORD' | 'ERLC_EXECUTE_COMMAND' | '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' | 'PLAY_TONE';
682
+ 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_MY_CALL' | '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_CLOCKIN_TYPES' | 'GET_LATEST_ACTIVITY' | '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' | 'GET_FORM_LOCK_STATUS' | 'SET_FORM_LOCK_STATUS' | 'GET_CURRENT_SESSION' | 'START_SESSION' | 'STOP_SESSION' | 'CANCEL_SESSION' | 'KICK_ACCOUNT' | 'BAN_ACCOUNT' | 'LOOKUP' | 'EDIT_ACC_PROFLIE_FIELDS' | 'SET_ACCOUNT_NAME' | 'FORCE_SYNC' | 'TRIGGER_PROMOTION_FLOWS' | 'GET_PROMOTION_FLOWS' | 'SET_GAME_SERVERS' | 'ERLC_GET_ONLINE_PLAYERS' | 'ERLC_GET_PLAYER_QUEUE' | 'ERLC_ADD_NEW_RECORD' | 'ERLC_EXECUTE_COMMAND' | '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' | 'PLAY_TONE';
647
683
 
648
684
  export interface CMSServerAPIStruct {
649
685
  id: number;
@@ -1143,7 +1179,8 @@ export interface RESTTypedAPIDataStructs {
1143
1179
  forceClockIn?: boolean,
1144
1180
  discord?: string,
1145
1181
  uniqueId?: string,
1146
- type?: string
1182
+ type?: string,
1183
+ forceClockOut?: boolean
1147
1184
  ];
1148
1185
  GET_DEPARTMENTS: [];
1149
1186
  GET_ACCOUNT_RANKS: [
@@ -1196,6 +1233,21 @@ export interface RESTTypedAPIDataStructs {
1196
1233
  FULL_WHITELIST: [
1197
1234
  serverId?: number,
1198
1235
  ]
1236
+ GET_CURRENT_SESSION: [
1237
+ serverId: number,
1238
+ ]
1239
+ STOP_SESSION: [
1240
+ serverId: number,
1241
+ accId?: string,
1242
+ ]
1243
+ START_SESSION: [
1244
+ serverId: number,
1245
+ accId?: string,
1246
+ ]
1247
+ CANCEL_SESSION: [
1248
+ serverId: number,
1249
+ accId?: string,
1250
+ ]
1199
1251
  RSVP : [
1200
1252
  eventId: string,
1201
1253
  apiId: string | undefined,
@@ -1226,6 +1278,13 @@ export interface RESTTypedAPIDataStructs {
1226
1278
  skip?: number,
1227
1279
  take?: number,
1228
1280
  ]
1281
+ GET_FORM_LOCK_STATUS: [
1282
+ templateId: number,
1283
+ ]
1284
+ SET_FORM_LOCK_STATUS: [
1285
+ templateId: number,
1286
+ state: boolean,
1287
+ ]
1229
1288
  BAN_ACCOUNT: [
1230
1289
  apiId: string | undefined,
1231
1290
  username: string | undefined,
@@ -1313,6 +1372,13 @@ export type PossibleRequestData =
1313
1372
  {
1314
1373
  recordTypeId?: number;
1315
1374
  } |
1375
+ {
1376
+ templateId: number;
1377
+ } |
1378
+ {
1379
+ templateId: number;
1380
+ state: boolean;
1381
+ } |
1316
1382
  {
1317
1383
  apiId?: string;
1318
1384
  username?: string;
@@ -1431,6 +1497,7 @@ export type PossibleRequestData =
1431
1497
  apiId?: string;
1432
1498
  accId?: string;
1433
1499
  forceClockIn?: boolean;
1500
+ forceClockOut?: boolean;
1434
1501
  discord?: string;
1435
1502
  uniqueId?: string;
1436
1503
  type?: string;
@@ -149,6 +149,7 @@ export class CMSManager extends BaseManager {
149
149
  * @param {string} [data.accId] (Optional) The account id to clock in or out.
150
150
  * @param {string} [data.apiId] (Optional) The api id to clock in or out.
151
151
  * @param {boolean} [data.forceClockIn] If true, it will override any current clock in with a new clock in at the time of the request.
152
+ * @param {boolean} [data.forceClockOut] If true, it will force a clock out regardless of current status.
152
153
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
153
154
  * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
154
155
  * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
@@ -157,7 +158,7 @@ export class CMSManager extends BaseManager {
157
158
  public async clockInOut(data: globalTypes.CMSClockInOutParams): Promise<globalTypes.CMSClockInOutPromiseResult> {
158
159
  return new Promise(async (resolve, reject) => {
159
160
  try {
160
- const clockInOutRequest = await this.rest?.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId, data.type);
161
+ const clockInOutRequest = await this.rest?.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId, data.type, !!data.forceClockOut);
161
162
  const clockInOutResponse = clockInOutRequest as globalTypes.clockInOutRequest;
162
163
  if (!clockInOutResponse) resolve({ success: false, reason: clockInOutRequest as string });
163
164
  resolve({ success: true, clockedIn: clockInOutResponse.completed });
@@ -463,6 +464,81 @@ export class CMSManager extends BaseManager {
463
464
  });
464
465
  }
465
466
 
467
+ /**
468
+ * Retrieves the lock status for a form template.
469
+ */
470
+ public async getFormLockStatus(templateId: number): Promise<globalTypes.CMSGetFormLockStatusPromiseResult> {
471
+ if (templateId === undefined || Number.isNaN(Number(templateId))) {
472
+ throw new Error('templateId is required to get form lock status.');
473
+ }
474
+
475
+ return new Promise(async (resolve, reject) => {
476
+ try {
477
+ const response: any = await this.rest?.request('GET_FORM_LOCK_STATUS', templateId);
478
+ if (typeof response === 'boolean') {
479
+ resolve({ success: true, locked: response });
480
+ return;
481
+ }
482
+
483
+ if (typeof response === 'string') {
484
+ const normalized = response.toLowerCase();
485
+ if (normalized === 'locked') {
486
+ resolve({ success: true, locked: true });
487
+ return;
488
+ }
489
+ if (normalized === 'unlocked') {
490
+ resolve({ success: true, locked: false });
491
+ return;
492
+ }
493
+ }
494
+
495
+ if (response && typeof response === 'object') {
496
+ if ('locked' in response) {
497
+ resolve({ success: true, locked: Boolean((response as any).locked) });
498
+ return;
499
+ }
500
+ if ('isLocked' in response) {
501
+ resolve({ success: true, locked: Boolean((response as any).isLocked) });
502
+ return;
503
+ }
504
+ }
505
+
506
+ resolve({ success: false, reason: response });
507
+ } catch (err) {
508
+ if (err instanceof APIError) {
509
+ resolve({ success: false, reason: err.response });
510
+ } else {
511
+ reject(err);
512
+ }
513
+ }
514
+ });
515
+ }
516
+
517
+ /**
518
+ * Sets the lock status for a form template.
519
+ */
520
+ public async setFormLockStatus(templateId: number, state: boolean): Promise<globalTypes.CMSSetFormLockStatusPromiseResult> {
521
+ if (templateId === undefined || Number.isNaN(Number(templateId))) {
522
+ throw new Error('templateId is required to set form lock status.');
523
+ }
524
+ if (typeof state !== 'boolean') {
525
+ throw new Error('state must be a boolean to set form lock status.');
526
+ }
527
+
528
+ return new Promise(async (resolve, reject) => {
529
+ try {
530
+ const response: any = await this.rest?.request('SET_FORM_LOCK_STATUS', templateId, state);
531
+ resolve({ success: true, data: response });
532
+ } catch (err) {
533
+ if (err instanceof APIError) {
534
+ resolve({ success: false, reason: err.response });
535
+ } else {
536
+ reject(err);
537
+ }
538
+ }
539
+ });
540
+ }
541
+
466
542
  /**
467
543
  * Retrieves submissions for a specific form template.
468
544
  */
@@ -591,6 +667,107 @@ export class CMSManager extends BaseManager {
591
667
  });
592
668
  }
593
669
 
670
+ /**
671
+ * Retrieves the current active session for the specified server, if present.
672
+ */
673
+ public async getCurrentSession(serverId?: number): Promise<globalTypes.CMSGetCurrentSessionPromiseResult> {
674
+ const resolvedServerId = serverId ?? this.instance.cmsDefaultServerId;
675
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
676
+ throw new Error('serverId is required to get current session.');
677
+ }
678
+
679
+ return new Promise(async (resolve, reject) => {
680
+ try {
681
+ const response: any = await this.rest?.request('GET_CURRENT_SESSION', resolvedServerId);
682
+ resolve({ success: true, data: response ?? null });
683
+ } catch (err) {
684
+ if (err instanceof APIError) {
685
+ resolve({ success: false, reason: err.response });
686
+ } else {
687
+ reject(err);
688
+ }
689
+ }
690
+ });
691
+ }
692
+
693
+ /**
694
+ * Starts a new CMS session for the specified server.
695
+ */
696
+ public async startSession(serverId?: number, accId?: string): Promise<globalTypes.CMSStartSessionPromiseResult> {
697
+ const resolvedServerId = serverId ?? this.instance.cmsDefaultServerId;
698
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
699
+ throw new Error('serverId is required to start a session.');
700
+ }
701
+ if (!accId) {
702
+ throw new Error('accId is required to start a session.');
703
+ }
704
+
705
+ return new Promise(async (resolve, reject) => {
706
+ try {
707
+ const response: any = await this.rest?.request('START_SESSION', resolvedServerId, accId);
708
+ resolve({ success: true, data: response ?? null });
709
+ } catch (err) {
710
+ if (err instanceof APIError) {
711
+ resolve({ success: false, reason: err.response });
712
+ } else {
713
+ reject(err);
714
+ }
715
+ }
716
+ });
717
+ }
718
+
719
+ /**
720
+ * Stops the current CMS session for the specified server.
721
+ */
722
+ public async stopSession(serverId?: number, accId?: string): Promise<globalTypes.CMSStopSessionPromiseResult> {
723
+ const resolvedServerId = serverId ?? this.instance.cmsDefaultServerId;
724
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
725
+ throw new Error('serverId is required to stop a session.');
726
+ }
727
+ if (!accId) {
728
+ throw new Error('accId is required to stop a session.');
729
+ }
730
+
731
+ return new Promise(async (resolve, reject) => {
732
+ try {
733
+ const response: any = await this.rest?.request('STOP_SESSION', resolvedServerId, accId);
734
+ resolve({ success: true, data: response ?? null });
735
+ } catch (err) {
736
+ if (err instanceof APIError) {
737
+ resolve({ success: false, reason: err.response });
738
+ } else {
739
+ reject(err);
740
+ }
741
+ }
742
+ });
743
+ }
744
+
745
+ /**
746
+ * Cancels the current CMS session for the specified server.
747
+ */
748
+ public async cancelSession(serverId?: number, accId?: string): Promise<globalTypes.CMSCancelSessionPromiseResult> {
749
+ const resolvedServerId = serverId ?? this.instance.cmsDefaultServerId;
750
+ if (resolvedServerId === undefined || Number.isNaN(Number(resolvedServerId))) {
751
+ throw new Error('serverId is required to cancel a session.');
752
+ }
753
+ if (!accId) {
754
+ throw new Error('accId is required to cancel a session.');
755
+ }
756
+
757
+ return new Promise(async (resolve, reject) => {
758
+ try {
759
+ const response: any = await this.rest?.request('CANCEL_SESSION', resolvedServerId, accId);
760
+ resolve({ success: true, data: response ?? null });
761
+ } catch (err) {
762
+ if (err instanceof APIError) {
763
+ resolve({ success: false, reason: err.response });
764
+ } else {
765
+ reject(err);
766
+ }
767
+ }
768
+ });
769
+ }
770
+
594
771
  /**
595
772
  * Gets the current ERLC player queue count for the provided roblox join code.
596
773
  * @param {string} robloxJoinCode The roblox join code to get the player queue size for.