import Parameters, { StorageOptions } from './parameters' type Optional = T|null|undefined type PaperFormat = 'letter'|'legal'|'tabloid'|'ledger'|'A0'|'A1'|'A2'|'A3'|'A4'|'A5'|'A6' export default class ConversionParameters implements Parameters { private params: { [key: string]: any } = {} /** * Static constructor for a fluent API. */ static make() { return new ConversionParameters() } /** * Set the HTML of the document. */ html(html: string) { this.params.html = html return this } /** * Set the URL to the document. */ url(url: string) { this.params.url = url return this } /** * Serve the PDF via the CDN. */ cdn(cdn: Optional = true) { this.params.cdn = cdn return this } /** * Upload the PDF directly to the user's configured storage disk. */ storage(options?: Partial|boolean) { this.params.storage = options ? options : true return this } /** * Set the landscape option. */ landscape(landscape: Optional = true) { this.params.landscape = landscape return this } /** * Set the printBackground option. */ printBackground(printBackground: Optional = true) { this.params.printBackground = printBackground return this } /** * Set the preferCSSPageSize option. */ preferCSSPageSize(preferCSSPageSize: Optional = true) { this.params.preferCSSPageSize = preferCSSPageSize return this } /** * Set the adblocker option. */ blockAds(blockAds: Optional = true) { this.params.blockAds = blockAds return this } /** * Set the allowErrorPage option. */ allowErrorPage(allow: Optional = true) { this.params.allowErrorPage = allow return this } /** * Set the optimize (CSS) option. */ optimize(optimize: Optional = true) { this.params.optimize = optimize return this } /** * Set the waitForSelectorTimeout option. */ waitForSelectorTimeout(waitForSelectorTimeout: Optional) { this.params.waitForSelectorTimeout = waitForSelectorTimeout return this } /** * Set the waitUntilTimeout option. */ waitUntilTimeout(waitUntilTimeout: Optional) { this.params.waitUntilTimeout = waitUntilTimeout return this } /** * Set the delay in milliseconds. */ delay(delay: Optional) { this.params.delay = delay return this } /** * Set the timeout in milliseconds. */ timeout(timeout: Optional) { this.params.timeout = timeout return this } /** * Set the viewport width in pixel. * @param viewportWidth */ viewportWidth(viewportWidth: Optional) { this.params.viewportWidth = viewportWidth return this } /** * Set the viewport height in milliseconds. */ viewportHeight(viewportHeight: Optional) { this.params.viewportHeight = viewportHeight return this } /** * Set the scale of the page. */ scale(scale: Optional) { this.params.scale = scale return this } /** * Set the PDF paper width. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ paperWidth(width: Optional) { this.params.paperWidth = width return this } /** * Set the PDF paper height. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ paperHeight(height: Optional) { this.params.paperHeight = height return this } /** * Set all PDF margins. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ margin(margin: Optional) { this.params.margin = margin return this } /** * Set the PDF top margin. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ marginTop(marginTop: Optional) { this.params.marginTop = marginTop return this } /** * Set the PDF right margin. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ marginRight(marginRight: Optional) { this.params.marginRight = marginRight return this } /** * Set the PDF bottom margin. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ marginBottom(marginBottom: Optional) { this.params.marginBottom = marginBottom return this } /** * Set the PDF left margin. Accepts values labeled with units (px, in, mm, cm). * Defaults to pixel when no unit given. */ marginLeft(marginLeft: Optional) { this.params.marginLeft = marginLeft return this } /** * Set the HTML template for the PDF header. */ headerTemplate(template: Optional) { this.params.headerTemplate = template return this } /** * Set the HTML template for the PDF footer. */ footerTemplate(template: Optional) { this.params.footerTemplate = template return this } /** * Set the emulated CSS media. */ emulateMedia(media: Optional<'screen'|'print'>) { if (!media) { this.params.emulateMedia = undefined return this } if (['screen', 'print'].indexOf(media) === -1) { throw new Error(`Cannot emulate unknown media '${media}'.`) } this.params.emulateMedia = media return this } /** * Set the CSS media to 'screen'. */ emulateMediaScreen() { return this.emulateMedia('screen') } /** * Set the CSS media to 'print'. */ emulateMediaPrint() { return this.emulateMedia('print') } /** * Secure the PDF with an owner password. */ ownerPassword(password: Optional) { this.params.ownerPassword = password return this } /** * Secure the PDF with an user password. */ userPassword(password: Optional) { this.params.userPassword = password return this } /** * Secure the PDF with an owner and a user password. */ passwords(owner: Optional, user: Optional) { return this.ownerPassword(owner).userPassword(user) } /** * Set the page ranges to be caputered in the PDF. */ pageRanges(...ranges: (number|string|(number|string)[])[]) { const normalized: string[] = [] for (const range of ranges) { if (Array.isArray(range)) { normalized.push(...range.map(r => r.toString())) continue } normalized.push(range.toString()) } this.params.pageRanges = normalized.map(v => v.trim()).join(',') return this } /** * Set the paper format. Overrides paperWidth and paperHeight options. */ format(format: Optional) { if (!format) { this.params.format = undefined return this } if (PAPER_FORMATS.indexOf(format) === -1) { throw new Error(`Unknown paper format '${format}'.`) } this.params.format = format return this } /** * Add a custom HTTP header to the request. */ header(key: string, value: any) { if (!this.params.headers) { this.params.headers = {} } this.params.headers[key] = value return this } /** * Add multiple HTTP headers to the request. */ headers(headers: { [key: string]: any } = {}) { for (const key in headers) { this.header(key, headers[key]) } return this } /** * Wait for a selector to appear on the page before capturing it. */ waitForSelector(selector: string) { this.params.waitForSelector = selector return this } /** * Set the browser event to wait for before capturing the page. */ waitUntil(event: Optional<'load'|'dom'>) { if (!event) { this.params.waitUntil = undefined return this } if (['load', 'dom'].indexOf(event) === -1) { throw new Error(`Unknown browser event '${event}'.`) } this.params.waitUntil = event return this } /** * Wait for the "load" event of the browser before capturing the page. */ waitUntilLoad() { return this.waitUntil('load') } /** * Wait for the "DOMContentLoaded" event of the browser before capturing the page. */ waitUntilDOM() { return this.waitUntil('dom') } /** * Set the DOM element on the page that's converted to a PDF. */ selector(selector: Optional) { this.params.selector = selector return this } all() { const params: { [key: string]: any } = {} for (const key in this.params) { const value = this.params[key] if (value === null || typeof value === 'undefined') { continue } params[key] = value } return params } } const PAPER_FORMATS: PaperFormat[] = [ 'letter', 'legal', 'tabloid', 'ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6' ]