n8n-nodes-contract-lite-2 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.
@@ -0,0 +1,2 @@
1
+ import { ContractGenerator } from './src/ContractGenerator';
2
+ export { ContractGenerator };
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractGenerator = void 0;
4
+ const ContractGenerator_1 = require("./src/ContractGenerator");
5
+ Object.defineProperty(exports, "ContractGenerator", { enumerable: true, get: function () { return ContractGenerator_1.ContractGenerator; } });
@@ -0,0 +1,5 @@
1
+ import { INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ export declare class ContractGenerator implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,77 @@
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.ContractGenerator = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const pdfkit_1 = __importDefault(require("pdfkit"));
9
+ class ContractGenerator {
10
+ constructor() {
11
+ this.description = {
12
+ displayName: 'Contract Generator Lite',
13
+ name: 'contractGeneratorLite',
14
+ group: ['transform'],
15
+ version: 1,
16
+ description: 'Generates a professional contract PDF (lightweight)',
17
+ defaults: { name: 'Contract Generator Lite' },
18
+ inputs: ['main'],
19
+ outputs: ['main'],
20
+ properties: [
21
+ { displayName: 'Contract Data', name: 'contractData', type: 'json', default: {}, description: 'Contract variables' },
22
+ { displayName: 'Seal Image', name: 'sealImage', type: 'string', default: '', description: 'Path to seal PNG/JPG' },
23
+ { displayName: 'Signature Image', name: 'signatureImage', type: 'string', default: '', description: 'Path to signature PNG/JPG' },
24
+ ],
25
+ };
26
+ }
27
+ async execute() {
28
+ const items = this.getInputData();
29
+ const returnData = [];
30
+ for (let i = 0; i < items.length; i++) {
31
+ const data = this.getNodeParameter('contractData', i);
32
+ const sealImage = this.getNodeParameter('sealImage', i);
33
+ const signatureImage = this.getNodeParameter('signatureImage', i);
34
+ ['company_name', 'client_name', 'contract_number', 'date'].forEach(field => {
35
+ if (!data[field])
36
+ throw new Error(`Missing field: ${field}`);
37
+ });
38
+ const doc = new pdfkit_1.default({ size: 'A4', margin: 50 });
39
+ const buffers = [];
40
+ doc.on('data', buffers.push.bind(buffers));
41
+ doc.on('end', () => { });
42
+ // --- HEADER ---
43
+ doc.rect(0, 0, 595.28, 70).fill('#007BFF'); // голубой хедер
44
+ doc.fillColor('white').fontSize(26).text('KNK GROUP', 50, 25, { align: 'left' });
45
+ doc.moveDown(4);
46
+ doc.fillColor('black').fontSize(12);
47
+ // --- CONTRACT INFO ---
48
+ doc.text(`Договор № ${data.contract_number}`, { continued: true }).text(` от ${data.date}`);
49
+ doc.moveDown();
50
+ // --- PARTIES ---
51
+ doc.font('Helvetica-Bold').text('Исполнитель: ', { continued: true }).font('Helvetica').text(`${data.company_name}, ИНН ${data.inn || ''}`);
52
+ doc.font('Helvetica-Bold').text('Заказчик: ', { continued: true }).font('Helvetica').text(`${data.client_name}`);
53
+ doc.moveDown();
54
+ // --- SUBJECT ---
55
+ doc.font('Helvetica-Bold').text('Предмет договора:');
56
+ doc.font('Helvetica').text(data.subject || 'Оказание услуг по автоматизации бизнес-процессов', { indent: 20 });
57
+ doc.moveDown();
58
+ if (data.VAT) {
59
+ doc.font('Helvetica-Bold').text('НДС: ', { continued: true }).font('Helvetica').text(`включён в сумму ${data.amount || ''} руб.`);
60
+ doc.moveDown();
61
+ }
62
+ // --- SIGNATURES ---
63
+ const startY = doc.y + 30;
64
+ if (fs_1.default.existsSync(signatureImage)) {
65
+ doc.image(signatureImage, 50, startY, { width: 150 });
66
+ }
67
+ if (fs_1.default.existsSync(sealImage)) {
68
+ doc.image(sealImage, 400, startY, { width: 150 });
69
+ }
70
+ doc.end();
71
+ const pdfBuffer = Buffer.concat(buffers);
72
+ returnData.push({ json: { pdf: pdfBuffer.toString('base64') } });
73
+ }
74
+ return [returnData];
75
+ }
76
+ }
77
+ exports.ContractGenerator = ContractGenerator;
package/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { ContractGenerator } from './src/ContractGenerator';
2
+
3
+ export { ContractGenerator };
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "n8n-nodes-contract-lite-2",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight contract PDF generator for n8n",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepare": "npm run build"
10
+ },
11
+ "keywords": [
12
+ "n8n-node",
13
+ "contract",
14
+ "pdf",
15
+ "lightweight"
16
+ ],
17
+ "author": "Your Name",
18
+ "license": "MIT",
19
+ "dependencies": {
20
+ "mustache": "^4.2.0",
21
+ "pdfkit": "^0.13.0"
22
+ },
23
+ "n8n": {
24
+ "nodes": [
25
+ "dist/index.js"
26
+ ]
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^20.19.30",
30
+ "@types/pdfkit": "^0.17.4",
31
+ "n8n-workflow": "^1.120.6",
32
+ "typescript": "^5.9.3"
33
+ }
34
+ }
@@ -0,0 +1,90 @@
1
+ import fs from 'fs';
2
+ import PDFDocument from 'pdfkit';
3
+
4
+ import {
5
+ INodeType,
6
+ INodeTypeDescription,
7
+ IExecuteFunctions,
8
+ INodeExecutionData,
9
+ } from 'n8n-workflow';
10
+
11
+
12
+ export class ContractGenerator implements INodeType {
13
+ description: INodeTypeDescription = {
14
+ displayName: 'Contract Generator Lite',
15
+ name: 'contractGeneratorLite',
16
+ group: ['transform'],
17
+ version: 1,
18
+ description: 'Generates a professional contract PDF (lightweight)',
19
+ defaults: { name: 'Contract Generator Lite' },
20
+ inputs: ['main'],
21
+ outputs: ['main'],
22
+ properties: [
23
+ { displayName: 'Contract Data', name: 'contractData', type: 'json', default: {}, description: 'Contract variables' },
24
+ { displayName: 'Seal Image', name: 'sealImage', type: 'string', default: '', description: 'Path to seal PNG/JPG' },
25
+ { displayName: 'Signature Image', name: 'signatureImage', type: 'string', default: '', description: 'Path to signature PNG/JPG' },
26
+ ],
27
+ };
28
+
29
+ async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
30
+ const items = this.getInputData();
31
+ const returnData: INodeExecutionData[] = [];
32
+
33
+ for (let i = 0; i < items.length; i++) {
34
+ const data = this.getNodeParameter('contractData', i) as Record<string, any>;
35
+ const sealImage = this.getNodeParameter('sealImage', i) as string;
36
+ const signatureImage = this.getNodeParameter('signatureImage', i) as string;
37
+
38
+ ['company_name', 'client_name', 'contract_number', 'date'].forEach(field => {
39
+ if (!data[field]) throw new Error(`Missing field: ${field}`);
40
+ });
41
+
42
+ const doc = new PDFDocument({ size: 'A4', margin: 50 });
43
+ const buffers: Buffer[] = [];
44
+ doc.on('data', buffers.push.bind(buffers));
45
+ doc.on('end', () => {});
46
+
47
+ // --- HEADER ---
48
+ doc.rect(0, 0, 595.28, 70).fill('#007BFF'); // голубой хедер
49
+ doc.fillColor('white').fontSize(26).text('KNK GROUP', 50, 25, { align: 'left' });
50
+
51
+ doc.moveDown(4);
52
+ doc.fillColor('black').fontSize(12);
53
+
54
+ // --- CONTRACT INFO ---
55
+ doc.text(`Договор № ${data.contract_number}`, { continued: true }).text(` от ${data.date}`);
56
+ doc.moveDown();
57
+
58
+ // --- PARTIES ---
59
+ doc.font('Helvetica-Bold').text('Исполнитель: ', { continued: true }).font('Helvetica').text(`${data.company_name}, ИНН ${data.inn || ''}`);
60
+ doc.font('Helvetica-Bold').text('Заказчик: ', { continued: true }).font('Helvetica').text(`${data.client_name}`);
61
+ doc.moveDown();
62
+
63
+ // --- SUBJECT ---
64
+ doc.font('Helvetica-Bold').text('Предмет договора:');
65
+ doc.font('Helvetica').text(data.subject || 'Оказание услуг по автоматизации бизнес-процессов', { indent: 20 });
66
+ doc.moveDown();
67
+
68
+ if (data.VAT) {
69
+ doc.font('Helvetica-Bold').text('НДС: ', { continued: true }).font('Helvetica').text(`включён в сумму ${data.amount || ''} руб.`);
70
+ doc.moveDown();
71
+ }
72
+
73
+ // --- SIGNATURES ---
74
+ const startY = doc.y + 30;
75
+ if (fs.existsSync(signatureImage)) {
76
+ doc.image(signatureImage, 50, startY, { width: 150 });
77
+ }
78
+ if (fs.existsSync(sealImage)) {
79
+ doc.image(sealImage, 400, startY, { width: 150 });
80
+ }
81
+
82
+ doc.end();
83
+
84
+ const pdfBuffer = Buffer.concat(buffers);
85
+ returnData.push({ json: { pdf: pdfBuffer.toString('base64') } });
86
+ }
87
+
88
+ return [returnData];
89
+ }
90
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "declaration": true,
6
+ "outDir": "dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["src/**/*.ts", "index.ts"]
12
+ }