@sonoransoftware/sonoran.js 1.0.39 → 1.0.41

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.
@@ -107,10 +107,27 @@ export interface CMSClockInOutPromiseResult {
107
107
  reason?: string;
108
108
  clockedIn?: boolean;
109
109
  }
110
+ export interface CMSClockInType {
111
+ id: string;
112
+ label: string;
113
+ }
114
+ export interface CMSGetClockInTypesPromiseResult {
115
+ success: boolean;
116
+ reason?: string;
117
+ data?: CMSClockInType[];
118
+ }
119
+ export interface CMSGetLatestActivityPromiseResult {
120
+ success: boolean;
121
+ reason?: string;
122
+ data?: string | null;
123
+ }
110
124
  export interface CMSClockInOutParams {
111
125
  accId?: string;
112
126
  apiId?: string;
113
127
  forceClockIn?: boolean;
128
+ discord?: string;
129
+ uniqueId?: string;
130
+ type?: string;
114
131
  }
115
132
  export interface CMSCheckComApiIdPromiseResult {
116
133
  success: boolean;
@@ -395,7 +412,7 @@ export interface CMSERLCAddNewRecordPromiseResult {
395
412
  logId?: string;
396
413
  }
397
414
  export interface CMSERLCExecuteCommandPayload {
398
- serverId: string;
415
+ robloxJoinCode: string;
399
416
  type: string;
400
417
  args: unknown;
401
418
  discordId: string | number;
@@ -118,6 +118,21 @@ class REST extends events_1.EventEmitter {
118
118
  uniqueId: args[4]
119
119
  };
120
120
  }
121
+ case 'GET_CLOCKIN_TYPES': {
122
+ return {};
123
+ }
124
+ case 'GET_LATEST_ACTIVITY': {
125
+ const payload = args[0];
126
+ if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
127
+ return payload;
128
+ }
129
+ return {
130
+ accId: args[0],
131
+ type: args[1],
132
+ serverId: args[2],
133
+ clockInType: args[3]
134
+ };
135
+ }
121
136
  case 'GET_ACCOUNTS': {
122
137
  return (_b = args[0]) !== null && _b !== void 0 ? _b : {};
123
138
  }
@@ -168,12 +183,16 @@ class REST extends events_1.EventEmitter {
168
183
  };
169
184
  }
170
185
  case 'CLOCK_IN_OUT': {
186
+ if (args[0] && typeof args[0] === 'object' && !Array.isArray(args[0])) {
187
+ return args[0];
188
+ }
171
189
  return {
172
190
  apiId: args[0],
173
191
  accId: args[1],
174
192
  forceClockIn: args[2],
175
193
  discord: args[3],
176
- uniqueId: args[4]
194
+ uniqueId: args[4],
195
+ type: args[5]
177
196
  };
178
197
  }
179
198
  case 'CHECK_COM_APIID': {
@@ -306,13 +325,13 @@ class REST extends events_1.EventEmitter {
306
325
  throw new Error('ERLC_EXECUTE_COMMAND requires an array of command payloads.');
307
326
  }
308
327
  return payload.map((cmd) => {
309
- const serverId = cmd.serverId;
310
- if (typeof serverId !== 'string' || serverId.length === 0) {
311
- throw new Error('ERLC_EXECUTE_COMMAND requires each command to include a valid serverId.');
328
+ const robloxJoinCode = cmd.robloxJoinCode;
329
+ if (typeof robloxJoinCode !== 'string' || robloxJoinCode.length === 0) {
330
+ throw new Error('ERLC_EXECUTE_COMMAND requires each command to include a valid robloxJoinCode.');
312
331
  }
313
332
  return {
314
333
  ...cmd,
315
- serverId
334
+ robloxJoinCode
316
335
  };
317
336
  });
318
337
  }
@@ -101,6 +101,10 @@ class RequestManager extends events_1.EventEmitter {
101
101
  apiData.data.data = [];
102
102
  break;
103
103
  }
104
+ case 'GET_CLOCKIN_TYPES': {
105
+ apiData.data.data = [];
106
+ break;
107
+ }
104
108
  case 'ERLC_EXECUTE_COMMAND': {
105
109
  apiData.data.data = clonedData;
106
110
  break;
@@ -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_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' | '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_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';
42
42
  export interface CMSServerAPIStruct {
43
43
  id: number;
44
44
  name: string;
@@ -428,6 +428,15 @@ export interface RESTTypedAPIDataStructs {
428
428
  discord?: string,
429
429
  uniqueId?: string
430
430
  ];
431
+ GET_CLOCKIN_TYPES: [];
432
+ GET_LATEST_ACTIVITY: [
433
+ data: {
434
+ accId: string;
435
+ type: 'clockin' | 'activity';
436
+ serverId?: number;
437
+ clockInType?: string;
438
+ }
439
+ ];
431
440
  GET_ACCOUNTS: [
432
441
  options?: {
433
442
  skip?: number;
@@ -445,7 +454,8 @@ export interface RESTTypedAPIDataStructs {
445
454
  accId?: string,
446
455
  forceClockIn?: boolean,
447
456
  discord?: string,
448
- uniqueId?: string
457
+ uniqueId?: string,
458
+ type?: string
449
459
  ];
450
460
  GET_DEPARTMENTS: [];
451
461
  GET_ACCOUNT_RANKS: [
@@ -684,8 +694,17 @@ export type PossibleRequestData = undefined | {
684
694
  apiId: string;
685
695
  serverId: number;
686
696
  } | {
687
- apiId: string;
688
- forceClockIn: boolean;
697
+ apiId?: string;
698
+ accId?: string;
699
+ forceClockIn?: boolean;
700
+ discord?: string;
701
+ uniqueId?: string;
702
+ type?: string;
703
+ } | {
704
+ accId: string;
705
+ type: 'clockin' | 'activity';
706
+ serverId?: number;
707
+ clockInType?: string;
689
708
  } | {
690
709
  accountId: string;
691
710
  set?: {
@@ -346,6 +346,18 @@ exports.GeneralCMSAPITypes = [
346
346
  method: 'POST',
347
347
  minVersion: 0
348
348
  },
349
+ {
350
+ type: 'GET_CLOCKIN_TYPES',
351
+ path: 'general/get_clockin_types',
352
+ method: 'POST',
353
+ minVersion: 0
354
+ },
355
+ {
356
+ type: 'GET_LATEST_ACTIVITY',
357
+ path: 'general/get_latest_activity',
358
+ method: 'POST',
359
+ minVersion: 0
360
+ },
349
361
  {
350
362
  type: 'GET_ACCOUNTS',
351
363
  path: 'general/get_accounts',
@@ -78,15 +78,15 @@ export declare class CMSManager extends BaseManager {
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
80
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
81
+ * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
82
+ * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
81
83
  * @returns {Promise} Promise object represents if the request was successful with reason for failure if needed.
82
84
  */
83
- clockInOut(data: {
84
- accId?: string;
85
- apiId?: string;
86
- forceClockIn?: boolean;
87
- discord?: string;
88
- uniqueId?: string;
89
- }): Promise<globalTypes.CMSClockInOutPromiseResult>;
85
+ clockInOut(data: globalTypes.CMSClockInOutParams): Promise<globalTypes.CMSClockInOutPromiseResult>;
86
+ /**
87
+ * Retrieves configured clock-in types for the community.
88
+ */
89
+ getClockInTypes(): Promise<globalTypes.CMSGetClockInTypesPromiseResult>;
90
90
  /**
91
91
  * Check if a given [apiId] is attached to any account within the community CMS.
92
92
  * @param {string} apiId The api id to check for an account.
@@ -228,6 +228,15 @@ export declare class CMSManager extends BaseManager {
228
228
  uniqueId?: string;
229
229
  profileFields: globalTypes.CMSProfileFieldUpdate[];
230
230
  }): Promise<globalTypes.CMSEditAccountProfileFieldsPromiseResult>;
231
+ /**
232
+ * Gets the latest clock-in or activity timestamp for the provided account.
233
+ */
234
+ getLatestActivity(params: {
235
+ accId: string;
236
+ type: 'clockin' | 'activity';
237
+ serverId?: number;
238
+ clockInType?: string;
239
+ }): Promise<globalTypes.CMSGetLatestActivityPromiseResult>;
231
240
  /**
232
241
  * Gets the current clock in entry for a community member.
233
242
  * @param {Object} params Identification parameters for the account.
@@ -177,13 +177,15 @@ class CMSManager extends BaseManager_1.BaseManager {
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
179
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
180
+ * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
181
+ * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
180
182
  * @returns {Promise} Promise object represents if the request was successful with reason for failure if needed.
181
183
  */
182
184
  async clockInOut(data) {
183
185
  return new Promise(async (resolve, reject) => {
184
186
  var _a;
185
187
  try {
186
- 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));
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));
187
189
  const clockInOutResponse = clockInOutRequest;
188
190
  if (!clockInOutResponse)
189
191
  resolve({ success: false, reason: clockInOutRequest });
@@ -199,6 +201,26 @@ class CMSManager extends BaseManager_1.BaseManager {
199
201
  }
200
202
  });
201
203
  }
204
+ /**
205
+ * Retrieves configured clock-in types for the community.
206
+ */
207
+ async getClockInTypes() {
208
+ return new Promise(async (resolve, reject) => {
209
+ var _a;
210
+ try {
211
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('GET_CLOCKIN_TYPES'));
212
+ resolve({ success: true, data: response });
213
+ }
214
+ catch (err) {
215
+ if (err instanceof src_1.APIError) {
216
+ resolve({ success: false, reason: err.response });
217
+ }
218
+ else {
219
+ reject(err);
220
+ }
221
+ }
222
+ });
223
+ }
202
224
  /**
203
225
  * Check if a given [apiId] is attached to any account within the community CMS.
204
226
  * @param {string} apiId The api id to check for an account.
@@ -539,6 +561,35 @@ class CMSManager extends BaseManager_1.BaseManager {
539
561
  }
540
562
  });
541
563
  }
564
+ /**
565
+ * Gets the latest clock-in or activity timestamp for the provided account.
566
+ */
567
+ async getLatestActivity(params) {
568
+ if (!(params === null || params === void 0 ? void 0 : params.accId)) {
569
+ throw new Error('accId is required to get latest activity.');
570
+ }
571
+ if (params.type !== 'clockin' && params.type !== 'activity') {
572
+ throw new Error('type must be either "clockin" or "activity".');
573
+ }
574
+ if (params.type === 'activity' && params.serverId === undefined) {
575
+ throw new Error('serverId is required when type is "activity".');
576
+ }
577
+ return new Promise(async (resolve, reject) => {
578
+ var _a;
579
+ try {
580
+ const response = await ((_a = this.rest) === null || _a === void 0 ? void 0 : _a.request('GET_LATEST_ACTIVITY', params));
581
+ resolve({ success: true, data: response });
582
+ }
583
+ catch (err) {
584
+ if (err instanceof src_1.APIError) {
585
+ resolve({ success: false, reason: err.response });
586
+ }
587
+ else {
588
+ reject(err);
589
+ }
590
+ }
591
+ });
592
+ }
542
593
  /**
543
594
  * Gets the current clock in entry for a community member.
544
595
  * @param {Object} params Identification parameters for the account.
@@ -639,15 +690,15 @@ class CMSManager extends BaseManager_1.BaseManager {
639
690
  const args = cmd.args;
640
691
  const discordId = cmd.discordId;
641
692
  const includesPlayerNameOrId = cmd.includesPlayerNameOrId;
642
- const serverId = cmd.serverId;
693
+ const robloxJoinCode = cmd.robloxJoinCode;
643
694
  if (!type) {
644
695
  throw new Error('Each ERLC command requires a type.');
645
696
  }
646
697
  if (!discordId) {
647
698
  throw new Error('Each ERLC command requires a discordId.');
648
699
  }
649
- if (typeof serverId !== 'string' || serverId.length === 0) {
650
- throw new Error('Each ERLC command requires a serverId.');
700
+ if (typeof robloxJoinCode !== 'string' || robloxJoinCode.length === 0) {
701
+ throw new Error('Each ERLC command requires a robloxJoinCode.');
651
702
  }
652
703
  return {
653
704
  ...cmd,
@@ -655,7 +706,7 @@ class CMSManager extends BaseManager_1.BaseManager {
655
706
  args,
656
707
  discordId,
657
708
  includesPlayerNameOrId,
658
- serverId,
709
+ robloxJoinCode,
659
710
  };
660
711
  });
661
712
  return new Promise(async (resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonoransoftware/sonoran.js",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
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/src/constants.ts CHANGED
@@ -122,10 +122,30 @@ export interface CMSClockInOutPromiseResult {
122
122
  clockedIn?: boolean;
123
123
  }
124
124
 
125
+ export interface CMSClockInType {
126
+ id: string;
127
+ label: string;
128
+ }
129
+
130
+ export interface CMSGetClockInTypesPromiseResult {
131
+ success: boolean;
132
+ reason?: string;
133
+ data?: CMSClockInType[];
134
+ }
135
+
136
+ export interface CMSGetLatestActivityPromiseResult {
137
+ success: boolean;
138
+ reason?: string;
139
+ data?: string | null;
140
+ }
141
+
125
142
  export interface CMSClockInOutParams {
126
143
  accId?: string;
127
144
  apiId?: string;
128
145
  forceClockIn?: boolean;
146
+ discord?: string;
147
+ uniqueId?: string;
148
+ type?: string;
129
149
  }
130
150
 
131
151
  export interface CMSCheckComApiIdPromiseResult {
@@ -444,7 +464,7 @@ export interface CMSERLCAddNewRecordPromiseResult {
444
464
  }
445
465
 
446
466
  export interface CMSERLCExecuteCommandPayload {
447
- serverId: string;
467
+ robloxJoinCode: string;
448
468
  type: string;
449
469
  args: unknown;
450
470
  discordId: string | number;
@@ -224,6 +224,21 @@ export class REST extends EventEmitter {
224
224
  uniqueId: args[4]
225
225
  };
226
226
  }
227
+ case 'GET_CLOCKIN_TYPES': {
228
+ return {};
229
+ }
230
+ case 'GET_LATEST_ACTIVITY': {
231
+ const payload = args[0];
232
+ if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
233
+ return payload;
234
+ }
235
+ return {
236
+ accId: args[0],
237
+ type: args[1],
238
+ serverId: args[2],
239
+ clockInType: args[3]
240
+ };
241
+ }
227
242
  case 'GET_ACCOUNTS': {
228
243
  return args[0] ?? {};
229
244
  }
@@ -272,12 +287,16 @@ export class REST extends EventEmitter {
272
287
  };
273
288
  }
274
289
  case 'CLOCK_IN_OUT': {
290
+ if (args[0] && typeof args[0] === 'object' && !Array.isArray(args[0])) {
291
+ return args[0];
292
+ }
275
293
  return {
276
294
  apiId: args[0],
277
295
  accId: args[1],
278
296
  forceClockIn: args[2],
279
297
  discord: args[3],
280
- uniqueId: args[4]
298
+ uniqueId: args[4],
299
+ type: args[5]
281
300
  };
282
301
  }
283
302
  case 'CHECK_COM_APIID': {
@@ -410,13 +429,13 @@ export class REST extends EventEmitter {
410
429
  throw new Error('ERLC_EXECUTE_COMMAND requires an array of command payloads.');
411
430
  }
412
431
  return payload.map((cmd) => {
413
- const serverId = cmd.serverId;
414
- if (typeof serverId !== 'string' || serverId.length === 0) {
415
- throw new Error('ERLC_EXECUTE_COMMAND requires each command to include a valid serverId.');
432
+ const robloxJoinCode = cmd.robloxJoinCode;
433
+ if (typeof robloxJoinCode !== 'string' || robloxJoinCode.length === 0) {
434
+ throw new Error('ERLC_EXECUTE_COMMAND requires each command to include a valid robloxJoinCode.');
416
435
  }
417
436
  return {
418
437
  ...cmd,
419
- serverId
438
+ robloxJoinCode
420
439
  };
421
440
  });
422
441
  }
@@ -174,6 +174,10 @@ export class RequestManager extends EventEmitter {
174
174
  apiData.data.data = [];
175
175
  break;
176
176
  }
177
+ case 'GET_CLOCKIN_TYPES': {
178
+ apiData.data.data = [];
179
+ break;
180
+ }
177
181
  case 'ERLC_EXECUTE_COMMAND': {
178
182
  apiData.data.data = clonedData;
179
183
  break;
@@ -378,6 +378,18 @@ export const GeneralCMSAPITypes: APITypeData[] = [
378
378
  method: 'POST', // Would've been 'GET' but fetch doesn't allow body with GET requests.
379
379
  minVersion: 0
380
380
  },
381
+ {
382
+ type: 'GET_CLOCKIN_TYPES',
383
+ path: 'general/get_clockin_types',
384
+ method: 'POST',
385
+ minVersion: 0
386
+ },
387
+ {
388
+ type: 'GET_LATEST_ACTIVITY',
389
+ path: 'general/get_latest_activity',
390
+ method: 'POST',
391
+ minVersion: 0
392
+ },
381
393
  {
382
394
  type: 'GET_ACCOUNTS',
383
395
  path: 'general/get_accounts',
@@ -625,7 +637,7 @@ function formatForAll(array: APITypeData[], product: productEnums): AllAPITypeDa
625
637
 
626
638
  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) ];
627
639
 
628
- 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' | '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';
640
+ 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_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';
629
641
 
630
642
  export interface CMSServerAPIStruct {
631
643
  id: number;
@@ -1046,6 +1058,15 @@ export interface RESTTypedAPIDataStructs {
1046
1058
  discord?: string,
1047
1059
  uniqueId?: string
1048
1060
  ];
1061
+ GET_CLOCKIN_TYPES: [];
1062
+ GET_LATEST_ACTIVITY: [
1063
+ data: {
1064
+ accId: string,
1065
+ type: 'clockin' | 'activity',
1066
+ serverId?: number,
1067
+ clockInType?: string,
1068
+ }
1069
+ ];
1049
1070
  GET_ACCOUNTS: [
1050
1071
  options?: {
1051
1072
  skip?: number,
@@ -1063,7 +1084,8 @@ export interface RESTTypedAPIDataStructs {
1063
1084
  accId?: string,
1064
1085
  forceClockIn?: boolean,
1065
1086
  discord?: string,
1066
- uniqueId?: string
1087
+ uniqueId?: string,
1088
+ type?: string
1067
1089
  ];
1068
1090
  GET_DEPARTMENTS: [];
1069
1091
  GET_ACCOUNT_RANKS: [
@@ -1335,8 +1357,18 @@ export type PossibleRequestData =
1335
1357
  serverId: number;
1336
1358
  } |
1337
1359
  {
1338
- apiId: string;
1339
- forceClockIn: boolean;
1360
+ apiId?: string;
1361
+ accId?: string;
1362
+ forceClockIn?: boolean;
1363
+ discord?: string;
1364
+ uniqueId?: string;
1365
+ type?: string;
1366
+ } |
1367
+ {
1368
+ accId: string;
1369
+ type: 'clockin' | 'activity';
1370
+ serverId?: number;
1371
+ clockInType?: string;
1340
1372
  } |
1341
1373
  {
1342
1374
  accountId: string,
@@ -150,12 +150,14 @@ export class CMSManager extends BaseManager {
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
152
  * @param {string} [data.discord] (Optional) The discord ID to clock in or out.
153
+ * @param {string} [data.uniqueId] (Optional) The unique ID to clock in or out.
154
+ * @param {string} [data.type] (Optional) The UUID of a specific clock-in type to use.
153
155
  * @returns {Promise} Promise object represents if the request was successful with reason for failure if needed.
154
156
  */
155
- public async clockInOut(data: { accId?: string, apiId?: string, forceClockIn?: boolean, discord?: string, uniqueId?: string }): Promise<globalTypes.CMSClockInOutPromiseResult> {
157
+ public async clockInOut(data: globalTypes.CMSClockInOutParams): Promise<globalTypes.CMSClockInOutPromiseResult> {
156
158
  return new Promise(async (resolve, reject) => {
157
159
  try {
158
- const clockInOutRequest = await this.rest?.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId);
160
+ const clockInOutRequest = await this.rest?.request('CLOCK_IN_OUT', data.apiId, data.accId, !!data.forceClockIn, data.discord, data.uniqueId, data.type);
159
161
  const clockInOutResponse = clockInOutRequest as globalTypes.clockInOutRequest;
160
162
  if (!clockInOutResponse) resolve({ success: false, reason: clockInOutRequest as string });
161
163
  resolve({ success: true, clockedIn: clockInOutResponse.completed });
@@ -169,6 +171,24 @@ export class CMSManager extends BaseManager {
169
171
  });
170
172
  }
171
173
 
174
+ /**
175
+ * Retrieves configured clock-in types for the community.
176
+ */
177
+ public async getClockInTypes(): Promise<globalTypes.CMSGetClockInTypesPromiseResult> {
178
+ return new Promise(async (resolve, reject) => {
179
+ try {
180
+ const response: any = await this.rest?.request('GET_CLOCKIN_TYPES');
181
+ resolve({ success: true, data: response });
182
+ } catch (err) {
183
+ if (err instanceof APIError) {
184
+ resolve({ success: false, reason: err.response });
185
+ } else {
186
+ reject(err);
187
+ }
188
+ }
189
+ });
190
+ }
191
+
172
192
  /**
173
193
  * Check if a given [apiId] is attached to any account within the community CMS.
174
194
  * @param {string} apiId The api id to check for an account.
@@ -483,6 +503,34 @@ export class CMSManager extends BaseManager {
483
503
  });
484
504
  }
485
505
 
506
+ /**
507
+ * Gets the latest clock-in or activity timestamp for the provided account.
508
+ */
509
+ public async getLatestActivity(params: { accId: string, type: 'clockin' | 'activity', serverId?: number, clockInType?: string }): Promise<globalTypes.CMSGetLatestActivityPromiseResult> {
510
+ if (!params?.accId) {
511
+ throw new Error('accId is required to get latest activity.');
512
+ }
513
+ if (params.type !== 'clockin' && params.type !== 'activity') {
514
+ throw new Error('type must be either "clockin" or "activity".');
515
+ }
516
+ if (params.type === 'activity' && params.serverId === undefined) {
517
+ throw new Error('serverId is required when type is "activity".');
518
+ }
519
+
520
+ return new Promise(async (resolve, reject) => {
521
+ try {
522
+ const response: any = await this.rest?.request('GET_LATEST_ACTIVITY', params);
523
+ resolve({ success: true, data: response });
524
+ } catch (err) {
525
+ if (err instanceof APIError) {
526
+ resolve({ success: false, reason: err.response });
527
+ } else {
528
+ reject(err);
529
+ }
530
+ }
531
+ });
532
+ }
533
+
486
534
  /**
487
535
  * Gets the current clock in entry for a community member.
488
536
  * @param {Object} params Identification parameters for the account.
@@ -575,7 +623,7 @@ export class CMSManager extends BaseManager {
575
623
  const args = cmd.args;
576
624
  const discordId = cmd.discordId;
577
625
  const includesPlayerNameOrId = cmd.includesPlayerNameOrId;
578
- const serverId = cmd.serverId;
626
+ const robloxJoinCode = cmd.robloxJoinCode;
579
627
 
580
628
  if (!type) {
581
629
  throw new Error('Each ERLC command requires a type.');
@@ -583,8 +631,8 @@ export class CMSManager extends BaseManager {
583
631
  if (!discordId) {
584
632
  throw new Error('Each ERLC command requires a discordId.');
585
633
  }
586
- if (typeof serverId !== 'string' || serverId.length === 0) {
587
- throw new Error('Each ERLC command requires a serverId.');
634
+ if (typeof robloxJoinCode !== 'string' || robloxJoinCode.length === 0) {
635
+ throw new Error('Each ERLC command requires a robloxJoinCode.');
588
636
  }
589
637
 
590
638
  return {
@@ -593,7 +641,7 @@ export class CMSManager extends BaseManager {
593
641
  args,
594
642
  discordId,
595
643
  includesPlayerNameOrId,
596
- serverId,
644
+ robloxJoinCode,
597
645
  };
598
646
  });
599
647