@ansonlai/docx-redline-js 0.1.6 → 0.2.1
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/ARCHITECTURE.md +19 -3
- package/README.md +15 -0
- package/core/redline-validation.js +156 -0
- package/dist/docx-redline-js.esm.js +152 -31
- package/dist/docx-redline-js.esm.js.map +4 -4
- package/dist/docx-redline-js.esm.min.js +62 -62
- package/dist/docx-redline-js.esm.min.js.map +4 -4
- package/docs/VALIDATION.md +79 -23
- package/docs/plans/2026-05-31-architectural changes.md +591 -0
- package/engine/formatting-removal.js +14 -8
- package/engine/run-builders.js +14 -10
- package/engine/surgical-diff-application.js +7 -21
- package/index.d.ts +24 -0
- package/index.js +35 -34
- package/package.json +5 -4
- package/scripts/build.mjs +10 -5
- package/scripts/check-types.mjs +2 -1
- package/scripts/export-validation-fixtures.mjs +73 -16
- package/scripts/lib/minimal-zip.mjs +155 -0
- package/scripts/validate-fixtures-xsd.sh +37 -0
- package/scripts/word-com-differential.ps1 +133 -0
package/docs/VALIDATION.md
CHANGED
|
@@ -1,48 +1,104 @@
|
|
|
1
1
|
# Validation
|
|
2
2
|
|
|
3
3
|
This package works on OOXML strings and intentionally leaves `.docx` zip
|
|
4
|
-
packaging to consumers
|
|
5
|
-
|
|
4
|
+
packaging to consumers (release *tooling* assembles minimal `.docx` fixtures
|
|
5
|
+
with a script-local zip writer; the published library still has no zip
|
|
6
|
+
dependency).
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
The test suite verifies the accept/reject round-trip invariant using the
|
|
9
|
+
library's own transforms. Because a shared misconception between the
|
|
10
|
+
generator and the resolver would pass those tests silently, release
|
|
11
|
+
validation adds **independent oracles**: Microsoft Word, LibreOffice, and
|
|
12
|
+
the ECMA-376 schemas.
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## Automated Checks (every `npm test`)
|
|
10
15
|
|
|
11
16
|
```bash
|
|
12
|
-
npm test
|
|
17
|
+
npm test # includes tests/roundtrip_fuzz_tests.mjs (seeded, deterministic)
|
|
13
18
|
npm run test:isolation
|
|
14
19
|
npm run check:types
|
|
15
20
|
```
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
The fuzz harness generates random paragraph structures and edits, then
|
|
23
|
+
asserts the round-trip invariant plus `validateRedlineOoxml` on each case.
|
|
24
|
+
Tune or reproduce with:
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
```bash
|
|
27
|
+
FUZZ_SEED=<seed> FUZZ_ITERATIONS=<n> node tests/roundtrip_fuzz_tests.mjs
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A failing case prints its exact reproduction command.
|
|
31
|
+
|
|
32
|
+
## Runtime Guardrail
|
|
33
|
+
|
|
34
|
+
`validateRedlineOoxml(oxml)` (exported from `index.js`) runs the structural
|
|
35
|
+
invariants at runtime and returns `{ valid, issues }`. Downstream packagers
|
|
36
|
+
should call it before writing engine output into `word/document.xml`.
|
|
37
|
+
|
|
38
|
+
## Export Fixtures
|
|
20
39
|
|
|
21
40
|
```bash
|
|
22
41
|
node scripts/export-validation-fixtures.mjs
|
|
23
42
|
```
|
|
24
43
|
|
|
25
|
-
|
|
26
|
-
`tmp/validation-docx/`. If a case emits numbering XML, it writes that alongside
|
|
27
|
-
the document XML. The script does not create full `.docx` files because the
|
|
28
|
-
library intentionally avoids a zip dependency.
|
|
44
|
+
Writes to `tmp/validation-docx/`, per case:
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
- `<name>.document.xml` — generated `word/document.xml` payload
|
|
47
|
+
- `<name>.docx` — minimal assembled package
|
|
48
|
+
- `<name>.expected.json` — expected accept-all / reject-all plain text,
|
|
49
|
+
derived from edit *intent* (not from this library's transforms), so
|
|
50
|
+
external consumers act as independent oracles
|
|
31
51
|
|
|
32
|
-
|
|
52
|
+
## Word Differential Check (Windows, desktop Word)
|
|
33
53
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
expected tracked changes are visible.
|
|
54
|
+
```bash
|
|
55
|
+
node scripts/export-validation-fixtures.mjs
|
|
56
|
+
npm run smoke:word:diff
|
|
57
|
+
```
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
For each fixture, desktop Word opens the `.docx`, confirms revisions are
|
|
60
|
+
visible, runs **AcceptAllRevisions**, and compares the document text to the
|
|
61
|
+
expected modified text; then reopens and runs **RejectAllRevisions** and
|
|
62
|
+
compares to the original text. This is the strongest check available: Word
|
|
63
|
+
itself resolves the revisions this library generated.
|
|
43
64
|
|
|
44
|
-
|
|
65
|
+
The older `npm run smoke:word -- path/to/file.docx` open-only smoke check
|
|
66
|
+
remains available for ad-hoc files.
|
|
67
|
+
|
|
68
|
+
## Schema Validation (ECMA-376 transitional XSD)
|
|
45
69
|
|
|
46
70
|
```bash
|
|
47
|
-
|
|
71
|
+
node scripts/export-validation-fixtures.mjs
|
|
72
|
+
bash scripts/validate-fixtures-xsd.sh
|
|
48
73
|
```
|
|
74
|
+
|
|
75
|
+
Downloads (and caches in `.cache/ooxml-schemas/`) the transitional
|
|
76
|
+
wordprocessingml schemas from ECMA-376 Part 4, patches the `xml:` namespace
|
|
77
|
+
import to resolve offline, and validates every `*.document.xml` fixture with
|
|
78
|
+
`xmllint`. Requires `curl`, `unzip`, and `xmllint` (`libxml2-utils` on
|
|
79
|
+
Debian/Ubuntu; available on Windows via conda/msys).
|
|
80
|
+
|
|
81
|
+
## LibreOffice Consumer Check
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cd tmp/validation-docx
|
|
85
|
+
soffice --headless --convert-to pdf --outdir converted *.docx
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A second independent OOXML consumer parsing the fixtures without error.
|
|
89
|
+
|
|
90
|
+
## Continuous Validation
|
|
91
|
+
|
|
92
|
+
`.github/workflows/validation.yml` runs nightly (and on demand via
|
|
93
|
+
`workflow_dispatch`):
|
|
94
|
+
|
|
95
|
+
1. **xsd-schema** — exports fixtures and validates them against the
|
|
96
|
+
ECMA-376 transitional `wml.xsd`.
|
|
97
|
+
2. **libreoffice** — exports fixtures and converts them with headless
|
|
98
|
+
LibreOffice.
|
|
99
|
+
3. **fuzz-extended** — 20,000 fuzz round-trip cases with a date-derived
|
|
100
|
+
seed, so every night explores new inputs. A failure log includes the
|
|
101
|
+
exact `FUZZ_SEED` reproduction command.
|
|
102
|
+
|
|
103
|
+
The Word differential check stays manual because it requires desktop Word;
|
|
104
|
+
run it before tagging a release.
|