@awacloud/pdf 0.0.0-stage → 1.0.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 (345) hide show
  1. package/CHANGELOG.md +609 -0
  2. package/LICENSE +661 -0
  3. package/NOTICE +77 -0
  4. package/README.md +363 -2
  5. package/dist/build/index.js +21 -0
  6. package/dist/build/pdf-full-rw.js +10972 -0
  7. package/dist/build/pdf-full-rw.meta.json +105 -0
  8. package/dist/build/pdf-full-rw.min.js +53 -0
  9. package/dist/build/pdf-full.js +6078 -0
  10. package/dist/build/pdf-full.meta.json +90 -0
  11. package/dist/build/pdf-full.min.js +32 -0
  12. package/dist/build/pdf-large-rw.js +10367 -0
  13. package/dist/build/pdf-large-rw.meta.json +99 -0
  14. package/dist/build/pdf-large-rw.min.js +53 -0
  15. package/dist/build/pdf-large.js +5473 -0
  16. package/dist/build/pdf-large.meta.json +84 -0
  17. package/dist/build/pdf-large.min.js +32 -0
  18. package/dist/build/pdf-legacy-rw.js +12402 -0
  19. package/dist/build/pdf-legacy-rw.meta.json +110 -0
  20. package/dist/build/pdf-legacy-rw.min.js +53 -0
  21. package/dist/build/pdf-legacy.js +7508 -0
  22. package/dist/build/pdf-legacy.meta.json +95 -0
  23. package/dist/build/pdf-legacy.min.js +32 -0
  24. package/dist/build/pdf-rw.js +7578 -0
  25. package/dist/build/pdf-rw.meta.json +77 -0
  26. package/dist/build/pdf-rw.min.js +53 -0
  27. package/dist/build/pdf.js +2684 -0
  28. package/dist/build/pdf.meta.json +62 -0
  29. package/dist/build/pdf.min.js +32 -0
  30. package/dist/standalone/pdf-full-rw.js +16798 -0
  31. package/dist/standalone/pdf-full-rw.meta.json +78 -0
  32. package/dist/standalone/pdf-full-rw.min.js +56 -0
  33. package/dist/standalone/pdf-full.js +11904 -0
  34. package/dist/standalone/pdf-full.meta.json +63 -0
  35. package/dist/standalone/pdf-full.min.js +35 -0
  36. package/dist/standalone/pdf-large-rw.js +16193 -0
  37. package/dist/standalone/pdf-large-rw.meta.json +72 -0
  38. package/dist/standalone/pdf-large-rw.min.js +56 -0
  39. package/dist/standalone/pdf-large.js +11299 -0
  40. package/dist/standalone/pdf-large.meta.json +57 -0
  41. package/dist/standalone/pdf-large.min.js +35 -0
  42. package/dist/standalone/pdf-legacy-rw.js +18228 -0
  43. package/dist/standalone/pdf-legacy-rw.meta.json +83 -0
  44. package/dist/standalone/pdf-legacy-rw.min.js +56 -0
  45. package/dist/standalone/pdf-legacy.js +13334 -0
  46. package/dist/standalone/pdf-legacy.meta.json +68 -0
  47. package/dist/standalone/pdf-legacy.min.js +35 -0
  48. package/dist/standalone/pdf-rw.js +13404 -0
  49. package/dist/standalone/pdf-rw.meta.json +50 -0
  50. package/dist/standalone/pdf-rw.min.js +56 -0
  51. package/dist/standalone/pdf.js +8510 -0
  52. package/dist/standalone/pdf.meta.json +35 -0
  53. package/dist/standalone/pdf.min.js +35 -0
  54. package/docs/README.md +53 -0
  55. package/docs/api/README.md +38 -0
  56. package/docs/api/_shared/README.md +91 -0
  57. package/docs/api/action/README.md +29 -0
  58. package/docs/api/action/action.md +81 -0
  59. package/docs/api/action/goTo.md +66 -0
  60. package/docs/api/action/launch.md +58 -0
  61. package/docs/api/action/named.md +55 -0
  62. package/docs/api/action/uri.md +54 -0
  63. package/docs/api/annot/README.md +53 -0
  64. package/docs/api/annot/annot.md +114 -0
  65. package/docs/api/annot/fileAttach.md +53 -0
  66. package/docs/api/annot/freeText.md +68 -0
  67. package/docs/api/annot/ink.md +69 -0
  68. package/docs/api/annot/link.md +74 -0
  69. package/docs/api/annot/markup.md +83 -0
  70. package/docs/api/annot/popup.md +52 -0
  71. package/docs/api/annot/projection.md +56 -0
  72. package/docs/api/annot/redact.md +67 -0
  73. package/docs/api/annot/square.md +87 -0
  74. package/docs/api/annot/stamp.md +54 -0
  75. package/docs/api/annot/text.md +69 -0
  76. package/docs/api/annot/widget.md +69 -0
  77. package/docs/api/associatedFiles/README.md +9 -0
  78. package/docs/api/associatedFiles/associatedFiles.md +78 -0
  79. package/docs/api/bundles/README.md +68 -0
  80. package/docs/api/bundles/dist-matrix.md +165 -0
  81. package/docs/api/bundles/pdf-full.md +148 -0
  82. package/docs/api/bundles/pdf-large.md +144 -0
  83. package/docs/api/bundles/pdf-legacy.md +169 -0
  84. package/docs/api/content/README.md +29 -0
  85. package/docs/api/content/color.md +99 -0
  86. package/docs/api/content/graphics.md +114 -0
  87. package/docs/api/content/images.md +124 -0
  88. package/docs/api/content/ops.md +100 -0
  89. package/docs/api/content/stream.md +107 -0
  90. package/docs/api/content/text.md +98 -0
  91. package/docs/api/crypto/README.md +29 -0
  92. package/docs/api/crypto/aesGcm.md +72 -0
  93. package/docs/api/crypto/permissions.md +79 -0
  94. package/docs/api/crypto/security.md +98 -0
  95. package/docs/api/crypto/standardV4.md +104 -0
  96. package/docs/api/crypto/standardV5.md +84 -0
  97. package/docs/api/crypto/standardV6.md +93 -0
  98. package/docs/api/destination/README.md +9 -0
  99. package/docs/api/destination/destination.md +79 -0
  100. package/docs/api/document/README.md +29 -0
  101. package/docs/api/document/builder.md +281 -0
  102. package/docs/api/document/catalog.md +98 -0
  103. package/docs/api/document/document.md +187 -0
  104. package/docs/api/document/encryptedWriter.md +149 -0
  105. package/docs/api/document/incrementalWriter.md +148 -0
  106. package/docs/api/document/page.md +99 -0
  107. package/docs/api/document/pages.md +82 -0
  108. package/docs/api/document/resources.md +102 -0
  109. package/docs/api/document/writer.md +157 -0
  110. package/docs/api/document/xrefStreamWriter.md +122 -0
  111. package/docs/api/embedded/README.md +13 -0
  112. package/docs/api/embedded/collection.md +80 -0
  113. package/docs/api/embedded/embeddedFile.md +86 -0
  114. package/docs/api/embedded/fileSpec.md +87 -0
  115. package/docs/api/errors.md +110 -0
  116. package/docs/api/extra/3d-richmedia.md +76 -0
  117. package/docs/api/extra/README.md +99 -0
  118. package/docs/api/extra/annot-extended.md +71 -0
  119. package/docs/api/extra/associated-files.md +70 -0
  120. package/docs/api/extra/ccitt-fax-decoder.md +74 -0
  121. package/docs/api/extra/color-spaces-extended.md +72 -0
  122. package/docs/api/extra/content-ops-extended.md +82 -0
  123. package/docs/api/extra/document-parts.md +69 -0
  124. package/docs/api/extra/embedded-files-portfolio.md +87 -0
  125. package/docs/api/extra/font-cid-typed.md +77 -0
  126. package/docs/api/extra/font-color-tagging.md +76 -0
  127. package/docs/api/extra/form-actions-extended.md +75 -0
  128. package/docs/api/extra/info-dict-deprecated.md +72 -0
  129. package/docs/api/extra/jbig2-read.md +80 -0
  130. package/docs/api/extra/legacy-deprecated-annots.md +89 -0
  131. package/docs/api/extra/legacy-deprecated-filters.md +78 -0
  132. package/docs/api/extra/legacy-rc4-read.md +74 -0
  133. package/docs/api/extra/legacy-xfa-read.md +65 -0
  134. package/docs/api/extra/linearization-write.md +71 -0
  135. package/docs/api/extra/misc.md +93 -0
  136. package/docs/api/extra/optional-content-extended.md +83 -0
  137. package/docs/api/extra/pdf-a-output-intent.md +65 -0
  138. package/docs/api/extra/pdf-sandbox.md +76 -0
  139. package/docs/api/extra/pdf-ua-tagged.md +63 -0
  140. package/docs/api/extra/pdf-x-prepress.md +65 -0
  141. package/docs/api/extra/redaction-iso32005.md +65 -0
  142. package/docs/api/extra/shading-typed.md +73 -0
  143. package/docs/api/extra/sig-aes-gcm.md +69 -0
  144. package/docs/api/extra/sig-pades.md +103 -0
  145. package/docs/api/extra/tagged-pdf-typed.md +78 -0
  146. package/docs/api/extra/transparency-typed.md +74 -0
  147. package/docs/api/extra/well-tagged-pdf.md +61 -0
  148. package/docs/api/extra/xmp-extended.md +65 -0
  149. package/docs/api/font/README.md +25 -0
  150. package/docs/api/font/embed.md +157 -0
  151. package/docs/api/font/encoding.md +95 -0
  152. package/docs/api/font/font.md +97 -0
  153. package/docs/api/font/type3.md +89 -0
  154. package/docs/api/form/README.md +35 -0
  155. package/docs/api/form/acroform.md +88 -0
  156. package/docs/api/form/appearance.md +87 -0
  157. package/docs/api/form/button.md +97 -0
  158. package/docs/api/form/choice.md +96 -0
  159. package/docs/api/form/fieldTree.md +93 -0
  160. package/docs/api/form/signature.md +90 -0
  161. package/docs/api/form/text.md +88 -0
  162. package/docs/api/linearization/README.md +11 -0
  163. package/docs/api/linearization/linearization.md +81 -0
  164. package/docs/api/main.md +116 -0
  165. package/docs/api/metadata/README.md +10 -0
  166. package/docs/api/metadata/info.md +70 -0
  167. package/docs/api/metadata/xmp.md +62 -0
  168. package/docs/api/ocg/README.md +23 -0
  169. package/docs/api/ocg/config.md +95 -0
  170. package/docs/api/ocg/ocg.md +77 -0
  171. package/docs/api/outline/README.md +11 -0
  172. package/docs/api/outline/outline.md +107 -0
  173. package/docs/api/pdf.md +152 -0
  174. package/docs/api/prepress/README.md +10 -0
  175. package/docs/api/prepress/outputIntent.md +79 -0
  176. package/docs/api/prepress/pageBoundary.md +75 -0
  177. package/docs/api/sig/README.md +32 -0
  178. package/docs/api/sig/byteRange.md +120 -0
  179. package/docs/api/sig/certChain.md +84 -0
  180. package/docs/api/sig/dss.md +111 -0
  181. package/docs/api/sig/oids.md +76 -0
  182. package/docs/api/sig/sha1.md +72 -0
  183. package/docs/api/sig/sign.md +317 -0
  184. package/docs/api/sig/signature.md +178 -0
  185. package/docs/api/sig/timestamp.md +84 -0
  186. package/docs/api/syntax/README.md +29 -0
  187. package/docs/api/syntax/crossRefStream.md +115 -0
  188. package/docs/api/syntax/filters/README.md +50 -0
  189. package/docs/api/syntax/filters/ascii85.md +76 -0
  190. package/docs/api/syntax/filters/asciiHex.md +73 -0
  191. package/docs/api/syntax/filters/dispatch.md +125 -0
  192. package/docs/api/syntax/filters/flate.md +134 -0
  193. package/docs/api/syntax/filters/runLength.md +78 -0
  194. package/docs/api/syntax/objStream.md +88 -0
  195. package/docs/api/syntax/parser-obj.md +97 -0
  196. package/docs/api/syntax/parser.md +151 -0
  197. package/docs/api/syntax/serializer.md +109 -0
  198. package/docs/api/syntax/tokenizer.md +104 -0
  199. package/docs/api/syntax/trailer.md +85 -0
  200. package/docs/api/syntax/xref.md +139 -0
  201. package/docs/api/tagged/README.md +25 -0
  202. package/docs/api/tagged/classMap.md +67 -0
  203. package/docs/api/tagged/markedContent.md +62 -0
  204. package/docs/api/tagged/parentTree.md +67 -0
  205. package/docs/api/tagged/roleMap.md +67 -0
  206. package/docs/api/tagged/structElement.md +76 -0
  207. package/docs/api/tagged/structTree.md +75 -0
  208. package/docs/guide/coverage.md +113 -0
  209. package/docs/guide/crypto.md +121 -0
  210. package/docs/guide/extending.md +76 -0
  211. package/docs/guide/getting-started.md +75 -0
  212. package/docs/guide/legacy-1.7.md +42 -0
  213. package/docs/guide/pades-integration.md +579 -0
  214. package/docs/guide/read-pdf.md +89 -0
  215. package/package.json +97 -4
  216. package/src/_shared/index.js +179 -0
  217. package/src/action/action.js +119 -0
  218. package/src/action/goTo.js +89 -0
  219. package/src/action/launch.js +61 -0
  220. package/src/action/named.js +54 -0
  221. package/src/action/uri.js +51 -0
  222. package/src/annot/annot.js +212 -0
  223. package/src/annot/fileAttach.js +55 -0
  224. package/src/annot/freeText.js +82 -0
  225. package/src/annot/ink.js +77 -0
  226. package/src/annot/link.js +77 -0
  227. package/src/annot/markup.js +91 -0
  228. package/src/annot/popup.js +53 -0
  229. package/src/annot/projection.js +52 -0
  230. package/src/annot/redact.js +87 -0
  231. package/src/annot/square.js +132 -0
  232. package/src/annot/stamp.js +48 -0
  233. package/src/annot/text.js +54 -0
  234. package/src/annot/widget.js +61 -0
  235. package/src/associatedFiles/associatedFiles.js +86 -0
  236. package/src/bundles/pdf-full.js +91 -0
  237. package/src/bundles/pdf-large.js +81 -0
  238. package/src/bundles/pdf-legacy.js +107 -0
  239. package/src/content/color.js +114 -0
  240. package/src/content/graphics.js +192 -0
  241. package/src/content/images.js +160 -0
  242. package/src/content/ops.js +137 -0
  243. package/src/content/stream.js +154 -0
  244. package/src/content/text.js +125 -0
  245. package/src/crypto/aesGcm.js +123 -0
  246. package/src/crypto/permissions.js +112 -0
  247. package/src/crypto/security.js +327 -0
  248. package/src/crypto/standardV4.js +443 -0
  249. package/src/crypto/standardV5.js +306 -0
  250. package/src/crypto/standardV6.js +334 -0
  251. package/src/destination/destination.js +183 -0
  252. package/src/document/builder.js +618 -0
  253. package/src/document/catalog.js +100 -0
  254. package/src/document/document.js +472 -0
  255. package/src/document/encryptedWriter.js +554 -0
  256. package/src/document/incrementalWriter.js +514 -0
  257. package/src/document/page.js +131 -0
  258. package/src/document/pages.js +103 -0
  259. package/src/document/resources.js +146 -0
  260. package/src/document/writer.js +211 -0
  261. package/src/document/xrefStreamWriter.js +353 -0
  262. package/src/embedded/collection.js +102 -0
  263. package/src/embedded/embeddedFile.js +99 -0
  264. package/src/embedded/fileSpec.js +137 -0
  265. package/src/errors.js +78 -0
  266. package/src/extra/3d-richmedia.js +171 -0
  267. package/src/extra/annot-extended.js +200 -0
  268. package/src/extra/associated-files.js +131 -0
  269. package/src/extra/ccitt-fax-decoder.js +776 -0
  270. package/src/extra/color-spaces-extended.js +196 -0
  271. package/src/extra/content-ops-extended.js +153 -0
  272. package/src/extra/document-parts.js +149 -0
  273. package/src/extra/embedded-files-portfolio.js +234 -0
  274. package/src/extra/font-cid-typed.js +185 -0
  275. package/src/extra/font-color-tagging.js +144 -0
  276. package/src/extra/form-actions-extended.js +196 -0
  277. package/src/extra/info-dict-deprecated.js +137 -0
  278. package/src/extra/jbig2-read.js +169 -0
  279. package/src/extra/legacy-deprecated-annots.js +198 -0
  280. package/src/extra/legacy-deprecated-filters.js +167 -0
  281. package/src/extra/legacy-rc4-read.js +235 -0
  282. package/src/extra/legacy-xfa-read.js +104 -0
  283. package/src/extra/linearization-write.js +97 -0
  284. package/src/extra/misc.js +217 -0
  285. package/src/extra/optional-content-extended.js +142 -0
  286. package/src/extra/pdf-a-output-intent.js +112 -0
  287. package/src/extra/pdf-sandbox.js +88 -0
  288. package/src/extra/pdf-ua-tagged.js +116 -0
  289. package/src/extra/pdf-x-prepress.js +114 -0
  290. package/src/extra/redaction-iso32005.js +136 -0
  291. package/src/extra/shading-typed.js +222 -0
  292. package/src/extra/sig-aes-gcm.js +135 -0
  293. package/src/extra/sig-pades.js +242 -0
  294. package/src/extra/tagged-pdf-typed.js +203 -0
  295. package/src/extra/transparency-typed.js +135 -0
  296. package/src/extra/well-tagged-pdf.js +138 -0
  297. package/src/extra/xmp-extended.js +190 -0
  298. package/src/font/embed.js +480 -0
  299. package/src/font/encoding.js +92 -0
  300. package/src/font/font.js +101 -0
  301. package/src/font/type3.js +75 -0
  302. package/src/form/acroform.js +94 -0
  303. package/src/form/appearance.js +90 -0
  304. package/src/form/button.js +105 -0
  305. package/src/form/choice.js +152 -0
  306. package/src/form/fieldTree.js +120 -0
  307. package/src/form/signature.js +100 -0
  308. package/src/form/text.js +101 -0
  309. package/src/linearization/linearization.js +107 -0
  310. package/src/main.js +411 -0
  311. package/src/metadata/info.js +87 -0
  312. package/src/metadata/xmp.js +62 -0
  313. package/src/ocg/config.js +156 -0
  314. package/src/ocg/ocg.js +124 -0
  315. package/src/outline/outline.js +157 -0
  316. package/src/pdf.js +133 -0
  317. package/src/prepress/outputIntent.js +118 -0
  318. package/src/prepress/pageBoundary.js +108 -0
  319. package/src/sig/byteRange.js +306 -0
  320. package/src/sig/certChain.js +247 -0
  321. package/src/sig/dss.js +317 -0
  322. package/src/sig/oids.js +157 -0
  323. package/src/sig/sha1.js +142 -0
  324. package/src/sig/sign.js +1899 -0
  325. package/src/sig/signature.js +1441 -0
  326. package/src/sig/timestamp.js +236 -0
  327. package/src/syntax/crossRefStream.js +133 -0
  328. package/src/syntax/filters/ascii85.js +122 -0
  329. package/src/syntax/filters/asciiHex.js +83 -0
  330. package/src/syntax/filters/dispatch.js +176 -0
  331. package/src/syntax/filters/flate.js +316 -0
  332. package/src/syntax/filters/runLength.js +96 -0
  333. package/src/syntax/objStream.js +99 -0
  334. package/src/syntax/parser-obj.js +52 -0
  335. package/src/syntax/parser.js +321 -0
  336. package/src/syntax/serializer.js +221 -0
  337. package/src/syntax/tokenizer.js +290 -0
  338. package/src/syntax/trailer.js +76 -0
  339. package/src/syntax/xref.js +341 -0
  340. package/src/tagged/classMap.js +81 -0
  341. package/src/tagged/markedContent.js +123 -0
  342. package/src/tagged/parentTree.js +126 -0
  343. package/src/tagged/roleMap.js +107 -0
  344. package/src/tagged/structElement.js +138 -0
  345. package/src/tagged/structTree.js +94 -0
@@ -0,0 +1,157 @@
1
+ ---
2
+ module: pdfWriter
3
+ category: pdf/document
4
+ dependencies: [pdfErrors, pdfSerializer]
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfWriter
11
+
12
+ > Model → PDF 2.0 `Uint8Array` — header, indirects, classical xref, trailer.
13
+
14
+ **Module** `pdfWriter` | **Source** `packages/front/office/pdf/src/document/writer.js` | **Deps** `pdfErrors`, `pdfSerializer` | **Worker-safe** yes
15
+
16
+ Emits a complete PDF document per ISO 32000-2 §7.5.2–7.5.5:
17
+
18
+ 1. Header `%PDF-x.y\n` plus the binary marker comment.
19
+ 2. For each indirect, `serializeIndirect` and the recording of its offset.
20
+ 3. Classical xref table — `xref` keyword, one `0 N` subsection, 20-byte entries
21
+ (`0000000000 65535 f ` for the free-list head, `oooooooooo 00000 n ` for live
22
+ objects, `0000000000 00000 f ` for holes).
23
+ 4. Trailer dictionary plus `startxref` and `%%EOF`.
24
+
25
+ `writeDocument` is model-agnostic: it happily emits a from-scratch indirect list
26
+ (see the second example). `assembleIndirects(model)` covers the **read → write
27
+ round trip**: it forces full resolution of a model read through `pdf.read()`,
28
+ then snapshots the `_raw.indirects` cache into an ordered list ready for
29
+ `writeDocument`. The result is byte-different but semantically equivalent.
30
+
31
+ Two sibling factories build on this one: `pdfBuilder` (`{ builder }`) offers a
32
+ chainable constructive DSL — `addPage`, `addContent`, `addFont`, `addMetadata`,
33
+ `setVersion`, `setId`, `build()` — and `pdfIncrementalWriter`
34
+ (`{ appendIncremental }`) appends an incremental-update section (§7.5.6) to
35
+ existing bytes. `pdfEncryptedWriter` (`{ writeEncryptedDocument }`) wraps
36
+ `writeDocument` with the standard security handlers.
37
+
38
+ ## Resolve
39
+
40
+ ```js
41
+ const writer = runtime.resolve('pdfWriter');
42
+ // Returns: { writeDocument, assembleIndirects }
43
+ ```
44
+
45
+ ## API
46
+
47
+ | Method | Signature | Returns |
48
+ |--------|-----------|---------|
49
+ | `writeDocument` | `(opts: WriteOpts) => Uint8Array` | Complete document. |
50
+ | `assembleIndirects` | `(model: ReadModel, opts?: { strict?: boolean }) => Array<{num, gen, value}>` | Ordered snapshot; carries `skippedObjects` (see below). |
51
+
52
+ ### `WriteOpts`
53
+
54
+ ```js
55
+ {
56
+ indirects: [ { num, gen, value }, … ], // required — num >= 1, no duplicates
57
+ root: { num, gen }, // required — trailer /Root
58
+ info?: { num, gen }, // optional — /Info
59
+ version?: '2.0' | '1.7' | … // default '2.0', matches /^\d\.\d$/
60
+ id?: [ Uint8Array, Uint8Array ] // 2 × 16 bytes for /ID
61
+ }
62
+ ```
63
+
64
+ `indirects` is sorted by `num` before emission, so the caller need not supply it
65
+ in ascending order.
66
+
67
+ ### Unresolvable objects (`skippedObjects`, `strict`)
68
+
69
+ `assembleIndirects` forces resolution of every in-use xref entry. An entry whose
70
+ resolution throws cannot be written, so it never reaches the snapshot. The loss is
71
+ reported, not silent:
72
+
73
+ - **Lenient (default)** — the snapshot is returned as before (byte-identical
74
+ output for a fully resolvable model) and carries the skipped entries on its
75
+ **non-enumerable** `skippedObjects` property: `Array<{ num, gen, code }>`,
76
+ empty when nothing was skipped. `code` is the caught error's `code` when it is a
77
+ typed pdf error, else `'unknown'`. Being non-enumerable, it does not change
78
+ iteration, spreading, `JSON.stringify` or deep equality of the array.
79
+ - **`opts.strict === true`** — throws a `RenderError` coded
80
+ `pdf/writer/unresolvable-objects` (message names the count) whose
81
+ `context.objects` is the same list.
82
+
83
+ ```js
84
+ const indirects = writer.assembleIndirects(model);
85
+ if (indirects.skippedObjects.length > 0) {
86
+ console.warn('dropped', indirects.skippedObjects); // [{ num, gen, code }, …]
87
+ }
88
+ writer.assembleIndirects(model, { strict: true }); // throws instead of dropping
89
+ ```
90
+
91
+ `pdf.write(model)` calls `assembleIndirects(model)` in lenient mode and does not
92
+ forward the list; call `assembleIndirects` directly to observe or forbid drops.
93
+
94
+ ## Examples
95
+
96
+ ### Read → write round trip
97
+
98
+ ```js
99
+ const pdf = runtime.resolve('pdf');
100
+ const writer = runtime.resolve('pdfWriter');
101
+
102
+ const model = pdf.read(srcBytes);
103
+ const indirects = writer.assembleIndirects(model);
104
+ const out = writer.writeDocument({
105
+ indirects,
106
+ root: { num: model.trailer.root.num, gen: model.trailer.root.gen },
107
+ info: model.trailer.info,
108
+ version: model.version
109
+ });
110
+ ```
111
+
112
+ ### Minimal from-scratch document
113
+
114
+ ```js
115
+ const writer = runtime.resolve('pdfWriter');
116
+ const out = writer.writeDocument({
117
+ indirects: [
118
+ { num: 1, gen: 0, value: { type: 'dict', entries: {
119
+ Type: { type: 'name', value: 'Catalog' },
120
+ Pages: { type: 'ref', num: 2, gen: 0 }
121
+ }}},
122
+ { num: 2, gen: 0, value: { type: 'dict', entries: {
123
+ Type: { type: 'name', value: 'Pages' },
124
+ Count: { type: 'int', value: 0 },
125
+ Kids: { type: 'array', items: [] }
126
+ }}}
127
+ ],
128
+ root: { num: 1, gen: 0 }
129
+ });
130
+ ```
131
+
132
+ ### `/ID` for reproducibility
133
+
134
+ ```js
135
+ const id = new Uint8Array(16); /* … filled … */
136
+ writer.writeDocument({ indirects, root, id: [id, id] });
137
+ ```
138
+
139
+ ## Errors
140
+
141
+ | Code | Class | When |
142
+ |------|-------|------|
143
+ | `pdf/writer/bad-input` | `RenderError` | `opts.indirects` is not an array. |
144
+ | `pdf/writer/no-root` | `RenderError` | `opts.root` missing or `num` not finite. |
145
+ | `pdf/writer/bad-version` | `RenderError` | `version` does not match `/^\d\.\d$/`. |
146
+ | `pdf/writer/bad-indirect` | `RenderError` | An element without a finite `num` ≥ 1. |
147
+ | `pdf/writer/duplicate-num` | `RenderError` | Two entries share the same `num`. |
148
+ | `pdf/writer/bad-model` | `RenderError` | `assembleIndirects` given something other than a `pdf.read()` model. |
149
+ | `pdf/writer/unresolvable-objects` | `RenderError` | `assembleIndirects(model, { strict: true })` and at least one in-use object could not be resolved; `context.objects` is `Array<{ num, gen, code }>`. |
150
+
151
+ It also propagates every code from [`pdfSerializer`](../syntax/serializer.md).
152
+
153
+ ## See also
154
+
155
+ - [`pdfSerializer`](../syntax/serializer.md) — per-object emission.
156
+ - [`pdfDocument`](./document.md) — inverse operation.
157
+ - [`pdfErrors`](../errors.md)
@@ -0,0 +1,122 @@
1
+ ---
2
+ module: pdfXrefStreamWriter
3
+ category: pdf/document
4
+ dependencies: [pdfErrors, pdfSerializer, pdfFlate]
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfXrefStreamWriter
11
+
12
+ > Alternative emitter using a `/Type /XRef` cross-reference stream instead of a classical table.
13
+
14
+ **Module** `pdfXrefStreamWriter` | **Source** `packages/front/office/pdf/src/document/xrefStreamWriter.js` | **Deps** `pdfErrors`, `pdfSerializer`, `pdfFlate` | **Worker-safe** yes
15
+
16
+ An alternative to `pdfWriter.writeDocument`: instead of a classical
17
+ `xref`/`trailer` tail, `writeXrefStreamDocument` emits the cross-reference as a
18
+ single `/Type /XRef` stream object (PDF 1.5+ / ISO 32000-2:2020 §7.5.8), with
19
+ `/W` widths sized to fit the largest observed offset/generation values and a
20
+ full `/Index`. Optionally (`useObjStm: true`), non-stream indirects with
21
+ `gen === 0` are grouped into `/Type /ObjStm` compressed object streams
22
+ (§7.5.7, chunked by `objStmCapacity`) and referenced as type-2 xref entries;
23
+ stream objects and non-zero-generation objects are always left as
24
+ uncompressed, type-1 entries. The xref-stream object itself is always
25
+ appended last and given a fresh, freshly-computed object number, then
26
+ flate-compressed like any other stream.
27
+
28
+ > **Note:** a document produced by this writer round-trips through the
29
+ > package's own read path — `pdfDocument.readDocument` composes
30
+ > [`pdfCrossRefStream`](../syntax/crossRefStream.md) and
31
+ > [`pdfObjStream`](../syntax/objStream.md), so both the plain and the
32
+ > `useObjStm` outputs re-read end to end (see [`pdfDocument`](./document.md)).
33
+ > What it cannot do is receive an **incremental update**:
34
+ > [`pdfIncrementalWriter`](./incrementalWriter.md) emits classical tables only.
35
+
36
+ ## Resolve
37
+
38
+ ```js
39
+ const xw = runtime.resolve('pdfXrefStreamWriter');
40
+ // Returns: { writeXrefStreamDocument }
41
+ ```
42
+
43
+ ## API
44
+
45
+ | Method | Signature | Returns |
46
+ |--------|-----------|---------|
47
+ | `writeXrefStreamDocument` | `(opts: XrefStmWriteOpts) => Uint8Array` | A full PDF: header + serialized indirects (+ ObjStm wrappers if requested) + xref-stream object + `startxref`/`%%EOF`. |
48
+
49
+ ### `XrefStmWriteOpts`
50
+
51
+ ```js
52
+ {
53
+ indirects: [ { num, gen, value }, … ], // required, num >= 1, no duplicates
54
+ root: { num, gen }, // required
55
+ info?: { num, gen },
56
+ id?: [ string | Uint8Array, string | Uint8Array ],
57
+ version?: string, // default '2.0', must match /^\d\.\d$/
58
+ useObjStm?: boolean, // default false — group compressible indirects into ObjStm(s)
59
+ objStmCapacity?: number // default 64 — max members per ObjStm
60
+ }
61
+ ```
62
+
63
+ Object 0 (the free-list head) is always synthesized and included in the
64
+ xref-stream's `/Index`; the xref-stream's own entry is always type 1
65
+ (uncompressed), pointing at its own byte offset, per §7.5.8.
66
+
67
+ ## Examples
68
+
69
+ ### Minimal document, classical-style indirects, xref-stream output
70
+
71
+ ```js
72
+ const { writeXrefStreamDocument } = runtime.resolve('pdfXrefStreamWriter');
73
+ const bytes = writeXrefStreamDocument({
74
+ indirects: [
75
+ { num: 1, gen: 0, value: obj.dict({ Type: obj.name('Catalog'), Pages: obj.ref(2, 0) }) },
76
+ { num: 2, gen: 0, value: obj.dict({ Type: obj.name('Pages'), Kids: obj.array([obj.ref(3, 0)]), Count: obj.int(1) }) },
77
+ { num: 3, gen: 0, value: obj.dict({ Type: obj.name('Page'), Parent: obj.ref(2, 0),
78
+ MediaBox: obj.array([obj.int(0), obj.int(0), obj.int(612), obj.int(792)]) }) }
79
+ ],
80
+ root: { num: 1, gen: 0 }
81
+ });
82
+ ```
83
+
84
+ ### Grouping non-stream objects into ObjStm(s)
85
+
86
+ ```js
87
+ const bytes = writeXrefStreamDocument({
88
+ indirects,
89
+ root: { num: 1, gen: 0 },
90
+ useObjStm: true,
91
+ objStmCapacity: 32 // split across several ObjStms once exceeded
92
+ });
93
+ ```
94
+
95
+ ### `/Info` and `/ID`
96
+
97
+ ```js
98
+ const bytes = writeXrefStreamDocument({
99
+ indirects,
100
+ root: { num: 1, gen: 0 },
101
+ info: { num: 4, gen: 0 },
102
+ id: [Uint8Array.of(0x00, 0x11), Uint8Array.of(0xAA, 0xBB)]
103
+ });
104
+ ```
105
+
106
+ ## Errors
107
+
108
+ | Code | Class | When |
109
+ |------|-------|------|
110
+ | `pdf/xrefstm-writer/bad-input` | `RenderError` | `opts.indirects` is not an array. |
111
+ | `pdf/xrefstm-writer/no-root` | `RenderError` | `opts.root` missing or `opts.root.num` not finite. |
112
+ | `pdf/xrefstm-writer/no-flate` | `RenderError` | `pdfFlate.encode` unavailable — required to emit the xref-stream and any ObjStm. |
113
+ | `pdf/xrefstm-writer/bad-version` | `RenderError` | `version` doesn't match `/^\d\.\d$/`. |
114
+ | `pdf/xrefstm-writer/bad-indirect` | `RenderError` | An indirect lacks a finite `num >= 1`. |
115
+ | `pdf/xrefstm-writer/duplicate-num` | `RenderError` | Two indirects share the same `num`. |
116
+
117
+ ## See also
118
+
119
+ - [`pdfWriter`](./writer.md) — the classical-xref counterpart (same `indirects`/`root`/`info`/`id` shape).
120
+ - [`pdfDocument`](./document.md) — the top-level reader; it reads this module's output back, see the note above.
121
+ - [`pdfCrossRefStream`](../syntax/crossRefStream.md) · [`pdfObjStream`](../syntax/objStream.md) — the parser-side counterparts `pdfDocument` composes to read back a document this module produced.
122
+ - [`pdfFlate`](../syntax/filters/flate.md) — required for both the xref-stream payload and any ObjStm.
@@ -0,0 +1,13 @@
1
+ # Embedded Files — ISO 32000-2 §7.11
2
+
3
+ Attachments and portfolios.
4
+
5
+ | Module | Returns | Deps | Description |
6
+ |--------|----------|------|-------------|
7
+ | [`pdfFileSpec`](./fileSpec.md) | `{ typeFileSpec }` | `pdfErrors`, `pdfParser` | §7.11.3 — file specification. |
8
+ | [`pdfEmbeddedFile`](./embeddedFile.md) | `{ typeEmbeddedFile }` | `pdfErrors`, `pdfParser` | §7.11.4 — embedded file stream. |
9
+ | [`pdfCollection`](./collection.md) | `{ typeCollection }` | `pdfErrors`, `pdfParser` | §7.11.6 — portfolio. |
10
+
11
+ ## See also
12
+
13
+ - [`pdfFileAttachAnnot`](../annot/fileAttach.md) · [`pdfAssociatedFiles`](../associatedFiles/README.md)
@@ -0,0 +1,80 @@
1
+ ---
2
+ module: pdfCollection
3
+ category: pdf/embedded
4
+ dependencies: [pdfErrors, pdfParser]
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfCollection
11
+
12
+ > Collection (portfolio) — ISO 32000-2 §7.11.6.
13
+
14
+ **Module** `pdfCollection` | **Source** `packages/front/office/pdf/src/embedded/collection.js` | **Deps** `pdfErrors`, `pdfParser` | **Worker-safe** yes
15
+
16
+ `/Type /Collection` lives on the Catalog. It describes a "PDF Portfolio": a cover PDF plus a set of embedded files. Entries: `/Schema` (dict of column definitions, kept raw), `/D` (default-displayed item name), `/View` (`D` details / `T` tile / `H` hidden / `C` custom), `/Sort` (kept raw), `/Navigator` (dict or ref, custom navigator extension).
17
+
18
+ ## Resolve
19
+
20
+ ```js
21
+ const coll = runtime.resolve('pdfCollection');
22
+ // Returns: { typeCollection }
23
+ ```
24
+
25
+ ## API
26
+
27
+ | Method | Signature | Returns |
28
+ |---------|-----------|----------|
29
+ | `typeCollection` | `(dict) => Collection` | Typing. |
30
+
31
+ ### Shape `Collection`
32
+
33
+ ```js
34
+ {
35
+ schema: PdfDict | undefined, // /Schema, untyped
36
+ initialDoc: string | undefined, // /D
37
+ view: 'D' | 'T' | 'H' | 'C' | undefined,
38
+ sort: PdfDict | undefined, // /Sort, untyped
39
+ navigator: PdfDict | PdfRef | undefined,
40
+ raw, _extras
41
+ }
42
+ ```
43
+
44
+ ## Examples
45
+
46
+ ### Reading a portfolio
47
+
48
+ ```js
49
+ const coll = runtime.resolve('pdfCollection').typeCollection(catalog.collection);
50
+ coll.view; // 'D' = details
51
+ coll.initialDoc; // name of the item shown by default
52
+ ```
53
+
54
+ ### Items
55
+
56
+ Portfolio items are the embedded files reachable from the Catalog's `/Names /EmbeddedFiles` name tree; each file spec carries `/CI` for the schema column values (kept raw on `pdfFileSpec`'s `.ci`).
57
+
58
+ ```js
59
+ for (const [name, fsRef] of nameTree.entries(catalog.names.embeddedFiles)) {
60
+ const fs = runtime.resolve('pdfFileSpec').typeFileSpec(resolveRef(fsRef));
61
+ fs.ci;
62
+ }
63
+ ```
64
+
65
+ ## Errors
66
+
67
+ | Code | Class | When |
68
+ |------|--------|------|
69
+ | `pdf/collection/not-dict` | `ParseError` | Argument is not a dict. |
70
+ | `pdf/collection/bad-type` | `ParseError` | `/Type` is not `/Collection`. |
71
+ | `pdf/collection/bad-schema` | `ParseError` | `/Schema` is not a dict. |
72
+ | `pdf/collection/bad-d` | `ParseError` | `/D` is not a string. |
73
+ | `pdf/collection/bad-view` | `ParseError` | `/View` is outside `D`/`T`/`H`/`C`. |
74
+ | `pdf/collection/bad-sort` | `ParseError` | `/Sort` is not a dict. |
75
+ | `pdf/collection/bad-navigator` | `ParseError` | `/Navigator` is neither a dict nor a ref. |
76
+
77
+ ## See also
78
+
79
+ - [`pdfFileSpec`](./fileSpec.md) · [`pdfEmbeddedFile`](./embeddedFile.md)
80
+ - [`pdfCatalog`](../document/catalog.md)
@@ -0,0 +1,86 @@
1
+ ---
2
+ module: pdfEmbeddedFile
3
+ category: pdf/embedded
4
+ dependencies: [pdfErrors, pdfParser]
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfEmbeddedFile
11
+
12
+ > Embedded file stream — ISO 32000-2 §7.11.4.
13
+
14
+ **Module** `pdfEmbeddedFile` | **Source** `packages/front/office/pdf/src/embedded/embeddedFile.js` | **Deps** `pdfErrors`, `pdfParser` | **Worker-safe** yes
15
+
16
+ Types the stream pointed at by a file spec's `/EF` entry. The stream dict carries `/Type /EmbeddedFile`, an optional `/Subtype` (MIME type as a name), and an optional `/Params` sub-dictionary (`/Size`, `/CreationDate`, `/ModDate`, `/CheckSum`). The binary content is the stream's raw (pre-filter) bytes.
17
+
18
+ ## Resolve
19
+
20
+ ```js
21
+ const ef = runtime.resolve('pdfEmbeddedFile');
22
+ // Returns: { typeEmbeddedFile }
23
+ ```
24
+
25
+ ## API
26
+
27
+ | Method | Signature | Returns |
28
+ |---------|-----------|----------|
29
+ | `typeEmbeddedFile` | `(stream) => EmbeddedFile` | Typing. |
30
+
31
+ ### Shape `EmbeddedFile`
32
+
33
+ ```js
34
+ {
35
+ subtype: string | undefined, // MIME, e.g. 'application/pdf'
36
+ params: Params | undefined,
37
+ bytes: Uint8Array, // raw stream (pre-filter)
38
+ raw: PdfStream,
39
+ _extras
40
+ }
41
+ ```
42
+
43
+ `Params` (the decoded `/Params` sub-dict):
44
+
45
+ ```js
46
+ {
47
+ size: number | undefined,
48
+ creationDate: string | undefined, // raw PDF date string, not parsed
49
+ modDate: string | undefined, // raw PDF date string, not parsed
50
+ checkSum: string | undefined, // 16-byte MD5, as the string bytes
51
+ raw, _extras
52
+ }
53
+ ```
54
+
55
+ ## Examples
56
+
57
+ ### Extraction
58
+
59
+ ```js
60
+ const ef = runtime.resolve('pdfEmbeddedFile').typeEmbeddedFile(stream);
61
+ const dispatch = runtime.resolve('pdfFilterDispatch');
62
+ const plain = dispatch.decode(ef.raw);
63
+ ```
64
+
65
+ ### Metadata
66
+
67
+ ```js
68
+ ef.subtype; // 'application/json'
69
+ ef.params?.size; // original byte size
70
+ ef.params?.checkSum; // MD5, as raw string bytes
71
+ ```
72
+
73
+ ## Errors
74
+
75
+ | Code | Class | When |
76
+ |------|--------|------|
77
+ | `pdf/embedded/not-stream` | `ParseError` | Argument is not a stream. |
78
+ | `pdf/embedded/no-dict` | `ParseError` | Stream has no dict. |
79
+ | `pdf/embedded/bad-type` | `ParseError` | `/Type` is not `/EmbeddedFile`. |
80
+ | `pdf/embedded/bad-subtype` | `ParseError` | `/Subtype` is not a name. |
81
+ | `pdf/embedded/bad-params` | `ParseError` | `/Params` is not a dict. |
82
+
83
+ ## See also
84
+
85
+ - [`pdfFileSpec`](./fileSpec.md) · [`pdfCollection`](./collection.md)
86
+ - [`pdfFilterDispatch`](../syntax/filters/README.md)
@@ -0,0 +1,87 @@
1
+ ---
2
+ module: pdfFileSpec
3
+ category: pdf/embedded
4
+ dependencies: [pdfErrors, pdfParser]
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfFileSpec
11
+
12
+ > File specification — ISO 32000-2 §7.11.3.
13
+
14
+ **Module** `pdfFileSpec` | **Source** `packages/front/office/pdf/src/embedded/fileSpec.js` | **Deps** `pdfErrors`, `pdfParser` | **Worker-safe** yes
15
+
16
+ Types a `/Type /Filespec` (or legacy `/Type /F`) dictionary. Entries: `/FS` (file system — `URL` or absent for local), `/F`/`/UF` (standard/Unicode path — `UF` preferred since 1.7), `/DOS`/`/Mac`/`/Unix` (platform-specific paths), `/ID` (array of 2 byte-strings — file identity), `/V` (volatile flag), `/EF` (dict of embedded-file stream refs — `F`/`UF`/`DOS`/`Mac`/`Unix`), `/RF` (related-files dict), `/Desc` (description), `/CI` (collection item), `/AFRelationship` (PDF 2.0 associated-file relationship name).
17
+
18
+ ## Resolve
19
+
20
+ ```js
21
+ const fs = runtime.resolve('pdfFileSpec');
22
+ // Returns: { typeFileSpec }
23
+ ```
24
+
25
+ ## API
26
+
27
+ | Method | Signature | Returns |
28
+ |---------|-----------|----------|
29
+ | `typeFileSpec` | `(dict) => FileSpec` | Strict typing; throws on malformed entries. |
30
+
31
+ ### Shape `FileSpec`
32
+
33
+ ```js
34
+ {
35
+ fs: 'URL' | undefined,
36
+ f, uf, dos, mac, unix, // string paths, whichever are present
37
+ id: string[] | undefined, // /ID, filtered to string items
38
+ volatile: boolean | undefined, // /V
39
+ embedded: { F?, UF?, DOS?, Mac?, Unix? } | undefined, // /EF entries (raw)
40
+ related: object | undefined, // /RF entries (raw)
41
+ desc: string | undefined,
42
+ ci: PdfDict | undefined, // /CI, untyped
43
+ afRelationship: string | undefined,
44
+ afRelationshipStandard: boolean, // true iff afRelationship is one of
45
+ // the 8 standard values
46
+ raw, _extras
47
+ }
48
+ ```
49
+
50
+ ## Examples
51
+
52
+ ### Reading an attachment
53
+
54
+ ```js
55
+ const fs = runtime.resolve('pdfFileSpec').typeFileSpec(dict);
56
+ const file = runtime.resolve('pdfEmbeddedFile').typeEmbeddedFile(
57
+ doc._raw.resolve(fs.embedded.F)
58
+ );
59
+ fs.uf; // 'attachment.txt'
60
+ file.bytes; // Uint8Array
61
+ ```
62
+
63
+ ### AF relationship (PDF 2.0)
64
+
65
+ ```js
66
+ fs.afRelationship; // 'Source' | 'Data' | 'Alternative' | 'Supplement' | …
67
+ fs.afRelationshipStandard; // false for a non-standard relationship name
68
+ ```
69
+
70
+ ## Errors
71
+
72
+ | Code | Class | When |
73
+ |------|--------|------|
74
+ | `pdf/filespec/not-dict` | `ParseError` | Argument is not a dict. |
75
+ | `pdf/filespec/bad-type` | `ParseError` | `/Type` is neither `/Filespec` nor `/F`. |
76
+ | `pdf/filespec/bad-fs` | `ParseError` | `/FS` is not a name. |
77
+ | `pdf/filespec/bad-path` | `ParseError` | `/F`/`/UF`/`/DOS`/`/Mac`/`/Unix` is not a string. |
78
+ | `pdf/filespec/bad-id` | `ParseError` | `/ID` is not an array. |
79
+ | `pdf/filespec/bad-ef` | `ParseError` | `/EF` is not a dict. |
80
+ | `pdf/filespec/bad-rf` | `ParseError` | `/RF` is not a dict. |
81
+ | `pdf/filespec/bad-desc` | `ParseError` | `/Desc` is not a string. |
82
+ | `pdf/filespec/bad-afrel` | `ParseError` | `/AFRelationship` is not a name. |
83
+ | `pdf/filespec/empty` | `ParseError` | No path and no `/EF` present. |
84
+
85
+ ## See also
86
+
87
+ - [`pdfEmbeddedFile`](./embeddedFile.md) · [`pdfCollection`](./collection.md) · [`pdfAssociatedFiles`](../associatedFiles/associatedFiles.md)
@@ -0,0 +1,110 @@
1
+ ---
2
+ module: pdfErrors
3
+ category: pdf
4
+ dependencies: []
5
+ returns: object
6
+ worker-safe: true
7
+ status: complete
8
+ ---
9
+
10
+ # pdfErrors
11
+
12
+ > Typed error hierarchy for `@awacloud/pdf` — base `PdfError` + 4 subclasses.
13
+
14
+ **Module** `pdfErrors` | **Source** `packages/front/office/pdf/src/errors.js` | **Deps** none | **Worker-safe** yes
15
+
16
+ Every error carries a stable kebab-case `code` (`'pdf/xref/truncated'`, `'pdf/page/bad-type'`, …), a human `message`, an optional structured `context`, and a chainable `cause`. No function in the package `throw new Error(...)` raw — everything goes through this hierarchy.
17
+
18
+ The classes are not exported at the top level from `@awacloud/pdf`: the only export is the `pdfErrors` factory descriptor. Consumers resolve the 5 classes (`PdfError`, `ParseError`, `RenderError`, `ContractError`, `EncryptionError`) + the `isPdfError` helper via `runtime.resolve('pdfErrors')` or `pdfErrors.factory()`. The classes are declared inside the factory body, so **each `factory()` call creates a fresh set of classes**: an error built from one call is not `instanceof` the classes of another, and that call's `isPdfError` returns `false` for it. A `ModuleRuntime` caches the resolved instance, so every module resolved through the same runtime shares one set of classes — catch with the classes resolved from that runtime, or compare `e.code` / `e.name` when the error may come from elsewhere.
19
+
20
+ ## Resolve
21
+
22
+ ```js
23
+ const errs = runtime.resolve('pdfErrors');
24
+ // Returns: { PdfError, ParseError, RenderError, ContractError, EncryptionError, isPdfError }
25
+ ```
26
+
27
+ Stand-alone (without a `ModuleRuntime`):
28
+
29
+ ```js
30
+ import { pdfErrors } from '@awacloud/pdf';
31
+ const { ParseError, EncryptionError } = pdfErrors.factory();
32
+ ```
33
+
34
+ ## API
35
+
36
+ | Class / method | Signature | Returns |
37
+ |------------------|-----------|----------|
38
+ | `PdfError` | `new (code: string, message: string, opts?: { context?, cause? })` | Instance. |
39
+ | `ParseError` | extends `PdfError` | Read-side / malformed bytes. |
40
+ | `RenderError` | extends `PdfError` | Invalid model at write time (L1+). |
41
+ | `ContractError` | extends `PdfError` | Consumer API contract violation. |
42
+ | `EncryptionError` | extends `PdfError` | Crypto / signatures (L3+). |
43
+ | `isPdfError` | `(e: any) => boolean` | `true` if `e instanceof PdfError`. |
44
+
45
+ ### `new PdfError(code, message, opts?)`
46
+
47
+ `code`: kebab-case (e.g. `'pdf/bad-header'`). `opts.context`: arbitrary payload (`{ offset, num, gen, raw }`). `opts.cause`: source `Error` (re-throw).
48
+
49
+ ## Examples
50
+
51
+ ### Typed catch at the root
52
+
53
+ ```js
54
+ import { ModuleRuntime } from '@awacloud/fw/core/runtime.js';
55
+ import { fw_require, modules } from '@awacloud/pdf';
56
+
57
+ const rt = new ModuleRuntime();
58
+ for (const m of fw_require) rt.register(m);
59
+ for (const m of modules) rt.register(m);
60
+
61
+ const api = rt.resolve('pdf');
62
+ const { isPdfError } = rt.resolve('pdfErrors'); // the classes api throws
63
+
64
+ try {
65
+ api.read(bytes);
66
+ } catch (e) {
67
+ if (isPdfError(e)) {
68
+ console.log(e.name, e.code, e.context);
69
+ } else {
70
+ throw e;
71
+ }
72
+ }
73
+ ```
74
+
75
+ ### Disambiguation by subclass
76
+
77
+ ```js
78
+ const errs = rt.resolve('pdfErrors');
79
+ try { rt.resolve('pdf').read(bytes); }
80
+ catch (e) {
81
+ if (e instanceof errs.ParseError) console.log('malformed input');
82
+ else if (e instanceof errs.ContractError) console.log('API misuse');
83
+ else throw e;
84
+ }
85
+ ```
86
+
87
+ ## Errors
88
+
89
+ This page **defines** the codes; the modules emit them. Prefixes by domain:
90
+
91
+ - `pdf/tokenizer/...` — emitted by [`pdfTokenizer`](./syntax/tokenizer.md).
92
+ - `pdf/parser/...` — emitted by [`pdfParser`](./syntax/parser.md).
93
+ - `pdf/xref/...` — emitted by [`pdfXref`](./syntax/xref.md).
94
+ - `pdf/trailer/...` — emitted by [`pdfTrailer`](./syntax/trailer.md).
95
+ - `pdf/catalog/...` — emitted by [`pdfCatalog`](./document/catalog.md).
96
+ - `pdf/pages/...` — emitted by [`pdfPages`](./document/pages.md).
97
+ - `pdf/page/...` — emitted by [`pdfPage`](./document/page.md).
98
+ - `pdf/document/...` — emitted by [`pdfDocument`](./document/document.md).
99
+ - `pdf/writer/...` — emitted by [`pdfWriter`](./document/writer.md); includes `pdf/writer/unresolvable-objects` (`RenderError`, `context.objects` = `Array<{ num, gen, code }>`), thrown by `assembleIndirects(model, { strict: true })` when an in-use object cannot be resolved.
100
+ - `pdf/use/...` — emitted by [`pdf`](./pdf.md).
101
+ - `pdf/sig/...` — emitted by [`pdfSignature`](./sig/signature.md), [`pdfByteRange`](./sig/byteRange.md), [`pdfCertChain`](./sig/certChain.md). The public-key verification path is wired and executed by construction — there is no `pdf/sig/pk-verify-not-wired` code; see [`pdfSignature`](./sig/signature.md)'s Errors table for the full `pdf/sig/*` and `pdf/sig/verify-pk/*` set.
102
+ - `pdf/ts/...` — emitted by [`pdfTimestamp`](./sig/timestamp.md) (RFC 3161) and by [`pdfSignature`](./sig/signature.md)'s `/DocTimeStamp` verification branch.
103
+ - `pdf/cert/...` — emitted by [`pdfCertChain`](./sig/certChain.md).
104
+ - `pdf/crypto/...` — emitted by [`pdfStandardV5`](./crypto/standardV5.md), [`pdfStandardV6`](./crypto/standardV6.md), [`pdfPermissions`](./crypto/permissions.md), [`pdfSecurity`](./crypto/security.md), [`pdfAesGcm`](./crypto/aesGcm.md).
105
+ - `pdf/sandbox/...` — emitted by the opt-in `pdfSandbox` module (bundle `pdf-full`).
106
+
107
+ ## See also
108
+
109
+ - [`pdf`](./pdf.md) — emitter of `ContractError` on the `.use()` side.
110
+ - [`pdfDocument`](./document/document.md) — propagates `ParseError` for full reads.