@relyio/sdk 0.12.0 → 0.14.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 +228 -0
- package/dist/{chunk-3DRDHXLY.js → chunk-5UMY6CS4.js} +435 -23
- package/dist/{chunk-FRJEUAAF.js → chunk-DBBZVZOS.js} +968 -2670
- package/dist/{chunk-DXCVO6M5.cjs → chunk-GUPV2M3X.cjs} +969 -2680
- package/dist/{chunk-POEEDYFM.js → chunk-PCFTJLEP.js} +543 -260
- package/dist/{chunk-FI5VIF4M.cjs → chunk-RSHMA4KT.cjs} +442 -22
- package/dist/{chunk-3MSFWXQL.cjs → chunk-X4KSS7PP.cjs} +542 -260
- package/dist/client/index.cjs +3 -3
- package/dist/client/index.d.cts +4 -5
- package/dist/client/index.d.ts +4 -5
- package/dist/client/index.js +1 -1
- package/dist/{include-paths-CL4gHv6I.d.cts → define-content-type-BUZeWtpk.d.cts} +4458 -1312
- package/dist/{include-paths-CrJNTsMl.d.ts → define-content-type-DOrZb_a_.d.ts} +4458 -1312
- package/dist/define-schema-5aHmsA8j.d.ts +699 -0
- package/dist/define-schema-nCfZeboB.d.cts +699 -0
- package/dist/index-B97ZDj44.d.ts +507 -0
- package/dist/index-C-pcllqY.d.cts +507 -0
- package/dist/index-DOhFQbv7.d.ts +3065 -0
- package/dist/index-DgVV5Nj7.d.cts +3065 -0
- package/dist/index.cjs +114 -147
- package/dist/index.d.cts +49 -87
- package/dist/index.d.ts +49 -87
- package/dist/index.js +5 -29
- 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 +26 -6
- package/dist/rich-text/index.d.cts +3 -148
- package/dist/rich-text/index.d.ts +3 -148
- package/dist/rich-text/index.js +1 -1
- 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 +33 -37
- package/dist/schema/index.d.cts +37 -191
- package/dist/schema/index.d.ts +37 -191
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -3
- package/dist/types/index.d.ts +2 -3
- package/package.json +14 -3
- package/dist/define-schema-DgctHlI2.d.cts +0 -1034
- package/dist/define-schema-mrEZbY1h.d.ts +0 -1034
- package/dist/index-B9RfZVF1.d.ts +0 -861
- package/dist/index-BrvEg6-A.d.cts +0 -3729
- package/dist/index-Pw0onkJe.d.ts +0 -3729
- package/dist/index-b-AkfTUv.d.cts +0 -861
- package/dist/rich-text.d-rKmpgdGd.d.cts +0 -200
- package/dist/rich-text.d-rKmpgdGd.d.ts +0 -200
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nesting composes through the declaration: a field's nested fields, each with the facets its own
|
|
3
|
+
* kind declares, under its key path (REL-1783). No package writes code per shape — an object's
|
|
4
|
+
* fields and a list item's fields are reached by the same walk, and each is declared by the kind it
|
|
5
|
+
* is.
|
|
6
|
+
*
|
|
7
|
+
* **An object's value and a list's items take a Shape** (REL-1796, REL-1799, ADR 0012): `config.of`
|
|
8
|
+
* is a fieldset, or several — a page builder for a list (REL-1798), one value of either shape for an
|
|
9
|
+
* object — and each item, and an object's one value, holds its fieldset's fields beside
|
|
10
|
+
* {@link LIST_ITEM_TYPE} (the fieldset's id) and {@link LIST_ITEM_KEY}. {@link shapesOf} is the one
|
|
11
|
+
* reading of `of`, for both kinds — every consumer asks it for a field's shapes and never reads
|
|
12
|
+
* `of` itself.
|
|
13
|
+
*
|
|
14
|
+
* **The path convention.** A path is its segments: the fields of an object's value and of a list's
|
|
15
|
+
* items sit under the field's id and the **item segment of their shape**, {@link itemSegmentOf} —
|
|
16
|
+
* `$` and the shape's id (`hero`, `$screenshot`, `alt`; `sections`, `$hero`, `heading`). Joined
|
|
17
|
+
* with `.`: `hero.$screenshot.alt`, `faq.$question.question`, `sections.$hero.heading`. An object's
|
|
18
|
+
* value is walked exactly as a list item is, so the walk path of an object's field and of a list
|
|
19
|
+
* item's look alike to every consumer, and an object is "a list of one" to anything that reads a
|
|
20
|
+
* path. The item segment names the shape because two shapes are two records: `heading` in `hero`
|
|
21
|
+
* and `heading` in `ctaBanner` are not one field (owner, REL-1990 item 2), so a change, a count or a
|
|
22
|
+
* rewrite of one never reaches the other's values, and a value walk takes only the values whose
|
|
23
|
+
* `_type` the segment names (`./values`). It names it for one shape too, so adding a second shape
|
|
24
|
+
* changes no path. A bare {@link LIST_ITEM_SEGMENT} is every item whatever its shape — what a caller
|
|
25
|
+
* writing a path by hand may still pass to `./values` — and the walk never produces it.
|
|
26
|
+
* `SchemaReader`'s own expansion (`ExpandedField.path`, `faq.$.question`) is the reader's spelling
|
|
27
|
+
* and is not this walk's; the validation document nests objects and AJV reports `/faq/0/question`
|
|
28
|
+
* and `/hero/alt`; and the design addresses one item by its key,
|
|
29
|
+
* `sections[_key=="f2k6ub9s"].heading`, and an object's field by its id, `hero.alt` — an object
|
|
30
|
+
* holds one value, so it needs no key in an address (`./item-keys`).
|
|
31
|
+
*
|
|
32
|
+
* Two differences from the reader's expansion are deliberate. The walk descends into shapes always,
|
|
33
|
+
* where the reader does only when asked; and it has no depth cap, where the reader stops at three
|
|
34
|
+
* levels of nesting (`maxDepth`). It stops at a shape that contains itself instead, and says so —
|
|
35
|
+
* deploy refuses such a schema (`FieldsetValidator`), so a served one has none.
|
|
36
|
+
*
|
|
37
|
+
* Structural, and dependency-free like `./declaration`: it reads `id`, `type` and `config.of` of a
|
|
38
|
+
* field and the `fields` of each shape and section, and nothing else.
|
|
39
|
+
*
|
|
40
|
+
* **A section adds no segment** (REL-1794). A type's `fields` — and a fieldset's — hold fields and
|
|
41
|
+
* fieldsets side by side, in one order; a fieldset placed there is a Section, whose fields join the
|
|
42
|
+
* record it sits in. So {@link walkMembers} reaches a section's fields under the path of the record
|
|
43
|
+
* the section sits in, exactly as if they had been declared beside it, and a read, a filter path, a
|
|
44
|
+
* reference path or a count never learns that a form groups them. {@link fieldsOfMembers} is the same
|
|
45
|
+
* flattening for a consumer that wants the fields and not their facets.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The `_type` of an entry link: a rich-text mark linking text to another entry (REL-1808,
|
|
50
|
+
* `./rich-text`'s `RichTextEntryLinkMark`). Declared here, beside the walk that finds it.
|
|
51
|
+
*/
|
|
52
|
+
declare const RICH_TEXT_ENTRY_LINK_TYPE = "entryLink";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Rich text's stored and served value: a tree we define (ADR 0013, REL-1803).
|
|
56
|
+
*
|
|
57
|
+
* A `richText` field holds one {@link RichTextValue} per locale — a documented, **versioned** JSON
|
|
58
|
+
* tree shaped like the editor's document: a quote and a list item hold blocks, lists nest, a text
|
|
59
|
+
* run names its marks. Every node carries `_type`; every node but a text run carries `_key`, unique
|
|
60
|
+
* within the field. It is not Portable Text (flat: a quote of two paragraphs becomes two quotes,
|
|
61
|
+
* nested lists become levels) and not TipTap's JSON (TipTap's node names and attributes would be
|
|
62
|
+
* our public API, and a TipTap upgrade a breaking change for customers). The vocabulary is written
|
|
63
|
+
* down for readers in `devtools/docs/guide/schema/field-types/rich-text-format.md`; this module is
|
|
64
|
+
* its one definition in code.
|
|
65
|
+
*
|
|
66
|
+
* **The version grows by addition.** {@link RICH_TEXT_VERSION} changes only when a node, a mark or
|
|
67
|
+
* an attribute is renamed, removed or reshaped. A new node type, a new mark, a new `list` style or a
|
|
68
|
+
* new optional attribute is not a version change — the docs set's built-ins (REL-1805: tables, task
|
|
69
|
+
* lists, code groups with tabs, highlight, sub- and superscript) arrived inside version 1, and P3b's
|
|
70
|
+
* entry links and declared blocks will, so a reader must treat a `_type` it does not know as content
|
|
71
|
+
* it cannot draw rather than as an error.
|
|
72
|
+
*
|
|
73
|
+
* **A field narrows the docs set** (REL-1805): its config's `structure`, `marks` and `multiline` are
|
|
74
|
+
* read by {@link richTextNarrowingOf}, held to on every write by {@link richTextNarrowingProblems}
|
|
75
|
+
* (the validation document's `x-richTextNarrowing` keyword), enforced in the editor by
|
|
76
|
+
* `@relyio/studio-core`'s `RichTextPolicy`, and applied by schema adaptation through
|
|
77
|
+
* {@link narrowRichText} when a field is narrowed over content it no longer allows.
|
|
78
|
+
*
|
|
79
|
+
* Who uses it: the projection writes and reads a live document by it (`@relyio/entry-projection`'s
|
|
80
|
+
* `./blocks`), the validation document holds a written value to it ({@link richTextProblems}), the
|
|
81
|
+
* write core keys a written value ({@link keyRichText}), the index embeds its text
|
|
82
|
+
* ({@link richTextPlainText}), and `@relyio/sdk` types a read by it (the types only, build-inlined
|
|
83
|
+
* through the package root).
|
|
84
|
+
*
|
|
85
|
+
* **Declared Blocks and Inline elements** (REL-1807): a field's `blocks` and `inline` name
|
|
86
|
+
* fieldsets an editor inserts between paragraphs and inside a sentence. Each stands in the tree as
|
|
87
|
+
* the fieldset's value — `{ _type: <fieldset id>, _key, …fields }`, exactly a page builder's item —
|
|
88
|
+
* wherever blocks, or inline content, go. A rich-text field of it is a tree of its own (a callout's
|
|
89
|
+
* title and body), whose keys are the field's. The tree's walk ({@link richTextProblems}) takes such
|
|
90
|
+
* a node by its `_type` and reads no schema; the field's narrowing says which it declares, and the
|
|
91
|
+
* shape's own validation fragment holds its fields.
|
|
92
|
+
*
|
|
93
|
+
* Dependency-free like `./declaration` (`__tests__/dependency-free.test.ts`): its runtime imports
|
|
94
|
+
* are `./walk`'s and `./declared-text`'s, inside the subpath.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/** The format's version. The stored value carries it, so a reader knows which vocabulary it holds. */
|
|
98
|
+
declare const RICH_TEXT_VERSION = 1;
|
|
99
|
+
/** The root's `_type`: what a value of a `richText` field is. */
|
|
100
|
+
declare const RICH_TEXT_TYPE = "richText";
|
|
101
|
+
/**
|
|
102
|
+
* A rich-text field's value: the root of the tree. The root is the field, so it has no `_key`.
|
|
103
|
+
*
|
|
104
|
+
* `B` and `I` are the field's declared Blocks and Inline elements (REL-1807): the values of the
|
|
105
|
+
* fieldsets its `blocks` and `inline` name, each `{ _type, _key, …fields }` exactly as a page
|
|
106
|
+
* builder's item is. Both are `never` for a field that declares none, which is every built-in's
|
|
107
|
+
* reading; the SDK infers them from a field's config, so a read of a field declaring a callout is a
|
|
108
|
+
* tree that may hold one where blocks go.
|
|
109
|
+
*/
|
|
110
|
+
interface RichTextValue<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> {
|
|
111
|
+
readonly _type: typeof RICH_TEXT_TYPE;
|
|
112
|
+
readonly version: typeof RICH_TEXT_VERSION;
|
|
113
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A link to another entry (REL-1808): a **reference** — `to`, the target entry's id — and an optional
|
|
117
|
+
* `anchor`, a heading on it ({@link richTextHeadingAnchors}). A mark, as a link to a URL is, so it
|
|
118
|
+
* wraps any run of text and the formatting inside it. It may point only at the types its field's
|
|
119
|
+
* `links` names, and it is found, checked on publish, blocks or is nullified on its target's delete,
|
|
120
|
+
* purges and expands as every reference does: its walk path is `<field>.~entryLink.to`
|
|
121
|
+
* (`./walk`'s `richTextTreeSegmentOf`).
|
|
122
|
+
*
|
|
123
|
+
* `To` is what `to` holds: the id, as it is stored and written — and the target entry itself in a read
|
|
124
|
+
* whose include paths expand the field, as a reference field's id becomes the entry.
|
|
125
|
+
*/
|
|
126
|
+
interface RichTextEntryLinkMark<To = string> {
|
|
127
|
+
readonly _type: typeof RICH_TEXT_ENTRY_LINK_TYPE;
|
|
128
|
+
readonly to: To;
|
|
129
|
+
readonly anchor?: string;
|
|
130
|
+
}
|
|
131
|
+
/** An entry link, whatever its `to` holds: the third parameter of {@link RichTextValue}. */
|
|
132
|
+
type AnyRichTextEntryLink = RichTextEntryLinkMark<unknown>;
|
|
133
|
+
/** What every node but a text run carries: its identity within the field (design decision 10). */
|
|
134
|
+
interface RichTextKeyed {
|
|
135
|
+
readonly _key: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* What every declared Block and Inline element carries (REL-1807): the fieldset's id in `_type` and
|
|
139
|
+
* its Item key in `_key`, beside the fieldset's fields — the value a page builder's item of the same
|
|
140
|
+
* fieldset is. Its `_type` is never a built-in's name (deploy refuses such a fieldset in rich text,
|
|
141
|
+
* {@link RICH_TEXT_RESERVED_SHAPE_IDS}).
|
|
142
|
+
*/
|
|
143
|
+
interface RichTextShapeValue extends RichTextKeyed {
|
|
144
|
+
readonly _type: string;
|
|
145
|
+
}
|
|
146
|
+
/** A paragraph: inline content. */
|
|
147
|
+
interface RichTextParagraph<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
148
|
+
readonly _type: 'paragraph';
|
|
149
|
+
readonly children: ReadonlyArray<RichTextInline<I, L>>;
|
|
150
|
+
}
|
|
151
|
+
/** The heading levels, as numbers. */
|
|
152
|
+
declare const RICH_TEXT_HEADING_LEVELS: readonly [1, 2, 3, 4, 5, 6];
|
|
153
|
+
/**
|
|
154
|
+
* A heading of `level` 1 to 6: inline content. Its anchor — what an entry link's `anchor` names and
|
|
155
|
+
* the `id` a renderer gives it — is derived from its text ({@link richTextHeadingAnchors}).
|
|
156
|
+
*/
|
|
157
|
+
interface RichTextHeading<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
158
|
+
readonly _type: 'heading';
|
|
159
|
+
readonly level: (typeof RICH_TEXT_HEADING_LEVELS)[number];
|
|
160
|
+
readonly children: ReadonlyArray<RichTextInline<I, L>>;
|
|
161
|
+
}
|
|
162
|
+
/** A quote: one block or more — a quote of two paragraphs is one quote. */
|
|
163
|
+
interface RichTextQuote<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
164
|
+
readonly _type: 'quote';
|
|
165
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The list styles. Version 1 held `bullet` and `numbered`; REL-1805 added `task`, whose items each
|
|
169
|
+
* carry `checked`, without a version change.
|
|
170
|
+
*/
|
|
171
|
+
declare const RICH_TEXT_LIST_STYLES: readonly ['bullet', 'numbered', 'task'];
|
|
172
|
+
type RichTextListStyle = (typeof RICH_TEXT_LIST_STYLES)[number];
|
|
173
|
+
/**
|
|
174
|
+
* A list: one item or more. `start` is a numbered list's first number, present only when it is not
|
|
175
|
+
* `1`. Lists nest: an item holds blocks, and a list is a block.
|
|
176
|
+
*/
|
|
177
|
+
interface RichTextList<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
178
|
+
readonly _type: 'list';
|
|
179
|
+
readonly style: RichTextListStyle;
|
|
180
|
+
readonly start?: number;
|
|
181
|
+
readonly children: ReadonlyArray<RichTextListItem<B, I, L>>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A list's item: blocks, the first of them a paragraph (the editor's model, `paragraph block*`).
|
|
185
|
+
* `checked` is a task list's item's, and present on every one of them: whether its task is done.
|
|
186
|
+
* An item of a bullet or a numbered list carries none.
|
|
187
|
+
*/
|
|
188
|
+
interface RichTextListItem<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
189
|
+
readonly _type: 'listItem';
|
|
190
|
+
readonly checked?: boolean;
|
|
191
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
192
|
+
}
|
|
193
|
+
/** The lines of a file a code block is, 1-based and inclusive: the docs' code citations. */
|
|
194
|
+
interface RichTextCodeLines {
|
|
195
|
+
readonly start: number;
|
|
196
|
+
readonly end: number;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A block of code: its text exactly, newlines included, with no marks, and the `language` it is
|
|
200
|
+
* written in when one is named. Standing in a code group it is one of the group's tabs, and `label`
|
|
201
|
+
* is the tab's name; `filename` is the file it shows and `lines` which of that file's lines. All
|
|
202
|
+
* three are optional, alone or in a group (REL-1805).
|
|
203
|
+
*/
|
|
204
|
+
interface RichTextCodeBlock extends RichTextKeyed {
|
|
205
|
+
readonly _type: 'codeBlock';
|
|
206
|
+
readonly language?: string;
|
|
207
|
+
readonly label?: string;
|
|
208
|
+
readonly filename?: string;
|
|
209
|
+
readonly lines?: RichTextCodeLines;
|
|
210
|
+
readonly text: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Code with tabs: one code block or more, each a tab — the same snippet for another language,
|
|
214
|
+
* package manager or client (REL-1805). Each tab's text is its own, so two people typing in two tabs
|
|
215
|
+
* keep both. A `code` field holds this node as its value (REL-1806).
|
|
216
|
+
*/
|
|
217
|
+
interface RichTextCodeGroup extends RichTextKeyed {
|
|
218
|
+
readonly _type: 'codeGroup';
|
|
219
|
+
readonly children: readonly RichTextCodeBlock[];
|
|
220
|
+
}
|
|
221
|
+
/** How a table cell's text is aligned. Absent is the reader's default. */
|
|
222
|
+
declare const RICH_TEXT_CELL_ALIGNMENTS: readonly ['left', 'center', 'right'];
|
|
223
|
+
type RichTextCellAlignment = (typeof RICH_TEXT_CELL_ALIGNMENTS)[number];
|
|
224
|
+
/**
|
|
225
|
+
* A table: one row or more, every row holding the same number of cells (REL-1805). `headerRow` is
|
|
226
|
+
* present, `true`, when the first row is the table's header. Cells hold formatted text, and nothing
|
|
227
|
+
* merges cells. A `table` field holds this node as its value (REL-1806).
|
|
228
|
+
*/
|
|
229
|
+
interface RichTextTable<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
230
|
+
readonly _type: 'table';
|
|
231
|
+
readonly headerRow?: true;
|
|
232
|
+
readonly children: ReadonlyArray<RichTextTableRow<I, L>>;
|
|
233
|
+
}
|
|
234
|
+
/** A table's row: one cell or more. */
|
|
235
|
+
interface RichTextTableRow<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
236
|
+
readonly _type: 'tableRow';
|
|
237
|
+
readonly children: ReadonlyArray<RichTextTableCell<I, L>>;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* A table's cell: one paragraph or more of formatted text, and its alignment when one is set. Its
|
|
241
|
+
* paragraphs hold the field's Inline elements as any paragraph does; never a declared Block.
|
|
242
|
+
*/
|
|
243
|
+
interface RichTextTableCell<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
244
|
+
readonly _type: 'tableCell';
|
|
245
|
+
readonly align?: RichTextCellAlignment;
|
|
246
|
+
readonly children: ReadonlyArray<RichTextParagraph<I, L>>;
|
|
247
|
+
}
|
|
248
|
+
/** A horizontal rule between blocks. */
|
|
249
|
+
interface RichTextDivider extends RichTextKeyed {
|
|
250
|
+
readonly _type: 'divider';
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* A block: what a field, a quote and a list item hold — a built-in, or one of the field's declared
|
|
254
|
+
* Blocks (`B`, REL-1807), which stand wherever blocks go and nowhere else.
|
|
255
|
+
*/
|
|
256
|
+
type RichTextBlock<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextParagraph<I, L> | RichTextHeading<I, L> | RichTextQuote<B, I, L> | RichTextList<B, I, L> | RichTextCodeBlock | RichTextCodeGroup | RichTextTable<I, L> | RichTextDivider | B;
|
|
257
|
+
/**
|
|
258
|
+
* A run of text: its characters and the marks on all of them. `marks` is absent when there are
|
|
259
|
+
* none, and in {@link RICH_TEXT_MARK_ORDER} when there are, each type at most once. A text run has no
|
|
260
|
+
* `_key`: it is not addressable apart from the block that holds it, and the live document gives it no
|
|
261
|
+
* identity to keep. `L` is the field's entry link (REL-1808), `never` for a field that declares no
|
|
262
|
+
* `links`.
|
|
263
|
+
*/
|
|
264
|
+
interface RichTextSpan<L extends AnyRichTextEntryLink = never> {
|
|
265
|
+
readonly _type: 'text';
|
|
266
|
+
readonly text: string;
|
|
267
|
+
readonly marks?: ReadonlyArray<RichTextMark | L>;
|
|
268
|
+
}
|
|
269
|
+
/** A line break inside a paragraph or a heading. */
|
|
270
|
+
interface RichTextLineBreak extends RichTextKeyed {
|
|
271
|
+
readonly _type: 'lineBreak';
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Inline content: what a paragraph and a heading hold — runs, line breaks, and the field's declared
|
|
275
|
+
* Inline elements (`I`, REL-1807) beside its text.
|
|
276
|
+
*/
|
|
277
|
+
type RichTextInline<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextSpan<L> | RichTextLineBreak | I;
|
|
278
|
+
/**
|
|
279
|
+
* The marks a field's `marks` option names, in the order a run holds them: the link first, so a
|
|
280
|
+
* renderer that nests marks in this order wraps the formatting in the anchor. REL-1805 added
|
|
281
|
+
* highlight, subscript and superscript after the first six. The entry link (REL-1808) is not among
|
|
282
|
+
* them: a field allows it by naming the types it links to in `links`, not in `marks` (design
|
|
283
|
+
* decision 31), and it stands second in a run's order ({@link RICH_TEXT_MARK_ORDER}).
|
|
284
|
+
*/
|
|
285
|
+
declare const RICH_TEXT_MARK_TYPES: readonly ['link', 'bold', 'italic', 'underline', 'strike', 'code', 'highlight', 'subscript', 'superscript'];
|
|
286
|
+
type RichTextMarkType = (typeof RICH_TEXT_MARK_TYPES)[number];
|
|
287
|
+
/**
|
|
288
|
+
* A link to a URL. `href` is all a reader is given: whether it opens a new tab and which `rel` it
|
|
289
|
+
* carries are the site's rendering decisions, not content (the editor's defaults for them are not
|
|
290
|
+
* stored), and a link's title was dropped before the tree existed (REL-1942).
|
|
291
|
+
*/
|
|
292
|
+
interface RichTextLinkMark {
|
|
293
|
+
readonly _type: 'link';
|
|
294
|
+
readonly href: string;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* A mark: formatting by name, or a link. `code` holds no other mark beside it, and `subscript` and
|
|
298
|
+
* `superscript` are never on one run together.
|
|
299
|
+
*/
|
|
300
|
+
type RichTextMark = RichTextLinkMark | {
|
|
301
|
+
readonly _type: Exclude<RichTextMarkType, 'link'>;
|
|
302
|
+
};
|
|
303
|
+
/** Any node of the tree below the root. */
|
|
304
|
+
type RichTextNode<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextBlock<B, I, L> | RichTextListItem<B, I, L> | RichTextTableRow<I, L> | RichTextTableCell<I, L> | RichTextInline<I, L>;
|
|
305
|
+
/**
|
|
306
|
+
* The built-ins a field kind holds as its whole value (REL-1806): a `table` field holds a
|
|
307
|
+
* {@link RichTextTable}, a `code` field a {@link RichTextCodeGroup} — the very node a rich-text value
|
|
308
|
+
* holds among its blocks, so a value copied from one to the other is accepted unchanged. Each is read
|
|
309
|
+
* by {@link richTextFieldBlockProblems}, keyed by {@link keyRichTextFieldBlock} and searched by
|
|
310
|
+
* {@link richTextFieldBlockPlainText}.
|
|
311
|
+
*/
|
|
312
|
+
declare const RICH_TEXT_FIELD_BLOCK_TYPES: readonly ['table', 'codeGroup'];
|
|
313
|
+
type RichTextFieldBlockType = (typeof RICH_TEXT_FIELD_BLOCK_TYPES)[number];
|
|
314
|
+
/** A built-in a field holds as its whole value, by its `_type`. */
|
|
315
|
+
type RichTextFieldBlock<T extends RichTextFieldBlockType = RichTextFieldBlockType> = Extract<RichTextBlock, {
|
|
316
|
+
readonly _type: T;
|
|
317
|
+
}>;
|
|
318
|
+
/**
|
|
319
|
+
* The built-in blocks a field's `structure` names (REL-1805): every block but the paragraph, which
|
|
320
|
+
* every field holds. A list is named by its style, since a field may want bullets and no tasks; a
|
|
321
|
+
* code group's tabs come with the group, whether or not `codeBlock` is named.
|
|
322
|
+
*/
|
|
323
|
+
declare const RICH_TEXT_STRUCTURES: readonly ['heading', 'quote', 'bulletList', 'numberedList', 'taskList', 'codeBlock', 'codeGroup', 'table', 'divider'];
|
|
324
|
+
type RichTextStructure = (typeof RICH_TEXT_STRUCTURES)[number];
|
|
325
|
+
|
|
326
|
+
export type { AnyRichTextEntryLink as A, RichTextTableRow as B, RichTextFieldBlockType as R, RichTextFieldBlock as a, RichTextValue as b, RichTextShapeValue as c, RichTextEntryLinkMark as d, RichTextBlock as e, RichTextCellAlignment as f, RichTextCodeBlock as g, RichTextCodeGroup as h, RichTextCodeLines as i, RichTextDivider as j, RichTextHeading as k, RichTextInline as l, RichTextLineBreak as m, RichTextLinkMark as n, RichTextList as o, RichTextListItem as p, RichTextListStyle as q, RichTextMark as r, RichTextMarkType as s, RichTextNode as t, RichTextParagraph as u, RichTextQuote as v, RichTextSpan as w, RichTextStructure as x, RichTextTable as y, RichTextTableCell as z };
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nesting composes through the declaration: a field's nested fields, each with the facets its own
|
|
3
|
+
* kind declares, under its key path (REL-1783). No package writes code per shape — an object's
|
|
4
|
+
* fields and a list item's fields are reached by the same walk, and each is declared by the kind it
|
|
5
|
+
* is.
|
|
6
|
+
*
|
|
7
|
+
* **An object's value and a list's items take a Shape** (REL-1796, REL-1799, ADR 0012): `config.of`
|
|
8
|
+
* is a fieldset, or several — a page builder for a list (REL-1798), one value of either shape for an
|
|
9
|
+
* object — and each item, and an object's one value, holds its fieldset's fields beside
|
|
10
|
+
* {@link LIST_ITEM_TYPE} (the fieldset's id) and {@link LIST_ITEM_KEY}. {@link shapesOf} is the one
|
|
11
|
+
* reading of `of`, for both kinds — every consumer asks it for a field's shapes and never reads
|
|
12
|
+
* `of` itself.
|
|
13
|
+
*
|
|
14
|
+
* **The path convention.** A path is its segments: the fields of an object's value and of a list's
|
|
15
|
+
* items sit under the field's id and the **item segment of their shape**, {@link itemSegmentOf} —
|
|
16
|
+
* `$` and the shape's id (`hero`, `$screenshot`, `alt`; `sections`, `$hero`, `heading`). Joined
|
|
17
|
+
* with `.`: `hero.$screenshot.alt`, `faq.$question.question`, `sections.$hero.heading`. An object's
|
|
18
|
+
* value is walked exactly as a list item is, so the walk path of an object's field and of a list
|
|
19
|
+
* item's look alike to every consumer, and an object is "a list of one" to anything that reads a
|
|
20
|
+
* path. The item segment names the shape because two shapes are two records: `heading` in `hero`
|
|
21
|
+
* and `heading` in `ctaBanner` are not one field (owner, REL-1990 item 2), so a change, a count or a
|
|
22
|
+
* rewrite of one never reaches the other's values, and a value walk takes only the values whose
|
|
23
|
+
* `_type` the segment names (`./values`). It names it for one shape too, so adding a second shape
|
|
24
|
+
* changes no path. A bare {@link LIST_ITEM_SEGMENT} is every item whatever its shape — what a caller
|
|
25
|
+
* writing a path by hand may still pass to `./values` — and the walk never produces it.
|
|
26
|
+
* `SchemaReader`'s own expansion (`ExpandedField.path`, `faq.$.question`) is the reader's spelling
|
|
27
|
+
* and is not this walk's; the validation document nests objects and AJV reports `/faq/0/question`
|
|
28
|
+
* and `/hero/alt`; and the design addresses one item by its key,
|
|
29
|
+
* `sections[_key=="f2k6ub9s"].heading`, and an object's field by its id, `hero.alt` — an object
|
|
30
|
+
* holds one value, so it needs no key in an address (`./item-keys`).
|
|
31
|
+
*
|
|
32
|
+
* Two differences from the reader's expansion are deliberate. The walk descends into shapes always,
|
|
33
|
+
* where the reader does only when asked; and it has no depth cap, where the reader stops at three
|
|
34
|
+
* levels of nesting (`maxDepth`). It stops at a shape that contains itself instead, and says so —
|
|
35
|
+
* deploy refuses such a schema (`FieldsetValidator`), so a served one has none.
|
|
36
|
+
*
|
|
37
|
+
* Structural, and dependency-free like `./declaration`: it reads `id`, `type` and `config.of` of a
|
|
38
|
+
* field and the `fields` of each shape and section, and nothing else.
|
|
39
|
+
*
|
|
40
|
+
* **A section adds no segment** (REL-1794). A type's `fields` — and a fieldset's — hold fields and
|
|
41
|
+
* fieldsets side by side, in one order; a fieldset placed there is a Section, whose fields join the
|
|
42
|
+
* record it sits in. So {@link walkMembers} reaches a section's fields under the path of the record
|
|
43
|
+
* the section sits in, exactly as if they had been declared beside it, and a read, a filter path, a
|
|
44
|
+
* reference path or a count never learns that a form groups them. {@link fieldsOfMembers} is the same
|
|
45
|
+
* flattening for a consumer that wants the fields and not their facets.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The `_type` of an entry link: a rich-text mark linking text to another entry (REL-1808,
|
|
50
|
+
* `./rich-text`'s `RichTextEntryLinkMark`). Declared here, beside the walk that finds it.
|
|
51
|
+
*/
|
|
52
|
+
declare const RICH_TEXT_ENTRY_LINK_TYPE = "entryLink";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Rich text's stored and served value: a tree we define (ADR 0013, REL-1803).
|
|
56
|
+
*
|
|
57
|
+
* A `richText` field holds one {@link RichTextValue} per locale — a documented, **versioned** JSON
|
|
58
|
+
* tree shaped like the editor's document: a quote and a list item hold blocks, lists nest, a text
|
|
59
|
+
* run names its marks. Every node carries `_type`; every node but a text run carries `_key`, unique
|
|
60
|
+
* within the field. It is not Portable Text (flat: a quote of two paragraphs becomes two quotes,
|
|
61
|
+
* nested lists become levels) and not TipTap's JSON (TipTap's node names and attributes would be
|
|
62
|
+
* our public API, and a TipTap upgrade a breaking change for customers). The vocabulary is written
|
|
63
|
+
* down for readers in `devtools/docs/guide/schema/field-types/rich-text-format.md`; this module is
|
|
64
|
+
* its one definition in code.
|
|
65
|
+
*
|
|
66
|
+
* **The version grows by addition.** {@link RICH_TEXT_VERSION} changes only when a node, a mark or
|
|
67
|
+
* an attribute is renamed, removed or reshaped. A new node type, a new mark, a new `list` style or a
|
|
68
|
+
* new optional attribute is not a version change — the docs set's built-ins (REL-1805: tables, task
|
|
69
|
+
* lists, code groups with tabs, highlight, sub- and superscript) arrived inside version 1, and P3b's
|
|
70
|
+
* entry links and declared blocks will, so a reader must treat a `_type` it does not know as content
|
|
71
|
+
* it cannot draw rather than as an error.
|
|
72
|
+
*
|
|
73
|
+
* **A field narrows the docs set** (REL-1805): its config's `structure`, `marks` and `multiline` are
|
|
74
|
+
* read by {@link richTextNarrowingOf}, held to on every write by {@link richTextNarrowingProblems}
|
|
75
|
+
* (the validation document's `x-richTextNarrowing` keyword), enforced in the editor by
|
|
76
|
+
* `@relyio/studio-core`'s `RichTextPolicy`, and applied by schema adaptation through
|
|
77
|
+
* {@link narrowRichText} when a field is narrowed over content it no longer allows.
|
|
78
|
+
*
|
|
79
|
+
* Who uses it: the projection writes and reads a live document by it (`@relyio/entry-projection`'s
|
|
80
|
+
* `./blocks`), the validation document holds a written value to it ({@link richTextProblems}), the
|
|
81
|
+
* write core keys a written value ({@link keyRichText}), the index embeds its text
|
|
82
|
+
* ({@link richTextPlainText}), and `@relyio/sdk` types a read by it (the types only, build-inlined
|
|
83
|
+
* through the package root).
|
|
84
|
+
*
|
|
85
|
+
* **Declared Blocks and Inline elements** (REL-1807): a field's `blocks` and `inline` name
|
|
86
|
+
* fieldsets an editor inserts between paragraphs and inside a sentence. Each stands in the tree as
|
|
87
|
+
* the fieldset's value — `{ _type: <fieldset id>, _key, …fields }`, exactly a page builder's item —
|
|
88
|
+
* wherever blocks, or inline content, go. A rich-text field of it is a tree of its own (a callout's
|
|
89
|
+
* title and body), whose keys are the field's. The tree's walk ({@link richTextProblems}) takes such
|
|
90
|
+
* a node by its `_type` and reads no schema; the field's narrowing says which it declares, and the
|
|
91
|
+
* shape's own validation fragment holds its fields.
|
|
92
|
+
*
|
|
93
|
+
* Dependency-free like `./declaration` (`__tests__/dependency-free.test.ts`): its runtime imports
|
|
94
|
+
* are `./walk`'s and `./declared-text`'s, inside the subpath.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/** The format's version. The stored value carries it, so a reader knows which vocabulary it holds. */
|
|
98
|
+
declare const RICH_TEXT_VERSION = 1;
|
|
99
|
+
/** The root's `_type`: what a value of a `richText` field is. */
|
|
100
|
+
declare const RICH_TEXT_TYPE = "richText";
|
|
101
|
+
/**
|
|
102
|
+
* A rich-text field's value: the root of the tree. The root is the field, so it has no `_key`.
|
|
103
|
+
*
|
|
104
|
+
* `B` and `I` are the field's declared Blocks and Inline elements (REL-1807): the values of the
|
|
105
|
+
* fieldsets its `blocks` and `inline` name, each `{ _type, _key, …fields }` exactly as a page
|
|
106
|
+
* builder's item is. Both are `never` for a field that declares none, which is every built-in's
|
|
107
|
+
* reading; the SDK infers them from a field's config, so a read of a field declaring a callout is a
|
|
108
|
+
* tree that may hold one where blocks go.
|
|
109
|
+
*/
|
|
110
|
+
interface RichTextValue<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> {
|
|
111
|
+
readonly _type: typeof RICH_TEXT_TYPE;
|
|
112
|
+
readonly version: typeof RICH_TEXT_VERSION;
|
|
113
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A link to another entry (REL-1808): a **reference** — `to`, the target entry's id — and an optional
|
|
117
|
+
* `anchor`, a heading on it ({@link richTextHeadingAnchors}). A mark, as a link to a URL is, so it
|
|
118
|
+
* wraps any run of text and the formatting inside it. It may point only at the types its field's
|
|
119
|
+
* `links` names, and it is found, checked on publish, blocks or is nullified on its target's delete,
|
|
120
|
+
* purges and expands as every reference does: its walk path is `<field>.~entryLink.to`
|
|
121
|
+
* (`./walk`'s `richTextTreeSegmentOf`).
|
|
122
|
+
*
|
|
123
|
+
* `To` is what `to` holds: the id, as it is stored and written — and the target entry itself in a read
|
|
124
|
+
* whose include paths expand the field, as a reference field's id becomes the entry.
|
|
125
|
+
*/
|
|
126
|
+
interface RichTextEntryLinkMark<To = string> {
|
|
127
|
+
readonly _type: typeof RICH_TEXT_ENTRY_LINK_TYPE;
|
|
128
|
+
readonly to: To;
|
|
129
|
+
readonly anchor?: string;
|
|
130
|
+
}
|
|
131
|
+
/** An entry link, whatever its `to` holds: the third parameter of {@link RichTextValue}. */
|
|
132
|
+
type AnyRichTextEntryLink = RichTextEntryLinkMark<unknown>;
|
|
133
|
+
/** What every node but a text run carries: its identity within the field (design decision 10). */
|
|
134
|
+
interface RichTextKeyed {
|
|
135
|
+
readonly _key: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* What every declared Block and Inline element carries (REL-1807): the fieldset's id in `_type` and
|
|
139
|
+
* its Item key in `_key`, beside the fieldset's fields — the value a page builder's item of the same
|
|
140
|
+
* fieldset is. Its `_type` is never a built-in's name (deploy refuses such a fieldset in rich text,
|
|
141
|
+
* {@link RICH_TEXT_RESERVED_SHAPE_IDS}).
|
|
142
|
+
*/
|
|
143
|
+
interface RichTextShapeValue extends RichTextKeyed {
|
|
144
|
+
readonly _type: string;
|
|
145
|
+
}
|
|
146
|
+
/** A paragraph: inline content. */
|
|
147
|
+
interface RichTextParagraph<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
148
|
+
readonly _type: 'paragraph';
|
|
149
|
+
readonly children: ReadonlyArray<RichTextInline<I, L>>;
|
|
150
|
+
}
|
|
151
|
+
/** The heading levels, as numbers. */
|
|
152
|
+
declare const RICH_TEXT_HEADING_LEVELS: readonly [1, 2, 3, 4, 5, 6];
|
|
153
|
+
/**
|
|
154
|
+
* A heading of `level` 1 to 6: inline content. Its anchor — what an entry link's `anchor` names and
|
|
155
|
+
* the `id` a renderer gives it — is derived from its text ({@link richTextHeadingAnchors}).
|
|
156
|
+
*/
|
|
157
|
+
interface RichTextHeading<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
158
|
+
readonly _type: 'heading';
|
|
159
|
+
readonly level: (typeof RICH_TEXT_HEADING_LEVELS)[number];
|
|
160
|
+
readonly children: ReadonlyArray<RichTextInline<I, L>>;
|
|
161
|
+
}
|
|
162
|
+
/** A quote: one block or more — a quote of two paragraphs is one quote. */
|
|
163
|
+
interface RichTextQuote<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
164
|
+
readonly _type: 'quote';
|
|
165
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The list styles. Version 1 held `bullet` and `numbered`; REL-1805 added `task`, whose items each
|
|
169
|
+
* carry `checked`, without a version change.
|
|
170
|
+
*/
|
|
171
|
+
declare const RICH_TEXT_LIST_STYLES: readonly ['bullet', 'numbered', 'task'];
|
|
172
|
+
type RichTextListStyle = (typeof RICH_TEXT_LIST_STYLES)[number];
|
|
173
|
+
/**
|
|
174
|
+
* A list: one item or more. `start` is a numbered list's first number, present only when it is not
|
|
175
|
+
* `1`. Lists nest: an item holds blocks, and a list is a block.
|
|
176
|
+
*/
|
|
177
|
+
interface RichTextList<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
178
|
+
readonly _type: 'list';
|
|
179
|
+
readonly style: RichTextListStyle;
|
|
180
|
+
readonly start?: number;
|
|
181
|
+
readonly children: ReadonlyArray<RichTextListItem<B, I, L>>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A list's item: blocks, the first of them a paragraph (the editor's model, `paragraph block*`).
|
|
185
|
+
* `checked` is a task list's item's, and present on every one of them: whether its task is done.
|
|
186
|
+
* An item of a bullet or a numbered list carries none.
|
|
187
|
+
*/
|
|
188
|
+
interface RichTextListItem<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
189
|
+
readonly _type: 'listItem';
|
|
190
|
+
readonly checked?: boolean;
|
|
191
|
+
readonly children: ReadonlyArray<RichTextBlock<B, I, L>>;
|
|
192
|
+
}
|
|
193
|
+
/** The lines of a file a code block is, 1-based and inclusive: the docs' code citations. */
|
|
194
|
+
interface RichTextCodeLines {
|
|
195
|
+
readonly start: number;
|
|
196
|
+
readonly end: number;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A block of code: its text exactly, newlines included, with no marks, and the `language` it is
|
|
200
|
+
* written in when one is named. Standing in a code group it is one of the group's tabs, and `label`
|
|
201
|
+
* is the tab's name; `filename` is the file it shows and `lines` which of that file's lines. All
|
|
202
|
+
* three are optional, alone or in a group (REL-1805).
|
|
203
|
+
*/
|
|
204
|
+
interface RichTextCodeBlock extends RichTextKeyed {
|
|
205
|
+
readonly _type: 'codeBlock';
|
|
206
|
+
readonly language?: string;
|
|
207
|
+
readonly label?: string;
|
|
208
|
+
readonly filename?: string;
|
|
209
|
+
readonly lines?: RichTextCodeLines;
|
|
210
|
+
readonly text: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Code with tabs: one code block or more, each a tab — the same snippet for another language,
|
|
214
|
+
* package manager or client (REL-1805). Each tab's text is its own, so two people typing in two tabs
|
|
215
|
+
* keep both. A `code` field holds this node as its value (REL-1806).
|
|
216
|
+
*/
|
|
217
|
+
interface RichTextCodeGroup extends RichTextKeyed {
|
|
218
|
+
readonly _type: 'codeGroup';
|
|
219
|
+
readonly children: readonly RichTextCodeBlock[];
|
|
220
|
+
}
|
|
221
|
+
/** How a table cell's text is aligned. Absent is the reader's default. */
|
|
222
|
+
declare const RICH_TEXT_CELL_ALIGNMENTS: readonly ['left', 'center', 'right'];
|
|
223
|
+
type RichTextCellAlignment = (typeof RICH_TEXT_CELL_ALIGNMENTS)[number];
|
|
224
|
+
/**
|
|
225
|
+
* A table: one row or more, every row holding the same number of cells (REL-1805). `headerRow` is
|
|
226
|
+
* present, `true`, when the first row is the table's header. Cells hold formatted text, and nothing
|
|
227
|
+
* merges cells. A `table` field holds this node as its value (REL-1806).
|
|
228
|
+
*/
|
|
229
|
+
interface RichTextTable<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
230
|
+
readonly _type: 'table';
|
|
231
|
+
readonly headerRow?: true;
|
|
232
|
+
readonly children: ReadonlyArray<RichTextTableRow<I, L>>;
|
|
233
|
+
}
|
|
234
|
+
/** A table's row: one cell or more. */
|
|
235
|
+
interface RichTextTableRow<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
236
|
+
readonly _type: 'tableRow';
|
|
237
|
+
readonly children: ReadonlyArray<RichTextTableCell<I, L>>;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* A table's cell: one paragraph or more of formatted text, and its alignment when one is set. Its
|
|
241
|
+
* paragraphs hold the field's Inline elements as any paragraph does; never a declared Block.
|
|
242
|
+
*/
|
|
243
|
+
interface RichTextTableCell<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> extends RichTextKeyed {
|
|
244
|
+
readonly _type: 'tableCell';
|
|
245
|
+
readonly align?: RichTextCellAlignment;
|
|
246
|
+
readonly children: ReadonlyArray<RichTextParagraph<I, L>>;
|
|
247
|
+
}
|
|
248
|
+
/** A horizontal rule between blocks. */
|
|
249
|
+
interface RichTextDivider extends RichTextKeyed {
|
|
250
|
+
readonly _type: 'divider';
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* A block: what a field, a quote and a list item hold — a built-in, or one of the field's declared
|
|
254
|
+
* Blocks (`B`, REL-1807), which stand wherever blocks go and nowhere else.
|
|
255
|
+
*/
|
|
256
|
+
type RichTextBlock<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextParagraph<I, L> | RichTextHeading<I, L> | RichTextQuote<B, I, L> | RichTextList<B, I, L> | RichTextCodeBlock | RichTextCodeGroup | RichTextTable<I, L> | RichTextDivider | B;
|
|
257
|
+
/**
|
|
258
|
+
* A run of text: its characters and the marks on all of them. `marks` is absent when there are
|
|
259
|
+
* none, and in {@link RICH_TEXT_MARK_ORDER} when there are, each type at most once. A text run has no
|
|
260
|
+
* `_key`: it is not addressable apart from the block that holds it, and the live document gives it no
|
|
261
|
+
* identity to keep. `L` is the field's entry link (REL-1808), `never` for a field that declares no
|
|
262
|
+
* `links`.
|
|
263
|
+
*/
|
|
264
|
+
interface RichTextSpan<L extends AnyRichTextEntryLink = never> {
|
|
265
|
+
readonly _type: 'text';
|
|
266
|
+
readonly text: string;
|
|
267
|
+
readonly marks?: ReadonlyArray<RichTextMark | L>;
|
|
268
|
+
}
|
|
269
|
+
/** A line break inside a paragraph or a heading. */
|
|
270
|
+
interface RichTextLineBreak extends RichTextKeyed {
|
|
271
|
+
readonly _type: 'lineBreak';
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Inline content: what a paragraph and a heading hold — runs, line breaks, and the field's declared
|
|
275
|
+
* Inline elements (`I`, REL-1807) beside its text.
|
|
276
|
+
*/
|
|
277
|
+
type RichTextInline<I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextSpan<L> | RichTextLineBreak | I;
|
|
278
|
+
/**
|
|
279
|
+
* The marks a field's `marks` option names, in the order a run holds them: the link first, so a
|
|
280
|
+
* renderer that nests marks in this order wraps the formatting in the anchor. REL-1805 added
|
|
281
|
+
* highlight, subscript and superscript after the first six. The entry link (REL-1808) is not among
|
|
282
|
+
* them: a field allows it by naming the types it links to in `links`, not in `marks` (design
|
|
283
|
+
* decision 31), and it stands second in a run's order ({@link RICH_TEXT_MARK_ORDER}).
|
|
284
|
+
*/
|
|
285
|
+
declare const RICH_TEXT_MARK_TYPES: readonly ['link', 'bold', 'italic', 'underline', 'strike', 'code', 'highlight', 'subscript', 'superscript'];
|
|
286
|
+
type RichTextMarkType = (typeof RICH_TEXT_MARK_TYPES)[number];
|
|
287
|
+
/**
|
|
288
|
+
* A link to a URL. `href` is all a reader is given: whether it opens a new tab and which `rel` it
|
|
289
|
+
* carries are the site's rendering decisions, not content (the editor's defaults for them are not
|
|
290
|
+
* stored), and a link's title was dropped before the tree existed (REL-1942).
|
|
291
|
+
*/
|
|
292
|
+
interface RichTextLinkMark {
|
|
293
|
+
readonly _type: 'link';
|
|
294
|
+
readonly href: string;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* A mark: formatting by name, or a link. `code` holds no other mark beside it, and `subscript` and
|
|
298
|
+
* `superscript` are never on one run together.
|
|
299
|
+
*/
|
|
300
|
+
type RichTextMark = RichTextLinkMark | {
|
|
301
|
+
readonly _type: Exclude<RichTextMarkType, 'link'>;
|
|
302
|
+
};
|
|
303
|
+
/** Any node of the tree below the root. */
|
|
304
|
+
type RichTextNode<B extends RichTextShapeValue = never, I extends RichTextShapeValue = never, L extends AnyRichTextEntryLink = never> = RichTextBlock<B, I, L> | RichTextListItem<B, I, L> | RichTextTableRow<I, L> | RichTextTableCell<I, L> | RichTextInline<I, L>;
|
|
305
|
+
/**
|
|
306
|
+
* The built-ins a field kind holds as its whole value (REL-1806): a `table` field holds a
|
|
307
|
+
* {@link RichTextTable}, a `code` field a {@link RichTextCodeGroup} — the very node a rich-text value
|
|
308
|
+
* holds among its blocks, so a value copied from one to the other is accepted unchanged. Each is read
|
|
309
|
+
* by {@link richTextFieldBlockProblems}, keyed by {@link keyRichTextFieldBlock} and searched by
|
|
310
|
+
* {@link richTextFieldBlockPlainText}.
|
|
311
|
+
*/
|
|
312
|
+
declare const RICH_TEXT_FIELD_BLOCK_TYPES: readonly ['table', 'codeGroup'];
|
|
313
|
+
type RichTextFieldBlockType = (typeof RICH_TEXT_FIELD_BLOCK_TYPES)[number];
|
|
314
|
+
/** A built-in a field holds as its whole value, by its `_type`. */
|
|
315
|
+
type RichTextFieldBlock<T extends RichTextFieldBlockType = RichTextFieldBlockType> = Extract<RichTextBlock, {
|
|
316
|
+
readonly _type: T;
|
|
317
|
+
}>;
|
|
318
|
+
/**
|
|
319
|
+
* The built-in blocks a field's `structure` names (REL-1805): every block but the paragraph, which
|
|
320
|
+
* every field holds. A list is named by its style, since a field may want bullets and no tasks; a
|
|
321
|
+
* code group's tabs come with the group, whether or not `codeBlock` is named.
|
|
322
|
+
*/
|
|
323
|
+
declare const RICH_TEXT_STRUCTURES: readonly ['heading', 'quote', 'bulletList', 'numberedList', 'taskList', 'codeBlock', 'codeGroup', 'table', 'divider'];
|
|
324
|
+
type RichTextStructure = (typeof RICH_TEXT_STRUCTURES)[number];
|
|
325
|
+
|
|
326
|
+
export type { AnyRichTextEntryLink as A, RichTextTableRow as B, RichTextFieldBlockType as R, RichTextFieldBlock as a, RichTextValue as b, RichTextShapeValue as c, RichTextEntryLinkMark as d, RichTextBlock as e, RichTextCellAlignment as f, RichTextCodeBlock as g, RichTextCodeGroup as h, RichTextCodeLines as i, RichTextDivider as j, RichTextHeading as k, RichTextInline as l, RichTextLineBreak as m, RichTextLinkMark as n, RichTextList as o, RichTextListItem as p, RichTextListStyle as q, RichTextMark as r, RichTextMarkType as s, RichTextNode as t, RichTextParagraph as u, RichTextQuote as v, RichTextSpan as w, RichTextStructure as x, RichTextTable as y, RichTextTableCell as z };
|