@relyio/sdk 0.2.1 → 0.4.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 +116 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-RJBIJ2ZK.js → chunk-43VPZT2G.js} +496 -103
- package/dist/chunk-BBUB7C2Z.js +81 -0
- package/dist/{chunk-FJK7ZWKK.cjs → chunk-HAQELDZN.cjs} +156 -221
- package/dist/chunk-LSRPMNPT.cjs +89 -0
- package/dist/{chunk-7W4MJXQ4.cjs → chunk-XS32U2UP.cjs} +497 -102
- package/dist/{chunk-2QUK2ZGD.js → chunk-XY5KFEFY.js} +157 -219
- 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-2xbHgtK-.d.cts} +63 -726
- package/dist/{define-schema-DHvUCKwj.d.ts → define-schema-DzYXk4HL.d.ts} +63 -726
- 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-BvO6HDtY.d.cts} +237 -12
- package/dist/{index-B-KiFHbx.d.ts → index-BzOFJJKS.d.ts} +237 -12
- package/dist/{index-BsUqCAu8.d.cts → index-DFehx5sI.d.cts} +749 -2160
- package/dist/{index-BsUqCAu8.d.ts → index-FDak5ofk.d.ts} +749 -2160
- package/dist/index.cjs +120 -70
- package/dist/index.d.cts +136 -55
- package/dist/index.d.ts +136 -55
- package/dist/index.js +45 -3
- 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 -19
- package/dist/react/index.cjs +0 -4
- package/dist/react/index.d.cts +0 -2
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.js +0 -3
|
@@ -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;
|
|
@@ -693,6 +736,158 @@ function fillPath(template, params) {
|
|
|
693
736
|
return filled;
|
|
694
737
|
}
|
|
695
738
|
chunkMWMSFIWN_cjs.__name(fillPath, "fillPath");
|
|
739
|
+
var DECLARED_PATHS = {
|
|
740
|
+
"/health": true,
|
|
741
|
+
"/health/cache": true,
|
|
742
|
+
"/health/live": true,
|
|
743
|
+
"/health/ready": true,
|
|
744
|
+
"/internal/media/claim": true,
|
|
745
|
+
"/internal/media/file-complete": true,
|
|
746
|
+
"/internal/media/progress": true,
|
|
747
|
+
"/internal/media/resolve": true,
|
|
748
|
+
"/internal/usage/cycle": true,
|
|
749
|
+
"/internal/usage/ingest": true,
|
|
750
|
+
"/v1/{contentType}": true,
|
|
751
|
+
"/v1/{contentType}/{id}": true,
|
|
752
|
+
"/v1/{contentType}/{id}/children": true,
|
|
753
|
+
"/v1/{contentType}/{id}/file": true,
|
|
754
|
+
"/v1/{contentType}/{id}/file/confirm": true,
|
|
755
|
+
"/v1/{contentType}/{id}/file/multipart/abort": true,
|
|
756
|
+
"/v1/{contentType}/{id}/file/multipart/complete": true,
|
|
757
|
+
"/v1/{contentType}/{id}/file/multipart/create": true,
|
|
758
|
+
"/v1/{contentType}/{id}/file/multipart/list-parts": true,
|
|
759
|
+
"/v1/{contentType}/{id}/file/multipart/sign-part": true,
|
|
760
|
+
"/v1/{contentType}/{id}/file/presign": true,
|
|
761
|
+
"/v1/{contentType}/{id}/file/url": true,
|
|
762
|
+
"/v1/{contentType}/{id}/versions": true,
|
|
763
|
+
"/v1/{contentType}/{id}/versions/{versionNumber}": true,
|
|
764
|
+
"/v1/{contentType}/{id}/versions/{versionNumber}/restore": true,
|
|
765
|
+
"/v1/batch": true,
|
|
766
|
+
"/v1/changes": true,
|
|
767
|
+
"/v1/meta/content-types": true,
|
|
768
|
+
"/v1/meta/info": true,
|
|
769
|
+
"/v1/meta/locales": true,
|
|
770
|
+
"/v1/meta/schema": true,
|
|
771
|
+
"/v1/meta/schema/{contentType}": true,
|
|
772
|
+
"/v1/meta/schema/{contentType}/fields": true,
|
|
773
|
+
"/v1/query": true,
|
|
774
|
+
"/v1/search": true,
|
|
775
|
+
"/v1/search/autocomplete": true,
|
|
776
|
+
"/v1/search/similar": true,
|
|
777
|
+
"/v1/settings": true,
|
|
778
|
+
"/v1/settings/{groupId}": true,
|
|
779
|
+
"/v1/settings/{groupId}/defaults": true,
|
|
780
|
+
"/v1/settings/{groupId}/reset": true,
|
|
781
|
+
"/v1/settings/{groupId}/versions": true,
|
|
782
|
+
"/v1/settings/{groupId}/versions/{versionNumber}": true,
|
|
783
|
+
"/v1/singletons/{key}": true,
|
|
784
|
+
"/v1/singletons/{key}/exists": true,
|
|
785
|
+
"/v1/singletons/{key}/versions": true,
|
|
786
|
+
"/v1/singletons/{key}/versions/{versionNumber}": true
|
|
787
|
+
};
|
|
788
|
+
function compile(path) {
|
|
789
|
+
const segments = path.split("/").slice(1).map((part) => {
|
|
790
|
+
const param = /^\{(\w+)\}$/.exec(part);
|
|
791
|
+
return param?.[1] === void 0 ? { kind: "static", value: part } : { kind: "param", name: param[1] };
|
|
792
|
+
});
|
|
793
|
+
return { path, segments };
|
|
794
|
+
}
|
|
795
|
+
chunkMWMSFIWN_cjs.__name(compile, "compile");
|
|
796
|
+
function byRouterPrecedence(a, b) {
|
|
797
|
+
const shared = Math.min(a.segments.length, b.segments.length);
|
|
798
|
+
for (let index = 0; index < shared; index += 1) {
|
|
799
|
+
const left = a.segments[index]?.kind;
|
|
800
|
+
const right = b.segments[index]?.kind;
|
|
801
|
+
if (left !== right) return left === "static" ? -1 : 1;
|
|
802
|
+
}
|
|
803
|
+
return 0;
|
|
804
|
+
}
|
|
805
|
+
chunkMWMSFIWN_cjs.__name(byRouterPrecedence, "byRouterPrecedence");
|
|
806
|
+
var COMPILED_ROUTES = Object.keys(DECLARED_PATHS).map(compile).sort(byRouterPrecedence);
|
|
807
|
+
function matchRoute(url, options = {}) {
|
|
808
|
+
const parsed = new URL(url, "http://relative.invalid");
|
|
809
|
+
let pathname = parsed.pathname;
|
|
810
|
+
if (options.baseUrl !== void 0) {
|
|
811
|
+
const prefix = new URL(options.baseUrl, "http://relative.invalid").pathname.replace(/\/+$/, "");
|
|
812
|
+
if (prefix !== "") {
|
|
813
|
+
if (pathname !== prefix && !pathname.startsWith(`${prefix}/`)) return null;
|
|
814
|
+
pathname = pathname.slice(prefix.length);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
const parts = pathname.split("/").slice(1);
|
|
818
|
+
for (const route of COMPILED_ROUTES) {
|
|
819
|
+
if (route.segments.length !== parts.length) continue;
|
|
820
|
+
const params = {};
|
|
821
|
+
const matched = route.segments.every((segment, index) => {
|
|
822
|
+
const part = parts[index];
|
|
823
|
+
if (part === void 0) return false;
|
|
824
|
+
if (segment.kind === "static") return segment.value === part;
|
|
825
|
+
if (part === "") return false;
|
|
826
|
+
params[segment.name] = decodeURIComponent(part);
|
|
827
|
+
return true;
|
|
828
|
+
});
|
|
829
|
+
if (matched) return { path: route.path, params, query: readQuery(parsed.searchParams) };
|
|
830
|
+
}
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
chunkMWMSFIWN_cjs.__name(matchRoute, "matchRoute");
|
|
834
|
+
function readQuery(searchParams) {
|
|
835
|
+
const query = {};
|
|
836
|
+
for (const key of new Set(searchParams.keys())) {
|
|
837
|
+
const values = searchParams.getAll(key);
|
|
838
|
+
query[key] = values.length === 1 && values[0] !== void 0 ? values[0] : values;
|
|
839
|
+
}
|
|
840
|
+
return query;
|
|
841
|
+
}
|
|
842
|
+
chunkMWMSFIWN_cjs.__name(readQuery, "readQuery");
|
|
843
|
+
|
|
844
|
+
// src/http/retry-policy.ts
|
|
845
|
+
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set([
|
|
846
|
+
"GET",
|
|
847
|
+
"HEAD",
|
|
848
|
+
"OPTIONS",
|
|
849
|
+
"PUT",
|
|
850
|
+
"DELETE",
|
|
851
|
+
"TRACE"
|
|
852
|
+
]);
|
|
853
|
+
function isReplaySafe(request) {
|
|
854
|
+
if (IDEMPOTENT_METHODS.has(request.method.toUpperCase())) return true;
|
|
855
|
+
return headerValue(request.headers, HEADER_IDEMPOTENCY_KEY.name) !== void 0;
|
|
856
|
+
}
|
|
857
|
+
chunkMWMSFIWN_cjs.__name(isReplaySafe, "isReplaySafe");
|
|
858
|
+
function serviceInstructedDelayMs(error, nowMs) {
|
|
859
|
+
if (error instanceof ServiceIndeterminateError) {
|
|
860
|
+
return error.retryAfterMs;
|
|
861
|
+
}
|
|
862
|
+
if (!(error instanceof RateLimitError)) return void 0;
|
|
863
|
+
if (error.retryAfterMs !== void 0) return error.retryAfterMs;
|
|
864
|
+
if (error.resetAt === void 0) return void 0;
|
|
865
|
+
const resetAtMs = Date.parse(error.resetAt);
|
|
866
|
+
if (Number.isNaN(resetAtMs)) return void 0;
|
|
867
|
+
const wait = resetAtMs - nowMs;
|
|
868
|
+
return wait > 0 ? wait : void 0;
|
|
869
|
+
}
|
|
870
|
+
chunkMWMSFIWN_cjs.__name(serviceInstructedDelayMs, "serviceInstructedDelayMs");
|
|
871
|
+
var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
872
|
+
constructor(config) {
|
|
873
|
+
chunkMWMSFIWN_cjs.__publicField(this, "config");
|
|
874
|
+
this.config = config;
|
|
875
|
+
}
|
|
876
|
+
shouldRetry(attempt, error, request) {
|
|
877
|
+
if (attempt >= this.config.maxAttempts) return false;
|
|
878
|
+
if (!ErrorMapper.isRetryable(error)) return false;
|
|
879
|
+
return isReplaySafe(request);
|
|
880
|
+
}
|
|
881
|
+
delayFor(attempt, error) {
|
|
882
|
+
const instructed = serviceInstructedDelayMs(error, Date.now());
|
|
883
|
+
if (instructed !== void 0) return instructed;
|
|
884
|
+
const exponential = this.config.baseDelay * Math.pow(this.config.backoffFactor, attempt - 1);
|
|
885
|
+
const delay = Math.min(exponential, this.config.maxDelay);
|
|
886
|
+
return this.config.jitter ? delay * (0.5 + Math.random() * 0.5) : delay;
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
chunkMWMSFIWN_cjs.__name(_DefaultRetryPolicy, "DefaultRetryPolicy");
|
|
890
|
+
var DefaultRetryPolicy = _DefaultRetryPolicy;
|
|
696
891
|
|
|
697
892
|
// src/http/http-client.ts
|
|
698
893
|
var _HttpClient = class _HttpClient {
|
|
@@ -700,7 +895,7 @@ var _HttpClient = class _HttpClient {
|
|
|
700
895
|
chunkMWMSFIWN_cjs.__publicField(this, "baseUrl");
|
|
701
896
|
chunkMWMSFIWN_cjs.__publicField(this, "defaultHeaders");
|
|
702
897
|
chunkMWMSFIWN_cjs.__publicField(this, "timeout");
|
|
703
|
-
chunkMWMSFIWN_cjs.__publicField(this, "
|
|
898
|
+
chunkMWMSFIWN_cjs.__publicField(this, "retryPolicy");
|
|
704
899
|
chunkMWMSFIWN_cjs.__publicField(this, "debug");
|
|
705
900
|
chunkMWMSFIWN_cjs.__publicField(this, "logger");
|
|
706
901
|
chunkMWMSFIWN_cjs.__publicField(this, "config");
|
|
@@ -721,16 +916,13 @@ var _HttpClient = class _HttpClient {
|
|
|
721
916
|
const globalWithVersion = globalThis;
|
|
722
917
|
this.defaultHeaders["User-Agent"] = `RelyIO-SDK/${globalWithVersion.__VERSION__ ?? "0.0.0"}`;
|
|
723
918
|
}
|
|
724
|
-
this.
|
|
919
|
+
this.retryPolicy = new DefaultRetryPolicy({
|
|
725
920
|
maxAttempts: config.retryAttempts,
|
|
726
921
|
baseDelay: 1e3,
|
|
727
922
|
maxDelay: 1e4,
|
|
728
923
|
backoffFactor: 2,
|
|
729
|
-
jitter: true
|
|
730
|
-
|
|
731
|
-
return ErrorMapper.isRetryable(error) && attempt < config.retryAttempts;
|
|
732
|
-
}, "retryCondition")
|
|
733
|
-
};
|
|
924
|
+
jitter: true
|
|
925
|
+
});
|
|
734
926
|
this.log("debug", "HttpClient initialized", {
|
|
735
927
|
baseUrl: this.baseUrl,
|
|
736
928
|
timeout: this.timeout,
|
|
@@ -763,7 +955,16 @@ var _HttpClient = class _HttpClient {
|
|
|
763
955
|
return readPayload(response.body);
|
|
764
956
|
}
|
|
765
957
|
/**
|
|
766
|
-
* Make an HTTP request
|
|
958
|
+
* Make an HTTP request, retrying only where a retry is safe.
|
|
959
|
+
*
|
|
960
|
+
* The headers are merged **once**, before the first attempt, and every attempt
|
|
961
|
+
* sends that same object. That is what makes a minted `Idempotency-Key` stable
|
|
962
|
+
* across the retries of one logical write: the service sees one key and
|
|
963
|
+
* answers the replay from the original outcome instead of applying it twice.
|
|
964
|
+
*
|
|
965
|
+
* The loop always makes one attempt. The incumbent's `while (attempt <
|
|
966
|
+
* maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
|
|
967
|
+
* accepts — and then dereferenced an unassigned `lastError`.
|
|
767
968
|
*/
|
|
768
969
|
async request(config) {
|
|
769
970
|
const mergedConfig = this.mergeRequestConfig(config);
|
|
@@ -772,14 +973,11 @@ var _HttpClient = class _HttpClient {
|
|
|
772
973
|
url: mergedConfig.url
|
|
773
974
|
// Show the final URL with query params
|
|
774
975
|
});
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
976
|
+
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
977
|
+
delete mergedConfig.headers["Content-Type"];
|
|
978
|
+
}
|
|
979
|
+
for (let attempt = 1; ; attempt++) {
|
|
779
980
|
try {
|
|
780
|
-
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
781
|
-
delete mergedConfig.headers["Content-Type"];
|
|
782
|
-
}
|
|
783
981
|
const response = await this.makeRequest(mergedConfig.url, mergedConfig);
|
|
784
982
|
this.log("debug", "Request successful", {
|
|
785
983
|
status: response.status,
|
|
@@ -788,31 +986,31 @@ var _HttpClient = class _HttpClient {
|
|
|
788
986
|
});
|
|
789
987
|
return response;
|
|
790
988
|
} catch (error) {
|
|
791
|
-
|
|
989
|
+
const failure = error;
|
|
990
|
+
if (config.signal?.aborted === true) throw failure;
|
|
792
991
|
this.log("warn", "Request failed", {
|
|
793
992
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
794
993
|
attempt,
|
|
795
994
|
url: mergedConfig.url
|
|
796
995
|
});
|
|
797
|
-
if (
|
|
798
|
-
const delay = this.
|
|
996
|
+
if (this.retryPolicy.shouldRetry(attempt, failure, mergedConfig)) {
|
|
997
|
+
const delay = this.retryPolicy.delayFor(attempt, failure);
|
|
799
998
|
this.log("debug", "Retrying request", { attempt, delay });
|
|
800
|
-
await this.sleep(delay);
|
|
999
|
+
await this.sleep(delay, config.signal);
|
|
801
1000
|
continue;
|
|
802
1001
|
}
|
|
803
|
-
|
|
1002
|
+
const sdkError = ErrorMapper.mapGenericError(failure, {
|
|
1003
|
+
url: mergedConfig.url,
|
|
1004
|
+
method: mergedConfig.method,
|
|
1005
|
+
attempt
|
|
1006
|
+
});
|
|
1007
|
+
this.log("error", "Request failed after all retries", {
|
|
1008
|
+
error: sdkError.toJSON(),
|
|
1009
|
+
url: mergedConfig.url
|
|
1010
|
+
});
|
|
1011
|
+
throw sdkError;
|
|
804
1012
|
}
|
|
805
1013
|
}
|
|
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
1014
|
}
|
|
817
1015
|
/**
|
|
818
1016
|
* Make a GET request
|
|
@@ -897,20 +1095,41 @@ var _HttpClient = class _HttpClient {
|
|
|
897
1095
|
getBaseUrl() {
|
|
898
1096
|
return this.baseUrl;
|
|
899
1097
|
}
|
|
1098
|
+
/**
|
|
1099
|
+
* One attempt.
|
|
1100
|
+
*
|
|
1101
|
+
* The caller's `signal` and the timeout both end it, through one controller.
|
|
1102
|
+
* The incumbent handed `fetch` the caller's signal **instead of** its own, so a
|
|
1103
|
+
* request that passed a signal had no timeout at all — and a caller abort then
|
|
1104
|
+
* surfaced as `Request timed out`. `timedOut` is what tells the two apart: a
|
|
1105
|
+
* timeout is a `TimeoutError`, a caller abort is the platform's `AbortError`,
|
|
1106
|
+
* rethrown as it came.
|
|
1107
|
+
*/
|
|
900
1108
|
async makeRequest(url, config) {
|
|
1109
|
+
const caller = config.signal;
|
|
1110
|
+
if (caller?.aborted === true) {
|
|
1111
|
+
throw new DOMException("The request was aborted before it was sent", "AbortError");
|
|
1112
|
+
}
|
|
901
1113
|
const controller = new AbortController();
|
|
902
|
-
|
|
1114
|
+
let timedOut = false;
|
|
1115
|
+
const timeoutId = setTimeout(() => {
|
|
1116
|
+
timedOut = true;
|
|
1117
|
+
controller.abort();
|
|
1118
|
+
}, config.timeout ?? this.timeout);
|
|
1119
|
+
const onCallerAbort = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name(() => controller.abort(), "onCallerAbort");
|
|
1120
|
+
caller?.addEventListener("abort", onCallerAbort, { once: true });
|
|
903
1121
|
try {
|
|
904
1122
|
const filteredHeaders = this.filterHeadersForBrowser(config.headers ?? {});
|
|
905
1123
|
const requestInit = {
|
|
906
1124
|
method: config.method,
|
|
907
1125
|
headers: filteredHeaders,
|
|
908
1126
|
body: this.prepareRequestBody(config),
|
|
909
|
-
signal:
|
|
1127
|
+
signal: controller.signal,
|
|
910
1128
|
// Include credentials for CORS requests if in browser and configured
|
|
911
1129
|
...typeof window !== "undefined" && this.config.browser.includeCredentials != null && { credentials: "include" }
|
|
912
1130
|
};
|
|
913
|
-
const
|
|
1131
|
+
const send = this.config.fetch ?? globalThis.fetch;
|
|
1132
|
+
const response = await send(url, requestInit);
|
|
914
1133
|
clearTimeout(timeoutId);
|
|
915
1134
|
const responseBody = await this.parseResponse(response);
|
|
916
1135
|
if (!response.ok) {
|
|
@@ -941,6 +1160,7 @@ var _HttpClient = class _HttpClient {
|
|
|
941
1160
|
throw error;
|
|
942
1161
|
}
|
|
943
1162
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
1163
|
+
if (!timedOut && isAborted(caller)) throw error;
|
|
944
1164
|
throw new TimeoutError(
|
|
945
1165
|
`Request timed out after ${config.timeout ?? this.timeout}ms`,
|
|
946
1166
|
config.timeout ?? this.timeout
|
|
@@ -972,6 +1192,8 @@ var _HttpClient = class _HttpClient {
|
|
|
972
1192
|
throw corsError;
|
|
973
1193
|
}
|
|
974
1194
|
throw error;
|
|
1195
|
+
} finally {
|
|
1196
|
+
caller?.removeEventListener("abort", onCallerAbort);
|
|
975
1197
|
}
|
|
976
1198
|
}
|
|
977
1199
|
/**
|
|
@@ -1060,16 +1282,21 @@ var _HttpClient = class _HttpClient {
|
|
|
1060
1282
|
});
|
|
1061
1283
|
return obj;
|
|
1062
1284
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1285
|
+
/** A backoff the caller's abort cuts short; the next attempt then refuses to send. */
|
|
1286
|
+
sleep(ms, signal) {
|
|
1287
|
+
return new Promise((resolve) => {
|
|
1288
|
+
if (isAborted(signal)) {
|
|
1289
|
+
resolve();
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
const done = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name(() => {
|
|
1293
|
+
clearTimeout(timer);
|
|
1294
|
+
signal?.removeEventListener("abort", done);
|
|
1295
|
+
resolve();
|
|
1296
|
+
}, "done");
|
|
1297
|
+
const timer = setTimeout(done, ms);
|
|
1298
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
1299
|
+
});
|
|
1073
1300
|
}
|
|
1074
1301
|
log(level, message, data) {
|
|
1075
1302
|
if (!this.debug) return;
|
|
@@ -1082,6 +1309,10 @@ var _HttpClient = class _HttpClient {
|
|
|
1082
1309
|
};
|
|
1083
1310
|
chunkMWMSFIWN_cjs.__name(_HttpClient, "HttpClient");
|
|
1084
1311
|
var HttpClient = _HttpClient;
|
|
1312
|
+
function isAborted(signal) {
|
|
1313
|
+
return signal?.aborted === true;
|
|
1314
|
+
}
|
|
1315
|
+
chunkMWMSFIWN_cjs.__name(isAborted, "isAborted");
|
|
1085
1316
|
|
|
1086
1317
|
// src/content/query-builder.ts
|
|
1087
1318
|
var _ContentQueryBuilder = class _ContentQueryBuilder {
|
|
@@ -1563,32 +1794,27 @@ var _ContentByIdBuilder = class _ContentByIdBuilder {
|
|
|
1563
1794
|
chunkMWMSFIWN_cjs.__name(_ContentByIdBuilder, "ContentByIdBuilder");
|
|
1564
1795
|
var ContentByIdBuilder = _ContentByIdBuilder;
|
|
1565
1796
|
|
|
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
1797
|
// src/http/write-options.ts
|
|
1798
|
+
function mintIdempotencyKey() {
|
|
1799
|
+
const webCrypto = globalThis.crypto;
|
|
1800
|
+
if (typeof webCrypto?.randomUUID !== "function") return void 0;
|
|
1801
|
+
return webCrypto.randomUUID();
|
|
1802
|
+
}
|
|
1803
|
+
chunkMWMSFIWN_cjs.__name(mintIdempotencyKey, "mintIdempotencyKey");
|
|
1574
1804
|
function writeHeaders(options) {
|
|
1575
|
-
if (options === void 0) return void 0;
|
|
1576
1805
|
const headers = {};
|
|
1577
|
-
if ("ifMatch" in options && options.ifMatch !== void 0) {
|
|
1806
|
+
if (options !== void 0 && "ifMatch" in options && options.ifMatch !== void 0) {
|
|
1578
1807
|
headers[HEADER_IF_MATCH.name] = options.ifMatch;
|
|
1579
1808
|
}
|
|
1580
|
-
|
|
1581
|
-
|
|
1809
|
+
const idempotencyKey = options?.idempotencyKey ?? mintIdempotencyKey();
|
|
1810
|
+
if (idempotencyKey !== void 0) {
|
|
1811
|
+
headers[HEADER_IDEMPOTENCY_KEY.name] = idempotencyKey;
|
|
1582
1812
|
}
|
|
1583
1813
|
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1584
1814
|
}
|
|
1585
1815
|
chunkMWMSFIWN_cjs.__name(writeHeaders, "writeHeaders");
|
|
1586
1816
|
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;
|
|
1817
|
+
return headerValue(response.headers, HEADER_ENTITY_TAG.name);
|
|
1592
1818
|
}
|
|
1593
1819
|
chunkMWMSFIWN_cjs.__name(entityTagOf, "entityTagOf");
|
|
1594
1820
|
|
|
@@ -3854,6 +4080,103 @@ var _AdhocQueryClient = class _AdhocQueryClient {
|
|
|
3854
4080
|
chunkMWMSFIWN_cjs.__name(_AdhocQueryClient, "AdhocQueryClient");
|
|
3855
4081
|
var AdhocQueryClient = _AdhocQueryClient;
|
|
3856
4082
|
|
|
4083
|
+
// src/changes/changes.ts
|
|
4084
|
+
var CHANGES_POLL_TIMEOUT_MS = 25e3 + 5e3;
|
|
4085
|
+
var _ChangesExpiredError = class _ChangesExpiredError extends ResourceExpiredError {
|
|
4086
|
+
/** The base class's signature, so `withContext` can rebuild one. */
|
|
4087
|
+
constructor(message, statusCode = 410, cause, context) {
|
|
4088
|
+
super(message, statusCode, cause, context);
|
|
4089
|
+
chunkMWMSFIWN_cjs.__publicField(this, "reason");
|
|
4090
|
+
this.name = "ChangesExpiredError";
|
|
4091
|
+
this.reason = expiredReasonOf(message);
|
|
4092
|
+
}
|
|
4093
|
+
static of(expired) {
|
|
4094
|
+
return new _ChangesExpiredError(expired.message, expired.statusCode, expired, expired.context);
|
|
4095
|
+
}
|
|
4096
|
+
};
|
|
4097
|
+
chunkMWMSFIWN_cjs.__name(_ChangesExpiredError, "ChangesExpiredError");
|
|
4098
|
+
var ChangesExpiredError = _ChangesExpiredError;
|
|
4099
|
+
function expiredReasonOf(message) {
|
|
4100
|
+
if (message.includes("(retention)")) return "retention";
|
|
4101
|
+
if (message.includes("(dataset-replaced)")) return "dataset-replaced";
|
|
4102
|
+
return "unknown";
|
|
4103
|
+
}
|
|
4104
|
+
chunkMWMSFIWN_cjs.__name(expiredReasonOf, "expiredReasonOf");
|
|
4105
|
+
async function* pollChanges(http, options = {}) {
|
|
4106
|
+
const { signal } = options;
|
|
4107
|
+
let since = options.since;
|
|
4108
|
+
let resynced;
|
|
4109
|
+
for (; ; ) {
|
|
4110
|
+
if (aborted(signal)) return;
|
|
4111
|
+
let response;
|
|
4112
|
+
try {
|
|
4113
|
+
response = await pollOnce(http, since, options);
|
|
4114
|
+
} catch (error) {
|
|
4115
|
+
if (aborted(signal)) return;
|
|
4116
|
+
if (!(error instanceof ResourceExpiredError) || since === void 0) throw error;
|
|
4117
|
+
const expired = ChangesExpiredError.of(error);
|
|
4118
|
+
const onExpired = options.onExpired ?? "throw";
|
|
4119
|
+
if (onExpired === "throw") throw expired;
|
|
4120
|
+
since = void 0;
|
|
4121
|
+
resynced = typeof onExpired === "function" ? expired : void 0;
|
|
4122
|
+
continue;
|
|
4123
|
+
}
|
|
4124
|
+
const { data, page } = response.body;
|
|
4125
|
+
if (page.nextCursor === null) {
|
|
4126
|
+
throw new Error("GET /v1/changes answered without page.nextCursor");
|
|
4127
|
+
}
|
|
4128
|
+
since = page.nextCursor;
|
|
4129
|
+
if (resynced !== void 0 && typeof options.onExpired === "function") {
|
|
4130
|
+
const expired = resynced;
|
|
4131
|
+
resynced = void 0;
|
|
4132
|
+
await options.onExpired(expired);
|
|
4133
|
+
if (aborted(signal)) return;
|
|
4134
|
+
}
|
|
4135
|
+
for (const change of data) {
|
|
4136
|
+
yield change;
|
|
4137
|
+
if (aborted(signal)) return;
|
|
4138
|
+
}
|
|
4139
|
+
if (data.length === 0) {
|
|
4140
|
+
const wait = parseRetryAfterMs(headerValue(response.headers, "Retry-After"), Date.now());
|
|
4141
|
+
if (wait !== void 0 && wait > 0) await sleep(wait, signal);
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
chunkMWMSFIWN_cjs.__name(pollChanges, "pollChanges");
|
|
4146
|
+
async function pollOnce(http, since, options) {
|
|
4147
|
+
const query = {};
|
|
4148
|
+
if (since !== void 0) query.since = since;
|
|
4149
|
+
if (options.types !== void 0) query.types = options.types.join(",");
|
|
4150
|
+
if (options.ids !== void 0) query.ids = options.ids.join(",");
|
|
4151
|
+
if (options.limit !== void 0) query.limit = options.limit;
|
|
4152
|
+
return http.send("/v1/changes", "get", {
|
|
4153
|
+
query,
|
|
4154
|
+
timeout: CHANGES_POLL_TIMEOUT_MS,
|
|
4155
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
4156
|
+
});
|
|
4157
|
+
}
|
|
4158
|
+
chunkMWMSFIWN_cjs.__name(pollOnce, "pollOnce");
|
|
4159
|
+
function sleep(ms, signal) {
|
|
4160
|
+
return new Promise((resolve) => {
|
|
4161
|
+
if (aborted(signal)) {
|
|
4162
|
+
resolve();
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
const done = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name(() => {
|
|
4166
|
+
clearTimeout(timer);
|
|
4167
|
+
signal?.removeEventListener("abort", done);
|
|
4168
|
+
resolve();
|
|
4169
|
+
}, "done");
|
|
4170
|
+
const timer = setTimeout(done, ms);
|
|
4171
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
4172
|
+
});
|
|
4173
|
+
}
|
|
4174
|
+
chunkMWMSFIWN_cjs.__name(sleep, "sleep");
|
|
4175
|
+
function aborted(signal) {
|
|
4176
|
+
return signal?.aborted === true;
|
|
4177
|
+
}
|
|
4178
|
+
chunkMWMSFIWN_cjs.__name(aborted, "aborted");
|
|
4179
|
+
|
|
3857
4180
|
// src/config/dev-detection.ts
|
|
3858
4181
|
function getProcess() {
|
|
3859
4182
|
return typeof process !== "undefined" ? process : void 0;
|
|
@@ -3872,47 +4195,76 @@ function isProduction(proc) {
|
|
|
3872
4195
|
return proc?.env?.NODE_ENV === "production";
|
|
3873
4196
|
}
|
|
3874
4197
|
chunkMWMSFIWN_cjs.__name(isProduction, "isProduction");
|
|
3875
|
-
function resolveFromEnv(proc) {
|
|
3876
|
-
const
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
4198
|
+
function resolveFromEnv(proc, now) {
|
|
4199
|
+
const verdict = chunkLSRPMNPT_cjs.parseDevEnv(proc?.env, now);
|
|
4200
|
+
switch (verdict.state) {
|
|
4201
|
+
case "active":
|
|
4202
|
+
return {
|
|
4203
|
+
state: "active",
|
|
4204
|
+
override: {
|
|
4205
|
+
dataset: verdict.credentials.dataset,
|
|
4206
|
+
apiKey: verdict.credentials.apiKey,
|
|
4207
|
+
source: "env"
|
|
4208
|
+
}
|
|
4209
|
+
};
|
|
4210
|
+
case "expired":
|
|
4211
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
4212
|
+
case "unreadable":
|
|
4213
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
4214
|
+
case "absent":
|
|
4215
|
+
return { state: "absent" };
|
|
3880
4216
|
}
|
|
3881
|
-
return null;
|
|
3882
4217
|
}
|
|
3883
4218
|
chunkMWMSFIWN_cjs.__name(resolveFromEnv, "resolveFromEnv");
|
|
3884
|
-
function resolveFromFile(proc) {
|
|
3885
|
-
if (proc == null || typeof proc.cwd !== "function") return
|
|
4219
|
+
function resolveFromFile(proc, now) {
|
|
4220
|
+
if (proc == null || typeof proc.cwd !== "function") return { state: "absent" };
|
|
3886
4221
|
const fs = getBuiltin(proc, "node:fs");
|
|
3887
4222
|
const path = getBuiltin(proc, "node:path");
|
|
3888
|
-
if (fs == null || path == null) return
|
|
4223
|
+
if (fs == null || path == null) return { state: "absent" };
|
|
3889
4224
|
let dir = proc.cwd();
|
|
3890
4225
|
for (; ; ) {
|
|
3891
|
-
const candidate = path.join(dir,
|
|
4226
|
+
const candidate = path.join(dir, chunkLSRPMNPT_cjs.DEV_CONTEXT_DIR, chunkLSRPMNPT_cjs.DEV_CONTEXT_FILENAME);
|
|
4227
|
+
let raw = null;
|
|
3892
4228
|
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
|
-
}
|
|
4229
|
+
if (fs.existsSync(candidate)) raw = fs.readFileSync(candidate, "utf8");
|
|
3902
4230
|
} catch {
|
|
4231
|
+
return { state: "absent" };
|
|
4232
|
+
}
|
|
4233
|
+
if (raw !== null) {
|
|
4234
|
+
const verdict = chunkLSRPMNPT_cjs.parseDevContextFile(raw, now);
|
|
4235
|
+
switch (verdict.state) {
|
|
4236
|
+
case "active":
|
|
4237
|
+
return {
|
|
4238
|
+
state: "active",
|
|
4239
|
+
override: {
|
|
4240
|
+
dataset: verdict.context.datasetId,
|
|
4241
|
+
apiKey: verdict.context.previewApiKey,
|
|
4242
|
+
source: "file"
|
|
4243
|
+
}
|
|
4244
|
+
};
|
|
4245
|
+
case "expired":
|
|
4246
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
4247
|
+
case "unreadable":
|
|
4248
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
4249
|
+
case "absent":
|
|
4250
|
+
return { state: "absent" };
|
|
4251
|
+
}
|
|
3903
4252
|
}
|
|
3904
4253
|
const parent = path.dirname(dir);
|
|
3905
4254
|
if (parent === dir) break;
|
|
3906
4255
|
dir = parent;
|
|
3907
4256
|
}
|
|
3908
|
-
return
|
|
4257
|
+
return { state: "absent" };
|
|
3909
4258
|
}
|
|
3910
4259
|
chunkMWMSFIWN_cjs.__name(resolveFromFile, "resolveFromFile");
|
|
3911
4260
|
function resolveDevOverride(dev) {
|
|
3912
|
-
if (dev === false) return
|
|
4261
|
+
if (dev === false) return { state: "disabled" };
|
|
3913
4262
|
const proc = getProcess();
|
|
3914
|
-
if (dev !== true && isProduction(proc)) return
|
|
3915
|
-
|
|
4263
|
+
if (dev !== true && isProduction(proc)) return { state: "disabled" };
|
|
4264
|
+
const now = Date.now();
|
|
4265
|
+
const fromEnv = resolveFromEnv(proc, now);
|
|
4266
|
+
if (fromEnv.state !== "absent") return fromEnv;
|
|
4267
|
+
return resolveFromFile(proc, now);
|
|
3916
4268
|
}
|
|
3917
4269
|
chunkMWMSFIWN_cjs.__name(resolveDevOverride, "resolveDevOverride");
|
|
3918
4270
|
|
|
@@ -3995,16 +4347,26 @@ function mergeConfig(userConfig) {
|
|
|
3995
4347
|
...userConfig.debug
|
|
3996
4348
|
}
|
|
3997
4349
|
};
|
|
3998
|
-
const
|
|
3999
|
-
if (
|
|
4000
|
-
merged.apiKey =
|
|
4001
|
-
merged.dataset =
|
|
4350
|
+
const dev = resolveDevOverride(userConfig.dev);
|
|
4351
|
+
if (dev.state === "active") {
|
|
4352
|
+
merged.apiKey = dev.override.apiKey;
|
|
4353
|
+
merged.dataset = dev.override.dataset;
|
|
4002
4354
|
if (!devOverrideNotified) {
|
|
4003
4355
|
devOverrideNotified = true;
|
|
4004
4356
|
console.info(
|
|
4005
|
-
`[RelyIO] Sandbox dev mode active (${
|
|
4357
|
+
`[RelyIO] Sandbox dev mode active (${dev.override.source}) \u2014 targeting dataset "${dev.override.dataset}" with a scoped preview key.`
|
|
4006
4358
|
);
|
|
4007
4359
|
}
|
|
4360
|
+
} else if (dev.state === "expired" && !devOverrideNotified) {
|
|
4361
|
+
devOverrideNotified = true;
|
|
4362
|
+
console.warn(
|
|
4363
|
+
`[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.`
|
|
4364
|
+
);
|
|
4365
|
+
} else if (dev.state === "unreadable" && !devOverrideNotified) {
|
|
4366
|
+
devOverrideNotified = true;
|
|
4367
|
+
console.warn(
|
|
4368
|
+
`[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.`
|
|
4369
|
+
);
|
|
4008
4370
|
}
|
|
4009
4371
|
return merged;
|
|
4010
4372
|
}
|
|
@@ -4185,6 +4547,37 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4185
4547
|
return this._batch.create();
|
|
4186
4548
|
}
|
|
4187
4549
|
// ============================================================================
|
|
4550
|
+
// CHANGES FEED
|
|
4551
|
+
// ============================================================================
|
|
4552
|
+
/**
|
|
4553
|
+
* Follow the dataset's changes feed: each write this key can see, as ids, in
|
|
4554
|
+
* order, long-polled from `GET /v1/changes`.
|
|
4555
|
+
*
|
|
4556
|
+
* Lazy — nothing is requested until the first `next()`. It runs until
|
|
4557
|
+
* `signal` aborts, which ends the `for await` cleanly rather than throwing.
|
|
4558
|
+
* A change names what changed; refetch it through the ordinary read path
|
|
4559
|
+
* (`INV-SS-CHANGE-IS-IDS`).
|
|
4560
|
+
*
|
|
4561
|
+
* @example
|
|
4562
|
+
* ```typescript
|
|
4563
|
+
* const controller = new AbortController()
|
|
4564
|
+
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
4565
|
+
* // { entryId, contentType, locale, kind, cursor }
|
|
4566
|
+
* }
|
|
4567
|
+
* ```
|
|
4568
|
+
*
|
|
4569
|
+
* @example Resync when the cursor has expired
|
|
4570
|
+
* ```typescript
|
|
4571
|
+
* for await (const change of relyio.changes({
|
|
4572
|
+
* since: cursor,
|
|
4573
|
+
* onExpired: async () => invalidateEverything(),
|
|
4574
|
+
* })) { … }
|
|
4575
|
+
* ```
|
|
4576
|
+
*/
|
|
4577
|
+
changes(options = {}) {
|
|
4578
|
+
return pollChanges(this.httpClient, options);
|
|
4579
|
+
}
|
|
4580
|
+
// ============================================================================
|
|
4188
4581
|
// QUERY OPERATIONS
|
|
4189
4582
|
// ============================================================================
|
|
4190
4583
|
/**
|
|
@@ -4383,6 +4776,7 @@ exports.AutocompleteBuilder = AutocompleteBuilder;
|
|
|
4383
4776
|
exports.BaseValidationError = BaseValidationError;
|
|
4384
4777
|
exports.BatchBuilder = BatchBuilder;
|
|
4385
4778
|
exports.BatchClient = BatchClient;
|
|
4779
|
+
exports.ChangesExpiredError = ChangesExpiredError;
|
|
4386
4780
|
exports.ConnectionError = ConnectionError;
|
|
4387
4781
|
exports.ContentByIdBuilder = ContentByIdBuilder;
|
|
4388
4782
|
exports.ContentClient = ContentClient;
|
|
@@ -4424,6 +4818,7 @@ exports.createClient = createClient;
|
|
|
4424
4818
|
exports.entityTagOf = entityTagOf;
|
|
4425
4819
|
exports.isAssetEntry = isAssetEntry;
|
|
4426
4820
|
exports.isResourceNotFound = isResourceNotFound;
|
|
4821
|
+
exports.matchRoute = matchRoute;
|
|
4427
4822
|
exports.validateFile = validateFile;
|
|
4428
|
-
//# sourceMappingURL=chunk-
|
|
4429
|
-
//# sourceMappingURL=chunk-
|
|
4823
|
+
//# sourceMappingURL=chunk-XS32U2UP.cjs.map
|
|
4824
|
+
//# sourceMappingURL=chunk-XS32U2UP.cjs.map
|