@office-open/docx 0.12.1 → 0.12.3

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 CHANGED
@@ -71,9 +71,32 @@ const buffer = await generateDocument({
71
71
  writeFileSync("My Document.docx", buffer);
72
72
  ```
73
73
 
74
+ ## API
75
+
76
+ - `generateDocument(options)` — generate a `.docx` file; `generateDocumentSync` and `generateDocumentStream` cover sync and streaming output
77
+ - `parseDocument(bytes)` — read a `.docx` back into `DocumentOptions`
78
+ - `patchDocument(input)` — patch an existing `.docx` template by placeholder replacement
79
+
80
+ Every input is a plain JSON object (`DocumentOptions` and its option types). The full typed API reference lives in the [documentation](https://www.office-open.com/en/docx/); the same types are also frozen as JSON Schemas — `npx office-open schema slice docx DocumentOptions`.
81
+
82
+ ## Parsing
83
+
84
+ Read existing `.docx` files and re-create them as `DocumentOptions`:
85
+
86
+ ```typescript
87
+ import { parseDocument, generateDocument } from "@office-open/docx";
88
+ import { readFileSync, writeFileSync } from "node:fs";
89
+
90
+ const opts = parseDocument(new Uint8Array(readFileSync("input.docx")));
91
+
92
+ // Modify parsed data, then re-generate
93
+ const buffer = await generateDocument(opts);
94
+ writeFileSync("output.docx", buffer);
95
+ ```
96
+
74
97
  ## Examples
75
98
 
76
- Check the [demo folder](./demo) for 100+ working examples covering every feature.
99
+ Check the [demo folder](https://github.com/DemoMacro/office-open/tree/main/packages/docx/demo) for 100+ working examples covering every feature.
77
100
 
78
101
  ## Benchmark
79
102
 
@@ -94,24 +117,24 @@ generateDocumentStream(options);
94
117
 
95
118
  | Scenario | Runtime | Default sync | Default async | All STORE sync | All STORE async | Default stream | docx |
96
119
  | ------------------------------ | ------- | ------------ | ------------- | -------------- | --------------- | -------------- | ---------- |
97
- | Simple (2p + 1 img) | Node 24 | 905 ops/s | 1,311 ops/s | 2,478 ops/s | 2,985 ops/s | 10.1 ops/s | 91.2 ops/s |
120
+ | Simple (2p + 1 img) | Node 24 | 905 ops/s | 1,311 ops/s | 2,478 ops/s | 2,985 ops/s | 1,477 ops/s | 91.2 ops/s |
98
121
  | | Bun 1.4 | 2,471 ops/s | 758 ops/s | 5,323 ops/s | 5,246 ops/s | 384 ops/s | 63.7 ops/s |
99
- | Styled paragraphs (20) + 1 img | Node 24 | 1,065 ops/s | 1,405 ops/s | 2,765 ops/s | 2,752 ops/s | 14.2 ops/s | 91.1 ops/s |
122
+ | Styled paragraphs (20) + 1 img | Node 24 | 1,065 ops/s | 1,405 ops/s | 2,765 ops/s | 2,752 ops/s | 1,365 ops/s | 91.1 ops/s |
100
123
  | | Bun 1.4 | 2,994 ops/s | 692 ops/s | 4,567 ops/s | 4,627 ops/s | 443 ops/s | 72.2 ops/s |
101
- | Table (10x5) | Node 24 | 1,301 ops/s | 1,286 ops/s | 3,154 ops/s | 3,163 ops/s | 14.3 ops/s | 196 ops/s |
124
+ | Table (10x5) | Node 24 | 1,301 ops/s | 1,286 ops/s | 3,154 ops/s | 3,163 ops/s | 1,571 ops/s | 196 ops/s |
102
125
  | | Bun 1.4 | 2,791 ops/s | 691 ops/s | 5,107 ops/s | 4,882 ops/s | 543 ops/s | 252 ops/s |
103
- | Full featured + 2 imgs | Node 24 | 763 ops/s | 1,031 ops/s | 1,671 ops/s | 1,576 ops/s | 12.7 ops/s | 54.2 ops/s |
126
+ | Full featured + 2 imgs | Node 24 | 763 ops/s | 1,031 ops/s | 1,671 ops/s | 1,576 ops/s | 972 ops/s | 54.2 ops/s |
104
127
  | | Bun 1.4 | 1,646 ops/s | 575 ops/s | 2,630 ops/s | 2,456 ops/s | 330 ops/s | 41.1 ops/s |
105
128
 
106
129
  **Large Files — Create + toBuffer / toStream**
107
130
 
108
131
  | Scenario | Runtime | Default sync | Default async | All STORE sync | All STORE async | Default stream | docx |
109
132
  | ------------------------------ | ------- | ------------ | ------------- | -------------- | --------------- | -------------- | ---------- |
110
- | 2000 paragraphs + 20 images | Node 24 | 104.5 ops/s | 109.4 ops/s | 111.6 ops/s | 114.9 ops/s | 11.3 ops/s | 2.85 ops/s |
133
+ | 2000 paragraphs + 20 images | Node 24 | 104.5 ops/s | 109.4 ops/s | 111.6 ops/s | 114.9 ops/s | 104 ops/s | 2.85 ops/s |
111
134
  | | Bun 1.4 | 148.8 ops/s | 126.5 ops/s | 168.0 ops/s | 164.9 ops/s | 37.4 ops/s | 2.18 ops/s |
112
- | 200x10 table | Node 24 | 252.4 ops/s | 247.3 ops/s | 282.1 ops/s | 288.7 ops/s | 13.7 ops/s | 35.6 ops/s |
135
+ | 200x10 table | Node 24 | 252.4 ops/s | 247.3 ops/s | 282.1 ops/s | 288.7 ops/s | 253 ops/s | 35.6 ops/s |
113
136
  | | Bun 1.4 | 372.0 ops/s | 272.4 ops/s | 441.5 ops/s | 405.6 ops/s | 169 ops/s | 44.5 ops/s |
114
- | 20 sections x 100p + 40 images | Node 24 | 89.6 ops/s | 94.5 ops/s | 103.6 ops/s | 103.7 ops/s | 3.53 ops/s | 1.73 ops/s |
137
+ | 20 sections x 100p + 40 images | Node 24 | 89.6 ops/s | 94.5 ops/s | 103.6 ops/s | 103.7 ops/s | 93 ops/s | 1.73 ops/s |
115
138
  | | Bun 1.4 | 141.9 ops/s | 90.9 ops/s | 163.7 ops/s | 170.4 ops/s | 33.2 ops/s | 1.15 ops/s |
116
139
 
117
140
  **Large File (~100MB) — Mixed Content**
@@ -120,11 +143,25 @@ generateDocumentStream(options);
120
143
 
121
144
  | Scenario | Runtime | Default sync | Default async | All STORE sync | All STORE async | Default stream | docx |
122
145
  | ------------------------ | ------- | ------------ | ------------- | -------------- | --------------- | -------------- | ---------- |
123
- | Mixed (500p+38img+50x10) | Node 24 | 23.1 ops/s | 21.2 ops/s | 23.7 ops/s | 23.9 ops/s | 3.56 ops/s | 0.28 ops/s |
146
+ | Mixed (500p+38img+50x10) | Node 24 | 23.1 ops/s | 21.2 ops/s | 23.7 ops/s | 23.9 ops/s | 20.5 ops/s | 0.28 ops/s |
124
147
  | | Bun 1.4 | 38.8 ops/s | 32.5 ops/s | 36.5 ops/s | 30.7 ops/s | 5.27 ops/s | 0.21 ops/s |
125
148
 
126
- **Stream** = `generateDocumentStream` (default compression, fully drained) it targets piping and a flat memory profile, not peak throughput.
149
+ **Stream** = `generateDocumentStream` (default compression, fully drained). Under Node the archive is deflated in parallel on the libuv thread pool; under Bun and browsers it deflates inline / off-thread via fflate.
150
+
151
+ ## Documentation
152
+
153
+ - [Documentation](https://www.office-open.com/en/docx/) — guides, API reference, and examples
154
+ - [Changelog](https://github.com/DemoMacro/office-open/releases) — release notes
155
+ - [Report Issues](https://github.com/DemoMacro/office-open/issues) — bug reports and feature requests
156
+
157
+ ## Related Packages
158
+
159
+ - [office-open](https://www.npmjs.com/package/office-open) — all formats + CLI + AI SDK tools in one install
160
+ - [@office-open/pptx](https://www.npmjs.com/package/@office-open/pptx) — PowerPoint (.pptx)
161
+ - [@office-open/xlsx](https://www.npmjs.com/package/@office-open/xlsx) — Excel (.xlsx)
162
+ - [@office-open/core](https://www.npmjs.com/package/@office-open/core) — shared OOXML infrastructure
163
+ - [@office-open/xml](https://www.npmjs.com/package/@office-open/xml) — XML parsing and serialization
127
164
 
128
165
  ## License
129
166
 
130
- - [MIT](LICENSE) © [Demo Macro](https://www.demomacro.com/)
167
+ - [MIT](https://github.com/DemoMacro/office-open/blob/main/LICENSE) © [Demo Macro](https://www.demomacro.com/)
package/dist/index.mjs CHANGED
@@ -12315,7 +12315,7 @@ var Styles = class {
12315
12315
  ...this.attributes
12316
12316
  };
12317
12317
  const attrParts = [];
12318
- for (const [k, v] of Object.entries(merged)) if (v !== void 0 && v !== null) attrParts.push(` ${k}="${v}"`);
12318
+ for (const [k, v] of Object.entries(merged)) if (v != null) attrParts.push(` ${k}="${v}"`);
12319
12319
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:styles${attrParts.join("")}>${this.parts.join("")}</w:styles>`;
12320
12320
  }
12321
12321
  };
@@ -13394,7 +13394,7 @@ const settingsDesc = {
13394
13394
  p.push(onOff("w:autoFormatOverride", opts.autoFormatOverride));
13395
13395
  p.push(onOff("w:styleLockTheme", opts.styleLockTheme));
13396
13396
  p.push(onOff("w:styleLockQFSet", opts.styleLockQFSet));
13397
- if (opts.defaultTabStop !== void 0) p.push(numVal("w:defaultTabStop", opts.defaultTabStop));
13397
+ p.push(numVal("w:defaultTabStop", opts.defaultTabStop));
13398
13398
  p.push(onOff("w:autoHyphenation", opts.autoHyphenation));
13399
13399
  p.push(numVal("w:consecutiveHyphenLimit", opts.consecutiveHyphenLimit));
13400
13400
  p.push(numVal("w:hyphenationZone", opts.hyphenationZone));
@@ -13491,11 +13491,11 @@ const settingsDesc = {
13491
13491
  p.push(onOff("w:doNotEmbedSmartTags", opts.doNotEmbedSmartTags));
13492
13492
  p.push(strVal("w:decimalSymbol", opts.decimalSymbol));
13493
13493
  p.push(strVal("w:listSeparator", opts.listSeparator));
13494
- if (opts.w14DocId !== void 0) p.push(strVal("w14:docId", opts.w14DocId));
13494
+ p.push(strVal("w14:docId", opts.w14DocId));
13495
13495
  p.push(onOff("w14:discardImageEditingData", opts.w14DiscardImageEditingData));
13496
13496
  if (opts.w14DefaultImageDpi !== void 0) p.push(strVal("w14:defaultImageDpi", String(opts.w14DefaultImageDpi)));
13497
13497
  if (opts.w15ChartTrackingRefBased) p.push(`<w15:chartTrackingRefBased/>`);
13498
- if (opts.w15DocId !== void 0) p.push(strVal("w15:docId", opts.w15DocId));
13498
+ p.push(strVal("w15:docId", opts.w15DocId));
13499
13499
  const body = p.join("");
13500
13500
  return `<w:settings ${SETTINGS_NS}>${body}</w:settings>`;
13501
13501
  },