document-schema 3.3.0 → 4.1.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/README.md +141 -30
- package/dist/codec.d.cts +2 -7
- package/dist/codec.d.ts +2 -7
- package/dist/construct-CdQuI9f5.d.cts +204 -0
- package/dist/construct-CdQuI9f5.d.ts +204 -0
- package/dist/construct.cjs +106 -0
- package/dist/construct.d.cts +2 -0
- package/dist/construct.d.ts +2 -0
- package/dist/construct.js +93 -0
- package/dist/content-BN0PWqpt.d.cts +2393 -0
- package/dist/content-CiZf6Fqn.d.ts +2393 -0
- package/dist/content-json-schema-defs.cjs +1227 -0
- package/dist/content-json-schema-defs.js +1227 -0
- package/dist/content.cjs +1 -7
- package/dist/content.d.cts +2 -2354
- package/dist/content.d.ts +2 -2354
- package/dist/content.js +1 -7
- package/dist/definitions.cjs +109 -0
- package/dist/definitions.d.cts +115 -0
- package/dist/definitions.d.ts +115 -0
- package/dist/definitions.js +99 -0
- package/dist/index.cjs +60 -18
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +7 -5
- package/dist/package-node-BiUEzIzl.d.cts +456 -0
- package/dist/package-node-DLUobcDQ.d.ts +456 -0
- package/dist/package-node.cjs +133 -0
- package/dist/package-node.d.cts +2 -0
- package/dist/package-node.d.ts +2 -0
- package/dist/package-node.js +102 -0
- package/dist/package.cjs +40 -7
- package/dist/package.d.cts +497 -755
- package/dist/package.d.ts +497 -755
- package/dist/package.js +42 -8
- package/dist/schema-io.cjs +55 -25
- package/dist/schema-io.d.cts +13 -11
- package/dist/schema-io.d.ts +13 -11
- package/dist/schema-io.js +54 -25
- package/package.json +2 -2
- package/schemas/content-document.schema.json +1813 -68
- package/schemas/document-package.schema.json +3528 -30
- package/dist/layout.cjs +0 -150
- package/dist/layout.d.cts +0 -684
- package/dist/layout.d.ts +0 -684
- package/dist/layout.js +0 -136
- package/schemas/layout-document.schema.json +0 -760
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ExaDev/document-schema.js) [](https://www.npmjs.com/package/document-schema.js) [](https://github.com/ExaDev/document-schema.js/releases/latest) [](https://github.com/ExaDev/document-schema.js/actions)
|
|
4
4
|
|
|
5
|
-
> The canonical, format-agnostic content and
|
|
5
|
+
> The canonical, format-agnostic content and document-package schema pivot shared by [ooxml.js](https://github.com/ExaDev/ooxml.js), [odf.js](https://github.com/ExaDev/odf.js), [documents.js](https://github.com/ExaDev/documents.js), [pdf-codec](https://github.com/ExaDev/pdf-codec), and [markdown-codec](https://github.com/ExaDev/markdown-codec).
|
|
6
6
|
|
|
7
7
|
Both `ooxml.js` and `documents.js` independently arrived at the same content vocabulary, producing two field-identical copies in two places. This package is the fix: one schema, imported by every format package instead of redefined by each. It also sidesteps a circular dependency (`documents.js` depends on both `ooxml.js` and `odf.js`).
|
|
8
8
|
|
|
@@ -48,30 +48,130 @@ graph TD
|
|
|
48
48
|
style schema fill:#f9a825,stroke:#333,stroke-width:3px
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
`ContentDocument` (the semantic pivot) is a discriminated union of five kinds: `wordprocessing` (docx/odt sections of paragraphs/runs/tables/images), `presentation` (pptx/odp slides of shapes), `spreadsheet` (xlsx/ods sheets of cells, columns, rows, print settings), `drawing` (odg pages of shapes plus vector primitives — rect/ellipse/line/path), and `formula` (an equation carrying its own MathML node tree plus StarMath source when the producing format had one, extended with the two-layer math model: an optional verbatim-LaTeX `presentation` authoritative for rendering, an optional semantic `content: MathExpression` tree authoritative for computation, and provenance — neither layer stored derived from the other, so editing one never silently mutates the other). `ContentEmbeddedObjectSchema` lets any of the five embed another whole `ContentDocument`. Every paragraph/run/image/table/shape/vector/spreadsheet-cell leaf also carries its own canonical `headingLevel`-or-position fields directly: a `ContentParagraph`'s optional `headingLevel` (1 = the outermost heading, independent of the round-trip-only `styleId`), and every such leaf's optional `frames: LayoutFrame[]` — that node's own rendered page position(s) (`pageIndex` plus PDF user-space `xPt`/`yPt`/`widthPt`/`heightPt`), fused directly onto the content tree once a layout pass has run. `
|
|
51
|
+
`ContentDocument` (the semantic pivot) is a discriminated union of five kinds: `wordprocessing` (docx/odt sections of paragraphs/runs/tables/images), `presentation` (pptx/odp slides of shapes), `spreadsheet` (xlsx/ods sheets of cells, columns, rows, print settings), `drawing` (odg pages of shapes plus vector primitives — rect/ellipse/line/path), and `formula` (an equation carrying its own MathML node tree plus StarMath source when the producing format had one, extended with the two-layer math model: an optional verbatim-LaTeX `presentation` authoritative for rendering, an optional semantic `content: MathExpression` tree authoritative for computation, and provenance — neither layer stored derived from the other, so editing one never silently mutates the other). `ContentEmbeddedObjectSchema` lets any of the five embed another whole `ContentDocument`. Every paragraph/run/image/table/shape/vector/spreadsheet-cell leaf also carries its own canonical `headingLevel`-or-position fields directly: a `ContentParagraph`'s optional `headingLevel` (1 = the outermost heading, independent of the round-trip-only `styleId`), and every such leaf's optional `frames: LayoutFrame[]` — that node's own rendered page position(s) (`pageIndex` plus PDF user-space `xPt`/`yPt`/`widthPt`/`heightPt`), fused directly onto the content tree once a layout pass has run. `DocumentPackage` is the single hierarchical artefact — structure, layout, and content fused in one tree (see [The package tree](#the-package-tree)): the root carries `kind`, `metadata`, the optional document-level `symbolTable` and rendered `pages`, the optional package-level `styles`/`definitions`/`layers`/`attachments`/`destinations` tables (see [Definitions tables and styles](#definitions-tables-and-styles)), and `children` — one group per top-level container with the content tree grouped inside it, where a group's node may also be one of the six fidelity construct descriptors (see [Fidelity constructs](#fidelity-constructs)); the schema does not keep populated `frames` fields and `pages` in sync or detect staleness, and does not check that a tree's `style` refs name table entries (both are producer responsibilities, exactly as the frames/pages pairing always was). Every one of the five kinds also accepts an optional document-level `symbolTable` — the math curation layer mapping each written symbol glyph (within a scope) to its id, quantity kind, preferred unit, and definition source, alongside the unit registry (SI dimension-exponent vectors, exact rational conversions, per-unit-system normalisation contexts) that the `qty` nodes of lowered formulas resolve against.
|
|
52
52
|
|
|
53
|
-
The
|
|
53
|
+
The `LayoutDocument` family (pages of positioned `LayoutItem`s — `text`/`image`/`rect`/`line`/`ellipse`/`path`/`link` in PDF user-space coordinates) no longer lives here: 4.0.0 demoted it to a pdf-codec-private model ([pdf-codec#65](https://github.com/ExaDev/pdf-codec/issues/65)), where the only codec that ever read or wrote it owns it outright. `documentFromJson` recognises old layout-document `$schema` URIs and throws a tombstone pointing at pdf-codec rather than failing as if the value were unrelated. Dependents stay on document-schema.js 3.x via semver until their own majors, so the demotion is not a cascade-breaker.
|
|
54
|
+
|
|
55
|
+
The package contains only [Zod](https://zod.dev) schemas, their inferred types, trivial schema-attached helpers (hex-colour conversion, recursive structural type guards, the style-resolution helpers of `src/definitions.ts`), and one small structural interface (`ContentCodec`, see [Codecs](#codecs)). No XML, ZIP, PDF, or binary handling; the sole dependency is `zod`.
|
|
54
56
|
|
|
55
57
|
Two format-agnostic helpers live here because they operate on the content model itself: cell-addressing utilities in `src/a1.ts` (0-based row/column indices, row-first order matching `ContentSheetCell`'s `{row, column}`) and the `FontFace` interface in `src/font-port.ts` (`{family, bold, italic}`).
|
|
56
58
|
|
|
57
59
|
## Usage
|
|
58
60
|
|
|
59
61
|
```ts
|
|
60
|
-
import { ContentDocumentSchema, DocumentPackageSchema
|
|
62
|
+
import { ContentDocumentSchema, DocumentPackageSchema } from 'document-schema.js';
|
|
61
63
|
|
|
64
|
+
// The codec-exchange form: what every format's reader produces and every writer consumes -- always flat,
|
|
65
|
+
// always fully materialised (no styles table, no refs), never versioned (that lives on the serialised artefact).
|
|
62
66
|
const content = ContentDocumentSchema.parse(someWordprocessingOrPresentationValue);
|
|
63
|
-
// A content-only package -- no layout pass has run yet, so no node carries `frames` and `pages` stays absent.
|
|
64
|
-
const pkg = DocumentPackageSchema.parse({ formatVersion: 2, content });
|
|
65
67
|
|
|
66
|
-
//
|
|
68
|
+
// The package tree: what a serialised dump carries. `children` holds one group per top-level container,
|
|
69
|
+
// with the content grouped inside it (see "The package tree" below).
|
|
70
|
+
const pkg = DocumentPackageSchema.parse({
|
|
71
|
+
kind: 'wordprocessing',
|
|
72
|
+
metadata: { title: 'Example' },
|
|
73
|
+
children: [
|
|
74
|
+
{
|
|
75
|
+
node: { kind: 'section', pageSize: { widthPt: 612, heightPt: 792 }, margins: { topPt: 72, rightPt: 72, bottomPt: 72, leftPt: 72 } },
|
|
76
|
+
children: [
|
|
77
|
+
{ node: { kind: 'paragraph', headingLevel: 1, runs: [{ text: 'Heading' }] }, children: [] },
|
|
78
|
+
{ kind: 'paragraph', runs: [{ text: 'Body.' }] },
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Once a layout pass has fused rendered positions onto the tree's own nodes (each via its own `frames` array)
|
|
67
85
|
// and reported each page's own size, `pages` is populated to match:
|
|
68
|
-
const laidOut = DocumentPackageSchema.parse({
|
|
86
|
+
const laidOut = DocumentPackageSchema.parse({ ...pkg, pages: [{ widthPt: 612, heightPt: 792 }] });
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## The package tree
|
|
90
|
+
|
|
91
|
+
`DocumentPackage` ([#20](https://github.com/ExaDev/document-schema.js/issues/20)) is the promoted single hierarchical artefact — one tree where 3.x carried `{ formatVersion, content, pages }` with the content flat. The tree's vocabulary is defined in `src/package-node.ts` and was proven first as [document-outline.js](https://github.com/ExaDev/document-outline.js)'s phase-1 `decompose`/`flatten` implementation ([document-outline.js#2](https://github.com/ExaDev/document-outline.js/issues/2)); this package's schemas are that shape's schema-home port, matching it node for node:
|
|
92
|
+
|
|
93
|
+
- **Groups** are `{ node, children }` where `node` embeds either an anchor paragraph (heading groups and list-item groups carry the full `ContentParagraph` — runs, formatting, frames — never a projected text label) or a container descriptor: `{ kind: 'section', pageSize, margins }`, `{ kind: 'slide', size, notes }`, `{ kind: 'sheet', name, cells, columns, rows, printSettings }`, `{ kind: 'drawPage', size }`, each tagged with a `kind` the flat container type does not carry, or a shape group's untagged frame descriptor, or — since 4.1.0 — a **construct descriptor** (see [Fidelity constructs](#fidelity-constructs)).
|
|
94
|
+
- **Bare leaves** carry their own `kind` and never `children`. Discrimination is structural on `node`+`children`, not on the presence of a `kind`.
|
|
95
|
+
- **Section groups are mandatory** — one per `ContentSection` — because a section carries pre-layout page geometry (`pageSize`/`margins`) that a rendered `pages` array cannot hold.
|
|
96
|
+
- **Grouping never crosses container boundaries**: a shape is its own group with its inner blocks grouped inside it (never a slide's paragraphs flattened across its shapes — that is a TOC projection, not a decomposition); a sheet's grid rides on the sheet node with images and embedded documents as children; embedded documents stay intact as one leaf.
|
|
97
|
+
- **Style refs ride on group wrappers only** — a group may carry `style: string` naming a `styles` table entry; `ContentDocument` nodes carry no ref field, so the flat codec-exchange form is always fully materialised.
|
|
98
|
+
|
|
99
|
+
The flat `ContentDocument` and the tree are **one format, two encodings**, related by three laws — the contract with document-outline.js (which property-tests them over real corpus documents) and, at the package boundary, with documents.js ([documents.js#623](https://github.com/ExaDev/documents.js/issues/623)):
|
|
69
100
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
101
|
+
1. **Strict structural equality, both directions, for table-free packages** — `decompose(flatten(pkg))` and `flatten(decompose(pkg))` reproduce their input exactly.
|
|
102
|
+
2. **Effective-property equality, universally** — resolve styles first, then compare: a factored and an unfactored serialisation of one document are equal (this is also why content hashing and structural diffing resolve first).
|
|
103
|
+
3. **Minting idempotence** — factoring a package a second time mints the identical styles table: `decompose(flatten(decompose(x))) === decompose(x)`.
|
|
104
|
+
|
|
105
|
+
The codecs do not change: they keep producing flat `ContentDocument`s (their natural reading shape); decomposition runs once at the package boundary in documents.js and flatten runs once where a builder consumes a package.
|
|
106
|
+
|
|
107
|
+
## Fidelity constructs
|
|
108
|
+
|
|
109
|
+
Every format carries constructs the flat content model drops — docx SDTs and field codes, ODF fields and tracked changes, PDF form widgets and link annotations, markdown footnotes and link titles. [#22](https://github.com/ExaDev/document-schema.js/issues/22) replaces those per-repo caveats with one **harmonised semantic vocabulary**: no format-specific node kinds, ever. Four codec inventories ([ooxml.js#65](https://github.com/ExaDev/ooxml.js/issues/65), [odf.js#59](https://github.com/ExaDev/odf.js/issues/59), [markdown-codec#63](https://github.com/ExaDev/markdown-codec/issues/63), [pdf-codec#66](https://github.com/ExaDev/pdf-codec/issues/66)) audited what each format actually carries, and 4.1.0 lands their answer additively ([#24](https://github.com/ExaDev/document-schema.js/issues/24)) — new descriptor kinds and package tables, no change to any existing node shape, so a 4.0.0 tree parses unchanged.
|
|
110
|
+
|
|
111
|
+
A construct is a group like any other: `{ node: <descriptor>, children }`, where the children are the extent the construct spans. The tree was designed construct-capable from day one for exactly this, which is why the kinds could land in a minor rather than a second structural break.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// A tracked insertion inside a docx content control, and a footnote marker whose body lives in the definitions table.
|
|
115
|
+
const pkg = DocumentPackageSchema.parse({
|
|
116
|
+
kind: 'wordprocessing',
|
|
117
|
+
metadata: {},
|
|
118
|
+
definitions: { n1: { kind: 'footnote', blocks: [{ kind: 'paragraph', runs: [{ text: 'The note body.' }] }] } },
|
|
119
|
+
children: [
|
|
120
|
+
{
|
|
121
|
+
node: { kind: 'section', pageSize: { widthPt: 612, heightPt: 792 }, margins: { topPt: 72, rightPt: 72, bottomPt: 72, leftPt: 72 } },
|
|
122
|
+
children: [
|
|
123
|
+
{
|
|
124
|
+
node: { kind: 'contentControl', controlType: 'richText', tag: 'ClientBlock', lock: 'container' },
|
|
125
|
+
children: [
|
|
126
|
+
{
|
|
127
|
+
node: { kind: 'provenance', change: 'insertion', author: 'A. Reviewer', dateIso: '2026-08-18T09:00:00Z' },
|
|
128
|
+
children: [{ kind: 'paragraph', runs: [{ text: 'Inserted sentence.' }] }],
|
|
129
|
+
},
|
|
130
|
+
{ node: { kind: 'anchor', anchorType: 'footnote', name: '1', definition: 'n1' }, children: [] },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
});
|
|
73
137
|
```
|
|
74
138
|
|
|
139
|
+
The six kinds (`src/construct.ts`):
|
|
140
|
+
|
|
141
|
+
| Kind | Carries | Where it comes from |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `contentControl` | `controlType`, `tag`, `alias`, `lock`, `value`, `checked`, `options` | docx block and inline SDTs, docx legacy `w:ffData` form fields, ODF `office:forms` controls and TOC/index wrappers, PDF AcroForm widgets and their field tree |
|
|
144
|
+
| `field` | `instruction`, `cachedResult` | docx `w:fldChar`/`w:instrText` and `w:fldSimple`, ODF field masters and simple fields, ODF cross-reference displays, pptx `a:fld` |
|
|
145
|
+
| `anchor` | `anchorType`, `name`, `definition` | docx bookmarks, comment extents, footnote/endnote references; ODF `text:bookmark`, `text:reference-mark*`, `text:note`, `office:annotation`; PDF sticky notes and markup annotations; markdown footnote markers |
|
|
146
|
+
| `link` | `target` (external URI or internal anchor name), `title` | docx `@w:anchor`, pptx slide jumps, PDF `GoTo`/`/Dest` and link annotations, markdown link/image titles |
|
|
147
|
+
| `provenance` | `change`, `author`, `dateIso` | docx `w:ins`/`w:del` and move tracking, ODF `text:tracked-changes`/`text:changed-region` |
|
|
148
|
+
| `division` | `name`, `columnCount`, `protected`, `source` | ODF `text:section` and `text:section-source`, tagged PDF `/Sect` and `/Div` |
|
|
149
|
+
|
|
150
|
+
Four things bound the vocabulary, and each is a decision rather than an omission:
|
|
151
|
+
|
|
152
|
+
- **Extents are block-scoped.** A construct group wraps the block flow of a section, heading group, shape, or list item. It cannot wrap a sub-sequence of one paragraph's runs, because a run-level extent is not expressible without changing `ContentParagraph`, and 4.1.0 changes no content shape. Run-level constructs keep their existing homes: **an external hyperlink stays on `ContentRun.hyperlink`** — `link` groups are for block-scoped and annotated extents a flat run field cannot express, never a replacement for it — and the inline field, bookmark, and tracked-change cases wait on a run-level mechanism rather than being forced into a wrapper that would split their paragraph.
|
|
153
|
+
- **Two group variants, one per block flow.** `SectionConstructGroup` sits in a section's or heading group's flow and admits heading children; `ShapeConstructGroup` sits in a shape's or list item's and does not — exactly the `SectionChild`/`ShapeChild` split that already existed. A construct nests in and around every other group, so a `provenance` wrapper inside a `contentControl` inside a `division` is a legal (and real) docx shape. Constructs are **not** legal as direct children of a slide, sheet, drawing page, or the package root: those hold containers and leaves, not block flow.
|
|
154
|
+
- **`division` is first-class, not degraded.** [#24](https://github.com/ExaDev/document-schema.js/issues/24) posed ODF `text:section` as a choice between a new generic kind and degrading to `contentControl` with the specifics in residue. It is first-class, on the odf inventory's own recommendation: `ContentSection` cannot host it (that is page geometry, one `pageSize`/`margins` pair, and it does not nest, while a division nests arbitrarily and usually changes no page geometry at all), and burying a structural container in the form-control vocabulary would make `contentControl` mean two unrelated things. It clears #22's no-format-specific-kinds bar on a real analogue — tagged PDF's `/Sect` and `/Div` are the same construct — not on ODF's say-so. It is spelled `division` rather than `section` because `{ kind: 'section' }` is already the page-geometry container descriptor.
|
|
155
|
+
- **Residue is not here.** #22's channel 2 — a per-node and package-level `source: { format, xml }` facility for what has no cross-format meaning — spans the whole content model and remains open on #22. Descriptors are closed objects with no escape hatch, deliberately: a descriptor-only residue field would mint exactly the parallel shape the general facility exists to avoid.
|
|
156
|
+
|
|
157
|
+
Two harmonisations the inventories asked for are also deliberately absent. There is **no `fieldType` enum**: `instruction` is required and verbatim, so nothing is lost without one, and #24 asks for exactly one new vocabulary — `link`'s internal targets — rather than one per kind, with the four inventories' own corpus gate still standing before a field-type member set could be frozen honestly. And a **sheet-scoped named range** (xlsx defined names and tables, ODF `table:named-expressions`) is a definitions-table entry, not an `anchor`: a sheet group's children are its images and embedded documents, never a block flow, so there is no extent for an anchor to wrap — which is the odf inventory's own verdict for the identical construct.
|
|
158
|
+
|
|
159
|
+
## Definitions tables and styles
|
|
160
|
+
|
|
161
|
+
The package root carries a generic definitions-table facility ([#21](https://github.com/ExaDev/document-schema.js/issues/21)): named tables whose entries tree nodes reference by string id. **Styles were the first tenant**; link, footnote, and comment definitions ride the tenant-generic `definitions` table (entries tagged with a `kind` discriminator and an open body, `src/definitions.ts`) alongside it — which is why that generic table exists rather than the facility being shaped around styles.
|
|
162
|
+
|
|
163
|
+
4.1.0 adds three more tables of that same generic type at the root ([#24](https://github.com/ExaDev/document-schema.js/issues/24), proposed by [pdf-codec#66](https://github.com/ExaDev/pdf-codec/issues/66)) — no new entry shape is minted anywhere:
|
|
164
|
+
|
|
165
|
+
- `layers` — optional-content/layer definitions: PDF `/OCProperties` groups and their configuration, ODF Draw's layer model. Definitions only; which content belongs to which layer is a membership fact the producing codec carries on its own item model.
|
|
166
|
+
- `attachments` — package attachments: PDF `/Names /EmbeddedFiles`, `/FileAttachment`, `/EF`, `/AF`, and the docx/ODF package attachments that make the facility cross-format rather than PDF-specific.
|
|
167
|
+
- `destinations` — named destinations and the navigation tree that resolves against them: PDF `/Dests`, the `/Names` name tree, and `/Outlines`. This is the other end of a `link` construct's internal target.
|
|
168
|
+
|
|
169
|
+
Each is its own root field rather than three more tenants of `definitions`, for the reason `styles` is its own field despite being the facility's first tenant: separate key namespaces, so a layer and a destination may share a name without colliding. The `kind` discriminator still earns its keep inside each, because each holds more than one tenant — a layers table carries group definitions alongside their configuration, and a destinations table carries named destinations alongside outline entries. Per-tenant entry fields stay the tenant's own, never this package's.
|
|
170
|
+
|
|
171
|
+
A styles entry carries `{ paragraph?, run? }` sub-objects of **resolved canonical properties only**: paragraph `alignment`/`list`/`spacingBeforePt`/`spacingAfterPt`/`lineSpacing`/`indentLeftPt`/`indentFirstLinePt`, run `bold`/`italic`/`underline`/`strike`/`fontFamily`/`sizePt`/`color`. Never `frames`, never `sourcePath`, never `styleId` (per-node facts — a position is a fact about a node, not a style), never a `basedOn` graph (the table is a dictionary, not a program) — and the ban list is **enforced by schema shape** (strict objects that reject those keys outright), not merely documented.
|
|
172
|
+
|
|
173
|
+
Resolution is one overlay chain — outermost ancestor group's style, each nearer group's style, the node's own direct properties; innermost wins, with the resolved run half applying one level further down as run defaults under each run's own properties. `src/definitions.ts` exports the pure helpers that implement it (`overlayStyleEntries`, `resolveStyleChain`, `applyParagraphStyleProperties`, `applyRunStyleProperties`); minting entries (the deterministic frequency pass that factors repeated property tuples into `s1`, `s2`, … refs) is documents.js's boundary behaviour, not this package's.
|
|
174
|
+
|
|
75
175
|
Every module is also importable directly — `tsdown` builds one file per source module, and `package.json`'s `"./*"` export makes each individually resolvable:
|
|
76
176
|
|
|
77
177
|
```ts
|
|
@@ -81,24 +181,23 @@ import { ColorSchema } from 'document-schema.js/color';
|
|
|
81
181
|
|
|
82
182
|
## Codecs
|
|
83
183
|
|
|
84
|
-
`ContentCodec
|
|
184
|
+
`ContentCodec` (`src/codec.ts`) is the format-agnostic *interface* a sibling package's docx/pptx/odt/odp/ods/odg/xlsx/markdown codec can implement, so a caller working across formats holds one of these instead of a format-specific function pair:
|
|
85
185
|
|
|
86
186
|
```ts
|
|
87
|
-
import type { ContentCodec
|
|
187
|
+
import type { ContentCodec } from 'document-schema.js';
|
|
88
188
|
|
|
89
189
|
declare const docxCodec: ContentCodec; // read(bytes) -> ContentDocument; write(content) -> bytes -- write is optional
|
|
90
|
-
declare const pdfCodec: LayoutCodec; // read(bytes) -> LayoutDocument; write(layout) -> bytes -- write is required
|
|
91
190
|
```
|
|
92
191
|
|
|
93
|
-
|
|
192
|
+
`ContentCodec.write` is optional (`odf` has a reader but no builder — recovering MathML from glyphs is OCR-adjacent), and the interface is generic over its own `TOptions`. There is no `LayoutCodec` any more: it modelled the one format that produces layout cheaply on read — PDF — and the whole `LayoutDocument` family it described moved to pdf-codec in 4.0.0 (see [pdf-codec#65](https://github.com/ExaDev/pdf-codec/issues/65)).
|
|
94
193
|
|
|
95
|
-
|
|
194
|
+
The interface constructs no `DocumentPackage`; composing one (decomposing a codec's flat `ContentDocument` into the tree) is the caller's job (`documents.js`'s `DOCUMENT_FORMAT_CODECS` registry is the concrete example).
|
|
96
195
|
|
|
97
196
|
This package also hosts the **port contracts** a layout engine consumes: `TextMeasurer`/`StyledRun`/`WrappedLine` (`src/text-layout.ts`), `ProvidedFont`/`FontSubstitution` (`src/font-port.ts`), `MathBox`/`MathFontMetrics`/`PositionedFormula` (`src/math-layout.ts`), and `Point` (`src/geometry.ts`).
|
|
98
197
|
|
|
99
198
|
## JSON Schema
|
|
100
199
|
|
|
101
|
-
|
|
200
|
+
Two plain [JSON Schema](https://json-schema.org) files are published — generated from the Zod definitions via [`z.toJSONSchema()`](https://zod.dev/json-schema) at build time (`scripts/generate-json-schemas.mjs`) — for non-TypeScript consumers:
|
|
102
201
|
|
|
103
202
|
```ts
|
|
104
203
|
const documentPackageSchema = require('document-schema.js/schemas/document-package.schema.json');
|
|
@@ -111,14 +210,13 @@ or from any language/tool that can read a file out of `node_modules`:
|
|
|
111
210
|
```
|
|
112
211
|
node_modules/document-schema.js/schemas/document-package.schema.json
|
|
113
212
|
node_modules/document-schema.js/schemas/content-document.schema.json
|
|
114
|
-
node_modules/document-schema.js/schemas/layout-document.schema.json
|
|
115
213
|
```
|
|
116
214
|
|
|
117
|
-
Each file's `$id` is a jsdelivr URL pinned to the exact npm version — immutable and live on publish
|
|
215
|
+
Each file's `$id` is a jsdelivr URL pinned to the exact npm version — immutable and live on publish, and (see [Versioning by `$schema`](#versioning-by-schema)) the version of anything stamped with it. Both files carry the same hand-authored `$defs` block (the same object emitted twice in one generator run, so the copies cannot drift), covering the recursive paragraph/table/embedded-object, MathML, and package-tree node models that Zod's converter cannot express directly; `content-json-schema-defs.ts` holds those fragments, and a regression test compares each fragment that has a real Zod counterpart against a live `z.toJSONSchema()` of that schema so a field changed without updating its fragment fails a test. The one deliberate cross-file `$ref` is the embedded-object cycle back to a whole `ContentDocument`. Fragments downstream of a `z.custom()` node (`ContentBlock`, `ContentTable`/`Cell`/`Row`, `ContentEmbeddedObject(Block)`, the nine package-tree group wrappers, `MathMlNode`/`Element`/`Attribute`, `ContentFormula`, `MathExpression` and its recursive variants) still need hand re-verification — the construct descriptors themselves do not, since each is a plain `z.strictObject` reaching no opaque node and is held to the live comparison against `src/content.ts`/`src/package-node.ts`/`src/mathml.ts`/`src/math.ts` — see below.
|
|
118
216
|
|
|
119
217
|
### `z.custom()` vs `z.lazy()` for recursive schemas
|
|
120
218
|
|
|
121
|
-
`ContentBlockSchema`, `ContentEmbeddedObjectSchema`, `MathMlNodeSchema`, and `MathExpressionSchema` are `z.custom()` type-guard predicates rather than real Zod schemas, because `z.lazy()` was believed to collapse to `unknown` for recursive children. A throwaway spike (reverted) re-tested `MathMlNodeSchema` (the simplest case) against `zod@4.4.3`.
|
|
219
|
+
`ContentBlockSchema`, `ContentEmbeddedObjectSchema`, the package tree's per-kind group schemas (`src/package-node.ts`), `MathMlNodeSchema`, and `MathExpressionSchema` are `z.custom()` type-guard predicates rather than real Zod schemas, because `z.lazy()` was believed to collapse to `unknown` for recursive children. A throwaway spike (reverted) re-tested `MathMlNodeSchema` (the simplest case) against `zod@4.4.3`.
|
|
122
220
|
|
|
123
221
|
**Finding: `z.lazy()` works now, with one constructional gotcha.** The naive rewrite —
|
|
124
222
|
|
|
@@ -138,41 +236,54 @@ export const MathMlNodeSchema: z.ZodType<MathMlNode> = z.discriminatedUnion('typ
|
|
|
138
236
|
|
|
139
237
|
**This is a tracked follow-up, not carried out here.** Converting `MathMlNodeSchema` for real would let the JSON-schema generator drop its hand-authored `$defs` entries; `ContentBlockSchema`/`ContentEmbeddedObjectSchema` are harder (mutual recursion across table/cell/row, plus the full `ContentDocument` cycle) and were not spiked.
|
|
140
238
|
|
|
239
|
+
### Versioning by `$schema`
|
|
240
|
+
|
|
241
|
+
There is no `formatVersion` field anywhere in a 4.0.0 dump. A serialised value states its version through the release-pinned `$schema` URI its dumper stamped, and that URI **is** the version — one source of truth instead of a hand-kept integer beside URIs that already named the release. `documentFromJson` is the enforcement point for untrusted input:
|
|
242
|
+
|
|
243
|
+
- a URI from the **same major** as the installed release parses (patch and minor releases are semver-compatible with their major's schema generation);
|
|
244
|
+
- an **older major's** URI throws `SchemaVersionMismatchError` naming the change — pre-4.0.0 dumps carry the retired `formatVersion` field and the flat `{ formatVersion, content, pages }` package shape, replaced by the tree form ([#20](https://github.com/ExaDev/document-schema.js/issues/20));
|
|
245
|
+
- a **newer major's** URI throws the same error with the upgrade pointer;
|
|
246
|
+
- a **layout-document** URI (any release) throws `LayoutSchemaDemotedError` pointing at pdf-codec — the demotion tombstone.
|
|
247
|
+
|
|
248
|
+
A bare `DocumentPackageSchema.parse(value)` does **not** version-discriminate — it structurally validates whatever it is handed against the installed schema, full stop — so a caller ingesting a dump it did not itself produce must go through `documentFromJson`, not a direct parse. `documentSchemaKindOf(value)` still answers "which kind does this URI name" version-agnostically without parsing. Content hashes and structural comparisons over serialised dumps must exclude `$schema` — it is envelope metadata that names the dumper, not content; two dumps of one document by two releases hash equal once it is excluded.
|
|
249
|
+
|
|
141
250
|
### Self-describing JSON
|
|
142
251
|
|
|
143
|
-
`documentPackageWithSchema`/`contentDocumentWithSchema
|
|
252
|
+
`documentPackageWithSchema`/`contentDocumentWithSchema` each stamp a `$schema` property pointing at the `.schema.json` file for the currently installed version:
|
|
144
253
|
|
|
145
254
|
```ts
|
|
146
255
|
import { documentPackageWithSchema } from 'document-schema.js';
|
|
147
256
|
|
|
148
257
|
const tagged = documentPackageWithSchema(pkg);
|
|
149
|
-
// { $schema: 'https://cdn.jsdelivr.net/npm/document-schema.js@
|
|
258
|
+
// { $schema: 'https://cdn.jsdelivr.net/npm/document-schema.js@4.0.0/schemas/document-package.schema.json', kind: 'wordprocessing', metadata: {...}, children: [...] }
|
|
150
259
|
writeFileSync('package.json.doc', JSON.stringify(tagged, null, 2));
|
|
151
260
|
```
|
|
152
261
|
|
|
153
|
-
A caller who already knows the kind can keep using the schemas directly — `DocumentPackageSchema.parse(value)` tolerates and strips an incoming `$schema` (none are `.strict()`). `documentFromJson` is for the "don't yet know the kind" case, reading `$schema` to decide which schema to run:
|
|
262
|
+
A caller who already knows the kind can keep using the schemas directly — `DocumentPackageSchema.parse(value)` tolerates and strips an incoming `$schema` (none are `.strict()`). `documentFromJson` is for the "don't yet know the kind or provenance" case, reading `$schema` to decide which schema to run and whether this release may run it:
|
|
154
263
|
|
|
155
264
|
```ts
|
|
156
|
-
import { documentFromJson, UnrecognizedDocumentSchemaError } from 'document-schema.js';
|
|
265
|
+
import { documentFromJson, SchemaVersionMismatchError, UnrecognizedDocumentSchemaError } from 'document-schema.js';
|
|
157
266
|
|
|
158
267
|
try {
|
|
159
268
|
const { kind, value } = documentFromJson(JSON.parse(readFileSync('some-file.json', 'utf8')));
|
|
160
|
-
// kind: 'DocumentPackage' | 'ContentDocument'
|
|
269
|
+
// kind: 'DocumentPackage' | 'ContentDocument'
|
|
161
270
|
} catch (error) {
|
|
162
271
|
if (error instanceof UnrecognizedDocumentSchemaError) {
|
|
163
272
|
console.error('not a document-schema.js value:', error.schema);
|
|
273
|
+
} else if (error instanceof SchemaVersionMismatchError) {
|
|
274
|
+
console.error(`dump is @${error.dumpVersion}, installed is @${error.installedVersion}`);
|
|
164
275
|
}
|
|
165
276
|
}
|
|
166
277
|
```
|
|
167
278
|
|
|
168
|
-
`
|
|
279
|
+
`schemaUriFor(kind)` is the URL builder. No JSON-Schema-validator dependency (e.g. `ajv`) for ingest — the `.schema.json` files are a weaker approximation of the real Zod schemas, so re-validating against them would be a fidelity regression.
|
|
169
280
|
|
|
170
281
|
## Used by
|
|
171
282
|
|
|
172
283
|
- [ooxml.js](https://github.com/ExaDev/ooxml.js) — `readDocx`/`readPptx`/`readXlsxContent` return types are typed against this package's schemas, not a local lookalike.
|
|
173
284
|
- [odf.js](https://github.com/ExaDev/odf.js) — ODF typed readers return the same shared types, so ODF and OOXML speak the identical pivot.
|
|
174
|
-
- [documents.js](https://github.com/ExaDev/documents.js) — primary consumer of `ContentDocument
|
|
175
|
-
- [pdf-codec](https://github.com/ExaDev/pdf-codec) — `readPdf`/`writePdf` operate on this package's `
|
|
285
|
+
- [documents.js](https://github.com/ExaDev/documents.js) — primary consumer of `ContentDocument` and `DocumentPackage`; its `DOCUMENT_FORMAT_CODECS` registry implements `ContentCodec` per format, and its package boundary runs decompose/flatten against the tree form.
|
|
286
|
+
- [pdf-codec](https://github.com/ExaDev/pdf-codec) — owns its layout item model outright since 4.0.0; `readPdf`/`writePdf` operate on pdf-codec's own `LayoutDocument`, and this package's `ContentDocument` remains its content pivot.
|
|
176
287
|
- [markdown-codec](https://github.com/ExaDev/markdown-codec) — `readMarkdown`/`writeMarkdown` read and write this package's `ContentDocument` directly.
|
|
177
288
|
|
|
178
289
|
None depend on each other for this vocabulary — each depends on `document-schema.js` directly.
|
|
@@ -183,13 +294,13 @@ Requires Node.js `>=20` and pnpm `11.6.0` (pinned via `packageManager` in `packa
|
|
|
183
294
|
|
|
184
295
|
```sh
|
|
185
296
|
pnpm install
|
|
186
|
-
pnpm build # turbo run _build -> tsdown && node scripts/generate-json-schemas.mjs (ESM + CJS + .d.ts in dist/, plus the
|
|
297
|
+
pnpm build # turbo run _build -> tsdown && node scripts/generate-json-schemas.mjs (ESM + CJS + .d.ts in dist/, plus the two published .schema.json files in schemas/)
|
|
187
298
|
pnpm typecheck # turbo run _typecheck _typecheck:node -> tsc -p tsconfig.json && tsc -p tsconfig.node.json
|
|
188
299
|
pnpm lint # turbo run _lint -> eslint . --fix --cache --max-warnings 0
|
|
189
300
|
pnpm test # turbo run _test -> vitest run --project unit
|
|
190
301
|
pnpm test:workers # turbo run _test:workers -> vitest run --config vitest.workers.config.ts (runs the test/workers suite under the real Cloudflare Workers runtime via @cloudflare/vitest-pool-workers, turning "pure Zod, no Node-API usage" into a runtime-checked fact rather than an assertion)
|
|
191
302
|
pnpm test:watch # vitest --project unit
|
|
192
|
-
pnpm test:smoke # turbo run _test:smoke -> rebuilds dist/ and schemas/ first, then verifies the built ESM/CJS output loads and exposes the public surface, and that the
|
|
303
|
+
pnpm test:smoke # turbo run _test:smoke -> rebuilds dist/ and schemas/ first, then verifies the built ESM/CJS output loads and exposes the public surface, and that the two generated JSON Schema files exist and are correctly version-pinned
|
|
193
304
|
```
|
|
194
305
|
|
|
195
306
|
To run a single test file: `pnpm vitest run src/path/to/file.test.ts`.
|
package/dist/codec.d.cts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { ContentDocument } from "./content.cjs";
|
|
2
|
-
import { LayoutDocument } from "./layout.cjs";
|
|
1
|
+
import { l as ContentDocument } from "./content-BN0PWqpt.cjs";
|
|
3
2
|
//#region src/codec.d.ts
|
|
4
3
|
interface ContentCodec<TOptions = unknown> {
|
|
5
4
|
read(bytes: Uint8Array, options?: TOptions): ContentDocument;
|
|
6
5
|
write?(content: ContentDocument, options?: TOptions): Uint8Array;
|
|
7
6
|
}
|
|
8
|
-
interface LayoutCodec<TOptions = unknown> {
|
|
9
|
-
read(bytes: Uint8Array, options?: TOptions): LayoutDocument;
|
|
10
|
-
write(layout: LayoutDocument, options?: TOptions): Uint8Array;
|
|
11
|
-
}
|
|
12
7
|
//#endregion
|
|
13
|
-
export { ContentCodec
|
|
8
|
+
export { ContentCodec };
|
package/dist/codec.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { ContentDocument } from "./content.js";
|
|
2
|
-
import { LayoutDocument } from "./layout.js";
|
|
1
|
+
import { l as ContentDocument } from "./content-CiZf6Fqn.js";
|
|
3
2
|
//#region src/codec.d.ts
|
|
4
3
|
interface ContentCodec<TOptions = unknown> {
|
|
5
4
|
read(bytes: Uint8Array, options?: TOptions): ContentDocument;
|
|
6
5
|
write?(content: ContentDocument, options?: TOptions): Uint8Array;
|
|
7
6
|
}
|
|
8
|
-
interface LayoutCodec<TOptions = unknown> {
|
|
9
|
-
read(bytes: Uint8Array, options?: TOptions): LayoutDocument;
|
|
10
|
-
write(layout: LayoutDocument, options?: TOptions): Uint8Array;
|
|
11
|
-
}
|
|
12
7
|
//#endregion
|
|
13
|
-
export { ContentCodec
|
|
8
|
+
export { ContentCodec };
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/construct.d.ts
|
|
3
|
+
declare const ContentControlTypeSchema: z.ZodEnum<{
|
|
4
|
+
richText: "richText";
|
|
5
|
+
plainText: "plainText";
|
|
6
|
+
checkbox: "checkbox";
|
|
7
|
+
dropDown: "dropDown";
|
|
8
|
+
comboBox: "comboBox";
|
|
9
|
+
date: "date";
|
|
10
|
+
picture: "picture";
|
|
11
|
+
repeatingSection: "repeatingSection";
|
|
12
|
+
button: "button";
|
|
13
|
+
index: "index";
|
|
14
|
+
group: "group";
|
|
15
|
+
}>;
|
|
16
|
+
type ContentControlType = z.infer<typeof ContentControlTypeSchema>;
|
|
17
|
+
declare const ContentControlLockSchema: z.ZodEnum<{
|
|
18
|
+
content: "content";
|
|
19
|
+
container: "container";
|
|
20
|
+
both: "both";
|
|
21
|
+
}>;
|
|
22
|
+
type ContentControlLock = z.infer<typeof ContentControlLockSchema>;
|
|
23
|
+
declare const ContentControlDescriptorSchema: z.ZodObject<{
|
|
24
|
+
kind: z.ZodLiteral<"contentControl">;
|
|
25
|
+
controlType: z.ZodEnum<{
|
|
26
|
+
richText: "richText";
|
|
27
|
+
plainText: "plainText";
|
|
28
|
+
checkbox: "checkbox";
|
|
29
|
+
dropDown: "dropDown";
|
|
30
|
+
comboBox: "comboBox";
|
|
31
|
+
date: "date";
|
|
32
|
+
picture: "picture";
|
|
33
|
+
repeatingSection: "repeatingSection";
|
|
34
|
+
button: "button";
|
|
35
|
+
index: "index";
|
|
36
|
+
group: "group";
|
|
37
|
+
}>;
|
|
38
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
39
|
+
alias: z.ZodOptional<z.ZodString>;
|
|
40
|
+
lock: z.ZodOptional<z.ZodEnum<{
|
|
41
|
+
content: "content";
|
|
42
|
+
container: "container";
|
|
43
|
+
both: "both";
|
|
44
|
+
}>>;
|
|
45
|
+
value: z.ZodOptional<z.ZodString>;
|
|
46
|
+
checked: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
|
+
}, z.core.$strict>;
|
|
49
|
+
type ContentControlDescriptor = z.infer<typeof ContentControlDescriptorSchema>;
|
|
50
|
+
declare const FieldDescriptorSchema: z.ZodObject<{
|
|
51
|
+
kind: z.ZodLiteral<"field">;
|
|
52
|
+
instruction: z.ZodString;
|
|
53
|
+
cachedResult: z.ZodOptional<z.ZodString>;
|
|
54
|
+
}, z.core.$strict>;
|
|
55
|
+
type FieldDescriptor = z.infer<typeof FieldDescriptorSchema>;
|
|
56
|
+
declare const AnchorTypeSchema: z.ZodEnum<{
|
|
57
|
+
bookmark: "bookmark";
|
|
58
|
+
footnote: "footnote";
|
|
59
|
+
endnote: "endnote";
|
|
60
|
+
comment: "comment";
|
|
61
|
+
}>;
|
|
62
|
+
type AnchorType = z.infer<typeof AnchorTypeSchema>;
|
|
63
|
+
declare const AnchorDescriptorSchema: z.ZodObject<{
|
|
64
|
+
kind: z.ZodLiteral<"anchor">;
|
|
65
|
+
anchorType: z.ZodEnum<{
|
|
66
|
+
bookmark: "bookmark";
|
|
67
|
+
footnote: "footnote";
|
|
68
|
+
endnote: "endnote";
|
|
69
|
+
comment: "comment";
|
|
70
|
+
}>;
|
|
71
|
+
name: z.ZodString;
|
|
72
|
+
definition: z.ZodOptional<z.ZodString>;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
type AnchorDescriptor = z.infer<typeof AnchorDescriptorSchema>;
|
|
75
|
+
declare const LinkTargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
76
|
+
kind: z.ZodLiteral<"external">;
|
|
77
|
+
uri: z.ZodString;
|
|
78
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
79
|
+
kind: z.ZodLiteral<"internal">;
|
|
80
|
+
anchor: z.ZodString;
|
|
81
|
+
}, z.core.$strict>], "kind">;
|
|
82
|
+
type LinkTarget = z.infer<typeof LinkTargetSchema>;
|
|
83
|
+
declare const LinkDescriptorSchema: z.ZodObject<{
|
|
84
|
+
kind: z.ZodLiteral<"link">;
|
|
85
|
+
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
86
|
+
kind: z.ZodLiteral<"external">;
|
|
87
|
+
uri: z.ZodString;
|
|
88
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
89
|
+
kind: z.ZodLiteral<"internal">;
|
|
90
|
+
anchor: z.ZodString;
|
|
91
|
+
}, z.core.$strict>], "kind">;
|
|
92
|
+
title: z.ZodOptional<z.ZodString>;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
type LinkDescriptor = z.infer<typeof LinkDescriptorSchema>;
|
|
95
|
+
declare const ProvenanceChangeSchema: z.ZodEnum<{
|
|
96
|
+
insertion: "insertion";
|
|
97
|
+
deletion: "deletion";
|
|
98
|
+
moveFrom: "moveFrom";
|
|
99
|
+
moveTo: "moveTo";
|
|
100
|
+
formatChange: "formatChange";
|
|
101
|
+
}>;
|
|
102
|
+
type ProvenanceChange = z.infer<typeof ProvenanceChangeSchema>;
|
|
103
|
+
declare const ProvenanceDescriptorSchema: z.ZodObject<{
|
|
104
|
+
kind: z.ZodLiteral<"provenance">;
|
|
105
|
+
change: z.ZodEnum<{
|
|
106
|
+
insertion: "insertion";
|
|
107
|
+
deletion: "deletion";
|
|
108
|
+
moveFrom: "moveFrom";
|
|
109
|
+
moveTo: "moveTo";
|
|
110
|
+
formatChange: "formatChange";
|
|
111
|
+
}>;
|
|
112
|
+
author: z.ZodOptional<z.ZodString>;
|
|
113
|
+
dateIso: z.ZodOptional<z.ZodString>;
|
|
114
|
+
}, z.core.$strict>;
|
|
115
|
+
type ProvenanceDescriptor = z.infer<typeof ProvenanceDescriptorSchema>;
|
|
116
|
+
declare const DivisionSourceSchema: z.ZodObject<{
|
|
117
|
+
href: z.ZodString;
|
|
118
|
+
sectionName: z.ZodOptional<z.ZodString>;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
type DivisionSource = z.infer<typeof DivisionSourceSchema>;
|
|
121
|
+
declare const DivisionDescriptorSchema: z.ZodObject<{
|
|
122
|
+
kind: z.ZodLiteral<"division">;
|
|
123
|
+
name: z.ZodOptional<z.ZodString>;
|
|
124
|
+
columnCount: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
protected: z.ZodOptional<z.ZodBoolean>;
|
|
126
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
127
|
+
href: z.ZodString;
|
|
128
|
+
sectionName: z.ZodOptional<z.ZodString>;
|
|
129
|
+
}, z.core.$strict>>;
|
|
130
|
+
}, z.core.$strict>;
|
|
131
|
+
type DivisionDescriptor = z.infer<typeof DivisionDescriptorSchema>;
|
|
132
|
+
declare const ConstructDescriptorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
133
|
+
kind: z.ZodLiteral<"contentControl">;
|
|
134
|
+
controlType: z.ZodEnum<{
|
|
135
|
+
richText: "richText";
|
|
136
|
+
plainText: "plainText";
|
|
137
|
+
checkbox: "checkbox";
|
|
138
|
+
dropDown: "dropDown";
|
|
139
|
+
comboBox: "comboBox";
|
|
140
|
+
date: "date";
|
|
141
|
+
picture: "picture";
|
|
142
|
+
repeatingSection: "repeatingSection";
|
|
143
|
+
button: "button";
|
|
144
|
+
index: "index";
|
|
145
|
+
group: "group";
|
|
146
|
+
}>;
|
|
147
|
+
tag: z.ZodOptional<z.ZodString>;
|
|
148
|
+
alias: z.ZodOptional<z.ZodString>;
|
|
149
|
+
lock: z.ZodOptional<z.ZodEnum<{
|
|
150
|
+
content: "content";
|
|
151
|
+
container: "container";
|
|
152
|
+
both: "both";
|
|
153
|
+
}>>;
|
|
154
|
+
value: z.ZodOptional<z.ZodString>;
|
|
155
|
+
checked: z.ZodOptional<z.ZodBoolean>;
|
|
156
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
157
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
158
|
+
kind: z.ZodLiteral<"field">;
|
|
159
|
+
instruction: z.ZodString;
|
|
160
|
+
cachedResult: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
162
|
+
kind: z.ZodLiteral<"anchor">;
|
|
163
|
+
anchorType: z.ZodEnum<{
|
|
164
|
+
bookmark: "bookmark";
|
|
165
|
+
footnote: "footnote";
|
|
166
|
+
endnote: "endnote";
|
|
167
|
+
comment: "comment";
|
|
168
|
+
}>;
|
|
169
|
+
name: z.ZodString;
|
|
170
|
+
definition: z.ZodOptional<z.ZodString>;
|
|
171
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
172
|
+
kind: z.ZodLiteral<"link">;
|
|
173
|
+
target: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
174
|
+
kind: z.ZodLiteral<"external">;
|
|
175
|
+
uri: z.ZodString;
|
|
176
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
177
|
+
kind: z.ZodLiteral<"internal">;
|
|
178
|
+
anchor: z.ZodString;
|
|
179
|
+
}, z.core.$strict>], "kind">;
|
|
180
|
+
title: z.ZodOptional<z.ZodString>;
|
|
181
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
182
|
+
kind: z.ZodLiteral<"provenance">;
|
|
183
|
+
change: z.ZodEnum<{
|
|
184
|
+
insertion: "insertion";
|
|
185
|
+
deletion: "deletion";
|
|
186
|
+
moveFrom: "moveFrom";
|
|
187
|
+
moveTo: "moveTo";
|
|
188
|
+
formatChange: "formatChange";
|
|
189
|
+
}>;
|
|
190
|
+
author: z.ZodOptional<z.ZodString>;
|
|
191
|
+
dateIso: z.ZodOptional<z.ZodString>;
|
|
192
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
193
|
+
kind: z.ZodLiteral<"division">;
|
|
194
|
+
name: z.ZodOptional<z.ZodString>;
|
|
195
|
+
columnCount: z.ZodOptional<z.ZodNumber>;
|
|
196
|
+
protected: z.ZodOptional<z.ZodBoolean>;
|
|
197
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
198
|
+
href: z.ZodString;
|
|
199
|
+
sectionName: z.ZodOptional<z.ZodString>;
|
|
200
|
+
}, z.core.$strict>>;
|
|
201
|
+
}, z.core.$strict>], "kind">;
|
|
202
|
+
type ConstructDescriptor = z.infer<typeof ConstructDescriptorSchema>;
|
|
203
|
+
//#endregion
|
|
204
|
+
export { ProvenanceChange as C, ProvenanceDescriptorSchema as E, LinkTargetSchema as S, ProvenanceDescriptor as T, FieldDescriptor as _, ConstructDescriptor as a, LinkDescriptorSchema as b, ContentControlDescriptorSchema as c, ContentControlType as d, ContentControlTypeSchema as f, DivisionSourceSchema as g, DivisionSource as h, AnchorTypeSchema as i, ContentControlLock as l, DivisionDescriptorSchema as m, AnchorDescriptorSchema as n, ConstructDescriptorSchema as o, DivisionDescriptor as p, AnchorType as r, ContentControlDescriptor as s, AnchorDescriptor as t, ContentControlLockSchema as u, FieldDescriptorSchema as v, ProvenanceChangeSchema as w, LinkTarget as x, LinkDescriptor as y };
|