@relyio/sdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +5 -310
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-7W4MJXQ4.cjs → chunk-54WP2PWG.cjs} +215 -96
- package/dist/chunk-BBUB7C2Z.js +81 -0
- package/dist/{chunk-FJK7ZWKK.cjs → chunk-HMVGXUGR.cjs} +156 -221
- package/dist/chunk-LSRPMNPT.cjs +89 -0
- package/dist/{chunk-2QUK2ZGD.js → chunk-LYRYCIX5.js} +157 -219
- package/dist/{chunk-RJBIJ2ZK.js → chunk-QIZOBT5F.js} +215 -96
- package/dist/client/index.cjs +4 -3
- package/dist/client/index.d.cts +4 -3
- package/dist/client/index.d.ts +4 -3
- package/dist/client/index.js +2 -1
- package/dist/define-content-type-CBfnTWSS.d.cts +716 -0
- package/dist/define-content-type-CBfnTWSS.d.ts +716 -0
- package/dist/{define-schema-DHvUCKwj.d.cts → define-schema-BD6HSPnG.d.ts} +55 -722
- package/dist/{define-schema-DHvUCKwj.d.ts → define-schema-BfXeR6K8.d.cts} +55 -722
- package/dist/dev-handshake/index.cjs +37 -0
- package/dist/dev-handshake/index.d.cts +144 -0
- package/dist/dev-handshake/index.d.ts +144 -0
- package/dist/dev-handshake/index.js +4 -0
- package/dist/{index-DGWaawHt.d.cts → index-BDpar3FO.d.cts} +22 -6
- package/dist/{index-BsUqCAu8.d.cts → index-DuEhsGdE.d.ts} +516 -2155
- package/dist/{index-B-KiFHbx.d.ts → index-Dx01iwaf.d.ts} +22 -6
- package/dist/{index-BsUqCAu8.d.ts → index-ulOrcfPa.d.cts} +516 -2155
- package/dist/index.cjs +67 -70
- package/dist/index.d.cts +28 -13
- package/dist/index.d.ts +28 -13
- package/dist/index.js +3 -2
- package/dist/schema/index.cjs +35 -47
- package/dist/schema/index.d.cts +3 -2
- package/dist/schema/index.d.ts +3 -2
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/package.json +15 -17
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var chunkLSRPMNPT_cjs = require('./chunk-LSRPMNPT.cjs');
|
|
3
4
|
var chunkMWMSFIWN_cjs = require('./chunk-MWMSFIWN.cjs');
|
|
4
5
|
|
|
5
6
|
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
@@ -167,14 +168,17 @@ var _UsageQuotaExceededError = class _UsageQuotaExceededError extends SDKError {
|
|
|
167
168
|
chunkMWMSFIWN_cjs.__name(_UsageQuotaExceededError, "UsageQuotaExceededError");
|
|
168
169
|
var UsageQuotaExceededError = _UsageQuotaExceededError;
|
|
169
170
|
var _RateLimitError = class _RateLimitError extends SDKError {
|
|
170
|
-
constructor(message = "Rate limit exceeded", limit, resetAt, context) {
|
|
171
|
+
constructor(message = "Rate limit exceeded", limit, resetAt, context, retryAfterMs) {
|
|
171
172
|
super(message, 429, void 0, context);
|
|
172
173
|
chunkMWMSFIWN_cjs.__publicField(this, "code", "RATE_LIMIT_EXCEEDED");
|
|
173
174
|
chunkMWMSFIWN_cjs.__publicField(this, "retryable", true);
|
|
174
175
|
chunkMWMSFIWN_cjs.__publicField(this, "limit");
|
|
175
176
|
chunkMWMSFIWN_cjs.__publicField(this, "resetAt");
|
|
177
|
+
/** `Retry-After`, in milliseconds, where the response carried a readable one. */
|
|
178
|
+
chunkMWMSFIWN_cjs.__publicField(this, "retryAfterMs");
|
|
176
179
|
this.limit = limit;
|
|
177
180
|
this.resetAt = resetAt;
|
|
181
|
+
this.retryAfterMs = retryAfterMs;
|
|
178
182
|
}
|
|
179
183
|
getUserMessage() {
|
|
180
184
|
return this.resetAt === void 0 ? "Too many requests. Please retry shortly." : `Too many requests. The window resets at ${this.resetAt}.`;
|
|
@@ -223,12 +227,15 @@ var _TransactionRolledBackError = class _TransactionRolledBackError extends SDKE
|
|
|
223
227
|
chunkMWMSFIWN_cjs.__name(_TransactionRolledBackError, "TransactionRolledBackError");
|
|
224
228
|
var TransactionRolledBackError = _TransactionRolledBackError;
|
|
225
229
|
var _ServiceIndeterminateError = class _ServiceIndeterminateError extends SDKError {
|
|
226
|
-
constructor(message = "The service could not decide this request", missing, context) {
|
|
230
|
+
constructor(message = "The service could not decide this request", missing, context, retryAfterMs) {
|
|
227
231
|
super(message, 503, void 0, context);
|
|
228
232
|
chunkMWMSFIWN_cjs.__publicField(this, "code", "SERVICE_INDETERMINATE");
|
|
229
233
|
chunkMWMSFIWN_cjs.__publicField(this, "retryable", true);
|
|
230
234
|
chunkMWMSFIWN_cjs.__publicField(this, "missing");
|
|
235
|
+
/** `Retry-After`, in milliseconds. The contract requires the header on this code. */
|
|
236
|
+
chunkMWMSFIWN_cjs.__publicField(this, "retryAfterMs");
|
|
231
237
|
this.missing = missing;
|
|
238
|
+
this.retryAfterMs = retryAfterMs;
|
|
232
239
|
}
|
|
233
240
|
getUserMessage() {
|
|
234
241
|
return "The service is temporarily unable to answer. Please retry.";
|
|
@@ -459,6 +466,14 @@ var _InvalidFieldTypeError = class _InvalidFieldTypeError extends BaseValidation
|
|
|
459
466
|
chunkMWMSFIWN_cjs.__name(_InvalidFieldTypeError, "InvalidFieldTypeError");
|
|
460
467
|
var InvalidFieldTypeError = _InvalidFieldTypeError;
|
|
461
468
|
|
|
469
|
+
// ../../platform/api-contract/dist/index.js
|
|
470
|
+
var HEADER_RETRY_AFTER = { name: "Retry-After" };
|
|
471
|
+
var HEADER_ENTITY_TAG = { name: "X-Entity-Tag" };
|
|
472
|
+
var HEADER_IF_MATCH = {
|
|
473
|
+
name: "If-Match"};
|
|
474
|
+
var HEADER_IDEMPOTENCY_KEY = {
|
|
475
|
+
name: "Idempotency-Key"};
|
|
476
|
+
|
|
462
477
|
// ../../platform/api-contract/dist/client/index.js
|
|
463
478
|
var _a;
|
|
464
479
|
var ContractBodyError = (_a = class extends Error {
|
|
@@ -502,19 +517,47 @@ function readError(body) {
|
|
|
502
517
|
}
|
|
503
518
|
chunkMWMSFIWN_cjs.__name(readError, "readError");
|
|
504
519
|
|
|
520
|
+
// src/http/retry-after.ts
|
|
521
|
+
function headerValue(headers, name) {
|
|
522
|
+
if (headers === void 0) return void 0;
|
|
523
|
+
const wanted = name.toLowerCase();
|
|
524
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
525
|
+
if (key.toLowerCase() === wanted) return value;
|
|
526
|
+
}
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
529
|
+
chunkMWMSFIWN_cjs.__name(headerValue, "headerValue");
|
|
530
|
+
function parseRetryAfterMs(value, nowMs) {
|
|
531
|
+
if (value === void 0) return void 0;
|
|
532
|
+
const trimmed = value.trim();
|
|
533
|
+
if (trimmed === "") return void 0;
|
|
534
|
+
if (/^\d+$/.test(trimmed)) {
|
|
535
|
+
return Number(trimmed) * 1e3;
|
|
536
|
+
}
|
|
537
|
+
if (!/[A-Za-z]/.test(trimmed)) return void 0;
|
|
538
|
+
const at = Date.parse(trimmed);
|
|
539
|
+
if (Number.isNaN(at)) return void 0;
|
|
540
|
+
return Math.max(0, at - nowMs);
|
|
541
|
+
}
|
|
542
|
+
chunkMWMSFIWN_cjs.__name(parseRetryAfterMs, "parseRetryAfterMs");
|
|
543
|
+
|
|
505
544
|
// src/errors/error-mapper.ts
|
|
506
545
|
var _ErrorMapper = class _ErrorMapper {
|
|
507
546
|
/** Map a non-2xx response to an SDK error. */
|
|
508
547
|
static mapHttpError(response, requestContext) {
|
|
509
|
-
const { status, statusText, body } = response;
|
|
548
|
+
const { status, statusText, body, headers } = response;
|
|
510
549
|
const refusal = readError(body);
|
|
511
550
|
const context = { ...requestContext, response: body };
|
|
512
551
|
if (refusal === void 0) {
|
|
513
552
|
return new NetworkError(`HTTP ${status}: ${statusText}`.trim(), status, void 0, context);
|
|
514
553
|
}
|
|
515
|
-
|
|
554
|
+
const retryAfterMs = parseRetryAfterMs(
|
|
555
|
+
headerValue(headers, HEADER_RETRY_AFTER.name),
|
|
556
|
+
Date.now()
|
|
557
|
+
);
|
|
558
|
+
return this.fromContractCode(refusal, status, context, retryAfterMs);
|
|
516
559
|
}
|
|
517
|
-
static fromContractCode(refusal, status, context) {
|
|
560
|
+
static fromContractCode(refusal, status, context, retryAfterMs) {
|
|
518
561
|
const message = refusal.messages[0] ?? `RelyIO refused with ${refusal.code}`;
|
|
519
562
|
switch (refusal.code) {
|
|
520
563
|
case "MISSING_API_KEY": {
|
|
@@ -545,7 +588,8 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
545
588
|
message,
|
|
546
589
|
detailNumber(refusal, "limit"),
|
|
547
590
|
detailString(refusal, "resetAt"),
|
|
548
|
-
context
|
|
591
|
+
context,
|
|
592
|
+
retryAfterMs
|
|
549
593
|
);
|
|
550
594
|
}
|
|
551
595
|
case "REQUEST_INVALID": {
|
|
@@ -588,7 +632,12 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
588
632
|
);
|
|
589
633
|
}
|
|
590
634
|
case "SERVICE_INDETERMINATE": {
|
|
591
|
-
return new ServiceIndeterminateError(
|
|
635
|
+
return new ServiceIndeterminateError(
|
|
636
|
+
message,
|
|
637
|
+
detailString(refusal, "missing"),
|
|
638
|
+
context,
|
|
639
|
+
retryAfterMs
|
|
640
|
+
);
|
|
592
641
|
}
|
|
593
642
|
case "INTERNAL_ERROR": {
|
|
594
643
|
return new ServerError(message, status, context);
|
|
@@ -630,12 +679,6 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
630
679
|
}
|
|
631
680
|
return error.name === "TypeError" && error.message.includes("fetch") || error.message.includes("timeout") || error.message.includes("Network Error") || error.message.includes("ECONNREFUSED");
|
|
632
681
|
}
|
|
633
|
-
/**
|
|
634
|
-
* Extract retry delay from error
|
|
635
|
-
*/
|
|
636
|
-
static getRetryDelay(_error) {
|
|
637
|
-
return 0;
|
|
638
|
-
}
|
|
639
682
|
};
|
|
640
683
|
chunkMWMSFIWN_cjs.__name(_ErrorMapper, "ErrorMapper");
|
|
641
684
|
var ErrorMapper = _ErrorMapper;
|
|
@@ -694,13 +737,61 @@ function fillPath(template, params) {
|
|
|
694
737
|
}
|
|
695
738
|
chunkMWMSFIWN_cjs.__name(fillPath, "fillPath");
|
|
696
739
|
|
|
740
|
+
// src/http/retry-policy.ts
|
|
741
|
+
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set([
|
|
742
|
+
"GET",
|
|
743
|
+
"HEAD",
|
|
744
|
+
"OPTIONS",
|
|
745
|
+
"PUT",
|
|
746
|
+
"DELETE",
|
|
747
|
+
"TRACE"
|
|
748
|
+
]);
|
|
749
|
+
function isReplaySafe(request) {
|
|
750
|
+
if (IDEMPOTENT_METHODS.has(request.method.toUpperCase())) return true;
|
|
751
|
+
return headerValue(request.headers, HEADER_IDEMPOTENCY_KEY.name) !== void 0;
|
|
752
|
+
}
|
|
753
|
+
chunkMWMSFIWN_cjs.__name(isReplaySafe, "isReplaySafe");
|
|
754
|
+
function serviceInstructedDelayMs(error, nowMs) {
|
|
755
|
+
if (error instanceof ServiceIndeterminateError) {
|
|
756
|
+
return error.retryAfterMs;
|
|
757
|
+
}
|
|
758
|
+
if (!(error instanceof RateLimitError)) return void 0;
|
|
759
|
+
if (error.retryAfterMs !== void 0) return error.retryAfterMs;
|
|
760
|
+
if (error.resetAt === void 0) return void 0;
|
|
761
|
+
const resetAtMs = Date.parse(error.resetAt);
|
|
762
|
+
if (Number.isNaN(resetAtMs)) return void 0;
|
|
763
|
+
const wait = resetAtMs - nowMs;
|
|
764
|
+
return wait > 0 ? wait : void 0;
|
|
765
|
+
}
|
|
766
|
+
chunkMWMSFIWN_cjs.__name(serviceInstructedDelayMs, "serviceInstructedDelayMs");
|
|
767
|
+
var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
768
|
+
constructor(config) {
|
|
769
|
+
chunkMWMSFIWN_cjs.__publicField(this, "config");
|
|
770
|
+
this.config = config;
|
|
771
|
+
}
|
|
772
|
+
shouldRetry(attempt, error, request) {
|
|
773
|
+
if (attempt >= this.config.maxAttempts) return false;
|
|
774
|
+
if (!ErrorMapper.isRetryable(error)) return false;
|
|
775
|
+
return isReplaySafe(request);
|
|
776
|
+
}
|
|
777
|
+
delayFor(attempt, error) {
|
|
778
|
+
const instructed = serviceInstructedDelayMs(error, Date.now());
|
|
779
|
+
if (instructed !== void 0) return instructed;
|
|
780
|
+
const exponential = this.config.baseDelay * Math.pow(this.config.backoffFactor, attempt - 1);
|
|
781
|
+
const delay = Math.min(exponential, this.config.maxDelay);
|
|
782
|
+
return this.config.jitter ? delay * (0.5 + Math.random() * 0.5) : delay;
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
chunkMWMSFIWN_cjs.__name(_DefaultRetryPolicy, "DefaultRetryPolicy");
|
|
786
|
+
var DefaultRetryPolicy = _DefaultRetryPolicy;
|
|
787
|
+
|
|
697
788
|
// src/http/http-client.ts
|
|
698
789
|
var _HttpClient = class _HttpClient {
|
|
699
790
|
constructor(config) {
|
|
700
791
|
chunkMWMSFIWN_cjs.__publicField(this, "baseUrl");
|
|
701
792
|
chunkMWMSFIWN_cjs.__publicField(this, "defaultHeaders");
|
|
702
793
|
chunkMWMSFIWN_cjs.__publicField(this, "timeout");
|
|
703
|
-
chunkMWMSFIWN_cjs.__publicField(this, "
|
|
794
|
+
chunkMWMSFIWN_cjs.__publicField(this, "retryPolicy");
|
|
704
795
|
chunkMWMSFIWN_cjs.__publicField(this, "debug");
|
|
705
796
|
chunkMWMSFIWN_cjs.__publicField(this, "logger");
|
|
706
797
|
chunkMWMSFIWN_cjs.__publicField(this, "config");
|
|
@@ -721,16 +812,13 @@ var _HttpClient = class _HttpClient {
|
|
|
721
812
|
const globalWithVersion = globalThis;
|
|
722
813
|
this.defaultHeaders["User-Agent"] = `RelyIO-SDK/${globalWithVersion.__VERSION__ ?? "0.0.0"}`;
|
|
723
814
|
}
|
|
724
|
-
this.
|
|
815
|
+
this.retryPolicy = new DefaultRetryPolicy({
|
|
725
816
|
maxAttempts: config.retryAttempts,
|
|
726
817
|
baseDelay: 1e3,
|
|
727
818
|
maxDelay: 1e4,
|
|
728
819
|
backoffFactor: 2,
|
|
729
|
-
jitter: true
|
|
730
|
-
|
|
731
|
-
return ErrorMapper.isRetryable(error) && attempt < config.retryAttempts;
|
|
732
|
-
}, "retryCondition")
|
|
733
|
-
};
|
|
820
|
+
jitter: true
|
|
821
|
+
});
|
|
734
822
|
this.log("debug", "HttpClient initialized", {
|
|
735
823
|
baseUrl: this.baseUrl,
|
|
736
824
|
timeout: this.timeout,
|
|
@@ -763,7 +851,16 @@ var _HttpClient = class _HttpClient {
|
|
|
763
851
|
return readPayload(response.body);
|
|
764
852
|
}
|
|
765
853
|
/**
|
|
766
|
-
* Make an HTTP request
|
|
854
|
+
* Make an HTTP request, retrying only where a retry is safe.
|
|
855
|
+
*
|
|
856
|
+
* The headers are merged **once**, before the first attempt, and every attempt
|
|
857
|
+
* sends that same object. That is what makes a minted `Idempotency-Key` stable
|
|
858
|
+
* across the retries of one logical write: the service sees one key and
|
|
859
|
+
* answers the replay from the original outcome instead of applying it twice.
|
|
860
|
+
*
|
|
861
|
+
* The loop always makes one attempt. The incumbent's `while (attempt <
|
|
862
|
+
* maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
|
|
863
|
+
* accepts — and then dereferenced an unassigned `lastError`.
|
|
767
864
|
*/
|
|
768
865
|
async request(config) {
|
|
769
866
|
const mergedConfig = this.mergeRequestConfig(config);
|
|
@@ -772,14 +869,11 @@ var _HttpClient = class _HttpClient {
|
|
|
772
869
|
url: mergedConfig.url
|
|
773
870
|
// Show the final URL with query params
|
|
774
871
|
});
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
872
|
+
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
873
|
+
delete mergedConfig.headers["Content-Type"];
|
|
874
|
+
}
|
|
875
|
+
for (let attempt = 1; ; attempt++) {
|
|
779
876
|
try {
|
|
780
|
-
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
781
|
-
delete mergedConfig.headers["Content-Type"];
|
|
782
|
-
}
|
|
783
877
|
const response = await this.makeRequest(mergedConfig.url, mergedConfig);
|
|
784
878
|
this.log("debug", "Request successful", {
|
|
785
879
|
status: response.status,
|
|
@@ -788,31 +882,30 @@ var _HttpClient = class _HttpClient {
|
|
|
788
882
|
});
|
|
789
883
|
return response;
|
|
790
884
|
} catch (error) {
|
|
791
|
-
|
|
885
|
+
const failure = error;
|
|
792
886
|
this.log("warn", "Request failed", {
|
|
793
887
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
794
888
|
attempt,
|
|
795
889
|
url: mergedConfig.url
|
|
796
890
|
});
|
|
797
|
-
if (
|
|
798
|
-
const delay = this.
|
|
891
|
+
if (this.retryPolicy.shouldRetry(attempt, failure, mergedConfig)) {
|
|
892
|
+
const delay = this.retryPolicy.delayFor(attempt, failure);
|
|
799
893
|
this.log("debug", "Retrying request", { attempt, delay });
|
|
800
894
|
await this.sleep(delay);
|
|
801
895
|
continue;
|
|
802
896
|
}
|
|
803
|
-
|
|
897
|
+
const sdkError = ErrorMapper.mapGenericError(failure, {
|
|
898
|
+
url: mergedConfig.url,
|
|
899
|
+
method: mergedConfig.method,
|
|
900
|
+
attempt
|
|
901
|
+
});
|
|
902
|
+
this.log("error", "Request failed after all retries", {
|
|
903
|
+
error: sdkError.toJSON(),
|
|
904
|
+
url: mergedConfig.url
|
|
905
|
+
});
|
|
906
|
+
throw sdkError;
|
|
804
907
|
}
|
|
805
908
|
}
|
|
806
|
-
const sdkError = ErrorMapper.mapGenericError(lastError, {
|
|
807
|
-
url: mergedConfig.url,
|
|
808
|
-
method: mergedConfig.method,
|
|
809
|
-
attempt
|
|
810
|
-
});
|
|
811
|
-
this.log("error", "Request failed after all retries", {
|
|
812
|
-
error: sdkError.toJSON(),
|
|
813
|
-
url: mergedConfig.url
|
|
814
|
-
});
|
|
815
|
-
throw sdkError;
|
|
816
909
|
}
|
|
817
910
|
/**
|
|
818
911
|
* Make a GET request
|
|
@@ -1060,14 +1153,6 @@ var _HttpClient = class _HttpClient {
|
|
|
1060
1153
|
});
|
|
1061
1154
|
return obj;
|
|
1062
1155
|
}
|
|
1063
|
-
calculateRetryDelay(attempt) {
|
|
1064
|
-
const exponentialDelay = this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffFactor, attempt - 1);
|
|
1065
|
-
const delay = Math.min(exponentialDelay, this.retryConfig.maxDelay);
|
|
1066
|
-
if (this.retryConfig.jitter) {
|
|
1067
|
-
return delay * (0.5 + Math.random() * 0.5);
|
|
1068
|
-
}
|
|
1069
|
-
return delay;
|
|
1070
|
-
}
|
|
1071
1156
|
sleep(ms) {
|
|
1072
1157
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1073
1158
|
}
|
|
@@ -1563,32 +1648,27 @@ var _ContentByIdBuilder = class _ContentByIdBuilder {
|
|
|
1563
1648
|
chunkMWMSFIWN_cjs.__name(_ContentByIdBuilder, "ContentByIdBuilder");
|
|
1564
1649
|
var ContentByIdBuilder = _ContentByIdBuilder;
|
|
1565
1650
|
|
|
1566
|
-
// ../../platform/api-contract/dist/index.js
|
|
1567
|
-
var HEADER_ENTITY_TAG = { name: "X-Entity-Tag" };
|
|
1568
|
-
var HEADER_IF_MATCH = {
|
|
1569
|
-
name: "If-Match"};
|
|
1570
|
-
var HEADER_IDEMPOTENCY_KEY = {
|
|
1571
|
-
name: "Idempotency-Key"};
|
|
1572
|
-
|
|
1573
1651
|
// src/http/write-options.ts
|
|
1652
|
+
function mintIdempotencyKey() {
|
|
1653
|
+
const webCrypto = globalThis.crypto;
|
|
1654
|
+
if (typeof webCrypto?.randomUUID !== "function") return void 0;
|
|
1655
|
+
return webCrypto.randomUUID();
|
|
1656
|
+
}
|
|
1657
|
+
chunkMWMSFIWN_cjs.__name(mintIdempotencyKey, "mintIdempotencyKey");
|
|
1574
1658
|
function writeHeaders(options) {
|
|
1575
|
-
if (options === void 0) return void 0;
|
|
1576
1659
|
const headers = {};
|
|
1577
|
-
if ("ifMatch" in options && options.ifMatch !== void 0) {
|
|
1660
|
+
if (options !== void 0 && "ifMatch" in options && options.ifMatch !== void 0) {
|
|
1578
1661
|
headers[HEADER_IF_MATCH.name] = options.ifMatch;
|
|
1579
1662
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1663
|
+
const idempotencyKey = options?.idempotencyKey ?? mintIdempotencyKey();
|
|
1664
|
+
if (idempotencyKey !== void 0) {
|
|
1665
|
+
headers[HEADER_IDEMPOTENCY_KEY.name] = idempotencyKey;
|
|
1582
1666
|
}
|
|
1583
1667
|
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1584
1668
|
}
|
|
1585
1669
|
chunkMWMSFIWN_cjs.__name(writeHeaders, "writeHeaders");
|
|
1586
1670
|
function entityTagOf(response) {
|
|
1587
|
-
|
|
1588
|
-
for (const [name, value] of Object.entries(response.headers)) {
|
|
1589
|
-
if (name.toLowerCase() === wanted) return value;
|
|
1590
|
-
}
|
|
1591
|
-
return void 0;
|
|
1671
|
+
return headerValue(response.headers, HEADER_ENTITY_TAG.name);
|
|
1592
1672
|
}
|
|
1593
1673
|
chunkMWMSFIWN_cjs.__name(entityTagOf, "entityTagOf");
|
|
1594
1674
|
|
|
@@ -3872,47 +3952,76 @@ function isProduction(proc) {
|
|
|
3872
3952
|
return proc?.env?.NODE_ENV === "production";
|
|
3873
3953
|
}
|
|
3874
3954
|
chunkMWMSFIWN_cjs.__name(isProduction, "isProduction");
|
|
3875
|
-
function resolveFromEnv(proc) {
|
|
3876
|
-
const
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3955
|
+
function resolveFromEnv(proc, now) {
|
|
3956
|
+
const verdict = chunkLSRPMNPT_cjs.parseDevEnv(proc?.env, now);
|
|
3957
|
+
switch (verdict.state) {
|
|
3958
|
+
case "active":
|
|
3959
|
+
return {
|
|
3960
|
+
state: "active",
|
|
3961
|
+
override: {
|
|
3962
|
+
dataset: verdict.credentials.dataset,
|
|
3963
|
+
apiKey: verdict.credentials.apiKey,
|
|
3964
|
+
source: "env"
|
|
3965
|
+
}
|
|
3966
|
+
};
|
|
3967
|
+
case "expired":
|
|
3968
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
3969
|
+
case "unreadable":
|
|
3970
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
3971
|
+
case "absent":
|
|
3972
|
+
return { state: "absent" };
|
|
3880
3973
|
}
|
|
3881
|
-
return null;
|
|
3882
3974
|
}
|
|
3883
3975
|
chunkMWMSFIWN_cjs.__name(resolveFromEnv, "resolveFromEnv");
|
|
3884
|
-
function resolveFromFile(proc) {
|
|
3885
|
-
if (proc == null || typeof proc.cwd !== "function") return
|
|
3976
|
+
function resolveFromFile(proc, now) {
|
|
3977
|
+
if (proc == null || typeof proc.cwd !== "function") return { state: "absent" };
|
|
3886
3978
|
const fs = getBuiltin(proc, "node:fs");
|
|
3887
3979
|
const path = getBuiltin(proc, "node:path");
|
|
3888
|
-
if (fs == null || path == null) return
|
|
3980
|
+
if (fs == null || path == null) return { state: "absent" };
|
|
3889
3981
|
let dir = proc.cwd();
|
|
3890
3982
|
for (; ; ) {
|
|
3891
|
-
const candidate = path.join(dir,
|
|
3983
|
+
const candidate = path.join(dir, chunkLSRPMNPT_cjs.DEV_CONTEXT_DIR, chunkLSRPMNPT_cjs.DEV_CONTEXT_FILENAME);
|
|
3984
|
+
let raw = null;
|
|
3892
3985
|
try {
|
|
3893
|
-
if (fs.existsSync(candidate))
|
|
3894
|
-
const parsed = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
3895
|
-
if (parsed.datasetId != null && parsed.datasetId !== "" && parsed.previewApiKey != null && parsed.previewApiKey !== "") {
|
|
3896
|
-
if (parsed.expiresAt != null && Number.isFinite(new Date(parsed.expiresAt).getTime()) && new Date(parsed.expiresAt).getTime() < Date.now()) {
|
|
3897
|
-
return null;
|
|
3898
|
-
}
|
|
3899
|
-
return { dataset: parsed.datasetId, apiKey: parsed.previewApiKey, source: "file" };
|
|
3900
|
-
}
|
|
3901
|
-
}
|
|
3986
|
+
if (fs.existsSync(candidate)) raw = fs.readFileSync(candidate, "utf8");
|
|
3902
3987
|
} catch {
|
|
3988
|
+
return { state: "absent" };
|
|
3989
|
+
}
|
|
3990
|
+
if (raw !== null) {
|
|
3991
|
+
const verdict = chunkLSRPMNPT_cjs.parseDevContextFile(raw, now);
|
|
3992
|
+
switch (verdict.state) {
|
|
3993
|
+
case "active":
|
|
3994
|
+
return {
|
|
3995
|
+
state: "active",
|
|
3996
|
+
override: {
|
|
3997
|
+
dataset: verdict.context.datasetId,
|
|
3998
|
+
apiKey: verdict.context.previewApiKey,
|
|
3999
|
+
source: "file"
|
|
4000
|
+
}
|
|
4001
|
+
};
|
|
4002
|
+
case "expired":
|
|
4003
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
4004
|
+
case "unreadable":
|
|
4005
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
4006
|
+
case "absent":
|
|
4007
|
+
return { state: "absent" };
|
|
4008
|
+
}
|
|
3903
4009
|
}
|
|
3904
4010
|
const parent = path.dirname(dir);
|
|
3905
4011
|
if (parent === dir) break;
|
|
3906
4012
|
dir = parent;
|
|
3907
4013
|
}
|
|
3908
|
-
return
|
|
4014
|
+
return { state: "absent" };
|
|
3909
4015
|
}
|
|
3910
4016
|
chunkMWMSFIWN_cjs.__name(resolveFromFile, "resolveFromFile");
|
|
3911
4017
|
function resolveDevOverride(dev) {
|
|
3912
|
-
if (dev === false) return
|
|
4018
|
+
if (dev === false) return { state: "disabled" };
|
|
3913
4019
|
const proc = getProcess();
|
|
3914
|
-
if (dev !== true && isProduction(proc)) return
|
|
3915
|
-
|
|
4020
|
+
if (dev !== true && isProduction(proc)) return { state: "disabled" };
|
|
4021
|
+
const now = Date.now();
|
|
4022
|
+
const fromEnv = resolveFromEnv(proc, now);
|
|
4023
|
+
if (fromEnv.state !== "absent") return fromEnv;
|
|
4024
|
+
return resolveFromFile(proc, now);
|
|
3916
4025
|
}
|
|
3917
4026
|
chunkMWMSFIWN_cjs.__name(resolveDevOverride, "resolveDevOverride");
|
|
3918
4027
|
|
|
@@ -3995,16 +4104,26 @@ function mergeConfig(userConfig) {
|
|
|
3995
4104
|
...userConfig.debug
|
|
3996
4105
|
}
|
|
3997
4106
|
};
|
|
3998
|
-
const
|
|
3999
|
-
if (
|
|
4000
|
-
merged.apiKey =
|
|
4001
|
-
merged.dataset =
|
|
4107
|
+
const dev = resolveDevOverride(userConfig.dev);
|
|
4108
|
+
if (dev.state === "active") {
|
|
4109
|
+
merged.apiKey = dev.override.apiKey;
|
|
4110
|
+
merged.dataset = dev.override.dataset;
|
|
4002
4111
|
if (!devOverrideNotified) {
|
|
4003
4112
|
devOverrideNotified = true;
|
|
4004
4113
|
console.info(
|
|
4005
|
-
`[RelyIO] Sandbox dev mode active (${
|
|
4114
|
+
`[RelyIO] Sandbox dev mode active (${dev.override.source}) \u2014 targeting dataset "${dev.override.dataset}" with a scoped preview key.`
|
|
4006
4115
|
);
|
|
4007
4116
|
}
|
|
4117
|
+
} else if (dev.state === "expired" && !devOverrideNotified) {
|
|
4118
|
+
devOverrideNotified = true;
|
|
4119
|
+
console.warn(
|
|
4120
|
+
`[RelyIO] Your sandbox's .relyio/dev.json expired at ${dev.expiredAt} \u2014 ignoring it and using the configured dataset "${merged.dataset}". Run \`relyio dev\` to refresh it.`
|
|
4121
|
+
);
|
|
4122
|
+
} else if (dev.state === "unreadable" && !devOverrideNotified) {
|
|
4123
|
+
devOverrideNotified = true;
|
|
4124
|
+
console.warn(
|
|
4125
|
+
`[RelyIO] Your .relyio/dev.json could not be read (${dev.reason}) \u2014 ignoring it and using the configured dataset "${merged.dataset}". Run \`relyio dev\` to rewrite it.`
|
|
4126
|
+
);
|
|
4008
4127
|
}
|
|
4009
4128
|
return merged;
|
|
4010
4129
|
}
|
|
@@ -4425,5 +4544,5 @@ exports.entityTagOf = entityTagOf;
|
|
|
4425
4544
|
exports.isAssetEntry = isAssetEntry;
|
|
4426
4545
|
exports.isResourceNotFound = isResourceNotFound;
|
|
4427
4546
|
exports.validateFile = validateFile;
|
|
4428
|
-
//# sourceMappingURL=chunk-
|
|
4429
|
-
//# sourceMappingURL=chunk-
|
|
4547
|
+
//# sourceMappingURL=chunk-54WP2PWG.cjs.map
|
|
4548
|
+
//# sourceMappingURL=chunk-54WP2PWG.cjs.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { __name } from './chunk-XQ4QHWZE.js';
|
|
2
|
+
|
|
3
|
+
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
4
|
+
|
|
5
|
+
// src/dev-handshake/index.ts
|
|
6
|
+
var DEV_CONTEXT_DIR = ".relyio";
|
|
7
|
+
var DEV_CONTEXT_FILENAME = "dev.json";
|
|
8
|
+
var DEV_CONTEXT_FILE = `${DEV_CONTEXT_DIR}/${DEV_CONTEXT_FILENAME}`;
|
|
9
|
+
var DEV_ENV = {
|
|
10
|
+
dataset: "RELYIO_DEV_DATASET",
|
|
11
|
+
apiKey: "RELYIO_DEV_API_KEY",
|
|
12
|
+
expiresAt: "RELYIO_DEV_EXPIRES_AT"
|
|
13
|
+
};
|
|
14
|
+
function readDeadline(raw, now) {
|
|
15
|
+
if (raw === void 0 || raw === null || raw === "") return { state: "none" };
|
|
16
|
+
if (typeof raw !== "string") return { state: "unreadable" };
|
|
17
|
+
const deadline = new Date(raw).getTime();
|
|
18
|
+
if (!Number.isFinite(deadline)) return { state: "unreadable" };
|
|
19
|
+
return deadline <= now ? { state: "passed", expiredAt: raw } : { state: "live", expiresAt: raw };
|
|
20
|
+
}
|
|
21
|
+
__name(readDeadline, "readDeadline");
|
|
22
|
+
function parseDevContextFile(raw, now) {
|
|
23
|
+
let parsed;
|
|
24
|
+
try {
|
|
25
|
+
parsed = JSON.parse(raw);
|
|
26
|
+
} catch {
|
|
27
|
+
return { state: "unreadable", reason: "not-json" };
|
|
28
|
+
}
|
|
29
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
30
|
+
return { state: "unreadable", reason: "not-json" };
|
|
31
|
+
}
|
|
32
|
+
const record = parsed;
|
|
33
|
+
const { datasetId, previewApiKey, branchId, expiresAt } = record;
|
|
34
|
+
if (typeof datasetId !== "string" || datasetId === "" || typeof previewApiKey !== "string" || previewApiKey === "" || typeof branchId !== "string" || branchId === "") {
|
|
35
|
+
return { state: "unreadable", reason: "missing-fields" };
|
|
36
|
+
}
|
|
37
|
+
const deadline = readDeadline(expiresAt, now);
|
|
38
|
+
if (deadline.state === "unreadable") return { state: "unreadable", reason: "bad-expiry" };
|
|
39
|
+
const context = {
|
|
40
|
+
datasetId,
|
|
41
|
+
previewApiKey,
|
|
42
|
+
branchId,
|
|
43
|
+
expiresAt: deadline.state === "none" ? null : expiresAt
|
|
44
|
+
};
|
|
45
|
+
return deadline.state === "passed" ? { state: "expired", context, expiredAt: deadline.expiredAt } : { state: "active", context };
|
|
46
|
+
}
|
|
47
|
+
__name(parseDevContextFile, "parseDevContextFile");
|
|
48
|
+
function buildDevEnv(context) {
|
|
49
|
+
const env = {
|
|
50
|
+
[DEV_ENV.dataset]: context.datasetId,
|
|
51
|
+
[DEV_ENV.apiKey]: context.previewApiKey
|
|
52
|
+
};
|
|
53
|
+
if (context.expiresAt != null && context.expiresAt !== "") {
|
|
54
|
+
env[DEV_ENV.expiresAt] = context.expiresAt;
|
|
55
|
+
}
|
|
56
|
+
return env;
|
|
57
|
+
}
|
|
58
|
+
__name(buildDevEnv, "buildDevEnv");
|
|
59
|
+
function parseDevEnv(env, now) {
|
|
60
|
+
const dataset = env?.[DEV_ENV.dataset];
|
|
61
|
+
const apiKey = env?.[DEV_ENV.apiKey];
|
|
62
|
+
if (dataset == null || dataset === "" || apiKey == null || apiKey === "") {
|
|
63
|
+
return { state: "absent" };
|
|
64
|
+
}
|
|
65
|
+
const deadline = readDeadline(env?.[DEV_ENV.expiresAt], now);
|
|
66
|
+
switch (deadline.state) {
|
|
67
|
+
case "unreadable":
|
|
68
|
+
return { state: "unreadable", reason: "bad-expiry" };
|
|
69
|
+
case "passed":
|
|
70
|
+
return { state: "expired", expiredAt: deadline.expiredAt };
|
|
71
|
+
case "live":
|
|
72
|
+
return { state: "active", credentials: { dataset, apiKey }, expiresAt: deadline.expiresAt };
|
|
73
|
+
case "none":
|
|
74
|
+
return { state: "active", credentials: { dataset, apiKey }, expiresAt: null };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
__name(parseDevEnv, "parseDevEnv");
|
|
78
|
+
|
|
79
|
+
export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, buildDevEnv, parseDevContextFile, parseDevEnv };
|
|
80
|
+
//# sourceMappingURL=chunk-BBUB7C2Z.js.map
|
|
81
|
+
//# sourceMappingURL=chunk-BBUB7C2Z.js.map
|