baptistejamin / node-microinvoice

Fast & elegant PDF invoice generator for Node using PDFKit. No Puppeteer
MIT License
131 stars 18 forks source link

I propose to add a builder #2

Open pleshevskiy opened 3 years ago

pleshevskiy commented 3 years ago

It seems to me that the builder design pattern is most suitable for this library.

const brandInvoiceBuilder = new InvoiceBuilder()
   .useStyles(
       new StyleBulder()
           .withDocument({ marginLeft: 30, marginRight: 30, marginTop: 30 })
           .withFonts({ ... })
           .withHeader({ ... })
       // or use style objects as well
       // if you pass style builder, invoice builder will build your styles automatically
   );

// then in any business logic
brandInvoiceBuilder.generate(invoiceData, 'path/to/your/invoice.pdf');

If you don't use custom styles, it will generate an invoice with default styles. Also if you use StyleBuilder with no or partial use of its methods, it will create default styles or your styles that have been merged with the default styles

const defaultInvoiceBuilder = new InvoiceBuilder();
// or new InvoiceBuilder().useStyles(new StyleBuilder())
defaultInvoiceBuilder.generate(invoiceData, 'path/to/your/invoice.pdf'); 
pleshevskiy commented 3 years ago

Alternatively, we could put StyleBuilder to above level. And also add a Prototype (Clone) design pattern. This makes it possible to generate styles for each brand more conveniently


const generalInvoiceBuilder = new InvoiceBuilder()
    .withDocument({ marginLeft: 30, marginRight: 30, marginTop: 30 })
    .withFonts({ ... })
    .withText({ ... })

const fooBrandInvoiceBuilder = generalInvoiceBuilder.clone()
    .withHeader({ ... })
    .withTable({ ... })
// fooBrandInvoiceBuilder.generate(data, 'invoice.pdf');

const barBrandInvoiceBuilder = generalInvoiceBuilder.clone()
    .withText({ ... }) // will be merged with general text styles
    .withHeader({ ... });
    // used default styles for `table`
// barBrandInvoiceBuilder.generate(data, 'invoice.pdf');