@alauda/doom
Version:
Doctor Doom making docs.
92 lines (91 loc) • 3.82 kB
JavaScript
import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import { red, yellow } from 'yoctocolors';
import { createProgress, isValidUrl, Printer, writeFileSafe, } from '../html-export-pdf/index.js';
import { getUrlLink, mergePDF, } from './utils/index.js';
/**
* Generate PDF from VuePress or VitePress dev server.
*/
export async function generatePdf({ pages, tempDir, port, host, outFile, outDir, cleanupTempDir = true, allOutlines = [], urlOrigin, pdfOptions, pdfOutlines = true, launchOptions, printerOptions, }) {
await fs.mkdir(tempDir, { recursive: true });
const isValidUrlOrigin = isValidUrl(urlOrigin ?? '');
if (urlOrigin && !isValidUrlOrigin) {
process.stdout.write(red(`${urlOrigin} is not a valid URL`));
process.exit(1);
}
let userURLOrigin = '';
if (urlOrigin && isValidUrlOrigin) {
userURLOrigin = new URL(urlOrigin).origin;
}
const localURLOrigin = `${host}:${port}`;
const normalizePages = pages.map((page) => {
return {
url: page.path,
title: page.title,
location: urlOrigin
? `${userURLOrigin}${page.path}`
: `http://${localURLOrigin}${page.path}`,
pagePath: path.resolve(tempDir, `${page.key}.pdf`),
};
});
if (allOutlines.length) {
const allOutlinesMapping = new Map(allOutlines);
allOutlines = normalizePages.map(({ location }) => {
const { link } = getUrlLink(location);
return [link, allOutlinesMapping.get(link)];
});
}
else {
const singleBar = createProgress();
singleBar.start(normalizePages.length);
const printer = new Printer(printerOptions);
const page = await printer.setup(launchOptions);
if (urlOrigin && isValidUrlOrigin) {
await page.route('**/*', (route) => {
const reqUrl = route.request().url();
if (!isValidUrl(reqUrl)) {
return route.continue();
}
// http or https
const parsedUrl = new URL(reqUrl);
if (userURLOrigin === parsedUrl.origin) {
parsedUrl.host = host;
parsedUrl.protocol = 'http:';
parsedUrl.port = `${port}`;
const parsedUrlString = parsedUrl.toString();
return route.continue({
url: parsedUrlString,
headers: Object.assign({}, route.request().headers(), {
refer: parsedUrlString,
// Same origin
// origin: parsedUrl.origin,
// CORS
// host: parsedUrl.host,
}),
});
}
});
}
for (const { location, pagePath, title } of normalizePages) {
const { data, outlineNodes } = await printer.pdf(location, {
format: 'A4',
...pdfOptions,
}, pdfOutlines);
if (pdfOutlines) {
allOutlines.push([getUrlLink(location).link, outlineNodes]);
}
await writeFileSafe(pagePath, data);
singleBar.increment(1, { headTitle: title || (await page.title()) });
}
singleBar.stop();
await printer.closeBrowser();
}
const exportedPath = await mergePDF(normalizePages, outFile, outDir, allOutlines);
const message = `Exported to ${yellow(exportedPath)}\n`;
process.stdout.write(message);
if (cleanupTempDir) {
await fs.rm(tempDir, { force: true, recursive: true });
}
return { exportedPath, allOutlines };
}