@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/.env.example +11 -0
- package/CHANGELOG.md +106 -0
- package/LICENSE +15 -0
- package/QUICK_START.md +462 -0
- package/README.md +580 -0
- package/SECURITY.md +417 -0
- package/package.json +57 -0
- package/server/app.js +151 -0
- package/src/index.js +7 -0
- package/src/services/forms.js +163 -0
- package/src/services/generator.js +147 -0
- package/src/services/merger.js +115 -0
- package/src/utils/helpers.js +220 -0
- package/src/xPDF.js +126 -0
- package/test/xPDF.test.js +903 -0
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
|
+
});
|