homebridge-adt-pulse 3.0.0-beta.3 → 3.0.0-beta.5
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.
- package/build/config.schema.json +237 -0
- package/build/src/index.js +6 -0
- package/build/src/index.js.map +1 -0
- package/build/src/lib/accessory.js +216 -0
- package/build/src/lib/accessory.js.map +1 -0
- package/build/src/lib/api.js +1876 -0
- package/build/src/lib/api.js.map +1 -0
- package/build/src/lib/detect.js +443 -0
- package/build/src/lib/detect.js.map +1 -0
- package/build/src/lib/platform.js +419 -0
- package/build/src/lib/platform.js.map +1 -0
- package/{src/lib/regex.ts → build/src/lib/regex.js} +1 -143
- package/build/src/lib/regex.js.map +1 -0
- package/build/src/lib/schema.js +29 -0
- package/build/src/lib/schema.js.map +1 -0
- package/build/src/lib/utility.js +434 -0
- package/build/src/lib/utility.js.map +1 -0
- package/build/src/scripts/repl.js +173 -0
- package/build/src/scripts/repl.js.map +1 -0
- package/build/src/scripts/test-api.js +171 -0
- package/build/src/scripts/test-api.js.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +0 -18
- package/src/lib/accessory.ts +0 -405
- package/src/lib/api.ts +0 -3483
- package/src/lib/detect.ts +0 -728
- package/src/lib/platform.ts +0 -890
- package/src/lib/schema.ts +0 -34
- package/src/lib/utility.ts +0 -933
- package/src/scripts/repl.ts +0 -300
- package/src/scripts/test-api.ts +0 -278
- package/src/types/constant.d.ts +0 -308
- package/src/types/index.d.ts +0 -1472
- package/src/types/shared.d.ts +0 -517
package/src/lib/utility.ts
DELETED
|
@@ -1,933 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { Categories } from 'homebridge';
|
|
3
|
-
import { JSDOM } from 'jsdom';
|
|
4
|
-
import _ from 'lodash';
|
|
5
|
-
import { createHash } from 'node:crypto';
|
|
6
|
-
import os from 'node:os';
|
|
7
|
-
import util from 'node:util';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
characterBackslashForwardSlash,
|
|
11
|
-
characterHtmlLineBreak,
|
|
12
|
-
characterWhitespace,
|
|
13
|
-
functionDoSubmit,
|
|
14
|
-
functionGoToUrl,
|
|
15
|
-
functionSetArmState,
|
|
16
|
-
paramSat,
|
|
17
|
-
textOrbSensorZone,
|
|
18
|
-
textOrbTextSummary,
|
|
19
|
-
textSyncCode,
|
|
20
|
-
} from '@/lib/regex.js';
|
|
21
|
-
import type {
|
|
22
|
-
ClearHtmlLineBreakData,
|
|
23
|
-
ClearHtmlLineBreakReturns,
|
|
24
|
-
ClearWhitespaceData,
|
|
25
|
-
ClearWhitespaceReturns,
|
|
26
|
-
CondenseSensorTypeCondensed,
|
|
27
|
-
CondenseSensorTypeReturns,
|
|
28
|
-
CondenseSensorTypeSensorType,
|
|
29
|
-
DebugLogCaller,
|
|
30
|
-
DebugLogLogger,
|
|
31
|
-
DebugLogMessage,
|
|
32
|
-
DebugLogReturns,
|
|
33
|
-
DebugLogType,
|
|
34
|
-
FetchErrorMessageResponse,
|
|
35
|
-
FetchErrorMessageReturns,
|
|
36
|
-
FetchMissingSatCodeResponse,
|
|
37
|
-
FetchMissingSatCodeReturns,
|
|
38
|
-
FetchTableCellsIncrementFrom,
|
|
39
|
-
FetchTableCellsIncrementTo,
|
|
40
|
-
FetchTableCellsMatched,
|
|
41
|
-
FetchTableCellsMatchList,
|
|
42
|
-
FetchTableCellsNodeElements,
|
|
43
|
-
FetchTableCellsReturns,
|
|
44
|
-
FindIndexWithValueArray,
|
|
45
|
-
FindIndexWithValueCondition,
|
|
46
|
-
FindIndexWithValueReturns,
|
|
47
|
-
FindNullKeysFound,
|
|
48
|
-
FindNullKeysParentKey,
|
|
49
|
-
FindNullKeysProperties,
|
|
50
|
-
FindNullKeysReturns,
|
|
51
|
-
GenerateDeviceIdId,
|
|
52
|
-
GenerateDeviceIdReturns,
|
|
53
|
-
GenerateDynatracePCHeaderValueMode,
|
|
54
|
-
GenerateDynatracePCHeaderValueReturns,
|
|
55
|
-
GenerateHashData,
|
|
56
|
-
GenerateHashReturns,
|
|
57
|
-
GetAccessoryCategoryDeviceCategory,
|
|
58
|
-
GetAccessoryCategoryReturns,
|
|
59
|
-
GetPluralFormCount,
|
|
60
|
-
GetPluralFormPlural,
|
|
61
|
-
GetPluralFormReturns,
|
|
62
|
-
GetPluralFormSingular,
|
|
63
|
-
IsForwardSlashOSReturns,
|
|
64
|
-
IsPortalSyncCodeSyncCode,
|
|
65
|
-
IsPortalSyncCodeVerifiedSyncCode,
|
|
66
|
-
ParseArmDisarmMessageElement,
|
|
67
|
-
ParseArmDisarmMessageReturns,
|
|
68
|
-
ParseDoSubmitHandlersElements,
|
|
69
|
-
ParseDoSubmitHandlersHandlers,
|
|
70
|
-
ParseDoSubmitHandlersRelativeUrl,
|
|
71
|
-
ParseDoSubmitHandlersReturns,
|
|
72
|
-
ParseDoSubmitHandlersUrlParamsArm,
|
|
73
|
-
ParseDoSubmitHandlersUrlParamsArmState,
|
|
74
|
-
ParseDoSubmitHandlersUrlParamsHref,
|
|
75
|
-
ParseOrbSecurityButtonsArm,
|
|
76
|
-
ParseOrbSecurityButtonsArmState,
|
|
77
|
-
ParseOrbSecurityButtonsButtonId,
|
|
78
|
-
ParseOrbSecurityButtonsButtons,
|
|
79
|
-
ParseOrbSecurityButtonsElements,
|
|
80
|
-
ParseOrbSecurityButtonsHref,
|
|
81
|
-
ParseOrbSecurityButtonsLoadingText,
|
|
82
|
-
ParseOrbSecurityButtonsPendingButtonText,
|
|
83
|
-
ParseOrbSecurityButtonsReadyButtonText,
|
|
84
|
-
ParseOrbSecurityButtonsRelativeUrl,
|
|
85
|
-
ParseOrbSecurityButtonsReturns,
|
|
86
|
-
ParseOrbSensorsCleanedIcon,
|
|
87
|
-
ParseOrbSensorsCleanedStatus,
|
|
88
|
-
ParseOrbSensorsElements,
|
|
89
|
-
ParseOrbSensorsReturns,
|
|
90
|
-
ParseOrbSensorsSensors,
|
|
91
|
-
ParseOrbSensorsTableDeviceType,
|
|
92
|
-
ParseOrbSensorsTableElements,
|
|
93
|
-
ParseOrbSensorsTableReturns,
|
|
94
|
-
ParseOrbSensorsTableSensors,
|
|
95
|
-
ParseOrbSensorsTableStatus,
|
|
96
|
-
ParseOrbTextSummaryCurrentState,
|
|
97
|
-
ParseOrbTextSummaryCurrentStatus,
|
|
98
|
-
ParseOrbTextSummaryElement,
|
|
99
|
-
ParseOrbTextSummaryReturns,
|
|
100
|
-
RemovePersonalIdentifiableInformationData,
|
|
101
|
-
RemovePersonalIdentifiableInformationModifiedObject,
|
|
102
|
-
RemovePersonalIdentifiableInformationReplaceValueObject,
|
|
103
|
-
RemovePersonalIdentifiableInformationReplaceValueReturns,
|
|
104
|
-
RemovePersonalIdentifiableInformationReturns,
|
|
105
|
-
SleepMilliseconds,
|
|
106
|
-
SleepReturns,
|
|
107
|
-
StackTracerError,
|
|
108
|
-
StackTracerReturns,
|
|
109
|
-
StackTracerType,
|
|
110
|
-
} from '@/types/index.d.ts';
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Clear html line break.
|
|
114
|
-
*
|
|
115
|
-
* @param {ClearHtmlLineBreakData} data - Data.
|
|
116
|
-
*
|
|
117
|
-
* @returns {ClearHtmlLineBreakReturns}
|
|
118
|
-
*
|
|
119
|
-
* @since 1.0.0
|
|
120
|
-
*/
|
|
121
|
-
export function clearHtmlLineBreak(data: ClearHtmlLineBreakData): ClearHtmlLineBreakReturns {
|
|
122
|
-
return data.replace(characterHtmlLineBreak, ' ').trim();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Clear whitespace.
|
|
127
|
-
*
|
|
128
|
-
* @param {ClearWhitespaceData} data - Data.
|
|
129
|
-
*
|
|
130
|
-
* @returns {ClearWhitespaceReturns}
|
|
131
|
-
*
|
|
132
|
-
* @since 1.0.0
|
|
133
|
-
*/
|
|
134
|
-
export function clearWhitespace(data: ClearWhitespaceData): ClearWhitespaceReturns {
|
|
135
|
-
return data.replace(characterWhitespace, ' ').trim();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Condense sensor type.
|
|
140
|
-
*
|
|
141
|
-
* @param {CondenseSensorTypeSensorType} sensorType - Sensor type.
|
|
142
|
-
*
|
|
143
|
-
* @returns {CondenseSensorTypeReturns}
|
|
144
|
-
*
|
|
145
|
-
* @since 1.0.0
|
|
146
|
-
*/
|
|
147
|
-
export function condenseSensorType(sensorType: CondenseSensorTypeSensorType): CondenseSensorTypeReturns {
|
|
148
|
-
let condensed: CondenseSensorTypeCondensed;
|
|
149
|
-
|
|
150
|
-
switch (sensorType) {
|
|
151
|
-
case 'Door Sensor':
|
|
152
|
-
case 'Window Sensor':
|
|
153
|
-
case 'Door/Window Sensor':
|
|
154
|
-
condensed = 'doorWindow';
|
|
155
|
-
break;
|
|
156
|
-
case 'Motion Sensor':
|
|
157
|
-
case 'Motion Sensor (Notable Events Only)':
|
|
158
|
-
condensed = 'motion';
|
|
159
|
-
break;
|
|
160
|
-
case 'Glass Break Detector':
|
|
161
|
-
condensed = 'glass';
|
|
162
|
-
break;
|
|
163
|
-
case 'Fire (Smoke/Heat) Detector':
|
|
164
|
-
condensed = 'fire';
|
|
165
|
-
break;
|
|
166
|
-
case 'Carbon Monoxide Detector':
|
|
167
|
-
condensed = 'co';
|
|
168
|
-
break;
|
|
169
|
-
case 'Water/Flood Sensor':
|
|
170
|
-
condensed = 'flood';
|
|
171
|
-
break;
|
|
172
|
-
case 'Temperature Sensor':
|
|
173
|
-
condensed = 'temperature';
|
|
174
|
-
break;
|
|
175
|
-
default:
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return condensed;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Debug log.
|
|
184
|
-
*
|
|
185
|
-
* @param {DebugLogLogger} logger - Logger.
|
|
186
|
-
* @param {DebugLogCaller} caller - Caller.
|
|
187
|
-
* @param {DebugLogType} type - Type.
|
|
188
|
-
* @param {DebugLogMessage} message - Message.
|
|
189
|
-
*
|
|
190
|
-
* @returns {DebugLogReturns}
|
|
191
|
-
*
|
|
192
|
-
* @since 1.0.0
|
|
193
|
-
*/
|
|
194
|
-
export function debugLog(logger: DebugLogLogger, caller: DebugLogCaller, type: DebugLogType, message: DebugLogMessage): DebugLogReturns {
|
|
195
|
-
const logMessage = chalk.reset(chalk.underline(caller), '-', message, '...');
|
|
196
|
-
|
|
197
|
-
switch (type) {
|
|
198
|
-
case 'error':
|
|
199
|
-
if (logger !== null) {
|
|
200
|
-
logger.error(chalk.gray('DEBUG'), chalk.redBright('ERROR:'), logMessage);
|
|
201
|
-
} else {
|
|
202
|
-
console.error('[ADT Pulse]', chalk.redBright('ERROR:'), logMessage);
|
|
203
|
-
}
|
|
204
|
-
break;
|
|
205
|
-
case 'warn':
|
|
206
|
-
if (logger !== null) {
|
|
207
|
-
logger.warn(chalk.gray('DEBUG'), chalk.yellowBright('WARNING:'), logMessage);
|
|
208
|
-
} else {
|
|
209
|
-
console.warn('[ADT Pulse]', chalk.yellowBright('WARNING:'), logMessage);
|
|
210
|
-
}
|
|
211
|
-
break;
|
|
212
|
-
case 'success':
|
|
213
|
-
if (logger !== null) {
|
|
214
|
-
logger.info(chalk.gray('DEBUG'), chalk.greenBright('SUCCESS:'), logMessage);
|
|
215
|
-
} else {
|
|
216
|
-
console.info('[ADT Pulse]', chalk.greenBright('SUCCESS:'), logMessage);
|
|
217
|
-
}
|
|
218
|
-
break;
|
|
219
|
-
case 'info':
|
|
220
|
-
if (logger !== null) {
|
|
221
|
-
logger.info(chalk.gray('DEBUG'), chalk.blueBright('INFO:'), logMessage);
|
|
222
|
-
} else {
|
|
223
|
-
console.info('[ADT Pulse]', chalk.blueBright('INFO:'), logMessage);
|
|
224
|
-
}
|
|
225
|
-
break;
|
|
226
|
-
default:
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Fetch error message.
|
|
233
|
-
*
|
|
234
|
-
* @param {FetchErrorMessageResponse} response - Response.
|
|
235
|
-
*
|
|
236
|
-
* @returns {FetchErrorMessageReturns}
|
|
237
|
-
*
|
|
238
|
-
* @since 1.0.0
|
|
239
|
-
*/
|
|
240
|
-
export function fetchErrorMessage(response: FetchErrorMessageResponse): FetchErrorMessageReturns {
|
|
241
|
-
if (response === undefined || typeof response.data !== 'string') {
|
|
242
|
-
return null;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Parse the response (normally it should be the sign-in page).
|
|
246
|
-
const jsdom = new JSDOM(
|
|
247
|
-
response.data,
|
|
248
|
-
{
|
|
249
|
-
url: response.config.url,
|
|
250
|
-
referrer: response.config.headers.Referer,
|
|
251
|
-
contentType: 'text/html',
|
|
252
|
-
pretendToBeVisual: true,
|
|
253
|
-
},
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
// Find the warn message contents.
|
|
257
|
-
const warnMessage = jsdom.window.document.querySelector('#warnMsgContents');
|
|
258
|
-
|
|
259
|
-
if (warnMessage !== null) {
|
|
260
|
-
return clearWhitespace(clearHtmlLineBreak(warnMessage.innerHTML));
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return null;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Fetch missing sat code.
|
|
268
|
-
*
|
|
269
|
-
* @param {FetchMissingSatCodeResponse} response - Response.
|
|
270
|
-
*
|
|
271
|
-
* @returns {FetchMissingSatCodeReturns}
|
|
272
|
-
*
|
|
273
|
-
* @since 1.0.0
|
|
274
|
-
*/
|
|
275
|
-
export function fetchMissingSatCode(response: FetchMissingSatCodeResponse): FetchMissingSatCodeReturns {
|
|
276
|
-
if (typeof response.data !== 'string') {
|
|
277
|
-
return null;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Find the sat code.
|
|
281
|
-
const satCode = response.data.match(paramSat);
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Original matches for the sat code.
|
|
285
|
-
*
|
|
286
|
-
* - "sat=3b59d412-0dcb-41fb-b925-3fcfe3144633"
|
|
287
|
-
* - "3b59d412-0dcb-41fb-b925-3fcfe3144633"
|
|
288
|
-
*
|
|
289
|
-
* Only need to store the sat code, and should be two elements.
|
|
290
|
-
* It is loosely matched for more to take unexpected changes into
|
|
291
|
-
* account. Used in case sat code is not found.
|
|
292
|
-
*
|
|
293
|
-
* @since 1.0.0
|
|
294
|
-
*/
|
|
295
|
-
if (satCode !== null && satCode.length >= 2) {
|
|
296
|
-
return satCode[1];
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return null;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Fetch table cells.
|
|
304
|
-
*
|
|
305
|
-
* @param {FetchTableCellsNodeElements} nodeElements - Node elements.
|
|
306
|
-
* @param {FetchTableCellsMatchList} matchList - Match list.
|
|
307
|
-
* @param {FetchTableCellsIncrementFrom} incrementFrom - Increment from.
|
|
308
|
-
* @param {FetchTableCellsIncrementTo} incrementTo - Increment to.
|
|
309
|
-
*
|
|
310
|
-
* @returns {FetchTableCellsReturns}
|
|
311
|
-
*
|
|
312
|
-
* @since 1.0.0
|
|
313
|
-
*/
|
|
314
|
-
export function fetchTableCells(nodeElements: FetchTableCellsNodeElements, matchList: FetchTableCellsMatchList, incrementFrom: FetchTableCellsIncrementFrom, incrementTo: FetchTableCellsIncrementTo): FetchTableCellsReturns {
|
|
315
|
-
const matched: FetchTableCellsMatched = {};
|
|
316
|
-
|
|
317
|
-
let newIncrementFrom = incrementFrom;
|
|
318
|
-
let newIncrementTo = incrementTo;
|
|
319
|
-
|
|
320
|
-
// Prevent negative numbers.
|
|
321
|
-
if (incrementFrom < 0) {
|
|
322
|
-
newIncrementFrom = 0;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Prevent numbers smaller than "incrementFrom".
|
|
326
|
-
if (incrementTo < incrementFrom) {
|
|
327
|
-
newIncrementTo = incrementFrom;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
nodeElements.forEach((nodeElement, nodeElementKey) => {
|
|
331
|
-
const currentNode = nodeElement.textContent;
|
|
332
|
-
|
|
333
|
-
if (currentNode === null) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const currentNodeCleaned = clearWhitespace(currentNode);
|
|
338
|
-
const collectedNodes = [];
|
|
339
|
-
|
|
340
|
-
if (!matchList.includes(currentNodeCleaned)) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Purpose of this loop is to capture all table cells starting
|
|
346
|
-
* from the "match index + incrementFrom" to "match index + incrementTo", then
|
|
347
|
-
* organize them based on the current matched list value.
|
|
348
|
-
*
|
|
349
|
-
* Using this as an example:
|
|
350
|
-
* - nodes[50].textContent = "Example"
|
|
351
|
-
* - nodes[51].textContent = "12345"
|
|
352
|
-
* - nodes[52].textContent = "67890"
|
|
353
|
-
* - nodes[53].textContent = null
|
|
354
|
-
* - nodes[54].textContent = "abcdef"
|
|
355
|
-
*
|
|
356
|
-
* If your criteria is set to the following settings, the result would be:
|
|
357
|
-
* (match: "Example", incrementFrom: 0, incrementTo: 1) ➜ { "Example": ["Example", "12345"] }
|
|
358
|
-
* (match: "Example", incrementFrom: 1, incrementTo: 3) ➜ { "Example": ["12345", "67890"] }
|
|
359
|
-
* (match: "Example", incrementFrom: 0, incrementTo: 4) ➜ { "Example": ["Example", "12345", "67890", "abcdef"] }
|
|
360
|
-
*
|
|
361
|
-
* @since 1.0.0
|
|
362
|
-
*/
|
|
363
|
-
for (let i = newIncrementFrom; i <= newIncrementTo; i += 1) {
|
|
364
|
-
const incrementedNode = nodeElements[nodeElementKey + i].textContent;
|
|
365
|
-
|
|
366
|
-
// Be aware, this checks for "incrementedNode" not "currentNode"
|
|
367
|
-
if (incrementedNode !== null) {
|
|
368
|
-
const incrementedNodeCleaned = clearWhitespace(incrementedNode);
|
|
369
|
-
|
|
370
|
-
collectedNodes.push(incrementedNodeCleaned);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
matched[currentNodeCleaned] = collectedNodes;
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
return matched;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Find index with value.
|
|
382
|
-
*
|
|
383
|
-
* @param {FindIndexWithValueArray} array - Array.
|
|
384
|
-
* @param {FindIndexWithValueCondition} condition - Condition.
|
|
385
|
-
*
|
|
386
|
-
* @returns {FindIndexWithValueReturns}
|
|
387
|
-
*
|
|
388
|
-
* @since 1.0.0
|
|
389
|
-
*/
|
|
390
|
-
export function findIndexWithValue<Value>(array: FindIndexWithValueArray<Value>, condition: FindIndexWithValueCondition<Value>): FindIndexWithValueReturns<Value> {
|
|
391
|
-
let index = -1;
|
|
392
|
-
let value;
|
|
393
|
-
|
|
394
|
-
for (let i = 0; i < array.length; i += 1) {
|
|
395
|
-
// If the current iteration matches the condition given, return that.
|
|
396
|
-
if (condition(array[i])) {
|
|
397
|
-
index = i;
|
|
398
|
-
value = array[i];
|
|
399
|
-
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
return {
|
|
405
|
-
index,
|
|
406
|
-
value,
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Find null keys.
|
|
412
|
-
*
|
|
413
|
-
* @param {FindNullKeysProperties} properties - Properties.
|
|
414
|
-
* @param {FindNullKeysParentKey} parentKey - Parent key.
|
|
415
|
-
*
|
|
416
|
-
* @returns {FindNullKeysReturns}
|
|
417
|
-
*
|
|
418
|
-
* @since 1.0.0
|
|
419
|
-
*/
|
|
420
|
-
export function findNullKeys(properties: FindNullKeysProperties, parentKey: FindNullKeysParentKey = ''): FindNullKeysReturns {
|
|
421
|
-
const found: FindNullKeysFound = [];
|
|
422
|
-
|
|
423
|
-
Object.entries(properties).forEach(([propertyKey, property]) => {
|
|
424
|
-
const currentKey = parentKey !== '' ? `${parentKey}.${propertyKey}` : propertyKey;
|
|
425
|
-
|
|
426
|
-
if (_.isPlainObject(property)) {
|
|
427
|
-
found.push(...findNullKeys(property, currentKey));
|
|
428
|
-
} else if (property == null) {
|
|
429
|
-
found.push(currentKey);
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
return found;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Generate device id.
|
|
438
|
-
*
|
|
439
|
-
* @param {GenerateDeviceIdId} id - Id.
|
|
440
|
-
*
|
|
441
|
-
* @returns {GenerateDeviceIdReturns}
|
|
442
|
-
*
|
|
443
|
-
* @since 1.0.0
|
|
444
|
-
*/
|
|
445
|
-
export function generateDeviceId(id: GenerateDeviceIdId): GenerateDeviceIdReturns {
|
|
446
|
-
return `adt-device-${id}`;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Generate dynatrace pc header value.
|
|
451
|
-
*
|
|
452
|
-
* @param {GenerateDynatracePCHeaderValueMode} mode - Mode.
|
|
453
|
-
*
|
|
454
|
-
* @returns {GenerateDynatracePCHeaderValueReturns}
|
|
455
|
-
*
|
|
456
|
-
* @since 1.0.0
|
|
457
|
-
*/
|
|
458
|
-
export function generateDynatracePCHeaderValue(mode: GenerateDynatracePCHeaderValueMode): GenerateDynatracePCHeaderValueReturns {
|
|
459
|
-
const serverId = _.sample([1, 3, 5, 6]);
|
|
460
|
-
const currentMillis = Date.now().toString();
|
|
461
|
-
const slicedMillis = (mode === 'keep-alive') ? currentMillis.slice(-8) : currentMillis.slice(-9);
|
|
462
|
-
const randomThreeDigit = Math.floor(Math.random() * (932 - 218 + 1)) + 218;
|
|
463
|
-
const randomTwoDigit = Math.floor(Math.random() * (29 - 11 + 1)) + 11;
|
|
464
|
-
const randomAlphabet = _.range(32).map(() => _.sample('ABCDEFGHIJKLMNOPQRSTUVW')).join('');
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Some information on how Dynatrace generates the "x-dtpc" header.
|
|
468
|
-
*
|
|
469
|
-
* Structure of "5$12345678_218h20vABCDEFGHIJKLMNOPQRSTUVWABCDEFGHI-0e0":
|
|
470
|
-
* - Server ID (1, 3, 5, 6)
|
|
471
|
-
* - $
|
|
472
|
-
* - Last 8 to 9 digits (depending on mode) of current time in milliseconds
|
|
473
|
-
* - _
|
|
474
|
-
* - Random 3 digit value (from 218 to 932)
|
|
475
|
-
* - h
|
|
476
|
-
* - Random 2 digit value (11 to 29)
|
|
477
|
-
* - v
|
|
478
|
-
* - Random 32 uppercase letters (except X, Y, or Z)
|
|
479
|
-
* - -0e0
|
|
480
|
-
*
|
|
481
|
-
* Purpose: Required to identify proper endpoints for beacon transmission; includes session ID for correlation.
|
|
482
|
-
*
|
|
483
|
-
* https://docs.dynatrace.com/docs/manage/data-privacy-and-security/data-privacy/cookies
|
|
484
|
-
* https://docs.dynatrace.com/docs/platform-modules/digital-experience/web-applications/initial-setup/firewall-constraints-for-rum
|
|
485
|
-
* https://docs.dynatrace.com/docs/whats-new/release-notes/oneagent/sprint-165
|
|
486
|
-
*
|
|
487
|
-
* @since 1.0.0
|
|
488
|
-
*/
|
|
489
|
-
return `${serverId}$${slicedMillis}_${randomThreeDigit}h${randomTwoDigit}v${randomAlphabet}-0e0`;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Generate hash.
|
|
494
|
-
*
|
|
495
|
-
* @param {GenerateHashData} data - Data.
|
|
496
|
-
*
|
|
497
|
-
* @returns {GenerateHashReturns}
|
|
498
|
-
*
|
|
499
|
-
* @since 1.0.0
|
|
500
|
-
*/
|
|
501
|
-
export function generateHash(data: GenerateHashData): GenerateHashReturns {
|
|
502
|
-
return createHash('sha512').update(data).digest('hex');
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* Get accessory category.
|
|
507
|
-
*
|
|
508
|
-
* @param {GetAccessoryCategoryDeviceCategory} deviceCategory - Device category.
|
|
509
|
-
*
|
|
510
|
-
* @returns {GetAccessoryCategoryReturns}
|
|
511
|
-
*
|
|
512
|
-
* @since 1.0.0
|
|
513
|
-
*/
|
|
514
|
-
export function getAccessoryCategory(deviceCategory: GetAccessoryCategoryDeviceCategory): GetAccessoryCategoryReturns {
|
|
515
|
-
switch (deviceCategory) {
|
|
516
|
-
case 'ALARM_SYSTEM':
|
|
517
|
-
return Categories.ALARM_SYSTEM;
|
|
518
|
-
case 'OTHER':
|
|
519
|
-
return Categories.OTHER;
|
|
520
|
-
case 'SECURITY_SYSTEM':
|
|
521
|
-
return Categories.SECURITY_SYSTEM;
|
|
522
|
-
case 'SENSOR':
|
|
523
|
-
return Categories.SENSOR;
|
|
524
|
-
default:
|
|
525
|
-
return Categories.OTHER;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Get plural form.
|
|
531
|
-
*
|
|
532
|
-
* @param {GetPluralFormCount} count - Count.
|
|
533
|
-
* @param {GetPluralFormSingular} singular - Singular.
|
|
534
|
-
* @param {GetPluralFormPlural} plural - Plural.
|
|
535
|
-
*
|
|
536
|
-
* @returns {GetPluralFormReturns}
|
|
537
|
-
*
|
|
538
|
-
* @since 1.0.0
|
|
539
|
-
*/
|
|
540
|
-
export function getPluralForm(count: GetPluralFormCount, singular: GetPluralFormSingular, plural: GetPluralFormPlural): GetPluralFormReturns {
|
|
541
|
-
if (count === 1) {
|
|
542
|
-
return singular;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
return plural;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Is forward slash os.
|
|
550
|
-
*
|
|
551
|
-
* @returns {IsForwardSlashOSReturns}
|
|
552
|
-
*
|
|
553
|
-
* @since 1.0.0
|
|
554
|
-
*/
|
|
555
|
-
export function isForwardSlashOS(): IsForwardSlashOSReturns {
|
|
556
|
-
const currentOS = os.platform();
|
|
557
|
-
|
|
558
|
-
return [
|
|
559
|
-
'aix',
|
|
560
|
-
'android',
|
|
561
|
-
'darwin',
|
|
562
|
-
'freebsd',
|
|
563
|
-
'haiku',
|
|
564
|
-
'linux',
|
|
565
|
-
'openbsd',
|
|
566
|
-
'sunos',
|
|
567
|
-
'netbsd',
|
|
568
|
-
].includes(currentOS);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Is portal sync code.
|
|
573
|
-
*
|
|
574
|
-
* @param {IsPortalSyncCodeSyncCode} syncCode - Sync code.
|
|
575
|
-
*
|
|
576
|
-
* @returns {boolean}
|
|
577
|
-
*
|
|
578
|
-
* @since 1.0.0
|
|
579
|
-
*/
|
|
580
|
-
export function isPortalSyncCode(syncCode: IsPortalSyncCodeSyncCode): syncCode is IsPortalSyncCodeVerifiedSyncCode {
|
|
581
|
-
return textSyncCode.test(syncCode);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Parse arm disarm message.
|
|
586
|
-
*
|
|
587
|
-
* @param {ParseArmDisarmMessageElement} element - Element.
|
|
588
|
-
*
|
|
589
|
-
* @returns {ParseArmDisarmMessageReturns}
|
|
590
|
-
*
|
|
591
|
-
* @since 1.0.0
|
|
592
|
-
*/
|
|
593
|
-
export function parseArmDisarmMessage(element: ParseArmDisarmMessageElement): ParseArmDisarmMessageReturns {
|
|
594
|
-
if (element === null || element.textContent === null) {
|
|
595
|
-
return null;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return clearWhitespace(element.textContent);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Parse do submit handlers.
|
|
603
|
-
*
|
|
604
|
-
* @param {ParseDoSubmitHandlersElements} elements - Elements.
|
|
605
|
-
*
|
|
606
|
-
* @returns {ParseDoSubmitHandlersReturns}
|
|
607
|
-
*
|
|
608
|
-
* @since 1.0.0
|
|
609
|
-
*/
|
|
610
|
-
export function parseDoSubmitHandlers(elements: ParseDoSubmitHandlersElements): ParseDoSubmitHandlersReturns {
|
|
611
|
-
const handlers: ParseDoSubmitHandlersHandlers = [];
|
|
612
|
-
|
|
613
|
-
elements.forEach((element) => {
|
|
614
|
-
const onClick = element.getAttribute('onclick');
|
|
615
|
-
|
|
616
|
-
// None of the force arm buttons are disabled, so if "onClick" is null, this button is useless.
|
|
617
|
-
if (onClick === null) {
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
const relativeUrl = onClick.replace(functionDoSubmit, '$1') as ParseDoSubmitHandlersRelativeUrl;
|
|
622
|
-
const urlParamsSat = onClick.replace(functionDoSubmit, '$2');
|
|
623
|
-
const urlParamsHref = onClick.replace(functionDoSubmit, '$3').replace(characterBackslashForwardSlash, '/') as ParseDoSubmitHandlersUrlParamsHref;
|
|
624
|
-
const urlParamsArmState = onClick.replace(functionDoSubmit, '$5') as ParseDoSubmitHandlersUrlParamsArmState;
|
|
625
|
-
const urlParamsArm = onClick.replace(functionDoSubmit, '$6') as ParseDoSubmitHandlersUrlParamsArm;
|
|
626
|
-
|
|
627
|
-
handlers.push({
|
|
628
|
-
relativeUrl,
|
|
629
|
-
urlParams: {
|
|
630
|
-
arm: (urlParamsArm !== '') ? urlParamsArm : null,
|
|
631
|
-
armState: (urlParamsArmState !== '') ? urlParamsArmState : null,
|
|
632
|
-
href: urlParamsHref,
|
|
633
|
-
sat: urlParamsSat,
|
|
634
|
-
},
|
|
635
|
-
});
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
return handlers;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* Parse orb sensors.
|
|
643
|
-
*
|
|
644
|
-
* @param {ParseOrbSensorsElements} elements - Elements.
|
|
645
|
-
*
|
|
646
|
-
* @returns {ParseOrbSensorsReturns}
|
|
647
|
-
*
|
|
648
|
-
* @since 1.0.0
|
|
649
|
-
*/
|
|
650
|
-
export function parseOrbSensors(elements: ParseOrbSensorsElements): ParseOrbSensorsReturns {
|
|
651
|
-
const sensors: ParseOrbSensorsSensors = [];
|
|
652
|
-
|
|
653
|
-
elements.forEach((element) => {
|
|
654
|
-
const canvas = element.querySelector('td:nth-child(1) canvas');
|
|
655
|
-
const name = element.querySelector('td:nth-child(3) a.p_deviceNameText');
|
|
656
|
-
const zone = element.querySelector('td:nth-child(3) span.p_grayNormalText, td:nth-child(3) div.p_grayNormalText');
|
|
657
|
-
const status = element.querySelector('td:nth-child(4)');
|
|
658
|
-
|
|
659
|
-
if (canvas !== null && name !== null && zone !== null && status !== null) {
|
|
660
|
-
const canvasIcon = canvas.getAttribute('icon');
|
|
661
|
-
const nameText = name.textContent;
|
|
662
|
-
const zoneText = zone.textContent;
|
|
663
|
-
const statusText = status.textContent;
|
|
664
|
-
|
|
665
|
-
if (canvasIcon !== null && nameText !== null && zoneText !== null && statusText !== null) {
|
|
666
|
-
const cleanedIcon = clearWhitespace(canvasIcon) as ParseOrbSensorsCleanedIcon;
|
|
667
|
-
const cleanedName = clearWhitespace(nameText);
|
|
668
|
-
const cleanedZone = Number(clearWhitespace(zoneText).replace(textOrbSensorZone, '$2'));
|
|
669
|
-
const cleanedStatus = clearWhitespace(statusText) as ParseOrbSensorsCleanedStatus;
|
|
670
|
-
|
|
671
|
-
sensors.push({
|
|
672
|
-
icon: cleanedIcon,
|
|
673
|
-
name: cleanedName,
|
|
674
|
-
status: cleanedStatus,
|
|
675
|
-
zone: cleanedZone,
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
|
|
681
|
-
return sensors.sort((a, b) => a.zone - b.zone);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* Parse orb text summary.
|
|
686
|
-
*
|
|
687
|
-
* @param {ParseOrbTextSummaryElement} element - Element.
|
|
688
|
-
*
|
|
689
|
-
* @returns {ParseOrbTextSummaryReturns}
|
|
690
|
-
*
|
|
691
|
-
* @since 1.0.0
|
|
692
|
-
*/
|
|
693
|
-
export function parseOrbTextSummary(element: ParseOrbTextSummaryElement): ParseOrbTextSummaryReturns {
|
|
694
|
-
if (element === null || element.textContent === null) {
|
|
695
|
-
return {
|
|
696
|
-
state: null,
|
|
697
|
-
status: null,
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
const cleanedNode = clearWhitespace(element.textContent);
|
|
702
|
-
const currentState = cleanedNode.replace(textOrbTextSummary, '$1') as ParseOrbTextSummaryCurrentState;
|
|
703
|
-
const currentStatus = cleanedNode.replace(textOrbTextSummary, '$2') as ParseOrbTextSummaryCurrentStatus;
|
|
704
|
-
|
|
705
|
-
return {
|
|
706
|
-
state: currentState,
|
|
707
|
-
status: (currentStatus !== '') ? currentStatus : null,
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
/**
|
|
712
|
-
* Parse orb security buttons.
|
|
713
|
-
*
|
|
714
|
-
* @param {ParseOrbSecurityButtonsElements} elements - Elements.
|
|
715
|
-
*
|
|
716
|
-
* @returns {ParseOrbSecurityButtonsReturns}
|
|
717
|
-
*
|
|
718
|
-
* @since 1.0.0
|
|
719
|
-
*/
|
|
720
|
-
export function parseOrbSecurityButtons(elements: ParseOrbSecurityButtonsElements): ParseOrbSecurityButtonsReturns {
|
|
721
|
-
const buttons: ParseOrbSecurityButtonsButtons = [];
|
|
722
|
-
|
|
723
|
-
elements.forEach((element) => {
|
|
724
|
-
const disabled = element.getAttribute('disabled');
|
|
725
|
-
const id = element.getAttribute('id');
|
|
726
|
-
const value = element.getAttribute('value');
|
|
727
|
-
const onClick = element.getAttribute('onclick');
|
|
728
|
-
|
|
729
|
-
// Type asserted variables for both pending (disabled) and ready (enabled) buttons.
|
|
730
|
-
const buttonId = id as ParseOrbSecurityButtonsButtonId;
|
|
731
|
-
|
|
732
|
-
// There is a pending (disabled) button displayed.
|
|
733
|
-
if (disabled !== null && onClick === null) {
|
|
734
|
-
const pendingButtonText = value as ParseOrbSecurityButtonsPendingButtonText;
|
|
735
|
-
|
|
736
|
-
buttons.push({
|
|
737
|
-
buttonDisabled: true,
|
|
738
|
-
buttonId,
|
|
739
|
-
buttonText: pendingButtonText,
|
|
740
|
-
});
|
|
741
|
-
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// There is a ready (enabled) button displayed.
|
|
746
|
-
if (disabled === null && onClick !== null) {
|
|
747
|
-
const readyButtonText = value as ParseOrbSecurityButtonsReadyButtonText;
|
|
748
|
-
|
|
749
|
-
const relativeUrl = onClick.replace(functionSetArmState, '$1') as ParseOrbSecurityButtonsRelativeUrl;
|
|
750
|
-
const loadingText = onClick.replace(functionSetArmState, '$2') as ParseOrbSecurityButtonsLoadingText;
|
|
751
|
-
const buttonIndex = Number(onClick.replace(functionSetArmState, '$3'));
|
|
752
|
-
const totalButtons = Number(onClick.replace(functionSetArmState, '$4'));
|
|
753
|
-
const changeAccessCode = Boolean(onClick.replace(functionSetArmState, '$5'));
|
|
754
|
-
const urlParamsHref = onClick.replace(functionSetArmState, '$6') as ParseOrbSecurityButtonsHref;
|
|
755
|
-
const urlParamsArmState = onClick.replace(functionSetArmState, '$7') as ParseOrbSecurityButtonsArmState;
|
|
756
|
-
const urlParamsArm = onClick.replace(functionSetArmState, '$8') as ParseOrbSecurityButtonsArm;
|
|
757
|
-
const urlParamsSat = onClick.replace(functionSetArmState, '$9');
|
|
758
|
-
|
|
759
|
-
buttons.push({
|
|
760
|
-
buttonDisabled: false,
|
|
761
|
-
buttonId,
|
|
762
|
-
buttonIndex,
|
|
763
|
-
buttonText: readyButtonText,
|
|
764
|
-
changeAccessCode,
|
|
765
|
-
loadingText,
|
|
766
|
-
relativeUrl,
|
|
767
|
-
totalButtons,
|
|
768
|
-
urlParams: {
|
|
769
|
-
arm: urlParamsArm,
|
|
770
|
-
armState: urlParamsArmState,
|
|
771
|
-
href: urlParamsHref,
|
|
772
|
-
sat: urlParamsSat,
|
|
773
|
-
},
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
});
|
|
777
|
-
|
|
778
|
-
return buttons;
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* Parse sensors table.
|
|
783
|
-
*
|
|
784
|
-
* @param {ParseOrbSensorsTableElements} elements - Elements.
|
|
785
|
-
*
|
|
786
|
-
* @returns {ParseOrbSensorsTableReturns}
|
|
787
|
-
*
|
|
788
|
-
* @since 1.0.0
|
|
789
|
-
*/
|
|
790
|
-
export function parseSensorsTable(elements: ParseOrbSensorsTableElements): ParseOrbSensorsTableReturns {
|
|
791
|
-
const sensors: ParseOrbSensorsTableSensors = [];
|
|
792
|
-
|
|
793
|
-
elements.forEach((element) => {
|
|
794
|
-
const onclick = element.getAttribute('onclick');
|
|
795
|
-
const icon = element.querySelector('td:nth-child(1) canvas');
|
|
796
|
-
const name = element.querySelector('td:nth-child(2) a');
|
|
797
|
-
const zone = element.querySelector('td:nth-child(3)');
|
|
798
|
-
const deviceType = element.querySelector('td:nth-child(5)');
|
|
799
|
-
|
|
800
|
-
if (onclick !== null && icon !== null && name !== null && zone !== null && deviceType !== null) {
|
|
801
|
-
const deviceId = onclick.replace(functionGoToUrl, '$1');
|
|
802
|
-
const iconTitle = icon.getAttribute('title');
|
|
803
|
-
const nameText = name.textContent;
|
|
804
|
-
const zoneText = zone.textContent;
|
|
805
|
-
const deviceTypeText = deviceType.textContent;
|
|
806
|
-
|
|
807
|
-
if (iconTitle !== null && nameText !== null && zoneText !== null && deviceTypeText !== null) {
|
|
808
|
-
// If the row does not have a zone, it is NOT a sensor.
|
|
809
|
-
const isSensor = clearWhitespace(zoneText) !== '';
|
|
810
|
-
|
|
811
|
-
if (isSensor) {
|
|
812
|
-
const cleanedDeviceId = Number(clearWhitespace(deviceId));
|
|
813
|
-
const cleanedDeviceType = clearWhitespace(deviceTypeText) as ParseOrbSensorsTableDeviceType;
|
|
814
|
-
const cleanedName = clearWhitespace(nameText);
|
|
815
|
-
const cleanedStatus = clearWhitespace(iconTitle) as ParseOrbSensorsTableStatus;
|
|
816
|
-
const cleanedZone = Number(clearWhitespace(zoneText));
|
|
817
|
-
|
|
818
|
-
sensors.push({
|
|
819
|
-
deviceId: cleanedDeviceId,
|
|
820
|
-
deviceType: cleanedDeviceType,
|
|
821
|
-
name: cleanedName,
|
|
822
|
-
status: cleanedStatus,
|
|
823
|
-
zone: cleanedZone,
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
return sensors.sort((a, b) => a.zone - b.zone);
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
/**
|
|
834
|
-
* Remove personal identifiable information.
|
|
835
|
-
*
|
|
836
|
-
* @param {RemovePersonalIdentifiableInformationData} data - Data.
|
|
837
|
-
*
|
|
838
|
-
* @returns {RemovePersonalIdentifiableInformationReturns}
|
|
839
|
-
*
|
|
840
|
-
* @since 1.0.0
|
|
841
|
-
*/
|
|
842
|
-
export function removePersonalIdentifiableInformation(data: RemovePersonalIdentifiableInformationData): RemovePersonalIdentifiableInformationReturns {
|
|
843
|
-
const redactedKeys = [
|
|
844
|
-
'ip',
|
|
845
|
-
'lanIp',
|
|
846
|
-
'mac',
|
|
847
|
-
'masterCode',
|
|
848
|
-
'sat',
|
|
849
|
-
'serialNumber',
|
|
850
|
-
'wanIp',
|
|
851
|
-
];
|
|
852
|
-
|
|
853
|
-
/**
|
|
854
|
-
* Remove personal identifiable information - Replace value.
|
|
855
|
-
*
|
|
856
|
-
* @param {RemovePersonalIdentifiableInformationReplaceValueObject} object - Object.
|
|
857
|
-
*
|
|
858
|
-
* @returns {RemovePersonalIdentifiableInformationReplaceValueReturns}
|
|
859
|
-
*
|
|
860
|
-
* @since 1.0.0
|
|
861
|
-
*/
|
|
862
|
-
const replaceValue = (object: RemovePersonalIdentifiableInformationReplaceValueObject): RemovePersonalIdentifiableInformationReplaceValueReturns => {
|
|
863
|
-
const modifiedObject: RemovePersonalIdentifiableInformationModifiedObject = {};
|
|
864
|
-
|
|
865
|
-
Object.keys(object).forEach((key) => {
|
|
866
|
-
const value = object[key];
|
|
867
|
-
|
|
868
|
-
if (_.isPlainObject(value)) {
|
|
869
|
-
modifiedObject[key] = replaceValue(value as RemovePersonalIdentifiableInformationModifiedObject);
|
|
870
|
-
} else if (redactedKeys.includes(key)) {
|
|
871
|
-
modifiedObject[key] = '*** REDACTED FOR PRIVACY ***';
|
|
872
|
-
} else {
|
|
873
|
-
modifiedObject[key] = value;
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
|
|
877
|
-
return modifiedObject;
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
if (Array.isArray(data)) {
|
|
881
|
-
return data.map(replaceValue);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
return replaceValue(data);
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
/**
|
|
888
|
-
* Sleep.
|
|
889
|
-
*
|
|
890
|
-
* @param {SleepMilliseconds} milliseconds - Milliseconds.
|
|
891
|
-
*
|
|
892
|
-
* @returns {SleepReturns}
|
|
893
|
-
*
|
|
894
|
-
* @since 1.0.0
|
|
895
|
-
*/
|
|
896
|
-
export async function sleep(milliseconds: SleepMilliseconds): SleepReturns {
|
|
897
|
-
return new Promise((resolve) => {
|
|
898
|
-
setTimeout(resolve, milliseconds);
|
|
899
|
-
});
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
/**
|
|
903
|
-
* Stack tracer.
|
|
904
|
-
*
|
|
905
|
-
* @param {StackTracerType} type - Type.
|
|
906
|
-
* @param {StackTracerError} error - Error.
|
|
907
|
-
*
|
|
908
|
-
* @returns {StackTracerReturns}
|
|
909
|
-
*
|
|
910
|
-
* @since 1.0.0
|
|
911
|
-
*/
|
|
912
|
-
export function stackTracer(type: StackTracerType, error: StackTracerError<StackTracerType>): StackTracerReturns {
|
|
913
|
-
let stringError;
|
|
914
|
-
|
|
915
|
-
switch (type) {
|
|
916
|
-
case 'api-response':
|
|
917
|
-
case 'detect-content':
|
|
918
|
-
case 'serialize-error':
|
|
919
|
-
stringError = util.inspect(error, {
|
|
920
|
-
showHidden: false,
|
|
921
|
-
depth: Infinity,
|
|
922
|
-
colors: false,
|
|
923
|
-
});
|
|
924
|
-
break;
|
|
925
|
-
case 'zod-error':
|
|
926
|
-
stringError = JSON.stringify(error, null, 2).replace(/\\"/g, '\'');
|
|
927
|
-
break;
|
|
928
|
-
default:
|
|
929
|
-
break;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
console.error(chalk.yellowBright(stringError));
|
|
933
|
-
}
|