@voltro/cms 0.83.1 → 0.85.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/dist/web.d.ts CHANGED
@@ -1,10 +1,19 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { Row } from '@voltro/database';
3
3
  import { Schema as Schema_2 } from 'effect';
4
+ import { YieldableError } from 'effect/Cause';
4
5
 
5
6
  /** A document's address in every language it has its own variant in. */
6
7
  export declare const alternatesOf: (trees: ReadonlyArray<LocalizedTree>, documentId: string) => ReadonlyArray<PageAlternate>;
7
8
 
9
+ export declare type AppliedSelection = {
10
+ readonly ok: true;
11
+ readonly values: Readonly<Record<string, unknown>>;
12
+ } | {
13
+ readonly ok: false;
14
+ readonly reason: 'otherIntent' | 'otherDocument' | 'revisionMoved' | 'targetGone';
15
+ };
16
+
8
17
  /**
9
18
  * Compute every `derivedFrom` field from its source value. Returns a NEW
10
19
  * row — the input is not mutated. A caller-provided value for a derived
@@ -15,6 +24,19 @@ export declare const alternatesOf: (trees: ReadonlyArray<LocalizedTree>, documen
15
24
  */
16
25
  export declare const applyDerivations: (type: Pick<ContentType, "fields" | "derivedFields"> & Partial<Pick<ContentType, "taxonomy">>, row: Readonly<Record<string, unknown>>) => Record<string, unknown>;
17
26
 
27
+ /**
28
+ * The values with the answer applied where the intent said: a field takes the
29
+ * chosen document; a placed component's prop takes it; an image block takes it
30
+ * as its asset; a paragraph or a heading gets a link to it over the selected
31
+ * text. Refused for another intent, another document or form, a revision that
32
+ * moved on, or a block or component that is gone.
33
+ */
34
+ export declare const applySelection: (values: Readonly<Record<string, unknown>>, intent: SelectionIntent, answer: SelectionAnswer, now: {
35
+ readonly documentId?: string | null;
36
+ readonly revisionId?: string | null;
37
+ readonly formId?: string;
38
+ }) => AppliedSelection;
39
+
18
40
  /**
19
41
  * The source values with each unit's target in place — what a translation
20
42
  * draft saves. A unit without a target keeps the source text; an id that
@@ -22,6 +44,18 @@ export declare const applyDerivations: (type: Pick<ContentType, "fields" | "deri
22
44
  */
23
45
  export declare const applyTranslation: (fields: Readonly<Record<string, FieldSchema>>, source: Readonly<Record<string, unknown>>, units: ReadonlyArray<TranslationUnit>) => Record<string, unknown>;
24
46
 
47
+ /**
48
+ * Attribute per-day values (`YYYY-MM-DD`, UTC) to the revision live at the end
49
+ * of each day. A day when nothing was live is left out (`unattributed`).
50
+ */
51
+ export declare const attributeToRevisions: (timeline: ReadonlyArray<LiveStretch>, daily: ReadonlyArray<{
52
+ readonly day: string;
53
+ readonly value: number;
54
+ }>) => {
55
+ readonly shares: ReadonlyArray<RevisionShare>;
56
+ readonly unattributed: number;
57
+ };
58
+
25
59
  export declare interface Audience {
26
60
  readonly id: string;
27
61
  /** Raise it when the rule changes meaning; a variant records the version it was written for. */
@@ -56,8 +90,26 @@ declare interface AvailabilityConfig {
56
90
  readonly until?: string;
57
91
  /** A boolean field: `true` withdraws the document at once. */
58
92
  readonly blocked?: string;
93
+ /** A date or datetime field: usable from this moment on. */
94
+ readonly from?: string;
95
+ /** A list-of-text field of territory codes (ISO 3166-1 alpha-2): usable only there. Empty: everywhere. */
96
+ readonly territories?: string;
97
+ /** A list-of-text field of channels (`web`, `app`, `print`, …): usable only on these. Empty: on every channel. */
98
+ readonly channels?: string;
99
+ /** A list-of-text field of purposes (`editorial`, `advertising`, …): usable only for these. Empty: for every purpose. */
100
+ readonly purposes?: string;
59
101
  }
60
102
 
103
+ /** Whether a block, or any text in it, holds a suggestion. */
104
+ export declare const blockHasChanges: (block: RichBlock) => boolean;
105
+
106
+ /**
107
+ * The markup a block is edited as: text blocks are one run, a list one line
108
+ * per item (two spaces of indent per level), a table one line per row with
109
+ * cells split by `|`; an image or a component has none.
110
+ */
111
+ export declare const blockMarkup: (block: RichBlock) => string;
112
+
61
113
  /**
62
114
  * Arrange one variant per document into a tree. `entries` holds at most one
63
115
  * entry per `documentId` (the first one wins). A node without a segment is
@@ -65,9 +117,77 @@ declare interface AvailabilityConfig {
65
117
  */
66
118
  export declare const buildTree: (entries: ReadonlyArray<TreeEntry>, config: TreeConfig) => CmsTree;
67
119
 
120
+ /** What a route's response depends on — declared once, read by every cache in front of it. */
121
+ export declare interface CacheContract {
122
+ /** The route pattern (`/v1/site/page`), the purge selector's route class. */
123
+ readonly route: string;
124
+ readonly query?: ReadonlyArray<QueryParam>;
125
+ /** The language, from a bounded set — never the raw `Accept-Language`. */
126
+ readonly locale?: CacheDimension;
127
+ /** Declared audiences or experiment cohorts the output differs by. */
128
+ readonly audience?: CacheDimension;
129
+ /** The reader's consent decision class — only when the output really varies by it. */
130
+ readonly consent?: CacheDimension;
131
+ /** Cookies and headers that make a response private when present (a session, a preview token). */
132
+ readonly credentials?: ReadonlyArray<string>;
133
+ /** The most variants one route may fan out to. Default 64. */
134
+ readonly cardinalityBudget?: number;
135
+ }
136
+
137
+ /** A bounded request dimension: where it is read from, and its values. */
138
+ export declare interface CacheDimension {
139
+ /** A request header (lowercase) or a cookie (`cookie:<name>`). */
140
+ readonly from: string;
141
+ readonly values: ReadonlyArray<string>;
142
+ /** Taken when the request names none, or one not in `values`. */
143
+ readonly fallback: string;
144
+ }
145
+
146
+ export declare type CacheIdentity = {
147
+ readonly cacheable: true;
148
+ /** The canonical identity — every dimension in a fixed order. */
149
+ readonly key: string;
150
+ /** A short, stable fingerprint of `key`. */
151
+ readonly fingerprint: string;
152
+ readonly vary: ReadonlyArray<string>;
153
+ /** What a purge of this response names: the route class and its tags. */
154
+ readonly purge: {
155
+ readonly route: string;
156
+ readonly tags: ReadonlyArray<string>;
157
+ };
158
+ readonly variants: number;
159
+ readonly explain: ReadonlyArray<ExplainLine>;
160
+ } | {
161
+ readonly cacheable: false;
162
+ readonly reason: 'method' | 'credential' | 'path' | 'budget';
163
+ readonly detail: string;
164
+ /** A refused or private request is never stored by a shared cache. */
165
+ readonly cacheControl: 'private, no-store';
166
+ readonly explain: ReadonlyArray<ExplainLine>;
167
+ };
168
+
169
+ export declare interface CacheRequest {
170
+ readonly method: string;
171
+ readonly host: string;
172
+ /** The path as received, still encoded. */
173
+ readonly path: string;
174
+ /** The query string without `?`. */
175
+ readonly query: string;
176
+ readonly headers: Readonly<Record<string, string | undefined>>;
177
+ }
178
+
179
+ /** Who suggests the edit, and when; `id` names the change. */
180
+ export declare type ChangeAuthor = Omit<RichChange, 'kind'>;
181
+
182
+ /** What to do with one suggestion. */
183
+ export declare type ChangeDecision = 'accept' | 'reject' | 'keep';
184
+
68
185
  /** The declared fields whose values differ between `before` and `after`, in declaration order. */
69
186
  export declare const changedFields: (fields: Readonly<Record<string, unknown>>, before: Readonly<Record<string, unknown>>, after: Readonly<Record<string, unknown>>) => ReadonlyArray<string>;
70
187
 
188
+ /** Throws for a vendor origin that is not exactly `https://host[:port]` — it would widen the policy. */
189
+ export declare const checkConsentPurposes: (purposes: ReadonlyArray<ConsentPurpose>) => void;
190
+
71
191
  /** Throws when a declaration cannot work: fields missing or of the wrong kind, a component the field does not allow. */
72
192
  export declare const checkTemplates: (name: string, fields: Readonly<Record<string, FieldSchema>>, config: TemplatesConfig) => void;
73
193
 
@@ -86,6 +206,20 @@ export declare interface CmsExtensionManifest {
86
206
  readonly settings?: ReadonlyArray<ExtensionSetting>;
87
207
  }
88
208
 
209
+ /**
210
+ * Where a content row lives besides its tenant: the site it belongs to, the
211
+ * content environment (e.g. `production`, `staging`) and its locale. Three
212
+ * separate axes, stored on every draft, published row and revision, and
213
+ * required by every write and read — never taken from a caller's free-form
214
+ * filter. The tenant comes from the request subject (`tenant()`).
215
+ */
216
+ declare interface CmsScope {
217
+ readonly site: string;
218
+ readonly environment: string;
219
+ /** A BCP 47 tag, e.g. `en-GB`. */
220
+ readonly locale: string;
221
+ }
222
+
89
223
  /** A built tree: every routable node, depth-first, siblings in order. */
90
224
  export declare interface CmsTree {
91
225
  readonly nodes: ReadonlyArray<TreeNode>;
@@ -103,6 +237,19 @@ export declare type CmsWriteError = ContentValidationFailed | ContentNotFound |
103
237
  /** Order of two `major.minor.patch` versions: negative, 0 or positive. */
104
238
  export declare const compareVersions: (a: string, b: string) => number;
105
239
 
240
+ /**
241
+ * The identity of `request` under `contract` at publication `checkpoint` (a
242
+ * release or publication id), with the document tags its response depends on.
243
+ */
244
+ export declare const compileCacheIdentity: (contract: CacheContract, request: CacheRequest, context: {
245
+ readonly checkpoint: string;
246
+ readonly tags?: ReadonlyArray<string>;
247
+ }) => CacheIdentity;
248
+
249
+ declare type ComponentBlock = Extract<RichBlock, {
250
+ readonly type: 'component';
251
+ }>;
252
+
106
253
  /**
107
254
  * A component editors compose pages from (ADR-CMS-015): a stable `id`, a
108
255
  * display name and typed props. The frontend renders it; the CMS validates
@@ -114,10 +261,29 @@ export declare interface ComponentDefinition {
114
261
  readonly displayName: string;
115
262
  readonly props: Readonly<Record<string, FieldSchema>>;
116
263
  readonly fingerprint: string;
264
+ /** What it is for, in an editor's words — searched by the picker. */
265
+ readonly description?: string;
266
+ /** The editorial jobs it serves (`'announce an event'`, `'collect leads'`) — the picker groups and searches by them. */
267
+ readonly jobs?: ReadonlyArray<string>;
268
+ /** Named presets an editor starts from (`dark`, `compact`): props that differ from empty. */
269
+ readonly variants?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
270
+ /** Example props — previews, galleries and tests render them; checked against `props` when a content type uses the component. */
271
+ readonly fixtures?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
272
+ /** Upgrades of instances saved against an earlier definition: its fingerprint → the props it becomes now. */
273
+ readonly migrations?: Readonly<Record<string, (props: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>>>>;
117
274
  /** The consent purpose a reader must grant before this component's props reach them (`gateConsent`). */
118
275
  readonly consent?: string;
119
276
  }
120
277
 
278
+ /** A component's fixtures and variants against its props: every violation, with the fixture or variant it is in. */
279
+ export declare const componentExampleViolations: (definition: ComponentDefinition) => ReadonlyArray<FieldViolation>;
280
+
281
+ /** The fingerprint a component with these props has — to key a migration from an earlier definition. */
282
+ export declare const componentFingerprint: (spec: {
283
+ readonly id: string;
284
+ readonly props: Readonly<Record<string, FieldSchema | PipeableField>>;
285
+ }) => string;
286
+
121
287
  /** One placed component in a `components` field, as stored. */
122
288
  export declare interface ComponentInstance {
123
289
  /** Stable across saves, reorders and translations of the same placement. */
@@ -131,6 +297,17 @@ export declare interface ComponentInstance {
131
297
  /** A reader's choices: purpose id → the version they allowed. */
132
298
  export declare type ConsentChoices = Readonly<Record<string, number>>;
133
299
 
300
+ /**
301
+ * The same decision as {@link gateConsent}, for the browser to enforce: a
302
+ * Content-Security-Policy whose `frame-src` lets in only this origin and the
303
+ * vendors the reader granted. Set it on the response (a web middleware) and
304
+ * an embed the reader refused cannot load even if one slipped into the page.
305
+ */
306
+ export declare const consentContentSecurityPolicy: (purposes: ReadonlyArray<ConsentPurpose>, choices: ConsentChoices, base?: string) => string;
307
+
308
+ /** The origins of the vendors whose purpose the reader granted in its current version. */
309
+ export declare const consentedOrigins: (purposes: ReadonlyArray<ConsentPurpose>, choices: ConsentChoices) => ReadonlyArray<string>;
310
+
134
311
  /** Something a reader can allow or refuse. */
135
312
  export declare interface ConsentPurpose {
136
313
  readonly id: string;
@@ -138,8 +315,31 @@ export declare interface ConsentPurpose {
138
315
  readonly version: number;
139
316
  readonly displayName: string;
140
317
  readonly description: string;
318
+ /** The third parties it lets in (none for a first-party purpose). */
319
+ readonly vendors?: ReadonlyArray<ConsentVendor>;
320
+ }
321
+
322
+ /**
323
+ * A third party a purpose lets in — kept apart from the purpose itself: who
324
+ * it is, where its content comes from (the origins a page may then load), what
325
+ * it stores on the reader's device, and what it does with the data.
326
+ */
327
+ export declare interface ConsentVendor {
328
+ /** camelCase, unique within the purpose — what a reader-facing text is keyed by. */
329
+ readonly id: string;
330
+ readonly name: string;
331
+ /** `https://host` origins, exactly — the browser loads frames from them once the purpose is granted. */
332
+ readonly origins: ReadonlyArray<string>;
333
+ readonly storage: string;
334
+ readonly dataUse: string;
141
335
  }
142
336
 
337
+ /** The `href` of a one-off contact: `mailto:` an address, `tel:` a number without its spacing. */
338
+ export declare const contactLiteralHref: (channel: "email" | "phone", value: string) => string;
339
+
340
+ /** Why `value` is not a usable one-off e-mail address or phone number, or null when it is. */
341
+ export declare const contactLiteralProblem: (channel: "email" | "phone", value: string) => string | null;
342
+
143
343
  export declare const CONTENT_FORM_STRINGS: ContentFormStrings;
144
344
 
145
345
  /**
@@ -189,6 +389,11 @@ export declare interface ContentFormProps {
189
389
  readonly strings?: ContentFormStringsInput;
190
390
  /** How rich text's paragraphs and headings are edited — see `RichDocumentEditorProps.surface`. */
191
391
  readonly richTextSurface?: 'markup' | 'visual';
392
+ /**
393
+ * Where each field's value lives, for its widget's `target`; by default the
394
+ * field itself. A placed component's props form names its instance and prop.
395
+ */
396
+ readonly widgetTarget?: (name: string) => WidgetTarget;
192
397
  }
193
398
 
194
399
  export declare interface ContentFormStrings {
@@ -204,6 +409,11 @@ export declare interface ContentFormStrings {
204
409
  readonly add: string;
205
410
  readonly addBlock: string;
206
411
  readonly addComponent: string;
412
+ /** The search above the component picker. */
413
+ readonly findComponent: string;
414
+ readonly noComponentFound: string;
415
+ /** The group of components that name no job. */
416
+ readonly otherComponents: string;
207
417
  readonly unknownComponent: (componentId: string) => string;
208
418
  readonly level: string;
209
419
  readonly numbered: string;
@@ -211,6 +421,10 @@ export declare interface ContentFormStrings {
211
421
  readonly numberedAt: (depth: number) => string;
212
422
  readonly headerRow: string;
213
423
  readonly image: string;
424
+ /** The label of a download block's file. */
425
+ readonly file: string;
426
+ /** The label of the text a download block's link shows. */
427
+ readonly fileLabel: string;
214
428
  readonly caption: string;
215
429
  readonly text: string;
216
430
  readonly listItems: string;
@@ -226,6 +440,27 @@ export declare interface ContentFormStrings {
226
440
  readonly bold: string;
227
441
  readonly italic: string;
228
442
  readonly underline: string;
443
+ /** A block's or a selection's named style (a rich-text profile's styles). */
444
+ readonly style: string;
445
+ readonly noStyle: string;
446
+ /** Which component a component block places. */
447
+ readonly component: string;
448
+ /** The contact inserter: a published contact point, or a one-off address or number. */
449
+ readonly contactKind: string;
450
+ readonly contactPoint: string;
451
+ readonly contactEmail: string;
452
+ readonly contactPhone: string;
453
+ readonly contactValue: string;
454
+ readonly contactText: string;
455
+ readonly insertContact: string;
456
+ /** Above a block holding suggested changes; it is edited again once they are decided. */
457
+ readonly suggestedChanges: string;
458
+ /** One suggestion: who made it, what it puts in and takes out. */
459
+ readonly changeBy: (by: string, inserted: string, deleted: string) => string;
460
+ readonly accept: string;
461
+ readonly reject: string;
462
+ readonly acceptLabel: (by: string) => string;
463
+ readonly rejectLabel: (by: string) => string;
229
464
  }
230
465
 
231
466
  /** The defaults with an app's words over them. */
@@ -281,13 +516,11 @@ export declare interface ContentfulNode {
281
516
  export declare class ContentGone extends ContentGone_base {
282
517
  }
283
518
 
284
- declare const ContentGone_base: Schema_2.TaggedErrorClass<ContentGone, "ContentGone", {
285
- readonly _tag: Schema_2.tag<"ContentGone">;
286
- } & {
287
- contentType: typeof Schema_2.String;
519
+ declare const ContentGone_base: Schema_2.Class<ContentGone, Schema_2.TaggedStruct<"ContentGone", {
520
+ readonly contentType: Schema_2.String;
288
521
  /** The address asked for. */
289
- path: typeof Schema_2.String;
290
- }>;
522
+ readonly path: Schema_2.String;
523
+ }>, YieldableError>;
291
524
 
292
525
  /**
293
526
  * Raised by `saveDraft` when the caller supplies an explicit `id` that
@@ -298,12 +531,10 @@ declare const ContentGone_base: Schema_2.TaggedErrorClass<ContentGone, "ContentG
298
531
  export declare class ContentIdConflict extends ContentIdConflict_base {
299
532
  }
300
533
 
301
- declare const ContentIdConflict_base: Schema_2.TaggedErrorClass<ContentIdConflict, "ContentIdConflict", {
302
- readonly _tag: Schema_2.tag<"ContentIdConflict">;
303
- } & {
304
- contentType: typeof Schema_2.String;
305
- id: typeof Schema_2.String;
306
- }>;
534
+ declare const ContentIdConflict_base: Schema_2.Class<ContentIdConflict, Schema_2.TaggedStruct<"ContentIdConflict", {
535
+ readonly contentType: Schema_2.String;
536
+ readonly id: Schema_2.String;
537
+ }>, YieldableError>;
307
538
 
308
539
  /**
309
540
  * Raised by `publish` / `unpublish` / `archive` when the row id doesn't
@@ -314,16 +545,14 @@ declare const ContentIdConflict_base: Schema_2.TaggedErrorClass<ContentIdConflic
314
545
  export declare class ContentNotFound extends ContentNotFound_base {
315
546
  }
316
547
 
317
- declare const ContentNotFound_base: Schema_2.TaggedErrorClass<ContentNotFound, "ContentNotFound", {
318
- readonly _tag: Schema_2.tag<"ContentNotFound">;
319
- } & {
320
- contentType: typeof Schema_2.String;
321
- id: typeof Schema_2.String;
548
+ declare const ContentNotFound_base: Schema_2.Class<ContentNotFound, Schema_2.TaggedStruct<"ContentNotFound", {
549
+ readonly contentType: Schema_2.String;
550
+ readonly id: Schema_2.String;
322
551
  /** Which lifecycle table the id was looked up in (`revision`: the
323
552
  * revision to publish is not one of this variant's; `share`: a preview
324
553
  * share of the caller's). */
325
- stage: Schema_2.Literal<["draft", "published", "revision", "share"]>;
326
- }>;
554
+ readonly stage: Schema_2.Literals<readonly ["draft", "published", "revision", "share"]>;
555
+ }>, YieldableError>;
327
556
 
328
557
  /** A registered content type. */
329
558
  declare interface ContentType {
@@ -343,6 +572,7 @@ declare interface ContentType {
343
572
  /** Whether publishing needs an approved revision — see `ContentTypeSpec.review`. */
344
573
  readonly review?: {
345
574
  readonly required: boolean | 'workspace';
575
+ readonly workflow?: ReviewWorkflow;
346
576
  };
347
577
  /** When documents may be used — see `ContentTypeSpec.availability`. */
348
578
  readonly availability?: AvailabilityConfig;
@@ -392,10 +622,15 @@ declare interface ContentTypeSpec {
392
622
  * (`approveReview`) — for every path that publishes: single, release,
393
623
  * rollback, schedule. Register `cmsReviewsTable` when set. `'workspace'`:
394
624
  * each workspace decides (team.ts `setReviewRequired`, or a blueprint's
395
- * `team.reviewRequired`) — register `cmsTeamTable` too.
625
+ * `team.reviewRequired`) — register `cmsTeamTable` too. With `workflow`
626
+ * (`defineReviewWorkflow`), the approval is a workflow instance that
627
+ * approved the exact revision — every applicable step decided — instead of
628
+ * one approval; register `cmsWorkflowInstancesTable` and
629
+ * `cmsWorkflowDecisionsTable`.
396
630
  */
397
631
  readonly review?: {
398
632
  readonly required: boolean | 'workspace';
633
+ readonly workflow?: ReviewWorkflow;
399
634
  };
400
635
  /**
401
636
  * When this type's documents may be used (`until`: a date/datetime field,
@@ -477,16 +712,14 @@ declare interface ContentTypeSpec {
477
712
  export declare class ContentValidationFailed extends ContentValidationFailed_base {
478
713
  }
479
714
 
480
- declare const ContentValidationFailed_base: Schema_2.TaggedErrorClass<ContentValidationFailed, "ContentValidationFailed", {
481
- readonly _tag: Schema_2.tag<"ContentValidationFailed">;
482
- } & {
483
- contentType: typeof Schema_2.String;
484
- violations: Schema_2.Array$<Schema_2.Struct<{
485
- field: typeof Schema_2.String;
486
- rule: typeof Schema_2.String;
487
- message: typeof Schema_2.String;
715
+ declare const ContentValidationFailed_base: Schema_2.Class<ContentValidationFailed, Schema_2.TaggedStruct<"ContentValidationFailed", {
716
+ readonly contentType: Schema_2.String;
717
+ readonly violations: Schema_2.$Array<Schema_2.Struct<{
718
+ readonly field: Schema_2.String;
719
+ readonly rule: Schema_2.String;
720
+ readonly message: Schema_2.String;
488
721
  }>>;
489
- }>;
722
+ }>, YieldableError>;
490
723
 
491
724
  export declare type ContentValue = Record<string, unknown>;
492
725
 
@@ -510,21 +743,67 @@ export declare type ContentValue = Record<string, unknown>;
510
743
  */
511
744
  export declare const contentViolations: (type: Pick<ContentType, "name" | "fields"> & Partial<Pick<ContentType, "taxonomy">>, row: Readonly<Record<string, unknown>>) => ReadonlyArray<FieldViolation>;
512
745
 
746
+ /** How many variants the contract allows at most (query strings count as unbounded beyond the budget). */
747
+ export declare const contractVariants: (contract: CacheContract) => number;
748
+
513
749
  /** Decode character references (`&amp;`, `&#8217;`, `&#x2014;`). */
514
750
  export declare const decodeEntities: (text: string) => string;
515
751
 
752
+ /** The intent a `?select=…` value carries, or null. */
753
+ export declare const decodeSelectionIntent: (value: string | null | undefined) => SelectionIntent | null;
754
+
516
755
  /** Define an audience; a rule with no condition would match everyone and is refused. */
517
756
  export declare const defineAudience: (audience: Audience) => Audience;
518
757
 
519
- /** Declare a component editors can place in a `Schema.Components` field. */
520
758
  export declare const defineComponent: (spec: {
521
759
  readonly id: string;
522
760
  readonly displayName: string;
523
761
  readonly props: Readonly<Record<string, FieldSchema | PipeableField>>;
524
762
  /** A consent purpose the reader must grant first — an embed that loads a third party. */
525
763
  readonly consent?: string;
764
+ /** What it is for, in an editor's words. */
765
+ readonly description?: string;
766
+ /** The editorial jobs it serves; the picker groups and searches by them. */
767
+ readonly jobs?: ReadonlyArray<string>;
768
+ readonly variants?: ComponentDefinition["variants"];
769
+ readonly fixtures?: ComponentDefinition["fixtures"];
770
+ readonly migrations?: ComponentDefinition["migrations"];
526
771
  }) => ComponentDefinition;
527
772
 
773
+ /**
774
+ * Declare the design tokens components may name (`Schema.Token(tokens, 'tone')`).
775
+ * Group and token names are camelCase; the values are what an editor reads
776
+ * beside each name — the renderer owns the actual styles.
777
+ */
778
+ export declare const defineDesignTokens: <T extends DesignTokens>(tokens: T) => T;
779
+
780
+ /** Declare a metric; the fingerprint follows its meaning. */
781
+ export declare const defineMetric: (spec: MetricSpec) => MetricDefinition;
782
+
783
+ /**
784
+ * Declare what a rich-text field allows (`Schema.RichText({ profile })`):
785
+ * its blocks, heading levels and marks, named styles from one design-token
786
+ * group, the components that may sit between blocks, and how e-mail
787
+ * addresses and phone numbers are given — a published contact point of
788
+ * `contactPoints`, and/or a one-off checked on save (`contactLiterals`).
789
+ * Bump `version` when it changes: a saved document records `<name>@<version>`.
790
+ * Unset lists allow every built-in block, heading level and mark.
791
+ */
792
+ export declare const defineRichTextProfile: (spec: {
793
+ readonly name: string;
794
+ readonly version: number;
795
+ readonly blocks?: ReadonlyArray<Exclude<RichBlockKind, "component">>;
796
+ readonly headings?: ReadonlyArray<2 | 3>;
797
+ readonly marks?: ReadonlyArray<RichMark>;
798
+ readonly styles?: {
799
+ readonly tokens: DesignTokens;
800
+ readonly group: string;
801
+ };
802
+ readonly components?: ReadonlyArray<ComponentDefinition>;
803
+ readonly contactPoints?: string;
804
+ readonly contactLiterals?: boolean;
805
+ }) => RichTextProfile;
806
+
528
807
  /**
529
808
  * Mark a field computed-on-save from another field. The transform runs
530
809
  * before the row is written — `saveDraft` applies it (via
@@ -551,6 +830,9 @@ export declare interface DerivedSpec {
551
830
  */
552
831
  export declare const describeEdit: (fields: Readonly<Record<string, FieldSchema>>, before: Readonly<Record<string, unknown>>, after: Readonly<Record<string, unknown>>, words: EditWords) => EditDescription | null;
553
832
 
833
+ /** A design system's tokens: group → token name → what it stands for (a value or a description). */
834
+ export declare type DesignTokens = Readonly<Record<string, Readonly<Record<string, string>>>>;
835
+
554
836
  /** One run of a word diff: text both sides share, or text only one side has. */
555
837
  export declare interface DiffSegment {
556
838
  readonly op: 'same' | 'removed' | 'added';
@@ -565,6 +847,36 @@ export declare interface DiffSegment {
565
847
  */
566
848
  export declare const diffWords: (before: string, after: string) => ReadonlyArray<DiffSegment>;
567
849
 
850
+ /** Whether any block of the document holds a suggestion. */
851
+ export declare const documentHasChanges: (doc: RichDocument) => boolean;
852
+
853
+ /**
854
+ * The response headers that tell `provider` how to keep this answer: how long
855
+ * (`maxAge`, then `staleWhileRevalidate` served stale while it refetches), the
856
+ * `Vary` from the identity, and the purge tags in the header the provider
857
+ * reads (`Cache-Tag` comma-separated; Fastly's `Surrogate-Key` space-separated
858
+ * with its own `Surrogate-Control`). A request that is not shared-cacheable
859
+ * gets `private, no-store` and no tags.
860
+ */
861
+ export declare const edgeHeaders: (provider: EdgeProvider, identity: CacheIdentity, lifetime: {
862
+ readonly maxAge: number;
863
+ readonly staleWhileRevalidate?: number;
864
+ }) => Readonly<Record<string, string>>;
865
+
866
+ /** A shared cache in front of the delivery API: your own (BYO) or a managed one. */
867
+ export declare type EdgeProvider = 'cloudflare' | 'fastly' | 'generic';
868
+
869
+ /**
870
+ * The requests that drop every cached answer carrying one of `tags`, and the
871
+ * answers at `urls` — none when there is nothing to purge or the target is
872
+ * unusable. Tags a header could not carry and addresses that are not absolute
873
+ * http(s) URLs are left out rather than sent.
874
+ */
875
+ export declare const edgePurgeRequests: (provider: PurgeProvider, config: {
876
+ readonly target: string;
877
+ readonly token: string | null;
878
+ }, tags: ReadonlyArray<string>, urls?: ReadonlyArray<string>) => ReadonlyArray<PurgeRequest>;
879
+
568
880
  /** What one change did, and a key that tells whether the next change continues it. */
569
881
  export declare interface EditDescription {
570
882
  readonly label: string;
@@ -615,11 +927,41 @@ export declare interface EditWords {
615
927
  /** The tools on for the last step of `chain`, and why each tool is as it is. */
616
928
  export declare const effectiveExposure: (input: ExposureInput) => ExposureResult;
617
929
 
930
+ /** One inherited field of a page as the editor shows it: what it is, where it came from, and what the page may do. */
931
+ export declare interface EffectiveInheritance extends Inherited {
932
+ readonly field: string;
933
+ readonly locked: boolean;
934
+ /** The mask field, when the field may be masked. */
935
+ readonly mask: string | null;
936
+ /** What it would be without the page's own value or mask — what "reset" brings back. */
937
+ readonly inherited: Inherited;
938
+ }
939
+
940
+ /**
941
+ * Every inherited field of `node` (the type's `tree.inherit`): its effective
942
+ * value with the document it came from and how, whether it is locked or may
943
+ * be masked, and what it would be after a reset. A draft not yet in the tree
944
+ * inherits through its parent — pass it as `node` and it is placed for the
945
+ * walk.
946
+ */
947
+ export declare const effectiveInheritance: (inherit: Readonly<Record<string, InheritRule>>, tree: CmsTree, node: TreeNode) => ReadonlyArray<EffectiveInheritance>;
948
+
618
949
  export declare const EMPTY_EDIT_HISTORY: EditHistory;
619
950
 
620
951
  /** An empty document. */
621
952
  export declare const emptyRichDocument: () => RichDocument;
622
953
 
954
+ /** The intent as a URL parameter value (`?select=…`). */
955
+ export declare const encodeSelectionIntent: (intent: SelectionIntent) => string;
956
+
957
+ /** Why a dimension is in the identity or not. */
958
+ export declare interface ExplainLine {
959
+ readonly dimension: string;
960
+ readonly included: boolean;
961
+ readonly value: string | null;
962
+ readonly why: string;
963
+ }
964
+
623
965
  export declare interface ExposureInput {
624
966
  readonly ceiling: ReadonlyArray<string>;
625
967
  readonly defaults: ReadonlyArray<string>;
@@ -648,12 +990,10 @@ export declare const EXTENSION_SLOTS: readonly ["dashboard", "sidebar", "fieldWi
648
990
  export declare class ExtensionAccessDenied extends ExtensionAccessDenied_base {
649
991
  }
650
992
 
651
- declare const ExtensionAccessDenied_base: Schema_2.TaggedErrorClass<ExtensionAccessDenied, "ExtensionAccessDenied", {
652
- readonly _tag: Schema_2.tag<"ExtensionAccessDenied">;
653
- } & {
654
- extensionId: typeof Schema_2.String;
655
- capability: typeof Schema_2.String;
656
- }>;
993
+ declare const ExtensionAccessDenied_base: Schema_2.Class<ExtensionAccessDenied, Schema_2.TaggedStruct<"ExtensionAccessDenied", {
994
+ readonly extensionId: Schema_2.String;
995
+ readonly capability: Schema_2.String;
996
+ }>, YieldableError>;
657
997
 
658
998
  /**
659
999
  * What an extension may do; everything else is refused.
@@ -669,31 +1009,31 @@ export declare type ExtensionCapability = 'content:read' | 'content:write' | `eg
669
1009
 
670
1010
  /** A manifest on the wire — for a descriptor's input or output. */
671
1011
  export declare const ExtensionManifestSchema: Schema_2.Struct<{
672
- id: typeof Schema_2.String;
673
- name: typeof Schema_2.String;
674
- version: typeof Schema_2.String;
675
- publisher: typeof Schema_2.String;
676
- capabilities: Schema_2.Array$<typeof Schema_2.String>;
677
- slots: Schema_2.Array$<typeof Schema_2.String>;
678
- fields: Schema_2.optional<Schema_2.Array$<typeof Schema_2.String>>;
679
- settings: Schema_2.optional<Schema_2.Array$<Schema_2.Union<[Schema_2.Struct<{
680
- key: typeof Schema_2.String;
681
- label: typeof Schema_2.String;
682
- kind: Schema_2.Literal<["number"]>;
683
- default: typeof Schema_2.Number;
684
- min: Schema_2.optional<typeof Schema_2.Number>;
685
- max: Schema_2.optional<typeof Schema_2.Number>;
1012
+ readonly id: Schema_2.String;
1013
+ readonly name: Schema_2.String;
1014
+ readonly version: Schema_2.String;
1015
+ readonly publisher: Schema_2.String;
1016
+ readonly capabilities: Schema_2.$Array<Schema_2.String>;
1017
+ readonly slots: Schema_2.$Array<Schema_2.String>;
1018
+ readonly fields: Schema_2.optional<Schema_2.$Array<Schema_2.String>>;
1019
+ readonly settings: Schema_2.optional<Schema_2.$Array<Schema_2.Union<readonly [Schema_2.Struct<{
1020
+ readonly key: Schema_2.String;
1021
+ readonly label: Schema_2.String;
1022
+ readonly kind: Schema_2.Literal<"number">;
1023
+ readonly default: Schema_2.Number;
1024
+ readonly min: Schema_2.optional<Schema_2.Number>;
1025
+ readonly max: Schema_2.optional<Schema_2.Number>;
686
1026
  }>, Schema_2.Struct<{
687
- key: typeof Schema_2.String;
688
- label: typeof Schema_2.String;
689
- kind: Schema_2.Literal<["boolean"]>;
690
- default: typeof Schema_2.Boolean;
1027
+ readonly key: Schema_2.String;
1028
+ readonly label: Schema_2.String;
1029
+ readonly kind: Schema_2.Literal<"boolean">;
1030
+ readonly default: Schema_2.Boolean;
691
1031
  }>, Schema_2.Struct<{
692
- key: typeof Schema_2.String;
693
- label: typeof Schema_2.String;
694
- kind: Schema_2.Literal<["choice"]>;
695
- default: typeof Schema_2.String;
696
- options: Schema_2.Array$<typeof Schema_2.String>;
1032
+ readonly key: Schema_2.String;
1033
+ readonly label: Schema_2.String;
1034
+ readonly kind: Schema_2.Literal<"choice">;
1035
+ readonly default: Schema_2.String;
1036
+ readonly options: Schema_2.$Array<Schema_2.String>;
697
1037
  }>]>>>;
698
1038
  }>;
699
1039
 
@@ -755,6 +1095,12 @@ export declare interface FieldSchema {
755
1095
  readonly pattern?: string;
756
1096
  /** Closed value set for `literal` fields → `<select>` + CHECK constraint. */
757
1097
  readonly literals?: ReadonlyArray<string>;
1098
+ /** What an editor reads for each literal (a token's value, an action's purpose). */
1099
+ readonly literalLabels?: Readonly<Record<string, string>>;
1100
+ /** Set by `Schema.Token`: the design-token group the value names. */
1101
+ readonly token?: string;
1102
+ /** Set by `Schema.Action`: the value names an action the renderer binds. */
1103
+ readonly action?: true;
758
1104
  /** A `number` field that takes fractions (a `real` column); without it a number is whole. */
759
1105
  readonly fraction?: boolean;
760
1106
  /**
@@ -837,6 +1183,8 @@ export declare interface HtmlImportOptions {
837
1183
  readonly resolveImage?: (src: string) => string | null;
838
1184
  /** Block ids; defaults to a counter, so a test reads stable ids. */
839
1185
  readonly newId?: () => string;
1186
+ /** Keep `mailto:` and `tel:` links as one-off contacts (a field profile with `contactLiterals`); one that is not a usable address or number is reported. */
1187
+ readonly contacts?: boolean;
840
1188
  }
841
1189
 
842
1190
  export declare interface HtmlImportResult {
@@ -846,12 +1194,22 @@ export declare interface HtmlImportResult {
846
1194
 
847
1195
  /** Where an inherited value came from. */
848
1196
  export declare interface Inherited {
849
- /** The value; undefined when neither the page nor an ancestor sets it. */
1197
+ /** The value; undefined when masked or when nothing in the tree sets it. */
850
1198
  readonly value: unknown;
851
- /** The document that set it: the page itself, an ancestor, or null for none. */
1199
+ /** The document that decided it: the page itself, an ancestor, or null for none. */
852
1200
  readonly from: string | null;
1201
+ readonly how: InheritedHow;
853
1202
  }
854
1203
 
1204
+ /**
1205
+ * How a page came by an inherited field:
1206
+ * - `own` — the page sets it;
1207
+ * - `ancestor` — the nearest ancestor that sets it;
1208
+ * - `masked` — the page or an ancestor masks it: nothing shows;
1209
+ * - `none` — nothing in the tree sets it (the app's site default applies).
1210
+ */
1211
+ export declare type InheritedHow = 'own' | 'ancestor' | 'masked' | 'none';
1212
+
855
1213
  /**
856
1214
  * The value of an inherited field for `node`: its own when set, else the
857
1215
  * nearest ancestor's in `tree` (the same locale's variants the tree was built
@@ -860,12 +1218,20 @@ export declare interface Inherited {
860
1218
  */
861
1219
  export declare const inheritedValue: (tree: CmsTree, node: TreeNode, field: string, options?: {
862
1220
  readonly ancestorsOnly?: boolean;
1221
+ readonly mask?: string;
863
1222
  }) => Inherited;
864
1223
 
865
1224
  /** How one inherited field may be set. */
866
1225
  export declare interface InheritRule {
867
1226
  /** No page may set the field; saving one that does is refused (`locked`). */
868
1227
  readonly locked?: boolean;
1228
+ /**
1229
+ * An optional Boolean field of the same type that MASKS this one: true on a
1230
+ * page means it shows nothing here, on purpose — not "unset" (that
1231
+ * inherits) and not an empty value. Pages below inherit the mask until one
1232
+ * sets its own value or mask. A locked field cannot be masked.
1233
+ */
1234
+ readonly mask?: string;
869
1235
  }
870
1236
 
871
1237
  /** The minimal DOM a surface is read from (a browser element, or jsdom's). */
@@ -884,7 +1250,7 @@ export declare interface InlineDomNode {
884
1250
  */
885
1251
  export declare const inlineFromDom: (root: InlineDomNode) => ReadonlyArray<RichInline>;
886
1252
 
887
- /** A run as the HTML a visual surface shows: `strong`, `em`, `u`, `a[data-target]`, escaped text. */
1253
+ /** A run as the HTML a visual surface shows: `strong`, `em`, `u`, `span[data-style]`, `a[data-target]`, `a[data-contact]`, escaped text. */
888
1254
  export declare const inlineHtml: (content: ReadonlyArray<RichInline>) => string;
889
1255
 
890
1256
  /** Inline nodes back to the editor's markup (the inverse of `parseInlineMarkup`). */
@@ -932,6 +1298,15 @@ export declare const listNumberedAt: (block: {
932
1298
  readonly sublists?: ReadonlyArray<ListKind>;
933
1299
  }, depth: number) => boolean;
934
1300
 
1301
+ /** One stretch of time a revision was live (`to` null: still live). */
1302
+ export declare interface LiveStretch {
1303
+ readonly revision: number;
1304
+ readonly releaseId: string | null;
1305
+ /** ISO timestamps. */
1306
+ readonly from: string;
1307
+ readonly to: string | null;
1308
+ }
1309
+
935
1310
  /** One language's published page tree. */
936
1311
  export declare interface LocalizedTree {
937
1312
  readonly locale: string;
@@ -960,9 +1335,61 @@ export declare const MAX_OCCURRENCES = 100;
960
1335
  /** Cap a string field's length. Past `value` the editor renders a textarea. */
961
1336
  export declare const maxLength: (value: number) => FieldRefinement;
962
1337
 
963
- /** Adjacent text runs with the same marks become one; empty text runs go. */
1338
+ /** Adjacent text runs with the same marks and style become one; empty text runs go. */
964
1339
  export declare const mergeInline: (content: ReadonlyArray<RichInline>) => ReadonlyArray<RichInline>;
965
1340
 
1341
+ export declare interface MetricDefinition extends MetricSpec {
1342
+ /** A digest of what the number means (not of its label or description). */
1343
+ readonly fingerprint: string;
1344
+ }
1345
+
1346
+ export declare type MetricDrill = 'document' | 'locale' | 'revision' | 'release';
1347
+
1348
+ export declare type MetricFreshness = {
1349
+ readonly kind: 'live';
1350
+ } | {
1351
+ readonly kind: 'daily';
1352
+ } | {
1353
+ readonly kind: 'interval';
1354
+ readonly minutes: number;
1355
+ };
1356
+
1357
+ export declare interface MetricSpec {
1358
+ readonly id: string;
1359
+ /** Raise it whenever the formula, scope, freshness, quality or drill changes. */
1360
+ readonly version: number;
1361
+ readonly label: string;
1362
+ readonly description: string;
1363
+ /** What is computed, in words a reviewer can check against the code. */
1364
+ readonly formula: string;
1365
+ readonly unit: MetricUnit;
1366
+ /** What it is counted over — `site`, `environment`, `locale`, `document`, `day`… */
1367
+ readonly scope: ReadonlyArray<string>;
1368
+ readonly freshness: MetricFreshness;
1369
+ /** Known limits of the number, e.g. `consent-only`, `utc-days`. */
1370
+ readonly quality: ReadonlyArray<string>;
1371
+ /** Where it drills down to. */
1372
+ readonly drill: ReadonlyArray<MetricDrill>;
1373
+ }
1374
+
1375
+ export declare type MetricUnit = 'count' | 'ratio' | 'percent' | 'seconds';
1376
+
1377
+ /**
1378
+ * The metrics whose meaning changed against a recorded set of
1379
+ * `{ id, version, fingerprint }` without a new version — keep the set in a
1380
+ * test, and this names every silent redefinition.
1381
+ */
1382
+ export declare const metricVersionDrift: (metrics: ReadonlyArray<MetricDefinition>, recorded: ReadonlyArray<{
1383
+ readonly id: string;
1384
+ readonly version: number;
1385
+ readonly fingerprint: string;
1386
+ }>) => ReadonlyArray<string>;
1387
+
1388
+ /** The stages of a migration, in the order they pass. */
1389
+ export declare const MIGRATION_STAGES: readonly ["inventory", "mapping", "dryRun", "reconciliation", "delta", "cutover", "fallback", "uat"];
1390
+
1391
+ export declare type MigrationStage = (typeof MIGRATION_STAGES)[number];
1392
+
966
1393
  /** `list` with the entry at `from` moved to `to` (clamped); the same list when nothing moves. */
967
1394
  export declare const moveEntry: <T>(list: ReadonlyArray<T>, from: number, to: number) => ReadonlyArray<T>;
968
1395
 
@@ -979,9 +1406,9 @@ export declare const newVisualNonce: () => string;
979
1406
  * The canonical form of a stored value: a plain string becomes paragraphs (a
980
1407
  * blank line starts a new one), a document keeps its blocks and gets an id on
981
1408
  * every block that lacks one, anything else is returned as is for the
982
- * validator to reject.
1409
+ * validator to reject. With a profile, the document records its id.
983
1410
  */
984
- export declare const normalizeRichDocument: (value: unknown) => unknown;
1411
+ export declare const normalizeRichDocument: (value: unknown, profile?: RichTextProfile) => unknown;
985
1412
 
986
1413
  /** The vocabulary's terms for `input`, in first-seen order, and what it does not know. */
987
1414
  export declare const normalizeTerms: (config: Pick<TaxonomyConfig, "terms">, input: ReadonlyArray<unknown>) => {
@@ -1030,10 +1457,25 @@ export declare interface PageTemplate {
1030
1457
  readonly component: ComponentDefinition;
1031
1458
  readonly count: number;
1032
1459
  }>;
1460
+ /** Other `Schema.Components` fields of the type (an aside), each with its own rules. */
1461
+ readonly regions?: Readonly<Record<string, RegionRule>>;
1462
+ /** The widths a component may take here: the values its `TemplatesConfig.width` prop may hold. */
1463
+ readonly widths?: ReadonlyArray<{
1464
+ readonly component: ComponentDefinition;
1465
+ readonly allowed: ReadonlyArray<string>;
1466
+ }>;
1467
+ /** How deep components may sit inside each other's slots; 1 = no nesting. */
1468
+ readonly maxDepth?: number;
1033
1469
  }
1034
1470
 
1035
- /** Parse the editor's inline markup into inline nodes. Unclosed markers stay text. */
1036
- export declare const parseInlineMarkup: (input: string) => ReadonlyArray<RichInline>;
1471
+ /** Parse the editor's inline markup into inline nodes. Unclosed markers stay text; `{name|…}` is a style only for a name in `styles`. */
1472
+ export declare const parseInlineMarkup: (input: string, styles?: ReadonlyArray<string>) => ReadonlyArray<RichInline>;
1473
+
1474
+ /** An anchor from someone else's presence, or null when it is not one of the declared shapes. */
1475
+ export declare const parsePresenceAnchor: (value: unknown) => PresenceAnchor | null;
1476
+
1477
+ /** An intent from a URL or a message, or null when it is not one of the declared shape. Untrusted input. */
1478
+ export declare const parseSelectionIntent: (value: unknown) => SelectionIntent | null;
1037
1479
 
1038
1480
  /** `sections.2` → `{ field: 'sections', index: 2 }`; `title` → `{ field: 'title' }`. */
1039
1481
  export declare const parseSourcePath: (path: string) => {
@@ -1047,6 +1489,21 @@ export declare const parseXliff: (xml: string) => XliffExchange;
1047
1489
  /** Constrain a string field to a regex (source form, validated on save). */
1048
1490
  export declare const pattern: (re: RegExp) => FieldRefinement;
1049
1491
 
1492
+ /** One suggestion: who made it and when, the blocks it touches, and the text it puts in and takes out. */
1493
+ export declare interface PendingChange {
1494
+ readonly id: string;
1495
+ readonly by: string;
1496
+ readonly at: string;
1497
+ readonly blockIds: ReadonlyArray<string>;
1498
+ readonly inserted: string;
1499
+ readonly deleted: string;
1500
+ /** Blocks it inserts or deletes whole (an image, a component, a paragraph). */
1501
+ readonly blocks: number;
1502
+ }
1503
+
1504
+ /** The suggestions in a document, in order of first appearance. */
1505
+ export declare const pendingChanges: (doc: RichDocument) => ReadonlyArray<PendingChange>;
1506
+
1050
1507
  /** The first variant whose audience matches, or null for the original. Variants naming an unknown audience never match. */
1051
1508
  export declare const pickVariant: <V extends {
1052
1509
  readonly audience: string;
@@ -1068,6 +1525,42 @@ export declare interface PipeableField extends FieldSchema {
1068
1525
  /** The document's text, one line per block — for excerpts and search. */
1069
1526
  export declare const plainTextOf: (doc: RichDocument) => string;
1070
1527
 
1528
+ export declare type PresenceAnchor = {
1529
+ readonly kind: 'view';
1530
+ readonly view: string;
1531
+ } | {
1532
+ readonly kind: 'field';
1533
+ readonly field: string;
1534
+ } | {
1535
+ readonly kind: 'component';
1536
+ readonly field: string;
1537
+ readonly instanceId: string;
1538
+ readonly componentId: string;
1539
+ } | {
1540
+ readonly kind: 'slot';
1541
+ readonly field: string;
1542
+ readonly instanceId: string;
1543
+ readonly componentId: string;
1544
+ readonly prop: string;
1545
+ } | {
1546
+ readonly kind: 'selection';
1547
+ readonly field: string;
1548
+ readonly start: number;
1549
+ readonly end: number;
1550
+ } | {
1551
+ readonly kind: 'assetRegion';
1552
+ readonly x: number;
1553
+ readonly y: number;
1554
+ readonly width: number;
1555
+ readonly height: number;
1556
+ };
1557
+
1558
+ /**
1559
+ * The anchor of a focused control in a `ContentForm`: the field, or — inside
1560
+ * a placed component — the component, or the prop (slot) within it.
1561
+ */
1562
+ export declare const presenceAnchorOf: (target: unknown) => PresenceAnchor | null;
1563
+
1071
1564
  /** What the preview sends the editor. `path` is a field (`title`) or a component (`sections.2`). */
1072
1565
  export declare type PreviewMessage = {
1073
1566
  readonly protocol: typeof VISUAL_EDITING_PROTOCOL;
@@ -1093,24 +1586,38 @@ export declare type PreviewMessage = {
1093
1586
  export declare class PreviewShareRejected extends PreviewShareRejected_base {
1094
1587
  }
1095
1588
 
1096
- declare const PreviewShareRejected_base: Schema_2.TaggedErrorClass<PreviewShareRejected, "PreviewShareRejected", {
1097
- readonly _tag: Schema_2.tag<"PreviewShareRejected">;
1098
- } & {
1099
- reason: Schema_2.Literal<["expiryInPast", "expiryTooFar"]>;
1100
- }>;
1589
+ declare const PreviewShareRejected_base: Schema_2.Class<PreviewShareRejected, Schema_2.TaggedStruct<"PreviewShareRejected", {
1590
+ readonly reason: Schema_2.Literals<readonly ["expiryInPast", "expiryTooFar"]>;
1591
+ }>, YieldableError>;
1101
1592
 
1102
1593
  /**
1103
1594
  * What stops these values from being published: every `requiredToPublish()`
1104
- * field that is empty (absent, null, or a blank string). Browser-safe, so an
1105
- * editor can say so before the publish is refused.
1595
+ * field that is empty (absent, null, or a blank string), and every rich text
1596
+ * that still holds suggested changes. Browser-safe, so an editor can say so
1597
+ * before the publish is refused.
1106
1598
  */
1107
1599
  export declare const publishViolations: (type: Pick<ContentType, "fields">, values: Readonly<Record<string, unknown>>) => ReadonlyArray<FieldViolation>;
1108
1600
 
1601
+ export declare type PurgeProvider = 'cloudflare' | 'fastly' | 'webhook';
1602
+
1603
+ export declare interface PurgeRequest {
1604
+ readonly url: string;
1605
+ readonly method: 'POST';
1606
+ readonly headers: Readonly<Record<string, string>>;
1607
+ readonly body?: string;
1608
+ }
1609
+
1109
1610
  /** The purposes the components of `type` need, for a banner to ask about. */
1110
1611
  export declare const purposesUsedBy: (type: {
1111
1612
  readonly fields: Readonly<Record<string, FieldSchema>>;
1112
1613
  }) => ReadonlySet<string>;
1113
1614
 
1615
+ /** When and where a quality rule is checked; `scope` is null where no place is known (every pack then applies). */
1616
+ declare interface QualityContext {
1617
+ readonly now: Date;
1618
+ readonly scope: CmsScope | null;
1619
+ }
1620
+
1114
1621
  /** One quality check of a type — see `ContentTypeSpec.quality`. */
1115
1622
  declare interface QualityRule {
1116
1623
  /** Stable id (letters, digits, `.`, `-`), unique in the type — exceptions name it. */
@@ -1121,10 +1628,37 @@ declare interface QualityRule {
1121
1628
  readonly message: string;
1122
1629
  /** Whether publishing waits for a repair or an approved exception. Default true. */
1123
1630
  readonly blocking?: boolean;
1124
- /** True when the values have the finding. Pure. */
1125
- readonly check: (values: Readonly<Record<string, unknown>>) => boolean;
1631
+ /**
1632
+ * The policy pack it belongs to (`'EU claims'`, `'German market'`) — shown
1633
+ * beside the finding. With `sites` / `locales` a pack applies only there;
1634
+ * absent, everywhere.
1635
+ */
1636
+ readonly pack?: string;
1637
+ readonly sites?: ReadonlyArray<string>;
1638
+ readonly locales?: ReadonlyArray<string>;
1639
+ /** True when the values have the finding. Pure; `at` says when and where (a claim's evidence may have run out). */
1640
+ readonly check: (values: Readonly<Record<string, unknown>>, at: QualityContext) => boolean;
1126
1641
  }
1127
1642
 
1643
+ /** One allowed query parameter. */
1644
+ export declare type QueryParam = {
1645
+ readonly name: string;
1646
+ readonly type: 'string';
1647
+ readonly maxLength?: number;
1648
+ readonly default?: string;
1649
+ } | {
1650
+ readonly name: string;
1651
+ readonly type: 'int';
1652
+ readonly min?: number;
1653
+ readonly max?: number;
1654
+ readonly default?: number;
1655
+ } | {
1656
+ readonly name: string;
1657
+ readonly type: 'enum';
1658
+ readonly values: ReadonlyArray<string>;
1659
+ readonly default?: string;
1660
+ };
1661
+
1128
1662
  /**
1129
1663
  * Raised when a create would take a tenant past a limit its app set — more
1130
1664
  * documents, keys or environments than it may hold. Nothing was written;
@@ -1133,13 +1667,11 @@ declare interface QualityRule {
1133
1667
  export declare class QuotaExceeded extends QuotaExceeded_base {
1134
1668
  }
1135
1669
 
1136
- declare const QuotaExceeded_base: Schema_2.TaggedErrorClass<QuotaExceeded, "QuotaExceeded", {
1137
- readonly _tag: Schema_2.tag<"QuotaExceeded">;
1138
- } & {
1139
- quota: typeof Schema_2.String;
1140
- limit: typeof Schema_2.Number;
1141
- used: typeof Schema_2.Number;
1142
- }>;
1670
+ declare const QuotaExceeded_base: Schema_2.Class<QuotaExceeded, Schema_2.TaggedStruct<"QuotaExceeded", {
1671
+ readonly quota: Schema_2.String;
1672
+ readonly limit: Schema_2.Number;
1673
+ readonly used: Schema_2.Number;
1674
+ }>, YieldableError>;
1143
1675
 
1144
1676
  /** The editor's message, or null for anything else. */
1145
1677
  export declare const readEditorMessage: (event: VisualMessageEvent, session: VisualSession) => EditorMessage | null;
@@ -1192,18 +1724,25 @@ export declare const redoEdit: (history: EditHistory, current: Readonly<Record<s
1192
1724
  export declare class ReferenceUnavailable extends ReferenceUnavailable_base {
1193
1725
  }
1194
1726
 
1195
- declare const ReferenceUnavailable_base: Schema_2.TaggedErrorClass<ReferenceUnavailable, "ReferenceUnavailable", {
1196
- readonly _tag: Schema_2.tag<"ReferenceUnavailable">;
1197
- } & {
1198
- contentType: typeof Schema_2.String;
1199
- id: typeof Schema_2.String;
1200
- targets: Schema_2.Array$<Schema_2.Struct<{
1201
- path: typeof Schema_2.String;
1202
- contentType: typeof Schema_2.String;
1203
- documentId: typeof Schema_2.String;
1204
- reason: Schema_2.Literal<["blocked", "expired"]>;
1727
+ declare const ReferenceUnavailable_base: Schema_2.Class<ReferenceUnavailable, Schema_2.TaggedStruct<"ReferenceUnavailable", {
1728
+ readonly contentType: Schema_2.String;
1729
+ readonly id: Schema_2.String;
1730
+ readonly targets: Schema_2.$Array<Schema_2.Struct<{
1731
+ readonly path: Schema_2.String;
1732
+ readonly contentType: Schema_2.String;
1733
+ readonly documentId: Schema_2.String;
1734
+ readonly reason: Schema_2.Literals<readonly ["blocked", "expired", "notYet", "territory", "channel", "purpose"]>;
1205
1735
  }>>;
1206
- }>;
1736
+ }>, YieldableError>;
1737
+
1738
+ /** The rules of one region of a template. */
1739
+ export declare interface RegionRule {
1740
+ /** Only these components may be placed here (all the field allows, when unset). */
1741
+ readonly allowed?: ReadonlyArray<ComponentDefinition>;
1742
+ readonly required?: ReadonlyArray<ComponentDefinition>;
1743
+ /** The most components the region may hold. */
1744
+ readonly maxItems?: number;
1745
+ }
1207
1746
 
1208
1747
  /**
1209
1748
  * Raised when a release is asked to change in a state that does not allow it:
@@ -1213,12 +1752,10 @@ declare const ReferenceUnavailable_base: Schema_2.TaggedErrorClass<ReferenceUnav
1213
1752
  export declare class ReleaseNotEditable extends ReleaseNotEditable_base {
1214
1753
  }
1215
1754
 
1216
- declare const ReleaseNotEditable_base: Schema_2.TaggedErrorClass<ReleaseNotEditable, "ReleaseNotEditable", {
1217
- readonly _tag: Schema_2.tag<"ReleaseNotEditable">;
1218
- } & {
1219
- id: typeof Schema_2.String;
1220
- status: typeof Schema_2.String;
1221
- }>;
1755
+ declare const ReleaseNotEditable_base: Schema_2.Class<ReleaseNotEditable, Schema_2.TaggedStruct<"ReleaseNotEditable", {
1756
+ readonly id: Schema_2.String;
1757
+ readonly status: Schema_2.String;
1758
+ }>, YieldableError>;
1222
1759
 
1223
1760
  /**
1224
1761
  * Replace the text in `[start, end)` with `text` (a paste, a typed line
@@ -1227,6 +1764,9 @@ declare const ReleaseNotEditable_base: Schema_2.TaggedErrorClass<ReleaseNotEdita
1227
1764
  */
1228
1765
  export declare const replaceText: (content: ReadonlyArray<RichInline>, start: number, end: number, text: string) => ReadonlyArray<RichInline>;
1229
1766
 
1767
+ /** The document with each suggestion accepted, rejected or kept, as `decide` says. */
1768
+ export declare const resolveChanges: (doc: RichDocument, decide: (change: RichChange) => ChangeDecision) => RichDocument;
1769
+
1230
1770
  /**
1231
1771
  * Raised when a revision of a content type that requires review is published
1232
1772
  * without an approval of exactly that revision.
@@ -1234,13 +1774,11 @@ export declare const replaceText: (content: ReadonlyArray<RichInline>, start: nu
1234
1774
  export declare class ReviewRequired extends ReviewRequired_base {
1235
1775
  }
1236
1776
 
1237
- declare const ReviewRequired_base: Schema_2.TaggedErrorClass<ReviewRequired, "ReviewRequired", {
1238
- readonly _tag: Schema_2.tag<"ReviewRequired">;
1239
- } & {
1240
- contentType: typeof Schema_2.String;
1241
- id: typeof Schema_2.String;
1242
- revisionId: typeof Schema_2.String;
1243
- }>;
1777
+ declare const ReviewRequired_base: Schema_2.Class<ReviewRequired, Schema_2.TaggedStruct<"ReviewRequired", {
1778
+ readonly contentType: Schema_2.String;
1779
+ readonly id: Schema_2.String;
1780
+ readonly revisionId: Schema_2.String;
1781
+ }>, YieldableError>;
1244
1782
 
1245
1783
  /**
1246
1784
  * Raised by the review steps when the step does not fit the variant's review:
@@ -1249,13 +1787,18 @@ declare const ReviewRequired_base: Schema_2.TaggedErrorClass<ReviewRequired, "Re
1249
1787
  export declare class ReviewStepRefused extends ReviewStepRefused_base {
1250
1788
  }
1251
1789
 
1252
- declare const ReviewStepRefused_base: Schema_2.TaggedErrorClass<ReviewStepRefused, "ReviewStepRefused", {
1253
- readonly _tag: Schema_2.tag<"ReviewStepRefused">;
1254
- } & {
1255
- contentType: typeof Schema_2.String;
1256
- id: typeof Schema_2.String;
1257
- reason: Schema_2.Literal<["notInReview", "selfApproval", "ambiguousOrder"]>;
1258
- }>;
1790
+ declare const ReviewStepRefused_base: Schema_2.Class<ReviewStepRefused, Schema_2.TaggedStruct<"ReviewStepRefused", {
1791
+ readonly contentType: Schema_2.String;
1792
+ readonly id: Schema_2.String;
1793
+ readonly reason: Schema_2.Literals<readonly ["notInReview", "selfApproval", "ambiguousOrder"]>;
1794
+ }>, YieldableError>;
1795
+
1796
+ declare interface ReviewWorkflow {
1797
+ readonly id: string;
1798
+ /** Raise it whenever the steps change: an instance keeps the version it started with. */
1799
+ readonly version: number;
1800
+ readonly steps: ReadonlyArray<WorkflowStep>;
1801
+ }
1259
1802
 
1260
1803
  /**
1261
1804
  * Raised by `publish` when the caller pinned a revision (`{ revisionId }`)
@@ -1265,28 +1808,40 @@ declare const ReviewStepRefused_base: Schema_2.TaggedErrorClass<ReviewStepRefuse
1265
1808
  export declare class RevisionMismatch extends RevisionMismatch_base {
1266
1809
  }
1267
1810
 
1268
- declare const RevisionMismatch_base: Schema_2.TaggedErrorClass<RevisionMismatch, "RevisionMismatch", {
1269
- readonly _tag: Schema_2.tag<"RevisionMismatch">;
1270
- } & {
1271
- contentType: typeof Schema_2.String;
1272
- id: typeof Schema_2.String;
1273
- expected: typeof Schema_2.String;
1274
- actual: typeof Schema_2.String;
1275
- }>;
1811
+ declare const RevisionMismatch_base: Schema_2.Class<RevisionMismatch, Schema_2.TaggedStruct<"RevisionMismatch", {
1812
+ readonly contentType: Schema_2.String;
1813
+ readonly id: Schema_2.String;
1814
+ readonly expected: Schema_2.String;
1815
+ readonly actual: Schema_2.String;
1816
+ }>, YieldableError>;
1817
+
1818
+ /** A value attributed to the revision live when it was counted. */
1819
+ export declare interface RevisionShare extends LiveStretch {
1820
+ readonly value: number;
1821
+ readonly days: number;
1822
+ }
1276
1823
 
1277
- /** A top-level block. `id` is stable across edits, moves and translations. */
1824
+ /** A top-level block. `id` is stable across edits, moves and translations. `style`
1825
+ * names a token of the profile's style group; `change` marks a block suggested
1826
+ * for insertion or deletion. */
1278
1827
  export declare type RichBlock = {
1279
1828
  readonly id: string;
1829
+ readonly change?: RichChange;
1280
1830
  readonly type: 'paragraph';
1281
1831
  readonly content: ReadonlyArray<RichInline>;
1832
+ readonly style?: string;
1282
1833
  } | {
1283
1834
  readonly id: string;
1835
+ readonly change?: RichChange;
1284
1836
  readonly type: 'heading';
1285
1837
  readonly level: 2 | 3;
1286
1838
  readonly content: ReadonlyArray<RichInline>;
1839
+ readonly style?: string;
1287
1840
  } | {
1288
1841
  readonly id: string;
1842
+ readonly change?: RichChange;
1289
1843
  readonly type: 'list';
1844
+ readonly style?: string;
1290
1845
  readonly ordered: boolean;
1291
1846
  readonly items: ReadonlyArray<ReadonlyArray<RichInline>>;
1292
1847
  /** How deep each item sits (0 at the top, at most `MAX_LIST_LEVEL`), one per item; absent: all at the top.
@@ -1297,6 +1852,7 @@ export declare type RichBlock = {
1297
1852
  readonly sublists?: ReadonlyArray<ListKind>;
1298
1853
  } | {
1299
1854
  readonly id: string;
1855
+ readonly change?: RichChange;
1300
1856
  readonly type: 'table';
1301
1857
  /** True when the first row holds the column headers. */
1302
1858
  readonly header: boolean;
@@ -1305,15 +1861,58 @@ export declare type RichBlock = {
1305
1861
  /** An image asset (by its documentId) with an optional caption. */
1306
1862
  | {
1307
1863
  readonly id: string;
1864
+ readonly change?: RichChange;
1308
1865
  readonly type: 'image';
1309
1866
  readonly asset: string;
1310
1867
  readonly caption?: string;
1868
+ }
1869
+ /** A file to download — an asset (by its documentId) from the media library — and the text its link shows. */
1870
+ | {
1871
+ readonly id: string;
1872
+ readonly change?: RichChange;
1873
+ readonly type: 'file';
1874
+ readonly asset: string;
1875
+ readonly label: string;
1876
+ }
1877
+ /** A component the profile allows, placed between blocks; `id` is its instance id. */
1878
+ | {
1879
+ readonly id: string;
1880
+ readonly change?: RichChange;
1881
+ readonly type: 'component';
1882
+ readonly componentId: string;
1883
+ readonly props: Readonly<Record<string, unknown>>;
1884
+ /** The definition's fingerprint when it was last saved. */
1885
+ readonly fingerprint?: string;
1886
+ };
1887
+
1888
+ /** A kind of block. */
1889
+ export declare type RichBlockKind = RichBlock['type'];
1890
+
1891
+ /** A suggested change (track changes): text or a block someone proposes to insert
1892
+ * or delete, until it is accepted or rejected (trackChanges.ts). */
1893
+ export declare interface RichChange {
1894
+ readonly id: string;
1895
+ readonly kind: 'insert' | 'delete';
1896
+ /** Who suggested it. */
1897
+ readonly by: string;
1898
+ /** When, as an ISO timestamp. */
1899
+ readonly at: string;
1900
+ }
1901
+
1902
+ /** How a contact is given: a published contact point (its documentId), or a one-off address or number. */
1903
+ export declare type RichContact = {
1904
+ readonly target: string;
1905
+ } | {
1906
+ readonly channel: 'email' | 'phone';
1907
+ readonly value: string;
1311
1908
  };
1312
1909
 
1313
1910
  /** A rich document. */
1314
1911
  export declare interface RichDocument {
1315
1912
  readonly type: 'doc';
1316
1913
  readonly blocks: ReadonlyArray<RichBlock>;
1914
+ /** The profile it was saved against (`article@2`). */
1915
+ readonly profile?: string;
1317
1916
  }
1318
1917
 
1319
1918
  export declare const RichDocumentEditor: (props: RichDocumentEditorProps) => ReactNode;
@@ -1333,6 +1932,8 @@ export declare interface RichDocumentEditorProps extends WidgetProps {
1333
1932
  * tables keep their lines either way.
1334
1933
  */
1335
1934
  readonly surface?: 'markup' | 'visual';
1935
+ /** Renders the props form of a component between the blocks (`ContentForm` passes its own, nested). */
1936
+ readonly renderComponentProps?: (definition: ComponentDefinition, props: Readonly<Record<string, unknown>>, onChange: (props: Readonly<Record<string, unknown>>) => void) => ReactNode;
1336
1937
  }
1337
1938
 
1338
1939
  /** Translate a Contentful rich-text document, and say what could not be translated. */
@@ -1350,6 +1951,15 @@ export declare type RichDocumentPicker = (props: {
1350
1951
  readonly type: string;
1351
1952
  readonly value: string;
1352
1953
  readonly onChange: (documentId: string) => void;
1954
+ /** Where the choice goes, for a picker that hands off to another tool (a selection intent): the field and, inside a rich text, the block. */
1955
+ readonly target?: {
1956
+ readonly field: string;
1957
+ readonly blockId?: string;
1958
+ };
1959
+ /** What the choice is for — an image block's image, a download block's file, a link's target, a contact — when two pickers share a `type`. */
1960
+ readonly role?: 'image' | 'file' | 'link' | 'contact';
1961
+ /** The id of the element that names the choice (a link's "Link to"): a control the picker renders is labelled by it (`aria-labelledby`). */
1962
+ readonly labelledBy?: string;
1353
1963
  }) => ReactNode;
1354
1964
 
1355
1965
  /** One problem with a rich document, at a path below the field. */
@@ -1359,7 +1969,7 @@ export declare interface RichDocumentProblem {
1359
1969
  readonly message: string;
1360
1970
  }
1361
1971
 
1362
- /** Everything wrong with `value` as a rich document under `options`. */
1972
+ /** Everything wrong with `value` as a rich document under `options` (component props are checked by the caller). */
1363
1973
  export declare const richDocumentProblems: (path: string, value: unknown, options: RichTextOptions) => ReadonlyArray<RichDocumentProblem>;
1364
1974
 
1365
1975
  /** A document reference found in a rich document. */
@@ -1373,7 +1983,7 @@ export declare interface RichDocumentReference {
1373
1983
  export declare const richDocumentReferences: (path: string, doc: RichDocument, options: RichTextOptions) => ReadonlyArray<RichDocumentReference>;
1374
1984
 
1375
1985
  /** The document's blocks, in order. Renders nothing for a value that is not a rich document. */
1376
- export declare const RichDocumentView: ({ document, hrefOf, renderImage }: RichDocumentViewProps) => ReactNode;
1986
+ export declare const RichDocumentView: ({ document, hrefOf, renderImage, contactHrefOf, renderComponent, fileHrefOf }: RichDocumentViewProps) => ReactNode;
1377
1987
 
1378
1988
  export declare interface RichDocumentViewProps {
1379
1989
  /** A stored `Schema.RichText()` value (a plain string renders as paragraphs). */
@@ -1385,19 +1995,37 @@ export declare interface RichDocumentViewProps {
1385
1995
  readonly asset: string;
1386
1996
  readonly caption?: string;
1387
1997
  }) => ReactNode;
1388
- }
1389
-
1390
- /** A run of text inside a block. */
1391
- export declare type RichInline = {
1998
+ /** The `mailto:` / `tel:` address of a published contact point, or undefined when it is not live. */
1999
+ readonly contactHrefOf?: (documentId: string) => string | undefined;
2000
+ /** Render a component placed between the blocks; without it, components are left out. */
2001
+ readonly renderComponent?: (block: ComponentBlock) => ReactNode;
2002
+ /** The address a download block's file is fetched from, or undefined when it is not live — then the download is left out, never a dead link. */
2003
+ readonly fileHrefOf?: (asset: string) => string | undefined;
2004
+ }
2005
+
2006
+ /** A run of text inside a block. `change` marks it as suggested. */
2007
+ export declare type RichInline =
2008
+ /** `style` names a token of the profile's style group (`lead`, `note`). */
2009
+ {
1392
2010
  readonly type: 'text';
1393
2011
  readonly text: string;
1394
2012
  readonly marks?: ReadonlyArray<RichMark>;
2013
+ readonly style?: string;
2014
+ readonly change?: RichChange;
1395
2015
  }
1396
2016
  /** A link to a document (by its documentId) — the site resolves its address. */
1397
2017
  | {
1398
2018
  readonly type: 'link';
1399
2019
  readonly target: string;
1400
2020
  readonly text: string;
2021
+ readonly change?: RichChange;
2022
+ }
2023
+ /** An e-mail address or a phone number — the site makes it a `mailto:` / `tel:` link. */
2024
+ | {
2025
+ readonly type: 'contact';
2026
+ readonly text: string;
2027
+ readonly contact: RichContact;
2028
+ readonly change?: RichChange;
1401
2029
  };
1402
2030
 
1403
2031
  /** An inline mark. */
@@ -1405,12 +2033,39 @@ export declare type RichMark = 'bold' | 'italic' | 'underline';
1405
2033
 
1406
2034
  /**
1407
2035
  * Which resources a rich-text field may hold: `images` names the content type
1408
- * an image block references (an asset type), `links` the type a link
1409
- * references (a page type). Unset → that node is not allowed.
2036
+ * an image block references (an asset type), `files` the type a download
2037
+ * block references (an asset type), `links` the type a link references (a
2038
+ * page type). Unset → that node is not allowed.
1410
2039
  */
1411
2040
  export declare interface RichTextOptions {
1412
2041
  readonly images?: string;
2042
+ /** The asset type a download block references; unset → no downloads. */
2043
+ readonly files?: string;
1413
2044
  readonly links?: string;
2045
+ /** What this field allows beyond that; without one, every built-in block and mark, no styles, components or contacts. */
2046
+ readonly profile?: RichTextProfile;
2047
+ }
2048
+
2049
+ /** What a rich-text field allows (`defineRichTextProfile`). Versioned: a change bumps `version`. */
2050
+ export declare interface RichTextProfile {
2051
+ readonly name: string;
2052
+ readonly version: number;
2053
+ /** `<name>@<version>` — what a saved document records. */
2054
+ readonly id: string;
2055
+ readonly blocks: ReadonlyArray<RichBlockKind>;
2056
+ readonly headings: ReadonlyArray<2 | 3>;
2057
+ readonly marks: ReadonlyArray<RichMark>;
2058
+ /** Named styles of paragraphs, headings, lists and runs of text: one design-token group, name → meaning. */
2059
+ readonly styles?: {
2060
+ readonly group: string;
2061
+ readonly tokens: Readonly<Record<string, string>>;
2062
+ };
2063
+ /** The components that may sit between the blocks. */
2064
+ readonly components: ReadonlyArray<ComponentDefinition>;
2065
+ /** The content type of the published contact points (e-mail, phone) a text may name. */
2066
+ readonly contactPoints?: string;
2067
+ /** Whether a text may hold a one-off e-mail address or phone number (checked on save). */
2068
+ readonly contactLiterals: boolean;
1414
2069
  }
1415
2070
 
1416
2071
  export declare const RichTextSurface: (props: RichTextSurfaceProps) => ReactNode;
@@ -1454,6 +2109,20 @@ export declare const Schema: {
1454
2109
  readonly unique: () => FieldRefinement;
1455
2110
  /** Closed value set → `<select>` widget + a CHECK constraint. */
1456
2111
  readonly Literal: (values_0: string, ...values: string[]) => PipeableField;
2112
+ /**
2113
+ * A design token of one group (`tone`, `space`) from the set the design
2114
+ * system declares with `defineDesignTokens`: the editor picks a NAME, never
2115
+ * a colour or a size, and the renderer maps the name to its style. Stored
2116
+ * and checked like a literal.
2117
+ */
2118
+ readonly Token: (tokens: DesignTokens, group: string) => PipeableField;
2119
+ /**
2120
+ * An action a component performs, chosen from the ones its renderer
2121
+ * implements (`{ follow: 'Go to the target page', share: 'Share this page' }`):
2122
+ * the editor picks what happens, the developer owns how. Stored and checked
2123
+ * like a literal; the labels are what the editor reads.
2124
+ */
2125
+ readonly Action: (actions: Readonly<Record<string, string>>) => PipeableField;
1457
2126
  /**
1458
2127
  * Rich text, stored as a `RichDocument` (see richDocument.ts): blocks with
1459
2128
  * stable ids — paragraph, heading, list, table, image — and inline text
@@ -1491,12 +2160,61 @@ declare interface SearchConfig {
1491
2160
  readonly title: string;
1492
2161
  }
1493
2162
 
2163
+ /** The answer of an intent: which resource was chosen. */
2164
+ export declare interface SelectionAnswer {
2165
+ readonly intentId: string;
2166
+ readonly documentId: string;
2167
+ /** What the chosen resource is called — the link text when nothing was selected. */
2168
+ readonly title?: string;
2169
+ }
2170
+
2171
+ export declare interface SelectionIntent {
2172
+ readonly id: string;
2173
+ /** The content type to pick from (`asset`, `page`). */
2174
+ readonly pick: string;
2175
+ /** What kind of it is wanted, when the type holds several (`image`, `file`); the tool shows only those. */
2176
+ readonly kind?: string;
2177
+ readonly target: SelectionTarget;
2178
+ /** The app-relative address to go back to. */
2179
+ readonly returnTo: string;
2180
+ /** What the picking tool shows about the target (`Planting guide — Text, image 3`). */
2181
+ readonly label?: string;
2182
+ }
2183
+
2184
+ /** Where a chosen resource goes. */
2185
+ export declare interface SelectionTarget {
2186
+ /** The type being edited; the document and the revision the intent was made on — or, before the draft is saved, the open form (`formId`). */
2187
+ readonly type: string;
2188
+ readonly documentId?: string;
2189
+ readonly revisionId?: string;
2190
+ readonly formId?: string;
2191
+ readonly locale?: string;
2192
+ /** The field; with `blockId`, a block of that rich text (an image block's asset, or a link over `selection`). */
2193
+ readonly field: string;
2194
+ readonly blockId?: string;
2195
+ /** With `prop`: a placed component of a components field, by its instance id, and the prop that takes the choice. */
2196
+ readonly instanceId?: string;
2197
+ readonly prop?: string;
2198
+ /** For a link: the text it is made over, by character offset in the block's text. */
2199
+ readonly selection?: {
2200
+ readonly start: number;
2201
+ readonly end: number;
2202
+ };
2203
+ }
2204
+
1494
2205
  /** What is wrong with values for a manifest's settings; empty when nothing is. Unknown keys are refused. */
1495
2206
  export declare const settingsProblems: (manifest: CmsExtensionManifest, values: Readonly<Record<string, unknown>>) => ReadonlyArray<string>;
1496
2207
 
1497
2208
  /** The settings with their defaults filled in, dropping keys the manifest no longer has. */
1498
2209
  export declare const settingsWithDefaults: (manifest: CmsExtensionManifest, stored: Readonly<Record<string, unknown>>) => Readonly<Record<string, ExtensionSettingValue>>;
1499
2210
 
2211
+ /**
2212
+ * Whether an origin response may be stored by a shared cache: eligibility is
2213
+ * checked again after the origin answered — a `Set-Cookie`, `private` or
2214
+ * `no-store` keeps it out whatever the request looked like.
2215
+ */
2216
+ export declare const sharedCacheable: (headers: Readonly<Record<string, string | undefined>>) => boolean;
2217
+
1500
2218
  export declare interface SitemapUrl extends PageAlternate {
1501
2219
  readonly documentId: string;
1502
2220
  /** ISO date of the variant's last change, when known. */
@@ -1533,6 +2251,16 @@ export declare const sourceAttributes: (path: string) => {
1533
2251
  /** The field path behind a clicked element of the preview, or null. */
1534
2252
  export declare const sourcePathOf: (target: unknown) => string | null;
1535
2253
 
2254
+ /** A placed component saved against an earlier definition of it, with no migration to upgrade it. */
2255
+ export declare interface StaleComponent {
2256
+ readonly path: string;
2257
+ readonly componentId: string;
2258
+ readonly fingerprint: string | null;
2259
+ }
2260
+
2261
+ /** The instances in `values` (nested ones included) that a save would not upgrade — their definition changed and names no migration from them. */
2262
+ export declare const staleComponents: (type: Pick<ContentType, "fields">, values: Readonly<Record<string, unknown>>) => ReadonlyArray<StaleComponent>;
2263
+
1536
2264
  /** A type's taxonomy — see `ContentTypeSpec.taxonomy`. */
1537
2265
  export declare interface TaxonomyConfig {
1538
2266
  /** A declared `Schema.Array(Schema.String)` field. */
@@ -1554,6 +2282,8 @@ export declare interface TemplatesConfig {
1554
2282
  readonly field: string;
1555
2283
  /** The `Schema.Components` field the rules apply to. */
1556
2284
  readonly components: string;
2285
+ /** The component prop that holds a placement's width (`widths`); default `width`. */
2286
+ readonly width?: string;
1557
2287
  readonly list: ReadonlyArray<PageTemplate>;
1558
2288
  }
1559
2289
 
@@ -1567,6 +2297,9 @@ export declare const templateValues: (type: Typed, templateId: string) => Record
1567
2297
  /** Where a row breaks the rules of the template it names. Empty when it keeps them. */
1568
2298
  export declare const templateViolations: (type: Typed, row: Readonly<Record<string, unknown>>) => ReadonlyArray<FieldViolation>;
1569
2299
 
2300
+ /** The current selection inside a text surface, as character offsets into its text — what a selection intent's `selection` is made of; null when it is elsewhere. */
2301
+ export declare const textSelectionIn: (root: HTMLElement) => [number, number] | null;
2302
+
1570
2303
  /**
1571
2304
  * Put `mark` on the text in `[start, end)`, or take it off when all of it
1572
2305
  * already carries it. Text runs are split at the edges; a link is left as it
@@ -1584,6 +2317,38 @@ export declare interface ToolExposure {
1584
2317
  /** An XLIFF 2.1 core document for one file. */
1585
2318
  export declare const toXliff: (exchange: XliffExchange) => string;
1586
2319
 
2320
+ /** `edited` (a copy of `base` someone changed) as suggestions inside `base`. */
2321
+ export declare const trackChanges: (base: RichDocument, edited: RichDocument, author: ChangeAuthor) => TrackedChanges;
2322
+
2323
+ /** The document with the edit suggested, and the blocks it could not suggest over (they hold others' suggestions). */
2324
+ export declare interface TrackedChanges {
2325
+ readonly document: RichDocument;
2326
+ readonly conflicts: ReadonlyArray<string>;
2327
+ }
2328
+
2329
+ /** One run with the edit from `base` to `edited` suggested: the changed middle as a deletion and an insertion. */
2330
+ export declare const trackInline: (base: ReadonlyArray<RichInline>, edited: ReadonlyArray<RichInline>, author: ChangeAuthor) => ReadonlyArray<RichInline>;
2331
+
2332
+ /**
2333
+ * What an exchange does not carry, so the export can say so instead of
2334
+ * losing it silently:
2335
+ *
2336
+ * - `suggestedChange`: a block holds suggested changes (track changes). Its
2337
+ * text goes out as written, insertions and deletions alike, and a
2338
+ * translation coming back has no suggestion marks — decide them first.
2339
+ * - `unknownComponent`: a component whose definition the field no longer
2340
+ * declares; its text is not exported and stays as it is.
2341
+ */
2342
+ export declare interface TranslationLoss {
2343
+ /** Where: `body/<blockId>`, `sections/<instanceId>`, or deeper inside a component. */
2344
+ readonly id: string;
2345
+ /** Suggested changes flattened into the text, or a component's text left out. */
2346
+ readonly kind: 'suggestedChange' | 'unknownComponent';
2347
+ }
2348
+
2349
+ /** What exporting these values as translation units leaves out or flattens, in field order. */
2350
+ export declare const translationLosses: (fields: Readonly<Record<string, FieldSchema>>, values: Readonly<Record<string, unknown>>, prefix?: string) => ReadonlyArray<TranslationLoss>;
2351
+
1587
2352
  export declare interface TranslationUnit {
1588
2353
  /** Where the text lives: `title`, `body/<blockId>`, `body/<blockId>/<item>`,
1589
2354
  * `body/<blockId>/<row>.<cell>`, `body/<blockId>/caption`,
@@ -1725,8 +2490,23 @@ export declare interface WidgetProps {
1725
2490
  readonly field: FieldSchema;
1726
2491
  readonly value: unknown;
1727
2492
  readonly onChange: (value: unknown) => void;
2493
+ /**
2494
+ * Where the value lives: the field, and for a prop of a placed component
2495
+ * its instance and prop — what a picker hands to a selection intent.
2496
+ */
2497
+ readonly target?: WidgetTarget;
1728
2498
  }
1729
2499
 
2500
+ /** Where a widget's value lives (a `SelectionTarget`'s `field`, `instanceId`, `prop`). */
2501
+ declare interface WidgetTarget {
2502
+ readonly field: string;
2503
+ readonly instanceId?: string;
2504
+ readonly prop?: string;
2505
+ }
2506
+
2507
+ /** A block with its text replaced by `text` in its markup (the inverse of `blockMarkup`); `styles` are the names `{name|…}` may use. */
2508
+ export declare const withBlockMarkup: (block: RichBlock, text: string, styles?: ReadonlyArray<string>) => RichBlock;
2509
+
1730
2510
  /** A component withheld for want of consent: which purpose would release it. */
1731
2511
  export declare interface WithheldInstance {
1732
2512
  readonly instanceId: string;
@@ -1735,6 +2515,22 @@ export declare interface WithheldInstance {
1735
2515
  readonly props: Readonly<Record<string, never>>;
1736
2516
  }
1737
2517
 
2518
+ declare interface WorkflowStep {
2519
+ /** camelCase, unique within the workflow. */
2520
+ readonly id: string;
2521
+ readonly label: string;
2522
+ /** The scope a person needs to decide this step (a delegate decides without it). */
2523
+ readonly approverScope: string;
2524
+ /** Steps that must be approved before this one opens. */
2525
+ readonly after?: ReadonlyArray<string>;
2526
+ /** The step applies only when this holds for the revision's values. */
2527
+ readonly when?: (values: Readonly<Record<string, unknown>>) => boolean;
2528
+ /** Hours the step may stay open once it is open; later it is overdue. */
2529
+ readonly slaHours?: number;
2530
+ /** Approving needs evidence: a link or a note saying what was checked. */
2531
+ readonly evidence?: boolean;
2532
+ }
2533
+
1738
2534
  export declare interface XliffExchange {
1739
2535
  readonly srcLang: string;
1740
2536
  readonly trgLang: string;