vesant-sdk 1.7.0-dev.059da4f → 1.7.0-dev.13bd228
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/dist/{client-C3DCmGe9.d.ts → client-749WqhDT.d.ts} +2 -2
- package/dist/{client-DMIRx7Tu.d.mts → client-BG8KtVMc.d.mts} +14 -1
- package/dist/{client-ZNdnpWe7.d.mts → client-CRZea-eJ.d.mts} +2 -2
- package/dist/{client-DoMSYMMR.d.ts → client-D9JZgN3X.d.ts} +14 -1
- package/dist/{client-BolQlL5e.d.mts → client-q9fN8Hhf.d.mts} +103 -1
- package/dist/{client-BolQlL5e.d.ts → client-q9fN8Hhf.d.ts} +103 -1
- package/dist/compliance/index.d.mts +3 -3
- package/dist/compliance/index.d.ts +3 -3
- package/dist/compliance/index.js +61 -9
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +61 -9
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/decisions/index.d.mts +1 -1
- package/dist/decisions/index.d.ts +1 -1
- package/dist/decisions/index.js +61 -6
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisions/index.mjs +61 -6
- package/dist/decisions/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +3 -3
- package/dist/geolocation/index.d.ts +3 -3
- package/dist/geolocation/index.js +61 -6
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +61 -6
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +138 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -34
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.d.mts +2 -2
- package/dist/kyc/core.d.ts +2 -2
- package/dist/kyc/core.js +87 -18
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +87 -18
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.d.mts +110 -13
- package/dist/kyc/index.d.ts +110 -13
- package/dist/kyc/index.js +87 -18
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +87 -18
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +5 -3
- package/dist/react.d.ts +5 -3
- package/dist/react.js +112 -73
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +112 -73
- package/dist/react.mjs.map +1 -1
- package/dist/risk-profile/index.d.mts +1 -1
- package/dist/risk-profile/index.d.ts +1 -1
- package/dist/risk-profile/index.js +61 -6
- package/dist/risk-profile/index.js.map +1 -1
- package/dist/risk-profile/index.mjs +61 -6
- package/dist/risk-profile/index.mjs.map +1 -1
- package/dist/scores/index.d.mts +1 -1
- package/dist/scores/index.d.ts +1 -1
- package/dist/scores/index.js +61 -6
- package/dist/scores/index.js.map +1 -1
- package/dist/scores/index.mjs +61 -6
- package/dist/scores/index.mjs.map +1 -1
- package/dist/tax/index.d.mts +3 -26
- package/dist/tax/index.d.ts +3 -26
- package/dist/tax/index.js +67 -18
- package/dist/tax/index.js.map +1 -1
- package/dist/tax/index.mjs +67 -18
- package/dist/tax/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,59 @@
|
|
|
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
|
+
var RefreshingTokenProvider = class {
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
this.opts = opts;
|
|
16
|
+
this.cached = null;
|
|
17
|
+
this.inFlight = null;
|
|
18
|
+
this.skewMs = opts.skewMs ?? 3e4;
|
|
19
|
+
this.scheme = opts.scheme ?? "Bearer";
|
|
20
|
+
this.now = opts.now ?? (() => Date.now());
|
|
21
|
+
}
|
|
22
|
+
canRefresh() {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
async getCredential(ctx) {
|
|
26
|
+
const forceRefresh = ctx?.forceRefresh ?? false;
|
|
27
|
+
if (!forceRefresh && this.cached && !this.isExpiring(this.cached)) {
|
|
28
|
+
return { scheme: this.scheme, token: this.cached.token };
|
|
29
|
+
}
|
|
30
|
+
const fresh = await this.refresh();
|
|
31
|
+
return { scheme: this.scheme, token: fresh.token };
|
|
32
|
+
}
|
|
33
|
+
isExpiring(token) {
|
|
34
|
+
if (token.expiresAt === void 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return this.now() >= token.expiresAt - this.skewMs;
|
|
38
|
+
}
|
|
39
|
+
refresh() {
|
|
40
|
+
if (this.inFlight) {
|
|
41
|
+
return this.inFlight;
|
|
42
|
+
}
|
|
43
|
+
this.inFlight = (async () => {
|
|
44
|
+
try {
|
|
45
|
+
const fresh = await this.opts.fetchToken();
|
|
46
|
+
this.cached = fresh;
|
|
47
|
+
this.opts.onRotate?.({ expiresAt: fresh.expiresAt });
|
|
48
|
+
return fresh;
|
|
49
|
+
} finally {
|
|
50
|
+
this.inFlight = null;
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
53
|
+
return this.inFlight;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
1
57
|
// src/core/errors.ts
|
|
2
58
|
var VesantError = class _VesantError extends Error {
|
|
3
59
|
constructor(message, code, statusCode, details) {
|
|
@@ -345,6 +401,7 @@ var BaseClient = class {
|
|
|
345
401
|
interceptors: this.interceptors,
|
|
346
402
|
logger: this.logger
|
|
347
403
|
};
|
|
404
|
+
this.authProvider = config.authProvider ?? (apiKey ? new StaticApiKeyProvider(apiKey) : void 0);
|
|
348
405
|
if (config.circuitBreaker) {
|
|
349
406
|
this.circuitBreaker = new CircuitBreaker(config.circuitBreaker);
|
|
350
407
|
}
|
|
@@ -352,6 +409,19 @@ var BaseClient = class {
|
|
|
352
409
|
this.rateLimitTracker = new RateLimitTracker();
|
|
353
410
|
}
|
|
354
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Resolve the Idempotency-Key for a request. Mutating methods (POST/PUT/PATCH)
|
|
414
|
+
* get the caller-supplied key or a freshly minted UUID; non-mutating methods get
|
|
415
|
+
* none. requestWithRetry resolves this once and injects it so every retry reuses
|
|
416
|
+
* one key (letting the server dedup replays); a direct request() resolves per call.
|
|
417
|
+
*/
|
|
418
|
+
resolveIdempotencyKey(method, requestOptions) {
|
|
419
|
+
const isMutating = ["POST", "PUT", "PATCH"].includes((method || "GET").toUpperCase());
|
|
420
|
+
if (!isMutating) {
|
|
421
|
+
return void 0;
|
|
422
|
+
}
|
|
423
|
+
return requestOptions?.idempotencyKey ?? generateUUID();
|
|
424
|
+
}
|
|
355
425
|
/**
|
|
356
426
|
* Make an HTTP request with timeout and error handling
|
|
357
427
|
*/
|
|
@@ -377,15 +447,20 @@ var BaseClient = class {
|
|
|
377
447
|
...this.config.headers,
|
|
378
448
|
...options.headers || {}
|
|
379
449
|
};
|
|
380
|
-
|
|
381
|
-
|
|
450
|
+
const credential = await this.authProvider?.getCredential({
|
|
451
|
+
tenantId: this.config.tenantId,
|
|
452
|
+
requestId
|
|
453
|
+
});
|
|
454
|
+
if (credential) {
|
|
455
|
+
headers["Authorization"] = `${credential.scheme ?? "Bearer"} ${credential.token}`;
|
|
382
456
|
}
|
|
383
457
|
if (this.config.environment === "sandbox") {
|
|
384
458
|
headers["X-Sandbox"] = "true";
|
|
385
459
|
}
|
|
386
460
|
const method = (options.method || "GET").toUpperCase();
|
|
387
|
-
|
|
388
|
-
|
|
461
|
+
const idempotencyKey = this.resolveIdempotencyKey(method, requestOptions);
|
|
462
|
+
if (idempotencyKey) {
|
|
463
|
+
headers["Idempotency-Key"] = idempotencyKey;
|
|
389
464
|
}
|
|
390
465
|
const controller = new AbortController();
|
|
391
466
|
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
@@ -406,10 +481,28 @@ var BaseClient = class {
|
|
|
406
481
|
if (this.config.debug) {
|
|
407
482
|
this.logger.debug(`${finalOptions.method || "GET"} ${endpoint}`);
|
|
408
483
|
}
|
|
409
|
-
|
|
484
|
+
let response = await fetch(url, {
|
|
410
485
|
...finalOptions,
|
|
411
486
|
signal: controller.signal
|
|
412
487
|
});
|
|
488
|
+
if (response.status === 401 && this.authProvider?.canRefresh?.()) {
|
|
489
|
+
const refreshed = await this.authProvider.getCredential({
|
|
490
|
+
tenantId: this.config.tenantId,
|
|
491
|
+
requestId,
|
|
492
|
+
forceRefresh: true
|
|
493
|
+
});
|
|
494
|
+
if (refreshed) {
|
|
495
|
+
this.config.onCredentialRotated?.({ reason: "unauthorized" });
|
|
496
|
+
finalOptions = {
|
|
497
|
+
...finalOptions,
|
|
498
|
+
headers: {
|
|
499
|
+
...finalOptions.headers,
|
|
500
|
+
Authorization: `${refreshed.scheme ?? "Bearer"} ${refreshed.token}`
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
response = await fetch(url, { ...finalOptions, signal: controller.signal });
|
|
504
|
+
}
|
|
505
|
+
}
|
|
413
506
|
clearTimeout(timeoutId);
|
|
414
507
|
if (this.rateLimitTracker) {
|
|
415
508
|
this.rateLimitTracker.updateFromHeaders(response.headers);
|
|
@@ -498,9 +591,11 @@ var BaseClient = class {
|
|
|
498
591
|
*/
|
|
499
592
|
async requestWithRetry(endpoint, options = {}, serviceURL, retries = this.config.retries, requestOptions) {
|
|
500
593
|
let lastError;
|
|
594
|
+
const idempotencyKey = this.resolveIdempotencyKey(options.method || "GET", requestOptions);
|
|
595
|
+
const attemptOptions = idempotencyKey ? { ...requestOptions, idempotencyKey } : requestOptions;
|
|
501
596
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
502
597
|
try {
|
|
503
|
-
return await this.request(endpoint, options, serviceURL,
|
|
598
|
+
return await this.request(endpoint, options, serviceURL, attemptOptions);
|
|
504
599
|
} catch (error) {
|
|
505
600
|
lastError = error instanceof Error ? error : new Error("Unknown error");
|
|
506
601
|
if (requestOptions?.signal?.aborted) {
|
|
@@ -597,6 +692,9 @@ var BaseClient = class {
|
|
|
597
692
|
if (config.interceptors) {
|
|
598
693
|
this.interceptors = config.interceptors;
|
|
599
694
|
}
|
|
695
|
+
if (config.authProvider !== void 0 || config.apiKey !== void 0) {
|
|
696
|
+
this.authProvider = this.config.authProvider ?? (this.config.apiKey ? new StaticApiKeyProvider(this.config.apiKey) : void 0);
|
|
697
|
+
}
|
|
600
698
|
}
|
|
601
699
|
/**
|
|
602
700
|
* Get current configuration (readonly)
|
|
@@ -1798,9 +1896,6 @@ var ComplianceClient = class {
|
|
|
1798
1896
|
if (cipherTextResult.risk?.is_blocked) {
|
|
1799
1897
|
blockReasons.push(...cipherTextResult.risk.block_reasons_structured ?? []);
|
|
1800
1898
|
}
|
|
1801
|
-
if (cipherTextResult.risk?.location_mismatch) {
|
|
1802
|
-
blockReasons.push(sdkReasons.gpsIPMismatch());
|
|
1803
|
-
}
|
|
1804
1899
|
}
|
|
1805
1900
|
if (geoVerification.gps_required && !cipherTextResult) {
|
|
1806
1901
|
blockReasons.push(sdkReasons.gpsRequired());
|
|
@@ -2710,7 +2805,13 @@ var KycClient = class extends BaseClient {
|
|
|
2710
2805
|
*
|
|
2711
2806
|
* Generates a link that the user can visit to submit their KYC documents.
|
|
2712
2807
|
*
|
|
2713
|
-
*
|
|
2808
|
+
* Optionally pass the customer's registered identity data as
|
|
2809
|
+
* `customer_data` (same shape as the geolocation `customer_data` block).
|
|
2810
|
+
* It seeds the customer's risk profile so document verification can
|
|
2811
|
+
* cross-check the submitted document against trusted reference data;
|
|
2812
|
+
* fields never overwrite data already on the profile.
|
|
2813
|
+
*
|
|
2814
|
+
* @param request - Request containing the user ID, optional redirect URL, optional callback URL (receives POST requests), and optional customer identity data
|
|
2714
2815
|
* @returns Response containing the redirect link and KYC ID
|
|
2715
2816
|
*
|
|
2716
2817
|
* @example
|
|
@@ -2718,19 +2819,27 @@ var KycClient = class extends BaseClient {
|
|
|
2718
2819
|
* const result = await client.requestKycSubmitLink({
|
|
2719
2820
|
* user_id: "user_123",
|
|
2720
2821
|
* redirect_url: "https://merchant.com/kyc-complete", // optional
|
|
2721
|
-
* callback_url: "https://merchant.com/api/kyc-webhook" // optional - receives POST requests on status change
|
|
2822
|
+
* callback_url: "https://merchant.com/api/kyc-webhook", // optional - receives POST requests on status change
|
|
2823
|
+
* customer_data: { // optional - seeds the risk profile for document cross-checks
|
|
2824
|
+
* full_name: "John Doe",
|
|
2825
|
+
* date_of_birth: "1999-06-02", // ISO 8601
|
|
2826
|
+
* email: "john@example.com",
|
|
2827
|
+
* phone: "+94771234567",
|
|
2828
|
+
* address: "12 Main St, Colombo", // used for address verification
|
|
2829
|
+
* country: "LK"
|
|
2830
|
+
* }
|
|
2722
2831
|
* });
|
|
2723
2832
|
*
|
|
2724
2833
|
* console.log(`Redirect user to: ${result.link}`);
|
|
2725
2834
|
* console.log(`KYC ID: ${result.kyc_id}`);
|
|
2726
2835
|
* ```
|
|
2727
2836
|
*/
|
|
2728
|
-
async requestKycSubmitLink(request) {
|
|
2837
|
+
async requestKycSubmitLink(request, requestOptions) {
|
|
2729
2838
|
return this.requestWithRetry("/api/v1/kyc/request", {
|
|
2730
2839
|
method: "POST",
|
|
2731
2840
|
body: JSON.stringify(request),
|
|
2732
2841
|
headers: this.getUserHeaders()
|
|
2733
|
-
});
|
|
2842
|
+
}, void 0, void 0, requestOptions);
|
|
2734
2843
|
}
|
|
2735
2844
|
/**
|
|
2736
2845
|
* Create a Event-Based Face Verification session.
|
|
@@ -2763,12 +2872,12 @@ var KycClient = class extends BaseClient {
|
|
|
2763
2872
|
*
|
|
2764
2873
|
* @param request - Token from `createEventBasedFaceVerificationSession`, plus the base64 selfie.
|
|
2765
2874
|
*/
|
|
2766
|
-
async submitEventBasedFaceVerificationSession(request) {
|
|
2875
|
+
async submitEventBasedFaceVerificationSession(request, requestOptions) {
|
|
2767
2876
|
return this.request("/api/v1/kyc/face/submit", {
|
|
2768
2877
|
method: "POST",
|
|
2769
2878
|
body: JSON.stringify(request),
|
|
2770
2879
|
headers: this.getUserHeaders()
|
|
2771
|
-
});
|
|
2880
|
+
}, void 0, requestOptions);
|
|
2772
2881
|
}
|
|
2773
2882
|
/**
|
|
2774
2883
|
* Look up the current state of a Event-Based Face Verification session by its
|
|
@@ -2867,7 +2976,7 @@ var KycClient = class extends BaseClient {
|
|
|
2867
2976
|
* @example
|
|
2868
2977
|
* ```typescript
|
|
2869
2978
|
* const result = await client.submitVerification({
|
|
2870
|
-
* reference: "
|
|
2979
|
+
* reference: "4d2aff34-ab86-422d-992e-50b1234a5b67",
|
|
2871
2980
|
* email: "customer@example.com",
|
|
2872
2981
|
* country: "US",
|
|
2873
2982
|
* document: {
|
|
@@ -2884,12 +2993,12 @@ var KycClient = class extends BaseClient {
|
|
|
2884
2993
|
* console.log(`Verification submitted: ${result.reference}`);
|
|
2885
2994
|
* ```
|
|
2886
2995
|
*/
|
|
2887
|
-
async submitVerification(request) {
|
|
2996
|
+
async submitVerification(request, requestOptions) {
|
|
2888
2997
|
return this.requestWithRetry("/api/v1/kyc/submit", {
|
|
2889
2998
|
method: "POST",
|
|
2890
2999
|
body: JSON.stringify(request),
|
|
2891
3000
|
headers: this.getUserHeaders()
|
|
2892
|
-
});
|
|
3001
|
+
}, void 0, void 0, requestOptions);
|
|
2893
3002
|
}
|
|
2894
3003
|
/**
|
|
2895
3004
|
* Get a KYC request by ID
|
|
@@ -2899,7 +3008,7 @@ var KycClient = class extends BaseClient {
|
|
|
2899
3008
|
*
|
|
2900
3009
|
* @example
|
|
2901
3010
|
* ```typescript
|
|
2902
|
-
* const kyc = await client.getKycRequest("
|
|
3011
|
+
* const kyc = await client.getKycRequest("550e8400-e29b-41d4-a716-446655440000");
|
|
2903
3012
|
* console.log(`Status: ${kyc.status}, ID Verified: ${kyc.id_verified}`);
|
|
2904
3013
|
* ```
|
|
2905
3014
|
*/
|
|
@@ -2974,7 +3083,7 @@ var KycClient = class extends BaseClient {
|
|
|
2974
3083
|
* @example
|
|
2975
3084
|
* ```typescript
|
|
2976
3085
|
* await client.requestAdditionalDocuments({
|
|
2977
|
-
* id: "
|
|
3086
|
+
* id: "550e8400-e29b-41d4-a716-446655440000",
|
|
2978
3087
|
* document_types: ["address", "document_two"],
|
|
2979
3088
|
* message: "Please provide proof of address and secondary ID"
|
|
2980
3089
|
* });
|
|
@@ -2995,7 +3104,7 @@ var KycClient = class extends BaseClient {
|
|
|
2995
3104
|
*
|
|
2996
3105
|
* @example
|
|
2997
3106
|
* ```typescript
|
|
2998
|
-
* const proofs = await client.getProofDownloadURLs("
|
|
3107
|
+
* const proofs = await client.getProofDownloadURLs("550e8400-e29b-41d4-a716-446655440000");
|
|
2999
3108
|
* proofs.forEach(proof => {
|
|
3000
3109
|
* console.log(`${proof.type}: ${proof.url} (expires: ${proof.expires_at})`);
|
|
3001
3110
|
* });
|
|
@@ -3329,19 +3438,13 @@ var TaxClient = class extends BaseClient {
|
|
|
3329
3438
|
{ method: "POST" }
|
|
3330
3439
|
);
|
|
3331
3440
|
}
|
|
3332
|
-
async
|
|
3333
|
-
return this.request(
|
|
3334
|
-
"/api/v1/tax/customer-tax-profiles/request-form-with-profile",
|
|
3335
|
-
{
|
|
3336
|
-
method: "POST",
|
|
3337
|
-
body: JSON.stringify(input)
|
|
3338
|
-
}
|
|
3339
|
-
);
|
|
3340
|
-
}
|
|
3341
|
-
async checkTINStatus(customerID) {
|
|
3441
|
+
async checkTINStatus(customerID, requestOptions) {
|
|
3342
3442
|
return this.requestWithRetry(
|
|
3343
3443
|
`/api/v1/tax/customer-tax-profiles/${customerID}/check-tin`,
|
|
3344
|
-
{ method: "POST" }
|
|
3444
|
+
{ method: "POST" },
|
|
3445
|
+
void 0,
|
|
3446
|
+
void 0,
|
|
3447
|
+
requestOptions
|
|
3345
3448
|
);
|
|
3346
3449
|
}
|
|
3347
3450
|
async reRequestTaxForm(customerID, input) {
|
|
@@ -3364,7 +3467,7 @@ var TaxClient = class extends BaseClient {
|
|
|
3364
3467
|
}
|
|
3365
3468
|
async getCustomerDocuments(customerID) {
|
|
3366
3469
|
return this.request(
|
|
3367
|
-
`/api/v1/
|
|
3470
|
+
`/api/v1/tm/customer-tax-profiles/${customerID}/documents`
|
|
3368
3471
|
);
|
|
3369
3472
|
}
|
|
3370
3473
|
async downloadTaxForm(customerID, requestOptions) {
|
|
@@ -3586,6 +3689,6 @@ function buildHandler(options) {
|
|
|
3586
3689
|
return handler;
|
|
3587
3690
|
}
|
|
3588
3691
|
|
|
3589
|
-
export { AuthenticationError, BaseClient, CGSError, CircuitBreaker, CircuitBreakerOpenError, ComplianceBlockedError, ComplianceClient, ComplianceError, DEFAULT_CURRENCY_RATES, GeolocationClient, KYC_DECLINED_DESCRIPTIONS, KycClient, NetworkError, RateLimitError, RateLimitTracker, RiskProfileClient, SDK_VERSION, ServiceUnavailableError, TaxClient, TimeoutError, ValidationError, VesantError, WebhookHandler, createConsoleLogger, createNextWebhookHandler, createWebhookMiddleware, decodeCipherText, generateCipherText, isCipherTextExpired, noopLogger, sdkReasons, verifyWebhookSignature };
|
|
3692
|
+
export { AuthenticationError, BaseClient, CGSError, CircuitBreaker, CircuitBreakerOpenError, ComplianceBlockedError, ComplianceClient, ComplianceError, DEFAULT_CURRENCY_RATES, GeolocationClient, KYC_DECLINED_DESCRIPTIONS, KycClient, NetworkError, RateLimitError, RateLimitTracker, RefreshingTokenProvider, RiskProfileClient, SDK_VERSION, ServiceUnavailableError, StaticApiKeyProvider, TaxClient, TimeoutError, ValidationError, VesantError, WebhookHandler, createConsoleLogger, createNextWebhookHandler, createWebhookMiddleware, decodeCipherText, generateCipherText, isCipherTextExpired, noopLogger, sdkReasons, verifyWebhookSignature };
|
|
3590
3693
|
//# sourceMappingURL=index.mjs.map
|
|
3591
3694
|
//# sourceMappingURL=index.mjs.map
|