@cj-tech-master/excelts 9.1.0 → 9.2.0

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 (147) hide show
  1. package/README.md +16 -1
  2. package/dist/browser/modules/archive/compression/crc32.js +1 -1
  3. package/dist/browser/modules/archive/crypto/aes.d.ts +0 -8
  4. package/dist/browser/modules/archive/crypto/aes.js +1 -20
  5. package/dist/browser/modules/archive/crypto/index.d.ts +2 -1
  6. package/dist/browser/modules/archive/crypto/index.js +3 -1
  7. package/dist/browser/modules/csv/parse/row-processor.d.ts +1 -1
  8. package/dist/browser/modules/csv/worker/worker-script.generated.js +1 -1
  9. package/dist/browser/modules/excel/utils/cell-matrix.js +1 -0
  10. package/dist/browser/modules/excel/utils/encryptor.browser.d.ts +4 -5
  11. package/dist/browser/modules/excel/utils/encryptor.browser.js +7 -12
  12. package/dist/browser/modules/excel/utils/encryptor.d.ts +1 -1
  13. package/dist/browser/modules/excel/utils/encryptor.js +4 -7
  14. package/dist/browser/modules/pdf/builder/document-builder.d.ts +517 -0
  15. package/dist/browser/modules/pdf/builder/document-builder.js +1493 -0
  16. package/dist/browser/modules/pdf/builder/form-appearance.d.ts +56 -0
  17. package/dist/browser/modules/pdf/builder/form-appearance.js +140 -0
  18. package/dist/browser/modules/pdf/builder/image-utils.d.ts +39 -0
  19. package/dist/browser/modules/pdf/builder/image-utils.js +129 -0
  20. package/dist/browser/modules/pdf/builder/pdf-editor.d.ts +230 -0
  21. package/dist/browser/modules/pdf/builder/pdf-editor.js +1574 -0
  22. package/dist/browser/modules/pdf/builder/resource-merger.d.ts +41 -0
  23. package/dist/browser/modules/pdf/builder/resource-merger.js +258 -0
  24. package/dist/browser/modules/pdf/core/digital-signature.d.ts +109 -0
  25. package/dist/browser/modules/pdf/core/digital-signature.js +659 -0
  26. package/dist/browser/modules/pdf/core/encryption.js +8 -7
  27. package/dist/browser/modules/pdf/core/pdf-object.d.ts +11 -0
  28. package/dist/browser/modules/pdf/core/pdf-object.js +38 -0
  29. package/dist/browser/modules/pdf/core/pdf-stream.d.ts +32 -0
  30. package/dist/browser/modules/pdf/core/pdf-stream.js +66 -0
  31. package/dist/browser/modules/pdf/core/pdf-writer.d.ts +55 -1
  32. package/dist/browser/modules/pdf/core/pdf-writer.js +271 -6
  33. package/dist/browser/modules/pdf/core/pdfa.d.ts +62 -0
  34. package/dist/browser/modules/pdf/core/pdfa.js +261 -0
  35. package/dist/browser/modules/pdf/index.d.ts +11 -0
  36. package/dist/browser/modules/pdf/index.js +9 -0
  37. package/dist/browser/modules/pdf/reader/bookmark-extractor.d.ts +35 -0
  38. package/dist/browser/modules/pdf/reader/bookmark-extractor.js +324 -0
  39. package/dist/browser/modules/pdf/reader/pdf-decrypt.js +6 -5
  40. package/dist/browser/modules/pdf/reader/pdf-reader.d.ts +17 -0
  41. package/dist/browser/modules/pdf/reader/pdf-reader.js +26 -2
  42. package/dist/browser/modules/pdf/reader/table-extractor.d.ts +69 -0
  43. package/dist/browser/modules/pdf/reader/table-extractor.js +365 -0
  44. package/dist/browser/modules/pdf/render/layout-engine.d.ts +21 -1
  45. package/dist/browser/modules/pdf/render/layout-engine.js +112 -5
  46. package/dist/browser/modules/pdf/render/page-renderer.d.ts +2 -9
  47. package/dist/browser/modules/pdf/render/page-renderer.js +62 -103
  48. package/dist/browser/modules/pdf/render/pdf-exporter.js +2 -61
  49. package/dist/browser/modules/pdf/render/style-converter.d.ts +4 -0
  50. package/dist/browser/modules/pdf/render/style-converter.js +1 -1
  51. package/dist/browser/modules/pdf/types.d.ts +14 -1
  52. package/dist/browser/modules/stream/browser/readable.js +8 -2
  53. package/dist/browser/utils/crypto.browser.d.ts +64 -0
  54. package/dist/browser/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +91 -101
  55. package/dist/browser/utils/crypto.d.ts +97 -0
  56. package/dist/browser/utils/crypto.js +209 -0
  57. package/dist/cjs/modules/archive/compression/crc32.js +1 -1
  58. package/dist/cjs/modules/archive/crypto/aes.js +2 -23
  59. package/dist/cjs/modules/archive/crypto/index.js +3 -1
  60. package/dist/cjs/modules/csv/worker/worker-script.generated.js +1 -1
  61. package/dist/cjs/modules/excel/utils/cell-matrix.js +1 -0
  62. package/dist/cjs/modules/excel/utils/encryptor.browser.js +7 -12
  63. package/dist/cjs/modules/excel/utils/encryptor.js +4 -10
  64. package/dist/cjs/modules/pdf/builder/document-builder.js +1532 -0
  65. package/dist/cjs/modules/pdf/builder/form-appearance.js +145 -0
  66. package/dist/cjs/modules/pdf/builder/image-utils.js +135 -0
  67. package/dist/cjs/modules/pdf/builder/pdf-editor.js +1612 -0
  68. package/dist/cjs/modules/pdf/builder/resource-merger.js +263 -0
  69. package/dist/cjs/modules/pdf/core/digital-signature.js +667 -0
  70. package/dist/cjs/modules/pdf/core/encryption.js +8 -7
  71. package/dist/cjs/modules/pdf/core/pdf-object.js +38 -0
  72. package/dist/cjs/modules/pdf/core/pdf-stream.js +66 -0
  73. package/dist/cjs/modules/pdf/core/pdf-writer.js +272 -6
  74. package/dist/cjs/modules/pdf/core/pdfa.js +266 -0
  75. package/dist/cjs/modules/pdf/index.js +19 -1
  76. package/dist/cjs/modules/pdf/reader/bookmark-extractor.js +327 -0
  77. package/dist/cjs/modules/pdf/reader/pdf-decrypt.js +6 -5
  78. package/dist/cjs/modules/pdf/reader/pdf-reader.js +26 -2
  79. package/dist/cjs/modules/pdf/reader/table-extractor.js +368 -0
  80. package/dist/cjs/modules/pdf/render/layout-engine.js +113 -4
  81. package/dist/cjs/modules/pdf/render/page-renderer.js +63 -105
  82. package/dist/cjs/modules/pdf/render/pdf-exporter.js +3 -62
  83. package/dist/cjs/modules/pdf/render/style-converter.js +1 -0
  84. package/dist/cjs/modules/stream/browser/readable.js +8 -2
  85. package/dist/cjs/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +95 -102
  86. package/dist/cjs/utils/crypto.js +228 -0
  87. package/dist/esm/modules/archive/compression/crc32.js +1 -1
  88. package/dist/esm/modules/archive/crypto/aes.js +1 -20
  89. package/dist/esm/modules/archive/crypto/index.js +3 -1
  90. package/dist/esm/modules/csv/worker/worker-script.generated.js +1 -1
  91. package/dist/esm/modules/excel/utils/cell-matrix.js +1 -0
  92. package/dist/esm/modules/excel/utils/encryptor.browser.js +7 -12
  93. package/dist/esm/modules/excel/utils/encryptor.js +4 -7
  94. package/dist/esm/modules/pdf/builder/document-builder.js +1493 -0
  95. package/dist/esm/modules/pdf/builder/form-appearance.js +140 -0
  96. package/dist/esm/modules/pdf/builder/image-utils.js +129 -0
  97. package/dist/esm/modules/pdf/builder/pdf-editor.js +1574 -0
  98. package/dist/esm/modules/pdf/builder/resource-merger.js +258 -0
  99. package/dist/esm/modules/pdf/core/digital-signature.js +659 -0
  100. package/dist/esm/modules/pdf/core/encryption.js +8 -7
  101. package/dist/esm/modules/pdf/core/pdf-object.js +38 -0
  102. package/dist/esm/modules/pdf/core/pdf-stream.js +66 -0
  103. package/dist/esm/modules/pdf/core/pdf-writer.js +271 -6
  104. package/dist/esm/modules/pdf/core/pdfa.js +261 -0
  105. package/dist/esm/modules/pdf/index.js +9 -0
  106. package/dist/esm/modules/pdf/reader/bookmark-extractor.js +324 -0
  107. package/dist/esm/modules/pdf/reader/pdf-decrypt.js +6 -5
  108. package/dist/esm/modules/pdf/reader/pdf-reader.js +26 -2
  109. package/dist/esm/modules/pdf/reader/table-extractor.js +365 -0
  110. package/dist/esm/modules/pdf/render/layout-engine.js +112 -5
  111. package/dist/esm/modules/pdf/render/page-renderer.js +62 -103
  112. package/dist/esm/modules/pdf/render/pdf-exporter.js +2 -61
  113. package/dist/esm/modules/pdf/render/style-converter.js +1 -1
  114. package/dist/esm/modules/stream/browser/readable.js +8 -2
  115. package/dist/esm/{modules/pdf/core/crypto.js → utils/crypto.browser.js} +91 -101
  116. package/dist/esm/utils/crypto.js +209 -0
  117. package/dist/iife/excelts.iife.js +1248 -1074
  118. package/dist/iife/excelts.iife.js.map +1 -1
  119. package/dist/iife/excelts.iife.min.js +53 -54
  120. package/dist/types/modules/archive/crypto/aes.d.ts +0 -8
  121. package/dist/types/modules/archive/crypto/index.d.ts +2 -1
  122. package/dist/types/modules/csv/parse/row-processor.d.ts +1 -1
  123. package/dist/types/modules/excel/utils/encryptor.browser.d.ts +4 -5
  124. package/dist/types/modules/excel/utils/encryptor.d.ts +1 -1
  125. package/dist/types/modules/pdf/builder/document-builder.d.ts +517 -0
  126. package/dist/types/modules/pdf/builder/form-appearance.d.ts +56 -0
  127. package/dist/types/modules/pdf/builder/image-utils.d.ts +39 -0
  128. package/dist/types/modules/pdf/builder/pdf-editor.d.ts +230 -0
  129. package/dist/types/modules/pdf/builder/resource-merger.d.ts +41 -0
  130. package/dist/types/modules/pdf/core/digital-signature.d.ts +109 -0
  131. package/dist/types/modules/pdf/core/pdf-object.d.ts +11 -0
  132. package/dist/types/modules/pdf/core/pdf-stream.d.ts +32 -0
  133. package/dist/types/modules/pdf/core/pdf-writer.d.ts +55 -1
  134. package/dist/types/modules/pdf/core/pdfa.d.ts +62 -0
  135. package/dist/types/modules/pdf/index.d.ts +11 -0
  136. package/dist/types/modules/pdf/reader/bookmark-extractor.d.ts +35 -0
  137. package/dist/types/modules/pdf/reader/pdf-reader.d.ts +17 -0
  138. package/dist/types/modules/pdf/reader/table-extractor.d.ts +69 -0
  139. package/dist/types/modules/pdf/render/layout-engine.d.ts +21 -1
  140. package/dist/types/modules/pdf/render/page-renderer.d.ts +2 -9
  141. package/dist/types/modules/pdf/render/style-converter.d.ts +4 -0
  142. package/dist/types/modules/pdf/types.d.ts +14 -1
  143. package/dist/types/utils/crypto.browser.d.ts +64 -0
  144. package/dist/types/utils/crypto.d.ts +97 -0
  145. package/package.json +110 -111
  146. package/dist/browser/modules/pdf/core/crypto.d.ts +0 -65
  147. package/dist/types/modules/pdf/core/crypto.d.ts +0 -65
@@ -0,0 +1,230 @@
1
+ /**
2
+ * PDF editor — modify existing PDF documents.
3
+ *
4
+ * Supports:
5
+ * - Adding new pages with free-form content
6
+ * - Adding text/shapes/images to existing pages (overlay)
7
+ * - Filling form fields (AcroForm)
8
+ * - Copying pages from other PDFs (merge)
9
+ * - Preserving page properties (Rotate, CropBox, etc.) and metadata
10
+ *
11
+ * Note: save() rebuilds the PDF from scratch rather than using incremental
12
+ * updates. This is simpler and more reliable but means object numbers change
13
+ * and existing digital signatures will be invalidated.
14
+ *
15
+ * @example Edit an existing PDF:
16
+ * ```typescript
17
+ * import { PdfEditor } from "@cj-tech-master/excelts/pdf";
18
+ *
19
+ * const editor = PdfEditor.load(existingPdfBytes);
20
+ * editor.getPage(0).drawText("APPROVED", { x: 200, y: 400, fontSize: 48, color: { r: 0, g: 0.5, b: 0 } });
21
+ * editor.setFormField("name", "John Doe");
22
+ * const result = await editor.save();
23
+ * ```
24
+ */
25
+ import type { PdfContentStream } from "../core/pdf-stream.js";
26
+ import type { PdfFormField } from "../reader/form-extractor.js";
27
+ import { PdfPageBuilder } from "./document-builder.js";
28
+ import type { DrawTextOptions, DrawRectOptions, DrawCircleOptions, DrawEllipseOptions, DrawLineOptions, DrawImageOptions, DrawPathOptions, PathOp, PageOptions, AnnotationOptions, FormFieldOptions, PdfSignatureOptions } from "./document-builder.js";
29
+ /** Options for loading a PDF for editing. */
30
+ export interface LoadOptions {
31
+ /** Password for encrypted PDFs. */
32
+ password?: string;
33
+ }
34
+ /**
35
+ * Proxy for an existing page that allows overlaying new content.
36
+ * New content is drawn on top of existing content via a separate content stream.
37
+ */
38
+ export declare class PdfEditorPage {
39
+ /** Page width in points. */
40
+ get width(): number;
41
+ /** Page height in points. */
42
+ get height(): number;
43
+ /**
44
+ * Measure the width of a text string in points.
45
+ */
46
+ measureText(text: string, options?: {
47
+ fontSize?: number;
48
+ fontFamily?: string;
49
+ bold?: boolean;
50
+ italic?: boolean;
51
+ }): number;
52
+ /**
53
+ * Draw text on this existing page (overlaid on top).
54
+ */
55
+ drawText(text: string, options: DrawTextOptions): this;
56
+ /**
57
+ * Draw a rectangle on this existing page.
58
+ */
59
+ drawRect(options: DrawRectOptions): this;
60
+ /**
61
+ * Draw a circle on this existing page.
62
+ */
63
+ drawCircle(options: DrawCircleOptions): this;
64
+ /**
65
+ * Draw an ellipse on this existing page.
66
+ */
67
+ drawEllipse(options: DrawEllipseOptions): this;
68
+ /**
69
+ * Draw a line on this existing page.
70
+ */
71
+ drawLine(options: DrawLineOptions): this;
72
+ /**
73
+ * Draw an image on this existing page.
74
+ */
75
+ drawImage(options: DrawImageOptions): this;
76
+ /**
77
+ * Get the raw overlay content stream.
78
+ */
79
+ getContentStream(): PdfContentStream;
80
+ /**
81
+ * Add an annotation to this existing page (Highlight, Text, FreeText, Stamp, etc.).
82
+ */
83
+ addAnnotation(options: AnnotationOptions): this;
84
+ /**
85
+ * Add a form field to this existing page.
86
+ */
87
+ addFormField(options: FormFieldOptions): this;
88
+ /**
89
+ * Draw an SVG path on this existing page.
90
+ */
91
+ drawSvgPath(d: string, options?: DrawPathOptions): this;
92
+ /**
93
+ * Draw a complex path from a list of path operations.
94
+ */
95
+ drawPath(ops: PathOp[], options?: DrawPathOptions): this;
96
+ }
97
+ /**
98
+ * Editor for modifying existing PDF documents.
99
+ *
100
+ * Load an existing PDF, overlay content on existing pages, fill form fields,
101
+ * add new pages, copy pages from other documents, and save.
102
+ */
103
+ export declare class PdfEditor {
104
+ private _doc;
105
+ private _password;
106
+ private _pages;
107
+ private _newPages;
108
+ private _fontManager;
109
+ private _formFieldUpdates;
110
+ private _copiedPages;
111
+ private _signaturePlaceholder;
112
+ private constructor();
113
+ /**
114
+ * Load a PDF for editing.
115
+ *
116
+ * @param data - Raw PDF file bytes
117
+ * @param options - Load options (e.g., password)
118
+ * @returns A PdfEditor instance
119
+ */
120
+ static load(data: Uint8Array, options?: LoadOptions): PdfEditor;
121
+ /** Number of existing pages. */
122
+ get pageCount(): number;
123
+ /**
124
+ * Get an existing page for editing (overlaying content).
125
+ *
126
+ * @param index - 0-based page index
127
+ */
128
+ getPage(index: number): PdfEditorPage;
129
+ /**
130
+ * Add a new blank page to the end of the document.
131
+ */
132
+ addPage(options?: PageOptions): PdfPageBuilder;
133
+ /**
134
+ * Remove a page from the document.
135
+ *
136
+ * @param index - 0-based page index (of original pages only)
137
+ */
138
+ removePage(index: number): this;
139
+ /**
140
+ * Set the rotation of an existing page.
141
+ *
142
+ * @param index - 0-based page index (of original pages only)
143
+ * @param degrees - Rotation in degrees (must be 0, 90, 180, or 270)
144
+ */
145
+ rotatePage(index: number, degrees: number): this;
146
+ /**
147
+ * Split the document: save each page (or a subset) as a separate PDF.
148
+ *
149
+ * @param pageIndices - 0-based page indices to extract. Omit to split all pages.
150
+ * @returns Array of Uint8Array, one per requested page.
151
+ */
152
+ splitPages(pageIndices?: number[]): Promise<Uint8Array[]>;
153
+ /**
154
+ * Embed a TrueType font for Unicode/CJK support.
155
+ */
156
+ embedFont(fontBytes: Uint8Array): this;
157
+ /**
158
+ * Set the value of a form field.
159
+ * The field is identified by its fully qualified name (e.g., "form.address.city").
160
+ *
161
+ * @param fieldName - Fully qualified field name
162
+ * @param value - New value to set
163
+ */
164
+ setFormField(fieldName: string, value: string): this;
165
+ /**
166
+ * Set multiple form field values at once.
167
+ *
168
+ * @param fields - Object mapping field names to values
169
+ */
170
+ setFormFields(fields: Record<string, string>): this;
171
+ /**
172
+ * Get current form fields (before any modifications).
173
+ */
174
+ getFormFields(): PdfFormField[];
175
+ /**
176
+ * Copy pages from another PDF document into this document.
177
+ *
178
+ * @param sourcePdf - Raw bytes of the source PDF
179
+ * @param pageIndices - 0-based page indices to copy. Omit to copy all pages.
180
+ * @param options - Load options for the source PDF (e.g., password)
181
+ */
182
+ copyPagesFrom(sourcePdf: Uint8Array, pageIndices?: number[], options?: LoadOptions): this;
183
+ /**
184
+ * Save the modified PDF.
185
+ *
186
+ * Rebuilds the PDF from scratch — content streams, resources, and page
187
+ * properties are deep-cloned into a new document. Original metadata and
188
+ * XMP streams are preserved. Digital signatures will be invalidated.
189
+ *
190
+ * @returns The modified PDF as Uint8Array
191
+ */
192
+ save(): Promise<Uint8Array>;
193
+ /**
194
+ * Save the modified PDF using incremental update.
195
+ *
196
+ * Appends new/modified objects after the original PDF bytes, preserving the
197
+ * original data byte-for-byte. This is ideal for overlays and form field
198
+ * updates on existing pages — it preserves digital signatures on unmodified
199
+ * content and produces smaller output.
200
+ *
201
+ * Falls back to {@link save} (full rebuild) if structural changes are
202
+ * present (new pages, copied pages, or removed pages).
203
+ *
204
+ * @returns The modified PDF as Uint8Array
205
+ */
206
+ saveIncremental(): Promise<Uint8Array>;
207
+ /** Page-level keys to preserve when rebuilding page dicts. */
208
+ private static readonly _PAGE_PRESERVE_KEYS;
209
+ /**
210
+ * Sign this PDF with a digital signature.
211
+ *
212
+ * Performs a full save with an embedded PKCS#7 signature placeholder,
213
+ * then fills in the real CMS SignedData.
214
+ *
215
+ * @param options - Certificate, private key, and optional signer metadata
216
+ * @returns The signed PDF as Uint8Array
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const editor = PdfEditor.load(pdfBytes);
221
+ * const signed = await editor.sign({
222
+ * certificate: certDerBytes,
223
+ * privateKey: pkcs8DerBytes,
224
+ * name: "Jane Doe",
225
+ * reason: "Approval"
226
+ * });
227
+ * ```
228
+ */
229
+ sign(options: PdfSignatureOptions): Promise<Uint8Array>;
230
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * PDF resource dictionary merger — structured merging at the parsed object level.
3
+ *
4
+ * Instead of manipulating serialized PDF dict strings directly, this module
5
+ * parses resource dicts into a structured `PdfResourceDict` (nested Maps),
6
+ * merges them, and serializes back to PDF dict strings.
7
+ */
8
+ /**
9
+ * Structured representation of a PDF resource dictionary.
10
+ *
11
+ * Outer key: category name (e.g. `Font`, `XObject`, `ExtGState`, `ColorSpace`,
12
+ * `Pattern`, `Shading`, `Properties`).
13
+ * Inner key: resource name (e.g. `F1`, `Im1`, `GS0`).
14
+ * Value: serialized ref or value string (e.g. `3 0 R`, `/DeviceRGB`).
15
+ *
16
+ * Categories whose value is not a sub-dict (e.g. `/ProcSet [/PDF /Text]`)
17
+ * are stored with an empty inner key `""` mapping to the raw value string.
18
+ */
19
+ export type PdfResourceDict = Map<string, Map<string, string>>;
20
+ /**
21
+ * Merge two parsed resource dicts. For sub-dict categories, entries are
22
+ * combined; overlay entries win on name collision. For non-sub-dict categories,
23
+ * the overlay value replaces the original.
24
+ */
25
+ export declare function mergeResourceDicts(original: PdfResourceDict, overlay: PdfResourceDict): PdfResourceDict;
26
+ /**
27
+ * Parse a serialized PDF resource dict string into a structured `PdfResourceDict`.
28
+ *
29
+ * Handles top-level entries like:
30
+ * ```
31
+ * << /Font << /F1 3 0 R /F2 5 0 R >> /XObject << /Im1 7 0 R >> /ProcSet [/PDF /Text] >>
32
+ * ```
33
+ *
34
+ * Sub-dict categories (`Font`, `XObject`, etc.) are parsed into inner name→value maps.
35
+ * Other categories are stored with a single entry keyed by `""`.
36
+ */
37
+ export declare function parseResourceDict(dictStr: string): PdfResourceDict;
38
+ /**
39
+ * Serialize a structured `PdfResourceDict` back to a PDF dict string.
40
+ */
41
+ export declare function serializeResourceDict(dict: PdfResourceDict): string;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * PDF digital signature — verification and creation.
3
+ *
4
+ * Implements:
5
+ * - ASN.1 DER decode/encode (shared codec)
6
+ * - PKCS#7 / CMS SignedData parse and build
7
+ * - X.509 certificate public key extraction
8
+ * - PDF /ByteRange extraction and hash computation
9
+ * - Signature verification (RSA PKCS#1 v1.5 + SHA-256)
10
+ * - Signature creation (with ByteRange placeholder/backfill)
11
+ *
12
+ * Uses platform-native RSA via `@utils/crypto` (node:crypto on Node,
13
+ * Web Crypto API in browsers).
14
+ *
15
+ * @see RFC 5652 — CMS (Cryptographic Message Syntax)
16
+ * @see ITU-T X.690 — ASN.1 DER encoding rules
17
+ * @see ISO 32000-2:2020 §12.8 — Digital Signatures in PDF
18
+ */
19
+ /** Parsed ASN.1 node. */
20
+ export interface Asn1Node {
21
+ tag: number;
22
+ /** Raw bytes of the value (for primitive types). */
23
+ bytes: Uint8Array;
24
+ /** Child nodes (for constructed types). */
25
+ children: Asn1Node[];
26
+ }
27
+ /**
28
+ * Parse ASN.1 DER data from the root.
29
+ */
30
+ export declare function asn1Parse(data: Uint8Array): Asn1Node;
31
+ /** Parsed CMS SignedData info for verification. */
32
+ export interface CmsSignedData {
33
+ /** The signer's certificate (DER). */
34
+ certificate: Uint8Array;
35
+ /** The signature value. */
36
+ signature: Uint8Array;
37
+ /** The digest algorithm OID. */
38
+ digestAlgorithmOid: string;
39
+ /** The signed attributes (DER-encoded SET for hash computation). */
40
+ signedAttrsRaw: Uint8Array;
41
+ /** The message digest from signed attributes. */
42
+ messageDigest: Uint8Array;
43
+ }
44
+ /**
45
+ * Parse a PKCS#7 / CMS SignedData structure from DER bytes.
46
+ * Extracts the first signer's info for verification.
47
+ */
48
+ export declare function parseCmsSignedData(derBytes: Uint8Array): CmsSignedData;
49
+ /** Options for building a CMS SignedData for PDF signing. */
50
+ export interface SignOptions {
51
+ /** DER-encoded X.509 certificate. */
52
+ certificate: Uint8Array;
53
+ /** DER-encoded PKCS#8 private key. */
54
+ privateKey: Uint8Array;
55
+ /** The data to sign (the PDF byte ranges). */
56
+ data: Uint8Array;
57
+ }
58
+ /**
59
+ * Build a CMS SignedData (PKCS#7) structure for a PDF signature.
60
+ *
61
+ * Uses SHA-256 for digest and RSA PKCS#1 v1.5 for signing.
62
+ * The signature is created over signed attributes that include
63
+ * the content-type, message-digest, and signing-time.
64
+ */
65
+ export declare function buildCmsSignedData(options: SignOptions): Promise<Uint8Array>;
66
+ /** Result of verifying a PDF signature. */
67
+ export interface SignatureVerificationResult {
68
+ /** Whether the signature is cryptographically valid. */
69
+ valid: boolean;
70
+ /** Whether the signed byte ranges cover the entire file (no unsigned gaps). */
71
+ coversWholeFile: boolean;
72
+ /** Digest algorithm used. */
73
+ digestAlgorithm: string;
74
+ /** Reason for failure, if any. */
75
+ reason?: string;
76
+ }
77
+ /**
78
+ * Verify a digital signature in a PDF document.
79
+ *
80
+ * @param pdfData - The complete PDF file bytes
81
+ * @param signatureHex - The hex-encoded PKCS#7 signature from the /Contents field
82
+ * @param byteRange - The /ByteRange array [offset1, length1, offset2, length2]
83
+ */
84
+ export declare function verifyPdfSignature(pdfData: Uint8Array, signatureHex: string, byteRange: [number, number, number, number]): Promise<SignatureVerificationResult>;
85
+ /**
86
+ * Create a PDF signature dictionary string with a placeholder /Contents.
87
+ * Returns the dict string and the placeholder that will be replaced.
88
+ *
89
+ * @param signerName - Optional signer name for /Name field
90
+ * @param reason - Optional reason for /Reason field
91
+ */
92
+ export declare function buildSignatureDictPlaceholder(options?: {
93
+ name?: string;
94
+ reason?: string;
95
+ location?: string;
96
+ contactInfo?: string;
97
+ }): {
98
+ dictString: string;
99
+ placeholder: string;
100
+ };
101
+ /**
102
+ * Patch a PDF with a real signature after the /ByteRange placeholder has been written.
103
+ *
104
+ * @param pdfBytes - The PDF bytes with placeholder /Contents and /ByteRange
105
+ * @param certificate - DER-encoded X.509 certificate
106
+ * @param privateKey - DER-encoded PKCS#8 private key
107
+ * @returns The signed PDF bytes
108
+ */
109
+ export declare function signPdf(pdfBytes: Uint8Array, certificate: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array>;
@@ -49,6 +49,13 @@ export declare function pdfDate(date: Date): string;
49
49
  */
50
50
  export declare class PdfDict {
51
51
  private entries;
52
+ /** When set, toString() returns this raw string. set() appends/replaces entries within it. */
53
+ private _raw;
54
+ /**
55
+ * Create a PdfDict that wraps a pre-serialized dictionary string.
56
+ * toString() returns the raw string (with any set() overrides applied).
57
+ */
58
+ static fromRawString(raw: string): PdfDict;
52
59
  /**
53
60
  * Set a dictionary entry. The key should NOT include the leading /.
54
61
  * The value should be a pre-serialized PDF value string.
@@ -58,6 +65,10 @@ export declare class PdfDict {
58
65
  * Conditionally set a dictionary entry.
59
66
  */
60
67
  setIf(condition: boolean, key: string, value: string): this;
68
+ /**
69
+ * Remove a dictionary entry by key.
70
+ */
71
+ delete(key: string): this;
61
72
  /**
62
73
  * Serialize to a PDF dictionary string.
63
74
  */
@@ -75,6 +75,21 @@ export declare class PdfContentStream {
75
75
  * PDF convention: (x, y) is the lower-left corner.
76
76
  */
77
77
  rect(x: number, y: number, width: number, height: number): this;
78
+ /**
79
+ * Append a cubic Bezier curve to the current path.
80
+ * From current point to (x3, y3), with control points (x1, y1) and (x2, y2).
81
+ */
82
+ curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): this;
83
+ /**
84
+ * Append a cubic Bezier curve where the first control point is the current point.
85
+ * From current point to (x3, y3), with control points (current, y1) and (x2, y2).
86
+ */
87
+ curveToV(x2: number, y2: number, x3: number, y3: number): this;
88
+ /**
89
+ * Append a cubic Bezier curve where the second control point equals (x3, y3).
90
+ * From current point to (x3, y3), with control point (x1, y1).
91
+ */
92
+ curveToY(x1: number, y1: number, x3: number, y3: number): this;
78
93
  /**
79
94
  * Stroke the current path.
80
95
  */
@@ -184,6 +199,23 @@ export declare class PdfContentStream {
184
199
  * Draw a stroked line.
185
200
  */
186
201
  drawLine(x1: number, y1: number, x2: number, y2: number, color: PdfColor, lineWidth: number, dashPattern?: number[]): this;
202
+ /**
203
+ * Append an ellipse to the current path using 4 cubic Bezier curves.
204
+ * (cx, cy) is the center; rx, ry are the radii.
205
+ *
206
+ * Uses the standard kappa = 4 * (sqrt(2) - 1) / 3 ≈ 0.5522847 approximation.
207
+ */
208
+ ellipse(cx: number, cy: number, rx: number, ry: number): this;
209
+ /**
210
+ * Append a circle to the current path.
211
+ * (cx, cy) is the center; r is the radius.
212
+ */
213
+ circle(cx: number, cy: number, r: number): this;
214
+ /**
215
+ * Append a rounded rectangle to the current path.
216
+ * (x, y) is the lower-left corner; r is the corner radius.
217
+ */
218
+ roundedRect(x: number, y: number, width: number, height: number, r: number): this;
187
219
  /**
188
220
  * Get the content stream as a string.
189
221
  */
@@ -8,6 +8,9 @@
8
8
  * 3. Cross-reference table
9
9
  * 4. Trailer (with document catalog reference)
10
10
  *
11
+ * Also provides {@link buildIncremental} for appending incremental updates
12
+ * to an existing PDF without rewriting the original bytes.
13
+ *
11
14
  * Encryption uses AES-256 (V=5, R=5) per ISO 32000-2:2020.
12
15
  *
13
16
  * @see ISO 32000-2:2020, Chapter 7.5 — File Structure
@@ -29,6 +32,12 @@ export declare class PdfWriter {
29
32
  private catalogRef;
30
33
  private infoRef;
31
34
  private encryption;
35
+ private pdfVersion;
36
+ /**
37
+ * Set the PDF version string (e.g. "1.4", "1.7", "2.0").
38
+ * Default is "2.0".
39
+ */
40
+ setVersion(version: string): void;
32
41
  /**
33
42
  * Enable encryption for this document.
34
43
  */
@@ -47,9 +56,26 @@ export declare class PdfWriter {
47
56
  /**
48
57
  * Add a stream object (dictionary + binary stream data) to the PDF.
49
58
  * The /Length key is automatically added to the dictionary.
59
+ *
60
+ * @param objectNumber - Previously allocated object number
61
+ * @param dict - The stream dictionary
62
+ * @param data - Stream content (PdfContentStream or raw Uint8Array)
63
+ * @param options - Optional settings (e.g. `{ compress: false }` to skip zlib)
50
64
  */
51
65
  addStreamObject(objectNumber: number, dict: PdfDict, stream: PdfContentStream): void;
52
66
  addStreamObject(objectNumber: number, dict: PdfDict, data: Uint8Array): void;
67
+ addStreamObject(objectNumber: number, dict: PdfDict, data: Uint8Array, options: {
68
+ compress?: boolean;
69
+ }): void;
70
+ /**
71
+ * Return all stored objects for inspection (e.g., incremental update remapping).
72
+ * Stream objects include their binary data.
73
+ */
74
+ getObjects(): Array<{
75
+ objectNumber: number;
76
+ content: string;
77
+ streamData?: Uint8Array;
78
+ }>;
53
79
  /**
54
80
  * Set the document catalog object number.
55
81
  * This is required and references the root of the document structure.
@@ -77,10 +103,38 @@ export declare class PdfWriter {
77
103
  }): number;
78
104
  /**
79
105
  * Create and add the Catalog dictionary.
106
+ *
107
+ * @param pagesRef - Object number of the Pages tree root
108
+ * @param optionsOrOutlinesRef - Either an outlinesRef number (legacy) or an options object
80
109
  */
81
- addCatalog(pagesRef: number, outlinesRef?: number): number;
110
+ addCatalog(pagesRef: number, optionsOrOutlinesRef?: number | {
111
+ outlinesRef?: number;
112
+ extraEntries?: Array<[key: string, value: string]>;
113
+ }): number;
82
114
  /**
83
115
  * Build the complete PDF file as a Uint8Array.
84
116
  */
85
117
  build(): Uint8Array;
86
118
  }
119
+ /**
120
+ * Build an incremental update that appends new/modified objects to an
121
+ * existing PDF without rewriting the original bytes.
122
+ *
123
+ * The result is `originalData + "\n" + new objects + xref + trailer + %%EOF`.
124
+ * The new trailer's `/Prev` points to the original xref offset so that PDF
125
+ * readers can follow the chain of incremental updates.
126
+ *
127
+ * @param originalData - The original, unmodified PDF bytes (preserved byte-for-byte)
128
+ * @param modifiedObjects - Map of object number → serialized content.
129
+ * Values are either a plain string (for non-stream objects) or
130
+ * `{ dict, data }` for stream objects.
131
+ * @param newTrailerEntries - Additional/override entries for the new trailer.
132
+ * Keys like `/Root`, `/Info`, `/Encrypt`, `/ID` are preserved from the
133
+ * original trailer by default but can be overridden here.
134
+ *
135
+ * @see ISO 32000-2:2020, §7.5.6 — Incremental Updates
136
+ */
137
+ export declare function buildIncremental(originalData: Uint8Array, modifiedObjects: Map<number, string | {
138
+ dict: PdfDict;
139
+ data: Uint8Array;
140
+ }>, newTrailerEntries: Map<string, string>): Uint8Array;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * PDF/A-1b compliance utilities.
3
+ *
4
+ * Provides XMP metadata stream writing and OutputIntent creation for
5
+ * PDF/A-1b (ISO 19005-1, Level B) conformance.
6
+ *
7
+ * **Limitations:**
8
+ * - Type1 base fonts (Helvetica, Times-Roman, Courier, etc.) are NOT embedded.
9
+ * PDF/A-1b strictly requires all fonts to be embedded. Documents using only
10
+ * CIDFonts (embedded TrueType via `embedFont()`) are fully compliant.
11
+ * Documents using base Type1 fonts will pass structural validation but may
12
+ * fail strict PDF/A font-embedding checks.
13
+ *
14
+ * @see ISO 19005-1:2005 — Document management — Electronic document file
15
+ * format for long-term preservation — Part 1: Use of PDF 1.4 (PDF/A-1)
16
+ */
17
+ import type { PdfWriter } from "./pdf-writer.js";
18
+ /**
19
+ * Minimal sRGB ICC profile (v2.1.0).
20
+ *
21
+ * This is a valid ICC profile with the correct header structure, profile
22
+ * signature, and a minimal tag table. It identifies the color space as RGB
23
+ * with the sRGB rendering intent. The profile is intentionally minimal
24
+ * (~128 bytes) — enough to satisfy PDF/A-1b OutputIntent requirements.
25
+ *
26
+ * Structure:
27
+ * - 128-byte header (profile size, preferred CMM, version, device class,
28
+ * color space, PCS, creation date, signature, platform, flags, etc.)
29
+ * - Tag table with 0 tags (profile is header-only for minimal compliance)
30
+ *
31
+ * @see ICC.1:2001-04 — File Format for Color Profiles (v2)
32
+ */
33
+ export declare const sRGB_ICC_PROFILE: Uint8Array;
34
+ /**
35
+ * Write a PDF/A-1b XMP metadata stream as an indirect object.
36
+ *
37
+ * The XMP packet contains:
38
+ * - `dc:title` — document title
39
+ * - `dc:creator` — document author
40
+ * - `xmp:CreatorTool` — creating application
41
+ * - `pdf:Producer` — PDF producer
42
+ * - `pdfaid:part` — PDF/A part (1)
43
+ * - `pdfaid:conformance` — PDF/A conformance level (B)
44
+ *
45
+ * @returns The object number of the XMP metadata stream.
46
+ */
47
+ export declare function writePdfAMetadata(writer: PdfWriter, metadata: {
48
+ title?: string;
49
+ author?: string;
50
+ subject?: string;
51
+ creator?: string;
52
+ }): number;
53
+ /**
54
+ * Write a PDF/A-1b OutputIntent with an embedded sRGB ICC profile.
55
+ *
56
+ * Creates two objects:
57
+ * 1. The ICC profile stream
58
+ * 2. The OutputIntent dictionary referencing the profile
59
+ *
60
+ * @returns The object number of the OutputIntent dictionary.
61
+ */
62
+ export declare function writePdfAOutputIntent(writer: PdfWriter): number;
@@ -46,6 +46,12 @@ export { pdf } from "./pdf.js";
46
46
  export { excelToPdf } from "./excel-bridge.js";
47
47
  /** Read a PDF file and extract text, images, and metadata. */
48
48
  export { readPdf } from "./reader/pdf-reader.js";
49
+ /** Build PDFs with free text positioning, vector drawing, and images. */
50
+ export { PdfDocumentBuilder, PdfPageBuilder, parseSvgPath } from "./builder/document-builder.js";
51
+ /** Edit existing PDFs: overlay content, fill forms, copy/merge pages. */
52
+ export { PdfEditor, PdfEditorPage } from "./builder/pdf-editor.js";
53
+ /** Digital signatures — verify and sign PDF documents. */
54
+ export { verifyPdfSignature, signPdf, buildSignatureDictPlaceholder, asn1Parse } from "./core/digital-signature.js";
49
55
  export type { PdfCell, PdfRow, PdfColumn, PdfSheet, PdfBook, PdfImage } from "./pdf.js";
50
56
  export type { PdfExportOptions, PdfOrientation, PdfPageSize, PdfMargins, PdfColor, PageSizeName, PdfWatermark, PdfTextWatermark, PdfImageWatermark, PdfWatermarkFilter } from "./types.js";
51
57
  export { PageSizes } from "./types.js";
@@ -55,4 +61,9 @@ export type { ExtractedImage } from "./reader/image-extractor.js";
55
61
  export type { TextLine } from "./reader/text-reconstruction.js";
56
62
  export type { PdfAnnotation, PdfRect } from "./reader/annotation-extractor.js";
57
63
  export type { PdfFormField, PdfFormFieldType } from "./reader/form-extractor.js";
64
+ export type { PdfBookmark } from "./reader/bookmark-extractor.js";
65
+ export type { PdfTable, PdfTableRow, PdfTableCell } from "./reader/table-extractor.js";
66
+ export type { PageOptions, DrawTextOptions, DrawRectOptions, DrawCircleOptions, DrawEllipseOptions, DrawLineOptions, DrawPathOptions, DrawImageOptions, DocumentMetadata, PathOp, TocOptions, AnnotationType, AnnotationOptions, TextMarkupAnnotationOptions, TextAnnotationOptions, FreeTextAnnotationOptions, StampAnnotationOptions, FormFieldOptions, TextFieldOptions, CheckboxOptions, DropdownOptions, RadioGroupOptions, PdfSignatureOptions } from "./builder/document-builder.js";
67
+ export type { LoadOptions } from "./builder/pdf-editor.js";
68
+ export type { SignatureVerificationResult, CmsSignedData, SignOptions, Asn1Node } from "./core/digital-signature.js";
58
69
  export { PdfError, PdfRenderError, PdfFontError, PdfStructureError, isPdfError } from "./errors.js";
@@ -0,0 +1,35 @@
1
+ /**
2
+ * PDF bookmark (outline) extractor.
3
+ *
4
+ * Extracts the document outline tree from a PDF's `/Outlines` dictionary.
5
+ * Each outline item has a title, a target page index, and optional children
6
+ * forming a hierarchical bookmark tree.
7
+ *
8
+ * Supports:
9
+ * - Direct destinations (`/Dest` as array or named destination)
10
+ * - Action-based destinations (`/A << /S /GoTo /D ... >>`)
11
+ * - Nested bookmarks (children via `/First`/`/Last` chains)
12
+ * - Circular reference protection
13
+ *
14
+ * @see PDF Reference 1.7, §12.3 - Document-Level Navigation
15
+ */
16
+ import type { PdfDocument } from "./pdf-document.js";
17
+ /** A bookmark (outline item) extracted from the PDF. */
18
+ export interface PdfBookmark {
19
+ /** Bookmark title text */
20
+ title: string;
21
+ /** 0-based page index the bookmark points to (-1 if unresolvable) */
22
+ pageIndex: number;
23
+ /** Child bookmarks (nested outline items) */
24
+ children: PdfBookmark[];
25
+ }
26
+ /**
27
+ * Extract bookmarks (outlines) from a PDF document.
28
+ *
29
+ * Reads the `/Outlines` dictionary from the catalog and recursively
30
+ * traverses the outline tree following `/First` → `/Next` chains.
31
+ *
32
+ * @param doc - The PDF document
33
+ * @returns Array of top-level bookmarks with nested children
34
+ */
35
+ export declare function extractBookmarks(doc: PdfDocument): PdfBookmark[];