@relyio/sdk 0.11.0 → 0.13.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 +172 -0
- package/dist/chunk-3NPPMGB6.js +1092 -0
- package/dist/{chunk-7GLDVHIH.js → chunk-6NGJXLOR.js} +65 -67
- package/dist/{chunk-4HTIU5YE.cjs → chunk-DEDIJKHY.cjs} +65 -67
- package/dist/{chunk-2TIJLV2X.js → chunk-EW23SZPX.js} +43 -65
- package/dist/{chunk-PO7CUR5U.cjs → chunk-FOSM4LMM.cjs} +42 -65
- package/dist/chunk-Z6GLWSSD.cjs +1106 -0
- package/dist/client/index.cjs +3 -3
- package/dist/client/index.d.cts +4 -4
- package/dist/client/index.d.ts +4 -4
- package/dist/client/index.js +1 -1
- package/dist/{define-schema-CVi8nwc7.d.ts → define-schema-UHViXKiv.d.ts} +33 -435
- package/dist/{define-schema-DqpipEHv.d.cts → define-schema-sWJ8Zn7C.d.cts} +33 -435
- package/dist/{define-content-type-ENAod5Ve.d.cts → include-paths-Bs5FhNw2.d.cts} +3505 -483
- package/dist/{define-content-type-ENAod5Ve.d.ts → include-paths-Cb7iPCW2.d.ts} +3505 -483
- package/dist/index--_u1nPHv.d.cts +507 -0
- package/dist/index-8DozAWsA.d.ts +507 -0
- package/dist/{index-MLAFUuco.d.cts → index-BT0L8xJj.d.cts} +139 -90
- package/dist/{index-BKEAYvvz.d.ts → index-CPjJ25R4.d.ts} +139 -90
- package/dist/index.cjs +134 -110
- package/dist/index.d.cts +44 -71
- package/dist/index.d.ts +44 -71
- package/dist/index.js +5 -28
- package/dist/markdown/index.cjs +13750 -0
- package/dist/markdown/index.d.cts +111 -0
- package/dist/markdown/index.d.ts +111 -0
- package/dist/markdown/index.js +13742 -0
- package/dist/rich-text/index.cjs +49 -0
- package/dist/rich-text/index.d.cts +3 -0
- package/dist/rich-text/index.d.ts +3 -0
- package/dist/rich-text/index.js +4 -0
- package/dist/rich-text.d-BWc-5gX1.d.cts +326 -0
- package/dist/rich-text.d-BWc-5gX1.d.ts +326 -0
- package/dist/schema/index.cjs +34 -38
- package/dist/schema/index.d.cts +15 -137
- package/dist/schema/index.d.ts +15 -137
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/package.json +19 -2
- package/dist/.tsbuildinfo +0 -1
- package/dist/index-BM42r4yg.d.cts +0 -860
- package/dist/index-C73cK2Tt.d.ts +0 -860
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { b as RichTextValue, c as RichTextShapeValue, d as RichTextEntryLinkMark, y as RichTextTable, h as RichTextCodeGroup, x as RichTextStructure, s as RichTextMarkType } from './rich-text.d-BWc-5gX1.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Generated by scripts/emit-openapi-types.mjs from @relyio/api's committed
|
|
3
5
|
* openapi-spec.json. Do not edit: run `pnpm codegen:openapi` in this package, which
|
|
@@ -984,6 +986,21 @@ interface components {
|
|
|
984
986
|
retriable?: boolean;
|
|
985
987
|
};
|
|
986
988
|
};
|
|
989
|
+
/** @description An asset entry’s `urls`, sent beside its `file` once `file.status` is `ready`: an image’s `original` and `variants`, a file’s `original`, a video’s `playback`, `poster` and `download`. Every URL is on the delivery gateway; a protected or private asset’s carries a short-lived token minted for this request. */
|
|
990
|
+
AssetUrls: {
|
|
991
|
+
/** @description An image or a file: its original bytes. */
|
|
992
|
+
original?: string;
|
|
993
|
+
/** @description An image: each delivery variant’s id, mapped to its URL. */
|
|
994
|
+
variants?: {
|
|
995
|
+
[key: string]: string;
|
|
996
|
+
};
|
|
997
|
+
/** @description A video: its HLS/DASH manifest. */
|
|
998
|
+
playback?: string;
|
|
999
|
+
/** @description A video: its poster image. */
|
|
1000
|
+
poster?: string;
|
|
1001
|
+
/** @description A video: its downloadable MP4, when enabled. */
|
|
1002
|
+
download?: string;
|
|
1003
|
+
};
|
|
987
1004
|
/** @description One distinct value of the field, and the entry it was first found in. */
|
|
988
1005
|
AutocompleteSuggestion: {
|
|
989
1006
|
/** @description The suggested value. */
|
|
@@ -995,6 +1012,19 @@ interface components {
|
|
|
995
1012
|
/** @description The value with its matched part wrapped in `<em>`, when Atlas highlighted it. */
|
|
996
1013
|
highlight?: string;
|
|
997
1014
|
};
|
|
1015
|
+
/** @description An entry link left pointing nowhere: who holds it, where, and the heading anchor it names. */
|
|
1016
|
+
BrokenEntryLink: {
|
|
1017
|
+
/** @description The linking entry’s id. */
|
|
1018
|
+
entryUid: string;
|
|
1019
|
+
/** @description The linking entry’s content type. */
|
|
1020
|
+
contentType: string;
|
|
1021
|
+
/** @description The rich-text field holding the link, spelt as the include path that names it: `body`, `sections.body`. */
|
|
1022
|
+
field: string;
|
|
1023
|
+
/** @description The heading anchor the link names, which this entry no longer has. */
|
|
1024
|
+
anchor: string;
|
|
1025
|
+
/** @description The locale the link is published in. */
|
|
1026
|
+
locale: string;
|
|
1027
|
+
};
|
|
998
1028
|
/** @description One change to one entry, ids only. Refetch the entry through the ordinary read path to see it. */
|
|
999
1029
|
Change: {
|
|
1000
1030
|
entryId: string;
|
|
@@ -1010,7 +1040,7 @@ interface components {
|
|
|
1010
1040
|
nextCursor: string | null;
|
|
1011
1041
|
hasMore: boolean;
|
|
1012
1042
|
};
|
|
1013
|
-
/** @description One entry: its fields at the top level, as the content type declares them, and `_metadata`. An asset entry also carries `file`, an `AssetFile`, and `urls` once the file is ready. */
|
|
1043
|
+
/** @description One entry: its fields at the top level, as the content type declares them, and `_metadata`. An asset entry also carries `file`, an `AssetFile`, and `urls`, an `AssetUrls`, once the file is ready. */
|
|
1014
1044
|
Entry: {
|
|
1015
1045
|
_metadata: components['schemas']['EntryMetadata'];
|
|
1016
1046
|
} & {
|
|
@@ -1070,6 +1100,8 @@ interface components {
|
|
|
1070
1100
|
localeFallbacksApplied?: {
|
|
1071
1101
|
[key: string]: string;
|
|
1072
1102
|
};
|
|
1103
|
+
/** @description Each required field the entry holds no value for, which this read filled with its kind’s empty value — `""` for text, the tree holding nothing (`{ _type: "richText", version: 1, children: [] }`) for rich text, `[]` for a list, `false` for a boolean — so a required field is always present. A draft may leave these empty; publishing refuses it. Each is a value path, a list item named by its key: `title`, `seo.title`, `faq[_key=="k1"].question` — the spelling a validation error’s path uses, so a path still finds its item after a reorder. Absent when none was filled. */
|
|
1104
|
+
emptyRequiredFields?: string[];
|
|
1073
1105
|
/** @description Every locale the entry has content in, the default first. */
|
|
1074
1106
|
availableLocales: components['schemas']['EntryLocale'][];
|
|
1075
1107
|
/** @description The fields of every other locale asked for, keyed by locale — on `?locales=a,b` and `?locale=*`. A locale with no visible fields is left out. */
|
|
@@ -1103,7 +1135,7 @@ interface components {
|
|
|
1103
1135
|
};
|
|
1104
1136
|
/** @description One outgoing reference. */
|
|
1105
1137
|
EntryRef: {
|
|
1106
|
-
/** @description The declaring field’s path
|
|
1138
|
+
/** @description The declaring field’s path, spelt as the include path that expands it: `sections.customers` for a reference inside a page builder’s blocks, `sections.media.image` for one inside an object inside a block — no shape, index or key. Two block types that declare one field id share a path; each row still names its target. */
|
|
1107
1139
|
path: string;
|
|
1108
1140
|
/** @description The referenced entry’s id. */
|
|
1109
1141
|
entryUid: string;
|
|
@@ -1111,7 +1143,7 @@ interface components {
|
|
|
1111
1143
|
ErrorResponse: {
|
|
1112
1144
|
error: {
|
|
1113
1145
|
/** @enum {string} */
|
|
1114
|
-
code: 'ACCESS_DENIED' | 'CONTENT_INVALID' | 'INTERNAL_ERROR' | 'INVALID_API_KEY' | 'METHOD_NOT_ALLOWED' | 'MISSING_API_KEY' | 'ORGANIZATION_DELETE_BLOCKED' | 'PAYLOAD_TOO_LARGE' | 'PLAN_DOWNGRADE_BLOCKED' | 'PLAN_FEATURE_UNAVAILABLE' | 'RATE_LIMIT_EXCEEDED' | 'READ_ONLY_KEY' | 'REQUEST_INVALID' | 'REQUEST_TIMEOUT' | 'RESOURCE_CONFLICT' | 'RESOURCE_EXPIRED' | 'RESOURCE_NOT_FOUND' | 'REVERIFICATION_REQUIRED' | 'SERVICE_INDETERMINATE' | 'TRANSACTION_ROLLED_BACK' | 'USAGE_QUOTA_EXCEEDED' | 'USER_NOT_PROVISIONED';
|
|
1146
|
+
code: 'ACCESS_DENIED' | 'AI_UNAVAILABLE_IN_REGION' | 'CONTENT_INVALID' | 'INTERNAL_ERROR' | 'INVALID_API_KEY' | 'METHOD_NOT_ALLOWED' | 'MISSING_API_KEY' | 'ORGANIZATION_BEING_DELETED' | 'ORGANIZATION_DELETE_BLOCKED' | 'ORGANIZATION_IN_ANOTHER_CELL' | 'PAYLOAD_TOO_LARGE' | 'PLAN_DOWNGRADE_BLOCKED' | 'PLAN_FEATURE_UNAVAILABLE' | 'PROJECT_IN_ANOTHER_CELL' | 'RATE_LIMIT_EXCEEDED' | 'READ_ONLY_KEY' | 'REQUEST_INVALID' | 'REQUEST_TIMEOUT' | 'RESOURCE_CONFLICT' | 'RESOURCE_EXPIRED' | 'RESOURCE_NOT_FOUND' | 'REVERIFICATION_REQUIRED' | 'SERVICE_INDETERMINATE' | 'TRANSACTION_ROLLED_BACK' | 'USAGE_QUOTA_EXCEEDED' | 'USER_NOT_PROVISIONED';
|
|
1115
1147
|
messages: string[];
|
|
1116
1148
|
details?: {
|
|
1117
1149
|
[key: string]: unknown;
|
|
@@ -1230,6 +1262,17 @@ interface components {
|
|
|
1230
1262
|
};
|
|
1231
1263
|
};
|
|
1232
1264
|
};
|
|
1265
|
+
RefusalProjectInAnotherCell: {
|
|
1266
|
+
error: {
|
|
1267
|
+
/** @enum {string} */
|
|
1268
|
+
code: 'PROJECT_IN_ANOTHER_CELL';
|
|
1269
|
+
messages: string[];
|
|
1270
|
+
details: {
|
|
1271
|
+
/** @description The data region whose cell holds the Project, as `us` or `eu`. */
|
|
1272
|
+
region: string;
|
|
1273
|
+
};
|
|
1274
|
+
};
|
|
1275
|
+
};
|
|
1233
1276
|
RefusalRateLimitExceeded: {
|
|
1234
1277
|
error: {
|
|
1235
1278
|
/** @enum {string} */
|
|
@@ -1300,6 +1343,270 @@ interface components {
|
|
|
1300
1343
|
};
|
|
1301
1344
|
};
|
|
1302
1345
|
};
|
|
1346
|
+
/** @description The entry after a restore: its fields at the top level and `_metadata`, which also lists what the restore left out and the links other entries publish that it left pointing nowhere. */
|
|
1347
|
+
RestoredEntry: {
|
|
1348
|
+
_metadata: components['schemas']['RestoredEntryMetadata'];
|
|
1349
|
+
} & {
|
|
1350
|
+
[key: string]: unknown;
|
|
1351
|
+
};
|
|
1352
|
+
/** @description What this service reports about an entry beside its fields, and what a restore left out of it. */
|
|
1353
|
+
RestoredEntryMetadata: {
|
|
1354
|
+
id: string;
|
|
1355
|
+
/** @description The content type. */
|
|
1356
|
+
type: string;
|
|
1357
|
+
/** @enum {string} */
|
|
1358
|
+
entryType: 'asset' | 'content' | 'settings' | 'singleton';
|
|
1359
|
+
/** @description The slug field’s value at `locale`, or null when the type declares none. */
|
|
1360
|
+
slug: string | null;
|
|
1361
|
+
/**
|
|
1362
|
+
* @description Container lifecycle only. Publication is per locale: `localeStatus`.
|
|
1363
|
+
* @enum {string}
|
|
1364
|
+
*/
|
|
1365
|
+
status: 'active' | 'archived' | 'proposed';
|
|
1366
|
+
/** @description The reported locale’s own version counter — not the entry’s shared-field counter. `0` when that locale has no content of its own. With `id` and `locale`, it is what `X-Entity-Tag` is minted from. */
|
|
1367
|
+
version: number;
|
|
1368
|
+
/** @description The locale the fields beside this object were composed for. */
|
|
1369
|
+
locale: string;
|
|
1370
|
+
/** @description How many versions `locale` has. Sent on a single-entry read; a list leaves it out. */
|
|
1371
|
+
versionCount?: number;
|
|
1372
|
+
/** @description `locale`’s version numbers, newest first, at most 25. Sent on a single-entry read; a list leaves it out. */
|
|
1373
|
+
versions?: number[];
|
|
1374
|
+
/**
|
|
1375
|
+
* @description Publication state of `locale`. Absent when that locale has no content of its own: what is visible in it is inherited through the fallback chain.
|
|
1376
|
+
* @enum {string}
|
|
1377
|
+
*/
|
|
1378
|
+
localeStatus?: 'archived' | 'draft' | 'published';
|
|
1379
|
+
/** @description Whether `locale` has unpublished changes of its own. */
|
|
1380
|
+
localeHasDraft: boolean;
|
|
1381
|
+
/** @description Every locale holding unpublished content of its own, sorted. A shared-field draft is not listed: it is `hasDraft`. */
|
|
1382
|
+
draftLocales: string[];
|
|
1383
|
+
/** @description Whether the shared (non-localized) fields have unpublished changes. Publishing any locale makes them live, so they are unpublished work in every locale. */
|
|
1384
|
+
hasDraft: boolean;
|
|
1385
|
+
/** @description The locale the request named, when it named one other than the default. On `?locales=a,b,c` it is always sent: the primary, or `*` when the list names as many locales as the entry has — as on `?locale=*`. */
|
|
1386
|
+
requestedLocale?: string;
|
|
1387
|
+
/** @description The schema’s default locale. */
|
|
1388
|
+
defaultLocale: string;
|
|
1389
|
+
/** @description Each field whose value came from another locale, mapped to that locale. Absent when none did. */
|
|
1390
|
+
localeFallbacksApplied?: {
|
|
1391
|
+
[key: string]: string;
|
|
1392
|
+
};
|
|
1393
|
+
/** @description Each required field the entry holds no value for, which this read filled with its kind’s empty value — `""` for text, the tree holding nothing (`{ _type: "richText", version: 1, children: [] }`) for rich text, `[]` for a list, `false` for a boolean — so a required field is always present. A draft may leave these empty; publishing refuses it. Each is a value path, a list item named by its key: `title`, `seo.title`, `faq[_key=="k1"].question` — the spelling a validation error’s path uses, so a path still finds its item after a reorder. Absent when none was filled. */
|
|
1394
|
+
emptyRequiredFields?: string[];
|
|
1395
|
+
/** @description Every locale the entry has content in, the default first. */
|
|
1396
|
+
availableLocales: components['schemas']['EntryLocale'][];
|
|
1397
|
+
/** @description The fields of every other locale asked for, keyed by locale — on `?locales=a,b` and `?locale=*`. A locale with no visible fields is left out. */
|
|
1398
|
+
localizations?: {
|
|
1399
|
+
[key: string]: {
|
|
1400
|
+
[key: string]: unknown;
|
|
1401
|
+
};
|
|
1402
|
+
};
|
|
1403
|
+
/**
|
|
1404
|
+
* Format: date-time
|
|
1405
|
+
* @description When the entry was created.
|
|
1406
|
+
*/
|
|
1407
|
+
createdAt: string;
|
|
1408
|
+
/**
|
|
1409
|
+
* Format: date-time
|
|
1410
|
+
* @description When the entry was last written.
|
|
1411
|
+
*/
|
|
1412
|
+
updatedAt: string;
|
|
1413
|
+
/**
|
|
1414
|
+
* Format: date-time
|
|
1415
|
+
* @description When the entry was last published. Absent until it is.
|
|
1416
|
+
*/
|
|
1417
|
+
publishedAt?: string;
|
|
1418
|
+
/**
|
|
1419
|
+
* Format: date-time
|
|
1420
|
+
* @description When the entry was first published. Absent until it is.
|
|
1421
|
+
*/
|
|
1422
|
+
firstPublishedAt?: string;
|
|
1423
|
+
/** @description The entry’s outgoing references, across every locale, each once. */
|
|
1424
|
+
refs: components['schemas']['EntryRef'][];
|
|
1425
|
+
/** @description Each value of the restored version the active schema no longer declares, by path (`legacy`, `seo.note`, `faq[_key=="k1"].note` — an item named by its key). A restore writes what the schema still declares and is never refused for the rest; empty when the version held nothing removed. A replay of the restore under the same `Idempotency-Key` answers the list the restore did. */
|
|
1426
|
+
leftOut?: string[];
|
|
1427
|
+
/** @description Each entry link another entry publishes whose `anchor` names a heading this restore took away from the content its reader lands on, as a revision lists them. A restore of a published locale lands on its draft, so it takes none away and this is empty. A replay of the restore under the same `Idempotency-Key` answers the list the restore did. */
|
|
1428
|
+
brokenLinks?: components['schemas']['BrokenEntryLink'][];
|
|
1429
|
+
};
|
|
1430
|
+
/** @description The entry after a revision: its fields at the top level and `_metadata`, which also lists the links other entries publish that the revision left pointing nowhere. */
|
|
1431
|
+
RevisedEntry: {
|
|
1432
|
+
_metadata: components['schemas']['RevisedEntryMetadata'];
|
|
1433
|
+
} & {
|
|
1434
|
+
[key: string]: unknown;
|
|
1435
|
+
};
|
|
1436
|
+
/** @description What this service reports about an entry beside its fields, and the links a revision left pointing nowhere. */
|
|
1437
|
+
RevisedEntryMetadata: {
|
|
1438
|
+
id: string;
|
|
1439
|
+
/** @description The content type. */
|
|
1440
|
+
type: string;
|
|
1441
|
+
/** @enum {string} */
|
|
1442
|
+
entryType: 'asset' | 'content' | 'settings' | 'singleton';
|
|
1443
|
+
/** @description The slug field’s value at `locale`, or null when the type declares none. */
|
|
1444
|
+
slug: string | null;
|
|
1445
|
+
/**
|
|
1446
|
+
* @description Container lifecycle only. Publication is per locale: `localeStatus`.
|
|
1447
|
+
* @enum {string}
|
|
1448
|
+
*/
|
|
1449
|
+
status: 'active' | 'archived' | 'proposed';
|
|
1450
|
+
/** @description The reported locale’s own version counter — not the entry’s shared-field counter. `0` when that locale has no content of its own. With `id` and `locale`, it is what `X-Entity-Tag` is minted from. */
|
|
1451
|
+
version: number;
|
|
1452
|
+
/** @description The locale the fields beside this object were composed for. */
|
|
1453
|
+
locale: string;
|
|
1454
|
+
/** @description How many versions `locale` has. Sent on a single-entry read; a list leaves it out. */
|
|
1455
|
+
versionCount?: number;
|
|
1456
|
+
/** @description `locale`’s version numbers, newest first, at most 25. Sent on a single-entry read; a list leaves it out. */
|
|
1457
|
+
versions?: number[];
|
|
1458
|
+
/**
|
|
1459
|
+
* @description Publication state of `locale`. Absent when that locale has no content of its own: what is visible in it is inherited through the fallback chain.
|
|
1460
|
+
* @enum {string}
|
|
1461
|
+
*/
|
|
1462
|
+
localeStatus?: 'archived' | 'draft' | 'published';
|
|
1463
|
+
/** @description Whether `locale` has unpublished changes of its own. */
|
|
1464
|
+
localeHasDraft: boolean;
|
|
1465
|
+
/** @description Every locale holding unpublished content of its own, sorted. A shared-field draft is not listed: it is `hasDraft`. */
|
|
1466
|
+
draftLocales: string[];
|
|
1467
|
+
/** @description Whether the shared (non-localized) fields have unpublished changes. Publishing any locale makes them live, so they are unpublished work in every locale. */
|
|
1468
|
+
hasDraft: boolean;
|
|
1469
|
+
/** @description The locale the request named, when it named one other than the default. On `?locales=a,b,c` it is always sent: the primary, or `*` when the list names as many locales as the entry has — as on `?locale=*`. */
|
|
1470
|
+
requestedLocale?: string;
|
|
1471
|
+
/** @description The schema’s default locale. */
|
|
1472
|
+
defaultLocale: string;
|
|
1473
|
+
/** @description Each field whose value came from another locale, mapped to that locale. Absent when none did. */
|
|
1474
|
+
localeFallbacksApplied?: {
|
|
1475
|
+
[key: string]: string;
|
|
1476
|
+
};
|
|
1477
|
+
/** @description Each required field the entry holds no value for, which this read filled with its kind’s empty value — `""` for text, the tree holding nothing (`{ _type: "richText", version: 1, children: [] }`) for rich text, `[]` for a list, `false` for a boolean — so a required field is always present. A draft may leave these empty; publishing refuses it. Each is a value path, a list item named by its key: `title`, `seo.title`, `faq[_key=="k1"].question` — the spelling a validation error’s path uses, so a path still finds its item after a reorder. Absent when none was filled. */
|
|
1478
|
+
emptyRequiredFields?: string[];
|
|
1479
|
+
/** @description Every locale the entry has content in, the default first. */
|
|
1480
|
+
availableLocales: components['schemas']['EntryLocale'][];
|
|
1481
|
+
/** @description The fields of every other locale asked for, keyed by locale — on `?locales=a,b` and `?locale=*`. A locale with no visible fields is left out. */
|
|
1482
|
+
localizations?: {
|
|
1483
|
+
[key: string]: {
|
|
1484
|
+
[key: string]: unknown;
|
|
1485
|
+
};
|
|
1486
|
+
};
|
|
1487
|
+
/**
|
|
1488
|
+
* Format: date-time
|
|
1489
|
+
* @description When the entry was created.
|
|
1490
|
+
*/
|
|
1491
|
+
createdAt: string;
|
|
1492
|
+
/**
|
|
1493
|
+
* Format: date-time
|
|
1494
|
+
* @description When the entry was last written.
|
|
1495
|
+
*/
|
|
1496
|
+
updatedAt: string;
|
|
1497
|
+
/**
|
|
1498
|
+
* Format: date-time
|
|
1499
|
+
* @description When the entry was last published. Absent until it is.
|
|
1500
|
+
*/
|
|
1501
|
+
publishedAt?: string;
|
|
1502
|
+
/**
|
|
1503
|
+
* Format: date-time
|
|
1504
|
+
* @description When the entry was first published. Absent until it is.
|
|
1505
|
+
*/
|
|
1506
|
+
firstPublishedAt?: string;
|
|
1507
|
+
/** @description The entry’s outgoing references, across every locale, each once. */
|
|
1508
|
+
refs: components['schemas']['EntryRef'][];
|
|
1509
|
+
/** @description Each entry link another entry publishes whose `anchor` names a heading this revision took away from the content its reader lands on — in the link’s locale, or the first locale of its fallback chain this entry publishes. The revision is never refused for them; the linking entry’s own next publish is (`ENTRY_LINK_ANCHOR_NOT_FOUND`). Only what this revision took away is listed, and empty when it took none. A replay of the revision under the same `Idempotency-Key` answers the list the revision did. */
|
|
1510
|
+
brokenLinks?: components['schemas']['BrokenEntryLink'][];
|
|
1511
|
+
};
|
|
1512
|
+
/** @description The settings group after a write or a reset: its fields at the top level and `_metadata`, which also lists the links other entries publish that the write left pointing nowhere. */
|
|
1513
|
+
RevisedSettingsGroup: {
|
|
1514
|
+
_metadata: components['schemas']['RevisedSettingsGroupMetadata'];
|
|
1515
|
+
} & {
|
|
1516
|
+
[key: string]: unknown;
|
|
1517
|
+
};
|
|
1518
|
+
/** @description What this service reports about a settings group beside its fields, and the links a write left pointing nowhere. */
|
|
1519
|
+
RevisedSettingsGroupMetadata: {
|
|
1520
|
+
id: string;
|
|
1521
|
+
/** @description The settings group. */
|
|
1522
|
+
groupId: string;
|
|
1523
|
+
/** @description The reported locale’s own version counter — not the entry’s shared-field counter. `0` when that locale has no content of its own. With `id` and `locale`, it is what `X-Entity-Tag` is minted from. */
|
|
1524
|
+
version: number;
|
|
1525
|
+
/** @description The locale the fields beside this object were composed for. */
|
|
1526
|
+
locale: string;
|
|
1527
|
+
/** @description How many versions `locale` has. */
|
|
1528
|
+
versionCount: number;
|
|
1529
|
+
/** @description `locale`’s version numbers, newest first, at most 25. */
|
|
1530
|
+
versions: number[];
|
|
1531
|
+
/**
|
|
1532
|
+
* @description Publication state of `locale`. Absent when that locale has no content of its own: what is visible in it is inherited through the fallback chain.
|
|
1533
|
+
* @enum {string}
|
|
1534
|
+
*/
|
|
1535
|
+
localeStatus?: 'archived' | 'draft' | 'published';
|
|
1536
|
+
/** @description Whether `locale` has unpublished changes of its own. */
|
|
1537
|
+
localeHasDraft: boolean;
|
|
1538
|
+
/** @description Every locale holding unpublished content of its own, sorted. A shared-field draft is not listed: it is `hasDraft`. */
|
|
1539
|
+
draftLocales: string[];
|
|
1540
|
+
/** @description Whether the shared (non-localized) fields have unpublished changes. Publishing any locale makes them live, so they are unpublished work in every locale. */
|
|
1541
|
+
hasDraft: boolean;
|
|
1542
|
+
/**
|
|
1543
|
+
* Format: date-time
|
|
1544
|
+
* @description When the group was last written.
|
|
1545
|
+
*/
|
|
1546
|
+
updatedAt: string;
|
|
1547
|
+
/** @description Each entry link another entry publishes whose `anchor` names a heading this write took away from the settings group’s content, as an entry revision lists them. The write is never refused for them; the linking entry’s own next publish is (`ENTRY_LINK_ANCHOR_NOT_FOUND`). Empty when it took none away. A replay of the write under the same `Idempotency-Key` answers the list the write did. */
|
|
1548
|
+
brokenLinks?: components['schemas']['BrokenEntryLink'][];
|
|
1549
|
+
};
|
|
1550
|
+
/** @description The singleton after a write: its fields at the top level and `_metadata`, which also lists the links other entries publish that the write left pointing nowhere. */
|
|
1551
|
+
RevisedSingleton: {
|
|
1552
|
+
_metadata: components['schemas']['RevisedSingletonMetadata'];
|
|
1553
|
+
} & {
|
|
1554
|
+
[key: string]: unknown;
|
|
1555
|
+
};
|
|
1556
|
+
/** @description What this service reports about a singleton beside its fields, and the links a write left pointing nowhere. */
|
|
1557
|
+
RevisedSingletonMetadata: {
|
|
1558
|
+
id: string;
|
|
1559
|
+
/** @description The singleton type. */
|
|
1560
|
+
type: string;
|
|
1561
|
+
/**
|
|
1562
|
+
* @description Container lifecycle only. Publication is per locale: `localeStatus`.
|
|
1563
|
+
* @enum {string}
|
|
1564
|
+
*/
|
|
1565
|
+
status: 'active' | 'archived' | 'proposed';
|
|
1566
|
+
/** @description The reported locale’s own version counter — not the entry’s shared-field counter. `0` when that locale has no content of its own. With `id` and `locale`, it is what `X-Entity-Tag` is minted from. */
|
|
1567
|
+
version: number;
|
|
1568
|
+
/** @description The locale the fields beside this object were composed for. */
|
|
1569
|
+
locale: string;
|
|
1570
|
+
/** @description How many versions `locale` has. */
|
|
1571
|
+
versionCount: number;
|
|
1572
|
+
/** @description `locale`’s version numbers, newest first, at most 25. */
|
|
1573
|
+
versions: number[];
|
|
1574
|
+
/**
|
|
1575
|
+
* @description Publication state of `locale`. Absent when that locale has no content of its own: what is visible in it is inherited through the fallback chain.
|
|
1576
|
+
* @enum {string}
|
|
1577
|
+
*/
|
|
1578
|
+
localeStatus?: 'archived' | 'draft' | 'published';
|
|
1579
|
+
/** @description Whether `locale` has unpublished changes of its own. */
|
|
1580
|
+
localeHasDraft: boolean;
|
|
1581
|
+
/** @description Every locale holding unpublished content of its own, sorted. A shared-field draft is not listed: it is `hasDraft`. */
|
|
1582
|
+
draftLocales: string[];
|
|
1583
|
+
/** @description Whether the shared (non-localized) fields have unpublished changes. Publishing any locale makes them live, so they are unpublished work in every locale. */
|
|
1584
|
+
hasDraft: boolean;
|
|
1585
|
+
/**
|
|
1586
|
+
* Format: date-time
|
|
1587
|
+
* @description When the singleton was created.
|
|
1588
|
+
*/
|
|
1589
|
+
createdAt: string;
|
|
1590
|
+
/**
|
|
1591
|
+
* Format: date-time
|
|
1592
|
+
* @description When the singleton was last written.
|
|
1593
|
+
*/
|
|
1594
|
+
updatedAt: string;
|
|
1595
|
+
/**
|
|
1596
|
+
* Format: date-time
|
|
1597
|
+
* @description When the singleton was last published. Absent until it is.
|
|
1598
|
+
*/
|
|
1599
|
+
publishedAt?: string;
|
|
1600
|
+
/**
|
|
1601
|
+
* Format: date-time
|
|
1602
|
+
* @description When the singleton was first published. Absent until it is.
|
|
1603
|
+
*/
|
|
1604
|
+
firstPublishedAt?: string;
|
|
1605
|
+
/** @description Each required field the singleton holds no value for, which this read filled with its kind’s empty value, as a value path naming a list item by its key — as on an entry. Absent when none was. */
|
|
1606
|
+
emptyRequiredFields?: string[];
|
|
1607
|
+
/** @description Each entry link another entry publishes whose `anchor` names a heading this write took away from the singleton’s content, as an entry revision lists them. The write is never refused for them; the linking entry’s own next publish is (`ENTRY_LINK_ANCHOR_NOT_FOUND`). Empty when it took none away. A replay of the write under the same `Idempotency-Key` answers the list the write did. */
|
|
1608
|
+
brokenLinks?: components['schemas']['BrokenEntryLink'][];
|
|
1609
|
+
};
|
|
1303
1610
|
/** @description How a hit’s relevance was reached. Sent on a search that asked for `explain`. */
|
|
1304
1611
|
ScoreBreakdown: {
|
|
1305
1612
|
keyword: number;
|
|
@@ -1320,7 +1627,7 @@ interface components {
|
|
|
1320
1627
|
} & {
|
|
1321
1628
|
[key: string]: unknown;
|
|
1322
1629
|
};
|
|
1323
|
-
/** @description One hit: the entry’s fields at the top level — at `_metadata.locale`, or only the aliases a `fields` projection names — its `_metadata`, and the score annotations the request asked for. Not an entry read: see `SearchHitMetadata`. */
|
|
1630
|
+
/** @description One hit: the entry’s fields at the top level — at `_metadata.locale`, or only the aliases a `fields` projection names — its `_metadata`, and the score annotations the request asked for. A hit of an asset type also carries `file`, an `AssetFile`, and `urls`, an `AssetUrls`, once the file is ready. Not an entry read: see `SearchHitMetadata`. */
|
|
1324
1631
|
SearchHit: {
|
|
1325
1632
|
_metadata: components['schemas']['SearchHitMetadata'];
|
|
1326
1633
|
/** @description Relevance. Sent on a search that asked for `includeScore`, and on every similar hit. */
|
|
@@ -1510,13 +1817,15 @@ interface components {
|
|
|
1510
1817
|
* @description When the singleton was first published. Absent until it is.
|
|
1511
1818
|
*/
|
|
1512
1819
|
firstPublishedAt?: string;
|
|
1820
|
+
/** @description Each required field the singleton holds no value for, which this read filled with its kind’s empty value, as a value path naming a list item by its key — as on an entry. Absent when none was. */
|
|
1821
|
+
emptyRequiredFields?: string[];
|
|
1513
1822
|
};
|
|
1514
1823
|
SubFailure: {
|
|
1515
1824
|
index: number;
|
|
1516
1825
|
id?: string;
|
|
1517
1826
|
error: {
|
|
1518
1827
|
/** @enum {string} */
|
|
1519
|
-
code: 'ACCESS_DENIED' | 'CONTENT_INVALID' | 'INTERNAL_ERROR' | 'INVALID_API_KEY' | 'METHOD_NOT_ALLOWED' | 'MISSING_API_KEY' | 'ORGANIZATION_DELETE_BLOCKED' | 'PAYLOAD_TOO_LARGE' | 'PLAN_DOWNGRADE_BLOCKED' | 'PLAN_FEATURE_UNAVAILABLE' | 'RATE_LIMIT_EXCEEDED' | 'READ_ONLY_KEY' | 'REQUEST_INVALID' | 'REQUEST_TIMEOUT' | 'RESOURCE_CONFLICT' | 'RESOURCE_EXPIRED' | 'RESOURCE_NOT_FOUND' | 'REVERIFICATION_REQUIRED' | 'SERVICE_INDETERMINATE' | 'TRANSACTION_ROLLED_BACK' | 'USAGE_QUOTA_EXCEEDED' | 'USER_NOT_PROVISIONED';
|
|
1828
|
+
code: 'ACCESS_DENIED' | 'AI_UNAVAILABLE_IN_REGION' | 'CONTENT_INVALID' | 'INTERNAL_ERROR' | 'INVALID_API_KEY' | 'METHOD_NOT_ALLOWED' | 'MISSING_API_KEY' | 'ORGANIZATION_BEING_DELETED' | 'ORGANIZATION_DELETE_BLOCKED' | 'ORGANIZATION_IN_ANOTHER_CELL' | 'PAYLOAD_TOO_LARGE' | 'PLAN_DOWNGRADE_BLOCKED' | 'PLAN_FEATURE_UNAVAILABLE' | 'PROJECT_IN_ANOTHER_CELL' | 'RATE_LIMIT_EXCEEDED' | 'READ_ONLY_KEY' | 'REQUEST_INVALID' | 'REQUEST_TIMEOUT' | 'RESOURCE_CONFLICT' | 'RESOURCE_EXPIRED' | 'RESOURCE_NOT_FOUND' | 'REVERIFICATION_REQUIRED' | 'SERVICE_INDETERMINATE' | 'TRANSACTION_ROLLED_BACK' | 'USAGE_QUOTA_EXCEEDED' | 'USER_NOT_PROVISIONED';
|
|
1520
1829
|
messages: string[];
|
|
1521
1830
|
details?: {
|
|
1522
1831
|
[key: string]: unknown;
|
|
@@ -2100,6 +2409,15 @@ interface operations {
|
|
|
2100
2409
|
'application/json': components['schemas']['RefusalInternalError'];
|
|
2101
2410
|
};
|
|
2102
2411
|
};
|
|
2412
|
+
/** @description SERVICE_INDETERMINATE */
|
|
2413
|
+
503: {
|
|
2414
|
+
headers: {
|
|
2415
|
+
[name: string]: unknown;
|
|
2416
|
+
};
|
|
2417
|
+
content: {
|
|
2418
|
+
'application/json': components['schemas']['RefusalServiceIndeterminate'];
|
|
2419
|
+
};
|
|
2420
|
+
};
|
|
2103
2421
|
};
|
|
2104
2422
|
};
|
|
2105
2423
|
ingestUsage: {
|
|
@@ -2286,6 +2604,15 @@ interface operations {
|
|
|
2286
2604
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
2287
2605
|
};
|
|
2288
2606
|
};
|
|
2607
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
2608
|
+
421: {
|
|
2609
|
+
headers: {
|
|
2610
|
+
[name: string]: unknown;
|
|
2611
|
+
};
|
|
2612
|
+
content: {
|
|
2613
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
2614
|
+
};
|
|
2615
|
+
};
|
|
2289
2616
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2290
2617
|
429: {
|
|
2291
2618
|
headers: {
|
|
@@ -2394,6 +2721,15 @@ interface operations {
|
|
|
2394
2721
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
2395
2722
|
};
|
|
2396
2723
|
};
|
|
2724
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
2725
|
+
421: {
|
|
2726
|
+
headers: {
|
|
2727
|
+
[name: string]: unknown;
|
|
2728
|
+
};
|
|
2729
|
+
content: {
|
|
2730
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
2731
|
+
};
|
|
2732
|
+
};
|
|
2397
2733
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2398
2734
|
429: {
|
|
2399
2735
|
headers: {
|
|
@@ -2490,6 +2826,15 @@ interface operations {
|
|
|
2490
2826
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
2491
2827
|
};
|
|
2492
2828
|
};
|
|
2829
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
2830
|
+
421: {
|
|
2831
|
+
headers: {
|
|
2832
|
+
[name: string]: unknown;
|
|
2833
|
+
};
|
|
2834
|
+
content: {
|
|
2835
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
2836
|
+
};
|
|
2837
|
+
};
|
|
2493
2838
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2494
2839
|
429: {
|
|
2495
2840
|
headers: {
|
|
@@ -2595,6 +2940,15 @@ interface operations {
|
|
|
2595
2940
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
2596
2941
|
};
|
|
2597
2942
|
};
|
|
2943
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
2944
|
+
421: {
|
|
2945
|
+
headers: {
|
|
2946
|
+
[name: string]: unknown;
|
|
2947
|
+
};
|
|
2948
|
+
content: {
|
|
2949
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
2950
|
+
};
|
|
2951
|
+
};
|
|
2598
2952
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2599
2953
|
429: {
|
|
2600
2954
|
headers: {
|
|
@@ -2646,8 +3000,7 @@ interface operations {
|
|
|
2646
3000
|
};
|
|
2647
3001
|
content: {
|
|
2648
3002
|
'application/json': {
|
|
2649
|
-
|
|
2650
|
-
data: unknown;
|
|
3003
|
+
data: components['schemas']['RevisedEntry'];
|
|
2651
3004
|
};
|
|
2652
3005
|
};
|
|
2653
3006
|
};
|
|
@@ -2705,6 +3058,15 @@ interface operations {
|
|
|
2705
3058
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
2706
3059
|
};
|
|
2707
3060
|
};
|
|
3061
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3062
|
+
421: {
|
|
3063
|
+
headers: {
|
|
3064
|
+
[name: string]: unknown;
|
|
3065
|
+
};
|
|
3066
|
+
content: {
|
|
3067
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3068
|
+
};
|
|
3069
|
+
};
|
|
2708
3070
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2709
3071
|
429: {
|
|
2710
3072
|
headers: {
|
|
@@ -2801,6 +3163,15 @@ interface operations {
|
|
|
2801
3163
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
2802
3164
|
};
|
|
2803
3165
|
};
|
|
3166
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3167
|
+
421: {
|
|
3168
|
+
headers: {
|
|
3169
|
+
[name: string]: unknown;
|
|
3170
|
+
};
|
|
3171
|
+
content: {
|
|
3172
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3173
|
+
};
|
|
3174
|
+
};
|
|
2804
3175
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2805
3176
|
429: {
|
|
2806
3177
|
headers: {
|
|
@@ -2889,6 +3260,15 @@ interface operations {
|
|
|
2889
3260
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
2890
3261
|
};
|
|
2891
3262
|
};
|
|
3263
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3264
|
+
421: {
|
|
3265
|
+
headers: {
|
|
3266
|
+
[name: string]: unknown;
|
|
3267
|
+
};
|
|
3268
|
+
content: {
|
|
3269
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3270
|
+
};
|
|
3271
|
+
};
|
|
2892
3272
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2893
3273
|
429: {
|
|
2894
3274
|
headers: {
|
|
@@ -2991,6 +3371,15 @@ interface operations {
|
|
|
2991
3371
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
2992
3372
|
};
|
|
2993
3373
|
};
|
|
3374
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3375
|
+
421: {
|
|
3376
|
+
headers: {
|
|
3377
|
+
[name: string]: unknown;
|
|
3378
|
+
};
|
|
3379
|
+
content: {
|
|
3380
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3381
|
+
};
|
|
3382
|
+
};
|
|
2994
3383
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
2995
3384
|
429: {
|
|
2996
3385
|
headers: {
|
|
@@ -3098,6 +3487,15 @@ interface operations {
|
|
|
3098
3487
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3099
3488
|
};
|
|
3100
3489
|
};
|
|
3490
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3491
|
+
421: {
|
|
3492
|
+
headers: {
|
|
3493
|
+
[name: string]: unknown;
|
|
3494
|
+
};
|
|
3495
|
+
content: {
|
|
3496
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3497
|
+
};
|
|
3498
|
+
};
|
|
3101
3499
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3102
3500
|
429: {
|
|
3103
3501
|
headers: {
|
|
@@ -3205,6 +3603,15 @@ interface operations {
|
|
|
3205
3603
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3206
3604
|
};
|
|
3207
3605
|
};
|
|
3606
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3607
|
+
421: {
|
|
3608
|
+
headers: {
|
|
3609
|
+
[name: string]: unknown;
|
|
3610
|
+
};
|
|
3611
|
+
content: {
|
|
3612
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3613
|
+
};
|
|
3614
|
+
};
|
|
3208
3615
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3209
3616
|
429: {
|
|
3210
3617
|
headers: {
|
|
@@ -3312,6 +3719,15 @@ interface operations {
|
|
|
3312
3719
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3313
3720
|
};
|
|
3314
3721
|
};
|
|
3722
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3723
|
+
421: {
|
|
3724
|
+
headers: {
|
|
3725
|
+
[name: string]: unknown;
|
|
3726
|
+
};
|
|
3727
|
+
content: {
|
|
3728
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3729
|
+
};
|
|
3730
|
+
};
|
|
3315
3731
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3316
3732
|
429: {
|
|
3317
3733
|
headers: {
|
|
@@ -3419,6 +3835,15 @@ interface operations {
|
|
|
3419
3835
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3420
3836
|
};
|
|
3421
3837
|
};
|
|
3838
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3839
|
+
421: {
|
|
3840
|
+
headers: {
|
|
3841
|
+
[name: string]: unknown;
|
|
3842
|
+
};
|
|
3843
|
+
content: {
|
|
3844
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3845
|
+
};
|
|
3846
|
+
};
|
|
3422
3847
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3423
3848
|
429: {
|
|
3424
3849
|
headers: {
|
|
@@ -3526,6 +3951,15 @@ interface operations {
|
|
|
3526
3951
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3527
3952
|
};
|
|
3528
3953
|
};
|
|
3954
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
3955
|
+
421: {
|
|
3956
|
+
headers: {
|
|
3957
|
+
[name: string]: unknown;
|
|
3958
|
+
};
|
|
3959
|
+
content: {
|
|
3960
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
3961
|
+
};
|
|
3962
|
+
};
|
|
3529
3963
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3530
3964
|
429: {
|
|
3531
3965
|
headers: {
|
|
@@ -3633,6 +4067,15 @@ interface operations {
|
|
|
3633
4067
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3634
4068
|
};
|
|
3635
4069
|
};
|
|
4070
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4071
|
+
421: {
|
|
4072
|
+
headers: {
|
|
4073
|
+
[name: string]: unknown;
|
|
4074
|
+
};
|
|
4075
|
+
content: {
|
|
4076
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4077
|
+
};
|
|
4078
|
+
};
|
|
3636
4079
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3637
4080
|
429: {
|
|
3638
4081
|
headers: {
|
|
@@ -3740,6 +4183,15 @@ interface operations {
|
|
|
3740
4183
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3741
4184
|
};
|
|
3742
4185
|
};
|
|
4186
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4187
|
+
421: {
|
|
4188
|
+
headers: {
|
|
4189
|
+
[name: string]: unknown;
|
|
4190
|
+
};
|
|
4191
|
+
content: {
|
|
4192
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4193
|
+
};
|
|
4194
|
+
};
|
|
3743
4195
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3744
4196
|
429: {
|
|
3745
4197
|
headers: {
|
|
@@ -3847,6 +4299,15 @@ interface operations {
|
|
|
3847
4299
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
3848
4300
|
};
|
|
3849
4301
|
};
|
|
4302
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4303
|
+
421: {
|
|
4304
|
+
headers: {
|
|
4305
|
+
[name: string]: unknown;
|
|
4306
|
+
};
|
|
4307
|
+
content: {
|
|
4308
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4309
|
+
};
|
|
4310
|
+
};
|
|
3850
4311
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3851
4312
|
429: {
|
|
3852
4313
|
headers: {
|
|
@@ -3936,6 +4397,15 @@ interface operations {
|
|
|
3936
4397
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
3937
4398
|
};
|
|
3938
4399
|
};
|
|
4400
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4401
|
+
421: {
|
|
4402
|
+
headers: {
|
|
4403
|
+
[name: string]: unknown;
|
|
4404
|
+
};
|
|
4405
|
+
content: {
|
|
4406
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4407
|
+
};
|
|
4408
|
+
};
|
|
3939
4409
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
3940
4410
|
429: {
|
|
3941
4411
|
headers: {
|
|
@@ -4025,6 +4495,15 @@ interface operations {
|
|
|
4025
4495
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4026
4496
|
};
|
|
4027
4497
|
};
|
|
4498
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4499
|
+
421: {
|
|
4500
|
+
headers: {
|
|
4501
|
+
[name: string]: unknown;
|
|
4502
|
+
};
|
|
4503
|
+
content: {
|
|
4504
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4505
|
+
};
|
|
4506
|
+
};
|
|
4028
4507
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4029
4508
|
429: {
|
|
4030
4509
|
headers: {
|
|
@@ -4115,6 +4594,15 @@ interface operations {
|
|
|
4115
4594
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4116
4595
|
};
|
|
4117
4596
|
};
|
|
4597
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4598
|
+
421: {
|
|
4599
|
+
headers: {
|
|
4600
|
+
[name: string]: unknown;
|
|
4601
|
+
};
|
|
4602
|
+
content: {
|
|
4603
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4604
|
+
};
|
|
4605
|
+
};
|
|
4118
4606
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4119
4607
|
429: {
|
|
4120
4608
|
headers: {
|
|
@@ -4167,8 +4655,7 @@ interface operations {
|
|
|
4167
4655
|
};
|
|
4168
4656
|
content: {
|
|
4169
4657
|
'application/json': {
|
|
4170
|
-
|
|
4171
|
-
data: unknown;
|
|
4658
|
+
data: components['schemas']['RestoredEntry'];
|
|
4172
4659
|
};
|
|
4173
4660
|
};
|
|
4174
4661
|
};
|
|
@@ -4226,6 +4713,15 @@ interface operations {
|
|
|
4226
4713
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
4227
4714
|
};
|
|
4228
4715
|
};
|
|
4716
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4717
|
+
421: {
|
|
4718
|
+
headers: {
|
|
4719
|
+
[name: string]: unknown;
|
|
4720
|
+
};
|
|
4721
|
+
content: {
|
|
4722
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4723
|
+
};
|
|
4724
|
+
};
|
|
4229
4725
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4230
4726
|
429: {
|
|
4231
4727
|
headers: {
|
|
@@ -4329,6 +4825,15 @@ interface operations {
|
|
|
4329
4825
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
4330
4826
|
};
|
|
4331
4827
|
};
|
|
4828
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4829
|
+
421: {
|
|
4830
|
+
headers: {
|
|
4831
|
+
[name: string]: unknown;
|
|
4832
|
+
};
|
|
4833
|
+
content: {
|
|
4834
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4835
|
+
};
|
|
4836
|
+
};
|
|
4332
4837
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4333
4838
|
429: {
|
|
4334
4839
|
headers: {
|
|
@@ -4440,6 +4945,21 @@ interface operations {
|
|
|
4440
4945
|
};
|
|
4441
4946
|
};
|
|
4442
4947
|
};
|
|
4948
|
+
/** @description RESOURCE_NOT_FOUND */
|
|
4949
|
+
404: {
|
|
4950
|
+
headers: {
|
|
4951
|
+
[name: string]: unknown;
|
|
4952
|
+
};
|
|
4953
|
+
content: {
|
|
4954
|
+
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4955
|
+
'text/event-stream': {
|
|
4956
|
+
/** @enum {string} */
|
|
4957
|
+
type: 'change' | 'complete' | 'error' | 'heartbeat';
|
|
4958
|
+
} & {
|
|
4959
|
+
[key: string]: unknown;
|
|
4960
|
+
};
|
|
4961
|
+
};
|
|
4962
|
+
};
|
|
4443
4963
|
/** @description RESOURCE_EXPIRED */
|
|
4444
4964
|
410: {
|
|
4445
4965
|
headers: {
|
|
@@ -4455,6 +4975,21 @@ interface operations {
|
|
|
4455
4975
|
};
|
|
4456
4976
|
};
|
|
4457
4977
|
};
|
|
4978
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
4979
|
+
421: {
|
|
4980
|
+
headers: {
|
|
4981
|
+
[name: string]: unknown;
|
|
4982
|
+
};
|
|
4983
|
+
content: {
|
|
4984
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
4985
|
+
'text/event-stream': {
|
|
4986
|
+
/** @enum {string} */
|
|
4987
|
+
type: 'change' | 'complete' | 'error' | 'heartbeat';
|
|
4988
|
+
} & {
|
|
4989
|
+
[key: string]: unknown;
|
|
4990
|
+
};
|
|
4991
|
+
};
|
|
4992
|
+
};
|
|
4458
4993
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4459
4994
|
429: {
|
|
4460
4995
|
headers: {
|
|
@@ -4552,6 +5087,24 @@ interface operations {
|
|
|
4552
5087
|
'application/json': components['schemas']['RefusalAccessDeniedOrPlanFeatureUnavailableOrUsageQuotaExceeded'];
|
|
4553
5088
|
};
|
|
4554
5089
|
};
|
|
5090
|
+
/** @description RESOURCE_NOT_FOUND */
|
|
5091
|
+
404: {
|
|
5092
|
+
headers: {
|
|
5093
|
+
[name: string]: unknown;
|
|
5094
|
+
};
|
|
5095
|
+
content: {
|
|
5096
|
+
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5097
|
+
};
|
|
5098
|
+
};
|
|
5099
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5100
|
+
421: {
|
|
5101
|
+
headers: {
|
|
5102
|
+
[name: string]: unknown;
|
|
5103
|
+
};
|
|
5104
|
+
content: {
|
|
5105
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5106
|
+
};
|
|
5107
|
+
};
|
|
4555
5108
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4556
5109
|
429: {
|
|
4557
5110
|
headers: {
|
|
@@ -4640,6 +5193,15 @@ interface operations {
|
|
|
4640
5193
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4641
5194
|
};
|
|
4642
5195
|
};
|
|
5196
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5197
|
+
421: {
|
|
5198
|
+
headers: {
|
|
5199
|
+
[name: string]: unknown;
|
|
5200
|
+
};
|
|
5201
|
+
content: {
|
|
5202
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5203
|
+
};
|
|
5204
|
+
};
|
|
4643
5205
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4644
5206
|
429: {
|
|
4645
5207
|
headers: {
|
|
@@ -4719,6 +5281,24 @@ interface operations {
|
|
|
4719
5281
|
'application/json': components['schemas']['RefusalAccessDeniedOrPlanFeatureUnavailableOrUsageQuotaExceeded'];
|
|
4720
5282
|
};
|
|
4721
5283
|
};
|
|
5284
|
+
/** @description RESOURCE_NOT_FOUND */
|
|
5285
|
+
404: {
|
|
5286
|
+
headers: {
|
|
5287
|
+
[name: string]: unknown;
|
|
5288
|
+
};
|
|
5289
|
+
content: {
|
|
5290
|
+
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5291
|
+
};
|
|
5292
|
+
};
|
|
5293
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5294
|
+
421: {
|
|
5295
|
+
headers: {
|
|
5296
|
+
[name: string]: unknown;
|
|
5297
|
+
};
|
|
5298
|
+
content: {
|
|
5299
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5300
|
+
};
|
|
5301
|
+
};
|
|
4722
5302
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4723
5303
|
429: {
|
|
4724
5304
|
headers: {
|
|
@@ -4807,6 +5387,15 @@ interface operations {
|
|
|
4807
5387
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4808
5388
|
};
|
|
4809
5389
|
};
|
|
5390
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5391
|
+
421: {
|
|
5392
|
+
headers: {
|
|
5393
|
+
[name: string]: unknown;
|
|
5394
|
+
};
|
|
5395
|
+
content: {
|
|
5396
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5397
|
+
};
|
|
5398
|
+
};
|
|
4810
5399
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4811
5400
|
429: {
|
|
4812
5401
|
headers: {
|
|
@@ -4897,6 +5486,15 @@ interface operations {
|
|
|
4897
5486
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4898
5487
|
};
|
|
4899
5488
|
};
|
|
5489
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5490
|
+
421: {
|
|
5491
|
+
headers: {
|
|
5492
|
+
[name: string]: unknown;
|
|
5493
|
+
};
|
|
5494
|
+
content: {
|
|
5495
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5496
|
+
};
|
|
5497
|
+
};
|
|
4900
5498
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4901
5499
|
429: {
|
|
4902
5500
|
headers: {
|
|
@@ -4987,6 +5585,15 @@ interface operations {
|
|
|
4987
5585
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
4988
5586
|
};
|
|
4989
5587
|
};
|
|
5588
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5589
|
+
421: {
|
|
5590
|
+
headers: {
|
|
5591
|
+
[name: string]: unknown;
|
|
5592
|
+
};
|
|
5593
|
+
content: {
|
|
5594
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5595
|
+
};
|
|
5596
|
+
};
|
|
4990
5597
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
4991
5598
|
429: {
|
|
4992
5599
|
headers: {
|
|
@@ -5073,6 +5680,15 @@ interface operations {
|
|
|
5073
5680
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5074
5681
|
};
|
|
5075
5682
|
};
|
|
5683
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5684
|
+
421: {
|
|
5685
|
+
headers: {
|
|
5686
|
+
[name: string]: unknown;
|
|
5687
|
+
};
|
|
5688
|
+
content: {
|
|
5689
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5690
|
+
};
|
|
5691
|
+
};
|
|
5076
5692
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5077
5693
|
429: {
|
|
5078
5694
|
headers: {
|
|
@@ -5173,6 +5789,15 @@ interface operations {
|
|
|
5173
5789
|
'application/json': components['schemas']['RefusalRequestTimeout'];
|
|
5174
5790
|
};
|
|
5175
5791
|
};
|
|
5792
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5793
|
+
421: {
|
|
5794
|
+
headers: {
|
|
5795
|
+
[name: string]: unknown;
|
|
5796
|
+
};
|
|
5797
|
+
content: {
|
|
5798
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5799
|
+
};
|
|
5800
|
+
};
|
|
5176
5801
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5177
5802
|
429: {
|
|
5178
5803
|
headers: {
|
|
@@ -5267,6 +5892,15 @@ interface operations {
|
|
|
5267
5892
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5268
5893
|
};
|
|
5269
5894
|
};
|
|
5895
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5896
|
+
421: {
|
|
5897
|
+
headers: {
|
|
5898
|
+
[name: string]: unknown;
|
|
5899
|
+
};
|
|
5900
|
+
content: {
|
|
5901
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5902
|
+
};
|
|
5903
|
+
};
|
|
5270
5904
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5271
5905
|
429: {
|
|
5272
5906
|
headers: {
|
|
@@ -5352,6 +5986,24 @@ interface operations {
|
|
|
5352
5986
|
'application/json': components['schemas']['RefusalAccessDeniedOrPlanFeatureUnavailableOrUsageQuotaExceeded'];
|
|
5353
5987
|
};
|
|
5354
5988
|
};
|
|
5989
|
+
/** @description RESOURCE_NOT_FOUND */
|
|
5990
|
+
404: {
|
|
5991
|
+
headers: {
|
|
5992
|
+
[name: string]: unknown;
|
|
5993
|
+
};
|
|
5994
|
+
content: {
|
|
5995
|
+
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5996
|
+
};
|
|
5997
|
+
};
|
|
5998
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
5999
|
+
421: {
|
|
6000
|
+
headers: {
|
|
6001
|
+
[name: string]: unknown;
|
|
6002
|
+
};
|
|
6003
|
+
content: {
|
|
6004
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6005
|
+
};
|
|
6006
|
+
};
|
|
5355
6007
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5356
6008
|
429: {
|
|
5357
6009
|
headers: {
|
|
@@ -5446,6 +6098,15 @@ interface operations {
|
|
|
5446
6098
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5447
6099
|
};
|
|
5448
6100
|
};
|
|
6101
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6102
|
+
421: {
|
|
6103
|
+
headers: {
|
|
6104
|
+
[name: string]: unknown;
|
|
6105
|
+
};
|
|
6106
|
+
content: {
|
|
6107
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6108
|
+
};
|
|
6109
|
+
};
|
|
5449
6110
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5450
6111
|
429: {
|
|
5451
6112
|
headers: {
|
|
@@ -5529,27 +6190,45 @@ interface operations {
|
|
|
5529
6190
|
'application/json': components['schemas']['RefusalAccessDeniedOrPlanFeatureUnavailableOrUsageQuotaExceeded'];
|
|
5530
6191
|
};
|
|
5531
6192
|
};
|
|
5532
|
-
/** @description
|
|
5533
|
-
|
|
6193
|
+
/** @description RESOURCE_NOT_FOUND */
|
|
6194
|
+
404: {
|
|
5534
6195
|
headers: {
|
|
5535
6196
|
[name: string]: unknown;
|
|
5536
6197
|
};
|
|
5537
6198
|
content: {
|
|
5538
|
-
'application/json': components['schemas']['
|
|
6199
|
+
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5539
6200
|
};
|
|
5540
6201
|
};
|
|
5541
|
-
/** @description
|
|
5542
|
-
|
|
6202
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6203
|
+
421: {
|
|
5543
6204
|
headers: {
|
|
5544
6205
|
[name: string]: unknown;
|
|
5545
6206
|
};
|
|
5546
6207
|
content: {
|
|
5547
|
-
'application/json': components['schemas']['
|
|
6208
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
5548
6209
|
};
|
|
5549
6210
|
};
|
|
5550
|
-
/** @description
|
|
5551
|
-
|
|
5552
|
-
headers: {
|
|
6211
|
+
/** @description RATE_LIMIT_EXCEEDED */
|
|
6212
|
+
429: {
|
|
6213
|
+
headers: {
|
|
6214
|
+
[name: string]: unknown;
|
|
6215
|
+
};
|
|
6216
|
+
content: {
|
|
6217
|
+
'application/json': components['schemas']['RefusalRateLimitExceeded'];
|
|
6218
|
+
};
|
|
6219
|
+
};
|
|
6220
|
+
/** @description INTERNAL_ERROR */
|
|
6221
|
+
500: {
|
|
6222
|
+
headers: {
|
|
6223
|
+
[name: string]: unknown;
|
|
6224
|
+
};
|
|
6225
|
+
content: {
|
|
6226
|
+
'application/json': components['schemas']['RefusalInternalError'];
|
|
6227
|
+
};
|
|
6228
|
+
};
|
|
6229
|
+
/** @description SERVICE_INDETERMINATE */
|
|
6230
|
+
503: {
|
|
6231
|
+
headers: {
|
|
5553
6232
|
[name: string]: unknown;
|
|
5554
6233
|
};
|
|
5555
6234
|
content: {
|
|
@@ -5624,6 +6303,15 @@ interface operations {
|
|
|
5624
6303
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5625
6304
|
};
|
|
5626
6305
|
};
|
|
6306
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6307
|
+
421: {
|
|
6308
|
+
headers: {
|
|
6309
|
+
[name: string]: unknown;
|
|
6310
|
+
};
|
|
6311
|
+
content: {
|
|
6312
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6313
|
+
};
|
|
6314
|
+
};
|
|
5627
6315
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5628
6316
|
429: {
|
|
5629
6317
|
headers: {
|
|
@@ -5674,8 +6362,7 @@ interface operations {
|
|
|
5674
6362
|
};
|
|
5675
6363
|
content: {
|
|
5676
6364
|
'application/json': {
|
|
5677
|
-
|
|
5678
|
-
data: unknown;
|
|
6365
|
+
data: components['schemas']['RevisedSettingsGroup'];
|
|
5679
6366
|
};
|
|
5680
6367
|
};
|
|
5681
6368
|
};
|
|
@@ -5733,6 +6420,15 @@ interface operations {
|
|
|
5733
6420
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
5734
6421
|
};
|
|
5735
6422
|
};
|
|
6423
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6424
|
+
421: {
|
|
6425
|
+
headers: {
|
|
6426
|
+
[name: string]: unknown;
|
|
6427
|
+
};
|
|
6428
|
+
content: {
|
|
6429
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6430
|
+
};
|
|
6431
|
+
};
|
|
5736
6432
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5737
6433
|
429: {
|
|
5738
6434
|
headers: {
|
|
@@ -5821,6 +6517,15 @@ interface operations {
|
|
|
5821
6517
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
5822
6518
|
};
|
|
5823
6519
|
};
|
|
6520
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6521
|
+
421: {
|
|
6522
|
+
headers: {
|
|
6523
|
+
[name: string]: unknown;
|
|
6524
|
+
};
|
|
6525
|
+
content: {
|
|
6526
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6527
|
+
};
|
|
6528
|
+
};
|
|
5824
6529
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5825
6530
|
429: {
|
|
5826
6531
|
headers: {
|
|
@@ -5871,8 +6576,7 @@ interface operations {
|
|
|
5871
6576
|
};
|
|
5872
6577
|
content: {
|
|
5873
6578
|
'application/json': {
|
|
5874
|
-
|
|
5875
|
-
data: unknown;
|
|
6579
|
+
data: components['schemas']['RevisedSettingsGroup'];
|
|
5876
6580
|
};
|
|
5877
6581
|
};
|
|
5878
6582
|
};
|
|
@@ -5930,6 +6634,15 @@ interface operations {
|
|
|
5930
6634
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
5931
6635
|
};
|
|
5932
6636
|
};
|
|
6637
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6638
|
+
421: {
|
|
6639
|
+
headers: {
|
|
6640
|
+
[name: string]: unknown;
|
|
6641
|
+
};
|
|
6642
|
+
content: {
|
|
6643
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6644
|
+
};
|
|
6645
|
+
};
|
|
5933
6646
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
5934
6647
|
429: {
|
|
5935
6648
|
headers: {
|
|
@@ -6018,6 +6731,15 @@ interface operations {
|
|
|
6018
6731
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6019
6732
|
};
|
|
6020
6733
|
};
|
|
6734
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6735
|
+
421: {
|
|
6736
|
+
headers: {
|
|
6737
|
+
[name: string]: unknown;
|
|
6738
|
+
};
|
|
6739
|
+
content: {
|
|
6740
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6741
|
+
};
|
|
6742
|
+
};
|
|
6021
6743
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6022
6744
|
429: {
|
|
6023
6745
|
headers: {
|
|
@@ -6107,6 +6829,15 @@ interface operations {
|
|
|
6107
6829
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6108
6830
|
};
|
|
6109
6831
|
};
|
|
6832
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6833
|
+
421: {
|
|
6834
|
+
headers: {
|
|
6835
|
+
[name: string]: unknown;
|
|
6836
|
+
};
|
|
6837
|
+
content: {
|
|
6838
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6839
|
+
};
|
|
6840
|
+
};
|
|
6110
6841
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6111
6842
|
429: {
|
|
6112
6843
|
headers: {
|
|
@@ -6202,6 +6933,15 @@ interface operations {
|
|
|
6202
6933
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6203
6934
|
};
|
|
6204
6935
|
};
|
|
6936
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
6937
|
+
421: {
|
|
6938
|
+
headers: {
|
|
6939
|
+
[name: string]: unknown;
|
|
6940
|
+
};
|
|
6941
|
+
content: {
|
|
6942
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
6943
|
+
};
|
|
6944
|
+
};
|
|
6205
6945
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6206
6946
|
429: {
|
|
6207
6947
|
headers: {
|
|
@@ -6252,8 +6992,7 @@ interface operations {
|
|
|
6252
6992
|
};
|
|
6253
6993
|
content: {
|
|
6254
6994
|
'application/json': {
|
|
6255
|
-
|
|
6256
|
-
data: unknown;
|
|
6995
|
+
data: components['schemas']['RevisedSingleton'];
|
|
6257
6996
|
};
|
|
6258
6997
|
};
|
|
6259
6998
|
};
|
|
@@ -6311,6 +7050,15 @@ interface operations {
|
|
|
6311
7050
|
'application/json': components['schemas']['RefusalResourceExpired'];
|
|
6312
7051
|
};
|
|
6313
7052
|
};
|
|
7053
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
7054
|
+
421: {
|
|
7055
|
+
headers: {
|
|
7056
|
+
[name: string]: unknown;
|
|
7057
|
+
};
|
|
7058
|
+
content: {
|
|
7059
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
7060
|
+
};
|
|
7061
|
+
};
|
|
6314
7062
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6315
7063
|
429: {
|
|
6316
7064
|
headers: {
|
|
@@ -6399,6 +7147,15 @@ interface operations {
|
|
|
6399
7147
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6400
7148
|
};
|
|
6401
7149
|
};
|
|
7150
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
7151
|
+
421: {
|
|
7152
|
+
headers: {
|
|
7153
|
+
[name: string]: unknown;
|
|
7154
|
+
};
|
|
7155
|
+
content: {
|
|
7156
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
7157
|
+
};
|
|
7158
|
+
};
|
|
6402
7159
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6403
7160
|
429: {
|
|
6404
7161
|
headers: {
|
|
@@ -6487,6 +7244,15 @@ interface operations {
|
|
|
6487
7244
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6488
7245
|
};
|
|
6489
7246
|
};
|
|
7247
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
7248
|
+
421: {
|
|
7249
|
+
headers: {
|
|
7250
|
+
[name: string]: unknown;
|
|
7251
|
+
};
|
|
7252
|
+
content: {
|
|
7253
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
7254
|
+
};
|
|
7255
|
+
};
|
|
6490
7256
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6491
7257
|
429: {
|
|
6492
7258
|
headers: {
|
|
@@ -6576,6 +7342,15 @@ interface operations {
|
|
|
6576
7342
|
'application/json': components['schemas']['RefusalResourceNotFound'];
|
|
6577
7343
|
};
|
|
6578
7344
|
};
|
|
7345
|
+
/** @description PROJECT_IN_ANOTHER_CELL */
|
|
7346
|
+
421: {
|
|
7347
|
+
headers: {
|
|
7348
|
+
[name: string]: unknown;
|
|
7349
|
+
};
|
|
7350
|
+
content: {
|
|
7351
|
+
'application/json': components['schemas']['RefusalProjectInAnotherCell'];
|
|
7352
|
+
};
|
|
7353
|
+
};
|
|
6579
7354
|
/** @description RATE_LIMIT_EXCEEDED */
|
|
6580
7355
|
429: {
|
|
6581
7356
|
headers: {
|
|
@@ -6608,284 +7383,456 @@ interface operations {
|
|
|
6608
7383
|
}
|
|
6609
7384
|
|
|
6610
7385
|
/**
|
|
6611
|
-
*
|
|
7386
|
+
* Where the SDK's transport gets its truth.
|
|
6612
7387
|
*
|
|
6613
|
-
* Every
|
|
6614
|
-
*
|
|
6615
|
-
*
|
|
6616
|
-
*
|
|
6617
|
-
*
|
|
6618
|
-
* `
|
|
6619
|
-
* the
|
|
7388
|
+
* Every route this client calls is named by its **path template as the
|
|
7389
|
+
* committed document spells it**, and the body type it expects is read out of
|
|
7390
|
+
* that document rather than written down here. `api-schema.ts` beside this file
|
|
7391
|
+
* is generated by `pnpm api:types` from `apps/services/api/openapi-spec.json`,
|
|
7392
|
+
* which is itself generated from that service's `RouteContract`s
|
|
7393
|
+
* (`INV-API-DOCUMENT-IS-DERIVED`). So the chain is: one declaration in
|
|
7394
|
+
* `routes.ts` → the serializer that produces the body → the document → these
|
|
7395
|
+
* types → the method that reads it.
|
|
7396
|
+
*
|
|
7397
|
+
* That chain is the answer to the question this phase exists to close. Before
|
|
7398
|
+
* it, six SDK methods read a key the server does not send; each had no caller
|
|
7399
|
+
* and no test, so nothing could see them. Now:
|
|
7400
|
+
*
|
|
7401
|
+
* - A route that changes **kind** — `collection` to `object`, say — changes
|
|
7402
|
+
* whether the document's 200 body carries `page` and whether `data` is an
|
|
7403
|
+
* array. `Wire<…>` follows, `readPayload` follows, and the method's declared
|
|
7404
|
+
* return type stops matching. `tsc` names the method.
|
|
7405
|
+
* - A route that changes **path** or is deleted stops being a `keyof paths`, so
|
|
7406
|
+
* the call site fails on the literal.
|
|
7407
|
+
* - A route that changes **dialect** changes `page` from `CursorPage` to
|
|
7408
|
+
* `OffsetPage`, and anything reading `nextCursor` fails.
|
|
7409
|
+
*
|
|
7410
|
+
* `/v1` lives in these templates because it lives in the document
|
|
7411
|
+
* (`INV-API-VERSION-IS-DECIDED-ONCE`). Before this phase the SDK's base URL was
|
|
7412
|
+
* `https://api.relyio.com` and its paths were `/{contentType}`, so every
|
|
7413
|
+
* versioned request went to a path the router does not serve.
|
|
7414
|
+
*
|
|
7415
|
+
* Spec: `devtools/docs/guide/engineering/api-contract-spec.md`,
|
|
7416
|
+
* `INV-API-CLIENT-IS-DERIVED`.
|
|
7417
|
+
*/
|
|
7418
|
+
|
|
7419
|
+
/** Every path the committed document declares. */
|
|
7420
|
+
type ApiPath = keyof paths;
|
|
7421
|
+
type Verb = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
7422
|
+
/** The verbs the document declares on this path — not the seven HTTP has. */
|
|
7423
|
+
type ApiMethod<P extends ApiPath> = {
|
|
7424
|
+
[M in Verb]: M extends keyof paths[P] ? paths[P][M] extends {
|
|
7425
|
+
responses: unknown;
|
|
7426
|
+
} ? M : never : never;
|
|
7427
|
+
}[Verb];
|
|
7428
|
+
type Operation<P extends ApiPath, M extends ApiMethod<P>> = M extends keyof paths[P] ? paths[P][M] : never;
|
|
7429
|
+
type JsonBody<R> = R extends {
|
|
7430
|
+
content: {
|
|
7431
|
+
'application/json': infer B;
|
|
7432
|
+
};
|
|
7433
|
+
} ? B : never;
|
|
7434
|
+
/**
|
|
7435
|
+
* The success body the document declares, preferring 200 where a route serves
|
|
7436
|
+
* both. A route with neither — `kind: 'empty'`, which serves 204 — resolves to
|
|
7437
|
+
* `never`, and `readPayload` cannot be called on it.
|
|
6620
7438
|
*/
|
|
7439
|
+
type ApiSuccessBody<P extends ApiPath, M extends ApiMethod<P>> = Operation<P, M> extends {
|
|
7440
|
+
responses: infer R;
|
|
7441
|
+
} ? 200 extends keyof R ? JsonBody<R[200]> : 201 extends keyof R ? JsonBody<R[201]> : never : never;
|
|
6621
7442
|
/**
|
|
6622
|
-
*
|
|
6623
|
-
* element is and how AI should produce its value. Attaches to fields, content
|
|
6624
|
-
* types, components, fieldsets, and (extended) asset types.
|
|
7443
|
+
* The document's success body with the payload typed as the caller's `T`.
|
|
6625
7444
|
*
|
|
6626
|
-
*
|
|
6627
|
-
*
|
|
6628
|
-
*
|
|
6629
|
-
*
|
|
6630
|
-
*
|
|
6631
|
-
* Write in a conversational tone.
|
|
6632
|
-
* Use short paragraphs (2-3 sentences).
|
|
6633
|
-
* Target grade 8 reading level.
|
|
6634
|
-
* `
|
|
6635
|
-
* }
|
|
6636
|
-
* })
|
|
6637
|
-
* ```
|
|
7445
|
+
* The array arm is tested **first** on purpose: `{ data: unknown[] }` also
|
|
7446
|
+
* satisfies `{ data: unknown }`, so the object arm would swallow every
|
|
7447
|
+
* collection and hand a list route's caller a single entity — which is the
|
|
7448
|
+
* exact defect class (`ContentClient.children` reading `.data.items` from an
|
|
7449
|
+
* object route) that this phase makes unrepresentable.
|
|
6638
7450
|
*/
|
|
6639
|
-
|
|
7451
|
+
type Wire<P extends ApiPath, M extends ApiMethod<P>, T> = ApiSuccessBody<P, M> extends {
|
|
7452
|
+
data: unknown[];
|
|
7453
|
+
} ? Omit<ApiSuccessBody<P, M>, 'data'> & {
|
|
7454
|
+
data: T[];
|
|
7455
|
+
} : ApiSuccessBody<P, M> extends {
|
|
7456
|
+
data: unknown;
|
|
7457
|
+
} ? Omit<ApiSuccessBody<P, M>, 'data'> & {
|
|
7458
|
+
data: T;
|
|
7459
|
+
} : ApiSuccessBody<P, M>;
|
|
7460
|
+
/**
|
|
7461
|
+
* The path parameters the document declares for this operation, or `never`
|
|
7462
|
+
* where it declares none.
|
|
7463
|
+
*
|
|
7464
|
+
* `never` rather than `{}`: a route with no segments must **forbid** a `path`
|
|
7465
|
+
* argument, not merely tolerate an empty one, and `keyof Record<string, never>`
|
|
7466
|
+
* is `string`, so an empty-object encoding cannot be told apart from a real
|
|
7467
|
+
* one at the type level.
|
|
7468
|
+
*/
|
|
7469
|
+
type PathParamsOf<P extends ApiPath, M extends ApiMethod<P>> = Operation<P, M> extends {
|
|
7470
|
+
parameters: {
|
|
7471
|
+
path?: infer X;
|
|
7472
|
+
};
|
|
7473
|
+
} ? [X] extends [undefined] ? never : NonNullable<X> : never;
|
|
7474
|
+
/** What {@link matchRoute} recovers from a URL the client emitted. */
|
|
7475
|
+
interface RouteMatch {
|
|
7476
|
+
/** The document's path template — the value a tag translator switches on. */
|
|
7477
|
+
path: ApiPath;
|
|
7478
|
+
/** The template's `{name}` segments, decoded: the inverse of {@link fillPath}. */
|
|
7479
|
+
params: Record<string, string>;
|
|
7480
|
+
/** The query string; a key that appears more than once comes back as an array. */
|
|
7481
|
+
query: Record<string, string | string[]>;
|
|
7482
|
+
}
|
|
7483
|
+
interface MatchRouteOptions {
|
|
6640
7484
|
/**
|
|
6641
|
-
*
|
|
6642
|
-
*
|
|
6643
|
-
*
|
|
6644
|
-
* `ai.autoGenerate` — by the automatic post-upload run.
|
|
6645
|
-
*
|
|
6646
|
-
* The fallback chain for AI guidance is:
|
|
6647
|
-
* 1. ai.instructions (most specific)
|
|
6648
|
-
* 2. ui.description (general field description)
|
|
6649
|
-
* 3. Field displayName + type (inferred from semantics)
|
|
7485
|
+
* The client's `baseUrl`, when it carries a path prefix of its own
|
|
7486
|
+
* (`https://example.com/relyio`). Its path is removed before the template is
|
|
7487
|
+
* matched. Unneeded for the default `https://api.relyio.com`.
|
|
6650
7488
|
*/
|
|
6651
|
-
|
|
7489
|
+
baseUrl?: string;
|
|
6652
7490
|
}
|
|
6653
7491
|
/**
|
|
6654
|
-
*
|
|
6655
|
-
*
|
|
7492
|
+
* Recover the route a URL names: the inverse of {@link fillPath}, over the same
|
|
7493
|
+
* committed document (`INV-API-CLIENT-IS-DERIVED`).
|
|
7494
|
+
*
|
|
7495
|
+
* `matchRoute(url).path` is an `ApiPath`, so anything that keys behaviour on a
|
|
7496
|
+
* request — a cache-tag translator, say — switches on the document's templates
|
|
7497
|
+
* and never on a route table of its own.
|
|
7498
|
+
*
|
|
7499
|
+
* Returns `null` for a URL no declared template matches — a presigned storage
|
|
7500
|
+
* URL, or a path outside `baseUrl` — rather than a guess.
|
|
6656
7501
|
*/
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
inputs?: string[];
|
|
6660
|
-
}
|
|
7502
|
+
declare function matchRoute(url: string | URL, options?: MatchRouteOptions): RouteMatch | null;
|
|
7503
|
+
|
|
6661
7504
|
/**
|
|
6662
|
-
*
|
|
6663
|
-
* the single switch that turns on automatic field generation after upload.
|
|
7505
|
+
* Configuration types for the RelyIO SDK
|
|
6664
7506
|
*/
|
|
6665
|
-
|
|
7507
|
+
|
|
7508
|
+
interface RelyIOConfig {
|
|
6666
7509
|
/**
|
|
6667
|
-
*
|
|
6668
|
-
*
|
|
6669
|
-
*
|
|
7510
|
+
* API key for authentication, sent as `X-API-Key`.
|
|
7511
|
+
*
|
|
7512
|
+
* Required by every request, not by construction: a client built without one — a module-scope
|
|
7513
|
+
* client whose `process.env` variable is unset during a build — constructs, and each request it
|
|
7514
|
+
* makes rejects with `MissingApiKeyError` before anything is sent. Under `relyio dev` the
|
|
7515
|
+
* sandbox's key is used instead, so none need be configured.
|
|
6670
7516
|
*/
|
|
6671
|
-
|
|
7517
|
+
apiKey: string;
|
|
7518
|
+
/** Base URL for the RelyIO API */
|
|
7519
|
+
baseUrl?: string;
|
|
7520
|
+
/** Dataset to use */
|
|
7521
|
+
dataset?: string;
|
|
7522
|
+
/**
|
|
7523
|
+
* Default locale for all content queries
|
|
7524
|
+
* Can be overridden per-query using .locale() or .withLocale()
|
|
7525
|
+
*
|
|
7526
|
+
* @example
|
|
7527
|
+
* const client = createClient({
|
|
7528
|
+
* apiKey: '...',
|
|
7529
|
+
* locale: 'en-US', // All queries default to English
|
|
7530
|
+
* })
|
|
7531
|
+
*/
|
|
7532
|
+
locale?: string;
|
|
7533
|
+
/**
|
|
7534
|
+
* How long one request may take, in milliseconds, before it ends as a `TimeoutError` (defaults
|
|
7535
|
+
* to 30000). A number from 1 to 2147483647, the longest a timer waits; `0`, `NaN`, `Infinity` or
|
|
7536
|
+
* anything larger is refused, and no value turns the timeout off.
|
|
7537
|
+
*/
|
|
7538
|
+
timeout?: number;
|
|
7539
|
+
/**
|
|
7540
|
+
* The most attempts one request makes, the first included (defaults to 3). `1` turns retrying
|
|
7541
|
+
* off; a value that is not a whole number of at least 1 is refused. Only a failure a later attempt
|
|
7542
|
+
* can change is retried, and only where sending the request twice cannot apply it twice.
|
|
7543
|
+
*/
|
|
7544
|
+
retryAttempts?: number;
|
|
7545
|
+
/** Whether to use HTTPS (defaults to true) */
|
|
7546
|
+
useSsl?: boolean;
|
|
7547
|
+
/** Environment mode */
|
|
7548
|
+
environment?: 'development' | 'staging' | 'production';
|
|
7549
|
+
/**
|
|
7550
|
+
* Cache configuration.
|
|
7551
|
+
*
|
|
7552
|
+
* Declarative only: the client keeps no response cache, and nothing in it reads
|
|
7553
|
+
* these values, so every call goes to `fetch`. There is no SDK-side cache to
|
|
7554
|
+
* turn off under a framework that caches `fetch` itself (Next.js).
|
|
7555
|
+
*/
|
|
7556
|
+
cache?: CacheConfig;
|
|
7557
|
+
/** Real-time configuration */
|
|
7558
|
+
realtime?: RealtimeConfig;
|
|
7559
|
+
/** Debug configuration */
|
|
7560
|
+
debug?: DebugConfig;
|
|
7561
|
+
/** Custom headers to include with requests */
|
|
7562
|
+
headers?: Record<string, string>;
|
|
7563
|
+
/**
|
|
7564
|
+
* The function every request to the RelyIO API is sent through. Omit it and the
|
|
7565
|
+
* client calls the runtime's `globalThis.fetch`, looked up per request. File
|
|
7566
|
+
* bytes an asset upload PUTs straight to a presigned storage URL do not pass
|
|
7567
|
+
* through it.
|
|
7568
|
+
*
|
|
7569
|
+
* The client still builds every request — URL, method, headers, body, signal —
|
|
7570
|
+
* and hands this function that `RequestInit` unchanged, retries included, so an
|
|
7571
|
+
* `Idempotency-Key` minted for a write is the same on every attempt. Supply one
|
|
7572
|
+
* to add what your framework reads off the `RequestInit`, for example Next.js
|
|
7573
|
+
* cache tags:
|
|
7574
|
+
*
|
|
7575
|
+
* @example
|
|
7576
|
+
* const client = createClient({
|
|
7577
|
+
* apiKey: '...',
|
|
7578
|
+
* fetch: (input, init) => fetch(input, { ...init, next: { tags: ['posts'] } }),
|
|
7579
|
+
* })
|
|
7580
|
+
*/
|
|
7581
|
+
fetch?: typeof globalThis.fetch;
|
|
7582
|
+
/**
|
|
7583
|
+
* RelyIO's live edge, which `liveChanges()` — and `<RelyIOProvider live>` from `@relyio/react`
|
|
7584
|
+
* with a publishable key — follows a dataset's published changes at. An `https:` or `wss:` URL
|
|
7585
|
+
* (`http:` or `ws:` for a local one); the socket and the poll each use the scheme they need.
|
|
7586
|
+
*
|
|
7587
|
+
* Omitted, it is derived from `baseUrl` for RelyIO's own API only: `https://api.relyio.com`
|
|
7588
|
+
* (the default) follows `https://live.relyio.com`. For any other `baseUrl` there is no address to
|
|
7589
|
+
* derive, so set this, or `liveChanges()` ends at once with a `LiveEdgeError` naming it and sends
|
|
7590
|
+
* nothing.
|
|
7591
|
+
*
|
|
7592
|
+
* @example
|
|
7593
|
+
* const relyio = createClient({
|
|
7594
|
+
* apiKey: 'rly_pub_…',
|
|
7595
|
+
* baseUrl: 'http://localhost:3000',
|
|
7596
|
+
* liveUrl: 'http://localhost:8787',
|
|
7597
|
+
* })
|
|
7598
|
+
*/
|
|
7599
|
+
liveUrl?: string;
|
|
7600
|
+
/**
|
|
7601
|
+
* The `WebSocket` class `liveChanges()` opens its socket with. Omit it and the client uses the
|
|
7602
|
+
* runtime's global `WebSocket` — every browser, and Node 22 or later — looked up per connection.
|
|
7603
|
+
* Where there is none, as in Node 18 and 20, it polls the edge instead, about every fifteen
|
|
7604
|
+
* seconds.
|
|
7605
|
+
*
|
|
7606
|
+
* Supply one to use a library's socket where the runtime has none, or to add what your runtime
|
|
7607
|
+
* lets a socket carry.
|
|
7608
|
+
*/
|
|
7609
|
+
webSocket?: LiveWebSocketConstructor;
|
|
7610
|
+
/** Browser-specific configuration */
|
|
7611
|
+
browser?: BrowserConfig;
|
|
7612
|
+
/**
|
|
7613
|
+
* `relyio dev` sandbox detection.
|
|
7614
|
+
*
|
|
7615
|
+
* When developing under `relyio dev`, the CLI injects an ephemeral sandbox's dataset + scoped
|
|
7616
|
+
* preview API key (via env vars or a local `.relyio/dev.json`). The SDK then transparently
|
|
7617
|
+
* targets that sandbox instead of production — no code changes required.
|
|
7618
|
+
*
|
|
7619
|
+
* - Omit (default): detection runs automatically unless `NODE_ENV === 'production'`, so
|
|
7620
|
+
* `relyio dev -- pnpm dev` "just works" while production builds stay untouched.
|
|
7621
|
+
* - `false`: disable detection entirely (force production targeting even in a dev shell).
|
|
7622
|
+
* - `true`: force detection even when `NODE_ENV === 'production'`.
|
|
7623
|
+
*/
|
|
7624
|
+
dev?: boolean;
|
|
6672
7625
|
}
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
7626
|
+
/**
|
|
7627
|
+
* The part of a `WebSocket` the live edge transport uses. A browser's `WebSocket` and Node's (22 and
|
|
7628
|
+
* later) are assignable as they are; `src/__tests__/changes.types.ts` holds the platform's to it.
|
|
7629
|
+
* Each event reaches its listener as `unknown` and is read field by field.
|
|
7630
|
+
*/
|
|
7631
|
+
interface LiveWebSocket {
|
|
7632
|
+
/** `0` connecting, `1` open, `2` closing, `3` closed. */
|
|
7633
|
+
readonly readyState: number;
|
|
7634
|
+
send(data: string): void;
|
|
7635
|
+
close(code?: number, reason?: string): void;
|
|
7636
|
+
addEventListener(type: 'open' | 'message' | 'close' | 'error', listener: (event: unknown) => void): void;
|
|
6680
7637
|
}
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
7638
|
+
type LiveWebSocketConstructor = new (url: string) => LiveWebSocket;
|
|
7639
|
+
/**
|
|
7640
|
+
* What `updateConfig()` takes: any option of {@link RelyIOConfig}, each laid over the value the
|
|
7641
|
+
* client holds rather than over its default.
|
|
7642
|
+
*
|
|
7643
|
+
* An option left out or given as `undefined` keeps the value the client holds, and a bag of options
|
|
7644
|
+
* you name keeps every field you do not name. `null` removes — "`undefined` keeps, `null` removes" —
|
|
7645
|
+
* and the types accept it only where a value can go: an option with no default (`locale`,
|
|
7646
|
+
* `dataset`, `fetch`, `browser.onCorsError`, `debug.logger`, …), which is then absent, and a header,
|
|
7647
|
+
* which is then no longer sent. An option with a default takes no `null`: removed, it would leave
|
|
7648
|
+
* nothing but that default. `createClient()` has nothing to remove, so its options take no `null`.
|
|
7649
|
+
*
|
|
7650
|
+
* Which options have no default is read off {@link UndefaultedOption} and {@link UndefaultedField} —
|
|
7651
|
+
* the names {@link ConfigDefaults} leaves optional — so an option that gains or loses a default
|
|
7652
|
+
* changes what `null` can clear with no edit here.
|
|
7653
|
+
*/
|
|
7654
|
+
type RelyIOConfigUpdate = Update<Omit<RelyIOConfig, OptionBag | 'headers'>, UndefaultedOption> & {
|
|
7655
|
+
browser?: Update<BrowserConfig, UndefaultedField['browser']>;
|
|
7656
|
+
cache?: Update<CacheConfig, UndefaultedField['cache']>;
|
|
7657
|
+
realtime?: Update<RealtimeConfig, UndefaultedField['realtime']>;
|
|
7658
|
+
debug?: Update<DebugConfig, UndefaultedField['debug']>;
|
|
7659
|
+
/** Headers to add or replace, each kept until named again; `null` stops sending that header. */
|
|
7660
|
+
headers?: Record<string, string | null>;
|
|
7661
|
+
};
|
|
7662
|
+
/** `T`'s options, each one optional, with `null` accepted for the ones named in `Clearable`. */
|
|
7663
|
+
type Update<T, Clearable extends keyof T> = {
|
|
7664
|
+
[K in keyof T]?: K extends Clearable ? T[K] | null : T[K];
|
|
7665
|
+
};
|
|
7666
|
+
interface CacheConfig {
|
|
7667
|
+
/** Whether caching is enabled (defaults to true) */
|
|
7668
|
+
enabled?: boolean;
|
|
7669
|
+
/** Cache TTL in milliseconds (defaults to 5 minutes) */
|
|
7670
|
+
ttl?: number;
|
|
7671
|
+
/** Maximum number of cache entries (defaults to 1000) */
|
|
7672
|
+
maxEntries?: number;
|
|
7673
|
+
/** Maximum cache size in bytes (defaults to 50MB) */
|
|
7674
|
+
maxSize?: number;
|
|
7675
|
+
/** Cache strategies to use */
|
|
7676
|
+
strategies?: CacheStrategy[];
|
|
6688
7677
|
}
|
|
6689
|
-
interface
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
7678
|
+
interface RealtimeConfig {
|
|
7679
|
+
/** Whether real-time features are enabled (defaults to true) */
|
|
7680
|
+
enabled?: boolean;
|
|
7681
|
+
/** WebSocket URL for real-time connections */
|
|
7682
|
+
wsUrl?: string;
|
|
7683
|
+
/** Maximum number of reconnection attempts (defaults to 10) */
|
|
7684
|
+
maxReconnectAttempts?: number;
|
|
7685
|
+
/** Reconnection delay in milliseconds (defaults to 1000) */
|
|
7686
|
+
reconnectDelay?: number;
|
|
7687
|
+
/** Heartbeat interval in milliseconds (defaults to 30000) */
|
|
7688
|
+
heartbeatInterval?: number;
|
|
6693
7689
|
}
|
|
6694
|
-
interface
|
|
6695
|
-
mode
|
|
6696
|
-
|
|
7690
|
+
interface DebugConfig {
|
|
7691
|
+
/** Whether debug mode is enabled (defaults to false) */
|
|
7692
|
+
enabled?: boolean;
|
|
7693
|
+
/** Whether to log network requests (defaults to false) */
|
|
7694
|
+
logRequests?: boolean;
|
|
7695
|
+
/** Whether to log cache operations (defaults to false) */
|
|
7696
|
+
logCache?: boolean;
|
|
7697
|
+
/** Whether to log WebSocket events (defaults to false) */
|
|
7698
|
+
logWebSocket?: boolean;
|
|
7699
|
+
/** Custom logger function */
|
|
7700
|
+
logger?: (_level: LogLevel, _message: string, _data?: unknown) => void;
|
|
6697
7701
|
}
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
7702
|
+
/**
|
|
7703
|
+
* The numbers the retry backoff is computed from.
|
|
7704
|
+
*
|
|
7705
|
+
* There is no `retryCondition` here any more. It was a predicate over
|
|
7706
|
+
* `(error, attempt)`, which is structurally unable to see the request — so the
|
|
7707
|
+
* only rule it could express is "is this error retryable", and the rule that
|
|
7708
|
+
* matters is "may this request be sent twice". That question, and the answer,
|
|
7709
|
+
* live in `RetryPolicy` (`http/retry-policy.ts`).
|
|
7710
|
+
*/
|
|
7711
|
+
interface RetryConfig {
|
|
7712
|
+
/** Maximum number of attempts, including the first. */
|
|
7713
|
+
maxAttempts: number;
|
|
7714
|
+
/** Base delay between retries in milliseconds */
|
|
7715
|
+
baseDelay: number;
|
|
7716
|
+
/** Maximum delay between retries in milliseconds */
|
|
7717
|
+
maxDelay: number;
|
|
7718
|
+
/** Backoff factor for exponential backoff */
|
|
7719
|
+
backoffFactor: number;
|
|
7720
|
+
/** Whether to add jitter to retry delays */
|
|
7721
|
+
jitter: boolean;
|
|
6702
7722
|
}
|
|
6703
|
-
interface
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
7723
|
+
interface RequestConfig {
|
|
7724
|
+
/** HTTP method */
|
|
7725
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
7726
|
+
/** Request URL */
|
|
7727
|
+
url: string;
|
|
7728
|
+
/** Request headers */
|
|
7729
|
+
headers?: Record<string, string>;
|
|
7730
|
+
/** Request body */
|
|
7731
|
+
body?: unknown;
|
|
7732
|
+
/** Query parameters */
|
|
7733
|
+
params?: Record<string, unknown>;
|
|
7734
|
+
/** Request timeout in milliseconds */
|
|
7735
|
+
timeout?: number;
|
|
7736
|
+
/** Whether to retry this request on failure */
|
|
7737
|
+
retryable?: boolean;
|
|
7738
|
+
/** Abort signal for canceling requests */
|
|
7739
|
+
signal?: AbortSignal;
|
|
7740
|
+
/** Additional metadata for the request */
|
|
7741
|
+
metadata?: Record<string, unknown>;
|
|
6707
7742
|
}
|
|
6708
|
-
interface
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
7743
|
+
interface ApiResponse<T = unknown> {
|
|
7744
|
+
/**
|
|
7745
|
+
* The response body exactly as the route's contract declares it —
|
|
7746
|
+
* `{ data }`, `{ data, page }`, `{ data, page, meta }` or `{ empty }`.
|
|
7747
|
+
*
|
|
7748
|
+
* Named `body`, not `data`, because the envelope's own key is `data`: the
|
|
7749
|
+
* incumbent `response.data.data` read like a typo and was one 33 times, in
|
|
7750
|
+
* six methods that read a key the server never sent. One `data` in the
|
|
7751
|
+
* spelling means `readPayload(response.body)` is the only way to reach a
|
|
7752
|
+
* payload (`INV-API-CLIENT-IS-DERIVED`).
|
|
7753
|
+
*/
|
|
7754
|
+
body: T;
|
|
7755
|
+
/** HTTP status code */
|
|
7756
|
+
status: number;
|
|
7757
|
+
/** HTTP status text */
|
|
7758
|
+
statusText: string;
|
|
7759
|
+
/** Response headers */
|
|
7760
|
+
headers: Record<string, string>;
|
|
7761
|
+
/** Request configuration that generated this response */
|
|
7762
|
+
config: RequestConfig;
|
|
7763
|
+
/** Whether this response came from cache */
|
|
7764
|
+
fromCache?: boolean;
|
|
7765
|
+
/** Cache metadata */
|
|
7766
|
+
cacheMetadata?: {
|
|
7767
|
+
key: string;
|
|
7768
|
+
timestamp: number;
|
|
7769
|
+
ttl: number;
|
|
7770
|
+
};
|
|
6713
7771
|
}
|
|
6714
|
-
interface
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
7772
|
+
interface BrowserConfig {
|
|
7773
|
+
/**
|
|
7774
|
+
* Whether requests the client sends from a web page carry the browser's cookies to another
|
|
7775
|
+
* origin (defaults to `false`).
|
|
7776
|
+
*
|
|
7777
|
+
* `false` — and leaving it out, or writing `undefined` — sends every request with
|
|
7778
|
+
* `credentials: 'same-origin'`: nothing to another origin, and a same-origin request — the API
|
|
7779
|
+
* behind a proxy on your own host — sent as the platform's own `fetch` would send it. `true`
|
|
7780
|
+
* sends it with `credentials: 'include'`, which a browser completes only when the answer names
|
|
7781
|
+
* your page's origin in `Access-Control-Allow-Origin` (not `*`) and carries
|
|
7782
|
+
* `Access-Control-Allow-Credentials: true`. The RelyIO API authenticates with your API key and
|
|
7783
|
+
* reads no cookie, so set `true` only for a server of your own in front of it that does.
|
|
7784
|
+
*
|
|
7785
|
+
* Applied only in a web page. On a server, in an edge runtime or in a Web Worker the client sets
|
|
7786
|
+
* no `credentials` mode at all, whatever this says.
|
|
7787
|
+
*/
|
|
7788
|
+
includeCredentials?: boolean;
|
|
7789
|
+
/** Whether to use relative URLs for same-origin requests (defaults to false) */
|
|
7790
|
+
useRelativeUrls?: boolean;
|
|
7791
|
+
/** Custom CORS error handling */
|
|
7792
|
+
onCorsError?: (_error: Error, _context: unknown) => void;
|
|
6718
7793
|
}
|
|
6719
|
-
type
|
|
6720
|
-
type
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
7794
|
+
type CacheStrategy = 'memory' | 'persistent' | 'network-first' | 'cache-first' | 'stale-while-revalidate';
|
|
7795
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
7796
|
+
type Environment = 'development' | 'staging' | 'production';
|
|
7797
|
+
/**
|
|
7798
|
+
* `T` once its defaults are applied: every field present, except the ones named in `NoDefault`,
|
|
7799
|
+
* which stay as optional as `T` declares them because nothing stands in for them.
|
|
7800
|
+
*/
|
|
7801
|
+
type WithDefaults<T, NoDefault extends keyof T = never> = Required<Omit<T, NoDefault>> & Pick<T, NoDefault>;
|
|
7802
|
+
/**
|
|
7803
|
+
* The options with no default, absent from a merged configuration until the caller gives one.
|
|
7804
|
+
* `fetch` and `webSocket` among them: absent means the runtime's own, and that is read per request
|
|
7805
|
+
* or per connection rather than captured here. `liveUrl` too: absent is derived from `baseUrl` when
|
|
7806
|
+
* the live transport opens, where RelyIO's own API names its edge, and is otherwise no address.
|
|
7807
|
+
*/
|
|
7808
|
+
type UndefaultedOption = 'apiKey' | 'dataset' | 'locale' | 'dev' | 'fetch' | 'liveUrl' | 'webSocket';
|
|
7809
|
+
/** The options that are themselves bags of options, each merged field by field. */
|
|
7810
|
+
type OptionBag = 'browser' | 'cache' | 'realtime' | 'debug';
|
|
7811
|
+
/**
|
|
7812
|
+
* The fields of each bag with no default, absent from a merged configuration until the caller gives
|
|
7813
|
+
* one — and the fields of a bag `updateConfig()` can clear with `null`.
|
|
7814
|
+
*/
|
|
7815
|
+
interface UndefaultedField {
|
|
7816
|
+
browser: 'onCorsError';
|
|
7817
|
+
cache: never;
|
|
7818
|
+
realtime: 'wsUrl';
|
|
7819
|
+
debug: 'logger';
|
|
7820
|
+
}
|
|
7821
|
+
/**
|
|
7822
|
+
* The value each option takes when the caller gives none, down to each field of each bag — so a
|
|
7823
|
+
* field of a merged configuration that has a default is never `undefined`, and a reader does not
|
|
7824
|
+
* restate the default. A field with no default (`onCorsError`, `wsUrl`, `logger`) is named in
|
|
7825
|
+
* {@link UndefaultedField}; a field added to a bag without one fails to compile at
|
|
7826
|
+
* {@link DEFAULT_CONFIG} until it gets a default or a name there.
|
|
7827
|
+
*/
|
|
7828
|
+
type ConfigDefaults = WithDefaults<Omit<RelyIOConfig, UndefaultedOption | OptionBag>> & {
|
|
7829
|
+
browser: WithDefaults<BrowserConfig, UndefaultedField['browser']>;
|
|
7830
|
+
cache: WithDefaults<CacheConfig, UndefaultedField['cache']>;
|
|
7831
|
+
realtime: WithDefaults<RealtimeConfig, UndefaultedField['realtime']>;
|
|
7832
|
+
debug: WithDefaults<DebugConfig, UndefaultedField['debug']>;
|
|
6724
7833
|
};
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
readonly id: TId;
|
|
6728
|
-
/** Field type */
|
|
6729
|
-
readonly type: TType;
|
|
6730
|
-
/** Type-specific configuration */
|
|
6731
|
-
config?: TConfig;
|
|
6732
|
-
/** UI display configuration */
|
|
6733
|
-
ui?: FieldUIConfig;
|
|
6734
|
-
/** AI configuration: generation/review guidance for this field */
|
|
6735
|
-
ai?: FieldAIConfig;
|
|
6736
|
-
/** Dynamic field rules */
|
|
6737
|
-
rules?: FieldRule[];
|
|
6738
|
-
/** Localization settings */
|
|
6739
|
-
localization?: LocalizationConfig;
|
|
6740
|
-
/** Fallback value when field is empty */
|
|
6741
|
-
fallback?: unknown;
|
|
6742
|
-
/** Whether this field is deprecated */
|
|
6743
|
-
deprecated?: boolean;
|
|
6744
|
-
}
|
|
6745
|
-
/**
|
|
6746
|
-
* Any field definition - used in arrays where we need to preserve specific field types
|
|
6747
|
-
*/
|
|
6748
|
-
type AnyFieldDefinition = FieldDefinition<string, string, unknown>;
|
|
6749
|
-
interface ShortTextConfig extends BaseFieldConfig {
|
|
6750
|
-
/** Maximum character length */
|
|
6751
|
-
maxLength?: number;
|
|
6752
|
-
/** Regex pattern for validation */
|
|
6753
|
-
pattern?: string;
|
|
6754
|
-
defaultValue?: string;
|
|
6755
|
-
}
|
|
6756
|
-
interface LongTextConfig extends BaseFieldConfig {
|
|
6757
|
-
minLength?: number;
|
|
6758
|
-
maxLength?: number;
|
|
6759
|
-
defaultValue?: string;
|
|
6760
|
-
}
|
|
6761
|
-
interface RichTextConfig extends BaseFieldConfig {
|
|
6762
|
-
/** Maximum character length for the rich text content */
|
|
6763
|
-
maxLength?: number;
|
|
6764
|
-
/** Allowed formatting options (e.g., bold, italic, underline) */
|
|
6765
|
-
allowedFormats?: string[];
|
|
6766
|
-
/** Allowed embed types (e.g., image, video, code) */
|
|
6767
|
-
embedTypes?: string[];
|
|
6768
|
-
defaultValue?: string;
|
|
6769
|
-
}
|
|
6770
|
-
interface SlugConfig extends BaseFieldConfig {
|
|
6771
|
-
/** Source field to generate slug from */
|
|
6772
|
-
sourceField?: string;
|
|
6773
|
-
/** Maximum character length */
|
|
6774
|
-
maxLength?: number;
|
|
6775
|
-
defaultValue?: string;
|
|
6776
|
-
}
|
|
6777
|
-
interface UrlConfig extends BaseFieldConfig {
|
|
6778
|
-
/** Allowed URL protocols */
|
|
6779
|
-
allowedProtocols?: ('http' | 'https' | 'ftp' | 'ftps')[];
|
|
6780
|
-
/** Maximum character length */
|
|
6781
|
-
maxLength?: number;
|
|
6782
|
-
defaultValue?: string;
|
|
6783
|
-
}
|
|
6784
|
-
interface EmailConfig extends BaseFieldConfig {
|
|
6785
|
-
/** Maximum character length */
|
|
6786
|
-
maxLength?: number;
|
|
6787
|
-
/** Whitelist of allowed email domains */
|
|
6788
|
-
domainWhitelist?: string[];
|
|
6789
|
-
defaultValue?: string;
|
|
6790
|
-
}
|
|
6791
|
-
interface IntegerConfig extends BaseFieldConfig {
|
|
6792
|
-
min?: number;
|
|
6793
|
-
max?: number;
|
|
6794
|
-
defaultValue?: number;
|
|
6795
|
-
}
|
|
6796
|
-
interface DecimalConfig extends BaseFieldConfig {
|
|
6797
|
-
min?: number;
|
|
6798
|
-
max?: number;
|
|
6799
|
-
decimalPlaces?: number;
|
|
6800
|
-
roundingMode?: 'HALF_UP' | 'FLOOR' | 'CEILING' | 'ROUND' | 'TRUNCATE';
|
|
6801
|
-
defaultValue?: number;
|
|
6802
|
-
}
|
|
6803
|
-
interface BooleanConfig extends BaseFieldConfig {
|
|
6804
|
-
/** The editor's word for `true` (e.g. `'Published'`). */
|
|
6805
|
-
labelTrue?: string;
|
|
6806
|
-
/** The editor's word for `false` (e.g. `'Draft'`). */
|
|
6807
|
-
labelFalse?: string;
|
|
6808
|
-
defaultValue?: boolean;
|
|
6809
|
-
}
|
|
6810
|
-
/**
|
|
6811
|
-
* `TValue` is the union of the option values and `TMulti` whether the field holds a list of them.
|
|
6812
|
-
* `fields.enum()` infers both from the declaration, so a read of the field is typed by its options
|
|
6813
|
-
* (`INV-SS-TYPES-INFERRED`); the defaults describe any enum field.
|
|
6814
|
-
*/
|
|
6815
|
-
interface EnumConfig<TValue extends string = string, TMulti extends boolean = boolean> extends BaseFieldConfig {
|
|
6816
|
-
/** The values the field may hold, each with the `label` an editor shows. Deploy refuses an option without one. */
|
|
6817
|
-
options: Array<{
|
|
6818
|
-
value: TValue;
|
|
6819
|
-
label: string;
|
|
6820
|
-
}>;
|
|
6821
|
-
multi?: TMulti;
|
|
6822
|
-
/** One option's value, or a list of them when `multi` is true. */
|
|
6823
|
-
defaultValue?: string | string[];
|
|
6824
|
-
}
|
|
6825
|
-
/** A display format is not config: it is `ui.options.format`, where the schema declares it. */
|
|
6826
|
-
interface DateConfig extends BaseFieldConfig {
|
|
6827
|
-
minDate?: string;
|
|
6828
|
-
maxDate?: string;
|
|
6829
|
-
/** `YYYY-MM-DD` */
|
|
6830
|
-
defaultValue?: string;
|
|
6831
|
-
}
|
|
6832
|
-
/** A display format is not config: it is `ui.options.format`, where the schema declares it. */
|
|
6833
|
-
interface DateTimeConfig extends BaseFieldConfig {
|
|
6834
|
-
minDateTime?: string;
|
|
6835
|
-
maxDateTime?: string;
|
|
6836
|
-
/**
|
|
6837
|
-
* Show the instant in UTC (`'UTC'`) or in the author's local time (`'local'`) in the editor. The
|
|
6838
|
-
* instant is stored in UTC either way.
|
|
6839
|
-
*/
|
|
6840
|
-
timeZoneHandling?: 'UTC' | 'local';
|
|
6841
|
-
defaultValue?: string;
|
|
6842
|
-
}
|
|
6843
|
-
/**
|
|
6844
|
-
* `TTo` is the union of the target type ids and `TMulti` whether the field holds a list.
|
|
6845
|
-
* `fields.reference()` infers both, so a read of the field is typed by what it points at
|
|
6846
|
-
* (`INV-SS-TYPES-INFERRED`); the defaults describe any reference field.
|
|
6847
|
-
*/
|
|
6848
|
-
interface ReferenceConfig<TTo extends string = string, TMulti extends boolean = boolean> extends BaseFieldConfig {
|
|
6849
|
-
/**
|
|
6850
|
-
* Target entry type id(s) — content type or asset type ids. Pass a single id
|
|
6851
|
-
* for one target or an array for several. All ids must belong to the same
|
|
6852
|
-
* family (all content types or all asset types).
|
|
6853
|
-
*/
|
|
6854
|
-
to: TTo | TTo[];
|
|
6855
|
-
/** Allow multiple references (the field value is a list). */
|
|
6856
|
-
multi?: TMulti;
|
|
6857
|
-
/** Reference strength for publish/unpublish behavior. */
|
|
6858
|
-
referenceStrength?: 'strong' | 'weak';
|
|
6859
|
-
/** Behavior when a referenced entry is deleted. */
|
|
6860
|
-
onTargetDelete?: 'block' | 'nullify';
|
|
6861
|
-
/** A target entry's id, or a list of them when `multi` is true. */
|
|
6862
|
-
defaultValue?: string | string[];
|
|
6863
|
-
}
|
|
6864
|
-
interface TagsConfig extends BaseFieldConfig {
|
|
6865
|
-
allowCustom?: boolean;
|
|
6866
|
-
predefinedTags?: string[];
|
|
6867
|
-
maxTags?: number;
|
|
6868
|
-
}
|
|
6869
|
-
/**
|
|
6870
|
-
* `TSubfields` is the declared subfields, which `fields.list()` infers so a read types each item by
|
|
6871
|
-
* them (`INV-SS-TYPES-INFERRED`); the default describes any list field.
|
|
6872
|
-
*/
|
|
6873
|
-
interface ListConfig<TSubfields extends readonly AnyFieldDefinition[] = FieldDefinition[]> extends BaseFieldConfig {
|
|
6874
|
-
dragAndDrop?: boolean;
|
|
6875
|
-
minItems?: number;
|
|
6876
|
-
maxItems?: number;
|
|
6877
|
-
/** Subfields for list items */
|
|
6878
|
-
subfields?: TSubfields;
|
|
6879
|
-
}
|
|
6880
|
-
/**
|
|
6881
|
-
* A component field's config: the options every field type takes, and no more — what the schema
|
|
6882
|
-
* declares for a `component(<id>)` field, which has no config of its own. The validation document
|
|
6883
|
-
* reads `required` from it as it does from any field's.
|
|
6884
|
-
*/
|
|
6885
|
-
type ComponentFieldConfig = BaseFieldConfig;
|
|
6886
|
-
type FieldType = 'shortText' | 'longText' | 'richText' | 'slug' | 'url' | 'email' | 'integer' | 'decimal' | 'boolean' | 'enum' | 'date' | 'dateTime' | 'reference' | 'tags' | 'list';
|
|
6887
|
-
type ComponentFieldType = `component(${string})`;
|
|
6888
|
-
type AllFieldTypes = FieldType | ComponentFieldType;
|
|
7834
|
+
/** The configuration a client runs on: each option the caller gave, and its default where not. */
|
|
7835
|
+
type MergedRelyIOConfig = ConfigDefaults & Pick<RelyIOConfig, UndefaultedOption>;
|
|
6889
7836
|
|
|
6890
7837
|
/**
|
|
6891
7838
|
* Workflow definition for content approval pipelines
|
|
@@ -7117,6 +8064,226 @@ declare function getFirstWorkflowStage(workflow: WorkflowDefinition): WorkflowSt
|
|
|
7117
8064
|
*/
|
|
7118
8065
|
declare function isFinalWorkflowStage(workflow: WorkflowDefinition, stageId: string): boolean;
|
|
7119
8066
|
|
|
8067
|
+
/**
|
|
8068
|
+
* Each field kind, declared once, with every facet the other packages decide by it — P0's field
|
|
8069
|
+
* contract (REL-1783 declared it, REL-1788 made it the only list; `docs/design/structured-fields/README.md`,
|
|
8070
|
+
* "What every package has to agree on").
|
|
8071
|
+
*
|
|
8072
|
+
* **Every consumer reads it.** Deploy's config verdict, the migration analyzer's change facts, entry
|
|
8073
|
+
* validation's document and entry-writes' date-time paths read `change`, `locale`, `value` and
|
|
8074
|
+
* `./rules` (REL-1784); the live document's projection and the Studio's field bindings read `live`
|
|
8075
|
+
* (REL-1785, `@relyio/entry-projection/document-shape`'s `liveHoldingOf`); the SDK and both code
|
|
8076
|
+
* generators key their tables by the union (REL-1786); the entry filter paths and the View
|
|
8077
|
+
* capabilities (`FIELD_CAPABILITIES`) read `filter`, the search mapping and embed set `search`,
|
|
8078
|
+
* settings' synthesized defaults `synthesized`, the read's fill of an empty required field and the
|
|
8079
|
+
* write core's required-from-creation refusal `empty` (REL-1795, through `./empty`), every
|
|
8080
|
+
* reference finder `references`
|
|
8081
|
+
* ({@link holdsReferenceValue}), the content-adaptation tasks `change` and the seeds `value`
|
|
8082
|
+
* (REL-1787). REL-1788 deleted the per-package tables these replaced (`FIELD_TYPE_KINDS`,
|
|
8083
|
+
* `FIELD_TYPE_OPERATORS`, `FIELD_TYPE_CATEGORIES`, the reader's `FIELD_TYPE_ICONS`).
|
|
8084
|
+
*
|
|
8085
|
+
* **The rule for a consumer:** index by the union, never by a `string` with a fallback. A decision
|
|
8086
|
+
* every kind takes part in is a facet here or a table in its own layer typed
|
|
8087
|
+
* `EveryFieldKind<Row>` (or `OverEveryFieldKind<…>` for a type), so a kind this union gains is a compile error in
|
|
8088
|
+
* every consumer that has not said what it does with it; a decision about one kind is
|
|
8089
|
+
* {@link isKind}; where references are is {@link holdsReferenceValue}. A `type` string is read with
|
|
8090
|
+
* {@link parseFieldType} first, and its `null` arm — a type the language does not declare — is
|
|
8091
|
+
* named, never folded into a kind's row.
|
|
8092
|
+
*
|
|
8093
|
+
* **This module has no runtime dependency at all**, so a browser, the live Worker and a
|
|
8094
|
+
* build-inlined customer package can each take it whole: every import below is `import type`,
|
|
8095
|
+
* and `__tests__/dependency-free.test.ts` refuses any other. The facets that need Zod (a kind's
|
|
8096
|
+
* config declaration) or the AJV fragment builders (its value validation) are in `./rules`, keyed by
|
|
8097
|
+
* the same {@link FieldKind}. The facets that belong to a fenced layer — the SDK's type and the
|
|
8098
|
+
* Python type (customer packages), the Studio field hook (headless Studio packages) — are named in
|
|
8099
|
+
* {@link FIELD_KIND_FACETS} and built in their layers, as a {@link EveryFieldKind} table, so a
|
|
8100
|
+
* missing row there is a compile error there.
|
|
8101
|
+
*
|
|
8102
|
+
* Nested kinds compose rather than declare per shape: an object's facets, and a list item's, are its
|
|
8103
|
+
* shape's fields' facets under `<field>.$<shape>` (`./walk`'s item segment). `./walk` is that
|
|
8104
|
+
* composition.
|
|
8105
|
+
*
|
|
8106
|
+
* Every declaration key is a kind (REL-1799, ADR 0012): a group of fields is an `object` with
|
|
8107
|
+
* `of`, so a table over the kinds is {@link EveryFieldKind}.
|
|
8108
|
+
*/
|
|
8109
|
+
|
|
8110
|
+
/**
|
|
8111
|
+
* Every field kind, in the order the schema language has always listed them. The one definition of
|
|
8112
|
+
* the union in `@relyio/schema`: `FIELD_TYPES` in `types/base/constants.ts` is this tuple.
|
|
8113
|
+
*/
|
|
8114
|
+
declare const FIELD_KINDS: readonly ['shortText', 'longText', 'richText', 'table', 'code', 'email', 'url', 'slug', 'integer', 'decimal', 'boolean', 'enum', 'date', 'dateTime', 'reference', 'tags', 'list', 'object', 'json'];
|
|
8115
|
+
/** A field kind: what a field's `type` names. The declaration is keyed by it and by nothing else. */
|
|
8116
|
+
type FieldKind = (typeof FIELD_KINDS)[number];
|
|
8117
|
+
/**
|
|
8118
|
+
* Holds a type-level table to one member per kind — for a facet that is a type rather than a value,
|
|
8119
|
+
* such as the SDK's value types: `type ValueByKind = OverEveryFieldKind<{ shortText: string; … }>`
|
|
8120
|
+
* fails to compile when a kind has no member.
|
|
8121
|
+
*/
|
|
8122
|
+
type OverEveryFieldKind<T extends {
|
|
8123
|
+
readonly [K in FieldKind]: unknown;
|
|
8124
|
+
}> = T;
|
|
8125
|
+
|
|
8126
|
+
/**
|
|
8127
|
+
* A `json` field's value and its JSON Schema (REL-1811, design decision 18): data nobody models in
|
|
8128
|
+
* RelyIO still has a place.
|
|
8129
|
+
*
|
|
8130
|
+
* - **The value** is any JSON value — an object, an array, a string, a finite number, a boolean or
|
|
8131
|
+
* `null` — stored and served parsed. {@link jsonValueProblems} names what keeps a value from being
|
|
8132
|
+
* one, and the validation document's `x-json` keyword refuses it (`JSON_INVALID`) under every
|
|
8133
|
+
* write profile, a draft's included: a value that is not JSON, or that its field's JSON Schema
|
|
8134
|
+
* refuses, is never stored.
|
|
8135
|
+
* - **The source** a person edits is collaborative text in the live document (ADR 0014), parsed on
|
|
8136
|
+
* save by {@link parseJsonSource}. While it does not parse, or the field's schema refuses what it
|
|
8137
|
+
* parses to, the live save leaves the field out — its stored value stands — and names it, so every
|
|
8138
|
+
* open editor shows it not saving until it does (`@relyio/entry-projection`'s `extractYDocData`,
|
|
8139
|
+
* `leftOut`).
|
|
8140
|
+
* - **The JSON Schema** is the field's optional `config.schema`, written in the vocabulary
|
|
8141
|
+
* {@link JSON_SCHEMA_KEYWORDS} names: a subset of draft-07 that the validation document enforces,
|
|
8142
|
+
* the SDK infers a read's type from and both code generators emit a type from. Deploy refuses any
|
|
8143
|
+
* other keyword by name (`types/fields/data/json.ts`), so the three never disagree about a schema.
|
|
8144
|
+
*
|
|
8145
|
+
* Dependency-free like the rest of `./field-kinds` (`__tests__/dependency-free.test.ts`).
|
|
8146
|
+
*/
|
|
8147
|
+
/** A JSON value: what a `json` field holds. */
|
|
8148
|
+
type JsonValue = string | number | boolean | null | readonly JsonValue[] | {
|
|
8149
|
+
readonly [key: string]: JsonValue;
|
|
8150
|
+
};
|
|
8151
|
+
/** The types a JSON Schema's `type` may name (draft-07's simple types). */
|
|
8152
|
+
declare const JSON_SCHEMA_TYPES: readonly ['string', 'number', 'integer', 'boolean', 'object', 'array', 'null'];
|
|
8153
|
+
type JsonSchemaType = (typeof JSON_SCHEMA_TYPES)[number];
|
|
8154
|
+
/**
|
|
8155
|
+
* The `format`s a json field's schema may name: those the validation document's AJV instance knows
|
|
8156
|
+
* (`ajv-formats`). A format it did not know would be ignored, and a constraint nothing enforces is
|
|
8157
|
+
* not one to accept.
|
|
8158
|
+
*/
|
|
8159
|
+
declare const JSON_SCHEMA_FORMATS: readonly ['date', 'time', 'date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uuid'];
|
|
8160
|
+
type JsonSchemaFormat = (typeof JSON_SCHEMA_FORMATS)[number];
|
|
8161
|
+
/** A json field's JSON Schema: one node of the vocabulary {@link JSON_SCHEMA_KEYWORDS} names. */
|
|
8162
|
+
interface JsonFieldSchema {
|
|
8163
|
+
readonly type?: JsonSchemaType | readonly JsonSchemaType[];
|
|
8164
|
+
readonly properties?: {
|
|
8165
|
+
readonly [key: string]: JsonFieldSchema;
|
|
8166
|
+
};
|
|
8167
|
+
readonly required?: readonly string[];
|
|
8168
|
+
readonly additionalProperties?: boolean | JsonFieldSchema;
|
|
8169
|
+
readonly items?: JsonFieldSchema;
|
|
8170
|
+
readonly enum?: readonly JsonValue[];
|
|
8171
|
+
readonly const?: JsonValue;
|
|
8172
|
+
readonly anyOf?: readonly JsonFieldSchema[];
|
|
8173
|
+
readonly oneOf?: readonly JsonFieldSchema[];
|
|
8174
|
+
readonly minLength?: number;
|
|
8175
|
+
readonly maxLength?: number;
|
|
8176
|
+
readonly pattern?: string;
|
|
8177
|
+
readonly format?: JsonSchemaFormat;
|
|
8178
|
+
readonly minimum?: number;
|
|
8179
|
+
readonly maximum?: number;
|
|
8180
|
+
readonly exclusiveMinimum?: number;
|
|
8181
|
+
readonly exclusiveMaximum?: number;
|
|
8182
|
+
readonly multipleOf?: number;
|
|
8183
|
+
readonly minItems?: number;
|
|
8184
|
+
readonly maxItems?: number;
|
|
8185
|
+
readonly uniqueItems?: boolean;
|
|
8186
|
+
readonly minProperties?: number;
|
|
8187
|
+
readonly maxProperties?: number;
|
|
8188
|
+
readonly title?: string;
|
|
8189
|
+
readonly description?: string;
|
|
8190
|
+
readonly default?: JsonValue;
|
|
8191
|
+
readonly examples?: readonly JsonValue[];
|
|
8192
|
+
}
|
|
8193
|
+
|
|
8194
|
+
/**
|
|
8195
|
+
* What a read returns for a `json` field (REL-1811): the value its JSON Schema describes, inferred
|
|
8196
|
+
* from the schema literal at the type level, and any JSON value when it gives none — `JsonValue`,
|
|
8197
|
+
* never `any`.
|
|
8198
|
+
*
|
|
8199
|
+
* **The subset that types a value** is the schema's structure, as `@relyio/schema`'s
|
|
8200
|
+
* `JSON_SCHEMA_KEYWORDS` names it — the vocabulary deploy accepts, so a schema that deploys is one
|
|
8201
|
+
* this reads:
|
|
8202
|
+
*
|
|
8203
|
+
* - `const` — that value; `enum` — the union of its members.
|
|
8204
|
+
* - `anyOf` / `oneOf` — the union of each branch.
|
|
8205
|
+
* - `type` — `string`, `number` and `integer` (a `number`), `boolean`, `null`, an `array` of its
|
|
8206
|
+
* `items` (any JSON value without them), an `object`; a list of types, their union.
|
|
8207
|
+
* - An object's `properties`, each a property of its own type — present when `required` names it,
|
|
8208
|
+
* optional otherwise — and its other keys by `additionalProperties`: none when it is `false`,
|
|
8209
|
+
* each of its schema's type when it is a schema and the object declares no `properties` (a map),
|
|
8210
|
+
* and `unknown` otherwise.
|
|
8211
|
+
*
|
|
8212
|
+
* The constraint keywords (`minLength`, `pattern`, `minimum`, `maxItems` …) narrow the values of a
|
|
8213
|
+
* type without changing it, and the annotations say nothing about it. **Anything the subset cannot
|
|
8214
|
+
* say is `JsonValue`**: a schema with none of these keywords, and one whose literal was widened —
|
|
8215
|
+
* `type: string` rather than `'object'` — since a literal the compiler did not keep names nothing.
|
|
8216
|
+
* Write the schema `as const` to keep every literal: without it `required` widens to `string[]` and
|
|
8217
|
+
* every property reads as optional, and an `enum` or a `const` as the type of its members — wider
|
|
8218
|
+
* than the value, never narrower. `relyio generate-types` writes it `as const`.
|
|
8219
|
+
*/
|
|
8220
|
+
|
|
8221
|
+
/** A json field's JSON Schema: the vocabulary deploy accepts (`@relyio/schema`'s `JsonFieldSchema`). */
|
|
8222
|
+
type JsonSchema = JsonFieldSchema;
|
|
8223
|
+
/** `true` for `any`, which every conditional would otherwise answer both ways. */
|
|
8224
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
8225
|
+
/** One object type from an intersection, so a read's type prints as one object. */
|
|
8226
|
+
type Flatten$1<T> = {
|
|
8227
|
+
[K in keyof T]: T[K];
|
|
8228
|
+
} & {};
|
|
8229
|
+
/**
|
|
8230
|
+
* The value a JSON Schema literal `S` describes — see the module note for the subset. Distributes
|
|
8231
|
+
* over a union of schemas, which is what an `anyOf`'s branches are.
|
|
8232
|
+
*/
|
|
8233
|
+
type InferJsonSchema<S> = IsAny<S> extends true ? JsonValue : S extends {
|
|
8234
|
+
readonly const: infer C;
|
|
8235
|
+
} ? C : S extends {
|
|
8236
|
+
readonly enum: ReadonlyArray<infer E>;
|
|
8237
|
+
} ? E : S extends {
|
|
8238
|
+
readonly anyOf: ReadonlyArray<infer A>;
|
|
8239
|
+
} ? InferJsonSchema<A> : S extends {
|
|
8240
|
+
readonly oneOf: ReadonlyArray<infer O>;
|
|
8241
|
+
} ? InferJsonSchema<O> : S extends {
|
|
8242
|
+
readonly type: infer T;
|
|
8243
|
+
} ? T extends ReadonlyArray<infer Each> ? OfType<S, Each> : OfType<S, T> : JsonValue;
|
|
8244
|
+
/** The value of type `T` (one of a schema's `type`s) that `S` describes. Distributes over `T`. */
|
|
8245
|
+
type OfType<S, T> = T extends 'string' ? string : T extends 'number' | 'integer' ? number : T extends 'boolean' ? boolean : T extends 'null' ? null : T extends 'array' ? ArrayOf<S> : T extends 'object' ? ObjectOf<S> : JsonValue;
|
|
8246
|
+
type ArrayOf<S> = S extends {
|
|
8247
|
+
readonly items: infer I;
|
|
8248
|
+
} ? Array<InferJsonSchema<I>> : JsonValue[];
|
|
8249
|
+
type PropertiesOf<S> = S extends {
|
|
8250
|
+
readonly properties: infer P;
|
|
8251
|
+
} ? P : {};
|
|
8252
|
+
/** The property names `required` lists; none when its literal was widened to `string`. */
|
|
8253
|
+
type RequiredOf<S> = S extends {
|
|
8254
|
+
readonly required: ReadonlyArray<infer R>;
|
|
8255
|
+
} ? string extends R ? never : R : never;
|
|
8256
|
+
type ObjectOf<S> = Flatten$1<{
|
|
8257
|
+
[K in keyof PropertiesOf<S> & RequiredOf<S>]: InferJsonSchema<PropertiesOf<S>[K]>;
|
|
8258
|
+
} & {
|
|
8259
|
+
[K in Exclude<keyof PropertiesOf<S>, RequiredOf<S>>]?: InferJsonSchema<PropertiesOf<S>[K]>;
|
|
8260
|
+
} & AdditionalOf<S>>;
|
|
8261
|
+
/**
|
|
8262
|
+
* The keys an object holds beyond its `properties`: none when `additionalProperties` is `false`;
|
|
8263
|
+
* each of its schema's type when the object declares no `properties` (a map); `unknown` otherwise,
|
|
8264
|
+
* since a declared property and an index signature of another type cannot both be read precisely.
|
|
8265
|
+
*/
|
|
8266
|
+
type AdditionalOf<S> = S extends {
|
|
8267
|
+
readonly additionalProperties: false;
|
|
8268
|
+
} ? {} : keyof PropertiesOf<S> extends never ? S extends {
|
|
8269
|
+
readonly additionalProperties: infer A;
|
|
8270
|
+
} ? A extends true ? {
|
|
8271
|
+
[key: string]: JsonValue;
|
|
8272
|
+
} : {
|
|
8273
|
+
[key: string]: InferJsonSchema<A>;
|
|
8274
|
+
} : {
|
|
8275
|
+
[key: string]: JsonValue;
|
|
8276
|
+
} : {
|
|
8277
|
+
[key: string]: unknown;
|
|
8278
|
+
};
|
|
8279
|
+
/**
|
|
8280
|
+
* A json field's read: `JsonValue` without a schema, the schema's value with one. `C` is the field's
|
|
8281
|
+
* config, as a builder keeps it.
|
|
8282
|
+
*/
|
|
8283
|
+
type JsonFieldValue<C> = C extends {
|
|
8284
|
+
readonly schema?: infer S;
|
|
8285
|
+
} ? [Exclude<S, undefined>] extends [never] ? JsonValue : InferJsonSchema<Exclude<S, undefined>> : JsonValue;
|
|
8286
|
+
|
|
7120
8287
|
/**
|
|
7121
8288
|
* Singleton content type definition matching @relyio/schema
|
|
7122
8289
|
*
|
|
@@ -7127,28 +8294,19 @@ declare function isFinalWorkflowStage(workflow: WorkflowDefinition, stageId: str
|
|
|
7127
8294
|
* the type system, enabling full autocomplete in SDK methods.
|
|
7128
8295
|
*/
|
|
7129
8296
|
|
|
7130
|
-
/**
|
|
7131
|
-
* Type alias for a fieldset with any fields.
|
|
7132
|
-
*/
|
|
7133
|
-
type AnyFieldset$2 = Fieldset<any>;
|
|
7134
8297
|
/**
|
|
7135
8298
|
* What a singleton takes: a content type's settings, since the schema declares a singleton with the
|
|
7136
|
-
* same `ContentTypeSchema` —
|
|
7137
|
-
* entry, with no parent and no children, and deploy
|
|
7138
|
-
*
|
|
7139
|
-
* whatever it was given.
|
|
8299
|
+
* same `ContentTypeSchema` — fields and fieldsets side by side (REL-1794) — except `hierarchical`,
|
|
8300
|
+
* which is `false` or absent. A singleton is one entry, with no parent and no children, and deploy
|
|
8301
|
+
* refuses `true` for one (`SINGLETON_CANNOT_BE_HIERARCHICAL`).
|
|
7140
8302
|
*/
|
|
7141
|
-
interface
|
|
7142
|
-
hierarchical?: false;
|
|
7143
|
-
}
|
|
7144
|
-
/** {@link SingletonConfigWithFields}, with its fields organised into fieldsets. */
|
|
7145
|
-
interface SingletonConfigWithFieldsets<TFieldsets extends readonly AnyFieldset$2[] = readonly AnyFieldset$2[]> extends Omit<ContentTypeConfigWithFieldsets<TFieldsets>, 'hierarchical'> {
|
|
8303
|
+
interface SingletonConfig<TFields extends readonly FieldMember[] = readonly FieldMember[]> extends Omit<ContentTypeConfig<TFields>, 'hierarchical'> {
|
|
7146
8304
|
hierarchical?: false;
|
|
7147
8305
|
}
|
|
7148
8306
|
/**
|
|
7149
8307
|
* Singleton content type definition - preserves field types for inference
|
|
7150
8308
|
*/
|
|
7151
|
-
interface SingletonContentTypeDefinition<TFields extends readonly
|
|
8309
|
+
interface SingletonContentTypeDefinition<TFields extends readonly FieldMember[] = readonly FieldMember[]> {
|
|
7152
8310
|
readonly _tag: 'singletonContentType';
|
|
7153
8311
|
readonly name: string;
|
|
7154
8312
|
readonly displayName: string;
|
|
@@ -7162,8 +8320,7 @@ interface SingletonContentTypeDefinition<TFields extends readonly AnyFieldDefini
|
|
|
7162
8320
|
readonly accessTags?: string[];
|
|
7163
8321
|
/** Workflow configuration for this singleton */
|
|
7164
8322
|
readonly workflow?: ContentTypeWorkflowConfig;
|
|
7165
|
-
readonly fields
|
|
7166
|
-
readonly fieldsets?: TFieldsets;
|
|
8323
|
+
readonly fields: TFields;
|
|
7167
8324
|
}
|
|
7168
8325
|
/**
|
|
7169
8326
|
* Define a singleton content type
|
|
@@ -7183,8 +8340,7 @@ interface SingletonContentTypeDefinition<TFields extends readonly AnyFieldDefini
|
|
|
7183
8340
|
* ]
|
|
7184
8341
|
* })
|
|
7185
8342
|
*/
|
|
7186
|
-
declare function defineSingletonContentType<TFields extends readonly
|
|
7187
|
-
declare function defineSingletonContentType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: SingletonConfigWithFieldsets<TFieldsets>): SingletonContentTypeDefinition<readonly [], TFieldsets>;
|
|
8343
|
+
declare function defineSingletonContentType<TFields extends readonly FieldMember[]>(name: string, config: SingletonConfig<TFields>): SingletonContentTypeDefinition<TFields>;
|
|
7188
8344
|
declare const defineSingleton: typeof defineSingletonContentType;
|
|
7189
8345
|
/**
|
|
7190
8346
|
* What a read reports about a singleton beside its fields: the committed document's
|
|
@@ -7198,15 +8354,15 @@ type SingletonMetadata = components['schemas']['SingletonMetadata'];
|
|
|
7198
8354
|
/**
|
|
7199
8355
|
* Type alias for any singleton content type definition.
|
|
7200
8356
|
*/
|
|
7201
|
-
type AnySingletonContentTypeDefinition = SingletonContentTypeDefinition<any
|
|
8357
|
+
type AnySingletonContentTypeDefinition = SingletonContentTypeDefinition<any>;
|
|
7202
8358
|
/**
|
|
7203
8359
|
* Infer the TypeScript type from a singleton definition: every field typed as a read returns it
|
|
7204
8360
|
* (`schema/infer-fields.ts`), plus `_metadata`. `S` is the schema, as for `InferContentType`.
|
|
7205
8361
|
*/
|
|
7206
|
-
type InferSingletonContentType<T extends AnySingletonContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined> = FieldValues<DeclaredFields<T>, S> & {
|
|
8362
|
+
type InferSingletonContentType<T extends AnySingletonContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = FieldValues<DeclaredFields<T>, S, 'required', I> & {
|
|
7207
8363
|
_metadata: SingletonMetadata;
|
|
7208
8364
|
};
|
|
7209
|
-
type InferSingleton<T extends AnySingletonContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined> = InferSingletonContentType<T, S>;
|
|
8365
|
+
type InferSingleton<T extends AnySingletonContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = InferSingletonContentType<T, S, I>;
|
|
7210
8366
|
|
|
7211
8367
|
/**
|
|
7212
8368
|
* Asset type definition matching @relyio/schema AssetTypeSchema
|
|
@@ -7366,35 +8522,16 @@ interface AssetTypeBaseConfig {
|
|
|
7366
8522
|
file?: FileKindConfig;
|
|
7367
8523
|
}
|
|
7368
8524
|
/**
|
|
7369
|
-
*
|
|
7370
|
-
|
|
7371
|
-
type
|
|
7372
|
-
/** Asset type configuration using direct fields. */
|
|
7373
|
-
interface AssetTypeConfigWithFields<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> extends AssetTypeBaseConfig {
|
|
7374
|
-
/** Direct field definitions - preserves literal types */
|
|
7375
|
-
fields: TFields;
|
|
7376
|
-
/** Cannot have fieldsets when using fields */
|
|
7377
|
-
fieldsets?: never;
|
|
7378
|
-
}
|
|
7379
|
-
/** Asset type configuration using fieldsets. */
|
|
7380
|
-
interface AssetTypeConfigWithFieldsets<TFieldsets extends readonly AnyFieldset$1[] = readonly AnyFieldset$1[]> extends AssetTypeBaseConfig {
|
|
7381
|
-
/** Field organization via fieldsets - preserves literal types */
|
|
7382
|
-
fieldsets: TFieldsets;
|
|
7383
|
-
/** Cannot have direct fields when using fieldsets */
|
|
7384
|
-
fields?: never;
|
|
7385
|
-
}
|
|
7386
|
-
/**
|
|
7387
|
-
* Asset type configuration with no metadata fields: the asset is its file. `AssetTypeSchema` makes
|
|
7388
|
-
* `fields` and `fieldsets` both optional, so this is an asset type deploy accepts (REL-1454).
|
|
8525
|
+
* Asset type configuration. Metadata fields are optional — an asset type with none is its file
|
|
8526
|
+
* (REL-1454) — and when declared, its `fields` hold fields and fieldsets side by side, as a content
|
|
8527
|
+
* type's do (REL-1794).
|
|
7389
8528
|
*/
|
|
7390
|
-
interface
|
|
7391
|
-
|
|
7392
|
-
|
|
8529
|
+
interface AssetTypeConfig<TFields extends readonly FieldMember[] = readonly FieldMember[]> extends AssetTypeBaseConfig {
|
|
8530
|
+
/** Fields and fieldsets, side by side - preserves literal types */
|
|
8531
|
+
fields?: TFields;
|
|
7393
8532
|
}
|
|
7394
|
-
/** Asset type configuration: direct fields, fieldsets, or neither. */
|
|
7395
|
-
type AssetTypeConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset$1[] = readonly AnyFieldset$1[]> = AssetTypeConfigWithFields<TFields> | AssetTypeConfigWithFieldsets<TFieldsets> | AssetTypeConfigWithoutFields;
|
|
7396
8533
|
/** Asset type definition - preserves field types for inference. */
|
|
7397
|
-
interface AssetTypeDefinition<TFields extends readonly
|
|
8534
|
+
interface AssetTypeDefinition<TFields extends readonly FieldMember[] = readonly FieldMember[]> {
|
|
7398
8535
|
readonly _tag: 'assetType';
|
|
7399
8536
|
readonly name: string;
|
|
7400
8537
|
readonly displayName: string;
|
|
@@ -7408,15 +8545,13 @@ interface AssetTypeDefinition<TFields extends readonly AnyFieldDefinition[] = re
|
|
|
7408
8545
|
readonly video?: VideoKindConfig;
|
|
7409
8546
|
readonly file?: FileKindConfig;
|
|
7410
8547
|
readonly fields?: TFields;
|
|
7411
|
-
readonly fieldsets?: TFieldsets;
|
|
7412
8548
|
}
|
|
7413
8549
|
/**
|
|
7414
8550
|
* Define an asset type.
|
|
7415
8551
|
*
|
|
7416
8552
|
* Exactly one kind key (`image`, `video`, or `file`) must be supplied. Metadata
|
|
7417
|
-
* fields are optional
|
|
7418
|
-
*
|
|
7419
|
-
* `defineContentType`.
|
|
8553
|
+
* fields are optional. The generic type parameter preserves literal field IDs for
|
|
8554
|
+
* inference, mirroring `defineContentType`.
|
|
7420
8555
|
*
|
|
7421
8556
|
* @example
|
|
7422
8557
|
* const productPhoto = defineAssetType('productPhoto', {
|
|
@@ -7430,58 +8565,102 @@ interface AssetTypeDefinition<TFields extends readonly AnyFieldDefinition[] = re
|
|
|
7430
8565
|
* ],
|
|
7431
8566
|
* })
|
|
7432
8567
|
*/
|
|
7433
|
-
declare function defineAssetType(name: string, config:
|
|
7434
|
-
declare function defineAssetType<TFields extends readonly AnyFieldDefinition[], _TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: AssetTypeConfigWithFields<TFields>): AssetTypeDefinition<TFields, readonly []>;
|
|
7435
|
-
declare function defineAssetType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: AssetTypeConfigWithFieldsets<TFieldsets>): AssetTypeDefinition<readonly [], TFieldsets>;
|
|
8568
|
+
declare function defineAssetType<TFields extends readonly FieldMember[] = readonly []>(name: string, config: AssetTypeConfig<TFields>): AssetTypeDefinition<TFields>;
|
|
7436
8569
|
/**
|
|
7437
8570
|
* Type alias for any asset type definition.
|
|
7438
8571
|
*/
|
|
7439
|
-
type AnyAssetTypeDefinition = AssetTypeDefinition<any
|
|
8572
|
+
type AnyAssetTypeDefinition = AssetTypeDefinition<any>;
|
|
7440
8573
|
/**
|
|
7441
8574
|
* Infer the TypeScript type from an asset type definition.
|
|
7442
8575
|
*
|
|
7443
|
-
* Mirrors {@link InferContentType}: produces the (
|
|
8576
|
+
* Mirrors {@link InferContentType}: produces the metadata field shape (a required field present)
|
|
7444
8577
|
* plus `_metadata`, so it is assignable to `BaseContent` and can parametrize
|
|
7445
|
-
* `AssetClient<T
|
|
7446
|
-
*
|
|
7447
|
-
* layer free of any dependency on the client layer.
|
|
8578
|
+
* `AssetClient<T>` — whose writes and `where` name exactly these fields. What a **read** returns
|
|
8579
|
+
* adds the {@link AssetServedBlocks}: {@link InferAssetEntry}.
|
|
7448
8580
|
*/
|
|
7449
|
-
type InferAssetType<T extends AnyAssetTypeDefinition, S extends FieldSchemaContext | undefined = undefined> = FieldValues<DeclaredFields<T>, S> & {
|
|
8581
|
+
type InferAssetType<T extends AnyAssetTypeDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = FieldValues<DeclaredFields<T>, S, 'required', I> & {
|
|
7450
8582
|
_metadata: EntryMetadata;
|
|
7451
8583
|
};
|
|
8584
|
+
/**
|
|
8585
|
+
* Customer-facing file binding block on an asset entry: the document's `AssetFile` — status,
|
|
8586
|
+
* backend, file name, MIME type, size, advisory hash, visibility, extracted metadata, focal point,
|
|
8587
|
+
* enrichment and scan status, processing stage/progress/error, and video playback readiness.
|
|
8588
|
+
*/
|
|
8589
|
+
type AssetFileBlock = components['schemas']['AssetFile'];
|
|
8590
|
+
/**
|
|
8591
|
+
* Computed gateway delivery URLs (the reserved `urls` key): the document's `AssetUrls` — an image's
|
|
8592
|
+
* `original` and `variants`, a file's `original`, a video's `playback`, `poster` and `download`.
|
|
8593
|
+
* Present only when `file.status` is `ready` — otherwise the response omits `urls` and callers read
|
|
8594
|
+
* `file.status`. Read from the committed document (REL-2194), which declared none until then, so this
|
|
8595
|
+
* was written here by hand.
|
|
8596
|
+
*/
|
|
8597
|
+
type AssetUrls = components['schemas']['AssetUrls'];
|
|
8598
|
+
/**
|
|
8599
|
+
* What every read of an asset carries beside its fields and `_metadata`, wherever the asset is read:
|
|
8600
|
+
* `file`, its binding, once one is bound, and `urls`, signed once the file is ready. The Content API
|
|
8601
|
+
* composes an asset's `file` into every entry it serves, an included reference at any depth among
|
|
8602
|
+
* them, and keeps it when an include path picks fields; its entry routes stamp `urls` onto every asset
|
|
8603
|
+
* the payload holds (REL-1812). A read's blocks, not fields: nothing writes or filters by them.
|
|
8604
|
+
*/
|
|
8605
|
+
interface AssetServedBlocks {
|
|
8606
|
+
file?: AssetFileBlock;
|
|
8607
|
+
urls?: AssetUrls;
|
|
8608
|
+
}
|
|
8609
|
+
/**
|
|
8610
|
+
* An asset as a read returns it (REL-1812): its fields and `_metadata` ({@link InferAssetType}) and
|
|
8611
|
+
* the {@link AssetServedBlocks}. What `asset(name)` reads, and what a reference to the asset type
|
|
8612
|
+
* reads as once an include path expands it — through a list, an object, rich text or a singleton
|
|
8613
|
+
* alike. `relyio generate-types` writes each asset type's alias with it.
|
|
8614
|
+
*/
|
|
8615
|
+
type InferAssetEntry<T extends AnyAssetTypeDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = InferAssetType<T, S, I> & AssetServedBlocks;
|
|
7452
8616
|
|
|
7453
8617
|
/**
|
|
7454
8618
|
* What a read returns for each field, derived from the field's declaration (`INV-SS-TYPES-INFERRED`).
|
|
7455
8619
|
*
|
|
7456
8620
|
* Every `Infer*` in this package — content types, singletons, asset types, settings groups — types
|
|
7457
|
-
* its fields here and nowhere else, so an entry, a referenced entry,
|
|
7458
|
-
* typed by one table. The types describe **what a read returns**, which is not always what a write
|
|
8621
|
+
* its fields here and nowhere else, so an entry, a referenced entry, an object's value and a list item
|
|
8622
|
+
* are typed by one table. The types describe **what a read returns**, which is not always what a write
|
|
7459
8623
|
* accepts:
|
|
7460
8624
|
*
|
|
7461
|
-
* - `richText` is the
|
|
8625
|
+
* - `richText` is the version-1 rich-text tree (`RichTextValue`, ADR 0013, REL-1803); a `table` is a
|
|
8626
|
+
* `RichTextTable` and a `code` field a `RichTextCodeGroup` — exactly the value of the same block
|
|
8627
|
+
* inside a tree (REL-1806); `date` is
|
|
8628
|
+
* `YYYY-MM-DD` and `dateTime` an ISO 8601 string
|
|
7462
8629
|
* in UTC at millisecond precision (`2026-10-01T04:30:00.000Z`), whatever offset it was written in
|
|
7463
8630
|
* — the client does not revive dates.
|
|
7464
|
-
* - A `reference` is the target's id
|
|
7465
|
-
*
|
|
7466
|
-
*
|
|
8631
|
+
* - A `reference` is the target's id, and the target entry itself where the read's include paths
|
|
8632
|
+
* expand it (REL-1801, `./include-paths.ts`): a path naming it, crossing it, or stopping at a list
|
|
8633
|
+
* or object that holds it. A path that picks fields (`features(name,slug)`) narrows the entry to
|
|
8634
|
+
* those and its `_metadata`. An include set the type cannot see — a `string[]` — types every
|
|
8635
|
+
* reference as either, `string | <entry>`. An optional single reference whose target was deleted
|
|
8636
|
+
* with its references nullified is `null`; a **required** one is never `null`, because its target
|
|
8637
|
+
* cannot be deleted while it holds it (REL-1795).
|
|
7467
8638
|
* - A localized field is the value for the one locale the read composed, like any other field; the
|
|
7468
8639
|
* other locales of a `locales=` read sit under `_metadata.localizations`, not here.
|
|
7469
|
-
* -
|
|
7470
|
-
*
|
|
7471
|
-
*
|
|
8640
|
+
* - **A required field is always present** (design decision 9, REL-1795); every other field is
|
|
8641
|
+
* optional. A required text, rich text, list or boolean a draft leaves empty is read as its kind's
|
|
8642
|
+
* empty value — `''`, the empty tree, `[]`, `false` — and named in
|
|
8643
|
+
* `_metadata.emptyRequiredFields`; a required number, date, choice, single reference, object,
|
|
8644
|
+
* table or code group has no empty value, so an entry holds it from
|
|
8645
|
+
* the moment it is created. An optional field the entry has no value for is omitted.
|
|
8646
|
+
* - An `object` is one value of its shape — `_type`, `_key` and the shape's fields — and of several,
|
|
8647
|
+
* their union told apart by `_type` (REL-1799). A **required** object is given a shape and that
|
|
8648
|
+
* shape's required values when the entry is created (REL-2034), so even a draft read holds its
|
|
8649
|
+
* `_type` and `_key`.
|
|
8650
|
+
* - A `json` field is the value its JSON Schema describes, inferred from the schema literal, and
|
|
8651
|
+
* `JsonValue` — any JSON value — without one (REL-1811, `./json-schema.ts`).
|
|
7472
8652
|
*/
|
|
7473
8653
|
|
|
7474
8654
|
/**
|
|
7475
|
-
* The parts of a schema a field's value type reads: the types a reference may expand to
|
|
7476
|
-
*
|
|
8655
|
+
* The parts of a schema a field's value type reads: the types a reference may expand to.
|
|
8656
|
+
* Structural, so every `defineSchema()` result fits. A list's or an object's shapes are not here:
|
|
8657
|
+
* a field carries its fieldsets itself.
|
|
7477
8658
|
*
|
|
7478
8659
|
* Without one in view — `InferContentType<typeof post>` with no second argument — a reference
|
|
7479
|
-
* expands to an {@link UnresolvedEntry}
|
|
7480
|
-
* is still typed, but what it names is not.
|
|
8660
|
+
* expands to an {@link UnresolvedEntry}: the field is still typed, but what it names is not.
|
|
7481
8661
|
*/
|
|
7482
8662
|
interface FieldSchemaContext {
|
|
7483
8663
|
readonly contentTypes: object;
|
|
7484
|
-
readonly components: object;
|
|
7485
8664
|
readonly singletonContentTypes: object;
|
|
7486
8665
|
readonly assetTypes?: object;
|
|
7487
8666
|
}
|
|
@@ -7492,21 +8671,26 @@ interface UnresolvedEntry {
|
|
|
7492
8671
|
_metadata: EntryMetadata;
|
|
7493
8672
|
[field: string]: unknown;
|
|
7494
8673
|
}
|
|
7495
|
-
/** A component whose definition is not in view: an object, with fields nothing declared. */
|
|
7496
|
-
type UnresolvedComponent = Record<string, unknown>;
|
|
7497
8674
|
/**
|
|
7498
|
-
* One row per field
|
|
7499
|
-
* construction: a
|
|
7500
|
-
* reading as `unknown`.
|
|
8675
|
+
* One row per field kind the schema declares. `OverEveryFieldKind`, from the field-kind declaration,
|
|
8676
|
+
* makes the table exhaustive by construction: a kind the declaration gains without a row here fails
|
|
8677
|
+
* to compile, rather than reading as `unknown`.
|
|
7501
8678
|
*/
|
|
7502
|
-
type
|
|
7503
|
-
[K in FieldType]: unknown;
|
|
7504
|
-
}> = T;
|
|
7505
|
-
type FieldValueByType<C, S extends Context> = OverEveryFieldType<{
|
|
8679
|
+
type FieldValueByType<C, S extends Context, K extends string, I extends string, A extends boolean> = OverEveryFieldKind<{
|
|
7506
8680
|
shortText: string;
|
|
7507
8681
|
longText: string;
|
|
7508
|
-
/**
|
|
7509
|
-
|
|
8682
|
+
/**
|
|
8683
|
+
* The version-1 tree (REL-1803): `{ _type: 'richText', version: 1, children }`, holding the
|
|
8684
|
+
* field's declared Blocks and Inline elements, each its fieldset's value (REL-1807), and — where it
|
|
8685
|
+
* declares `links` — its entry links (REL-1808). The field is one include path: included, every
|
|
8686
|
+
* entry link's `to` is the entry it links to and every reference inside a declared node its entry;
|
|
8687
|
+
* not included, each is its id.
|
|
8688
|
+
*/
|
|
8689
|
+
richText: RichTextValue<DeclaredIn<BlocksIn<C>, S, InsideRichText<I, K, BlocksIn<C>>, ExpandsHere<I, K, A>>, DeclaredIn<InlineIn<C>, S, InsideRichText<I, K, InlineIn<C>>, ExpandsHere<I, K, A>>, EntryLinkIn<C, S, K, I, A>>;
|
|
8690
|
+
/** Exactly a rich-text table block's value (REL-1806). */
|
|
8691
|
+
table: RichTextTable;
|
|
8692
|
+
/** Exactly a rich-text code group's value: code with tabs (REL-1806). */
|
|
8693
|
+
code: RichTextCodeGroup;
|
|
7510
8694
|
email: string;
|
|
7511
8695
|
url: string;
|
|
7512
8696
|
slug: string;
|
|
@@ -7518,34 +8702,74 @@ type FieldValueByType<C, S extends Context> = OverEveryFieldType<{
|
|
|
7518
8702
|
date: string;
|
|
7519
8703
|
/** ISO 8601 in UTC at millisecond precision: `2026-10-01T04:30:00.000Z`. */
|
|
7520
8704
|
dateTime: string;
|
|
7521
|
-
reference: ReferenceValue<C, S>;
|
|
8705
|
+
reference: ReferenceValue<C, S, K, I, A>;
|
|
7522
8706
|
tags: string[];
|
|
7523
|
-
list: ListValue<C, S
|
|
8707
|
+
list: ListValue<C, S, IncludesUnder<I, K>, CoversBelow<I, K, A>>;
|
|
8708
|
+
object: ObjectValue<C, S, IncludesUnder<I, K>, CoversBelow<I, K, A>>;
|
|
8709
|
+
/**
|
|
8710
|
+
* The value its JSON Schema describes, and any JSON value without one — `JsonValue`, never `any`
|
|
8711
|
+
* (REL-1811, `./json-schema.ts`).
|
|
8712
|
+
*/
|
|
8713
|
+
json: JsonFieldValue<C>;
|
|
7524
8714
|
}>;
|
|
7525
8715
|
/**
|
|
7526
|
-
* The value a read returns for field `F
|
|
8716
|
+
* The value a read returns for field `F`, under the include paths `I` of the record it sits in —
|
|
8717
|
+
* relative to that record, so `features` inside `sections` — and `A`, whether a path stopping at a
|
|
8718
|
+
* list or object above it expands every reference below (`./include-paths.ts`).
|
|
7527
8719
|
*
|
|
7528
8720
|
* The last arm is the one `unknown` in this module, and it is deliberate: a field whose `type` is not
|
|
7529
8721
|
* a declared literal — a definition built from a plain `string` rather than through `fields.*` — has
|
|
7530
8722
|
* no row to read.
|
|
7531
8723
|
*/
|
|
7532
|
-
type FieldValue<F extends AnyFieldDefinition, S extends Context = undefined
|
|
7533
|
-
/**
|
|
7534
|
-
|
|
7535
|
-
|
|
8724
|
+
type FieldValue<F extends AnyFieldDefinition, S extends Context = undefined, I extends string = never, A extends boolean = false> = F['type'] extends FieldType ? FieldValueByType<NonNullable<F['config']>, S, F['id'], I, A>[F['type']] : unknown;
|
|
8725
|
+
/**
|
|
8726
|
+
* `true` when a config declares `required: true` — a builder keeps the literal it was written as —
|
|
8727
|
+
* and `false` for `false`, `boolean`, or no `required` at all.
|
|
8728
|
+
*/
|
|
8729
|
+
type RequiredIn<C> = C extends {
|
|
8730
|
+
readonly required?: infer R;
|
|
8731
|
+
} ? [Exclude<R, undefined>] extends [never] ? false : [Exclude<R, undefined>] extends [true] ? true : false : false;
|
|
8732
|
+
/** Whether `F` declares `config.required: true`. */
|
|
8733
|
+
type IsRequired<F extends AnyFieldDefinition> = RequiredIn<NonNullable<F['config']>>;
|
|
8734
|
+
/** The ids of the required fields among `F` — each always present in a read (the module note). */
|
|
8735
|
+
type RequiredIds<F extends AnyFieldDefinition> = F extends AnyFieldDefinition ? IsRequired<F> extends true ? F['id'] : never : never;
|
|
8736
|
+
/** One object type from an intersection, so a read's type prints as one object. */
|
|
8737
|
+
type Flatten<T> = {
|
|
8738
|
+
[K in keyof T]: T[K];
|
|
8739
|
+
} & {};
|
|
8740
|
+
/**
|
|
8741
|
+
* Whether a read holds a record's required fields present: `required` for an entry, a singleton, an
|
|
8742
|
+
* asset and every value nested in one; `none` for a settings group, whose read starts from the
|
|
8743
|
+
* declared and synthesized defaults and leaves a required field with neither absent (the Content
|
|
8744
|
+
* API does not fill a settings group's empty required fields — REL-1795 left settings as they were).
|
|
8745
|
+
*/
|
|
8746
|
+
type Presence = 'required' | 'none';
|
|
8747
|
+
/**
|
|
8748
|
+
* The fields `F` (a union of field definitions) as an object: a required field present, every other
|
|
8749
|
+
* one optional — see the module note. With `P` `none`, every field optional.
|
|
8750
|
+
*/
|
|
8751
|
+
type FieldValues<F extends AnyFieldDefinition, S extends Context = undefined, P extends Presence = 'required', I extends string = never, A extends boolean = false> = Flatten<{
|
|
8752
|
+
[K in PresentIds<F, P>]: FieldValue<Extract<F, {
|
|
7536
8753
|
readonly id: K;
|
|
7537
|
-
}>, S>;
|
|
7538
|
-
}
|
|
8754
|
+
}>, S, I, A>;
|
|
8755
|
+
} & {
|
|
8756
|
+
[K in Exclude<F['id'], PresentIds<F, P>>]?: FieldValue<Extract<F, {
|
|
8757
|
+
readonly id: K;
|
|
8758
|
+
}>, S, I, A>;
|
|
8759
|
+
}>;
|
|
8760
|
+
type PresentIds<F extends AnyFieldDefinition, P extends Presence> = P extends 'required' ? RequiredIds<F> : never;
|
|
7539
8761
|
/**
|
|
7540
|
-
* Every field a definition declares,
|
|
7541
|
-
* over `fields`
|
|
8762
|
+
* Every field a definition declares, beside its sections or inside one at any depth, as one union —
|
|
8763
|
+
* the one walk over `fields` every `Infer*` shares. A section's fields join the record it sits in
|
|
8764
|
+
* (REL-1794), so a section leaves no key of its own: its fields read flat.
|
|
7542
8765
|
*/
|
|
7543
8766
|
type DeclaredFields<T extends {
|
|
7544
8767
|
readonly fields?: unknown;
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
8768
|
+
}> = Extract<NonNullable<T['fields']> extends readonly (infer Member)[] ? FieldsOfMember<Member> : never, AnyFieldDefinition>;
|
|
8769
|
+
/** A member's fields: a field is itself; a section is the fields of its own members. */
|
|
8770
|
+
type FieldsOfMember<Member> = Member extends AnyFieldDefinition ? Member : Member extends {
|
|
8771
|
+
readonly fields: readonly (infer Inner)[];
|
|
8772
|
+
} ? FieldsOfMember<Inner> : never;
|
|
7549
8773
|
/** `multi` as declared: `true`, `false`, or `boolean` when the declaration does not say. */
|
|
7550
8774
|
type Multiplicity<C> = C extends {
|
|
7551
8775
|
readonly multi?: infer M;
|
|
@@ -7562,24 +8786,149 @@ type ReferenceTarget<C> = C extends {
|
|
|
7562
8786
|
} ? T extends readonly (infer E)[] ? E : T : string;
|
|
7563
8787
|
/** `R[K]` where `R` declares `K`. A `Record<string, never>` default declares nothing. */
|
|
7564
8788
|
type Declared<R, K> = K extends keyof R ? R[K] : never;
|
|
7565
|
-
type ContentEntryOf<D, S extends Context> = D extends ContentTypeDefinition ? InferContentType<D, S> : never;
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
type
|
|
7573
|
-
|
|
7574
|
-
}
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
*
|
|
7578
|
-
*
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
8789
|
+
type ContentEntryOf<D, S extends Context, I extends string> = D extends ContentTypeDefinition ? InferContentType<D, S, I> : never;
|
|
8790
|
+
/**
|
|
8791
|
+
* An expanded singleton: its fields, as a singleton read types them, beside the `_metadata` every
|
|
8792
|
+
* expanded entry carries — {@link EntryMetadata}, not the singleton read's `SingletonMetadata`. The
|
|
8793
|
+
* Content API builds every record an include expands with the entry transform, a singleton's too
|
|
8794
|
+
* (REL-2195), so it reports `entryType`, `slug`, `refs` and the rest, and no version history.
|
|
8795
|
+
*/
|
|
8796
|
+
type SingletonEntryOf<D, S extends Context, I extends string> = D extends SingletonContentTypeDefinition ? Omit<InferSingletonContentType<D, S, I>, '_metadata'> & {
|
|
8797
|
+
_metadata: EntryMetadata;
|
|
8798
|
+
} : never;
|
|
8799
|
+
/**
|
|
8800
|
+
* An expanded asset: the fields a path picked of it beside `_metadata`, and the
|
|
8801
|
+
* {@link AssetServedBlocks} — `file` and `urls` — picked or not, as the Content API serves every asset
|
|
8802
|
+
* an include expands, at any depth (REL-1812). With every field, exactly what `asset(name)` reads
|
|
8803
|
+
* (`InferAssetEntry`).
|
|
8804
|
+
*/
|
|
8805
|
+
type AssetEntryOf<D, S extends Context, I extends string, Fields> = D extends AssetTypeDefinition ? Selected<InferAssetType<D, S, I>, Fields> & AssetServedBlocks : never;
|
|
8806
|
+
type OrUnresolved<T, Fields> = [T] extends [never] ? Selected<UnresolvedEntry, Fields> : T;
|
|
8807
|
+
/**
|
|
8808
|
+
* What `include` expands a reference to `Target` into: that type's entry, typed by the schema, under
|
|
8809
|
+
* `I`, the include paths that continue past the reference (`customers.logo` → `logo` inside the
|
|
8810
|
+
* customer), cut down to `Fields`, the fields a path picked (`./include-paths.ts`'s `Selected`). The
|
|
8811
|
+
* one place every expansion is typed — a reference at any depth, an entry link, a singleton's or a
|
|
8812
|
+
* settings group's include — so an asset reads as the API serves it wherever it is reached.
|
|
8813
|
+
*/
|
|
8814
|
+
type ExpandedEntry<Target, S extends Context, I extends string = never, Fields = EveryField> = S extends FieldSchemaContext ? OrUnresolved<Selected<ContentEntryOf<Declared<S['contentTypes'], Target>, S, I>, Fields> | Selected<SingletonEntryOf<Declared<S['singletonContentTypes'], Target>, S, I>, Fields> | AssetEntryOf<Declared<NonNullable<S['assetTypes']>, Target>, S, I, Fields>, Fields> : Selected<UnresolvedEntry, Fields>;
|
|
8815
|
+
/**
|
|
8816
|
+
* What a single reference reads as once its target is gone: `null` for an optional one, whose
|
|
8817
|
+
* referrers a delete may nullify, and nothing for a required one, whose target cannot be deleted
|
|
8818
|
+
* while it holds it (REL-1795).
|
|
8819
|
+
*/
|
|
8820
|
+
type Nullified<C> = RequiredIn<C> extends true ? never : null;
|
|
8821
|
+
/**
|
|
8822
|
+
* A reference field `K` under the include paths `I` of its record (REL-1801): the target's id, or —
|
|
8823
|
+
* where a path expands it — the target's entry, narrowed to the fields a path picked. Under an include
|
|
8824
|
+
* set the type cannot see (`string`), either.
|
|
8825
|
+
*/
|
|
8826
|
+
type ReferenceValue<C, S extends Context, K extends string, I extends string, A extends boolean> = string extends I ? ReferenceAs<C, string | ExpandedEntry<ReferenceTarget<C>, S, string>> : ReferenceAs<C, ExpandsHere<I, K, A> extends true ? ExpandedEntry<ReferenceTarget<C>, S, IncludesUnder<I, K>, SelectionAt<I, K>> : string>;
|
|
8827
|
+
/** One reference value `V`, as the field holds it: alone, nullable unless required, or a list. */
|
|
8828
|
+
type ReferenceAs<C, V> = [Multiplicity<C>] extends [true] ? V[] : [Multiplicity<C>] extends [false | undefined] ? V | Nullified<C> : V | Nullified<C> | V[];
|
|
8829
|
+
/**
|
|
8830
|
+
* A list of a shape (`of`, REL-1796) is a list of items, each its shape's values — a section's
|
|
8831
|
+
* fields read flat — plus `_type`, the shape's id as a literal, and `_key`, its item key. A list of
|
|
8832
|
+
* several shapes, a page builder (REL-1798), is a list of their union, told apart by `_type`. A list
|
|
8833
|
+
* without one is a list of strings, which is what the validation document enforces for it.
|
|
8834
|
+
*/
|
|
8835
|
+
type ListValue<C, S extends Context, I extends string, A extends boolean> = C extends {
|
|
8836
|
+
readonly of?: infer Shape;
|
|
8837
|
+
} ? [ShapesIn<Exclude<Shape, undefined>>] extends [never] ? string[] : Array<ShapeItem<ShapesIn<Exclude<Shape, undefined>>, S, I, A>> : string[];
|
|
8838
|
+
/**
|
|
8839
|
+
* A declared shape's value inside rich text: its item, as a page builder's is — every reference in it
|
|
8840
|
+
* expanded when `A`, the field being included, says so (a rich-text field is one include path).
|
|
8841
|
+
*/
|
|
8842
|
+
type DeclaredIn<Shape, S extends Context, I extends string, A extends boolean> = Extract<ShapeItem<Shape, S, I, A>, RichTextShapeValue>;
|
|
8843
|
+
/**
|
|
8844
|
+
* The include paths a rich-text field `K`'s declared nodes `Shape` are read under. Rich text has no
|
|
8845
|
+
* path inside it: the field is one include path, so what a path does at `K` it does to every
|
|
8846
|
+
* reference the nodes hold, at any depth — the server picks each one's fields by `K(…)`'s
|
|
8847
|
+
* parentheses and continues each by `K.…`'s rest (REL-1808). So each path stopping at or past `K` is
|
|
8848
|
+
* re-spelt at every path the shape can include (`body(slug)` → `see(slug)`, `items.ref(slug)`),
|
|
8849
|
+
* and every reference reads the selection and the hops the field was given. An include set the type
|
|
8850
|
+
* cannot see (`string`) may expand anything.
|
|
8851
|
+
*/
|
|
8852
|
+
type InsideRichText<I extends string, K extends string, Shape> = string extends I ? string : `${IncludablePaths<FieldsOfShapes$1<Shape>>}${SuffixAt<I, K>}`;
|
|
8853
|
+
/** What each path does at `K`, as a suffix: `''` stops there, `(slug)` picks, `.author` continues. */
|
|
8854
|
+
type SuffixAt<I extends string, K extends string> = I extends K ? '' : I extends `${K}(${infer Picked})` ? `(${Picked})` : I extends `${K}.${infer Rest}` ? `.${Rest}` : never;
|
|
8855
|
+
/** The fields of the fieldsets `Shape` names, sections read flat. */
|
|
8856
|
+
type FieldsOfShapes$1<Shape> = Shape extends {
|
|
8857
|
+
readonly fields: readonly unknown[];
|
|
8858
|
+
} ? DeclaredFields<Shape> : never;
|
|
8859
|
+
/**
|
|
8860
|
+
* The content types a rich-text config's `links` names (REL-1808), as a union; `never` for a field
|
|
8861
|
+
* that declares none — and for a config the type cannot read `links` from.
|
|
8862
|
+
*/
|
|
8863
|
+
type LinkTargetsIn<C> = C extends {
|
|
8864
|
+
readonly links?: {
|
|
8865
|
+
readonly to: infer To;
|
|
8866
|
+
} | undefined;
|
|
8867
|
+
} ? unknown extends To ? never : ReferenceTarget<{
|
|
8868
|
+
readonly to: To;
|
|
8869
|
+
}> : never;
|
|
8870
|
+
/**
|
|
8871
|
+
* A rich-text field's entry link (REL-1808): `never` for a field declaring no `links`; otherwise the
|
|
8872
|
+
* mark, its `to` the target's id — or, where the field is included, the target's entry, narrowed to
|
|
8873
|
+
* the fields a path picked and holding the paths that continue past the field.
|
|
8874
|
+
*/
|
|
8875
|
+
type EntryLinkIn<C, S extends Context, K extends string, I extends string, A extends boolean> = [
|
|
8876
|
+
LinkTargetsIn<C>
|
|
8877
|
+
] extends [never] ? never : RichTextEntryLinkMark<string extends I ? string | ExpandedEntry<LinkTargetsIn<C>, S, string> : ExpandsHere<I, K, A> extends true ? ExpandedEntry<LinkTargetsIn<C>, S, IncludesUnder<I, K>, SelectionAt<I, K>> : string>;
|
|
8878
|
+
/** The fieldsets a rich-text config declares as Blocks (REL-1807), as a union; `never` for none. */
|
|
8879
|
+
type BlocksIn<C> = C extends {
|
|
8880
|
+
readonly blocks?: ReadonlyArray<infer Shape>;
|
|
8881
|
+
} ? Shape : never;
|
|
8882
|
+
/** The fieldsets a rich-text config declares as Inline elements (REL-1807), as a union. */
|
|
8883
|
+
type InlineIn<C> = C extends {
|
|
8884
|
+
readonly inline?: ReadonlyArray<infer Shape>;
|
|
8885
|
+
} ? Shape : never;
|
|
8886
|
+
/** The shapes an `of` names: the one fieldset, or each of a list of them. Distributes. */
|
|
8887
|
+
type ShapesIn<Of> = Of extends readonly (infer Shape)[] ? Shape : Of;
|
|
8888
|
+
/**
|
|
8889
|
+
* An object (`of`, REL-1799) is one value of its shape: the shape's values — a section's fields read
|
|
8890
|
+
* flat — plus `_type` and `_key`, as a list item is. Of several shapes, their union, told apart by
|
|
8891
|
+
* `_type`, so `media._type === 'video'` narrows it. `of` is required, so an object always has one.
|
|
8892
|
+
*/
|
|
8893
|
+
type ObjectValue<C, S extends Context, I extends string, A extends boolean> = C extends {
|
|
8894
|
+
readonly of: infer Shape;
|
|
8895
|
+
} ? ShapeItem<ShapesIn<Shape>, S, I, A> : never;
|
|
8896
|
+
/**
|
|
8897
|
+
* What every structured item carries (design decision 6): `_type`, the fieldset it takes, and
|
|
8898
|
+
* `_key`, its identity in its list for life. A list of shapes reads as an array of these.
|
|
8899
|
+
*/
|
|
8900
|
+
interface Keyed {
|
|
8901
|
+
readonly _type: string;
|
|
8902
|
+
readonly _key: string;
|
|
8903
|
+
}
|
|
8904
|
+
/**
|
|
8905
|
+
* One block of a page builder (REL-1798): the item of `List` — a list field's value as a read types
|
|
8906
|
+
* it, optional or not — whose `_type` is `Type`. What a site's component for that block receives:
|
|
8907
|
+
* `BlockOf<Page['sections'], 'hero'>`. An object's value (REL-1799) is one such item rather than a
|
|
8908
|
+
* list of them, so `BlockOf<Hero['media'], 'video'>` is the arm of the value whose `_type` is `video`.
|
|
8909
|
+
*/
|
|
8910
|
+
type BlockOf<List, Type extends string> = Extract<NonNullable<List> extends ReadonlyArray<infer Item> ? Item : NonNullable<List>, {
|
|
8911
|
+
readonly _type: Type;
|
|
8912
|
+
}>;
|
|
8913
|
+
/**
|
|
8914
|
+
* One item of a shape: `_type` and `_key` beside its values, under the include paths `I` that reach
|
|
8915
|
+
* into the list or object (a path names fields, never shapes, so every shape reads the same `I`).
|
|
8916
|
+
* Distributes over a union of shapes.
|
|
8917
|
+
*/
|
|
8918
|
+
type ShapeItem<Shape, S extends Context, I extends string = never, A extends boolean = false> = Shape extends {
|
|
8919
|
+
readonly id: infer Id;
|
|
8920
|
+
readonly fields: readonly unknown[];
|
|
8921
|
+
} ? Flatten<{
|
|
8922
|
+
readonly _type: Id;
|
|
8923
|
+
readonly _key: string;
|
|
8924
|
+
} & FieldValues<DeclaredFields<Shape>, S, 'required', I, A>> : never;
|
|
8925
|
+
/**
|
|
8926
|
+
* The value a fieldset holds wherever it is a shape — an object's value, or one item of a list —
|
|
8927
|
+
* typed by schema `S`: `_type`, `_key` and its fields. `relyio generate-types` writes one alias per
|
|
8928
|
+
* fieldset id with it (`export type HeroFieldset = ShapeValue<typeof heroFieldset, SchemaTypes>`),
|
|
8929
|
+
* so a site names a shape's value without reaching through the field that holds it.
|
|
8930
|
+
*/
|
|
8931
|
+
type ShapeValue<Shape extends AnyFieldset, S extends Context = undefined> = ShapeItem<Shape, S>;
|
|
7583
8932
|
|
|
7584
8933
|
/**
|
|
7585
8934
|
* Content type definition matching @relyio/schema ContentTypeSchema
|
|
@@ -7589,34 +8938,42 @@ type ListValue<C, S extends Context> = C extends {
|
|
|
7589
8938
|
*/
|
|
7590
8939
|
|
|
7591
8940
|
/**
|
|
7592
|
-
*
|
|
7593
|
-
*
|
|
8941
|
+
* A fieldset: a named group of fields and fieldsets. Where it is placed decides what it is (ADR
|
|
8942
|
+
* 0012). Among a type's (or another fieldset's) `fields` it is a **section** of the form, and its
|
|
8943
|
+
* fields join the record it sits in: a read returns them beside the type's other fields, so
|
|
8944
|
+
* grouping the form never changes a read (REL-1794).
|
|
8945
|
+
*
|
|
8946
|
+
* A fieldset id names one shape across the whole schema. Reuse one by passing the same value
|
|
8947
|
+
* wherever it is wanted; deploy refuses two different fieldsets under one id.
|
|
7594
8948
|
*/
|
|
7595
|
-
interface Fieldset<
|
|
7596
|
-
/**
|
|
7597
|
-
readonly id:
|
|
8949
|
+
interface Fieldset<TMembers extends readonly FieldMember[] = readonly FieldMember[], TId extends string = string> {
|
|
8950
|
+
/** The fieldset's id — one shape across the schema, and what each item of a list of it names in `_type` */
|
|
8951
|
+
readonly id: TId;
|
|
7598
8952
|
/** Display name shown in the UI */
|
|
7599
8953
|
readonly displayName: string;
|
|
7600
8954
|
/** Optional description */
|
|
7601
8955
|
readonly description?: string;
|
|
7602
|
-
/** Whether an editing surface shows this
|
|
8956
|
+
/** Whether an editing surface shows this section collapsed to begin with */
|
|
7603
8957
|
readonly collapsedByDefault?: boolean;
|
|
7604
8958
|
/** AI configuration for content generation and review */
|
|
7605
8959
|
readonly ai?: AIConfig;
|
|
7606
|
-
/** Fields
|
|
7607
|
-
readonly fields:
|
|
8960
|
+
/** Fields and fieldsets, in the order the form shows them - preserves literal types */
|
|
8961
|
+
readonly fields: TMembers;
|
|
7608
8962
|
}
|
|
7609
8963
|
/**
|
|
7610
|
-
* Type alias for a fieldset with any
|
|
8964
|
+
* Type alias for a fieldset with any members.
|
|
7611
8965
|
* Used in generic constraints where we need to accept any fieldset type.
|
|
7612
8966
|
*/
|
|
7613
8967
|
type AnyFieldset = Fieldset<any>;
|
|
8968
|
+
/** One entry of a `fields` list: a field, or a fieldset placed there as a section. */
|
|
8969
|
+
type FieldMember = AnyFieldDefinition | AnyFieldset;
|
|
7614
8970
|
/**
|
|
7615
|
-
* Create a fieldset
|
|
7616
|
-
*
|
|
8971
|
+
* Create a fieldset. Place it among a type's fields to make a section of the form, or pass it as a
|
|
8972
|
+
* list's `of` to make it the shape each item takes (REL-1796). Generic to preserve its id and the
|
|
8973
|
+
* specific field types for type inference: a list item's `_type` is this id.
|
|
7617
8974
|
*
|
|
7618
8975
|
* @example
|
|
7619
|
-
* const
|
|
8976
|
+
* export const seo = fieldset('seo', {
|
|
7620
8977
|
* displayName: 'SEO Settings',
|
|
7621
8978
|
* fields: [
|
|
7622
8979
|
* fields.shortText('metaTitle', { config: { maxLength: 60 } }),
|
|
@@ -7624,19 +8981,19 @@ type AnyFieldset = Fieldset<any>;
|
|
|
7624
8981
|
* ]
|
|
7625
8982
|
* })
|
|
7626
8983
|
*/
|
|
7627
|
-
declare function fieldset<
|
|
8984
|
+
declare function fieldset<TId extends string, TMembers extends readonly FieldMember[]>(id: TId, config: {
|
|
7628
8985
|
displayName: string;
|
|
7629
8986
|
description?: string;
|
|
7630
|
-
/** Show the
|
|
8987
|
+
/** Show the section collapsed until an editor opens it */
|
|
7631
8988
|
collapsedByDefault?: boolean;
|
|
7632
8989
|
ai?: AIConfig;
|
|
7633
|
-
fields:
|
|
7634
|
-
}): Fieldset<
|
|
8990
|
+
fields: TMembers;
|
|
8991
|
+
}): Fieldset<TMembers, TId>;
|
|
7635
8992
|
/**
|
|
7636
|
-
* Content type configuration
|
|
7637
|
-
* Generic to preserve literal field IDs for type inference
|
|
8993
|
+
* Content type configuration. Its `fields` hold fields and fieldsets side by side, in the order the
|
|
8994
|
+
* form shows them (REL-1794). Generic to preserve literal field IDs for type inference.
|
|
7638
8995
|
*/
|
|
7639
|
-
interface
|
|
8996
|
+
interface ContentTypeConfig<TFields extends readonly FieldMember[] = readonly FieldMember[]> {
|
|
7640
8997
|
/** Display name shown in the UI */
|
|
7641
8998
|
displayName: string;
|
|
7642
8999
|
/** Plural display name shown in the UI (e.g., "Products" for "Product") */
|
|
@@ -7656,48 +9013,13 @@ interface ContentTypeConfigWithFields<TFields extends readonly AnyFieldDefinitio
|
|
|
7656
9013
|
accessTags?: string[];
|
|
7657
9014
|
/** Workflow configuration for this content type */
|
|
7658
9015
|
workflow?: ContentTypeWorkflowConfig;
|
|
7659
|
-
/**
|
|
9016
|
+
/** Fields and fieldsets, side by side - preserves literal types */
|
|
7660
9017
|
fields: TFields;
|
|
7661
|
-
/** Cannot have fieldsets when using fields */
|
|
7662
|
-
fieldsets?: never;
|
|
7663
9018
|
}
|
|
7664
9019
|
/**
|
|
7665
|
-
* Content type
|
|
7666
|
-
* Generic to preserve fieldset field types
|
|
9020
|
+
* Content type definition - preserves field types for inference
|
|
7667
9021
|
*/
|
|
7668
|
-
interface
|
|
7669
|
-
/** Display name shown in the UI */
|
|
7670
|
-
displayName: string;
|
|
7671
|
-
/** Plural display name shown in the UI (e.g., "Products" for "Product") */
|
|
7672
|
-
displayNamePlural?: string;
|
|
7673
|
-
/** Description of the content type */
|
|
7674
|
-
description?: string;
|
|
7675
|
-
/** AI configuration: generation/review guidance */
|
|
7676
|
-
ai?: AIConfig;
|
|
7677
|
-
/**
|
|
7678
|
-
* Field ID to use as entry display title in lists, references, and editor header.
|
|
7679
|
-
* If not set, falls back to: title → name → slug → first shortText field → entryUid
|
|
7680
|
-
*/
|
|
7681
|
-
displayField?: string;
|
|
7682
|
-
/** Access tags for role-based access control */
|
|
7683
|
-
accessTags?: string[];
|
|
7684
|
-
/** Whether this content type supports hierarchical (parent-child) relationships */
|
|
7685
|
-
hierarchical?: boolean;
|
|
7686
|
-
/** Workflow configuration for this content type */
|
|
7687
|
-
workflow?: ContentTypeWorkflowConfig;
|
|
7688
|
-
/** Field organization via fieldsets - preserves literal types */
|
|
7689
|
-
fieldsets: TFieldsets;
|
|
7690
|
-
/** Cannot have direct fields when using fieldsets */
|
|
7691
|
-
fields?: never;
|
|
7692
|
-
}
|
|
7693
|
-
/**
|
|
7694
|
-
* Content type configuration (either fields OR fieldsets, not both)
|
|
7695
|
-
*/
|
|
7696
|
-
type ContentTypeConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset[] = readonly AnyFieldset[]> = ContentTypeConfigWithFields<TFields> | ContentTypeConfigWithFieldsets<TFieldsets>;
|
|
7697
|
-
/**
|
|
7698
|
-
* Content type definition - preserves field types for inference
|
|
7699
|
-
*/
|
|
7700
|
-
interface ContentTypeDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset[] = readonly AnyFieldset[]> {
|
|
9022
|
+
interface ContentTypeDefinition<TFields extends readonly FieldMember[] = readonly FieldMember[]> {
|
|
7701
9023
|
readonly _tag: 'contentType';
|
|
7702
9024
|
readonly name: string;
|
|
7703
9025
|
readonly displayName: string;
|
|
@@ -7710,8 +9032,7 @@ interface ContentTypeDefinition<TFields extends readonly AnyFieldDefinition[] =
|
|
|
7710
9032
|
readonly hierarchical?: boolean;
|
|
7711
9033
|
readonly accessTags?: string[];
|
|
7712
9034
|
readonly workflow?: ContentTypeWorkflowConfig;
|
|
7713
|
-
readonly fields
|
|
7714
|
-
readonly fieldsets?: TFieldsets;
|
|
9035
|
+
readonly fields: TFields;
|
|
7715
9036
|
}
|
|
7716
9037
|
/**
|
|
7717
9038
|
* Define a content type with type-safe fields
|
|
@@ -7720,41 +9041,27 @@ interface ContentTypeDefinition<TFields extends readonly AnyFieldDefinition[] =
|
|
|
7720
9041
|
* system, enabling autocomplete in SDK methods like where(), select(), etc.
|
|
7721
9042
|
*
|
|
7722
9043
|
* @example
|
|
7723
|
-
* //
|
|
9044
|
+
* // Fields, and a fieldset placed among them as a section of the form
|
|
7724
9045
|
* const product = defineContentType('product', {
|
|
7725
9046
|
* displayName: 'Product',
|
|
7726
9047
|
* fields: [
|
|
7727
9048
|
* fields.shortText('title', { config: { required: true } }),
|
|
7728
|
-
* fields.decimal('price', { config: { min: 0, decimalPlaces: 2 } }),
|
|
7729
|
-
* ]
|
|
7730
|
-
* })
|
|
7731
|
-
*
|
|
7732
|
-
* @example
|
|
7733
|
-
* // Using fieldsets for organization
|
|
7734
|
-
* const product = defineContentType('product', {
|
|
7735
|
-
* displayName: 'Product',
|
|
7736
|
-
* fieldsets: [
|
|
7737
|
-
* fieldset('basic', {
|
|
7738
|
-
* displayName: 'Basic Info',
|
|
7739
|
-
* fields: [
|
|
7740
|
-
* fields.shortText('title', { config: { required: true } }),
|
|
7741
|
-
* ]
|
|
7742
|
-
* }),
|
|
7743
9049
|
* fieldset('pricing', {
|
|
7744
9050
|
* displayName: 'Pricing',
|
|
7745
9051
|
* fields: [
|
|
7746
9052
|
* fields.decimal('price', { config: { min: 0, decimalPlaces: 2 } }),
|
|
7747
9053
|
* ]
|
|
7748
9054
|
* }),
|
|
9055
|
+
* fields.richText('description'),
|
|
7749
9056
|
* ]
|
|
7750
9057
|
* })
|
|
9058
|
+
* // A read returns { title, price, description }: a section's fields are the entry's own
|
|
7751
9059
|
*/
|
|
7752
|
-
declare function defineContentType<TFields extends readonly
|
|
7753
|
-
declare function defineContentType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: ContentTypeConfigWithFieldsets<TFieldsets>): ContentTypeDefinition<readonly [], TFieldsets>;
|
|
9060
|
+
declare function defineContentType<TFields extends readonly FieldMember[]>(name: string, config: ContentTypeConfig<TFields>): ContentTypeDefinition<TFields>;
|
|
7754
9061
|
/**
|
|
7755
9062
|
* Type alias for any content type definition.
|
|
7756
9063
|
*/
|
|
7757
|
-
type AnyContentTypeDefinition = ContentTypeDefinition<any
|
|
9064
|
+
type AnyContentTypeDefinition = ContentTypeDefinition<any>;
|
|
7758
9065
|
/**
|
|
7759
9066
|
* What a read reports about an entry beside its fields: the committed document's `EntryMetadata`
|
|
7760
9067
|
* (`apps/services/api/openapi-spec.json`), read through `http/api-schema.ts`, its one derivation in
|
|
@@ -7786,19 +9093,19 @@ type EntryMetadata = components['schemas']['EntryMetadata'];
|
|
|
7786
9093
|
type LocalePublicationFields = Pick<EntryMetadata, 'localeStatus' | 'localeHasDraft' | 'draftLocales' | 'hasDraft'>;
|
|
7787
9094
|
/**
|
|
7788
9095
|
* Infer the TypeScript type of an entry from a content type definition: every field it declares,
|
|
7789
|
-
*
|
|
7790
|
-
* `_metadata`.
|
|
7791
|
-
* reads as.
|
|
9096
|
+
* beside its sections or inside one — a section's fields read flat — typed as a read returns it (`INV-SS-TYPES-INFERRED`), plus
|
|
9097
|
+
* `_metadata`. A required field is always present and every other one optional —
|
|
9098
|
+
* `schema/infer-fields.ts` says why, and what each field type reads as.
|
|
7792
9099
|
*
|
|
7793
9100
|
* `S` is the schema the type belongs to. With it, a reference expanded by `include` is typed as the
|
|
7794
|
-
* entry it points at
|
|
7795
|
-
*
|
|
9101
|
+
* entry it points at; without it, as an entry whose fields are not known. A client typed by a schema
|
|
9102
|
+
* passes it.
|
|
7796
9103
|
*
|
|
7797
9104
|
* @example
|
|
7798
9105
|
* const product = defineContentType('product', {
|
|
7799
9106
|
* displayName: 'Product',
|
|
7800
9107
|
* fields: [
|
|
7801
|
-
* fields.shortText('title'),
|
|
9108
|
+
* fields.shortText('title', { config: { required: true } }),
|
|
7802
9109
|
* fields.decimal('price'),
|
|
7803
9110
|
* fields.enum('status', {
|
|
7804
9111
|
* config: {
|
|
@@ -7812,10 +9119,1725 @@ type LocalePublicationFields = Pick<EntryMetadata, 'localeStatus' | 'localeHasDr
|
|
|
7812
9119
|
* })
|
|
7813
9120
|
*
|
|
7814
9121
|
* type Product = InferContentType<typeof product>
|
|
7815
|
-
* // { title
|
|
9122
|
+
* // { title: string; price?: number; status?: 'draft' | 'live'; _metadata: EntryMetadata }
|
|
7816
9123
|
*/
|
|
7817
|
-
type InferContentType<T extends AnyContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined> = FieldValues<DeclaredFields<T>, S> & {
|
|
9124
|
+
type InferContentType<T extends AnyContentTypeDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = FieldValues<DeclaredFields<T>, S, 'required', I> & {
|
|
7818
9125
|
_metadata: EntryMetadata;
|
|
7819
9126
|
};
|
|
7820
9127
|
|
|
7821
|
-
|
|
9128
|
+
/**
|
|
9129
|
+
* Field type definitions matching @relyio/schema package
|
|
9130
|
+
*
|
|
9131
|
+
* Every config option here is spelled as `@relyio/schema`'s field config schema spells it, because
|
|
9132
|
+
* the CLI sends a field's `config` to deploy verbatim, and deploy — and `relyio validate` before it —
|
|
9133
|
+
* refuses an option the field's type does not declare, naming its path (REL-1480). This package has
|
|
9134
|
+
* no runtime dependency on `@relyio/schema`, so the
|
|
9135
|
+
* options are pinned from `@relyio/codegen-typescript`, which depends on both: its
|
|
9136
|
+
* `src/__tests__/sdk-field-config.types.ts` fails to compile when a key, whether it is required, or
|
|
9137
|
+
* the values it accepts differs between the two (REL-1408).
|
|
9138
|
+
*
|
|
9139
|
+
* The field kinds themselves are not restated: {@link FieldType} is the declaration's union, taken
|
|
9140
|
+
* as a type (REL-1786). The import is erased from the JavaScript, and `dts.resolve` in
|
|
9141
|
+
* `tsup.config.ts` rolls the union into the published `.d.ts`, as it does `@relyio/api-contract`'s
|
|
9142
|
+
* types, so a customer installs nothing more for it. `@relyio/schema` is a devDependency for that
|
|
9143
|
+
* reason: a build-time input, like the contract.
|
|
9144
|
+
*/
|
|
9145
|
+
|
|
9146
|
+
/**
|
|
9147
|
+
* AI configuration. A single prompt — `instructions` — describes what the
|
|
9148
|
+
* element is and how AI should produce its value. Attaches to fields, content
|
|
9149
|
+
* types, fieldsets, and (extended) asset types.
|
|
9150
|
+
*
|
|
9151
|
+
* @example
|
|
9152
|
+
* ```typescript
|
|
9153
|
+
* fields.richText('body', {
|
|
9154
|
+
* ai: {
|
|
9155
|
+
* instructions: `
|
|
9156
|
+
* Write in a conversational tone.
|
|
9157
|
+
* Use short paragraphs (2-3 sentences).
|
|
9158
|
+
* Target grade 8 reading level.
|
|
9159
|
+
* `
|
|
9160
|
+
* }
|
|
9161
|
+
* })
|
|
9162
|
+
* ```
|
|
9163
|
+
*/
|
|
9164
|
+
interface AIConfig {
|
|
9165
|
+
/**
|
|
9166
|
+
* AI brief for this element: what it should contain and how to produce it.
|
|
9167
|
+
*
|
|
9168
|
+
* Used by the Studio authoring agent and — on asset types with
|
|
9169
|
+
* `ai.autoGenerate` — by the automatic post-upload run.
|
|
9170
|
+
*
|
|
9171
|
+
* The fallback chain for AI guidance is:
|
|
9172
|
+
* 1. ai.instructions (most specific)
|
|
9173
|
+
* 2. ui.description (general field description)
|
|
9174
|
+
* 3. Field displayName + type (inferred from semantics)
|
|
9175
|
+
*/
|
|
9176
|
+
instructions?: string;
|
|
9177
|
+
}
|
|
9178
|
+
/**
|
|
9179
|
+
* Field-level AI config. `inputs` names the fields this instruction reads.
|
|
9180
|
+
* Unknown ids and cycles are refused when the schema is parsed.
|
|
9181
|
+
*/
|
|
9182
|
+
interface FieldAIConfig extends AIConfig {
|
|
9183
|
+
/** Field ids this instruction reads. Never inferred from instruction text. */
|
|
9184
|
+
inputs?: string[];
|
|
9185
|
+
}
|
|
9186
|
+
/**
|
|
9187
|
+
* Asset-type AI configuration. Extends {@link AIConfig} with `autoGenerate`,
|
|
9188
|
+
* the single switch that turns on automatic field generation after upload.
|
|
9189
|
+
*/
|
|
9190
|
+
interface AssetAIConfig extends AIConfig {
|
|
9191
|
+
/**
|
|
9192
|
+
* Master switch for automatic, post-upload field generation. When `true`, the
|
|
9193
|
+
* derived analysis agent fills every field that declares `ai.instructions`,
|
|
9194
|
+
* applied as a review proposal. Only meaningful for image asset types in v1.
|
|
9195
|
+
*/
|
|
9196
|
+
autoGenerate?: boolean;
|
|
9197
|
+
}
|
|
9198
|
+
interface BaseFieldConfig {
|
|
9199
|
+
/** Whether the field is required */
|
|
9200
|
+
required?: boolean;
|
|
9201
|
+
/** Whether the field value must be unique */
|
|
9202
|
+
unique?: boolean;
|
|
9203
|
+
/** Default value for the field. Each field type narrows it to the values its schema accepts. */
|
|
9204
|
+
defaultValue?: unknown;
|
|
9205
|
+
}
|
|
9206
|
+
interface FieldUIConfig {
|
|
9207
|
+
/** Display name shown in the UI */
|
|
9208
|
+
displayName: string;
|
|
9209
|
+
/** Field description/help text */
|
|
9210
|
+
description?: string;
|
|
9211
|
+
/** Widget-specific options */
|
|
9212
|
+
options?: Record<string, unknown>;
|
|
9213
|
+
}
|
|
9214
|
+
interface RuleCondition {
|
|
9215
|
+
field: string;
|
|
9216
|
+
operator: 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'greater_than' | 'less_than' | 'is_empty' | 'is_not_empty';
|
|
9217
|
+
value?: unknown;
|
|
9218
|
+
}
|
|
9219
|
+
interface RuleConditions {
|
|
9220
|
+
mode: 'all' | 'any' | 'none';
|
|
9221
|
+
conditions: RuleCondition[];
|
|
9222
|
+
}
|
|
9223
|
+
interface VisibilityRule {
|
|
9224
|
+
type: 'visibility';
|
|
9225
|
+
action: 'show' | 'hide';
|
|
9226
|
+
conditions: RuleConditions;
|
|
9227
|
+
}
|
|
9228
|
+
interface RequirementRule {
|
|
9229
|
+
type: 'requirement';
|
|
9230
|
+
action: 'require' | 'optional';
|
|
9231
|
+
conditions: RuleConditions;
|
|
9232
|
+
}
|
|
9233
|
+
interface ValidationRule$1 {
|
|
9234
|
+
type: 'validation';
|
|
9235
|
+
action: 'validate' | 'skip';
|
|
9236
|
+
message?: string;
|
|
9237
|
+
conditions: RuleConditions;
|
|
9238
|
+
}
|
|
9239
|
+
interface ReadOnlyRule {
|
|
9240
|
+
type: 'readOnly';
|
|
9241
|
+
action: 'enable' | 'disable';
|
|
9242
|
+
conditions: RuleConditions;
|
|
9243
|
+
}
|
|
9244
|
+
type FieldRule = VisibilityRule | RequirementRule | ValidationRule$1 | ReadOnlyRule;
|
|
9245
|
+
type LocalizationConfig = boolean | string[] | {
|
|
9246
|
+
enabled: boolean;
|
|
9247
|
+
requiredLocales?: string[];
|
|
9248
|
+
fallback?: boolean;
|
|
9249
|
+
};
|
|
9250
|
+
interface FieldDefinition$1<TId extends string = string, TType extends string = string, TConfig = unknown> {
|
|
9251
|
+
/** Unique field identifier - preserves literal type for type inference */
|
|
9252
|
+
readonly id: TId;
|
|
9253
|
+
/** Field type */
|
|
9254
|
+
readonly type: TType;
|
|
9255
|
+
/** Type-specific configuration */
|
|
9256
|
+
config?: TConfig;
|
|
9257
|
+
/** UI display configuration */
|
|
9258
|
+
ui?: FieldUIConfig;
|
|
9259
|
+
/** AI configuration: generation/review guidance for this field */
|
|
9260
|
+
ai?: FieldAIConfig;
|
|
9261
|
+
/** Dynamic field rules */
|
|
9262
|
+
rules?: FieldRule[];
|
|
9263
|
+
/** Localization settings */
|
|
9264
|
+
localization?: LocalizationConfig;
|
|
9265
|
+
/** Fallback value when field is empty */
|
|
9266
|
+
fallback?: unknown;
|
|
9267
|
+
/** Whether this field is deprecated */
|
|
9268
|
+
deprecated?: boolean;
|
|
9269
|
+
}
|
|
9270
|
+
/**
|
|
9271
|
+
* Any field definition - used in arrays where we need to preserve specific field types
|
|
9272
|
+
*/
|
|
9273
|
+
type AnyFieldDefinition = FieldDefinition$1<string, string, unknown>;
|
|
9274
|
+
interface ShortTextConfig extends BaseFieldConfig {
|
|
9275
|
+
/** Maximum character length */
|
|
9276
|
+
maxLength?: number;
|
|
9277
|
+
/** Regex pattern for validation */
|
|
9278
|
+
pattern?: string;
|
|
9279
|
+
defaultValue?: string;
|
|
9280
|
+
}
|
|
9281
|
+
interface LongTextConfig extends BaseFieldConfig {
|
|
9282
|
+
minLength?: number;
|
|
9283
|
+
maxLength?: number;
|
|
9284
|
+
defaultValue?: string;
|
|
9285
|
+
}
|
|
9286
|
+
/**
|
|
9287
|
+
* A rich-text field's config. With none of `structure`, `marks` and `multiline` the field has the
|
|
9288
|
+
* whole docs set of built-ins; each narrows it, and the Studio's editor and every write hold the
|
|
9289
|
+
* field to the narrowing (REL-1805). `blocks` and `inline` declare the fieldsets an editor inserts
|
|
9290
|
+
* between paragraphs and inside a sentence (REL-1807) — `TBlock` and `TInline`, which
|
|
9291
|
+
* `fields.richText()` infers so a read types each one by its fieldset — and `links` the content types
|
|
9292
|
+
* its text may link to (REL-1808), `TLinks`, so a read types each entry link's target.
|
|
9293
|
+
*/
|
|
9294
|
+
/** A rich-text field's `links` (REL-1808): the content types its entry links may point at. */
|
|
9295
|
+
interface RichTextLinks<TTo extends string = string> {
|
|
9296
|
+
/** As a reference field's `to` is written: one content type's id, or several */
|
|
9297
|
+
to: TTo | TTo[];
|
|
9298
|
+
}
|
|
9299
|
+
interface RichTextConfig<TBlock extends AnyFieldset = AnyFieldset, TInline extends AnyFieldset = AnyFieldset, TLinks extends string = string> extends BaseFieldConfig {
|
|
9300
|
+
/** Maximum count of the value's text characters, its markup not counted (default 50,000) */
|
|
9301
|
+
maxLength?: number;
|
|
9302
|
+
/**
|
|
9303
|
+
* The built-in blocks the field allows besides paragraphs. Absent allows them all; `[]` allows
|
|
9304
|
+
* paragraphs only.
|
|
9305
|
+
*/
|
|
9306
|
+
structure?: readonly RichTextStructure[];
|
|
9307
|
+
/** The marks the field allows. Absent allows them all; `[]` allows none. */
|
|
9308
|
+
marks?: readonly RichTextMarkType[];
|
|
9309
|
+
/** `false` makes a one-line field: one paragraph, no line break, no other block. Default `true`. */
|
|
9310
|
+
multiline?: boolean;
|
|
9311
|
+
/**
|
|
9312
|
+
* The fieldsets an editor may insert between paragraphs (REL-1807): each is a node of the tree
|
|
9313
|
+
* wherever blocks go, `{ _type, _key, …its fields }` — exactly a page builder's item of the same
|
|
9314
|
+
* fieldset. `<RichText>` needs a component for each. Not in a one-line field.
|
|
9315
|
+
*/
|
|
9316
|
+
blocks?: readonly TBlock[];
|
|
9317
|
+
/**
|
|
9318
|
+
* The fieldsets an editor may insert inside a sentence (REL-1807): each stands beside a
|
|
9319
|
+
* paragraph's text as `{ _type, _key, …its fields }`. `<RichText>` needs a component for each.
|
|
9320
|
+
*/
|
|
9321
|
+
inline?: readonly TInline[];
|
|
9322
|
+
/**
|
|
9323
|
+
* The content types the text may link to (REL-1808): `{ to }`, one type or several, as a
|
|
9324
|
+
* reference names them. Each entry link is a reference — checked on publish, blocking or unwrapped
|
|
9325
|
+
* on its target's delete, expanded when the field is included — with an optional heading anchor.
|
|
9326
|
+
* `<RichText>` needs an `entryLink` component wherever it is set: only your site knows its URLs.
|
|
9327
|
+
* Absent allows no entry link.
|
|
9328
|
+
*/
|
|
9329
|
+
links?: RichTextLinks<TLinks>;
|
|
9330
|
+
/** A version-1 rich-text tree, every node but a text run keyed (REL-1803) */
|
|
9331
|
+
defaultValue?: RichTextValue;
|
|
9332
|
+
}
|
|
9333
|
+
/**
|
|
9334
|
+
* A `table` field's config (REL-1806). Its value is exactly a rich-text table block's
|
|
9335
|
+
* (`RichTextTable`): rows of cells, each cell formatted text, an optional header row and per-cell
|
|
9336
|
+
* alignment — the same value a table inside rich text holds, so one copied from either is accepted
|
|
9337
|
+
* by the other.
|
|
9338
|
+
*/
|
|
9339
|
+
interface TableConfig extends BaseFieldConfig {
|
|
9340
|
+
/** A table, every node but a text run keyed */
|
|
9341
|
+
defaultValue?: RichTextTable;
|
|
9342
|
+
}
|
|
9343
|
+
/**
|
|
9344
|
+
* A `code` field's config (REL-1806). Its value is exactly a rich-text code group's
|
|
9345
|
+
* (`RichTextCodeGroup`): one tab or more, each a code block with its text and an optional label,
|
|
9346
|
+
* language, filename and line range.
|
|
9347
|
+
*/
|
|
9348
|
+
interface CodeConfig extends BaseFieldConfig {
|
|
9349
|
+
/** The languages a tab may be written in; set, every tab names one of them */
|
|
9350
|
+
languages?: readonly string[];
|
|
9351
|
+
/** The most tabs the group may hold */
|
|
9352
|
+
maxTabs?: number;
|
|
9353
|
+
/** A code group, every node keyed, held to `languages` and `maxTabs` */
|
|
9354
|
+
defaultValue?: RichTextCodeGroup;
|
|
9355
|
+
}
|
|
9356
|
+
/**
|
|
9357
|
+
* A slug field's value is lowercase letters, numbers and hyphens, and may have segments separated by
|
|
9358
|
+
* a slash (`guide/schema/text-fields`), each segment a slug on its own. A leading, a trailing and a
|
|
9359
|
+
* doubled slash are refused `SLUG_INVALID_FORMAT`, the message naming which. Unique as a whole.
|
|
9360
|
+
*/
|
|
9361
|
+
interface SlugConfig extends BaseFieldConfig {
|
|
9362
|
+
/** Source field to generate slug from */
|
|
9363
|
+
sourceField?: string;
|
|
9364
|
+
/** Maximum character length */
|
|
9365
|
+
maxLength?: number;
|
|
9366
|
+
defaultValue?: string;
|
|
9367
|
+
}
|
|
9368
|
+
/**
|
|
9369
|
+
* A url field's value is an absolute URL (`https://relyio.com/docs`) or a site-relative path
|
|
9370
|
+
* (`/sign-up`) — every url field takes both. A bare word, a path with no leading slash and a
|
|
9371
|
+
* protocol-relative `//host` are refused `URL_INVALID`.
|
|
9372
|
+
*/
|
|
9373
|
+
interface UrlConfig extends BaseFieldConfig {
|
|
9374
|
+
/** The protocols an absolute URL may use; a site-relative path is accepted whatever they are. */
|
|
9375
|
+
allowedProtocols?: ('http' | 'https' | 'ftp' | 'ftps')[];
|
|
9376
|
+
/** Maximum character length */
|
|
9377
|
+
maxLength?: number;
|
|
9378
|
+
defaultValue?: string;
|
|
9379
|
+
}
|
|
9380
|
+
interface EmailConfig extends BaseFieldConfig {
|
|
9381
|
+
/** Maximum character length */
|
|
9382
|
+
maxLength?: number;
|
|
9383
|
+
/** Whitelist of allowed email domains */
|
|
9384
|
+
domainWhitelist?: string[];
|
|
9385
|
+
defaultValue?: string;
|
|
9386
|
+
}
|
|
9387
|
+
interface IntegerConfig extends BaseFieldConfig {
|
|
9388
|
+
min?: number;
|
|
9389
|
+
max?: number;
|
|
9390
|
+
defaultValue?: number;
|
|
9391
|
+
}
|
|
9392
|
+
interface DecimalConfig extends BaseFieldConfig {
|
|
9393
|
+
min?: number;
|
|
9394
|
+
max?: number;
|
|
9395
|
+
decimalPlaces?: number;
|
|
9396
|
+
roundingMode?: 'HALF_UP' | 'FLOOR' | 'CEILING' | 'ROUND' | 'TRUNCATE';
|
|
9397
|
+
defaultValue?: number;
|
|
9398
|
+
}
|
|
9399
|
+
interface BooleanConfig extends BaseFieldConfig {
|
|
9400
|
+
/** The editor's word for `true` (e.g. `'Published'`). */
|
|
9401
|
+
labelTrue?: string;
|
|
9402
|
+
/** The editor's word for `false` (e.g. `'Draft'`). */
|
|
9403
|
+
labelFalse?: string;
|
|
9404
|
+
defaultValue?: boolean;
|
|
9405
|
+
}
|
|
9406
|
+
/**
|
|
9407
|
+
* `TValue` is the union of the option values and `TMulti` whether the field holds a list of them.
|
|
9408
|
+
* `fields.enum()` infers both from the declaration, so a read of the field is typed by its options
|
|
9409
|
+
* (`INV-SS-TYPES-INFERRED`); the defaults describe any enum field.
|
|
9410
|
+
*/
|
|
9411
|
+
interface EnumConfig<TValue extends string = string, TMulti extends boolean = boolean> extends BaseFieldConfig {
|
|
9412
|
+
/** The values the field may hold, each with the `label` an editor shows. Deploy refuses an option without one. */
|
|
9413
|
+
options: Array<{
|
|
9414
|
+
value: TValue;
|
|
9415
|
+
label: string;
|
|
9416
|
+
}>;
|
|
9417
|
+
multi?: TMulti;
|
|
9418
|
+
/** One option's value, or a list of them when `multi` is true. */
|
|
9419
|
+
defaultValue?: string | string[];
|
|
9420
|
+
}
|
|
9421
|
+
/** A display format is not config: it is `ui.options.format`, where the schema declares it. */
|
|
9422
|
+
interface DateConfig extends BaseFieldConfig {
|
|
9423
|
+
minDate?: string;
|
|
9424
|
+
maxDate?: string;
|
|
9425
|
+
/** `YYYY-MM-DD` */
|
|
9426
|
+
defaultValue?: string;
|
|
9427
|
+
}
|
|
9428
|
+
/** A display format is not config: it is `ui.options.format`, where the schema declares it. */
|
|
9429
|
+
interface DateTimeConfig extends BaseFieldConfig {
|
|
9430
|
+
minDateTime?: string;
|
|
9431
|
+
maxDateTime?: string;
|
|
9432
|
+
/**
|
|
9433
|
+
* Show the instant in UTC (`'UTC'`) or in the author's local time (`'local'`) in the editor. The
|
|
9434
|
+
* instant is stored in UTC either way.
|
|
9435
|
+
*/
|
|
9436
|
+
timeZoneHandling?: 'UTC' | 'local';
|
|
9437
|
+
defaultValue?: string;
|
|
9438
|
+
}
|
|
9439
|
+
/**
|
|
9440
|
+
* `TTo` is the union of the target type ids and `TMulti` whether the field holds a list.
|
|
9441
|
+
* `fields.reference()` infers both, so a read of the field is typed by what it points at
|
|
9442
|
+
* (`INV-SS-TYPES-INFERRED`); the defaults describe any reference field.
|
|
9443
|
+
*/
|
|
9444
|
+
interface ReferenceConfig<TTo extends string = string, TMulti extends boolean = boolean> extends BaseFieldConfig {
|
|
9445
|
+
/**
|
|
9446
|
+
* Target entry type id(s) — content type or asset type ids. Pass a single id
|
|
9447
|
+
* for one target or an array for several. All ids must belong to the same
|
|
9448
|
+
* family (all content types or all asset types).
|
|
9449
|
+
*/
|
|
9450
|
+
to: TTo | TTo[];
|
|
9451
|
+
/** Allow multiple references (the field value is a list). */
|
|
9452
|
+
multi?: TMulti;
|
|
9453
|
+
/**
|
|
9454
|
+
* The fewest and the most entries a multi reference holds, as a list's: your limit, enforced on
|
|
9455
|
+
* every write and publish (`LIST_TOO_FEW_ITEMS`, `LIST_TOO_MANY_ITEMS`). A single reference
|
|
9456
|
+
* takes neither.
|
|
9457
|
+
*/
|
|
9458
|
+
minItems?: number;
|
|
9459
|
+
maxItems?: number;
|
|
9460
|
+
/** Reference strength for publish/unpublish behavior. */
|
|
9461
|
+
referenceStrength?: 'strong' | 'weak';
|
|
9462
|
+
/** Behavior when a referenced entry is deleted. */
|
|
9463
|
+
onTargetDelete?: 'block' | 'nullify';
|
|
9464
|
+
/** A target entry's id, or a list of them when `multi` is true. */
|
|
9465
|
+
defaultValue?: string | string[];
|
|
9466
|
+
}
|
|
9467
|
+
interface TagsConfig extends BaseFieldConfig {
|
|
9468
|
+
allowCustom?: boolean;
|
|
9469
|
+
predefinedTags?: string[];
|
|
9470
|
+
maxTags?: number;
|
|
9471
|
+
}
|
|
9472
|
+
/**
|
|
9473
|
+
* `TShape` is the fieldset each item takes — or the union of the several a page builder's items
|
|
9474
|
+
* may take — which `fields.list()` infers so a read types each item by it (`INV-SS-TYPES-INFERRED`);
|
|
9475
|
+
* the default describes any list field. A list without one holds strings.
|
|
9476
|
+
*/
|
|
9477
|
+
interface ListConfig<TShape extends AnyFieldset = AnyFieldset> extends BaseFieldConfig {
|
|
9478
|
+
dragAndDrop?: boolean;
|
|
9479
|
+
minItems?: number;
|
|
9480
|
+
maxItems?: number;
|
|
9481
|
+
/**
|
|
9482
|
+
* The fieldset each item takes (REL-1796): every item holds its fields — a section's read flat —
|
|
9483
|
+
* plus `_type`, the fieldset's id, and `_key`, the item key that stays with it for life. Or
|
|
9484
|
+
* several, a page builder (REL-1798): `of: [hero, featureGrid, ctaBanner]`, each item naming in
|
|
9485
|
+
* `_type` the one it takes, in whatever order an editor puts them.
|
|
9486
|
+
*/
|
|
9487
|
+
of?: TShape | readonly TShape[];
|
|
9488
|
+
}
|
|
9489
|
+
/**
|
|
9490
|
+
* `TShape` is the fieldset an object's one value takes — or the union of the several it may take —
|
|
9491
|
+
* which `fields.object()` infers so a read types the value by it (`INV-SS-TYPES-INFERRED`). Unlike a
|
|
9492
|
+
* list's, `of` is required: an object without a shape holds nothing it could declare.
|
|
9493
|
+
*/
|
|
9494
|
+
interface ObjectConfig<TShape extends AnyFieldset = AnyFieldset> extends BaseFieldConfig {
|
|
9495
|
+
/**
|
|
9496
|
+
* The fieldset the value takes (REL-1799, ADR 0012): it holds that fieldset's fields — a section's
|
|
9497
|
+
* read flat — plus `_type`, the fieldset's id, and `_key`, its key. Or several: `of: [screenshot,
|
|
9498
|
+
* video]`, the value naming in `_type` the one it takes. `_type` names the fieldset even where
|
|
9499
|
+
* only one is allowed, so a second shape later changes no stored value.
|
|
9500
|
+
*/
|
|
9501
|
+
of: TShape | readonly TShape[];
|
|
9502
|
+
}
|
|
9503
|
+
/**
|
|
9504
|
+
* A `json` field's config (REL-1811): any JSON value, held to `schema` when it is given — on every
|
|
9505
|
+
* write, a draft included, since a value its schema refuses is never stored. `TSchema` is the schema
|
|
9506
|
+
* literal, which `fields.json()` keeps so a read is typed by it (`InferJsonSchema`); write it
|
|
9507
|
+
* `as const` to keep `required`, `enum` and `const` exact. A json field takes no `defaultValue`.
|
|
9508
|
+
*/
|
|
9509
|
+
interface JsonConfig<TSchema extends JsonSchema = JsonSchema> {
|
|
9510
|
+
/** Whether the field is required: required from creation, since no value is every schema's */
|
|
9511
|
+
required?: boolean;
|
|
9512
|
+
/** Whether the field value must be unique */
|
|
9513
|
+
unique?: boolean;
|
|
9514
|
+
/**
|
|
9515
|
+
* The JSON Schema every value is held to: `type`, `properties`, `required`,
|
|
9516
|
+
* `additionalProperties`, `items`, `enum`, `const`, `anyOf` and `oneOf` say what a value is;
|
|
9517
|
+
* `minLength`, `maxLength`, `pattern`, `format`, `minimum`, `maximum`, `exclusiveMinimum`,
|
|
9518
|
+
* `exclusiveMaximum`, `multipleOf`, `minItems`, `maxItems`, `uniqueItems`, `minProperties` and
|
|
9519
|
+
* `maxProperties` narrow it; `title`, `description`, `default` and `examples` annotate it. Any
|
|
9520
|
+
* other keyword — `$ref`, `$id`, `allOf`, `not` — is refused at deploy by name.
|
|
9521
|
+
*/
|
|
9522
|
+
schema?: TSchema;
|
|
9523
|
+
}
|
|
9524
|
+
/**
|
|
9525
|
+
* Every field kind: the one union, `FieldKind` in `@relyio/schema`'s field-kind declaration
|
|
9526
|
+
* (REL-1783). A kind the declaration gains is a kind here, and every table this package keys by it
|
|
9527
|
+
* stops compiling until it has a row: the read types (`OverEveryFieldKind` in `infer-fields.ts`) and
|
|
9528
|
+
* the builders (`fields` in `schema/index.ts`).
|
|
9529
|
+
*/
|
|
9530
|
+
type FieldType = FieldKind;
|
|
9531
|
+
|
|
9532
|
+
/**
|
|
9533
|
+
* Field builders for defining schema fields
|
|
9534
|
+
* Matches the @relyio/schema FieldSchema structure
|
|
9535
|
+
*
|
|
9536
|
+
* All builders are generic over the ID to preserve literal types for type inference. `enum`,
|
|
9537
|
+
* `reference` and `list` are generic over the parts of their config a read's type depends on too —
|
|
9538
|
+
* the option values, the targets, `multi` and the list's shape — each through a type parameter with a
|
|
9539
|
+
* primitive or field constraint, which is what keeps a literal from widening without a `const`
|
|
9540
|
+
* type parameter (the package supports TypeScript 4.9, which has none).
|
|
9541
|
+
*/
|
|
9542
|
+
|
|
9543
|
+
interface FieldOptions$1<TConfig, TLocalization extends LocalizationConfig = LocalizationConfig> {
|
|
9544
|
+
/** Type-specific configuration */
|
|
9545
|
+
config?: TConfig;
|
|
9546
|
+
/** UI display configuration */
|
|
9547
|
+
ui?: FieldUIConfig;
|
|
9548
|
+
/** AI configuration: generation/review guidance (`instructions`) for this field. */
|
|
9549
|
+
ai?: FieldAIConfig;
|
|
9550
|
+
/** Dynamic field rules */
|
|
9551
|
+
rules?: FieldRule[];
|
|
9552
|
+
/** Localization settings */
|
|
9553
|
+
localization?: TLocalization;
|
|
9554
|
+
/** Fallback value */
|
|
9555
|
+
fallback?: unknown;
|
|
9556
|
+
/** Whether this field is deprecated */
|
|
9557
|
+
deprecated?: boolean;
|
|
9558
|
+
}
|
|
9559
|
+
/**
|
|
9560
|
+
* `required`, kept as the literal it was written as, so a read's type knows which fields are always
|
|
9561
|
+
* present (`schema/infer-fields.ts`, REL-1795) — through a type parameter with a primitive
|
|
9562
|
+
* constraint, as `multi` is, so `true` does not widen to `boolean`.
|
|
9563
|
+
*/
|
|
9564
|
+
type RequiredAs<TRequired extends boolean> = {
|
|
9565
|
+
required?: TRequired;
|
|
9566
|
+
};
|
|
9567
|
+
/** The key a field definition's type keeps its `localization` literal under. Types only. */
|
|
9568
|
+
declare const localizedAs: unique symbol;
|
|
9569
|
+
/**
|
|
9570
|
+
* `localization`, kept as the literal it was written as — `true`, `{ enabled: true }` — by the
|
|
9571
|
+
* builders of the kinds whose translation decides what a filter may name (REL-2136): a reference and
|
|
9572
|
+
* rich text, and the list or object they sit in. A reference or rich text a shared list translates
|
|
9573
|
+
* item by item has no stored path a filter names, so a typed `where` refuses it
|
|
9574
|
+
* (`schema/include-paths.ts`'s `FilterPaths`). `never` where none is written.
|
|
9575
|
+
*
|
|
9576
|
+
* Kept under a key of its own, which holds nothing at runtime: kept under `localization`, a field
|
|
9577
|
+
* inside a `fieldset()` or a type's `fields` widened `true` to `boolean`, inferred from the
|
|
9578
|
+
* `localization` every field definition declares (measured, REL-2136), as `required` is not, which
|
|
9579
|
+
* sits in a `config` the surrounding list does not type.
|
|
9580
|
+
*/
|
|
9581
|
+
interface LocalizedAs<TLocalization extends LocalizationConfig> {
|
|
9582
|
+
readonly [localizedAs]?: TLocalization;
|
|
9583
|
+
}
|
|
9584
|
+
/** The `localization` a field definition's type kept ({@link LocalizedAs}); `never` where none. */
|
|
9585
|
+
type LocalizationOf<F> = F extends LocalizedAs<infer L> ? L : never;
|
|
9586
|
+
/**
|
|
9587
|
+
* Short text field (single line)
|
|
9588
|
+
* @example fields.shortText('title', { config: { required: true, maxLength: 200 } })
|
|
9589
|
+
*/
|
|
9590
|
+
declare function shortText<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<ShortTextConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'shortText', ShortTextConfig & RequiredAs<TRequired>>;
|
|
9591
|
+
/**
|
|
9592
|
+
* Long text field (multi-line textarea)
|
|
9593
|
+
* @example fields.longText('description', { config: { maxLength: 5000 } })
|
|
9594
|
+
*/
|
|
9595
|
+
declare function longText<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<LongTextConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'longText', LongTextConfig & RequiredAs<TRequired>>;
|
|
9596
|
+
/**
|
|
9597
|
+
* Rich text: the docs set of built-ins, narrowed by `structure`, `marks` and `multiline`, the
|
|
9598
|
+
* fieldsets an editor inserts between paragraphs (`blocks`) and inside a sentence (`inline`), and the
|
|
9599
|
+
* content types its entry links point at (`links`)
|
|
9600
|
+
* @example fields.richText('content', { config: { structure: ['heading', 'bulletList'], marks: ['bold', 'italic', 'link'] } })
|
|
9601
|
+
* @example fields.richText('body', { config: { blocks: [{ id: 'callout', displayName: 'Callout', fields: [fields.shortText('title')] }] } })
|
|
9602
|
+
* @example fields.richText('body', { config: { links: { to: 'docPage' } } })
|
|
9603
|
+
*/
|
|
9604
|
+
declare function richText<TId extends string, TBlock extends AnyFieldset = never, TInline extends AnyFieldset = never, TLinks extends string = never, TRequired extends boolean = false, TLocalization extends LocalizationConfig = never>(id: TId, options?: FieldOptions$1<RichTextConfig<TBlock, TInline, TLinks> & RequiredAs<TRequired>, TLocalization>): FieldDefinition$1<TId, 'richText', RichTextConfig<TBlock, TInline, TLinks> & RequiredAs<TRequired>> & LocalizedAs<TLocalization>;
|
|
9605
|
+
/**
|
|
9606
|
+
* A table: exactly a rich-text table block's value — rows of formatted cells, an optional header row
|
|
9607
|
+
* and per-cell alignment — so a comparison table on a page and a table in a doc are one thing
|
|
9608
|
+
* (REL-1806). Read as `RichTextTable`; `<RichText>` and `richTextToHtml` render it.
|
|
9609
|
+
* @example fields.table('comparison', { config: { required: true } })
|
|
9610
|
+
*/
|
|
9611
|
+
declare function table<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<TableConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'table', TableConfig & RequiredAs<TRequired>>;
|
|
9612
|
+
/**
|
|
9613
|
+
* Code with tabs: exactly a rich-text code group's value — one tab or more, each with its label,
|
|
9614
|
+
* language, filename and line range (REL-1806). Read as `RichTextCodeGroup`; `<RichText>` and
|
|
9615
|
+
* `richTextToHtml` render it.
|
|
9616
|
+
* @example fields.code('snippet', { config: { languages: ['typescript', 'bash'], maxTabs: 4 } })
|
|
9617
|
+
*/
|
|
9618
|
+
declare function code<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<CodeConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'code', CodeConfig & RequiredAs<TRequired>>;
|
|
9619
|
+
/**
|
|
9620
|
+
* Slug field (URL-friendly identifier)
|
|
9621
|
+
* @example fields.slug('slug', { config: { sourceField: 'title' } })
|
|
9622
|
+
*/
|
|
9623
|
+
declare function slug<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<SlugConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'slug', SlugConfig & RequiredAs<TRequired>>;
|
|
9624
|
+
/**
|
|
9625
|
+
* URL field with validation
|
|
9626
|
+
* @example fields.url('website', { config: { allowedProtocols: ['https'] } })
|
|
9627
|
+
*/
|
|
9628
|
+
declare function url<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<UrlConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'url', UrlConfig & RequiredAs<TRequired>>;
|
|
9629
|
+
/**
|
|
9630
|
+
* Email field with validation
|
|
9631
|
+
* @example fields.email('contactEmail', { config: { required: true } })
|
|
9632
|
+
*/
|
|
9633
|
+
declare function email<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<EmailConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'email', EmailConfig & RequiredAs<TRequired>>;
|
|
9634
|
+
/**
|
|
9635
|
+
* Integer field
|
|
9636
|
+
* @example fields.integer('quantity', { config: { min: 0, max: 100 } })
|
|
9637
|
+
*/
|
|
9638
|
+
declare function integer<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<IntegerConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'integer', IntegerConfig & RequiredAs<TRequired>>;
|
|
9639
|
+
/**
|
|
9640
|
+
* Decimal field with precision
|
|
9641
|
+
* @example fields.decimal('weight', { config: { decimalPlaces: 2, min: 0 } })
|
|
9642
|
+
*/
|
|
9643
|
+
declare function decimal<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<DecimalConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'decimal', DecimalConfig & RequiredAs<TRequired>>;
|
|
9644
|
+
/**
|
|
9645
|
+
* Boolean field (true/false toggle)
|
|
9646
|
+
* @example fields.boolean('isActive', { config: { defaultValue: false } })
|
|
9647
|
+
*/
|
|
9648
|
+
declare function boolean<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<BooleanConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'boolean', BooleanConfig & RequiredAs<TRequired>>;
|
|
9649
|
+
/**
|
|
9650
|
+
* Enum field with predefined options
|
|
9651
|
+
* @example fields.enum('status', {
|
|
9652
|
+
* config: {
|
|
9653
|
+
* options: [
|
|
9654
|
+
* { value: 'draft', label: 'Draft' },
|
|
9655
|
+
* { value: 'published', label: 'Published' },
|
|
9656
|
+
* ]
|
|
9657
|
+
* }
|
|
9658
|
+
* })
|
|
9659
|
+
*/
|
|
9660
|
+
declare function enumField<TId extends string, TValue extends string = string, TMulti extends boolean = false, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<EnumConfig<TValue, TMulti> & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'enum', EnumConfig<TValue, TMulti> & RequiredAs<TRequired>>;
|
|
9661
|
+
/**
|
|
9662
|
+
* Date field (no time)
|
|
9663
|
+
* @example fields.date('publishDate', { config: { minDate: '2024-01-01' } })
|
|
9664
|
+
*/
|
|
9665
|
+
declare function date<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<DateConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'date', DateConfig & RequiredAs<TRequired>>;
|
|
9666
|
+
/**
|
|
9667
|
+
* DateTime field: an instant, stored and read back in UTC whatever offset it is written in.
|
|
9668
|
+
* `timeZoneHandling` says whether the editor shows it in UTC or in the author's local time.
|
|
9669
|
+
* @example fields.dateTime('createdAt', { config: { timeZoneHandling: 'UTC' } })
|
|
9670
|
+
*/
|
|
9671
|
+
declare function dateTime<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<DateTimeConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'dateTime', DateTimeConfig & RequiredAs<TRequired>>;
|
|
9672
|
+
/**
|
|
9673
|
+
* Reference to other entries (content types or asset types)
|
|
9674
|
+
* @example fields.reference('category', { config: { to: 'category' } })
|
|
9675
|
+
* @example fields.reference('relatedItems', { config: { to: ['product', 'service'], multi: true } })
|
|
9676
|
+
* @example fields.reference('heroImage', { config: { to: 'productPhoto' } })
|
|
9677
|
+
*/
|
|
9678
|
+
declare function reference<TId extends string, TTo extends string = string, TMulti extends boolean = false, TRequired extends boolean = false, TLocalization extends LocalizationConfig = never>(id: TId, options?: FieldOptions$1<ReferenceConfig<TTo, TMulti> & RequiredAs<TRequired>, TLocalization>): FieldDefinition$1<TId, 'reference', ReferenceConfig<TTo, TMulti> & RequiredAs<TRequired>> & LocalizedAs<TLocalization>;
|
|
9679
|
+
/**
|
|
9680
|
+
* Tags field (array of strings with autocomplete)
|
|
9681
|
+
* @example fields.tags('keywords', { config: { predefinedTags: ['featured', 'sale'], maxTags: 10 } })
|
|
9682
|
+
*/
|
|
9683
|
+
declare function tags<TId extends string, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<TagsConfig & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'tags', TagsConfig & RequiredAs<TRequired>>;
|
|
9684
|
+
/**
|
|
9685
|
+
* List field: a repeatable group of one shape. Each item holds the fields of the fieldset `of`
|
|
9686
|
+
* names — usually a `fieldset()` value, declared once and passed wherever it is wanted — plus
|
|
9687
|
+
* `_type` (that fieldset's id) and `_key` (its item key). Without `of`, a list of strings.
|
|
9688
|
+
* @example fields.list('specifications', {
|
|
9689
|
+
* config: {
|
|
9690
|
+
* minItems: 1,
|
|
9691
|
+
* maxItems: 20,
|
|
9692
|
+
* of: {
|
|
9693
|
+
* id: 'spec',
|
|
9694
|
+
* displayName: 'Specification',
|
|
9695
|
+
* fields: [
|
|
9696
|
+
* fields.shortText('name', { config: { required: true } }),
|
|
9697
|
+
* fields.shortText('value', { config: { required: true } }),
|
|
9698
|
+
* ],
|
|
9699
|
+
* },
|
|
9700
|
+
* },
|
|
9701
|
+
* })
|
|
9702
|
+
*/
|
|
9703
|
+
declare function list<TId extends string, TShape extends AnyFieldset = never, TRequired extends boolean = false, TLocalization extends LocalizationConfig = never>(id: TId, options?: FieldOptions$1<ListConfig<TShape> & RequiredAs<TRequired>, TLocalization>): FieldDefinition$1<TId, 'list', ListConfig<TShape> & RequiredAs<TRequired>> & LocalizedAs<TLocalization>;
|
|
9704
|
+
/**
|
|
9705
|
+
* Object field: one value of a shape. It holds the fields of the fieldset `of` names — usually a
|
|
9706
|
+
* `fieldset()` value, declared once and passed wherever it is wanted — plus `_type` (that
|
|
9707
|
+
* fieldset's id) and `_key`. Or of one of several shapes, `_type` saying which (REL-1799).
|
|
9708
|
+
* @example fields.object('seo', {
|
|
9709
|
+
* config: {
|
|
9710
|
+
* of: { id: 'seo', displayName: 'SEO', fields: [fields.shortText('metaTitle')] },
|
|
9711
|
+
* },
|
|
9712
|
+
* })
|
|
9713
|
+
* @example fields.object('media', {
|
|
9714
|
+
* config: {
|
|
9715
|
+
* required: true,
|
|
9716
|
+
* of: [
|
|
9717
|
+
* { id: 'screenshot', displayName: 'Screenshot', fields: [fields.reference('image', { config: { to: 'image' } })] },
|
|
9718
|
+
* { id: 'video', displayName: 'Video', fields: [fields.url('src', { config: { required: true } })] },
|
|
9719
|
+
* ],
|
|
9720
|
+
* },
|
|
9721
|
+
* })
|
|
9722
|
+
*/
|
|
9723
|
+
declare function object<TId extends string, TShape extends AnyFieldset, TRequired extends boolean = false, TLocalization extends LocalizationConfig = never>(id: TId, options: Omit<FieldOptions$1<ObjectConfig<TShape> & RequiredAs<TRequired>, TLocalization>, 'config'> & {
|
|
9724
|
+
config: ObjectConfig<TShape> & RequiredAs<TRequired>;
|
|
9725
|
+
}): FieldDefinition$1<TId, 'object', ObjectConfig<TShape> & RequiredAs<TRequired>> & LocalizedAs<TLocalization>;
|
|
9726
|
+
/**
|
|
9727
|
+
* JSON field: data nobody models, any JSON value — held to `schema`, a JSON Schema, when it is given
|
|
9728
|
+
* (REL-1811). A read is typed by the schema (`InferJsonSchema`), and is `JsonValue` without one.
|
|
9729
|
+
* Write the schema `as const` so `required`, `enum` and `const` keep their literals. Its source is
|
|
9730
|
+
* edited in the Studio as text, and saved when it parses to a value the schema admits.
|
|
9731
|
+
* @example fields.json('chart', {
|
|
9732
|
+
* config: {
|
|
9733
|
+
* schema: {
|
|
9734
|
+
* type: 'object',
|
|
9735
|
+
* properties: { points: { type: 'array', items: { type: 'number' } } },
|
|
9736
|
+
* required: ['points'],
|
|
9737
|
+
* } as const,
|
|
9738
|
+
* },
|
|
9739
|
+
* })
|
|
9740
|
+
*/
|
|
9741
|
+
declare function json<TId extends string, TSchema extends JsonSchema = never, TRequired extends boolean = false>(id: TId, options?: FieldOptions$1<JsonConfig<TSchema> & RequiredAs<TRequired>>): FieldDefinition$1<TId, 'json', JsonConfig<TSchema> & RequiredAs<TRequired>>;
|
|
9742
|
+
|
|
9743
|
+
/**
|
|
9744
|
+
* Settings group definition matching @relyio/schema SettingsGroupSchema
|
|
9745
|
+
*
|
|
9746
|
+
* Settings groups are for project-level configuration that doesn't fit
|
|
9747
|
+
* into content types (e.g., API keys, feature flags, integrations).
|
|
9748
|
+
*
|
|
9749
|
+
* Uses advanced TypeScript generics to preserve literal field IDs through
|
|
9750
|
+
* the type system, enabling full autocomplete in SDK methods.
|
|
9751
|
+
*/
|
|
9752
|
+
|
|
9753
|
+
/**
|
|
9754
|
+
* Settings group configuration - generic to preserve field types
|
|
9755
|
+
*/
|
|
9756
|
+
interface SettingsGroupConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
9757
|
+
/** Display name shown in the UI */
|
|
9758
|
+
displayName: string;
|
|
9759
|
+
/** Description of the settings group */
|
|
9760
|
+
description?: string;
|
|
9761
|
+
/** AI configuration for content generation and review */
|
|
9762
|
+
ai?: AIConfig;
|
|
9763
|
+
/** Access tags for role-based access control */
|
|
9764
|
+
accessTags?: string[];
|
|
9765
|
+
/** Settings fields - preserves literal types */
|
|
9766
|
+
fields: TFields;
|
|
9767
|
+
}
|
|
9768
|
+
/**
|
|
9769
|
+
* Settings group definition - preserves field types for inference
|
|
9770
|
+
*/
|
|
9771
|
+
interface SettingsGroupDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
9772
|
+
readonly _tag: 'settingsGroup';
|
|
9773
|
+
readonly name: string;
|
|
9774
|
+
readonly displayName: string;
|
|
9775
|
+
readonly description?: string;
|
|
9776
|
+
/** AI configuration for content generation and review */
|
|
9777
|
+
readonly ai?: AIConfig;
|
|
9778
|
+
readonly accessTags?: string[];
|
|
9779
|
+
readonly fields: TFields;
|
|
9780
|
+
}
|
|
9781
|
+
/**
|
|
9782
|
+
* Define a settings group
|
|
9783
|
+
*
|
|
9784
|
+
* The generic type parameter preserves the literal field IDs through the type
|
|
9785
|
+
* system, enabling autocomplete in SDK methods.
|
|
9786
|
+
*
|
|
9787
|
+
* @example
|
|
9788
|
+
* const integrations = defineSettingsGroup('integrations', {
|
|
9789
|
+
* displayName: 'Integrations',
|
|
9790
|
+
* description: 'Third-party service integrations',
|
|
9791
|
+
* fields: [
|
|
9792
|
+
* fields.shortText('stripeApiKey', {
|
|
9793
|
+
* config: { required: true },
|
|
9794
|
+
* ui: { displayName: 'Stripe API Key' }
|
|
9795
|
+
* }),
|
|
9796
|
+
* fields.shortText('sendgridApiKey', {
|
|
9797
|
+
* ui: { displayName: 'SendGrid API Key' }
|
|
9798
|
+
* }),
|
|
9799
|
+
* fields.boolean('enableAnalytics', {
|
|
9800
|
+
* config: { defaultValue: true },
|
|
9801
|
+
* ui: { displayName: 'Enable Analytics' }
|
|
9802
|
+
* }),
|
|
9803
|
+
* ]
|
|
9804
|
+
* })
|
|
9805
|
+
*/
|
|
9806
|
+
declare function defineSettingsGroup<TFields extends readonly AnyFieldDefinition[]>(name: string, config: SettingsGroupConfig<TFields>): SettingsGroupDefinition<TFields>;
|
|
9807
|
+
/**
|
|
9808
|
+
* Type alias for any settings group definition.
|
|
9809
|
+
*/
|
|
9810
|
+
type AnySettingsGroupDefinition = SettingsGroupDefinition<any>;
|
|
9811
|
+
/**
|
|
9812
|
+
* What a read reports about a settings group beside its fields: the committed document's
|
|
9813
|
+
* `SettingsGroupMetadata`, read through `http/api-schema.ts` rather than declared again here.
|
|
9814
|
+
*
|
|
9815
|
+
* It names the group by `id` and `groupId`, carries the per-locale facts and the version history
|
|
9816
|
+
* of `locale`, and says when the group was last written — there is no `createdAt`. The hand-written
|
|
9817
|
+
* type this replaces declared a `key`, a `groupType` and a `createdAt` the wire does not carry, and
|
|
9818
|
+
* `Date` timestamps where it sends ISO 8601 strings.
|
|
9819
|
+
*/
|
|
9820
|
+
type SettingsGroupMetadata = components['schemas']['SettingsGroupMetadata'];
|
|
9821
|
+
/**
|
|
9822
|
+
* Infer the TypeScript type from a settings group definition: every field typed as a read returns it
|
|
9823
|
+
* (`schema/infer-fields.ts`), plus `_metadata`. `S` is the schema, as for `InferContentType`. Every
|
|
9824
|
+
* field is optional, required or not: a group reads as its declared and synthesized defaults until
|
|
9825
|
+
* it is written, and a required field with neither is absent (`Presence`).
|
|
9826
|
+
*/
|
|
9827
|
+
type InferSettingsGroup<T extends AnySettingsGroupDefinition, S extends FieldSchemaContext | undefined = undefined, I extends string = never> = FieldValues<DeclaredFields<T>, S, 'none', I> & {
|
|
9828
|
+
_metadata: SettingsGroupMetadata;
|
|
9829
|
+
};
|
|
9830
|
+
|
|
9831
|
+
/**
|
|
9832
|
+
* Base error class for all RelyIO SDK errors
|
|
9833
|
+
* Provides consistent error handling, context tracking, and retry logic
|
|
9834
|
+
*/
|
|
9835
|
+
declare abstract class SDKError extends Error {
|
|
9836
|
+
/** Unique error code for programmatic error handling */
|
|
9837
|
+
abstract readonly code: string;
|
|
9838
|
+
/** Whether this error is retryable */
|
|
9839
|
+
abstract readonly retryable: boolean;
|
|
9840
|
+
/** HTTP status code if applicable */
|
|
9841
|
+
readonly statusCode?: number;
|
|
9842
|
+
/** Original error that caused this error */
|
|
9843
|
+
readonly cause?: Error;
|
|
9844
|
+
/** Additional context about the error */
|
|
9845
|
+
readonly context?: Record<string, unknown>;
|
|
9846
|
+
/** Timestamp when the error occurred */
|
|
9847
|
+
readonly timestamp: number;
|
|
9848
|
+
constructor(message: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
9849
|
+
/**
|
|
9850
|
+
* Convert error to JSON for logging and debugging
|
|
9851
|
+
*/
|
|
9852
|
+
toJSON(): {
|
|
9853
|
+
name: string;
|
|
9854
|
+
message: string;
|
|
9855
|
+
code: string;
|
|
9856
|
+
statusCode: number | undefined;
|
|
9857
|
+
retryable: boolean;
|
|
9858
|
+
context: Record<string, unknown> | undefined;
|
|
9859
|
+
timestamp: number;
|
|
9860
|
+
stack: string | undefined;
|
|
9861
|
+
};
|
|
9862
|
+
/**
|
|
9863
|
+
* Get a user-friendly error message
|
|
9864
|
+
*/
|
|
9865
|
+
getUserMessage(): string;
|
|
9866
|
+
/**
|
|
9867
|
+
* Get detailed error information for debugging
|
|
9868
|
+
*/
|
|
9869
|
+
getDebugInfo(): string;
|
|
9870
|
+
/**
|
|
9871
|
+
* Check if this error is of a specific type
|
|
9872
|
+
*/
|
|
9873
|
+
isType(errorType: string): boolean;
|
|
9874
|
+
/**
|
|
9875
|
+
* Create a new error with additional context
|
|
9876
|
+
*/
|
|
9877
|
+
withContext(context: Record<string, unknown>): this;
|
|
9878
|
+
}
|
|
9879
|
+
|
|
9880
|
+
/**
|
|
9881
|
+
* Validation errors and related interfaces.
|
|
9882
|
+
*
|
|
9883
|
+
* `SchemaValidationError`, `RequiredFieldError` and `InvalidFieldTypeError` were deleted by
|
|
9884
|
+
* REL-1471: nothing constructed them. The API refuses content the schema does not accept with one
|
|
9885
|
+
* code, `CONTENT_INVALID`, whose `details.issues` name each field and its problem — the mapper
|
|
9886
|
+
* throws `ValidationError` for it, and a missing required field or a value of the wrong type is a
|
|
9887
|
+
* `violations` entry whose `code` says which.
|
|
9888
|
+
*/
|
|
9889
|
+
interface ValidationViolation {
|
|
9890
|
+
field: string;
|
|
9891
|
+
message: string;
|
|
9892
|
+
code: string;
|
|
9893
|
+
value?: unknown;
|
|
9894
|
+
path?: string[];
|
|
9895
|
+
}
|
|
9896
|
+
declare abstract class BaseValidationError extends SDKError {
|
|
9897
|
+
readonly retryable = false;
|
|
9898
|
+
readonly violations: ValidationViolation[];
|
|
9899
|
+
/**
|
|
9900
|
+
* @param context - Carried beside `violations`. The mapper passes the refusal body as
|
|
9901
|
+
* `context.response`, as it does for every other contract code, so a consumer that hands the
|
|
9902
|
+
* service's own words on can read them here too.
|
|
9903
|
+
*/
|
|
9904
|
+
constructor(message?: string, violations?: ValidationViolation[], statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
9905
|
+
getUserMessage(): string;
|
|
9906
|
+
/**
|
|
9907
|
+
* Get violations for a specific field
|
|
9908
|
+
*/
|
|
9909
|
+
getViolationsForField(fieldName: string): ValidationViolation[];
|
|
9910
|
+
/**
|
|
9911
|
+
* Check if a specific field has validation errors
|
|
9912
|
+
*/
|
|
9913
|
+
hasFieldError(fieldName: string): boolean;
|
|
9914
|
+
/**
|
|
9915
|
+
* Get all validation messages as a formatted string
|
|
9916
|
+
*/
|
|
9917
|
+
getFormattedMessages(): string;
|
|
9918
|
+
}
|
|
9919
|
+
declare class ValidationError extends BaseValidationError {
|
|
9920
|
+
readonly code = "VALIDATION_ERROR";
|
|
9921
|
+
}
|
|
9922
|
+
declare class InvalidPayloadError extends BaseValidationError {
|
|
9923
|
+
readonly code = "INVALID_PAYLOAD";
|
|
9924
|
+
constructor(message?: string, violations?: ValidationViolation[], cause?: Error, context?: Record<string, unknown>);
|
|
9925
|
+
getUserMessage(): string;
|
|
9926
|
+
}
|
|
9927
|
+
|
|
9928
|
+
/**
|
|
9929
|
+
* View definitions for SDK schema
|
|
9930
|
+
*
|
|
9931
|
+
* Views define pre-configured entry list configurations with filters,
|
|
9932
|
+
* columns, and metadata display settings.
|
|
9933
|
+
*/
|
|
9934
|
+
/**
|
|
9935
|
+
* View scope defines which content types a view applies to.
|
|
9936
|
+
*
|
|
9937
|
+
* When using `contentTypes` (plural) or `all`, the view displays entries
|
|
9938
|
+
* from multiple content types. In this case:
|
|
9939
|
+
*
|
|
9940
|
+
* - Columns/fields may only exist on some content types
|
|
9941
|
+
* - For entries where a field doesn't exist, the UI displays "—"
|
|
9942
|
+
* - System fields (id, status, createdAt, updatedAt) exist on all entries
|
|
9943
|
+
* - Filters on non-existent fields are skipped for that entry type
|
|
9944
|
+
*
|
|
9945
|
+
* Example display:
|
|
9946
|
+
* | Content Type | title | author | productCode |
|
|
9947
|
+
* |--------------|-------|--------|-------------|
|
|
9948
|
+
* | post | ✓ | ✓ | — |
|
|
9949
|
+
* | product | ✓ | — | ✓ |
|
|
9950
|
+
*/
|
|
9951
|
+
/**
|
|
9952
|
+
* Scope for a single content type
|
|
9953
|
+
*/
|
|
9954
|
+
interface ContentTypeScopeConfig {
|
|
9955
|
+
type: 'contentType';
|
|
9956
|
+
contentType: string;
|
|
9957
|
+
}
|
|
9958
|
+
/**
|
|
9959
|
+
* Scope for multiple content types
|
|
9960
|
+
*
|
|
9961
|
+
* Fields not present on all content types will show "—" in the UI
|
|
9962
|
+
*/
|
|
9963
|
+
interface ContentTypesScopeConfig {
|
|
9964
|
+
type: 'contentTypes';
|
|
9965
|
+
contentTypes: string[];
|
|
9966
|
+
}
|
|
9967
|
+
/**
|
|
9968
|
+
* Scope for an entry type (content, singleton, settings, asset)
|
|
9969
|
+
*/
|
|
9970
|
+
interface EntryTypeScopeConfig {
|
|
9971
|
+
type: 'entryType';
|
|
9972
|
+
entryType: 'content' | 'singleton' | 'settings' | 'asset';
|
|
9973
|
+
}
|
|
9974
|
+
/**
|
|
9975
|
+
* Scope for all content
|
|
9976
|
+
*
|
|
9977
|
+
* Fields not present on all content types will show "—" in the UI
|
|
9978
|
+
*/
|
|
9979
|
+
interface AllScopeConfig {
|
|
9980
|
+
type: 'all';
|
|
9981
|
+
}
|
|
9982
|
+
/**
|
|
9983
|
+
* View scope options
|
|
9984
|
+
*/
|
|
9985
|
+
type ViewScopeConfig = ContentTypeScopeConfig | ContentTypesScopeConfig | EntryTypeScopeConfig | AllScopeConfig;
|
|
9986
|
+
/**
|
|
9987
|
+
* The operators a view filter may name: the schema's `FILTER_OPERATORS`, which deploy parses a view
|
|
9988
|
+
* with and the read core compiles every one of.
|
|
9989
|
+
*
|
|
9990
|
+
* This list used to be its own: ten of its names — `doesNotContain`, `isNotEmpty`, `isOnOrBefore`,
|
|
9991
|
+
* `isOnOrAfter`, `tomorrow`, `lastWeek`, `lastMonth`, `includesAll`, `includesAny`, `excludes` —
|
|
9992
|
+
* are none the schema declares, so a view naming one was refused at deploy, and six the schema does
|
|
9993
|
+
* declare — `notContains`, `notIncludes`, `isOn`, `isBetween`, `thisYear`, `hasValue` — could not be
|
|
9994
|
+
* written here, so a view pulled by `relyio generate-types` that named one did not compile.
|
|
9995
|
+
* `@relyio/codegen-typescript`'s `src/__tests__/sdk-definition-config.types.ts` holds the two to each
|
|
9996
|
+
* other (REL-1457).
|
|
9997
|
+
*/
|
|
9998
|
+
type ViewFilterOperator = 'is' | 'isNot' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'isAnyOf' | 'isNoneOf' | 'includes' | 'notIncludes' | 'isTrue' | 'isFalse' | 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'between' | 'isOn' | 'isBefore' | 'isAfter' | 'isBetween' | 'inTheLast' | 'inTheNext' | 'today' | 'yesterday' | 'thisWeek' | 'thisMonth' | 'thisYear' | 'isEmpty' | 'hasValue';
|
|
9999
|
+
/** A span of time back or forward from now, for `inTheLast` and `inTheNext`. */
|
|
10000
|
+
interface ViewFilterRelativeDate {
|
|
10001
|
+
amount: number;
|
|
10002
|
+
unit: 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years';
|
|
10003
|
+
}
|
|
10004
|
+
/** What a filter compares against: the schema's `FilterValueSchema`. */
|
|
10005
|
+
type ViewFilterValue = string | number | boolean | null | (string | number)[] | {
|
|
10006
|
+
from: string | number | Date;
|
|
10007
|
+
to: string | number | Date;
|
|
10008
|
+
} | ViewFilterRelativeDate | Date;
|
|
10009
|
+
/**
|
|
10010
|
+
* One filter of a view: a field, an operator and the value it compares with.
|
|
10011
|
+
*/
|
|
10012
|
+
interface ViewFilterCondition {
|
|
10013
|
+
/**
|
|
10014
|
+
* The Property to filter on, as the Studio's entry list names it: `fields.<id>` for a field your
|
|
10015
|
+
* schema declares (`fields.seo.title` for a field of an object's value), `_metadata.<id>` for a system
|
|
10016
|
+
* field — `_metadata.status`, `_metadata.createdAt`, `_metadata.updatedAt`. So a field called
|
|
10017
|
+
* `status` (`fields.status`) and the entry's own lifecycle (`_metadata.status`) are both
|
|
10018
|
+
* filterable.
|
|
10019
|
+
*/
|
|
10020
|
+
field: string;
|
|
10021
|
+
/**
|
|
10022
|
+
* Filter operator
|
|
10023
|
+
*/
|
|
10024
|
+
operator: ViewFilterOperator;
|
|
10025
|
+
/**
|
|
10026
|
+
* Filter value (optional for some operators like isEmpty)
|
|
10027
|
+
*/
|
|
10028
|
+
value?: ViewFilterValue;
|
|
10029
|
+
}
|
|
10030
|
+
/**
|
|
10031
|
+
* A view's filter. A view's filters are a flat list joined by AND — the Filters the Studio's entry
|
|
10032
|
+
* list takes, each drawn as a Chip — so there is no filter group: an OR within one field is
|
|
10033
|
+
* `isAnyOf`. RelyIO refuses a group by name when you deploy.
|
|
10034
|
+
*/
|
|
10035
|
+
type ViewFilter = ViewFilterCondition;
|
|
10036
|
+
/**
|
|
10037
|
+
* View definition configuration
|
|
10038
|
+
*/
|
|
10039
|
+
interface ViewConfig {
|
|
10040
|
+
/**
|
|
10041
|
+
* Display name for the view
|
|
10042
|
+
*/
|
|
10043
|
+
name: string;
|
|
10044
|
+
/**
|
|
10045
|
+
* URL-friendly slug for the view, used in Studio URLs like /studio/views/:slug. Absent, the
|
|
10046
|
+
* platform derives one from the id when it reads the schema.
|
|
10047
|
+
*/
|
|
10048
|
+
slug?: string;
|
|
10049
|
+
/**
|
|
10050
|
+
* Optional description for the view
|
|
10051
|
+
*/
|
|
10052
|
+
description?: string;
|
|
10053
|
+
/**
|
|
10054
|
+
* Icon (emoji or icon name) for the view
|
|
10055
|
+
*/
|
|
10056
|
+
icon?: string;
|
|
10057
|
+
/**
|
|
10058
|
+
* Color for the view in the sidebar
|
|
10059
|
+
*/
|
|
10060
|
+
color?: string;
|
|
10061
|
+
/**
|
|
10062
|
+
* View scope - what content types this view applies to
|
|
10063
|
+
*/
|
|
10064
|
+
scope: ViewScopeConfig;
|
|
10065
|
+
/**
|
|
10066
|
+
* Filter conditions (optional), combined with AND. A flat list: an OR within one field is
|
|
10067
|
+
* `isAnyOf`, and there is no filter group.
|
|
10068
|
+
*
|
|
10069
|
+
* Deploy judges each against the entries the view lists: the field must be one they can be
|
|
10070
|
+
* narrowed by, and it must offer the operator — a boolean field takes `is` with `true` or
|
|
10071
|
+
* `false`, for example, not `isTrue`.
|
|
10072
|
+
*/
|
|
10073
|
+
filters?: ViewFilter[];
|
|
10074
|
+
/**
|
|
10075
|
+
* Column field IDs to display (optional)
|
|
10076
|
+
* If not specified, uses default columns
|
|
10077
|
+
*/
|
|
10078
|
+
columns?: string[];
|
|
10079
|
+
/**
|
|
10080
|
+
* Metadata field IDs to show under title (max 3)
|
|
10081
|
+
*/
|
|
10082
|
+
metadataFields?: string[];
|
|
10083
|
+
/**
|
|
10084
|
+
* Default sort (optional). `field` names the Property to sort by, as a filter names one —
|
|
10085
|
+
* `fields.<id>` or `_metadata.<id>` — and deploy refuses one the view's entries cannot be sorted
|
|
10086
|
+
* by. `columns` and `metadataFields` are display settings and name field IDs as written.
|
|
10087
|
+
*/
|
|
10088
|
+
sort?: {
|
|
10089
|
+
field: string;
|
|
10090
|
+
direction: 'asc' | 'desc';
|
|
10091
|
+
};
|
|
10092
|
+
/**
|
|
10093
|
+
* Sort order in the sidebar (lower = higher priority)
|
|
10094
|
+
*/
|
|
10095
|
+
sortOrder?: number;
|
|
10096
|
+
}
|
|
10097
|
+
/**
|
|
10098
|
+
* Complete view definition with ID
|
|
10099
|
+
*/
|
|
10100
|
+
interface ViewDefinition extends ViewConfig {
|
|
10101
|
+
/**
|
|
10102
|
+
* Internal tag for type discrimination
|
|
10103
|
+
*/
|
|
10104
|
+
readonly _tag: 'view';
|
|
10105
|
+
/**
|
|
10106
|
+
* Unique view ID (must start with a letter)
|
|
10107
|
+
*/
|
|
10108
|
+
readonly id: string;
|
|
10109
|
+
}
|
|
10110
|
+
/**
|
|
10111
|
+
* Define a schema view
|
|
10112
|
+
*
|
|
10113
|
+
* Views are pre-configured entry list displays with filters,
|
|
10114
|
+
* columns, and metadata settings.
|
|
10115
|
+
*
|
|
10116
|
+
* @example
|
|
10117
|
+
* const featuredPosts = defineView('featuredPosts', {
|
|
10118
|
+
* name: 'Featured Posts',
|
|
10119
|
+
* description: 'Blog posts marked as featured',
|
|
10120
|
+
* icon: '📝',
|
|
10121
|
+
* scope: { type: 'contentType', contentType: 'post' },
|
|
10122
|
+
* filters: [
|
|
10123
|
+
* { field: 'fields.featured', operator: 'is', value: true }
|
|
10124
|
+
* ],
|
|
10125
|
+
* columns: ['title', 'author', 'publishedAt'],
|
|
10126
|
+
* metadataFields: ['category', 'views'],
|
|
10127
|
+
* sort: { field: '_metadata.publishedAt', direction: 'desc' }
|
|
10128
|
+
* })
|
|
10129
|
+
*
|
|
10130
|
+
* @example
|
|
10131
|
+
* const archivedContent = defineView('archivedContent', {
|
|
10132
|
+
* name: 'Archived',
|
|
10133
|
+
* scope: { type: 'all' },
|
|
10134
|
+
* filters: [
|
|
10135
|
+
* { field: '_metadata.status', operator: 'is', value: 'archived' }
|
|
10136
|
+
* ]
|
|
10137
|
+
* })
|
|
10138
|
+
*
|
|
10139
|
+
* @param id - Unique view ID (must start with a letter)
|
|
10140
|
+
* @param config - View configuration
|
|
10141
|
+
* @returns View definition object
|
|
10142
|
+
*/
|
|
10143
|
+
declare function defineView(id: string, config: ViewConfig): ViewDefinition;
|
|
10144
|
+
|
|
10145
|
+
/**
|
|
10146
|
+
* Core type definitions for the RelyIO SDK
|
|
10147
|
+
*/
|
|
10148
|
+
|
|
10149
|
+
/**
|
|
10150
|
+
* Base interface for all content items
|
|
10151
|
+
* Matches the actual RelyIO API structure with _metadata object
|
|
10152
|
+
*/
|
|
10153
|
+
interface BaseContent {
|
|
10154
|
+
/**
|
|
10155
|
+
* What the read reports about the entry beside its fields: the committed document's
|
|
10156
|
+
* `EntryMetadata`, and nothing added to it. A `sourceDatasetId` was declared here for an entry
|
|
10157
|
+
* inherited from a linked dataset's source; no read sends one.
|
|
10158
|
+
*/
|
|
10159
|
+
_metadata: EntryMetadata;
|
|
10160
|
+
}
|
|
10161
|
+
/**
|
|
10162
|
+
* Whether `T` declares no field: `BaseContent`, the entry of a client with no schema registered.
|
|
10163
|
+
*
|
|
10164
|
+
* Every input that names fields — a condition, a sort, a selection, a write — takes any name then,
|
|
10165
|
+
* because nothing declares which exist; the API checks them against the deployed schema. Before
|
|
10166
|
+
* REL-1406 only `where` asked, so the others took no field at all from an unregistered client.
|
|
10167
|
+
*/
|
|
10168
|
+
type DeclaresNoField<T> = [Exclude<keyof T, '_metadata'>] extends [never] ? true : false;
|
|
10169
|
+
/**
|
|
10170
|
+
* The value a `where` condition compares a field against: one of the values the field holds.
|
|
10171
|
+
*
|
|
10172
|
+
* Not the field's read type. The REST dialect (`fromRestWhere` in `@relyio/entry-reads`) reads a
|
|
10173
|
+
* bare value as `eq`, an array as `in` and an object as operators — refusing an object with none —
|
|
10174
|
+
* and drops `null`. So a list field (`tags`) is matched by one of its items, a reference by the
|
|
10175
|
+
* target's id, and an object's value or an expanded entry is never a value to send.
|
|
10176
|
+
*/
|
|
10177
|
+
type WhereScalar<V> = Exclude<V extends readonly (infer Item)[] ? Item : V, null | undefined | object>;
|
|
10178
|
+
/** One field's condition: a value (`eq`), a list of values (`in`), or operators. */
|
|
10179
|
+
type WhereFieldCondition<V> = WhereScalar<V> | WhereScalar<V>[] | WhereOperator<WhereScalar<V>>;
|
|
10180
|
+
/**
|
|
10181
|
+
* Query conditions for filtering content: conditions on the fields the content type declares.
|
|
10182
|
+
*
|
|
10183
|
+
* Typed by the content type's fields where a schema types the client: each key is a declared field
|
|
10184
|
+
* and each value one of that field's values. Untyped (`BaseContent`, which declares no fields), any
|
|
10185
|
+
* field name is accepted — nothing declares which exist.
|
|
10186
|
+
*
|
|
10187
|
+
* Nothing under `_metadata` is a field. This type used to accept `{ _metadata: { status } }`, and
|
|
10188
|
+
* the API filters on no `_metadata` key: measured through a real request (REL-1413), that condition
|
|
10189
|
+
* answered `500 INTERNAL_ERROR` and a dotted `_metadata.status` an empty page. A typed client is now
|
|
10190
|
+
* refused at compile time, and every client before sending (`refuseMetadataConditions`).
|
|
10191
|
+
*/
|
|
10192
|
+
type WhereClause<T extends BaseContent = BaseContent> = DeclaresNoField<T> extends true ? {
|
|
10193
|
+
[field: string]: unknown;
|
|
10194
|
+
} : {
|
|
10195
|
+
[K in Exclude<keyof T, '_metadata'>]?: WhereFieldCondition<T[K]>;
|
|
10196
|
+
};
|
|
10197
|
+
/**
|
|
10198
|
+
* Query operators for advanced filtering: the REST dialect's spellings (`@relyio/entry-reads`'
|
|
10199
|
+
* `REST_PREFIXED_OPERATOR_TO_ID`). `$regex` was here and is no spelling the API reads: alone it was
|
|
10200
|
+
* refused, beside another operator dropped (REL-2136).
|
|
10201
|
+
*/
|
|
10202
|
+
interface WhereOperator<T = unknown> {
|
|
10203
|
+
/** Equals */
|
|
10204
|
+
$eq?: T;
|
|
10205
|
+
/** Not equals */
|
|
10206
|
+
$ne?: T;
|
|
10207
|
+
/** Greater than */
|
|
10208
|
+
$gt?: T;
|
|
10209
|
+
/** Greater than or equal */
|
|
10210
|
+
$gte?: T;
|
|
10211
|
+
/** Less than */
|
|
10212
|
+
$lt?: T;
|
|
10213
|
+
/** Less than or equal */
|
|
10214
|
+
$lte?: T;
|
|
10215
|
+
/** In array */
|
|
10216
|
+
$in?: T[];
|
|
10217
|
+
/** Not in array */
|
|
10218
|
+
$nin?: T[];
|
|
10219
|
+
/** Contains (for strings) */
|
|
10220
|
+
$contains?: string;
|
|
10221
|
+
/** Starts with (for strings) */
|
|
10222
|
+
$startsWith?: string;
|
|
10223
|
+
/** Ends with (for strings) */
|
|
10224
|
+
$endsWith?: string;
|
|
10225
|
+
/** Exists (field is not null/undefined) */
|
|
10226
|
+
$exists?: boolean;
|
|
10227
|
+
/**
|
|
10228
|
+
* `true`: the value is empty — no value, or no block or tree holding a reference there; `false`:
|
|
10229
|
+
* it has one. Taken by every path a filter names (REL-2136).
|
|
10230
|
+
*/
|
|
10231
|
+
$isNull?: boolean;
|
|
10232
|
+
/**
|
|
10233
|
+
* Within the span back from the moment of the read, both ends included, counted in UTC: `{ amount:
|
|
10234
|
+
* 7, unit: 'days' }`. Asked of a field that holds a date — `date` or `dateTime` — only; the API
|
|
10235
|
+
* refuses it on any other (REL-1817), and a typed read does not offer it there (REL-2195).
|
|
10236
|
+
*/
|
|
10237
|
+
$inTheLast?: ViewFilterRelativeDate;
|
|
10238
|
+
/** Within the span forward from the moment of the read, as {@link WhereOperator.$inTheLast}. */
|
|
10239
|
+
$inTheNext?: ViewFilterRelativeDate;
|
|
10240
|
+
}
|
|
10241
|
+
/** The operators the API asks only of a field that holds a date (`NotADateError` elsewhere). */
|
|
10242
|
+
type DateOnlyOperator = '$inTheLast' | '$inTheNext';
|
|
10243
|
+
/**
|
|
10244
|
+
* Sort options for query results: by a key `T` declares, or by any field where it declares none.
|
|
10245
|
+
*/
|
|
10246
|
+
type SortOptions<T extends BaseContent = BaseContent> = {
|
|
10247
|
+
[K in DeclaresNoField<T> extends true ? string : keyof T]?: 'asc' | 'desc';
|
|
10248
|
+
};
|
|
10249
|
+
/**
|
|
10250
|
+
* Query options for content requests
|
|
10251
|
+
*
|
|
10252
|
+
* `F` is the shape whose fields a condition or a sort names, which is the read's own except for an
|
|
10253
|
+
* asset: its read adds the `file` and `urls` blocks beside the fields, and a condition on those
|
|
10254
|
+
* would name no field — and would make an unregistered asset client refuse every field it was given.
|
|
10255
|
+
*/
|
|
10256
|
+
interface QueryOptions<T extends BaseContent = BaseContent, F extends BaseContent = T> {
|
|
10257
|
+
/** Conditions to filter by */
|
|
10258
|
+
where?: WhereClause<F>;
|
|
10259
|
+
/** Fields to include in response: any, where nothing declares them */
|
|
10260
|
+
select?: (DeclaresNoField<F> extends true ? string : keyof T)[];
|
|
10261
|
+
/** Related content to include */
|
|
10262
|
+
include?: string[];
|
|
10263
|
+
/** Sort options */
|
|
10264
|
+
sort?: SortOptions<F>;
|
|
10265
|
+
/** Limit number of results */
|
|
10266
|
+
limit?: number;
|
|
10267
|
+
/** Offset for pagination */
|
|
10268
|
+
offset?: number;
|
|
10269
|
+
/** Cursor for cursor-based pagination */
|
|
10270
|
+
cursor?: string;
|
|
10271
|
+
}
|
|
10272
|
+
/**
|
|
10273
|
+
* The fields a write sends: the ones the content type declares, as it declares them — or, where
|
|
10274
|
+
* nothing declares any (`BaseContent`, the entry of a client with no schema registered), any field.
|
|
10275
|
+
* The API validates the body against the deployed schema, the only place those names exist.
|
|
10276
|
+
*
|
|
10277
|
+
* `Omit<BaseContent, '_metadata'>` declares no key at all, so before this every write from an
|
|
10278
|
+
* unregistered client — `relyio.content('post').create({ title })`, the SDK without codegen — was
|
|
10279
|
+
* TS2353, and so was every `batch()` operation, whose `content` is untyped for every client.
|
|
10280
|
+
*/
|
|
10281
|
+
type WriteFields<T extends BaseContent> = DeclaresNoField<T> extends true ? {
|
|
10282
|
+
[field: string]: unknown;
|
|
10283
|
+
} : Omit<T, '_metadata'>;
|
|
10284
|
+
/**
|
|
10285
|
+
* Content creation input - excludes metadata fields that are managed by the system
|
|
10286
|
+
*/
|
|
10287
|
+
type CreateInput<T extends BaseContent> = WriteFields<T> & {
|
|
10288
|
+
/** Optional metadata that can be set during creation */
|
|
10289
|
+
_metadata?: {
|
|
10290
|
+
/** Parent ID for hierarchical content */
|
|
10291
|
+
parentId?: string | null;
|
|
10292
|
+
/** Content locale */
|
|
10293
|
+
locale?: string;
|
|
10294
|
+
};
|
|
10295
|
+
};
|
|
10296
|
+
/**
|
|
10297
|
+
* What a revision answers: the entry, its `_metadata` also listing the entry links other entries
|
|
10298
|
+
* publish that the revision left pointing nowhere — the document's `RevisedEntryMetadata`
|
|
10299
|
+
* (REL-2110, REL-2130). The write is never refused for them; the linking entry's next publish is.
|
|
10300
|
+
*/
|
|
10301
|
+
type RevisedContent<T extends BaseContent> = Omit<T, '_metadata'> & {
|
|
10302
|
+
_metadata: T['_metadata'] & Pick<components['schemas']['RevisedEntryMetadata'], 'brokenLinks'>;
|
|
10303
|
+
};
|
|
10304
|
+
/**
|
|
10305
|
+
* What a version restore answers: the entry, its `_metadata` also listing what the restore left out
|
|
10306
|
+
* and the links it left pointing nowhere — the document's `RestoredEntryMetadata` (REL-1793,
|
|
10307
|
+
* REL-2130).
|
|
10308
|
+
*/
|
|
10309
|
+
type RestoredContent<T extends BaseContent> = Omit<T, '_metadata'> & {
|
|
10310
|
+
_metadata: T['_metadata'] & Pick<components['schemas']['RestoredEntryMetadata'], 'leftOut' | 'brokenLinks'>;
|
|
10311
|
+
};
|
|
10312
|
+
/**
|
|
10313
|
+
* Content update input - excludes system-managed metadata fields
|
|
10314
|
+
*/
|
|
10315
|
+
type UpdateInput<T extends BaseContent> = Partial<WriteFields<T>> & {
|
|
10316
|
+
/** Optional metadata that can be updated */
|
|
10317
|
+
_metadata?: {
|
|
10318
|
+
/** Parent ID for hierarchical content */
|
|
10319
|
+
parentId?: string | null;
|
|
10320
|
+
/** Content locale */
|
|
10321
|
+
locale?: string;
|
|
10322
|
+
};
|
|
10323
|
+
};
|
|
10324
|
+
/**
|
|
10325
|
+
* What the entry list serves — **read from the committed document**, not
|
|
10326
|
+
* written down here.
|
|
10327
|
+
*
|
|
10328
|
+
* It used to be a hand-written `{ items, total?, hasMore, nextCursor }`, and
|
|
10329
|
+
* every field of it was wrong after API2: the route is the cursor dialect, so
|
|
10330
|
+
* the body is `{ data, page: { nextCursor, hasMore } }` and there is no total
|
|
10331
|
+
* at all. `execute()` therefore resolved `result.items` — `undefined` — for
|
|
10332
|
+
* every caller of the SDK's most-used method, and nothing could see it because
|
|
10333
|
+
* the type said otherwise.
|
|
10334
|
+
*
|
|
10335
|
+
* Deriving it means the next dialect change is a compile error in user code
|
|
10336
|
+
* rather than an `undefined` at runtime (`INV-API-CLIENT-IS-DERIVED`).
|
|
10337
|
+
*/
|
|
10338
|
+
type ContentQueryResult<T extends BaseContent = BaseContent> = Wire<'/v1/{contentType}', 'get', T>;
|
|
10339
|
+
/**
|
|
10340
|
+
* A singleton as `GET /v1/singletons/{key}` serves it: its fields at the top level and
|
|
10341
|
+
* `_metadata`, the document's `Singleton` rather than a second declaration of it.
|
|
10342
|
+
*/
|
|
10343
|
+
type SingletonContent = components['schemas']['Singleton'];
|
|
10344
|
+
/**
|
|
10345
|
+
* Custom query definition
|
|
10346
|
+
*/
|
|
10347
|
+
interface CustomQuery<TVariables = unknown, TResponse = unknown> {
|
|
10348
|
+
/** Query name */
|
|
10349
|
+
name: string;
|
|
10350
|
+
/** Query variables */
|
|
10351
|
+
variables?: TVariables;
|
|
10352
|
+
/** Expected response type */
|
|
10353
|
+
response?: TResponse;
|
|
10354
|
+
}
|
|
10355
|
+
/**
|
|
10356
|
+
* Content type schema information
|
|
10357
|
+
*/
|
|
10358
|
+
interface ContentTypeSchema {
|
|
10359
|
+
/** Content type name */
|
|
10360
|
+
name: string;
|
|
10361
|
+
/** Display name */
|
|
10362
|
+
displayName: string;
|
|
10363
|
+
/** Description */
|
|
10364
|
+
description?: string;
|
|
10365
|
+
/** Field definitions */
|
|
10366
|
+
fields: FieldDefinition[];
|
|
10367
|
+
/** Whether this content type is hierarchical */
|
|
10368
|
+
hierarchical?: boolean;
|
|
10369
|
+
/** Preview configuration */
|
|
10370
|
+
preview?: {
|
|
10371
|
+
select?: Record<string, string>;
|
|
10372
|
+
prepare?: (_selection: Record<string, unknown>) => Record<string, unknown>;
|
|
10373
|
+
};
|
|
10374
|
+
}
|
|
10375
|
+
/**
|
|
10376
|
+
* Field definition for content types
|
|
10377
|
+
*/
|
|
10378
|
+
interface FieldDefinition {
|
|
10379
|
+
/** Field name */
|
|
10380
|
+
name: string;
|
|
10381
|
+
/** Field type */
|
|
10382
|
+
type: FieldTypeName;
|
|
10383
|
+
/** Display title */
|
|
10384
|
+
title?: string;
|
|
10385
|
+
/** Field description */
|
|
10386
|
+
description?: string;
|
|
10387
|
+
/** Whether field is required */
|
|
10388
|
+
required?: boolean;
|
|
10389
|
+
/** Default value */
|
|
10390
|
+
default?: unknown;
|
|
10391
|
+
/** Validation rules */
|
|
10392
|
+
validation?: ValidationRule[];
|
|
10393
|
+
/** Field options */
|
|
10394
|
+
options?: FieldOptions;
|
|
10395
|
+
}
|
|
10396
|
+
/**
|
|
10397
|
+
* Supported field type names (string identifiers)
|
|
10398
|
+
*/
|
|
10399
|
+
type FieldTypeName = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'text' | 'markdown' | 'richtext' | 'slug' | 'url' | 'email' | 'image' | 'file' | 'reference' | 'array' | 'object' | 'geopoint' | 'color';
|
|
10400
|
+
/**
|
|
10401
|
+
* Field validation rules
|
|
10402
|
+
*/
|
|
10403
|
+
interface ValidationRule {
|
|
10404
|
+
/** Rule type */
|
|
10405
|
+
type: 'required' | 'min' | 'max' | 'pattern' | 'custom';
|
|
10406
|
+
/** Rule value */
|
|
10407
|
+
value?: unknown;
|
|
10408
|
+
/** Error message */
|
|
10409
|
+
message?: string;
|
|
10410
|
+
}
|
|
10411
|
+
/**
|
|
10412
|
+
* Field-specific options
|
|
10413
|
+
*/
|
|
10414
|
+
interface FieldOptions {
|
|
10415
|
+
/** For array fields */
|
|
10416
|
+
of?: FieldDefinition;
|
|
10417
|
+
/** For reference fields */
|
|
10418
|
+
to?: string | string[];
|
|
10419
|
+
/** For string fields */
|
|
10420
|
+
list?: string[];
|
|
10421
|
+
/** For number fields */
|
|
10422
|
+
min?: number;
|
|
10423
|
+
max?: number;
|
|
10424
|
+
/** For image/file fields */
|
|
10425
|
+
accept?: string[];
|
|
10426
|
+
/** For rich text fields */
|
|
10427
|
+
marks?: string[];
|
|
10428
|
+
blocks?: string[];
|
|
10429
|
+
}
|
|
10430
|
+
/**
|
|
10431
|
+
* Real-time event types
|
|
10432
|
+
*/
|
|
10433
|
+
type RealtimeEventType = 'created' | 'updated' | 'deleted' | 'published' | 'unpublished';
|
|
10434
|
+
/**
|
|
10435
|
+
* Real-time event payload
|
|
10436
|
+
*/
|
|
10437
|
+
interface RealtimeEvent<T extends BaseContent = BaseContent> {
|
|
10438
|
+
/** Event type */
|
|
10439
|
+
type: RealtimeEventType;
|
|
10440
|
+
/** Content type */
|
|
10441
|
+
contentType: string;
|
|
10442
|
+
/** Content item (for created/updated events) */
|
|
10443
|
+
item?: T;
|
|
10444
|
+
/** Content ID (for deleted events) */
|
|
10445
|
+
id?: string;
|
|
10446
|
+
/** Timestamp */
|
|
10447
|
+
timestamp: number;
|
|
10448
|
+
/** Event metadata */
|
|
10449
|
+
metadata?: Record<string, unknown>;
|
|
10450
|
+
}
|
|
10451
|
+
/**
|
|
10452
|
+
* Subscription options
|
|
10453
|
+
*/
|
|
10454
|
+
interface SubscriptionOptions<T extends BaseContent = BaseContent> {
|
|
10455
|
+
/** Content type to subscribe to */
|
|
10456
|
+
contentType: string;
|
|
10457
|
+
/** Filter conditions */
|
|
10458
|
+
where?: WhereClause<T>;
|
|
10459
|
+
/** Events to listen for */
|
|
10460
|
+
events?: RealtimeEventType[];
|
|
10461
|
+
/** Subscription metadata */
|
|
10462
|
+
metadata?: Record<string, unknown>;
|
|
10463
|
+
}
|
|
10464
|
+
/**
|
|
10465
|
+
* Performance metrics
|
|
10466
|
+
*/
|
|
10467
|
+
interface PerformanceMetrics {
|
|
10468
|
+
/** Request duration in milliseconds */
|
|
10469
|
+
duration: number;
|
|
10470
|
+
/** Request timestamp */
|
|
10471
|
+
timestamp: number;
|
|
10472
|
+
/** Request URL */
|
|
10473
|
+
url: string;
|
|
10474
|
+
/** HTTP method */
|
|
10475
|
+
method: string;
|
|
10476
|
+
/** Response status code */
|
|
10477
|
+
statusCode: number;
|
|
10478
|
+
/** Whether response came from cache */
|
|
10479
|
+
fromCache: boolean;
|
|
10480
|
+
/** Cache hit ratio */
|
|
10481
|
+
cacheHitRatio?: number;
|
|
10482
|
+
}
|
|
10483
|
+
|
|
10484
|
+
/**
|
|
10485
|
+
* Include paths, typed (REL-1801, design decision 12): a read's type follows the paths it names.
|
|
10486
|
+
*
|
|
10487
|
+
* ```ts
|
|
10488
|
+
* const home = await relyio
|
|
10489
|
+
* .content('page')
|
|
10490
|
+
* .findById('home')
|
|
10491
|
+
* .include(['sections.features(name,slug)', 'sections.customers.logo', 'ogImage'])
|
|
10492
|
+
* .execute()
|
|
10493
|
+
* ```
|
|
10494
|
+
*
|
|
10495
|
+
* - **A path names fields, joined by dots**, through lists, page builders, objects and references:
|
|
10496
|
+
* `sections.features` reaches `features` in whichever block declares it. Each hop across a
|
|
10497
|
+
* reference is written out — `sections.customers.logo` expands each customer and its logo — and
|
|
10498
|
+
* nothing expands past where a path stops, so a read costs what it names. A path that stops at a
|
|
10499
|
+
* list or an object expands every reference it holds.
|
|
10500
|
+
* - **Parentheses pick fields**: `sections.features(name,slug)` returns each feature with its `name`,
|
|
10501
|
+
* its `slug` and its `_metadata`, and is typed so.
|
|
10502
|
+
* - **A reference a path expands is typed as the entry; every other one as its id.** One path is one
|
|
10503
|
+
* element of the array; a path that holds no reference does not compile, and the error lists the
|
|
10504
|
+
* paths that do.
|
|
10505
|
+
*
|
|
10506
|
+
* The grammar is `@relyio/schema`'s `readIncludePaths`, which the Content API reads `?include=` with;
|
|
10507
|
+
* the API holds each path to the deployed schema and refuses one it does not hold, naming the ones it
|
|
10508
|
+
* does.
|
|
10509
|
+
*/
|
|
10510
|
+
|
|
10511
|
+
/**
|
|
10512
|
+
* The include paths that continue below field `K`, relative to it: `sections.features` → `features`
|
|
10513
|
+
* under `sections`. An include set the type cannot see (`string`) continues everywhere.
|
|
10514
|
+
*/
|
|
10515
|
+
type IncludesUnder<I extends string, K extends string> = string extends I ? string : I extends `${K}.${infer Rest}` ? Rest : never;
|
|
10516
|
+
/**
|
|
10517
|
+
* The paths that stop at field `K`: `''` for one that picks no fields, and what the parentheses hold
|
|
10518
|
+
* for one that does (`'name,slug'`). `never` when none stops here.
|
|
10519
|
+
*/
|
|
10520
|
+
type StopsAt<I extends string, K extends string> = string extends I ? never : I extends K ? '' : I extends `${K}(${infer Picked})` ? Picked : never;
|
|
10521
|
+
/** Whether the reference at `K` is expanded: a path names it or crosses it, or one above covers it. */
|
|
10522
|
+
type ExpandsHere<I extends string, K extends string, A extends boolean> = A extends true ? true : [StopsAt<I, K> | IncludesUnder<I, K>] extends [never] ? false : true;
|
|
10523
|
+
/** Whether every reference below the list or object `K` is expanded: a path stops at it, or above. */
|
|
10524
|
+
type CoversBelow<I extends string, K extends string, A extends boolean> = A extends true ? true : '' extends StopsAt<I, K> ? true : false;
|
|
10525
|
+
/** Every field of an entry: what a reference a path picks nothing of returns. */
|
|
10526
|
+
interface EveryField {
|
|
10527
|
+
readonly __everyField: true;
|
|
10528
|
+
}
|
|
10529
|
+
type Trim<S extends string> = S extends ` ${infer R}` ? Trim<R> : S extends `${infer R} ` ? Trim<R> : S;
|
|
10530
|
+
/** `'name, slug'` → `'name' | 'slug'`. */
|
|
10531
|
+
type Split<S extends string> = S extends `${infer Head},${infer Rest}` ? Trim<Head> | Split<Rest> : Trim<S>;
|
|
10532
|
+
/** The field a path below a reference crosses first: `logo(alt)` and `logo.credit` → `logo`. */
|
|
10533
|
+
type FirstField<P extends string> = P extends `${infer Head}.${string}` ? FirstField<Head> : P extends `${infer Head}(${string}` ? Head : P;
|
|
10534
|
+
/**
|
|
10535
|
+
* The fields the entry a reference reaches returns: every field, unless every path stopping at it
|
|
10536
|
+
* picks — then the picked fields and the fields deeper paths cross.
|
|
10537
|
+
*/
|
|
10538
|
+
type SelectionAt<I extends string, K extends string> = [StopsAt<I, K>] extends [never] ? EveryField : '' extends StopsAt<I, K> ? EveryField : Split<StopsAt<I, K>> | FirstField<IncludesUnder<I, K>>;
|
|
10539
|
+
/** An entry cut down to a selection, beside its `_metadata`. Distributes over a union of entries. */
|
|
10540
|
+
type Selected<E, Fields> = [Fields] extends [EveryField] ? E : E extends unknown ? {
|
|
10541
|
+
[Key in keyof E as Key extends Fields | '_metadata' ? Key : never]: E[Key];
|
|
10542
|
+
} : never;
|
|
10543
|
+
type ReferenceKind = Extract<FieldType, 'reference'>;
|
|
10544
|
+
type IsReference<F> = F extends {
|
|
10545
|
+
readonly type: ReferenceKind;
|
|
10546
|
+
} ? true : false;
|
|
10547
|
+
/** The fields of the shapes a list's items or an object's value take; `never` for any other field. */
|
|
10548
|
+
type ShapeFields<F> = F extends {
|
|
10549
|
+
readonly config?: infer C;
|
|
10550
|
+
} ? NonNullable<C> extends {
|
|
10551
|
+
readonly of?: infer Of;
|
|
10552
|
+
} ? FieldsOfShapes<ShapesIn<Exclude<Of, undefined>>> : never : never;
|
|
10553
|
+
type FieldsOfShapes<Shape> = Shape extends {
|
|
10554
|
+
readonly fields: readonly unknown[];
|
|
10555
|
+
} ? DeclaredFields<Shape> : never;
|
|
10556
|
+
/** The fields of every type a reference may point at, sections read flat. */
|
|
10557
|
+
type TargetFields<F, S> = F extends {
|
|
10558
|
+
readonly config?: infer C;
|
|
10559
|
+
} ? S extends FieldSchemaContext ? FieldsOfDefinition<Declared<S['contentTypes'], ReferenceTarget<NonNullable<C>>> | Declared<S['singletonContentTypes'], ReferenceTarget<NonNullable<C>>> | Declared<NonNullable<S['assetTypes']>, ReferenceTarget<NonNullable<C>>>> : never : never;
|
|
10560
|
+
type FieldsOfDefinition<D> = D extends {
|
|
10561
|
+
readonly fields: readonly unknown[];
|
|
10562
|
+
} ? DeclaredFields<D> : never;
|
|
10563
|
+
/** `true` when a field is a reference, or a list or object holding one at any depth. */
|
|
10564
|
+
type HoldsReference<F> = F extends AnyFieldDefinition ? IsReference<F> extends true ? true : true extends HoldsReference<ShapeFields<F>> ? true : true extends IsLinkingRichText<F> ? true : false : false;
|
|
10565
|
+
type RichTextKind = Extract<FieldType, 'richText'>;
|
|
10566
|
+
/** The fields of a rich-text field's declared Blocks and Inline elements (REL-1807). */
|
|
10567
|
+
type DeclaredNodeFields<F> = F extends {
|
|
10568
|
+
readonly config?: infer C;
|
|
10569
|
+
} ? NonNullable<C> extends {
|
|
10570
|
+
readonly blocks?: ReadonlyArray<infer B>;
|
|
10571
|
+
readonly inline?: ReadonlyArray<infer N>;
|
|
10572
|
+
} ? FieldsOfShapes<B | N> : never : never;
|
|
10573
|
+
/**
|
|
10574
|
+
* `true` for a rich-text field holding references (REL-1808): its entry links, where it declares
|
|
10575
|
+
* `links`, or a reference among its declared nodes' fields. Such a field is **one** include path —
|
|
10576
|
+
* nothing inside rich text is a path — and including it expands every reference in it.
|
|
10577
|
+
*/
|
|
10578
|
+
type IsLinkingRichText<F> = F extends {
|
|
10579
|
+
readonly type: RichTextKind;
|
|
10580
|
+
readonly config?: infer C;
|
|
10581
|
+
} ? [LinkTargetsIn<NonNullable<C>>] extends [never] ? true extends HoldsReference<DeclaredNodeFields<F>> ? true : false : true : false;
|
|
10582
|
+
/**
|
|
10583
|
+
* The fields of every entry a rich-text field's references reach — its entry links' targets and
|
|
10584
|
+
* those of the references its declared nodes declare directly — what a pick or a hop past it names.
|
|
10585
|
+
*/
|
|
10586
|
+
type RichTextTargetFields<F, S> = F extends {
|
|
10587
|
+
readonly config?: infer C;
|
|
10588
|
+
} ? S extends FieldSchemaContext ? FieldsOfDefinition<Declared<S['contentTypes'], RichTextTargets<NonNullable<C>, F>> | Declared<S['singletonContentTypes'], RichTextTargets<NonNullable<C>, F>>> : never : never;
|
|
10589
|
+
type RichTextTargets<C, F> = LinkTargetsIn<C> | (Extract<DeclaredNodeFields<F>, {
|
|
10590
|
+
readonly type: ReferenceKind;
|
|
10591
|
+
}> extends {
|
|
10592
|
+
readonly config?: infer R;
|
|
10593
|
+
} ? ReferenceTarget<NonNullable<R>> : never);
|
|
10594
|
+
/**
|
|
10595
|
+
* Every path a record can include, below `Prefix`: each reference, and each list or object holding
|
|
10596
|
+
* one, then the paths inside it. Distributes over the record's fields.
|
|
10597
|
+
*/
|
|
10598
|
+
type IncludablePaths<Fields, Prefix extends string = ''> = Fields extends AnyFieldDefinition ? IsReference<Fields> extends true ? `${Prefix}${Fields['id']}` : true extends IsLinkingRichText<Fields> ? `${Prefix}${Fields['id']}` : true extends HoldsReference<ShapeFields<Fields>> ? `${Prefix}${Fields['id']}` | IncludablePaths<ShapeFields<Fields>, `${Prefix}${Fields['id']}.`> : never : never;
|
|
10599
|
+
type ListKind = Extract<FieldType, 'list'>;
|
|
10600
|
+
type ObjectKind = Extract<FieldType, 'object'>;
|
|
10601
|
+
type JsonKind = Extract<FieldType, 'json'>;
|
|
10602
|
+
/**
|
|
10603
|
+
* The kinds a filter reads as dates, which alone take `$inTheLast` and `$inTheNext`: those whose
|
|
10604
|
+
* field-kind declaration gives a `filter` facet of kind `date`. `__tests__/where-paths.types.ts`
|
|
10605
|
+
* holds the two to one answer, as it does {@link FiltersByValue}.
|
|
10606
|
+
*/
|
|
10607
|
+
type DateKind = Extract<FieldType, 'date' | 'dateTime'>;
|
|
10608
|
+
/**
|
|
10609
|
+
* Whether a filter names a field of each kind by its own value: `true` where `@relyio/schema`'s
|
|
10610
|
+
* field-kind declaration gives the kind a `filter` facet, `false` where it says `NOT_FILTERED`.
|
|
10611
|
+
* Restated as a type, because the declaration object is not rolled into this package's `.d.ts`;
|
|
10612
|
+
* `__tests__/where-paths.types.ts` holds the two to one answer, so a kind whose facet changes fails
|
|
10613
|
+
* to compile there.
|
|
10614
|
+
*/
|
|
10615
|
+
type FiltersByValue = OverEveryFieldKind<{
|
|
10616
|
+
shortText: true;
|
|
10617
|
+
longText: true;
|
|
10618
|
+
richText: false;
|
|
10619
|
+
table: false;
|
|
10620
|
+
code: false;
|
|
10621
|
+
email: true;
|
|
10622
|
+
url: true;
|
|
10623
|
+
slug: true;
|
|
10624
|
+
integer: true;
|
|
10625
|
+
decimal: true;
|
|
10626
|
+
boolean: true;
|
|
10627
|
+
enum: true;
|
|
10628
|
+
date: true;
|
|
10629
|
+
dateTime: true;
|
|
10630
|
+
reference: true;
|
|
10631
|
+
tags: true;
|
|
10632
|
+
list: false;
|
|
10633
|
+
object: false;
|
|
10634
|
+
json: false;
|
|
10635
|
+
}>;
|
|
10636
|
+
/**
|
|
10637
|
+
* Whether a field says `localization` the API reads as translated (`isFieldLocalized`): `true`, a
|
|
10638
|
+
* list of locales, or `{ enabled: true }`. A builder keeps what was written (`LocalizedAs`,
|
|
10639
|
+
* REL-2136); a definition whose type does not — one written without a builder, or `LocalizationConfig`
|
|
10640
|
+
* as a whole — reads as shared, which is how the API answers a field that says nothing.
|
|
10641
|
+
*/
|
|
10642
|
+
type SaysLocalized<F> = [Exclude<LocalizationOf<F>, undefined>] extends [never] ? false : [Exclude<LocalizationOf<F>, undefined>] extends [
|
|
10643
|
+
true | readonly string[] | {
|
|
10644
|
+
readonly enabled: true;
|
|
10645
|
+
}
|
|
10646
|
+
] ? true : false;
|
|
10647
|
+
/**
|
|
10648
|
+
* Where a value's translation is held, walking a path down from the record: `shared` while no field
|
|
10649
|
+
* on it is translated, `root` once the field at its root is (the whole value, a list's items and all,
|
|
10650
|
+
* held per locale), `deep` once a field below the root is — inside a block, the item-by-item
|
|
10651
|
+
* translation no stored path names.
|
|
10652
|
+
*/
|
|
10653
|
+
type Translation = 'shared' | 'root' | 'deep';
|
|
10654
|
+
/** The translation below field `F`, which `Prefix` reaches, under the translation `T` above it. */
|
|
10655
|
+
type TranslationBelow<F, T extends Translation, Prefix extends string> = T extends 'shared' ? true extends SaysLocalized<F> ? Prefix extends '' ? 'root' : 'deep' : 'shared' : T;
|
|
10656
|
+
/**
|
|
10657
|
+
* One stored path a field's declaration holds, with what it is to a filter and the condition it
|
|
10658
|
+
* takes. A path several shapes declare is held once by each, and {@link FilterPaths} reads them
|
|
10659
|
+
* together, as the API does.
|
|
10660
|
+
*
|
|
10661
|
+
* - `field`: a value a filter compares, outside every block — at the top level or in an object.
|
|
10662
|
+
* - `reference`: a reference inside a block — named by the API's one path resolver, or, where a
|
|
10663
|
+
* shared list translates it item by item, by each locale's per-item resolution the write derives
|
|
10664
|
+
* (`itemRefs`, REL-2134).
|
|
10665
|
+
* - `richText`, `plainRichText`: rich text whose tree a filter asks for the entries it points at —
|
|
10666
|
+
* one that can point at an entry, or one that cannot.
|
|
10667
|
+
* - `blockValue`: any other value inside a block. `whole`: a list, an object, a table, code, or rich
|
|
10668
|
+
* text whose tree no stored path names, as a whole. `json`: a json field.
|
|
10669
|
+
*/
|
|
10670
|
+
interface Held<P extends string, Role extends string, Condition> {
|
|
10671
|
+
readonly path: P;
|
|
10672
|
+
readonly role: Role;
|
|
10673
|
+
readonly condition: Condition;
|
|
10674
|
+
}
|
|
10675
|
+
/**
|
|
10676
|
+
* A condition on a value that holds no date: {@link WhereFieldCondition} without `$inTheLast` and
|
|
10677
|
+
* `$inTheNext`, which the API asks of a date alone (`NotADateError`, REL-2195).
|
|
10678
|
+
*/
|
|
10679
|
+
type UndatedCondition<V> = WhereScalar<V> | WhereScalar<V>[] | Omit<WhereOperator<WhereScalar<V>>, DateOnlyOperator>;
|
|
10680
|
+
/** A reference, or rich text pointing at entries, compared with an entry id. */
|
|
10681
|
+
type EntryIdCondition = UndatedCondition<string>;
|
|
10682
|
+
/** What a record's fields hold, path by path, below `Prefix`. Distributes over the fields. */
|
|
10683
|
+
type HeldPaths<Fields, S, Prefix extends string = '', InItems extends boolean = false, T extends Translation = 'shared'> = Fields extends AnyFieldDefinition ? HeldBy<Fields, S, `${Prefix}${Fields['id']}`, InItems, T, TranslationBelow<Fields, T, Prefix>> : never;
|
|
10684
|
+
type HeldBy<F extends AnyFieldDefinition, S, Path extends string, InItems extends boolean, Above extends Translation, Below extends Translation> = F extends {
|
|
10685
|
+
readonly type: JsonKind;
|
|
10686
|
+
} ? Held<Path, 'json', never> : F extends {
|
|
10687
|
+
readonly type: ListKind;
|
|
10688
|
+
} ? Held<Path, 'whole', never> | HeldPaths<ShapeFields<F>, S, `${Path}.`, true, Below> : F extends {
|
|
10689
|
+
readonly type: ObjectKind;
|
|
10690
|
+
} ? Held<Path, 'whole', never> | HeldPaths<ShapeFields<F>, S, `${Path}.`, InItems, Below> : F extends {
|
|
10691
|
+
readonly type: RichTextKind;
|
|
10692
|
+
} ? RichTextNamed<F, InItems, Above, Below> extends true ? Held<Path, true extends IsLinkingRichText<F> ? 'richText' : 'plainRichText', EntryIdCondition> : Held<Path, 'whole', never> : F extends {
|
|
10693
|
+
readonly type: ReferenceKind;
|
|
10694
|
+
} ? InItems extends true ? Held<Path, 'reference', EntryIdCondition> : Held<Path, 'field', FieldCondition<F, S>> : F['type'] extends FieldType ? FiltersByValue[F['type']] extends true ? InItems extends true ? Held<Path, 'blockValue', never> : Held<Path, 'field', FieldCondition<F, S>> : Held<Path, 'whole', never> : Held<Path, 'field', unknown>;
|
|
10695
|
+
/**
|
|
10696
|
+
* A field's own condition: one of the values it holds (`WhereScalar`), as its read types them — and,
|
|
10697
|
+
* where it holds a date, a span back or forward from the read (`$inTheLast`, `$inTheNext`).
|
|
10698
|
+
*/
|
|
10699
|
+
type FieldCondition<F extends AnyFieldDefinition, S> = F extends {
|
|
10700
|
+
readonly type: DateKind;
|
|
10701
|
+
} ? WhereFieldCondition<FieldValue<F, S extends FieldSchemaContext ? S : undefined>> : UndatedCondition<FieldValue<F, S extends FieldSchemaContext ? S : undefined>>;
|
|
10702
|
+
/**
|
|
10703
|
+
* Whether a filter names rich text's trees: shared, translated with the field at the root of the
|
|
10704
|
+
* path, translated itself outside every block, or translated item by item inside a list, which each
|
|
10705
|
+
* locale's per-item resolution names (`itemRefs`, REL-2134) — never translated by an object between
|
|
10706
|
+
* the root and it outside every list, which nothing names (`nameableRichText`).
|
|
10707
|
+
*/
|
|
10708
|
+
type RichTextNamed<F, InItems extends boolean, Above extends Translation, Below extends Translation> = Below extends 'shared' | 'root' ? true : InItems extends true ? true : Above extends 'shared' ? true extends SaysLocalized<F> ? true : false : false;
|
|
10709
|
+
/**
|
|
10710
|
+
* Whether a filter names a path its declarations hold as `Roles` — the API's one filter check
|
|
10711
|
+
* (`assertFilterableInBlocks`, REL-1810, REL-1811, REL-2135), read in its order: a json field
|
|
10712
|
+
* anywhere at the path refuses it; rich text every declaration of which a stored path names, one of
|
|
10713
|
+
* them pointing at entries, is filtered by them; a reference inside a block that no other value there
|
|
10714
|
+
* shares the path with is; outside every block, a value a filter compares is, unless a whole value
|
|
10715
|
+
* shares the path.
|
|
10716
|
+
*/
|
|
10717
|
+
type Admits<Roles> = 'json' extends Roles ? false : [Roles] extends ['richText' | 'plainRichText'] ? 'richText' extends Roles ? true : false : 'reference' extends Roles ? 'blockValue' extends Roles ? false : true : [Roles] extends ['field'] ? true : false;
|
|
10718
|
+
type PathsOf<H> = H extends Held<infer P, string, unknown> ? P : never;
|
|
10719
|
+
type RolesAt<H, P extends string> = H extends Held<P, infer Role, unknown> ? Role : never;
|
|
10720
|
+
type AdmittedPaths<H, P = PathsOf<H>> = P extends string ? Admits<RolesAt<H, P>> extends true ? P : never : never;
|
|
10721
|
+
/**
|
|
10722
|
+
* The conditions a typed read's `where` takes, by path (REL-2136): exactly the keys the API filters
|
|
10723
|
+
* by, each taking the condition the value at it does.
|
|
10724
|
+
*
|
|
10725
|
+
* - A field a filter compares, at the top level or in an object, by its path — `title`,
|
|
10726
|
+
* `'pricing.basePrice'` — taking one of the values it holds, a list of them, or operators.
|
|
10727
|
+
* - A reference inside a block, at any depth (`'sections.features'`, REL-1810), and rich text that
|
|
10728
|
+
* can point at an entry, at the top level or inside one (`body`, `'sections.text'`), each compared
|
|
10729
|
+
* with an entry id: some block or tree points at it.
|
|
10730
|
+
*
|
|
10731
|
+
* And no other key: a json field or a key inside one, a list, an object, a table, code, rich text
|
|
10732
|
+
* that points at nothing, any value inside a block but a reference, a reference or rich text a shared
|
|
10733
|
+
* list translates item by item, or `_metadata` — each refused by the API by name, and here by the
|
|
10734
|
+
* compiler. A read no schema types names any key, and the API holds it to the deployed schema.
|
|
10735
|
+
*/
|
|
10736
|
+
type FilterPaths<Fields, S> = {
|
|
10737
|
+
[P in AdmittedPaths<HeldPaths<Fields, S>>]?: Extract<HeldPaths<Fields, S>, {
|
|
10738
|
+
readonly path: P;
|
|
10739
|
+
}>['condition'];
|
|
10740
|
+
};
|
|
10741
|
+
/**
|
|
10742
|
+
* A read's `where`: {@link FilterPaths} where a schema types the read (`R['where']`), and `W`, the
|
|
10743
|
+
* conditions its record's own keys take, where none does.
|
|
10744
|
+
*/
|
|
10745
|
+
type ReadWhere<W, R> = R extends {
|
|
10746
|
+
readonly where: infer C;
|
|
10747
|
+
} ? C : W;
|
|
10748
|
+
/** The path part of a written path, and what its parentheses pick. */
|
|
10749
|
+
type PathOf<X extends string> = X extends `${infer Path}(${string})` ? Path : X;
|
|
10750
|
+
type PickedOf<X extends string> = X extends `${string}(${infer Picked})` ? Picked : never;
|
|
10751
|
+
/**
|
|
10752
|
+
* `X` when it is a path the record `Root` can include; otherwise the paths it can include at the
|
|
10753
|
+
* point `X` went wrong, which is what the compiler names: `Type '"sections.title"' is not
|
|
10754
|
+
* assignable to type '"ogImage" | "sections" | "sections.features" | …'`.
|
|
10755
|
+
*/
|
|
10756
|
+
type CheckInclude<Root, S, X extends string> = Walk<Root, Root, S, PathOf<X>, PickedOf<X>, '', ''> extends true ? X : Walk<Root, Root, S, PathOf<X>, PickedOf<X>, '', ''>;
|
|
10757
|
+
/** The paths `Root` can include, written after `Entry` — the path up to the entry they belong to. */
|
|
10758
|
+
type Suggest<Root, Entry extends string> = IncludablePaths<Root, Entry>;
|
|
10759
|
+
type Walk<Fields, Root, S, Rest extends string, Picked extends string, Done extends string, Entry extends string> = Rest extends `${infer Segment}.${infer Tail}` ? Step<Extract<Fields, {
|
|
10760
|
+
readonly id: Segment;
|
|
10761
|
+
}>, Root, S, Segment, Tail, Picked, Done, Entry> : Step<Extract<Fields, {
|
|
10762
|
+
readonly id: Rest;
|
|
10763
|
+
}>, Root, S, Rest, '', Picked, Done, Entry>;
|
|
10764
|
+
type Step<F, Root, S, Segment extends string, Tail extends string, Picked extends string, Done extends string, Entry extends string> = [F] extends [never] ? Suggest<Root, Entry> : true extends IsReference<F> ? Tail extends '' ? [Picked] extends [never] ? true : CheckPicked<TargetFields<Extract<F, {
|
|
10765
|
+
readonly type: ReferenceKind;
|
|
10766
|
+
}>, S>, Picked, `${Done}${Segment}`> : Walk<TargetFields<Extract<F, {
|
|
10767
|
+
readonly type: ReferenceKind;
|
|
10768
|
+
}>, S>, TargetFields<Extract<F, {
|
|
10769
|
+
readonly type: ReferenceKind;
|
|
10770
|
+
}>, S>, S, Tail, Picked, `${Done}${Segment}.`, `${Done}${Segment}.`> : true extends IsLinkingRichText<F> ? Tail extends '' ? [Picked] extends [never] ? true : CheckPicked<RichTextTargetFields<F, S>, Picked, `${Done}${Segment}`> : Walk<RichTextTargetFields<F, S>, RichTextTargetFields<F, S>, S, Tail, Picked, `${Done}${Segment}.`, `${Done}${Segment}.`> : true extends HoldsReference<ShapeFields<F>> ? Tail extends '' ? [Picked] extends [never] ? true : Suggest<Root, Entry> : Walk<ShapeFields<F>, Root, S, Tail, Picked, `${Done}${Segment}.`, Entry> : Suggest<Root, Entry>;
|
|
10771
|
+
/** `true` when every picked field is one the reached entry declares; otherwise each pick it could. */
|
|
10772
|
+
type CheckPicked<Target, Picked extends string, Path extends string> = [
|
|
10773
|
+
Exclude<Split<Picked>, Target extends AnyFieldDefinition ? Target['id'] : never>
|
|
10774
|
+
] extends [never] ? true : `${Path}(${Target extends AnyFieldDefinition ? Target['id'] : never})`;
|
|
10775
|
+
/**
|
|
10776
|
+
* How one read is typed by the include paths it names — a type-level function, applied with
|
|
10777
|
+
* {@link ReadWith} and {@link CheckedInclude}. Each typed client carries the one for its type.
|
|
10778
|
+
*/
|
|
10779
|
+
interface Reading {
|
|
10780
|
+
/** The include paths the read names (set by {@link ReadWith}). */
|
|
10781
|
+
readonly include: string;
|
|
10782
|
+
/** One path to check (set by {@link CheckedInclude}). */
|
|
10783
|
+
readonly path: string;
|
|
10784
|
+
/** What the read returns under `include`. */
|
|
10785
|
+
readonly read: unknown;
|
|
10786
|
+
/** `path` when it holds, or the paths that would. */
|
|
10787
|
+
readonly checked: unknown;
|
|
10788
|
+
}
|
|
10789
|
+
/** What a read typed by `R` returns under the include paths `I`. */
|
|
10790
|
+
type ReadWith<R extends Reading, I extends string> = (R & {
|
|
10791
|
+
readonly include: I;
|
|
10792
|
+
})['read'];
|
|
10793
|
+
/** `X` when `R`'s type can include it, or the paths it can. */
|
|
10794
|
+
type CheckedInclude<R extends Reading, X extends string> = (R & {
|
|
10795
|
+
readonly path: X;
|
|
10796
|
+
})['checked'];
|
|
10797
|
+
/**
|
|
10798
|
+
* A path as written: inferred from the argument, never from what checking it answers. TypeScript's
|
|
10799
|
+
* own `NoInfer` does this from 5.4; this is the form every version the package supports reads.
|
|
10800
|
+
*/
|
|
10801
|
+
type Written<X> = [X][X extends unknown ? 0 : never];
|
|
10802
|
+
/**
|
|
10803
|
+
* An `include()` argument, each path checked against the type. A path the type cannot see — a
|
|
10804
|
+
* `string` — is taken as written, and the read typed as if it may expand anything.
|
|
10805
|
+
*/
|
|
10806
|
+
type CheckedIncludes<R extends Reading, P extends readonly string[]> = {
|
|
10807
|
+
readonly [K in keyof P]: string extends P[K] ? P[K] : CheckedInclude<R, Written<P[K]>>;
|
|
10808
|
+
};
|
|
10809
|
+
/** A read no schema types: it returns `T` whatever it includes, and any path is taken as written. */
|
|
10810
|
+
interface UntypedReading<T> extends Reading {
|
|
10811
|
+
readonly read: T;
|
|
10812
|
+
readonly checked: this['path'];
|
|
10813
|
+
}
|
|
10814
|
+
/** A read of the content type `D` defines, in schema `S`. */
|
|
10815
|
+
interface ContentReading<D extends AnyContentTypeDefinition, S extends FieldSchemaContext | undefined> extends Reading {
|
|
10816
|
+
readonly read: InferContentType<D, S, this['include']>;
|
|
10817
|
+
readonly checked: CheckInclude<FieldsOfDefinition<D>, S, this['path']>;
|
|
10818
|
+
/** What its `where` takes: every key the API filters it by ({@link FilterPaths}, REL-2136). */
|
|
10819
|
+
readonly where: FilterPaths<FieldsOfDefinition<D>, S>;
|
|
10820
|
+
}
|
|
10821
|
+
/** A read of the singleton `D` defines, in schema `S`. */
|
|
10822
|
+
interface SingletonReading<D extends AnySingletonContentTypeDefinition, S extends FieldSchemaContext | undefined> extends Reading {
|
|
10823
|
+
readonly read: InferSingletonContentType<D, S, this['include']>;
|
|
10824
|
+
readonly checked: CheckInclude<FieldsOfDefinition<D>, S, this['path']>;
|
|
10825
|
+
}
|
|
10826
|
+
/** A read of the asset type `D` defines, in schema `S`. */
|
|
10827
|
+
interface AssetReading<D extends AnyAssetTypeDefinition, S extends FieldSchemaContext | undefined> extends Reading {
|
|
10828
|
+
readonly read: InferAssetType<D, S, this['include']>;
|
|
10829
|
+
readonly checked: CheckInclude<FieldsOfDefinition<D>, S, this['path']>;
|
|
10830
|
+
/**
|
|
10831
|
+
* What its `where` takes: every key the API filters its fields by, as a content type's
|
|
10832
|
+
* ({@link FilterPaths}) — an asset is an entry on the same routes, held to the same check (REL-2195).
|
|
10833
|
+
* Its `fields` are optional, so they are read with `DeclaredFields`, which takes them so.
|
|
10834
|
+
*/
|
|
10835
|
+
readonly where: FilterPaths<DeclaredFields<D>, S>;
|
|
10836
|
+
}
|
|
10837
|
+
/** A read of the settings group `D` defines, in schema `S`. */
|
|
10838
|
+
interface SettingsReading<D extends AnySettingsGroupDefinition, S extends FieldSchemaContext | undefined> extends Reading {
|
|
10839
|
+
readonly read: InferSettingsGroup<D, S, this['include']>;
|
|
10840
|
+
readonly checked: CheckInclude<FieldsOfDefinition<D>, S, this['path']>;
|
|
10841
|
+
}
|
|
10842
|
+
|
|
10843
|
+
export { tags as $, type AIConfig as A, type BaseFieldConfig as B, type CodeConfig as C, type DateConfig as D, type EmailConfig as E, type FieldAIConfig as F, email as G, enumField as H, type IntegerConfig as I, type JsonConfig as J, integer as K, type ListConfig as L, json as M, list as N, type ObjectConfig as O, longText as P, object as Q, type ReadOnlyRule as R, type ShortTextConfig as S, type TableConfig as T, type UrlConfig as U, type ValidationRule$1 as V, reference as W, richText as X, shortText as Y, slug as Z, table as _, type AnyFieldDefinition as a, defineWorkflow as a$, url as a0, type FieldSchemaContext as a1, type FieldValue as a2, type FieldValues as a3, type DeclaredFields as a4, type UnresolvedEntry as a5, type Keyed as a6, type BlockOf as a7, type ShapeValue as a8, type AssetReading as a9, type SettingsGroupConfig as aA, type SettingsGroupDefinition as aB, type SettingsGroupMetadata as aC, type InferSettingsGroup as aD, defineAssetType as aE, type AssetTypeConfig as aF, type AssetTypeDefinition as aG, type InferAssetType as aH, type InferAssetEntry as aI, type AssetServedBlocks as aJ, type ImageKindConfig as aK, type VideoKindConfig as aL, type FileKindConfig as aM, type ImageTransform as aN, type ImageFitMode as aO, type ImageOutputFormat as aP, type ImageUploadConfig as aQ, type ImageSourceConfig as aR, type ImageExifConfig as aS, type VariantDefinition as aT, type VideoUploadConfig as aU, type VideoPosterConfig as aV, type VideoCaptionsConfig as aW, type VideoDownloadConfig as aX, type VideoWatermarkConfig as aY, type FileUploadConfig as aZ, type FileScanConfig as a_, type CheckedIncludes as aa, type CheckInclude as ab, type ContentReading as ac, type IncludablePaths as ad, type Reading as ae, type ReadWith as af, type SettingsReading as ag, type SingletonReading as ah, type UntypedReading as ai, defineContentType as aj, fieldset as ak, type Fieldset as al, type FieldMember as am, type ContentTypeConfig as an, type ContentTypeDefinition as ao, type EntryMetadata as ap, type InferContentType as aq, type LocalePublicationFields as ar, defineSingletonContentType as as, defineSingleton as at, type SingletonConfig as au, type SingletonContentTypeDefinition as av, type SingletonMetadata as aw, type InferSingletonContentType as ax, type InferSingleton as ay, defineSettingsGroup as az, type AssetAIConfig as b, type FieldTypeName as b$, defineWorkflowStage as b0, defineContentTypeWorkflow as b1, isWorkflowDefinition as b2, isWorkflowStageDefinition as b3, getWorkflowStageIds as b4, findWorkflowStage as b5, getNextWorkflowStage as b6, getFirstWorkflowStage as b7, isFinalWorkflowStage as b8, type WorkflowEscalation as b9, type LiveWebSocket as bA, type LiveWebSocketConstructor as bB, type ApiPath as bC, type ApiMethod as bD, type ApiSuccessBody as bE, type Wire as bF, matchRoute as bG, type RouteMatch as bH, type MatchRouteOptions as bI, type AssetFileBlock as bJ, type AssetUrls as bK, type BaseContent as bL, type WhereScalar as bM, type WhereFieldCondition as bN, type WhereClause as bO, type WhereOperator as bP, type DateOnlyOperator as bQ, type SortOptions as bR, type QueryOptions as bS, type CreateInput as bT, type RevisedContent as bU, type RestoredContent as bV, type UpdateInput as bW, type ContentQueryResult as bX, type SingletonContent as bY, type CustomQuery as bZ, type ContentTypeSchema as b_, type WorkflowAutoAssign as ba, type WorkflowStageConfig as bb, type WorkflowStageDefinition as bc, type WorkflowConfig as bd, type WorkflowDefinition as be, type ContentTypeWorkflowConfig as bf, defineView as bg, type ViewScopeConfig as bh, type ContentTypeScopeConfig as bi, type ContentTypesScopeConfig as bj, type EntryTypeScopeConfig as bk, type AllScopeConfig as bl, type ViewFilterOperator as bm, type ViewFilterValue as bn, type ViewFilterRelativeDate as bo, type ViewFilterCondition as bp, type ViewFilter as bq, type ViewConfig as br, type ViewDefinition as bs, type InferJsonSchema as bt, type JsonFieldValue as bu, type JsonSchema as bv, type JsonValue as bw, SDKError as bx, type RelyIOConfig as by, type RelyIOConfigUpdate as bz, type BooleanConfig as c, type ValidationRule as c0, type FieldOptions as c1, type RealtimeEventType as c2, type RealtimeEvent as c3, type SubscriptionOptions as c4, type PerformanceMetrics as c5, type CacheConfig as c6, type RealtimeConfig as c7, type DebugConfig as c8, type RequestConfig as c9, type ApiResponse as ca, type RetryConfig as cb, type CacheStrategy as cc, type LogLevel as cd, type Environment as ce, type ValidationViolation as cf, BaseValidationError as cg, ValidationError as ch, InvalidPayloadError as ci, type MergedRelyIOConfig as cj, type PathParamsOf as ck, type ReadWhere as cl, type CheckedInclude as cm, type components as cn, type paths as co, type FieldDefinition as cp, type DateTimeConfig as d, type DecimalConfig as e, type EnumConfig as f, type FieldDefinition$1 as g, type FieldRule as h, type FieldType as i, type FieldUIConfig as j, type LocalizationConfig as k, type LongTextConfig as l, type ReferenceConfig as m, type RequirementRule as n, type RichTextConfig as o, type RichTextLinks as p, type RuleCondition as q, type RuleConditions as r, type SlugConfig as s, type TagsConfig as t, type VisibilityRule as u, boolean as v, code as w, date as x, dateTime as y, decimal as z };
|