@xenterprises/fastify-xpdf 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/src/xPDF.js ADDED
@@ -0,0 +1,126 @@
1
+ // src/xPDF.js
2
+ import fp from "fastify-plugin";
3
+ import puppeteer from "puppeteer";
4
+ import { getGeneratorMethods } from "./services/generator.js";
5
+ import { getFormsMethods } from "./services/forms.js";
6
+ import { getMergerMethods } from "./services/merger.js";
7
+
8
+ /**
9
+ * xPDF Plugin for Fastify
10
+ * PDF generation and manipulation library with optional xStorage integration
11
+ *
12
+ * Provides methods for:
13
+ * - Generate PDFs from HTML/Markdown (Puppeteer-based)
14
+ * - Fill PDF forms and flatten them
15
+ * - Merge multiple PDFs
16
+ * - Optional automatic saving to S3-compatible storage via xStorage
17
+ *
18
+ * Usage:
19
+ * await fastify.xPDF.generateFromHtml('<h1>Hello</h1>')
20
+ * await fastify.xPDF.generateFromMarkdown('# Hello')
21
+ * await fastify.xPDF.fillForm(pdfBuffer, { fieldName: 'value' })
22
+ * await fastify.xPDF.mergePDFs([pdfBuffer1, pdfBuffer2])
23
+ */
24
+ async function xPDFPlugin(fastify, options) {
25
+ const {
26
+ // Puppeteer options
27
+ headless = true,
28
+ args = ["--no-sandbox", "--disable-setuid-sandbox"],
29
+
30
+ // xStorage integration (optional)
31
+ useStorage = false,
32
+ defaultFolder = "pdfs",
33
+
34
+ // PDF generation defaults
35
+ format = "A4",
36
+ printBackground = true,
37
+ margin = {
38
+ top: "1cm",
39
+ right: "1cm",
40
+ bottom: "1cm",
41
+ left: "1cm",
42
+ },
43
+ } = options;
44
+
45
+ console.info("\n 📄 Starting xPDF...\n");
46
+
47
+ // Browser instance (lazy initialized)
48
+ let browser = null;
49
+
50
+ /**
51
+ * Get or initialize browser instance
52
+ * Implements lazy initialization and reconnection handling
53
+ */
54
+ const getBrowser = async () => {
55
+ try {
56
+ // Reconnect if existing browser disconnected
57
+ if (browser && !browser.isConnected()) {
58
+ browser = null;
59
+ }
60
+
61
+ if (!browser) {
62
+ browser = await puppeteer.launch({
63
+ headless,
64
+ args,
65
+ });
66
+ }
67
+
68
+ return browser;
69
+ } catch (error) {
70
+ fastify.log.error("Failed to initialize browser:", error);
71
+ throw new Error(`Failed to initialize PDF browser: ${error.message}`);
72
+ }
73
+ };
74
+
75
+ // Store configuration
76
+ const config = {
77
+ getBrowser,
78
+ fastify,
79
+ format,
80
+ printBackground,
81
+ margin,
82
+ useStorage,
83
+ defaultFolder,
84
+ };
85
+
86
+ // Check if xStorage is available
87
+ const hasXStorage = fastify.hasDecorator("xStorage");
88
+ if (useStorage && !hasXStorage) {
89
+ fastify.log.warn(
90
+ "xPDF: useStorage is true but xStorage plugin not registered. PDFs will not be saved to storage."
91
+ );
92
+ }
93
+
94
+ // Get all PDF methods
95
+ const generatorMethods = getGeneratorMethods(config);
96
+ const formsMethods = getFormsMethods(config);
97
+ const mergerMethods = getMergerMethods(config);
98
+
99
+ // Combine all methods
100
+ const pdfMethods = {
101
+ ...generatorMethods,
102
+ ...formsMethods,
103
+ ...mergerMethods,
104
+ };
105
+
106
+ // Decorate Fastify with xPDF namespace
107
+ fastify.decorate("xPDF", pdfMethods);
108
+
109
+ // Cleanup on Fastify shutdown
110
+ fastify.addHook("onClose", async () => {
111
+ if (browser) {
112
+ try {
113
+ await browser.close();
114
+ fastify.log.info("xPDF browser closed");
115
+ } catch (error) {
116
+ fastify.log.warn("Error closing xPDF browser:", error.message);
117
+ }
118
+ }
119
+ });
120
+
121
+ console.info("\n 📄 xPDF Ready!\n");
122
+ }
123
+
124
+ export default fp(xPDFPlugin, {
125
+ name: "xPDF",
126
+ });