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