503 lines
11 KiB
TypeScript
503 lines
11 KiB
TypeScript
/**
|
|
* @file pdf.ts
|
|
* @description PDF generation configuration interfaces
|
|
* Templates, branding, layout, headers/footers, and security
|
|
*/
|
|
|
|
import * as plugins from './plugins.js';
|
|
import type {
|
|
TPageSize,
|
|
TPageOrientation,
|
|
THeaderFooterContentType,
|
|
TPageNumberFormat,
|
|
TPdfEncryptionAlgorithm,
|
|
TPdfPrintingPermission,
|
|
TPdfJobStatus,
|
|
} from './types.js';
|
|
|
|
// ============================================================================
|
|
// FONT CONFIGURATION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Font configuration
|
|
*/
|
|
export interface IFontConfig {
|
|
family: string;
|
|
fallback: string[];
|
|
size: number;
|
|
lineHeight: number;
|
|
weight?: 'normal' | 'bold' | number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// BRANDING
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Logo configuration
|
|
*/
|
|
export interface ILogoConfig {
|
|
url: string;
|
|
position: 'left' | 'center' | 'right';
|
|
maxWidth: number;
|
|
maxHeight: number;
|
|
}
|
|
|
|
/**
|
|
* Watermark configuration
|
|
*/
|
|
export interface IWatermarkConfig {
|
|
text?: string;
|
|
imageUrl?: string;
|
|
opacity: number;
|
|
position: 'center' | 'diagonal';
|
|
showOnlyOnDraft: boolean;
|
|
}
|
|
|
|
/**
|
|
* Branding configuration for PDF
|
|
*/
|
|
export interface IPdfBranding {
|
|
logo?: ILogoConfig;
|
|
primaryColor: string;
|
|
secondaryColor: string;
|
|
textColor: string;
|
|
fonts: {
|
|
heading: IFontConfig;
|
|
body: IFontConfig;
|
|
monospace?: IFontConfig;
|
|
};
|
|
watermark?: IWatermarkConfig;
|
|
}
|
|
|
|
// ============================================================================
|
|
// LAYOUT
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Custom page size
|
|
*/
|
|
export interface ICustomPageSize {
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
/**
|
|
* Page margins
|
|
*/
|
|
export interface IPageMargins {
|
|
top: number;
|
|
right: number;
|
|
bottom: number;
|
|
left: number;
|
|
}
|
|
|
|
/**
|
|
* PDF layout configuration
|
|
*/
|
|
export interface IPdfLayout {
|
|
pageSize: TPageSize;
|
|
customSize?: ICustomPageSize;
|
|
orientation: TPageOrientation;
|
|
margins: IPageMargins;
|
|
columns: 1 | 2;
|
|
columnGap?: number;
|
|
paragraphSpacing: number;
|
|
sectionSpacing: number;
|
|
firstPageDifferent: boolean;
|
|
firstPageMargins?: IPageMargins;
|
|
}
|
|
|
|
// ============================================================================
|
|
// HEADER/FOOTER
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Header/Footer content definition
|
|
*/
|
|
export interface IPdfHeaderFooterContent {
|
|
type: THeaderFooterContentType;
|
|
text?: string;
|
|
imageUrl?: string;
|
|
pageNumberFormat?: TPageNumberFormat;
|
|
pageNumberPrefix?: string;
|
|
includeTotal?: boolean;
|
|
dateFormat?: string;
|
|
customTemplate?: string;
|
|
fontSize?: number;
|
|
fontWeight?: 'normal' | 'bold';
|
|
color?: string;
|
|
}
|
|
|
|
/**
|
|
* Header/Footer configuration
|
|
*/
|
|
export interface IPdfHeaderFooter {
|
|
enabled: boolean;
|
|
height: number;
|
|
left?: IPdfHeaderFooterContent;
|
|
center?: IPdfHeaderFooterContent;
|
|
right?: IPdfHeaderFooterContent;
|
|
borderBottom?: boolean;
|
|
borderTop?: boolean;
|
|
borderColor?: string;
|
|
skipFirstPage: boolean;
|
|
skipLastPage: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// PAGE NUMBERING
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Page numbering configuration
|
|
*/
|
|
export interface IPdfPageNumbering {
|
|
enabled: boolean;
|
|
startFrom: number;
|
|
format: TPageNumberFormat;
|
|
position: 'header' | 'footer';
|
|
alignment: 'left' | 'center' | 'right';
|
|
prefix?: string;
|
|
suffix?: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// CONTENT OPTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Table of contents configuration
|
|
*/
|
|
export interface ITocConfig {
|
|
enabled: boolean;
|
|
depth: number;
|
|
title: string;
|
|
pageBreakAfter: boolean;
|
|
}
|
|
|
|
/**
|
|
* Cover page configuration
|
|
*/
|
|
export interface ICoverPageConfig {
|
|
enabled: boolean;
|
|
template: 'standard' | 'minimal' | 'custom';
|
|
customTemplateId?: string;
|
|
showLogo: boolean;
|
|
showDate: boolean;
|
|
showParties: boolean;
|
|
showConfidentialityNotice: boolean;
|
|
confidentialityText?: string;
|
|
}
|
|
|
|
/**
|
|
* Signature page configuration
|
|
*/
|
|
export interface ISignaturePageConfig {
|
|
enabled: boolean;
|
|
signatureBlockStyle: 'inline' | 'separate_page' | 'both';
|
|
includeWitnessLines: boolean;
|
|
includeInitialsOnEachPage: boolean;
|
|
}
|
|
|
|
/**
|
|
* Attachment handling configuration
|
|
*/
|
|
export interface IAttachmentConfig {
|
|
includeInline: boolean;
|
|
includeSeparately: boolean;
|
|
attachmentToc: boolean;
|
|
}
|
|
|
|
/**
|
|
* Content formatting configuration
|
|
*/
|
|
export interface IFormattingConfig {
|
|
headingNumbering: boolean;
|
|
paragraphNumbering: boolean;
|
|
preserveMarkdownFormatting: boolean;
|
|
convertLinksToFootnotes: boolean;
|
|
}
|
|
|
|
/**
|
|
* Content rendering options
|
|
*/
|
|
export interface IPdfContentOptions {
|
|
tableOfContents: ITocConfig;
|
|
coverPage?: ICoverPageConfig;
|
|
signaturePages: ISignaturePageConfig;
|
|
attachments: IAttachmentConfig;
|
|
formatting: IFormattingConfig;
|
|
}
|
|
|
|
// ============================================================================
|
|
// SECURITY
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Encryption configuration
|
|
*/
|
|
export interface IPdfEncryption {
|
|
enabled: boolean;
|
|
algorithm: TPdfEncryptionAlgorithm;
|
|
}
|
|
|
|
/**
|
|
* Password protection
|
|
*/
|
|
export interface IPdfPasswords {
|
|
userPassword?: string;
|
|
ownerPassword?: string;
|
|
}
|
|
|
|
/**
|
|
* PDF permissions
|
|
*/
|
|
export interface IPdfPermissions {
|
|
printing: TPdfPrintingPermission;
|
|
copying: boolean;
|
|
modifying: boolean;
|
|
annotating: boolean;
|
|
formFilling: boolean;
|
|
accessibility: boolean;
|
|
assembly: boolean;
|
|
}
|
|
|
|
/**
|
|
* PDF digital signature configuration
|
|
*/
|
|
export interface IPdfDigitalSignature {
|
|
enabled: boolean;
|
|
certificateId: string;
|
|
signatureReason: string;
|
|
signatureLocation?: string;
|
|
timestampAuthority?: string;
|
|
}
|
|
|
|
/**
|
|
* PDF security options
|
|
*/
|
|
export interface IPdfSecurity {
|
|
encryption: IPdfEncryption;
|
|
passwords?: IPdfPasswords;
|
|
permissions: IPdfPermissions;
|
|
digitalSignature?: IPdfDigitalSignature;
|
|
}
|
|
|
|
// ============================================================================
|
|
// METADATA
|
|
// ============================================================================
|
|
|
|
/**
|
|
* PDF metadata
|
|
*/
|
|
export interface IPdfMetadata {
|
|
title: string;
|
|
subject?: string;
|
|
author?: string;
|
|
creator: string;
|
|
producer: string;
|
|
keywords: string[];
|
|
creationDate: number;
|
|
modificationDate?: number;
|
|
customProperties?: Record<string, string>;
|
|
}
|
|
|
|
// ============================================================================
|
|
// COMPLETE CONFIGURATION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Complete PDF generation configuration
|
|
*/
|
|
export interface IPdfGenerationConfig {
|
|
templateId?: string;
|
|
useDefaultTemplate: boolean;
|
|
branding: IPdfBranding;
|
|
layout: IPdfLayout;
|
|
header?: IPdfHeaderFooter;
|
|
footer?: IPdfHeaderFooter;
|
|
pageNumbering: IPdfPageNumbering;
|
|
contentOptions: IPdfContentOptions;
|
|
security?: IPdfSecurity;
|
|
metadata: IPdfMetadata;
|
|
}
|
|
|
|
// ============================================================================
|
|
// PDF TEMPLATE
|
|
// ============================================================================
|
|
|
|
/**
|
|
* PDF template definition
|
|
*/
|
|
export interface IPdfTemplate {
|
|
id: string;
|
|
name: string;
|
|
description?: string;
|
|
version: string;
|
|
config: IPdfGenerationConfig;
|
|
allowedContractTypes?: string[];
|
|
organizationId?: string;
|
|
isSystem: boolean;
|
|
createdAt: number;
|
|
createdBy: string;
|
|
lastModifiedAt?: number;
|
|
lastModifiedBy?: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// PDF GENERATION JOB
|
|
// ============================================================================
|
|
|
|
/**
|
|
* PDF generation result
|
|
*/
|
|
export interface IPdfGenerationResult {
|
|
pdf: plugins.tsclass.business.IPdf;
|
|
pageCount: number;
|
|
fileSize: number;
|
|
}
|
|
|
|
/**
|
|
* PDF generation error
|
|
*/
|
|
export interface IPdfGenerationError {
|
|
code: string;
|
|
message: string;
|
|
details?: unknown;
|
|
}
|
|
|
|
/**
|
|
* PDF generation job
|
|
*/
|
|
export interface IPdfGenerationJob {
|
|
id: string;
|
|
contractId: string;
|
|
versionId: string;
|
|
config: IPdfGenerationConfig;
|
|
status: TPdfJobStatus;
|
|
progress?: number;
|
|
queuedAt: number;
|
|
startedAt?: number;
|
|
completedAt?: number;
|
|
result?: IPdfGenerationResult;
|
|
error?: IPdfGenerationError;
|
|
retryCount: number;
|
|
maxRetries: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// FACTORY FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Create default branding
|
|
*/
|
|
export function createDefaultBranding(): IPdfBranding {
|
|
return {
|
|
primaryColor: '#1a1a1a',
|
|
secondaryColor: '#666666',
|
|
textColor: '#333333',
|
|
fonts: {
|
|
heading: {
|
|
family: 'Helvetica',
|
|
fallback: ['Arial', 'sans-serif'],
|
|
size: 14,
|
|
lineHeight: 1.4,
|
|
weight: 'bold',
|
|
},
|
|
body: {
|
|
family: 'Helvetica',
|
|
fallback: ['Arial', 'sans-serif'],
|
|
size: 11,
|
|
lineHeight: 1.5,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create default layout
|
|
*/
|
|
export function createDefaultLayout(): IPdfLayout {
|
|
return {
|
|
pageSize: 'A4',
|
|
orientation: 'portrait',
|
|
margins: {
|
|
top: 25,
|
|
right: 20,
|
|
bottom: 25,
|
|
left: 20,
|
|
},
|
|
columns: 1,
|
|
paragraphSpacing: 10,
|
|
sectionSpacing: 20,
|
|
firstPageDifferent: false,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create default content options
|
|
*/
|
|
export function createDefaultContentOptions(): IPdfContentOptions {
|
|
return {
|
|
tableOfContents: {
|
|
enabled: true,
|
|
depth: 2,
|
|
title: 'Table of Contents',
|
|
pageBreakAfter: true,
|
|
},
|
|
signaturePages: {
|
|
enabled: true,
|
|
signatureBlockStyle: 'inline',
|
|
includeWitnessLines: false,
|
|
includeInitialsOnEachPage: false,
|
|
},
|
|
attachments: {
|
|
includeInline: false,
|
|
includeSeparately: true,
|
|
attachmentToc: true,
|
|
},
|
|
formatting: {
|
|
headingNumbering: true,
|
|
paragraphNumbering: false,
|
|
preserveMarkdownFormatting: true,
|
|
convertLinksToFootnotes: false,
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create default page numbering
|
|
*/
|
|
export function createDefaultPageNumbering(): IPdfPageNumbering {
|
|
return {
|
|
enabled: true,
|
|
startFrom: 1,
|
|
format: 'numeric',
|
|
position: 'footer',
|
|
alignment: 'center',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Create default PDF generation config
|
|
*/
|
|
export function createDefaultPdfConfig(title: string): IPdfGenerationConfig {
|
|
return {
|
|
useDefaultTemplate: true,
|
|
branding: createDefaultBranding(),
|
|
layout: createDefaultLayout(),
|
|
pageNumbering: createDefaultPageNumbering(),
|
|
contentOptions: createDefaultContentOptions(),
|
|
metadata: {
|
|
title,
|
|
creator: 'signature.digital',
|
|
producer: 'signature.digital PDF Generator',
|
|
keywords: [],
|
|
creationDate: Date.now(),
|
|
},
|
|
};
|
|
}
|