@t4h.framework/pdf 0.3.3 → 0.4.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/.ai/skills/framework-pdf/SKILL.md +14 -7
- package/CHANGELOG.md +41 -0
- package/README.md +4 -0
- package/dist/activities/RenderPDFActivity.d.ts.map +1 -1
- package/dist/activities/RenderPDFActivity.js +16 -11
- package/dist/activities/RenderPDFActivity.js.map +1 -1
- package/dist/helpers/document-to-element.d.ts.map +1 -1
- package/dist/helpers/document-to-element.js +2 -8
- package/dist/helpers/document-to-element.js.map +1 -1
- package/dist/helpers/materialize-binary.d.ts +7 -0
- package/dist/helpers/materialize-binary.d.ts.map +1 -0
- package/dist/helpers/materialize-binary.js +45 -0
- package/dist/helpers/materialize-binary.js.map +1 -0
- package/dist/helpers/materialize-document.d.ts +3 -0
- package/dist/helpers/materialize-document.d.ts.map +1 -0
- package/dist/helpers/materialize-document.js +29 -0
- package/dist/helpers/materialize-document.js.map +1 -0
- package/dist/helpers/register-fonts.d.ts +1 -0
- package/dist/helpers/register-fonts.d.ts.map +1 -1
- package/dist/helpers/register-fonts.js +33 -6
- package/dist/helpers/register-fonts.js.map +1 -1
- package/dist/helpers/render-document.d.ts +8 -0
- package/dist/helpers/render-document.d.ts.map +1 -0
- package/dist/helpers/render-document.js +54 -0
- package/dist/helpers/render-document.js.map +1 -0
- package/dist/helpers/render.d.ts +3 -0
- package/dist/helpers/render.d.ts.map +1 -0
- package/dist/helpers/render.js +19 -0
- package/dist/helpers/render.js.map +1 -0
- package/dist/tools/encrypt-pdf.d.ts +4 -1
- package/dist/tools/encrypt-pdf.d.ts.map +1 -1
- package/dist/tools/encrypt-pdf.js +31 -16
- package/dist/tools/encrypt-pdf.js.map +1 -1
- package/dist/workers/render.d.ts +14 -0
- package/dist/workers/render.d.ts.map +1 -0
- package/dist/workers/render.js +9 -0
- package/dist/workers/render.js.map +1 -0
- package/package.json +10 -7
|
@@ -63,12 +63,18 @@ import {
|
|
|
63
63
|
`DocumentNode` JSON tree that is stored in the workflow history. User
|
|
64
64
|
function components, fragments, arrays, and conditionals are flattened
|
|
65
65
|
here; only marker components and strings remain.
|
|
66
|
-
2. **`run`** (activity side):
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
2. **`run`** (activity side): `Binary` image and font sources are read through
|
|
67
|
+
their claims and inlined as `data:` URIs on the calling thread, then the
|
|
68
|
+
resolved tree is handed to a **worker thread** (pool size
|
|
69
|
+
`PDF_RENDER_CONCURRENCY`, default `1`, created on first render, idle workers
|
|
70
|
+
unrefed) that registers fonts once per process, converts the `DocumentNode`
|
|
71
|
+
tree back into real `@react-pdf/renderer` elements and renders it to a
|
|
72
|
+
buffer. The buffer is written through **`FileSystemClaim`** at
|
|
73
|
+
`pdf/${activityId}.pdf`. With the `encrypt` option, a password-protected
|
|
74
|
+
copy (AES-128, `%PDF-1.6`) is written from the same layout at
|
|
75
|
+
`pdf/${activityId}-encrypted.pdf` — no second layout pass, no re-encryption
|
|
76
|
+
of the finished file. A render therefore blocks the event loop of the
|
|
77
|
+
calling process for milliseconds, not for the whole document.
|
|
72
78
|
3. The activity returns the **`Binary`** the claim produced — a reference to
|
|
73
79
|
the stored file, not in-memory bytes. Replay-safe by construction. With
|
|
74
80
|
`encrypt`, it returns the `[original, encrypted]` pair instead, and the
|
|
@@ -277,7 +283,8 @@ const [original, encrypted] = await render(<Invoice />, {
|
|
|
277
283
|
Test the **workflow** with `TestWorkflowEnvironment` from
|
|
278
284
|
`@t4h.framework/core/testing`, mocking the single claim the render activity
|
|
279
285
|
uses: `FileSystemClaim`. See the **framework-workflow-testing** skill for the
|
|
280
|
-
harness API.
|
|
286
|
+
harness API. The render runs in a worker in tests too, so the first render in a
|
|
287
|
+
test file pays for the thread starting up (around 400 ms).
|
|
281
288
|
|
|
282
289
|
```typescript
|
|
283
290
|
import { Readable } from 'node:stream'
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @t4h.framework/pdf
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#181](https://github.com/tech4humans-brasil/framework/pull/181) [`9449e4e`](https://github.com/tech4humans-brasil/framework/commit/9449e4e9889f42dea1d52418140f47d25dff0535) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Renders in a worker thread and encrypts through pdfkit.
|
|
8
|
+
|
|
9
|
+
Layout and writing were one uninterrupted stretch of CPU on the calling
|
|
10
|
+
thread, so a long document stalled every HTTP handler and queue consumer in
|
|
11
|
+
the process. The activity now resolves `Binary` images and fonts into data
|
|
12
|
+
URIs and hands the tree to a worker; an image or font with a `Binary.identity`
|
|
13
|
+
is materialized once per process and shared by every render that embeds it.
|
|
14
|
+
|
|
15
|
+
The encrypted copy was produced by `muhammara.recrypt` over the finished file,
|
|
16
|
+
a synchronous native pass quadratic in the document size. It is now written by
|
|
17
|
+
pdfkit while the file is produced, from the layout the first render already
|
|
18
|
+
computed, so the pair costs one layout. The copy is AES-128 (`%PDF-1.6`)
|
|
19
|
+
instead of 40-bit RC4; `ProtectionFlags` map onto the same `/P` bits, and
|
|
20
|
+
`muhammara` is no longer a dependency.
|
|
21
|
+
|
|
22
|
+
Embedded fonts register once per process, keyed by family, weight, style and a
|
|
23
|
+
digest of the file, instead of retaining a fresh copy on every render.
|
|
24
|
+
|
|
25
|
+
`@react-pdf/renderer`, `@react-pdf/render` and `pdfkit` are pinned to one
|
|
26
|
+
consistent set, guarded by a test that compares the shared-layout writer
|
|
27
|
+
byte for byte against a full render. The public API and `fs.write` output are
|
|
28
|
+
unchanged.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [[`9449e4e`](https://github.com/tech4humans-brasil/framework/commit/9449e4e9889f42dea1d52418140f47d25dff0535), [`9449e4e`](https://github.com/tech4humans-brasil/framework/commit/9449e4e9889f42dea1d52418140f47d25dff0535), [`9449e4e`](https://github.com/tech4humans-brasil/framework/commit/9449e4e9889f42dea1d52418140f47d25dff0535)]:
|
|
33
|
+
- @t4h.framework/core@0.15.0
|
|
34
|
+
- @t4h.framework/fs@0.10.0
|
|
35
|
+
|
|
36
|
+
## 0.3.4
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [[`aa72268`](https://github.com/tech4humans-brasil/framework/commit/aa72268d040a743743cac31cc14e26b8620b0e3f)]:
|
|
41
|
+
- @t4h.framework/core@0.14.0
|
|
42
|
+
- @t4h.framework/fs@0.9.4
|
|
43
|
+
|
|
3
44
|
## 0.3.3
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -131,10 +131,14 @@ const pdf = await render(<Doc />, {
|
|
|
131
131
|
|
|
132
132
|
Select variants in styles with `fontFamily`, `fontWeight` (`100–900`), and `fontStyle` (`'normal' | 'italic'`).
|
|
133
133
|
|
|
134
|
+
Each variant reaches the process-wide font store once, keyed by family, weight, style and the file's digest, so passing `fonts` on every render costs nothing after the first.
|
|
135
|
+
|
|
134
136
|
## Encryption
|
|
135
137
|
|
|
136
138
|
Pass `encrypt` to also persist a password-protected copy — `render` then resolves with an `[original, encrypted]` pair (the return type narrows automatically). `password` is a bare string or `{ user, owner }`; `protection` is a `ProtectionFlags` bitmask (defaults follow the viewer; use `ProtectionPresets.ReadOnly` for view-and-print documents). Permission flags are honored by viewers, not enforced cryptographically.
|
|
137
139
|
|
|
140
|
+
The encrypted copy is written with pdfkit's own encryption (AES-128, PDF 1.6) from the layout the first render already produced, so neither a re-encryption pass over the finished file nor a second layout is paid for.
|
|
141
|
+
|
|
138
142
|
```tsx
|
|
139
143
|
import { ProtectionPresets, render } from '@t4h.framework/pdf'
|
|
140
144
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderPDFActivity.d.ts","sourceRoot":"","sources":["../../src/activities/RenderPDFActivity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RenderPDFActivity.d.ts","sourceRoot":"","sources":["../../src/activities/RenderPDFActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAIzC,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,8BAA8B,CAAA;AAEvE,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,YAAY,CAAA;CACvB,GAAG,gBAAgB,CAAA;AAEpB,qBAAa,iBAAkB,SAAQ,YAAY,CACjD,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,EAC5D,cAAc,EACd,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACzB,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAC1B;IACC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAErD,OAAO,CACZ,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,cAAc;IAQJ,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAmBpE,QAAQ,CACb,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;CAG7B;AAED,wBAAsB,MAAM,CAC1B,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,gBAAgB,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,GACzD,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;AACjD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,gBAAgB,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,GACnD,OAAO,CAAC,MAAM,CAAC,CAAA;AAClB,wBAAsB,MAAM,CAC1B,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { renderToBuffer } from '@react-pdf/renderer';
|
|
2
1
|
import { Binary, Claim, History, SyncActivity } from '@t4h.framework/core';
|
|
3
2
|
import { FileSystemClaim } from '@t4h.framework/fs';
|
|
4
|
-
import { documentToElement } from '../helpers/document-to-element.js';
|
|
5
3
|
import { elementToDocument } from '../helpers/element-to-document.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { materializeDocument } from '../helpers/materialize-document.js';
|
|
5
|
+
import { resolveFonts } from '../helpers/register-fonts.js';
|
|
6
|
+
import { render as renderInPool } from '../helpers/render.js';
|
|
7
|
+
import { toDocumentEncryptionProps, } from '../tools/encrypt-pdf.js';
|
|
8
8
|
export class RenderPDFActivity extends SyncActivity {
|
|
9
9
|
claims = new Claim({ fs: FileSystemClaim });
|
|
10
10
|
toInput(element, options) {
|
|
@@ -15,15 +15,20 @@ export class RenderPDFActivity extends SyncActivity {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
async run(input) {
|
|
18
|
-
|
|
19
|
-
await
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const { pdf, encrypted } = await renderInPool({
|
|
19
|
+
document: await materializeDocument(input.document),
|
|
20
|
+
fonts: input.fonts ? await resolveFonts(input.fonts) : undefined,
|
|
21
|
+
encryption: input.encrypt
|
|
22
|
+
? toDocumentEncryptionProps(input.encrypt)
|
|
23
|
+
: undefined,
|
|
24
|
+
});
|
|
22
25
|
const original = await this.claims.fs.write(`pdf/${this.id}.pdf`, pdf);
|
|
23
|
-
if (!
|
|
26
|
+
if (!encrypted)
|
|
24
27
|
return original;
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
return [
|
|
29
|
+
original,
|
|
30
|
+
await this.claims.fs.write(`pdf/${this.id}-encrypted.pdf`, encrypted),
|
|
31
|
+
];
|
|
27
32
|
}
|
|
28
33
|
toOutput(output) {
|
|
29
34
|
return output;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderPDFActivity.js","sourceRoot":"","sources":["../../src/activities/RenderPDFActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"RenderPDFActivity.js","sourceRoot":"","sources":["../../src/activities/RenderPDFActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAc,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EACL,yBAAyB,GAE1B,MAAM,yBAAyB,CAAA;AAYhC,MAAM,OAAO,iBAAkB,SAAQ,YAKtC;IACkB,MAAM,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;IAErD,OAAO,CACZ,OAAqB,EACrB,OAA0B;QAE1B,OAAO;YACL,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC;YACpC,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,OAAO,EAAE,OAAO,EAAE,OAAO;SAC1B,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAqB;QACpC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC;YAC5C,QAAQ,EAAE,MAAM,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC;YACnD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YAChE,UAAU,EAAE,KAAK,CAAC,OAAO;gBACvB,CAAC,CAAC,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC;gBAC1C,CAAC,CAAC,SAAS;SACd,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;QAEtE,IAAI,CAAC,SAAS;YAAE,OAAO,QAAQ,CAAA;QAE/B,OAAO;YACL,QAAQ;YACR,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,gBAAgB,EAAE,SAAS,CAAC;SACtE,CAAA;IACH,CAAC;IAEM,QAAQ,CACb,MAAiC;QAEjC,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAcD,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAqB,EACrB,OAA0B;IAE1B,OAAO,MAAM,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AACtE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-to-element.d.ts","sourceRoot":"","sources":["../../src/helpers/document-to-element.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"document-to-element.d.ts","sourceRoot":"","sources":["../../src/helpers/document-to-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiC,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AAG7E,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,mBAAmB,CAAA;AAiF1B,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAMxD"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { buffer } from 'node:stream/consumers';
|
|
2
1
|
import { Document, Image, Link, Page, Text, View } from '@react-pdf/renderer';
|
|
3
2
|
import { createElement } from 'react';
|
|
4
|
-
|
|
5
|
-
if (typeof src === 'string')
|
|
6
|
-
return src;
|
|
7
|
-
const data = await buffer(await src.stream());
|
|
8
|
-
return `data:${src.contentType};base64,${data.toString('base64')}`;
|
|
9
|
-
}
|
|
3
|
+
import { materializeBinary } from './materialize-binary.js';
|
|
10
4
|
async function toTextChildren(children) {
|
|
11
5
|
if (children === undefined)
|
|
12
6
|
return [];
|
|
@@ -29,7 +23,7 @@ async function nodeToElement(node) {
|
|
|
29
23
|
const { src, ...props } = node.props;
|
|
30
24
|
return createElement(Image, {
|
|
31
25
|
...props,
|
|
32
|
-
src: await
|
|
26
|
+
src: await materializeBinary(src),
|
|
33
27
|
});
|
|
34
28
|
}
|
|
35
29
|
case 'page-number': {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-to-element.js","sourceRoot":"","sources":["../../src/helpers/document-to-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"document-to-element.js","sourceRoot":"","sources":["../../src/helpers/document-to-element.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Binary } from '@t4h.framework/core';
|
|
2
|
+
export interface MaterializeBinaryOptions {
|
|
3
|
+
contentType?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function toDataUrl(contentType: string, bytes: Buffer): string;
|
|
6
|
+
export declare function materializeBinary(src: string | Binary, { contentType }?: MaterializeBinaryOptions): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=materialize-binary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize-binary.d.ts","sourceRoot":"","sources":["../../src/helpers/materialize-binary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAaD,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpE;AAmCD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,EAAE,WAAW,EAAE,GAAE,wBAA6B,GAC7C,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { buffer } from 'node:stream/consumers';
|
|
2
|
+
const CACHE_MAX_TOTAL_SIZE_IN_BYTES = 32 * 1024 * 1024;
|
|
3
|
+
const cache = new Map();
|
|
4
|
+
let cachedSizeInBytes = 0;
|
|
5
|
+
export function toDataUrl(contentType, bytes) {
|
|
6
|
+
return `data:${contentType};base64,${bytes.toString('base64')}`;
|
|
7
|
+
}
|
|
8
|
+
function evictOldest() {
|
|
9
|
+
for (const [key, entry] of cache) {
|
|
10
|
+
if (cachedSizeInBytes <= CACHE_MAX_TOTAL_SIZE_IN_BYTES)
|
|
11
|
+
return;
|
|
12
|
+
cache.delete(key);
|
|
13
|
+
cachedSizeInBytes -= entry.sizeInBytes;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function remember(key, read) {
|
|
17
|
+
const entry = { dataUrl: read(), sizeInBytes: 0 };
|
|
18
|
+
cache.set(key, entry);
|
|
19
|
+
entry.dataUrl.then(value => {
|
|
20
|
+
if (cache.get(key) !== entry)
|
|
21
|
+
return;
|
|
22
|
+
entry.sizeInBytes = value.length;
|
|
23
|
+
cachedSizeInBytes += value.length;
|
|
24
|
+
evictOldest();
|
|
25
|
+
}, () => {
|
|
26
|
+
if (cache.get(key) === entry)
|
|
27
|
+
cache.delete(key);
|
|
28
|
+
});
|
|
29
|
+
return entry.dataUrl;
|
|
30
|
+
}
|
|
31
|
+
export async function materializeBinary(src, { contentType } = {}) {
|
|
32
|
+
if (typeof src === 'string')
|
|
33
|
+
return src;
|
|
34
|
+
const type = contentType ?? src.contentType;
|
|
35
|
+
const read = async () => toDataUrl(type, await buffer(await src.stream()));
|
|
36
|
+
const identity = src.identity;
|
|
37
|
+
if (identity === undefined)
|
|
38
|
+
return await read();
|
|
39
|
+
const key = `${type}\0${identity}`;
|
|
40
|
+
const cached = cache.get(key);
|
|
41
|
+
if (cached)
|
|
42
|
+
return await cached.dataUrl;
|
|
43
|
+
return await remember(key, read);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=materialize-binary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize-binary.js","sourceRoot":"","sources":["../../src/helpers/materialize-binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAQ9C,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAOtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;AAE3C,IAAI,iBAAiB,GAAG,CAAC,CAAA;AAEzB,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,KAAa;IAC1D,OAAO,QAAQ,WAAW,WAAW,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;AACjE,CAAC;AAED,SAAS,WAAW;IAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,IAAI,iBAAiB,IAAI,6BAA6B;YAAE,OAAM;QAE9D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAEjB,iBAAiB,IAAI,KAAK,CAAC,WAAW,CAAA;IACxC,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,IAA2B;IACxD,MAAM,KAAK,GAAe,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAA;IAE7D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAErB,KAAK,CAAC,OAAO,CAAC,IAAI,CAChB,KAAK,CAAC,EAAE;QACN,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,OAAM;QAEpC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,MAAM,CAAA;QAEhC,iBAAiB,IAAI,KAAK,CAAC,MAAM,CAAA;QAEjC,WAAW,EAAE,CAAA;IACf,CAAC,EACD,GAAG,EAAE;QACH,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACjD,CAAC,CACF,CAAA;IAED,OAAO,KAAK,CAAC,OAAO,CAAA;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAoB,EACpB,EAAE,WAAW,KAA+B,EAAE;IAE9C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IAEvC,MAAM,IAAI,GAAG,WAAW,IAAI,GAAG,CAAC,WAAW,CAAA;IAE3C,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAE1E,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAE7B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,MAAM,IAAI,EAAE,CAAA;IAE/C,MAAM,GAAG,GAAG,GAAG,IAAI,KAAK,QAAQ,EAAE,CAAA;IAElC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAE7B,IAAI,MAAM;QAAE,OAAO,MAAM,MAAM,CAAC,OAAO,CAAA;IAEvC,OAAO,MAAM,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize-document.d.ts","sourceRoot":"","sources":["../../src/helpers/materialize-document.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,mBAAmB,CAAA;AA0BxE,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,YAAY,CAAC,CAKvB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { materializeBinary } from './materialize-binary.js';
|
|
2
|
+
async function materializeNode(node) {
|
|
3
|
+
if (node.type === 'image')
|
|
4
|
+
return {
|
|
5
|
+
...node,
|
|
6
|
+
props: { ...node.props, src: await materializeBinary(node.props.src) },
|
|
7
|
+
};
|
|
8
|
+
if (node.type !== 'view' || !node.children)
|
|
9
|
+
return node;
|
|
10
|
+
return {
|
|
11
|
+
...node,
|
|
12
|
+
children: await Promise.all(node.children.map(materializeNode)),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
async function materializePage(page) {
|
|
16
|
+
if (!page.children)
|
|
17
|
+
return page;
|
|
18
|
+
return {
|
|
19
|
+
...page,
|
|
20
|
+
children: await Promise.all(page.children.map(materializeNode)),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export async function materializeDocument(document) {
|
|
24
|
+
return {
|
|
25
|
+
...document,
|
|
26
|
+
children: await Promise.all(document.children.map(materializePage)),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=materialize-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialize-document.js","sourceRoot":"","sources":["../../src/helpers/materialize-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAG3D,KAAK,UAAU,eAAe,CAAC,IAAa;IAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QACvB,OAAO;YACL,GAAG,IAAI;YACP,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;SACvE,CAAA;IAEH,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAEvD,OAAO;QACL,GAAG,IAAI;QACP,QAAQ,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;KAChE,CAAA;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAc;IAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAE/B,OAAO;QACL,GAAG,IAAI;QACP,QAAQ,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;KAChE,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAsB;IAEtB,OAAO;QACL,GAAG,QAAQ;QACX,QAAQ,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;KACpE,CAAA;AACH,CAAC"}
|
|
@@ -10,5 +10,6 @@ export type FontVariant = {
|
|
|
10
10
|
export type Fonts = {
|
|
11
11
|
[name: string]: FontSource | readonly FontVariant[];
|
|
12
12
|
};
|
|
13
|
+
export declare function resolveFonts(raw: Fonts): Promise<Fonts>;
|
|
13
14
|
export declare function registerFonts(raw: Fonts): Promise<void>;
|
|
14
15
|
//# sourceMappingURL=register-fonts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-fonts.d.ts","sourceRoot":"","sources":["../../src/helpers/register-fonts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"register-fonts.d.ts","sourceRoot":"","sources":["../../src/helpers/register-fonts.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAI5C,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAE5E,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE3C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAExC,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,UAAU,CAAA;IACf,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,WAAW,EAAE,CAAA;CACpD,CAAA;AAiBD,wBAAsB,YAAY,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAsB7D;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,KAAK,iBA0D7C"}
|
|
@@ -1,9 +1,28 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { buffer } from 'node:stream/consumers';
|
|
2
3
|
import { Font } from '@react-pdf/renderer';
|
|
3
4
|
import { Binary } from '@t4h.framework/core';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { materializeBinary, toDataUrl } from './materialize-binary.js';
|
|
6
|
+
const FONT_CONTENT_TYPE = 'font/ttf';
|
|
7
|
+
const registered = new Set();
|
|
8
|
+
function toVariantKey(family, fontWeight, fontStyle, source) {
|
|
9
|
+
const digest = createHash('sha256').update(source).digest('hex');
|
|
10
|
+
return `${family}\0${fontWeight}\0${fontStyle}\0${digest}`;
|
|
11
|
+
}
|
|
12
|
+
export async function resolveFonts(raw) {
|
|
13
|
+
const families = await Promise.all(Object.entries(raw ?? {}).map(async ([name, source]) => {
|
|
14
|
+
const variants = typeof source === 'string' || source instanceof Binary
|
|
15
|
+
? [{ src: source }]
|
|
16
|
+
: source;
|
|
17
|
+
const resolved = await Promise.all(variants.map(async (variant) => ({
|
|
18
|
+
...variant,
|
|
19
|
+
src: await materializeBinary(variant.src, {
|
|
20
|
+
contentType: FONT_CONTENT_TYPE,
|
|
21
|
+
}),
|
|
22
|
+
})));
|
|
23
|
+
return [name, resolved];
|
|
24
|
+
}));
|
|
25
|
+
return Object.fromEntries(families);
|
|
7
26
|
}
|
|
8
27
|
export async function registerFonts(raw) {
|
|
9
28
|
const fonts = await Promise.all(Object.entries(raw ?? {}).flatMap(([name, source]) => {
|
|
@@ -26,13 +45,21 @@ export async function registerFonts(raw) {
|
|
|
26
45
|
}));
|
|
27
46
|
const families = new Map();
|
|
28
47
|
for (const font of fonts) {
|
|
48
|
+
const fontWeight = font.weight ?? 400;
|
|
49
|
+
const fontStyle = font.style ?? 'normal';
|
|
50
|
+
const key = toVariantKey(font.name, fontWeight, fontStyle, font.src);
|
|
51
|
+
if (registered.has(key))
|
|
52
|
+
continue;
|
|
29
53
|
const variants = families.get(font.name) ?? [];
|
|
30
54
|
variants.push({
|
|
31
|
-
src: typeof font.src === 'string'
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
src: typeof font.src === 'string'
|
|
56
|
+
? font.src
|
|
57
|
+
: toDataUrl(FONT_CONTENT_TYPE, font.src),
|
|
58
|
+
fontWeight,
|
|
59
|
+
fontStyle,
|
|
34
60
|
});
|
|
35
61
|
families.set(font.name, variants);
|
|
62
|
+
registered.add(key);
|
|
36
63
|
}
|
|
37
64
|
for (const [family, variants] of families)
|
|
38
65
|
Font.register({ family, fonts: variants });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-fonts.js","sourceRoot":"","sources":["../../src/helpers/register-fonts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"register-fonts.js","sourceRoot":"","sources":["../../src/helpers/register-fonts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type DocumentProps } from '@react-pdf/renderer';
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { DocumentEncryptionProps } from '../tools/encrypt-pdf.js';
|
|
4
|
+
export declare function renderDocument(element: ReactElement<DocumentProps>, encryption?: DocumentEncryptionProps): Promise<{
|
|
5
|
+
pdf: Buffer;
|
|
6
|
+
encrypted?: Buffer;
|
|
7
|
+
}>;
|
|
8
|
+
//# sourceMappingURL=render-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-document.d.ts","sourceRoot":"","sources":["../../src/helpers/render-document.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExE,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AA6CtE,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC,EACpC,UAAU,CAAC,EAAE,uBAAuB,GACnC,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B9C"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import renderPDF from '@react-pdf/render';
|
|
2
|
+
import { renderToBuffer } from '@react-pdf/renderer';
|
|
3
|
+
import { PDFDocument } from 'pdfkit';
|
|
4
|
+
import { cloneElement } from 'react';
|
|
5
|
+
function toContext(props, encryption) {
|
|
6
|
+
const info = {};
|
|
7
|
+
const put = (key, value) => {
|
|
8
|
+
if (value !== undefined)
|
|
9
|
+
info[key] = value;
|
|
10
|
+
};
|
|
11
|
+
put('Title', props.title);
|
|
12
|
+
put('Author', props.author);
|
|
13
|
+
put('Subject', props.subject);
|
|
14
|
+
put('Creator', props.creator ?? 'react-pdf');
|
|
15
|
+
put('Producer', props.producer ?? 'react-pdf');
|
|
16
|
+
put('CreationDate', props.creationDate);
|
|
17
|
+
put('ModificationDate', props.modificationDate);
|
|
18
|
+
return new PDFDocument({
|
|
19
|
+
compress: true,
|
|
20
|
+
displayTitle: true,
|
|
21
|
+
autoFirstPage: false,
|
|
22
|
+
lang: props.language,
|
|
23
|
+
info,
|
|
24
|
+
...encryption,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function toBuffer(context) {
|
|
28
|
+
const chunks = [];
|
|
29
|
+
for await (const chunk of context)
|
|
30
|
+
chunks.push(chunk);
|
|
31
|
+
return Buffer.concat(chunks);
|
|
32
|
+
}
|
|
33
|
+
export async function renderDocument(element, encryption) {
|
|
34
|
+
if (!encryption)
|
|
35
|
+
return { pdf: await renderToBuffer(element) };
|
|
36
|
+
const props = {
|
|
37
|
+
...element.props,
|
|
38
|
+
creationDate: element.props.creationDate ?? new Date(),
|
|
39
|
+
};
|
|
40
|
+
let layout;
|
|
41
|
+
const pdf = await renderToBuffer(cloneElement(element, {
|
|
42
|
+
...props,
|
|
43
|
+
onRender: rendered => {
|
|
44
|
+
layout = rendered._INTERNAL__LAYOUT__DATA_;
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
if (!layout)
|
|
48
|
+
throw new Error('Rendering exposed no document layout. @react-pdf/renderer and @react-pdf/render are likely out of step.');
|
|
49
|
+
return {
|
|
50
|
+
pdf,
|
|
51
|
+
encrypted: await toBuffer(renderPDF(toContext(props, encryption), layout)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=render-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-document.js","sourceRoot":"","sources":["../../src/helpers/render-document.ts"],"names":[],"mappings":"AAEA,OAAO,SAAS,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,EAAE,YAAY,EAAqB,MAAM,OAAO,CAAA;AAUvD,SAAS,SAAS,CAChB,KAAoB,EACpB,UAAoC;IAEpC,MAAM,IAAI,GAAkC,EAAE,CAAA;IAE9C,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,KAAgC,EAAE,EAAE;QAC5D,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAC5C,CAAC,CAAA;IAED,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACzB,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC3B,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAC7B,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC,CAAA;IAC5C,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,IAAI,WAAW,CAAC,CAAA;IAC9C,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;IACvC,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;IAE/C,OAAO,IAAI,WAAW,CAAC;QACrB,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,KAAK;QACpB,IAAI,EAAE,KAAK,CAAC,QAAQ;QACpB,IAAI;QACJ,GAAG,UAAU;KACd,CAA+B,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,OAAwB;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAA8B;QACtD,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAA;IAE9B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAoC,EACpC,UAAoC;IAEpC,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC,OAAO,CAAC,EAAE,CAAA;IAE9D,MAAM,KAAK,GAAkB;QAC3B,GAAG,OAAO,CAAC,KAAK;QAChB,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,IAAI,EAAE;KACvD,CAAA;IAED,IAAI,MAAkC,CAAA;IAEtC,MAAM,GAAG,GAAG,MAAM,cAAc,CAC9B,YAAY,CAAC,OAAO,EAAE;QACpB,GAAG,KAAK;QACR,QAAQ,EAAE,QAAQ,CAAC,EAAE;YACnB,MAAM,GAAI,QAA6B,CAAC,wBAAwB,CAAA;QAClE,CAAC;KACF,CAAC,CACH,CAAA;IAED,IAAI,CAAC,MAAM;QACT,MAAM,IAAI,KAAK,CACb,yGAAyG,CAC1G,CAAA;IAEH,OAAO;QACL,GAAG;QACH,SAAS,EAAE,MAAM,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;KAC3E,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/helpers/render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAiBpE,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAYpE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { Piscina } from 'piscina';
|
|
3
|
+
const WORKER = fileURLToPath(new URL('../../dist/workers/render.js', import.meta.url));
|
|
4
|
+
let pool = null;
|
|
5
|
+
function toBuffer(bytes) {
|
|
6
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
7
|
+
}
|
|
8
|
+
export async function render(task) {
|
|
9
|
+
pool ??= new Piscina({
|
|
10
|
+
filename: WORKER,
|
|
11
|
+
minThreads: 1,
|
|
12
|
+
maxThreads: 1,
|
|
13
|
+
});
|
|
14
|
+
const { pdf, encrypted } = await pool.run(task);
|
|
15
|
+
if (!encrypted)
|
|
16
|
+
return { pdf: toBuffer(pdf) };
|
|
17
|
+
return { pdf: toBuffer(pdf), encrypted: toBuffer(encrypted) };
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/helpers/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAIjC,MAAM,MAAM,GAAG,aAAa,CAC1B,IAAI,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACzD,CAAA;AAOD,IAAI,IAAI,GAA2C,IAAI,CAAA;AAEvD,SAAS,QAAQ,CAAC,KAAiB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAgB;IAC3C,IAAI,KAAK,IAAI,OAAO,CAAyB;QAC3C,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;KACd,CAAC,CAAA;IAEF,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAE/C,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAA;IAE7C,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAA;AAC/D,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DocumentProps } from '@react-pdf/renderer';
|
|
1
2
|
export declare enum ProtectionFlags {
|
|
2
3
|
Print = 4,
|
|
3
4
|
Modify = 8,
|
|
@@ -20,6 +21,8 @@ export type EncryptPDFOptions = {
|
|
|
20
21
|
password: Password;
|
|
21
22
|
protection?: ProtectionFlags;
|
|
22
23
|
};
|
|
23
|
-
export
|
|
24
|
+
export type DocumentEncryptionProps = Pick<DocumentProps, 'pdfVersion' | 'userPassword' | 'ownerPassword' | 'permissions'>;
|
|
25
|
+
export declare function toPermissions(protection: ProtectionFlags): NonNullable<DocumentProps['permissions']>;
|
|
26
|
+
export declare function toDocumentEncryptionProps(options: EncryptPDFOptions): DocumentEncryptionProps;
|
|
24
27
|
export {};
|
|
25
28
|
//# sourceMappingURL=encrypt-pdf.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/encrypt-pdf.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encrypt-pdf.d.ts","sourceRoot":"","sources":["../../src/tools/encrypt-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,oBAAY,eAAe;IACzB,KAAK,IAAI;IACT,MAAM,IAAI;IACV,cAAc,KAAK;IACnB,eAAe,KAAK;IACpB,SAAS,MAAM;IACf,uBAAuB,MAAM;IAC7B,QAAQ,OAAO;IACf,mBAAmB,OAAO;CAC3B;AAED,eAAO,MAAM,iBAAiB;;;CAcpB,CAAA;AAEV,KAAK,QAAQ,GACT,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAEL,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,QAAQ,CAAA;IAClB,UAAU,CAAC,EAAE,eAAe,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,aAAa,EACb,YAAY,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAChE,CAAA;AASD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,GAC1B,WAAW,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAmB3C;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,iBAAiB,GACzB,uBAAuB,CAczB"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable cspell/spellchecker */
|
|
2
|
-
import muhammara from 'muhammara';
|
|
3
1
|
export var ProtectionFlags;
|
|
4
2
|
(function (ProtectionFlags) {
|
|
5
3
|
ProtectionFlags[ProtectionFlags["Print"] = 4] = "Print";
|
|
@@ -24,19 +22,36 @@ export const ProtectionPresets = {
|
|
|
24
22
|
ProtectionFlags.Assemble |
|
|
25
23
|
ProtectionFlags.PrintHighResolution,
|
|
26
24
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
const ENCRYPTED_PDF_VERSION = '1.6';
|
|
26
|
+
const DEFAULT_PROTECTION = ProtectionFlags.Print;
|
|
27
|
+
const has = (protection, flag) => (protection & flag) === flag;
|
|
28
|
+
export function toPermissions(protection) {
|
|
29
|
+
const printing = has(protection, ProtectionFlags.PrintHighResolution)
|
|
30
|
+
? 'highResolution'
|
|
31
|
+
: has(protection, ProtectionFlags.Print)
|
|
32
|
+
? 'lowResolution'
|
|
33
|
+
: undefined;
|
|
34
|
+
return {
|
|
35
|
+
printing,
|
|
36
|
+
modifying: has(protection, ProtectionFlags.Modify),
|
|
37
|
+
copying: has(protection, ProtectionFlags.CopyAndExtract),
|
|
38
|
+
annotating: has(protection, ProtectionFlags.AnnotateAndFill),
|
|
39
|
+
fillingForms: has(protection, ProtectionFlags.FillForms),
|
|
40
|
+
contentAccessibility: has(protection, ProtectionFlags.ExtractForAccessibility),
|
|
41
|
+
documentAssembly: has(protection, ProtectionFlags.Assemble),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function toDocumentEncryptionProps(options) {
|
|
45
|
+
const password = typeof options.password === 'string'
|
|
46
|
+
? { userPassword: options.password }
|
|
47
|
+
: {
|
|
48
|
+
userPassword: options.password.user,
|
|
49
|
+
ownerPassword: options.password.owner,
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
pdfVersion: ENCRYPTED_PDF_VERSION,
|
|
53
|
+
permissions: toPermissions(options.protection ?? DEFAULT_PROTECTION),
|
|
54
|
+
...password,
|
|
55
|
+
};
|
|
41
56
|
}
|
|
42
57
|
//# sourceMappingURL=encrypt-pdf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt-pdf.js","sourceRoot":"","sources":["../../src/tools/encrypt-pdf.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encrypt-pdf.js","sourceRoot":"","sources":["../../src/tools/encrypt-pdf.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,eASX;AATD,WAAY,eAAe;IACzB,uDAAS,CAAA;IACT,yDAAU,CAAA;IACV,0EAAmB,CAAA;IACnB,4EAAoB,CAAA;IACpB,iEAAe,CAAA;IACf,6FAA6B,CAAA;IAC7B,gEAAe,CAAA;IACf,sFAA0B,CAAA;AAC5B,CAAC,EATW,eAAe,KAAf,eAAe,QAS1B;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,EACN,eAAe,CAAC,KAAK;QACrB,eAAe,CAAC,mBAAmB;QACnC,eAAe,CAAC,uBAAuB;IACzC,GAAG,EACD,eAAe,CAAC,KAAK;QACrB,eAAe,CAAC,MAAM;QACtB,eAAe,CAAC,cAAc;QAC9B,eAAe,CAAC,eAAe;QAC/B,eAAe,CAAC,SAAS;QACzB,eAAe,CAAC,uBAAuB;QACvC,eAAe,CAAC,QAAQ;QACxB,eAAe,CAAC,mBAAmB;CAC7B,CAAA;AAmBV,MAAM,qBAAqB,GAAgC,KAAK,CAAA;AAEhE,MAAM,kBAAkB,GAAG,eAAe,CAAC,KAAK,CAAA;AAEhD,MAAM,GAAG,GAAG,CAAC,UAAkB,EAAE,IAAqB,EAAE,EAAE,CACxD,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,IAAI,CAAA;AAE9B,MAAM,UAAU,aAAa,CAC3B,UAA2B;IAE3B,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,mBAAmB,CAAC;QACnE,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC;YACtC,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,SAAS,CAAA;IAEf,OAAO;QACL,QAAQ;QACR,SAAS,EAAE,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC;QAClD,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,cAAc,CAAC;QACxD,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,eAAe,CAAC;QAC5D,YAAY,EAAE,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,SAAS,CAAC;QACxD,oBAAoB,EAAE,GAAG,CACvB,UAAU,EACV,eAAe,CAAC,uBAAuB,CACxC;QACD,gBAAgB,EAAE,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,QAAQ,CAAC;KAC5D,CAAA;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAA0B;IAE1B,MAAM,QAAQ,GACZ,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAClC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,QAAQ,EAAE;QACpC,CAAC,CAAC;YACE,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;YACnC,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK;SACtC,CAAA;IAEP,OAAO;QACL,UAAU,EAAE,qBAAqB;QACjC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,UAAU,IAAI,kBAAkB,CAAC;QACpE,GAAG,QAAQ;KACZ,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Fonts } from '../helpers/register-fonts.js';
|
|
2
|
+
import type { DocumentEncryptionProps } from '../tools/encrypt-pdf.js';
|
|
3
|
+
import type { DocumentNode } from '../typings/pdf.js';
|
|
4
|
+
export type RenderTask = {
|
|
5
|
+
document: DocumentNode;
|
|
6
|
+
fonts?: Fonts | undefined;
|
|
7
|
+
encryption?: DocumentEncryptionProps | undefined;
|
|
8
|
+
};
|
|
9
|
+
export type RenderResult = {
|
|
10
|
+
pdf: Buffer;
|
|
11
|
+
encrypted?: Buffer;
|
|
12
|
+
};
|
|
13
|
+
export default function render({ document, fonts, encryption, }: RenderTask): Promise<RenderResult>;
|
|
14
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/workers/render.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,KAAK,EAAE,MAAM,8BAA8B,CAAA;AAExE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,YAAY,CAAA;IACtB,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;IACzB,UAAU,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAA8B,MAAM,CAAC,EACnC,QAAQ,EACR,KAAK,EACL,UAAU,GACX,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAIpC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { documentToElement } from '../helpers/document-to-element.js';
|
|
2
|
+
import { registerFonts } from '../helpers/register-fonts.js';
|
|
3
|
+
import { renderDocument } from '../helpers/render-document.js';
|
|
4
|
+
export default async function render({ document, fonts, encryption, }) {
|
|
5
|
+
if (fonts)
|
|
6
|
+
await registerFonts(fonts);
|
|
7
|
+
return await renderDocument(await documentToElement(document), encryption);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/workers/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAc,MAAM,8BAA8B,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAe9D,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,MAAM,CAAC,EACnC,QAAQ,EACR,KAAK,EACL,UAAU,GACC;IACX,IAAI,KAAK;QAAE,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;IAErC,OAAO,MAAM,cAAc,CAAC,MAAM,iBAAiB,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAA;AAC5E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t4h.framework/pdf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Declarative PDF rendering module for the T4H Framework",
|
|
5
5
|
"homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/pdf",
|
|
6
6
|
"bugs": "https://github.com/tech4humans-brasil/framework/issues",
|
|
@@ -32,23 +32,26 @@
|
|
|
32
32
|
"test:watch": "vitest"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@t4h.framework/core": "^0.
|
|
36
|
-
"@t4h.framework/fs": "^0.
|
|
35
|
+
"@t4h.framework/core": "^0.15.0",
|
|
36
|
+
"@t4h.framework/fs": "^0.10.0",
|
|
37
37
|
"@types/react": "^19.2.17",
|
|
38
|
+
"muhammara": "^6.0.5",
|
|
38
39
|
"typescript": "^5.9.3",
|
|
39
40
|
"vitest": "^4.0.18"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
|
-
"@t4h.framework/core": "^0.
|
|
43
|
-
"@t4h.framework/fs": "^0.
|
|
43
|
+
"@t4h.framework/core": "^0.15.0",
|
|
44
|
+
"@t4h.framework/fs": "^0.10.0"
|
|
44
45
|
},
|
|
45
46
|
"packageManager": "yarn@4.12.0",
|
|
46
47
|
"engines": {
|
|
47
48
|
"node": ">=22"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"@react-pdf/
|
|
51
|
-
"
|
|
51
|
+
"@react-pdf/render": "4.7.0",
|
|
52
|
+
"@react-pdf/renderer": "4.9.0",
|
|
53
|
+
"pdfkit": "0.20.1",
|
|
54
|
+
"piscina": "5.3.2",
|
|
52
55
|
"react": "^19.2.8"
|
|
53
56
|
}
|
|
54
57
|
}
|