xlvane 1.2.3 → 1.3.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.
@@ -0,0 +1,131 @@
1
+ # Migrating from ExcelJS
2
+
3
+ xlvane is not affiliated with the ExcelJS project; its name is used only to identify the package.
4
+
5
+ `@xlvane/compat` offers the commonly used part of the exceljs 4.4.0 API on top of xlvane. It is installed under the name `exceljs` with an npm alias, so code that imports `exceljs` keeps its imports:
6
+
7
+ ```json
8
+ "dependencies": {
9
+ "exceljs": "npm:@xlvane/compat@^1"
10
+ }
11
+ ```
12
+
13
+ npm installs an alias `<alias>@npm:<name>` under the alias name in `node_modules` (npm/cli `docs/lib/content/using-npm/package-spec.md`, "Aliases"; docs/exceljs-compat.md), so `import ExcelJS from 'exceljs'` and `require('exceljs')` load `@xlvane/compat`. What is supported, partly supported and not supported is listed method by method in [docs/exceljs-compat.md](https://github.com/DevXord/xlvane/blob/main/docs/exceljs-compat.md) (also in `node_modules/xlvane/docs/exceljs-compat.md` after installing xlvane).
14
+
15
+ This guide uses the `xlvane migrate` command of the `xlvane` package. The `xlvane` commands, the report shown below and the TypeScript examples are checked by the tests in `tests/docs/`; the npm commands were run with npm 10.9.9 on 2026-11-03.
16
+
17
+ ## Before you start
18
+
19
+ - **Node.js.** `@xlvane/compat` is an ES module and declares `engines.node` `>=22.12`. `require('exceljs')` of an ES module works without a flag from Node.js 22.12 (docs/exceljs-compat.md); `import` works too, and so do named imports such as `import { Workbook } from 'exceljs'`.
20
+ - **Version control.** Commit `package.json` and the lockfile first, so the change can be reviewed and undone.
21
+
22
+ ## 1. See what would change
23
+
24
+ In the directory that holds the project's `package.json`:
25
+
26
+ ```sh
27
+ npx xlvane migrate
28
+ ```
29
+
30
+ `xlvane migrate` does the following, and nothing else:
31
+
32
+ 1. It reads `package.json` of the project directory (the current directory, or the directory given as the first argument). A `package.json` that is a symbolic link is refused.
33
+ 2. It looks for an `"exceljs"` entry in `dependencies`, `devDependencies`, `optionalDependencies` and `peerDependencies`, and shows how each would change to `"npm:@xlvane/compat@^1"`. Other sections, such as `overrides`, are not changed.
34
+ 3. It prints the Node.js requirement of `require('exceljs')` next to the project's own `engines.node`.
35
+ 4. It scans the source files of the project (`.js`, `.mjs`, `.cjs`, `.jsx`, `.ts`, `.mts`, `.cts`, `.tsx`, up to 2 MiB each and 10 000 files) for exceljs API that `@xlvane/compat` does not support: `ModelContainer` and deep imports of `exceljs/lib/...`. Only files that contain the text `exceljs` are checked; `node_modules`, folders whose names start with a dot, and symbolic links are skipped. The matching is textual, so a finding is a place to look at, not proof.
36
+ 5. It writes nothing unless `--force` is given.
37
+
38
+ For a project whose `package.json` has `"exceljs": "^4.4.0"` in `dependencies`, with a file `src/report.js` that imports `exceljs` and a file `src/legacy.cjs` that requires `exceljs/lib/xlsx/xform/base-xform`, the report is:
39
+
40
+ ```text
41
+ Change in package.json:
42
+ dependencies: - "exceljs": "^4.4.0"
43
+ + "exceljs": "npm:@xlvane/compat@^1"
44
+ Node.js: require('exceljs') of @xlvane/compat needs Node.js 22.12 or later (package.json engines.node: not set).
45
+
46
+ Scanned 2 source files for exceljs API that @xlvane/compat does not fully support:
47
+ not supported src/legacy.cjs:1:27 deep import (exceljs/lib/...)
48
+ Details: docs/exceljs-compat.md. Unsupported calls throw XLV_E_NOT_SUPPORTED at run time.
49
+
50
+ Nothing was written. Run "xlvane migrate --force" to change package.json.
51
+ ```
52
+
53
+ The same report as JSON (schema in [docs/cli-json.md](https://github.com/DevXord/xlvane/blob/main/docs/cli-json.md)):
54
+
55
+ ```sh
56
+ npx xlvane migrate --json
57
+ ```
58
+
59
+ ## 2. Change package.json and install
60
+
61
+ ```sh
62
+ npx xlvane migrate --force --dry-run # show the change without writing it
63
+ npx xlvane migrate --force # change package.json
64
+ npm install # install @xlvane/compat under the name exceljs
65
+ ```
66
+
67
+ `--force` replaces only the value of each `"exceljs"` entry; the rest of `package.json` keeps its formatting and key order. Instead of `xlvane migrate`, the alias can also be installed directly:
68
+
69
+ ```sh
70
+ npm install exceljs@npm:@xlvane/compat@^1
71
+ ```
72
+
73
+ npm then saves the version it installed as the range (with npm 10.9.9 and `@xlvane/compat` 1.2.2: `"exceljs": "npm:@xlvane/compat@^1.2.2"`).
74
+
75
+ The code stays as it was. For example, this exceljs code runs unchanged on `@xlvane/compat`:
76
+
77
+ ```ts
78
+ import ExcelJS from 'exceljs';
79
+
80
+ const workbook = new ExcelJS.Workbook();
81
+ const sheet = workbook.addWorksheet('Sales');
82
+ sheet.columns = [
83
+ { header: 'Region', key: 'region', width: 15 },
84
+ { header: 'Revenue', key: 'revenue', width: 12 },
85
+ ];
86
+ sheet.addRow({ region: 'North', revenue: 1200 });
87
+ await workbook.xlsx.writeFile('sales.xlsx');
88
+
89
+ const check = new ExcelJS.Workbook();
90
+ await check.xlsx.readFile('sales.xlsx');
91
+ console.log(check.getWorksheet('Sales')?.getCell('B2').value); // 1200
92
+ ```
93
+
94
+ In CommonJS, `const ExcelJS = require('exceljs');` gives the same object.
95
+
96
+ ## 3. Check the result
97
+
98
+ - **Run the project's tests.** Unsupported API throws an `XlvError` whose `code` is `XLV_E_NOT_SUPPORTED` and whose message names the method; nothing is dropped silently.
99
+ - **Look at each finding of `xlvane migrate`.** Deep imports of `exceljs/lib/...` do not resolve (`exceljs/dist/es5` and the `exceljs/dist/exceljs*.js` files do); `ModelContainer` throws `XLV_E_NOT_SUPPORTED` when it is constructed.
100
+ - **Read the differences.** [docs/exceljs-compat.md](https://github.com/DevXord/xlvane/blob/main/docs/exceljs-compat.md) lists every method with its status and the exceljs source of each behaviour, and ends with the differences found in reviews and cross-checks. The ones most likely to matter are summarised in the [@xlvane/compat README](https://github.com/DevXord/xlvane/blob/main/packages/compat/README.md#differences-from-exceljs): CSV output escapes text that starts like a formula (`formulaInjection: "off"` writes it unchanged, as exceljs does), a sheet id outside 1 to 65534 is written as the lowest unused id, only the first view of a worksheet is written, the module object is frozen, the streaming writer compresses in JavaScript, and input files are checked against ZIP and XML limits.
101
+ - **TypeScript.** The type names of exceljs's `index.d.ts` are exported and work with `moduleResolution` `bundler` and `nodenext` and with `module: commonjs`. Under `module: node16`, TypeScript refuses `import ExcelJS = require('exceljs')` of an ES module (TS1471); use `nodenext` or `commonjs`.
102
+ - **Browsers and Workers.** The methods that read or write files (`xlsx.readFile`, `xlsx.writeFile`, `csv.readFile`, `csv.writeFile`, the `filename` forms of the streaming classes and of `addImage`) work in Node.js, Bun and Deno; in browsers and Workers they throw `XLV_E_NOT_SUPPORTED`.
103
+
104
+ To handle an unsupported call in code:
105
+
106
+ ```ts
107
+ import ExcelJS from 'exceljs';
108
+
109
+ const workbook = new ExcelJS.Workbook();
110
+ try {
111
+ await workbook.xlsx.readFile('report.xlsx');
112
+ } catch (error) {
113
+ const code = (error as { code?: unknown }).code;
114
+ if (code === 'XLV_E_NOT_SUPPORTED') console.error('Not supported by @xlvane/compat:', (error as Error).message);
115
+ else throw error;
116
+ }
117
+ ```
118
+
119
+ ## 4. Roll back
120
+
121
+ Install exceljs again under its own name, with the range the project used before (here `^4.4.0`):
122
+
123
+ ```sh
124
+ npm install exceljs@^4.4.0
125
+ ```
126
+
127
+ npm replaces the alias in `package.json` and `node_modules`. Restoring `package.json` and the lockfile from version control and running `npm install` has the same effect.
128
+
129
+ ## Reporting a problem
130
+
131
+ When exceljs code behaves differently on `@xlvane/compat` and the difference is not listed in docs/exceljs-compat.md, please open an issue at https://github.com/DevXord/xlvane/issues with a small script that shows it.
@@ -0,0 +1,88 @@
1
+ # How to fix the CVEs in the `xlsx` package from npm
2
+
3
+ xlvane is not affiliated with SheetJS or with the ExcelJS project. Their names are used only to identify the packages this page is about; the facts below are quoted from the cited advisories and registry data, and the fixes SheetJS publishes are listed first.
4
+
5
+ The `xlsx` package on npm is the SheetJS Community Edition. Its latest version on npm is 0.18.5, published on 2022-03-24, and two published advisories cover that version. The fixed versions are distributed by SheetJS outside npm. This page lists the facts with their sources and two ways to deal with them: the fixed SheetJS version, or moving to xlvane. The sources were read on 2026-11-03.
6
+
7
+ ## The advisories
8
+
9
+ | CVE | GitHub advisory | What | Affected | Fixed in |
10
+ |---|---|---|---|---|
11
+ | CVE-2023-30533 | [GHSA-4r6h-8v6p-xvw6](https://github.com/advisories/GHSA-4r6h-8v6p-xvw6) | Prototype pollution when reading specially crafted files (CWE-1321) | SheetJS CE through 0.19.2, including every version of `xlsx` on npm | 0.19.3 |
12
+ | CVE-2024-22363 | [GHSA-5pgg-2g8v-p4x9](https://github.com/advisories/GHSA-5pgg-2g8v-p4x9) | Regular expression denial of service, ReDoS (CWE-1333) | SheetJS CE before 0.20.2, including every version of `xlsx` on npm | 0.20.2 |
13
+
14
+ - GitHub rates both advisories "high" (CVSS 3.1 base scores 7.8 for CVE-2023-30533 and 7.5 for CVE-2024-22363, as listed by the npm registry's advisory data).
15
+ - GHSA-4r6h-8v6p-xvw6 says: "Workflows that do not read arbitrary files (for example, exporting data to spreadsheet files) are unaffected."
16
+ - Both GitHub advisories say: "A non-vulnerable version cannot be found via npm", and that the fixed version (0.19.3, and 0.20.2) "can be downloaded via https://cdn.sheetjs.com/".
17
+ - The CVE records (published 2023-04-24 and 2024-04-05) give the same affected and fixed versions and link to SheetJS's own advisories, `https://cdn.sheetjs.com/advisories/CVE-2023-30533` and `https://cdn.sheetjs.com/advisories/CVE-2024-22363`.
18
+
19
+ ### Sources
20
+
21
+ | Source | Version | What it gives |
22
+ |---|---|---|
23
+ | https://registry.npmjs.org/xlsx | registry document, 2026-11-03 | `dist-tags.latest` `0.18.5`; `time["0.18.5"]` `2022-03-24T14:23:09.623Z` |
24
+ | `POST https://registry.npmjs.org/-/npm/v1/security/advisories/bulk` with `{"xlsx":["0.18.5"]}` | answer of 2026-11-03 | both advisories for 0.18.5: GHSA-4r6h-8v6p-xvw6, `vulnerable_versions` `<0.19.3`, CVSS 7.8; GHSA-5pgg-2g8v-p4x9, `<0.20.2`, CVSS 7.5; severity "high" |
25
+ | GitHub Advisory Database, `advisories/github-reviewed/2023/04/GHSA-4r6h-8v6p-xvw6/GHSA-4r6h-8v6p-xvw6.json` | github/advisory-database commit `887dcb68f13a7d9be8bf3d604c2e32fc3d6960e8` | alias CVE-2023-30533, details, `last_known_affected_version_range` `< 0.19.3`, CWE-1321 |
26
+ | GitHub Advisory Database, `advisories/github-reviewed/2024/04/GHSA-5pgg-2g8v-p4x9/GHSA-5pgg-2g8v-p4x9.json` | same commit | alias CVE-2024-22363, details, `< 0.20.2`, CWE-1333 |
27
+ | CVE records `cves/2023/30xxx/CVE-2023-30533.json` and `cves/2024/22xxx/CVE-2024-22363.json` | CVEProject/cvelistV5 commit `cc01a172ea2819376e943af6fb3d73336eacea6b` | descriptions ("SheetJS Community Edition before 0.19.3 allows Prototype Pollution via a crafted file"; for CVE-2024-22363, SheetJS Community Edition before 0.20.2 and ReDoS), publication dates, references |
28
+ | `README.md` of github.com/SheetJS/sheetjs, branch `github` | commit `3f44ddd99c704d7ca35ea76fef7b8af2d2d435cb` | the source repository moved to https://git.sheetjs.com/sheetjs/sheetjs; "Scripts and NodeJS modules are available at https://cdn.sheetjs.com" |
29
+
30
+ The advisory files and CVE records were read through raw.githubusercontent.com at the commits given. The GitHub advisory web pages, the SheetJS sites (sheetjs.com, docs.sheetjs.com, cdn.sheetjs.com, git.sheetjs.com) and other advisory sites could not be reached from the environment where this page was written, so they are linked but not quoted.
31
+
32
+ ## Route 1: the fixed SheetJS Community Edition
33
+
34
+ The fixed versions of the Community Edition (0.19.3 and later) are distributed by SheetJS from its own site, not from npm: the advisories name https://cdn.sheetjs.com/ for both fixes. The SheetJS README points to its documentation at https://docs.sheetjs.com and says "Scripts and NodeJS modules are available at https://cdn.sheetjs.com". Install the fixed version as the SheetJS documentation describes; this page does not copy an install command, because that documentation could not be read when the page was written. This route keeps the SheetJS API; check the SheetJS changelog (https://git.sheetjs.com/sheetjs/sheetjs/src/branch/master/CHANGELOG.md, linked from the CVE-2023-30533 record) for changes between 0.18.5 and the version you install.
35
+
36
+ ## Route 2: move to xlvane
37
+
38
+ xlvane is a different library with a different API; it is not a drop-in replacement for `xlsx`. A package with a SheetJS-compatible API, `@xlvane/xlsx-compat`, is planned as a later phase ([ROADMAP.md](https://github.com/DevXord/xlvane/blob/main/ROADMAP.md)); it does not exist yet.
39
+
40
+ Facts about the package (npm registry, 2026-11-03; [docs/facts/comparison.md](https://github.com/DevXord/xlvane/blob/main/docs/facts/comparison.md)):
41
+
42
+ - `xlvane` is installed from npm (`npm install xlvane`), under the MIT license, with one runtime dependency, `fflate`.
43
+ - Versions from 1.0.1 are published from GitHub Actions with npm provenance ([SECURITY.md](https://github.com/DevXord/xlvane/blob/main/SECURITY.md#supported-versions)).
44
+ - It reads XLSX, XLSM, XLTX and XLTM, writes XLSX, and converts to and from CSV and JSON. It does not read legacy `.xls`, XLSB, ODS, Numbers or the other formats SheetJS supports, does not open encrypted workbooks, and does not calculate formulas.
45
+ - How it treats input files from untrusted sources (ZIP and XML limits, prototype pollution, amplification by small files, CSV formula injection) is described in [SECURITY.md](https://github.com/DevXord/xlvane/blob/main/SECURITY.md#what-the-library-defends-against).
46
+
47
+ ### Equivalent calls
48
+
49
+ The SheetJS names are those of the `xlsx` 0.18.5 README ("Interface"). xlvane's functions take the file's bytes (`Uint8Array` or `ArrayBuffer`) or a workbook already read; `xlvane/node` adds file helpers for Node.js.
50
+
51
+ | SheetJS (`xlsx` 0.18.5) | xlvane |
52
+ |---|---|
53
+ | `XLSX.read(data)` | `readWorkbook(bytes)` |
54
+ | `XLSX.readFile(path)` | `await readWorkbookFile(path)` from `xlvane/node` |
55
+ | `workbook.SheetNames` | `workbook.sheets.map((sheet) => sheet.name)` |
56
+ | `XLSX.utils.sheet_to_json(worksheet)` | `readTable(bytes, { sheet }).rows`, or `toJSON(bytes, { sheet }).rows` for JSON-ready values |
57
+ | `XLSX.utils.sheet_to_csv(worksheet)` | `toCSV(bytes, { sheet })` |
58
+ | `XLSX.utils.json_to_sheet(rows)`, `book_new`, `book_append_sheet`, `XLSX.write(...)` | `writeTable(rows, { sheet })` or `fromJSON(rows)`, which return the `.xlsx` file as a `Uint8Array` |
59
+ | `XLSX.writeFile(workbook, path)` | `writeFile(path, writeTable(rows))` with `node:fs/promises`, or `writeWorkbookFile(workbook, path)` from `xlvane/node` for a workbook built with `createWorkbook` |
60
+
61
+ ```ts
62
+ import { readTable, toCSV, toJSON, writeTable } from 'xlvane';
63
+ import { readWorkbookFile } from 'xlvane/node';
64
+ import { writeFile } from 'node:fs/promises';
65
+
66
+ const workbook = await readWorkbookFile('orders.xlsx');
67
+ console.log(workbook.sheets.map((sheet) => sheet.name)); // like workbook.SheetNames
68
+
69
+ // Rows as objects keyed by the header row (detected like inspect(); `header: 1` takes row 1).
70
+ const { rows } = readTable(workbook, { sheet: 'Orders' });
71
+ // The same rows with dates as ISO text, ready for JSON.stringify.
72
+ const json = toJSON(workbook, { sheet: 'Orders' }).rows;
73
+ // CSV; text that starts like a formula gets a leading ' (formulaInjection: 'off' turns this off).
74
+ const csv = toCSV(workbook, { sheet: 'Orders' });
75
+
76
+ // A new .xlsx file from objects: bold header, frozen first row, filter, fitted widths.
77
+ const bytes = writeTable(rows, { sheet: 'Orders' });
78
+ await writeFile('orders-copy.xlsx', bytes);
79
+ console.log(json.length, csv.length);
80
+ ```
81
+
82
+ Differences to expect:
83
+
84
+ - `readTable` finds the header row the way `inspect()` does (`header: 'auto'`), or takes `header: 3` (a 1-based row) or `header: false` (keys are the column letters). It returns `Date` objects for date cells; `toJSON` and `toCSV` give ISO 8601 text.
85
+ - Unknown sheet names and damaged files throw an `XlvError` with a stable `XLV_E_*` code, a location and a hint ([docs/errors.md](https://github.com/DevXord/xlvane/blob/main/docs/errors.md)).
86
+ - Read limits (cells, decompressed bytes, XML size) apply by default and can be raised per call: `readWorkbook(bytes, { limits: { maxCells: 50_000_000 } })`. The defaults are in the [package README](https://github.com/DevXord/xlvane/blob/main/packages/xlvane/README.md#untrusted-input-and-limits).
87
+
88
+ The full API is described in the [package README](https://github.com/DevXord/xlvane/blob/main/packages/xlvane/README.md) (also in `node_modules/xlvane/README.md` after installing).