n8n-nodes-pdfbro 0.1.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/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # n8n-nodes-pdfbro
2
+
3
+ This is an n8n community node. It lets you manipulate PDF files in your workflows without external dependencies or API calls.
4
+
5
+ [n8n](https://n8n.io/) is a fair-code licensed workflow automation platform.
6
+
7
+ ## Features
8
+
9
+ - **Merge PDFs**: Combine multiple PDF files into one.
10
+ - **Split Pages**: Split a PDF into individual pages.
11
+ - **Extract Text**: Extract text content from PDF files.
12
+ - **Extract Metadata**: Get title, author, page count, etc.
13
+ - **Rotate Pages**: Rotate pages by 90, 180, or 270 degrees.
14
+
15
+ ## Installation
16
+
17
+ Follow the [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/installation/) to install this node.
18
+
19
+ ### Community Nodes (Recommended)
20
+ 1. Go to **Settings > Community Nodes**.
21
+ 2. Select **Install**.
22
+ 3. Enter `n8n-nodes-pdfbro`.
23
+
24
+ ### Manual
25
+ Running n8n with npm:
26
+ ```bash
27
+ npm install n8n-nodes-pdfbro
28
+ ```
29
+
30
+ ## Operations
31
+
32
+ ### Merge PDFs
33
+ Merges all input items containing PDF binary data into a single output item with the merged PDF.
34
+
35
+ ### Split Pages
36
+ Splits a PDF into multiple items, one per page.
37
+
38
+ ### Extract Text
39
+ Extracts all text from the PDF and adds it to the JSON output.
40
+
41
+ ### Extract Metadata
42
+ Adds PDF metadata (Title, Author, Creation Date, etc.) to the JSON output.
43
+
44
+ ### Rotate Pages
45
+ Rotates all pages in the PDF by the specified degrees (default 90).
46
+
47
+ ## License
48
+
49
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodes = void 0;
4
+ const PdfUtils_node_1 = require("./nodes/PdfUtils/PdfUtils.node");
5
+ exports.nodes = [PdfUtils_node_1.PdfUtils];
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PdfUtils = void 0;
7
+ const pdf_lib_1 = require("pdf-lib");
8
+ // @ts-ignore
9
+ const pdf_parse_1 = __importDefault(require("pdf-parse"));
10
+ class PdfUtils {
11
+ constructor() {
12
+ this.description = {
13
+ displayName: 'PDF Utils',
14
+ name: 'pdfUtils',
15
+ icon: 'file:pdfUtils.svg',
16
+ group: ['transform'],
17
+ version: 1,
18
+ description: 'Offline PDF operations',
19
+ defaults: {
20
+ name: 'PDF Utils',
21
+ },
22
+ inputs: ['main'],
23
+ outputs: ['main'],
24
+ properties: [
25
+ {
26
+ displayName: 'Operation',
27
+ name: 'operation',
28
+ type: 'options',
29
+ noDataExpression: true,
30
+ options: [
31
+ {
32
+ name: 'Merge PDFs',
33
+ value: 'merge',
34
+ description: 'Merge multiple PDF items into a single PDF',
35
+ },
36
+ {
37
+ name: 'Split Pages',
38
+ value: 'split',
39
+ description: 'Split a PDF into separate pages',
40
+ },
41
+ {
42
+ name: 'Extract Text',
43
+ value: 'extractText',
44
+ description: 'Extract text content from PDF',
45
+ },
46
+ {
47
+ name: 'Extract Metadata',
48
+ value: 'metadata',
49
+ description: 'Get PDF metadata (title, author, pages)',
50
+ },
51
+ {
52
+ name: 'Rotate Pages',
53
+ value: 'rotate',
54
+ description: 'Rotate all pages in a PDF',
55
+ },
56
+ ],
57
+ default: 'merge',
58
+ },
59
+ {
60
+ displayName: 'Input Binary Field',
61
+ name: 'binaryPropertyName',
62
+ type: 'string',
63
+ default: 'data',
64
+ required: true,
65
+ description: 'The name of the binary field containing the PDF',
66
+ },
67
+ {
68
+ displayName: 'Rotation Degrees',
69
+ name: 'rotationDegrees',
70
+ type: 'number',
71
+ default: 90,
72
+ displayOptions: {
73
+ show: {
74
+ operation: ['rotate'],
75
+ },
76
+ },
77
+ description: 'Clockwise rotation (e.g. 90, 180, 270)',
78
+ },
79
+ ],
80
+ };
81
+ }
82
+ async execute() {
83
+ const items = this.getInputData();
84
+ const returnData = [];
85
+ const operation = this.getNodeParameter('operation', 0);
86
+ const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0);
87
+ if (operation === 'merge') {
88
+ // Merge all inputs into one PDF
89
+ const mergedPdf = await pdf_lib_1.PDFDocument.create();
90
+ for (let i = 0; i < items.length; i++) {
91
+ try {
92
+ const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
93
+ const validBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
94
+ const pdf = await pdf_lib_1.PDFDocument.load(validBuffer);
95
+ const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
96
+ copiedPages.forEach((page) => mergedPdf.addPage(page));
97
+ }
98
+ catch (error) {
99
+ if (this.continueOnFail()) {
100
+ continue;
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ const mergedPdfBuffer = await mergedPdf.save();
106
+ returnData.push({
107
+ json: { success: true, pageCount: mergedPdf.getPageCount() },
108
+ binary: {
109
+ [binaryPropertyName]: await this.helpers.prepareBinaryData(Buffer.from(mergedPdfBuffer), 'merged.pdf', 'application/pdf'),
110
+ },
111
+ });
112
+ }
113
+ else if (operation === 'split') {
114
+ // Split each input PDF into single pages
115
+ for (let i = 0; i < items.length; i++) {
116
+ const validBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
117
+ const pdf = await pdf_lib_1.PDFDocument.load(validBuffer);
118
+ const numberOfPages = pdf.getPageCount();
119
+ for (let j = 0; j < numberOfPages; j++) {
120
+ const newPdf = await pdf_lib_1.PDFDocument.create();
121
+ const [copiedPage] = await newPdf.copyPages(pdf, [j]);
122
+ newPdf.addPage(copiedPage);
123
+ const newPdfBuffer = await newPdf.save();
124
+ returnData.push({
125
+ json: { ...items[i].json, pageNumber: j + 1, totalPages: numberOfPages },
126
+ binary: {
127
+ [binaryPropertyName]: await this.helpers.prepareBinaryData(Buffer.from(newPdfBuffer), `page_${j + 1}.pdf`, 'application/pdf'),
128
+ },
129
+ });
130
+ }
131
+ }
132
+ }
133
+ else if (operation === 'rotate') {
134
+ const degreesVal = this.getNodeParameter('rotationDegrees', 0);
135
+ for (let i = 0; i < items.length; i++) {
136
+ const validBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
137
+ const pdf = await pdf_lib_1.PDFDocument.load(validBuffer);
138
+ const pages = pdf.getPages();
139
+ pages.forEach(page => {
140
+ const currentRotation = page.getRotation().angle;
141
+ page.setRotation((0, pdf_lib_1.degrees)(currentRotation + degreesVal));
142
+ });
143
+ const rotatedPdfBuffer = await pdf.save();
144
+ returnData.push({
145
+ json: items[i].json,
146
+ binary: {
147
+ [binaryPropertyName]: await this.helpers.prepareBinaryData(Buffer.from(rotatedPdfBuffer), 'rotated.pdf', 'application/pdf'),
148
+ },
149
+ });
150
+ }
151
+ }
152
+ else if (operation === 'extractText') {
153
+ for (let i = 0; i < items.length; i++) {
154
+ const validBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
155
+ const data = await (0, pdf_parse_1.default)(validBuffer);
156
+ returnData.push({
157
+ json: {
158
+ ...items[i].json,
159
+ text: data.text,
160
+ numpages: data.numpages,
161
+ info: data.info,
162
+ },
163
+ binary: items[i].binary,
164
+ });
165
+ }
166
+ }
167
+ else if (operation === 'metadata') {
168
+ for (let i = 0; i < items.length; i++) {
169
+ const validBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
170
+ const pdf = await pdf_lib_1.PDFDocument.load(validBuffer);
171
+ returnData.push({
172
+ json: {
173
+ ...items[i].json,
174
+ title: pdf.getTitle(),
175
+ author: pdf.getAuthor(),
176
+ subject: pdf.getSubject(),
177
+ creator: pdf.getCreator(),
178
+ producer: pdf.getProducer(),
179
+ keywords: pdf.getKeywords(),
180
+ pageCount: pdf.getPageCount(),
181
+ creationDate: pdf.getCreationDate(),
182
+ modificationDate: pdf.getModificationDate(),
183
+ },
184
+ binary: items[i].binary,
185
+ });
186
+ }
187
+ }
188
+ return [returnData];
189
+ }
190
+ }
191
+ exports.PdfUtils = PdfUtils;
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "n8n-nodes-pdfbro",
3
+ "version": "0.1.0",
4
+ "description": "Offline PDF utility node for n8n",
5
+ "keywords": [
6
+ "n8n-community-node"
7
+ ],
8
+ "license": "MIT",
9
+ "author": "Blankarray",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/blankarrayy/pdfbro"
13
+ },
14
+ "main": "dist/index.js",
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "dependencies": {
23
+ "pdf-lib": "^1.17.1",
24
+ "pdf-parse": "^1.1.1"
25
+ },
26
+ "devDependencies": {
27
+ "n8n-workflow": "*",
28
+ "typescript": "^5.0.0",
29
+ "@types/node": "^16.0.0"
30
+ }
31
+ }