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
package/lib/native.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Shared loader for the pdf-oxide N-API addon.
3
+ *
4
+ * Extracted so that modules which can't import from `./index.ts`
5
+ * (due to the index ↔ editor / builder cycle) can still reach the
6
+ * addon through the same prebuild-aware resolver. The published
7
+ * package ships a platform-specific `.node` file under
8
+ * `prebuilds/<triple>/`; loading the addon through this helper is
9
+ * what makes `DocumentEditor` / `DocumentBuilder` work for consumers
10
+ * installed from npm (where `build/Release/` does not exist).
11
+ *
12
+ * In development mode (`NODE_ENV=development` or `NAPI_DEV` set), we
13
+ * fall back to `../build/Release/pdf_oxide.node` — the node-gyp
14
+ * output that in-tree tests run against.
15
+ */
16
+ import { createRequire } from 'node:module';
17
+ import { arch, platform } from 'node:os';
18
+ const require = createRequire(import.meta.url);
19
+ // Prebuild paths are relative to the *compiled* `lib/native.js` — at
20
+ // runtime the file lives at `js/lib/native.js`, so `../prebuilds/`
21
+ // resolves to `js/prebuilds/`.
22
+ const PLATFORMS = {
23
+ darwin: {
24
+ x64: '../prebuilds/darwin-x64/pdf_oxide.node',
25
+ arm64: '../prebuilds/darwin-arm64/pdf_oxide.node',
26
+ },
27
+ linux: {
28
+ x64: '../prebuilds/linux-x64/pdf_oxide.node',
29
+ arm64: '../prebuilds/linux-arm64/pdf_oxide.node',
30
+ },
31
+ win32: {
32
+ x64: '../prebuilds/win32-x64/pdf_oxide.node',
33
+ },
34
+ };
35
+ function getPrebuildPath() {
36
+ const os = platform();
37
+ const cpu = arch();
38
+ const osPaths = PLATFORMS[os];
39
+ if (!osPaths) {
40
+ throw new Error(`Unsupported platform: ${os}. Supported: ${Object.keys(PLATFORMS).join(', ')}`);
41
+ }
42
+ const prebuildPath = osPaths[cpu];
43
+ if (!prebuildPath) {
44
+ throw new Error(`Unsupported architecture: ${cpu} for ${os}. Supported: ${Object.keys(osPaths).join(', ')}`);
45
+ }
46
+ return prebuildPath;
47
+ }
48
+ let cached;
49
+ export function loadNative() {
50
+ if (cached)
51
+ return cached;
52
+ try {
53
+ cached = require(getPrebuildPath());
54
+ return cached;
55
+ }
56
+ catch (e) {
57
+ // Dev fallback — in-tree `node-gyp rebuild` output.
58
+ if (process.env.NODE_ENV === 'development' || process.env.NAPI_DEV) {
59
+ try {
60
+ cached = require('../build/Release/pdf_oxide.node');
61
+ return cached;
62
+ }
63
+ catch {
64
+ /* fall through to rethrow the original error */
65
+ }
66
+ }
67
+ throw new Error(`Failed to load pdf-oxide native addon: ${e.message}`);
68
+ }
69
+ }
@@ -200,7 +200,10 @@ export class PdfCreatorManager extends EventEmitter {
200
200
  this.ensureCurrentPage();
201
201
  const lineContent = {
202
202
  type: 'line',
203
- x1, y1, x2, y2,
203
+ x1,
204
+ y1,
205
+ x2,
206
+ y2,
204
207
  color,
205
208
  width,
206
209
  };
@@ -698,7 +698,9 @@ export class ResultAccessorsManager extends EventEmitter {
698
698
  clearCachePattern(pattern) {
699
699
  const regex = new RegExp(pattern);
700
700
  const keysToDelete = Array.from(this.resultCache.keys()).filter((key) => regex.test(key));
701
- keysToDelete.forEach((key) => this.resultCache.delete(key));
701
+ keysToDelete.forEach((key) => {
702
+ this.resultCache.delete(key);
703
+ });
702
704
  }
703
705
  }
704
706
  export default ResultAccessorsManager;
@@ -0,0 +1,54 @@
1
+ /** Hash-algorithm enum matching the FFI contract (0 = unknown). */
2
+ export declare enum TimestampHashAlgorithm {
3
+ Unknown = 0,
4
+ Sha1 = 1,
5
+ Sha256 = 2,
6
+ Sha384 = 3,
7
+ Sha512 = 4
8
+ }
9
+ /**
10
+ * Parsed RFC 3161 timestamp token. The underlying native handle is
11
+ * released by `close()` or on garbage collection (N-API finalizer in
12
+ * the C++ binding).
13
+ */
14
+ export declare class Timestamp {
15
+ private handle;
16
+ private closed;
17
+ /** Internal — only the static constructors and sibling classes create Timestamps. */
18
+ private constructor();
19
+ /**
20
+ * Parse a DER blob that may be either a full TimeStampToken (CMS-wrapped)
21
+ * or the bare TSTInfo SEQUENCE. Throws on parse failure.
22
+ */
23
+ static parse(data: Uint8Array | Buffer): Timestamp;
24
+ /**
25
+ * Wrap an existing native timestamp handle (produced by
26
+ * `signatureGetTimestamp` or `tsaRequestTimestamp`). Internal use only.
27
+ */
28
+ static fromNativeHandle(handle: unknown): Timestamp;
29
+ /** Generation time as Unix epoch seconds. */
30
+ get time(): number;
31
+ /** Serial number as a hex string (no `0x` prefix). */
32
+ get serial(): string;
33
+ /** TSA policy OID in dotted-decimal form. */
34
+ get policyOid(): string;
35
+ /** TSA name from the token (may be empty). */
36
+ get tsaName(): string;
37
+ /** Hash algorithm used for the message imprint. */
38
+ get hashAlgorithm(): TimestampHashAlgorithm;
39
+ /** Raw message-imprint hash bytes. */
40
+ get messageImprint(): Uint8Array;
41
+ /** Raw DER token bytes. */
42
+ get token(): Uint8Array;
43
+ /**
44
+ * Cryptographic verify. Today this surfaces whatever the Rust core
45
+ * returns — real TSA-signer verification lands when the CMS signer
46
+ * path is wired through `pdf_timestamp_verify`.
47
+ */
48
+ verify(): boolean;
49
+ /** Release the native handle. Idempotent. */
50
+ close(): void;
51
+ /** Internal native handle accessor for sibling classes (Signature.addTimestamp). */
52
+ getInternalHandle(): unknown;
53
+ private assertOpen;
54
+ }
@@ -0,0 +1,115 @@
1
+ // RFC 3161 TimeStampToken / TSTInfo wrapper for the Node binding.
2
+ //
3
+ // Mirrors the Python PyTimestamp, WASM WasmTimestamp, Go Timestamp, and
4
+ // C# Timestamp surfaces so every binding exposes the same shape.
5
+ // Sourced from:
6
+ // - Timestamp.parse(buffer) — a standalone DER blob
7
+ // - A Signature object's embedded timestamp (via the signature manager)
8
+ // - A TsaClient.requestTimestamp(...) response (see tsa-client.ts)
9
+ import { getNative } from './native-loader.js';
10
+ /** Hash-algorithm enum matching the FFI contract (0 = unknown). */
11
+ export var TimestampHashAlgorithm;
12
+ (function (TimestampHashAlgorithm) {
13
+ TimestampHashAlgorithm[TimestampHashAlgorithm["Unknown"] = 0] = "Unknown";
14
+ TimestampHashAlgorithm[TimestampHashAlgorithm["Sha1"] = 1] = "Sha1";
15
+ TimestampHashAlgorithm[TimestampHashAlgorithm["Sha256"] = 2] = "Sha256";
16
+ TimestampHashAlgorithm[TimestampHashAlgorithm["Sha384"] = 3] = "Sha384";
17
+ TimestampHashAlgorithm[TimestampHashAlgorithm["Sha512"] = 4] = "Sha512";
18
+ })(TimestampHashAlgorithm || (TimestampHashAlgorithm = {}));
19
+ /**
20
+ * Parsed RFC 3161 timestamp token. The underlying native handle is
21
+ * released by `close()` or on garbage collection (N-API finalizer in
22
+ * the C++ binding).
23
+ */
24
+ export class Timestamp {
25
+ /** Internal — only the static constructors and sibling classes create Timestamps. */
26
+ constructor(handle) {
27
+ this.closed = false;
28
+ this.handle = handle;
29
+ }
30
+ /**
31
+ * Parse a DER blob that may be either a full TimeStampToken (CMS-wrapped)
32
+ * or the bare TSTInfo SEQUENCE. Throws on parse failure.
33
+ */
34
+ static parse(data) {
35
+ if (!data || data.length === 0) {
36
+ throw new Error('Timestamp.parse: data must not be empty');
37
+ }
38
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
39
+ const handle = getNative().timestampParse(buf);
40
+ if (!handle) {
41
+ throw new Error('Timestamp.parse: native parse returned null');
42
+ }
43
+ return new Timestamp(handle);
44
+ }
45
+ /**
46
+ * Wrap an existing native timestamp handle (produced by
47
+ * `signatureGetTimestamp` or `tsaRequestTimestamp`). Internal use only.
48
+ */
49
+ static fromNativeHandle(handle) {
50
+ return new Timestamp(handle);
51
+ }
52
+ /** Generation time as Unix epoch seconds. */
53
+ get time() {
54
+ this.assertOpen();
55
+ return Number(getNative().timestampGetTime(this.handle));
56
+ }
57
+ /** Serial number as a hex string (no `0x` prefix). */
58
+ get serial() {
59
+ this.assertOpen();
60
+ return getNative().timestampGetSerial(this.handle);
61
+ }
62
+ /** TSA policy OID in dotted-decimal form. */
63
+ get policyOid() {
64
+ this.assertOpen();
65
+ return getNative().timestampGetPolicyOid(this.handle);
66
+ }
67
+ /** TSA name from the token (may be empty). */
68
+ get tsaName() {
69
+ this.assertOpen();
70
+ return getNative().timestampGetTsaName(this.handle);
71
+ }
72
+ /** Hash algorithm used for the message imprint. */
73
+ get hashAlgorithm() {
74
+ this.assertOpen();
75
+ const v = getNative().timestampGetHashAlgorithm(this.handle);
76
+ return v;
77
+ }
78
+ /** Raw message-imprint hash bytes. */
79
+ get messageImprint() {
80
+ this.assertOpen();
81
+ return new Uint8Array(getNative().timestampGetMessageImprint(this.handle));
82
+ }
83
+ /** Raw DER token bytes. */
84
+ get token() {
85
+ this.assertOpen();
86
+ return new Uint8Array(getNative().timestampGetToken(this.handle));
87
+ }
88
+ /**
89
+ * Cryptographic verify. Today this surfaces whatever the Rust core
90
+ * returns — real TSA-signer verification lands when the CMS signer
91
+ * path is wired through `pdf_timestamp_verify`.
92
+ */
93
+ verify() {
94
+ this.assertOpen();
95
+ return getNative().timestampVerify(this.handle);
96
+ }
97
+ /** Release the native handle. Idempotent. */
98
+ close() {
99
+ if (!this.closed && this.handle) {
100
+ getNative().timestampFree(this.handle);
101
+ this.closed = true;
102
+ this.handle = null;
103
+ }
104
+ }
105
+ /** Internal native handle accessor for sibling classes (Signature.addTimestamp). */
106
+ getInternalHandle() {
107
+ this.assertOpen();
108
+ return this.handle;
109
+ }
110
+ assertOpen() {
111
+ if (this.closed) {
112
+ throw new Error('Timestamp: handle is closed');
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,44 @@
1
+ import { Timestamp, TimestampHashAlgorithm } from './timestamp.js';
2
+ /** Constructor options for a TsaClient. */
3
+ export interface TsaClientOptions {
4
+ /** TSA server URL, e.g. `https://freetsa.org/tsr`. */
5
+ url: string;
6
+ /** HTTP Basic auth username (optional). */
7
+ username?: string;
8
+ /** HTTP Basic auth password (optional). */
9
+ password?: string;
10
+ /** Request timeout in seconds. Defaults to 30. */
11
+ timeoutSeconds?: number;
12
+ /** Hash algorithm to request the TSA use. Defaults to SHA-256. */
13
+ hashAlgorithm?: TimestampHashAlgorithm;
14
+ /** Include a nonce in the request (RFC 3161 §2.4.1). Defaults to true. */
15
+ useNonce?: boolean;
16
+ /** Ask the TSA to include its certificate in the response. Defaults to true. */
17
+ certReq?: boolean;
18
+ }
19
+ /**
20
+ * HTTP client for an RFC 3161 Time Stamp Authority. Construct with a
21
+ * URL (+ optional HTTP Basic auth), then call `requestTimestamp()` to
22
+ * turn a blob of data into a Timestamp.
23
+ */
24
+ export declare class TsaClient {
25
+ private handle;
26
+ private closed;
27
+ constructor(options: TsaClientOptions);
28
+ /**
29
+ * Request a timestamp over `data`. The TSA hashes the data using its
30
+ * configured algorithm and returns a TimeStampToken. Networking and
31
+ * hashing both happen inside the native call — this method blocks.
32
+ */
33
+ requestTimestamp(data: Uint8Array | Buffer): Timestamp;
34
+ /**
35
+ * Request a timestamp over an already-computed hash. Use this when the
36
+ * caller wants to hash the data themselves (e.g. signing the same
37
+ * bytes end-to-end). `hashAlgorithm` overrides the client's default
38
+ * for this single request.
39
+ */
40
+ requestTimestampHash(hash: Uint8Array | Buffer, hashAlgorithm?: TimestampHashAlgorithm): Timestamp;
41
+ /** Release the native client. Idempotent. */
42
+ close(): void;
43
+ private assertOpen;
44
+ }
@@ -0,0 +1,67 @@
1
+ // RFC 3161 Time Stamp Authority HTTP client wrapper for the Node binding.
2
+ //
3
+ // Mirrors the Python PyTsaClient, Go TsaClient, and C# TsaClient surfaces.
4
+ // (WASM TsaClient is intentionally unshipped — ureq, the HTTP driver in
5
+ // the Rust core, does not run under wasm32-unknown-unknown.)
6
+ import { getNative } from './native-loader.js';
7
+ import { Timestamp, TimestampHashAlgorithm } from './timestamp.js';
8
+ /**
9
+ * HTTP client for an RFC 3161 Time Stamp Authority. Construct with a
10
+ * URL (+ optional HTTP Basic auth), then call `requestTimestamp()` to
11
+ * turn a blob of data into a Timestamp.
12
+ */
13
+ export class TsaClient {
14
+ constructor(options) {
15
+ this.closed = false;
16
+ if (!options || typeof options.url !== 'string' || options.url.length === 0) {
17
+ throw new Error('TsaClient: options.url is required');
18
+ }
19
+ const handle = getNative().tsaClientCreate(options.url, options.username ?? '', options.password ?? '', options.timeoutSeconds ?? 30, options.hashAlgorithm ?? TimestampHashAlgorithm.Sha256, options.useNonce ?? true, options.certReq ?? true);
20
+ if (!handle) {
21
+ throw new Error('TsaClient: native create returned null');
22
+ }
23
+ this.handle = handle;
24
+ }
25
+ /**
26
+ * Request a timestamp over `data`. The TSA hashes the data using its
27
+ * configured algorithm and returns a TimeStampToken. Networking and
28
+ * hashing both happen inside the native call — this method blocks.
29
+ */
30
+ requestTimestamp(data) {
31
+ this.assertOpen();
32
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
33
+ const tsHandle = getNative().tsaRequestTimestamp(this.handle, buf);
34
+ if (!tsHandle) {
35
+ throw new Error('TsaClient.requestTimestamp: native returned null');
36
+ }
37
+ return Timestamp.fromNativeHandle(tsHandle);
38
+ }
39
+ /**
40
+ * Request a timestamp over an already-computed hash. Use this when the
41
+ * caller wants to hash the data themselves (e.g. signing the same
42
+ * bytes end-to-end). `hashAlgorithm` overrides the client's default
43
+ * for this single request.
44
+ */
45
+ requestTimestampHash(hash, hashAlgorithm = TimestampHashAlgorithm.Sha256) {
46
+ this.assertOpen();
47
+ const buf = Buffer.isBuffer(hash) ? hash : Buffer.from(hash);
48
+ const tsHandle = getNative().tsaRequestTimestampHash(this.handle, buf, hashAlgorithm);
49
+ if (!tsHandle) {
50
+ throw new Error('TsaClient.requestTimestampHash: native returned null');
51
+ }
52
+ return Timestamp.fromNativeHandle(tsHandle);
53
+ }
54
+ /** Release the native client. Idempotent. */
55
+ close() {
56
+ if (!this.closed && this.handle) {
57
+ getNative().tsaClientFree(this.handle);
58
+ this.closed = true;
59
+ this.handle = null;
60
+ }
61
+ }
62
+ assertOpen() {
63
+ if (this.closed) {
64
+ throw new Error('TsaClient: handle is closed');
65
+ }
66
+ }
67
+ }
@@ -14,7 +14,7 @@ export interface Table {
14
14
  * failure, etc.). */
15
15
  cells: (string | null)[][];
16
16
  }
17
- export type { SearchOptions, SearchResult, Metadata, DocumentInfo, EmbeddedFile, Annotation, NativePdfDocument, NativePdf, NativePdfPage, Rect, Point, Color, PdfElement, PdfText, PdfImage, PdfPath, PdfTable, PdfTableCell, TextAnnotation, HighlightAnnotation, LinkAnnotation, InkAnnotation, SquareAnnotation, CircleAnnotation, LineAnnotation, PolygonAnnotation, } from './native-bindings';
17
+ export type { Annotation, CircleAnnotation, Color, DocumentInfo, EmbeddedFile, HighlightAnnotation, InkAnnotation, LineAnnotation, LinkAnnotation, Metadata, NativePdf, NativePdfDocument, NativePdfPage, PdfElement, PdfImage, PdfPath, PdfTable, PdfTableCell, PdfText, Point, PolygonAnnotation, Rect, SearchOptions, SearchResult, SquareAnnotation, TextAnnotation, } from './native-bindings';
18
18
  /**
19
19
  * Page range specification for document operations
20
20
  */
@@ -103,3 +103,82 @@ export type StreamErrorCallback = (error: Error) => void;
103
103
  * Stream end callback
104
104
  */
105
105
  export type StreamEndCallback = () => void;
106
+ /**
107
+ * Horizontal alignment for wrapped text and table cells.
108
+ * Matches the C FFI integer encoding used by
109
+ * `pdf_page_builder_text_in_rect` and `pdf_page_builder_table`.
110
+ */
111
+ export declare enum Align {
112
+ Left = 0,
113
+ Center = 1,
114
+ Right = 2
115
+ }
116
+ /**
117
+ * Column descriptor for {@link TableSpec} / {@link StreamingTableConfig}.
118
+ */
119
+ export interface Column {
120
+ /** Header label rendered in bold (used only when `hasHeader`/`repeatHeader`). */
121
+ header: string;
122
+ /** Column width in PDF points. */
123
+ width: number;
124
+ /** Cell alignment (default {@link Align.Left}). */
125
+ align?: Align;
126
+ }
127
+ /**
128
+ * Buffered-table spec passed to `PageBuilder.table(...)`.
129
+ *
130
+ * All rows are held in JS memory and flushed to the native
131
+ * `pdf_page_builder_table` call in a single step.
132
+ */
133
+ export interface TableSpec {
134
+ /** Column layout — widths, alignments, and header labels. */
135
+ columns: Column[];
136
+ /** Body rows, each row has `columns.length` cells (nullable = empty). */
137
+ rows: Array<Array<string | null | undefined>>;
138
+ /** Promote the column headers to a styled first row. Defaults to true. */
139
+ hasHeader?: boolean;
140
+ }
141
+ /**
142
+ * Column-sizing strategy for streaming tables (issue #400).
143
+ *
144
+ * - `fixed` — use the `width` from each `Column` as-is (default).
145
+ * - `sample` — buffer the first N rows, measure content, then freeze
146
+ * column widths automatically. Supply `sampleRows`, `minColWidth`,
147
+ * and `maxColWidth` to tune.
148
+ */
149
+ export type TableMode = {
150
+ kind: 'fixed';
151
+ } | {
152
+ kind: 'sample';
153
+ sampleRows?: number;
154
+ minColWidthPt?: number;
155
+ maxColWidthPt?: number;
156
+ };
157
+ /**
158
+ * Configuration for the managed streaming-table adapter.
159
+ */
160
+ export interface StreamingTableConfig {
161
+ /** Column layout — widths, alignments, and header labels. */
162
+ columns: Column[];
163
+ /**
164
+ * Whether to repeat the header row on every page break. Defaults to true.
165
+ */
166
+ repeatHeader?: boolean;
167
+ /**
168
+ * Column-sizing mode. Defaults to `{ kind: 'fixed' }`.
169
+ */
170
+ mode?: TableMode;
171
+ /**
172
+ * Maximum rowspan a cell may carry. 0 or 1 (default) disables rowspan.
173
+ * Set to ≥2 to allow `pushRowSpan` cells to span multiple rows.
174
+ */
175
+ maxRowspan?: number;
176
+ }
177
+ /**
178
+ * A single cell value for `StreamingTable.pushRowSpan`.
179
+ * `rowspan == 1` is equivalent to a normal cell.
180
+ */
181
+ export interface SpanCell {
182
+ text: string;
183
+ rowspan: number;
184
+ }
@@ -1,4 +1,17 @@
1
1
  /**
2
2
  * Common type definitions and utilities
3
3
  */
4
- export {};
4
+ // ============================================================================
5
+ // DocumentBuilder — table primitives (v0.3.39, issue #393)
6
+ // ============================================================================
7
+ /**
8
+ * Horizontal alignment for wrapped text and table cells.
9
+ * Matches the C FFI integer encoding used by
10
+ * `pdf_page_builder_text_in_rect` and `pdf_page_builder_table`.
11
+ */
12
+ export var Align;
13
+ (function (Align) {
14
+ Align[Align["Left"] = 0] = "Left";
15
+ Align[Align["Center"] = 1] = "Center";
16
+ Align[Align["Right"] = 2] = "Right";
17
+ })(Align || (Align = {}));
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Type definitions index - re-exports all types for easy consumption
3
3
  */
4
- export * from './native-bindings';
5
4
  export * from './common';
5
+ export * from './native-bindings';
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Type definitions index - re-exports all types for easy consumption
3
3
  */
4
- export * from './native-bindings.js';
5
4
  export * from './common.js';
5
+ export * from './native-bindings.js';
@@ -88,8 +88,10 @@ export class BaseManager extends EventEmitter {
88
88
  }
89
89
  invalidateCache(pattern) {
90
90
  if (pattern) {
91
- const keys = Array.from(this.cache.keys()).filter(k => k.includes(pattern));
92
- keys.forEach(k => this.cache.delete(k));
91
+ const keys = Array.from(this.cache.keys()).filter((k) => k.includes(pattern));
92
+ keys.forEach((k) => {
93
+ this.cache.delete(k);
94
+ });
93
95
  }
94
96
  else {
95
97
  this.cache.clear();
@@ -2,5 +2,5 @@
2
2
  * Worker Threads Module
3
3
  * Exports worker pool and types for parallel PDF processing
4
4
  */
5
+ export type { WorkerResult, WorkerTask } from './pool.js';
5
6
  export { WorkerPool, workerPool } from './pool.js';
6
- export type { WorkerTask, WorkerResult } from './pool.js';
@@ -2,10 +2,10 @@
2
2
  * Worker Thread Pool Manager
3
3
  * Enables non-blocking parallel PDF processing
4
4
  */
5
- import { Worker } from 'worker_threads';
6
5
  import os from 'os';
7
6
  import path from 'path';
8
7
  import { fileURLToPath } from 'url';
8
+ import { Worker } from 'worker_threads';
9
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
10
  /**
11
11
  * Thread pool for parallel PDF processing
@@ -151,9 +151,7 @@ export class WorkerPool {
151
151
  }
152
152
  }
153
153
  // Terminate all workers
154
- await Promise.all(this.workers.map((worker) => worker
155
- .terminate()
156
- .catch((error) => console.warn('Error terminating worker:', error))));
154
+ await Promise.all(this.workers.map((worker) => worker.terminate().catch((error) => console.warn('Error terminating worker:', error))));
157
155
  this.cleanup();
158
156
  }
159
157
  cleanup() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-oxide",
3
- "version": "0.3.37",
3
+ "version": "0.3.39",
4
4
  "type": "module",
5
5
  "description": "High-performance PDF parsing and text extraction library — prebuilt native bindings, no build toolchain required",
6
6
  "main": "lib/index.js",
@@ -14,7 +14,13 @@
14
14
  "clean:ts": "rimraf lib/",
15
15
  "clean": "npm run clean:ts && node-gyp clean",
16
16
  "prepack": "npm run build:ts",
17
- "test": "node --test tests/smoke.test.mjs"
17
+ "lint": "biome check .",
18
+ "lint:fix": "biome check --write .",
19
+ "format": "biome format --write .",
20
+ "check:publint": "publint",
21
+ "check:types": "attw --pack . --ignore-rules=cjs-resolves-to-esm",
22
+ "audit:prod": "npm audit --omit=dev --audit-level=high",
23
+ "test": "node --test tests/smoke.test.mjs tests/feature-guard.test.mjs tests/api-coverage.test.mjs tests/html-css.test.mjs tests/document-builder.test.mjs tests/document-editor.test.mjs tests/render-options.test.mjs tests/tables.test.mjs"
18
24
  },
19
25
  "files": [
20
26
  "lib/",
@@ -36,7 +42,7 @@
36
42
  "homepage": "https://github.com/yfedoseev/pdf_oxide",
37
43
  "repository": {
38
44
  "type": "git",
39
- "url": "https://github.com/yfedoseev/pdf_oxide.git",
45
+ "url": "git+https://github.com/yfedoseev/pdf_oxide.git",
40
46
  "directory": "js"
41
47
  },
42
48
  "engines": {
@@ -44,20 +50,20 @@
44
50
  },
45
51
  "exports": {
46
52
  ".": {
47
- "import": "./lib/index.js",
48
- "types": "./lib/index.d.ts"
53
+ "types": "./lib/index.d.ts",
54
+ "import": "./lib/index.js"
49
55
  },
50
56
  "./builders": {
51
- "import": "./lib/builders/index.js",
52
- "types": "./lib/builders/index.d.ts"
57
+ "types": "./lib/builders/index.d.ts",
58
+ "import": "./lib/builders/index.js"
53
59
  },
54
60
  "./managers": {
55
- "import": "./lib/managers/index.js",
56
- "types": "./lib/managers/index.d.ts"
61
+ "types": "./lib/managers/index.d.ts",
62
+ "import": "./lib/managers/index.js"
57
63
  },
58
64
  "./errors": {
59
- "import": "./lib/errors.js",
60
- "types": "./lib/errors.d.ts"
65
+ "types": "./lib/errors.d.ts",
66
+ "import": "./lib/errors.js"
61
67
  }
62
68
  },
63
69
  "devDependencies": {
Binary file
Binary file
Binary file