@aibrains/pdf-renderer 0.9.0 → 0.10.1
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/dist/core/fonts.d.ts +7 -1
- package/dist/core/fonts.d.ts.map +1 -1
- package/dist/core/fonts.js +14 -3
- package/dist/core/fonts.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/merge-pdfs.d.ts +49 -0
- package/dist/merge-pdfs.d.ts.map +1 -0
- package/dist/merge-pdfs.js +81 -0
- package/dist/merge-pdfs.js.map +1 -0
- package/package.json +5 -4
package/dist/core/fonts.d.ts
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* Both are sourced from @fontsource/* at build time and copied to ./fonts/ at the
|
|
9
9
|
* package root (see scripts/copy-fonts.js). At runtime, paths resolve identically
|
|
10
10
|
* from `src/core/fonts.ts` and `dist/core/fonts.js` because both live two
|
|
11
|
-
* directories below the package root (../../fonts/).
|
|
11
|
+
* directories below the package root (../../fonts/). A consumer that bundles
|
|
12
|
+
* this module into a single file (esbuild for AWS Lambda) loses that layout:
|
|
13
|
+
* `__dirname` is then the bundle's own directory. Such a consumer ships the
|
|
14
|
+
* `fonts/` directory beside its bundle and names it in `PDF_FONT_DIR`.
|
|
12
15
|
*
|
|
13
16
|
* Devanagari rendering uses Yoga + Fontkit + Harfbuzz inside @react-pdf/renderer v4
|
|
14
17
|
* to handle complex script shaping (conjuncts, vowel marks). This is the canary for
|
|
@@ -23,6 +26,9 @@
|
|
|
23
26
|
* pick them up via the relative path. URL-based registration for CDN deployments
|
|
24
27
|
* is a Sprint C.2 concern.
|
|
25
28
|
*/
|
|
29
|
+
/** Environment variable naming the font directory when the package-relative default cannot apply. */
|
|
30
|
+
export declare const FONT_DIR_ENV = "PDF_FONT_DIR";
|
|
31
|
+
export declare function resolveFontDir(env?: NodeJS.ProcessEnv): string;
|
|
26
32
|
/** Latin font family registered by `registerFonts()`. */
|
|
27
33
|
export declare const FONT_FAMILY_LATIN: "Noto Sans";
|
|
28
34
|
/** Devanagari (Nepali) font family registered by `registerFonts()`. */
|
package/dist/core/fonts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/core/fonts.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/core/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,qGAAqG;AACrG,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG3E;AAED,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,EAAG,WAAoB,CAAC;AACtD,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,EAAG,sBAA+B,CAAC;AAStE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,iBAAiB,GAAG,OAAO,sBAAsB,CAI1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAI1C;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAqCpC;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
package/dist/core/fonts.js
CHANGED
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* Both are sourced from @fontsource/* at build time and copied to ./fonts/ at the
|
|
10
10
|
* package root (see scripts/copy-fonts.js). At runtime, paths resolve identically
|
|
11
11
|
* from `src/core/fonts.ts` and `dist/core/fonts.js` because both live two
|
|
12
|
-
* directories below the package root (../../fonts/).
|
|
12
|
+
* directories below the package root (../../fonts/). A consumer that bundles
|
|
13
|
+
* this module into a single file (esbuild for AWS Lambda) loses that layout:
|
|
14
|
+
* `__dirname` is then the bundle's own directory. Such a consumer ships the
|
|
15
|
+
* `fonts/` directory beside its bundle and names it in `PDF_FONT_DIR`.
|
|
13
16
|
*
|
|
14
17
|
* Devanagari rendering uses Yoga + Fontkit + Harfbuzz inside @react-pdf/renderer v4
|
|
15
18
|
* to handle complex script shaping (conjuncts, vowel marks). This is the canary for
|
|
@@ -58,14 +61,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
58
61
|
};
|
|
59
62
|
})();
|
|
60
63
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
61
|
-
exports.FONT_FAMILY_DEVANAGARI = exports.FONT_FAMILY_LATIN = void 0;
|
|
64
|
+
exports.FONT_FAMILY_DEVANAGARI = exports.FONT_FAMILY_LATIN = exports.FONT_DIR_ENV = void 0;
|
|
65
|
+
exports.resolveFontDir = resolveFontDir;
|
|
62
66
|
exports.pickFontFamily = pickFontFamily;
|
|
63
67
|
exports.registerFonts = registerFonts;
|
|
64
68
|
exports._resetFontsForTest = _resetFontsForTest;
|
|
65
69
|
const path = __importStar(require("node:path"));
|
|
66
70
|
const renderer_1 = require("@react-pdf/renderer");
|
|
67
71
|
const PACKAGE_ROOT = path.resolve(__dirname, '..', '..');
|
|
68
|
-
|
|
72
|
+
/** Environment variable naming the font directory when the package-relative default cannot apply. */
|
|
73
|
+
exports.FONT_DIR_ENV = 'PDF_FONT_DIR';
|
|
74
|
+
function resolveFontDir(env = process.env) {
|
|
75
|
+
var _a;
|
|
76
|
+
const override = (_a = env[exports.FONT_DIR_ENV]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
77
|
+
return override ? path.resolve(override) : path.join(PACKAGE_ROOT, 'fonts');
|
|
78
|
+
}
|
|
69
79
|
/** Latin font family registered by `registerFonts()`. */
|
|
70
80
|
exports.FONT_FAMILY_LATIN = 'Noto Sans';
|
|
71
81
|
/** Devanagari (Nepali) font family registered by `registerFonts()`. */
|
|
@@ -120,6 +130,7 @@ let registered = false;
|
|
|
120
130
|
function registerFonts() {
|
|
121
131
|
if (registered)
|
|
122
132
|
return;
|
|
133
|
+
const FONT_DIR = resolveFontDir();
|
|
123
134
|
// @react-pdf/renderer uses NUMERIC fontWeight internally (400 for normal,
|
|
124
135
|
// 700 for bold). Passing the string 'normal'/'bold' to Font.register stores
|
|
125
136
|
// them as strings but the resolver looks up numerics, so the registration
|
package/dist/core/fonts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../src/core/fonts.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../src/core/fonts.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUH,wCAGC;AAwCD,wCAMC;AAgCD,sCAqCC;AAGD,gDAEC;AAnID,gDAAkC;AAClC,kDAA2C;AAE3C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAEzD,qGAAqG;AACxF,QAAA,YAAY,GAAG,cAAc,CAAC;AAE3C,SAAgB,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;;IACjE,MAAM,QAAQ,GAAG,MAAA,GAAG,CAAC,oBAAY,CAAC,0CAAE,IAAI,EAAE,CAAC;IAC3C,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED,yDAAyD;AAC5C,QAAA,iBAAiB,GAAG,WAAoB,CAAC;AACtD,uEAAuE;AAC1D,QAAA,sBAAsB,GAAG,sBAA+B,CAAC;AAEtE,+EAA+E;AAC/E,uEAAuE;AACvE,0EAA0E;AAC1E,6EAA6E;AAC7E,wDAAwD;AACxD,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAgB,cAAc,CAC5B,IAAwC;IAExC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,yBAAiB,CAAC;IACjF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,8BAAsB,CAAC,CAAC,CAAC,yBAAiB,CAAC;AACjF,CAAC;AAsBD,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB;;;;;;;GAOG;AACH,SAAgB,aAAa;IAC3B,IAAI,UAAU;QAAE,OAAO;IACvB,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,0EAA0E;IAC1E,4EAA4E;IAC5E,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAI,CAAC,QAAQ,CAAC;QACZ,MAAM,EAAE,yBAAiB;QACzB,KAAK,EAAE;YACL;gBACE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,uBAAuB,CAAC;gBACjD,UAAU,EAAE,GAAG;aAChB;YACD;gBACE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC;gBAC9C,UAAU,EAAE,GAAG;aAChB;SACF;KACF,CAAC,CAAC;IAEH,eAAI,CAAC,QAAQ,CAAC;QACZ,MAAM,EAAE,8BAAsB;QAC9B,KAAK,EAAE;YACL;gBACE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,iCAAiC,CAAC;gBAC3D,UAAU,EAAE,GAAG;aAChB;YACD;gBACE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,8BAA8B,CAAC;gBACxD,UAAU,EAAE,GAAG;aAChB;SACF;KACF,CAAC,CAAC;IAEH,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,wFAAwF;AACxF,SAAgB,kBAAkB;IAChC,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -29,4 +29,6 @@ import './descriptors/receipt';
|
|
|
29
29
|
export { ReceiptPdf } from './documents/ReceiptPdf';
|
|
30
30
|
export type { ReceiptTemplateConfig, ReceiptDocumentData } from './documents/ReceiptPdf';
|
|
31
31
|
export { receiptDescriptor } from './descriptors/receipt';
|
|
32
|
+
export { mergePdfBuffers } from './merge-pdfs';
|
|
33
|
+
export type { MergePdfBuffersOptions } from './merge-pdfs';
|
|
32
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,4BAA4B,UAAU,CAAC;AAGpD,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAM9B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM1D,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,4BAA4B,UAAU,CAAC;AAGpD,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAM9B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM1D,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM1D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
32
32
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.receiptDescriptor = exports.ReceiptPdf = exports.invoiceDescriptor = exports.InvoicePdf = exports.PDF_RENDERER_PACKAGE_VERSION = void 0;
|
|
35
|
+
exports.mergePdfBuffers = exports.receiptDescriptor = exports.ReceiptPdf = exports.invoiceDescriptor = exports.InvoicePdf = exports.PDF_RENDERER_PACKAGE_VERSION = void 0;
|
|
36
36
|
exports.PDF_RENDERER_PACKAGE_VERSION = '0.6.0';
|
|
37
37
|
// Core + primitives + components + descriptor registry from Sprint C.0.
|
|
38
38
|
__exportStar(require("./core"), exports);
|
|
@@ -57,4 +57,10 @@ var ReceiptPdf_1 = require("./documents/ReceiptPdf");
|
|
|
57
57
|
Object.defineProperty(exports, "ReceiptPdf", { enumerable: true, get: function () { return ReceiptPdf_1.ReceiptPdf; } });
|
|
58
58
|
var receipt_1 = require("./descriptors/receipt");
|
|
59
59
|
Object.defineProperty(exports, "receiptDescriptor", { enumerable: true, get: function () { return receipt_1.receiptDescriptor; } });
|
|
60
|
+
// Sprint H.1 — pdf-lib-based helper for concatenating rendered PDF buffers
|
|
61
|
+
// into a single merged output. Consumed by the finance bulk-invoice-pdf-export
|
|
62
|
+
// and bulk-receipt-pdf-export workers when the operator picks
|
|
63
|
+
// `outputFormat: 'merged_pdf'`.
|
|
64
|
+
var merge_pdfs_1 = require("./merge-pdfs");
|
|
65
|
+
Object.defineProperty(exports, "mergePdfBuffers", { enumerable: true, get: function () { return merge_pdfs_1.mergePdfBuffers; } });
|
|
60
66
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;;;;;;;;;;;;AAEU,QAAA,4BAA4B,GAAG,OAAO,CAAC;AAEpD,wEAAwE;AACxE,yCAAuB;AACvB,+CAA6B;AAC7B,+CAA6B;AAC7B,gDAA8B;AAE9B,2EAA2E;AAC3E,0EAA0E;AAC1E,qEAAqE;AACrE,mDAAmD;AACnD,iCAA+B;AAC/B,qDAAoD;AAA3C,wGAAA,UAAU,OAAA;AAEnB,iDAA0D;AAAjD,4GAAA,iBAAiB,OAAA;AAE1B,0EAA0E;AAC1E,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,iCAA+B;AAC/B,qDAAoD;AAA3C,wGAAA,UAAU,OAAA;AAEnB,iDAA0D;AAAjD,4GAAA,iBAAiB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;;;;;;;;;;;;AAEU,QAAA,4BAA4B,GAAG,OAAO,CAAC;AAEpD,wEAAwE;AACxE,yCAAuB;AACvB,+CAA6B;AAC7B,+CAA6B;AAC7B,gDAA8B;AAE9B,2EAA2E;AAC3E,0EAA0E;AAC1E,qEAAqE;AACrE,mDAAmD;AACnD,iCAA+B;AAC/B,qDAAoD;AAA3C,wGAAA,UAAU,OAAA;AAEnB,iDAA0D;AAAjD,4GAAA,iBAAiB,OAAA;AAE1B,0EAA0E;AAC1E,0EAA0E;AAC1E,yEAAyE;AACzE,yEAAyE;AACzE,iCAA+B;AAC/B,qDAAoD;AAA3C,wGAAA,UAAU,OAAA;AAEnB,iDAA0D;AAAjD,4GAAA,iBAAiB,OAAA;AAE1B,2EAA2E;AAC3E,+EAA+E;AAC/E,8DAA8D;AAC9D,gCAAgC;AAChC,2CAA+C;AAAtC,6GAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mergePdfBuffers — Sprint H.1
|
|
3
|
+
*
|
|
4
|
+
* Concatenate multiple PDF buffers into a single merged PDF, preserving the
|
|
5
|
+
* page order of the input list. The output PDF's pages appear in the same
|
|
6
|
+
* order as the input buffers; each source PDF's pages appear in the same
|
|
7
|
+
* order they were in the source.
|
|
8
|
+
*
|
|
9
|
+
* First step of the merged-PDF output variant for the bulk finance export
|
|
10
|
+
* (Sprint H). The bulk-invoice-pdf-export and bulk-receipt-pdf-export
|
|
11
|
+
* workers call this helper after rendering the individual PDFs when the
|
|
12
|
+
* operator picks `outputFormat: 'merged_pdf'` (see Sprint H.3 for the
|
|
13
|
+
* worker wiring).
|
|
14
|
+
*
|
|
15
|
+
* Determinism:
|
|
16
|
+
* pdf-lib's `save()` does NOT auto-refresh ModDate — the only source of
|
|
17
|
+
* run-to-run drift is what we set on the document ourselves (CreationDate,
|
|
18
|
+
* ModificationDate, Producer, Creator). This function fixes all four to
|
|
19
|
+
* known values so identical input yields identical output — required for
|
|
20
|
+
* the audit-trail invariant in the worker (a re-run of the same job MUST
|
|
21
|
+
* produce byte-identical artifacts so a downstream signature/hash gate is
|
|
22
|
+
* stable). `useObjectStreams: false` on save is a secondary belt-and-
|
|
23
|
+
* -braces for the same guarantee (see save() call for the rationale).
|
|
24
|
+
*
|
|
25
|
+
* Memory profile:
|
|
26
|
+
* Peak RSS ≈ Σ(input bytes) + Σ(merged bytes). pdf-lib holds every
|
|
27
|
+
* parsed source document + the merged output in memory at once. At the
|
|
28
|
+
* Sprint H cap of 1000 documents and typical ~20 kB per invoice PDF,
|
|
29
|
+
* that's ~20 MB peak — well within the finance ECS task's 2 GB budget.
|
|
30
|
+
* For the 100-invoice pilot case, peak is ~2 MB.
|
|
31
|
+
*/
|
|
32
|
+
export interface MergePdfBuffersOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The PDF `/Title` metadata field written into the merged output.
|
|
35
|
+
* Optional; when omitted, no title is set. Useful for operator-facing
|
|
36
|
+
* artifacts that show up in the browser's tab title.
|
|
37
|
+
*/
|
|
38
|
+
title?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Merge PDF byte buffers into a single output buffer.
|
|
42
|
+
*
|
|
43
|
+
* @param buffers - Non-empty list of PDF byte buffers to concatenate.
|
|
44
|
+
* @param options - Optional metadata overrides.
|
|
45
|
+
* @returns The merged PDF as a Node Buffer.
|
|
46
|
+
* @throws When `buffers` is empty.
|
|
47
|
+
*/
|
|
48
|
+
export declare function mergePdfBuffers(buffers: Buffer[], options?: MergePdfBuffersOptions): Promise<Buffer>;
|
|
49
|
+
//# sourceMappingURL=merge-pdfs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-pdfs.d.ts","sourceRoot":"","sources":["../src/merge-pdfs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* mergePdfBuffers — Sprint H.1
|
|
4
|
+
*
|
|
5
|
+
* Concatenate multiple PDF buffers into a single merged PDF, preserving the
|
|
6
|
+
* page order of the input list. The output PDF's pages appear in the same
|
|
7
|
+
* order as the input buffers; each source PDF's pages appear in the same
|
|
8
|
+
* order they were in the source.
|
|
9
|
+
*
|
|
10
|
+
* First step of the merged-PDF output variant for the bulk finance export
|
|
11
|
+
* (Sprint H). The bulk-invoice-pdf-export and bulk-receipt-pdf-export
|
|
12
|
+
* workers call this helper after rendering the individual PDFs when the
|
|
13
|
+
* operator picks `outputFormat: 'merged_pdf'` (see Sprint H.3 for the
|
|
14
|
+
* worker wiring).
|
|
15
|
+
*
|
|
16
|
+
* Determinism:
|
|
17
|
+
* pdf-lib's `save()` does NOT auto-refresh ModDate — the only source of
|
|
18
|
+
* run-to-run drift is what we set on the document ourselves (CreationDate,
|
|
19
|
+
* ModificationDate, Producer, Creator). This function fixes all four to
|
|
20
|
+
* known values so identical input yields identical output — required for
|
|
21
|
+
* the audit-trail invariant in the worker (a re-run of the same job MUST
|
|
22
|
+
* produce byte-identical artifacts so a downstream signature/hash gate is
|
|
23
|
+
* stable). `useObjectStreams: false` on save is a secondary belt-and-
|
|
24
|
+
* -braces for the same guarantee (see save() call for the rationale).
|
|
25
|
+
*
|
|
26
|
+
* Memory profile:
|
|
27
|
+
* Peak RSS ≈ Σ(input bytes) + Σ(merged bytes). pdf-lib holds every
|
|
28
|
+
* parsed source document + the merged output in memory at once. At the
|
|
29
|
+
* Sprint H cap of 1000 documents and typical ~20 kB per invoice PDF,
|
|
30
|
+
* that's ~20 MB peak — well within the finance ECS task's 2 GB budget.
|
|
31
|
+
* For the 100-invoice pilot case, peak is ~2 MB.
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.mergePdfBuffers = mergePdfBuffers;
|
|
35
|
+
const pdf_lib_1 = require("pdf-lib");
|
|
36
|
+
const EPOCH = new Date(0);
|
|
37
|
+
/**
|
|
38
|
+
* Merge PDF byte buffers into a single output buffer.
|
|
39
|
+
*
|
|
40
|
+
* @param buffers - Non-empty list of PDF byte buffers to concatenate.
|
|
41
|
+
* @param options - Optional metadata overrides.
|
|
42
|
+
* @returns The merged PDF as a Node Buffer.
|
|
43
|
+
* @throws When `buffers` is empty.
|
|
44
|
+
*/
|
|
45
|
+
async function mergePdfBuffers(buffers, options = {}) {
|
|
46
|
+
if (buffers.length === 0) {
|
|
47
|
+
throw new Error('mergePdfBuffers: refusing to merge an empty buffer list');
|
|
48
|
+
}
|
|
49
|
+
const merged = await pdf_lib_1.PDFDocument.create();
|
|
50
|
+
for (const buf of buffers) {
|
|
51
|
+
// Trusted-input fast path: sources come from our own worker in the same
|
|
52
|
+
// process, so we can skip pdf-lib's default object-graph validation.
|
|
53
|
+
// ParseSpeeds.Fastest tells pdf-lib to defer optional integrity checks.
|
|
54
|
+
const src = await pdf_lib_1.PDFDocument.load(buf, {
|
|
55
|
+
parseSpeed: pdf_lib_1.ParseSpeeds.Fastest,
|
|
56
|
+
});
|
|
57
|
+
const pages = await merged.copyPages(src, src.getPageIndices());
|
|
58
|
+
for (const page of pages) {
|
|
59
|
+
merged.addPage(page);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Byte-determinism: pdf-lib's save() does NOT auto-refresh ModDate — the
|
|
63
|
+
// only source of run-to-run drift is the values we set here. Fixing them
|
|
64
|
+
// to a known epoch is what makes identical input produce identical output.
|
|
65
|
+
merged.setCreationDate(EPOCH);
|
|
66
|
+
merged.setModificationDate(EPOCH);
|
|
67
|
+
merged.setProducer('@aibrains/pdf-renderer mergePdfBuffers');
|
|
68
|
+
merged.setCreator('@aibrains/pdf-renderer');
|
|
69
|
+
if (options.title !== undefined) {
|
|
70
|
+
merged.setTitle(options.title);
|
|
71
|
+
}
|
|
72
|
+
const bytes = await merged.save({
|
|
73
|
+
// useObjectStreams: false emits the classic xref table format instead of
|
|
74
|
+
// xref streams. Slightly larger output, but byte-stable across pdf-lib
|
|
75
|
+
// minor upgrades that might change stream-compression heuristics — worth
|
|
76
|
+
// the size trade for the audit-hash guarantee.
|
|
77
|
+
useObjectStreams: false,
|
|
78
|
+
});
|
|
79
|
+
return Buffer.from(bytes);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=merge-pdfs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-pdfs.js","sourceRoot":"","sources":["../src/merge-pdfs.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;AAuBH,0CA2CC;AAhED,qCAAmD;AAWnD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AAE1B;;;;;;;GAOG;AACI,KAAK,UAAU,eAAe,CACnC,OAAiB,EACjB,UAAkC,EAAE;IAEpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,qBAAW,CAAC,MAAM,EAAE,CAAC;IAE1C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,wEAAwE;QACxE,qEAAqE;QACrE,wEAAwE;QACxE,MAAM,GAAG,GAAG,MAAM,qBAAW,CAAC,IAAI,CAAC,GAAG,EAAE;YACtC,UAAU,EAAE,qBAAW,CAAC,OAAO;SAChC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;IAC7D,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;QAC9B,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,+CAA+C;QAC/C,gBAAgB,EAAE,KAAK;KACxB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aibrains/pdf-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "EdForge PDF rendering library. JSX-based document templates built on @react-pdf/renderer, with localization (EN + NE), Bikram Sambat date support, and a TemplateDescriptor registry for cross-domain doc types (invoice, receipt, report card, admit card, etc.).",
|
|
5
|
-
"license": "
|
|
6
|
-
"author": "
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Shoaib Rain",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@aibrains/shared-types": "^0.65.0",
|
|
52
|
-
"@react-pdf/renderer": "^3.4.5"
|
|
52
|
+
"@react-pdf/renderer": "^3.4.5",
|
|
53
|
+
"pdf-lib": "^1.17.1"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"react": ">=18.0.0 <20.0.0"
|