pdf-oxide 0.3.37 → 0.3.39

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 (65) hide show
  1. package/lib/builders/document-builder.d.ts +350 -0
  2. package/lib/builders/document-builder.js +724 -0
  3. package/lib/builders/index.d.ts +4 -2
  4. package/lib/builders/index.js +4 -2
  5. package/lib/builders/pdf-builder.d.ts +2 -0
  6. package/lib/builders/pdf-builder.js +12 -0
  7. package/lib/builders/streaming-table.d.ts +49 -0
  8. package/lib/builders/streaming-table.js +110 -0
  9. package/lib/document-editor.d.ts +122 -0
  10. package/lib/document-editor.js +313 -0
  11. package/lib/errors.js +3 -4
  12. package/lib/form-field-manager.js +3 -1
  13. package/lib/index.d.ts +41 -7
  14. package/lib/index.js +266 -90
  15. package/lib/managers/accessibility-manager.js +19 -8
  16. package/lib/managers/annotation-manager.js +9 -9
  17. package/lib/managers/barcode-manager.js +18 -7
  18. package/lib/managers/batch-manager.js +2 -5
  19. package/lib/managers/cache-manager.js +1 -3
  20. package/lib/managers/compliance-manager.js +58 -19
  21. package/lib/managers/document-utility-manager.js +6 -6
  22. package/lib/managers/dom-pdf-creator.js +9 -9
  23. package/lib/managers/enterprise-manager.js +4 -1
  24. package/lib/managers/extended-managers.js +8 -1
  25. package/lib/managers/extraction-manager.js +7 -2
  26. package/lib/managers/final-utilities.d.ts +3 -3
  27. package/lib/managers/final-utilities.js +9 -4
  28. package/lib/managers/hybrid-ml-advanced.js +22 -6
  29. package/lib/managers/index.d.ts +22 -22
  30. package/lib/managers/index.js +23 -23
  31. package/lib/managers/layer-manager.js +20 -21
  32. package/lib/managers/ocr-manager.d.ts +2 -2
  33. package/lib/managers/ocr-manager.js +7 -7
  34. package/lib/managers/optimization-manager.js +24 -4
  35. package/lib/managers/page-manager.js +5 -6
  36. package/lib/managers/pattern-detection.d.ts +1 -1
  37. package/lib/managers/pattern-detection.js +4 -6
  38. package/lib/managers/search-manager.js +3 -3
  39. package/lib/managers/signature-manager.d.ts +14 -0
  40. package/lib/managers/signature-manager.js +185 -40
  41. package/lib/managers/streams.js +8 -2
  42. package/lib/managers/xfa-manager.js +69 -19
  43. package/lib/native-loader.d.ts +7 -0
  44. package/lib/native-loader.js +62 -0
  45. package/lib/native.d.ts +16 -0
  46. package/lib/native.js +69 -0
  47. package/lib/pdf-creator-manager.js +4 -1
  48. package/lib/result-accessors-manager.js +3 -1
  49. package/lib/timestamp.d.ts +54 -0
  50. package/lib/timestamp.js +115 -0
  51. package/lib/tsa-client.d.ts +44 -0
  52. package/lib/tsa-client.js +67 -0
  53. package/lib/types/common.d.ts +80 -1
  54. package/lib/types/common.js +14 -1
  55. package/lib/types/index.d.ts +1 -1
  56. package/lib/types/index.js +1 -1
  57. package/lib/types/manager-types.js +4 -2
  58. package/lib/workers/index.d.ts +1 -1
  59. package/lib/workers/pool.js +2 -4
  60. package/package.json +17 -11
  61. package/prebuilds/darwin-arm64/pdf_oxide.node +0 -0
  62. package/prebuilds/darwin-x64/pdf_oxide.node +0 -0
  63. package/prebuilds/linux-arm64/pdf_oxide.node +0 -0
  64. package/prebuilds/linux-x64/pdf_oxide.node +0 -0
  65. package/prebuilds/win32-x64/pdf_oxide.node +0 -0
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Fluent document builder — the programmatic multi-page construction API
3
+ * exposed through the C FFI.
4
+ *
5
+ * Mirrors the Python / WASM / C# / Go equivalents. The same handle-lifetime
6
+ * contract applies: terminal methods (`build`, `save`, `saveEncrypted`,
7
+ * `toBytesEncrypted`) CONSUME the builder, and only one `PageBuilder` may
8
+ * be open at a time.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { DocumentBuilder, EmbeddedFont } from 'pdf-oxide';
13
+ *
14
+ * const font = EmbeddedFont.fromFile('DejaVuSans.ttf');
15
+ * const builder = DocumentBuilder.create()
16
+ * .title('Hello')
17
+ * .registerEmbeddedFont('DejaVu', font); // consumes `font`
18
+ * builder.a4Page()
19
+ * .font('DejaVu', 12)
20
+ * .at(72, 720).text('Привет, мир!')
21
+ * .at(72, 700).text('Καλημέρα κόσμε')
22
+ * .done();
23
+ * const bytes = builder.build(); // consumes the builder
24
+ * ```
25
+ */
26
+ import { Align, type Column, type SpanCell, type StreamingTableConfig, type TableMode, type TableSpec } from '../types/common.js';
27
+ import { StreamingTable } from './streaming-table.js';
28
+ /**
29
+ * TTF/OTF font handle registerable with {@link DocumentBuilder}. Single-use:
30
+ * after `registerEmbeddedFont` the native handle is moved into the builder
31
+ * and this object becomes disposed.
32
+ */
33
+ export declare class EmbeddedFont {
34
+ private _handle;
35
+ private _consumed;
36
+ private constructor();
37
+ /** Load a TTF / OTF font from disk. */
38
+ static fromFile(path: string): EmbeddedFont;
39
+ /** Load a font from a byte buffer; pass `name` to override the PostScript name. */
40
+ static fromBytes(data: Uint8Array | Buffer, name?: string): EmbeddedFont;
41
+ /** @internal — used by {@link DocumentBuilder.registerEmbeddedFont} */
42
+ get handle(): unknown;
43
+ /** @internal — called by the builder after the FFI transfers ownership. */
44
+ markConsumed(): void;
45
+ /** Release the native font handle if it hasn't been consumed. */
46
+ close(): void;
47
+ /** Symbol.dispose support for `using` declarations. */
48
+ [Symbol.dispose](): void;
49
+ }
50
+ /**
51
+ * Fluent top-level API for multi-page PDF construction.
52
+ * Use {@link DocumentBuilder.create} to start a new builder.
53
+ */
54
+ export declare class DocumentBuilder {
55
+ private _handle;
56
+ private _consumed;
57
+ private _openPage;
58
+ private constructor();
59
+ /** Create a fresh empty builder. */
60
+ static create(): DocumentBuilder;
61
+ /** @internal — used by PageBuilder.done */
62
+ clearOpenPage(): void;
63
+ private checkUsable;
64
+ /** Set the document title. */
65
+ title(title: string): this;
66
+ /** Set the document author. */
67
+ author(author: string): this;
68
+ /** Set the document subject. */
69
+ subject(subject: string): this;
70
+ /** Set the document keywords (comma-separated per PDF convention). */
71
+ keywords(keywords: string): this;
72
+ /** Set the creator application name. */
73
+ creator(creator: string): this;
74
+ /** Run a JavaScript script when the document is opened (/OpenAction). */
75
+ onOpen(script: string): this;
76
+ /**
77
+ * Enable PDF/UA-1 tagged PDF mode.
78
+ *
79
+ * When enabled, `build()` emits `/MarkInfo`, `/StructTreeRoot`, `/Lang`, and
80
+ * `/ViewerPreferences` in the catalog. Opt-in — no effect unless called.
81
+ * Bundle F-1/F-2.
82
+ */
83
+ taggedPdfUa1(): this;
84
+ /**
85
+ * Set the document's natural language tag, e.g. `"en-US"`.
86
+ *
87
+ * Emitted as `/Lang` in the catalog when `taggedPdfUa1()` is set. Bundle F-2.
88
+ */
89
+ language(lang: string): this;
90
+ /**
91
+ * Add a role-map entry: custom structure type → standard PDF structure type.
92
+ *
93
+ * Emitted in `/RoleMap` inside the StructTreeRoot when `taggedPdfUa1()` is
94
+ * set. Multiple calls accumulate entries. Bundle F-4.
95
+ */
96
+ roleMap(custom: string, standard: string): this;
97
+ /**
98
+ * Register a TTF / OTF font under `name`. CONSUMES `font` on success —
99
+ * do not call `close()` on the font afterwards.
100
+ */
101
+ registerEmbeddedFont(name: string, font: EmbeddedFont): this;
102
+ /** Start a new A4 page. Only one page may be outstanding per builder. */
103
+ a4Page(): PageBuilder;
104
+ /** Start a new US Letter page. */
105
+ letterPage(): PageBuilder;
106
+ /** Start a page with custom dimensions in PDF points (72 pt = 1 inch). */
107
+ page(width: number, height: number): PageBuilder;
108
+ private consumeHandle;
109
+ /** Build the PDF and return the bytes. CONSUMES the builder. */
110
+ build(): Buffer;
111
+ /** Save the PDF to a file. CONSUMES the builder. */
112
+ save(path: string): void;
113
+ /** Save the PDF with AES-256 encryption. CONSUMES the builder. */
114
+ saveEncrypted(path: string, userPassword: string, ownerPassword: string): void;
115
+ /** Return the PDF as encrypted bytes (AES-256). CONSUMES the builder. */
116
+ toBytesEncrypted(userPassword: string, ownerPassword: string): Buffer;
117
+ /** Release native resources if the builder wasn't consumed. */
118
+ close(): void;
119
+ /** Symbol.dispose support for `using` declarations. */
120
+ [Symbol.dispose](): void;
121
+ }
122
+ /**
123
+ * Fluent per-page builder returned by `DocumentBuilder.a4Page` etc.
124
+ * Single-use — `done()` commits the page and invalidates this builder.
125
+ */
126
+ export declare class PageBuilder {
127
+ private _parent;
128
+ private _handle;
129
+ private _done;
130
+ /** @internal — constructed by DocumentBuilder */
131
+ constructor(parent: DocumentBuilder, handle: unknown);
132
+ private h;
133
+ /** Set font + size for subsequent text. */
134
+ font(name: string, size: number): this;
135
+ /** Move the cursor to absolute coordinates. */
136
+ at(x: number, y: number): this;
137
+ /** Emit a line of text at the current cursor position. */
138
+ text(text: string): this;
139
+ /** Emit a heading (level 1-6). */
140
+ heading(level: number, text: string): this;
141
+ /** Emit a paragraph with automatic line wrapping. */
142
+ paragraph(text: string): this;
143
+ /** Advance the cursor by the given number of points. */
144
+ space(points: number): this;
145
+ /** Draw a horizontal rule across the page. */
146
+ horizontalRule(): this;
147
+ /** Attach a URL link to the previous text element. */
148
+ linkUrl(url: string): this;
149
+ /** Link the previous text to an internal page (0-based). */
150
+ linkPage(pageIndex: number): this;
151
+ /** Link the previous text to a named destination. */
152
+ linkNamed(destination: string): this;
153
+ /** Link the previous text to a JavaScript action. */
154
+ linkJavascript(script: string): this;
155
+ /** Run JavaScript when this page is opened (/AA /O). */
156
+ onOpen(script: string): this;
157
+ /** Run JavaScript when this page is closed (/AA /C). */
158
+ onClose(script: string): this;
159
+ /** Set a keystroke JS action (/AA /K) on the last form field. */
160
+ fieldKeystroke(script: string): this;
161
+ /** Set a format JS action (/AA /F) on the last form field. */
162
+ fieldFormat(script: string): this;
163
+ /** Set a validate JS action (/AA /V) on the last form field. */
164
+ fieldValidate(script: string): this;
165
+ /** Set a calculate JS action (/AA /C) on the last form field. */
166
+ fieldCalculate(script: string): this;
167
+ /** Highlight the previous text with an RGB colour (channels 0-1). */
168
+ highlight(r: number, g: number, b: number): this;
169
+ /** Underline the previous text. */
170
+ underline(r: number, g: number, b: number): this;
171
+ /** Strike through the previous text. */
172
+ strikeout(r: number, g: number, b: number): this;
173
+ /** Squiggly-underline the previous text. */
174
+ squiggly(r: number, g: number, b: number): this;
175
+ /** Attach a sticky-note annotation to the previous text. */
176
+ stickyNote(text: string): this;
177
+ /** Place a sticky-note at an absolute position. */
178
+ stickyNoteAt(x: number, y: number, text: string): this;
179
+ /** Apply a text watermark to the page. */
180
+ watermark(text: string): this;
181
+ /** Apply the standard "CONFIDENTIAL" diagonal watermark. */
182
+ watermarkConfidential(): this;
183
+ /** Apply the standard "DRAFT" diagonal watermark. */
184
+ watermarkDraft(): this;
185
+ /**
186
+ * Attach a standard stamp annotation at the cursor (150×50 default).
187
+ * `typeName` matches the PDF spec's standard stamps (Approved,
188
+ * NotApproved, Draft, Confidential, Final, Experimental, Expired,
189
+ * ForPublicRelease, NotForPublicRelease, AsIs, Sold, Departmental,
190
+ * ForComment, TopSecret) — any other name becomes a custom stamp.
191
+ */
192
+ stamp(typeName: string): this;
193
+ /** Place a free-flowing text annotation inside the rectangle (x, y, w, h). */
194
+ freeText(x: number, y: number, w: number, h: number, text: string): this;
195
+ /**
196
+ * Add a single-line text form field at the rectangle (x, y, w, h).
197
+ * `name` is the unique field identifier used for form submission;
198
+ * `defaultValue` is the initial text (pass undefined for blank).
199
+ */
200
+ textField(name: string, x: number, y: number, w: number, h: number, defaultValue?: string): this;
201
+ /**
202
+ * Add a checkbox form field at the rectangle (x, y, w, h).
203
+ * `checked` sets the initial state.
204
+ */
205
+ checkbox(name: string, x: number, y: number, w: number, h: number, checked?: boolean): this;
206
+ /**
207
+ * Add a dropdown combo-box form field. `options` are the user-
208
+ * visible choices; `selected` picks the initial value.
209
+ */
210
+ comboBox(name: string, x: number, y: number, w: number, h: number, options: string[], selected?: string): this;
211
+ /**
212
+ * Add a radio-button group. `buttons` is an array of
213
+ * `[exportValue, x, y, w, h]` tuples — one per option. `selected`
214
+ * picks the initial value by export value.
215
+ */
216
+ radioGroup(name: string, buttons: Array<[string, number, number, number, number]>, selected?: string): this;
217
+ /** Add a clickable push button with a visible caption. */
218
+ pushButton(name: string, x: number, y: number, w: number, h: number, caption: string): this;
219
+ /** Add an unsigned signature placeholder field (/FT /Sig) at the given bounds. */
220
+ signatureField(name: string, x: number, y: number, w: number, h: number): this;
221
+ /**
222
+ * Add a footnote: inline `refMark` emitted at the cursor position, and
223
+ * `noteText` placed near the page bottom with a separator artifact line.
224
+ */
225
+ footnote(refMark: string, noteText: string): this;
226
+ /**
227
+ * Lay out `text` as balanced multi-column flow.
228
+ * `columnCount` columns separated by `gapPt` points.
229
+ * Paragraphs in `text` are delimited by `"\n\n"`.
230
+ */
231
+ columns(columnCount: number, gapPt: number, text: string): this;
232
+ /**
233
+ * Emit `text` inline at the current cursor position without advancing
234
+ * to a new line. The cursor advances horizontally so the next `inline`
235
+ * call follows on the same line.
236
+ */
237
+ inline(text: string): this;
238
+ /** Emit `text` inline in bold weight. */
239
+ inlineBold(text: string): this;
240
+ /** Emit `text` inline in italic style. */
241
+ inlineItalic(text: string): this;
242
+ /** Emit `text` inline in an RGB colour (channels 0–1). */
243
+ inlineColor(r: number, g: number, b: number, text: string): this;
244
+ /** Advance the cursor to the start of the next line. */
245
+ newline(): this;
246
+ /**
247
+ * Place a 1-D barcode image on the page at `(x, y, w, h)`.
248
+ * `barcodeType`: 0=Code128 1=Code39 2=EAN13 3=EAN8 4=UPCA 5=ITF
249
+ * 6=Code93 7=Codabar.
250
+ */
251
+ barcode1d(barcodeType: number, data: string, x: number, y: number, w: number, h: number): this;
252
+ /** Place a QR-code image on the page (square: `size × size` pt). */
253
+ barcodeQr(data: string, x: number, y: number, size: number): this;
254
+ /**
255
+ * Embed an image with an accessibility alt text (PDF/UA-1 §Figure).
256
+ * `bytes` must contain raw JPEG/PNG/WebP image data.
257
+ */
258
+ imageWithAlt(bytes: Buffer | Uint8Array, x: number, y: number, w: number, h: number, altText: string): this;
259
+ /**
260
+ * Embed a decorative image as an /Artifact (no alt text, PDF/UA-1 §Artifact).
261
+ * `bytes` must contain raw JPEG/PNG/WebP image data.
262
+ */
263
+ imageArtifact(bytes: Buffer | Uint8Array, x: number, y: number, w: number, h: number): this;
264
+ /** Draw a stroked rectangle outline (1pt black). */
265
+ rect(x: number, y: number, w: number, h: number): this;
266
+ /** Draw a filled rectangle in RGB colour (channels 0–1). */
267
+ filledRect(x: number, y: number, w: number, h: number, r: number, g: number, b: number): this;
268
+ /** Draw a line from `(x1, y1)` to `(x2, y2)` with 1pt black stroke. */
269
+ line(x1: number, y1: number, x2: number, y2: number): this;
270
+ /**
271
+ * Draw a stroked rectangle outline with caller-supplied width + RGB
272
+ * colour (channels 0–1). Underlies the Table surface.
273
+ */
274
+ strokeRect(x: number, y: number, w: number, h: number, style?: {
275
+ width?: number;
276
+ color?: [number, number, number];
277
+ }): this;
278
+ /**
279
+ * Draw a straight line with caller-supplied width + RGB colour.
280
+ */
281
+ strokeLine(x1: number, y1: number, x2: number, y2: number, style?: {
282
+ width?: number;
283
+ color?: [number, number, number];
284
+ }): this;
285
+ /**
286
+ * Place wrapped text inside the rectangle (x, y, w, h) with the
287
+ * given horizontal alignment. Uses the current font + size. Text
288
+ * that does not fit is clipped to the rectangle height.
289
+ */
290
+ textInRect(x: number, y: number, w: number, h: number, text: string, align?: Align): this;
291
+ /**
292
+ * Start a new page with the *same* dimensions as the current one.
293
+ * Text config (font + size) carries over; the cursor resets to the
294
+ * top-left margin. Callers wanting header-repeat-on-break must
295
+ * re-emit the header explicitly.
296
+ */
297
+ newPageSameSize(): this;
298
+ /**
299
+ * Measure the width of `text` in the current font and size.
300
+ *
301
+ * Note: v0.3.39 ships a JS-side approximation (0.55em per glyph for
302
+ * ASCII / typical Latin-1 characters). A true per-glyph measurement
303
+ * FFI is pending. The result is in PDF points.
304
+ */
305
+ measure(text: string): number;
306
+ /**
307
+ * Estimate the remaining vertical space on the page at the current
308
+ * cursor position. v0.3.39 returns `null` when the native cursor is
309
+ * unknown — callers should treat `null` as "unknown; assume fresh
310
+ * page". A real FFI hook is pending in a follow-up release.
311
+ */
312
+ remainingSpace(): number | null;
313
+ /**
314
+ * Emit a buffered table at the current cursor. All rows are
315
+ * marshalled into a single FFI call — memory scales with the row
316
+ * count. For million-row streams use {@link streamingTable}.
317
+ */
318
+ table(spec: TableSpec): this;
319
+ /**
320
+ * Begin a streaming table. Uses the native row-at-a-time FFI
321
+ * (`pdf_page_builder_streaming_table_begin_v2`). Pass a `mode` in
322
+ * `config` to control column-sizing strategy (default: fixed widths).
323
+ */
324
+ streamingTable(config: StreamingTableConfig): StreamingTable;
325
+ /** @internal — open streaming table FFI handle on this page. */
326
+ _streamingTableBeginV2(headers: string[], widths: number[], aligns: number[], repeatHeader: boolean, mode: TableMode | undefined, maxRowspan: number): void;
327
+ /** @internal — push one row into the open streaming table (all rowspan=1). */
328
+ _streamingTablePushRow(cells: Array<string | null>): void;
329
+ /** @internal — push one row with per-cell rowspan values. */
330
+ _streamingTablePushRowV2(cells: Array<[string | null, number]>): void;
331
+ /** @internal — close the open streaming table. */
332
+ _streamingTableFinish(): void;
333
+ /** @internal — track the last font size for JS-side `measure()`. */
334
+ _lastFontSize?: number;
335
+ /**
336
+ * Commit the page's buffered operations to the parent builder and
337
+ * return the parent for chaining. After `done()` this PageBuilder is
338
+ * invalid.
339
+ */
340
+ done(): DocumentBuilder;
341
+ /**
342
+ * Drop an uncommitted page. Use only for error recovery — the parent's
343
+ * open-page slot is released so the next `a4Page()` etc. succeeds.
344
+ */
345
+ close(): void;
346
+ /** Symbol.dispose support for `using`. */
347
+ [Symbol.dispose](): void;
348
+ }
349
+ export { StreamingTable } from './streaming-table.js';
350
+ export { Align, type Column, type SpanCell, type StreamingTableConfig, type TableMode, type TableSpec, };