vesant-sdk 1.7.0-dev.362ac6b → 1.7.0-dev.3f9ec86

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.
Files changed (75) hide show
  1. package/dist/{client-DoMSYMMR.d.ts → client-0NOPDnT0.d.ts} +29 -26
  2. package/dist/{client-DMIRx7Tu.d.mts → client-CvWNRwwg.d.mts} +29 -26
  3. package/dist/{client-ZNdnpWe7.d.mts → client-Dps40EtF.d.mts} +2 -2
  4. package/dist/{client-C3DCmGe9.d.ts → client-SMxqod4j.d.ts} +2 -2
  5. package/dist/{client-BolQlL5e.d.mts → client-q9fN8Hhf.d.mts} +103 -1
  6. package/dist/{client-BolQlL5e.d.ts → client-q9fN8Hhf.d.ts} +103 -1
  7. package/dist/compliance/index.d.mts +3 -3
  8. package/dist/compliance/index.d.ts +3 -3
  9. package/dist/compliance/index.js +133 -22
  10. package/dist/compliance/index.js.map +1 -1
  11. package/dist/compliance/index.mjs +133 -22
  12. package/dist/compliance/index.mjs.map +1 -1
  13. package/dist/decisions/index.d.mts +1 -1
  14. package/dist/decisions/index.d.ts +1 -1
  15. package/dist/decisions/index.js +68 -7
  16. package/dist/decisions/index.js.map +1 -1
  17. package/dist/decisions/index.mjs +68 -7
  18. package/dist/decisions/index.mjs.map +1 -1
  19. package/dist/geolocation/index.d.mts +59 -4
  20. package/dist/geolocation/index.d.ts +59 -4
  21. package/dist/geolocation/index.js +136 -19
  22. package/dist/geolocation/index.js.map +1 -1
  23. package/dist/geolocation/index.mjs +134 -20
  24. package/dist/geolocation/index.mjs.map +1 -1
  25. package/dist/index-C3zUKydT.d.mts +264 -0
  26. package/dist/index-DSDgS09k.d.ts +264 -0
  27. package/dist/index.d.mts +27 -10
  28. package/dist/index.d.ts +27 -10
  29. package/dist/index.js +343 -69
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +336 -70
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/kyc/core.d.mts +2 -2
  34. package/dist/kyc/core.d.ts +2 -2
  35. package/dist/kyc/core.js +109 -30
  36. package/dist/kyc/core.js.map +1 -1
  37. package/dist/kyc/core.mjs +109 -30
  38. package/dist/kyc/core.mjs.map +1 -1
  39. package/dist/kyc/index.d.mts +164 -61
  40. package/dist/kyc/index.d.ts +164 -61
  41. package/dist/kyc/index.js +109 -30
  42. package/dist/kyc/index.js.map +1 -1
  43. package/dist/kyc/index.mjs +109 -30
  44. package/dist/kyc/index.mjs.map +1 -1
  45. package/dist/react.d.mts +21 -15
  46. package/dist/react.d.ts +21 -15
  47. package/dist/react.js +199 -87
  48. package/dist/react.js.map +1 -1
  49. package/dist/react.mjs +199 -87
  50. package/dist/react.mjs.map +1 -1
  51. package/dist/risk-profile/index.d.mts +1 -1
  52. package/dist/risk-profile/index.d.ts +1 -1
  53. package/dist/risk-profile/index.js +68 -7
  54. package/dist/risk-profile/index.js.map +1 -1
  55. package/dist/risk-profile/index.mjs +68 -7
  56. package/dist/risk-profile/index.mjs.map +1 -1
  57. package/dist/scores/index.d.mts +1 -1
  58. package/dist/scores/index.d.ts +1 -1
  59. package/dist/scores/index.js +68 -7
  60. package/dist/scores/index.js.map +1 -1
  61. package/dist/scores/index.mjs +68 -7
  62. package/dist/scores/index.mjs.map +1 -1
  63. package/dist/tax/index.d.mts +20 -3
  64. package/dist/tax/index.d.ts +20 -3
  65. package/dist/tax/index.js +77 -10
  66. package/dist/tax/index.js.map +1 -1
  67. package/dist/tax/index.mjs +77 -10
  68. package/dist/tax/index.mjs.map +1 -1
  69. package/dist/webhooks/index.d.mts +2 -189
  70. package/dist/webhooks/index.d.ts +2 -189
  71. package/dist/webhooks/index.js +85 -21
  72. package/dist/webhooks/index.js.map +1 -1
  73. package/dist/webhooks/index.mjs +85 -22
  74. package/dist/webhooks/index.mjs.map +1 -1
  75. package/package.json +4 -1
package/dist/kyc/index.js CHANGED
@@ -1,5 +1,18 @@
1
1
  'use strict';
2
2
 
3
+ // src/core/auth.ts
4
+ var StaticApiKeyProvider = class {
5
+ constructor(apiKey) {
6
+ this.apiKey = apiKey;
7
+ }
8
+ async getCredential() {
9
+ return this.apiKey ? { scheme: "Bearer", token: this.apiKey } : null;
10
+ }
11
+ canRefresh() {
12
+ return false;
13
+ }
14
+ };
15
+
3
16
  // src/core/errors.ts
4
17
  var VesantError = class _VesantError extends Error {
5
18
  constructor(message, code, statusCode, details) {
@@ -241,6 +254,12 @@ var BaseClient = class {
241
254
  if (!config.tenantId?.trim()) {
242
255
  throw new ValidationError("tenantId is required and must be a non-empty string", ["tenantId"]);
243
256
  }
257
+ if (typeof fetch === "undefined") {
258
+ throw new VesantError(
259
+ "The Vesant SDK requires a global fetch (Node.js >= 18). Upgrade Node or provide a fetch polyfill.",
260
+ "RUNTIME_UNSUPPORTED"
261
+ );
262
+ }
244
263
  this.interceptors = config.interceptors || [];
245
264
  this.logger = config.logger || createConsoleLogger();
246
265
  let environment = config.environment;
@@ -259,11 +278,12 @@ var BaseClient = class {
259
278
  environment,
260
279
  headers: config.headers || {},
261
280
  timeout: config.timeout || 1e4,
262
- retries: config.retries || 3,
281
+ retries: config.retries ?? 3,
263
282
  debug: config.debug || false,
264
283
  interceptors: this.interceptors,
265
284
  logger: this.logger
266
285
  };
286
+ this.authProvider = config.authProvider ?? (apiKey ? new StaticApiKeyProvider(apiKey) : void 0);
267
287
  if (config.circuitBreaker) {
268
288
  this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
269
289
  }
@@ -271,6 +291,19 @@ var BaseClient = class {
271
291
  this.rateLimitTracker = new RateLimitTracker();
272
292
  }
273
293
  }
294
+ /**
295
+ * Resolve the Idempotency-Key for a request. Mutating methods (POST/PUT/PATCH)
296
+ * get the caller-supplied key or a freshly minted UUID; non-mutating methods get
297
+ * none. requestWithRetry resolves this once and injects it so every retry reuses
298
+ * one key (letting the server dedup replays); a direct request() resolves per call.
299
+ */
300
+ resolveIdempotencyKey(method, requestOptions) {
301
+ const isMutating = ["POST", "PUT", "PATCH"].includes((method || "GET").toUpperCase());
302
+ if (!isMutating) {
303
+ return void 0;
304
+ }
305
+ return requestOptions?.idempotencyKey ?? generateUUID();
306
+ }
274
307
  /**
275
308
  * Make an HTTP request with timeout and error handling
276
309
  */
@@ -296,15 +329,20 @@ var BaseClient = class {
296
329
  ...this.config.headers,
297
330
  ...options.headers || {}
298
331
  };
299
- if (this.config.apiKey) {
300
- headers["Authorization"] = `Bearer ${this.config.apiKey}`;
332
+ const credential = await this.authProvider?.getCredential({
333
+ tenantId: this.config.tenantId,
334
+ requestId
335
+ });
336
+ if (credential) {
337
+ headers["Authorization"] = `${credential.scheme ?? "Bearer"} ${credential.token}`;
301
338
  }
302
339
  if (this.config.environment === "sandbox") {
303
340
  headers["X-Sandbox"] = "true";
304
341
  }
305
342
  const method = (options.method || "GET").toUpperCase();
306
- if (["POST", "PUT", "PATCH"].includes(method)) {
307
- headers["Idempotency-Key"] = requestOptions?.idempotencyKey || generateUUID();
343
+ const idempotencyKey = this.resolveIdempotencyKey(method, requestOptions);
344
+ if (idempotencyKey) {
345
+ headers["Idempotency-Key"] = idempotencyKey;
308
346
  }
309
347
  const controller = new AbortController();
310
348
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
@@ -325,10 +363,28 @@ var BaseClient = class {
325
363
  if (this.config.debug) {
326
364
  this.logger.debug(`${finalOptions.method || "GET"} ${endpoint}`);
327
365
  }
328
- const response = await fetch(url, {
366
+ let response = await fetch(url, {
329
367
  ...finalOptions,
330
368
  signal: controller.signal
331
369
  });
370
+ if (response.status === 401 && this.authProvider?.canRefresh?.()) {
371
+ const refreshed = await this.authProvider.getCredential({
372
+ tenantId: this.config.tenantId,
373
+ requestId,
374
+ forceRefresh: true
375
+ });
376
+ if (refreshed) {
377
+ this.config.onCredentialRotated?.({ reason: "unauthorized" });
378
+ finalOptions = {
379
+ ...finalOptions,
380
+ headers: {
381
+ ...finalOptions.headers,
382
+ Authorization: `${refreshed.scheme ?? "Bearer"} ${refreshed.token}`
383
+ }
384
+ };
385
+ response = await fetch(url, { ...finalOptions, signal: controller.signal });
386
+ }
387
+ }
332
388
  clearTimeout(timeoutId);
333
389
  if (this.rateLimitTracker) {
334
390
  this.rateLimitTracker.updateFromHeaders(response.headers);
@@ -417,9 +473,11 @@ var BaseClient = class {
417
473
  */
418
474
  async requestWithRetry(endpoint, options = {}, serviceURL, retries = this.config.retries, requestOptions) {
419
475
  let lastError;
476
+ const idempotencyKey = this.resolveIdempotencyKey(options.method || "GET", requestOptions);
477
+ const attemptOptions = idempotencyKey ? { ...requestOptions, idempotencyKey } : requestOptions;
420
478
  for (let attempt = 0; attempt <= retries; attempt++) {
421
479
  try {
422
- return await this.request(endpoint, options, serviceURL, requestOptions);
480
+ return await this.request(endpoint, options, serviceURL, attemptOptions);
423
481
  } catch (error) {
424
482
  lastError = error instanceof Error ? error : new Error("Unknown error");
425
483
  if (requestOptions?.signal?.aborted) {
@@ -516,6 +574,9 @@ var BaseClient = class {
516
574
  if (config.interceptors) {
517
575
  this.interceptors = config.interceptors;
518
576
  }
577
+ if (config.authProvider !== void 0 || config.apiKey !== void 0) {
578
+ this.authProvider = this.config.authProvider ?? (this.config.apiKey ? new StaticApiKeyProvider(this.config.apiKey) : void 0);
579
+ }
519
580
  }
520
581
  /**
521
582
  * Get current configuration (readonly)
@@ -603,7 +664,13 @@ var KycClient = class extends BaseClient {
603
664
  *
604
665
  * Generates a link that the user can visit to submit their KYC documents.
605
666
  *
606
- * @param request - Request containing the user ID, optional redirect URL, and optional callback URL (receives POST requests)
667
+ * Optionally pass the customer's registered identity data as
668
+ * `customer_data` (same shape as the geolocation `customer_data` block).
669
+ * It seeds the customer's risk profile so document verification can
670
+ * cross-check the submitted document against trusted reference data;
671
+ * fields never overwrite data already on the profile.
672
+ *
673
+ * @param request - Request containing the user ID, optional redirect URL, optional callback URL (receives POST requests), and optional customer identity data
607
674
  * @returns Response containing the redirect link and KYC ID
608
675
  *
609
676
  * @example
@@ -611,22 +678,30 @@ var KycClient = class extends BaseClient {
611
678
  * const result = await client.requestKycSubmitLink({
612
679
  * user_id: "user_123",
613
680
  * redirect_url: "https://merchant.com/kyc-complete", // optional
614
- * callback_url: "https://merchant.com/api/kyc-webhook" // optional - receives POST requests on status change
681
+ * callback_url: "https://merchant.com/api/kyc-webhook", // optional - receives POST requests on status change
682
+ * customer_data: { // optional - seeds the risk profile for document cross-checks
683
+ * full_name: "John Doe",
684
+ * date_of_birth: "1999-06-02", // ISO 8601
685
+ * email: "john@example.com",
686
+ * phone: "+94771234567",
687
+ * address: "12 Main St, Colombo", // used for address verification
688
+ * country: "LK"
689
+ * }
615
690
  * });
616
691
  *
617
692
  * console.log(`Redirect user to: ${result.link}`);
618
693
  * console.log(`KYC ID: ${result.kyc_id}`);
619
694
  * ```
620
695
  */
621
- async requestKycSubmitLink(request) {
696
+ async requestKycSubmitLink(request, requestOptions) {
622
697
  return this.requestWithRetry("/api/v1/kyc/request", {
623
698
  method: "POST",
624
699
  body: JSON.stringify(request),
625
700
  headers: this.getUserHeaders()
626
- });
701
+ }, void 0, void 0, requestOptions);
627
702
  }
628
703
  /**
629
- * Create a Re-Use KYC session.
704
+ * Create a Event-Based Face Verification session.
630
705
  *
631
706
  * Inspect the response before showing UI:
632
707
  * - `is_required === false` → skip face capture; `reason` explains why.
@@ -636,7 +711,7 @@ var KycClient = class extends BaseClient {
636
711
  *
637
712
  * @param request - Reference, customer_id, event, amount (for threshold events), optional URLs.
638
713
  */
639
- async createReuseKycSession(request) {
714
+ async createEventBasedFaceVerificationSession(request) {
640
715
  return this.request("/api/v1/kyc/face/session", {
641
716
  method: "POST",
642
717
  body: JSON.stringify(request),
@@ -644,33 +719,37 @@ var KycClient = class extends BaseClient {
644
719
  });
645
720
  }
646
721
  /**
647
- * Submit a real-time face capture for an active Re-Use KYC session.
722
+ * Submit a real-time face capture for an active Event-Based Face Verification session.
648
723
  *
649
724
  * **Mobile-only.** The server rejects desktop User-Agents with HTTP
650
725
  * 400 (`face capture must be completed on a mobile device`). Use the
651
- * QR handoff from `createReuseKycSession` for desktop callers.
726
+ * QR handoff from `createEventBasedFaceVerificationSession` for desktop callers.
652
727
  *
653
728
  * The `data` field on the response carries `retries_remaining`,
654
729
  * `retry_limit_exceeded`, and the reaction flags (`enforce_logout`,
655
730
  * `freeze_account`, etc.) so the tenant app can act on a final failure.
656
731
  *
657
- * @param request - Token from `createReuseKycSession`, plus the base64 selfie.
732
+ * @param request - Token from `createEventBasedFaceVerificationSession`, plus the base64 selfie.
658
733
  */
659
- async submitReuseKycSession(request) {
734
+ async submitEventBasedFaceVerificationSession(request, requestOptions) {
660
735
  return this.request("/api/v1/kyc/face/submit", {
661
736
  method: "POST",
662
737
  body: JSON.stringify(request),
663
738
  headers: this.getUserHeaders()
664
- });
739
+ }, void 0, requestOptions);
665
740
  }
666
741
  /**
667
- * Look up the current state of a Re-Use KYC session by its forward
668
- * reference. Useful for desktop pollers waiting on the mobile handoff.
742
+ * Look up the current state of a Event-Based Face Verification session by its
743
+ * session token. Useful for desktop pollers waiting on the mobile handoff.
669
744
  *
670
- * @param reference - The reference used when the session was created.
745
+ * The lookup is scoped by the unguessable, server-issued session token (not
746
+ * the enumerable forward reference): the endpoint is public/unauthenticated,
747
+ * and scoping by the token is what prevents cross-tenant status reads.
748
+ *
749
+ * @param token - The session token returned by `createEventBasedFaceVerificationSession`.
671
750
  */
672
- async getReuseKycSessionStatus(reference) {
673
- return this.requestWithRetry(`/api/v1/kyc/face/verify/${encodeURIComponent(reference)}`, {
751
+ async getEventBasedFaceVerificationSessionStatus(token) {
752
+ return this.requestWithRetry(`/api/v1/kyc/face/verify/${encodeURIComponent(token)}`, {
674
753
  method: "GET",
675
754
  headers: this.getUserHeaders()
676
755
  });
@@ -681,7 +760,7 @@ var KycClient = class extends BaseClient {
681
760
  * callers poll `mobile_connected` to detect when a mobile device has
682
761
  * scanned the QR and attached.
683
762
  *
684
- * @param token - The session token returned by `createReuseKycSession`.
763
+ * @param token - The session token returned by `createEventBasedFaceVerificationSession`.
685
764
  */
686
765
  async getHandoffSession(token) {
687
766
  return this.request(
@@ -756,7 +835,7 @@ var KycClient = class extends BaseClient {
756
835
  * @example
757
836
  * ```typescript
758
837
  * const result = await client.submitVerification({
759
- * reference: "customer_123",
838
+ * reference: "4d2aff34-ab86-422d-992e-50b1234a5b67",
760
839
  * email: "customer@example.com",
761
840
  * country: "US",
762
841
  * document: {
@@ -773,12 +852,12 @@ var KycClient = class extends BaseClient {
773
852
  * console.log(`Verification submitted: ${result.reference}`);
774
853
  * ```
775
854
  */
776
- async submitVerification(request) {
855
+ async submitVerification(request, requestOptions) {
777
856
  return this.requestWithRetry("/api/v1/kyc/submit", {
778
857
  method: "POST",
779
858
  body: JSON.stringify(request),
780
859
  headers: this.getUserHeaders()
781
- });
860
+ }, void 0, void 0, requestOptions);
782
861
  }
783
862
  /**
784
863
  * Get a KYC request by ID
@@ -788,7 +867,7 @@ var KycClient = class extends BaseClient {
788
867
  *
789
868
  * @example
790
869
  * ```typescript
791
- * const kyc = await client.getKycRequest("kyc_abc123");
870
+ * const kyc = await client.getKycRequest("550e8400-e29b-41d4-a716-446655440000");
792
871
  * console.log(`Status: ${kyc.status}, ID Verified: ${kyc.id_verified}`);
793
872
  * ```
794
873
  */
@@ -863,7 +942,7 @@ var KycClient = class extends BaseClient {
863
942
  * @example
864
943
  * ```typescript
865
944
  * await client.requestAdditionalDocuments({
866
- * id: "kyc_abc123",
945
+ * id: "550e8400-e29b-41d4-a716-446655440000",
867
946
  * document_types: ["address", "document_two"],
868
947
  * message: "Please provide proof of address and secondary ID"
869
948
  * });
@@ -884,7 +963,7 @@ var KycClient = class extends BaseClient {
884
963
  *
885
964
  * @example
886
965
  * ```typescript
887
- * const proofs = await client.getProofDownloadURLs("kyc_abc123");
966
+ * const proofs = await client.getProofDownloadURLs("550e8400-e29b-41d4-a716-446655440000");
888
967
  * proofs.forEach(proof => {
889
968
  * console.log(`${proof.type}: ${proof.url} (expires: ${proof.expires_at})`);
890
969
  * });