@vesant-sdk/fraud 0.1.1-dev.0d9ee60 → 0.1.1-dev.5d49984
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/README.md +196 -14
- package/dist/index.d.mts +123 -11
- package/dist/index.d.ts +123 -11
- package/dist/index.js +197 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -120,7 +120,60 @@ var TransactionStatus = {
|
|
|
120
120
|
Pending: "$pending"
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
+
// src/types/rule-signals.ts
|
|
124
|
+
var LOGIN_RULE_SIGNAL_KEYS = ["ip_country_mismatch"];
|
|
125
|
+
var UPDATE_ACCOUNT_RULE_SIGNAL_KEYS = [
|
|
126
|
+
"two_fa_enabled",
|
|
127
|
+
"two_fa_disabled",
|
|
128
|
+
"two_fa_method_changed"
|
|
129
|
+
];
|
|
130
|
+
var TRANSACTION_RULE_SIGNAL_KEYS = [
|
|
131
|
+
"payment_method",
|
|
132
|
+
"is_first_deposit",
|
|
133
|
+
"cumulative_deposit_amount",
|
|
134
|
+
"deposit_count",
|
|
135
|
+
"failed_deposit_count",
|
|
136
|
+
"is_first_withdrawal",
|
|
137
|
+
"withdrawal_method_differs",
|
|
138
|
+
"cumulative_withdrawal_amount",
|
|
139
|
+
"withdrawal_count",
|
|
140
|
+
"hours_since_last_deposit",
|
|
141
|
+
"days_since_last_activity",
|
|
142
|
+
"hours_since_account_creation"
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
// src/normalization/sift-keys.ts
|
|
146
|
+
function siftKey(key) {
|
|
147
|
+
return key.startsWith("$") ? key : `$${key}`;
|
|
148
|
+
}
|
|
149
|
+
function toSiftKeyedObject(value) {
|
|
150
|
+
if (value === null || value === void 0) {
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
if (Array.isArray(value)) {
|
|
154
|
+
return value.map((item) => toSiftKeyedObject(item));
|
|
155
|
+
}
|
|
156
|
+
if (typeof value === "object") {
|
|
157
|
+
const out = {};
|
|
158
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
159
|
+
out[siftKey(key)] = toSiftKeyedObject(nested);
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
|
|
123
166
|
// src/normalization/normalize.ts
|
|
167
|
+
var BASE_SIFT_FIELD_KEYS = [
|
|
168
|
+
"session_id",
|
|
169
|
+
"user_email",
|
|
170
|
+
"name",
|
|
171
|
+
"phone",
|
|
172
|
+
"sift_payment_method",
|
|
173
|
+
"payment_methods",
|
|
174
|
+
"billing_address",
|
|
175
|
+
"app"
|
|
176
|
+
];
|
|
124
177
|
function mergeMetadata(base, extras) {
|
|
125
178
|
return { ...base, ...extras };
|
|
126
179
|
}
|
|
@@ -143,17 +196,82 @@ function applySiftMetadata(body, metadata, siftMetadata, onlyWhenNonEmpty = fals
|
|
|
143
196
|
}
|
|
144
197
|
return body;
|
|
145
198
|
}
|
|
199
|
+
function collectRuleSignals(request, keys) {
|
|
200
|
+
const signals = {};
|
|
201
|
+
for (const key of keys) {
|
|
202
|
+
const value = request[key];
|
|
203
|
+
if (value !== void 0) {
|
|
204
|
+
signals[key] = value;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return signals;
|
|
208
|
+
}
|
|
209
|
+
function buildBaseSiftMetadata(body) {
|
|
210
|
+
const {
|
|
211
|
+
session_id,
|
|
212
|
+
user_email,
|
|
213
|
+
name,
|
|
214
|
+
phone,
|
|
215
|
+
sift_payment_method,
|
|
216
|
+
payment_methods,
|
|
217
|
+
billing_address,
|
|
218
|
+
app,
|
|
219
|
+
metadata
|
|
220
|
+
} = body;
|
|
221
|
+
const siftMetadata = {
|
|
222
|
+
...metadata ?? {}
|
|
223
|
+
};
|
|
224
|
+
if (session_id !== void 0) siftMetadata.$session_id = session_id;
|
|
225
|
+
if (user_email !== void 0) siftMetadata.$user_email = user_email;
|
|
226
|
+
if (name !== void 0) siftMetadata.$name = name;
|
|
227
|
+
if (phone !== void 0) siftMetadata.$phone = phone;
|
|
228
|
+
if (sift_payment_method !== void 0) {
|
|
229
|
+
siftMetadata.$payment_method = toSiftKeyedObject(sift_payment_method);
|
|
230
|
+
}
|
|
231
|
+
if (payment_methods !== void 0) {
|
|
232
|
+
siftMetadata.$payment_methods = toSiftKeyedObject(payment_methods);
|
|
233
|
+
}
|
|
234
|
+
if (billing_address !== void 0) {
|
|
235
|
+
siftMetadata.$billing_address = toSiftKeyedObject(billing_address);
|
|
236
|
+
}
|
|
237
|
+
if (app !== void 0) siftMetadata.$app = toSiftKeyedObject(app);
|
|
238
|
+
return siftMetadata;
|
|
239
|
+
}
|
|
240
|
+
function normalizeBaseSiftFields(body) {
|
|
241
|
+
const siftMetadata = buildBaseSiftMetadata(body);
|
|
242
|
+
const stripped = stripSdkOnlyFields(body, [...BASE_SIFT_FIELD_KEYS]);
|
|
243
|
+
if (Object.keys(siftMetadata).length > 0) {
|
|
244
|
+
stripped.metadata = siftMetadata;
|
|
245
|
+
}
|
|
246
|
+
return stripped;
|
|
247
|
+
}
|
|
248
|
+
function applyRuleSignals(body, request, keys, stripKeys) {
|
|
249
|
+
const ruleSignals = collectRuleSignals(request, keys);
|
|
250
|
+
const stripped = stripSdkOnlyFields(body, [...stripKeys]);
|
|
251
|
+
if (Object.keys(ruleSignals).length > 0) {
|
|
252
|
+
stripped.metadata = mergeMetadata(
|
|
253
|
+
stripped.metadata,
|
|
254
|
+
ruleSignals
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return stripped;
|
|
258
|
+
}
|
|
146
259
|
function normalizeUpdatePassword(request) {
|
|
147
260
|
const { password_reason, password_status, metadata, ...rest } = request;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
261
|
+
let body = createStrippedBody(rest, metadata, [
|
|
262
|
+
"password_reason",
|
|
263
|
+
"password_status"
|
|
264
|
+
]);
|
|
265
|
+
const siftMetadata = {
|
|
266
|
+
$reason: password_reason ?? PasswordUpdateReason.UserUpdate,
|
|
267
|
+
$status: password_status ?? PasswordUpdateStatus.Success
|
|
268
|
+
};
|
|
269
|
+
body = applySiftMetadata(body, metadata, siftMetadata);
|
|
270
|
+
return normalizeBaseSiftFields(body);
|
|
153
271
|
}
|
|
154
272
|
function normalizeWager(request) {
|
|
155
273
|
const { wager_type, wager_status, wager_event_type, wager_event_name, wager_event_id, metadata, ...rest } = request;
|
|
156
|
-
|
|
274
|
+
let body = createStrippedBody(rest, metadata, [
|
|
157
275
|
"wager_type",
|
|
158
276
|
"wager_status",
|
|
159
277
|
"wager_event_type",
|
|
@@ -164,17 +282,19 @@ function normalizeWager(request) {
|
|
|
164
282
|
$wager_type: wager_type,
|
|
165
283
|
$wager_status: wager_status
|
|
166
284
|
};
|
|
167
|
-
if (wager_event_type) siftMetadata
|
|
168
|
-
if (wager_event_name) siftMetadata
|
|
169
|
-
if (wager_event_id) siftMetadata
|
|
170
|
-
|
|
285
|
+
if (wager_event_type) siftMetadata.$wager_event_type = wager_event_type;
|
|
286
|
+
if (wager_event_name) siftMetadata.$wager_event_name = wager_event_name;
|
|
287
|
+
if (wager_event_id) siftMetadata.$wager_event_id = wager_event_id;
|
|
288
|
+
body = applySiftMetadata(body, metadata, siftMetadata);
|
|
289
|
+
return normalizeBaseSiftFields(body);
|
|
171
290
|
}
|
|
172
291
|
function normalizeLogin(request) {
|
|
173
292
|
const { login_status, login_failure_reason, metadata, ...rest } = request;
|
|
174
293
|
const effectiveStatus = login_status ?? LoginStatus.Success;
|
|
175
|
-
|
|
294
|
+
let body = createStrippedBody(rest, metadata, [
|
|
176
295
|
"login_status",
|
|
177
|
-
"login_failure_reason"
|
|
296
|
+
"login_failure_reason",
|
|
297
|
+
...LOGIN_RULE_SIGNAL_KEYS
|
|
178
298
|
]);
|
|
179
299
|
const siftMetadata = {
|
|
180
300
|
$login_status: effectiveStatus
|
|
@@ -182,14 +302,22 @@ function normalizeLogin(request) {
|
|
|
182
302
|
if (effectiveStatus === LoginStatus.Failure && login_failure_reason) {
|
|
183
303
|
siftMetadata.$failure_reason = login_failure_reason;
|
|
184
304
|
}
|
|
185
|
-
|
|
305
|
+
body = applySiftMetadata(body, metadata, siftMetadata);
|
|
306
|
+
body = applyRuleSignals(
|
|
307
|
+
body,
|
|
308
|
+
request,
|
|
309
|
+
LOGIN_RULE_SIGNAL_KEYS,
|
|
310
|
+
[]
|
|
311
|
+
);
|
|
312
|
+
return normalizeBaseSiftFields(body);
|
|
186
313
|
}
|
|
187
314
|
function normalizeTransaction(request) {
|
|
188
315
|
const { transaction_status, decline_category, transfer_recipient_user_id, metadata, ...rest } = request;
|
|
189
|
-
|
|
316
|
+
let body = createStrippedBody(rest, metadata, [
|
|
190
317
|
"transaction_status",
|
|
191
318
|
"decline_category",
|
|
192
|
-
"transfer_recipient_user_id"
|
|
319
|
+
"transfer_recipient_user_id",
|
|
320
|
+
...TRANSACTION_RULE_SIGNAL_KEYS
|
|
193
321
|
]);
|
|
194
322
|
const siftMetadata = {};
|
|
195
323
|
if (transaction_status) siftMetadata.$transaction_status = transaction_status;
|
|
@@ -197,7 +325,30 @@ function normalizeTransaction(request) {
|
|
|
197
325
|
if (transfer_recipient_user_id) {
|
|
198
326
|
siftMetadata.$transfer_recipient_user_id = transfer_recipient_user_id;
|
|
199
327
|
}
|
|
200
|
-
|
|
328
|
+
body = applySiftMetadata(body, metadata, siftMetadata, true);
|
|
329
|
+
body = applyRuleSignals(
|
|
330
|
+
body,
|
|
331
|
+
request,
|
|
332
|
+
TRANSACTION_RULE_SIGNAL_KEYS,
|
|
333
|
+
[]
|
|
334
|
+
);
|
|
335
|
+
return normalizeBaseSiftFields(body);
|
|
336
|
+
}
|
|
337
|
+
function normalizeUpdateAccount(request) {
|
|
338
|
+
const { metadata, ...rest } = request;
|
|
339
|
+
let body = createStrippedBody(rest, metadata, [
|
|
340
|
+
...UPDATE_ACCOUNT_RULE_SIGNAL_KEYS
|
|
341
|
+
]);
|
|
342
|
+
body = applyRuleSignals(
|
|
343
|
+
body,
|
|
344
|
+
request,
|
|
345
|
+
UPDATE_ACCOUNT_RULE_SIGNAL_KEYS,
|
|
346
|
+
[]
|
|
347
|
+
);
|
|
348
|
+
return normalizeBaseSiftFields(body);
|
|
349
|
+
}
|
|
350
|
+
function normalizeDefault(request) {
|
|
351
|
+
return normalizeBaseSiftFields({ ...request });
|
|
201
352
|
}
|
|
202
353
|
function normalizeScoreRequestForApi(request) {
|
|
203
354
|
switch (request.event_type) {
|
|
@@ -209,8 +360,10 @@ function normalizeScoreRequestForApi(request) {
|
|
|
209
360
|
return normalizeLogin(request);
|
|
210
361
|
case "$transaction":
|
|
211
362
|
return normalizeTransaction(request);
|
|
363
|
+
case "$update_account":
|
|
364
|
+
return normalizeUpdateAccount(request);
|
|
212
365
|
default:
|
|
213
|
-
return
|
|
366
|
+
return normalizeDefault(request);
|
|
214
367
|
}
|
|
215
368
|
}
|
|
216
369
|
|
|
@@ -251,10 +404,20 @@ function isSupportedFraudEventType(eventType) {
|
|
|
251
404
|
}
|
|
252
405
|
|
|
253
406
|
// src/types/metadata.ts
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
407
|
+
var TYPED_SIFT_METADATA_KEYS = {
|
|
408
|
+
session_id: "$session_id",
|
|
409
|
+
user_email: "$user_email",
|
|
410
|
+
name: "$name",
|
|
411
|
+
phone: "$phone",
|
|
412
|
+
sift_payment_method: "$payment_method",
|
|
413
|
+
billing_address: "$billing_address",
|
|
414
|
+
payment_methods: "$payment_methods",
|
|
415
|
+
app: "$app"
|
|
416
|
+
};
|
|
417
|
+
function findMetadataConflictWithTypedFields(metadata, request) {
|
|
418
|
+
for (const [field, metaKey] of Object.entries(TYPED_SIFT_METADATA_KEYS)) {
|
|
419
|
+
if (request[field] !== void 0 && metadata[metaKey] !== void 0) {
|
|
420
|
+
return metaKey;
|
|
258
421
|
}
|
|
259
422
|
}
|
|
260
423
|
return void 0;
|
|
@@ -280,12 +443,15 @@ function assertPositiveAmount(amount, field, errors, prefix) {
|
|
|
280
443
|
errors.push(`${prefix}${field} must be greater than 0`);
|
|
281
444
|
}
|
|
282
445
|
}
|
|
283
|
-
function validateMetadata(metadata, errors, prefix) {
|
|
446
|
+
function validateMetadata(metadata, request, errors, prefix) {
|
|
284
447
|
if (!metadata) return;
|
|
285
|
-
const
|
|
286
|
-
|
|
448
|
+
const conflictKey = findMetadataConflictWithTypedFields(
|
|
449
|
+
metadata,
|
|
450
|
+
request
|
|
451
|
+
);
|
|
452
|
+
if (conflictKey) {
|
|
287
453
|
errors.push(
|
|
288
|
-
`${prefix}metadata
|
|
454
|
+
`${prefix}metadata.${conflictKey} conflicts with a typed request field that maps to the same key; omit metadata.${conflictKey} or remove the typed field`
|
|
289
455
|
);
|
|
290
456
|
}
|
|
291
457
|
}
|
|
@@ -295,7 +461,7 @@ function validateBase(request, errors, prefix) {
|
|
|
295
461
|
assertNonEmpty(request.customer_id, "customer_id", errors, prefix);
|
|
296
462
|
assertNonEmpty(request.sift_user_id, "sift_user_id", errors, prefix);
|
|
297
463
|
assertNonEmpty(request.event_type, "event_type", errors, prefix);
|
|
298
|
-
validateMetadata(request.metadata, errors, prefix);
|
|
464
|
+
validateMetadata(request.metadata, request, errors, prefix);
|
|
299
465
|
}
|
|
300
466
|
function validateLogin(request, errors, prefix) {
|
|
301
467
|
assertEnum(request.login_status, SiftLoginStatusValues, "login_status", errors, prefix);
|
|
@@ -321,9 +487,6 @@ function validateUpdatePassword(request, errors, prefix) {
|
|
|
321
487
|
errors,
|
|
322
488
|
prefix
|
|
323
489
|
);
|
|
324
|
-
if (!request.password_reason) {
|
|
325
|
-
errors.push(`${prefix}password_reason is required`);
|
|
326
|
-
}
|
|
327
490
|
assertEnum(
|
|
328
491
|
request.password_status,
|
|
329
492
|
SiftPasswordUpdateStatusValues,
|
|
@@ -331,9 +494,6 @@ function validateUpdatePassword(request, errors, prefix) {
|
|
|
331
494
|
errors,
|
|
332
495
|
prefix
|
|
333
496
|
);
|
|
334
|
-
if (!request.password_status) {
|
|
335
|
-
errors.push(`${prefix}password_status is required`);
|
|
336
|
-
}
|
|
337
497
|
}
|
|
338
498
|
function validateTransaction(request, errors, prefix) {
|
|
339
499
|
assertPositiveAmount(request.amount, "amount", errors, prefix);
|
|
@@ -466,6 +626,6 @@ var FraudClient = class extends BaseClient {
|
|
|
466
626
|
}
|
|
467
627
|
};
|
|
468
628
|
|
|
469
|
-
export { CHARGEBACK_FRAUD_EVENT_TYPE, ChargebackReason, ChargebackState, FraudClient, LoginStatus, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, SiftChargebackReasonValues, SiftChargebackStateValues, SiftLoginFailureReasonValues, SiftLoginStatusValues, SiftPasswordUpdateReasonValues, SiftPasswordUpdateStatusValues, SiftTransactionStatusValues, SiftTransactionTypeValues, SiftWagerStatusValues, TransactionStatus, TransactionType, WagerStatus, buildScoreRequestPreview,
|
|
629
|
+
export { CHARGEBACK_FRAUD_EVENT_TYPE, ChargebackReason, ChargebackState, FraudClient, LOGIN_RULE_SIGNAL_KEYS, LoginStatus, PLANNED_FRAUD_EVENT_TYPES, PasswordUpdateReason, PasswordUpdateStatus, SCORED_FRAUD_EVENT_TYPES, SUPPORTED_FRAUD_EVENT_TYPES, SiftChargebackReasonValues, SiftChargebackStateValues, SiftLoginFailureReasonValues, SiftLoginStatusValues, SiftPasswordUpdateReasonValues, SiftPasswordUpdateStatusValues, SiftTransactionStatusValues, SiftTransactionTypeValues, SiftWagerStatusValues, TRANSACTION_RULE_SIGNAL_KEYS, TYPED_SIFT_METADATA_KEYS, TransactionStatus, TransactionType, UPDATE_ACCOUNT_RULE_SIGNAL_KEYS, WagerStatus, buildScoreRequestPreview, findMetadataConflictWithTypedFields, isPlannedFraudEventType, isSupportedFraudEventType, normalizeScoreRequestForApi, validateScoreRequest };
|
|
470
630
|
//# sourceMappingURL=index.mjs.map
|
|
471
631
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/enums.ts","../src/normalization/normalize.ts","../src/normalization/preview.ts","../src/types/events.ts","../src/types/metadata.ts","../src/validation/helpers.ts","../src/validation/rules.ts","../src/client.ts"],"names":["ValidationError"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Sift-aligned enum types and const objects for fraud scoring requests.\n */\n\nexport type SiftTransactionType =\n | '$sale'\n | '$authorize'\n | '$capture'\n | '$void'\n | '$refund'\n | '$deposit'\n | '$withdrawal'\n | '$transfer'\n | '$buy'\n | '$sell'\n | '$send'\n | '$receive';\n\nexport const SiftTransactionTypeValues = [\n '$sale',\n '$authorize',\n '$capture',\n '$void',\n '$refund',\n '$deposit',\n '$withdrawal',\n '$transfer',\n '$buy',\n '$sell',\n '$send',\n '$receive',\n] as const satisfies readonly SiftTransactionType[];\n\nexport const TransactionType = {\n Sale: '$sale',\n Authorize: '$authorize',\n Capture: '$capture',\n Void: '$void',\n Refund: '$refund',\n Deposit: '$deposit',\n Withdrawal: '$withdrawal',\n Transfer: '$transfer',\n Buy: '$buy',\n Sell: '$sell',\n Send: '$send',\n Receive: '$receive',\n} as const satisfies Record<string, SiftTransactionType>;\n\nexport type SiftChargebackState =\n | '$received'\n | '$accepted'\n | '$disputed'\n | '$won'\n | '$lost';\n\nexport const SiftChargebackStateValues = [\n '$received',\n '$accepted',\n '$disputed',\n '$won',\n '$lost',\n] as const satisfies readonly SiftChargebackState[];\n\nexport const ChargebackState = {\n Received: '$received',\n Accepted: '$accepted',\n Disputed: '$disputed',\n Won: '$won',\n Lost: '$lost',\n} as const satisfies Record<string, SiftChargebackState>;\n\nexport type SiftChargebackReason =\n | '$fraud'\n | '$duplicate'\n | '$product_not_received'\n | '$product_unacceptable'\n | '$authorization'\n | '$consumer_disputes'\n | '$processing_errors'\n | '$cancel_subscription'\n | '$friendly_fraud'\n | '$ach_return'\n | '$ach_reversal'\n | '$other';\n\nexport const SiftChargebackReasonValues = [\n '$fraud',\n '$duplicate',\n '$product_not_received',\n '$product_unacceptable',\n '$authorization',\n '$consumer_disputes',\n '$processing_errors',\n '$cancel_subscription',\n '$friendly_fraud',\n '$ach_return',\n '$ach_reversal',\n '$other',\n] as const satisfies readonly SiftChargebackReason[];\n\nexport const ChargebackReason = {\n Fraud: '$fraud',\n Duplicate: '$duplicate',\n ProductNotReceived: '$product_not_received',\n ProductUnacceptable: '$product_unacceptable',\n Authorization: '$authorization',\n ConsumerDisputes: '$consumer_disputes',\n ProcessingErrors: '$processing_errors',\n CancelSubscription: '$cancel_subscription',\n FriendlyFraud: '$friendly_fraud',\n AchReturn: '$ach_return',\n AchReversal: '$ach_reversal',\n Other: '$other',\n} as const satisfies Record<string, SiftChargebackReason>;\n\nexport type SiftLoginStatus = '$success' | '$failure';\n\nexport const SiftLoginStatusValues = ['$success', '$failure'] as const satisfies readonly SiftLoginStatus[];\n\nexport const LoginStatus = {\n Success: '$success',\n Failure: '$failure',\n} as const satisfies Record<string, SiftLoginStatus>;\n\nexport type SiftLoginFailureReason =\n | '$account_unknown'\n | '$account_suspended'\n | '$account_disabled'\n | '$wrong_password';\n\nexport const SiftLoginFailureReasonValues = [\n '$account_unknown',\n '$account_suspended',\n '$account_disabled',\n '$wrong_password',\n] as const satisfies readonly SiftLoginFailureReason[];\n\nexport type SiftPasswordUpdateReason =\n | '$user_update'\n | '$forgot_password'\n | '$forced_reset';\n\nexport const SiftPasswordUpdateReasonValues = [\n '$user_update',\n '$forgot_password',\n '$forced_reset',\n] as const satisfies readonly SiftPasswordUpdateReason[];\n\nexport const PasswordUpdateReason = {\n UserUpdate: SiftPasswordUpdateReasonValues[0],\n ForgotPassword: SiftPasswordUpdateReasonValues[1],\n ForcedReset: SiftPasswordUpdateReasonValues[2],\n} as const satisfies Record<string, SiftPasswordUpdateReason>;\n\nexport type SiftPasswordUpdateStatus = '$pending' | '$success' | '$failure';\n\nexport const SiftPasswordUpdateStatusValues = [\n '$pending',\n '$success',\n '$failure',\n] as const satisfies readonly SiftPasswordUpdateStatus[];\n\nexport const PasswordUpdateStatus = {\n Pending: '$pending',\n Success: '$success',\n Failure: '$failure',\n} as const satisfies Record<string, SiftPasswordUpdateStatus>;\n\nexport type SiftWagerStatus = '$accept' | '$cancel';\n\nexport const SiftWagerStatusValues = ['$accept', '$cancel'] as const satisfies readonly SiftWagerStatus[];\n\nexport const WagerStatus = {\n Accept: '$accept',\n Cancel: '$cancel',\n} as const satisfies Record<string, SiftWagerStatus>;\n\nexport type SiftTransactionStatus = '$success' | '$failure' | '$pending';\n\nexport const SiftTransactionStatusValues = [\n '$success',\n '$failure',\n '$pending',\n] as const satisfies readonly SiftTransactionStatus[];\n\nexport const TransactionStatus = {\n Success: '$success',\n Failure: '$failure',\n Pending: '$pending',\n} as const satisfies Record<string, SiftTransactionStatus>;\n\nexport type FraudRiskLevel = 'low' | 'medium' | 'high' | 'critical';\n","import { LoginStatus } from '../types/enums';\nimport type { FraudScoreRequest } from '../types/requests';\nimport type { FraudCustomMetadata } from '../types/metadata';\n\nfunction mergeMetadata(\n base: FraudCustomMetadata | undefined,\n extras: FraudCustomMetadata\n): FraudCustomMetadata {\n return { ...base, ...extras };\n}\n\nfunction stripSdkOnlyFields(\n request: Record<string, unknown>,\n keys: string[]\n): Record<string, unknown> {\n const body = { ...request };\n for (const key of keys) {\n delete body[key];\n }\n return body;\n}\n\nfunction createStrippedBody(\n rest: Record<string, unknown>,\n metadata: FraudCustomMetadata | undefined,\n stripKeys: string[]\n): Record<string, unknown> {\n return stripSdkOnlyFields(\n { ...rest, metadata: mergeMetadata(metadata, {}) },\n stripKeys\n );\n}\n\nfunction applySiftMetadata(\n body: Record<string, unknown>,\n metadata: FraudCustomMetadata | undefined,\n siftMetadata: FraudCustomMetadata,\n onlyWhenNonEmpty = false\n): Record<string, unknown> {\n if (!onlyWhenNonEmpty || Object.keys(siftMetadata).length > 0) {\n body.metadata = mergeMetadata(metadata, siftMetadata);\n }\n return body;\n}\n\nfunction normalizeUpdatePassword(\n request: Extract<FraudScoreRequest, { event_type: '$update_password' }>\n): Record<string, unknown> {\n const { password_reason, password_status, metadata, ...rest } = request;\n const body = createStrippedBody(rest, metadata, []);\n const siftMetadata: FraudCustomMetadata = {};\n if (password_reason) siftMetadata.$reason = password_reason;\n if (password_status) siftMetadata.$status = password_status;\n return applySiftMetadata(body, metadata, siftMetadata);\n}\n\nfunction normalizeWager(\n request: Extract<FraudScoreRequest, { event_type: '$wager' }>\n): Record<string, unknown> {\n const { wager_type, wager_status, wager_event_type, wager_event_name, wager_event_id, metadata, ...rest } =\n request;\n const body = createStrippedBody(rest, metadata, [\n 'wager_type',\n 'wager_status',\n 'wager_event_type',\n 'wager_event_name',\n 'wager_event_id',\n ]);\n const siftMetadata: FraudCustomMetadata = {\n $wager_type: wager_type,\n $wager_status: wager_status,\n };\n if (wager_event_type) siftMetadata.wager_event_type = wager_event_type;\n if (wager_event_name) siftMetadata.wager_event_name = wager_event_name;\n if (wager_event_id) siftMetadata.wager_event_id = wager_event_id;\n return applySiftMetadata(body, metadata, siftMetadata);\n}\n\nfunction normalizeLogin(\n request: Extract<FraudScoreRequest, { event_type: '$login' }>\n): Record<string, unknown> {\n const { login_status, login_failure_reason, metadata, ...rest } = request;\n const effectiveStatus = login_status ?? LoginStatus.Success;\n const body = createStrippedBody(rest, metadata, [\n 'login_status',\n 'login_failure_reason',\n ]);\n const siftMetadata: FraudCustomMetadata = {\n $login_status: effectiveStatus,\n };\n if (effectiveStatus === LoginStatus.Failure && login_failure_reason) {\n siftMetadata.$failure_reason = login_failure_reason;\n }\n return applySiftMetadata(body, metadata, siftMetadata);\n}\n\nfunction normalizeTransaction(\n request: Extract<FraudScoreRequest, { event_type: '$transaction' }>\n): Record<string, unknown> {\n const { transaction_status, decline_category, transfer_recipient_user_id, metadata, ...rest } =\n request;\n const body = createStrippedBody(rest, metadata, [\n 'transaction_status',\n 'decline_category',\n 'transfer_recipient_user_id',\n ]);\n const siftMetadata: FraudCustomMetadata = {};\n if (transaction_status) siftMetadata.$transaction_status = transaction_status;\n if (decline_category) siftMetadata.$decline_category = decline_category;\n if (transfer_recipient_user_id) {\n siftMetadata.$transfer_recipient_user_id = transfer_recipient_user_id;\n }\n return applySiftMetadata(body, metadata, siftMetadata, true);\n}\n\nexport function normalizeScoreRequestForApi(request: FraudScoreRequest): Record<string, unknown> {\n switch (request.event_type) {\n case '$update_password':\n return normalizeUpdatePassword(request);\n case '$wager':\n return normalizeWager(request);\n case '$login':\n return normalizeLogin(request);\n case '$transaction':\n return normalizeTransaction(request);\n default:\n return { ...request };\n }\n}\n","import type { FraudScoreRequest } from '../types/requests';\nimport { normalizeScoreRequestForApi } from './normalize';\n\n/**\n * Returns the JSON body that would be sent to POST /api/v1/fraud/score after normalization.\n * Useful for debugging without calling the API.\n */\nexport function buildScoreRequestPreview(request: FraudScoreRequest): Record<string, unknown> {\n return normalizeScoreRequestForApi(request);\n}\n","/**\n * Fraud event type unions aligned with fraud-service support matrix.\n */\n\n/** Events that run Sift scoring + rule engine */\nexport type ScoredFraudEventType =\n | '$create_account'\n | '$login'\n | '$logout'\n | '$update_account'\n | '$update_password'\n | '$transaction'\n | '$wager';\n\n/** Feedback-only; no meaningful fraud score in response */\nexport type ChargebackFraudEventType = '$chargeback';\n\n/** Union accepted by scoreEvent / scoreEventsBulk */\nexport type SupportedFraudEventType = ScoredFraudEventType | ChargebackFraudEventType;\n\nexport const SCORED_FRAUD_EVENT_TYPES: readonly ScoredFraudEventType[] = [\n '$create_account',\n '$login',\n '$logout',\n '$update_account',\n '$update_password',\n '$transaction',\n '$wager',\n] as const;\n\nexport const CHARGEBACK_FRAUD_EVENT_TYPE = '$chargeback' as const;\n\nexport const SUPPORTED_FRAUD_EVENT_TYPES: readonly SupportedFraudEventType[] = [\n ...SCORED_FRAUD_EVENT_TYPES,\n CHARGEBACK_FRAUD_EVENT_TYPE,\n] as const;\n\nexport const PLANNED_FRAUD_EVENT_TYPES = [\n '$verification',\n '$link_session_to_user',\n '$security_notification',\n '$create_order',\n '$update_order',\n '$order_status',\n '$add_promotion',\n] as const;\n\n/**\n * Listed in Vesant dashboard / future API — NOT valid for scoreEvent today.\n * @deprecated Not supported by POST /api/v1/fraud/score\n */\nexport type PlannedFraudEventType = (typeof PLANNED_FRAUD_EVENT_TYPES)[number];\n\n/**\n * @deprecated Use SupportedFraudEventType; kept for migration\n */\nexport type FraudEventType = SupportedFraudEventType | (typeof PLANNED_FRAUD_EVENT_TYPES)[number];\n\nexport function isPlannedFraudEventType(\n eventType: string\n): eventType is (typeof PLANNED_FRAUD_EVENT_TYPES)[number] {\n return (PLANNED_FRAUD_EVENT_TYPES as readonly string[]).includes(eventType);\n}\n\nexport function isSupportedFraudEventType(\n eventType: string\n): eventType is SupportedFraudEventType {\n return (SUPPORTED_FRAUD_EVENT_TYPES as readonly string[]).includes(eventType);\n}\n","/**\n * Custom metadata for fraud score requests (non-Sift reserved keys).\n */\n\nexport type FraudCustomMetadata = Record<string, unknown>;\n\nexport function hasReservedMetadataKey(metadata: FraudCustomMetadata): string | undefined {\n for (const key of Object.keys(metadata)) {\n if (key.startsWith('$')) {\n return key;\n }\n }\n return undefined;\n}\n","import { hasReservedMetadataKey } from '../types/metadata';\nimport type { FraudCustomMetadata } from '../types/metadata';\n\nexport function fieldPrefix(index?: number): string {\n return index === undefined ? '' : `requests[${index}].`;\n}\n\nexport function assertNonEmpty(\n value: string | undefined,\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (!value?.trim()) {\n errors.push(`${prefix}${field} is required`);\n }\n}\n\nexport function assertEnum<T extends string>(\n value: string | undefined,\n allowed: readonly T[],\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (value === undefined) return;\n if (!(allowed as readonly string[]).includes(value)) {\n errors.push(`${prefix}${field} must be one of: ${allowed.join(', ')}`);\n }\n}\n\nexport function assertPositiveAmount(\n amount: number | undefined,\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (amount === undefined || amount <= 0) {\n errors.push(`${prefix}${field} must be greater than 0`);\n }\n}\n\nexport function validateMetadata(\n metadata: FraudCustomMetadata | undefined,\n errors: string[],\n prefix: string\n): void {\n if (!metadata) return;\n const reservedKey = hasReservedMetadataKey(metadata);\n if (reservedKey) {\n errors.push(\n `${prefix}metadata keys must not start with '$' (found '${reservedKey}'). Use typed request fields instead.`\n );\n }\n}\n","import { ValidationError } from '@vesant-sdk/core';\nimport {\n SiftChargebackReasonValues,\n SiftChargebackStateValues,\n SiftLoginFailureReasonValues,\n SiftLoginStatusValues,\n SiftPasswordUpdateReasonValues,\n SiftPasswordUpdateStatusValues,\n SiftTransactionStatusValues,\n SiftTransactionTypeValues,\n SiftWagerStatusValues,\n TransactionType,\n} from '../types/enums';\nimport {\n isPlannedFraudEventType,\n isSupportedFraudEventType,\n SUPPORTED_FRAUD_EVENT_TYPES,\n} from '../types/events';\nimport type { FraudScoreRequest } from '../types/requests';\nimport {\n assertEnum,\n assertNonEmpty,\n assertPositiveAmount,\n fieldPrefix,\n validateMetadata,\n} from './helpers';\n\nfunction validateBase(\n request: FraudScoreRequest,\n errors: string[],\n prefix: string\n): void {\n assertNonEmpty(request.customer_id, 'customer_id', errors, prefix);\n assertNonEmpty(request.sift_user_id, 'sift_user_id', errors, prefix);\n assertNonEmpty(request.event_type, 'event_type', errors, prefix);\n validateMetadata(request.metadata, errors, prefix);\n}\n\nfunction validateLogin(\n request: Extract<FraudScoreRequest, { event_type: '$login' }>,\n errors: string[],\n prefix: string\n): void {\n assertEnum(request.login_status, SiftLoginStatusValues, 'login_status', errors, prefix);\n if (request.login_failure_reason !== undefined) {\n if (request.login_status === '$failure') {\n assertEnum(\n request.login_failure_reason,\n SiftLoginFailureReasonValues,\n 'login_failure_reason',\n errors,\n prefix\n );\n } else {\n errors.push(`${prefix}login_failure_reason is only allowed when login_status is '$failure'`);\n }\n }\n}\n\nfunction validateUpdatePassword(\n request: Extract<FraudScoreRequest, { event_type: '$update_password' }>,\n errors: string[],\n prefix: string\n): void {\n assertEnum(\n request.password_reason,\n SiftPasswordUpdateReasonValues,\n 'password_reason',\n errors,\n prefix\n );\n if (!request.password_reason) {\n errors.push(`${prefix}password_reason is required`);\n }\n assertEnum(\n request.password_status,\n SiftPasswordUpdateStatusValues,\n 'password_status',\n errors,\n prefix\n );\n if (!request.password_status) {\n errors.push(`${prefix}password_status is required`);\n }\n}\n\nfunction validateTransaction(\n request: Extract<FraudScoreRequest, { event_type: '$transaction' }>,\n errors: string[],\n prefix: string\n): void {\n assertPositiveAmount(request.amount, 'amount', errors, prefix);\n assertNonEmpty(request.currency, 'currency', errors, prefix);\n assertEnum(request.transaction_type, SiftTransactionTypeValues, 'transaction_type', errors, prefix);\n assertEnum(\n request.transaction_status,\n SiftTransactionStatusValues,\n 'transaction_status',\n errors,\n prefix\n );\n\n if (request.decline_category !== undefined && request.transaction_status !== '$failure') {\n errors.push(\n `${prefix}decline_category is only allowed when transaction_status is '$failure'`\n );\n }\n\n if (\n request.transfer_recipient_user_id !== undefined &&\n request.transaction_type !== TransactionType.Transfer\n ) {\n errors.push(\n `${prefix}transfer_recipient_user_id is only allowed when transaction_type is '$transfer'`\n );\n }\n}\n\nfunction validateWager(\n request: Extract<FraudScoreRequest, { event_type: '$wager' }>,\n errors: string[],\n prefix: string\n): void {\n assertNonEmpty(request.transaction_id, 'transaction_id', errors, prefix);\n assertNonEmpty(request.wager_type, 'wager_type', errors, prefix);\n assertEnum(request.wager_status, SiftWagerStatusValues, 'wager_status', errors, prefix);\n if (!request.wager_status) {\n errors.push(`${prefix}wager_status is required`);\n }\n assertPositiveAmount(request.amount, 'amount', errors, prefix);\n assertNonEmpty(request.currency, 'currency', errors, prefix);\n}\n\nfunction validateChargeback(\n request: Extract<FraudScoreRequest, { event_type: '$chargeback' }>,\n errors: string[],\n prefix: string\n): void {\n const hasTransactionId = !!request.transaction_id?.trim();\n const hasOrderId = !!request.order_id?.trim();\n if (!hasTransactionId && !hasOrderId) {\n errors.push(`${prefix}transaction_id or order_id is required`);\n }\n assertEnum(request.chargeback_state, SiftChargebackStateValues, 'chargeback_state', errors, prefix);\n assertEnum(\n request.chargeback_reason,\n SiftChargebackReasonValues,\n 'chargeback_reason',\n errors,\n prefix\n );\n if (request.ach_return_code !== undefined && request.ach_return_code.trim() !== '') {\n if (!/^R\\d{2}$/i.test(request.ach_return_code.trim())) {\n errors.push(`${prefix}ach_return_code must match NACHA R## pattern (e.g. R01)`);\n }\n }\n}\n\nfunction validateByEventType(request: FraudScoreRequest, errors: string[], prefix: string): void {\n switch (request.event_type) {\n case '$login':\n validateLogin(request, errors, prefix);\n break;\n case '$update_password':\n validateUpdatePassword(request, errors, prefix);\n break;\n case '$transaction':\n validateTransaction(request, errors, prefix);\n break;\n case '$wager':\n validateWager(request, errors, prefix);\n break;\n case '$chargeback':\n validateChargeback(request, errors, prefix);\n break;\n case '$create_account':\n case '$logout':\n case '$update_account':\n break;\n default:\n break;\n }\n}\n\nexport function validateScoreRequest(request: FraudScoreRequest, index?: number): void {\n const errors: string[] = [];\n const prefix = fieldPrefix(index);\n\n validateBase(request, errors, prefix);\n\n if (request.event_type && isPlannedFraudEventType(request.event_type)) {\n errors.push(\n `${prefix}event_type ${request.event_type} is not supported by POST /api/v1/fraud/score. Supported: ${SUPPORTED_FRAUD_EVENT_TYPES.join(', ')}`\n );\n } else if (request.event_type && !isSupportedFraudEventType(request.event_type)) {\n errors.push(\n `${prefix}event_type must be one of: ${SUPPORTED_FRAUD_EVENT_TYPES.join(', ')}`\n );\n } else if (isSupportedFraudEventType(request.event_type)) {\n validateByEventType(request, errors, prefix);\n }\n\n if (errors.length > 0) {\n throw new ValidationError(`Invalid fraud score request: ${errors.join(', ')}`, errors);\n }\n}\n","/**\n * Fraud scoring API client.\n */\n\nimport { BaseClient } from '@vesant-sdk/core';\nimport type { RequestOptions } from '@vesant-sdk/core';\nimport { ValidationError } from '@vesant-sdk/core';\nimport { normalizeScoreRequestForApi } from './normalization';\nimport type {\n FraudScoreRequest,\n FraudScoreResponseData,\n FraudScoreResponseEnvelope,\n} from './types';\nimport { validateScoreRequest } from './validation/rules';\n\nexport class FraudClient extends BaseClient {\n async scoreEvent(\n request: FraudScoreRequest,\n requestOptions?: RequestOptions\n ): Promise<FraudScoreResponseEnvelope<FraudScoreResponseData>> {\n validateScoreRequest(request);\n const body = normalizeScoreRequestForApi(request);\n\n return this.requestWithRetry<FraudScoreResponseEnvelope<FraudScoreResponseData>>(\n '/api/v1/fraud/score',\n {\n method: 'POST',\n body: JSON.stringify(body),\n },\n undefined,\n undefined,\n requestOptions\n );\n }\n\n async scoreEventsBulk(\n requests: FraudScoreRequest[],\n requestOptions?: RequestOptions\n ): Promise<FraudScoreResponseEnvelope<FraudScoreResponseData[]>> {\n if (!Array.isArray(requests) || requests.length === 0) {\n throw new ValidationError(\n 'Invalid bulk score request: at least one score request is required',\n ['requests']\n );\n }\n\n const bodies = requests.map((request, index) => {\n validateScoreRequest(request, index);\n return normalizeScoreRequestForApi(request);\n });\n\n return this.requestWithRetry<FraudScoreResponseEnvelope<FraudScoreResponseData[]>>(\n '/api/v1/fraud/score/bulk',\n {\n method: 'POST',\n body: JSON.stringify(bodies),\n },\n undefined,\n undefined,\n requestOptions\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/enums.ts","../src/types/rule-signals.ts","../src/normalization/sift-keys.ts","../src/normalization/normalize.ts","../src/normalization/preview.ts","../src/types/events.ts","../src/types/metadata.ts","../src/validation/helpers.ts","../src/validation/rules.ts","../src/client.ts"],"names":["ValidationError"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Sift-aligned enum types and const objects for fraud scoring requests.\n */\n\nexport type SiftTransactionType =\n | '$sale'\n | '$authorize'\n | '$capture'\n | '$void'\n | '$refund'\n | '$deposit'\n | '$withdrawal'\n | '$transfer'\n | '$buy'\n | '$sell'\n | '$send'\n | '$receive';\n\nexport const SiftTransactionTypeValues = [\n '$sale',\n '$authorize',\n '$capture',\n '$void',\n '$refund',\n '$deposit',\n '$withdrawal',\n '$transfer',\n '$buy',\n '$sell',\n '$send',\n '$receive',\n] as const satisfies readonly SiftTransactionType[];\n\nexport const TransactionType = {\n Sale: '$sale',\n Authorize: '$authorize',\n Capture: '$capture',\n Void: '$void',\n Refund: '$refund',\n Deposit: '$deposit',\n Withdrawal: '$withdrawal',\n Transfer: '$transfer',\n Buy: '$buy',\n Sell: '$sell',\n Send: '$send',\n Receive: '$receive',\n} as const satisfies Record<string, SiftTransactionType>;\n\nexport type SiftChargebackState =\n | '$received'\n | '$accepted'\n | '$disputed'\n | '$won'\n | '$lost';\n\nexport const SiftChargebackStateValues = [\n '$received',\n '$accepted',\n '$disputed',\n '$won',\n '$lost',\n] as const satisfies readonly SiftChargebackState[];\n\nexport const ChargebackState = {\n Received: '$received',\n Accepted: '$accepted',\n Disputed: '$disputed',\n Won: '$won',\n Lost: '$lost',\n} as const satisfies Record<string, SiftChargebackState>;\n\nexport type SiftChargebackReason =\n | '$fraud'\n | '$duplicate'\n | '$product_not_received'\n | '$product_unacceptable'\n | '$authorization'\n | '$consumer_disputes'\n | '$processing_errors'\n | '$cancel_subscription'\n | '$friendly_fraud'\n | '$ach_return'\n | '$ach_reversal'\n | '$other';\n\nexport const SiftChargebackReasonValues = [\n '$fraud',\n '$duplicate',\n '$product_not_received',\n '$product_unacceptable',\n '$authorization',\n '$consumer_disputes',\n '$processing_errors',\n '$cancel_subscription',\n '$friendly_fraud',\n '$ach_return',\n '$ach_reversal',\n '$other',\n] as const satisfies readonly SiftChargebackReason[];\n\nexport const ChargebackReason = {\n Fraud: '$fraud',\n Duplicate: '$duplicate',\n ProductNotReceived: '$product_not_received',\n ProductUnacceptable: '$product_unacceptable',\n Authorization: '$authorization',\n ConsumerDisputes: '$consumer_disputes',\n ProcessingErrors: '$processing_errors',\n CancelSubscription: '$cancel_subscription',\n FriendlyFraud: '$friendly_fraud',\n AchReturn: '$ach_return',\n AchReversal: '$ach_reversal',\n Other: '$other',\n} as const satisfies Record<string, SiftChargebackReason>;\n\nexport type SiftLoginStatus = '$success' | '$failure';\n\nexport const SiftLoginStatusValues = ['$success', '$failure'] as const satisfies readonly SiftLoginStatus[];\n\nexport const LoginStatus = {\n Success: '$success',\n Failure: '$failure',\n} as const satisfies Record<string, SiftLoginStatus>;\n\nexport type SiftLoginFailureReason =\n | '$account_unknown'\n | '$account_suspended'\n | '$account_disabled'\n | '$wrong_password';\n\nexport const SiftLoginFailureReasonValues = [\n '$account_unknown',\n '$account_suspended',\n '$account_disabled',\n '$wrong_password',\n] as const satisfies readonly SiftLoginFailureReason[];\n\nexport type SiftPasswordUpdateReason =\n | '$user_update'\n | '$forgot_password'\n | '$forced_reset';\n\nexport const SiftPasswordUpdateReasonValues = [\n '$user_update',\n '$forgot_password',\n '$forced_reset',\n] as const satisfies readonly SiftPasswordUpdateReason[];\n\nexport const PasswordUpdateReason = {\n UserUpdate: SiftPasswordUpdateReasonValues[0],\n ForgotPassword: SiftPasswordUpdateReasonValues[1],\n ForcedReset: SiftPasswordUpdateReasonValues[2],\n} as const satisfies Record<string, SiftPasswordUpdateReason>;\n\nexport type SiftPasswordUpdateStatus = '$pending' | '$success' | '$failure';\n\nexport const SiftPasswordUpdateStatusValues = [\n '$pending',\n '$success',\n '$failure',\n] as const satisfies readonly SiftPasswordUpdateStatus[];\n\nexport const PasswordUpdateStatus = {\n Pending: '$pending',\n Success: '$success',\n Failure: '$failure',\n} as const satisfies Record<string, SiftPasswordUpdateStatus>;\n\nexport type SiftWagerStatus = '$accept' | '$cancel';\n\nexport const SiftWagerStatusValues = ['$accept', '$cancel'] as const satisfies readonly SiftWagerStatus[];\n\nexport const WagerStatus = {\n Accept: '$accept',\n Cancel: '$cancel',\n} as const satisfies Record<string, SiftWagerStatus>;\n\nexport type SiftTransactionStatus = '$success' | '$failure' | '$pending';\n\nexport const SiftTransactionStatusValues = [\n '$success',\n '$failure',\n '$pending',\n] as const satisfies readonly SiftTransactionStatus[];\n\nexport const TransactionStatus = {\n Success: '$success',\n Failure: '$failure',\n Pending: '$pending',\n} as const satisfies Record<string, SiftTransactionStatus>;\n\nexport type FraudRiskLevel = 'low' | 'medium' | 'high' | 'critical';\n","/**\n * Optional top-level rule-signal fields copied into plain metadata on the wire.\n */\n\nexport interface LoginRuleSignals {\n ip_country_mismatch?: boolean;\n}\n\nexport interface UpdateAccountRuleSignals {\n two_fa_enabled?: boolean;\n two_fa_disabled?: boolean;\n two_fa_method_changed?: boolean;\n}\n\nexport interface TransactionRuleSignals {\n payment_method?: string;\n is_first_deposit?: boolean;\n cumulative_deposit_amount?: number;\n deposit_count?: number;\n failed_deposit_count?: number;\n is_first_withdrawal?: boolean;\n withdrawal_method_differs?: boolean;\n cumulative_withdrawal_amount?: number;\n withdrawal_count?: number;\n hours_since_last_deposit?: number;\n days_since_last_activity?: number;\n hours_since_account_creation?: number;\n}\n\nexport const LOGIN_RULE_SIGNAL_KEYS = ['ip_country_mismatch'] as const;\n\nexport const UPDATE_ACCOUNT_RULE_SIGNAL_KEYS = [\n 'two_fa_enabled',\n 'two_fa_disabled',\n 'two_fa_method_changed',\n] as const;\n\nexport const TRANSACTION_RULE_SIGNAL_KEYS = [\n 'payment_method',\n 'is_first_deposit',\n 'cumulative_deposit_amount',\n 'deposit_count',\n 'failed_deposit_count',\n 'is_first_withdrawal',\n 'withdrawal_method_differs',\n 'cumulative_withdrawal_amount',\n 'withdrawal_count',\n 'hours_since_last_deposit',\n 'days_since_last_activity',\n 'hours_since_account_creation',\n] as const;\n","function siftKey(key: string): string {\n return key.startsWith('$') ? key : `$${key}`;\n}\n\n/**\n * Recursively prefix object keys with $ for Sift wire format (no double-prefix).\n */\nexport function toSiftKeyedObject(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item) => toSiftKeyedObject(item));\n }\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, nested] of Object.entries(value as Record<string, unknown>)) {\n out[siftKey(key)] = toSiftKeyedObject(nested);\n }\n return out;\n }\n return value;\n}\n","import { LoginStatus, PasswordUpdateReason, PasswordUpdateStatus } from '../types/enums';\nimport type { FraudCustomMetadata } from '../types/metadata';\nimport type { FraudScoreRequest } from '../types/requests';\nimport {\n LOGIN_RULE_SIGNAL_KEYS,\n TRANSACTION_RULE_SIGNAL_KEYS,\n UPDATE_ACCOUNT_RULE_SIGNAL_KEYS,\n} from '../types/rule-signals';\nimport { toSiftKeyedObject } from './sift-keys';\n\nconst BASE_SIFT_FIELD_KEYS = [\n 'session_id',\n 'user_email',\n 'name',\n 'phone',\n 'sift_payment_method',\n 'payment_methods',\n 'billing_address',\n 'app',\n] as const;\n\nfunction mergeMetadata(\n base: FraudCustomMetadata | undefined,\n extras: FraudCustomMetadata\n): FraudCustomMetadata {\n return { ...base, ...extras };\n}\n\nfunction stripSdkOnlyFields(\n request: Record<string, unknown>,\n keys: string[]\n): Record<string, unknown> {\n const body = { ...request };\n for (const key of keys) {\n delete body[key];\n }\n return body;\n}\n\nfunction createStrippedBody(\n rest: Record<string, unknown>,\n metadata: FraudCustomMetadata | undefined,\n stripKeys: string[]\n): Record<string, unknown> {\n return stripSdkOnlyFields(\n { ...rest, metadata: mergeMetadata(metadata, {}) },\n stripKeys\n );\n}\n\nfunction applySiftMetadata(\n body: Record<string, unknown>,\n metadata: FraudCustomMetadata | undefined,\n siftMetadata: FraudCustomMetadata,\n onlyWhenNonEmpty = false\n): Record<string, unknown> {\n if (!onlyWhenNonEmpty || Object.keys(siftMetadata).length > 0) {\n body.metadata = mergeMetadata(metadata, siftMetadata);\n }\n return body;\n}\n\nfunction collectRuleSignals(\n request: Record<string, unknown>,\n keys: readonly string[]\n): FraudCustomMetadata {\n const signals: FraudCustomMetadata = {};\n for (const key of keys) {\n const value = request[key];\n if (value !== undefined) {\n signals[key] = value;\n }\n }\n return signals;\n}\n\nfunction buildBaseSiftMetadata(body: Record<string, unknown>): FraudCustomMetadata {\n const {\n session_id,\n user_email,\n name,\n phone,\n sift_payment_method,\n payment_methods,\n billing_address,\n app,\n metadata,\n } = body;\n\n const siftMetadata: FraudCustomMetadata = {\n ...((metadata as FraudCustomMetadata | undefined) ?? {}),\n };\n\n if (session_id !== undefined) siftMetadata.$session_id = session_id;\n if (user_email !== undefined) siftMetadata.$user_email = user_email;\n if (name !== undefined) siftMetadata.$name = name;\n if (phone !== undefined) siftMetadata.$phone = phone;\n if (sift_payment_method !== undefined) {\n siftMetadata.$payment_method = toSiftKeyedObject(sift_payment_method) as FraudCustomMetadata[string];\n }\n if (payment_methods !== undefined) {\n siftMetadata.$payment_methods = toSiftKeyedObject(payment_methods) as FraudCustomMetadata[string];\n }\n if (billing_address !== undefined) {\n siftMetadata.$billing_address = toSiftKeyedObject(billing_address) as FraudCustomMetadata[string];\n }\n if (app !== undefined) siftMetadata.$app = toSiftKeyedObject(app) as FraudCustomMetadata[string];\n\n return siftMetadata;\n}\n\nfunction normalizeBaseSiftFields(body: Record<string, unknown>): Record<string, unknown> {\n const siftMetadata = buildBaseSiftMetadata(body);\n const stripped = stripSdkOnlyFields(body, [...BASE_SIFT_FIELD_KEYS]);\n\n if (Object.keys(siftMetadata).length > 0) {\n stripped.metadata = siftMetadata;\n }\n\n return stripped;\n}\n\nfunction applyRuleSignals(\n body: Record<string, unknown>,\n request: Record<string, unknown>,\n keys: readonly string[],\n stripKeys: readonly string[]\n): Record<string, unknown> {\n const ruleSignals = collectRuleSignals(request, keys);\n const stripped = stripSdkOnlyFields(body, [...stripKeys]);\n if (Object.keys(ruleSignals).length > 0) {\n stripped.metadata = mergeMetadata(\n stripped.metadata as FraudCustomMetadata | undefined,\n ruleSignals\n );\n }\n return stripped;\n}\n\nfunction normalizeUpdatePassword(\n request: Extract<FraudScoreRequest, { event_type: '$update_password' }>\n): Record<string, unknown> {\n const { password_reason, password_status, metadata, ...rest } = request;\n let body = createStrippedBody(rest as Record<string, unknown>, metadata, [\n 'password_reason',\n 'password_status',\n ]);\n const siftMetadata: FraudCustomMetadata = {\n $reason: password_reason ?? PasswordUpdateReason.UserUpdate,\n $status: password_status ?? PasswordUpdateStatus.Success,\n };\n body = applySiftMetadata(body, metadata, siftMetadata);\n return normalizeBaseSiftFields(body);\n}\n\nfunction normalizeWager(\n request: Extract<FraudScoreRequest, { event_type: '$wager' }>\n): Record<string, unknown> {\n const { wager_type, wager_status, wager_event_type, wager_event_name, wager_event_id, metadata, ...rest } =\n request;\n let body = createStrippedBody(rest as Record<string, unknown>, metadata, [\n 'wager_type',\n 'wager_status',\n 'wager_event_type',\n 'wager_event_name',\n 'wager_event_id',\n ]);\n const siftMetadata: FraudCustomMetadata = {\n $wager_type: wager_type,\n $wager_status: wager_status,\n };\n if (wager_event_type) siftMetadata.$wager_event_type = wager_event_type;\n if (wager_event_name) siftMetadata.$wager_event_name = wager_event_name;\n if (wager_event_id) siftMetadata.$wager_event_id = wager_event_id;\n body = applySiftMetadata(body, metadata, siftMetadata);\n return normalizeBaseSiftFields(body);\n}\n\nfunction normalizeLogin(\n request: Extract<FraudScoreRequest, { event_type: '$login' }>\n): Record<string, unknown> {\n const { login_status, login_failure_reason, metadata, ...rest } = request;\n const effectiveStatus = login_status ?? LoginStatus.Success;\n let body = createStrippedBody(rest as Record<string, unknown>, metadata, [\n 'login_status',\n 'login_failure_reason',\n ...LOGIN_RULE_SIGNAL_KEYS,\n ]);\n const siftMetadata: FraudCustomMetadata = {\n $login_status: effectiveStatus,\n };\n if (effectiveStatus === LoginStatus.Failure && login_failure_reason) {\n siftMetadata.$failure_reason = login_failure_reason;\n }\n body = applySiftMetadata(body, metadata, siftMetadata);\n body = applyRuleSignals(\n body,\n request as unknown as Record<string, unknown>,\n LOGIN_RULE_SIGNAL_KEYS,\n []\n );\n return normalizeBaseSiftFields(body);\n}\n\nfunction normalizeTransaction(\n request: Extract<FraudScoreRequest, { event_type: '$transaction' }>\n): Record<string, unknown> {\n const { transaction_status, decline_category, transfer_recipient_user_id, metadata, ...rest } =\n request;\n let body = createStrippedBody(rest as Record<string, unknown>, metadata, [\n 'transaction_status',\n 'decline_category',\n 'transfer_recipient_user_id',\n ...TRANSACTION_RULE_SIGNAL_KEYS,\n ]);\n const siftMetadata: FraudCustomMetadata = {};\n if (transaction_status) siftMetadata.$transaction_status = transaction_status;\n if (decline_category) siftMetadata.$decline_category = decline_category;\n if (transfer_recipient_user_id) {\n siftMetadata.$transfer_recipient_user_id = transfer_recipient_user_id;\n }\n body = applySiftMetadata(body, metadata, siftMetadata, true);\n body = applyRuleSignals(\n body,\n request as unknown as Record<string, unknown>,\n TRANSACTION_RULE_SIGNAL_KEYS,\n []\n );\n return normalizeBaseSiftFields(body);\n}\n\nfunction normalizeUpdateAccount(\n request: Extract<FraudScoreRequest, { event_type: '$update_account' }>\n): Record<string, unknown> {\n const { metadata, ...rest } = request;\n let body = createStrippedBody(rest as Record<string, unknown>, metadata, [\n ...UPDATE_ACCOUNT_RULE_SIGNAL_KEYS,\n ]);\n body = applyRuleSignals(\n body,\n request as unknown as Record<string, unknown>,\n UPDATE_ACCOUNT_RULE_SIGNAL_KEYS,\n []\n );\n return normalizeBaseSiftFields(body);\n}\n\nfunction normalizeDefault(request: FraudScoreRequest): Record<string, unknown> {\n return normalizeBaseSiftFields({ ...request } as Record<string, unknown>);\n}\n\nexport function normalizeScoreRequestForApi(request: FraudScoreRequest): Record<string, unknown> {\n switch (request.event_type) {\n case '$update_password':\n return normalizeUpdatePassword(request);\n case '$wager':\n return normalizeWager(request);\n case '$login':\n return normalizeLogin(request);\n case '$transaction':\n return normalizeTransaction(request);\n case '$update_account':\n return normalizeUpdateAccount(request);\n default:\n return normalizeDefault(request);\n }\n}\n","import type { FraudScoreRequest } from '../types/requests';\nimport { normalizeScoreRequestForApi } from './normalize';\n\n/**\n * Returns the JSON body that would be sent to POST /api/v1/fraud/score after normalization.\n * Useful for debugging without calling the API.\n */\nexport function buildScoreRequestPreview(request: FraudScoreRequest): Record<string, unknown> {\n return normalizeScoreRequestForApi(request);\n}\n","/**\n * Fraud event type unions aligned with fraud-service support matrix.\n */\n\n/** Events that run Sift scoring + rule engine */\nexport type ScoredFraudEventType =\n | '$create_account'\n | '$login'\n | '$logout'\n | '$update_account'\n | '$update_password'\n | '$transaction'\n | '$wager';\n\n/** Feedback-only; no meaningful fraud score in response */\nexport type ChargebackFraudEventType = '$chargeback';\n\n/** Union accepted by scoreEvent / scoreEventsBulk */\nexport type SupportedFraudEventType = ScoredFraudEventType | ChargebackFraudEventType;\n\nexport const SCORED_FRAUD_EVENT_TYPES: readonly ScoredFraudEventType[] = [\n '$create_account',\n '$login',\n '$logout',\n '$update_account',\n '$update_password',\n '$transaction',\n '$wager',\n] as const;\n\nexport const CHARGEBACK_FRAUD_EVENT_TYPE = '$chargeback' as const;\n\nexport const SUPPORTED_FRAUD_EVENT_TYPES: readonly SupportedFraudEventType[] = [\n ...SCORED_FRAUD_EVENT_TYPES,\n CHARGEBACK_FRAUD_EVENT_TYPE,\n] as const;\n\nexport const PLANNED_FRAUD_EVENT_TYPES = [\n '$verification',\n '$link_session_to_user',\n '$security_notification',\n '$create_order',\n '$update_order',\n '$order_status',\n '$add_promotion',\n] as const;\n\n/**\n * Listed in Vesant dashboard / future API — NOT valid for scoreEvent today.\n * @deprecated Not supported by POST /api/v1/fraud/score\n */\nexport type PlannedFraudEventType = (typeof PLANNED_FRAUD_EVENT_TYPES)[number];\n\n/**\n * @deprecated Use SupportedFraudEventType; kept for migration\n */\nexport type FraudEventType = SupportedFraudEventType | (typeof PLANNED_FRAUD_EVENT_TYPES)[number];\n\nexport function isPlannedFraudEventType(\n eventType: string\n): eventType is (typeof PLANNED_FRAUD_EVENT_TYPES)[number] {\n return (PLANNED_FRAUD_EVENT_TYPES as readonly string[]).includes(eventType);\n}\n\nexport function isSupportedFraudEventType(\n eventType: string\n): eventType is SupportedFraudEventType {\n return (SUPPORTED_FRAUD_EVENT_TYPES as readonly string[]).includes(eventType);\n}\n","/**\n * Metadata for fraud score requests.\n * Plain keys are Vesant rule signals; $-prefixed keys are Sift pass-through (or set via typed fields).\n */\n\nexport interface FraudRuleSignalMetadata {\n /** Rule signal payment method (e.g. \"$credit_card\"), not Sift $payment_method object */\n payment_method?: string;\n country?: string;\n two_fa_enabled?: boolean;\n two_fa_disabled?: boolean;\n two_fa_method_changed?: boolean;\n ip_country_mismatch?: boolean;\n is_first_deposit?: boolean;\n cumulative_deposit_amount?: number;\n deposit_count?: number;\n failed_deposit_count?: number;\n is_first_withdrawal?: boolean;\n withdrawal_method_differs?: boolean;\n cumulative_withdrawal_amount?: number;\n withdrawal_count?: number;\n hours_since_last_deposit?: number;\n days_since_last_activity?: number;\n hours_since_account_creation?: number;\n}\n\n/** Extra Sift fields forwarded verbatim in metadata (e.g. $referrer_user_id, $promotions). */\nexport type SiftPassThroughMetadata = Record<`$${string}`, unknown>;\n\nexport type FraudCustomMetadata = FraudRuleSignalMetadata &\n SiftPassThroughMetadata &\n Record<string, unknown>;\n\n/** Maps typed request fields to metadata keys they populate (typed values win on normalize). */\nexport const TYPED_SIFT_METADATA_KEYS: Readonly<Record<string, string>> = {\n session_id: '$session_id',\n user_email: '$user_email',\n name: '$name',\n phone: '$phone',\n sift_payment_method: '$payment_method',\n billing_address: '$billing_address',\n payment_methods: '$payment_methods',\n app: '$app',\n};\n\nexport function findMetadataConflictWithTypedFields(\n metadata: FraudCustomMetadata,\n request: Record<string, unknown>\n): string | undefined {\n for (const [field, metaKey] of Object.entries(TYPED_SIFT_METADATA_KEYS)) {\n if (request[field] !== undefined && metadata[metaKey] !== undefined) {\n return metaKey;\n }\n }\n return undefined;\n}\n","import { findMetadataConflictWithTypedFields } from '../types/metadata';\nimport type { FraudCustomMetadata } from '../types/metadata';\nimport type { FraudScoreRequestBase } from '../types/requests';\n\nexport function fieldPrefix(index?: number): string {\n return index === undefined ? '' : `requests[${index}].`;\n}\n\nexport function assertNonEmpty(\n value: string | undefined,\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (!value?.trim()) {\n errors.push(`${prefix}${field} is required`);\n }\n}\n\nexport function assertEnum<T extends string>(\n value: string | undefined,\n allowed: readonly T[],\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (value === undefined) return;\n if (!(allowed as readonly string[]).includes(value)) {\n errors.push(`${prefix}${field} must be one of: ${allowed.join(', ')}`);\n }\n}\n\nexport function assertPositiveAmount(\n amount: number | undefined,\n field: string,\n errors: string[],\n prefix: string\n): void {\n if (amount === undefined || amount <= 0) {\n errors.push(`${prefix}${field} must be greater than 0`);\n }\n}\n\nexport function validateMetadata(\n metadata: FraudCustomMetadata | undefined,\n request: FraudScoreRequestBase,\n errors: string[],\n prefix: string\n): void {\n if (!metadata) return;\n const conflictKey = findMetadataConflictWithTypedFields(\n metadata,\n request as unknown as Record<string, unknown>\n );\n if (conflictKey) {\n errors.push(\n `${prefix}metadata.${conflictKey} conflicts with a typed request field that maps to the same key; omit metadata.${conflictKey} or remove the typed field`\n );\n }\n}\n","import { ValidationError } from '@vesant-sdk/core';\nimport {\n SiftChargebackReasonValues,\n SiftChargebackStateValues,\n SiftLoginFailureReasonValues,\n SiftLoginStatusValues,\n SiftPasswordUpdateReasonValues,\n SiftPasswordUpdateStatusValues,\n SiftTransactionStatusValues,\n SiftTransactionTypeValues,\n SiftWagerStatusValues,\n TransactionType,\n} from '../types/enums';\nimport {\n isPlannedFraudEventType,\n isSupportedFraudEventType,\n SUPPORTED_FRAUD_EVENT_TYPES,\n} from '../types/events';\nimport type { FraudScoreRequest } from '../types/requests';\nimport {\n assertEnum,\n assertNonEmpty,\n assertPositiveAmount,\n fieldPrefix,\n validateMetadata,\n} from './helpers';\n\nfunction validateBase(\n request: FraudScoreRequest,\n errors: string[],\n prefix: string\n): void {\n assertNonEmpty(request.customer_id, 'customer_id', errors, prefix);\n assertNonEmpty(request.sift_user_id, 'sift_user_id', errors, prefix);\n assertNonEmpty(request.event_type, 'event_type', errors, prefix);\n validateMetadata(request.metadata, request, errors, prefix);\n}\n\nfunction validateLogin(\n request: Extract<FraudScoreRequest, { event_type: '$login' }>,\n errors: string[],\n prefix: string\n): void {\n assertEnum(request.login_status, SiftLoginStatusValues, 'login_status', errors, prefix);\n if (request.login_failure_reason !== undefined) {\n if (request.login_status === '$failure') {\n assertEnum(\n request.login_failure_reason,\n SiftLoginFailureReasonValues,\n 'login_failure_reason',\n errors,\n prefix\n );\n } else {\n errors.push(`${prefix}login_failure_reason is only allowed when login_status is '$failure'`);\n }\n }\n}\n\nfunction validateUpdatePassword(\n request: Extract<FraudScoreRequest, { event_type: '$update_password' }>,\n errors: string[],\n prefix: string\n): void {\n assertEnum(\n request.password_reason,\n SiftPasswordUpdateReasonValues,\n 'password_reason',\n errors,\n prefix\n );\n assertEnum(\n request.password_status,\n SiftPasswordUpdateStatusValues,\n 'password_status',\n errors,\n prefix\n );\n}\n\nfunction validateTransaction(\n request: Extract<FraudScoreRequest, { event_type: '$transaction' }>,\n errors: string[],\n prefix: string\n): void {\n assertPositiveAmount(request.amount, 'amount', errors, prefix);\n assertNonEmpty(request.currency, 'currency', errors, prefix);\n assertEnum(request.transaction_type, SiftTransactionTypeValues, 'transaction_type', errors, prefix);\n assertEnum(\n request.transaction_status,\n SiftTransactionStatusValues,\n 'transaction_status',\n errors,\n prefix\n );\n\n if (request.decline_category !== undefined && request.transaction_status !== '$failure') {\n errors.push(\n `${prefix}decline_category is only allowed when transaction_status is '$failure'`\n );\n }\n\n if (\n request.transfer_recipient_user_id !== undefined &&\n request.transaction_type !== TransactionType.Transfer\n ) {\n errors.push(\n `${prefix}transfer_recipient_user_id is only allowed when transaction_type is '$transfer'`\n );\n }\n}\n\nfunction validateWager(\n request: Extract<FraudScoreRequest, { event_type: '$wager' }>,\n errors: string[],\n prefix: string\n): void {\n assertNonEmpty(request.transaction_id, 'transaction_id', errors, prefix);\n assertNonEmpty(request.wager_type, 'wager_type', errors, prefix);\n assertEnum(request.wager_status, SiftWagerStatusValues, 'wager_status', errors, prefix);\n if (!request.wager_status) {\n errors.push(`${prefix}wager_status is required`);\n }\n assertPositiveAmount(request.amount, 'amount', errors, prefix);\n assertNonEmpty(request.currency, 'currency', errors, prefix);\n}\n\nfunction validateChargeback(\n request: Extract<FraudScoreRequest, { event_type: '$chargeback' }>,\n errors: string[],\n prefix: string\n): void {\n const hasTransactionId = !!request.transaction_id?.trim();\n const hasOrderId = !!request.order_id?.trim();\n if (!hasTransactionId && !hasOrderId) {\n errors.push(`${prefix}transaction_id or order_id is required`);\n }\n assertEnum(request.chargeback_state, SiftChargebackStateValues, 'chargeback_state', errors, prefix);\n assertEnum(\n request.chargeback_reason,\n SiftChargebackReasonValues,\n 'chargeback_reason',\n errors,\n prefix\n );\n if (request.ach_return_code !== undefined && request.ach_return_code.trim() !== '') {\n if (!/^R\\d{2}$/i.test(request.ach_return_code.trim())) {\n errors.push(`${prefix}ach_return_code must match NACHA R## pattern (e.g. R01)`);\n }\n }\n}\n\nfunction validateByEventType(request: FraudScoreRequest, errors: string[], prefix: string): void {\n switch (request.event_type) {\n case '$login':\n validateLogin(request, errors, prefix);\n break;\n case '$update_password':\n validateUpdatePassword(request, errors, prefix);\n break;\n case '$transaction':\n validateTransaction(request, errors, prefix);\n break;\n case '$wager':\n validateWager(request, errors, prefix);\n break;\n case '$chargeback':\n validateChargeback(request, errors, prefix);\n break;\n case '$create_account':\n case '$logout':\n case '$update_account':\n break;\n default:\n break;\n }\n}\n\nexport function validateScoreRequest(request: FraudScoreRequest, index?: number): void {\n const errors: string[] = [];\n const prefix = fieldPrefix(index);\n\n validateBase(request, errors, prefix);\n\n if (request.event_type && isPlannedFraudEventType(request.event_type)) {\n errors.push(\n `${prefix}event_type ${request.event_type} is not supported by POST /api/v1/fraud/score. Supported: ${SUPPORTED_FRAUD_EVENT_TYPES.join(', ')}`\n );\n } else if (request.event_type && !isSupportedFraudEventType(request.event_type)) {\n errors.push(\n `${prefix}event_type must be one of: ${SUPPORTED_FRAUD_EVENT_TYPES.join(', ')}`\n );\n } else if (isSupportedFraudEventType(request.event_type)) {\n validateByEventType(request, errors, prefix);\n }\n\n if (errors.length > 0) {\n throw new ValidationError(`Invalid fraud score request: ${errors.join(', ')}`, errors);\n }\n}\n","/**\n * Fraud scoring API client.\n */\n\nimport { BaseClient } from '@vesant-sdk/core';\nimport type { RequestOptions } from '@vesant-sdk/core';\nimport { ValidationError } from '@vesant-sdk/core';\nimport { normalizeScoreRequestForApi } from './normalization';\nimport type {\n FraudScoreRequest,\n FraudScoreResponseData,\n FraudScoreResponseEnvelope,\n} from './types';\nimport { validateScoreRequest } from './validation/rules';\n\nexport class FraudClient extends BaseClient {\n async scoreEvent(\n request: FraudScoreRequest,\n requestOptions?: RequestOptions\n ): Promise<FraudScoreResponseEnvelope<FraudScoreResponseData>> {\n validateScoreRequest(request);\n const body = normalizeScoreRequestForApi(request);\n\n return this.requestWithRetry<FraudScoreResponseEnvelope<FraudScoreResponseData>>(\n '/api/v1/fraud/score',\n {\n method: 'POST',\n body: JSON.stringify(body),\n },\n undefined,\n undefined,\n requestOptions\n );\n }\n\n async scoreEventsBulk(\n requests: FraudScoreRequest[],\n requestOptions?: RequestOptions\n ): Promise<FraudScoreResponseEnvelope<FraudScoreResponseData[]>> {\n if (!Array.isArray(requests) || requests.length === 0) {\n throw new ValidationError(\n 'Invalid bulk score request: at least one score request is required',\n ['requests']\n );\n }\n\n const bodies = requests.map((request, index) => {\n validateScoreRequest(request, index);\n return normalizeScoreRequestForApi(request);\n });\n\n return this.requestWithRetry<FraudScoreResponseEnvelope<FraudScoreResponseData[]>>(\n '/api/v1/fraud/score/bulk',\n {\n method: 'POST',\n body: JSON.stringify(bodies),\n },\n undefined,\n undefined,\n requestOptions\n );\n }\n}\n"]}
|
package/package.json
CHANGED