@reportwright/engine 0.12.1 → 0.13.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +89 -5
  3. package/THIRD-PARTY-NOTICES.md +52 -0
  4. package/dist/index.js +10994 -4609
  5. package/dist/pdfstreamworker.js +2 -2
  6. package/dist/types/packages/engine/entry.d.ts +64 -22
  7. package/dist/types/src/engine/data/index.d.ts +14 -1
  8. package/dist/types/src/engine/expr/evaluate.d.ts +1 -0
  9. package/dist/types/src/engine/index.d.ts +11 -3
  10. package/dist/types/src/engine/lazylibs.d.ts +46 -0
  11. package/dist/types/src/engine/notices.d.ts +1 -0
  12. package/dist/types/src/engine/options.d.ts +10 -0
  13. package/dist/types/src/engine/schema/report.schema.d.ts +3 -0
  14. package/dist/types/src/engine/schema/validate.d.ts +2 -0
  15. package/dist/types/src/engine/stream.d.ts +30 -35
  16. package/dist/types/src/engine/text/fonts.d.ts +35 -5
  17. package/dist/types/src/engine/text/measure.d.ts +6 -1
  18. package/dist/types/src/engine/text/standard-metrics.d.ts +190 -0
  19. package/dist/types/src/engine/text/standard.d.ts +42 -0
  20. package/dist/types/src/exporters/docx.d.ts +14 -0
  21. package/dist/types/src/exporters/officestream.d.ts +27 -0
  22. package/dist/types/src/exporters/pdf.d.ts +5 -3
  23. package/dist/types/src/exporters/pdfstandard.d.ts +23 -0
  24. package/dist/types/src/exporters/pdfstream.d.ts +15 -6
  25. package/dist/types/src/exporters/pdfstreamtags.d.ts +2 -0
  26. package/dist/types/src/exporters/spill.d.ts +15 -3
  27. package/dist/types/src/exporters/subset.d.ts +14 -0
  28. package/dist/types/src/exporters/xlsxstream.d.ts +22 -0
  29. package/package.json +4 -3
  30. package/report.d.ts +1 -0
  31. package/schema.json +3 -0
@@ -0,0 +1,190 @@
1
+ export namespace ENCODINGS {
2
+ let WinAnsi: number[];
3
+ let Symbol: number[];
4
+ let ZapfDingbats: number[];
5
+ }
6
+ /** PostScript name → the font's metrics (units per em 1000); widths: the advance of each code in its encoding */
7
+ export const METRICS: {
8
+ Helvetica: {
9
+ encoding: string;
10
+ familyName: string;
11
+ ascent: number;
12
+ descent: number;
13
+ capHeight: number;
14
+ xHeight: number;
15
+ italicAngle: number;
16
+ underlinePosition: number;
17
+ underlineThickness: number;
18
+ bbox: number[];
19
+ widths: number[];
20
+ };
21
+ 'Helvetica-Bold': {
22
+ encoding: string;
23
+ familyName: string;
24
+ ascent: number;
25
+ descent: number;
26
+ capHeight: number;
27
+ xHeight: number;
28
+ italicAngle: number;
29
+ underlinePosition: number;
30
+ underlineThickness: number;
31
+ bbox: number[];
32
+ widths: number[];
33
+ };
34
+ 'Helvetica-Oblique': {
35
+ encoding: string;
36
+ familyName: string;
37
+ ascent: number;
38
+ descent: number;
39
+ capHeight: number;
40
+ xHeight: number;
41
+ italicAngle: number;
42
+ underlinePosition: number;
43
+ underlineThickness: number;
44
+ bbox: number[];
45
+ widths: number[];
46
+ };
47
+ 'Helvetica-BoldOblique': {
48
+ encoding: string;
49
+ familyName: string;
50
+ ascent: number;
51
+ descent: number;
52
+ capHeight: number;
53
+ xHeight: number;
54
+ italicAngle: number;
55
+ underlinePosition: number;
56
+ underlineThickness: number;
57
+ bbox: number[];
58
+ widths: number[];
59
+ };
60
+ 'Times-Roman': {
61
+ encoding: string;
62
+ familyName: string;
63
+ ascent: number;
64
+ descent: number;
65
+ capHeight: number;
66
+ xHeight: number;
67
+ italicAngle: number;
68
+ underlinePosition: number;
69
+ underlineThickness: number;
70
+ bbox: number[];
71
+ widths: number[];
72
+ };
73
+ 'Times-Bold': {
74
+ encoding: string;
75
+ familyName: string;
76
+ ascent: number;
77
+ descent: number;
78
+ capHeight: number;
79
+ xHeight: number;
80
+ italicAngle: number;
81
+ underlinePosition: number;
82
+ underlineThickness: number;
83
+ bbox: number[];
84
+ widths: number[];
85
+ };
86
+ 'Times-Italic': {
87
+ encoding: string;
88
+ familyName: string;
89
+ ascent: number;
90
+ descent: number;
91
+ capHeight: number;
92
+ xHeight: number;
93
+ italicAngle: number;
94
+ underlinePosition: number;
95
+ underlineThickness: number;
96
+ bbox: number[];
97
+ widths: number[];
98
+ };
99
+ 'Times-BoldItalic': {
100
+ encoding: string;
101
+ familyName: string;
102
+ ascent: number;
103
+ descent: number;
104
+ capHeight: number;
105
+ xHeight: number;
106
+ italicAngle: number;
107
+ underlinePosition: number;
108
+ underlineThickness: number;
109
+ bbox: number[];
110
+ widths: number[];
111
+ };
112
+ Courier: {
113
+ encoding: string;
114
+ familyName: string;
115
+ ascent: number;
116
+ descent: number;
117
+ capHeight: number;
118
+ xHeight: number;
119
+ italicAngle: number;
120
+ underlinePosition: number;
121
+ underlineThickness: number;
122
+ bbox: number[];
123
+ widths: number[];
124
+ };
125
+ 'Courier-Bold': {
126
+ encoding: string;
127
+ familyName: string;
128
+ ascent: number;
129
+ descent: number;
130
+ capHeight: number;
131
+ xHeight: number;
132
+ italicAngle: number;
133
+ underlinePosition: number;
134
+ underlineThickness: number;
135
+ bbox: number[];
136
+ widths: number[];
137
+ };
138
+ 'Courier-Oblique': {
139
+ encoding: string;
140
+ familyName: string;
141
+ ascent: number;
142
+ descent: number;
143
+ capHeight: number;
144
+ xHeight: number;
145
+ italicAngle: number;
146
+ underlinePosition: number;
147
+ underlineThickness: number;
148
+ bbox: number[];
149
+ widths: number[];
150
+ };
151
+ 'Courier-BoldOblique': {
152
+ encoding: string;
153
+ familyName: string;
154
+ ascent: number;
155
+ descent: number;
156
+ capHeight: number;
157
+ xHeight: number;
158
+ italicAngle: number;
159
+ underlinePosition: number;
160
+ underlineThickness: number;
161
+ bbox: number[];
162
+ widths: number[];
163
+ };
164
+ Symbol: {
165
+ encoding: string;
166
+ familyName: string;
167
+ ascent: number;
168
+ descent: number;
169
+ capHeight: number;
170
+ xHeight: number;
171
+ italicAngle: number;
172
+ underlinePosition: number;
173
+ underlineThickness: number;
174
+ bbox: number[];
175
+ widths: number[];
176
+ };
177
+ ZapfDingbats: {
178
+ encoding: string;
179
+ familyName: string;
180
+ ascent: number;
181
+ descent: number;
182
+ capHeight: number;
183
+ xHeight: number;
184
+ italicAngle: number;
185
+ underlinePosition: number;
186
+ underlineThickness: number;
187
+ bbox: number[];
188
+ widths: number[];
189
+ };
190
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * A standard font as a fontkit-like object (unitsPerEm 1000). The tables (about 22 KB) load on first use.
3
+ * @param {string} key a PostScript name of STANDARD_FACES
4
+ */
5
+ export function standardFont(key: string): Promise<{
6
+ standard: boolean;
7
+ postscriptName: string;
8
+ familyName: any;
9
+ unitsPerEm: number;
10
+ ascent: any;
11
+ descent: any;
12
+ capHeight: any;
13
+ xHeight: any;
14
+ italicAngle: any;
15
+ underlinePosition: any;
16
+ underlineThickness: any;
17
+ bbox: {
18
+ minX: any;
19
+ minY: any;
20
+ maxX: any;
21
+ maxY: any;
22
+ };
23
+ /** WinAnsi for the text fonts (Symbol and ZapfDingbats use their own built-in encodings) */
24
+ winAnsi: boolean;
25
+ widths: any;
26
+ /** @param {number} cp */
27
+ hasGlyphForCodePoint: (cp: number) => boolean;
28
+ /** @param {number} cp */
29
+ glyphForCodePoint: (cp: number) => any;
30
+ getGlyph: (id: number) => any;
31
+ }>;
32
+ /**
33
+ * The 14 standard PDF fonts (Helvetica, Times, Courier in four faces each, Symbol, ZapfDingbats): every PDF reader has
34
+ * them, so a PDF names them and embeds nothing. Their metrics are Adobe's AFM files, generated into standard-metrics.js
35
+ * (scripts/gen-standard-metrics.mjs, from @pdf-lib/standard-fonts); this wraps one in the part of fontkit's font API
36
+ * the engine and the PDF exporters read, so layout measures with the widths the PDF's /Widths array gives. A glyph ID
37
+ * here is the character's code in the font's encoding (WinAnsi; Symbol and ZapfDingbats have their own), one byte;
38
+ * 0 = not in the encoding. */
39
+ /** [family, PostScript name, weight, style] */
40
+ export const STANDARD_FACES: (string | number)[][];
41
+ export const STANDARD_KEYS: Set<string>;
42
+ export function isStandard(key: string): boolean;
@@ -21,3 +21,17 @@ export function exportDocx(model: any, opt?: {
21
21
  figures?: boolean;
22
22
  xmlChunk?: number;
23
23
  }): Promise<Uint8Array>;
24
+ /**
25
+ * The .docx of pages as they come (an array, or an async iterable: exportDocxStream's pages, a window at a time), its
26
+ * zip bytes handed to put as they are made (awaited: back-pressure). Each page's XML goes into word/document.xml's
27
+ * deflater once the page is converted, so neither the pages nor the document XML are held whole; the parts that name
28
+ * the pictures follow the document. model: the model, or a paged plan's info (width, height; locale, name).
29
+ * @param {Iterable<any>|AsyncIterable<any>} pages @param {{ width: number, height: number, locale?: string, name?: string }} model
30
+ * @param {NonNullable<Parameters<typeof exportDocx>[1]>} opt @param {(bytes: Uint8Array) => any} put
31
+ */
32
+ export function writeDocx(pages: Iterable<any> | AsyncIterable<any>, model: {
33
+ width: number;
34
+ height: number;
35
+ locale?: string;
36
+ name?: string;
37
+ }, opt: NonNullable<Parameters<typeof exportDocx>[1]>, put: (bytes: Uint8Array) => any): Promise<void>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Report definition → .docx written to sink as its pages are laid out.
3
+ * @param {any} def @param {any} opts render()'s options and exportDocx's (fontStore, fetchImage, figures, rasterize, lang,
4
+ * title), plus timeoutMs or deadline, signal, window (rows laid out at once), maxRows, sorter, sqlRows as exportPdfStream
5
+ * @param {Sink} sink not closed
6
+ * @returns {Promise<StreamResult>}
7
+ */
8
+ export function exportDocxStream(def: any, opts: any, sink: Sink): Promise<StreamResult>;
9
+ /**
10
+ * Report definition → .xlsx written to sink as its rows come.
11
+ * @param {any} def @param {any} opts render()'s options and exportXlsx's (currency, title, formulas, fontStore,
12
+ * fetchImage), plus timeoutMs or deadline, signal, maxRows, sorter, sqlRows as exportPdfStream
13
+ * @param {Sink} sink not closed
14
+ * @returns {Promise<StreamResult>}
15
+ */
16
+ export function exportXlsxStream(def: any, opts: any, sink: Sink): Promise<StreamResult>;
17
+ export type Sink = {
18
+ write(u8: Uint8Array): any;
19
+ once?: (ev: string, cb: () => void) => any;
20
+ };
21
+ export type StreamResult = {
22
+ streamed: boolean;
23
+ pages?: number;
24
+ rows?: number;
25
+ warnings: string[];
26
+ why?: string;
27
+ };
@@ -9,8 +9,10 @@
9
9
  * tagged?: { lang?: string }, drillBase?: string, onWarning?: (message: string) => void, timeoutMs?: number,
10
10
  * creationDate?: Date }} [opt]
11
11
  * subset: a HarfBuzz subsetter (see subset.js). Without it, fonts embed in full.
12
- * pdfa: make a PDF/A-2b file (needs an sRGB ICC profile). prepare: last change before saving
13
- * (the server adds a signature placeholder there). save: extra pdf-lib save options.
12
+ * pdfa: a PDF/A-2b file (2a with tagged): true uses the sRGB profile of @reportwright/fonts, or pass { icc } (this
13
+ * function itself needs icc; the engine package fills it in). prepare: last change to the pdf-lib PDFDocument before
14
+ * saving (the server adds a signature placeholder there). save: pdf-lib save options. These, encrypt and PDF/A without
15
+ * a profile take the whole-model path in exportPdfStream; a PDF/A file with a profile streams.
14
16
  * encrypt: { userPassword, ownerPassword, permissions } — AES-256 (see encrypt.js); not with pdfa or prepare.
15
17
  * tagged: an accessible PDF (PDF/UA-1, see pdfua.js): structure tree, marked content, artifacts, language, title
16
18
  * shown; with pdfa it is PDF/A-2a. Off, the file is exactly what it was.
@@ -42,4 +44,4 @@ export function exportPdf(model: any, fontStore: import("../engine/text/fonts.js
42
44
  timeoutMs?: number;
43
45
  creationDate?: Date;
44
46
  }): any;
45
- import { PDFDocument } from 'pdf-lib';
47
+ import { PDFDocument } from '../engine/lazylibs.js';
@@ -0,0 +1,23 @@
1
+ /** The font dictionary's entries (pdf-lib's context.obj takes them as they are: strings become names). @param {any} f a standard font */
2
+ export function standardFontEntries(f: any): {
3
+ FirstChar: number;
4
+ LastChar: number;
5
+ Widths: any;
6
+ Encoding?: string;
7
+ Type: string;
8
+ Subtype: string;
9
+ BaseFont: any;
10
+ };
11
+ /** The same dictionary as PDF syntax. @param {any} f */
12
+ export function standardFontDict(f: any): string;
13
+ /** A literal string's body: one byte per character, escaped. @param {any} f a standard font @param {string} text */
14
+ export function standardLiteral(f: any, text: string): string;
15
+ /**
16
+ * A page whose standard-font text is redrawn in the embedded stand-ins (PDF/A, PDF/UA), at the standard font's glyph
17
+ * positions. The page and the items it changes are copies; families gets the standard families it found.
18
+ * @param {any} pg @param {(key: string) => any} fontOf the loaded fonts by key @param {Set<string>} families
19
+ */
20
+ export function embeddedPage(pg: any, fontOf: (key: string) => any, families: Set<string>): any;
21
+ /** The warnings for the standard families a PDF/A or PDF/UA file drew in their stand-ins (a family's name is its regular face's key). @param {Set<string>} families */
22
+ export function embeddedWarnings(families: Set<string>): string[];
23
+ export function standIns(store: import("../engine/text/fonts.js").FontStore): string[];
@@ -1,16 +1,16 @@
1
1
  /**
2
- * @typedef {{ write(u8: Uint8Array): any, once?: (ev: string, cb: () => void) => any }} Sink
3
- * write may return a promise (awaited: back-pressure), or false with a 'drain' event to wait for (a Node Writable).
4
- * @typedef {{ title: string, page: number, top?: number, level?: number }} OutlineEntry
5
- * page: 1-based; top: the destination's y in PDF space (from the bottom), else the page fits the window.
2
+ * p, or signal's reason as soon as it aborts (p goes on, unwatched).
3
+ * @template T @param {Promise<T>} p @param {AbortSignal} [signal] @returns {Promise<T>}
6
4
  */
5
+ export function raced<T>(p: Promise<T>, signal?: AbortSignal): Promise<T>;
7
6
  /**
8
7
  * @param {Sink} sink
9
8
  * @param {{ fontStore: import('../engine/text/fonts.js').FontStore, fonts?: string[],
10
9
  * subset?: (font: Uint8Array, codePoints: Iterable<number>, opt?: { glyphs?: Iterable<number> }) => Promise<Uint8Array>,
11
- * id?: string }} opt
10
+ * id?: string, signal?: AbortSignal }} opt
12
11
  * fonts: font keys to name now (F1, F2… in this order); any other font is named on first use.
13
12
  * subset: subset.js's subsetter; without it fonts embed in full. id: the file ID (32 hex digits), else random.
13
+ * signal: stops a wait for the sink (back-pressure) when it aborts.
14
14
  */
15
15
  export function createPdfStream(sink: Sink, opt: {
16
16
  fontStore: import("../engine/text/fonts.js").FontStore;
@@ -19,6 +19,7 @@ export function createPdfStream(sink: Sink, opt: {
19
19
  glyphs?: Iterable<number>;
20
20
  }) => Promise<Uint8Array>;
21
21
  id?: string;
22
+ signal?: AbortSignal;
22
23
  }): {
23
24
  /** @param {string} key @returns {string} the font's resource name (F1…) */
24
25
  fontName: (key: string) => string;
@@ -60,6 +61,8 @@ export function createPdfStream(sink: Sink, opt: {
60
61
  * @param {string} dict @param {Uint8Array} [stream]
61
62
  */
62
63
  object(dict: string, stream?: Uint8Array): Promise<number>;
64
+ /** Bytes held for the cross-reference: the open blocks, the deflated ones, the late entries (a Map's ~40 each). */
65
+ readonly xrefBytes: number;
63
66
  /** An object number to write later (objectAt). */
64
67
  reserve: () => number;
65
68
  /** Write a reserved object. @param {number} n @param {string} dict @param {Uint8Array} [stream] */
@@ -127,6 +130,9 @@ export function createPdfStream(sink: Sink, opt: {
127
130
  * opts: render()'s options and exportPdf's (fontStore, subset, title, author, creationDate, drillBase…). Tagged
128
131
  * (PDF/UA-1) and PDF/A files stream too; encrypted and signed files, save options and PDF/A without a colour profile
129
132
  * take the whole-model path (the result's why says which).
133
+ * timeoutMs (or deadline) bounds the whole export, waits for the sink included; signal (an AbortSignal) stops it at its
134
+ * next wait (a row batch, the sink, a sort, a page). Stopped or failed: it rejects (the signal's reason, an AbortError;
135
+ * a timeout: status 504, code 'ETIMEDOUT'), the rows' cursors are closed, a sort's temporary files removed.
130
136
  * @param {any} def @param {any} opts @param {Sink} sink
131
137
  * @returns {Promise<{ streamed: boolean, pages: number, warnings: string[], why?: string }>}
132
138
  */
@@ -158,12 +164,13 @@ export function paintPage(pg: any, H: number, env: any): {
158
164
  };
159
165
  /**
160
166
  * What paintPage draws with: a writer's resource names and glyph records (w), the fonts, shaped glyphs' texts.
161
- * @param {any} w @param {any} fontStore @param {{ drillBase?: string, pageRef?: (i: number) => any, tags?: any }} [o]
167
+ * @param {any} w @param {any} fontStore @param {{ drillBase?: string, pageRef?: (i: number) => any, tags?: any, embedAll?: boolean }} [o]
162
168
  */
163
169
  export function paintEnv(w: any, fontStore: any, o?: {
164
170
  drillBase?: string;
165
171
  pageRef?: (i: number) => any;
166
172
  tags?: any;
173
+ embedAll?: boolean;
167
174
  }): {
168
175
  shared: {
169
176
  font: (f: any) => any;
@@ -180,6 +187,8 @@ export function paintEnv(w: any, fontStore: any, o?: {
180
187
  reserve: () => any;
181
188
  drillBase: string;
182
189
  tags: any;
190
+ /** PDF/A, PDF/UA: standard fonts drawn in embedded stand-ins; the families that were @type {Set<string>|null} */
191
+ embedded: Set<string> | null;
183
192
  };
184
193
  /**
185
194
  * write may return a promise (awaited: back-pressure), or false with a 'drain' event to wait for (a Node Writable).
@@ -17,6 +17,8 @@ export function createStreamTagger(w: any, { maxElements }?: {
17
17
  }): {
18
18
  /** structure elements so far */
19
19
  readonly count: number;
20
+ /** elements of the page being drawn, held until it ends */
21
+ readonly held: number;
20
22
  /** a new page (window: the paged window it came from; row ids are its own) @param {number} window */
21
23
  page(window: number): void;
22
24
  /**
@@ -1,20 +1,32 @@
1
1
  /** At the server's start: remove the spill folders of processes that are gone (pw-spill-<pid>-…) and old-style ones. */
2
2
  export function sweepAtBoot(root?: any): void;
3
- export function spillSorter({ run, runBytes, frame, maxMB, totalMB, dir: root, staleMs }?: {
3
+ /**
4
+ * A sorter factory for planStream (engine/stream.js): sorter(cmp) → { push, drain, close }. The engine closes it
5
+ * when the rows end, fail or are abandoned (a client that left): its files go then.
6
+ * Memory, whatever the row count (N44): one run in memory while reading (runMB of records, about, and at most run
7
+ * records), and while merging at most mergeMB of batches (frame records a run): past that many runs, groups of runs
8
+ * are first merged into longer ones on disk (one more pass over those records), so the merge never holds a batch from
9
+ * every run of a large sort.
10
+ * @param {{ runMB?: number, mergeMB?: number, run?: number, runBytes?: number, frame?: number, maxMB?: number, totalMB?: number, dir?: string, staleMs?: number }} [o]
11
+ */
12
+ export function spillSorter({ runMB, mergeMB, run, runBytes, frame, maxMB, totalMB, dir: root, staleMs }?: {
13
+ runMB?: number;
14
+ mergeMB?: number;
4
15
  run?: number;
5
16
  runBytes?: number;
6
17
  frame?: number;
7
18
  maxMB?: number;
8
19
  totalMB?: number;
9
- dir?: any;
20
+ dir?: string;
10
21
  staleMs?: number;
11
22
  }): (cmp: (a: any, b: any) => number) => {
12
23
  /** @param {any} r */
13
24
  push(r: any): Promise<void>;
14
25
  drain(): AsyncGenerator<any, void, unknown>;
15
26
  close(): Promise<void>;
16
- /** Tests: the runs written so far. */
27
+ /** Tests: the runs on disk now, and the merges of groups of runs before the last. */
17
28
  readonly runs: number;
29
+ readonly passes: number;
18
30
  };
19
31
  export function canSpill(): boolean;
20
32
  export function spillShared(): any;
@@ -1,3 +1,17 @@
1
+ /**
2
+ * The tables of a single-face sfnt (TrueType or CFF) as a Map of tag to bytes. A collection (ttcf) gives an empty map.
3
+ * @param {Uint8Array} bytes
4
+ */
5
+ export function sfntTables(bytes: Uint8Array): Map<any, any>;
6
+ /** A sfnt from its tables: directory, 4-byte padding, table checksums and the head checkSumAdjustment. */
7
+ export function buildSfnt(version: any, tables: any): Uint8Array<ArrayBuffer>;
8
+ /**
9
+ * The name table with the given strings replaced (nameID to text). Each replaced string is written in its record's own
10
+ * encoding: UTF-16BE for Windows and Unicode, one byte per character for Macintosh.
11
+ * @param {Uint8Array} name
12
+ * @param {Map<number, string>} strings
13
+ */
14
+ export function setNameStrings(name: Uint8Array, strings: Map<number, string>): Uint8Array<ArrayBuffer>;
1
15
  /** @param {() => Promise<ArrayBuffer|Uint8Array>} loadWasm */
2
16
  export function createSubsetter(loadWasm: () => Promise<ArrayBuffer | Uint8Array>): (font: Uint8Array, codePoints: Iterable<number>, opt?: {
3
17
  glyphs?: Iterable<number>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @param {{ name: string, title: string, columns: number[], timeZone: string|null, locale: string|null, currency: string|null, rows: () => AsyncGenerator<any> }} plan
3
+ * @param {(bytes: Uint8Array) => any} put the zip's bytes as they come (awaited: back-pressure)
4
+ * @param {{ currency?: string, title?: string, formulas?: boolean, maxRows?: number, timeZone?: string }} [opt]
5
+ */
6
+ export function writeXlsxStream(plan: {
7
+ name: string;
8
+ title: string;
9
+ columns: number[];
10
+ timeZone: string | null;
11
+ locale: string | null;
12
+ currency: string | null;
13
+ rows: () => AsyncGenerator<any>;
14
+ }, put: (bytes: Uint8Array) => any, opt?: {
15
+ currency?: string;
16
+ title?: string;
17
+ formulas?: boolean;
18
+ maxRows?: number;
19
+ timeZone?: string;
20
+ }): Promise<void>;
21
+ export const EXCEL_ROWS: 1048576;
22
+ export const EXCEL_COLS: 16384;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reportwright/engine",
3
- "version": "0.12.1",
3
+ "version": "0.13.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -57,7 +57,8 @@
57
57
  "schema.json",
58
58
  "README.md",
59
59
  "CHANGELOG.md",
60
- "LICENSE"
60
+ "LICENSE",
61
+ "THIRD-PARTY-NOTICES.md"
61
62
  ],
62
63
  "engines": {
63
64
  "node": ">=20.9"
@@ -71,7 +72,7 @@
71
72
  "bidi-js": "1.0.3"
72
73
  },
73
74
  "peerDependencies": {
74
- "@reportwright/fonts": "0.12.1"
75
+ "@reportwright/fonts": "0.13.1"
75
76
  },
76
77
  "peerDependenciesMeta": {
77
78
  "@reportwright/fonts": {
package/report.d.ts CHANGED
@@ -344,6 +344,7 @@ export interface FormField extends ItemBase {
344
344
  type: 'field';
345
345
  kind?: 'text' | 'multiline' | 'checkbox' | 'choice';
346
346
  fieldName?: Expr<string>;
347
+ label?: Expr<string>;
347
348
  value?: Expr;
348
349
  options?: Expr;
349
350
  required?: boolean;
package/schema.json CHANGED
@@ -1259,6 +1259,9 @@
1259
1259
  "fieldName": {
1260
1260
  "x-ts": "Expr<string>"
1261
1261
  },
1262
+ "label": {
1263
+ "x-ts": "Expr<string>"
1264
+ },
1262
1265
  "value": {
1263
1266
  "x-ts": "Expr"
1264
1267
  },