@truesift/express 0.1.0
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/CHANGELOG.md +191 -0
- package/LICENSE +21 -0
- package/README.md +567 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +158 -0
- package/dist/index-DWCqfBfQ.d.ts +135 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +921 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
// src/http/buildBotGuardUrl.ts
|
|
2
|
+
var BOT_GUARD_ENDPOINT_PATHS = {
|
|
3
|
+
challenge: "/challenge",
|
|
4
|
+
verify: "/verify"
|
|
5
|
+
};
|
|
6
|
+
function removeTrailingSlashes(value) {
|
|
7
|
+
return value.replace(/\/+$/, "");
|
|
8
|
+
}
|
|
9
|
+
function buildBotGuardUrl(apiBaseUrl, endpoint) {
|
|
10
|
+
const normalizedApiBaseUrl = removeTrailingSlashes(apiBaseUrl);
|
|
11
|
+
const endpointPath = BOT_GUARD_ENDPOINT_PATHS[endpoint];
|
|
12
|
+
return `${normalizedApiBaseUrl}${endpointPath}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/errors/BotGuardError.ts
|
|
16
|
+
var BotGuardError = class extends Error {
|
|
17
|
+
code;
|
|
18
|
+
statusCode;
|
|
19
|
+
requestId;
|
|
20
|
+
context;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
const errorOptions = options.cause === void 0 ? void 0 : { cause: options.cause };
|
|
23
|
+
super(options.message, errorOptions);
|
|
24
|
+
this.name = new.target.name;
|
|
25
|
+
this.code = options.code;
|
|
26
|
+
if (options.statusCode !== void 0) {
|
|
27
|
+
this.statusCode = options.statusCode;
|
|
28
|
+
}
|
|
29
|
+
if (options.requestId !== void 0) {
|
|
30
|
+
this.requestId = options.requestId;
|
|
31
|
+
}
|
|
32
|
+
if (options.context !== void 0) {
|
|
33
|
+
this.context = options.context;
|
|
34
|
+
}
|
|
35
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
36
|
+
}
|
|
37
|
+
toJSON() {
|
|
38
|
+
return {
|
|
39
|
+
name: this.name,
|
|
40
|
+
code: this.code,
|
|
41
|
+
message: this.message,
|
|
42
|
+
...this.statusCode !== void 0 ? { statusCode: this.statusCode } : {},
|
|
43
|
+
...this.requestId !== void 0 ? { requestId: this.requestId } : {},
|
|
44
|
+
...this.context !== void 0 ? { context: this.context } : {}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/errors/BotGuardRequestError.ts
|
|
50
|
+
var DEFAULT_REQUEST_ERROR_MESSAGE = "TrueSift API request failed.";
|
|
51
|
+
var BotGuardRequestError = class extends BotGuardError {
|
|
52
|
+
constructor(options = {}) {
|
|
53
|
+
const errorOptions = {
|
|
54
|
+
code: "TRUESIFT_REQUEST_ERROR",
|
|
55
|
+
message: options.message ?? DEFAULT_REQUEST_ERROR_MESSAGE,
|
|
56
|
+
...options.statusCode !== void 0 ? { statusCode: options.statusCode } : {},
|
|
57
|
+
...options.requestId !== void 0 ? { requestId: options.requestId } : {},
|
|
58
|
+
...options.context !== void 0 ? { context: options.context } : {},
|
|
59
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
60
|
+
};
|
|
61
|
+
super(errorOptions);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/errors/BotGuardTimeoutError.ts
|
|
66
|
+
var DEFAULT_TIMEOUT_ERROR_MESSAGE = "TrueSift API request timed out.";
|
|
67
|
+
var BotGuardTimeoutError = class extends BotGuardError {
|
|
68
|
+
timeoutMs;
|
|
69
|
+
constructor(options = {}) {
|
|
70
|
+
const context = {
|
|
71
|
+
...options.context ?? {},
|
|
72
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
|
|
73
|
+
};
|
|
74
|
+
const errorOptions = {
|
|
75
|
+
code: "TRUESIFT_TIMEOUT_ERROR",
|
|
76
|
+
message: options.message ?? DEFAULT_TIMEOUT_ERROR_MESSAGE,
|
|
77
|
+
...options.requestId !== void 0 ? { requestId: options.requestId } : {},
|
|
78
|
+
...Object.keys(context).length > 0 ? { context } : {},
|
|
79
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
80
|
+
};
|
|
81
|
+
super(errorOptions);
|
|
82
|
+
if (options.timeoutMs !== void 0) {
|
|
83
|
+
this.timeoutMs = options.timeoutMs;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
toJSON() {
|
|
87
|
+
return {
|
|
88
|
+
...super.toJSON(),
|
|
89
|
+
code: "TRUESIFT_TIMEOUT_ERROR",
|
|
90
|
+
...this.timeoutMs !== void 0 ? { timeoutMs: this.timeoutMs } : {}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/errors/BotGuardApiError.ts
|
|
96
|
+
var DEFAULT_API_ERROR_MESSAGE = "TrueSift API returned an error response.";
|
|
97
|
+
var BotGuardApiError = class extends BotGuardError {
|
|
98
|
+
apiError;
|
|
99
|
+
constructor(options = {}) {
|
|
100
|
+
const context = {
|
|
101
|
+
...options.context ?? {},
|
|
102
|
+
...options.apiError !== void 0 ? { apiError: options.apiError } : {}
|
|
103
|
+
};
|
|
104
|
+
const errorOptions = {
|
|
105
|
+
code: "TRUESIFT_API_ERROR",
|
|
106
|
+
message: options.message ?? DEFAULT_API_ERROR_MESSAGE,
|
|
107
|
+
...options.statusCode !== void 0 ? { statusCode: options.statusCode } : {},
|
|
108
|
+
...options.requestId !== void 0 ? { requestId: options.requestId } : {},
|
|
109
|
+
...Object.keys(context).length > 0 ? { context } : {},
|
|
110
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
111
|
+
};
|
|
112
|
+
super(errorOptions);
|
|
113
|
+
if (options.apiError !== void 0) {
|
|
114
|
+
this.apiError = options.apiError;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
toJSON() {
|
|
118
|
+
return {
|
|
119
|
+
...super.toJSON(),
|
|
120
|
+
code: "TRUESIFT_API_ERROR",
|
|
121
|
+
...this.apiError !== void 0 ? { apiError: this.apiError } : {}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// src/errors/BotGuardAuthError.ts
|
|
127
|
+
var DEFAULT_AUTH_ERROR_MESSAGE = "TrueSift API authentication failed.";
|
|
128
|
+
var BotGuardAuthError = class extends BotGuardError {
|
|
129
|
+
constructor(options = {}) {
|
|
130
|
+
const errorOptions = {
|
|
131
|
+
code: "TRUESIFT_AUTH_ERROR",
|
|
132
|
+
message: options.message ?? DEFAULT_AUTH_ERROR_MESSAGE,
|
|
133
|
+
...options.statusCode !== void 0 ? { statusCode: options.statusCode } : {},
|
|
134
|
+
...options.requestId !== void 0 ? { requestId: options.requestId } : {},
|
|
135
|
+
...options.context !== void 0 ? { context: options.context } : {},
|
|
136
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
137
|
+
};
|
|
138
|
+
super(errorOptions);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// src/errors/BotGuardResponseError.ts
|
|
143
|
+
var DEFAULT_RESPONSE_ERROR_MESSAGE = "TrueSift API returned an invalid response.";
|
|
144
|
+
var BotGuardResponseError = class extends BotGuardError {
|
|
145
|
+
constructor(options = {}) {
|
|
146
|
+
const errorOptions = {
|
|
147
|
+
code: "TRUESIFT_RESPONSE_ERROR",
|
|
148
|
+
message: options.message ?? DEFAULT_RESPONSE_ERROR_MESSAGE,
|
|
149
|
+
...options.statusCode !== void 0 ? { statusCode: options.statusCode } : {},
|
|
150
|
+
...options.requestId !== void 0 ? { requestId: options.requestId } : {},
|
|
151
|
+
...options.context !== void 0 ? { context: options.context } : {},
|
|
152
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
153
|
+
};
|
|
154
|
+
super(errorOptions);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/utils/isRecord.ts
|
|
159
|
+
function isRecord(value) {
|
|
160
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/http/parseBotGuardResponse.ts
|
|
164
|
+
function getRequestIdFromHeaders(headers) {
|
|
165
|
+
const requestId = headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-trace-id");
|
|
166
|
+
return requestId === null || requestId.trim().length === 0 ? void 0 : requestId.trim();
|
|
167
|
+
}
|
|
168
|
+
function isJsonContentType(headers) {
|
|
169
|
+
const contentType = headers.get("content-type");
|
|
170
|
+
return contentType !== null && contentType.toLowerCase().includes("json");
|
|
171
|
+
}
|
|
172
|
+
function isTrueSiftJsonErrorResponse(body) {
|
|
173
|
+
return isRecord(body) && body["success"] === false && (body["error"] === void 0 || isRecord(body["error"]));
|
|
174
|
+
}
|
|
175
|
+
function getApiErrorMessage(body) {
|
|
176
|
+
return body.error?.message ?? "TrueSift API returned an error response.";
|
|
177
|
+
}
|
|
178
|
+
function getApiErrorCode(body) {
|
|
179
|
+
return body.error?.code;
|
|
180
|
+
}
|
|
181
|
+
async function parseJsonBody(response) {
|
|
182
|
+
try {
|
|
183
|
+
return await response.json();
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw new BotGuardResponseError({
|
|
186
|
+
message: "TrueSift API returned invalid JSON.",
|
|
187
|
+
statusCode: response.status,
|
|
188
|
+
requestId: getRequestIdFromHeaders(response.headers),
|
|
189
|
+
context: {
|
|
190
|
+
statusCode: response.status
|
|
191
|
+
},
|
|
192
|
+
cause: error
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function parseBotGuardResponse(response) {
|
|
197
|
+
const requestId = getRequestIdFromHeaders(response.headers);
|
|
198
|
+
if (!isJsonContentType(response.headers)) {
|
|
199
|
+
throw new BotGuardResponseError({
|
|
200
|
+
message: "TrueSift API response must be JSON.",
|
|
201
|
+
statusCode: response.status,
|
|
202
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
203
|
+
context: {
|
|
204
|
+
statusCode: response.status,
|
|
205
|
+
contentType: response.headers.get("content-type")
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const body = await parseJsonBody(response);
|
|
210
|
+
if (response.status === 401 || response.status === 403) {
|
|
211
|
+
throw new BotGuardAuthError({
|
|
212
|
+
statusCode: response.status,
|
|
213
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
214
|
+
context: {
|
|
215
|
+
statusCode: response.status
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (!response.ok) {
|
|
220
|
+
if (isTrueSiftJsonErrorResponse(body)) {
|
|
221
|
+
throw new BotGuardApiError({
|
|
222
|
+
message: getApiErrorMessage(body),
|
|
223
|
+
statusCode: response.status,
|
|
224
|
+
requestId: body.requestId ?? requestId,
|
|
225
|
+
apiError: {
|
|
226
|
+
...getApiErrorCode(body) !== void 0 ? { code: getApiErrorCode(body) } : {},
|
|
227
|
+
message: getApiErrorMessage(body),
|
|
228
|
+
...body.error?.details !== void 0 ? { details: body.error.details } : {}
|
|
229
|
+
},
|
|
230
|
+
context: {
|
|
231
|
+
statusCode: response.status
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
throw new BotGuardResponseError({
|
|
236
|
+
message: "TrueSift API returned an unexpected error response.",
|
|
237
|
+
statusCode: response.status,
|
|
238
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
239
|
+
context: {
|
|
240
|
+
statusCode: response.status
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
statusCode: response.status,
|
|
246
|
+
ok: response.ok,
|
|
247
|
+
headers: response.headers,
|
|
248
|
+
body,
|
|
249
|
+
...requestId !== void 0 ? { requestId } : {}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/http/botGuardFetch.ts
|
|
254
|
+
function isAbortError(error) {
|
|
255
|
+
return error instanceof DOMException || error instanceof Error && error.name === "AbortError";
|
|
256
|
+
}
|
|
257
|
+
async function botGuardFetch(config, options) {
|
|
258
|
+
const timeoutMs = options.timeoutMs ?? config.timeoutMs;
|
|
259
|
+
const controller = new AbortController();
|
|
260
|
+
const timeoutId = setTimeout(() => {
|
|
261
|
+
controller.abort();
|
|
262
|
+
}, timeoutMs);
|
|
263
|
+
try {
|
|
264
|
+
const response = await config.fetchImpl(options.url, {
|
|
265
|
+
method: "POST",
|
|
266
|
+
headers: {
|
|
267
|
+
"content-type": "application/json",
|
|
268
|
+
accept: "application/json"
|
|
269
|
+
},
|
|
270
|
+
body: JSON.stringify(options.body),
|
|
271
|
+
signal: controller.signal
|
|
272
|
+
});
|
|
273
|
+
const parsedResponse = await parseBotGuardResponse(response);
|
|
274
|
+
return parsedResponse.body;
|
|
275
|
+
} catch (error) {
|
|
276
|
+
if (isAbortError(error)) {
|
|
277
|
+
throw new BotGuardTimeoutError({
|
|
278
|
+
timeoutMs,
|
|
279
|
+
context: {
|
|
280
|
+
url: options.url,
|
|
281
|
+
timeoutMs
|
|
282
|
+
},
|
|
283
|
+
cause: error
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (error instanceof BotGuardError) {
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
289
|
+
throw new BotGuardRequestError({
|
|
290
|
+
context: {
|
|
291
|
+
url: options.url
|
|
292
|
+
},
|
|
293
|
+
cause: error
|
|
294
|
+
});
|
|
295
|
+
} finally {
|
|
296
|
+
clearTimeout(timeoutId);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/utils/decisionHelpers.ts
|
|
301
|
+
function isAllowedDecision(decision) {
|
|
302
|
+
return decision === "allow";
|
|
303
|
+
}
|
|
304
|
+
function isReviewDecision(decision) {
|
|
305
|
+
return decision === "review";
|
|
306
|
+
}
|
|
307
|
+
function isBlockedDecision(decision) {
|
|
308
|
+
return decision === "block";
|
|
309
|
+
}
|
|
310
|
+
function createDecisionFlags(decision) {
|
|
311
|
+
return {
|
|
312
|
+
isAllowed: isAllowedDecision(decision),
|
|
313
|
+
isReview: isReviewDecision(decision),
|
|
314
|
+
isBlocked: isBlockedDecision(decision)
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function isAllowed(result) {
|
|
318
|
+
return result.decision === "allow";
|
|
319
|
+
}
|
|
320
|
+
function isReview(result) {
|
|
321
|
+
return result.decision === "review";
|
|
322
|
+
}
|
|
323
|
+
function isBlocked(result) {
|
|
324
|
+
return result.decision === "block";
|
|
325
|
+
}
|
|
326
|
+
var isBotGuardAllowedDecision = isAllowedDecision;
|
|
327
|
+
var isBotGuardReviewDecision = isReviewDecision;
|
|
328
|
+
var isBotGuardBlockedDecision = isBlockedDecision;
|
|
329
|
+
function createBotGuardDecisionFlags(decision) {
|
|
330
|
+
return createDecisionFlags(decision);
|
|
331
|
+
}
|
|
332
|
+
function isBotGuardAllowed(result) {
|
|
333
|
+
return isAllowed(result);
|
|
334
|
+
}
|
|
335
|
+
function isBotGuardReview(result) {
|
|
336
|
+
return isReview(result);
|
|
337
|
+
}
|
|
338
|
+
function isBotGuardBlocked(result) {
|
|
339
|
+
return isBlocked(result);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// src/types/decision.types.ts
|
|
343
|
+
var TRUE_SIFT_DECISIONS = ["allow", "review", "block"];
|
|
344
|
+
|
|
345
|
+
// src/utils/normalizeDecision.ts
|
|
346
|
+
var TRUE_SIFT_DECISION_SET = new Set(
|
|
347
|
+
TRUE_SIFT_DECISIONS
|
|
348
|
+
);
|
|
349
|
+
function isTrueSiftDecision(value) {
|
|
350
|
+
return typeof value === "string" && TRUE_SIFT_DECISION_SET.has(value);
|
|
351
|
+
}
|
|
352
|
+
var isBotGuardDecision = isTrueSiftDecision;
|
|
353
|
+
function normalizeDecision(value) {
|
|
354
|
+
if (isTrueSiftDecision(value)) {
|
|
355
|
+
return value;
|
|
356
|
+
}
|
|
357
|
+
if (typeof value === "string") {
|
|
358
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
359
|
+
if (isTrueSiftDecision(normalizedValue)) {
|
|
360
|
+
return normalizedValue;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
throw new TypeError(
|
|
364
|
+
`Invalid TrueSift decision. Expected one of: ${TRUE_SIFT_DECISIONS.join(
|
|
365
|
+
", "
|
|
366
|
+
)}.`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function normalizeBotGuardDecision(value) {
|
|
370
|
+
return normalizeDecision(value);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/validation/validateBotGuardResponse.ts
|
|
374
|
+
var TRUE_SIFT_VERIFICATION_MODES = ["observe", "protect"];
|
|
375
|
+
function createResponseError(message, context) {
|
|
376
|
+
return new BotGuardResponseError({
|
|
377
|
+
message,
|
|
378
|
+
context
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function requireRecord(response) {
|
|
382
|
+
if (!isRecord(response)) {
|
|
383
|
+
throw createResponseError("TrueSift API response must be an object.", {
|
|
384
|
+
fieldName: "response",
|
|
385
|
+
expected: "object"
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
return response;
|
|
389
|
+
}
|
|
390
|
+
function requireSuccessTrue(record) {
|
|
391
|
+
if (record["success"] !== true) {
|
|
392
|
+
throw createResponseError(
|
|
393
|
+
"TrueSift API success response must contain success: true.",
|
|
394
|
+
{
|
|
395
|
+
fieldName: "success",
|
|
396
|
+
expected: "true"
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function requireStringField(record, fieldName) {
|
|
402
|
+
const value = record[fieldName];
|
|
403
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
404
|
+
throw createResponseError(
|
|
405
|
+
`TrueSift API response field "${fieldName}" must be a non-empty string.`,
|
|
406
|
+
{
|
|
407
|
+
fieldName,
|
|
408
|
+
expected: "non-empty string"
|
|
409
|
+
}
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
return value.trim();
|
|
413
|
+
}
|
|
414
|
+
function optionalStringField(record, fieldName) {
|
|
415
|
+
const value = record[fieldName];
|
|
416
|
+
if (value === void 0) {
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
419
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
420
|
+
throw createResponseError(
|
|
421
|
+
`TrueSift API response field "${fieldName}" must be a non-empty string when present.`,
|
|
422
|
+
{
|
|
423
|
+
fieldName,
|
|
424
|
+
expected: "non-empty string"
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
return value.trim();
|
|
429
|
+
}
|
|
430
|
+
function requireFiniteNumberField(record, fieldName) {
|
|
431
|
+
const value = record[fieldName];
|
|
432
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
433
|
+
throw createResponseError(
|
|
434
|
+
`TrueSift API response field "${fieldName}" must be a finite number.`,
|
|
435
|
+
{
|
|
436
|
+
fieldName,
|
|
437
|
+
expected: "finite number"
|
|
438
|
+
}
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
return value;
|
|
442
|
+
}
|
|
443
|
+
function optionalStringArrayField(record, fieldName) {
|
|
444
|
+
const value = record[fieldName];
|
|
445
|
+
if (value === void 0) {
|
|
446
|
+
return [];
|
|
447
|
+
}
|
|
448
|
+
if (!Array.isArray(value)) {
|
|
449
|
+
throw createResponseError(
|
|
450
|
+
`TrueSift API response field "${fieldName}" must be an array when present.`,
|
|
451
|
+
{
|
|
452
|
+
fieldName,
|
|
453
|
+
expected: "string[]"
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
const reasonCodes = [];
|
|
458
|
+
for (const item of value) {
|
|
459
|
+
if (typeof item !== "string") {
|
|
460
|
+
throw createResponseError(
|
|
461
|
+
`TrueSift API response field "${fieldName}" must contain only strings.`,
|
|
462
|
+
{
|
|
463
|
+
fieldName,
|
|
464
|
+
expected: "string[]"
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
const trimmedItem = item.trim();
|
|
469
|
+
if (trimmedItem.length > 0) {
|
|
470
|
+
reasonCodes.push(trimmedItem);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return reasonCodes;
|
|
474
|
+
}
|
|
475
|
+
function optionalVerificationModeField(record, fieldName) {
|
|
476
|
+
const value = record[fieldName];
|
|
477
|
+
if (value === void 0) {
|
|
478
|
+
return void 0;
|
|
479
|
+
}
|
|
480
|
+
if (typeof value === "string" && TRUE_SIFT_VERIFICATION_MODES.includes(value)) {
|
|
481
|
+
return value;
|
|
482
|
+
}
|
|
483
|
+
throw createResponseError(
|
|
484
|
+
`TrueSift API response field "${fieldName}" must be a valid verification mode when present.`,
|
|
485
|
+
{
|
|
486
|
+
fieldName,
|
|
487
|
+
expected: "observe | protect"
|
|
488
|
+
}
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
function optionalDecisionField(record, fieldName) {
|
|
492
|
+
const value = record[fieldName];
|
|
493
|
+
if (value === void 0) {
|
|
494
|
+
return void 0;
|
|
495
|
+
}
|
|
496
|
+
return normalizeDecision(value);
|
|
497
|
+
}
|
|
498
|
+
function getDecisionMetadata(record) {
|
|
499
|
+
const mode = optionalVerificationModeField(record, "mode");
|
|
500
|
+
const calculatedDecision = optionalDecisionField(record, "calculatedDecision");
|
|
501
|
+
const effectiveDecision = optionalDecisionField(record, "effectiveDecision");
|
|
502
|
+
return {
|
|
503
|
+
...mode !== void 0 ? { mode } : {},
|
|
504
|
+
...calculatedDecision !== void 0 ? { calculatedDecision } : {},
|
|
505
|
+
...effectiveDecision !== void 0 ? { effectiveDecision } : {}
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function validateCreateChallengeResponse(response) {
|
|
509
|
+
const record = requireRecord(response);
|
|
510
|
+
requireSuccessTrue(record);
|
|
511
|
+
const requestId = optionalStringField(record, "requestId");
|
|
512
|
+
return {
|
|
513
|
+
success: true,
|
|
514
|
+
challengeId: requireStringField(record, "challengeId"),
|
|
515
|
+
challengeToken: requireStringField(record, "challengeToken"),
|
|
516
|
+
expiresAt: requireStringField(record, "expiresAt"),
|
|
517
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
518
|
+
raw: record
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function validateVerifyChallengeResponse(response) {
|
|
522
|
+
const record = requireRecord(response);
|
|
523
|
+
requireSuccessTrue(record);
|
|
524
|
+
const decision = normalizeDecision(requireStringField(record, "decision"));
|
|
525
|
+
const decisionFlags = createDecisionFlags(decision);
|
|
526
|
+
const metadata = getDecisionMetadata(record);
|
|
527
|
+
const challengeId = optionalStringField(record, "challengeId");
|
|
528
|
+
const requestId = optionalStringField(record, "requestId");
|
|
529
|
+
return {
|
|
530
|
+
success: true,
|
|
531
|
+
decision,
|
|
532
|
+
score: requireFiniteNumberField(record, "score"),
|
|
533
|
+
reasonCodes: optionalStringArrayField(record, "reasonCodes"),
|
|
534
|
+
...challengeId !== void 0 ? { challengeId } : {},
|
|
535
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
536
|
+
...metadata,
|
|
537
|
+
...decisionFlags,
|
|
538
|
+
raw: record
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// src/errors/BotGuardConfigError.ts
|
|
543
|
+
var DEFAULT_CONFIG_ERROR_MESSAGE = "TrueSift SDK configuration is invalid.";
|
|
544
|
+
var BotGuardConfigError = class extends BotGuardError {
|
|
545
|
+
constructor(options = {}) {
|
|
546
|
+
const errorOptions = {
|
|
547
|
+
code: "TRUESIFT_CONFIG_ERROR",
|
|
548
|
+
message: options.message ?? DEFAULT_CONFIG_ERROR_MESSAGE,
|
|
549
|
+
...options.context !== void 0 ? { context: options.context } : {},
|
|
550
|
+
...options.cause !== void 0 ? { cause: options.cause } : {}
|
|
551
|
+
};
|
|
552
|
+
super(errorOptions);
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// src/validation/validateChallengeInput.ts
|
|
557
|
+
function validateChallengeString(value, context) {
|
|
558
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
559
|
+
throw new BotGuardConfigError({
|
|
560
|
+
message: `TrueSift challenge field "${context.fieldName}" is required.`,
|
|
561
|
+
context
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return value.trim();
|
|
565
|
+
}
|
|
566
|
+
function resolveChallengeString(inputValue, configValue, fieldName) {
|
|
567
|
+
if (inputValue !== void 0) {
|
|
568
|
+
return validateChallengeString(inputValue, {
|
|
569
|
+
fieldName,
|
|
570
|
+
source: "input"
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
return validateChallengeString(configValue, {
|
|
574
|
+
fieldName,
|
|
575
|
+
source: "config"
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
function validateChallengeInput(input, config) {
|
|
579
|
+
const siteKey = resolveChallengeString(
|
|
580
|
+
input.siteKey,
|
|
581
|
+
config.siteKey,
|
|
582
|
+
"siteKey"
|
|
583
|
+
);
|
|
584
|
+
const origin = resolveChallengeString(
|
|
585
|
+
input.origin,
|
|
586
|
+
config.defaultOrigin,
|
|
587
|
+
"origin"
|
|
588
|
+
);
|
|
589
|
+
const action = resolveChallengeString(
|
|
590
|
+
input.action,
|
|
591
|
+
config.defaultAction,
|
|
592
|
+
"action"
|
|
593
|
+
);
|
|
594
|
+
const path = validateChallengeString(input.path, {
|
|
595
|
+
fieldName: "path",
|
|
596
|
+
source: "input"
|
|
597
|
+
});
|
|
598
|
+
return {
|
|
599
|
+
siteKey,
|
|
600
|
+
origin,
|
|
601
|
+
action,
|
|
602
|
+
path,
|
|
603
|
+
...input.metadata !== void 0 ? { metadata: input.metadata } : {}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// src/validation/validateVerifyInput.ts
|
|
608
|
+
function validateVerifyString(value, context) {
|
|
609
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
610
|
+
throw new BotGuardConfigError({
|
|
611
|
+
message: `TrueSift verify field "${context.fieldName}" is required.`,
|
|
612
|
+
context
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
return value.trim();
|
|
616
|
+
}
|
|
617
|
+
function resolveVerifyString(inputValue, configValue, fieldName) {
|
|
618
|
+
if (inputValue !== void 0) {
|
|
619
|
+
return validateVerifyString(inputValue, {
|
|
620
|
+
fieldName,
|
|
621
|
+
source: "input"
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
return validateVerifyString(configValue, {
|
|
625
|
+
fieldName,
|
|
626
|
+
source: "config"
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
function normalizeClientSignals(clientSignals) {
|
|
630
|
+
if (clientSignals === void 0) {
|
|
631
|
+
return void 0;
|
|
632
|
+
}
|
|
633
|
+
const elapsedMs = typeof clientSignals.elapsedMs === "number" && Number.isFinite(clientSignals.elapsedMs) && clientSignals.elapsedMs >= 0 ? Math.trunc(clientSignals.elapsedMs) : void 0;
|
|
634
|
+
const honeypotValue = typeof clientSignals.honeypotValue === "string" ? clientSignals.honeypotValue.slice(0, 500) : void 0;
|
|
635
|
+
const normalizedSignals = {
|
|
636
|
+
...elapsedMs !== void 0 ? { elapsedMs } : {},
|
|
637
|
+
...honeypotValue !== void 0 ? { honeypotValue } : {}
|
|
638
|
+
};
|
|
639
|
+
return Object.keys(normalizedSignals).length > 0 ? normalizedSignals : void 0;
|
|
640
|
+
}
|
|
641
|
+
function validateVerifyInput(input, config) {
|
|
642
|
+
const siteKey = resolveVerifyString(input.siteKey, config.siteKey, "siteKey");
|
|
643
|
+
const secretKey = resolveVerifyString(
|
|
644
|
+
input.secretKey,
|
|
645
|
+
config.secretKey,
|
|
646
|
+
"secretKey"
|
|
647
|
+
);
|
|
648
|
+
const challengeId = validateVerifyString(input.challengeId, {
|
|
649
|
+
fieldName: "challengeId",
|
|
650
|
+
source: "input"
|
|
651
|
+
});
|
|
652
|
+
const challengeToken = validateVerifyString(input.challengeToken, {
|
|
653
|
+
fieldName: "challengeToken",
|
|
654
|
+
source: "input"
|
|
655
|
+
});
|
|
656
|
+
const origin = resolveVerifyString(
|
|
657
|
+
input.origin,
|
|
658
|
+
config.defaultOrigin,
|
|
659
|
+
"origin"
|
|
660
|
+
);
|
|
661
|
+
const action = resolveVerifyString(
|
|
662
|
+
input.action,
|
|
663
|
+
config.defaultAction,
|
|
664
|
+
"action"
|
|
665
|
+
);
|
|
666
|
+
const path = validateVerifyString(input.path, {
|
|
667
|
+
fieldName: "path",
|
|
668
|
+
source: "input"
|
|
669
|
+
});
|
|
670
|
+
const clientSignals = normalizeClientSignals(input.clientSignals);
|
|
671
|
+
return {
|
|
672
|
+
siteKey,
|
|
673
|
+
secretKey,
|
|
674
|
+
challengeId,
|
|
675
|
+
challengeToken,
|
|
676
|
+
origin,
|
|
677
|
+
action,
|
|
678
|
+
path,
|
|
679
|
+
...clientSignals !== void 0 ? { clientSignals } : {},
|
|
680
|
+
...input.metadata !== void 0 ? { metadata: input.metadata } : {}
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// src/client/BotGuardClient.ts
|
|
685
|
+
var BotGuardClient = class {
|
|
686
|
+
config;
|
|
687
|
+
constructor(config) {
|
|
688
|
+
this.config = config;
|
|
689
|
+
}
|
|
690
|
+
async createChallenge(input = {}) {
|
|
691
|
+
const payload = validateChallengeInput(input, this.config);
|
|
692
|
+
const url = buildBotGuardUrl(this.config.apiBaseUrl, "challenge");
|
|
693
|
+
const response = await botGuardFetch(this.config, {
|
|
694
|
+
url,
|
|
695
|
+
body: payload
|
|
696
|
+
});
|
|
697
|
+
return validateCreateChallengeResponse(response);
|
|
698
|
+
}
|
|
699
|
+
async verifyChallenge(input) {
|
|
700
|
+
const payload = validateVerifyInput(input, this.config);
|
|
701
|
+
const url = buildBotGuardUrl(this.config.apiBaseUrl, "verify");
|
|
702
|
+
const response = await botGuardFetch(this.config, {
|
|
703
|
+
url,
|
|
704
|
+
body: payload
|
|
705
|
+
});
|
|
706
|
+
return validateVerifyChallengeResponse(response);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
var TrueSiftClient = class extends BotGuardClient {
|
|
710
|
+
constructor(config) {
|
|
711
|
+
super(config);
|
|
712
|
+
}
|
|
713
|
+
async createChallenge(input = {}) {
|
|
714
|
+
return super.createChallenge(input);
|
|
715
|
+
}
|
|
716
|
+
async verifyChallenge(input) {
|
|
717
|
+
return super.verifyChallenge(input);
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// src/utils/redactBotGuardConfig.ts
|
|
722
|
+
var REDACTED_VALUE = "[REDACTED]";
|
|
723
|
+
var SENSITIVE_KEY_PATTERNS = [
|
|
724
|
+
"secret",
|
|
725
|
+
"token",
|
|
726
|
+
"authorization",
|
|
727
|
+
"auth",
|
|
728
|
+
"credential",
|
|
729
|
+
"password",
|
|
730
|
+
"cookie",
|
|
731
|
+
"set-cookie",
|
|
732
|
+
"api-key",
|
|
733
|
+
"apikey",
|
|
734
|
+
"private"
|
|
735
|
+
];
|
|
736
|
+
function redactSensitiveValue(value) {
|
|
737
|
+
if (typeof value === "string" && value.length > 0) {
|
|
738
|
+
return REDACTED_VALUE;
|
|
739
|
+
}
|
|
740
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
741
|
+
return value;
|
|
742
|
+
}
|
|
743
|
+
if (value === null || value === void 0) {
|
|
744
|
+
return value;
|
|
745
|
+
}
|
|
746
|
+
if (Array.isArray(value)) {
|
|
747
|
+
return value.map((item) => redactSensitiveValue(item));
|
|
748
|
+
}
|
|
749
|
+
if (typeof value === "object") {
|
|
750
|
+
return redactSensitiveRecord(value);
|
|
751
|
+
}
|
|
752
|
+
return REDACTED_VALUE;
|
|
753
|
+
}
|
|
754
|
+
function isSensitiveKey(key) {
|
|
755
|
+
const normalizedKey = key.trim().toLowerCase();
|
|
756
|
+
return SENSITIVE_KEY_PATTERNS.some(
|
|
757
|
+
(pattern) => normalizedKey.includes(pattern)
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
function redactSensitiveRecord(record) {
|
|
761
|
+
const redactedRecord = {};
|
|
762
|
+
for (const [key, value] of Object.entries(record)) {
|
|
763
|
+
redactedRecord[key] = isSensitiveKey(key) ? REDACTED_VALUE : redactSensitiveValue(value);
|
|
764
|
+
}
|
|
765
|
+
return redactedRecord;
|
|
766
|
+
}
|
|
767
|
+
function redactTrueSiftClientConfig(config) {
|
|
768
|
+
return {
|
|
769
|
+
...typeof config.apiBaseUrl === "string" ? { apiBaseUrl: config.apiBaseUrl } : {},
|
|
770
|
+
...typeof config.siteKey === "string" ? { siteKey: config.siteKey } : {},
|
|
771
|
+
...typeof config.defaultAction === "string" ? { defaultAction: config.defaultAction } : {},
|
|
772
|
+
...typeof config.defaultOrigin === "string" ? { defaultOrigin: config.defaultOrigin } : {},
|
|
773
|
+
...typeof config.timeoutMs === "number" ? { timeoutMs: config.timeoutMs } : {},
|
|
774
|
+
hasSecretKey: typeof config.secretKey === "string" && config.secretKey.length > 0,
|
|
775
|
+
hasCustomFetch: typeof config.fetchImpl === "function",
|
|
776
|
+
hasLogger: typeof config.logger === "object" && config.logger !== null
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function redactBotGuardConfig(config) {
|
|
780
|
+
return redactTrueSiftClientConfig(config);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// src/validation/validateClientConfig.ts
|
|
784
|
+
var DEFAULT_TIMEOUT_MS = 2500;
|
|
785
|
+
var MIN_TIMEOUT_MS = 100;
|
|
786
|
+
var MAX_TIMEOUT_MS = 3e4;
|
|
787
|
+
function validateRequiredString(value, fieldName, config) {
|
|
788
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
789
|
+
throw new BotGuardConfigError({
|
|
790
|
+
message: `TrueSift SDK configuration field "${fieldName}" is required.`,
|
|
791
|
+
context: {
|
|
792
|
+
fieldName,
|
|
793
|
+
config: redactBotGuardConfig(config)
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
return value.trim();
|
|
798
|
+
}
|
|
799
|
+
function validateOptionalString(value, fieldName, config) {
|
|
800
|
+
if (value === void 0) {
|
|
801
|
+
return void 0;
|
|
802
|
+
}
|
|
803
|
+
if (typeof value !== "string") {
|
|
804
|
+
throw new BotGuardConfigError({
|
|
805
|
+
message: `TrueSift SDK configuration field "${fieldName}" must be a string.`,
|
|
806
|
+
context: {
|
|
807
|
+
fieldName,
|
|
808
|
+
config: redactBotGuardConfig(config)
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
const trimmedValue = value.trim();
|
|
813
|
+
return trimmedValue.length > 0 ? trimmedValue : void 0;
|
|
814
|
+
}
|
|
815
|
+
function validateTimeoutMs(value, config) {
|
|
816
|
+
if (value === void 0) {
|
|
817
|
+
return DEFAULT_TIMEOUT_MS;
|
|
818
|
+
}
|
|
819
|
+
if (!Number.isFinite(value)) {
|
|
820
|
+
throw new BotGuardConfigError({
|
|
821
|
+
message: 'TrueSift SDK configuration field "timeoutMs" must be finite.',
|
|
822
|
+
context: {
|
|
823
|
+
fieldName: "timeoutMs",
|
|
824
|
+
config: redactBotGuardConfig(config)
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
if (!Number.isInteger(value)) {
|
|
829
|
+
throw new BotGuardConfigError({
|
|
830
|
+
message: 'TrueSift SDK configuration field "timeoutMs" must be an integer.',
|
|
831
|
+
context: {
|
|
832
|
+
fieldName: "timeoutMs",
|
|
833
|
+
config: redactBotGuardConfig(config)
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
if (value < MIN_TIMEOUT_MS || value > MAX_TIMEOUT_MS) {
|
|
838
|
+
throw new BotGuardConfigError({
|
|
839
|
+
message: `TrueSift SDK configuration field "timeoutMs" must be between ${MIN_TIMEOUT_MS} and ${MAX_TIMEOUT_MS}.`,
|
|
840
|
+
context: {
|
|
841
|
+
fieldName: "timeoutMs",
|
|
842
|
+
minTimeoutMs: MIN_TIMEOUT_MS,
|
|
843
|
+
maxTimeoutMs: MAX_TIMEOUT_MS,
|
|
844
|
+
config: redactBotGuardConfig(config)
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
return value;
|
|
849
|
+
}
|
|
850
|
+
function validateApiBaseUrl(value, config) {
|
|
851
|
+
try {
|
|
852
|
+
const url = new URL(value);
|
|
853
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
854
|
+
throw new BotGuardConfigError({
|
|
855
|
+
message: 'TrueSift SDK configuration field "apiBaseUrl" must use http or https.',
|
|
856
|
+
context: {
|
|
857
|
+
fieldName: "apiBaseUrl",
|
|
858
|
+
config: redactBotGuardConfig(config)
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
return url.toString().replace(/\/$/, "");
|
|
863
|
+
} catch (error) {
|
|
864
|
+
if (error instanceof BotGuardConfigError) {
|
|
865
|
+
throw error;
|
|
866
|
+
}
|
|
867
|
+
throw new BotGuardConfigError({
|
|
868
|
+
message: 'TrueSift SDK configuration field "apiBaseUrl" must be a valid URL.',
|
|
869
|
+
context: {
|
|
870
|
+
fieldName: "apiBaseUrl",
|
|
871
|
+
config: redactBotGuardConfig(config)
|
|
872
|
+
},
|
|
873
|
+
cause: error
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function validateClientConfig(config) {
|
|
878
|
+
const rawApiBaseUrl = validateRequiredString(
|
|
879
|
+
config.apiBaseUrl,
|
|
880
|
+
"apiBaseUrl",
|
|
881
|
+
config
|
|
882
|
+
);
|
|
883
|
+
const apiBaseUrl = validateApiBaseUrl(rawApiBaseUrl, config);
|
|
884
|
+
const siteKey = validateRequiredString(config.siteKey, "siteKey", config);
|
|
885
|
+
const secretKey = validateRequiredString(
|
|
886
|
+
config.secretKey,
|
|
887
|
+
"secretKey",
|
|
888
|
+
config
|
|
889
|
+
);
|
|
890
|
+
const defaultAction = validateOptionalString(
|
|
891
|
+
config.defaultAction,
|
|
892
|
+
"defaultAction",
|
|
893
|
+
config
|
|
894
|
+
);
|
|
895
|
+
const defaultOrigin = validateOptionalString(
|
|
896
|
+
config.defaultOrigin,
|
|
897
|
+
"defaultOrigin",
|
|
898
|
+
config
|
|
899
|
+
);
|
|
900
|
+
const timeoutMs = validateTimeoutMs(config.timeoutMs, config);
|
|
901
|
+
return {
|
|
902
|
+
apiBaseUrl,
|
|
903
|
+
siteKey,
|
|
904
|
+
secretKey,
|
|
905
|
+
...defaultAction !== void 0 ? { defaultAction } : {},
|
|
906
|
+
...defaultOrigin !== void 0 ? { defaultOrigin } : {},
|
|
907
|
+
timeoutMs,
|
|
908
|
+
fetchImpl: config.fetchImpl ?? fetch,
|
|
909
|
+
...config.logger !== void 0 ? { logger: config.logger } : {}
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// src/client/createBotGuardClient.ts
|
|
914
|
+
function createBotGuardClient(config) {
|
|
915
|
+
return new BotGuardClient(validateClientConfig(config));
|
|
916
|
+
}
|
|
917
|
+
function createTrueSiftClient(config) {
|
|
918
|
+
return new TrueSiftClient(validateClientConfig(config));
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
export { BotGuardApiError, BotGuardAuthError, BotGuardClient, BotGuardConfigError, BotGuardError, BotGuardRequestError, BotGuardResponseError, BotGuardTimeoutError, REDACTED_VALUE, BotGuardApiError as TrueSiftApiError, BotGuardAuthError as TrueSiftAuthError, TrueSiftClient, BotGuardConfigError as TrueSiftConfigError, BotGuardError as TrueSiftError, BotGuardRequestError as TrueSiftRequestError, BotGuardResponseError as TrueSiftResponseError, BotGuardTimeoutError as TrueSiftTimeoutError, createBotGuardClient, createBotGuardDecisionFlags, createDecisionFlags, createTrueSiftClient, isAllowed, isAllowedDecision, isBlocked, isBlockedDecision, isBotGuardAllowed, isBotGuardAllowedDecision, isBotGuardBlocked, isBotGuardBlockedDecision, isBotGuardDecision, isBotGuardReview, isBotGuardReviewDecision, isReview, isReviewDecision, isSensitiveKey, isTrueSiftDecision, normalizeBotGuardDecision, normalizeDecision, redactBotGuardConfig, redactSensitiveRecord, redactSensitiveValue, redactTrueSiftClientConfig };
|