pdf-gen-js 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.
Files changed (51) hide show
  1. package/README.md +179 -0
  2. package/bin/cli.js +74 -0
  3. package/dist/config.d.ts +20 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +24 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/generator.d.ts +44 -0
  8. package/dist/generator.d.ts.map +1 -0
  9. package/dist/generator.js +144 -0
  10. package/dist/generator.js.map +1 -0
  11. package/dist/index.d.ts +24 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +32 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/templates/certificate.d.ts +17 -0
  16. package/dist/templates/certificate.d.ts.map +1 -0
  17. package/dist/templates/certificate.js +78 -0
  18. package/dist/templates/certificate.js.map +1 -0
  19. package/dist/templates/invoice.d.ts +31 -0
  20. package/dist/templates/invoice.d.ts.map +1 -0
  21. package/dist/templates/invoice.js +115 -0
  22. package/dist/templates/invoice.js.map +1 -0
  23. package/dist/templates/receipt.d.ts +26 -0
  24. package/dist/templates/receipt.d.ts.map +1 -0
  25. package/dist/templates/receipt.js +93 -0
  26. package/dist/templates/receipt.js.map +1 -0
  27. package/dist/theme.d.ts +21 -0
  28. package/dist/theme.d.ts.map +1 -0
  29. package/dist/theme.js +26 -0
  30. package/dist/theme.js.map +1 -0
  31. package/dist/types.d.ts +7 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +9 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/utils/image.d.ts +32 -0
  36. package/dist/utils/image.d.ts.map +1 -0
  37. package/dist/utils/image.js +98 -0
  38. package/dist/utils/image.js.map +1 -0
  39. package/dist/utils/logo.d.ts +15 -0
  40. package/dist/utils/logo.d.ts.map +1 -0
  41. package/dist/utils/logo.js +16 -0
  42. package/dist/utils/logo.js.map +1 -0
  43. package/dist/utils/table.d.ts +23 -0
  44. package/dist/utils/table.d.ts.map +1 -0
  45. package/dist/utils/table.js +83 -0
  46. package/dist/utils/table.js.map +1 -0
  47. package/dist/utils/validate.d.ts +6 -0
  48. package/dist/utils/validate.d.ts.map +1 -0
  49. package/dist/utils/validate.js +35 -0
  50. package/dist/utils/validate.js.map +1 -0
  51. package/package.json +48 -0
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderCertificate = renderCertificate;
4
+ const validate_1 = require("../utils/validate");
5
+ const logo_1 = require("../utils/logo");
6
+ async function renderCertificate(pdf, config, data, theme) {
7
+ (0, validate_1.requireFields)(data, ['title', 'recipientName', 'achievementText', 'issuerName'], 'certificate');
8
+ const pageWidth = pdf.page.width;
9
+ const pageHeight = pdf.page.height;
10
+ const centerX = pageWidth / 2;
11
+ const borderColor = data.borderColor || theme.primary;
12
+ if (data.decorativeElements !== false) {
13
+ pdf.strokeColor(borderColor).lineWidth(3);
14
+ pdf.rect(30, 30, pageWidth - 60, pageHeight - 60).stroke();
15
+ pdf.strokeColor(theme.accent).lineWidth(1);
16
+ pdf.rect(42, 42, pageWidth - 84, pageHeight - 84).stroke();
17
+ // Corner flourishes
18
+ const cornerSize = 26;
19
+ const corners = [
20
+ [42, 42],
21
+ [pageWidth - 42, 42],
22
+ [42, pageHeight - 42],
23
+ [pageWidth - 42, pageHeight - 42]
24
+ ];
25
+ corners.forEach(([cx, cy]) => {
26
+ pdf.circle(cx, cy, 4).fill(theme.accent);
27
+ });
28
+ void cornerSize;
29
+ }
30
+ let y = pageHeight * 0.14;
31
+ const logo = (0, logo_1.resolveLogo)(data.logo, 60);
32
+ if (logo) {
33
+ await (0, logo_1.embedImage)(pdf, logo.src, centerX - logo.width / 2, y - logo.height - 15, { width: logo.width, height: logo.height });
34
+ }
35
+ pdf.font('Helvetica-Bold').fontSize(30).fillColor(borderColor).text(data.title, 60, y, {
36
+ align: 'center',
37
+ width: pageWidth - 120
38
+ });
39
+ y = pdf.y + 20;
40
+ pdf.font('Helvetica').fontSize(15).fillColor(theme.text).text('This certificate is proudly presented to', 60, y, {
41
+ align: 'center',
42
+ width: pageWidth - 120
43
+ });
44
+ y = pdf.y + 20;
45
+ pdf.font('Helvetica-Bold').fontSize(30).fillColor(theme.primaryDark).text(data.recipientName, 60, y, {
46
+ align: 'center',
47
+ width: pageWidth - 120
48
+ });
49
+ y = pdf.y + 6;
50
+ pdf
51
+ .strokeColor(theme.accent)
52
+ .lineWidth(1.5)
53
+ .moveTo(centerX - 120, y)
54
+ .lineTo(centerX + 120, y)
55
+ .stroke();
56
+ y += 24;
57
+ pdf.font('Helvetica').fontSize(13).fillColor(theme.text).text(data.achievementText, 100, y, {
58
+ align: 'center',
59
+ width: pageWidth - 200
60
+ });
61
+ const bottomY = pageHeight - 150;
62
+ pdf.font('Helvetica').fontSize(11).fillColor(theme.muted);
63
+ pdf.text(`Date: ${(0, validate_1.formatDate)(data.issueDate)}`, 100, bottomY, { width: 220 });
64
+ if (data.certificationNumber) {
65
+ pdf.text(`Certificate No: ${data.certificationNumber}`, 100, pdf.y + 4, { width: 220 });
66
+ }
67
+ pdf.strokeColor(theme.border).lineWidth(1).moveTo(100, bottomY - 10).lineTo(320, bottomY - 10).stroke();
68
+ pdf.strokeColor(theme.border).moveTo(pageWidth - 320, bottomY - 10).lineTo(pageWidth - 100, bottomY - 10).stroke();
69
+ pdf.font('Helvetica-Bold').fontSize(11).fillColor(theme.text).text(data.issuerName, pageWidth - 320, bottomY, {
70
+ width: 220,
71
+ align: 'right'
72
+ });
73
+ pdf.font('Helvetica').fontSize(9).fillColor(theme.muted).text('Authorized Signature', pageWidth - 320, pdf.y + 4, {
74
+ width: 220,
75
+ align: 'right'
76
+ });
77
+ }
78
+ //# sourceMappingURL=certificate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certificate.js","sourceRoot":"","sources":["../../src/templates/certificate.ts"],"names":[],"mappings":";;AAkBA,8CAsFC;AArGD,gDAA8D;AAC9D,wCAAmE;AAc5D,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,MAAiB,EAAE,IAAqB,EAAE,KAAY;IACzG,IAAA,wBAAa,EAAC,IAAW,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,CAAC,EAAE,aAAa,CAAC,CAAC;IAEvG,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IACjC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC;IAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC;IAEtD,IAAI,IAAI,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC;QACtC,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAE3D,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC3C,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAE3D,oBAAoB;QACpB,MAAM,UAAU,GAAG,EAAE,CAAC;QACtB,MAAM,OAAO,GAAuB;YAClC,CAAC,EAAE,EAAE,EAAE,CAAC;YACR,CAAC,SAAS,GAAG,EAAE,EAAE,EAAE,CAAC;YACpB,CAAC,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC;YACrB,CAAC,SAAS,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC;SAClC,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;YAC3B,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QACH,KAAK,UAAU,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC;IAE1B,MAAM,IAAI,GAAG,IAAA,kBAAW,EAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAA,iBAAU,EAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9H,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE;QACrF,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,SAAS,GAAG,GAAG;KACvB,CAAC,CAAC;IACH,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAEf,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0CAA0C,EAAE,EAAE,EAAE,CAAC,EAAE;QAC/G,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,SAAS,GAAG,GAAG;KACvB,CAAC,CAAC;IACH,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAEf,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,CAAC,EAAE;QACnG,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,SAAS,GAAG,GAAG;KACvB,CAAC,CAAC;IACH,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAEd,GAAG;SACA,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;SACzB,SAAS,CAAC,GAAG,CAAC;SACd,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;SACxB,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;SACxB,MAAM,EAAE,CAAC;IACZ,CAAC,IAAI,EAAE,CAAC;IAER,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,EAAE;QAC1F,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,SAAS,GAAG,GAAG;KACvB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,UAAU,GAAG,GAAG,CAAC;IAEjC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1D,GAAG,CAAC,IAAI,CAAC,SAAS,IAAA,qBAAU,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9E,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,GAAG,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,mBAAmB,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACxG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAEnH,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE;QAC5G,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,OAAO;KACf,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE;QAChH,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,OAAO;KACf,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { PDFConfig } from '../config';
2
+ import { Theme } from '../theme';
3
+ import { PDFDoc } from '../types';
4
+ import { LogoInput } from '../utils/logo';
5
+ export interface InvoiceItem {
6
+ description: string;
7
+ quantity: number;
8
+ unitPrice: number;
9
+ total?: number;
10
+ }
11
+ export interface InvoiceData {
12
+ invoiceNumber: string;
13
+ date: Date | string;
14
+ dueDate?: Date | string;
15
+ logo?: LogoInput;
16
+ companyName: string;
17
+ companyAddress?: string;
18
+ clientName: string;
19
+ clientAddress?: string;
20
+ items: InvoiceItem[];
21
+ subtotal: number;
22
+ tax?: number;
23
+ taxRate?: number;
24
+ total: number;
25
+ currency?: string;
26
+ notes?: string;
27
+ paymentTerms?: string;
28
+ status?: 'PAID' | 'DUE' | 'OVERDUE';
29
+ }
30
+ export declare function renderInvoice(pdf: PDFDoc, config: PDFConfig, data: InvoiceData, theme: Theme): Promise<void>;
31
+ //# sourceMappingURL=invoice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../src/templates/invoice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAc,SAAS,EAAe,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;CACrC;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAiIlH"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderInvoice = renderInvoice;
4
+ const table_1 = require("../utils/table");
5
+ const validate_1 = require("../utils/validate");
6
+ const logo_1 = require("../utils/logo");
7
+ async function renderInvoice(pdf, config, data, theme) {
8
+ (0, validate_1.requireFields)(data, ['invoiceNumber', 'companyName', 'clientName', 'items', 'subtotal', 'total'], 'invoice');
9
+ const left = config.margins.left;
10
+ const right = pdf.page.width - config.margins.right;
11
+ const contentWidth = right - left;
12
+ const currency = data.currency || 'USD';
13
+ // --- Header banner -------------------------------------------------
14
+ const bannerHeight = 90;
15
+ pdf.rect(0, 0, pdf.page.width, bannerHeight).fill(theme.primary);
16
+ let textLeft = left;
17
+ const logo = (0, logo_1.resolveLogo)(data.logo, 50);
18
+ if (logo) {
19
+ const plate = logo.height + 10;
20
+ pdf.roundedRect(left, (bannerHeight - plate) / 2, plate, plate, 6).fill('#ffffff');
21
+ await (0, logo_1.embedImage)(pdf, logo.src, left + 5, (bannerHeight - plate) / 2 + 5, { width: logo.width, height: logo.height });
22
+ textLeft = left + plate + 15;
23
+ }
24
+ pdf.fillColor('#ffffff').font('Helvetica-Bold').fontSize(26).text('INVOICE', textLeft, 30);
25
+ pdf
26
+ .font('Helvetica')
27
+ .fontSize(10)
28
+ .text(data.companyName, textLeft, 62, { width: contentWidth * 0.6 - (textLeft - left) });
29
+ pdf.font('Helvetica-Bold').fontSize(12).text(`#${data.invoiceNumber}`, left, 30, {
30
+ width: contentWidth,
31
+ align: 'right'
32
+ });
33
+ pdf.font('Helvetica').fontSize(10).text((0, validate_1.formatDate)(data.date), left, 50, { width: contentWidth, align: 'right' });
34
+ if (data.status) {
35
+ const statusColors = { PAID: '#1e8e3e', DUE: theme.accent, OVERDUE: '#c62828' };
36
+ pdf
37
+ .font('Helvetica-Bold')
38
+ .fontSize(10)
39
+ .fillColor(statusColors[data.status] || theme.accent)
40
+ .text(data.status, left, 68, { width: contentWidth, align: 'right' });
41
+ }
42
+ // --- From / Bill To --------------------------------------------------
43
+ let y = bannerHeight + 30;
44
+ pdf.fillColor(theme.muted).font('Helvetica-Bold').fontSize(9).text('FROM', left, y);
45
+ pdf.fillColor(theme.muted).font('Helvetica-Bold').fontSize(9).text('BILL TO', left + contentWidth / 2, y);
46
+ y += 14;
47
+ pdf.fillColor(theme.text).font('Helvetica-Bold').fontSize(11).text(data.companyName, left, y, { width: contentWidth / 2 - 10 });
48
+ pdf.fillColor(theme.text).font('Helvetica-Bold').fontSize(11).text(data.clientName, left + contentWidth / 2, y, {
49
+ width: contentWidth / 2
50
+ });
51
+ y += 16;
52
+ pdf.font('Helvetica').fontSize(10).fillColor(theme.muted);
53
+ if (data.companyAddress)
54
+ pdf.text(data.companyAddress, left, y, { width: contentWidth / 2 - 10 });
55
+ if (data.clientAddress)
56
+ pdf.text(data.clientAddress, left + contentWidth / 2, y, { width: contentWidth / 2 });
57
+ if (data.dueDate) {
58
+ y = Math.max(pdf.y, y) + 10;
59
+ pdf.font('Helvetica-Bold').fontSize(9).fillColor(theme.muted).text(`Due date: ${(0, validate_1.formatDate)(data.dueDate)}`, left, y);
60
+ }
61
+ // --- Line items table --------------------------------------------------
62
+ const tableTop = Math.max(pdf.y, y) + 25;
63
+ pdf.y = tableTop;
64
+ const rows = data.items.map((item) => {
65
+ const itemTotal = item.total ?? item.quantity * item.unitPrice;
66
+ return {
67
+ description: item.description,
68
+ quantity: String(item.quantity),
69
+ unitPrice: (0, validate_1.formatCurrency)(item.unitPrice, currency),
70
+ total: (0, validate_1.formatCurrency)(itemTotal, currency)
71
+ };
72
+ });
73
+ const finalY = (0, table_1.drawTable)(pdf, config, theme, [
74
+ { header: 'Description', key: 'description' },
75
+ { header: 'Qty', key: 'quantity', width: contentWidth * 0.12, align: 'right' },
76
+ { header: 'Unit Price', key: 'unitPrice', width: contentWidth * 0.2, align: 'right' },
77
+ { header: 'Total', key: 'total', width: contentWidth * 0.2, align: 'right' }
78
+ ], rows, { startY: tableTop });
79
+ // --- Totals summary --------------------------------------------------
80
+ const summaryWidth = 220;
81
+ const summaryX = right - summaryWidth;
82
+ let sy = finalY + 15;
83
+ pdf.font('Helvetica').fontSize(10).fillColor(theme.text);
84
+ pdf.text('Subtotal', summaryX, sy, { width: summaryWidth - 90 });
85
+ pdf.text((0, validate_1.formatCurrency)(data.subtotal, currency), summaryX + summaryWidth - 90, sy, { width: 90, align: 'right' });
86
+ sy += 18;
87
+ if (data.tax || data.taxRate) {
88
+ const taxLabel = data.taxRate ? `Tax (${data.taxRate}%)` : 'Tax';
89
+ pdf.text(taxLabel, summaryX, sy, { width: summaryWidth - 90 });
90
+ pdf.text((0, validate_1.formatCurrency)(data.tax || 0, currency), summaryX + summaryWidth - 90, sy, { width: 90, align: 'right' });
91
+ sy += 18;
92
+ }
93
+ pdf.moveTo(summaryX, sy).lineTo(summaryX + summaryWidth, sy).strokeColor(theme.border).stroke();
94
+ sy += 8;
95
+ pdf.rect(summaryX, sy, summaryWidth, 30).fill(theme.primary);
96
+ pdf.fillColor('#ffffff').font('Helvetica-Bold').fontSize(12);
97
+ pdf.text('Total', summaryX + 10, sy + 8, { width: summaryWidth - 100 });
98
+ pdf.text((0, validate_1.formatCurrency)(data.total, currency), summaryX + summaryWidth - 100, sy + 8, { width: 90, align: 'right' });
99
+ // --- Notes & payment terms --------------------------------------------------
100
+ if (data.notes || data.paymentTerms) {
101
+ let ny = sy + 55;
102
+ if (ny + 60 > pdf.page.height - config.margins.bottom) {
103
+ pdf.addPage();
104
+ ny = config.margins.top;
105
+ }
106
+ pdf.fillColor(theme.muted).font('Helvetica-Bold').fontSize(9).text('NOTES', left, ny);
107
+ ny += 14;
108
+ pdf.font('Helvetica').fontSize(10).fillColor(theme.text);
109
+ if (data.notes)
110
+ pdf.text(data.notes, left, ny, { width: contentWidth });
111
+ if (data.paymentTerms)
112
+ pdf.text(`Payment terms: ${data.paymentTerms}`, left, pdf.y + 4, { width: contentWidth });
113
+ }
114
+ }
115
+ //# sourceMappingURL=invoice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice.js","sourceRoot":"","sources":["../../src/templates/invoice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { PDFConfig } from '../config';
2
+ import { Theme } from '../theme';
3
+ import { PDFDoc } from '../types';
4
+ import { LogoInput } from '../utils/logo';
5
+ export interface ReceiptItem {
6
+ name: string;
7
+ quantity: number;
8
+ price: number;
9
+ total?: number;
10
+ }
11
+ export interface ReceiptData {
12
+ storeName: string;
13
+ storeAddress?: string;
14
+ logo?: LogoInput;
15
+ receiptNumber: string;
16
+ dateTime: Date | string;
17
+ items: ReceiptItem[];
18
+ subtotal: number;
19
+ tax?: number;
20
+ total: number;
21
+ currency?: string;
22
+ paymentMethod: string;
23
+ thankYouMessage?: string;
24
+ }
25
+ export declare function renderReceipt(pdf: PDFDoc, config: PDFConfig, data: ReceiptData, theme: Theme): Promise<void>;
26
+ //# sourceMappingURL=receipt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../../src/templates/receipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAc,SAAS,EAAe,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CA4GlH"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderReceipt = renderReceipt;
4
+ const validate_1 = require("../utils/validate");
5
+ const logo_1 = require("../utils/logo");
6
+ async function renderReceipt(pdf, config, data, theme) {
7
+ (0, validate_1.requireFields)(data, ['storeName', 'receiptNumber', 'items', 'subtotal', 'total', 'paymentMethod'], 'receipt');
8
+ const left = config.margins.left;
9
+ const right = pdf.page.width - config.margins.right;
10
+ const width = right - left;
11
+ const centerX = left + width / 2;
12
+ const currency = data.currency || 'USD';
13
+ const dateTime = (0, validate_1.toDate)(data.dateTime);
14
+ let y = config.margins.top;
15
+ const logo = (0, logo_1.resolveLogo)(data.logo, 44);
16
+ if (logo) {
17
+ await (0, logo_1.embedImage)(pdf, logo.src, centerX - logo.width / 2, y, { width: logo.width, height: logo.height });
18
+ y += logo.height + 8;
19
+ }
20
+ pdf.fillColor(theme.primary).font('Helvetica-Bold').fontSize(18).text(data.storeName, left, y, {
21
+ align: 'center',
22
+ width
23
+ });
24
+ y = pdf.y + 2;
25
+ if (data.storeAddress) {
26
+ pdf.fillColor(theme.muted).font('Helvetica').fontSize(9).text(data.storeAddress, left, y, { align: 'center', width });
27
+ y = pdf.y;
28
+ }
29
+ y += 12;
30
+ pdf
31
+ .strokeColor(theme.border)
32
+ .lineWidth(1)
33
+ .moveTo(left, y)
34
+ .lineTo(right, y)
35
+ .stroke();
36
+ y += 12;
37
+ pdf.fillColor(theme.text).font('Helvetica').fontSize(9);
38
+ pdf.text(`Receipt #: ${data.receiptNumber}`, left, y);
39
+ pdf.text(dateTime.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }), left, pdf.y + 2);
40
+ y = pdf.y + 14;
41
+ pdf.strokeColor(theme.border).dash(2, { space: 2 }).moveTo(left, y).lineTo(right, y).stroke();
42
+ pdf.undash();
43
+ y += 10;
44
+ pdf.font('Helvetica-Bold').fontSize(9).fillColor(theme.muted);
45
+ pdf.text('ITEM', left, y, { width: width * 0.5 });
46
+ pdf.text('QTY x PRICE', left + width * 0.5, y, { width: width * 0.3, align: 'right' });
47
+ pdf.text('TOTAL', left + width * 0.8, y, { width: width * 0.2, align: 'right' });
48
+ y += 14;
49
+ pdf.font('Helvetica').fontSize(10).fillColor(theme.text);
50
+ data.items.forEach((item) => {
51
+ const itemTotal = item.total ?? item.quantity * item.price;
52
+ if (y + 16 > pdf.page.height - config.margins.bottom) {
53
+ pdf.addPage();
54
+ y = config.margins.top;
55
+ }
56
+ pdf.text(item.name, left, y, { width: width * 0.5 });
57
+ pdf.text(`${item.quantity} x ${(0, validate_1.formatCurrency)(item.price, currency)}`, left + width * 0.5, y, {
58
+ width: width * 0.3,
59
+ align: 'right'
60
+ });
61
+ pdf.text((0, validate_1.formatCurrency)(itemTotal, currency), left + width * 0.8, y, { width: width * 0.2, align: 'right' });
62
+ y += 16;
63
+ });
64
+ y += 4;
65
+ pdf.strokeColor(theme.border).moveTo(left, y).lineTo(right, y).stroke();
66
+ y += 10;
67
+ const labelWidth = width - 90;
68
+ pdf.font('Helvetica').fontSize(10).fillColor(theme.text);
69
+ pdf.text('Subtotal', left, y, { width: labelWidth });
70
+ pdf.text((0, validate_1.formatCurrency)(data.subtotal, currency), left + labelWidth, y, { width: 90, align: 'right' });
71
+ y += 16;
72
+ if (data.tax) {
73
+ pdf.text('Tax', left, y, { width: labelWidth });
74
+ pdf.text((0, validate_1.formatCurrency)(data.tax, currency), left + labelWidth, y, { width: 90, align: 'right' });
75
+ y += 16;
76
+ }
77
+ pdf.font('Helvetica-Bold').fontSize(13).fillColor(theme.primary);
78
+ pdf.text('TOTAL', left, y, { width: labelWidth });
79
+ pdf.text((0, validate_1.formatCurrency)(data.total, currency), left + labelWidth, y, { width: 90, align: 'right' });
80
+ y += 24;
81
+ pdf.font('Helvetica').fontSize(9).fillColor(theme.muted).text(`Payment method: ${data.paymentMethod}`, left, y, {
82
+ align: 'center',
83
+ width
84
+ });
85
+ y = pdf.y + 14;
86
+ if (data.thankYouMessage) {
87
+ pdf.font('Helvetica-BoldOblique').fontSize(11).fillColor(theme.primary).text(data.thankYouMessage, left, y, {
88
+ align: 'center',
89
+ width
90
+ });
91
+ }
92
+ }
93
+ //# sourceMappingURL=receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt.js","sourceRoot":"","sources":["../../src/templates/receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface Theme {
2
+ primary: string;
3
+ primaryDark: string;
4
+ accent: string;
5
+ text: string;
6
+ muted: string;
7
+ border: string;
8
+ tableHeaderBg: string;
9
+ tableHeaderText: string;
10
+ tableStripeBg: string;
11
+ background: string;
12
+ }
13
+ export declare const DEFAULT_THEME: Theme;
14
+ export declare const FONTS: {
15
+ regular: string;
16
+ bold: string;
17
+ italic: string;
18
+ boldItalic: string;
19
+ };
20
+ export declare function mergeTheme(overrides?: Partial<Theme>): Theme;
21
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAW3B,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;CAKjB,CAAC;AAEF,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,CAAC,KAAK,CAAM,GAAG,KAAK,CAEhE"}
package/dist/theme.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FONTS = exports.DEFAULT_THEME = void 0;
4
+ exports.mergeTheme = mergeTheme;
5
+ exports.DEFAULT_THEME = {
6
+ primary: '#2b5797',
7
+ primaryDark: '#1c3a66',
8
+ accent: '#e8b923',
9
+ text: '#1a1a1a',
10
+ muted: '#6b7280',
11
+ border: '#d9dee4',
12
+ tableHeaderBg: '#2b5797',
13
+ tableHeaderText: '#ffffff',
14
+ tableStripeBg: '#f4f6f9',
15
+ background: '#ffffff'
16
+ };
17
+ exports.FONTS = {
18
+ regular: 'Helvetica',
19
+ bold: 'Helvetica-Bold',
20
+ italic: 'Helvetica-Oblique',
21
+ boldItalic: 'Helvetica-BoldOblique'
22
+ };
23
+ function mergeTheme(overrides = {}) {
24
+ return { ...exports.DEFAULT_THEME, ...overrides };
25
+ }
26
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":";;;AAiCA,gCAEC;AAtBY,QAAA,aAAa,GAAU;IAClC,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,SAAS;IACtB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;IACjB,aAAa,EAAE,SAAS;IACxB,eAAe,EAAE,SAAS;IAC1B,aAAa,EAAE,SAAS;IACxB,UAAU,EAAE,SAAS;CACtB,CAAC;AAEW,QAAA,KAAK,GAAG;IACnB,OAAO,EAAE,WAAW;IACpB,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,mBAAmB;IAC3B,UAAU,EAAE,uBAAuB;CACpC,CAAC;AAEF,SAAgB,UAAU,CAAC,YAA4B,EAAE;IACvD,OAAO,EAAE,GAAG,qBAAa,EAAE,GAAG,SAAS,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Instance type for a PDFKit document — the community typings expose it as an
2
+ * interface rather than a proper class, so `new` needs an explicit cast. */
3
+ export type PDFDoc = PDFKit.PDFDocument;
4
+ type PDFDocumentConstructor = new (options?: PDFKit.PDFDocumentOptions) => PDFKit.PDFDocument;
5
+ export declare const PDFDocumentCtor: PDFDocumentConstructor;
6
+ export {};
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;6EAC6E;AAC7E,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;AAExC,KAAK,sBAAsB,GAAG,KAAK,OAAO,CAAC,EAAE,MAAM,CAAC,kBAAkB,KAAK,MAAM,CAAC,WAAW,CAAC;AAE9F,eAAO,MAAM,eAAe,EAAmC,sBAAsB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
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.PDFDocumentCtor = void 0;
7
+ const pdfkit_1 = __importDefault(require("pdfkit"));
8
+ exports.PDFDocumentCtor = pdfkit_1.default;
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAuC;AAQ1B,QAAA,eAAe,GAAG,gBAAsD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { PDFDoc } from '../types';
2
+ export type ImageFormat = 'png' | 'jpeg' | 'webp' | 'gif' | 'svg' | 'unknown';
3
+ export declare function detectFormat(source: string | Buffer): ImageFormat;
4
+ /**
5
+ * Resolves any supported image source (PNG, JPEG, GIF, WEBP, SVG — as a file
6
+ * path or an in-memory Buffer) down to either:
7
+ * - `{ kind: 'raster', buffer }` — a PNG/JPEG buffer PDFKit can embed directly
8
+ * via `doc.image()`, or
9
+ * - `{ kind: 'svg', markup }` — SVG markup to be drawn as vector paths via
10
+ * `svg-to-pdfkit`.
11
+ *
12
+ * WEBP and other raster formats are transparently normalized to PNG using
13
+ * `sharp` since PDFKit only natively understands PNG/JPEG.
14
+ */
15
+ export declare function resolveImage(source: string | Buffer): Promise<{
16
+ kind: 'raster';
17
+ buffer: Buffer;
18
+ } | {
19
+ kind: 'svg';
20
+ markup: string;
21
+ }>;
22
+ export interface EmbedImageOptions {
23
+ width?: number;
24
+ height?: number;
25
+ }
26
+ /**
27
+ * Draws an image (PNG, JPEG, GIF, WEBP, or SVG — file path or Buffer) onto a
28
+ * PDFKit document at the given top-left position. SVG is drawn as true vector
29
+ * paths via `svg-to-pdfkit` rather than being rasterized, so logos stay crisp.
30
+ */
31
+ export declare function embedImage(doc: PDFDoc, source: string | Buffer, x: number, y: number, options?: EmbedImageOptions): Promise<void>;
32
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/utils/image.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAsC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAOjE;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB/E;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3I"}
@@ -0,0 +1,98 @@
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.detectFormat = detectFormat;
7
+ exports.resolveImage = resolveImage;
8
+ exports.embedImage = embedImage;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const MAGIC_BYTES = [
12
+ ['png', Buffer.from([0x89, 0x50, 0x4e, 0x47])],
13
+ ['jpeg', Buffer.from([0xff, 0xd8, 0xff])],
14
+ ['gif', Buffer.from('GIF8')]
15
+ ];
16
+ function detectFromBuffer(buf) {
17
+ for (const [format, magic] of MAGIC_BYTES) {
18
+ if (buf.subarray(0, magic.length).equals(magic))
19
+ return format;
20
+ }
21
+ if (buf.subarray(0, 4).toString('ascii') === 'RIFF' && buf.subarray(8, 12).toString('ascii') === 'WEBP') {
22
+ return 'webp';
23
+ }
24
+ const head = buf.subarray(0, 512).toString('utf8').trimStart();
25
+ if (head.startsWith('<svg') || head.startsWith('<?xml'))
26
+ return 'svg';
27
+ return 'unknown';
28
+ }
29
+ function detectFromExtension(ext) {
30
+ switch (ext.toLowerCase()) {
31
+ case '.png':
32
+ return 'png';
33
+ case '.jpg':
34
+ case '.jpeg':
35
+ return 'jpeg';
36
+ case '.webp':
37
+ return 'webp';
38
+ case '.gif':
39
+ return 'gif';
40
+ case '.svg':
41
+ return 'svg';
42
+ default:
43
+ return 'unknown';
44
+ }
45
+ }
46
+ function detectFormat(source) {
47
+ if (Buffer.isBuffer(source)) {
48
+ return detectFromBuffer(source);
49
+ }
50
+ const byExtension = detectFromExtension(path_1.default.extname(source));
51
+ if (byExtension !== 'unknown')
52
+ return byExtension;
53
+ return detectFromBuffer(fs_1.default.readFileSync(source));
54
+ }
55
+ function readSource(source) {
56
+ return Buffer.isBuffer(source) ? source : fs_1.default.readFileSync(source);
57
+ }
58
+ /**
59
+ * Resolves any supported image source (PNG, JPEG, GIF, WEBP, SVG — as a file
60
+ * path or an in-memory Buffer) down to either:
61
+ * - `{ kind: 'raster', buffer }` — a PNG/JPEG buffer PDFKit can embed directly
62
+ * via `doc.image()`, or
63
+ * - `{ kind: 'svg', markup }` — SVG markup to be drawn as vector paths via
64
+ * `svg-to-pdfkit`.
65
+ *
66
+ * WEBP and other raster formats are transparently normalized to PNG using
67
+ * `sharp` since PDFKit only natively understands PNG/JPEG.
68
+ */
69
+ async function resolveImage(source) {
70
+ const format = detectFormat(source);
71
+ if (format === 'svg') {
72
+ return { kind: 'svg', markup: readSource(source).toString('utf8') };
73
+ }
74
+ if (format === 'png' || format === 'jpeg') {
75
+ return { kind: 'raster', buffer: readSource(source) };
76
+ }
77
+ // WEBP, GIF, or anything else raster PDFKit can't embed natively — normalize via sharp.
78
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
79
+ const sharp = require('sharp');
80
+ const buffer = await sharp(readSource(source)).png().toBuffer();
81
+ return { kind: 'raster', buffer };
82
+ }
83
+ /**
84
+ * Draws an image (PNG, JPEG, GIF, WEBP, or SVG — file path or Buffer) onto a
85
+ * PDFKit document at the given top-left position. SVG is drawn as true vector
86
+ * paths via `svg-to-pdfkit` rather than being rasterized, so logos stay crisp.
87
+ */
88
+ async function embedImage(doc, source, x, y, options = {}) {
89
+ const resolved = await resolveImage(source);
90
+ if (resolved.kind === 'svg') {
91
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
92
+ const SVGtoPDF = require('svg-to-pdfkit');
93
+ SVGtoPDF(doc, resolved.markup, x, y, { width: options.width, height: options.height, preserveAspectRatio: 'xMidYMid meet' });
94
+ return;
95
+ }
96
+ doc.image(resolved.buffer, x, y, { width: options.width, height: options.height });
97
+ }
98
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/utils/image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { embedImage } from './image';
2
+ export type LogoInput = string | Buffer | {
3
+ src: string | Buffer;
4
+ width?: number;
5
+ height?: number;
6
+ };
7
+ export interface ResolvedLogo {
8
+ src: string | Buffer;
9
+ width: number;
10
+ height: number;
11
+ }
12
+ /** Normalizes a template's `logo` field (bare path/Buffer, or `{src,width,height}`) to a fixed shape. */
13
+ export declare function resolveLogo(logo: LogoInput | undefined, defaultSize: number): ResolvedLogo | null;
14
+ export { embedImage };
15
+ //# sourceMappingURL=logo.d.ts.map