@reportwright/cli 0.13.1 → 0.13.2-rc.2
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/CHANGELOG.md +51 -0
- package/README.md +157 -4
- package/dist/pdfstreamworker.js +4 -0
- package/dist/pw.mjs +1131 -537
- package/dist/pw.mjs.map +3 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
All `@reportwright/*` packages (formerly `@pagewrightjs/*`) share one version. The versioning policy is in [CONTRIBUTING.md](CONTRIBUTING.md#versioning-semver).
|
|
4
4
|
|
|
5
|
+
## 0.13.2-rc.2 — 2026-10-09 (release candidate)
|
|
6
|
+
|
|
7
|
+
### Fixed (from the rc.1 release gate)
|
|
8
|
+
- **E11 Viewer accessibility:** the scrolling page area (`div.vpages`) is keyboard-focusable (`tabindex="0"`), a named `region`, with a visible inset focus ring; the arrow keys scroll it (axe `scrollable-region-focusable`).
|
|
9
|
+
- **E12 Designer arrow keys on pages with margins:** Arrow and Shift+Arrow move the selection by the whole step (1/10 pt, or 1/10 grid steps with Snap to grid). The step used to be clamped to the band's leftover width, so an item as wide as an A4 body with 36 pt margins (523.28 pt) moved 0.28 pt and then not at all. A keyboard nudge still stops at the band's start; overflow past its end shows in the Issues panel. Dragging still keeps items inside the band.
|
|
10
|
+
- **E10 webpack and Next.js builds:** `@reportwright/viewer` (`dist/`, `dist/peer/`) and `@reportwright/cli` ship `pdfstreamworker.js` next to the bundles that name it with `new URL('./pdfstreamworker.js', import.meta.url)`, so bundlers resolve it. The parallel PDF paint worker itself is `@reportwright/engine`'s (Node only); the stand-ins answer that `exportPdfStream` with `parallel` needs the engine.
|
|
11
|
+
- **E13 missing HarfBuzz subset WASM:** when `harfbuzz-subset.wasm` cannot be loaded (fonts then embed in full, PDFs many times larger), `exportPdf` and `exportPdfStream` warn once on the console and add a warning to the result (the model's `warnings`, the stream result's `warnings`), naming the expected path (`@reportwright/fonts/public/harfbuzz-subset.wasm`) and the fix: install `@reportwright/fonts`, or pass `subset: createSubsetter(() => wasmBytes)`.
|
|
12
|
+
- **E09 importer:**
|
|
13
|
+
- files are read in their own encoding: a UTF-16 LE/BE or UTF-8 byte-order mark, else the XML declaration's `encoding` (ISO-8859-1, Latin-1, windows-1252, …), else UTF-8. `Straße` and `Grüße` survive. Applies to `pw import`, `pw import <folder>` and `POST /api/reports/import`.
|
|
14
|
+
- a compiled `.jasper` file gets "This is a compiled JasperReports file; import the .jrxml source instead."
|
|
15
|
+
- `pw import` prints each error once (it printed it twice, the second time cut short).
|
|
16
|
+
- **E07 SQL connection pool:** a PostgreSQL or MySQL query that cannot get a pooled connection within `PW_DB_ACQUIRE_MS` (default 5000) fails with 503 and `Retry-After` instead of a 500; a connection that frees later goes back to the pool. A streaming query whose reader aborts frees its connection at once (the backend is terminated and the connection discarded) instead of holding it until the deadline. PostgreSQL queries run under `statement_timeout` from their first statement.
|
|
17
|
+
|
|
18
|
+
## 0.13.2-rc.1 — 2026-10-09 (release candidate)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **The rename to ReportWright is finished; every old Pagewright name keeps working until 1.0.** New names, with the old one kept as a deprecated alias:
|
|
22
|
+
- report schema: `reportwright/report@1` is now what new and saved reports carry; `pagewright/report@1` is read as the same format (a server before 0.9 cannot open a report saved by 0.13.2).
|
|
23
|
+
- HTTP headers: `x-reportwright-pages`, `-ms`, `-warnings`, `-snapshot`, `-pending`, `-signature` (webhooks and the audit SIEM webhook) and `-idempotency-key` (mail) are sent together with the old `x-pagewright-*` header; the proxy secret is read from `x-reportwright-proxy-secret`, else `x-pagewright-proxy-secret`.
|
|
24
|
+
- Prometheus metrics: `/api/v1/metrics` emits every family as `reportwright_*` and again as `pagewright_*` (the old ones go in 1.0: move dashboards and alerts). `scripts/uptime-check.mjs` reads either.
|
|
25
|
+
- one console warning per page for `definePagewrightElements`, the `<pagewright-viewer>` / `<pagewright-designer>` tags, the Svelte `pagewrightViewer` / `pagewrightDesigner` actions, `window.Pagewright` and `/embed/pagewright-viewer.js` (and `-viewer.full.js`). The React and Vue `PagewrightViewer` / `PagewrightDesigner` stay the same components, without a warning; all are typed `@deprecated`.
|
|
26
|
+
- the live demo moved to https://mrarun005.github.io/reportwright-demo/ (the site build's default base is `/reportwright-demo/`).
|
|
27
|
+
- kept as they are, since changing them would break stored data: the `.pw.json` extension, the designer clipboard format `pagewright/items@1`, and the salts of the TOTP secret key and the audit checkpoint chain.
|
|
28
|
+
- **The render worker is minified.** `engine.worker.js` (and `engine.worker.bwip.js`) in `@reportwright/viewer` and the embed builds are minified, still one file with no chunk imports, with a linked source map (`engine.worker.js.map`) beside it so worker stack traces stay readable. `engine.worker.js` 2,195,290 → 1,218,659 bytes (608 → 503 KB gzipped); `engine.worker.bwip.js` 1,651,602 → 973,261 bytes (315 → 267 KB gzipped). The size budget in tests/engine/b10-bundle-size.test.js is now 504 KB gzipped (was 600).
|
|
29
|
+
- **Publishing verifies before `latest` moves.** The publish workflow publishes to the `next` dist-tag, installs all nine packages from the registry and smoke-tests them (imports, PDF/XLSX/DOCX export, `qpdf --check`, `pw render`, the viewer's files, the wrappers' peer), and only then moves `latest`.
|
|
30
|
+
|
|
31
|
+
### Performance
|
|
32
|
+
- **Trade-off made by 0.13.1: less memory, about 10–14% slower.** The 0.13.1 fixes for grouped sorts (N44: sort runs spill to disk in smaller runs, about 8 MB) and for streamed tagged PDFs (N44: tagged structure flushed per page) cost time for the memory they save: about 10–14% slower on the tester's 2 vCPU machine (not measured here). Memory: a 200,000-row grouped ledger peaks at 232 MB instead of 280 MB, and the same with 50 runs (1,000,000 rows' run count) 240 MB instead of 296 MB; a tagged streamed PDF at 50k/100k/200k rows holds 6.7/7.3/9.3 MB off-heap instead of 16.8/29.1/36.6 MB. `spillSorter({ runMB, mergeMB })` sets the sort's run size if speed matters more than memory.
|
|
33
|
+
### Added
|
|
34
|
+
- **`pw import <folder>`: bulk import.** Every `.rdl`, `.rdlc`, `.jrxml`, `.rptdesign` and `.rdlx-json` report in a folder (`--recursive` for subfolders) is imported into `-o <outDir>`, which mirrors the folder.
|
|
35
|
+
- One bad file never stops the batch. Exit 0 means all were imported, 2 some failed, 1 none.
|
|
36
|
+
- Subreports, SSRS shared data sources (`.rds`), JasperReports style templates (`.jrtx`) and images are resolved across the batch. Images are copied once per content. Unresolved references are listed per file.
|
|
37
|
+
- `import-report.json` and a standalone, escaped `import-report.html` give for each file the mapped, approximated and dropped counts, each item's reason, and every expression that was not translated with its line and column.
|
|
38
|
+
- `.pw-import.json` holds the hash of each written file, and a re-run skips an output the user edited unless `--force`.
|
|
39
|
+
- `--verify` renders each report with its embedded or sample data and compares it with the output it replaced.
|
|
40
|
+
- Paths from the folder are untrusted. Links that point outside it are refused, outputs stay in `outDir`, and `--max-files` and `--max-bytes` cap the input.
|
|
41
|
+
- The importers now return structured `items` (each item's notes, untranslated expressions and source position) and take a `resolve` option for shared data sources and style templates.
|
|
42
|
+
- Docs: the CLI README, "Bulk import". Test: tests/engine/c132-import-batch.test.js.
|
|
43
|
+
- **`pw --version` / `pw -v`** prints the CLI version (from its package.json) and the version of the engine it carries.
|
|
44
|
+
- **`showWarnings`** (viewer option, default `false`): shows the render's warnings under the pages; the designer's Preview always shows them. Documented in the viewer README and typed in `ViewerOptions`.
|
|
45
|
+
- **ⓘ help tooltips in the designer.** Long help paragraphs (the Outline, Layers and Parts panels, field hints over 90 characters) sit behind an ⓘ button that opens on hover, keyboard focus or click and closes with Esc; the button is described by the text (`aria-describedby`).
|
|
46
|
+
### Fixed
|
|
47
|
+
- **An unchecked check box has no tick on the designer canvas.** The canvas drew ✓ in every check box; it now follows the value as the renderer does (`false`, `=False`, a missing value: empty), and dims the tick of a value only the data decides.
|
|
48
|
+
- **Selecting an item no longer moves the canvas.** The canvas toolbar grew a second row (24 px) when the align buttons of a selection appeared; it now has one fixed height (it scrolls sideways when narrow) and its hint moved to the status bar.
|
|
49
|
+
- **Keyboard nudge steps.** Arrow moves the selection 1 pt, or one grid step with Snap to grid on (a cell in cell mode); Shift+Arrow moves ten of them (it was 4 grid steps); positions stay rounded to 2 decimals.
|
|
50
|
+
- **Render warnings in the viewer read as words.** The count says "8 warnings" or "1 warning", not "warning(s)".
|
|
51
|
+
- **The Data panel lists a data set's fields when it declares none.** It said "No fields" next to 300 rows; it now detects them from inline JSON or the first rows of fetched data with the engine's own detection (`detectFields`, the one streaming uses) and marks them as detected.
|
|
52
|
+
- **No cut-off text in the Inspector and the Outline.** The Regional "Division by zero" choice gets the full width ("Infinity (as SSRS)" was cut); a long name in the Outline wraps inside the panel, with the full name as its tooltip, and the item type and buttons move under it together.
|
|
53
|
+
- **The parameter dialog's help matches the viewer.** The live-parameters option no longer says that turning it off adds a View report button (the button is always there), and the panel-columns help says the grid applies on a wide screen.
|
|
54
|
+
- **Export options icon.** The sun-like gear is a sliders icon; the button keeps its name, Export options.
|
|
55
|
+
|
|
5
56
|
## 0.13.1 — 2026-10-09
|
|
6
57
|
|
|
7
58
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,20 +1,173 @@
|
|
|
1
1
|
# @reportwright/cli
|
|
2
2
|
|
|
3
|
+
`pw`: render, snapshot-test, diff and import ReportWright reports from the command line, with no server.
|
|
4
|
+
|
|
3
5
|
[](https://www.npmjs.com/package/@reportwright/cli) [](https://github.com/MrArun005/reportwright/blob/main/LICENSE) [](https://socket.dev/npm/package/@reportwright/cli)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**Live demo:** [mrarun005.github.io/reportwright-demo](https://mrarun005.github.io/reportwright-demo). [Switch to ReportWright](https://mrarun005.github.io/reportwright-demo/switch.html) runs the same importers as `pw import` in your browser: drop a `.jrxml`, `.rdl` or `.rptdesign` and see what carries over.
|
|
8
|
+
|
|
9
|
+
The CLI carries [`@reportwright/engine`](https://github.com/MrArun005/reportwright/tree/main/packages/engine); fonts come from [`@reportwright/fonts`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i -D @reportwright/cli @reportwright/fonts # then: npx pw …
|
|
15
|
+
# or one-off, without installing:
|
|
16
|
+
npx -p @reportwright/cli pw --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick start (30 seconds)
|
|
20
|
+
|
|
21
|
+
`orders.pw.json` is the report from the [engine's examples](https://github.com/MrArun005/reportwright/tree/main/packages/engine#examples) (a table of customers and amounts with a
|
|
22
|
+
total); `orders.json` is its data:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{ "rows": [{ "customer": "Asha Rao", "amount": 1200.5 }, { "customer": "Ben Ode", "amount": 80 }] }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx pw render orders.pw.json -d orders=orders.json -f pdf -o orders.pdf
|
|
30
|
+
# pw: wrote orders.pdf (1 pages, streamed)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`-d orders=orders.json` replaces the data source named `orders` with the file's JSON.
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
Each was run against this version.
|
|
38
|
+
|
|
39
|
+
**Render to every format.** `-f` is `pdf`, `xlsx`, `docx`, `pptx`, `html`, `csv`, `json` or `txt`; `-o -` writes to stdout.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx pw render orders.pw.json -d orders=orders.json -f xlsx -o orders.xlsx
|
|
43
|
+
npx pw render orders.pw.json -d orders=orders.json -f csv -o orders.csv # Customer,Amount / Asha Rao,1200.5 / Ben Ode,80
|
|
44
|
+
npx pw render statement.pw.json -p accountId=LN-1 -f pdf -o statement.pdf # -p sets a report parameter
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Archival, accessible or protected PDF.**
|
|
6
48
|
|
|
7
49
|
```bash
|
|
8
|
-
npx
|
|
9
|
-
npx
|
|
10
|
-
npx -p @reportwright/cli pw import invoice.jrxml # JasperReports, SSRS (.rdl) or BIRT → invoice.pw.json
|
|
50
|
+
npx pw render orders.pw.json -d orders=orders.json --pdfa --ua -o orders.pdf # PDF/A-2a + PDF/UA-1
|
|
51
|
+
npx pw render orders.pw.json -d orders=orders.json --password s3cret --deny copy -o locked.pdf
|
|
11
52
|
```
|
|
12
53
|
|
|
54
|
+
**Bulk import a folder of legacy reports.** One bad file does not stop the batch; the exit code says how it went.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx pw import legacy -o imported --recursive
|
|
58
|
+
# pw: finance/Kitchen Sink.rdl → finance/kitchen-sink.pw.json: written, 2 unresolved
|
|
59
|
+
# pw: truncated.rdl: FAILED: The file is not readable XML: Text outside the root element (character 27503)
|
|
60
|
+
# pw: 1 of 2 reports imported, 1 failed, 2 unresolved references; report: imported/import-report.html
|
|
61
|
+
echo $? # 2: some failed
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Snapshot-test reports as code.** With `reports/__tests__/orders.test.json`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "report": "../orders.pw.json", "cases": [{ "name": "two-orders", "data": { "orders": "orders.json" } }] }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx pw test reports --update # 1 passed, 0 failed, 1 snapshot written
|
|
72
|
+
npx pw test reports # 1 passed, 0 failed (exit 1 when a case changes)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Diff two versions of a report** (the words, page by page; exit 1 when they differ):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx pw diff orders.pw.json orders-v2.pw.json -d orders=orders.json
|
|
79
|
+
# orders-v2.pw.json: page 1 changed
|
|
80
|
+
# - Orders
|
|
81
|
+
# + All orders
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Commands and options
|
|
85
|
+
|
|
86
|
+
| Command | Options |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `pw render <report.pw.json>` | `-p name=value` (repeat), `-d source=data.json` (repeat), `-f` format (default `pdf`), `-o file\|-`, `--base URL` (where relative data URLs go), `--allow-internal`, `--pdfa`, `--ua`, `--values` (Excel totals as values), `--static` (HTML without its Tables view), `--layout` (CSV of the printed layout), `--password`, `--owner-password`, `--deny print\|modify\|copy\|annotate\|fillForms\|accessibility\|assemble\|printHighQuality` |
|
|
89
|
+
| `pw import <file>` | `-o out.pw.json` |
|
|
90
|
+
| `pw import <folder>` | `-o outDir`, `--recursive`, `--force`, `--verify`, `--report path`, `--max-files N` (2000), `--max-bytes N` (16 MB) |
|
|
91
|
+
| `pw test [folder]` | `--update`, `--layout` |
|
|
92
|
+
| `pw diff <old> <new>` | `-p`, `-d`, `--base` |
|
|
93
|
+
| `pw --version` | prints the CLI and engine versions |
|
|
94
|
+
|
|
95
|
+
Exit codes: 0 ok; 1 a test failed or the pages differ; 2 bad usage (`pw import <folder>`: 2 some failed, 1 none imported).
|
|
96
|
+
|
|
97
|
+
## Supported formats
|
|
98
|
+
|
|
99
|
+
| Direction | Formats |
|
|
100
|
+
|---|---|
|
|
101
|
+
| Output (`-f`) | `pdf` (also `--pdfa`, `--ua`, encrypted), `xlsx`, `docx`, `pptx`, `html`, `csv`, `json`, `txt` |
|
|
102
|
+
| Import | SSRS `.rdl` / `.rdlc` (+ shared data sources `.rds`), JasperReports `.jrxml` (+ style templates `.jrtx`), BIRT `.rptdesign`, ActiveReports `.rdlx-json`, referenced images |
|
|
103
|
+
|
|
104
|
+
## Requirements and limits
|
|
105
|
+
|
|
106
|
+
- Node 20.9 or later. Install `@reportwright/fonts` next to the CLI.
|
|
107
|
+
- `pw render -f pdf -o file` streams a flowing table, so memory stays flat on large reports (see the engine's
|
|
108
|
+
[streaming notes](https://github.com/MrArun005/reportwright/tree/main/packages/engine#streaming-pdf-for-large-reports)); other formats render the whole model in memory.
|
|
109
|
+
- Bulk import reads at most `--max-files` files (2000) of at most `--max-bytes` each (16 MB). BIRT libraries
|
|
110
|
+
(`.rptlibrary`) are listed but not read.
|
|
111
|
+
|
|
112
|
+
## Related packages
|
|
113
|
+
|
|
114
|
+
[`@reportwright/engine`](https://github.com/MrArun005/reportwright/tree/main/packages/engine) (the same rendering from code), [`@reportwright/fonts`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts),
|
|
115
|
+
[`@reportwright/fonts-cjk`](https://github.com/MrArun005/reportwright/tree/main/packages/fonts-cjk), [`@reportwright/viewer`](https://github.com/MrArun005/reportwright/tree/main/packages/viewer) (view and design in the browser).
|
|
116
|
+
|
|
117
|
+
## Notes on `pw render`
|
|
118
|
+
|
|
13
119
|
`pw render -f pdf -o file` streams a flowing table into the file as it is laid out (`exportPdfStream`; the message says
|
|
14
120
|
`streamed`), so a large report's memory stays flat; other reports, `--password` and `-o -` render the whole model first.
|
|
15
121
|
It writes to a temporary file beside the target and renames it when the export succeeded: a failed run leaves no
|
|
16
122
|
damaged PDF, and an older file at the path stays as it was.
|
|
17
123
|
|
|
124
|
+
## Bulk import
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pw import legacy-reports -o imported --recursive [--force] [--verify] [--report path] [--max-files 2000] [--max-bytes 16777216]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`pw import <folder>` imports every SSRS (`.rdl`, `.rdlc`), JasperReports (`.jrxml`), BIRT (`.rptdesign`) and
|
|
131
|
+
ActiveReports (`.rdlx-json`) report in the folder (and its subfolders with `--recursive`) into `<outDir>`, which mirrors
|
|
132
|
+
the folder. Each report becomes `<its folder>/<report id>.pw.json` (the id is the file name in lower case with dashes,
|
|
133
|
+
e.g. `Sales Report.rdl` → `sales-report.pw.json`), because `pw render` and the server find subreports by that id.
|
|
134
|
+
|
|
135
|
+
- **One bad file never stops the batch.** Its error goes into the report and the rest go on.
|
|
136
|
+
Exit code: **0** every report was imported, **2** some failed, **1** none was imported (or the folder has none).
|
|
137
|
+
- **References are resolved across the batch.** These are found among the folder's files: by their path relative to
|
|
138
|
+
the report, else by their file name, nearest first.
|
|
139
|
+
- subreports by their id;
|
|
140
|
+
- SSRS shared data sources (`.rds`, named by a `DataSourceReference`): the provider comes from the `.rds`, but the
|
|
141
|
+
connection string does not (set `PW_DB_<NAME>` on the server, as for any SQL source);
|
|
142
|
+
- JasperReports style templates (`.jrtx`, nested ones too): the report's own style of the same name wins;
|
|
143
|
+
- images named by a relative path: copied next to the report once per content (the same picture referenced from two
|
|
144
|
+
folders is one file) and the report's `src` rewritten to the copy.
|
|
145
|
+
|
|
146
|
+
An unresolved reference is listed for its file and does not stop the import. BIRT libraries (`.rptlibrary`) are
|
|
147
|
+
listed, but the BIRT importer does not read them, so their items are missing.
|
|
148
|
+
- **The migration report** is `import-report.json` and `import-report.html` in `<outDir>`. With
|
|
149
|
+
`--report file.json` it goes there with the `.html` beside it, and with `--report folder` it goes into that folder.
|
|
150
|
+
For each file it gives the status, the counts of items mapped, approximated and dropped, and every item approximated
|
|
151
|
+
or dropped with the reason. It also lists every expression that was not translated with its item and its line and
|
|
152
|
+
column, and the references with what each resolved to. The rest of the importer's notes are listed under the report.
|
|
153
|
+
Every importer warning is in the report once. The HTML page stands alone and escapes file names and expressions.
|
|
154
|
+
Line and column are where the item's element starts in the XML file. ActiveReports `.rdlx-json` is JSON and gives
|
|
155
|
+
none. A data set's or a filter's expression is reported in that report's notes, not with a line.
|
|
156
|
+
- **Edited outputs are kept.** `<outDir>/.pw-import.json` holds the hash of each file as written. On a re-run, a
|
|
157
|
+
target whose hash differs (you edited it, or it was there before and is not from an import) is skipped with a message.
|
|
158
|
+
`--force` overwrites it. Unchanged targets are refreshed, and new ones are written.
|
|
159
|
+
- **`--verify`** renders each imported report with its embedded data, or with `<id>.data.json` beside the output
|
|
160
|
+
(`{ "<data source>": [rows] }`). A report with neither is skipped with a note. When the run replaced an earlier output,
|
|
161
|
+
the two are compared with `pw diff`'s comparison (the words, page by page), and the changed lines go into the report.
|
|
162
|
+
Otherwise the check confirms that it renders. A verify makes no network requests.
|
|
163
|
+
- **The folder is untrusted.** A report never opens a file by the path it names. Only files found by walking the
|
|
164
|
+
folder are read, so `../` and absolute paths cannot reach outside it. Symbolic links that point out of the folder,
|
|
165
|
+
or to folders, are refused and listed. Every output path is checked to stay in `<outDir>`, and nothing is written
|
|
166
|
+
through a link. `--max-files` and `--max-bytes` cap the file count and each file's size. Nothing in an imported file
|
|
167
|
+
is run: custom code and scriptlets stay text.
|
|
168
|
+
|
|
169
|
+
`pw --version` (or `-v`) prints the CLI's version and the version of the engine it carries.
|
|
170
|
+
|
|
18
171
|
## Snapshot tests: `pw test`
|
|
19
172
|
|
|
20
173
|
`pw test <folder>` renders every `<folder>/__tests__/*.test.json` and compares it with a snapshot beside it. Each test file says which report to render and which cases to run:
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// The streaming PDF's parallel paint worker is @reportwright/engine's (dist/pdfstreamworker.js). This stand-in ships so
|
|
2
|
+
// bundlers resolve new URL('./pdfstreamworker.js', import.meta.url) in this package.
|
|
3
|
+
const { parentPort } = globalThis.process.getBuiltinModule('node:worker_threads');
|
|
4
|
+
parentPort.on('message', (job) => parentPort.postMessage({ id: job.id, error: { message: 'exportPdfStream with parallel needs @reportwright/engine' } }));
|