clear-excel 1.0.4 → 1.0.5

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +67 -184
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project are documented in this file. The project
4
4
  follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [1.0.5] - 2026-10-11
7
+
8
+ ### Changed
9
+
10
+ - Simplify the README to focus on installation, usage, options, errors, and
11
+ supported workbook limitations.
12
+
6
13
  ## [1.0.4] - 2026-10-09
7
14
 
8
15
  ### Fixed
@@ -48,6 +55,7 @@ follows [Semantic Versioning](https://semver.org/).
48
55
  - Initial release with buffer and file APIs for sanitizing `.xls`, `.xlsx`,
49
56
  and `.xlsm` workbooks.
50
57
 
58
+ [1.0.5]: https://www.npmjs.com/package/clear-excel/v/1.0.5
51
59
  [1.0.4]: https://www.npmjs.com/package/clear-excel/v/1.0.4
52
60
  [1.0.0]: https://www.npmjs.com/package/clear-excel/v/1.0.0
53
61
  [0.1.0]: https://www.npmjs.com/package/clear-excel/v/0.1.0
package/README.md CHANGED
@@ -1,63 +1,34 @@
1
- <div align="center">
1
+ # clear-excel
2
2
 
3
- <h1>clear-excel</h1>
3
+ Remove images, drawings, comments, controls, and embedded objects from `.xls`,
4
+ `.xlsx`, and `.xlsm` workbooks. Cell values, formulas, merged cells, worksheets,
5
+ and used styles are preserved. Unused styles are also removed from `.xlsx` and
6
+ `.xlsm` workbooks.
4
7
 
5
- <p><strong>Remove drawings, comments, and embedded objects from Excel workbooks
6
- without rebuilding their data model.</strong></p>
8
+ ## Install
7
9
 
8
- <p>
9
- <a href="https://www.npmjs.com/package/clear-excel"><img alt="npm version" src="https://img.shields.io/npm/v/clear-excel?style=flat-square&amp;logo=npm"></a>
10
- <a href="https://www.npmjs.com/package/clear-excel"><img alt="npm downloads" src="https://img.shields.io/npm/dm/clear-excel?style=flat-square&amp;logo=npm"></a>
11
- <a href="https://github.com/Vlad1slav1vanov/clear-excel/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/Vlad1slav1vanov/clear-excel/ci.yml?branch=main&amp;style=flat-square&amp;logo=github&amp;label=CI"></a>
12
- <a href="https://www.npmjs.com/package/clear-excel"><img alt="Node.js" src="https://img.shields.io/node/v/clear-excel?style=flat-square&amp;logo=nodedotjs"></a>
13
- <a href="./LICENSE"><img alt="License" src="https://img.shields.io/npm/l/clear-excel?style=flat-square"></a>
14
- </p>
15
-
16
- <p>
17
- <a href="https://www.npmjs.com/package/clear-excel">npm</a> ·
18
- <a href="https://github.com/Vlad1slav1vanov/clear-excel/releases">Releases</a> ·
19
- <a href="./CHANGELOG.md">Changelog</a> ·
20
- <a href="./CONTRIBUTING.md">Contributing</a> ·
21
- <a href="./SECURITY.md">Security</a>
22
- </p>
23
-
24
- </div>
25
-
26
- `clear-excel` is an ESM-only Node.js library for sanitizing legacy `.xls` and
27
- OOXML `.xlsx`/`.xlsm` workbooks while preserving worksheet data and structure.
28
- It has no framework or consumer-side build requirement.
29
-
30
- ## What it removes
31
-
32
- - drawings, images, comments, controls, and embedded OLE objects;
33
- - VML drawings, threaded comments, and person metadata in OOXML workbooks;
34
- - unused `cellXfs` style records in OOXML workbooks;
35
- - BIFF drawing, note, object, and picture records plus embedded object storages
36
- in legacy `.xls` workbooks.
37
-
38
- Values, formulas and cached results, merged cells, worksheets, and styles that
39
- are still referenced by cells, rows, or columns are retained. `.xlsm` VBA
40
- projects and legacy `.xls` VBA storages are preserved; the library does not
41
- execute or remove macros.
10
+ ```sh
11
+ npm install clear-excel
12
+ ```
42
13
 
43
- ## Requirements
14
+ Requires Node.js 22 or newer. ESM only; TypeScript declarations are included.
44
15
 
45
- - Node.js 22 or newer;
46
- - Excel 97-2003 BIFF8 `.xls`, OOXML `.xlsx`, or macro-enabled `.xlsm` input.
16
+ ## Usage
47
17
 
48
- Encrypted `.xls` workbooks are not supported.
18
+ ### Files
49
19
 
50
- ## Installation
20
+ ```js
21
+ import { sanitizeExcelFile } from "clear-excel";
51
22
 
52
- ```sh
53
- pnpm add clear-excel
23
+ await sanitizeExcelFile("report.xlsx", "report.cleaned.xlsx");
54
24
  ```
55
25
 
56
- The package is published on
57
- [npm](https://www.npmjs.com/package/clear-excel) and includes TypeScript
58
- declarations.
26
+ `sanitizeExcelFile(inputPath, outputPath, options?)` returns `Promise<void>`.
27
+ Input and output must refer to different files and use the same supported
28
+ extension (`.xls`, `.xlsx`, or `.xlsm`, case-insensitive). The output directory
29
+ must already exist. To replace an existing output file, set `overwrite: true`.
59
30
 
60
- ## Buffer API
31
+ ### Buffers
61
32
 
62
33
  ```js
63
34
  import { readFile, writeFile } from "node:fs/promises";
@@ -68,54 +39,40 @@ const output = await sanitizeExcel(input);
68
39
  await writeFile("report.cleaned.xlsx", output);
69
40
  ```
70
41
 
71
- `sanitizeExcel` accepts a Node.js `Buffer`, returns a new `Buffer`, and never
72
- modifies the input buffer. It detects legacy CFB/BIFF workbooks by their file
73
- signature and keeps the input format in the returned buffer.
42
+ `sanitizeExcel(buffer, options?)` accepts a Node.js `Buffer` and returns
43
+ `Promise<Buffer>`. The input buffer is not modified; the output keeps the
44
+ original workbook format.
74
45
 
75
- ## Version 1 migration
46
+ ### Filename checks
76
47
 
77
- Version 1 is ESM-only. Replace CommonJS `require("clear-excel")` calls with
78
- ECMAScript imports. Runtime exports, option types, error codes, and sanitizing
79
- behavior otherwise remain compatible with version 0.1.
48
+ The package also exports `isExcelFilename(name)` for `.xls`, `.xlsx`, and `.xlsm`,
49
+ and `isXlsxFilename(name)` for `.xlsx` only. Both return a boolean, ignore case,
50
+ and check the extension without reading the file.
80
51
 
81
- ## File API
52
+ ## Options
53
+
54
+ | Option | Default | Description |
55
+ | ------------------------ | ---------------- | ------------------------------------------------------- |
56
+ | `requireSingleWorksheet` | `false` | Reject workbooks that do not contain exactly one sheet. |
57
+ | `limits` | `DEFAULT_LIMITS` | Override individual size and entry-count limits. |
58
+ | `overwrite` | `false` | Replace an existing output; `sanitizeExcelFile` only. |
82
59
 
83
60
  ```js
84
61
  import { sanitizeExcelFile } from "clear-excel";
85
62
 
86
- await sanitizeExcelFile("report.xlsx", "report.cleaned.xlsx");
87
- ```
88
-
89
- The input and output paths must be different and use the same supported
90
- extension: `.xls`, `.xlsx`, or `.xlsm` (case-insensitive). The file API does not
91
- convert between formats. The output directory must already exist. An existing
92
- output file is not replaced unless `overwrite: true` is explicitly supplied:
93
-
94
- ```js
95
63
  await sanitizeExcelFile("report.xlsx", "report.cleaned.xlsx", {
96
64
  overwrite: true,
97
65
  requireSingleWorksheet: true,
66
+ limits: {
67
+ maxUncompressedBytes: 128 * 1024 * 1024,
68
+ },
98
69
  });
99
70
  ```
100
71
 
101
- Paths that refer to the source through symbolic links or hard links are also
102
- rejected. New outputs are created exclusively; a failed open leaves an existing
103
- file intact. Overwrites use an atomic replacement and preserve the existing
104
- output's file permissions.
105
-
106
- ## Options
72
+ ### Limits
107
73
 
108
- Both sanitizing functions accept these options:
109
-
110
- | Option | Type | Default | Description |
111
- | ------------------------ | --------- | --------- | ------------------------------------------------------- |
112
- | `requireSingleWorksheet` | `boolean` | `false` | Reject workbooks that do not contain exactly one sheet. |
113
- | `limits` | `object` | See below | Override individual ZIP/XML safety limits. |
114
-
115
- `sanitizeExcelFile` additionally accepts `overwrite`, which defaults to
116
- `false`.
117
-
118
- The exported `DEFAULT_LIMITS` object contains the defaults:
74
+ The exported `DEFAULT_LIMITS` contains these defaults. Only specified values
75
+ are overridden; each must be a positive safe integer. Sizes are in bytes.
119
76
 
120
77
  | Limit | Default |
121
78
  | -------------------------- | ---------------------------: |
@@ -127,32 +84,20 @@ The exported `DEFAULT_LIMITS` object contains the defaults:
127
84
  | `maxMetadataXmlBytes` | 16 MiB per metadata part |
128
85
  | `maxRelationshipsXmlBytes` | 8 MiB per relationships part |
129
86
 
130
- Only specified values are overridden:
131
-
132
- ```js
133
- const output = await sanitizeExcel(input, {
134
- limits: {
135
- maxUncompressedBytes: 128 * 1024 * 1024,
136
- maxWorksheetXmlBytes: 64 * 1024 * 1024,
137
- },
138
- });
139
- ```
140
-
141
- Every limit must be a positive safe integer. Raising limits can significantly
142
- increase memory usage. For `.xls`, `maxEntryCount` and
143
- `maxUncompressedBytes` apply to the CFB container; the XML-specific limits apply
144
- only to `.xlsx` and `.xlsm`.
87
+ For `.xls`, only `maxEntryCount` and `maxUncompressedBytes` apply. XML limits
88
+ apply to `.xlsx` and `.xlsm`.
145
89
 
146
90
  ## Errors
147
91
 
148
- Public functions reject with `ExcelSanitizationError`. Use its stable `code`
149
- instead of matching the English message:
92
+ Both sanitizing functions reject with `ExcelSanitizationError`. Check `code`
93
+ instead of matching the error message. `details` contains additional context
94
+ when available, and `cause` holds the original error when one exists.
150
95
 
151
96
  ```js
152
- import { ExcelSanitizationError, sanitizeExcel } from "clear-excel";
97
+ import { ExcelSanitizationError, sanitizeExcelFile } from "clear-excel";
153
98
 
154
99
  try {
155
- await sanitizeExcel(input);
100
+ await sanitizeExcelFile("report.xlsx", "report.cleaned.xlsx");
156
101
  } catch (error) {
157
102
  if (error instanceof ExcelSanitizationError) {
158
103
  console.error(error.code, error.details);
@@ -161,88 +106,26 @@ try {
161
106
  }
162
107
  ```
163
108
 
164
- | Code | Meaning |
165
- | --------------------------- | --------------------------------------------------- |
166
- | `ERR_INVALID_ARGUMENT` | An argument or option has an invalid type or value. |
167
- | `ERR_UNSUPPORTED_EXTENSION` | Paths use an unsupported or mismatched extension. |
168
- | `ERR_INVALID_XLS` | The CFB/BIFF workbook is malformed or unsupported. |
169
- | `ERR_INVALID_XLSX` | The ZIP/OOXML package is malformed or unsupported. |
170
- | `ERR_LIMIT_EXCEEDED` | A configured ZIP or XML limit was exceeded. |
171
- | `ERR_WORKSHEET_COUNT` | Exactly one worksheet was required. |
172
- | `ERR_SAME_PATH` | Input and output refer to the same file. |
173
- | `ERR_OUTPUT_EXISTS` | Output exists and `overwrite` is false. |
174
- | `ERR_FILE_READ` | The input could not be read. |
175
- | `ERR_FILE_WRITE` | The sanitized output could not be written. |
176
-
177
- The original technical error is available through `error.cause` when one
178
- exists. Limit and worksheet-count failures also include structured `details`.
179
-
180
- ## Security and memory model
181
-
182
- Before loading an OOXML archive, `clear-excel` validates the ZIP central
183
- directory, rejects ZIP64 and multi-disk archives, rejects unsafe entry paths,
184
- and checks declared entry counts and expansion sizes. Required XML parts are
185
- inflated lazily with both per-part and aggregate runtime budgets, including
186
- protection when ZIP size metadata has been forged. Before generating the output,
187
- all retained archive parts are streamed through one actual-byte
188
- `maxUncompressedBytes` budget, including binary VBA projects and other retained
189
- content.
190
-
191
- Processed OOXML XML parts support UTF-8, UTF-16LE, and UTF-16BE. Rewritten parts
192
- use UTF-8 with a matching XML declaration. XML cleanup resolves namespace URIs
193
- independently of prefix names and preserves text, CDATA, XML comments, and
194
- unrelated elements. Missing or invalid worksheet relationships are rejected
195
- before style records can be removed.
196
-
197
- For `.xls`, the library validates CFB entry and byte limits, parses the BIFF
198
- record stream without evaluating formulas, removes drawing-layer records, and
199
- rewrites worksheet offsets after records move. Workbook records are not
200
- converted through an OOXML or generic tabular representation.
201
-
202
- JSZip still loads the ZIP directory and regenerates the complete workbook in
203
- memory. Plan for memory usage above the input size, especially when increasing
204
- the defaults. The sanitizer does not evaluate formulas, execute embedded
205
- content, or execute VBA projects.
206
-
207
- ## Development
208
-
209
- Install dependencies and run the complete verification suite:
210
-
211
- ```sh
212
- pnpm install --frozen-lockfile
213
- pnpm run check
214
- ```
215
-
216
- `pnpm run check` verifies Oxfmt formatting, runs type-aware Oxlint and strict
217
- TypeScript checks, executes the tests, builds the ESM modules and declarations,
218
- inspects `pnpm pack --dry-run`, and installs a temporary tarball to verify both
219
- APIs with `.xls`, `.xlsx`, and `.xlsm` workbooks and a NodeNext TypeScript
220
- consumer.
221
-
222
- The build cleans `dist` and runs `tsc` once in NodeNext mode. It emits separate
223
- ESM modules, TypeScript declarations, and JavaScript source maps with embedded
224
- sources. Runtime dependencies are installed normally; the package does not
225
- bundle a second copy of them.
226
-
227
- Useful development commands:
228
-
229
- ```sh
230
- pnpm run format
231
- pnpm run lint
232
- pnpm run check:types
233
- pnpm test
234
- pnpm run build
235
- ```
236
-
237
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for the contribution and release
238
- process.
239
-
240
- ## Security
241
-
242
- Please report vulnerabilities privately by following
243
- [SECURITY.md](./SECURITY.md). Do not open a public issue for a suspected
244
- security vulnerability.
109
+ | Code | Meaning |
110
+ | --------------------------- | ---------------------------------------------------- |
111
+ | `ERR_INVALID_ARGUMENT` | An argument or option has an invalid type or value. |
112
+ | `ERR_UNSUPPORTED_EXTENSION` | Paths use an unsupported or mismatched extension. |
113
+ | `ERR_INVALID_XLS` | The XLS workbook is malformed or unsupported. |
114
+ | `ERR_INVALID_XLSX` | The XLSX/XLSM workbook is malformed or unsupported. |
115
+ | `ERR_LIMIT_EXCEEDED` | A configured size or entry-count limit was exceeded. |
116
+ | `ERR_WORKSHEET_COUNT` | Exactly one worksheet was required. |
117
+ | `ERR_SAME_PATH` | Input and output refer to the same file. |
118
+ | `ERR_OUTPUT_EXISTS` | Output exists and `overwrite` is false. |
119
+ | `ERR_FILE_READ` | The input could not be read. |
120
+ | `ERR_FILE_WRITE` | The output could not be written. |
121
+
122
+ ## Limitations
123
+
124
+ - `.xls` input must use Excel 97–2003 BIFF8. Encrypted `.xls` files are not supported.
125
+ - VBA macros are preserved. The library does not execute macros or evaluate formulas.
126
+ - Workbooks are processed in memory. Memory usage can exceed the input size,
127
+ especially when increasing limits.
245
128
 
246
129
  ## License
247
130
 
248
- [MIT](./LICENSE) © Vladislav Ivanov
131
+ [MIT](./LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-excel",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Safely remove drawings, comments, and embedded objects from XLS, XLSX, and XLSM workbooks.",
5
5
  "keywords": [
6
6
  "comments",