@relyio/sdk 0.6.0 → 0.8.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 +400 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-DY2XT7OF.cjs → chunk-72UK5U7T.cjs} +70 -60
- package/dist/{chunk-I3ESNANB.js → chunk-H6IBQSMM.js} +2 -2
- package/dist/{chunk-7ABNXVWL.js → chunk-QFHVF3YF.js} +1617 -404
- package/dist/{chunk-HT6NFRM2.cjs → chunk-TZL374LS.cjs} +2 -2
- package/dist/{chunk-GCMQUM6N.cjs → chunk-XIE7WJV3.cjs} +1621 -407
- package/dist/{chunk-XJVY2CLY.js → chunk-YEJUMW4X.js} +70 -60
- package/dist/client/index.cjs +4 -3
- package/dist/client/index.d.cts +5 -4
- package/dist/client/index.d.ts +5 -4
- package/dist/client/index.js +2 -1
- package/dist/{index-d1Kz1e19.d.cts → define-content-type-cEGjIwT5.d.cts} +1859 -733
- package/dist/{index-yPbhZc6q.d.ts → define-content-type-cEGjIwT5.d.ts} +1859 -733
- package/dist/{define-schema-1kr2HIzN.d.cts → define-schema-BPj2srgh.d.ts} +189 -85
- package/dist/{define-schema-ChvAzY8H.d.ts → define-schema-DgbJ5Kwn.d.cts} +189 -85
- package/dist/index-B_rIWO_l.d.cts +860 -0
- package/dist/index-Cv4tmcrw.d.ts +860 -0
- package/dist/{index-Df1VsfJR.d.cts → index-DBoPPlT1.d.cts} +684 -277
- package/dist/{index-XqoGUaAY.d.ts → index-yRJ2IqM_.d.ts} +684 -277
- package/dist/index.cjs +148 -124
- package/dist/index.d.cts +174 -64
- package/dist/index.d.ts +174 -64
- package/dist/index.js +43 -18
- package/dist/schema/index.cjs +35 -35
- package/dist/schema/index.d.cts +13 -11
- package/dist/schema/index.d.ts +13 -11
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/utils/index.cjs +19 -19
- package/dist/utils/index.d.cts +10 -1
- package/dist/utils/index.d.ts +10 -1
- package/dist/utils/index.js +1 -1
- package/package.json +2 -1
- package/dist/define-content-type-CDB3kyeA.d.cts +0 -1173
- package/dist/define-content-type-CDB3kyeA.d.ts +0 -1173
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { K as MergedRelyIOConfig, A as ApiPath, c as ApiMethod, N as PathParamsOf, w as ApiResponse, W as Wire, v as RequestConfig, B as BaseContent, h as WhereClause, Q as QueryOptions, j as SortOptions, k as ContentQueryResult, C as CreateInput, U as UpdateInput, S as SDKError, H as BaseValidationError, G as ValidationViolation, R as RelyIOConfig, a as RelyIOConfigUpdate } from './index-Cv4tmcrw.js';
|
|
2
|
+
import { aK as components, aJ as paths, W as InferContentType, aa as InferAssetType, a3 as InferSingleton } from './define-content-type-cEGjIwT5.js';
|
|
3
|
+
import { a as SchemaDefinition, b as SchemaContentTypeNames, j as SchemaEntryOf, ay as FilterOperator, h as SchemaAssetTypeNames, c as SchemaSingletonNames, g as SchemaSettingsGroupNames, I as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-BPj2srgh.js';
|
|
4
|
+
import { VisitorResyncReason } from './live-visitor.js';
|
|
4
5
|
import { DevUnreadableReason } from './dev-handshake/index.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -99,14 +100,21 @@ type SendOptions<P extends ApiPath, M extends ApiMethod<P>> = {
|
|
|
99
100
|
* nothing inside the SDK uses them.
|
|
100
101
|
*/
|
|
101
102
|
declare class HttpClient {
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
private timeout;
|
|
105
|
-
private retryPolicy;
|
|
106
|
-
private debug;
|
|
107
|
-
private logger?;
|
|
108
|
-
private config;
|
|
103
|
+
/** What every request reads off the configuration, derived by {@link configure} and nowhere else. */
|
|
104
|
+
private connection;
|
|
109
105
|
constructor(config: MergedRelyIOConfig);
|
|
106
|
+
/**
|
|
107
|
+
* Run on `config` from now on: every later request — whoever holds this client — is sent to its
|
|
108
|
+
* `baseUrl`, with its headers, key and dataset, its timeout and retries, through its `fetch`, and
|
|
109
|
+
* logged by its `debug` options.
|
|
110
|
+
*
|
|
111
|
+
* The client's own `updateConfig()` calls this rather than building a second client, so a
|
|
112
|
+
* `content()` or other sub-client taken before the update sends through the update too. Anything
|
|
113
|
+
* set on this client since it was last configured — `setDefaultHeaders()`, `setBaseUrl()` — is
|
|
114
|
+
* replaced by what `config` says.
|
|
115
|
+
*/
|
|
116
|
+
configure(config: MergedRelyIOConfig): void;
|
|
117
|
+
private announce;
|
|
110
118
|
/**
|
|
111
119
|
* Call a route the committed document declares, and get back the body that
|
|
112
120
|
* document says it serves.
|
|
@@ -129,13 +137,17 @@ declare class HttpClient {
|
|
|
129
137
|
*
|
|
130
138
|
* The loop always makes one attempt. The incumbent's `while (attempt <
|
|
131
139
|
* maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
|
|
132
|
-
*
|
|
140
|
+
* then accepted, and now refuses — and then dereferenced an unassigned
|
|
141
|
+
* `lastError`. `retryAttempts` is the most attempts, the first included; an
|
|
142
|
+
* `HttpClient` constructed directly is not validated, so the first attempt
|
|
143
|
+
* stays unconditional.
|
|
133
144
|
*
|
|
134
145
|
* A request that would carry no `X-API-Key` makes none: it rejects with
|
|
135
146
|
* `MissingApiKeyError` before `fetch` is called, is not retried, and names
|
|
136
147
|
* `apiKey`. This is where a client built without a key learns it — the
|
|
137
148
|
* constructor accepts one so that a module-scope client can be evaluated by a
|
|
138
|
-
* build that holds no key (REL-1120)
|
|
149
|
+
* build that holds no key (REL-1120) — and so does one whose `setApiKey` was
|
|
150
|
+
* given none.
|
|
139
151
|
*/
|
|
140
152
|
request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>>;
|
|
141
153
|
/**
|
|
@@ -159,13 +171,28 @@ declare class HttpClient {
|
|
|
159
171
|
*/
|
|
160
172
|
patch<T = unknown>(url: string, data?: unknown, params?: Record<string, unknown>): Promise<ApiResponse<T>>;
|
|
161
173
|
/**
|
|
162
|
-
*
|
|
174
|
+
* Add headers to every later request, each replacing any header of the same name — the name
|
|
175
|
+
* matched without regard to case — until the client is next configured.
|
|
163
176
|
*/
|
|
164
177
|
setDefaultHeaders(headers: Record<string, string>): void;
|
|
165
178
|
/**
|
|
166
|
-
*
|
|
179
|
+
* Replace the key every later request sends as `X-API-Key`, and the `apiKey` the configuration
|
|
180
|
+
* reports.
|
|
181
|
+
*
|
|
182
|
+
* The key is read the way construction reads it (`presentKey`): an absent, empty or blank key is
|
|
183
|
+
* no key, so the header is dropped and the next request is refused with `MissingApiKeyError`
|
|
184
|
+
* before anything is sent. A key header of any other spelling — one given in `headers` — goes
|
|
185
|
+
* too, from the headers sent and from the headers the configuration reports, so the old key is
|
|
186
|
+
* never sent beside the new one.
|
|
187
|
+
*
|
|
188
|
+
* The configuration is the one the owning `TypedRelyIOClient` holds (it hands its own to the
|
|
189
|
+
* constructor), so its `getConfig().apiKey` — what a surface reads to decide a key's kind — is the
|
|
190
|
+
* key sent from here on.
|
|
191
|
+
*
|
|
192
|
+
* This replaced `setAuthToken`, which added `Authorization: Bearer` beside an `X-API-Key` it
|
|
193
|
+
* never touched: the API reads `X-API-Key` first, so the old key was the one used (REL-1385).
|
|
167
194
|
*/
|
|
168
|
-
|
|
195
|
+
setApiKey(apiKey: string): void;
|
|
169
196
|
/**
|
|
170
197
|
* Get current default headers
|
|
171
198
|
*/
|
|
@@ -190,7 +217,12 @@ declare class HttpClient {
|
|
|
190
217
|
*/
|
|
191
218
|
private makeRequest;
|
|
192
219
|
/**
|
|
193
|
-
*
|
|
220
|
+
* The headers without those a browser controls itself, when this is a browser; unchanged when it
|
|
221
|
+
* is not.
|
|
222
|
+
*
|
|
223
|
+
* A name is matched without regard to case (RFC 9110 §5.1), because a browser refuses `Origin`
|
|
224
|
+
* whatever case a page spells it in. This matched only the all-lowercase and all-uppercase
|
|
225
|
+
* spellings, so `Origin` and `User-Agent` — how people write them — reached `fetch` (REL-1409).
|
|
194
226
|
*/
|
|
195
227
|
private filterHeadersForBrowser;
|
|
196
228
|
/**
|
|
@@ -205,6 +237,18 @@ declare class HttpClient {
|
|
|
205
237
|
private log;
|
|
206
238
|
}
|
|
207
239
|
|
|
240
|
+
/**
|
|
241
|
+
* The client's locale as a sub-client holds it: a function it asks on every call, or a locale fixed
|
|
242
|
+
* when it was built.
|
|
243
|
+
*
|
|
244
|
+
* `TypedRelyIOClient` hands every sub-client and builder a function over the configuration it holds,
|
|
245
|
+
* so one taken before `updateConfig({ locale })` sends the locale the client holds when the call is
|
|
246
|
+
* made, and none once `updateConfig({ locale: null })` has cleared it (REL-1453). A string is a locale
|
|
247
|
+
* fixed at construction — a sub-client's own `withLocale()`, or one built directly — and stays what it
|
|
248
|
+
* was.
|
|
249
|
+
*/
|
|
250
|
+
type ClientLocale = string | (() => string | undefined);
|
|
251
|
+
|
|
208
252
|
/**
|
|
209
253
|
* Children population options
|
|
210
254
|
*/
|
|
@@ -244,10 +288,9 @@ type ExtendedQueryResult<T extends BaseContent = BaseContent> = ContentQueryResu
|
|
|
244
288
|
* .execute()
|
|
245
289
|
* ```
|
|
246
290
|
*/
|
|
247
|
-
declare class ContentQueryBuilder<T extends BaseContent = BaseContent> {
|
|
291
|
+
declare class ContentQueryBuilder<T extends BaseContent = BaseContent, F extends BaseContent = T> {
|
|
248
292
|
private readonly httpClient;
|
|
249
293
|
private readonly contentType;
|
|
250
|
-
private readonly defaultLocale?;
|
|
251
294
|
private queryOptions;
|
|
252
295
|
private localeValue?;
|
|
253
296
|
private localesArray?;
|
|
@@ -257,7 +300,22 @@ declare class ContentQueryBuilder<T extends BaseContent = BaseContent> {
|
|
|
257
300
|
private pageNumber?;
|
|
258
301
|
private pageSizeValue?;
|
|
259
302
|
private requestHeaders?;
|
|
260
|
-
|
|
303
|
+
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
304
|
+
private readonly clientLocale;
|
|
305
|
+
private freshValue?;
|
|
306
|
+
/**
|
|
307
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when the
|
|
308
|
+
* query names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
309
|
+
*/
|
|
310
|
+
constructor(httpClient: HttpClient, contentType: string, locale?: ClientLocale);
|
|
311
|
+
/**
|
|
312
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
313
|
+
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
314
|
+
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
315
|
+
* the change, and every read naming the same position shares that answer. The answer is the
|
|
316
|
+
* read's own; omit it for a read no change prompted.
|
|
317
|
+
*/
|
|
318
|
+
fresh(position: string): this;
|
|
261
319
|
/**
|
|
262
320
|
* Headers this query adds to the client's own, e.g. `X-RelyIO-Dataset` to list another dataset
|
|
263
321
|
* the key can see. A name the client already sends is replaced for this query only; the client
|
|
@@ -265,13 +323,14 @@ declare class ContentQueryBuilder<T extends BaseContent = BaseContent> {
|
|
|
265
323
|
*/
|
|
266
324
|
headers(headers: Record<string, string>): this;
|
|
267
325
|
/**
|
|
268
|
-
* Add where conditions to the query
|
|
326
|
+
* Add where conditions to the query: conditions on the fields the content type declares. A
|
|
327
|
+
* condition on `_metadata` is refused here, before anything is sent (`refuseMetadataConditions`).
|
|
269
328
|
*/
|
|
270
|
-
where(conditions: WhereClause<
|
|
329
|
+
where(conditions: WhereClause<F>): this;
|
|
271
330
|
/**
|
|
272
331
|
* Select specific fields to return
|
|
273
332
|
*/
|
|
274
|
-
select(fields:
|
|
333
|
+
select(fields: NonNullable<QueryOptions<T, F>['select']>): this;
|
|
275
334
|
/**
|
|
276
335
|
* Include related content in the response
|
|
277
336
|
*/
|
|
@@ -289,7 +348,7 @@ declare class ContentQueryBuilder<T extends BaseContent = BaseContent> {
|
|
|
289
348
|
* ```
|
|
290
349
|
*/
|
|
291
350
|
sort(field: string, direction: 'asc' | 'desc'): this;
|
|
292
|
-
sort(sortOptions: SortOptions<
|
|
351
|
+
sort(sortOptions: SortOptions<F>): this;
|
|
293
352
|
/**
|
|
294
353
|
* Sort by a specific field in ascending order
|
|
295
354
|
*/
|
|
@@ -418,11 +477,11 @@ declare class ContentQueryBuilder<T extends BaseContent = BaseContent> {
|
|
|
418
477
|
/**
|
|
419
478
|
* Clone the query builder
|
|
420
479
|
*/
|
|
421
|
-
clone(): ContentQueryBuilder<T>;
|
|
480
|
+
clone(): ContentQueryBuilder<T, F>;
|
|
422
481
|
/**
|
|
423
482
|
* Get the current query options
|
|
424
483
|
*/
|
|
425
|
-
getQueryOptions(): QueryOptions<T>;
|
|
484
|
+
getQueryOptions(): QueryOptions<T, F>;
|
|
426
485
|
/**
|
|
427
486
|
* Execute the query and return the whole body.
|
|
428
487
|
*
|
|
@@ -459,14 +518,28 @@ declare class ContentByIdBuilder<T extends BaseContent = BaseContent> {
|
|
|
459
518
|
private readonly httpClient;
|
|
460
519
|
private readonly contentType;
|
|
461
520
|
private readonly id;
|
|
462
|
-
private readonly defaultLocale?;
|
|
463
521
|
private includeRelations?;
|
|
464
522
|
private localeValue?;
|
|
465
523
|
private localesArray?;
|
|
466
524
|
private fetchAllLocales;
|
|
467
525
|
private childrenOptions?;
|
|
468
526
|
private requestHeaders?;
|
|
469
|
-
|
|
527
|
+
/** The client's locale, asked when the read is sent rather than copied when it was built. */
|
|
528
|
+
private readonly clientLocale;
|
|
529
|
+
private freshValue?;
|
|
530
|
+
/**
|
|
531
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when the
|
|
532
|
+
* read names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
533
|
+
*/
|
|
534
|
+
constructor(httpClient: HttpClient, contentType: string, id: string, locale?: ClientLocale);
|
|
535
|
+
/**
|
|
536
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
537
|
+
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
538
|
+
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
539
|
+
* the change, and every read naming the same position shares that answer. The answer is the
|
|
540
|
+
* read's own; omit it for a read no change prompted.
|
|
541
|
+
*/
|
|
542
|
+
fresh(position: string): this;
|
|
470
543
|
/**
|
|
471
544
|
* Include related content in the response
|
|
472
545
|
*/
|
|
@@ -615,8 +688,13 @@ interface ContentFetchOptions<T extends BaseContent = BaseContent> {
|
|
|
615
688
|
declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
616
689
|
private readonly httpClient;
|
|
617
690
|
private readonly contentType;
|
|
618
|
-
|
|
619
|
-
|
|
691
|
+
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
692
|
+
private readonly clientLocale;
|
|
693
|
+
/**
|
|
694
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
695
|
+
* every call, or a locale fixed for this client
|
|
696
|
+
*/
|
|
697
|
+
constructor(httpClient: HttpClient, contentType: string, locale?: ClientLocale);
|
|
620
698
|
/**
|
|
621
699
|
* Create a new query builder for this content type
|
|
622
700
|
*/
|
|
@@ -683,7 +761,7 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
683
761
|
* @param options - Create options (slug, locale, parentId, sortOrder), and `headers` this one
|
|
684
762
|
* request adds — e.g. `{ 'X-RelyIO-Dataset': 'staging' }` to write a dataset other than the
|
|
685
763
|
* client's. They are sent, never put in the body; `idempotencyKey` still wins over an
|
|
686
|
-
* `Idempotency-Key` among them.
|
|
764
|
+
* `Idempotency-Key` among them. `locale` defaults to the client's own (`withLocale()`).
|
|
687
765
|
*/
|
|
688
766
|
create(data: CreateInput<T>, options?: {
|
|
689
767
|
slug?: string;
|
|
@@ -698,7 +776,8 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
698
776
|
* @param data - Fields to update
|
|
699
777
|
* @param options - Update options (slug, locale, parentId, sortOrder), and `headers` this one
|
|
700
778
|
* request adds, as for {@link create}. `ifMatch` and `idempotencyKey` win over the same
|
|
701
|
-
* header among them.
|
|
779
|
+
* header among them. `locale` defaults to the client's own, the locale whose entity tag
|
|
780
|
+
* {@link fetchOneWithTag} reads, so the tag it hands back is checked against the same locale.
|
|
702
781
|
*/
|
|
703
782
|
update(id: string, data: UpdateInput<T>, options?: {
|
|
704
783
|
slug?: string;
|
|
@@ -719,8 +798,9 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
719
798
|
* Get version history for one locale of an entry.
|
|
720
799
|
*
|
|
721
800
|
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
722
|
-
* schema default
|
|
723
|
-
* rather than another locale's rows. Every row names the
|
|
801
|
+
* client's own (`withLocale()`), else the schema default; no fallback is applied, and a locale
|
|
802
|
+
* with no history returns an empty array rather than another locale's rows. Every row names the
|
|
803
|
+
* locale it belongs to.
|
|
724
804
|
*/
|
|
725
805
|
versions(id: string, options?: {
|
|
726
806
|
limit?: number;
|
|
@@ -732,8 +812,8 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
732
812
|
/**
|
|
733
813
|
* Get a specific version of an entry.
|
|
734
814
|
*
|
|
735
|
-
* `locale` defaults to the
|
|
736
|
-
* different content in each one.
|
|
815
|
+
* `locale` defaults to the client's own (`withLocale()`), else the schema default. Version
|
|
816
|
+
* numbers are per locale, so version 2 is different content in each one.
|
|
737
817
|
*/
|
|
738
818
|
version(id: string, versionNumber: number, options?: {
|
|
739
819
|
locale?: string;
|
|
@@ -770,11 +850,12 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
770
850
|
*/
|
|
771
851
|
ofType<U extends BaseContent = BaseContent>(contentType: string): ContentClient<U>;
|
|
772
852
|
/**
|
|
773
|
-
* Create a new ContentClient with a different default locale
|
|
853
|
+
* Create a new ContentClient with a different default locale, fixed: an update of the client's
|
|
854
|
+
* locale (`updateConfig({ locale })`) does not reach it
|
|
774
855
|
*/
|
|
775
856
|
withLocale(locale: string): ContentClient<T>;
|
|
776
857
|
/**
|
|
777
|
-
* Get the
|
|
858
|
+
* Get the default locale as it is now: the client's, or the one `withLocale()` fixed
|
|
778
859
|
*/
|
|
779
860
|
getDefaultLocale(): string | undefined;
|
|
780
861
|
}
|
|
@@ -785,21 +866,40 @@ declare class ContentClient<T extends BaseContent = BaseContent> {
|
|
|
785
866
|
* A **thin customer-side mirror** of the realtime-contracts `FileErrorCode`
|
|
786
867
|
* (correction C6 — the SDK must not import the server/Studio contracts package).
|
|
787
868
|
* Keep the members in sync with `@relyio/realtime-contracts`.
|
|
869
|
+
*
|
|
870
|
+
* Written once, as values, because a processing failure's code arrives as a string the service
|
|
871
|
+
* stored and has to be recognised at runtime; `FileErrorCode` is read off this list. The module is
|
|
872
|
+
* internal — `errors/index.ts` does not re-export it — so the list is not a second public name for
|
|
873
|
+
* the type.
|
|
788
874
|
*/
|
|
789
|
-
|
|
875
|
+
declare const FILE_ERROR_CODES: readonly ["UPLOAD_TOO_LARGE", "UNSUPPORTED_MIME", "DIMENSION_OUT_OF_RANGE", "ASPECT_RATIO", "CORRUPT_FILE", "UNSUPPORTED_CODEC", "IMAGES_LIMIT_EXCEEDED", "STREAM_ENCODE_FAILED", "SCAN_INFECTED", "INTERNAL"];
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Upload/processing error taxonomy (plan 17, 00b Step 4): a customer-side mirror of the
|
|
879
|
+
* realtime-contracts `FileErrorCode`, read off the list in `./file-error-codes`.
|
|
880
|
+
*/
|
|
881
|
+
type FileErrorCode = (typeof FILE_ERROR_CODES)[number];
|
|
882
|
+
/**
|
|
883
|
+
* The code a {@link FileUploadError} carries: a {@link FileErrorCode}, or `PROCESSING_FAILED` for a
|
|
884
|
+
* processing failure this SDK cannot name — the service stored no code, as an image or file
|
|
885
|
+
* processing failure is stored today, or one this version of the SDK predates. What the service
|
|
886
|
+
* stored is in the error's `context.processingError` either way.
|
|
887
|
+
*/
|
|
888
|
+
type FileUploadErrorCode = FileErrorCode | 'PROCESSING_FAILED';
|
|
790
889
|
/**
|
|
791
890
|
* A failure during the upload protocol (presign / PUT / multipart / confirm) or
|
|
792
|
-
* surfaced by the server's processing pipeline. Carries a typed {@link
|
|
891
|
+
* surfaced by the server's processing pipeline. Carries a typed {@link FileUploadErrorCode}
|
|
793
892
|
* and a `retriable` hint so callers (and `upload()`'s bounded auto-retry) can
|
|
794
893
|
* decide whether to retry on the same entry.
|
|
795
894
|
*/
|
|
796
895
|
declare class FileUploadError extends SDKError {
|
|
797
|
-
readonly code:
|
|
896
|
+
readonly code: FileUploadErrorCode;
|
|
798
897
|
readonly retryable: boolean;
|
|
799
|
-
constructor(code:
|
|
898
|
+
constructor(code: FileUploadErrorCode, message: string, options?: {
|
|
800
899
|
retriable?: boolean;
|
|
801
900
|
statusCode?: number;
|
|
802
901
|
cause?: Error;
|
|
902
|
+
context?: Record<string, unknown>;
|
|
803
903
|
});
|
|
804
904
|
getUserMessage(): string;
|
|
805
905
|
}
|
|
@@ -837,73 +937,20 @@ type AssetVisibility = 'public' | 'protected' | 'private';
|
|
|
837
937
|
type FileStatus = 'pending_upload' | 'uploading' | 'processing' | 'ready' | 'failed';
|
|
838
938
|
/** Storage backend: `r2` = image + file kinds, `stream` = video kind. */
|
|
839
939
|
type FileBackend = 'r2' | 'stream';
|
|
840
|
-
/**
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
codec?: string;
|
|
855
|
-
bitrate?: number;
|
|
856
|
-
framerate?: number;
|
|
857
|
-
audioTracks?: unknown[];
|
|
858
|
-
};
|
|
859
|
-
pageCount?: number;
|
|
860
|
-
text?: string;
|
|
861
|
-
safety?: {
|
|
862
|
-
nsfwScore?: number;
|
|
863
|
-
flagged?: boolean;
|
|
864
|
-
categories?: string[];
|
|
865
|
-
};
|
|
866
|
-
[key: string]: unknown;
|
|
867
|
-
}
|
|
868
|
-
/** Customer-facing file binding block on an asset entry. */
|
|
869
|
-
interface AssetFileBlock {
|
|
870
|
-
status: FileStatus;
|
|
871
|
-
backend: FileBackend;
|
|
872
|
-
fileName: string;
|
|
873
|
-
mimeType?: string | null;
|
|
874
|
-
size?: number | null;
|
|
875
|
-
/** Advisory client-computed SHA-256 (duplicate detection only). */
|
|
876
|
-
hash?: string | null;
|
|
877
|
-
visibility: AssetVisibility;
|
|
878
|
-
extracted?: AssetFileExtracted;
|
|
879
|
-
/** 0..1 normalized smart-crop anchor (written by plan 18). */
|
|
880
|
-
focalPoint?: {
|
|
881
|
-
x: number;
|
|
882
|
-
y: number;
|
|
883
|
-
};
|
|
884
|
-
/** Phase-2 enrichment status — independent of `status` (plan 15). */
|
|
885
|
-
enrichment?: {
|
|
886
|
-
status: 'pending' | 'running' | 'complete' | 'partial' | 'failed';
|
|
887
|
-
};
|
|
888
|
-
/** File-kind malware scan status (plan 19). */
|
|
889
|
-
scan?: {
|
|
890
|
-
status: 'pending' | 'clean' | 'infected' | 'error' | 'skipped';
|
|
891
|
-
};
|
|
892
|
-
/** Processing progress (e.g. video encoding %) + terminal error. */
|
|
893
|
-
processing?: {
|
|
894
|
-
stage?: string;
|
|
895
|
-
progress?: number;
|
|
896
|
-
error?: {
|
|
897
|
-
code?: string;
|
|
898
|
-
message?: string;
|
|
899
|
-
retriable?: boolean;
|
|
900
|
-
};
|
|
901
|
-
};
|
|
902
|
-
/** Video playback readiness. */
|
|
903
|
-
playback?: {
|
|
904
|
-
ready?: boolean;
|
|
905
|
-
};
|
|
906
|
-
}
|
|
940
|
+
/**
|
|
941
|
+
* Customer-facing file binding block on an asset entry: the document's `AssetFile` — status,
|
|
942
|
+
* backend, file name, MIME type, size, advisory hash, visibility, extracted metadata, focal point,
|
|
943
|
+
* enrichment and scan status, processing stage/progress/error, and video playback readiness.
|
|
944
|
+
*/
|
|
945
|
+
type AssetFileBlock = components['schemas']['AssetFile'];
|
|
946
|
+
/** Extracted media metadata (Phase 1 basics + Phase 2 enrichment, plans 15–19); open-ended. */
|
|
947
|
+
type AssetFileExtracted = NonNullable<AssetFileBlock['extracted']>;
|
|
948
|
+
/**
|
|
949
|
+
* Where one file binding's upload got to, as {@link AssetFileBuilder.status} reads it
|
|
950
|
+
* (`GET /v1/{assetType}/{id}/file`): the document's `FileStatus` — the binding's lifecycle and
|
|
951
|
+
* nothing of the entry's content. `processing.error` is present exactly while `status` is `failed`.
|
|
952
|
+
*/
|
|
953
|
+
type FileStatusResult = components['schemas']['FileStatus'];
|
|
907
954
|
/**
|
|
908
955
|
* Computed gateway delivery URLs (the reserved `urls` key). Always served from
|
|
909
956
|
* `cdn.relyio.net`. Image bindings expose `original` + `variants`; video bindings
|
|
@@ -1036,9 +1083,12 @@ type UpdateAssetOptions = {
|
|
|
1036
1083
|
interface WaitUntilReadyOptions {
|
|
1037
1084
|
/** Locale of the binding to watch. */
|
|
1038
1085
|
locale?: string;
|
|
1039
|
-
/**
|
|
1086
|
+
/**
|
|
1087
|
+
* Total time to wait before giving up (ms), from 0 to 2147483647. Default 60000. `0` reads the
|
|
1088
|
+
* file once and rejects with a `TimeoutError` if it is not ready.
|
|
1089
|
+
*/
|
|
1040
1090
|
timeoutMs?: number;
|
|
1041
|
-
/** Delay between polls (ms). Default 1500. */
|
|
1091
|
+
/** Delay between polls (ms), from 1 to 2147483647. Default 1500. */
|
|
1042
1092
|
pollIntervalMs?: number;
|
|
1043
1093
|
}
|
|
1044
1094
|
/**
|
|
@@ -1049,8 +1099,13 @@ declare class AssetFileBuilder<T extends BaseContent = BaseContent> {
|
|
|
1049
1099
|
private readonly httpClient;
|
|
1050
1100
|
private readonly assetType;
|
|
1051
1101
|
private readonly entryUid;
|
|
1052
|
-
|
|
1053
|
-
|
|
1102
|
+
/** The client's locale, asked on every call rather than copied when this builder was taken. */
|
|
1103
|
+
private readonly clientLocale;
|
|
1104
|
+
/**
|
|
1105
|
+
* @param locale - The client's locale, sent when a call names none: the function
|
|
1106
|
+
* `TypedRelyIOClient` hands over, or a locale fixed for this builder
|
|
1107
|
+
*/
|
|
1108
|
+
constructor(httpClient: HttpClient, assetType: string, entryUid: string, locale?: ClientLocale);
|
|
1054
1109
|
/**
|
|
1055
1110
|
* The path parameters every `/file/*` route on this builder takes.
|
|
1056
1111
|
*
|
|
@@ -1060,6 +1115,12 @@ declare class AssetFileBuilder<T extends BaseContent = BaseContent> {
|
|
|
1060
1115
|
*/
|
|
1061
1116
|
private get target();
|
|
1062
1117
|
private withLocale;
|
|
1118
|
+
/**
|
|
1119
|
+
* The `locale` body field of a multipart call: the session's, else the client's. The API finds
|
|
1120
|
+
* the binding by it, so a session a `withLocale()` client opened must name the same locale on
|
|
1121
|
+
* every later call or its `objectKey` is refused as another binding's.
|
|
1122
|
+
*/
|
|
1123
|
+
private localeField;
|
|
1063
1124
|
/**
|
|
1064
1125
|
* Issue a single upload target — an R2 presigned PUT (image/file) or a
|
|
1065
1126
|
* Cloudflare Stream direct-creator URL (video). Resumable multipart is plan 17.
|
|
@@ -1096,6 +1157,18 @@ declare class AssetFileBuilder<T extends BaseContent = BaseContent> {
|
|
|
1096
1157
|
* Throws if the binding is not `ready`.
|
|
1097
1158
|
*/
|
|
1098
1159
|
url(input?: ResolveUrlInput): Promise<ResolveUrlResult>;
|
|
1160
|
+
/**
|
|
1161
|
+
* Read where this file's upload got to — `status`, and the processing stage, progress and error
|
|
1162
|
+
* the pipeline recorded — whatever the asset entry is published in.
|
|
1163
|
+
*
|
|
1164
|
+
* An asset is a draft until its file is ready, and stays one when its file fails, so a key that
|
|
1165
|
+
* reads published content finds no entry for an upload in flight or one that failed. This read
|
|
1166
|
+
* answers for the binding itself. It takes the capability the upload calls take, so a read-only
|
|
1167
|
+
* key is refused with `ReadOnlyKeyError`, and it never returns the entry's fields.
|
|
1168
|
+
*/
|
|
1169
|
+
status(options?: {
|
|
1170
|
+
locale?: string;
|
|
1171
|
+
}): Promise<FileStatusResult>;
|
|
1099
1172
|
/**
|
|
1100
1173
|
* Update the binding's delivery visibility (token-based; no byte relocation —
|
|
1101
1174
|
* a downgrade purges the gateway cache). Returns the refreshed asset entry.
|
|
@@ -1123,8 +1196,23 @@ declare class AssetFileBuilder<T extends BaseContent = BaseContent> {
|
|
|
1123
1196
|
locale?: string;
|
|
1124
1197
|
}): Promise<void>;
|
|
1125
1198
|
/**
|
|
1126
|
-
* Poll the asset entry until its file binding reaches `ready
|
|
1127
|
-
*
|
|
1199
|
+
* Poll the asset entry until its file binding reaches `ready`, and resolve with the ready entry.
|
|
1200
|
+
*
|
|
1201
|
+
* Each poll reads the entry through the key's lens. When that finds nothing — a key that reads
|
|
1202
|
+
* published content, and an asset that is a draft until its file is ready and stays one when it
|
|
1203
|
+
* fails — the poll reads the binding itself ({@link status}), so a failed upload rejects as one
|
|
1204
|
+
* rather than running out the limit (REL-1481).
|
|
1205
|
+
*
|
|
1206
|
+
* @throws {FileUploadError} When processing failed. `code` is the processing code the service
|
|
1207
|
+
* stored — `UNSUPPORTED_CODEC`, `CORRUPT_FILE` and so on — or `PROCESSING_FAILED` where it
|
|
1208
|
+
* stored none this SDK knows; `context.processingError` holds what it stored, and `retryable`
|
|
1209
|
+
* is its `retriable` hint.
|
|
1210
|
+
* @throws {TimeoutError} When `timeoutMs` passes first. The file may still become ready; the
|
|
1211
|
+
* error's `context.timeout` is the limit and `context.fileStatus` the status last seen. A file
|
|
1212
|
+
* that is `ready` in an asset the key's lens never shows — created with `publish: false`, or
|
|
1213
|
+
* awaiting a workflow — ends here too, and the message says so.
|
|
1214
|
+
* @throws {ReadOnlyKeyError} When the key's lens does not show the asset and the key may not read
|
|
1215
|
+
* its binding either: nothing it can read would ever report the file.
|
|
1128
1216
|
*/
|
|
1129
1217
|
waitUntilReady(options?: WaitUntilReadyOptions): Promise<AssetEntryResponse<T>>;
|
|
1130
1218
|
}
|
|
@@ -1139,7 +1227,6 @@ declare class AssetUploadBuilder<T extends BaseContent = BaseContent> {
|
|
|
1139
1227
|
private readonly httpClient;
|
|
1140
1228
|
private readonly assetType;
|
|
1141
1229
|
private readonly file;
|
|
1142
|
-
private readonly defaultLocale?;
|
|
1143
1230
|
private _fileName?;
|
|
1144
1231
|
private _visibility?;
|
|
1145
1232
|
private _locale?;
|
|
@@ -1151,7 +1238,13 @@ declare class AssetUploadBuilder<T extends BaseContent = BaseContent> {
|
|
|
1151
1238
|
private _onProgress?;
|
|
1152
1239
|
private _validate?;
|
|
1153
1240
|
private _maxPartRetries;
|
|
1154
|
-
|
|
1241
|
+
/** The client's locale, read once when the upload starts. */
|
|
1242
|
+
private readonly clientLocale;
|
|
1243
|
+
/**
|
|
1244
|
+
* @param locale - The client's locale, the upload's when `.locale()` names none: the function
|
|
1245
|
+
* `TypedRelyIOClient` hands over, or a locale fixed for this upload
|
|
1246
|
+
*/
|
|
1247
|
+
constructor(httpClient: HttpClient, assetType: string, file: Blob, locale?: ClientLocale);
|
|
1155
1248
|
/** Subscribe to client → storage upload progress (single PUT + multipart). */
|
|
1156
1249
|
onProgress(callback: (_progress: UploadProgress) => void): this;
|
|
1157
1250
|
/**
|
|
@@ -1173,7 +1266,12 @@ declare class AssetUploadBuilder<T extends BaseContent = BaseContent> {
|
|
|
1173
1266
|
content(content: Record<string, unknown>): this;
|
|
1174
1267
|
/** Set an explicit slug for the new entry. */
|
|
1175
1268
|
slug(slug: string): this;
|
|
1176
|
-
/**
|
|
1269
|
+
/**
|
|
1270
|
+
* Wait until the file binding becomes `ready` before resolving.
|
|
1271
|
+
*
|
|
1272
|
+
* @throws {Error} When `timeoutMs` or `pollIntervalMs` is one the wait cannot honour — refused
|
|
1273
|
+
* here, before anything is uploaded, rather than after the bytes are in.
|
|
1274
|
+
*/
|
|
1177
1275
|
waitForReady(options?: boolean | Omit<WaitUntilReadyOptions, 'locale'>): this;
|
|
1178
1276
|
/** Execute the full upload flow and resolve with the asset entry. */
|
|
1179
1277
|
execute(): Promise<AssetEntryResponse<T>>;
|
|
@@ -1197,10 +1295,18 @@ declare class AssetUploadBuilder<T extends BaseContent = BaseContent> {
|
|
|
1197
1295
|
declare class AssetClient<T extends BaseContent = BaseContent> {
|
|
1198
1296
|
private readonly httpClient;
|
|
1199
1297
|
private readonly assetType;
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
/**
|
|
1203
|
-
|
|
1298
|
+
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
1299
|
+
private readonly clientLocale;
|
|
1300
|
+
/**
|
|
1301
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
1302
|
+
* every call, or a locale fixed for this client
|
|
1303
|
+
*/
|
|
1304
|
+
constructor(httpClient: HttpClient, assetType: string, locale?: ClientLocale);
|
|
1305
|
+
/**
|
|
1306
|
+
* Create a query builder for this asset type. It resolves asset reads; its conditions name the
|
|
1307
|
+
* asset type's fields, which the `file` and `urls` blocks are not.
|
|
1308
|
+
*/
|
|
1309
|
+
query(): ContentQueryBuilder<AssetEntryResponse<T>, T>;
|
|
1204
1310
|
/** Find an asset entry by id (or slug) with fluent options. */
|
|
1205
1311
|
findById(id: string): ContentByIdBuilder<AssetEntryResponse<T>>;
|
|
1206
1312
|
/** Fetch a single asset entry by id (or slug), or `null` if not found. */
|
|
@@ -1209,14 +1315,18 @@ declare class AssetClient<T extends BaseContent = BaseContent> {
|
|
|
1209
1315
|
locale?: string;
|
|
1210
1316
|
}): Promise<AssetEntryResponse<T> | null>;
|
|
1211
1317
|
/** Fetch the first asset entry matching the conditions, or `null`. */
|
|
1212
|
-
fetchFirst(where?: WhereClause<
|
|
1318
|
+
fetchFirst(where?: WhereClause<T>, locale?: string): Promise<AssetEntryResponse<T> | null>;
|
|
1213
1319
|
/**
|
|
1214
1320
|
* Create a new asset entry as a draft. The binary is uploaded separately via
|
|
1215
1321
|
* `file(uid)` (or use the high-level `upload()` helper), and the entry
|
|
1216
1322
|
* auto-publishes when its file becomes ready (unless `publish: false`).
|
|
1323
|
+
* `locale` defaults to the client's own (`withLocale()`).
|
|
1217
1324
|
*/
|
|
1218
1325
|
create(data: CreateInput<T>, options?: CreateAssetOptions & RetryableWriteOptions): Promise<AssetEntryResponse<T>>;
|
|
1219
|
-
/**
|
|
1326
|
+
/**
|
|
1327
|
+
* Update an asset entry's metadata fields (and/or slug). `locale` defaults to the client's own
|
|
1328
|
+
* (`withLocale()`).
|
|
1329
|
+
*/
|
|
1220
1330
|
update(id: string, data: UpdateInput<T>, options?: UpdateAssetOptions): Promise<AssetEntryResponse<T>>;
|
|
1221
1331
|
/** Delete an asset entry (cascades file-byte cleanup + gateway purge). */
|
|
1222
1332
|
delete(id: string, options?: ConditionalWriteOptions): Promise<void>;
|
|
@@ -1226,9 +1336,12 @@ declare class AssetClient<T extends BaseContent = BaseContent> {
|
|
|
1226
1336
|
upload(file: Blob): AssetUploadBuilder<T>;
|
|
1227
1337
|
/** Get the asset type id. */
|
|
1228
1338
|
getAssetType(): string;
|
|
1229
|
-
/** Get the
|
|
1339
|
+
/** Get the default locale as it is now: the client's, or the one `withLocale()` fixed. */
|
|
1230
1340
|
getDefaultLocale(): string | undefined;
|
|
1231
|
-
/**
|
|
1341
|
+
/**
|
|
1342
|
+
* Create a new AssetClient for this type with a different default locale, fixed: an update of the
|
|
1343
|
+
* client's locale (`updateConfig({ locale })`) does not reach it.
|
|
1344
|
+
*/
|
|
1232
1345
|
withLocale(locale: string): AssetClient<T>;
|
|
1233
1346
|
}
|
|
1234
1347
|
/**
|
|
@@ -1258,13 +1371,21 @@ interface SingletonFetchOptions {
|
|
|
1258
1371
|
locale?: string;
|
|
1259
1372
|
/** Reference fields to populate */
|
|
1260
1373
|
include?: string[];
|
|
1374
|
+
/**
|
|
1375
|
+
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
1376
|
+
* `?_fresh`: no cache holds an answer for it from before that position, so the read is answered
|
|
1377
|
+
* after the change. The answer is the read's own; omit it for a read no change prompted.
|
|
1378
|
+
*/
|
|
1379
|
+
fresh?: string;
|
|
1261
1380
|
}
|
|
1262
1381
|
/**
|
|
1263
1382
|
* Singleton client for managing singleton content operations
|
|
1264
1383
|
* Provides a fluent API for singleton operations following the same pattern as ContentClient
|
|
1265
1384
|
*
|
|
1266
|
-
*
|
|
1267
|
-
* `
|
|
1385
|
+
* Every call is in the locale it names — the argument (`fetch({ locale })`, `update(data, locale)`,
|
|
1386
|
+
* `versions({ locale })`), then `.locale()` — and otherwise in the client's own (`withLocale()`,
|
|
1387
|
+
* `updateConfig({ locale })`) as it is when the call is made, as `content()`'s are: reads, the write,
|
|
1388
|
+
* and version history alike.
|
|
1268
1389
|
*
|
|
1269
1390
|
* @example
|
|
1270
1391
|
* ```typescript
|
|
@@ -1277,10 +1398,15 @@ interface SingletonFetchOptions {
|
|
|
1277
1398
|
declare class SingletonClient<T = unknown> {
|
|
1278
1399
|
private httpClient;
|
|
1279
1400
|
private singletonKey;
|
|
1280
|
-
private readonly defaultLocale?;
|
|
1281
1401
|
private includeFields?;
|
|
1282
1402
|
private localeValue?;
|
|
1283
|
-
|
|
1403
|
+
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
1404
|
+
private readonly clientLocale;
|
|
1405
|
+
/**
|
|
1406
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
1407
|
+
* every call, or a locale fixed for this client
|
|
1408
|
+
*/
|
|
1409
|
+
constructor(httpClient: HttpClient, singletonKey: string, locale?: ClientLocale);
|
|
1284
1410
|
/**
|
|
1285
1411
|
* Include reference fields in the response
|
|
1286
1412
|
* @param fields - Reference field names to populate
|
|
@@ -1311,7 +1437,8 @@ declare class SingletonClient<T = unknown> {
|
|
|
1311
1437
|
* Update singleton content. The API auto-publishes on PATCH — there is no
|
|
1312
1438
|
* separate publish route; calling `update()` writes and publishes.
|
|
1313
1439
|
* @param data - The content fields to update
|
|
1314
|
-
* @param locale - Optional locale for localized content (overrides fluent locale
|
|
1440
|
+
* @param locale - Optional locale for localized content (overrides the fluent locale, which
|
|
1441
|
+
* overrides the client's own)
|
|
1315
1442
|
* @param options - `If-Match` / `Idempotency-Key`, both declared on this route
|
|
1316
1443
|
*/
|
|
1317
1444
|
update(data: Partial<T>, locale?: string, options?: ConditionalWriteOptions): Promise<T>;
|
|
@@ -1323,8 +1450,9 @@ declare class SingletonClient<T = unknown> {
|
|
|
1323
1450
|
* Get version history for one locale of the singleton.
|
|
1324
1451
|
*
|
|
1325
1452
|
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1453
|
+
* fluent `.locale()`, then the client's own (`withLocale()`), then the schema default; no
|
|
1454
|
+
* fallback is applied, and a locale with no history returns an empty array rather than another
|
|
1455
|
+
* locale's rows. Every row names the locale it belongs to.
|
|
1328
1456
|
*/
|
|
1329
1457
|
versions(options?: {
|
|
1330
1458
|
limit?: number;
|
|
@@ -1336,12 +1464,14 @@ declare class SingletonClient<T = unknown> {
|
|
|
1336
1464
|
/**
|
|
1337
1465
|
* Get a specific version of the singleton.
|
|
1338
1466
|
*
|
|
1339
|
-
* `locale` defaults to the
|
|
1340
|
-
* different content in each one.
|
|
1467
|
+
* `locale` defaults to the fluent `.locale()`, then the client's own (`withLocale()`), then the
|
|
1468
|
+
* schema default. Version numbers are per locale, so version 2 is different content in each one.
|
|
1341
1469
|
*/
|
|
1342
1470
|
version(versionNumber: number, options?: {
|
|
1343
1471
|
locale?: string;
|
|
1344
1472
|
}): Promise<T | null>;
|
|
1473
|
+
/** The locale a write or history read sends: the call's, the fluent one, else the client's. */
|
|
1474
|
+
private localeOf;
|
|
1345
1475
|
/**
|
|
1346
1476
|
* Get the singleton key
|
|
1347
1477
|
*/
|
|
@@ -1365,8 +1495,10 @@ interface SettingsFetchOptions {
|
|
|
1365
1495
|
* Settings client for managing settings group operations
|
|
1366
1496
|
* Provides a fluent API for settings operations following the same pattern as ContentClient
|
|
1367
1497
|
*
|
|
1368
|
-
*
|
|
1369
|
-
* `
|
|
1498
|
+
* Every call is in the locale it names — the argument (`fetch({ locale })`, `update(settings,
|
|
1499
|
+
* locale)`, `reset(locale)`, `versions({ locale })`), then `.locale()` — and otherwise in the
|
|
1500
|
+
* client's own (`withLocale()`, `updateConfig({ locale })`) as it is when the call is made, as
|
|
1501
|
+
* `content()`'s are: reads, writes and version history alike.
|
|
1370
1502
|
*
|
|
1371
1503
|
* @example
|
|
1372
1504
|
* ```typescript
|
|
@@ -1379,10 +1511,15 @@ interface SettingsFetchOptions {
|
|
|
1379
1511
|
declare class SettingsClient<T = unknown> {
|
|
1380
1512
|
private readonly httpClient;
|
|
1381
1513
|
private readonly groupId;
|
|
1382
|
-
private readonly defaultLocale?;
|
|
1383
1514
|
private includeFields?;
|
|
1384
1515
|
private localeValue?;
|
|
1385
|
-
|
|
1516
|
+
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
1517
|
+
private readonly clientLocale;
|
|
1518
|
+
/**
|
|
1519
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
1520
|
+
* every call, or a locale fixed for this client
|
|
1521
|
+
*/
|
|
1522
|
+
constructor(httpClient: HttpClient, groupId: string, locale?: ClientLocale);
|
|
1386
1523
|
/**
|
|
1387
1524
|
* Include reference fields in the response
|
|
1388
1525
|
* @param fields - Reference field names to populate
|
|
@@ -1400,8 +1537,13 @@ declare class SettingsClient<T = unknown> {
|
|
|
1400
1537
|
fetch(options?: SettingsFetchOptions): Promise<T | null>;
|
|
1401
1538
|
/**
|
|
1402
1539
|
* Update settings group
|
|
1540
|
+
*
|
|
1541
|
+
* The fields travel as `content` beside an optional `locale`, the body the route validates
|
|
1542
|
+
* (`UpdateSettingsDto`); any other top-level key is refused `REQUEST_INVALID`.
|
|
1543
|
+
*
|
|
1403
1544
|
* @param settings - The settings fields to update
|
|
1404
|
-
* @param locale - Optional locale for localized settings (overrides fluent locale
|
|
1545
|
+
* @param locale - Optional locale for localized settings (overrides the fluent locale, which
|
|
1546
|
+
* overrides the client's own)
|
|
1405
1547
|
*/
|
|
1406
1548
|
update(settings: Partial<T>, locale?: string, options?: ConditionalWriteOptions): Promise<T>;
|
|
1407
1549
|
/**
|
|
@@ -1415,7 +1557,11 @@ declare class SettingsClient<T = unknown> {
|
|
|
1415
1557
|
}>;
|
|
1416
1558
|
/**
|
|
1417
1559
|
* Reset settings to default values
|
|
1418
|
-
*
|
|
1560
|
+
*
|
|
1561
|
+
* The route reads its locale from `?locale=` and takes no body, so that is where it is sent.
|
|
1562
|
+
*
|
|
1563
|
+
* @param locale - Optional locale for localized settings (overrides the fluent locale, which
|
|
1564
|
+
* overrides the client's own)
|
|
1419
1565
|
*/
|
|
1420
1566
|
reset(locale?: string, options?: ConditionalWriteOptions): Promise<T>;
|
|
1421
1567
|
/**
|
|
@@ -1430,8 +1576,9 @@ declare class SettingsClient<T = unknown> {
|
|
|
1430
1576
|
* Get version history for one locale of the settings group.
|
|
1431
1577
|
*
|
|
1432
1578
|
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
1433
|
-
*
|
|
1434
|
-
*
|
|
1579
|
+
* fluent `.locale()`, then the client's own (`withLocale()`), then the schema default; no
|
|
1580
|
+
* fallback is applied, and a locale with no history returns an empty array rather than another
|
|
1581
|
+
* locale's rows. Every row names the locale it belongs to.
|
|
1435
1582
|
*/
|
|
1436
1583
|
versions(options?: {
|
|
1437
1584
|
limit?: number;
|
|
@@ -1443,12 +1590,14 @@ declare class SettingsClient<T = unknown> {
|
|
|
1443
1590
|
/**
|
|
1444
1591
|
* Get a specific version of the settings.
|
|
1445
1592
|
*
|
|
1446
|
-
* `locale` defaults to the
|
|
1447
|
-
* different content in each one.
|
|
1593
|
+
* `locale` defaults to the fluent `.locale()`, then the client's own (`withLocale()`), then the
|
|
1594
|
+
* schema default. Version numbers are per locale, so version 2 is different content in each one.
|
|
1448
1595
|
*/
|
|
1449
1596
|
version(versionNumber: number, options?: {
|
|
1450
1597
|
locale?: string;
|
|
1451
1598
|
}): Promise<T | null>;
|
|
1599
|
+
/** The locale a write or history read sends: the call's, the fluent one, else the client's. */
|
|
1600
|
+
private localeOf;
|
|
1452
1601
|
/**
|
|
1453
1602
|
* Get the settings group ID
|
|
1454
1603
|
*/
|
|
@@ -1499,17 +1648,27 @@ type RegisteredSchema = Register extends {
|
|
|
1499
1648
|
*/
|
|
1500
1649
|
type SearchMode = 'keyword' | 'semantic' | 'hybrid';
|
|
1501
1650
|
/**
|
|
1502
|
-
*
|
|
1503
|
-
*
|
|
1651
|
+
* What a search or similar hit reports beside its fields: the committed document's
|
|
1652
|
+
* `SearchHitMetadata`, read through `http/api-schema.ts`.
|
|
1653
|
+
*
|
|
1654
|
+
* Narrower than an entry read's `EntryMetadata`, because a hit is not built by the entry read: it
|
|
1655
|
+
* carries no `entryType`, `defaultLocale`, `availableLocales`, `refs`, `firstPublishedAt` or
|
|
1656
|
+
* version history. Until REL-1413 a hit was typed as an entry and so promised all five — the
|
|
1657
|
+
* locale helpers kept an optional chain after `availableLocales` for the hits that lacked it. Read
|
|
1658
|
+
* the entry (`content(type).findById(hit._metadata.id)`) for those.
|
|
1659
|
+
*/
|
|
1660
|
+
type SearchHitMetadata = components['schemas']['SearchHitMetadata'];
|
|
1661
|
+
/** What a hit carries beside the entry's fields, as the document declares it. */
|
|
1662
|
+
type SearchHitSystemFields = Pick<components['schemas']['SearchHit'], '_metadata' | '_score' | '_scoreBreakdown' | '_highlights'>;
|
|
1663
|
+
/**
|
|
1664
|
+
* One search hit as the route emits it — the document's `SearchHit`: the fields `T` declares at the
|
|
1665
|
+
* top level (at `_metadata.locale`, or only the aliases a `fields` projection names), the hit's own
|
|
1666
|
+
* `_metadata`, and the score annotations the request asked for. There is no per-item `data` wrapper.
|
|
1667
|
+
*
|
|
1668
|
+
* `T`'s `_metadata` is replaced, not kept: `T` is an entry type, and a hit is not an entry read.
|
|
1669
|
+
* Distributes over a union of entry types, so a search across two types keeps each one's fields.
|
|
1504
1670
|
*/
|
|
1505
|
-
type SearchResultItem<T = unknown> = T &
|
|
1506
|
-
_score?: number;
|
|
1507
|
-
_scoreBreakdown?: {
|
|
1508
|
-
keyword?: number;
|
|
1509
|
-
semantic?: number;
|
|
1510
|
-
};
|
|
1511
|
-
_highlights?: Record<string, string[]>;
|
|
1512
|
-
};
|
|
1671
|
+
type SearchResultItem<T = unknown> = T extends unknown ? Omit<T, '_metadata'> & SearchHitSystemFields : never;
|
|
1513
1672
|
/**
|
|
1514
1673
|
* Search response from API
|
|
1515
1674
|
*/
|
|
@@ -1529,20 +1688,12 @@ type SearchResultItem<T = unknown> = T & {
|
|
|
1529
1688
|
*/
|
|
1530
1689
|
type SearchResponse<T = unknown> = Wire<'/v1/search', 'post', SearchResultItem<T>>;
|
|
1531
1690
|
/**
|
|
1532
|
-
*
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
highlighted?: string;
|
|
1539
|
-
/** Score */
|
|
1540
|
-
score?: number;
|
|
1541
|
-
/** Source entry ID */
|
|
1542
|
-
entryId?: string;
|
|
1543
|
-
/** Content type */
|
|
1544
|
-
contentType?: string;
|
|
1545
|
-
}
|
|
1691
|
+
* One autocomplete suggestion — the document's `AutocompleteSuggestion`: the value, its best score,
|
|
1692
|
+
* an entry holding it (`id`), and the value with its match wrapped in `<em>` when Atlas highlighted
|
|
1693
|
+
* it. The hand-written type this replaces named `highlighted`, `entryId` and `contentType`, none of
|
|
1694
|
+
* which the route sends, and made `score` optional where it is always sent.
|
|
1695
|
+
*/
|
|
1696
|
+
type AutocompleteSuggestion = components['schemas']['AutocompleteSuggestion'];
|
|
1546
1697
|
/**
|
|
1547
1698
|
* Autocomplete response
|
|
1548
1699
|
*/
|
|
@@ -1555,11 +1706,10 @@ interface AutocompleteSuggestion {
|
|
|
1555
1706
|
*/
|
|
1556
1707
|
type AutocompleteResponse = Wire<'/v1/search/autocomplete', 'post', AutocompleteSuggestion>;
|
|
1557
1708
|
/**
|
|
1558
|
-
* One similar-content hit as the route emits it
|
|
1709
|
+
* One similar-content hit as the route emits it: the same `SearchHit` a search serves, built by
|
|
1710
|
+
* the same transform, with `_score` on every hit.
|
|
1559
1711
|
*/
|
|
1560
|
-
type SimilarResult<T = unknown> = T
|
|
1561
|
-
_score?: number;
|
|
1562
|
-
};
|
|
1712
|
+
type SimilarResult<T = unknown> = SearchResultItem<T>;
|
|
1563
1713
|
/**
|
|
1564
1714
|
* Similar response
|
|
1565
1715
|
*/
|
|
@@ -1610,19 +1760,28 @@ interface SearchSort {
|
|
|
1610
1760
|
*/
|
|
1611
1761
|
declare class SearchBuilder<T extends BaseContent = BaseContent, S extends AnySchemaDefinition | undefined = undefined> {
|
|
1612
1762
|
private readonly httpClient;
|
|
1613
|
-
private readonly defaultLocale?;
|
|
1614
1763
|
private query;
|
|
1615
1764
|
private searchOptions;
|
|
1616
1765
|
private requestHeaders?;
|
|
1766
|
+
private freshValue?;
|
|
1767
|
+
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
1768
|
+
private readonly clientLocale;
|
|
1617
1769
|
/**
|
|
1618
|
-
* @param
|
|
1770
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
1771
|
+
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
1619
1772
|
*/
|
|
1620
|
-
constructor(httpClient: HttpClient, query: string,
|
|
1773
|
+
constructor(httpClient: HttpClient, query: string, locale?: ClientLocale);
|
|
1621
1774
|
/**
|
|
1622
1775
|
* Headers this search adds to the client's own, e.g. `X-RelyIO-Dataset` to search another
|
|
1623
1776
|
* dataset the key can see. A name the client already sends is replaced for this search only.
|
|
1624
1777
|
*/
|
|
1625
1778
|
headers(headers: Record<string, string>): this;
|
|
1779
|
+
/**
|
|
1780
|
+
* The feed position this search follows — a change's `fresh` (`FeedChange`), or a resync's. Sent
|
|
1781
|
+
* as `?_fresh` on the query string beside the body: the edge keys a search on both, so no answer
|
|
1782
|
+
* it holds from before that position can answer it. The answer is the search's own.
|
|
1783
|
+
*/
|
|
1784
|
+
fresh(position: string): this;
|
|
1626
1785
|
/**
|
|
1627
1786
|
* Search within a single content type. Where a schema types the client, the name is one of its
|
|
1628
1787
|
* content types and the results are that type's entries.
|
|
@@ -1636,7 +1795,8 @@ declare class SearchBuilder<T extends BaseContent = BaseContent, S extends AnySc
|
|
|
1636
1795
|
*/
|
|
1637
1796
|
across<K extends SearchTypeName<S>>(contentTypes: K[] | '*'): SearchBuilder<SearchEntry<S, K, T>, S>;
|
|
1638
1797
|
/**
|
|
1639
|
-
* Add filter conditions
|
|
1798
|
+
* Add filter conditions, on the fields the content types declare. A condition on `_metadata` is
|
|
1799
|
+
* refused here, before anything is sent.
|
|
1640
1800
|
* @param conditions - Filter conditions
|
|
1641
1801
|
*/
|
|
1642
1802
|
where(conditions: SearchFilter): this;
|
|
@@ -1708,13 +1868,15 @@ declare class SearchBuilder<T extends BaseContent = BaseContent, S extends AnySc
|
|
|
1708
1868
|
*/
|
|
1709
1869
|
declare class AutocompleteBuilder {
|
|
1710
1870
|
private readonly httpClient;
|
|
1711
|
-
private readonly defaultLocale?;
|
|
1712
1871
|
private query;
|
|
1713
1872
|
private autocompleteOptions;
|
|
1873
|
+
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
1874
|
+
private readonly clientLocale;
|
|
1714
1875
|
/**
|
|
1715
|
-
* @param
|
|
1876
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
1877
|
+
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
1716
1878
|
*/
|
|
1717
|
-
constructor(httpClient: HttpClient, query: string,
|
|
1879
|
+
constructor(httpClient: HttpClient, query: string, locale?: ClientLocale);
|
|
1718
1880
|
/**
|
|
1719
1881
|
* Autocomplete within a content type
|
|
1720
1882
|
* @param contentType - Content type to search
|
|
@@ -1730,7 +1892,8 @@ declare class AutocompleteBuilder {
|
|
|
1730
1892
|
*/
|
|
1731
1893
|
fuzzy(): this;
|
|
1732
1894
|
/**
|
|
1733
|
-
* Add filter conditions
|
|
1895
|
+
* Add filter conditions, on the fields the content types declare. A condition on `_metadata` is
|
|
1896
|
+
* refused here, before anything is sent.
|
|
1734
1897
|
* @param conditions - Filter conditions
|
|
1735
1898
|
*/
|
|
1736
1899
|
where(conditions: SearchFilter): this;
|
|
@@ -1767,14 +1930,16 @@ declare class AutocompleteBuilder {
|
|
|
1767
1930
|
*/
|
|
1768
1931
|
declare class SimilarBuilder<T extends BaseContent = BaseContent> {
|
|
1769
1932
|
private readonly httpClient;
|
|
1770
|
-
private readonly defaultLocale?;
|
|
1771
1933
|
private sourceId;
|
|
1772
1934
|
private similarOptions;
|
|
1773
1935
|
private requestHeaders?;
|
|
1936
|
+
/** The client's locale, asked when the read is sent rather than copied when it was built. */
|
|
1937
|
+
private readonly clientLocale;
|
|
1774
1938
|
/**
|
|
1775
|
-
* @param
|
|
1939
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
1940
|
+
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
1776
1941
|
*/
|
|
1777
|
-
constructor(httpClient: HttpClient, sourceId: string,
|
|
1942
|
+
constructor(httpClient: HttpClient, sourceId: string, locale?: ClientLocale);
|
|
1778
1943
|
/**
|
|
1779
1944
|
* Headers this read adds to the client's own, e.g. `X-RelyIO-Dataset` to read another dataset
|
|
1780
1945
|
* the key can see. A name the client already sends is replaced for this read only.
|
|
@@ -1790,11 +1955,6 @@ declare class SimilarBuilder<T extends BaseContent = BaseContent> {
|
|
|
1790
1955
|
* @param contentTypes - Array of content types or '*' for all
|
|
1791
1956
|
*/
|
|
1792
1957
|
across(contentTypes: string[] | '*'): this;
|
|
1793
|
-
/**
|
|
1794
|
-
* Add filter conditions
|
|
1795
|
-
* @param conditions - Filter conditions
|
|
1796
|
-
*/
|
|
1797
|
-
where(conditions: SearchFilter): this;
|
|
1798
1958
|
/**
|
|
1799
1959
|
* Limit number of results
|
|
1800
1960
|
* @param count - Maximum results
|
|
@@ -1845,12 +2005,14 @@ declare class SimilarBuilder<T extends BaseContent = BaseContent> {
|
|
|
1845
2005
|
*/
|
|
1846
2006
|
declare class SearchClient {
|
|
1847
2007
|
private readonly httpClient;
|
|
1848
|
-
|
|
2008
|
+
/** The client's locale, handed to every builder here to ask when it sends. */
|
|
2009
|
+
private readonly clientLocale;
|
|
1849
2010
|
/**
|
|
1850
|
-
* @param
|
|
1851
|
-
* the query names none, as `content()`'s reads do
|
|
2011
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`): every builder
|
|
2012
|
+
* here sends it when the query names none, as `content()`'s reads do — the function
|
|
2013
|
+
* `TypedRelyIOClient` hands over, or a locale fixed for this client
|
|
1852
2014
|
*/
|
|
1853
|
-
constructor(httpClient: HttpClient,
|
|
2015
|
+
constructor(httpClient: HttpClient, locale?: ClientLocale);
|
|
1854
2016
|
/**
|
|
1855
2017
|
* Start a search query
|
|
1856
2018
|
* @param query - Search query string
|
|
@@ -1866,12 +2028,6 @@ declare class SearchClient {
|
|
|
1866
2028
|
* @param sourceId - Entry ID to find similar content for
|
|
1867
2029
|
*/
|
|
1868
2030
|
similar<T extends BaseContent = BaseContent>(sourceId: string): SimilarBuilder<T>;
|
|
1869
|
-
/**
|
|
1870
|
-
* Quick search helper - searches all content types
|
|
1871
|
-
* @param query - Search query
|
|
1872
|
-
* @param limit - Max results (default 20)
|
|
1873
|
-
*/
|
|
1874
|
-
global<T extends BaseContent = BaseContent>(query: string, limit?: number): Promise<SearchResponse<T>>;
|
|
1875
2031
|
}
|
|
1876
2032
|
|
|
1877
2033
|
/**
|
|
@@ -1900,7 +2056,10 @@ interface BatchOptions {
|
|
|
1900
2056
|
*
|
|
1901
2057
|
* Requires that all operations be the same kind of write — one transaction cannot span two
|
|
1902
2058
|
* calls — so a batch mixing creates and deletes, or `update` and `replace`, is rejected with
|
|
1903
|
-
* a 400 before anything is attempted
|
|
2059
|
+
* a 400 before anything is attempted: `execute()` rejects with `InvalidPayloadError`. A
|
|
2060
|
+
* singleton write is a create when the dataset has never written that singleton and an update
|
|
2061
|
+
* after, and an atomic batch cannot create one — that operation reports `REQUEST_INVALID` and
|
|
2062
|
+
* every other `TRANSACTION_ROLLED_BACK` — so create it in a request of its own first.
|
|
1904
2063
|
*
|
|
1905
2064
|
* @default false
|
|
1906
2065
|
*/
|
|
@@ -1958,16 +2117,33 @@ type BatchResponse = components['schemas']['MultiPayload'];
|
|
|
1958
2117
|
/**
|
|
1959
2118
|
* Fluent builder for batch operations
|
|
1960
2119
|
*
|
|
2120
|
+
* Every create, update, replace and singleton operation it builds is in the locale that operation
|
|
2121
|
+
* names, and otherwise in the client's own (`withLocale()`), sent as that operation's
|
|
2122
|
+
* `body.locale` — a batch is one request, but the API reads a locale per operation. A delete names
|
|
2123
|
+
* none (it removes the whole entry), and a `raw()` operation is sent exactly as written.
|
|
2124
|
+
*
|
|
2125
|
+
* An atomic batch — `.atomic()` or `execute({ atomic: true })` — is one transaction: every
|
|
2126
|
+
* operation lands or none does. The API accepts one only when every operation is the same kind of
|
|
2127
|
+
* write and none writes a singleton that does not exist yet (see {@link BatchOptions.atomic}).
|
|
2128
|
+
*
|
|
1961
2129
|
* @example
|
|
1962
2130
|
* ```typescript
|
|
2131
|
+
* // Each operation lands or fails on its own
|
|
1963
2132
|
* const result = await relyio.batch()
|
|
1964
2133
|
* .create('product', { content: { title: 'iPhone', price: 999 } })
|
|
1965
2134
|
* .update('product', 'entry_abc', { content: { price: 899 } })
|
|
1966
2135
|
* .delete('product', 'entry_xyz')
|
|
1967
2136
|
* .upsertSingleton('homepage', { content: { hero: 'Welcome!' } })
|
|
1968
|
-
* .execute(
|
|
2137
|
+
* .execute()
|
|
2138
|
+
*
|
|
2139
|
+
* console.log(result.summary.succeeded)
|
|
1969
2140
|
*
|
|
1970
|
-
*
|
|
2141
|
+
* // All or nothing: one kind of write
|
|
2142
|
+
* await relyio.batch()
|
|
2143
|
+
* .create('product', { content: { title: 'iPhone', price: 999 } })
|
|
2144
|
+
* .create('product', { content: { title: 'iPad', price: 799 } })
|
|
2145
|
+
* .atomic()
|
|
2146
|
+
* .execute()
|
|
1971
2147
|
* ```
|
|
1972
2148
|
*/
|
|
1973
2149
|
declare class BatchBuilder<TSchema = unknown> {
|
|
@@ -1975,7 +2151,19 @@ declare class BatchBuilder<TSchema = unknown> {
|
|
|
1975
2151
|
private operations;
|
|
1976
2152
|
private defaultOptions;
|
|
1977
2153
|
private requestHeaders;
|
|
1978
|
-
|
|
2154
|
+
/** The client's locale, asked as each operation is added rather than copied when this was built. */
|
|
2155
|
+
private readonly clientLocale;
|
|
2156
|
+
/**
|
|
2157
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), each
|
|
2158
|
+
* operation's when it names none: the function `TypedRelyIOClient` hands over, or a locale fixed
|
|
2159
|
+
* for this batch
|
|
2160
|
+
*/
|
|
2161
|
+
constructor(httpClient: HttpClient, locale?: ClientLocale);
|
|
2162
|
+
/**
|
|
2163
|
+
* An operation's body with its locale: the one it names, else the client's as it is when the
|
|
2164
|
+
* operation is added.
|
|
2165
|
+
*/
|
|
2166
|
+
private localized;
|
|
1979
2167
|
/**
|
|
1980
2168
|
* Add a create operation
|
|
1981
2169
|
* @param contentType - Content type to create
|
|
@@ -2053,7 +2241,8 @@ declare class BatchBuilder<TSchema = unknown> {
|
|
|
2053
2241
|
locale?: string;
|
|
2054
2242
|
}, id?: string): this;
|
|
2055
2243
|
/**
|
|
2056
|
-
* Add a raw operation (for advanced use cases)
|
|
2244
|
+
* Add a raw operation (for advanced use cases). It is sent exactly as written: the client's
|
|
2245
|
+
* locale is not added to it.
|
|
2057
2246
|
* @param operation - The operation to add
|
|
2058
2247
|
*/
|
|
2059
2248
|
raw(operation: BatchOperation): this;
|
|
@@ -2170,9 +2359,15 @@ declare class BatchBuilder<TSchema = unknown> {
|
|
|
2170
2359
|
*/
|
|
2171
2360
|
declare class BatchClient<TSchema = unknown> {
|
|
2172
2361
|
private readonly httpClient;
|
|
2173
|
-
|
|
2362
|
+
/** The client's locale, handed to every batch this builds to ask as operations are added. */
|
|
2363
|
+
private readonly clientLocale;
|
|
2364
|
+
/**
|
|
2365
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, or a locale
|
|
2366
|
+
* fixed for this client
|
|
2367
|
+
*/
|
|
2368
|
+
constructor(httpClient: HttpClient, locale?: ClientLocale);
|
|
2174
2369
|
/**
|
|
2175
|
-
* Create a new batch builder
|
|
2370
|
+
* Create a new batch builder, whose operations default to this client's locale
|
|
2176
2371
|
*/
|
|
2177
2372
|
create(): BatchBuilder<TSchema>;
|
|
2178
2373
|
/**
|
|
@@ -2251,13 +2446,14 @@ interface AggregateBlock {
|
|
|
2251
2446
|
}
|
|
2252
2447
|
/**
|
|
2253
2448
|
* One metric, as the Query DSL writes it: `<field>.<fn>`, where `fn` is `count`, `sum`, `avg`,
|
|
2254
|
-
* `min` or `
|
|
2255
|
-
* against that form (`INVALID_AGGREGATION_EXPRESSION`); `count` ignores the
|
|
2449
|
+
* `min`, `max`, `first` or `last` — `'id.count'`, `'pricing.basePrice.avg'`. The service
|
|
2450
|
+
* validates every metric against that form (`INVALID_AGGREGATION_EXPRESSION`); `count` ignores the
|
|
2451
|
+
* field it names. `first` and `last` were missing here while the service ran them (REL-1470).
|
|
2256
2452
|
*
|
|
2257
2453
|
* It used to be `{ fn, field? }`, a shape the service refuses on every request: the validator
|
|
2258
2454
|
* tests the metric as a string, so an object arrives as `[object Object]`.
|
|
2259
2455
|
*/
|
|
2260
|
-
type AggregateMetric = `${string}.${'count' | 'sum' | 'avg' | 'min' | 'max'}`;
|
|
2456
|
+
type AggregateMetric = `${string}.${'count' | 'sum' | 'avg' | 'min' | 'max' | 'first' | 'last'}`;
|
|
2261
2457
|
/**
|
|
2262
2458
|
* Search block for full-text/semantic search
|
|
2263
2459
|
*/
|
|
@@ -2276,36 +2472,11 @@ interface SearchBlock {
|
|
|
2276
2472
|
limit?: number;
|
|
2277
2473
|
}
|
|
2278
2474
|
/**
|
|
2279
|
-
*
|
|
2475
|
+
* One post-fetch filter: a parameter expression, or the operators every query clause compares with
|
|
2476
|
+
* (`FilterOperator`, REL-1479). This kept a copy of eleven, without `exists` or `notExists`; and a
|
|
2477
|
+
* bare number or boolean, which it took, the service does not read as a filter.
|
|
2280
2478
|
*/
|
|
2281
|
-
|
|
2282
|
-
/** Content type */
|
|
2283
|
-
contentType: string;
|
|
2284
|
-
/** Source entry ID */
|
|
2285
|
-
source: string;
|
|
2286
|
-
/** Minimum similarity threshold */
|
|
2287
|
-
threshold?: number;
|
|
2288
|
-
/** Additional filters */
|
|
2289
|
-
where?: Record<string, unknown>;
|
|
2290
|
-
/** Maximum results */
|
|
2291
|
-
limit?: number;
|
|
2292
|
-
}
|
|
2293
|
-
/**
|
|
2294
|
-
* Post-fetch filters with parameter support
|
|
2295
|
-
*/
|
|
2296
|
-
type FilterValue = string | number | boolean | {
|
|
2297
|
-
eq?: unknown;
|
|
2298
|
-
ne?: unknown;
|
|
2299
|
-
gt?: unknown;
|
|
2300
|
-
gte?: unknown;
|
|
2301
|
-
lt?: unknown;
|
|
2302
|
-
lte?: unknown;
|
|
2303
|
-
in?: unknown[];
|
|
2304
|
-
nin?: unknown[];
|
|
2305
|
-
contains?: unknown;
|
|
2306
|
-
startsWith?: string;
|
|
2307
|
-
endsWith?: string;
|
|
2308
|
-
};
|
|
2479
|
+
type FilterValue = string | FilterOperator;
|
|
2309
2480
|
/**
|
|
2310
2481
|
* Full-text search configuration
|
|
2311
2482
|
*/
|
|
@@ -2327,8 +2498,6 @@ interface AdhocQueryDefinition {
|
|
|
2327
2498
|
aggregate?: AggregateBlock;
|
|
2328
2499
|
/** Search block - full-text/semantic search */
|
|
2329
2500
|
search?: SearchBlock;
|
|
2330
|
-
/** Similar block - vector similarity */
|
|
2331
|
-
similar?: SimilarBlock;
|
|
2332
2501
|
/** Field selection/transformation */
|
|
2333
2502
|
select?: Record<string, string>;
|
|
2334
2503
|
/** Post-fetch filters with parameter support */
|
|
@@ -2416,15 +2585,17 @@ interface AdhocQueryResult<T = unknown> {
|
|
|
2416
2585
|
*/
|
|
2417
2586
|
declare class AdhocQueryBuilder<T = unknown> {
|
|
2418
2587
|
private readonly httpClient;
|
|
2419
|
-
private readonly defaultLocale?;
|
|
2420
2588
|
private queryDef;
|
|
2421
2589
|
private parameters;
|
|
2422
2590
|
private options;
|
|
2591
|
+
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
2592
|
+
private readonly clientLocale;
|
|
2423
2593
|
/**
|
|
2424
|
-
* @param
|
|
2425
|
-
* when `.param('locale', …)` binds none
|
|
2594
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent as the
|
|
2595
|
+
* `locale` parameter when `.param('locale', …)` binds none: the function `TypedRelyIOClient`
|
|
2596
|
+
* hands over, or a locale fixed for this builder
|
|
2426
2597
|
*/
|
|
2427
|
-
constructor(httpClient: HttpClient,
|
|
2598
|
+
constructor(httpClient: HttpClient, locale?: ClientLocale);
|
|
2428
2599
|
/**
|
|
2429
2600
|
* Add a fetch block to retrieve content
|
|
2430
2601
|
* @param config - Fetch configuration
|
|
@@ -2450,11 +2621,6 @@ declare class AdhocQueryBuilder<T = unknown> {
|
|
|
2450
2621
|
* @param config - Search configuration
|
|
2451
2622
|
*/
|
|
2452
2623
|
search(config: SearchBlock): this;
|
|
2453
|
-
/**
|
|
2454
|
-
* Add similar block
|
|
2455
|
-
* @param config - Similar configuration
|
|
2456
|
-
*/
|
|
2457
|
-
similar(config: SimilarBlock): this;
|
|
2458
2624
|
/**
|
|
2459
2625
|
* Add where conditions to fetch
|
|
2460
2626
|
* @param conditions - Filter conditions
|
|
@@ -2583,12 +2749,14 @@ declare class AdhocQueryBuilder<T = unknown> {
|
|
|
2583
2749
|
*/
|
|
2584
2750
|
declare class AdhocQueryClient {
|
|
2585
2751
|
private readonly httpClient;
|
|
2586
|
-
|
|
2752
|
+
/** The client's locale, asked on every query rather than copied when this client was taken. */
|
|
2753
|
+
private readonly clientLocale;
|
|
2587
2754
|
/**
|
|
2588
|
-
* @param
|
|
2589
|
-
* every query that binds none
|
|
2755
|
+
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent as the
|
|
2756
|
+
* `locale` parameter of every query that binds none: the function `TypedRelyIOClient` hands
|
|
2757
|
+
* over, or a locale fixed for this client
|
|
2590
2758
|
*/
|
|
2591
|
-
constructor(httpClient: HttpClient,
|
|
2759
|
+
constructor(httpClient: HttpClient, locale?: ClientLocale);
|
|
2592
2760
|
/**
|
|
2593
2761
|
* Create a new query builder
|
|
2594
2762
|
*/
|
|
@@ -2697,8 +2865,34 @@ type ChangesPageBody = PollChanges['responses'][200]['content']['application/jso
|
|
|
2697
2865
|
* item, and fails if it is ever `unknown` again.
|
|
2698
2866
|
*/
|
|
2699
2867
|
type Change = ChangesPageBody['data'][number];
|
|
2700
|
-
/**
|
|
2701
|
-
|
|
2868
|
+
/**
|
|
2869
|
+
* A change as `relyio.changes()` and `relyio.liveChanges()` deliver it: the document's
|
|
2870
|
+
* {@link Change}, and `fresh`.
|
|
2871
|
+
*
|
|
2872
|
+
* `fresh` is the feed position a refetch for this change names, as the one query term the API
|
|
2873
|
+
* declares on every read its edge may keep (`?_fresh`, `sdk-surfaces-spec.md` decision 32): hand it
|
|
2874
|
+
* to the read — `.fresh(change.fresh)` on `findById()`, `query()` and `search()`, `{ fresh }` to a
|
|
2875
|
+
* singleton's `fetch()`. A position no request named before the change is a key no cache holds a
|
|
2876
|
+
* body under, so the read is answered after the change — at the edge and in the browser, whether
|
|
2877
|
+
* or not the change's purge has reached them — and every later read naming it shares that answer.
|
|
2878
|
+
*
|
|
2879
|
+
* It is at or after the change, never before: on `/v1/changes` the change's own cursor, the ledger
|
|
2880
|
+
* row it came from; at the live edge the cursor of the batch it arrived in. It is not always
|
|
2881
|
+
* `cursor`: at the edge an earlier change of a batch carries the position **before** the batch as
|
|
2882
|
+
* its `cursor`, so a failure part-way through replays the batch, and a refetch naming that position
|
|
2883
|
+
* would be answered from before the change.
|
|
2884
|
+
*/
|
|
2885
|
+
type FeedChange = Change & {
|
|
2886
|
+
/** The feed position a refetch for this change names (`?_fresh`); at or after the change. */
|
|
2887
|
+
readonly fresh: string;
|
|
2888
|
+
};
|
|
2889
|
+
/**
|
|
2890
|
+
* Why a cursor could no longer be replayed, or why everything must be refetched. `/v1/changes`
|
|
2891
|
+
* names `retention` and `dataset-replaced`; the live edge's `feed.resync` may name any reason its
|
|
2892
|
+
* wire declares (`VisitorResyncReason` in `@relyio/api-contract`, read from there rather than
|
|
2893
|
+
* restated). `unknown` when the message named none.
|
|
2894
|
+
*/
|
|
2895
|
+
type ChangesExpiredReason = VisitorResyncReason | 'unknown';
|
|
2702
2896
|
/**
|
|
2703
2897
|
* `RESOURCE_EXPIRED` from the changes feed: the cursor names a position the
|
|
2704
2898
|
* ledger can no longer replay from (`INV-SS-CURSOR-REPLAYS`). The consumer
|
|
@@ -2707,12 +2901,28 @@ type ChangesExpiredReason = 'retention' | 'dataset-replaced' | 'unknown';
|
|
|
2707
2901
|
* A `ResourceExpiredError`, so code that already catches that still does. The
|
|
2708
2902
|
* refusal declares no details, so `reason` is read from the message the api
|
|
2709
2903
|
* writes (`apps/services/api/src/changes/changes-request.ts` `refusalOf`).
|
|
2904
|
+
*
|
|
2905
|
+
* The live edge's `feed.resync` — a socket's frame or a poll's answer — is the
|
|
2906
|
+
* same instruction and arrives as the same error ({@link ChangesExpiredError.resync}),
|
|
2907
|
+
* so `onExpired` means one thing on both transports.
|
|
2710
2908
|
*/
|
|
2711
2909
|
declare class ChangesExpiredError extends ResourceExpiredError {
|
|
2712
2910
|
readonly reason: ChangesExpiredReason;
|
|
2713
|
-
/**
|
|
2714
|
-
|
|
2715
|
-
|
|
2911
|
+
/**
|
|
2912
|
+
* The position the feed resynced to, which a refetch of everything names as `?_fresh`, as a
|
|
2913
|
+
* change's {@link FeedChange.fresh} is named: the head a `/v1/changes` resync took, or the cursor
|
|
2914
|
+
* the edge's `feed.resync` sent. `undefined` when there was no resync to take one — the error was
|
|
2915
|
+
* thrown (`onExpired: 'throw'`) — and on an error a caller built itself.
|
|
2916
|
+
*/
|
|
2917
|
+
readonly fresh: string | undefined;
|
|
2918
|
+
/** The base class's signature, so `withContext` can rebuild one; then the position resynced to. */
|
|
2919
|
+
constructor(message: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>, fresh?: string);
|
|
2920
|
+
/** The base class rebuilds from its four arguments, which would drop the position resynced to. */
|
|
2921
|
+
withContext(context: Record<string, unknown>): this;
|
|
2922
|
+
/** `/v1/changes`' refusal, with the head the feed resynced to when it did. */
|
|
2923
|
+
static of(expired: ResourceExpiredError, fresh?: string): ChangesExpiredError;
|
|
2924
|
+
/** The live edge's `feed.resync`: refetch everything, then continue from the cursor it sent. */
|
|
2925
|
+
static resync(reason: VisitorResyncReason, cursor: string): ChangesExpiredError;
|
|
2716
2926
|
}
|
|
2717
2927
|
interface ChangesOptions {
|
|
2718
2928
|
/**
|
|
@@ -2746,7 +2956,8 @@ interface ChangesOptions {
|
|
|
2746
2956
|
* - a function — resync, and call it with the error once the new position is
|
|
2747
2957
|
* taken and before any change after it is yielded. This is the observable
|
|
2748
2958
|
* form: whatever the consumer derived from the feed may be stale, so the
|
|
2749
|
-
* function is where it invalidates everything
|
|
2959
|
+
* function is where it invalidates everything — naming the error's `fresh`,
|
|
2960
|
+
* the new position, on every refetch. The iterator waits for it.
|
|
2750
2961
|
*/
|
|
2751
2962
|
onExpired?: 'throw' | 'resync' | ((expired: ChangesExpiredError) => void | Promise<void>);
|
|
2752
2963
|
}
|
|
@@ -2755,6 +2966,81 @@ interface ChangesHeadOptions {
|
|
|
2755
2966
|
signal?: AbortSignal;
|
|
2756
2967
|
}
|
|
2757
2968
|
|
|
2969
|
+
/**
|
|
2970
|
+
* `relyio.liveChanges()` — a dataset's published changes at RelyIO's live edge, for a publishable key
|
|
2971
|
+
* (`live-layer-spec.md` decision 20; LV5.2, REL-1158).
|
|
2972
|
+
*
|
|
2973
|
+
* The wire is `@relyio/api-contract`'s `live-visitor.ts`, read from there and never restated: the
|
|
2974
|
+
* path and query names, the frames and their reader, the keepalive, the poll's answer and its reader,
|
|
2975
|
+
* the poll interval, and what each close code and each refused poll means a client does next.
|
|
2976
|
+
*
|
|
2977
|
+
* **One open, two ways in.** A subscription opens a WebSocket to the edge. Where it cannot — the
|
|
2978
|
+
* runtime has no `WebSocket` (Node 18 and 20), constructing one throws, or the socket fails before it
|
|
2979
|
+
* opens (a network that blocks sockets) — it polls the edge instead, from the same cursor, about
|
|
2980
|
+
* every {@link VISITOR_POLL_INTERVAL_MS}, and tries a socket again about once a minute. Both carry
|
|
2981
|
+
* one cursor space, so a switch either way loses nothing.
|
|
2982
|
+
*
|
|
2983
|
+
* **It ends only when its signal aborts, and throws every other end** — a socket closed by a refusal
|
|
2984
|
+
* or a deploy, a refused poll, a keepalive nobody answered — as a `LiveEdgeError` saying what to do
|
|
2985
|
+
* next, so `followChanges()` reconnects, backs off or stops by the edge's own tables. That loop is
|
|
2986
|
+
* the one reconnect policy (`INV-SS-ONE-CORE`, REL-1215); this module keeps no back-off of its own.
|
|
2987
|
+
*
|
|
2988
|
+
* **Cursors.** The edge sends one cursor after a batch of changes. The last change of a batch carries
|
|
2989
|
+
* it; each earlier one carries the position before the batch, so a failure part-way through a batch
|
|
2990
|
+
* replays the whole batch rather than skipping its rest. Delivery is at-least-once: a replay and the
|
|
2991
|
+
* live frames after it may name one change twice, and a refetch makes a repeat cost a read, never a
|
|
2992
|
+
* wrong view (`INV-SS-CHANGE-IS-IDS`).
|
|
2993
|
+
*
|
|
2994
|
+
* **What a refetch names.** Every change of a batch carries the batch's own cursor as `fresh`
|
|
2995
|
+
* (`FeedChange`), the position its refetch names as `?_fresh` — not `cursor`, which for an earlier
|
|
2996
|
+
* change is the position before the batch: the previous batch's refetches were answered under that
|
|
2997
|
+
* one, before this batch, and a cache would hand the same answer back. A `feed.resync`'s error
|
|
2998
|
+
* carries the cursor it sent the same way.
|
|
2999
|
+
*/
|
|
3000
|
+
|
|
3001
|
+
/**
|
|
3002
|
+
* How often an open socket sends the keepalive, which the edge's runtime answers without waking the
|
|
3003
|
+
* feed — the Studio's dataset room sends its own on the same interval. A socket that has heard
|
|
3004
|
+
* nothing by the next one, not even the answer, is presumed dead and reconnected: a client that only
|
|
3005
|
+
* receives never learns otherwise that a network change dropped its connection.
|
|
3006
|
+
*/
|
|
3007
|
+
declare const LIVE_KEEPALIVE_INTERVAL_MS = 30000;
|
|
3008
|
+
interface LiveChangesOptions {
|
|
3009
|
+
/**
|
|
3010
|
+
* A change's cursor from an earlier subscription. Omitted, the edge answers the dataset's current
|
|
3011
|
+
* position first and replays nothing; fetch what you show **after** that position arrives — with
|
|
3012
|
+
* `followChanges()`, after `onState` reports `following` — so nothing lands in between unseen.
|
|
3013
|
+
*/
|
|
3014
|
+
since?: string;
|
|
3015
|
+
/** Content types to keep. Omitted keeps every type; an empty list is refused. At most 50. */
|
|
3016
|
+
types?: readonly string[];
|
|
3017
|
+
/** Entry ids to keep. Omitted keeps every entry; an empty list is refused. At most 100. */
|
|
3018
|
+
ids?: readonly string[];
|
|
3019
|
+
/**
|
|
3020
|
+
* Ends the subscription. An abort — while connected, while polling, or between polls — makes the
|
|
3021
|
+
* `for await` **complete**, with the socket closed, no further request and nothing thrown.
|
|
3022
|
+
*/
|
|
3023
|
+
signal?: AbortSignal;
|
|
3024
|
+
/**
|
|
3025
|
+
* What to do when the edge says to refetch everything (`feed.resync`: the cursor is too old, was
|
|
3026
|
+
* never this dataset's, or the dataset was replaced) — as `relyio.changes()` takes it: `'throw'`
|
|
3027
|
+
* (default) throws a `ChangesExpiredError`, `'resync'` carries on from the edge's position, and a
|
|
3028
|
+
* function is awaited with the error before any change after that position is yielded.
|
|
3029
|
+
*/
|
|
3030
|
+
onExpired?: ChangesOptions['onExpired'];
|
|
3031
|
+
/**
|
|
3032
|
+
* Called when the edge has the subscription in hand — its `feed.opened` frame, or an answered
|
|
3033
|
+
* poll. `followChanges()` passes it to reset its back-off; see `ChangeSourceOptions.opened`.
|
|
3034
|
+
*/
|
|
3035
|
+
opened?: () => void;
|
|
3036
|
+
/**
|
|
3037
|
+
* Called with a position reached without a change to carry it. `followChanges()` passes it so a
|
|
3038
|
+
* connection dropped before its first change reconnects from there; see
|
|
3039
|
+
* `ChangeSourceOptions.reached`.
|
|
3040
|
+
*/
|
|
3041
|
+
reached?: (cursor: string) => void;
|
|
3042
|
+
}
|
|
3043
|
+
|
|
2758
3044
|
/**
|
|
2759
3045
|
* The key's project, as `GET /v1/project` describes it: organization, project, dataset and branch,
|
|
2760
3046
|
* each by id and name, and `studioUrl` — the Studio root the preview toolbar deep-links from
|
|
@@ -2797,13 +3083,27 @@ interface TypedClientConfig<TSchema extends AnySchemaDefinition | undefined = un
|
|
|
2797
3083
|
* ```
|
|
2798
3084
|
*/
|
|
2799
3085
|
declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined = undefined> {
|
|
2800
|
-
|
|
3086
|
+
/**
|
|
3087
|
+
* The one HTTP client every sub-client sends through. `updateConfig()` and `setApiKey()` change it
|
|
3088
|
+
* in place rather than replacing it, so a sub-client taken before either sends through the change.
|
|
3089
|
+
*/
|
|
3090
|
+
private readonly httpClient;
|
|
2801
3091
|
private config;
|
|
3092
|
+
/**
|
|
3093
|
+
* The configuration as `createClient()`, `setApiKey()` and `updateConfig()` gave it, before the
|
|
3094
|
+
* `relyio dev` handshake: what the next update is laid over, and what `withLocale()` starts from.
|
|
3095
|
+
*/
|
|
3096
|
+
private configured;
|
|
2802
3097
|
private _sandbox;
|
|
2803
|
-
private _search;
|
|
2804
|
-
private _batch;
|
|
2805
|
-
private _adhocQuery;
|
|
2806
3098
|
private _schema;
|
|
3099
|
+
/**
|
|
3100
|
+
* The client's locale as it is when a call is made. Every sub-client and builder is handed this
|
|
3101
|
+
* rather than a copy of the locale, so one taken before `updateConfig({ locale })` sends the new
|
|
3102
|
+
* locale, or none after `locale: null` (REL-1453).
|
|
3103
|
+
*/
|
|
3104
|
+
private readonly currentLocale;
|
|
3105
|
+
/** The live edge's poll client id: chosen once, when first needed, and kept for this client's life. */
|
|
3106
|
+
private _liveClientId;
|
|
2807
3107
|
constructor(config: TypedClientConfig<TSchema>);
|
|
2808
3108
|
/**
|
|
2809
3109
|
* Get the schema definition
|
|
@@ -2825,7 +3125,7 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2825
3125
|
*/
|
|
2826
3126
|
get sandbox(): SandboxState;
|
|
2827
3127
|
/**
|
|
2828
|
-
* Get the ad-hoc query client
|
|
3128
|
+
* Get the ad-hoc query client. Every query it sends is in the client's locale as it is then.
|
|
2829
3129
|
*/
|
|
2830
3130
|
get query(): AdhocQueryClient;
|
|
2831
3131
|
/**
|
|
@@ -2932,7 +3232,11 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2932
3232
|
*/
|
|
2933
3233
|
similar<T extends BaseContent = BaseContent>(sourceId: string): SimilarBuilder<T>;
|
|
2934
3234
|
/**
|
|
2935
|
-
* Start a batch operation for bulk create/update/delete
|
|
3235
|
+
* Start a batch operation for bulk create/update/delete.
|
|
3236
|
+
*
|
|
3237
|
+
* By default each operation lands or fails on its own. `atomic: true` makes the batch one
|
|
3238
|
+
* transaction, which the API accepts only when every operation is the same kind of write and none
|
|
3239
|
+
* writes a singleton that does not exist yet.
|
|
2936
3240
|
*
|
|
2937
3241
|
* @example
|
|
2938
3242
|
* ```typescript
|
|
@@ -2941,12 +3245,20 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2941
3245
|
* .update('product', 'entry_abc', { content: { price: 899 } })
|
|
2942
3246
|
* .delete('product', 'entry_xyz')
|
|
2943
3247
|
* .upsertSingleton('homepage', { content: { hero: 'Welcome!' } })
|
|
2944
|
-
* .execute(
|
|
3248
|
+
* .execute()
|
|
2945
3249
|
*
|
|
2946
3250
|
* console.log(result.summary.succeeded)
|
|
3251
|
+
*
|
|
3252
|
+
* // All or nothing: one kind of write
|
|
3253
|
+
* await relyio.batch()
|
|
3254
|
+
* .update('product', 'entry_abc', { content: { price: 899 } })
|
|
3255
|
+
* .update('product', 'entry_def', { content: { price: 799 } })
|
|
3256
|
+
* .execute({ atomic: true })
|
|
2947
3257
|
* ```
|
|
2948
3258
|
*/
|
|
2949
3259
|
batch(): BatchBuilder<NonNullable<TSchema>>;
|
|
3260
|
+
/** The search client, whose builders send the client's locale as it is when each one is sent. */
|
|
3261
|
+
private searchClient;
|
|
2950
3262
|
/**
|
|
2951
3263
|
* Follow the dataset's changes feed: each write this key can see, as ids, in
|
|
2952
3264
|
* order, long-polled from `GET /v1/changes`.
|
|
@@ -2954,13 +3266,15 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2954
3266
|
* Lazy — nothing is requested until the first `next()`. It runs until
|
|
2955
3267
|
* `signal` aborts, which ends the `for await` cleanly rather than throwing.
|
|
2956
3268
|
* A change names what changed; refetch it through the ordinary read path
|
|
2957
|
-
* (`INV-SS-CHANGE-IS-IDS`)
|
|
3269
|
+
* (`INV-SS-CHANGE-IS-IDS`), naming its `fresh` so no cache answers with the
|
|
3270
|
+
* body from before it (`FeedChange`).
|
|
2958
3271
|
*
|
|
2959
3272
|
* @example
|
|
2960
3273
|
* ```typescript
|
|
2961
3274
|
* const controller = new AbortController()
|
|
2962
3275
|
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
2963
|
-
* // { entryId, contentType, locale, kind, cursor }
|
|
3276
|
+
* // { entryId, contentType, locale, kind, cursor, fresh }
|
|
3277
|
+
* await relyio.content(change.contentType).findById(change.entryId).fresh(change.fresh).execute()
|
|
2964
3278
|
* }
|
|
2965
3279
|
* ```
|
|
2966
3280
|
*
|
|
@@ -2968,11 +3282,42 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2968
3282
|
* ```typescript
|
|
2969
3283
|
* for await (const change of relyio.changes({
|
|
2970
3284
|
* since: cursor,
|
|
2971
|
-
* onExpired: async
|
|
3285
|
+
* onExpired: async expired => refetchEverything(expired.fresh),
|
|
2972
3286
|
* })) { … }
|
|
2973
3287
|
* ```
|
|
2974
3288
|
*/
|
|
2975
|
-
changes(options?: ChangesOptions): AsyncIterable<
|
|
3289
|
+
changes(options?: ChangesOptions): AsyncIterable<FeedChange>;
|
|
3290
|
+
/**
|
|
3291
|
+
* Follow the dataset's **published** changes at RelyIO's live edge, with a publishable key
|
|
3292
|
+
* (`rly_pub_…`): each change as ids, in order — the transport a browser follows changes with.
|
|
3293
|
+
*
|
|
3294
|
+
* A WebSocket to the edge, from `since` or the dataset's current position; where a socket cannot
|
|
3295
|
+
* open — the runtime has none, or the network refuses it — it polls the edge instead, about every
|
|
3296
|
+
* fifteen seconds, from the same cursor. The edge is `liveUrl`, or derived from the default
|
|
3297
|
+
* `baseUrl` (see `RelyIOConfig.liveUrl`).
|
|
3298
|
+
*
|
|
3299
|
+
* One subscription ends only when `signal` aborts, which ends the `for await` cleanly; every other
|
|
3300
|
+
* end — a socket a deploy dropped, a refusal, a refused poll — is thrown as a `LiveEdgeError`
|
|
3301
|
+
* that says whether to stop, retry or back off. Hand it to `followChanges()`, the one loop that
|
|
3302
|
+
* reconnects from the last cursor with jittered back-off and honours those answers:
|
|
3303
|
+
*
|
|
3304
|
+
* @example
|
|
3305
|
+
* ```typescript
|
|
3306
|
+
* const relyio = createClient({ apiKey: 'rly_pub_…' })
|
|
3307
|
+
* const controller = new AbortController()
|
|
3308
|
+
* await followChanges(from => relyio.liveChanges({ ...from, types: ['post'] }), {
|
|
3309
|
+
* signal: controller.signal,
|
|
3310
|
+
* // `fresh` names a position no cache holds a body for from before the change.
|
|
3311
|
+
* onChange: change =>
|
|
3312
|
+
* relyio.content(change.contentType).findById(change.entryId).fresh(change.fresh).execute(),
|
|
3313
|
+
* onResync: resync => refetchEverything(resync.cause === 'expired' ? resync.expired.fresh : undefined),
|
|
3314
|
+
* })
|
|
3315
|
+
* ```
|
|
3316
|
+
*
|
|
3317
|
+
* A client without a publishable key sends nothing: a secret or preview key is never put in the
|
|
3318
|
+
* edge's URL. On a server, follow `changes()` with it instead.
|
|
3319
|
+
*/
|
|
3320
|
+
liveChanges(options?: LiveChangesOptions): AsyncIterable<FeedChange>;
|
|
2976
3321
|
/**
|
|
2977
3322
|
* The dataset's current position in the changes feed, as a cursor to start
|
|
2978
3323
|
* `changes({ since })` or `followChanges(…, { since })` from. One
|
|
@@ -3065,15 +3410,73 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
3065
3410
|
*/
|
|
3066
3411
|
testConnection(): Promise<boolean>;
|
|
3067
3412
|
/**
|
|
3068
|
-
*
|
|
3413
|
+
* Change some of the client's options and keep the rest.
|
|
3414
|
+
*
|
|
3415
|
+
* What you pass is laid over the configuration the client holds, field by field:
|
|
3416
|
+
*
|
|
3417
|
+
* - an option you name replaces the value the client holds;
|
|
3418
|
+
* - an option left out, or given as `undefined`, keeps the value the client holds;
|
|
3419
|
+
* - an option with no default given as `null` is cleared — `locale`, `dataset`, `apiKey`, `dev`,
|
|
3420
|
+
* `fetch`, `browser.onCorsError`, `realtime.wsUrl`, `debug.logger` — so the client runs as though
|
|
3421
|
+
* it had never been given one. An option with a default takes no `null`;
|
|
3422
|
+
* - a bag of options you name — `browser`, `cache`, `realtime`, `debug` — keeps every field of it
|
|
3423
|
+
* you do not name, so `updateConfig({ browser: { includeCredentials: true } })` keeps a
|
|
3424
|
+
* configured `onCorsError`;
|
|
3425
|
+
* - `headers` is laid over the headers the client sends, a name matched without regard to case: a
|
|
3426
|
+
* header you name is added or replaces every spelling of it, every other one is still sent, and a
|
|
3427
|
+
* header given as `null` is no longer sent;
|
|
3428
|
+
* - naming `apiKey` — a key, or `null` — replaces every key the client holds, one given in
|
|
3429
|
+
* `headers` included.
|
|
3430
|
+
*
|
|
3431
|
+
* The configuration it is laid over is what `createClient()`, `setApiKey()` and earlier updates
|
|
3432
|
+
* gave the client. The `relyio dev` handshake is read again, as `createClient()` reads it: while a
|
|
3433
|
+
* sandbox is active its key and dataset are sent over the configured ones, and once it has gone
|
|
3434
|
+
* the configured ones are.
|
|
3435
|
+
*
|
|
3436
|
+
* The client's one HTTP client is changed in place, so every request from now on is sent as the
|
|
3437
|
+
* update says — including one from a `content()`, `asset()`, `singleton()` or `settings()`
|
|
3438
|
+
* sub-client, a `query` client, or a builder such as `search()` or `batch()`, taken before the
|
|
3439
|
+
* call. The locale reaches them too: each reads the client's locale when it sends, so a new
|
|
3440
|
+
* `locale` is the default of its next request and `locale: null` leaves that request with none. A
|
|
3441
|
+
* locale the call names, and a sub-client's own `withLocale()`, still win over it. A client made
|
|
3442
|
+
* by `withLocale()` is a client of its own: an update of this one does not reach it.
|
|
3443
|
+
*
|
|
3444
|
+
* @example
|
|
3445
|
+
* ```typescript
|
|
3446
|
+
* const relyio = createClient({ apiKey, headers: { 'X-Tenant': 'acme' }, browser: { onCorsError } })
|
|
3447
|
+
*
|
|
3448
|
+
* relyio.updateConfig({ headers: { 'X-Trace': traceId } }) // X-Tenant is still sent
|
|
3449
|
+
* relyio.updateConfig({ browser: { includeCredentials: true } }) // onCorsError is kept
|
|
3450
|
+
* relyio.updateConfig({ headers: { 'X-Tenant': null } }) // X-Tenant is no longer sent
|
|
3451
|
+
* relyio.updateConfig({ locale: null }) // reads name no locale of the client's
|
|
3452
|
+
* ```
|
|
3069
3453
|
*/
|
|
3070
|
-
updateConfig(
|
|
3454
|
+
updateConfig(update: RelyIOConfigUpdate): void;
|
|
3071
3455
|
/**
|
|
3072
3456
|
* Get the current configuration
|
|
3073
3457
|
*/
|
|
3074
3458
|
getConfig(): Readonly<MergedRelyIOConfig>;
|
|
3075
3459
|
/**
|
|
3076
|
-
*
|
|
3460
|
+
* Replace the API key every later request sends as `X-API-Key`.
|
|
3461
|
+
*
|
|
3462
|
+
* It reaches every request this client makes from now on, including those of a `content()`,
|
|
3463
|
+
* `asset()` or other sub-client taken before the call, and `getConfig().apiKey` reports it. A key
|
|
3464
|
+
* given in `headers`, under any spelling, is replaced with it and does not come back on a later
|
|
3465
|
+
* `updateConfig()`. A client already derived with `withLocale()` is a client of its own and keeps
|
|
3466
|
+
* its key.
|
|
3467
|
+
*
|
|
3468
|
+
* An empty or blank key is no key, as it is when passed to `createClient`: the next request
|
|
3469
|
+
* rejects with `MissingApiKeyError` and nothing is sent.
|
|
3470
|
+
*
|
|
3471
|
+
* Under an active `relyio dev` sandbox the sandbox's scoped key stands, as it does over the key
|
|
3472
|
+
* passed to `createClient` — replacing the configured key does not retarget the client at the
|
|
3473
|
+
* sandbox's dataset with a key the sandbox did not issue.
|
|
3474
|
+
*
|
|
3475
|
+
* @example
|
|
3476
|
+
* ```typescript
|
|
3477
|
+
* const relyio = createClient({ apiKey: process.env.RELYIO_API_KEY! })
|
|
3478
|
+
* relyio.setApiKey(rotatedKey) // the next read sends `X-API-Key: <rotatedKey>`
|
|
3479
|
+
* ```
|
|
3077
3480
|
*/
|
|
3078
3481
|
setApiKey(apiKey: string): void;
|
|
3079
3482
|
/**
|
|
@@ -3083,9 +3486,12 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
3083
3486
|
/**
|
|
3084
3487
|
* Create a locale-scoped client
|
|
3085
3488
|
*
|
|
3086
|
-
* Every
|
|
3087
|
-
* `
|
|
3088
|
-
*
|
|
3489
|
+
* Every call the returned client builds is in this locale unless the call names one of its own,
|
|
3490
|
+
* which wins: every read — `content()`, `asset()`, `singleton()`, `settings()`, `search()`,
|
|
3491
|
+
* `similar()`, `autocomplete()`, `executeQuery()` and the ad-hoc queries — and every write and
|
|
3492
|
+
* version-history read — `create()` and `update()`, the singleton and settings writes, the asset
|
|
3493
|
+
* file writes, `versions()` and `version()`, and each operation `batch()` builds. `restore()`
|
|
3494
|
+
* always names its locale; a delete, and a `batch().raw()` operation, carry none of the client's.
|
|
3089
3495
|
*
|
|
3090
3496
|
* Type-safe when schema is provided: autocompletes valid locale codes!
|
|
3091
3497
|
*
|
|
@@ -3093,10 +3499,11 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
3093
3499
|
* ```typescript
|
|
3094
3500
|
* const spanish = relyio.withLocale('es-ES') // ← Autocompletes with schema!
|
|
3095
3501
|
*
|
|
3096
|
-
* // Reads use Spanish
|
|
3502
|
+
* // Reads and writes use Spanish
|
|
3097
3503
|
* const products = await spanish.content('product').query().execute()
|
|
3098
3504
|
* const homepage = await spanish.singleton('homepage').fetch()
|
|
3099
3505
|
* const results = await spanish.search('zapatos').execute()
|
|
3506
|
+
* await spanish.content('product').update(id, { title: 'Zapatos' })
|
|
3100
3507
|
*
|
|
3101
3508
|
* // Original client unchanged
|
|
3102
3509
|
* const englishProducts = await relyio.content('product').query().execute()
|
|
@@ -3192,4 +3599,4 @@ declare function createClient<TSchema extends AnySchemaDefinition>(config: Typed
|
|
|
3192
3599
|
*/
|
|
3193
3600
|
type ClientSchema<T extends TypedRelyIOClient<AnySchemaDefinition>> = T extends TypedRelyIOClient<infer TSchema> ? TSchema : never;
|
|
3194
3601
|
|
|
3195
|
-
export {
|
|
3602
|
+
export { type BatchOperationResult as $, type ActiveSandbox as A, type SearchResultItem as B, type Change as C, type SearchHitMetadata as D, type ExtendedQueryResult as E, type FeedChange as F, type SearchResponse as G, HttpClient as H, type AutocompleteSuggestion as I, type AutocompleteResponse as J, type SimilarResult as K, LIVE_KEEPALIVE_INTERVAL_MS as L, type SimilarResponse as M, type SearchFilter as N, type SearchFields as O, type Project as P, type SearchSort as Q, type Register as R, type SandboxState as S, TypedRelyIOClient as T, type SearchTypeName as U, type SearchEntry as V, BatchClient as W, BatchBuilder as X, type BatchMethod as Y, type BatchOperation as Z, type BatchOptions as _, ChangesExpiredError as a, type BatchSummary as a0, type BatchResponse as a1, AdhocQueryClient as a2, AdhocQueryBuilder as a3, type FetchBlock as a4, type AggregateBlock as a5, type AggregateMetric as a6, type SearchBlock as a7, type FilterValue as a8, type FullTextConfig as a9, type MultipartPart as aA, type MultipartTarget as aB, type UploadProgress as aC, ResourceNotFoundError as aD, ResourceConflictError as aE, ResourceExpiredError as aF, isResourceNotFound as aG, type FileErrorCode as aH, type FileUploadErrorCode as aI, FileUploadError as aJ, FileValidationError as aK, type FileValidationConstraints as aL, validateFile as aM, type AdhocQueryDefinition as aa, type AdhocQueryOptions as ab, type QueryMetadata as ac, type AdhocQueryResult as ad, AssetClient as ae, AssetFileBuilder as af, AssetUploadBuilder as ag, isAssetEntry as ah, type AssetVisibility as ai, type FileStatus as aj, type FileBackend as ak, type AssetFileBlock as al, type AssetFileExtracted as am, type FileStatusResult as an, type AssetUrls as ao, type AssetEntryResponse as ap, type PopulatedAssetReference as aq, type PresignInput as ar, type PresignResult as as, type ConfirmInput as at, type ConfirmResult as au, type ResolveUrlInput as av, type ResolveUrlResult as aw, type CreateAssetOptions as ax, type WaitUntilReadyOptions as ay, type MultipartCreateResult as az, type ChangesExpiredReason as b, createClient as c, type TypedClientConfig as d, type ClientSchema as e, type RegisteredSchema as f, type SendOptions as g, entityTagOf as h, type ConditionalWriteOptions as i, type RetryableWriteOptions as j, type ChangesHeadOptions as k, type ChangesOptions as l, type LiveChangesOptions as m, ContentClient as n, SingletonClient as o, SettingsClient as p, ContentQueryBuilder as q, ContentByIdBuilder as r, type ChildrenOptions as s, type SingletonFetchOptions as t, type SettingsFetchOptions as u, SearchClient as v, SearchBuilder as w, AutocompleteBuilder as x, SimilarBuilder as y, type SearchMode as z };
|