@ansonlai/docx-redline-js 0.1.4 → 0.2.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/AGENTS.md +53 -4
- package/ARCHITECTURE.md +75 -11
- package/README.md +62 -3
- package/core/redline-validation.js +156 -0
- package/core/types.js +35 -8
- package/core/word-xml.js +90 -0
- package/dist/docx-redline-js.esm.js +3195 -2592
- package/dist/docx-redline-js.esm.js.map +4 -4
- package/dist/docx-redline-js.esm.min.js +71 -67
- package/dist/docx-redline-js.esm.min.js.map +4 -4
- package/docs/VALIDATION.md +104 -0
- package/docs/plans/2026-03-01-release-0.1.4-design.md +31 -0
- package/docs/plans/2026-03-01-release-0.1.4.md +108 -0
- package/docs/plans/2026-05-31-architectural changes.md +591 -0
- package/engine/format-application.js +13 -14
- package/engine/format-span-application.js +7 -6
- package/engine/formatting-removal.js +15 -12
- package/engine/oxml-engine.js +146 -55
- package/engine/reconstruction-mapper.js +35 -8
- package/engine/reconstruction-mode.js +14 -13
- package/engine/reconstruction-writer.js +97 -78
- package/engine/rpr-helpers.js +34 -32
- package/engine/run-builders.js +150 -39
- package/engine/surgical-diff-application.js +216 -0
- package/engine/surgical-mode.js +84 -519
- package/engine/surgical-run-splitting.js +96 -0
- package/engine/surgical-spans.js +169 -0
- package/engine/table-cell-context.js +15 -13
- package/engine/table-mode.js +39 -35
- package/index.d.ts +172 -0
- package/index.js +50 -47
- package/package.json +10 -2
- package/pipeline/ingestion-export.js +1 -0
- package/pipeline/ingestion-paragraph.js +37 -12
- package/pipeline/ingestion-table.js +11 -8
- package/scripts/build.mjs +40 -0
- package/scripts/check-types.mjs +29 -0
- package/scripts/export-validation-fixtures.mjs +125 -0
- package/scripts/lib/minimal-zip.mjs +155 -0
- package/scripts/run-tests.mjs +43 -0
- package/scripts/validate-fixtures-xsd.sh +37 -0
- package/scripts/word-com-differential.ps1 +133 -0
- package/scripts/word-com-smoke.ps1 +48 -0
- package/services/comment-locator.js +10 -9
- package/services/revision-comment-management.js +115 -1
- package/services/standalone-operation-runner.js +119 -69
- package/services/table-reconciliation.js +7 -8
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Validation
|
|
2
|
+
|
|
3
|
+
This package works on OOXML strings and intentionally leaves `.docx` zip
|
|
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).
|
|
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.
|
|
13
|
+
|
|
14
|
+
## Automated Checks (every `npm test`)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm test # includes tests/roundtrip_fuzz_tests.mjs (seeded, deterministic)
|
|
18
|
+
npm run test:isolation
|
|
19
|
+
npm run check:types
|
|
20
|
+
```
|
|
21
|
+
|
|
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:
|
|
25
|
+
|
|
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
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
node scripts/export-validation-fixtures.mjs
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Writes to `tmp/validation-docx/`, per case:
|
|
45
|
+
|
|
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
|
|
51
|
+
|
|
52
|
+
## Word Differential Check (Windows, desktop Word)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
node scripts/export-validation-fixtures.mjs
|
|
56
|
+
npm run smoke:word:diff
|
|
57
|
+
```
|
|
58
|
+
|
|
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.
|
|
64
|
+
|
|
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)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
node scripts/export-validation-fixtures.mjs
|
|
72
|
+
bash scripts/validate-fixtures-xsd.sh
|
|
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.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 0.1.4 Release Prep Design
|
|
2
|
+
|
|
3
|
+
**Objective:** Prepare the repository for a `0.1.4` patch release without publishing from this session.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
- Bump the package version from `0.1.3` to `0.1.4` in release metadata.
|
|
8
|
+
- Update local release-note examples that are pinned to the prior version.
|
|
9
|
+
- Run release preflight verification locally after the version bump.
|
|
10
|
+
- Hand off the exact npm commands for the manual publish step.
|
|
11
|
+
|
|
12
|
+
## Approach
|
|
13
|
+
|
|
14
|
+
Use minimal, explicit edits so the release prep is easy to review. Keep the release workflow local and manual, consistent with the existing policy in `.anson/release-ci-cd-notes.md`.
|
|
15
|
+
|
|
16
|
+
## Verification
|
|
17
|
+
|
|
18
|
+
Run the same preflight commands documented in the local release notes:
|
|
19
|
+
|
|
20
|
+
- `npm test:isolation`
|
|
21
|
+
- `npm test`
|
|
22
|
+
- `npm run build`
|
|
23
|
+
- `npm pack --dry-run`
|
|
24
|
+
|
|
25
|
+
## Manual Handoff
|
|
26
|
+
|
|
27
|
+
After verification, provide the exact commands for:
|
|
28
|
+
|
|
29
|
+
- `npm whoami`
|
|
30
|
+
- `npm publish --access public`
|
|
31
|
+
- `npm view @ansonlai/docx-redline-js version`
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 0.1.4 Release Prep Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Prepare the repository for a local/manual `0.1.4` release and verify it is ready to publish.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Keep the release prep narrowly scoped to version metadata, local release instructions, and preflight verification. Do not publish from the implementation step; instead, leave the workspace in a verified, reviewable state and hand off the final npm commands.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js, npm, PowerShell, package metadata files
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: Update Release Metadata
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Create: `docs/plans/2026-03-01-release-0.1.4-design.md`
|
|
17
|
+
- Create: `docs/plans/2026-03-01-release-0.1.4.md`
|
|
18
|
+
- Modify: `package.json`
|
|
19
|
+
- Modify: `package-lock.json`
|
|
20
|
+
- Modify: `.anson/release-ci-cd-notes.md`
|
|
21
|
+
|
|
22
|
+
**Step 1: Write the failing test**
|
|
23
|
+
|
|
24
|
+
Inspect the current version references and confirm they still show `0.1.3`.
|
|
25
|
+
|
|
26
|
+
**Step 2: Run test to verify it fails**
|
|
27
|
+
|
|
28
|
+
Run: `rg -uu -n "0\\.1\\.3|0\\.1\\.4" .`
|
|
29
|
+
Expected: package metadata and local release-note examples still point to `0.1.3`.
|
|
30
|
+
|
|
31
|
+
**Step 3: Write minimal implementation**
|
|
32
|
+
|
|
33
|
+
- Change package version fields to `0.1.4`.
|
|
34
|
+
- Update local release-note example commands and CDN URLs to `0.1.4`.
|
|
35
|
+
- Save the release design and implementation plan docs.
|
|
36
|
+
|
|
37
|
+
**Step 4: Run test to verify it passes**
|
|
38
|
+
|
|
39
|
+
Run: `rg -uu -n "0\\.1\\.3|0\\.1\\.4" package.json package-lock.json .anson/release-ci-cd-notes.md`
|
|
40
|
+
Expected: only `0.1.4` appears in those release-facing files.
|
|
41
|
+
|
|
42
|
+
**Step 5: Commit**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git add docs/plans/2026-03-01-release-0.1.4-design.md docs/plans/2026-03-01-release-0.1.4.md package.json package-lock.json .anson/release-ci-cd-notes.md
|
|
46
|
+
git commit -m "release: prep v0.1.4"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Task 2: Run Release Preflight
|
|
50
|
+
|
|
51
|
+
**Files:**
|
|
52
|
+
- Modify: `dist/docx-redline-js.esm.js`
|
|
53
|
+
|
|
54
|
+
**Step 1: Write the failing test**
|
|
55
|
+
|
|
56
|
+
Assume the built artifact banner still reflects the previous version until the build runs.
|
|
57
|
+
|
|
58
|
+
**Step 2: Run test to verify it fails**
|
|
59
|
+
|
|
60
|
+
Run: `rg -n "v0\\.1\\.3|v0\\.1\\.4" dist/docx-redline-js.esm.js`
|
|
61
|
+
Expected: the banner still shows `v0.1.3` before rebuilding.
|
|
62
|
+
|
|
63
|
+
**Step 3: Write minimal implementation**
|
|
64
|
+
|
|
65
|
+
Run the documented preflight:
|
|
66
|
+
|
|
67
|
+
- `npm test:isolation`
|
|
68
|
+
- `npm test`
|
|
69
|
+
- `npm run build`
|
|
70
|
+
- `npm pack --dry-run`
|
|
71
|
+
|
|
72
|
+
**Step 4: Run test to verify it passes**
|
|
73
|
+
|
|
74
|
+
Run: `rg -n "v0\\.1\\.3|v0\\.1\\.4" dist/docx-redline-js.esm.js`
|
|
75
|
+
Expected: the banner shows `v0.1.4`, and the preflight commands complete successfully.
|
|
76
|
+
|
|
77
|
+
**Step 5: Commit**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git add dist/docx-redline-js.esm.js
|
|
81
|
+
git commit -m "build: refresh dist for v0.1.4"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Task 3: Publish Handoff
|
|
85
|
+
|
|
86
|
+
**Files:**
|
|
87
|
+
- No file changes
|
|
88
|
+
|
|
89
|
+
**Step 1: Write the failing test**
|
|
90
|
+
|
|
91
|
+
Confirm the package is not yet published from this session.
|
|
92
|
+
|
|
93
|
+
**Step 2: Run test to verify it fails**
|
|
94
|
+
|
|
95
|
+
Run: `npm view @ansonlai/docx-redline-js version`
|
|
96
|
+
Expected: the registry version may still report the prior published release until you publish manually.
|
|
97
|
+
|
|
98
|
+
**Step 3: Write minimal implementation**
|
|
99
|
+
|
|
100
|
+
Provide the exact local commands for npm auth check, publish, optional tag push, and post-publish verification.
|
|
101
|
+
|
|
102
|
+
**Step 4: Run test to verify it passes**
|
|
103
|
+
|
|
104
|
+
User runs the publish commands locally and confirms `npm view @ansonlai/docx-redline-js version` returns `0.1.4`.
|
|
105
|
+
|
|
106
|
+
**Step 5: Commit**
|
|
107
|
+
|
|
108
|
+
No additional commit required.
|