@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,3 +1,4 @@
|
|
|
1
|
+
import { parseDevEnv, DEV_CONTEXT_DIR, DEV_CONTEXT_FILENAME, parseDevContextFile } from './chunk-BBUB7C2Z.js';
|
|
1
2
|
import { __name, __publicField } from './chunk-XQ4QHWZE.js';
|
|
2
3
|
|
|
3
4
|
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
@@ -165,14 +166,17 @@ var _UsageQuotaExceededError = class _UsageQuotaExceededError extends SDKError {
|
|
|
165
166
|
__name(_UsageQuotaExceededError, "UsageQuotaExceededError");
|
|
166
167
|
var UsageQuotaExceededError = _UsageQuotaExceededError;
|
|
167
168
|
var _RateLimitError = class _RateLimitError extends SDKError {
|
|
168
|
-
constructor(message = "Rate limit exceeded", limit, resetAt, context) {
|
|
169
|
+
constructor(message = "Rate limit exceeded", limit, resetAt, context, retryAfterMs) {
|
|
169
170
|
super(message, 429, void 0, context);
|
|
170
171
|
__publicField(this, "code", "RATE_LIMIT_EXCEEDED");
|
|
171
172
|
__publicField(this, "retryable", true);
|
|
172
173
|
__publicField(this, "limit");
|
|
173
174
|
__publicField(this, "resetAt");
|
|
175
|
+
/** `Retry-After`, in milliseconds, where the response carried a readable one. */
|
|
176
|
+
__publicField(this, "retryAfterMs");
|
|
174
177
|
this.limit = limit;
|
|
175
178
|
this.resetAt = resetAt;
|
|
179
|
+
this.retryAfterMs = retryAfterMs;
|
|
176
180
|
}
|
|
177
181
|
getUserMessage() {
|
|
178
182
|
return this.resetAt === void 0 ? "Too many requests. Please retry shortly." : `Too many requests. The window resets at ${this.resetAt}.`;
|
|
@@ -221,12 +225,15 @@ var _TransactionRolledBackError = class _TransactionRolledBackError extends SDKE
|
|
|
221
225
|
__name(_TransactionRolledBackError, "TransactionRolledBackError");
|
|
222
226
|
var TransactionRolledBackError = _TransactionRolledBackError;
|
|
223
227
|
var _ServiceIndeterminateError = class _ServiceIndeterminateError extends SDKError {
|
|
224
|
-
constructor(message = "The service could not decide this request", missing, context) {
|
|
228
|
+
constructor(message = "The service could not decide this request", missing, context, retryAfterMs) {
|
|
225
229
|
super(message, 503, void 0, context);
|
|
226
230
|
__publicField(this, "code", "SERVICE_INDETERMINATE");
|
|
227
231
|
__publicField(this, "retryable", true);
|
|
228
232
|
__publicField(this, "missing");
|
|
233
|
+
/** `Retry-After`, in milliseconds. The contract requires the header on this code. */
|
|
234
|
+
__publicField(this, "retryAfterMs");
|
|
229
235
|
this.missing = missing;
|
|
236
|
+
this.retryAfterMs = retryAfterMs;
|
|
230
237
|
}
|
|
231
238
|
getUserMessage() {
|
|
232
239
|
return "The service is temporarily unable to answer. Please retry.";
|
|
@@ -457,6 +464,14 @@ var _InvalidFieldTypeError = class _InvalidFieldTypeError extends BaseValidation
|
|
|
457
464
|
__name(_InvalidFieldTypeError, "InvalidFieldTypeError");
|
|
458
465
|
var InvalidFieldTypeError = _InvalidFieldTypeError;
|
|
459
466
|
|
|
467
|
+
// ../../platform/api-contract/dist/index.js
|
|
468
|
+
var HEADER_RETRY_AFTER = { name: "Retry-After" };
|
|
469
|
+
var HEADER_ENTITY_TAG = { name: "X-Entity-Tag" };
|
|
470
|
+
var HEADER_IF_MATCH = {
|
|
471
|
+
name: "If-Match"};
|
|
472
|
+
var HEADER_IDEMPOTENCY_KEY = {
|
|
473
|
+
name: "Idempotency-Key"};
|
|
474
|
+
|
|
460
475
|
// ../../platform/api-contract/dist/client/index.js
|
|
461
476
|
var _a;
|
|
462
477
|
var ContractBodyError = (_a = class extends Error {
|
|
@@ -500,19 +515,47 @@ function readError(body) {
|
|
|
500
515
|
}
|
|
501
516
|
__name(readError, "readError");
|
|
502
517
|
|
|
518
|
+
// src/http/retry-after.ts
|
|
519
|
+
function headerValue(headers, name) {
|
|
520
|
+
if (headers === void 0) return void 0;
|
|
521
|
+
const wanted = name.toLowerCase();
|
|
522
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
523
|
+
if (key.toLowerCase() === wanted) return value;
|
|
524
|
+
}
|
|
525
|
+
return void 0;
|
|
526
|
+
}
|
|
527
|
+
__name(headerValue, "headerValue");
|
|
528
|
+
function parseRetryAfterMs(value, nowMs) {
|
|
529
|
+
if (value === void 0) return void 0;
|
|
530
|
+
const trimmed = value.trim();
|
|
531
|
+
if (trimmed === "") return void 0;
|
|
532
|
+
if (/^\d+$/.test(trimmed)) {
|
|
533
|
+
return Number(trimmed) * 1e3;
|
|
534
|
+
}
|
|
535
|
+
if (!/[A-Za-z]/.test(trimmed)) return void 0;
|
|
536
|
+
const at = Date.parse(trimmed);
|
|
537
|
+
if (Number.isNaN(at)) return void 0;
|
|
538
|
+
return Math.max(0, at - nowMs);
|
|
539
|
+
}
|
|
540
|
+
__name(parseRetryAfterMs, "parseRetryAfterMs");
|
|
541
|
+
|
|
503
542
|
// src/errors/error-mapper.ts
|
|
504
543
|
var _ErrorMapper = class _ErrorMapper {
|
|
505
544
|
/** Map a non-2xx response to an SDK error. */
|
|
506
545
|
static mapHttpError(response, requestContext) {
|
|
507
|
-
const { status, statusText, body } = response;
|
|
546
|
+
const { status, statusText, body, headers } = response;
|
|
508
547
|
const refusal = readError(body);
|
|
509
548
|
const context = { ...requestContext, response: body };
|
|
510
549
|
if (refusal === void 0) {
|
|
511
550
|
return new NetworkError(`HTTP ${status}: ${statusText}`.trim(), status, void 0, context);
|
|
512
551
|
}
|
|
513
|
-
|
|
552
|
+
const retryAfterMs = parseRetryAfterMs(
|
|
553
|
+
headerValue(headers, HEADER_RETRY_AFTER.name),
|
|
554
|
+
Date.now()
|
|
555
|
+
);
|
|
556
|
+
return this.fromContractCode(refusal, status, context, retryAfterMs);
|
|
514
557
|
}
|
|
515
|
-
static fromContractCode(refusal, status, context) {
|
|
558
|
+
static fromContractCode(refusal, status, context, retryAfterMs) {
|
|
516
559
|
const message = refusal.messages[0] ?? `RelyIO refused with ${refusal.code}`;
|
|
517
560
|
switch (refusal.code) {
|
|
518
561
|
case "MISSING_API_KEY": {
|
|
@@ -543,7 +586,8 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
543
586
|
message,
|
|
544
587
|
detailNumber(refusal, "limit"),
|
|
545
588
|
detailString(refusal, "resetAt"),
|
|
546
|
-
context
|
|
589
|
+
context,
|
|
590
|
+
retryAfterMs
|
|
547
591
|
);
|
|
548
592
|
}
|
|
549
593
|
case "REQUEST_INVALID": {
|
|
@@ -586,7 +630,12 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
586
630
|
);
|
|
587
631
|
}
|
|
588
632
|
case "SERVICE_INDETERMINATE": {
|
|
589
|
-
return new ServiceIndeterminateError(
|
|
633
|
+
return new ServiceIndeterminateError(
|
|
634
|
+
message,
|
|
635
|
+
detailString(refusal, "missing"),
|
|
636
|
+
context,
|
|
637
|
+
retryAfterMs
|
|
638
|
+
);
|
|
590
639
|
}
|
|
591
640
|
case "INTERNAL_ERROR": {
|
|
592
641
|
return new ServerError(message, status, context);
|
|
@@ -628,12 +677,6 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
628
677
|
}
|
|
629
678
|
return error.name === "TypeError" && error.message.includes("fetch") || error.message.includes("timeout") || error.message.includes("Network Error") || error.message.includes("ECONNREFUSED");
|
|
630
679
|
}
|
|
631
|
-
/**
|
|
632
|
-
* Extract retry delay from error
|
|
633
|
-
*/
|
|
634
|
-
static getRetryDelay(_error) {
|
|
635
|
-
return 0;
|
|
636
|
-
}
|
|
637
680
|
};
|
|
638
681
|
__name(_ErrorMapper, "ErrorMapper");
|
|
639
682
|
var ErrorMapper = _ErrorMapper;
|
|
@@ -691,6 +734,158 @@ function fillPath(template, params) {
|
|
|
691
734
|
return filled;
|
|
692
735
|
}
|
|
693
736
|
__name(fillPath, "fillPath");
|
|
737
|
+
var DECLARED_PATHS = {
|
|
738
|
+
"/health": true,
|
|
739
|
+
"/health/cache": true,
|
|
740
|
+
"/health/live": true,
|
|
741
|
+
"/health/ready": true,
|
|
742
|
+
"/internal/media/claim": true,
|
|
743
|
+
"/internal/media/file-complete": true,
|
|
744
|
+
"/internal/media/progress": true,
|
|
745
|
+
"/internal/media/resolve": true,
|
|
746
|
+
"/internal/usage/cycle": true,
|
|
747
|
+
"/internal/usage/ingest": true,
|
|
748
|
+
"/v1/{contentType}": true,
|
|
749
|
+
"/v1/{contentType}/{id}": true,
|
|
750
|
+
"/v1/{contentType}/{id}/children": true,
|
|
751
|
+
"/v1/{contentType}/{id}/file": true,
|
|
752
|
+
"/v1/{contentType}/{id}/file/confirm": true,
|
|
753
|
+
"/v1/{contentType}/{id}/file/multipart/abort": true,
|
|
754
|
+
"/v1/{contentType}/{id}/file/multipart/complete": true,
|
|
755
|
+
"/v1/{contentType}/{id}/file/multipart/create": true,
|
|
756
|
+
"/v1/{contentType}/{id}/file/multipart/list-parts": true,
|
|
757
|
+
"/v1/{contentType}/{id}/file/multipart/sign-part": true,
|
|
758
|
+
"/v1/{contentType}/{id}/file/presign": true,
|
|
759
|
+
"/v1/{contentType}/{id}/file/url": true,
|
|
760
|
+
"/v1/{contentType}/{id}/versions": true,
|
|
761
|
+
"/v1/{contentType}/{id}/versions/{versionNumber}": true,
|
|
762
|
+
"/v1/{contentType}/{id}/versions/{versionNumber}/restore": true,
|
|
763
|
+
"/v1/batch": true,
|
|
764
|
+
"/v1/changes": true,
|
|
765
|
+
"/v1/meta/content-types": true,
|
|
766
|
+
"/v1/meta/info": true,
|
|
767
|
+
"/v1/meta/locales": true,
|
|
768
|
+
"/v1/meta/schema": true,
|
|
769
|
+
"/v1/meta/schema/{contentType}": true,
|
|
770
|
+
"/v1/meta/schema/{contentType}/fields": true,
|
|
771
|
+
"/v1/query": true,
|
|
772
|
+
"/v1/search": true,
|
|
773
|
+
"/v1/search/autocomplete": true,
|
|
774
|
+
"/v1/search/similar": true,
|
|
775
|
+
"/v1/settings": true,
|
|
776
|
+
"/v1/settings/{groupId}": true,
|
|
777
|
+
"/v1/settings/{groupId}/defaults": true,
|
|
778
|
+
"/v1/settings/{groupId}/reset": true,
|
|
779
|
+
"/v1/settings/{groupId}/versions": true,
|
|
780
|
+
"/v1/settings/{groupId}/versions/{versionNumber}": true,
|
|
781
|
+
"/v1/singletons/{key}": true,
|
|
782
|
+
"/v1/singletons/{key}/exists": true,
|
|
783
|
+
"/v1/singletons/{key}/versions": true,
|
|
784
|
+
"/v1/singletons/{key}/versions/{versionNumber}": true
|
|
785
|
+
};
|
|
786
|
+
function compile(path) {
|
|
787
|
+
const segments = path.split("/").slice(1).map((part) => {
|
|
788
|
+
const param = /^\{(\w+)\}$/.exec(part);
|
|
789
|
+
return param?.[1] === void 0 ? { kind: "static", value: part } : { kind: "param", name: param[1] };
|
|
790
|
+
});
|
|
791
|
+
return { path, segments };
|
|
792
|
+
}
|
|
793
|
+
__name(compile, "compile");
|
|
794
|
+
function byRouterPrecedence(a, b) {
|
|
795
|
+
const shared = Math.min(a.segments.length, b.segments.length);
|
|
796
|
+
for (let index = 0; index < shared; index += 1) {
|
|
797
|
+
const left = a.segments[index]?.kind;
|
|
798
|
+
const right = b.segments[index]?.kind;
|
|
799
|
+
if (left !== right) return left === "static" ? -1 : 1;
|
|
800
|
+
}
|
|
801
|
+
return 0;
|
|
802
|
+
}
|
|
803
|
+
__name(byRouterPrecedence, "byRouterPrecedence");
|
|
804
|
+
var COMPILED_ROUTES = Object.keys(DECLARED_PATHS).map(compile).sort(byRouterPrecedence);
|
|
805
|
+
function matchRoute(url, options = {}) {
|
|
806
|
+
const parsed = new URL(url, "http://relative.invalid");
|
|
807
|
+
let pathname = parsed.pathname;
|
|
808
|
+
if (options.baseUrl !== void 0) {
|
|
809
|
+
const prefix = new URL(options.baseUrl, "http://relative.invalid").pathname.replace(/\/+$/, "");
|
|
810
|
+
if (prefix !== "") {
|
|
811
|
+
if (pathname !== prefix && !pathname.startsWith(`${prefix}/`)) return null;
|
|
812
|
+
pathname = pathname.slice(prefix.length);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const parts = pathname.split("/").slice(1);
|
|
816
|
+
for (const route of COMPILED_ROUTES) {
|
|
817
|
+
if (route.segments.length !== parts.length) continue;
|
|
818
|
+
const params = {};
|
|
819
|
+
const matched = route.segments.every((segment, index) => {
|
|
820
|
+
const part = parts[index];
|
|
821
|
+
if (part === void 0) return false;
|
|
822
|
+
if (segment.kind === "static") return segment.value === part;
|
|
823
|
+
if (part === "") return false;
|
|
824
|
+
params[segment.name] = decodeURIComponent(part);
|
|
825
|
+
return true;
|
|
826
|
+
});
|
|
827
|
+
if (matched) return { path: route.path, params, query: readQuery(parsed.searchParams) };
|
|
828
|
+
}
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
__name(matchRoute, "matchRoute");
|
|
832
|
+
function readQuery(searchParams) {
|
|
833
|
+
const query = {};
|
|
834
|
+
for (const key of new Set(searchParams.keys())) {
|
|
835
|
+
const values = searchParams.getAll(key);
|
|
836
|
+
query[key] = values.length === 1 && values[0] !== void 0 ? values[0] : values;
|
|
837
|
+
}
|
|
838
|
+
return query;
|
|
839
|
+
}
|
|
840
|
+
__name(readQuery, "readQuery");
|
|
841
|
+
|
|
842
|
+
// src/http/retry-policy.ts
|
|
843
|
+
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set([
|
|
844
|
+
"GET",
|
|
845
|
+
"HEAD",
|
|
846
|
+
"OPTIONS",
|
|
847
|
+
"PUT",
|
|
848
|
+
"DELETE",
|
|
849
|
+
"TRACE"
|
|
850
|
+
]);
|
|
851
|
+
function isReplaySafe(request) {
|
|
852
|
+
if (IDEMPOTENT_METHODS.has(request.method.toUpperCase())) return true;
|
|
853
|
+
return headerValue(request.headers, HEADER_IDEMPOTENCY_KEY.name) !== void 0;
|
|
854
|
+
}
|
|
855
|
+
__name(isReplaySafe, "isReplaySafe");
|
|
856
|
+
function serviceInstructedDelayMs(error, nowMs) {
|
|
857
|
+
if (error instanceof ServiceIndeterminateError) {
|
|
858
|
+
return error.retryAfterMs;
|
|
859
|
+
}
|
|
860
|
+
if (!(error instanceof RateLimitError)) return void 0;
|
|
861
|
+
if (error.retryAfterMs !== void 0) return error.retryAfterMs;
|
|
862
|
+
if (error.resetAt === void 0) return void 0;
|
|
863
|
+
const resetAtMs = Date.parse(error.resetAt);
|
|
864
|
+
if (Number.isNaN(resetAtMs)) return void 0;
|
|
865
|
+
const wait = resetAtMs - nowMs;
|
|
866
|
+
return wait > 0 ? wait : void 0;
|
|
867
|
+
}
|
|
868
|
+
__name(serviceInstructedDelayMs, "serviceInstructedDelayMs");
|
|
869
|
+
var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
870
|
+
constructor(config) {
|
|
871
|
+
__publicField(this, "config");
|
|
872
|
+
this.config = config;
|
|
873
|
+
}
|
|
874
|
+
shouldRetry(attempt, error, request) {
|
|
875
|
+
if (attempt >= this.config.maxAttempts) return false;
|
|
876
|
+
if (!ErrorMapper.isRetryable(error)) return false;
|
|
877
|
+
return isReplaySafe(request);
|
|
878
|
+
}
|
|
879
|
+
delayFor(attempt, error) {
|
|
880
|
+
const instructed = serviceInstructedDelayMs(error, Date.now());
|
|
881
|
+
if (instructed !== void 0) return instructed;
|
|
882
|
+
const exponential = this.config.baseDelay * Math.pow(this.config.backoffFactor, attempt - 1);
|
|
883
|
+
const delay = Math.min(exponential, this.config.maxDelay);
|
|
884
|
+
return this.config.jitter ? delay * (0.5 + Math.random() * 0.5) : delay;
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
__name(_DefaultRetryPolicy, "DefaultRetryPolicy");
|
|
888
|
+
var DefaultRetryPolicy = _DefaultRetryPolicy;
|
|
694
889
|
|
|
695
890
|
// src/http/http-client.ts
|
|
696
891
|
var _HttpClient = class _HttpClient {
|
|
@@ -698,7 +893,7 @@ var _HttpClient = class _HttpClient {
|
|
|
698
893
|
__publicField(this, "baseUrl");
|
|
699
894
|
__publicField(this, "defaultHeaders");
|
|
700
895
|
__publicField(this, "timeout");
|
|
701
|
-
__publicField(this, "
|
|
896
|
+
__publicField(this, "retryPolicy");
|
|
702
897
|
__publicField(this, "debug");
|
|
703
898
|
__publicField(this, "logger");
|
|
704
899
|
__publicField(this, "config");
|
|
@@ -719,16 +914,13 @@ var _HttpClient = class _HttpClient {
|
|
|
719
914
|
const globalWithVersion = globalThis;
|
|
720
915
|
this.defaultHeaders["User-Agent"] = `RelyIO-SDK/${globalWithVersion.__VERSION__ ?? "0.0.0"}`;
|
|
721
916
|
}
|
|
722
|
-
this.
|
|
917
|
+
this.retryPolicy = new DefaultRetryPolicy({
|
|
723
918
|
maxAttempts: config.retryAttempts,
|
|
724
919
|
baseDelay: 1e3,
|
|
725
920
|
maxDelay: 1e4,
|
|
726
921
|
backoffFactor: 2,
|
|
727
|
-
jitter: true
|
|
728
|
-
|
|
729
|
-
return ErrorMapper.isRetryable(error) && attempt < config.retryAttempts;
|
|
730
|
-
}, "retryCondition")
|
|
731
|
-
};
|
|
922
|
+
jitter: true
|
|
923
|
+
});
|
|
732
924
|
this.log("debug", "HttpClient initialized", {
|
|
733
925
|
baseUrl: this.baseUrl,
|
|
734
926
|
timeout: this.timeout,
|
|
@@ -761,7 +953,16 @@ var _HttpClient = class _HttpClient {
|
|
|
761
953
|
return readPayload(response.body);
|
|
762
954
|
}
|
|
763
955
|
/**
|
|
764
|
-
* Make an HTTP request
|
|
956
|
+
* Make an HTTP request, retrying only where a retry is safe.
|
|
957
|
+
*
|
|
958
|
+
* The headers are merged **once**, before the first attempt, and every attempt
|
|
959
|
+
* sends that same object. That is what makes a minted `Idempotency-Key` stable
|
|
960
|
+
* across the retries of one logical write: the service sees one key and
|
|
961
|
+
* answers the replay from the original outcome instead of applying it twice.
|
|
962
|
+
*
|
|
963
|
+
* The loop always makes one attempt. The incumbent's `while (attempt <
|
|
964
|
+
* maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
|
|
965
|
+
* accepts — and then dereferenced an unassigned `lastError`.
|
|
765
966
|
*/
|
|
766
967
|
async request(config) {
|
|
767
968
|
const mergedConfig = this.mergeRequestConfig(config);
|
|
@@ -770,14 +971,11 @@ var _HttpClient = class _HttpClient {
|
|
|
770
971
|
url: mergedConfig.url
|
|
771
972
|
// Show the final URL with query params
|
|
772
973
|
});
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
974
|
+
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
975
|
+
delete mergedConfig.headers["Content-Type"];
|
|
976
|
+
}
|
|
977
|
+
for (let attempt = 1; ; attempt++) {
|
|
777
978
|
try {
|
|
778
|
-
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
779
|
-
delete mergedConfig.headers["Content-Type"];
|
|
780
|
-
}
|
|
781
979
|
const response = await this.makeRequest(mergedConfig.url, mergedConfig);
|
|
782
980
|
this.log("debug", "Request successful", {
|
|
783
981
|
status: response.status,
|
|
@@ -786,31 +984,31 @@ var _HttpClient = class _HttpClient {
|
|
|
786
984
|
});
|
|
787
985
|
return response;
|
|
788
986
|
} catch (error) {
|
|
789
|
-
|
|
987
|
+
const failure = error;
|
|
988
|
+
if (config.signal?.aborted === true) throw failure;
|
|
790
989
|
this.log("warn", "Request failed", {
|
|
791
990
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
792
991
|
attempt,
|
|
793
992
|
url: mergedConfig.url
|
|
794
993
|
});
|
|
795
|
-
if (
|
|
796
|
-
const delay = this.
|
|
994
|
+
if (this.retryPolicy.shouldRetry(attempt, failure, mergedConfig)) {
|
|
995
|
+
const delay = this.retryPolicy.delayFor(attempt, failure);
|
|
797
996
|
this.log("debug", "Retrying request", { attempt, delay });
|
|
798
|
-
await this.sleep(delay);
|
|
997
|
+
await this.sleep(delay, config.signal);
|
|
799
998
|
continue;
|
|
800
999
|
}
|
|
801
|
-
|
|
1000
|
+
const sdkError = ErrorMapper.mapGenericError(failure, {
|
|
1001
|
+
url: mergedConfig.url,
|
|
1002
|
+
method: mergedConfig.method,
|
|
1003
|
+
attempt
|
|
1004
|
+
});
|
|
1005
|
+
this.log("error", "Request failed after all retries", {
|
|
1006
|
+
error: sdkError.toJSON(),
|
|
1007
|
+
url: mergedConfig.url
|
|
1008
|
+
});
|
|
1009
|
+
throw sdkError;
|
|
802
1010
|
}
|
|
803
1011
|
}
|
|
804
|
-
const sdkError = ErrorMapper.mapGenericError(lastError, {
|
|
805
|
-
url: mergedConfig.url,
|
|
806
|
-
method: mergedConfig.method,
|
|
807
|
-
attempt
|
|
808
|
-
});
|
|
809
|
-
this.log("error", "Request failed after all retries", {
|
|
810
|
-
error: sdkError.toJSON(),
|
|
811
|
-
url: mergedConfig.url
|
|
812
|
-
});
|
|
813
|
-
throw sdkError;
|
|
814
1012
|
}
|
|
815
1013
|
/**
|
|
816
1014
|
* Make a GET request
|
|
@@ -895,20 +1093,41 @@ var _HttpClient = class _HttpClient {
|
|
|
895
1093
|
getBaseUrl() {
|
|
896
1094
|
return this.baseUrl;
|
|
897
1095
|
}
|
|
1096
|
+
/**
|
|
1097
|
+
* One attempt.
|
|
1098
|
+
*
|
|
1099
|
+
* The caller's `signal` and the timeout both end it, through one controller.
|
|
1100
|
+
* The incumbent handed `fetch` the caller's signal **instead of** its own, so a
|
|
1101
|
+
* request that passed a signal had no timeout at all — and a caller abort then
|
|
1102
|
+
* surfaced as `Request timed out`. `timedOut` is what tells the two apart: a
|
|
1103
|
+
* timeout is a `TimeoutError`, a caller abort is the platform's `AbortError`,
|
|
1104
|
+
* rethrown as it came.
|
|
1105
|
+
*/
|
|
898
1106
|
async makeRequest(url, config) {
|
|
1107
|
+
const caller = config.signal;
|
|
1108
|
+
if (caller?.aborted === true) {
|
|
1109
|
+
throw new DOMException("The request was aborted before it was sent", "AbortError");
|
|
1110
|
+
}
|
|
899
1111
|
const controller = new AbortController();
|
|
900
|
-
|
|
1112
|
+
let timedOut = false;
|
|
1113
|
+
const timeoutId = setTimeout(() => {
|
|
1114
|
+
timedOut = true;
|
|
1115
|
+
controller.abort();
|
|
1116
|
+
}, config.timeout ?? this.timeout);
|
|
1117
|
+
const onCallerAbort = /* @__PURE__ */ __name(() => controller.abort(), "onCallerAbort");
|
|
1118
|
+
caller?.addEventListener("abort", onCallerAbort, { once: true });
|
|
901
1119
|
try {
|
|
902
1120
|
const filteredHeaders = this.filterHeadersForBrowser(config.headers ?? {});
|
|
903
1121
|
const requestInit = {
|
|
904
1122
|
method: config.method,
|
|
905
1123
|
headers: filteredHeaders,
|
|
906
1124
|
body: this.prepareRequestBody(config),
|
|
907
|
-
signal:
|
|
1125
|
+
signal: controller.signal,
|
|
908
1126
|
// Include credentials for CORS requests if in browser and configured
|
|
909
1127
|
...typeof window !== "undefined" && this.config.browser.includeCredentials != null && { credentials: "include" }
|
|
910
1128
|
};
|
|
911
|
-
const
|
|
1129
|
+
const send = this.config.fetch ?? globalThis.fetch;
|
|
1130
|
+
const response = await send(url, requestInit);
|
|
912
1131
|
clearTimeout(timeoutId);
|
|
913
1132
|
const responseBody = await this.parseResponse(response);
|
|
914
1133
|
if (!response.ok) {
|
|
@@ -939,6 +1158,7 @@ var _HttpClient = class _HttpClient {
|
|
|
939
1158
|
throw error;
|
|
940
1159
|
}
|
|
941
1160
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
1161
|
+
if (!timedOut && isAborted(caller)) throw error;
|
|
942
1162
|
throw new TimeoutError(
|
|
943
1163
|
`Request timed out after ${config.timeout ?? this.timeout}ms`,
|
|
944
1164
|
config.timeout ?? this.timeout
|
|
@@ -970,6 +1190,8 @@ var _HttpClient = class _HttpClient {
|
|
|
970
1190
|
throw corsError;
|
|
971
1191
|
}
|
|
972
1192
|
throw error;
|
|
1193
|
+
} finally {
|
|
1194
|
+
caller?.removeEventListener("abort", onCallerAbort);
|
|
973
1195
|
}
|
|
974
1196
|
}
|
|
975
1197
|
/**
|
|
@@ -1058,16 +1280,21 @@ var _HttpClient = class _HttpClient {
|
|
|
1058
1280
|
});
|
|
1059
1281
|
return obj;
|
|
1060
1282
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1283
|
+
/** A backoff the caller's abort cuts short; the next attempt then refuses to send. */
|
|
1284
|
+
sleep(ms, signal) {
|
|
1285
|
+
return new Promise((resolve) => {
|
|
1286
|
+
if (isAborted(signal)) {
|
|
1287
|
+
resolve();
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
const done = /* @__PURE__ */ __name(() => {
|
|
1291
|
+
clearTimeout(timer);
|
|
1292
|
+
signal?.removeEventListener("abort", done);
|
|
1293
|
+
resolve();
|
|
1294
|
+
}, "done");
|
|
1295
|
+
const timer = setTimeout(done, ms);
|
|
1296
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
1297
|
+
});
|
|
1071
1298
|
}
|
|
1072
1299
|
log(level, message, data) {
|
|
1073
1300
|
if (!this.debug) return;
|
|
@@ -1080,6 +1307,10 @@ var _HttpClient = class _HttpClient {
|
|
|
1080
1307
|
};
|
|
1081
1308
|
__name(_HttpClient, "HttpClient");
|
|
1082
1309
|
var HttpClient = _HttpClient;
|
|
1310
|
+
function isAborted(signal) {
|
|
1311
|
+
return signal?.aborted === true;
|
|
1312
|
+
}
|
|
1313
|
+
__name(isAborted, "isAborted");
|
|
1083
1314
|
|
|
1084
1315
|
// src/content/query-builder.ts
|
|
1085
1316
|
var _ContentQueryBuilder = class _ContentQueryBuilder {
|
|
@@ -1561,32 +1792,27 @@ var _ContentByIdBuilder = class _ContentByIdBuilder {
|
|
|
1561
1792
|
__name(_ContentByIdBuilder, "ContentByIdBuilder");
|
|
1562
1793
|
var ContentByIdBuilder = _ContentByIdBuilder;
|
|
1563
1794
|
|
|
1564
|
-
// ../../platform/api-contract/dist/index.js
|
|
1565
|
-
var HEADER_ENTITY_TAG = { name: "X-Entity-Tag" };
|
|
1566
|
-
var HEADER_IF_MATCH = {
|
|
1567
|
-
name: "If-Match"};
|
|
1568
|
-
var HEADER_IDEMPOTENCY_KEY = {
|
|
1569
|
-
name: "Idempotency-Key"};
|
|
1570
|
-
|
|
1571
1795
|
// src/http/write-options.ts
|
|
1796
|
+
function mintIdempotencyKey() {
|
|
1797
|
+
const webCrypto = globalThis.crypto;
|
|
1798
|
+
if (typeof webCrypto?.randomUUID !== "function") return void 0;
|
|
1799
|
+
return webCrypto.randomUUID();
|
|
1800
|
+
}
|
|
1801
|
+
__name(mintIdempotencyKey, "mintIdempotencyKey");
|
|
1572
1802
|
function writeHeaders(options) {
|
|
1573
|
-
if (options === void 0) return void 0;
|
|
1574
1803
|
const headers = {};
|
|
1575
|
-
if ("ifMatch" in options && options.ifMatch !== void 0) {
|
|
1804
|
+
if (options !== void 0 && "ifMatch" in options && options.ifMatch !== void 0) {
|
|
1576
1805
|
headers[HEADER_IF_MATCH.name] = options.ifMatch;
|
|
1577
1806
|
}
|
|
1578
|
-
|
|
1579
|
-
|
|
1807
|
+
const idempotencyKey = options?.idempotencyKey ?? mintIdempotencyKey();
|
|
1808
|
+
if (idempotencyKey !== void 0) {
|
|
1809
|
+
headers[HEADER_IDEMPOTENCY_KEY.name] = idempotencyKey;
|
|
1580
1810
|
}
|
|
1581
1811
|
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1582
1812
|
}
|
|
1583
1813
|
__name(writeHeaders, "writeHeaders");
|
|
1584
1814
|
function entityTagOf(response) {
|
|
1585
|
-
|
|
1586
|
-
for (const [name, value] of Object.entries(response.headers)) {
|
|
1587
|
-
if (name.toLowerCase() === wanted) return value;
|
|
1588
|
-
}
|
|
1589
|
-
return void 0;
|
|
1815
|
+
return headerValue(response.headers, HEADER_ENTITY_TAG.name);
|
|
1590
1816
|
}
|
|
1591
1817
|
__name(entityTagOf, "entityTagOf");
|
|
1592
1818
|
|
|
@@ -3852,6 +4078,103 @@ var _AdhocQueryClient = class _AdhocQueryClient {
|
|
|
3852
4078
|
__name(_AdhocQueryClient, "AdhocQueryClient");
|
|
3853
4079
|
var AdhocQueryClient = _AdhocQueryClient;
|
|
3854
4080
|
|
|
4081
|
+
// src/changes/changes.ts
|
|
4082
|
+
var CHANGES_POLL_TIMEOUT_MS = 25e3 + 5e3;
|
|
4083
|
+
var _ChangesExpiredError = class _ChangesExpiredError extends ResourceExpiredError {
|
|
4084
|
+
/** The base class's signature, so `withContext` can rebuild one. */
|
|
4085
|
+
constructor(message, statusCode = 410, cause, context) {
|
|
4086
|
+
super(message, statusCode, cause, context);
|
|
4087
|
+
__publicField(this, "reason");
|
|
4088
|
+
this.name = "ChangesExpiredError";
|
|
4089
|
+
this.reason = expiredReasonOf(message);
|
|
4090
|
+
}
|
|
4091
|
+
static of(expired) {
|
|
4092
|
+
return new _ChangesExpiredError(expired.message, expired.statusCode, expired, expired.context);
|
|
4093
|
+
}
|
|
4094
|
+
};
|
|
4095
|
+
__name(_ChangesExpiredError, "ChangesExpiredError");
|
|
4096
|
+
var ChangesExpiredError = _ChangesExpiredError;
|
|
4097
|
+
function expiredReasonOf(message) {
|
|
4098
|
+
if (message.includes("(retention)")) return "retention";
|
|
4099
|
+
if (message.includes("(dataset-replaced)")) return "dataset-replaced";
|
|
4100
|
+
return "unknown";
|
|
4101
|
+
}
|
|
4102
|
+
__name(expiredReasonOf, "expiredReasonOf");
|
|
4103
|
+
async function* pollChanges(http, options = {}) {
|
|
4104
|
+
const { signal } = options;
|
|
4105
|
+
let since = options.since;
|
|
4106
|
+
let resynced;
|
|
4107
|
+
for (; ; ) {
|
|
4108
|
+
if (aborted(signal)) return;
|
|
4109
|
+
let response;
|
|
4110
|
+
try {
|
|
4111
|
+
response = await pollOnce(http, since, options);
|
|
4112
|
+
} catch (error) {
|
|
4113
|
+
if (aborted(signal)) return;
|
|
4114
|
+
if (!(error instanceof ResourceExpiredError) || since === void 0) throw error;
|
|
4115
|
+
const expired = ChangesExpiredError.of(error);
|
|
4116
|
+
const onExpired = options.onExpired ?? "throw";
|
|
4117
|
+
if (onExpired === "throw") throw expired;
|
|
4118
|
+
since = void 0;
|
|
4119
|
+
resynced = typeof onExpired === "function" ? expired : void 0;
|
|
4120
|
+
continue;
|
|
4121
|
+
}
|
|
4122
|
+
const { data, page } = response.body;
|
|
4123
|
+
if (page.nextCursor === null) {
|
|
4124
|
+
throw new Error("GET /v1/changes answered without page.nextCursor");
|
|
4125
|
+
}
|
|
4126
|
+
since = page.nextCursor;
|
|
4127
|
+
if (resynced !== void 0 && typeof options.onExpired === "function") {
|
|
4128
|
+
const expired = resynced;
|
|
4129
|
+
resynced = void 0;
|
|
4130
|
+
await options.onExpired(expired);
|
|
4131
|
+
if (aborted(signal)) return;
|
|
4132
|
+
}
|
|
4133
|
+
for (const change of data) {
|
|
4134
|
+
yield change;
|
|
4135
|
+
if (aborted(signal)) return;
|
|
4136
|
+
}
|
|
4137
|
+
if (data.length === 0) {
|
|
4138
|
+
const wait = parseRetryAfterMs(headerValue(response.headers, "Retry-After"), Date.now());
|
|
4139
|
+
if (wait !== void 0 && wait > 0) await sleep(wait, signal);
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
__name(pollChanges, "pollChanges");
|
|
4144
|
+
async function pollOnce(http, since, options) {
|
|
4145
|
+
const query = {};
|
|
4146
|
+
if (since !== void 0) query.since = since;
|
|
4147
|
+
if (options.types !== void 0) query.types = options.types.join(",");
|
|
4148
|
+
if (options.ids !== void 0) query.ids = options.ids.join(",");
|
|
4149
|
+
if (options.limit !== void 0) query.limit = options.limit;
|
|
4150
|
+
return http.send("/v1/changes", "get", {
|
|
4151
|
+
query,
|
|
4152
|
+
timeout: CHANGES_POLL_TIMEOUT_MS,
|
|
4153
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
4154
|
+
});
|
|
4155
|
+
}
|
|
4156
|
+
__name(pollOnce, "pollOnce");
|
|
4157
|
+
function sleep(ms, signal) {
|
|
4158
|
+
return new Promise((resolve) => {
|
|
4159
|
+
if (aborted(signal)) {
|
|
4160
|
+
resolve();
|
|
4161
|
+
return;
|
|
4162
|
+
}
|
|
4163
|
+
const done = /* @__PURE__ */ __name(() => {
|
|
4164
|
+
clearTimeout(timer);
|
|
4165
|
+
signal?.removeEventListener("abort", done);
|
|
4166
|
+
resolve();
|
|
4167
|
+
}, "done");
|
|
4168
|
+
const timer = setTimeout(done, ms);
|
|
4169
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
4170
|
+
});
|
|
4171
|
+
}
|
|
4172
|
+
__name(sleep, "sleep");
|
|
4173
|
+
function aborted(signal) {
|
|
4174
|
+
return signal?.aborted === true;
|
|
4175
|
+
}
|
|
4176
|
+
__name(aborted, "aborted");
|
|
4177
|
+
|
|
3855
4178
|
// src/config/dev-detection.ts
|
|
3856
4179
|
function getProcess() {
|
|
3857
4180
|
return typeof process !== "undefined" ? process : void 0;
|
|
@@ -3870,47 +4193,76 @@ function isProduction(proc) {
|
|
|
3870
4193
|
return proc?.env?.NODE_ENV === "production";
|
|
3871
4194
|
}
|
|
3872
4195
|
__name(isProduction, "isProduction");
|
|
3873
|
-
function resolveFromEnv(proc) {
|
|
3874
|
-
const
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
4196
|
+
function resolveFromEnv(proc, now) {
|
|
4197
|
+
const verdict = parseDevEnv(proc?.env, now);
|
|
4198
|
+
switch (verdict.state) {
|
|
4199
|
+
case "active":
|
|
4200
|
+
return {
|
|
4201
|
+
state: "active",
|
|
4202
|
+
override: {
|
|
4203
|
+
dataset: verdict.credentials.dataset,
|
|
4204
|
+
apiKey: verdict.credentials.apiKey,
|
|
4205
|
+
source: "env"
|
|
4206
|
+
}
|
|
4207
|
+
};
|
|
4208
|
+
case "expired":
|
|
4209
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
4210
|
+
case "unreadable":
|
|
4211
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
4212
|
+
case "absent":
|
|
4213
|
+
return { state: "absent" };
|
|
3878
4214
|
}
|
|
3879
|
-
return null;
|
|
3880
4215
|
}
|
|
3881
4216
|
__name(resolveFromEnv, "resolveFromEnv");
|
|
3882
|
-
function resolveFromFile(proc) {
|
|
3883
|
-
if (proc == null || typeof proc.cwd !== "function") return
|
|
4217
|
+
function resolveFromFile(proc, now) {
|
|
4218
|
+
if (proc == null || typeof proc.cwd !== "function") return { state: "absent" };
|
|
3884
4219
|
const fs = getBuiltin(proc, "node:fs");
|
|
3885
4220
|
const path = getBuiltin(proc, "node:path");
|
|
3886
|
-
if (fs == null || path == null) return
|
|
4221
|
+
if (fs == null || path == null) return { state: "absent" };
|
|
3887
4222
|
let dir = proc.cwd();
|
|
3888
4223
|
for (; ; ) {
|
|
3889
|
-
const candidate = path.join(dir,
|
|
4224
|
+
const candidate = path.join(dir, DEV_CONTEXT_DIR, DEV_CONTEXT_FILENAME);
|
|
4225
|
+
let raw = null;
|
|
3890
4226
|
try {
|
|
3891
|
-
if (fs.existsSync(candidate))
|
|
3892
|
-
const parsed = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
3893
|
-
if (parsed.datasetId != null && parsed.datasetId !== "" && parsed.previewApiKey != null && parsed.previewApiKey !== "") {
|
|
3894
|
-
if (parsed.expiresAt != null && Number.isFinite(new Date(parsed.expiresAt).getTime()) && new Date(parsed.expiresAt).getTime() < Date.now()) {
|
|
3895
|
-
return null;
|
|
3896
|
-
}
|
|
3897
|
-
return { dataset: parsed.datasetId, apiKey: parsed.previewApiKey, source: "file" };
|
|
3898
|
-
}
|
|
3899
|
-
}
|
|
4227
|
+
if (fs.existsSync(candidate)) raw = fs.readFileSync(candidate, "utf8");
|
|
3900
4228
|
} catch {
|
|
4229
|
+
return { state: "absent" };
|
|
4230
|
+
}
|
|
4231
|
+
if (raw !== null) {
|
|
4232
|
+
const verdict = parseDevContextFile(raw, now);
|
|
4233
|
+
switch (verdict.state) {
|
|
4234
|
+
case "active":
|
|
4235
|
+
return {
|
|
4236
|
+
state: "active",
|
|
4237
|
+
override: {
|
|
4238
|
+
dataset: verdict.context.datasetId,
|
|
4239
|
+
apiKey: verdict.context.previewApiKey,
|
|
4240
|
+
source: "file"
|
|
4241
|
+
}
|
|
4242
|
+
};
|
|
4243
|
+
case "expired":
|
|
4244
|
+
return { state: "expired", expiredAt: verdict.expiredAt };
|
|
4245
|
+
case "unreadable":
|
|
4246
|
+
return { state: "unreadable", reason: verdict.reason };
|
|
4247
|
+
case "absent":
|
|
4248
|
+
return { state: "absent" };
|
|
4249
|
+
}
|
|
3901
4250
|
}
|
|
3902
4251
|
const parent = path.dirname(dir);
|
|
3903
4252
|
if (parent === dir) break;
|
|
3904
4253
|
dir = parent;
|
|
3905
4254
|
}
|
|
3906
|
-
return
|
|
4255
|
+
return { state: "absent" };
|
|
3907
4256
|
}
|
|
3908
4257
|
__name(resolveFromFile, "resolveFromFile");
|
|
3909
4258
|
function resolveDevOverride(dev) {
|
|
3910
|
-
if (dev === false) return
|
|
4259
|
+
if (dev === false) return { state: "disabled" };
|
|
3911
4260
|
const proc = getProcess();
|
|
3912
|
-
if (dev !== true && isProduction(proc)) return
|
|
3913
|
-
|
|
4261
|
+
if (dev !== true && isProduction(proc)) return { state: "disabled" };
|
|
4262
|
+
const now = Date.now();
|
|
4263
|
+
const fromEnv = resolveFromEnv(proc, now);
|
|
4264
|
+
if (fromEnv.state !== "absent") return fromEnv;
|
|
4265
|
+
return resolveFromFile(proc, now);
|
|
3914
4266
|
}
|
|
3915
4267
|
__name(resolveDevOverride, "resolveDevOverride");
|
|
3916
4268
|
|
|
@@ -3993,16 +4345,26 @@ function mergeConfig(userConfig) {
|
|
|
3993
4345
|
...userConfig.debug
|
|
3994
4346
|
}
|
|
3995
4347
|
};
|
|
3996
|
-
const
|
|
3997
|
-
if (
|
|
3998
|
-
merged.apiKey =
|
|
3999
|
-
merged.dataset =
|
|
4348
|
+
const dev = resolveDevOverride(userConfig.dev);
|
|
4349
|
+
if (dev.state === "active") {
|
|
4350
|
+
merged.apiKey = dev.override.apiKey;
|
|
4351
|
+
merged.dataset = dev.override.dataset;
|
|
4000
4352
|
if (!devOverrideNotified) {
|
|
4001
4353
|
devOverrideNotified = true;
|
|
4002
4354
|
console.info(
|
|
4003
|
-
`[RelyIO] Sandbox dev mode active (${
|
|
4355
|
+
`[RelyIO] Sandbox dev mode active (${dev.override.source}) \u2014 targeting dataset "${dev.override.dataset}" with a scoped preview key.`
|
|
4004
4356
|
);
|
|
4005
4357
|
}
|
|
4358
|
+
} else if (dev.state === "expired" && !devOverrideNotified) {
|
|
4359
|
+
devOverrideNotified = true;
|
|
4360
|
+
console.warn(
|
|
4361
|
+
`[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.`
|
|
4362
|
+
);
|
|
4363
|
+
} else if (dev.state === "unreadable" && !devOverrideNotified) {
|
|
4364
|
+
devOverrideNotified = true;
|
|
4365
|
+
console.warn(
|
|
4366
|
+
`[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.`
|
|
4367
|
+
);
|
|
4006
4368
|
}
|
|
4007
4369
|
return merged;
|
|
4008
4370
|
}
|
|
@@ -4183,6 +4545,37 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4183
4545
|
return this._batch.create();
|
|
4184
4546
|
}
|
|
4185
4547
|
// ============================================================================
|
|
4548
|
+
// CHANGES FEED
|
|
4549
|
+
// ============================================================================
|
|
4550
|
+
/**
|
|
4551
|
+
* Follow the dataset's changes feed: each write this key can see, as ids, in
|
|
4552
|
+
* order, long-polled from `GET /v1/changes`.
|
|
4553
|
+
*
|
|
4554
|
+
* Lazy — nothing is requested until the first `next()`. It runs until
|
|
4555
|
+
* `signal` aborts, which ends the `for await` cleanly rather than throwing.
|
|
4556
|
+
* A change names what changed; refetch it through the ordinary read path
|
|
4557
|
+
* (`INV-SS-CHANGE-IS-IDS`).
|
|
4558
|
+
*
|
|
4559
|
+
* @example
|
|
4560
|
+
* ```typescript
|
|
4561
|
+
* const controller = new AbortController()
|
|
4562
|
+
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
4563
|
+
* // { entryId, contentType, locale, kind, cursor }
|
|
4564
|
+
* }
|
|
4565
|
+
* ```
|
|
4566
|
+
*
|
|
4567
|
+
* @example Resync when the cursor has expired
|
|
4568
|
+
* ```typescript
|
|
4569
|
+
* for await (const change of relyio.changes({
|
|
4570
|
+
* since: cursor,
|
|
4571
|
+
* onExpired: async () => invalidateEverything(),
|
|
4572
|
+
* })) { … }
|
|
4573
|
+
* ```
|
|
4574
|
+
*/
|
|
4575
|
+
changes(options = {}) {
|
|
4576
|
+
return pollChanges(this.httpClient, options);
|
|
4577
|
+
}
|
|
4578
|
+
// ============================================================================
|
|
4186
4579
|
// QUERY OPERATIONS
|
|
4187
4580
|
// ============================================================================
|
|
4188
4581
|
/**
|
|
@@ -4370,6 +4763,6 @@ function createClient(config) {
|
|
|
4370
4763
|
}
|
|
4371
4764
|
__name(createClient, "createClient");
|
|
4372
4765
|
|
|
4373
|
-
export { AdhocQueryBuilder, AdhocQueryClient, AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthenticationError, AuthorizationError, AutocompleteBuilder, BaseValidationError, BatchBuilder, BatchClient, ConnectionError, ContentByIdBuilder, ContentClient, ContentQueryBuilder, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidFieldTypeError, InvalidPayloadError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, RequiredFieldError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, SchemaValidationError, SearchBuilder, SearchClient, ServerError, ServiceIndeterminateError, SettingsClient, SimilarBuilder, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, entityTagOf, isAssetEntry, isResourceNotFound, validateFile };
|
|
4374
|
-
//# sourceMappingURL=chunk-
|
|
4375
|
-
//# sourceMappingURL=chunk-
|
|
4766
|
+
export { AdhocQueryBuilder, AdhocQueryClient, AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthenticationError, AuthorizationError, AutocompleteBuilder, BaseValidationError, BatchBuilder, BatchClient, ChangesExpiredError, ConnectionError, ContentByIdBuilder, ContentClient, ContentQueryBuilder, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidFieldTypeError, InvalidPayloadError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, RequiredFieldError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, SchemaValidationError, SearchBuilder, SearchClient, ServerError, ServiceIndeterminateError, SettingsClient, SimilarBuilder, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, entityTagOf, isAssetEntry, isResourceNotFound, matchRoute, validateFile };
|
|
4767
|
+
//# sourceMappingURL=chunk-43VPZT2G.js.map
|
|
4768
|
+
//# sourceMappingURL=chunk-43VPZT2G.js.map
|