feat: complete OpenAPI docs with all Puppeteer PDF options
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Add scale, pageRanges, preferCSSPageSize, width, height to PdfOptions - Add headerTemplate, footerTemplate, displayHeaderFooter to docs - Pass all options through routes to browser service for HTML, Markdown, and URL endpoints - Export PdfRenderOptions interface for type reuse - Bump version to 0.4.5
This commit is contained in:
parent
f332d425ec
commit
1545df9a7b
5 changed files with 111 additions and 21 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "docfast-api",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "docfast-api",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.5",
|
||||
"dependencies": {
|
||||
"compression": "^1.8.1",
|
||||
"express": "^4.21.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "docfast-api",
|
||||
"version": "0.4.4",
|
||||
"version": "0.4.5",
|
||||
"description": "Markdown/HTML to PDF API with built-in invoice templates",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ interface ConvertBody {
|
|||
margin?: { top?: string; right?: string; bottom?: string; left?: string };
|
||||
printBackground?: boolean;
|
||||
filename?: string;
|
||||
headerTemplate?: string;
|
||||
footerTemplate?: string;
|
||||
displayHeaderFooter?: boolean;
|
||||
scale?: number;
|
||||
pageRanges?: string;
|
||||
preferCSSPageSize?: boolean;
|
||||
width?: string;
|
||||
height?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,6 +139,14 @@ convertRouter.post("/html", async (req: Request & { acquirePdfSlot?: () => Promi
|
|||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "document.pdf");
|
||||
|
|
@ -228,6 +244,14 @@ convertRouter.post("/markdown", async (req: Request & { acquirePdfSlot?: () => P
|
|||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "document.pdf");
|
||||
|
|
@ -310,7 +334,7 @@ convertRouter.post("/url", async (req: Request & { acquirePdfSlot?: () => Promis
|
|||
res.status(415).json({ error: "Unsupported Content-Type. Use application/json." });
|
||||
return;
|
||||
}
|
||||
const body = req.body as { url?: string; format?: string; landscape?: boolean; margin?: any; printBackground?: boolean; waitUntil?: string; filename?: string };
|
||||
const body = req.body as { url?: string; format?: string; landscape?: boolean; margin?: any; printBackground?: boolean; waitUntil?: string; filename?: string; headerTemplate?: string; footerTemplate?: string; displayHeaderFooter?: boolean; scale?: number; pageRanges?: string; preferCSSPageSize?: boolean; width?: string; height?: string };
|
||||
|
||||
if (!body.url) {
|
||||
res.status(400).json({ error: "Missing 'url' field" });
|
||||
|
|
@ -355,6 +379,14 @@ convertRouter.post("/url", async (req: Request & { acquirePdfSlot?: () => Promis
|
|||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
waitUntil: body.waitUntil,
|
||||
hostResolverRules: `MAP ${parsed.hostname} ${resolvedAddress}`,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -218,9 +218,7 @@ export async function closeBrowser(): Promise<void> {
|
|||
instances.length = 0;
|
||||
}
|
||||
|
||||
export async function renderPdf(
|
||||
html: string,
|
||||
options: {
|
||||
export interface PdfRenderOptions {
|
||||
format?: string;
|
||||
landscape?: boolean;
|
||||
margin?: { top?: string; right?: string; bottom?: string; left?: string };
|
||||
|
|
@ -228,7 +226,16 @@ export async function renderPdf(
|
|||
headerTemplate?: string;
|
||||
footerTemplate?: string;
|
||||
displayHeaderFooter?: boolean;
|
||||
} = {}
|
||||
scale?: number;
|
||||
pageRanges?: string;
|
||||
preferCSSPageSize?: boolean;
|
||||
width?: string;
|
||||
height?: string;
|
||||
}
|
||||
|
||||
export async function renderPdf(
|
||||
html: string,
|
||||
options: PdfRenderOptions = {}
|
||||
): Promise<Buffer> {
|
||||
const { page, instance } = await acquirePage();
|
||||
try {
|
||||
|
|
@ -245,6 +252,11 @@ export async function renderPdf(
|
|||
headerTemplate: options.headerTemplate,
|
||||
footerTemplate: options.footerTemplate,
|
||||
displayHeaderFooter: options.displayHeaderFooter || false,
|
||||
...(options.scale !== undefined && { scale: options.scale }),
|
||||
...(options.pageRanges && { pageRanges: options.pageRanges }),
|
||||
...(options.preferCSSPageSize !== undefined && { preferCSSPageSize: options.preferCSSPageSize }),
|
||||
...(options.width && { width: options.width }),
|
||||
...(options.height && { height: options.height }),
|
||||
});
|
||||
return Buffer.from(pdf);
|
||||
})(),
|
||||
|
|
@ -260,11 +272,7 @@ export async function renderPdf(
|
|||
|
||||
export async function renderUrlPdf(
|
||||
url: string,
|
||||
options: {
|
||||
format?: string;
|
||||
landscape?: boolean;
|
||||
margin?: { top?: string; right?: string; bottom?: string; left?: string };
|
||||
printBackground?: boolean;
|
||||
options: PdfRenderOptions & {
|
||||
waitUntil?: string;
|
||||
hostResolverRules?: string;
|
||||
} = {}
|
||||
|
|
@ -316,6 +324,14 @@ export async function renderUrlPdf(
|
|||
landscape: options.landscape || false,
|
||||
printBackground: options.printBackground !== false,
|
||||
margin: options.margin || { top: "0", right: "0", bottom: "0", left: "0" },
|
||||
...(options.headerTemplate && { headerTemplate: options.headerTemplate }),
|
||||
...(options.footerTemplate && { footerTemplate: options.footerTemplate }),
|
||||
...(options.displayHeaderFooter !== undefined && { displayHeaderFooter: options.displayHeaderFooter }),
|
||||
...(options.scale !== undefined && { scale: options.scale }),
|
||||
...(options.pageRanges && { pageRanges: options.pageRanges }),
|
||||
...(options.preferCSSPageSize !== undefined && { preferCSSPageSize: options.preferCSSPageSize }),
|
||||
...(options.width && { width: options.width }),
|
||||
...(options.height && { height: options.height }),
|
||||
});
|
||||
return Buffer.from(pdf);
|
||||
})(),
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ const options: swaggerJsdoc.Options = {
|
|||
type: "string",
|
||||
enum: ["A4", "Letter", "Legal", "A3", "A5", "Tabloid"],
|
||||
default: "A4",
|
||||
description: "Page size",
|
||||
description: "Page size. Ignored if width/height are set.",
|
||||
},
|
||||
landscape: {
|
||||
type: "boolean",
|
||||
|
|
@ -58,6 +58,7 @@ const options: swaggerJsdoc.Options = {
|
|||
},
|
||||
margin: {
|
||||
type: "object",
|
||||
description: "Page margins. Accepts CSS units (e.g. '20mm', '1in', '72px').",
|
||||
properties: {
|
||||
top: { type: "string", example: "20mm" },
|
||||
bottom: { type: "string", example: "20mm" },
|
||||
|
|
@ -68,12 +69,53 @@ const options: swaggerJsdoc.Options = {
|
|||
printBackground: {
|
||||
type: "boolean",
|
||||
default: true,
|
||||
description: "Print background graphics",
|
||||
description: "Print background graphics and colors",
|
||||
},
|
||||
filename: {
|
||||
type: "string",
|
||||
default: "document.pdf",
|
||||
description: "Suggested filename for the PDF",
|
||||
description: "Suggested filename for the PDF download",
|
||||
},
|
||||
headerTemplate: {
|
||||
type: "string",
|
||||
description: "HTML template for the page header. Requires displayHeaderFooter: true. Use these CSS classes for dynamic values: date, title, url, pageNumber, totalPages. Example: '<span class=\"pageNumber\"></span> / <span class=\"totalPages\"></span>'",
|
||||
},
|
||||
footerTemplate: {
|
||||
type: "string",
|
||||
description: "HTML template for the page footer. Requires displayHeaderFooter: true. Supports the same CSS classes as headerTemplate.",
|
||||
},
|
||||
displayHeaderFooter: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "Whether to show header and footer templates. Must be true for headerTemplate/footerTemplate to render.",
|
||||
},
|
||||
scale: {
|
||||
type: "number",
|
||||
minimum: 0.1,
|
||||
maximum: 2,
|
||||
default: 1,
|
||||
description: "Scale of the webpage rendering. 1 = 100%, 0.5 = 50%, 2 = 200%.",
|
||||
example: 1,
|
||||
},
|
||||
pageRanges: {
|
||||
type: "string",
|
||||
description: "Paper ranges to print, e.g. '1-5', '1,3,5', '2-4,6'. Empty string means all pages.",
|
||||
example: "1-3",
|
||||
},
|
||||
preferCSSPageSize: {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "Give any CSS @page size declared in the page priority over the format option.",
|
||||
},
|
||||
width: {
|
||||
type: "string",
|
||||
description: "Paper width with units. Overrides format. Accepts CSS units (e.g. '10in', '210mm', '8.5in').",
|
||||
example: "8.5in",
|
||||
},
|
||||
height: {
|
||||
type: "string",
|
||||
description: "Paper height with units. Overrides format. Accepts CSS units (e.g. '11in', '297mm').",
|
||||
example: "11in",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue