@relyio/sdk 0.14.0 → 0.16.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 +59 -0
- package/dist/chunk-7BZW6XYJ.cjs +433 -0
- package/dist/chunk-CQHEG7QA.js +411 -0
- package/dist/{chunk-PCFTJLEP.js → chunk-DIZY6CKM.js} +2 -2
- package/dist/{chunk-X4KSS7PP.cjs → chunk-GHYB6IZK.cjs} +2 -2
- package/dist/{chunk-DBBZVZOS.js → chunk-NIUOPIIB.js} +413 -552
- package/dist/{chunk-GUPV2M3X.cjs → chunk-RLLZUFDB.cjs} +450 -585
- package/dist/client/index.cjs +4 -3
- package/dist/client/index.d.cts +3 -4
- package/dist/client/index.d.ts +3 -4
- package/dist/client/index.js +2 -1
- package/dist/{define-content-type-DOrZb_a_.d.ts → define-content-type-CAWSlgn0.d.ts} +579 -81
- package/dist/{define-content-type-BUZeWtpk.d.cts → define-content-type-LkI0rS2W.d.cts} +579 -81
- package/dist/{define-schema-5aHmsA8j.d.ts → define-schema-Dxu3RoHV.d.ts} +1 -1
- package/dist/{define-schema-nCfZeboB.d.cts → define-schema-wlsJOrnY.d.cts} +1 -1
- package/dist/{index-DOhFQbv7.d.ts → index-BH8JksfG.d.ts} +472 -179
- package/dist/{index-B97ZDj44.d.ts → index-CGtYxUuh.d.ts} +1 -1
- package/dist/{index-C-pcllqY.d.cts → index-CcHmRALk.d.cts} +1 -1
- package/dist/{index-DgVV5Nj7.d.cts → index-D80MXUkf.d.cts} +472 -179
- package/dist/index.cjs +96 -71
- package/dist/index.d.cts +26 -16
- package/dist/index.d.ts +26 -16
- package/dist/index.js +4 -3
- package/dist/markdown/index.cjs +10 -2
- package/dist/markdown/index.d.cts +12 -3
- package/dist/markdown/index.d.ts +12 -3
- package/dist/markdown/index.js +10 -2
- package/dist/preview/index.cjs +29 -0
- package/dist/preview/index.d.cts +117 -0
- package/dist/preview/index.d.ts +117 -0
- package/dist/preview/index.js +4 -0
- package/dist/rich-text/index.d.cts +2 -2
- package/dist/rich-text/index.d.ts +2 -2
- package/dist/schema/index.cjs +33 -33
- package/dist/schema/index.d.cts +3 -3
- package/dist/schema/index.d.ts +3 -3
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +10 -4
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { parseDevEnv, DEV_CONTEXT_DIR, DEV_CONTEXT_FILENAME, parseDevContextFile } from './chunk-BBUB7C2Z.js';
|
|
2
|
+
import { VISITOR_CLOSE_CODES, HEADER_RETRY_AFTER, HEADER_IDEMPOTENCY_KEY, UNKNOWN_PREVIEW_RECHECK_MS, entityTag, HEADER_IF_MATCH, FRESH_PARAMETER, VISITOR_KEEPALIVE, parseVisitorFrame, VISITOR_FRAMES, VISITOR_POLL_INTERVAL_MS, VISITOR_CLOSE_RETRY, readVisitorPollAnswer, VISITOR_POLL_RETRY, VISITOR_LIVE_PATH, VISITOR_QUERY, previewAtRequest, previewDatasetSlug } from './chunk-CQHEG7QA.js';
|
|
2
3
|
import { isBrowser } from './chunk-H6IBQSMM.js';
|
|
3
4
|
import { __name, __publicField } from './chunk-XQ4QHWZE.js';
|
|
4
5
|
|
|
5
6
|
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
6
7
|
|
|
8
|
+
// src/config/key-kind.ts
|
|
9
|
+
var PUBLISHABLE_KEY_PREFIX = "rly_pub_";
|
|
10
|
+
var isPublishableKey = /* @__PURE__ */ __name((apiKey) => apiKey?.startsWith(PUBLISHABLE_KEY_PREFIX) === true, "isPublishableKey");
|
|
11
|
+
var PREVIEW_KEY_PREFIX = "rly_prev_";
|
|
12
|
+
var isPreviewKey = /* @__PURE__ */ __name((apiKey) => apiKey?.startsWith(PREVIEW_KEY_PREFIX) === true, "isPreviewKey");
|
|
13
|
+
|
|
7
14
|
// src/errors/sdk-error.ts
|
|
8
15
|
var _SDKError = class _SDKError extends Error {
|
|
9
16
|
constructor(message, statusCode, cause, context) {
|
|
@@ -57,19 +64,84 @@ var _SDKError = class _SDKError extends Error {
|
|
|
57
64
|
return this.code === errorType;
|
|
58
65
|
}
|
|
59
66
|
/**
|
|
60
|
-
* Create a
|
|
67
|
+
* Create a copy of this error with additional context.
|
|
68
|
+
*
|
|
69
|
+
* The copy is made from this error's own properties, not by calling a constructor: subclasses
|
|
70
|
+
* declare constructors of their own (violations, a timeout, a feature, a failed index second),
|
|
71
|
+
* and no single argument order fits them all. Rebuilding through the base order put the status
|
|
72
|
+
* code in the subclass's second slot. Copying keeps every field, the subclass's own included, and
|
|
73
|
+
* the original `timestamp` and `stack`, since it is the same failure.
|
|
74
|
+
*
|
|
75
|
+
* `Object.create` runs no constructor, so a `#private` field would not survive the copy; none
|
|
76
|
+
* exist in this directory. `stack` is not an own property on V8 and is copied by hand below.
|
|
61
77
|
*/
|
|
62
78
|
withContext(context) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
return Object.create(Object.getPrototypeOf(this), {
|
|
80
|
+
...Object.getOwnPropertyDescriptors(this),
|
|
81
|
+
stack: { value: this.stack, writable: true, enumerable: false, configurable: true },
|
|
82
|
+
context: {
|
|
83
|
+
value: { ...this.context, ...context },
|
|
84
|
+
writable: true,
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true
|
|
87
|
+
}
|
|
67
88
|
});
|
|
68
89
|
}
|
|
69
90
|
};
|
|
70
91
|
__name(_SDKError, "SDKError");
|
|
71
92
|
var SDKError = _SDKError;
|
|
72
93
|
|
|
94
|
+
// src/errors/content-errors.ts
|
|
95
|
+
var _ResourceNotFoundError = class _ResourceNotFoundError extends SDKError {
|
|
96
|
+
constructor(message = "Resource not found", statusCode = 404, cause, context) {
|
|
97
|
+
super(message, statusCode, cause, context);
|
|
98
|
+
__publicField(this, "code", "RESOURCE_NOT_FOUND");
|
|
99
|
+
__publicField(this, "retryable", false);
|
|
100
|
+
}
|
|
101
|
+
getUserMessage() {
|
|
102
|
+
const resourceType = this.context?.resourceType;
|
|
103
|
+
const resourceId = this.context?.resourceId;
|
|
104
|
+
if (resourceType != null && resourceId != null) {
|
|
105
|
+
return `${resourceType} with ID "${resourceId}" was not found.`;
|
|
106
|
+
}
|
|
107
|
+
return "The requested resource was not found.";
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
__name(_ResourceNotFoundError, "ResourceNotFoundError");
|
|
111
|
+
var ResourceNotFoundError = _ResourceNotFoundError;
|
|
112
|
+
var _ResourceConflictError = class _ResourceConflictError extends SDKError {
|
|
113
|
+
constructor(message = "Resource conflict", statusCode = 409, cause, context) {
|
|
114
|
+
super(message, statusCode, cause, context);
|
|
115
|
+
__publicField(this, "code", "RESOURCE_CONFLICT");
|
|
116
|
+
__publicField(this, "retryable", false);
|
|
117
|
+
}
|
|
118
|
+
getUserMessage() {
|
|
119
|
+
return "The resource could not be created or updated due to a conflict.";
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
__name(_ResourceConflictError, "ResourceConflictError");
|
|
123
|
+
var ResourceConflictError = _ResourceConflictError;
|
|
124
|
+
var _ResourceExpiredError = class _ResourceExpiredError extends SDKError {
|
|
125
|
+
constructor(message = "Resource has expired", statusCode = 410, cause, context) {
|
|
126
|
+
super(message, statusCode, cause, context);
|
|
127
|
+
__publicField(this, "code", "RESOURCE_EXPIRED");
|
|
128
|
+
__publicField(this, "retryable", false);
|
|
129
|
+
}
|
|
130
|
+
getUserMessage() {
|
|
131
|
+
return "The resource is no longer available.";
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
__name(_ResourceExpiredError, "ResourceExpiredError");
|
|
135
|
+
var ResourceExpiredError = _ResourceExpiredError;
|
|
136
|
+
function isResourceNotFound(error) {
|
|
137
|
+
return error instanceof ResourceNotFoundError;
|
|
138
|
+
}
|
|
139
|
+
__name(isResourceNotFound, "isResourceNotFound");
|
|
140
|
+
function isMissingEntry(error) {
|
|
141
|
+
return error instanceof ResourceNotFoundError && error.context?.resourceType === "entry";
|
|
142
|
+
}
|
|
143
|
+
__name(isMissingEntry, "isMissingEntry");
|
|
144
|
+
|
|
73
145
|
// src/errors/contract-errors.ts
|
|
74
146
|
var _MissingApiKeyError = class _MissingApiKeyError extends SDKError {
|
|
75
147
|
constructor(message = "No API key was sent", context) {
|
|
@@ -182,7 +254,7 @@ var _TransactionRolledBackError = class _TransactionRolledBackError extends SDKE
|
|
|
182
254
|
this.failedIndex = failedIndex;
|
|
183
255
|
}
|
|
184
256
|
getUserMessage() {
|
|
185
|
-
return this.failedIndex === void 0 ? "The batch was rolled back; nothing was written." : `The batch was rolled back
|
|
257
|
+
return this.failedIndex === void 0 ? "The batch was rolled back; nothing was written." : `The batch was rolled back; nothing was written. This refusal is for operation ${this.failedIndex} of the batch, which is not necessarily the one that failed.`;
|
|
186
258
|
}
|
|
187
259
|
};
|
|
188
260
|
__name(_TransactionRolledBackError, "TransactionRolledBackError");
|
|
@@ -256,57 +328,6 @@ var _InvalidApiKeyError = class _InvalidApiKeyError extends SDKError {
|
|
|
256
328
|
__name(_InvalidApiKeyError, "InvalidApiKeyError");
|
|
257
329
|
var InvalidApiKeyError = _InvalidApiKeyError;
|
|
258
330
|
|
|
259
|
-
// src/errors/content-errors.ts
|
|
260
|
-
var _ResourceNotFoundError = class _ResourceNotFoundError extends SDKError {
|
|
261
|
-
constructor(message = "Resource not found", statusCode = 404, cause, context) {
|
|
262
|
-
super(message, statusCode, cause, context);
|
|
263
|
-
__publicField(this, "code", "RESOURCE_NOT_FOUND");
|
|
264
|
-
__publicField(this, "retryable", false);
|
|
265
|
-
}
|
|
266
|
-
getUserMessage() {
|
|
267
|
-
const resourceType = this.context?.resourceType;
|
|
268
|
-
const resourceId = this.context?.resourceId;
|
|
269
|
-
if (resourceType != null && resourceId != null) {
|
|
270
|
-
return `${resourceType} with ID "${resourceId}" was not found.`;
|
|
271
|
-
}
|
|
272
|
-
return "The requested resource was not found.";
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
__name(_ResourceNotFoundError, "ResourceNotFoundError");
|
|
276
|
-
var ResourceNotFoundError = _ResourceNotFoundError;
|
|
277
|
-
var _ResourceConflictError = class _ResourceConflictError extends SDKError {
|
|
278
|
-
constructor(message = "Resource conflict", statusCode = 409, cause, context) {
|
|
279
|
-
super(message, statusCode, cause, context);
|
|
280
|
-
__publicField(this, "code", "RESOURCE_CONFLICT");
|
|
281
|
-
__publicField(this, "retryable", false);
|
|
282
|
-
}
|
|
283
|
-
getUserMessage() {
|
|
284
|
-
return "The resource could not be created or updated due to a conflict.";
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
__name(_ResourceConflictError, "ResourceConflictError");
|
|
288
|
-
var ResourceConflictError = _ResourceConflictError;
|
|
289
|
-
var _ResourceExpiredError = class _ResourceExpiredError extends SDKError {
|
|
290
|
-
constructor(message = "Resource has expired", statusCode = 410, cause, context) {
|
|
291
|
-
super(message, statusCode, cause, context);
|
|
292
|
-
__publicField(this, "code", "RESOURCE_EXPIRED");
|
|
293
|
-
__publicField(this, "retryable", false);
|
|
294
|
-
}
|
|
295
|
-
getUserMessage() {
|
|
296
|
-
return "The resource is no longer available.";
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
__name(_ResourceExpiredError, "ResourceExpiredError");
|
|
300
|
-
var ResourceExpiredError = _ResourceExpiredError;
|
|
301
|
-
function isResourceNotFound(error) {
|
|
302
|
-
return error instanceof ResourceNotFoundError;
|
|
303
|
-
}
|
|
304
|
-
__name(isResourceNotFound, "isResourceNotFound");
|
|
305
|
-
function isMissingEntry(error) {
|
|
306
|
-
return error instanceof ResourceNotFoundError && error.context?.resourceType === "entry";
|
|
307
|
-
}
|
|
308
|
-
__name(isMissingEntry, "isMissingEntry");
|
|
309
|
-
|
|
310
331
|
// src/errors/network-errors.ts
|
|
311
332
|
var _NetworkError = class _NetworkError extends SDKError {
|
|
312
333
|
constructor(message = "Network request failed", statusCode, cause, context) {
|
|
@@ -414,229 +435,6 @@ var _InvalidPayloadError = class _InvalidPayloadError extends BaseValidationErro
|
|
|
414
435
|
__name(_InvalidPayloadError, "InvalidPayloadError");
|
|
415
436
|
var InvalidPayloadError = _InvalidPayloadError;
|
|
416
437
|
|
|
417
|
-
// ../../platform/api-contract/dist/chunk-46347LG2.js
|
|
418
|
-
function defineRoute(route) {
|
|
419
|
-
if (route.kind === "raw" && route.standardShape === void 0) {
|
|
420
|
-
throw new Error("kind 'raw' requires a named StandardShape");
|
|
421
|
-
}
|
|
422
|
-
if (route.kind === "raw" && route.success === 302 && !route.headers.some((header) => header.name === "Location")) {
|
|
423
|
-
throw new Error("a raw route declaring success 302 must declare its 'Location' header");
|
|
424
|
-
}
|
|
425
|
-
if (route.kind === "stream" && route.stream === void 0) {
|
|
426
|
-
throw new Error("kind 'stream' requires a StreamDeclaration");
|
|
427
|
-
}
|
|
428
|
-
if (route.kind === "collection" && route.page === void 0) {
|
|
429
|
-
throw new Error("kind 'collection' requires a page dialect");
|
|
430
|
-
}
|
|
431
|
-
if (route.queues === true) {
|
|
432
|
-
if (route.kind !== "object" && route.kind !== "empty") {
|
|
433
|
-
throw new Error(
|
|
434
|
-
`kind '${route.kind}' cannot declare \`queues\`: only an object or empty route answers 202 beside its own status`
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
if (route.kind === "object" && route.success === 202) {
|
|
438
|
-
throw new Error("a route whose own status is 202 cannot also declare `queues`");
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
if ((route.kind === "object" || route.kind === "collection") && route.negotiated !== void 0) {
|
|
442
|
-
refuseMismatchedAlternate(route, route.negotiated["text/event-stream"]);
|
|
443
|
-
}
|
|
444
|
-
return route;
|
|
445
|
-
}
|
|
446
|
-
__name(defineRoute, "defineRoute");
|
|
447
|
-
function refuseMismatchedAlternate(route, stream) {
|
|
448
|
-
if (stream.kind !== "stream") {
|
|
449
|
-
throw new Error("a negotiated 'text/event-stream' alternate must be kind 'stream'");
|
|
450
|
-
}
|
|
451
|
-
if (stream.stream.mediaType !== "text/event-stream") {
|
|
452
|
-
throw new Error(
|
|
453
|
-
`a negotiated 'text/event-stream' alternate declares media type "${stream.stream.mediaType}"`
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
const own = [...new Set(route.codes)].sort();
|
|
457
|
-
const alternate = [...new Set(stream.codes)].sort();
|
|
458
|
-
if (own.length !== alternate.length || own.some((code, index) => code !== alternate[index])) {
|
|
459
|
-
throw new Error(
|
|
460
|
-
`a negotiated alternate refuses with [${alternate.join(", ")}] while its route refuses with [${own.join(", ")}]; one route refuses with one set of codes on every transport`
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
__name(refuseMismatchedAlternate, "refuseMismatchedAlternate");
|
|
465
|
-
|
|
466
|
-
// ../../platform/api-contract/dist/index.js
|
|
467
|
-
var HEADER_RETRY_AFTER = { name: "Retry-After" };
|
|
468
|
-
var HEADER_IF_MATCH = {
|
|
469
|
-
name: "If-Match"};
|
|
470
|
-
function entityTag(parts) {
|
|
471
|
-
return `"${parts.entryUid}:${parts.locale}:${parts.version}:${parts.sharedVersion}"`;
|
|
472
|
-
}
|
|
473
|
-
__name(entityTag, "entityTag");
|
|
474
|
-
var HEADER_IDEMPOTENCY_KEY = {
|
|
475
|
-
name: "Idempotency-Key"};
|
|
476
|
-
var FRESH_PARAMETER = "_fresh";
|
|
477
|
-
var VISITOR_LIVE_PATH = "/visitor/changes";
|
|
478
|
-
var VISITOR_QUERY = {
|
|
479
|
-
/** The publishable key. */
|
|
480
|
-
key: "key",
|
|
481
|
-
/** A dataset id or name the key reaches; absent, the key's default dataset. */
|
|
482
|
-
dataset: "dataset",
|
|
483
|
-
/** The cursor to continue from; absent, the socket starts now. */
|
|
484
|
-
since: "since",
|
|
485
|
-
/** Comma-separated content types to keep; absent keeps every type. */
|
|
486
|
-
types: "types",
|
|
487
|
-
/** Comma-separated entry ids to keep; absent keeps every entry. */
|
|
488
|
-
ids: "ids",
|
|
489
|
-
/** The poll's client id. Required on a poll, and not read on a socket. */
|
|
490
|
-
client: "client"
|
|
491
|
-
};
|
|
492
|
-
var VISITOR_CURSOR = /^[\w.~-]{1,256}$/;
|
|
493
|
-
var VISITOR_POLL_INTERVAL_MS = 15e3;
|
|
494
|
-
var VISITOR_KEEPALIVE = { request: "ping", response: "pong" };
|
|
495
|
-
var VISITOR_FRAMES = {
|
|
496
|
-
opened: "feed.opened",
|
|
497
|
-
changes: "feed.changes",
|
|
498
|
-
resync: "feed.resync"
|
|
499
|
-
};
|
|
500
|
-
defineRoute({
|
|
501
|
-
kind: "object",
|
|
502
|
-
headers: [HEADER_RETRY_AFTER],
|
|
503
|
-
codes: [
|
|
504
|
-
"REQUEST_INVALID",
|
|
505
|
-
"MISSING_API_KEY",
|
|
506
|
-
"INVALID_API_KEY",
|
|
507
|
-
"ACCESS_DENIED",
|
|
508
|
-
"METHOD_NOT_ALLOWED",
|
|
509
|
-
"SERVICE_INDETERMINATE",
|
|
510
|
-
"USAGE_QUOTA_EXCEEDED",
|
|
511
|
-
"RATE_LIMIT_EXCEEDED"
|
|
512
|
-
]
|
|
513
|
-
});
|
|
514
|
-
var VISITOR_CLOSE_CODES = {
|
|
515
|
-
/** A query the door cannot read: a malformed `since`, filter, `dataset` or `client`. */
|
|
516
|
-
requestInvalid: 4400,
|
|
517
|
-
/** No publishable key, or one that is unknown, revoked, expired, a secret key or a preview key. */
|
|
518
|
-
keyRefused: 4401,
|
|
519
|
-
/** The page's `Origin` is absent, or not on the key's allowed origins. */
|
|
520
|
-
originRefused: 4403,
|
|
521
|
-
/** `dataset` names nothing the key reaches. */
|
|
522
|
-
datasetRefused: 4404,
|
|
523
|
-
/** The key's scope, the project's counter or the feed could not be reached just now. */
|
|
524
|
-
unavailable: 1013,
|
|
525
|
-
/**
|
|
526
|
-
* The project holds as many visitor connections as its plan allows — Starter's 100 — or its
|
|
527
|
-
* Organization is suspended. As HTTP's 402: more needs a bigger plan, or visitors leaving.
|
|
528
|
-
*/
|
|
529
|
-
allowanceReached: 4402,
|
|
530
|
-
/** This client's address holds as many connections to the project as one address may. */
|
|
531
|
-
addressLimitReached: 4429,
|
|
532
|
-
/** The project is at its per-project safety ceiling — Pro's 50,000 — whatever it would pay for. */
|
|
533
|
-
ceilingReached: 4503
|
|
534
|
-
};
|
|
535
|
-
var VISITOR_CLOSE_RETRY = {
|
|
536
|
-
4400: "stop",
|
|
537
|
-
4401: "stop",
|
|
538
|
-
4403: "stop",
|
|
539
|
-
4404: "stop",
|
|
540
|
-
1013: "retry",
|
|
541
|
-
4402: "back-off",
|
|
542
|
-
4429: "back-off",
|
|
543
|
-
4503: "back-off"
|
|
544
|
-
};
|
|
545
|
-
var VISITOR_POLL_RETRY = {
|
|
546
|
-
REQUEST_INVALID: "stop",
|
|
547
|
-
MISSING_API_KEY: "stop",
|
|
548
|
-
INVALID_API_KEY: "stop",
|
|
549
|
-
ACCESS_DENIED: "stop",
|
|
550
|
-
METHOD_NOT_ALLOWED: "stop",
|
|
551
|
-
SERVICE_INDETERMINATE: "retry",
|
|
552
|
-
USAGE_QUOTA_EXCEEDED: "back-off",
|
|
553
|
-
RATE_LIMIT_EXCEEDED: "back-off"
|
|
554
|
-
};
|
|
555
|
-
var VISITOR_ADMISSION_RETRY_AFTER_SECONDS = 60;
|
|
556
|
-
function parseVisitorFrame(text) {
|
|
557
|
-
let value;
|
|
558
|
-
try {
|
|
559
|
-
value = JSON.parse(text);
|
|
560
|
-
} catch {
|
|
561
|
-
return null;
|
|
562
|
-
}
|
|
563
|
-
if (!isRecord2(value) || !isCursor(value.cursor)) return null;
|
|
564
|
-
switch (value.type) {
|
|
565
|
-
case VISITOR_FRAMES.opened: {
|
|
566
|
-
return hasOnly(value, ["type", "cursor"]) ? { type: VISITOR_FRAMES.opened, cursor: value.cursor } : null;
|
|
567
|
-
}
|
|
568
|
-
case VISITOR_FRAMES.changes: {
|
|
569
|
-
const changes = hasOnly(value, ["type", "changes", "cursor"]) ? readVisitorChanges(value.changes) : null;
|
|
570
|
-
return changes === null ? null : { type: VISITOR_FRAMES.changes, changes, cursor: value.cursor };
|
|
571
|
-
}
|
|
572
|
-
case VISITOR_FRAMES.resync: {
|
|
573
|
-
return hasOnly(value, ["type", "reason", "cursor"]) && isResyncReason(value.reason) ? { type: VISITOR_FRAMES.resync, reason: value.reason, cursor: value.cursor } : null;
|
|
574
|
-
}
|
|
575
|
-
default: {
|
|
576
|
-
return null;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
__name(parseVisitorFrame, "parseVisitorFrame");
|
|
581
|
-
function readVisitorPollAnswer(value) {
|
|
582
|
-
if (!isRecord2(value) || !isCursor(value.cursor)) return null;
|
|
583
|
-
if (value.kind === "resync") {
|
|
584
|
-
return hasOnly(value, ["kind", "reason", "cursor"]) && isResyncReason(value.reason) ? { kind: "resync", reason: value.reason, cursor: value.cursor } : null;
|
|
585
|
-
}
|
|
586
|
-
if (value.kind !== "changes" || !hasOnly(value, ["kind", "changes", "cursor"])) return null;
|
|
587
|
-
const changes = readVisitorChanges(value.changes);
|
|
588
|
-
return changes === null ? null : { kind: "changes", changes, cursor: value.cursor };
|
|
589
|
-
}
|
|
590
|
-
__name(readVisitorPollAnswer, "readVisitorPollAnswer");
|
|
591
|
-
var CHANGE_KINDS = /* @__PURE__ */ new Set([
|
|
592
|
-
"published",
|
|
593
|
-
"updated",
|
|
594
|
-
"unpublished",
|
|
595
|
-
"deleted"
|
|
596
|
-
]);
|
|
597
|
-
var RESYNC_REASONS = /* @__PURE__ */ new Set([
|
|
598
|
-
"retention",
|
|
599
|
-
"dataset-replaced",
|
|
600
|
-
"ahead-of-head",
|
|
601
|
-
"foreign-cursor",
|
|
602
|
-
"too-far-behind"
|
|
603
|
-
]);
|
|
604
|
-
function isResyncReason(value) {
|
|
605
|
-
return typeof value === "string" && RESYNC_REASONS.has(value);
|
|
606
|
-
}
|
|
607
|
-
__name(isResyncReason, "isResyncReason");
|
|
608
|
-
function readVisitorChanges(value) {
|
|
609
|
-
if (!Array.isArray(value)) return null;
|
|
610
|
-
const changes = [];
|
|
611
|
-
for (const item of value) {
|
|
612
|
-
if (!isRecord2(item) || !hasOnly(item, ["entryId", "contentType", "locale", "kind"])) return null;
|
|
613
|
-
const { entryId, contentType, locale, kind } = item;
|
|
614
|
-
if (!isNonEmptyString2(entryId) || !isNonEmptyString2(contentType)) return null;
|
|
615
|
-
if (locale !== null && typeof locale !== "string") return null;
|
|
616
|
-
if (typeof kind !== "string" || !CHANGE_KINDS.has(kind)) return null;
|
|
617
|
-
changes.push({ entryId, contentType, locale, kind });
|
|
618
|
-
}
|
|
619
|
-
return changes;
|
|
620
|
-
}
|
|
621
|
-
__name(readVisitorChanges, "readVisitorChanges");
|
|
622
|
-
function isCursor(value) {
|
|
623
|
-
return typeof value === "string" && VISITOR_CURSOR.test(value);
|
|
624
|
-
}
|
|
625
|
-
__name(isCursor, "isCursor");
|
|
626
|
-
function isRecord2(value) {
|
|
627
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
628
|
-
}
|
|
629
|
-
__name(isRecord2, "isRecord2");
|
|
630
|
-
function isNonEmptyString2(value) {
|
|
631
|
-
return typeof value === "string" && value.length > 0;
|
|
632
|
-
}
|
|
633
|
-
__name(isNonEmptyString2, "isNonEmptyString2");
|
|
634
|
-
function hasOnly(value, keys) {
|
|
635
|
-
const present = Object.keys(value);
|
|
636
|
-
return present.length === keys.length && present.every((key) => keys.includes(key));
|
|
637
|
-
}
|
|
638
|
-
__name(hasOnly, "hasOnly");
|
|
639
|
-
|
|
640
438
|
// ../../platform/api-contract/dist/client/index.js
|
|
641
439
|
var _a;
|
|
642
440
|
var ContractBodyError = (_a = class extends Error {
|
|
@@ -774,9 +572,13 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
774
572
|
}
|
|
775
573
|
case "RESOURCE_CONFLICT": {
|
|
776
574
|
const expectedVersion = detailNumber(refusal, "expectedVersion");
|
|
777
|
-
const
|
|
575
|
+
const blockage = blockageOf(refusal);
|
|
576
|
+
const guidance = blockage !== void 0 || expectedVersion === void 0 ? message : `${message.endsWith(".") ? message : `${message}.`} ${STALE_VERSION_GUIDANCE}`;
|
|
778
577
|
return new ResourceConflictError(guidance, 409, void 0, {
|
|
779
578
|
...context,
|
|
579
|
+
// What stands in the way, as a declared kind a program switches on: `draft-exists`,
|
|
580
|
+
// `release-locked` or `slug-taken` from the Content API (REL-2446).
|
|
581
|
+
blockage,
|
|
780
582
|
expectedVersion,
|
|
781
583
|
actualVersion: detailNumber(refusal, "actualVersion"),
|
|
782
584
|
// The shared fields' counter, which the `If-Match` tag carries beside the locale's and a
|
|
@@ -786,7 +588,10 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
786
588
|
});
|
|
787
589
|
}
|
|
788
590
|
case "RESOURCE_EXPIRED": {
|
|
789
|
-
return new ResourceExpiredError(message, 410, void 0,
|
|
591
|
+
return new ResourceExpiredError(message, 410, void 0, {
|
|
592
|
+
...context,
|
|
593
|
+
reason: detailString(refusal, "reason")
|
|
594
|
+
});
|
|
790
595
|
}
|
|
791
596
|
case "REQUEST_TIMEOUT": {
|
|
792
597
|
return new TimeoutError(message, void 0, status, void 0, context);
|
|
@@ -873,6 +678,15 @@ function detailNumber(refusal, key) {
|
|
|
873
678
|
return typeof value === "number" ? value : void 0;
|
|
874
679
|
}
|
|
875
680
|
__name(detailNumber, "detailNumber");
|
|
681
|
+
function blockageOf(refusal) {
|
|
682
|
+
const blockage = detailBag(refusal)?.blockage;
|
|
683
|
+
if (typeof blockage !== "object" || blockage === null) return void 0;
|
|
684
|
+
const { kind, facts } = blockage;
|
|
685
|
+
if (typeof kind !== "string") return void 0;
|
|
686
|
+
const named = typeof facts === "object" && facts !== null && !Array.isArray(facts) ? facts : {};
|
|
687
|
+
return { kind, facts: named };
|
|
688
|
+
}
|
|
689
|
+
__name(blockageOf, "blockageOf");
|
|
876
690
|
function violationsOf(refusal) {
|
|
877
691
|
const issues = detailBag(refusal)?.issues;
|
|
878
692
|
if (!Array.isArray(issues)) return [];
|
|
@@ -932,6 +746,7 @@ var DECLARED_PATHS = {
|
|
|
932
746
|
"/v1/{contentType}/{id}/file/multipart/sign-part": true,
|
|
933
747
|
"/v1/{contentType}/{id}/file/presign": true,
|
|
934
748
|
"/v1/{contentType}/{id}/file/url": true,
|
|
749
|
+
"/v1/{contentType}/{id}/shared-versions/{versionNumber}/restore": true,
|
|
935
750
|
"/v1/{contentType}/{id}/versions": true,
|
|
936
751
|
"/v1/{contentType}/{id}/versions/{versionNumber}": true,
|
|
937
752
|
"/v1/{contentType}/{id}/versions/{versionNumber}/restore": true,
|
|
@@ -1016,42 +831,6 @@ function readQuery(searchParams) {
|
|
|
1016
831
|
}
|
|
1017
832
|
__name(readQuery, "readQuery");
|
|
1018
833
|
|
|
1019
|
-
// src/http/abortable-sleep.ts
|
|
1020
|
-
function sleep(ms, signal) {
|
|
1021
|
-
return new Promise((resolve) => {
|
|
1022
|
-
if (isAborted(signal)) {
|
|
1023
|
-
resolve();
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
const done = /* @__PURE__ */ __name(() => {
|
|
1027
|
-
clearTimeout(timer);
|
|
1028
|
-
signal?.removeEventListener("abort", done);
|
|
1029
|
-
resolve();
|
|
1030
|
-
}, "done");
|
|
1031
|
-
const timer = setTimeout(done, ms);
|
|
1032
|
-
signal?.addEventListener("abort", done, { once: true });
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
__name(sleep, "sleep");
|
|
1036
|
-
function isAborted(signal) {
|
|
1037
|
-
return signal?.aborted === true;
|
|
1038
|
-
}
|
|
1039
|
-
__name(isAborted, "isAborted");
|
|
1040
|
-
|
|
1041
|
-
// src/http/request-timeout.ts
|
|
1042
|
-
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
1043
|
-
function isTimerDelay(value) {
|
|
1044
|
-
return typeof value === "number" && value >= 1 && value <= MAX_TIMER_DELAY_MS;
|
|
1045
|
-
}
|
|
1046
|
-
__name(isTimerDelay, "isTimerDelay");
|
|
1047
|
-
function assertRequestTimeout(timeout) {
|
|
1048
|
-
if (isTimerDelay(timeout)) return;
|
|
1049
|
-
throw new Error(
|
|
1050
|
-
`timeout must be a number of milliseconds from 1 to ${MAX_TIMER_DELAY_MS} \u2014 a timer given 0, NaN, Infinity or more fires at once and ends every request \u2014 and got ${String(timeout)}`
|
|
1051
|
-
);
|
|
1052
|
-
}
|
|
1053
|
-
__name(assertRequestTimeout, "assertRequestTimeout");
|
|
1054
|
-
|
|
1055
834
|
// src/errors/instructed-delay.ts
|
|
1056
835
|
function serviceInstructedDelayMs(error, nowMs) {
|
|
1057
836
|
if (error instanceof ServiceIndeterminateError) {
|
|
@@ -1081,6 +860,17 @@ function isReplaySafe(request) {
|
|
|
1081
860
|
return headerValue(request.headers, HEADER_IDEMPOTENCY_KEY.name) !== void 0;
|
|
1082
861
|
}
|
|
1083
862
|
__name(isReplaySafe, "isReplaySafe");
|
|
863
|
+
var UNREACHABLE_CODES = /* @__PURE__ */ new Set(["ECONNREFUSED", "ENOTFOUND"]);
|
|
864
|
+
function isUnreachableHost(error, depth = 0) {
|
|
865
|
+
if (depth > 4 || typeof error !== "object" || error === null) return false;
|
|
866
|
+
const { code, cause, errors } = error;
|
|
867
|
+
if (typeof code === "string" && UNREACHABLE_CODES.has(code)) return true;
|
|
868
|
+
if (Array.isArray(errors) && errors.length > 0) {
|
|
869
|
+
if (errors.every((one) => isUnreachableHost(one, depth + 1))) return true;
|
|
870
|
+
}
|
|
871
|
+
return isUnreachableHost(cause, depth + 1);
|
|
872
|
+
}
|
|
873
|
+
__name(isUnreachableHost, "isUnreachableHost");
|
|
1084
874
|
var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
1085
875
|
constructor(config) {
|
|
1086
876
|
__publicField(this, "config");
|
|
@@ -1089,6 +879,7 @@ var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
|
1089
879
|
shouldRetry(attempt, error, request) {
|
|
1090
880
|
if (attempt >= this.config.maxAttempts) return false;
|
|
1091
881
|
if (!ErrorMapper.isRetryable(error)) return false;
|
|
882
|
+
if (isUnreachableHost(error)) return false;
|
|
1092
883
|
return isReplaySafe(request);
|
|
1093
884
|
}
|
|
1094
885
|
delayFor(attempt, error) {
|
|
@@ -1101,6 +892,86 @@ var _DefaultRetryPolicy = class _DefaultRetryPolicy {
|
|
|
1101
892
|
};
|
|
1102
893
|
__name(_DefaultRetryPolicy, "DefaultRetryPolicy");
|
|
1103
894
|
var DefaultRetryPolicy = _DefaultRetryPolicy;
|
|
895
|
+
function retryPolicyFor(maxAttempts) {
|
|
896
|
+
return new DefaultRetryPolicy({
|
|
897
|
+
maxAttempts,
|
|
898
|
+
baseDelay: 1e3,
|
|
899
|
+
maxDelay: 1e4,
|
|
900
|
+
backoffFactor: 2,
|
|
901
|
+
jitter: true
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
__name(retryPolicyFor, "retryPolicyFor");
|
|
905
|
+
|
|
906
|
+
// src/config/preview-read.ts
|
|
907
|
+
var derived = /* @__PURE__ */ new Set();
|
|
908
|
+
var unknown = /* @__PURE__ */ new Map();
|
|
909
|
+
var announced = /* @__PURE__ */ new Set();
|
|
910
|
+
function noteDerivedPreview(dataset) {
|
|
911
|
+
derived.add(dataset);
|
|
912
|
+
}
|
|
913
|
+
__name(noteDerivedPreview, "noteDerivedPreview");
|
|
914
|
+
function isDerivedPreview(dataset) {
|
|
915
|
+
return derived.has(dataset);
|
|
916
|
+
}
|
|
917
|
+
__name(isDerivedPreview, "isDerivedPreview");
|
|
918
|
+
function isUnknownPreview(dataset) {
|
|
919
|
+
const since = unknown.get(dataset);
|
|
920
|
+
if (since === void 0) return false;
|
|
921
|
+
if (Date.now() - since < UNKNOWN_PREVIEW_RECHECK_MS) return true;
|
|
922
|
+
unknown.delete(dataset);
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
__name(isUnknownPreview, "isUnknownPreview");
|
|
926
|
+
function rememberUnknownPreview(dataset) {
|
|
927
|
+
unknown.set(dataset, Date.now());
|
|
928
|
+
if (announced.has(dataset)) return;
|
|
929
|
+
announced.add(dataset);
|
|
930
|
+
console.info(
|
|
931
|
+
`[RelyIO] No preview dataset "${dataset}" exists for this deployment's branch \u2014 reading the key's default dataset instead, and asking again in a minute.`
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
__name(rememberUnknownPreview, "rememberUnknownPreview");
|
|
935
|
+
function answersUnknownDataset(error, dataset) {
|
|
936
|
+
return error instanceof ResourceNotFoundError && error.context?.resourceType === "dataset" && error.context.resourceId === dataset;
|
|
937
|
+
}
|
|
938
|
+
__name(answersUnknownDataset, "answersUnknownDataset");
|
|
939
|
+
|
|
940
|
+
// src/http/abortable-sleep.ts
|
|
941
|
+
function sleep(ms, signal) {
|
|
942
|
+
return new Promise((resolve) => {
|
|
943
|
+
if (isAborted(signal)) {
|
|
944
|
+
resolve();
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
const done = /* @__PURE__ */ __name(() => {
|
|
948
|
+
clearTimeout(timer);
|
|
949
|
+
signal?.removeEventListener("abort", done);
|
|
950
|
+
resolve();
|
|
951
|
+
}, "done");
|
|
952
|
+
const timer = setTimeout(done, ms);
|
|
953
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
__name(sleep, "sleep");
|
|
957
|
+
function isAborted(signal) {
|
|
958
|
+
return signal?.aborted === true;
|
|
959
|
+
}
|
|
960
|
+
__name(isAborted, "isAborted");
|
|
961
|
+
|
|
962
|
+
// src/http/request-timeout.ts
|
|
963
|
+
var MAX_TIMER_DELAY_MS = 2147483647;
|
|
964
|
+
function isTimerDelay(value) {
|
|
965
|
+
return typeof value === "number" && value >= 1 && value <= MAX_TIMER_DELAY_MS;
|
|
966
|
+
}
|
|
967
|
+
__name(isTimerDelay, "isTimerDelay");
|
|
968
|
+
function assertRequestTimeout(timeout) {
|
|
969
|
+
if (isTimerDelay(timeout)) return;
|
|
970
|
+
throw new Error(
|
|
971
|
+
`timeout must be a number of milliseconds from 1 to ${MAX_TIMER_DELAY_MS} \u2014 a timer given 0, NaN, Infinity or more fires at once and ends every request \u2014 and got ${String(timeout)}`
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
__name(assertRequestTimeout, "assertRequestTimeout");
|
|
1104
975
|
|
|
1105
976
|
// src/http/http-client.ts
|
|
1106
977
|
var _HttpClient = class _HttpClient {
|
|
@@ -1116,33 +987,6 @@ var _HttpClient = class _HttpClient {
|
|
|
1116
987
|
this.connection = connectionFor(config);
|
|
1117
988
|
this.announce();
|
|
1118
989
|
}
|
|
1119
|
-
/**
|
|
1120
|
-
* A view of this client that sends every request through it with `headers` added — beneath the
|
|
1121
|
-
* request's own, over this client's — and changes nothing else: its key, base URL, timeout,
|
|
1122
|
-
* retries and `fetch` are this client's as they are when each request is sent, so a later
|
|
1123
|
-
* `configure()` or `setApiKey()` on this client reaches the view, and one on the view reaches
|
|
1124
|
-
* this client. `client.with({ dataset })` is one (REL-2417).
|
|
1125
|
-
*/
|
|
1126
|
-
withHeaders(headers) {
|
|
1127
|
-
const view = new _HttpClient(this.connection.config);
|
|
1128
|
-
view.view = { client: this, headers: { ...headers } };
|
|
1129
|
-
return view;
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Run on `config` from now on: every later request — whoever holds this client — is sent to its
|
|
1133
|
-
* `baseUrl`, with its headers, key and dataset, its timeout and retries, through its `fetch`, and
|
|
1134
|
-
* logged by its `debug` options.
|
|
1135
|
-
*
|
|
1136
|
-
* The client's own `updateConfig()` calls this rather than building a second client, so a
|
|
1137
|
-
* `content()` or other sub-client taken before the update sends through the update too. Anything
|
|
1138
|
-
* set on this client since it was last configured — `setDefaultHeaders()`, `setBaseUrl()` — is
|
|
1139
|
-
* replaced by what `config` says.
|
|
1140
|
-
*/
|
|
1141
|
-
configure(config) {
|
|
1142
|
-
if (this.view !== void 0) return this.view.client.configure(config);
|
|
1143
|
-
this.connection = connectionFor(config);
|
|
1144
|
-
this.announce();
|
|
1145
|
-
}
|
|
1146
990
|
announce() {
|
|
1147
991
|
this.log("debug", "HttpClient initialized", {
|
|
1148
992
|
baseUrl: this.connection.baseUrl,
|
|
@@ -1151,6 +995,20 @@ var _HttpClient = class _HttpClient {
|
|
|
1151
995
|
environment: isBrowser() ? "browser" : "node"
|
|
1152
996
|
});
|
|
1153
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Send bytes to an address that is not a RelyIO route — an asset upload's presigned `PUT` and its
|
|
1000
|
+
* multipart parts — through the client's configured `fetch`, so a wrapper that records, proxies or
|
|
1001
|
+
* forbids network access sees every request this client makes (REL-2671). Nothing else is added: no
|
|
1002
|
+
* key, no retry, no timeout, because the address belongs to the storage service, not to RelyIO.
|
|
1003
|
+
*
|
|
1004
|
+
* Static so the instances a customer holds stay `send` and `fetchPayload` (REL-3107). The `fetch`
|
|
1005
|
+
* is read per call, from the client a view sends through, like the requests are.
|
|
1006
|
+
*/
|
|
1007
|
+
static transfer(client, url, init) {
|
|
1008
|
+
const owner = client.view?.client ?? client;
|
|
1009
|
+
const send = owner.connection.config.fetch ?? globalThis.fetch;
|
|
1010
|
+
return send(url, init);
|
|
1011
|
+
}
|
|
1154
1012
|
/**
|
|
1155
1013
|
* Call a route the committed document declares, and get back the body that
|
|
1156
1014
|
* document says it serves.
|
|
@@ -1220,6 +1078,11 @@ var _HttpClient = class _HttpClient {
|
|
|
1220
1078
|
if (config.method === "DELETE" && mergedConfig.headers) {
|
|
1221
1079
|
mergedConfig.headers = layerHeaders(mergedConfig.headers, { "Content-Type": null });
|
|
1222
1080
|
}
|
|
1081
|
+
let preview = derivedPreviewIn(mergedConfig.headers);
|
|
1082
|
+
if (preview !== void 0 && (isUnknownPreview(preview) || !isPreviewKey(headerValue(mergedConfig.headers, API_KEY_HEADER)))) {
|
|
1083
|
+
mergedConfig.headers = layerHeaders(mergedConfig.headers ?? {}, { [DATASET_HEADER]: null });
|
|
1084
|
+
preview = void 0;
|
|
1085
|
+
}
|
|
1223
1086
|
for (let attempt = 1; ; attempt++) {
|
|
1224
1087
|
try {
|
|
1225
1088
|
const response = await this.makeRequest(mergedConfig.url, mergedConfig);
|
|
@@ -1248,6 +1111,10 @@ var _HttpClient = class _HttpClient {
|
|
|
1248
1111
|
method: mergedConfig.method,
|
|
1249
1112
|
attempt
|
|
1250
1113
|
});
|
|
1114
|
+
if (preview !== void 0 && answersUnknownDataset(sdkError, preview)) {
|
|
1115
|
+
rememberUnknownPreview(preview);
|
|
1116
|
+
return this.request(config);
|
|
1117
|
+
}
|
|
1251
1118
|
this.log("error", "Request failed after all retries", {
|
|
1252
1119
|
error: sdkError.toJSON(),
|
|
1253
1120
|
url: mergedConfig.url
|
|
@@ -1256,122 +1123,6 @@ var _HttpClient = class _HttpClient {
|
|
|
1256
1123
|
}
|
|
1257
1124
|
}
|
|
1258
1125
|
}
|
|
1259
|
-
/**
|
|
1260
|
-
* Make a GET request
|
|
1261
|
-
*/
|
|
1262
|
-
async get(url, params) {
|
|
1263
|
-
return this.request({
|
|
1264
|
-
method: "GET",
|
|
1265
|
-
url,
|
|
1266
|
-
params
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
/**
|
|
1270
|
-
* Make a POST request
|
|
1271
|
-
*/
|
|
1272
|
-
async post(url, data, params) {
|
|
1273
|
-
return this.request({
|
|
1274
|
-
method: "POST",
|
|
1275
|
-
url,
|
|
1276
|
-
body: data,
|
|
1277
|
-
params
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Make a PUT request
|
|
1282
|
-
*/
|
|
1283
|
-
async put(url, data, params) {
|
|
1284
|
-
return this.request({
|
|
1285
|
-
method: "PUT",
|
|
1286
|
-
url,
|
|
1287
|
-
body: data,
|
|
1288
|
-
params
|
|
1289
|
-
});
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* Make a DELETE request
|
|
1293
|
-
*/
|
|
1294
|
-
async delete(url, params) {
|
|
1295
|
-
return this.request({
|
|
1296
|
-
method: "DELETE",
|
|
1297
|
-
url,
|
|
1298
|
-
params
|
|
1299
|
-
});
|
|
1300
|
-
}
|
|
1301
|
-
/**
|
|
1302
|
-
* Make a PATCH request
|
|
1303
|
-
*/
|
|
1304
|
-
async patch(url, data, params) {
|
|
1305
|
-
return this.request({
|
|
1306
|
-
method: "PATCH",
|
|
1307
|
-
url,
|
|
1308
|
-
body: data,
|
|
1309
|
-
params
|
|
1310
|
-
});
|
|
1311
|
-
}
|
|
1312
|
-
/**
|
|
1313
|
-
* Add headers to every later request, each replacing any header of the same name — the name
|
|
1314
|
-
* matched without regard to case — until the client is next configured.
|
|
1315
|
-
*/
|
|
1316
|
-
setDefaultHeaders(headers) {
|
|
1317
|
-
if (this.view !== void 0) return this.view.client.setDefaultHeaders(headers);
|
|
1318
|
-
this.connection = {
|
|
1319
|
-
...this.connection,
|
|
1320
|
-
defaultHeaders: layerHeaders(this.connection.defaultHeaders, headers)
|
|
1321
|
-
};
|
|
1322
|
-
}
|
|
1323
|
-
/**
|
|
1324
|
-
* Replace the key every later request sends as `X-API-Key`, and the `apiKey` the configuration
|
|
1325
|
-
* reports.
|
|
1326
|
-
*
|
|
1327
|
-
* The key is read the way construction reads it (`presentKey`): an absent, empty or blank key is
|
|
1328
|
-
* no key, so the header is dropped and the next request is refused with `MissingApiKeyError`
|
|
1329
|
-
* before anything is sent. A key header of any other spelling — one given in `headers` — goes
|
|
1330
|
-
* too, from the headers sent and from the headers the configuration reports, so the old key is
|
|
1331
|
-
* never sent beside the new one.
|
|
1332
|
-
*
|
|
1333
|
-
* The configuration is the one the owning `TypedRelyIOClient` holds (it hands its own to the
|
|
1334
|
-
* constructor), so its `getConfig().apiKey` — what a surface reads to decide a key's kind — is the
|
|
1335
|
-
* key sent from here on.
|
|
1336
|
-
*
|
|
1337
|
-
* This replaced `setAuthToken`, which added `Authorization: Bearer` beside an `X-API-Key` it
|
|
1338
|
-
* never touched: the API reads `X-API-Key` first, so the old key was the one used (REL-1385).
|
|
1339
|
-
*/
|
|
1340
|
-
setApiKey(apiKey) {
|
|
1341
|
-
if (this.view !== void 0) return this.view.client.setApiKey(apiKey);
|
|
1342
|
-
const { config } = this.connection;
|
|
1343
|
-
config.apiKey = apiKey;
|
|
1344
|
-
config.headers = layerHeaders(config.headers, { [API_KEY_HEADER]: null });
|
|
1345
|
-
this.connection = {
|
|
1346
|
-
...this.connection,
|
|
1347
|
-
defaultHeaders: layerHeaders(this.connection.defaultHeaders, {
|
|
1348
|
-
[API_KEY_HEADER]: presentKey(apiKey) ?? null
|
|
1349
|
-
})
|
|
1350
|
-
};
|
|
1351
|
-
}
|
|
1352
|
-
/**
|
|
1353
|
-
* Get current default headers
|
|
1354
|
-
*/
|
|
1355
|
-
getDefaultHeaders() {
|
|
1356
|
-
if (this.view !== void 0) {
|
|
1357
|
-
return layerHeaders(this.view.client.getDefaultHeaders(), this.view.headers);
|
|
1358
|
-
}
|
|
1359
|
-
return { ...this.connection.defaultHeaders };
|
|
1360
|
-
}
|
|
1361
|
-
/**
|
|
1362
|
-
* Update base URL
|
|
1363
|
-
*/
|
|
1364
|
-
setBaseUrl(baseUrl) {
|
|
1365
|
-
if (this.view !== void 0) return this.view.client.setBaseUrl(baseUrl);
|
|
1366
|
-
this.connection = { ...this.connection, baseUrl };
|
|
1367
|
-
}
|
|
1368
|
-
/**
|
|
1369
|
-
* Get current base URL
|
|
1370
|
-
*/
|
|
1371
|
-
getBaseUrl() {
|
|
1372
|
-
if (this.view !== void 0) return this.view.client.getBaseUrl();
|
|
1373
|
-
return this.connection.baseUrl;
|
|
1374
|
-
}
|
|
1375
1126
|
/**
|
|
1376
1127
|
* One attempt.
|
|
1377
1128
|
*
|
|
@@ -1517,10 +1268,11 @@ var _HttpClient = class _HttpClient {
|
|
|
1517
1268
|
if (contentType.includes("text/")) {
|
|
1518
1269
|
return await response.text();
|
|
1519
1270
|
}
|
|
1271
|
+
const text = await response.text();
|
|
1520
1272
|
try {
|
|
1521
|
-
return
|
|
1273
|
+
return JSON.parse(text);
|
|
1522
1274
|
} catch {
|
|
1523
|
-
return
|
|
1275
|
+
return text;
|
|
1524
1276
|
}
|
|
1525
1277
|
}
|
|
1526
1278
|
resolveUrl(url) {
|
|
@@ -1575,8 +1327,73 @@ var _HttpClient = class _HttpClient {
|
|
|
1575
1327
|
};
|
|
1576
1328
|
__name(_HttpClient, "HttpClient");
|
|
1577
1329
|
var HttpClient = _HttpClient;
|
|
1330
|
+
var _ControlledHttpClient = class _ControlledHttpClient extends HttpClient {
|
|
1331
|
+
/**
|
|
1332
|
+
* A view of this client that sends every request through it with `headers` added — beneath the
|
|
1333
|
+
* request's own, over this client's — and changes nothing else: its key, base URL, timeout,
|
|
1334
|
+
* retries and `fetch` are this client's as they are when each request is sent, so a later
|
|
1335
|
+
* `configure()` or `setApiKey()` on this client reaches the view, and one on the view reaches
|
|
1336
|
+
* this client. `client.with({ dataset })` is one (REL-2417).
|
|
1337
|
+
*/
|
|
1338
|
+
withHeaders(headers) {
|
|
1339
|
+
const view = new _ControlledHttpClient(this.connection.config);
|
|
1340
|
+
view.view = { client: this, headers: { ...headers } };
|
|
1341
|
+
return view;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Run on `config` from now on: every later request — whoever holds this client — is sent to its
|
|
1345
|
+
* `baseUrl`, with its headers, key and dataset, its timeout and retries, through its `fetch`, and
|
|
1346
|
+
* logged by its `debug` options.
|
|
1347
|
+
*
|
|
1348
|
+
* The client's own `updateConfig()` calls this rather than building a second client, so a
|
|
1349
|
+
* `content()` or other sub-client taken before the update sends through the update too. Anything
|
|
1350
|
+
* set on this client since it was last configured — `setApiKey()` — is replaced by what `config`
|
|
1351
|
+
* says.
|
|
1352
|
+
*/
|
|
1353
|
+
configure(config) {
|
|
1354
|
+
if (this.view !== void 0) return this.view.client.configure(config);
|
|
1355
|
+
this.connection = connectionFor(config);
|
|
1356
|
+
this.announce();
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Replace the key every later request sends as `X-API-Key`, and the `apiKey` the configuration
|
|
1360
|
+
* reports.
|
|
1361
|
+
*
|
|
1362
|
+
* The key is read the way construction reads it (`presentKey`): an absent, empty or blank key is
|
|
1363
|
+
* no key, so the header is dropped and the next request is refused with `MissingApiKeyError`
|
|
1364
|
+
* before anything is sent. A key header of any other spelling — one given in `headers` — goes
|
|
1365
|
+
* too, from the headers sent and from the headers the configuration reports, so the old key is
|
|
1366
|
+
* never sent beside the new one.
|
|
1367
|
+
*
|
|
1368
|
+
* The configuration is the one the owning `TypedRelyIOClient` holds (it hands its own to the
|
|
1369
|
+
* constructor), so its `getConfig().apiKey` — what a surface reads to decide a key's kind — is the
|
|
1370
|
+
* key sent from here on.
|
|
1371
|
+
*
|
|
1372
|
+
* This replaced `setAuthToken`, which added `Authorization: Bearer` beside an `X-API-Key` it
|
|
1373
|
+
* never touched: the API reads `X-API-Key` first, so the old key was the one used (REL-1385).
|
|
1374
|
+
*/
|
|
1375
|
+
setApiKey(apiKey) {
|
|
1376
|
+
if (this.view !== void 0) return this.view.client.setApiKey(apiKey);
|
|
1377
|
+
const { config } = this.connection;
|
|
1378
|
+
config.apiKey = apiKey;
|
|
1379
|
+
config.headers = layerHeaders(config.headers, { [API_KEY_HEADER]: null });
|
|
1380
|
+
this.connection = {
|
|
1381
|
+
...this.connection,
|
|
1382
|
+
defaultHeaders: layerHeaders(this.connection.defaultHeaders, {
|
|
1383
|
+
[API_KEY_HEADER]: presentKey(apiKey) ?? null
|
|
1384
|
+
})
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
__name(_ControlledHttpClient, "ControlledHttpClient");
|
|
1389
|
+
var ControlledHttpClient = _ControlledHttpClient;
|
|
1578
1390
|
var API_KEY_HEADER = "X-API-Key";
|
|
1579
1391
|
var DATASET_HEADER = "X-RelyIO-Dataset";
|
|
1392
|
+
function derivedPreviewIn(headers) {
|
|
1393
|
+
const dataset = headerValue(headers, DATASET_HEADER);
|
|
1394
|
+
return dataset !== void 0 && isDerivedPreview(dataset) ? dataset : void 0;
|
|
1395
|
+
}
|
|
1396
|
+
__name(derivedPreviewIn, "derivedPreviewIn");
|
|
1580
1397
|
var BROWSER_CONTROLLED_HEADERS = /* @__PURE__ */ new Set([
|
|
1581
1398
|
"user-agent",
|
|
1582
1399
|
"referer",
|
|
@@ -1605,13 +1422,7 @@ function connectionFor(config) {
|
|
|
1605
1422
|
// The policy, not a predicate over `(error, attempt)`: whether a request may be sent again is a
|
|
1606
1423
|
// property of the **route** as much as of the refusal, and a callback that never sees the
|
|
1607
1424
|
// request cannot express that.
|
|
1608
|
-
retryPolicy:
|
|
1609
|
-
maxAttempts: config.retryAttempts,
|
|
1610
|
-
baseDelay: 1e3,
|
|
1611
|
-
maxDelay: 1e4,
|
|
1612
|
-
backoffFactor: 2,
|
|
1613
|
-
jitter: true
|
|
1614
|
-
})
|
|
1425
|
+
retryPolicy: retryPolicyFor(config.retryAttempts)
|
|
1615
1426
|
};
|
|
1616
1427
|
}
|
|
1617
1428
|
__name(connectionFor, "connectionFor");
|
|
@@ -1720,6 +1531,15 @@ function listQuery(options, clientLocale) {
|
|
|
1720
1531
|
return query;
|
|
1721
1532
|
}
|
|
1722
1533
|
__name(listQuery, "listQuery");
|
|
1534
|
+
function childrenQuery(options, clientLocale) {
|
|
1535
|
+
const query = {};
|
|
1536
|
+
if (options.limit !== void 0) query.limit = options.limit;
|
|
1537
|
+
if (options.cursor !== void 0) query.cursor = options.cursor;
|
|
1538
|
+
if (options.page !== void 0) query.page = options.page;
|
|
1539
|
+
writeReadTerms(query, options, clientLocale);
|
|
1540
|
+
return query;
|
|
1541
|
+
}
|
|
1542
|
+
__name(childrenQuery, "childrenQuery");
|
|
1723
1543
|
function entryQuery(options, clientLocale) {
|
|
1724
1544
|
const query = {};
|
|
1725
1545
|
writeReadTerms(query, options, clientLocale);
|
|
@@ -1762,6 +1582,10 @@ function writeLocale(query, locale) {
|
|
|
1762
1582
|
query.locales = locale.join(",");
|
|
1763
1583
|
}
|
|
1764
1584
|
__name(writeLocale, "writeLocale");
|
|
1585
|
+
function signalOf(options) {
|
|
1586
|
+
return options.signal === void 0 ? {} : { signal: options.signal };
|
|
1587
|
+
}
|
|
1588
|
+
__name(signalOf, "signalOf");
|
|
1765
1589
|
function readHeaders(options) {
|
|
1766
1590
|
const headers = {};
|
|
1767
1591
|
if (options.dataset !== void 0) headers[DATASET_HEADER] = options.dataset;
|
|
@@ -1815,7 +1639,8 @@ var _EntryHandle = class _EntryHandle {
|
|
|
1815
1639
|
{
|
|
1816
1640
|
path: { contentType: this.typeName },
|
|
1817
1641
|
query: listQuery(options, this.clientLocale()),
|
|
1818
|
-
headers: readHeaders(options)
|
|
1642
|
+
headers: readHeaders(options),
|
|
1643
|
+
...signalOf(options)
|
|
1819
1644
|
}
|
|
1820
1645
|
);
|
|
1821
1646
|
return response.body;
|
|
@@ -1870,7 +1695,8 @@ var _EntryHandle = class _EntryHandle {
|
|
|
1870
1695
|
return await this.httpClient.fetchPayload("/v1/{contentType}/{id}", "get", {
|
|
1871
1696
|
path: { contentType: this.typeName, id: idOrSlug },
|
|
1872
1697
|
query: entryQuery(options, this.clientLocale()),
|
|
1873
|
-
headers: readHeaders(options)
|
|
1698
|
+
headers: readHeaders(options),
|
|
1699
|
+
...signalOf(options)
|
|
1874
1700
|
});
|
|
1875
1701
|
} catch (error) {
|
|
1876
1702
|
if (isMissingEntry(error)) return null;
|
|
@@ -1937,7 +1763,7 @@ var _ContentClient = class _ContentClient extends EntryHandle {
|
|
|
1937
1763
|
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
1938
1764
|
* client's own, else the schema default; no fallback is applied, and a locale
|
|
1939
1765
|
* with no history returns an empty array rather than another locale's rows. Every row names the
|
|
1940
|
-
* locale it belongs to
|
|
1766
|
+
* locale it belongs to, and holds that locale's fields under `fields`.
|
|
1941
1767
|
*/
|
|
1942
1768
|
async versions(id, options) {
|
|
1943
1769
|
const locale = callLocale(options?.locale, this.clientLocale());
|
|
@@ -1958,6 +1784,9 @@ var _ContentClient = class _ContentClient extends EntryHandle {
|
|
|
1958
1784
|
* There is no `null`: a version the locale does not have, an entry that is not there, a type the
|
|
1959
1785
|
* schema does not declare and a dataset with no schema all throw `ResourceNotFoundError`, its
|
|
1960
1786
|
* `context.resourceType` naming which (REL-2409 Q12).
|
|
1787
|
+
*
|
|
1788
|
+
* It answers the version, not the entry: that locale's own fields as the version stored them, and
|
|
1789
|
+
* `_metadata` with `status: 'version'` ({@link ContentVersion}).
|
|
1961
1790
|
*/
|
|
1962
1791
|
async version(id, options) {
|
|
1963
1792
|
const locale = callLocale(options.locale, this.clientLocale());
|
|
@@ -1984,7 +1813,12 @@ var _ContentClient = class _ContentClient extends EntryHandle {
|
|
|
1984
1813
|
});
|
|
1985
1814
|
}
|
|
1986
1815
|
/**
|
|
1987
|
-
*
|
|
1816
|
+
* One page of the direct children of a hierarchical entry, each read as `get` reads an entry:
|
|
1817
|
+
* the API's own `{ data, page }`, as `list` answers it (REL-1864).
|
|
1818
|
+
*
|
|
1819
|
+
* Page by `cursor` — the `page.nextCursor` a page handed back — to reach every child, or by
|
|
1820
|
+
* `page` number; `limit` is the page size for both. `page.hasMore` says whether there are more,
|
|
1821
|
+
* and a parent with more children than a page has them on the next one.
|
|
1988
1822
|
*
|
|
1989
1823
|
* It takes `get`'s options — `include` (checked against the type), `locale` (a code, a list or
|
|
1990
1824
|
* `'*'`), `dataset`, `fresh` and `children` — the terms its route declares as the entry route
|
|
@@ -1992,13 +1826,26 @@ var _ContentClient = class _ContentClient extends EntryHandle {
|
|
|
1992
1826
|
* under each child is the `children` option.
|
|
1993
1827
|
*
|
|
1994
1828
|
* @param id - Parent entry ID
|
|
1829
|
+
*
|
|
1830
|
+
* @example
|
|
1831
|
+
* ```typescript
|
|
1832
|
+
* let page = await relyio.content('category').children('cat_1', { limit: 50 })
|
|
1833
|
+
* while (page.page.hasMore && page.page.nextCursor !== null) {
|
|
1834
|
+
* page = await relyio.content('category').children('cat_1', {
|
|
1835
|
+
* limit: 50,
|
|
1836
|
+
* cursor: page.page.nextCursor,
|
|
1837
|
+
* })
|
|
1838
|
+
* }
|
|
1839
|
+
* ```
|
|
1995
1840
|
*/
|
|
1996
1841
|
async children(id, options = {}) {
|
|
1997
|
-
|
|
1842
|
+
const response = await this.httpClient.send("/v1/{contentType}/{id}/children", "get", {
|
|
1998
1843
|
path: { contentType: this.typeName, id },
|
|
1999
|
-
query:
|
|
2000
|
-
headers: readHeaders(options)
|
|
1844
|
+
query: childrenQuery(options, this.clientLocale()),
|
|
1845
|
+
headers: readHeaders(options),
|
|
1846
|
+
...signalOf(options)
|
|
2001
1847
|
});
|
|
1848
|
+
return response.body;
|
|
2002
1849
|
}
|
|
2003
1850
|
};
|
|
2004
1851
|
__name(_ContentClient, "ContentClient");
|
|
@@ -2530,7 +2377,7 @@ var _AssetUploadBuilder = class _AssetUploadBuilder {
|
|
|
2530
2377
|
}
|
|
2531
2378
|
const total = this.file.size;
|
|
2532
2379
|
this.emitProgress(0, total);
|
|
2533
|
-
const uploadResponse = await
|
|
2380
|
+
const uploadResponse = await HttpClient.transfer(this.httpClient, presigned.uploadUrl, {
|
|
2534
2381
|
method: presigned.method,
|
|
2535
2382
|
headers: presigned.headers,
|
|
2536
2383
|
body: this.file
|
|
@@ -2597,7 +2444,10 @@ var _AssetUploadBuilder = class _AssetUploadBuilder {
|
|
|
2597
2444
|
for (let attempt = 0; attempt <= this._maxPartRetries; attempt += 1) {
|
|
2598
2445
|
try {
|
|
2599
2446
|
const { url } = await fileBuilder.signPart({ ...target, partNumber });
|
|
2600
|
-
const response = await
|
|
2447
|
+
const response = await HttpClient.transfer(this.httpClient, url, {
|
|
2448
|
+
method: "PUT",
|
|
2449
|
+
body: blob
|
|
2450
|
+
});
|
|
2601
2451
|
if (!response.ok) {
|
|
2602
2452
|
const retriable = response.status >= 500 || response.status === 408 || response.status === 429;
|
|
2603
2453
|
if (!retriable) {
|
|
@@ -2782,7 +2632,8 @@ var _SingletonClient = class _SingletonClient extends DocumentHandle {
|
|
|
2782
2632
|
return await this.httpClient.fetchPayload("/v1/singletons/{key}", "get", {
|
|
2783
2633
|
path: { key: this.name },
|
|
2784
2634
|
query: documentQuery(options, this.clientLocale()),
|
|
2785
|
-
headers: readHeaders(options)
|
|
2635
|
+
headers: readHeaders(options),
|
|
2636
|
+
...signalOf(options)
|
|
2786
2637
|
});
|
|
2787
2638
|
} catch (error) {
|
|
2788
2639
|
if (isMissingEntry(error)) return null;
|
|
@@ -2805,14 +2656,10 @@ var _SingletonClient = class _SingletonClient extends DocumentHandle {
|
|
|
2805
2656
|
return this.httpClient.fetchPayload("/v1/singletons/{key}/versions", "get", { path: { key: this.name }, query });
|
|
2806
2657
|
}
|
|
2807
2658
|
readVersion(versionNumber, query) {
|
|
2808
|
-
return this.httpClient.fetchPayload(
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
path: { key: this.name, versionNumber },
|
|
2813
|
-
query
|
|
2814
|
-
}
|
|
2815
|
-
);
|
|
2659
|
+
return this.httpClient.fetchPayload("/v1/singletons/{key}/versions/{versionNumber}", "get", {
|
|
2660
|
+
path: { key: this.name, versionNumber },
|
|
2661
|
+
query
|
|
2662
|
+
});
|
|
2816
2663
|
}
|
|
2817
2664
|
};
|
|
2818
2665
|
__name(_SingletonClient, "SingletonClient");
|
|
@@ -2845,7 +2692,8 @@ var _SettingsClient = class _SettingsClient extends DocumentHandle {
|
|
|
2845
2692
|
{
|
|
2846
2693
|
path: { groupId: this.name },
|
|
2847
2694
|
query: documentQuery(options, this.clientLocale()),
|
|
2848
|
-
headers: readHeaders(options)
|
|
2695
|
+
headers: readHeaders(options),
|
|
2696
|
+
...signalOf(options)
|
|
2849
2697
|
}
|
|
2850
2698
|
);
|
|
2851
2699
|
}
|
|
@@ -2896,7 +2744,7 @@ var SettingsClient = _SettingsClient;
|
|
|
2896
2744
|
|
|
2897
2745
|
// src/changes/changes.ts
|
|
2898
2746
|
var CHANGES_POLL_TIMEOUT_MS = 25e3 + 5e3;
|
|
2899
|
-
var
|
|
2747
|
+
var EXPIRED_REASONS2 = {
|
|
2900
2748
|
retention: "retention",
|
|
2901
2749
|
"dataset-replaced": "dataset-replaced",
|
|
2902
2750
|
"ahead-of-head": "ahead-of-head",
|
|
@@ -2916,7 +2764,7 @@ var _ChangesExpiredError = class _ChangesExpiredError extends ResourceExpiredErr
|
|
|
2916
2764
|
*/
|
|
2917
2765
|
__publicField(this, "fresh");
|
|
2918
2766
|
this.name = "ChangesExpiredError";
|
|
2919
|
-
this.reason = expiredReasonOf(
|
|
2767
|
+
this.reason = expiredReasonOf(context?.reason);
|
|
2920
2768
|
this.fresh = fresh;
|
|
2921
2769
|
}
|
|
2922
2770
|
/** The base class rebuilds from its four arguments, which would drop the position resynced to. */
|
|
@@ -2946,16 +2794,16 @@ var _ChangesExpiredError = class _ChangesExpiredError extends ResourceExpiredErr
|
|
|
2946
2794
|
`The live edge cannot list the changes since this cursor (${reason}). Refetch everything derived from the feed; it continues from the position it sent.`,
|
|
2947
2795
|
410,
|
|
2948
2796
|
void 0,
|
|
2949
|
-
{ transport: "live-edge" },
|
|
2797
|
+
{ transport: "live-edge", reason },
|
|
2950
2798
|
cursor
|
|
2951
2799
|
);
|
|
2952
2800
|
}
|
|
2953
2801
|
};
|
|
2954
2802
|
__name(_ChangesExpiredError, "ChangesExpiredError");
|
|
2955
2803
|
var ChangesExpiredError = _ChangesExpiredError;
|
|
2956
|
-
function expiredReasonOf(
|
|
2957
|
-
for (const reason of Object.values(
|
|
2958
|
-
if (
|
|
2804
|
+
function expiredReasonOf(named) {
|
|
2805
|
+
for (const reason of Object.values(EXPIRED_REASONS2)) {
|
|
2806
|
+
if (named === reason) return reason;
|
|
2959
2807
|
}
|
|
2960
2808
|
return "unknown";
|
|
2961
2809
|
}
|
|
@@ -3035,10 +2883,6 @@ async function pollOnce(http, since, options) {
|
|
|
3035
2883
|
}
|
|
3036
2884
|
__name(pollOnce, "pollOnce");
|
|
3037
2885
|
|
|
3038
|
-
// src/config/key-kind.ts
|
|
3039
|
-
var PUBLISHABLE_KEY_PREFIX = "rly_pub_";
|
|
3040
|
-
var isPublishableKey = /* @__PURE__ */ __name((apiKey) => apiKey?.startsWith(PUBLISHABLE_KEY_PREFIX) === true, "isPublishableKey");
|
|
3041
|
-
|
|
3042
2886
|
// src/errors/live-errors.ts
|
|
3043
2887
|
var _LiveEdgeError = class _LiveEdgeError extends SDKError {
|
|
3044
2888
|
constructor(message, end, retry, options = {}) {
|
|
@@ -3054,19 +2898,6 @@ var _LiveEdgeError = class _LiveEdgeError extends SDKError {
|
|
|
3054
2898
|
this.retryable = retry !== "stop";
|
|
3055
2899
|
this.retryAfterMs = options.retryAfterMs;
|
|
3056
2900
|
}
|
|
3057
|
-
/**
|
|
3058
|
-
* The base class rebuilds an error through its own four-argument constructor, which this class
|
|
3059
|
-
* does not have; rebuilt that way, `end` would be a string and `retry` a number.
|
|
3060
|
-
*/
|
|
3061
|
-
withContext(context) {
|
|
3062
|
-
const rebuilt = new _LiveEdgeError(this.message, this.end, this.retry, {
|
|
3063
|
-
...this.statusCode === void 0 ? {} : { statusCode: this.statusCode },
|
|
3064
|
-
...this.cause === void 0 ? {} : { cause: this.cause },
|
|
3065
|
-
...this.retryAfterMs === void 0 ? {} : { retryAfterMs: this.retryAfterMs },
|
|
3066
|
-
context: { ...this.context, ...context }
|
|
3067
|
-
});
|
|
3068
|
-
return rebuilt;
|
|
3069
|
-
}
|
|
3070
2901
|
getUserMessage() {
|
|
3071
2902
|
return this.message;
|
|
3072
2903
|
}
|
|
@@ -3086,8 +2917,8 @@ var HTTP_SCHEME_OF = {
|
|
|
3086
2917
|
};
|
|
3087
2918
|
function liveEdgeAddress(config) {
|
|
3088
2919
|
if (config.liveUrl !== void 0) return readLiveUrl(config.liveUrl);
|
|
3089
|
-
const
|
|
3090
|
-
const edge =
|
|
2920
|
+
const derived2 = originOf(config.baseUrl);
|
|
2921
|
+
const edge = derived2 === void 0 ? void 0 : LIVE_EDGE_OF_API[derived2];
|
|
3091
2922
|
if (edge !== void 0) return { ok: true, url: new URL(edge) };
|
|
3092
2923
|
return {
|
|
3093
2924
|
ok: false,
|
|
@@ -3337,19 +3168,18 @@ var CLOSE_MEANING = {
|
|
|
3337
3168
|
[VISITOR_CLOSE_CODES.keyRefused]: "the key is not a publishable key the edge accepts \u2014 unknown, revoked or expired",
|
|
3338
3169
|
[VISITOR_CLOSE_CODES.originRefused]: "this page\u2019s origin is not on the publishable key\u2019s allowed origins",
|
|
3339
3170
|
[VISITOR_CLOSE_CODES.datasetRefused]: "`dataset` names no dataset the key reaches",
|
|
3340
|
-
|
|
3341
|
-
// placement (reason `moved`, REL-1514): either way the same request succeeds again shortly.
|
|
3342
|
-
[VISITOR_CLOSE_CODES.unavailable]: "the edge could not serve this connection just now \u2014 it could not reach what it needed, or it moved the project\u2019s live connections elsewhere",
|
|
3171
|
+
[VISITOR_CLOSE_CODES.unavailable]: "the edge could not serve this connection just now \u2014 it could not reach what it needed",
|
|
3343
3172
|
[VISITOR_CLOSE_CODES.allowanceReached]: "the project holds as many live connections as its plan allows",
|
|
3344
3173
|
[VISITOR_CLOSE_CODES.addressLimitReached]: "this address holds as many live connections to the project as one address may",
|
|
3345
3174
|
[VISITOR_CLOSE_CODES.ceilingReached]: "the project is at its safety ceiling of live connections"
|
|
3346
3175
|
};
|
|
3347
3176
|
async function* followPolls(client, request, reach, options) {
|
|
3348
3177
|
const { signal } = options;
|
|
3178
|
+
let starting = reach.position === void 0;
|
|
3349
3179
|
for (let poll = 0; poll < LIVE_POLLS_BEFORE_SOCKET; poll += 1) {
|
|
3350
3180
|
if (isAborted(signal)) return "aborted";
|
|
3351
3181
|
const answer = await pollOnce2(client, request, reach.position, signal);
|
|
3352
|
-
if (answer === void 0) return "aborted";
|
|
3182
|
+
if (answer === void 0 || isAborted(signal)) return "aborted";
|
|
3353
3183
|
options.opened?.();
|
|
3354
3184
|
if (answer.kind === "resync") {
|
|
3355
3185
|
await expire(answer.reason, answer.cursor, options);
|
|
@@ -3366,8 +3196,9 @@ async function* followPolls(client, request, reach, options) {
|
|
|
3366
3196
|
if (isAborted(signal)) return "aborted";
|
|
3367
3197
|
}
|
|
3368
3198
|
reach.position = answer.cursor;
|
|
3369
|
-
if (
|
|
3199
|
+
if (starting) options.reached?.(answer.cursor);
|
|
3370
3200
|
}
|
|
3201
|
+
starting = false;
|
|
3371
3202
|
await sleep(VISITOR_POLL_INTERVAL_MS, signal);
|
|
3372
3203
|
}
|
|
3373
3204
|
return isAborted(signal) ? "aborted" : "socket";
|
|
@@ -3559,6 +3390,7 @@ __name(given, "given");
|
|
|
3559
3390
|
function transportOf(options) {
|
|
3560
3391
|
const headers = readHeaders(options);
|
|
3561
3392
|
return {
|
|
3393
|
+
...signalOf(options),
|
|
3562
3394
|
...headers === void 0 ? {} : { headers },
|
|
3563
3395
|
...typeof options.fresh === "string" ? { query: { [FRESH_PARAMETER]: options.fresh } } : {}
|
|
3564
3396
|
};
|
|
@@ -3636,7 +3468,7 @@ __name(runSimilar, "runSimilar");
|
|
|
3636
3468
|
// src/batch/batch-operations.ts
|
|
3637
3469
|
var VERBS = ["create", "update", "replace", "delete", "singleton"];
|
|
3638
3470
|
async function runBatch(http, operations, options, clientLocale) {
|
|
3639
|
-
const { atomic, dryRun, stopOnError, returnData, dataset } = options;
|
|
3471
|
+
const { atomic, dryRun, stopOnError, returnData, dataset, signal } = options;
|
|
3640
3472
|
const runOptions = {
|
|
3641
3473
|
...atomic === void 0 ? {} : { atomic },
|
|
3642
3474
|
...dryRun === void 0 ? {} : { dryRun },
|
|
@@ -3649,7 +3481,8 @@ async function runBatch(http, operations, options, clientLocale) {
|
|
|
3649
3481
|
operations: operations.map((operation, index) => operationOf(operation, index, clientLocale)),
|
|
3650
3482
|
...Object.keys(runOptions).length === 0 ? {} : { options: runOptions }
|
|
3651
3483
|
},
|
|
3652
|
-
...headers === void 0 ? {} : { headers }
|
|
3484
|
+
...headers === void 0 ? {} : { headers },
|
|
3485
|
+
...signalOf({ signal })
|
|
3653
3486
|
});
|
|
3654
3487
|
return response.body;
|
|
3655
3488
|
}
|
|
@@ -3729,7 +3562,7 @@ async function runAdhocQuery(http, query, clientLocale) {
|
|
|
3729
3562
|
const order = sort === void 0 ? [] : Object.entries(sort).flatMap(
|
|
3730
3563
|
([field, direction]) => direction === void 0 ? [] : [{ [field]: direction }]
|
|
3731
3564
|
);
|
|
3732
|
-
const
|
|
3565
|
+
const fetch = {
|
|
3733
3566
|
contentType: query.from,
|
|
3734
3567
|
...where === void 0 || Object.keys(where).length === 0 ? {} : { where },
|
|
3735
3568
|
...include === void 0 || include.length === 0 ? {} : { include: [...include] },
|
|
@@ -3737,14 +3570,14 @@ async function runAdhocQuery(http, query, clientLocale) {
|
|
|
3737
3570
|
...limit === void 0 ? {} : { limit },
|
|
3738
3571
|
...page === void 0 ? {} : { offset: offsetOf(page, limit) }
|
|
3739
3572
|
};
|
|
3740
|
-
const
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
};
|
|
3573
|
+
const terms = {};
|
|
3574
|
+
if (query.cursor !== void 0) terms.cursor = query.cursor;
|
|
3575
|
+
writeLocale(terms, query.locale ?? clientLocale);
|
|
3576
|
+
if (typeof query.fresh === "string") terms[FRESH_PARAMETER] = query.fresh;
|
|
3577
|
+
const parameters = { ...query.params };
|
|
3745
3578
|
const body = {
|
|
3746
3579
|
query: {
|
|
3747
|
-
fetch
|
|
3580
|
+
fetch,
|
|
3748
3581
|
...aggregate === void 0 ? {} : { aggregate },
|
|
3749
3582
|
...select === void 0 || select.length === 0 ? {} : { select: Object.fromEntries(select.map((field) => [field, field])) },
|
|
3750
3583
|
...fullText === void 0 ? {} : { fullText }
|
|
@@ -3754,8 +3587,9 @@ async function runAdhocQuery(http, query, clientLocale) {
|
|
|
3754
3587
|
const headers = readHeaders(query);
|
|
3755
3588
|
const response = await http.send("/v1/query", "post", {
|
|
3756
3589
|
body,
|
|
3590
|
+
...Object.keys(terms).length === 0 ? {} : { query: terms },
|
|
3757
3591
|
...headers === void 0 ? {} : { headers },
|
|
3758
|
-
...
|
|
3592
|
+
...signalOf(query)
|
|
3759
3593
|
});
|
|
3760
3594
|
return response.body;
|
|
3761
3595
|
}
|
|
@@ -3772,6 +3606,9 @@ function offsetOf(page, limit) {
|
|
|
3772
3606
|
__name(offsetOf, "offsetOf");
|
|
3773
3607
|
async function runNamedQuery(http, name, options, clientLocale) {
|
|
3774
3608
|
const locale = options.locale ?? clientLocale;
|
|
3609
|
+
const terms = {};
|
|
3610
|
+
if (locale !== void 0 && locale !== "") terms.locale = locale;
|
|
3611
|
+
if (typeof options.fresh === "string") terms[FRESH_PARAMETER] = options.fresh;
|
|
3775
3612
|
const headers = readHeaders(options);
|
|
3776
3613
|
const response = await http.send(
|
|
3777
3614
|
"/v1/queries/{name}",
|
|
@@ -3779,8 +3616,9 @@ async function runNamedQuery(http, name, options, clientLocale) {
|
|
|
3779
3616
|
{
|
|
3780
3617
|
path: { name },
|
|
3781
3618
|
body: options.params === void 0 ? {} : { params: options.params },
|
|
3782
|
-
...
|
|
3783
|
-
...headers === void 0 ? {} : { headers }
|
|
3619
|
+
...Object.keys(terms).length === 0 ? {} : { query: terms },
|
|
3620
|
+
...headers === void 0 ? {} : { headers },
|
|
3621
|
+
...signalOf(options)
|
|
3784
3622
|
}
|
|
3785
3623
|
);
|
|
3786
3624
|
return response.body;
|
|
@@ -3888,6 +3726,17 @@ function resolveDevOverride(dev) {
|
|
|
3888
3726
|
}
|
|
3889
3727
|
__name(resolveDevOverride, "resolveDevOverride");
|
|
3890
3728
|
|
|
3729
|
+
// src/config/preview-environment.ts
|
|
3730
|
+
function readPreviewAtRequest() {
|
|
3731
|
+
const env = typeof process === "undefined" ? void 0 : process.env;
|
|
3732
|
+
return previewAtRequest(isEnvironment(env) ? env : {});
|
|
3733
|
+
}
|
|
3734
|
+
__name(readPreviewAtRequest, "readPreviewAtRequest");
|
|
3735
|
+
function isEnvironment(value) {
|
|
3736
|
+
return typeof value === "object" && value !== null;
|
|
3737
|
+
}
|
|
3738
|
+
__name(isEnvironment, "isEnvironment");
|
|
3739
|
+
|
|
3891
3740
|
// src/config/types.ts
|
|
3892
3741
|
var DEFAULT_CONFIG = {
|
|
3893
3742
|
baseUrl: "https://api.relyio.com",
|
|
@@ -3909,12 +3758,6 @@ var DEFAULT_CONFIG = {
|
|
|
3909
3758
|
// 50MB
|
|
3910
3759
|
strategies: ["memory", "stale-while-revalidate"]
|
|
3911
3760
|
},
|
|
3912
|
-
realtime: {
|
|
3913
|
-
enabled: true,
|
|
3914
|
-
maxReconnectAttempts: 10,
|
|
3915
|
-
reconnectDelay: 1e3,
|
|
3916
|
-
heartbeatInterval: 3e4
|
|
3917
|
-
},
|
|
3918
3761
|
debug: {
|
|
3919
3762
|
enabled: false,
|
|
3920
3763
|
logRequests: false,
|
|
@@ -3966,7 +3809,7 @@ __name(withoutKeyHeader, "withoutKeyHeader");
|
|
|
3966
3809
|
function withHandshake(configured) {
|
|
3967
3810
|
const dev = resolveDevOverride(configured.dev);
|
|
3968
3811
|
const merged = withDefaults(
|
|
3969
|
-
configured,
|
|
3812
|
+
withPreview(configured),
|
|
3970
3813
|
dev.state === "active" ? { apiKey: dev.apiKey, dataset: dev.sandbox.datasetId } : {},
|
|
3971
3814
|
DEFAULT_CONFIG
|
|
3972
3815
|
);
|
|
@@ -3991,6 +3834,22 @@ function withHandshake(configured) {
|
|
|
3991
3834
|
return { config: merged, sandbox: sandboxStateOf(dev), configured };
|
|
3992
3835
|
}
|
|
3993
3836
|
__name(withHandshake, "withHandshake");
|
|
3837
|
+
var previewNotified = false;
|
|
3838
|
+
function withPreview(configured) {
|
|
3839
|
+
if (configured.dataset !== void 0 || !isPreviewKey(configured.apiKey)) return configured;
|
|
3840
|
+
const preview = readPreviewAtRequest();
|
|
3841
|
+
if (preview.state !== "preview") return configured;
|
|
3842
|
+
const dataset = previewDatasetSlug(preview.branch);
|
|
3843
|
+
noteDerivedPreview(dataset);
|
|
3844
|
+
if (!previewNotified) {
|
|
3845
|
+
previewNotified = true;
|
|
3846
|
+
console.info(
|
|
3847
|
+
`[RelyIO] ${preview.host} preview deployment of "${preview.branch}" \u2014 reading its preview dataset "${dataset}".`
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3850
|
+
return { ...configured, dataset };
|
|
3851
|
+
}
|
|
3852
|
+
__name(withPreview, "withPreview");
|
|
3994
3853
|
function withDefaults(base, given2, defaults) {
|
|
3995
3854
|
const merged = new Map(Object.entries(base));
|
|
3996
3855
|
const givenValues = new Map(Object.entries(given2 ?? {}));
|
|
@@ -4057,7 +3916,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4057
3916
|
this.config = resolved.config;
|
|
4058
3917
|
this.configured = resolved.configured;
|
|
4059
3918
|
this._sandbox = resolved.sandbox;
|
|
4060
|
-
this.httpClient = new
|
|
3919
|
+
this.httpClient = new ControlledHttpClient(this.config);
|
|
4061
3920
|
}
|
|
4062
3921
|
// ============================================================================
|
|
4063
3922
|
// CORE CLIENTS
|
|
@@ -4082,14 +3941,16 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4082
3941
|
/**
|
|
4083
3942
|
* Run a query in one call (REL-2421, REL-2409 Q22):
|
|
4084
3943
|
*
|
|
4085
|
-
* - `query({ from, … })` runs one inline, with `list`'s
|
|
4086
|
-
*
|
|
4087
|
-
* plus `aggregate`, `params` and `fullText
|
|
3944
|
+
* - `query({ from, … })` runs one inline, with `list`'s options — `where`, `include`, `select`
|
|
3945
|
+
* (beside `include`), `sort`, `limit`, `cursor`, `page`, `locale` (a code, a list or `'*'`),
|
|
3946
|
+
* `dataset`, `fresh` — plus `aggregate`, `params` and `fullText`. It answers a list's envelope,
|
|
3947
|
+
* `{ data, page, meta }` (REL-2460);
|
|
4088
3948
|
* - `query(name, { params, … })` runs the saved query the schema declares under `name`, its
|
|
4089
|
-
* `params` typed from that declaration.
|
|
3949
|
+
* `params` typed from that declaration. It answers the API's body,
|
|
3950
|
+
* `{ data: { result, metadata } }`.
|
|
4090
3951
|
*
|
|
4091
|
-
*
|
|
4092
|
-
*
|
|
3952
|
+
* See {@link QueryCall}. Every query is sent in the client's locale as it is then, unless it names
|
|
3953
|
+
* its own.
|
|
4093
3954
|
*/
|
|
4094
3955
|
get query() {
|
|
4095
3956
|
const call = /* @__PURE__ */ __name((target, options = {}) => typeof target === "string" ? runNamedQuery(this.httpClient, target, options, this.currentLocale()) : runAdhocQuery(this.httpClient, target, this.currentLocale()), "call");
|
|
@@ -4274,7 +4135,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4274
4135
|
* edge's URL. On a server, follow `changes()` with it instead.
|
|
4275
4136
|
*/
|
|
4276
4137
|
liveChanges(options = {}) {
|
|
4277
|
-
const { apiKey, dataset, baseUrl, liveUrl, fetch
|
|
4138
|
+
const { apiKey, dataset, baseUrl, liveUrl, fetch, webSocket, timeout } = this.getConfig();
|
|
4278
4139
|
this._liveClientId ?? (this._liveClientId = randomClientId());
|
|
4279
4140
|
return subscribeLiveEdge(
|
|
4280
4141
|
{
|
|
@@ -4282,7 +4143,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4282
4143
|
dataset,
|
|
4283
4144
|
baseUrl,
|
|
4284
4145
|
liveUrl,
|
|
4285
|
-
fetch
|
|
4146
|
+
fetch,
|
|
4286
4147
|
webSocket,
|
|
4287
4148
|
timeout,
|
|
4288
4149
|
clientId: this._liveClientId
|
|
@@ -4391,9 +4252,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
4391
4252
|
* - an option you name replaces the value the client holds;
|
|
4392
4253
|
* - an option left out, or given as `undefined`, keeps the value the client holds;
|
|
4393
4254
|
* - an option with no default given as `null` is cleared — `locale`, `dataset`, `apiKey`, `dev`,
|
|
4394
|
-
* `fetch`, `browser.onCorsError`, `
|
|
4255
|
+
* `fetch`, `browser.onCorsError`, `debug.logger` — so the client runs as though
|
|
4395
4256
|
* it had never been given one. An option with a default takes no `null`;
|
|
4396
|
-
* - a bag of options you name — `browser`, `cache`, `
|
|
4257
|
+
* - a bag of options you name — `browser`, `cache`, `debug` — keeps every field of it
|
|
4397
4258
|
* you do not name, so `updateConfig({ browser: { includeCredentials: true } })` keeps a
|
|
4398
4259
|
* configured `onCorsError`;
|
|
4399
4260
|
* - `headers` is laid over the headers the client sends, a name matched without regard to case: a
|
|
@@ -4569,6 +4430,6 @@ function randomClientId() {
|
|
|
4569
4430
|
}
|
|
4570
4431
|
__name(randomClientId, "randomClientId");
|
|
4571
4432
|
|
|
4572
|
-
export { AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthorizationError, BaseValidationError, ChangesExpiredError, ConnectionError, ContentClient, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidPayloadError, LIVE_KEEPALIVE_INTERVAL_MS, LIVE_SOCKET_OPEN_TIMEOUT_MS, LiveEdgeError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PUBLISHABLE_KEY_PREFIX, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, SettingsClient, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError,
|
|
4573
|
-
//# sourceMappingURL=chunk-
|
|
4574
|
-
//# sourceMappingURL=chunk-
|
|
4433
|
+
export { AssetClient, AssetFileBuilder, AssetUploadBuilder, AuthorizationError, BaseValidationError, ChangesExpiredError, ConnectionError, ContentClient, DefaultRetryPolicy, ErrorMapper, FileUploadError, FileValidationError, HttpClient, InvalidApiKeyError, InvalidPayloadError, LIVE_KEEPALIVE_INTERVAL_MS, LIVE_SOCKET_OPEN_TIMEOUT_MS, LiveEdgeError, MethodNotAllowedError, MissingApiKeyError, NetworkError, PREVIEW_KEY_PREFIX, PUBLISHABLE_KEY_PREFIX, PayloadTooLargeError, PlanFeatureUnavailableError, RateLimitError, ReadOnlyKeyError, ResourceConflictError, ResourceExpiredError, ResourceNotFoundError, SDKError, ServerError, ServiceIndeterminateError, SettingsClient, SingletonClient, TimeoutError, TransactionRolledBackError, TypedRelyIOClient, UnknownContractError, UsageQuotaExceededError, ValidationError, createClient, isAborted, isAssetEntry, isMissingEntry, isPreviewKey, isPublishableKey, isReplaySafe, isResourceNotFound, matchRoute, retryPolicyFor, serviceInstructedDelayMs, sleep, validateFile, versionCheckOf };
|
|
4434
|
+
//# sourceMappingURL=chunk-NIUOPIIB.js.map
|
|
4435
|
+
//# sourceMappingURL=chunk-NIUOPIIB.js.map
|