fix(invoice): Rechnung ohne PDF/A statt Fehler, wenn Schriften fehlen
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 0s
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 0s
Fehlt assets/fonts im Container, entsteht das PDF mit Standardschriften und eingebettetem XML, nur nicht als PDF/A; der Fehler steht laut im Log. Eine Rechnung darf nie an den Schriften scheitern. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
051eedaf7f
commit
4b15ca0b8d
1 file changed
+18
-7
@@ -24,12 +24,21 @@ const FONT_FILES = {
|
|||||||
|
|
||||||
type FontName = keyof typeof FONT_FILES;
|
type FontName = keyof typeof FONT_FILES;
|
||||||
|
|
||||||
let fontCache: Record<FontName, Buffer> | null = null;
|
/** undefined: noch nicht gelesen; null: Schriften fehlen (Rueckfall auf Standardschriften). */
|
||||||
|
let fontCache: Record<FontName, Buffer> | null | undefined;
|
||||||
|
|
||||||
function fonts(): Record<FontName, Buffer> {
|
function fonts(): Record<FontName, Buffer> | null {
|
||||||
if (!fontCache) {
|
if (fontCache === undefined) {
|
||||||
const entries = Object.entries(FONT_FILES).map(([name, file]) => [name, readFileSync(path.join(FONT_DIR, file))]);
|
try {
|
||||||
fontCache = Object.fromEntries(entries) as Record<FontName, Buffer>;
|
const entries = Object.entries(FONT_FILES).map(([name, file]) => [name, readFileSync(path.join(FONT_DIR, file))]);
|
||||||
|
fontCache = Object.fromEntries(entries) as Record<FontName, Buffer>;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
// Eine Rechnung darf nie an den Schriften scheitern: ohne sie entsteht
|
||||||
|
// das PDF mit Standardschriften und eingebettetem XML, nur nicht als
|
||||||
|
// PDF/A. Laut melden, damit das fehlende Verzeichnis auffaellt.
|
||||||
|
console.error(`[invoice-pdf] Schriften fuer PDF/A fehlen unter ${FONT_DIR} — Rechnungen ohne PDF/A:`, error);
|
||||||
|
fontCache = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fontCache;
|
return fontCache;
|
||||||
}
|
}
|
||||||
@@ -37,15 +46,17 @@ function fonts(): Record<FontName, Buffer> {
|
|||||||
/**
|
/**
|
||||||
* Optionen fuer new PDFDocument(): PDF/A-3b und eine eingebettete Grundschrift.
|
* Optionen fuer new PDFDocument(): PDF/A-3b und eine eingebettete Grundschrift.
|
||||||
* Ohne "font" laedt pdfkit beim Anlegen die Standard-Helvetica, die dann
|
* Ohne "font" laedt pdfkit beim Anlegen die Standard-Helvetica, die dann
|
||||||
* nicht eingebettet im Dokument stuende.
|
* nicht eingebettet im Dokument stuende. PDF 1.7 auch im Rueckfall, sonst
|
||||||
|
* schreibt pdfkit keine XMP-Metadaten (Factur-X-Angaben).
|
||||||
*/
|
*/
|
||||||
export function pdfaOptions(): PDFKit.PDFDocumentOptions {
|
export function pdfaOptions(): PDFKit.PDFDocumentOptions {
|
||||||
|
if (!fonts()) return { pdfVersion: "1.7" };
|
||||||
return { pdfVersion: "1.7", subset: "PDF/A-3b", font: path.join(FONT_DIR, FONT_FILES.Helvetica) };
|
return { pdfVersion: "1.7", subset: "PDF/A-3b", font: path.join(FONT_DIR, FONT_FILES.Helvetica) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Registriert die eingebetteten Schriften unter den Namen der Standardschriften. */
|
/** Registriert die eingebetteten Schriften unter den Namen der Standardschriften. */
|
||||||
export function registerEmbeddedFonts(doc: PDFKit.PDFDocument): void {
|
export function registerEmbeddedFonts(doc: PDFKit.PDFDocument): void {
|
||||||
for (const [name, data] of Object.entries(fonts())) {
|
for (const [name, data] of Object.entries(fonts() ?? {})) {
|
||||||
doc.registerFont(name, data);
|
doc.registerFont(name, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user