@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.
- package/CHANGELOG.md +609 -0
- package/LICENSE +661 -0
- package/NOTICE +77 -0
- package/README.md +363 -2
- package/dist/build/index.js +21 -0
- package/dist/build/pdf-full-rw.js +10972 -0
- package/dist/build/pdf-full-rw.meta.json +105 -0
- package/dist/build/pdf-full-rw.min.js +53 -0
- package/dist/build/pdf-full.js +6078 -0
- package/dist/build/pdf-full.meta.json +90 -0
- package/dist/build/pdf-full.min.js +32 -0
- package/dist/build/pdf-large-rw.js +10367 -0
- package/dist/build/pdf-large-rw.meta.json +99 -0
- package/dist/build/pdf-large-rw.min.js +53 -0
- package/dist/build/pdf-large.js +5473 -0
- package/dist/build/pdf-large.meta.json +84 -0
- package/dist/build/pdf-large.min.js +32 -0
- package/dist/build/pdf-legacy-rw.js +12402 -0
- package/dist/build/pdf-legacy-rw.meta.json +110 -0
- package/dist/build/pdf-legacy-rw.min.js +53 -0
- package/dist/build/pdf-legacy.js +7508 -0
- package/dist/build/pdf-legacy.meta.json +95 -0
- package/dist/build/pdf-legacy.min.js +32 -0
- package/dist/build/pdf-rw.js +7578 -0
- package/dist/build/pdf-rw.meta.json +77 -0
- package/dist/build/pdf-rw.min.js +53 -0
- package/dist/build/pdf.js +2684 -0
- package/dist/build/pdf.meta.json +62 -0
- package/dist/build/pdf.min.js +32 -0
- package/dist/standalone/pdf-full-rw.js +16798 -0
- package/dist/standalone/pdf-full-rw.meta.json +78 -0
- package/dist/standalone/pdf-full-rw.min.js +56 -0
- package/dist/standalone/pdf-full.js +11904 -0
- package/dist/standalone/pdf-full.meta.json +63 -0
- package/dist/standalone/pdf-full.min.js +35 -0
- package/dist/standalone/pdf-large-rw.js +16193 -0
- package/dist/standalone/pdf-large-rw.meta.json +72 -0
- package/dist/standalone/pdf-large-rw.min.js +56 -0
- package/dist/standalone/pdf-large.js +11299 -0
- package/dist/standalone/pdf-large.meta.json +57 -0
- package/dist/standalone/pdf-large.min.js +35 -0
- package/dist/standalone/pdf-legacy-rw.js +18228 -0
- package/dist/standalone/pdf-legacy-rw.meta.json +83 -0
- package/dist/standalone/pdf-legacy-rw.min.js +56 -0
- package/dist/standalone/pdf-legacy.js +13334 -0
- package/dist/standalone/pdf-legacy.meta.json +68 -0
- package/dist/standalone/pdf-legacy.min.js +35 -0
- package/dist/standalone/pdf-rw.js +13404 -0
- package/dist/standalone/pdf-rw.meta.json +50 -0
- package/dist/standalone/pdf-rw.min.js +56 -0
- package/dist/standalone/pdf.js +8510 -0
- package/dist/standalone/pdf.meta.json +35 -0
- package/dist/standalone/pdf.min.js +35 -0
- package/docs/README.md +53 -0
- package/docs/api/README.md +38 -0
- package/docs/api/_shared/README.md +91 -0
- package/docs/api/action/README.md +29 -0
- package/docs/api/action/action.md +81 -0
- package/docs/api/action/goTo.md +66 -0
- package/docs/api/action/launch.md +58 -0
- package/docs/api/action/named.md +55 -0
- package/docs/api/action/uri.md +54 -0
- package/docs/api/annot/README.md +53 -0
- package/docs/api/annot/annot.md +114 -0
- package/docs/api/annot/fileAttach.md +53 -0
- package/docs/api/annot/freeText.md +68 -0
- package/docs/api/annot/ink.md +69 -0
- package/docs/api/annot/link.md +74 -0
- package/docs/api/annot/markup.md +83 -0
- package/docs/api/annot/popup.md +52 -0
- package/docs/api/annot/projection.md +56 -0
- package/docs/api/annot/redact.md +67 -0
- package/docs/api/annot/square.md +87 -0
- package/docs/api/annot/stamp.md +54 -0
- package/docs/api/annot/text.md +69 -0
- package/docs/api/annot/widget.md +69 -0
- package/docs/api/associatedFiles/README.md +9 -0
- package/docs/api/associatedFiles/associatedFiles.md +78 -0
- package/docs/api/bundles/README.md +68 -0
- package/docs/api/bundles/dist-matrix.md +165 -0
- package/docs/api/bundles/pdf-full.md +148 -0
- package/docs/api/bundles/pdf-large.md +144 -0
- package/docs/api/bundles/pdf-legacy.md +169 -0
- package/docs/api/content/README.md +29 -0
- package/docs/api/content/color.md +99 -0
- package/docs/api/content/graphics.md +114 -0
- package/docs/api/content/images.md +124 -0
- package/docs/api/content/ops.md +100 -0
- package/docs/api/content/stream.md +107 -0
- package/docs/api/content/text.md +98 -0
- package/docs/api/crypto/README.md +29 -0
- package/docs/api/crypto/aesGcm.md +72 -0
- package/docs/api/crypto/permissions.md +79 -0
- package/docs/api/crypto/security.md +98 -0
- package/docs/api/crypto/standardV4.md +104 -0
- package/docs/api/crypto/standardV5.md +84 -0
- package/docs/api/crypto/standardV6.md +93 -0
- package/docs/api/destination/README.md +9 -0
- package/docs/api/destination/destination.md +79 -0
- package/docs/api/document/README.md +29 -0
- package/docs/api/document/builder.md +281 -0
- package/docs/api/document/catalog.md +98 -0
- package/docs/api/document/document.md +187 -0
- package/docs/api/document/encryptedWriter.md +149 -0
- package/docs/api/document/incrementalWriter.md +148 -0
- package/docs/api/document/page.md +99 -0
- package/docs/api/document/pages.md +82 -0
- package/docs/api/document/resources.md +102 -0
- package/docs/api/document/writer.md +157 -0
- package/docs/api/document/xrefStreamWriter.md +122 -0
- package/docs/api/embedded/README.md +13 -0
- package/docs/api/embedded/collection.md +80 -0
- package/docs/api/embedded/embeddedFile.md +86 -0
- package/docs/api/embedded/fileSpec.md +87 -0
- package/docs/api/errors.md +110 -0
- package/docs/api/extra/3d-richmedia.md +76 -0
- package/docs/api/extra/README.md +99 -0
- package/docs/api/extra/annot-extended.md +71 -0
- package/docs/api/extra/associated-files.md +70 -0
- package/docs/api/extra/ccitt-fax-decoder.md +74 -0
- package/docs/api/extra/color-spaces-extended.md +72 -0
- package/docs/api/extra/content-ops-extended.md +82 -0
- package/docs/api/extra/document-parts.md +69 -0
- package/docs/api/extra/embedded-files-portfolio.md +87 -0
- package/docs/api/extra/font-cid-typed.md +77 -0
- package/docs/api/extra/font-color-tagging.md +76 -0
- package/docs/api/extra/form-actions-extended.md +75 -0
- package/docs/api/extra/info-dict-deprecated.md +72 -0
- package/docs/api/extra/jbig2-read.md +80 -0
- package/docs/api/extra/legacy-deprecated-annots.md +89 -0
- package/docs/api/extra/legacy-deprecated-filters.md +78 -0
- package/docs/api/extra/legacy-rc4-read.md +74 -0
- package/docs/api/extra/legacy-xfa-read.md +65 -0
- package/docs/api/extra/linearization-write.md +71 -0
- package/docs/api/extra/misc.md +93 -0
- package/docs/api/extra/optional-content-extended.md +83 -0
- package/docs/api/extra/pdf-a-output-intent.md +65 -0
- package/docs/api/extra/pdf-sandbox.md +76 -0
- package/docs/api/extra/pdf-ua-tagged.md +63 -0
- package/docs/api/extra/pdf-x-prepress.md +65 -0
- package/docs/api/extra/redaction-iso32005.md +65 -0
- package/docs/api/extra/shading-typed.md +73 -0
- package/docs/api/extra/sig-aes-gcm.md +69 -0
- package/docs/api/extra/sig-pades.md +103 -0
- package/docs/api/extra/tagged-pdf-typed.md +78 -0
- package/docs/api/extra/transparency-typed.md +74 -0
- package/docs/api/extra/well-tagged-pdf.md +61 -0
- package/docs/api/extra/xmp-extended.md +65 -0
- package/docs/api/font/README.md +25 -0
- package/docs/api/font/embed.md +157 -0
- package/docs/api/font/encoding.md +95 -0
- package/docs/api/font/font.md +97 -0
- package/docs/api/font/type3.md +89 -0
- package/docs/api/form/README.md +35 -0
- package/docs/api/form/acroform.md +88 -0
- package/docs/api/form/appearance.md +87 -0
- package/docs/api/form/button.md +97 -0
- package/docs/api/form/choice.md +96 -0
- package/docs/api/form/fieldTree.md +93 -0
- package/docs/api/form/signature.md +90 -0
- package/docs/api/form/text.md +88 -0
- package/docs/api/linearization/README.md +11 -0
- package/docs/api/linearization/linearization.md +81 -0
- package/docs/api/main.md +116 -0
- package/docs/api/metadata/README.md +10 -0
- package/docs/api/metadata/info.md +70 -0
- package/docs/api/metadata/xmp.md +62 -0
- package/docs/api/ocg/README.md +23 -0
- package/docs/api/ocg/config.md +95 -0
- package/docs/api/ocg/ocg.md +77 -0
- package/docs/api/outline/README.md +11 -0
- package/docs/api/outline/outline.md +107 -0
- package/docs/api/pdf.md +152 -0
- package/docs/api/prepress/README.md +10 -0
- package/docs/api/prepress/outputIntent.md +79 -0
- package/docs/api/prepress/pageBoundary.md +75 -0
- package/docs/api/sig/README.md +32 -0
- package/docs/api/sig/byteRange.md +120 -0
- package/docs/api/sig/certChain.md +84 -0
- package/docs/api/sig/dss.md +111 -0
- package/docs/api/sig/oids.md +76 -0
- package/docs/api/sig/sha1.md +72 -0
- package/docs/api/sig/sign.md +317 -0
- package/docs/api/sig/signature.md +178 -0
- package/docs/api/sig/timestamp.md +84 -0
- package/docs/api/syntax/README.md +29 -0
- package/docs/api/syntax/crossRefStream.md +115 -0
- package/docs/api/syntax/filters/README.md +50 -0
- package/docs/api/syntax/filters/ascii85.md +76 -0
- package/docs/api/syntax/filters/asciiHex.md +73 -0
- package/docs/api/syntax/filters/dispatch.md +125 -0
- package/docs/api/syntax/filters/flate.md +134 -0
- package/docs/api/syntax/filters/runLength.md +78 -0
- package/docs/api/syntax/objStream.md +88 -0
- package/docs/api/syntax/parser-obj.md +97 -0
- package/docs/api/syntax/parser.md +151 -0
- package/docs/api/syntax/serializer.md +109 -0
- package/docs/api/syntax/tokenizer.md +104 -0
- package/docs/api/syntax/trailer.md +85 -0
- package/docs/api/syntax/xref.md +139 -0
- package/docs/api/tagged/README.md +25 -0
- package/docs/api/tagged/classMap.md +67 -0
- package/docs/api/tagged/markedContent.md +62 -0
- package/docs/api/tagged/parentTree.md +67 -0
- package/docs/api/tagged/roleMap.md +67 -0
- package/docs/api/tagged/structElement.md +76 -0
- package/docs/api/tagged/structTree.md +75 -0
- package/docs/guide/coverage.md +113 -0
- package/docs/guide/crypto.md +121 -0
- package/docs/guide/extending.md +76 -0
- package/docs/guide/getting-started.md +75 -0
- package/docs/guide/legacy-1.7.md +42 -0
- package/docs/guide/pades-integration.md +579 -0
- package/docs/guide/read-pdf.md +89 -0
- package/package.json +97 -4
- package/src/_shared/index.js +179 -0
- package/src/action/action.js +119 -0
- package/src/action/goTo.js +89 -0
- package/src/action/launch.js +61 -0
- package/src/action/named.js +54 -0
- package/src/action/uri.js +51 -0
- package/src/annot/annot.js +212 -0
- package/src/annot/fileAttach.js +55 -0
- package/src/annot/freeText.js +82 -0
- package/src/annot/ink.js +77 -0
- package/src/annot/link.js +77 -0
- package/src/annot/markup.js +91 -0
- package/src/annot/popup.js +53 -0
- package/src/annot/projection.js +52 -0
- package/src/annot/redact.js +87 -0
- package/src/annot/square.js +132 -0
- package/src/annot/stamp.js +48 -0
- package/src/annot/text.js +54 -0
- package/src/annot/widget.js +61 -0
- package/src/associatedFiles/associatedFiles.js +86 -0
- package/src/bundles/pdf-full.js +91 -0
- package/src/bundles/pdf-large.js +81 -0
- package/src/bundles/pdf-legacy.js +107 -0
- package/src/content/color.js +114 -0
- package/src/content/graphics.js +192 -0
- package/src/content/images.js +160 -0
- package/src/content/ops.js +137 -0
- package/src/content/stream.js +154 -0
- package/src/content/text.js +125 -0
- package/src/crypto/aesGcm.js +123 -0
- package/src/crypto/permissions.js +112 -0
- package/src/crypto/security.js +327 -0
- package/src/crypto/standardV4.js +443 -0
- package/src/crypto/standardV5.js +306 -0
- package/src/crypto/standardV6.js +334 -0
- package/src/destination/destination.js +183 -0
- package/src/document/builder.js +618 -0
- package/src/document/catalog.js +100 -0
- package/src/document/document.js +472 -0
- package/src/document/encryptedWriter.js +554 -0
- package/src/document/incrementalWriter.js +514 -0
- package/src/document/page.js +131 -0
- package/src/document/pages.js +103 -0
- package/src/document/resources.js +146 -0
- package/src/document/writer.js +211 -0
- package/src/document/xrefStreamWriter.js +353 -0
- package/src/embedded/collection.js +102 -0
- package/src/embedded/embeddedFile.js +99 -0
- package/src/embedded/fileSpec.js +137 -0
- package/src/errors.js +78 -0
- package/src/extra/3d-richmedia.js +171 -0
- package/src/extra/annot-extended.js +200 -0
- package/src/extra/associated-files.js +131 -0
- package/src/extra/ccitt-fax-decoder.js +776 -0
- package/src/extra/color-spaces-extended.js +196 -0
- package/src/extra/content-ops-extended.js +153 -0
- package/src/extra/document-parts.js +149 -0
- package/src/extra/embedded-files-portfolio.js +234 -0
- package/src/extra/font-cid-typed.js +185 -0
- package/src/extra/font-color-tagging.js +144 -0
- package/src/extra/form-actions-extended.js +196 -0
- package/src/extra/info-dict-deprecated.js +137 -0
- package/src/extra/jbig2-read.js +169 -0
- package/src/extra/legacy-deprecated-annots.js +198 -0
- package/src/extra/legacy-deprecated-filters.js +167 -0
- package/src/extra/legacy-rc4-read.js +235 -0
- package/src/extra/legacy-xfa-read.js +104 -0
- package/src/extra/linearization-write.js +97 -0
- package/src/extra/misc.js +217 -0
- package/src/extra/optional-content-extended.js +142 -0
- package/src/extra/pdf-a-output-intent.js +112 -0
- package/src/extra/pdf-sandbox.js +88 -0
- package/src/extra/pdf-ua-tagged.js +116 -0
- package/src/extra/pdf-x-prepress.js +114 -0
- package/src/extra/redaction-iso32005.js +136 -0
- package/src/extra/shading-typed.js +222 -0
- package/src/extra/sig-aes-gcm.js +135 -0
- package/src/extra/sig-pades.js +242 -0
- package/src/extra/tagged-pdf-typed.js +203 -0
- package/src/extra/transparency-typed.js +135 -0
- package/src/extra/well-tagged-pdf.js +138 -0
- package/src/extra/xmp-extended.js +190 -0
- package/src/font/embed.js +480 -0
- package/src/font/encoding.js +92 -0
- package/src/font/font.js +101 -0
- package/src/font/type3.js +75 -0
- package/src/form/acroform.js +94 -0
- package/src/form/appearance.js +90 -0
- package/src/form/button.js +105 -0
- package/src/form/choice.js +152 -0
- package/src/form/fieldTree.js +120 -0
- package/src/form/signature.js +100 -0
- package/src/form/text.js +101 -0
- package/src/linearization/linearization.js +107 -0
- package/src/main.js +411 -0
- package/src/metadata/info.js +87 -0
- package/src/metadata/xmp.js +62 -0
- package/src/ocg/config.js +156 -0
- package/src/ocg/ocg.js +124 -0
- package/src/outline/outline.js +157 -0
- package/src/pdf.js +133 -0
- package/src/prepress/outputIntent.js +118 -0
- package/src/prepress/pageBoundary.js +108 -0
- package/src/sig/byteRange.js +306 -0
- package/src/sig/certChain.js +247 -0
- package/src/sig/dss.js +317 -0
- package/src/sig/oids.js +157 -0
- package/src/sig/sha1.js +142 -0
- package/src/sig/sign.js +1899 -0
- package/src/sig/signature.js +1441 -0
- package/src/sig/timestamp.js +236 -0
- package/src/syntax/crossRefStream.js +133 -0
- package/src/syntax/filters/ascii85.js +122 -0
- package/src/syntax/filters/asciiHex.js +83 -0
- package/src/syntax/filters/dispatch.js +176 -0
- package/src/syntax/filters/flate.js +316 -0
- package/src/syntax/filters/runLength.js +96 -0
- package/src/syntax/objStream.js +99 -0
- package/src/syntax/parser-obj.js +52 -0
- package/src/syntax/parser.js +321 -0
- package/src/syntax/serializer.js +221 -0
- package/src/syntax/tokenizer.js +290 -0
- package/src/syntax/trailer.js +76 -0
- package/src/syntax/xref.js +341 -0
- package/src/tagged/classMap.js +81 -0
- package/src/tagged/markedContent.js +123 -0
- package/src/tagged/parentTree.js +126 -0
- package/src/tagged/roleMap.js +107 -0
- package/src/tagged/structElement.js +138 -0
- 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.
|