@maistik/nuxt-pdf
Version:
A Nuxt 3 module for server-side PDF generation using Handlebars templates
114 lines (111 loc) • 3.18 kB
JavaScript
import { defineNuxtModule, createResolver, addServerHandler, addImports } from '@nuxt/kit';
import { existsSync, readdirSync, statSync, readFileSync } from 'fs';
import { join } from 'path';
const module = defineNuxtModule({
meta: {
name: "@maistik/nuxt-pdf",
configKey: "pdf",
compatibility: {
nuxt: "^3.0.0"
}
},
defaults: {
provider: "gotenberg",
components: ["pdf"],
sharedComponents: ["pdf/partials"],
enableI18n: true,
defaultLocale: "en",
availableLocales: ["en"],
i18nMessages: {},
providers: {
gotenberg: {
url: "http://localhost:3000"
},
browserless: {
url: "https://chrome.browserless.io",
apiKey: ""
},
puppeteer: {
launchOptions: {
headless: true,
args: ["--no-sandbox", "--disable-setuid-sandbox"]
}
}
},
customHelpers: {},
defaultOptions: {
format: "A4",
margin: {
top: 20,
bottom: 20,
left: 20,
right: 20
},
landscape: false,
printBackground: true,
pageBreak: {
before: ["always"],
after: ["always"],
avoid: [".no-break"]
}
}
},
setup(options, nuxt) {
const resolver = createResolver(import.meta.url);
const templateSources = {};
const partialSources = {};
for (const componentDir of options.components) {
const fullPath = join(nuxt.options.srcDir, componentDir);
if (existsSync(fullPath)) {
scanDirectory(fullPath, templateSources, ".hbs");
}
}
for (const sharedDir of options.sharedComponents) {
const fullPath = join(nuxt.options.srcDir, sharedDir);
if (existsSync(fullPath)) {
scanDirectory(fullPath, partialSources, ".hbs");
}
}
nuxt.options.runtimeConfig.pdf = {
provider: options.provider,
enableI18n: options.enableI18n,
defaultLocale: options.defaultLocale,
availableLocales: options.availableLocales,
i18nMessages: options.i18nMessages,
providers: options.providers,
defaultOptions: options.defaultOptions,
templateSources,
partialSources,
customHelpers: options.customHelpers || {}
};
nuxt.options.runtimeConfig.public.pdf = {
enableI18n: options.enableI18n,
defaultLocale: options.defaultLocale,
availableLocales: options.availableLocales
};
addServerHandler({
route: "/api/pdf",
handler: resolver.resolve("./runtime/server/api/pdf.post")
});
addImports({
name: "usePdf",
as: "usePdf",
from: resolver.resolve("./runtime/composables/usePdf")
});
}
});
function scanDirectory(dir, sources, extension) {
if (!existsSync(dir)) return;
const files = readdirSync(dir);
for (const file of files) {
const filePath = join(dir, file);
const stat = statSync(filePath);
if (stat.isDirectory()) {
scanDirectory(filePath, sources, extension);
} else if (file.endsWith(extension)) {
const templateName = file.replace(extension, "");
sources[templateName] = readFileSync(filePath, "utf-8");
}
}
}
export { module as default };