@sonoransoftware/sonoran.js 1.0.40 → 1.0.42

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,50 @@ 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 AccountActivityLog {
115
+ id: string;
116
+ status: boolean;
117
+ accId: string;
118
+ serverId: number;
119
+ start: string;
120
+ end: string | null;
121
+ clearReason: string | null;
122
+ metadata: Record<string, any>;
123
+ objKey: string;
124
+ }
125
+ export interface AccountClockInLog {
126
+ id: number;
127
+ startTime: string | null;
128
+ endTime: string | null;
129
+ completed: boolean;
130
+ notes: {
131
+ timestamp: string;
132
+ message: string;
133
+ }[];
134
+ type?: string;
135
+ objKey: string;
136
+ }
137
+ export interface CMSGetClockInTypesPromiseResult {
138
+ success: boolean;
139
+ reason?: string;
140
+ data?: CMSClockInType[];
141
+ }
142
+ export interface CMSGetLatestActivityPromiseResult {
143
+ success: boolean;
144
+ reason?: string;
145
+ data?: AccountClockInLog[] | AccountActivityLog[];
146
+ }
110
147
  export interface CMSClockInOutParams {
111
148
  accId?: string;
112
149
  apiId?: string;
113
150
  forceClockIn?: boolean;
151
+ discord?: string;
152
+ uniqueId?: string;
153
+ type?: string;
114
154
  }
115
155
  export interface CMSCheckComApiIdPromiseResult {
116
156
  success: boolean;
@@ -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': {
@@ -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,36 @@ 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
+ const data = response && typeof response === 'object' && 'data' in response ? response.data : response;
582
+ resolve({ success: true, data });
583
+ }
584
+ catch (err) {
585
+ if (err instanceof src_1.APIError) {
586
+ resolve({ success: false, reason: err.response });
587
+ }
588
+ else {
589
+ reject(err);
590
+ }
591
+ }
592
+ });
593
+ }
542
594
  /**
543
595
  * Gets the current clock in entry for a community member.
544
596
  * @param {Object} params Identification parameters for the account.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonoransoftware/sonoran.js",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
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
@@ -232,7 +232,7 @@ const getRanks = await instance.cms.getAccountRanks(params);
232
232
  ### clockInOut(obj)
233
233
  Clock a user in or out in the CMS system
234
234
  #### Arugment `obj`
235
- ##### Type `object` `{accId?: string, apiId?: string, forceClockIn?: boolean, discord?: string, uniqueId?: string}`
235
+ ##### Type `object` `{accId?: string, apiId?: string, forceClockIn?: boolean, discord?: string, uniqueId?: string, type?: string}`
236
236
  ```js
237
237
  const params = {
238
238
  accId: '',
@@ -240,11 +240,19 @@ const params = {
240
240
  forceClockIn: true,
241
241
  discord: '',
242
242
  uniqueId: '1234',
243
+ type: 'clockin-type-uuid'
243
244
  };
244
245
  // Clocks a user in or out
245
246
  const clock = await instance.cms.clockInOut(params);
246
247
  ```
247
248
 
249
+ ### getClockInTypes()
250
+ Returns the configured clock-in types.
251
+ ```js
252
+ const types = await instance.cms.getClockInTypes();
253
+ // [{ id: 'uuid', label: 'Patrol' }]
254
+ ```
255
+
248
256
  ### checkComApiId(apiId)
249
257
  Checks if a given API ID is attatched to any account within the community, and if true, returns the username of the associated account.
250
258
  #### Arugment `apiId`
@@ -327,6 +335,16 @@ Fetches the current clock-in entry for the account if one exists.
327
335
  const currentEntry = await instance.cms.getCurrentClockIn({ apiId: '1234' });
328
336
  ```
329
337
 
338
+ ### getLatestActivity(params)
339
+ Gets the latest clock-in or activity entries for an account.
340
+ ```js
341
+ // Clock-in history
342
+ const clockins = await instance.cms.getLatestActivity({ accId: 'account-uuid', type: 'clockin' });
343
+ // Activity history (requires serverId)
344
+ const activity = await instance.cms.getLatestActivity({ accId: 'account-uuid', type: 'activity', serverId: 1 });
345
+ ```
346
+ *Returns an array of clock-in logs (`AccountClockInLog`) or activity logs (`AccountActivityLog`); each item includes `objKey` alongside the other fields.*
347
+
330
348
  ### getAccounts(options)
331
349
  Retrieves CMS accounts with optional pagination and status filters.
332
350
  ```js
package/src/constants.ts CHANGED
@@ -122,10 +122,55 @@ 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 AccountActivityLog {
131
+ id: string;
132
+ status: boolean;
133
+ accId: string;
134
+ serverId: number;
135
+ start: string;
136
+ end: string | null;
137
+ clearReason: string | null;
138
+ metadata: Record<string, any>;
139
+ objKey: string;
140
+ }
141
+
142
+ export interface AccountClockInLog {
143
+ id: number;
144
+ startTime: string | null;
145
+ endTime: string | null;
146
+ completed: boolean;
147
+ notes: {
148
+ timestamp: string;
149
+ message: string;
150
+ }[];
151
+ type?: string;
152
+ objKey: string;
153
+ }
154
+
155
+ export interface CMSGetClockInTypesPromiseResult {
156
+ success: boolean;
157
+ reason?: string;
158
+ data?: CMSClockInType[];
159
+ }
160
+
161
+ export interface CMSGetLatestActivityPromiseResult {
162
+ success: boolean;
163
+ reason?: string;
164
+ data?: AccountClockInLog[] | AccountActivityLog[];
165
+ }
166
+
125
167
  export interface CMSClockInOutParams {
126
168
  accId?: string;
127
169
  apiId?: string;
128
170
  forceClockIn?: boolean;
171
+ discord?: string;
172
+ uniqueId?: string;
173
+ type?: string;
129
174
  }
130
175
 
131
176
  export interface CMSCheckComApiIdPromiseResult {
@@ -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': {
@@ -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,35 @@ 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
+ const data = response && typeof response === 'object' && 'data' in response ? (response as any).data : response;
524
+ resolve({ success: true, data });
525
+ } catch (err) {
526
+ if (err instanceof APIError) {
527
+ resolve({ success: false, reason: err.response });
528
+ } else {
529
+ reject(err);
530
+ }
531
+ }
532
+ });
533
+ }
534
+
486
535
  /**
487
536
  * Gets the current clock in entry for a community member.
488
537
  * @param {Object} params Identification parameters for the account.