@signiphi/pdf-signer 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALLING_LOCALLY.md +184 -0
- package/LICENSE +2 -0
- package/README.md +1093 -0
- package/assets/viewer.html +314 -0
- package/dist/__tests__/helpers/fixtures.d.ts +43 -0
- package/dist/__tests__/helpers/fixtures.d.ts.map +1 -0
- package/dist/__tests__/helpers/mocks.d.ts +333 -0
- package/dist/__tests__/helpers/mocks.d.ts.map +1 -0
- package/dist/__tests__/setup.d.ts +6 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/components/AttachmentUpload.d.ts +17 -0
- package/dist/components/AttachmentUpload.d.ts.map +1 -0
- package/dist/components/EditableFieldsPanel.d.ts +30 -0
- package/dist/components/EditableFieldsPanel.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +67 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/FormFieldsView.d.ts +42 -0
- package/dist/components/FormFieldsView.d.ts.map +1 -0
- package/dist/components/PdfViewerStyled.d.ts +16 -0
- package/dist/components/PdfViewerStyled.d.ts.map +1 -0
- package/dist/components/PoweredBySigniphi.d.ts +11 -0
- package/dist/components/PoweredBySigniphi.d.ts.map +1 -0
- package/dist/components/SignatureCanvas.d.ts +12 -0
- package/dist/components/SignatureCanvas.d.ts.map +1 -0
- package/dist/components/SignatureInitialsBox.d.ts +23 -0
- package/dist/components/SignatureInitialsBox.d.ts.map +1 -0
- package/dist/components/SignatureModal.d.ts +22 -0
- package/dist/components/SignatureModal.d.ts.map +1 -0
- package/dist/components/SigningInstructions.d.ts +12 -0
- package/dist/components/SigningInstructions.d.ts.map +1 -0
- package/dist/components/SubmissionForm.d.ts +52 -0
- package/dist/components/SubmissionForm.d.ts.map +1 -0
- package/dist/components/ViewToggleToolbar.d.ts +30 -0
- package/dist/components/ViewToggleToolbar.d.ts.map +1 -0
- package/dist/components/form-fields/CheckboxRenderer.d.ts +10 -0
- package/dist/components/form-fields/CheckboxRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/DateFieldRenderer.d.ts +14 -0
- package/dist/components/form-fields/DateFieldRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/DropdownRenderer.d.ts +14 -0
- package/dist/components/form-fields/DropdownRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/FormFieldRenderer.d.ts +20 -0
- package/dist/components/form-fields/FormFieldRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/InitialsFieldRenderer.d.ts +14 -0
- package/dist/components/form-fields/InitialsFieldRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/RadioGroupRenderer.d.ts +10 -0
- package/dist/components/form-fields/RadioGroupRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/SignatureFieldRenderer.d.ts +16 -0
- package/dist/components/form-fields/SignatureFieldRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/TextFieldRenderer.d.ts +14 -0
- package/dist/components/form-fields/TextFieldRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/TextLabelRenderer.d.ts +14 -0
- package/dist/components/form-fields/TextLabelRenderer.d.ts.map +1 -0
- package/dist/components/form-fields/index.d.ts +14 -0
- package/dist/components/form-fields/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +14 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6297 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +6248 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/core/PdfViewerCore.d.ts +19 -0
- package/dist/core/PdfViewerCore.d.ts.map +1 -0
- package/dist/core/SignatureCaptureCore.d.ts +37 -0
- package/dist/core/SignatureCaptureCore.d.ts.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +907 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +884 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +2167 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +2139 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/hooks/useAttachments.d.ts +25 -0
- package/dist/hooks/useAttachments.d.ts.map +1 -0
- package/dist/hooks/useFieldFiltering.d.ts +29 -0
- package/dist/hooks/useFieldFiltering.d.ts.map +1 -0
- package/dist/hooks/useFormFields.d.ts +23 -0
- package/dist/hooks/useFormFields.d.ts.map +1 -0
- package/dist/hooks/useMultiSignerContext.d.ts +25 -0
- package/dist/hooks/useMultiSignerContext.d.ts.map +1 -0
- package/dist/hooks/usePdfViewer.d.ts +52 -0
- package/dist/hooks/usePdfViewer.d.ts.map +1 -0
- package/dist/hooks/useSignatureCapture.d.ts +17 -0
- package/dist/hooks/useSignatureCapture.d.ts.map +1 -0
- package/dist/hooks/useSignatures.d.ts +25 -0
- package/dist/hooks/useSignatures.d.ts.map +1 -0
- package/dist/index.css +4929 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7220 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7093 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integrations/index.d.ts +6 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +242 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/index.mjs +218 -0
- package/dist/integrations/index.mjs.map +1 -0
- package/dist/integrations/next-config.d.ts +46 -0
- package/dist/integrations/next-config.d.ts.map +1 -0
- package/dist/integrations/vite-plugin.d.ts +48 -0
- package/dist/integrations/vite-plugin.d.ts.map +1 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/ui/alert.d.ts +9 -0
- package/dist/lib/ui/alert.d.ts.map +1 -0
- package/dist/lib/ui/button.d.ts +12 -0
- package/dist/lib/ui/button.d.ts.map +1 -0
- package/dist/lib/ui/calendar.d.ts +10 -0
- package/dist/lib/ui/calendar.d.ts.map +1 -0
- package/dist/lib/ui/card.d.ts +9 -0
- package/dist/lib/ui/card.d.ts.map +1 -0
- package/dist/lib/ui/checkbox.d.ts +5 -0
- package/dist/lib/ui/checkbox.d.ts.map +1 -0
- package/dist/lib/ui/dialog.d.ts +20 -0
- package/dist/lib/ui/dialog.d.ts.map +1 -0
- package/dist/lib/ui/index.d.ts +12 -0
- package/dist/lib/ui/index.d.ts.map +1 -0
- package/dist/lib/ui/input.d.ts +6 -0
- package/dist/lib/ui/input.d.ts.map +1 -0
- package/dist/lib/ui/label.d.ts +6 -0
- package/dist/lib/ui/label.d.ts.map +1 -0
- package/dist/lib/ui/popover.d.ts +7 -0
- package/dist/lib/ui/popover.d.ts.map +1 -0
- package/dist/lib/ui/radio-group.d.ts +6 -0
- package/dist/lib/ui/radio-group.d.ts.map +1 -0
- package/dist/lib/ui/select.d.ts +14 -0
- package/dist/lib/ui/select.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +7 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/styles/index.css +5004 -0
- package/dist/types/index.d.ts +265 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +26 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +23 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/utils/attachment-validators.d.ts +118 -0
- package/dist/utils/attachment-validators.d.ts.map +1 -0
- package/dist/utils/audit-trail.d.ts +27 -0
- package/dist/utils/audit-trail.d.ts.map +1 -0
- package/dist/utils/date-validation.d.ts +30 -0
- package/dist/utils/date-validation.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +106 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/field-extraction.d.ts +27 -0
- package/dist/utils/field-extraction.d.ts.map +1 -0
- package/dist/utils/field-visibility.d.ts +104 -0
- package/dist/utils/field-visibility.d.ts.map +1 -0
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2501 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +2404 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/pdf-field-type-helpers.d.ts +78 -0
- package/dist/utils/pdf-field-type-helpers.d.ts.map +1 -0
- package/dist/utils/pdf-helpers.d.ts +38 -0
- package/dist/utils/pdf-helpers.d.ts.map +1 -0
- package/dist/utils/pdf-lib-loader.d.ts +45 -0
- package/dist/utils/pdf-lib-loader.d.ts.map +1 -0
- package/dist/utils/pdf-manipulation.d.ts +93 -0
- package/dist/utils/pdf-manipulation.d.ts.map +1 -0
- package/dist/utils/pdf-validators.d.ts +149 -0
- package/dist/utils/pdf-validators.d.ts.map +1 -0
- package/dist/utils/pdf-viewer-filter.d.ts +35 -0
- package/dist/utils/pdf-viewer-filter.d.ts.map +1 -0
- package/dist/utils/pdf-widget-helpers.d.ts +98 -0
- package/dist/utils/pdf-widget-helpers.d.ts.map +1 -0
- package/dist/utils/pdfjs-config.d.ts +56 -0
- package/dist/utils/pdfjs-config.d.ts.map +1 -0
- package/dist/utils/pdfjs-version-check.d.ts +28 -0
- package/dist/utils/pdfjs-version-check.d.ts.map +1 -0
- package/dist/utils/performance-monitor.d.ts +172 -0
- package/dist/utils/performance-monitor.d.ts.map +1 -0
- package/dist/utils/tracking.d.ts +89 -0
- package/dist/utils/tracking.d.ts.map +1 -0
- package/package.json +180 -0
- package/scripts/analyze-bundle.js +271 -0
- package/scripts/copy-utils.js +227 -0
- package/scripts/copy-utils.test.js +164 -0
- package/scripts/postinstall.js +109 -0
- package/scripts/setup.js +108 -0
- package/src/styles/index.css +139 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/logger.ts","../../src/utils/pdf-validators.ts","../../src/utils/pdf-helpers.ts","../../src/utils/pdf-lib-loader.ts","../../src/utils/field-visibility.ts","../../src/utils/pdf-widget-helpers.ts","../../src/utils/pdf-field-type-helpers.ts","../../src/utils/pdf-manipulation.ts","../../src/utils/field-extraction.ts","../../src/utils/pdfjs-config.ts","../../src/utils/pdfjs-version-check.ts","../../src/utils/audit-trail.ts","../../src/utils/errors.ts","../../src/utils/attachment-validators.ts","../../src/utils/performance-monitor.ts","../../src/utils/date-validation.ts","../../src/utils/tracking.ts"],"names":["pdfjsLib","isSignatureField","isInitialsField","pdfjsLib2","pdfjsLib3","parseISO","isValidDate","parse"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Logger Utility\r\n * Centralized logging system with environment-based log level control\r\n */\r\n\r\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\ninterface Logger {\r\n debug(message: string, ...args: unknown[]): void;\r\n info(message: string, ...args: unknown[]): void;\r\n warn(message: string, ...args: unknown[]): void;\r\n error(message: string, ...args: unknown[]): void;\r\n}\r\n\r\n/**\r\n * Determines if the current environment is production\r\n */\r\nfunction isProduction(): boolean {\r\n return typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\r\n}\r\n\r\n/**\r\n * Creates a formatted log prefix\r\n */\r\nfunction createPrefix(level: LogLevel): string {\r\n return `[@signiphi/pdf-signer] [${level.toUpperCase()}]`;\r\n}\r\n\r\n/**\r\n * Creates the logger instance with environment-based behavior\r\n */\r\nfunction createLogger(): Logger {\r\n const isProd = isProduction();\r\n\r\n return {\r\n debug(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('debug'), message, ...args);\r\n }\r\n },\r\n\r\n info(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.log(createPrefix('info'), message, ...args);\r\n }\r\n },\r\n\r\n warn(message: string, ...args: unknown[]): void {\r\n if (!isProd) {\r\n console.warn(createPrefix('warn'), message, ...args);\r\n }\r\n },\r\n\r\n error(message: string, ...args: unknown[]): void {\r\n // Errors are shown in both development and production\r\n console.error(createPrefix('error'), message, ...args);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Singleton logger instance\r\n */\r\nexport const logger = createLogger();\r\n\r\n\r\n\r\n","/**\r\n * PDF Validation Utilities\r\n * Common validation functions used across the package\r\n */\r\n\r\nimport type { FormField } from '../types';\r\n\r\n/**\r\n * Validate that bytes represent a valid PDF file\r\n * \r\n * Checks for:\r\n * - Non-empty bytes\r\n * - Valid PDF header (%PDF-)\r\n * \r\n * @param pdfBytes - The PDF bytes to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validatePdfBytes(pdfBytes);\r\n * if (!result.valid) {\r\n * console.error(result.error);\r\n * return;\r\n * }\r\n * ```\r\n */\r\nexport function validatePdfBytes(pdfBytes: Uint8Array): { \r\n valid: boolean; \r\n error?: string \r\n} {\r\n // Check for empty bytes\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return { \r\n valid: false, \r\n error: 'PDF bytes are empty' \r\n };\r\n }\r\n \r\n // Check for valid PDF header\r\n const header = new TextDecoder().decode(pdfBytes.slice(0, 12));\r\n if (!header.startsWith('%PDF-')) {\r\n return { \r\n valid: false, \r\n error: 'Invalid PDF format: Missing PDF header' \r\n };\r\n }\r\n \r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Check if a label is auto-generated (not user-typed)\r\n * \r\n * Auto-generated labels are simple type names like \"Text\", \"Signature\", etc.\r\n * These are default labels assigned by the form builder and should not be\r\n * displayed to users in the same way as custom labels.\r\n * \r\n * Works identically in both single-signer and multi-signer flows.\r\n * \r\n * @param label - The label to check\r\n * @returns true if the label is auto-generated, false if it's a custom user label\r\n * \r\n * @example\r\n * ```ts\r\n * isAutoGeneratedLabel('Signature') // true\r\n * isAutoGeneratedLabel('Sign here please') // false\r\n * isAutoGeneratedLabel('') // true\r\n * ```\r\n */\r\nexport function isAutoGeneratedLabel(label: string): boolean {\r\n if (!label || !label.trim()) return true;\r\n \r\n const autoLabels = [\r\n 'Signature',\r\n 'Initials',\r\n 'Date',\r\n 'Text',\r\n 'Checkbox',\r\n 'Dropdown',\r\n 'Option',\r\n 'Radio',\r\n ];\r\n \r\n return autoLabels.includes(label.trim());\r\n}\r\n\r\n/**\r\n * Validate field values object\r\n * \r\n * Checks that the values object is properly formatted and contains\r\n * only string values for field IDs.\r\n * \r\n * @param values - Field values to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFieldValues({ field1: 'value1', field2: 'value2' });\r\n * if (!result.valid) {\r\n * console.error('Validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFieldValues(values: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if values is an object\r\n if (!values || typeof values !== 'object') {\r\n errors.push('Field values must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each value is a string\r\n const valuesObj = values as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(valuesObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Field value for \"${key}\" must be a string, got ${typeof value}`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate signatures object\r\n * \r\n * Checks that signatures are properly formatted data URLs.\r\n * \r\n * @param signatures - Signatures to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateSignatures({\r\n * sig1: 'data:image/png;base64,iVBORw0KG...',\r\n * sig2: 'data:image/png;base64,iVBORw0KG...'\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Invalid signatures:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateSignatures(signatures: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if signatures is an object\r\n if (!signatures || typeof signatures !== 'object') {\r\n errors.push('Signatures must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n // Check each signature is a valid data URL\r\n const sigsObj = signatures as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(sigsObj)) {\r\n if (typeof value !== 'string') {\r\n errors.push(`Signature for \"${key}\" must be a string, got ${typeof value}`);\r\n continue;\r\n }\r\n \r\n // Validate data URL format\r\n if (!value.startsWith('data:image/')) {\r\n errors.push(`Signature for \"${key}\" must be a data URL starting with \"data:image/\"`);\r\n }\r\n \r\n // Check for base64 data\r\n const parts = value.split(',');\r\n if (parts.length !== 2 || !parts[1]) {\r\n errors.push(`Signature for \"${key}\" has invalid data URL format (missing base64 data)`);\r\n }\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate a form field definition\r\n * \r\n * Checks that a field has all required properties and they are valid.\r\n * \r\n * @param field - Form field to validate\r\n * @returns Validation result with valid flag and errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFormField({\r\n * id: 'field1',\r\n * name: 'firstName',\r\n * type: FormFieldType.TEXT,\r\n * label: 'First Name',\r\n * position: { x: 100, y: 200, width: 150, height: 30, page: 1 },\r\n * required: true\r\n * });\r\n * if (!result.valid) {\r\n * console.error('Field validation errors:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFormField(field: unknown): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n \r\n // Check if field is an object\r\n if (!field || typeof field !== 'object') {\r\n errors.push('Form field must be an object');\r\n return { valid: false, errors };\r\n }\r\n \r\n const f = field as Partial<FormField>;\r\n \r\n // Required properties\r\n if (!f.id || typeof f.id !== 'string') {\r\n errors.push('Field must have a valid \"id\" string');\r\n }\r\n \r\n if (!f.type || typeof f.type !== 'string') {\r\n errors.push('Field must have a valid \"type\" string');\r\n }\r\n \r\n if (!f.name || typeof f.name !== 'string') {\r\n errors.push('Field must have a valid \"name\" string');\r\n }\r\n \r\n if (!f.label || typeof f.label !== 'string') {\r\n errors.push('Field must have a valid \"label\" string');\r\n }\r\n \r\n // Validate position\r\n if (!f.position || typeof f.position !== 'object') {\r\n errors.push('Field must have a valid \"position\" object');\r\n } else {\r\n const pos = f.position;\r\n if (typeof pos.x !== 'number') {\r\n errors.push('Field position must have a numeric \"x\" coordinate');\r\n }\r\n if (typeof pos.y !== 'number') {\r\n errors.push('Field position must have a numeric \"y\" coordinate');\r\n }\r\n if (typeof pos.width !== 'number' || pos.width <= 0) {\r\n errors.push('Field position must have a positive \"width\"');\r\n }\r\n if (typeof pos.height !== 'number' || pos.height <= 0) {\r\n errors.push('Field position must have a positive \"height\"');\r\n }\r\n if (typeof pos.page !== 'number' || pos.page < 1) {\r\n errors.push('Field position must have a valid \"page\" number (1-indexed)');\r\n }\r\n }\r\n \r\n if (typeof f.required !== 'boolean') {\r\n errors.push('Field must have a boolean \"required\" property');\r\n }\r\n \r\n // Optional properties validation\r\n if (f.fontSize !== undefined && (typeof f.fontSize !== 'number' || f.fontSize < 8 || f.fontSize > 72)) {\r\n errors.push('Field fontSize must be a number between 8 and 72');\r\n }\r\n \r\n if (f.maxLength !== undefined && (typeof f.maxLength !== 'number' || f.maxLength <= 0)) {\r\n errors.push('Field maxLength must be a positive number');\r\n }\r\n \r\n if (f.options !== undefined && !Array.isArray(f.options)) {\r\n errors.push('Field options must be an array');\r\n }\r\n \r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate PDF URL format\r\n * \r\n * Accepts absolute URLs, relative paths, and data URLs.\r\n * \r\n * @param url - URL to validate\r\n * @returns Validation result with valid flag and optional error message\r\n * \r\n * @example\r\n * ```ts\r\n * // Absolute URLs\r\n * validatePdfUrl('https://example.com/document.pdf'); // valid\r\n * validatePdfUrl('http://localhost:3000/doc.pdf'); // valid\r\n * \r\n * // Relative paths\r\n * validatePdfUrl('/public/document.pdf'); // valid\r\n * validatePdfUrl('./document.pdf'); // valid\r\n * \r\n * // Data URLs and blobs\r\n * validatePdfUrl('data:application/pdf;base64,...'); // valid\r\n * validatePdfUrl('blob:http://localhost/...'); // valid\r\n * \r\n * // Local files\r\n * validatePdfUrl('file:///C:/path/to/file.pdf'); // valid\r\n * ```\r\n */\r\nexport function validatePdfUrl(url: unknown): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (typeof url !== 'string') {\r\n return { valid: false, error: 'URL must be a string' };\r\n }\r\n \r\n if (!url || url.trim().length === 0) {\r\n return { valid: false, error: 'URL cannot be empty' };\r\n }\r\n \r\n const trimmedUrl = url.trim();\r\n \r\n // Check for absolute URLs with protocols\r\n const validPrefixes = ['http://', 'https://', 'blob:', 'data:', 'file://'];\r\n const hasValidPrefix = validPrefixes.some(prefix => trimmedUrl.startsWith(prefix));\r\n \r\n if (hasValidPrefix) {\r\n return { valid: true };\r\n }\r\n \r\n // Allow relative paths (start with / or ./ or ../)\r\n if (trimmedUrl.startsWith('/') || trimmedUrl.startsWith('./') || trimmedUrl.startsWith('../')) {\r\n return { valid: true };\r\n }\r\n \r\n // Reject URLs that look malformed\r\n return {\r\n valid: false,\r\n error: 'URL must be an absolute URL (http://, https://, blob:, data:, file://) or a relative path (/, ./, ../)',\r\n };\r\n}\r\n\r\n","/**\r\n * PDF utility helper functions\r\n */\r\n\r\nimport { logger } from \"./logger\";\r\nimport { validatePdfBytes } from \"./pdf-validators\";\r\n\r\n/**\r\n * Create a blob URL from PDF bytes for preview\r\n */\r\nexport function createPdfBlobUrl(pdfBytes: Uint8Array): string {\r\n const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\n/**\r\n * Download PDF file\r\n */\r\nexport function downloadPdf(pdfBytes: Uint8Array, filename: string): void {\r\n const url = createPdfBlobUrl(pdfBytes);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = filename;\r\n a.click();\r\n URL.revokeObjectURL(url);\r\n}\r\n\r\n/**\r\n * Convert URL to PDF bytes\r\n * @param url - The URL to fetch the PDF from\r\n * @returns PDF bytes as Uint8Array\r\n */\r\nexport async function urlToPdfBytes(url: string): Promise<Uint8Array> {\r\n try {\r\n const response = await fetch(url);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch PDF: ${response.status} ${response.statusText}`);\r\n }\r\n\r\n const arrayBuffer = await response.arrayBuffer();\r\n\r\n // Create a new Uint8Array and copy the data to avoid detached ArrayBuffer issues\r\n const pdfBytes = new Uint8Array(arrayBuffer.byteLength);\r\n pdfBytes.set(new Uint8Array(arrayBuffer));\r\n\r\n // Validate that we have a PDF\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n return pdfBytes;\r\n } catch (error) {\r\n logger.error('Error fetching PDF from URL:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Validate that data is a valid PDF\r\n */\r\nexport function isValidPdf(pdfBytes: Uint8Array): boolean {\r\n const validation = validatePdfBytes(pdfBytes);\r\n return validation.valid;\r\n}\r\n\r\n/**\r\n * Convert base64 data URL to image bytes\r\n */\r\nexport function dataUrlToBytes(dataUrl: string): Uint8Array {\r\n const base64Data = dataUrl.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid data URL format: missing base64 data');\r\n }\r\n return Uint8Array.from(atob(base64Data), (c) => c.charCodeAt(0));\r\n}\r\n\r\n/**\r\n * Format field name for display\r\n */\r\nexport function formatFieldName(fieldName: string): string {\r\n return fieldName\r\n .replace(/[_-]/g, ' ')\r\n .replace(/\\b\\w/g, (l) => l.toUpperCase())\r\n .replace('Signature', '')\r\n .replace('Initials', '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Check if a field is a signature field\r\n */\r\nexport function isSignatureField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('signature');\r\n}\r\n\r\n/**\r\n * Check if a field is an initials field\r\n */\r\nexport function isInitialsField(fieldName: string): boolean {\r\n return fieldName.toLowerCase().includes('initials');\r\n}\r\n\r\n","/**\r\n * Lazy loader for pdf-lib\r\n * \r\n * This module provides a lazy loading mechanism for the pdf-lib library (~150KB).\r\n * By deferring the import until actually needed, we can significantly reduce\r\n * the initial bundle size for consumers who only view PDFs without filling forms.\r\n * \r\n * The pdf-lib library is only loaded when:\r\n * - fillPdf() is called\r\n * - combinePdfs() is called\r\n * - Other PDF manipulation functions are used\r\n */\r\n\r\n// Cache the promise to ensure we only import once\r\nlet pdfLibPromise: Promise<typeof import('pdf-lib')> | null = null;\r\n\r\n/**\r\n * Dynamically import pdf-lib library\r\n * \r\n * This function lazily loads pdf-lib only when needed. The import is cached\r\n * so subsequent calls return the same promise, avoiding multiple imports.\r\n * \r\n * @returns Promise resolving to the pdf-lib module\r\n * \r\n * @example\r\n * ```typescript\r\n * const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n * const pdfDoc = await PDFDocument.load(pdfBytes);\r\n * ```\r\n */\r\nexport async function loadPdfLib() {\r\n if (!pdfLibPromise) {\r\n pdfLibPromise = import('pdf-lib');\r\n }\r\n return pdfLibPromise;\r\n}\r\n\r\n/**\r\n * Check if pdf-lib has been loaded\r\n * \r\n * Useful for debugging and testing to verify lazy loading behavior.\r\n * \r\n * @returns true if pdf-lib has been loaded, false otherwise\r\n */\r\nexport function isPdfLibLoaded(): boolean {\r\n return pdfLibPromise !== null;\r\n}\r\n\r\n/**\r\n * Reset the pdf-lib cache (primarily for testing)\r\n * \r\n * This should only be used in test environments to reset state\r\n * between tests.\r\n * \r\n * @internal\r\n */\r\nexport function resetPdfLibCache(): void {\r\n pdfLibPromise = null;\r\n}\r\n\r\n","/**\r\n * Field Visibility Utilities\r\n * Core logic for determining which fields are visible/editable in multi-signer mode\r\n * \r\n * CRITICAL: This logic must work identically in both flows:\r\n * - Single-signer flow: isMultiSigner = false, all fields visible\r\n * - Multi-signer flow: isMultiSigner = true, filtered by assignment rules\r\n */\r\n\r\nimport type { EsignFormField, MultiSignerContext } from '../types';\r\n\r\n/**\r\n * Determine if a field should be visible to the current signer\r\n * \r\n * Implements the 5-rule visibility logic used throughout the application:\r\n * - Rule 1: Unassigned fields → only final signer sees them\r\n * - Rule 2: Direct assignment → show if assigned to current signer\r\n * - Rule 3: Recipients group → only primary signers (signOrder === 1)\r\n * - Rule 4: Signers group → only final signer\r\n * - Rule 5: Assigned to different signer → hide\r\n * \r\n * @param field - The form field to check\r\n * @param multiSignerContext - Multi-signer context with current signer info\r\n * @returns true if field should be visible, false if hidden\r\n * \r\n * @example Single-signer flow\r\n * ```ts\r\n * const context = { isMultiSigner: false, ... };\r\n * isFieldVisibleToSigner(anyField, context); // always returns true\r\n * ```\r\n * \r\n * @example Multi-signer flow\r\n * ```ts\r\n * const context = {\r\n * isMultiSigner: true,\r\n * currentSignerEmail: 'signer1@example.com',\r\n * isPrimarySigner: true,\r\n * isFinalSigner: false\r\n * };\r\n * \r\n * // Unassigned field - only final signer sees it\r\n * isFieldVisibleToSigner({ assignedSignerEmail: undefined, ... }, context); // false\r\n * \r\n * // Direct assignment to current signer\r\n * isFieldVisibleToSigner({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\r\n * \r\n * // Recipients group - primary signer sees it\r\n * isFieldVisibleToSigner({ assignedSignerEmail: 'recipients', ... }, context); // true\r\n * ```\r\n */\r\nexport function isFieldVisibleToSigner(\r\n field: EsignFormField,\r\n multiSignerContext: MultiSignerContext\r\n): boolean {\r\n // Single-signer mode: all fields are visible\r\n if (!multiSignerContext.isMultiSigner) {\r\n return true;\r\n }\r\n\r\n const { currentSignerEmail, isPrimarySigner, isFinalSigner } = multiSignerContext;\r\n\r\n // RULE 1: Unassigned fields - only final signer sees them\r\n if (!field.assignedSignerEmail) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 2: Direct assignment - show if assigned to current signer\r\n if (field.assignedSignerEmail === currentSignerEmail) {\r\n return true;\r\n }\r\n\r\n // RULE 3: Recipients group - only primary signers (signOrder === 1)\r\n if (field.assignedSignerEmail.includes('recipients')) {\r\n return isPrimarySigner;\r\n }\r\n\r\n // RULE 4: Signers group - only final signer\r\n if (field.assignedSignerEmail.includes('signers')) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 5: Assigned to different signer - hide\r\n return false;\r\n}\r\n\r\n/**\r\n * Filter an array of fields to only those visible to the current signer\r\n * \r\n * @param fields - All form fields\r\n * @param multiSignerContext - Multi-signer context\r\n * @returns Filtered array of visible fields\r\n * \r\n * @example\r\n * ```ts\r\n * const allFields = [...]; // 10 fields\r\n * const context = { isMultiSigner: true, isPrimarySigner: true, ... };\r\n * const visible = filterFieldsBySigner(allFields, context); // 5 fields (only primary signer's)\r\n * ```\r\n */\r\nexport function filterFieldsBySigner(\r\n fields: EsignFormField[],\r\n multiSignerContext: MultiSignerContext\r\n): EsignFormField[] {\r\n // Single-signer mode: return all fields\r\n if (!multiSignerContext.isMultiSigner) {\r\n return fields;\r\n }\r\n\r\n // Multi-signer mode: filter using visibility logic\r\n return fields.filter(field => isFieldVisibleToSigner(field, multiSignerContext));\r\n}\r\n\r\n/**\r\n * Determine if a field should be flattened (made non-editable) by the current signer\r\n * \r\n * Used during PDF submission to determine which fields to flatten.\r\n * In multi-signer mode, only flatten fields assigned to current signer.\r\n * In single-signer mode, flatten all fields.\r\n * \r\n * CRITICAL: This affects PDF flattening behavior - must preserve exact logic!\r\n * \r\n * @param field - The form field to check\r\n * @param multiSignerContext - Multi-signer context\r\n * @returns true if current signer should flatten this field\r\n * \r\n * @example Single-signer flow\r\n * ```ts\r\n * const context = { isMultiSigner: false, ... };\r\n * shouldFlattenField(anyField, context); // always returns true\r\n * ```\r\n * \r\n * @example Multi-signer flow\r\n * ```ts\r\n * const context = {\r\n * isMultiSigner: true,\r\n * currentSignerEmail: 'signer1@example.com',\r\n * isPrimarySigner: true,\r\n * isFinalSigner: false\r\n * };\r\n * \r\n * // Current signer's field - flatten it\r\n * shouldFlattenField({ assignedSignerEmail: 'signer1@example.com', ... }, context); // true\r\n * \r\n * // Different signer's field - don't flatten (keep editable for them)\r\n * shouldFlattenField({ assignedSignerEmail: 'signer2@example.com', ... }, context); // false\r\n * \r\n * // Unassigned field - only final signer flattens\r\n * shouldFlattenField({ assignedSignerEmail: undefined, ... }, context); // false (not final)\r\n * ```\r\n */\r\nexport function shouldFlattenField(\r\n field: EsignFormField,\r\n multiSignerContext: MultiSignerContext\r\n): boolean {\r\n // Single-signer mode: flatten all fields\r\n if (!multiSignerContext.isMultiSigner) {\r\n return true;\r\n }\r\n\r\n const { currentSignerEmail, isPrimarySigner, isFinalSigner } = multiSignerContext;\r\n\r\n // RULE 1: Unassigned fields - only final signer flattens them\r\n if (!field.assignedSignerEmail) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 2: Direct assignment - flatten if assigned to current signer\r\n if (field.assignedSignerEmail === currentSignerEmail) {\r\n return true;\r\n }\r\n\r\n // RULE 3: Recipients group - only primaries flatten them\r\n if (field.assignedSignerEmail.includes('recipients')) {\r\n return isPrimarySigner;\r\n }\r\n\r\n // RULE 4: Signers group - only final signer flattens them\r\n if (field.assignedSignerEmail.includes('signers')) {\r\n return isFinalSigner;\r\n }\r\n\r\n // RULE 5: Assigned to different signer - DON'T flatten (keep editable for them)\r\n return false;\r\n}\r\n\r\n","/**\r\n * PDF Widget Helper Utilities\r\n * Common utilities for working with PDF widgets and pages\r\n * \r\n * Used across pdf-manipulation.ts and pdf-viewer-filter.ts\r\n */\r\n\r\nimport type { PDFPage } from 'pdf-lib';\r\n\r\n/**\r\n * Extended type for PDF pages with ref property\r\n */\r\ninterface PDFPageWithRef {\r\n ref: unknown;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Find the page index for a given page reference\r\n * \r\n * This is a common pattern used when working with PDF widgets to determine\r\n * which page a widget belongs to by comparing page references.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * const widget = widgets[0];\r\n * const pageRef = widget.P?.();\r\n * const pageIndex = findPageIndexByRef(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * // Draw on the page\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexByRef(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) return -1;\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i] as unknown as PDFPageWithRef;\r\n if (page.ref === pageRef) {\r\n return i;\r\n }\r\n }\r\n \r\n return -1;\r\n}\r\n\r\n/**\r\n * Extended type for PDF widgets with rectangle and page methods\r\n */\r\nexport interface PDFWidgetWithExtensions {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number } | undefined;\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Get widget rectangle and its page\r\n * \r\n * Helper to extract both the rectangle coordinates and the page that a widget\r\n * belongs to in a single operation.\r\n * \r\n * @param widget - The PDF widget\r\n * @param pages - Array of PDF pages\r\n * @returns Object with rect, page, and pageIndex, or null if unable to determine\r\n * \r\n * @example\r\n * ```ts\r\n * for (const widget of widgets) {\r\n * const result = getWidgetRectangleAndPage(widget, pages);\r\n * if (result) {\r\n * const { rect, page, pageIndex } = result;\r\n * // Draw something at rect coordinates on page\r\n * page.drawRectangle({ x: rect.x, y: rect.y, ... });\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function getWidgetRectangleAndPage(\r\n widget: PDFWidgetWithExtensions,\r\n pages: PDFPage[]\r\n): {\r\n rect: { x: number; y: number; width: number; height: number };\r\n page: PDFPage;\r\n pageIndex: number;\r\n} | null {\r\n const rect = widget.getRectangle?.();\r\n if (!rect) return null;\r\n \r\n const pageRef = widget.P?.();\r\n if (!pageRef) return null;\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n if (pageIndex === -1) return null;\r\n \r\n const page = pages[pageIndex];\r\n if (!page) return null;\r\n \r\n return { rect, page, pageIndex };\r\n}\r\n\r\n/**\r\n * Find page index with fallback to single-page PDFs\r\n * \r\n * Same as findPageIndexByRef but with a fallback: if pageRef lookup fails\r\n * and there's only one page in the document, returns index 0.\r\n * \r\n * This is useful for label drawing where single-page PDFs might not have\r\n * proper page references but we can safely assume page 0.\r\n * \r\n * @param pages - Array of PDF pages\r\n * @param pageRef - The page reference to search for\r\n * @returns Page index (0-based), 0 if single-page PDF, or -1 if not found\r\n * \r\n * @example\r\n * ```ts\r\n * // Used in pdf-viewer-filter for label drawing\r\n * const pageIndex = findPageIndexWithFallback(pages, pageRef);\r\n * if (pageIndex >= 0) {\r\n * const page = pages[pageIndex];\r\n * page.drawText(label, ...);\r\n * }\r\n * ```\r\n */\r\nexport function findPageIndexWithFallback(\r\n pages: PDFPage[],\r\n pageRef: unknown\r\n): number {\r\n if (!pageRef) {\r\n // No page ref - fallback to page 0 if single-page PDF\r\n return pages.length === 1 ? 0 : -1;\r\n }\r\n \r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n \r\n // If not found but single-page PDF, assume page 0\r\n if (pageIndex === -1 && pages.length === 1) {\r\n return 0;\r\n }\r\n \r\n return pageIndex;\r\n}\r\n\r\n","/**\r\n * PDF Field Type Helper Utilities\r\n * Common utilities for detecting field types and extracting values\r\n * \r\n * Used across pdf-manipulation.ts for consistent field processing\r\n */\r\n\r\n/**\r\n * PDF form field type for operations\r\n */\r\ninterface PDFFormField {\r\n getName(): string;\r\n constructor: { name: string };\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n getSelected?(): string[];\r\n enableReadOnly?(): void;\r\n}\r\n\r\n/**\r\n * Detect the field type from a PDF field\r\n * \r\n * Maps pdf-lib's field constructor names to standardized type strings.\r\n * \r\n * @param field - The PDF form field\r\n * @returns Standardized field type string\r\n * \r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * // Returns: 'text', 'checkbox', 'dropdown', 'radiogroup', 'signature', etc.\r\n * ```\r\n */\r\nexport function detectFieldType(field: PDFFormField): string {\r\n const typeName = field.constructor.name;\r\n \r\n if (typeName === 'PDFTextField') {\r\n return 'text';\r\n } else if (typeName === 'PDFCheckBox') {\r\n return 'checkbox';\r\n } else if (typeName === 'PDFDropdown') {\r\n return 'dropdown';\r\n } else if (typeName === 'PDFOptionList') {\r\n return 'optionlist';\r\n } else if (typeName === 'PDFRadioGroup') {\r\n return 'radiogroup';\r\n } else if (typeName === 'PDFSignature') {\r\n return 'signature';\r\n }\r\n \r\n return 'unknown';\r\n}\r\n\r\n/**\r\n * Extract the current value from a PDF field based on its type\r\n * \r\n * Handles different field types appropriately:\r\n * - Text fields: getText()\r\n * - Checkboxes: isChecked() → 'true'/'false'\r\n * - Dropdowns: getSelected()[0]\r\n * - Radio groups: getSelected()[0]\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns The field value as a string, or empty string if no value\r\n * \r\n * @example\r\n * ```ts\r\n * const fieldType = detectFieldType(field);\r\n * const value = extractFieldValue(field, fieldType);\r\n * ```\r\n */\r\nexport function extractFieldValue(field: PDFFormField, fieldType: string): string {\r\n try {\r\n switch (fieldType) {\r\n case 'text':\r\n return field.getText?.() || '';\r\n \r\n case 'checkbox':\r\n return field.isChecked?.() ? 'true' : 'false';\r\n \r\n case 'dropdown':\r\n case 'optionlist':\r\n case 'radiogroup':\r\n return field.getSelected?.()?.[0] || '';\r\n \r\n default:\r\n return '';\r\n }\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Check if a field is required based on field metadata and name patterns\r\n * \r\n * Attempts to determine required status through:\r\n * 1. field.isRequired() method (if available)\r\n * 2. Field name patterns (signature, initials, required)\r\n * 3. Field type (signatures are always required)\r\n * \r\n * @param field - The PDF form field\r\n * @param fieldName - The field name\r\n * @param fieldType - The field type (from detectFieldType)\r\n * @returns true if field is required\r\n * \r\n * @example\r\n * ```ts\r\n * const isRequired = isRequiredField(field, 'signature_1', 'text');\r\n * // Returns: true (signature fields are required)\r\n * ```\r\n */\r\nexport function isRequiredField(\r\n field: PDFFormField,\r\n fieldName: string,\r\n fieldType: string\r\n): boolean {\r\n // Signature fields are always required\r\n if (fieldType === 'signature') {\r\n return true;\r\n }\r\n \r\n // Try the isRequired method if available\r\n try {\r\n if (field.isRequired?.()) {\r\n return true;\r\n }\r\n } catch {\r\n // isRequired() not available or threw error\r\n }\r\n \r\n // Check field name patterns\r\n if (\r\n fieldName.includes('signature') ||\r\n fieldName.includes('initials') ||\r\n fieldName.includes('required')\r\n ) {\r\n return true;\r\n }\r\n \r\n return false;\r\n}\r\n\r\n","/**\r\n * PDF Manipulation Utilities\r\n * Core utilities for PDF processing, page manipulation, and file combining\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { \r\n PdfPage, \r\n EsignFormField, \r\n FormFieldType, \r\n FormFieldPosition,\r\n MultiSignerContext \r\n} from '../types';\r\nimport { logger } from './logger';\r\nimport { validatePdfBytes, isAutoGeneratedLabel } from './pdf-validators';\r\nimport { isFieldVisibleToSigner, shouldFlattenField } from './field-visibility';\r\nimport { findPageIndexByRef, getWidgetRectangleAndPage, type PDFWidgetWithExtensions } from './pdf-widget-helpers';\r\nimport { detectFieldType, extractFieldValue, isRequiredField } from './pdf-field-type-helpers';\r\n\r\n// PDF.js worker is automatically configured by pdfjs-config module\r\n\r\n// Type definitions for PDF internal structures\r\ninterface PDFFieldWithAcro {\r\n getName(): string;\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n };\r\n constructor: { name: string };\r\n}\r\n\r\ninterface PDFWidget {\r\n getRectangle?: () => { x: number; y: number; width: number; height: number };\r\n P?: () => unknown;\r\n}\r\n\r\n/**\r\n * Convert PDF pages to images for rendering in the UI using PDF.js\r\n */\r\nexport async function pdfToImages(\r\n pdfBytes: Uint8Array,\r\n options?: { hideFormFields?: boolean }\r\n): Promise<PdfPage[]> {\r\n try {\r\n // Validate PDF bytes\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n logger.error('Invalid PDF:', validation.error);\r\n throw new Error(validation.error || 'Invalid PDF format');\r\n }\r\n\r\n // Load PDF with PDF.js\r\n const loadingTask = pdfjsLib.getDocument({\r\n data: pdfBytes,\r\n verbosity: 0,\r\n });\r\n const pdfDoc = await loadingTask.promise;\r\n\r\n const pages: PdfPage[] = [];\r\n\r\n // Try to load with pdf-lib for dimension comparison\r\n let pdfLibDoc = null;\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n pdfLibDoc = await PDFDocument.load(pdfBytes);\r\n } catch {\r\n // PDF.js dimensions will be used instead\r\n }\r\n\r\n for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {\r\n const page = await pdfDoc.getPage(pageNum);\r\n const viewport = page.getViewport({ scale: 2.0 });\r\n\r\n // Get actual PDF dimensions\r\n let pdfWidth = viewport.width / 2.0;\r\n let pdfHeight = viewport.height / 2.0;\r\n\r\n // Use pdf-lib dimensions if available for consistency\r\n if (pdfLibDoc) {\r\n try {\r\n const pdfLibPage = pdfLibDoc.getPage(pageNum - 1);\r\n pdfWidth = pdfLibPage.getWidth();\r\n pdfHeight = pdfLibPage.getHeight();\r\n } catch {\r\n // Use PDF.js dimensions as fallback\r\n }\r\n }\r\n\r\n // Create canvas at the scaled size for high quality rendering\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.height = viewport.height;\r\n canvas.width = viewport.width;\r\n\r\n // Render PDF page to canvas\r\n const hideFormFields = options?.hideFormFields ?? false;\r\n const renderContext: any = {\r\n canvasContext: context,\r\n viewport: viewport,\r\n renderInteractiveForms: !hideFormFields,\r\n ...(hideFormFields && {\r\n annotationMode: 0,\r\n renderAnnotations: false,\r\n renderForms: false,\r\n }),\r\n };\r\n\r\n await page.render(renderContext).promise;\r\n\r\n // Convert canvas to data URL\r\n const imageUrl = canvas.toDataURL('image/png');\r\n\r\n pages.push({\r\n pageNumber: pageNum,\r\n width: pdfWidth,\r\n height: pdfHeight,\r\n imageUrl,\r\n renderWidth: viewport.width,\r\n renderHeight: viewport.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error converting PDF to images with PDF.js:', error);\r\n return await fallbackPdfToImages(pdfBytes);\r\n }\r\n}\r\n\r\n/**\r\n * Fallback function to create placeholder images when PDF.js fails\r\n */\r\nasync function fallbackPdfToImages(pdfBytes: Uint8Array): Promise<PdfPage[]> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdf = await PDFDocument.load(pdfBytes);\r\n const pages: PdfPage[] = [];\r\n\r\n for (let i = 0; i < pdf.getPageCount(); i++) {\r\n const page = pdf.getPage(i);\r\n const { width, height } = page.getSize();\r\n \r\n // Create placeholder canvas\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n \r\n const scale = 1.5;\r\n canvas.width = width * scale;\r\n canvas.height = height * scale;\r\n \r\n // Draw placeholder\r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#6b7280';\r\n context.font = 'bold 24px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText(`Page ${i + 1}`, canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '16px system-ui';\r\n context.fillStyle = '#9ca3af';\r\n context.fillText('PDF preview not available', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n const imageUrl = canvas.toDataURL('image/png');\r\n \r\n pages.push({\r\n pageNumber: i + 1,\r\n width,\r\n height,\r\n imageUrl,\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n });\r\n }\r\n\r\n return pages;\r\n } catch (error) {\r\n logger.error('Error with pdf-lib fallback:', error);\r\n // Return single error page\r\n return [createErrorPage()];\r\n }\r\n}\r\n\r\n/**\r\n * Create an error page when all processing fails\r\n */\r\nfunction createErrorPage(): PdfPage {\r\n const canvas = document.createElement('canvas');\r\n const context = canvas.getContext('2d')!;\r\n canvas.width = 600;\r\n canvas.height = 800;\r\n \r\n context.fillStyle = '#ffffff';\r\n context.fillRect(0, 0, canvas.width, canvas.height);\r\n context.strokeStyle = '#e5e7eb';\r\n context.lineWidth = 2;\r\n context.strokeRect(0, 0, canvas.width, canvas.height);\r\n context.fillStyle = '#ef4444';\r\n context.font = 'bold 20px system-ui';\r\n context.textAlign = 'center';\r\n context.fillText('PDF Processing Error', canvas.width / 2, canvas.height / 2 - 20);\r\n context.font = '14px system-ui';\r\n context.fillStyle = '#6b7280';\r\n context.fillText('Unable to process the uploaded PDF file', canvas.width / 2, canvas.height / 2 + 20);\r\n \r\n return {\r\n pageNumber: 1,\r\n width: 600,\r\n height: 800,\r\n imageUrl: canvas.toDataURL('image/png'),\r\n renderWidth: canvas.width,\r\n renderHeight: canvas.height,\r\n };\r\n}\r\n\r\n// Type definitions for PDF form field operations\r\ninterface PDFFormField {\r\n getName(): string;\r\n constructor: { name: string };\r\n getText?(): string;\r\n setText?(text: string): void;\r\n isRequired?(): boolean;\r\n isChecked?(): boolean;\r\n getSelected?(): string[];\r\n enableReadOnly?(): void;\r\n}\r\n\r\ninterface PDFFormFieldWithAcro extends PDFFormField {\r\n acroField: {\r\n getWidgets(): unknown[];\r\n removeWidget(index: number): void;\r\n };\r\n}\r\n\r\ninterface PDFDict {\r\n get(key: unknown): unknown;\r\n delete(key: unknown): void;\r\n}\r\n\r\n/**\r\n * Remove all existing form fields from a PDF using robust widget cleanup\r\n * @param pdfBytes - The PDF bytes\r\n * @param stripAllAnnotations - If true, removes all annotations from pages (more aggressive cleanup)\r\n * @returns The PDF bytes with all form fields removed\r\n */\r\nexport async function removeAllFormFields(pdfBytes: Uint8Array, stripAllAnnotations = false): Promise<Uint8Array> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return pdfBytes;\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n \r\n if (stripAllAnnotations) {\r\n // More aggressive approach: strip all annotations from all pages\r\n const pages = pdfDoc.getPages();\r\n \r\n for (let i = 0; i < pages.length; i++) {\r\n const page = pages[i];\r\n \r\n try {\r\n // Access the page's annotation array\r\n const pageRef = (page as any).ref;\r\n const pageDictObj = pdfDoc.context.lookup(pageRef);\r\n \r\n if (pageDictObj) {\r\n const pageDict = pageDictObj as unknown as PDFDict;\r\n \r\n if (pageDict && pageDict.get && pageDict.delete) {\r\n const annotsRef = pageDict.get((pdfDoc.context as any).obj('Annots'));\r\n \r\n if (annotsRef) {\r\n pageDict.delete((pdfDoc.context as any).obj('Annots'));\r\n }\r\n } else {\r\n }\r\n } else {\r\n }\r\n } catch (pageError) {\r\n }\r\n }\r\n } else {\r\n // Robust widget-based removal approach\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return pdfBytes;\r\n }\r\n \r\n // Remove all fields using robust widget cleanup\r\n for (const field of fields) {\r\n try {\r\n const acroField = (field as unknown as PDFFormFieldWithAcro).acroField;\r\n if (acroField && typeof acroField.getWidgets === 'function') {\r\n let widgets = acroField.getWidgets();\r\n \r\n // Remove widgets one by one with safety counter\r\n let safetyCounter = 0;\r\n const maxIterations = widgets.length + 5;\r\n \r\n while (widgets.length > 0 && safetyCounter < maxIterations) {\r\n try {\r\n const widgetIndex = widgets.length - 1;\r\n acroField.removeWidget(widgetIndex);\r\n widgets = acroField.getWidgets();\r\n } catch (widgetError) {\r\n break;\r\n }\r\n safetyCounter++;\r\n }\r\n \r\n if (safetyCounter >= maxIterations) {\r\n }\r\n }\r\n \r\n form.removeField(field as any);\r\n } catch (error) {\r\n \r\n try {\r\n form.removeField(field as any);\r\n } catch (fallbackError) {\r\n }\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n if (remainingFields.length > 0) {\r\n }\r\n }\r\n \r\n const updatedPdfBytes = await pdfDoc.save();\r\n return updatedPdfBytes;\r\n } catch (error) {\r\n logger.error('Error removing form fields from PDF:', error);\r\n return pdfBytes;\r\n }\r\n}\r\n\r\n/**\r\n * Read existing PDF form fields and their properties\r\n */\r\nexport async function readPdfFormFields(pdfBytes: Uint8Array): Promise<{\r\n name: string;\r\n type: string;\r\n required: boolean;\r\n value?: string;\r\n}[]> {\r\n try {\r\n // Validate PDF data first\r\n const validation = validatePdfBytes(pdfBytes);\r\n if (!validation.valid) {\r\n return [];\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n if (fields.length === 0) {\r\n return [];\r\n }\r\n \r\n const formFields = fields.map(field => {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n const required = isRequiredField(pdfField, fieldName, fieldType);\r\n \r\n return {\r\n name: fieldName,\r\n type: fieldType,\r\n required,\r\n value\r\n };\r\n } catch (fieldError) {\r\n // Fallback to defaults on error\r\n return {\r\n name: fieldName,\r\n type: 'text',\r\n required: false,\r\n value: ''\r\n };\r\n }\r\n });\r\n \r\n return formFields;\r\n } catch (error) {\r\n logger.error('Error reading PDF form fields:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Read current PDF form field values (including user-filled data)\r\n */\r\nexport async function readCurrentPdfFormValues(pdfBytes: Uint8Array): Promise<Record<string, string>> {\r\n try {\r\n if (!pdfBytes || pdfBytes.length === 0) {\r\n return {};\r\n }\r\n \r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n \r\n const currentValues: Record<string, string> = {};\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const pdfField = field as unknown as PDFFormField;\r\n \r\n try {\r\n // Use centralized field type detection and value extraction\r\n const fieldType = detectFieldType(pdfField);\r\n const value = extractFieldValue(pdfField, fieldType);\r\n \r\n currentValues[fieldName] = value;\r\n } catch (fieldError) {\r\n currentValues[fieldName] = '';\r\n }\r\n }\r\n \r\n return currentValues;\r\n } catch (error) {\r\n logger.error('Error reading current PDF form values:', error);\r\n return {};\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against provided values\r\n * In multi-signer mode, only validates fields visible to the current signer\r\n */\r\nexport async function validatePdfFormFields(\r\n pdfBytes: Uint8Array,\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>,\r\n extractedFields?: EsignFormField[], // Pass extracted fields to know which are visible\r\n multiSignerContext?: MultiSignerContext // Pass context to filter validation\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n \r\n for (const field of pdfFormFields) {\r\n if (field.required) {\r\n // In multi-signer mode, only validate fields visible to current signer\r\n if (multiSignerContext?.isMultiSigner && extractedFields) {\r\n const extractedField = extractedFields.find(f => f.name === field.name);\r\n if (!extractedField) {\r\n // Field not in extractedFields means it's not visible to current signer\r\n continue;\r\n }\r\n }\r\n \r\n let hasValue = false;\r\n const fieldValue = fieldValues[field.name];\r\n const signatureValue = signatures[field.name];\r\n const mainSignature = signatures['signature_field_main'];\r\n const mainInitials = signatures['initials_field_main'] || fieldValues['initials_field_main'];\r\n \r\n if (field.name.includes('signature') || field.type === 'signature') {\r\n hasValue = !!(signatureValue || fieldValue || mainSignature);\r\n } else if (field.name.includes('initials')) {\r\n hasValue = !!(signatureValue || fieldValue || mainInitials);\r\n } else {\r\n hasValue = !!(fieldValue || field.value);\r\n }\r\n \r\n if (!hasValue) {\r\n let friendlyName = field.name.replace(/[_-]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\r\n \r\n if (field.name.includes('signature')) {\r\n friendlyName = 'Signature';\r\n } else if (field.name.includes('initials')) {\r\n friendlyName = 'Initials';\r\n }\r\n \r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n \r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating PDF form fields:', error);\r\n return ['Unable to validate form fields. Please ensure all required fields are completed.'];\r\n }\r\n}\r\n\r\n/**\r\n * Validate PDF form fields against current form state\r\n */\r\nexport async function validateCurrentPdfState(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {}\r\n): Promise<string[]> {\r\n try {\r\n const pdfFormFields = await readPdfFormFields(pdfBytes);\r\n const currentValues = await readCurrentPdfFormValues(pdfBytes);\r\n const errors: string[] = [];\r\n \r\n for (const field of pdfFormFields) {\r\n const isSignatureField = field.name.includes('signature') && field.type === 'text';\r\n const isInitialsField = field.name.includes('initials') && field.type === 'text';\r\n \r\n if (field.required || isSignatureField || isInitialsField) {\r\n let hasValue = false;\r\n const currentValue = currentValues[field.name] || '';\r\n \r\n if (isSignatureField) {\r\n hasValue = !!signatures[field.name];\r\n } else if (isInitialsField) {\r\n hasValue = !!signatures[field.name] || !!(formFieldValues[field.name]?.trim()) || currentValue.trim() !== '';\r\n } else {\r\n hasValue = currentValue.trim() !== '';\r\n }\r\n \r\n if (!hasValue) {\r\n let friendlyName = field.name.replace(/[_-]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\r\n \r\n if (field.name.includes('signature')) {\r\n friendlyName = 'Signature';\r\n } else if (field.name.includes('initials')) {\r\n friendlyName = 'Initials';\r\n }\r\n \r\n errors.push(`${friendlyName} is required`);\r\n }\r\n }\r\n }\r\n \r\n return errors;\r\n } catch (error) {\r\n logger.error('Error validating current PDF state:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Fill PDF with signature images and form field values, then flatten the form\r\n * @param pdfBytes - The PDF bytes\r\n * @param signatures - The signature data URLs (field name -> base64 PNG)\r\n * @param formFieldValues - The form field values to fill\r\n * @returns The filled and flattened PDF bytes\r\n */\r\nexport async function fillPdfWithSignatures(\r\n pdfBytes: Uint8Array,\r\n signatures: Record<string, string>,\r\n formFieldValues: Record<string, string> = {},\r\n currentSignerEmail?: string,\r\n extractedFormFields?: EsignFormField[],\r\n metadata?: { submissionId?: string; documentId?: string; author?: string; signerEmail?: string; signerInitials?: string; createdAt?: Date },\r\n auditTrail?: { userAgent?: string; screenResolution?: string; timezone?: string; language?: string; platform?: string; ipAddress?: string; geolocation?: { latitude: number; longitude: number; accuracy?: number } },\r\n multiSignerContext?: { isMultiSigner: boolean; currentSigner: any; currentSignerEmail: string; isPrimarySigner: boolean; isFinalSigner: boolean }\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const pages = pdfDoc.getPages();\r\n \r\n // Get field positions and page numbers\r\n const { pageMap: fieldPageMap, positionMap: fieldPositionMap } = await getFieldPageNumbers(pdfBytes);\r\n \r\n // STEP 1: Fill all text form fields\r\n \r\n const fields = form.getFields();\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldValue = formFieldValues[fieldName];\r\n \r\n if (!fieldValue) {\r\n // Log missing values for radio fields to diagnose\r\n if (fieldName.includes('radio')) {\r\n }\r\n continue;\r\n }\r\n \r\n try {\r\n const fieldTypeName = field.constructor.name;\r\n \r\n // Handle text fields\r\n if (fieldTypeName === 'PDFTextField' || fieldTypeName === 'PDFTextField2') {\r\n const textField = field as any;\r\n textField.setText?.(fieldValue);\r\n }\r\n // Handle checkbox fields\r\n else if (fieldTypeName === 'PDFCheckBox' || fieldTypeName === 'PDFCheckBox2') {\r\n const checkBox = field as any;\r\n if (fieldValue === 'true' || fieldValue === 'Yes' || fieldValue === 'checked' || fieldValue === 'On') {\r\n checkBox.check?.();\r\n } else {\r\n checkBox.uncheck?.();\r\n }\r\n }\r\n // Handle radio group fields\r\n else if (fieldTypeName === 'PDFRadioGroup' || fieldTypeName === 'PDFRadioGroup2') {\r\n const radioGroup = field as any;\r\n \r\n // Skip invalid values (boolean strings from checkbox-like behavior)\r\n if (fieldValue === 'true' || fieldValue === 'false') {\r\n continue;\r\n }\r\n \r\n // Handle __RADIO_OPTION_INDEX_ pattern\r\n const idxMatch = fieldValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (idxMatch && idxMatch[1]) {\r\n const selectedIndex = parseInt(idxMatch[1], 10);\r\n const options = radioGroup.getOptions?.() || [];\r\n if (selectedIndex >= 0 && selectedIndex < options.length) {\r\n radioGroup.select?.(options[selectedIndex]);\r\n }\r\n } else {\r\n // Try to use the value directly if it's a valid option\r\n const options = radioGroup.getOptions?.() || [];\r\n if (options.includes(fieldValue)) {\r\n radioGroup.select?.(fieldValue);\r\n } else {\r\n }\r\n }\r\n }\r\n // Handle dropdown fields\r\n else if (fieldTypeName === 'PDFDropdown' || fieldTypeName === 'PDFDropdown2') {\r\n const dropdown = field as any;\r\n dropdown.select?.(fieldValue);\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error setting field \"${fieldName}\":`, fieldError);\r\n }\r\n }\r\n\r\n // Update form field appearances to ensure radio button selections render correctly\r\n // This is critical for radio buttons to display properly in PDF viewers\r\n // Fix based on dm-web-frontend commit aafc786 (Oct 29, 2025)\r\n try {\r\n form.updateFieldAppearances();\r\n } catch (appearanceError) {\r\n // Some PDFs may not support this operation - fail gracefully\r\n }\r\n\r\n // STEP 2: Apply signature images to ALL signature fields\r\n const mainSignatureData = signatures['signature_field_main'];\r\n if (mainSignatureData && mainSignatureData.trim()) {\r\n \r\n // Find ALL signature field names (excluding text_ prefix and non-signature fields)\r\n // Match dockmaster patterns including '_es_:signer:signature' for esign integration\r\n const signatureFieldNames = [\r\n 'signature', 'Signature', 'SIGNATURE',\r\n 'sign', 'Sign', 'SIGN',\r\n '_es_:signer:signature'\r\n ];\r\n let foundSignatureFields = Object.keys(fieldPageMap).filter(fieldName => {\r\n const hasSignaturePattern = signatureFieldNames.some(pattern => \r\n fieldName.toLowerCase().includes(pattern.toLowerCase())\r\n );\r\n const isNotTextField = !fieldName.toLowerCase().startsWith('text_');\r\n return hasSignaturePattern && isNotTextField;\r\n });\r\n \r\n // CRITICAL: Filter to only ACTUAL signature fields, not checkbox/radio/dropdown\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n const currentSignerSignatureFields = foundSignatureFields.filter(fieldName => {\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName);\r\n if (!fieldInfo) {\r\n return false;\r\n }\r\n \r\n // CRITICAL FIX: Only process ACTUAL signature fields, NOT initials\r\n // Signature images should ONLY be applied to signature fields\r\n // Initials are handled separately as text (not images)\r\n // Fix based on dm-web-frontend commit 30895b5 (Oct 29, 2025)\r\n const isActualSignatureField = (fieldInfo.type === 'signature' ||\r\n fieldName.toLowerCase().includes('signature'))\r\n && !fieldName.toLowerCase().includes('initials'); // Explicitly exclude initials\r\n\r\n if (!isActualSignatureField) {\r\n return false;\r\n }\r\n \r\n // Use centralized visibility logic for multi-signer and single-signer modes\r\n const isVisible = multiSignerContext \r\n ? isFieldVisibleToSigner(fieldInfo, multiSignerContext)\r\n : true; // Single signer mode: all fields visible\r\n \r\n return isVisible;\r\n });\r\n foundSignatureFields = currentSignerSignatureFields;\r\n }\r\n \r\n \r\n if (foundSignatureFields.length > 0) {\r\n try {\r\n // Detect image format with binary signature detection\r\n let signatureImage;\r\n if (mainSignatureData.includes('data:image/png')) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } else if (mainSignatureData.includes('data:image/jpeg') || mainSignatureData.includes('data:image/jpg')) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } else {\r\n // Fallback: detect by binary signature\r\n const base64Data = mainSignatureData.split(',')[1];\r\n if (!base64Data) {\r\n throw new Error('Invalid signature data format: missing base64 data');\r\n }\r\n const binaryData = atob(base64Data);\r\n \r\n // Check PNG signature (first 8 bytes: 89 50 4E 47 0D 0A 1A 0A)\r\n if (binaryData.charCodeAt(0) === 0x89 && \r\n binaryData.charCodeAt(1) === 0x50 && \r\n binaryData.charCodeAt(2) === 0x4E && \r\n binaryData.charCodeAt(3) === 0x47) {\r\n signatureImage = await pdfDoc.embedPng(mainSignatureData);\r\n } \r\n // Check JPEG signature (first 3 bytes: FF D8 FF)\r\n else if (binaryData.charCodeAt(0) === 0xFF && \r\n binaryData.charCodeAt(1) === 0xD8 && \r\n binaryData.charCodeAt(2) === 0xFF) {\r\n signatureImage = await pdfDoc.embedJpg(mainSignatureData);\r\n } \r\n else {\r\n throw new Error('Unsupported image format. Please use PNG or JPEG.');\r\n }\r\n }\r\n \r\n // Draw signature images using EXACT field coordinates\r\n for (const fieldName of foundSignatureFields) {\r\n \r\n const pageNumber = fieldPageMap[fieldName];\r\n \r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1]; // Convert to 0-based index\r\n if (!page) continue;\r\n \r\n // Get EXACT field position from the map\r\n const fieldPosition = fieldPositionMap[fieldName];\r\n \r\n if (fieldPosition) {\r\n // Use EXACT field coordinates (NO CENTERING)\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const width = Math.max(fieldPosition.width, 80);\r\n const height = Math.max(fieldPosition.height, 30);\r\n \r\n // Scale signature to fit the field\r\n const signatureDims = signatureImage.scaleToFit(width - 4, height - 4);\r\n \r\n // FIXED POSITIONING: Use exact field coordinates\r\n const finalX = x;\r\n const finalY = y;\r\n \r\n \r\n page.drawImage(signatureImage, {\r\n x: finalX,\r\n y: finalY,\r\n width: signatureDims.width,\r\n height: signatureDims.height,\r\n });\r\n \r\n } else {\r\n }\r\n } else {\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying signatures:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 3: Apply initials to ALL initials fields\r\n const mainInitialsData = formFieldValues['initials_field_main'];\r\n if (mainInitialsData && mainInitialsData.trim()) {\r\n \r\n const initialsFieldNames = ['initials', 'Initials', 'INITIALS'];\r\n let foundInitialsFields = Object.keys(fieldPageMap).filter(fieldName =>\r\n initialsFieldNames.some(pattern => fieldName.toLowerCase().includes(pattern.toLowerCase()))\r\n );\r\n \r\n // Filter by signer if needed\r\n if (extractedFormFields && extractedFormFields.length > 0) {\r\n foundInitialsFields = foundInitialsFields.filter(fieldName => {\r\n const fieldInfo = extractedFormFields.find(f => f.name === fieldName);\r\n if (!fieldInfo) return false;\r\n \r\n const isActualInitialsField = fieldInfo.type === 'initials' || \r\n fieldName.toLowerCase().includes('initials');\r\n if (!isActualInitialsField) return false;\r\n \r\n return !fieldInfo.assignedSignerEmail || fieldInfo.assignedSignerEmail === currentSignerEmail;\r\n });\r\n }\r\n \r\n \r\n if (foundInitialsFields.length > 0) {\r\n try {\r\n const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold);\r\n \r\n for (const fieldName of foundInitialsFields) {\r\n const pageNumber = fieldPageMap[fieldName];\r\n if (pageNumber && pageNumber <= pages.length) {\r\n const page = pages[pageNumber - 1];\r\n if (!page) continue;\r\n \r\n const fieldPosition = fieldPositionMap[fieldName];\r\n if (fieldPosition) {\r\n const x = fieldPosition.x;\r\n const y = fieldPosition.y;\r\n const height = Math.max(fieldPosition.height, 20);\r\n \r\n const fontSize = Math.min(height * 0.7, 14);\r\n \r\n // EXACT positioning (no centering)\r\n const finalX = x + 2;\r\n const finalY = y + (height - fontSize) / 2;\r\n \r\n page.drawText(mainInitialsData, {\r\n x: finalX,\r\n y: finalY,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n }\r\n } catch (error) {\r\n logger.error('Error applying initials:', error);\r\n }\r\n }\r\n }\r\n \r\n // STEP 4: Flatten form fields based on multi-signer mode\r\n \r\n const allFormFields = form.getFields();\r\n \r\n let fieldsToFlatten;\r\n \r\n if (multiSignerContext?.isMultiSigner) {\r\n // PARTIAL FLATTENING: Only flatten current signer's fields (Dockmaster logic lines 2500-2526)\r\n \r\n fieldsToFlatten = allFormFields.filter(f => {\r\n const fieldName = f.getName();\r\n \r\n if (!extractedFormFields || extractedFormFields.length === 0) {\r\n return true; // Flatten all if no field info\r\n }\r\n \r\n const fieldInfo = extractedFormFields.find(fi => fi.name === fieldName);\r\n if (!fieldInfo) {\r\n return true; // Flatten unknown fields\r\n }\r\n \r\n // Use centralized flattening logic\r\n return shouldFlattenField(fieldInfo, multiSignerContext);\r\n });\r\n } else {\r\n // COMPLETE FLATTENING: Flatten all fields (single signer mode)\r\n fieldsToFlatten = allFormFields;\r\n }\r\n \r\n // Helper interfaces for widget access\r\n interface PDFFieldWithAcro {\r\n acroField?: {\r\n getWidgets?: () => PDFWidget[];\r\n dict?: any;\r\n };\r\n }\r\n \r\n let flattenedCount = 0;\r\n \r\n for (const field of fieldsToFlatten) {\r\n const fieldName = field.getName();\r\n const fieldType = field.constructor.name;\r\n \r\n try {\r\n // Get user entered value\r\n const userEnteredValue = formFieldValues[fieldName];\r\n \r\n // Check if this is a signature/initials field\r\n const isSignatureField = fieldName.toLowerCase().includes('signature') || fieldType.includes('Signature');\r\n const isInitialsField = fieldName.toLowerCase().includes('initials') || fieldType.includes('Initials');\r\n \r\n if (isSignatureField || isInitialsField) {\r\n // Signature/initials fields were already drawn in STEP 2/3, just remove the field\r\n form.removeField(field);\r\n flattenedCount++;\r\n continue;\r\n }\r\n \r\n // Get field widgets for drawing\r\n const fieldWithWidgets = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithWidgets.acroField?.getWidgets?.() || [];\r\n \r\n // Handle different field types - draw their content\r\n if (fieldType === 'PDFCheckBox' || fieldType === 'PDFCheckBox2') {\r\n // Checkbox field - draw checkbox with checkmark if checked\r\n const stringValue = String(userEnteredValue || '');\r\n const isChecked = stringValue === 'true' || stringValue === 'Yes' || \r\n stringValue === 'On' || stringValue === 'checked';\r\n \r\n \r\n if (isChecked) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw checkbox border\r\n const checkboxSize = Math.min(rect.width, rect.height) * 0.6;\r\n const checkboxX = rect.x + (rect.width - checkboxSize) / 2;\r\n const checkboxY = rect.y + (rect.height - checkboxSize) / 2;\r\n \r\n page.drawRectangle({\r\n x: checkboxX,\r\n y: checkboxY,\r\n width: checkboxSize,\r\n height: checkboxSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n \r\n // Draw checkmark using \"X\"\r\n const checkSize = checkboxSize * 0.6;\r\n const textWidth = checkSize * 0.6;\r\n const textHeight = checkSize * 0.8;\r\n \r\n page.drawText('X', {\r\n x: checkboxX + (checkboxSize - textWidth) / 2,\r\n y: checkboxY + (checkboxSize - textHeight) / 2 + textHeight * 0.2,\r\n size: checkSize,\r\n font: await pdfDoc.embedFont(StandardFonts.HelveticaBold),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n } else if (fieldType === 'PDFRadioGroup' || fieldType === 'PDFRadioGroup2') {\r\n // Radio group field - draw all radio buttons, fill the selected one\r\n let selectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n // Handle __RADIO_OPTION_INDEX_ pattern\r\n if (selectedValue.startsWith('__RADIO_OPTION_INDEX_')) {\r\n const indexMatch = selectedValue.match(/__RADIO_OPTION_INDEX_(\\d+)__/);\r\n if (indexMatch && indexMatch[1]) {\r\n selectedValue = indexMatch[1];\r\n }\r\n }\r\n \r\n \r\n // Determine selected index\r\n let selectedIndex = -1;\r\n if (selectedValue === 'Option A') selectedIndex = 0;\r\n else if (selectedValue === 'Option B') selectedIndex = 1;\r\n else if (selectedValue === 'Option C') selectedIndex = 2;\r\n else if (/^\\d+$/.test(selectedValue)) {\r\n selectedIndex = parseInt(selectedValue, 10);\r\n }\r\n \r\n // Get field info for labels and options\r\n const fieldInfo = extractedFormFields?.find(f => f.name === fieldName);\r\n const labelFont = await pdfDoc.embedFont('Helvetica-Bold');\r\n const drawnGroupLabels = new Set<string>();\r\n const drawnOptionLabels = new Set<string>();\r\n \r\n // Draw borders for ALL radio buttons\r\n for (let i = 0; i < widgets.length; i++) {\r\n const widget = widgets[i];\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page, pageIndex } = result;\r\n \r\n // Draw radio GROUP label (once, above first widget)\r\n // Only draw if it's a user-typed custom label (not auto-generated)\r\n if (i === 0 && fieldInfo?.label && fieldInfo.label.trim() && !isAutoGeneratedLabel(fieldInfo.label)) {\r\n const groupLabelKey = `${pageIndex}-${fieldName}-grouplabel`;\r\n if (!drawnGroupLabels.has(groupLabelKey)) {\r\n const labelY = rect.y + rect.height + 3;\r\n page.drawText(fieldInfo.label, {\r\n x: rect.x,\r\n y: labelY,\r\n size: 8,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnGroupLabels.add(groupLabelKey);\r\n }\r\n } else if (i === 0 && isAutoGeneratedLabel(fieldInfo?.label || '')) {\r\n }\r\n \r\n // Draw radio button border (circle)\r\n const radioSize = Math.min(rect.width, rect.height) * 0.5;\r\n const radioX = rect.x + (rect.width - radioSize) / 2;\r\n const radioY = rect.y + (rect.height - radioSize) / 2;\r\n \r\n page.drawCircle({\r\n x: radioX + radioSize / 2,\r\n y: radioY + radioSize / 2,\r\n size: radioSize,\r\n borderColor: rgb(0, 0, 0),\r\n borderWidth: 1,\r\n });\r\n \r\n // Draw filled circle ONLY for selected option\r\n if (i === selectedIndex) {\r\n const circleSize = radioSize * 0.5;\r\n page.drawCircle({\r\n x: radioX + radioSize / 2,\r\n y: radioY + radioSize / 2,\r\n size: circleSize,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n \r\n // Draw option text next to each radio button\r\n if (fieldInfo?.options && fieldInfo.options.length > i) {\r\n const optionText = fieldInfo.options[i];\r\n const optionKey = `${pageIndex}-${fieldName}-opt-${i}`;\r\n \r\n if (optionText && !drawnOptionLabels.has(optionKey)) {\r\n page.drawText(optionText, {\r\n x: rect.x + rect.width + 4,\r\n y: rect.y + (rect.height - 8) / 2,\r\n size: 8,\r\n font: labelFont,\r\n color: rgb(0, 0, 0),\r\n });\r\n drawnOptionLabels.add(optionKey);\r\n }\r\n }\r\n }\r\n \r\n if (fieldInfo?.options) {\r\n }\r\n } else if (fieldType === 'PDFDropdown' || fieldType === 'PDFDropdown2') {\r\n // Dropdown field - draw the selected value\r\n const selectedValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n \r\n if (selectedValue && selectedValue.trim()) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw the selected value\r\n page.drawText(selectedValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: 10,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n } else {\r\n // Text field or other field types - draw the field value\r\n const fieldValue = userEnteredValue ? String(userEnteredValue) : '';\r\n \r\n \r\n if (fieldValue && fieldValue.trim()) {\r\n for (const widget of widgets) {\r\n const result = getWidgetRectangleAndPage(widget as unknown as PDFWidgetWithExtensions, pages);\r\n if (!result) continue;\r\n \r\n const { rect, page } = result;\r\n \r\n // Draw the field value\r\n page.drawText(fieldValue, {\r\n x: rect.x + 2,\r\n y: rect.y + 2,\r\n size: 10,\r\n font: await pdfDoc.embedFont(StandardFonts.Helvetica),\r\n color: rgb(0, 0, 0),\r\n });\r\n \r\n }\r\n }\r\n }\r\n \r\n // Remove the field to flatten it\r\n form.removeField(field);\r\n flattenedCount++;\r\n } catch (error) {\r\n }\r\n }\r\n \r\n const remainingFields = form.getFields();\r\n \r\n // Verify flattening worked\r\n if (multiSignerContext?.isMultiSigner) {\r\n // MULTI-SIGNER MODE: Remaining fields are EXPECTED (for other signers)\r\n const expectedRemainingCount = allFormFields.length - fieldsToFlatten.length;\r\n if (remainingFields.length === expectedRemainingCount) {\r\n } else {\r\n }\r\n } else {\r\n // SINGLE-SIGNER MODE: All fields should be flattened\r\n if (remainingFields.length > 0) {\r\n logger.error(`MANUAL FLATTENING INCOMPLETE: ${remainingFields.length} fields still exist!`);\r\n logger.error(`Remaining fields:`, remainingFields.map(f => f.getName()));\r\n \r\n // Try basic flattening as final fallback (only in single-signer mode)\r\n try {\r\n form.flatten();\r\n const finalRemainingFields = form.getFields();\r\n \r\n if (finalRemainingFields.length > 0) {\r\n logger.error(`ALL FLATTENING METHODS FAILED: ${finalRemainingFields.length} fields still exist!`);\r\n logger.error(`Final remaining fields:`, finalRemainingFields.map(f => f.getName()));\r\n }\r\n } catch (fallbackError) {\r\n logger.error('Fallback flattening failed:', fallbackError);\r\n }\r\n } else {\r\n }\r\n }\r\n \r\n // STEP 6: Set document metadata for tracking and compliance\r\n try {\r\n // Set document metadata based on submission data\r\n // Set Title (with default if not provided)\r\n const documentTitle = metadata?.documentId \r\n ? `Document ID: ${metadata.documentId}`\r\n : 'Signed Document';\r\n pdfDoc.setTitle(documentTitle);\r\n \r\n // Set Subject (with default if not provided)\r\n const documentSubject = metadata?.submissionId\r\n ? `Submission ID: ${metadata.submissionId}`\r\n : metadata?.signerEmail\r\n ? `Signed by ${metadata.signerEmail}`\r\n : 'Digitally Signed Document';\r\n pdfDoc.setSubject(documentSubject);\r\n \r\n // Set Author (with default if not provided)\r\n const documentAuthor = metadata?.author || metadata?.signerEmail || 'Unknown';\r\n pdfDoc.setAuthor(documentAuthor);\r\n \r\n pdfDoc.setProducer('Created by signiphi (https://signiphi.ai/)');\r\n \r\n if (metadata?.signerEmail) {\r\n pdfDoc.setCreator(`Signer: ${metadata.signerEmail}`);\r\n }\r\n \r\n // Set creation date from submission\r\n if (metadata?.createdAt) {\r\n pdfDoc.setCreationDate(metadata.createdAt);\r\n }\r\n \r\n // Set current date as modification date\r\n pdfDoc.setModificationDate(new Date());\r\n \r\n // Set keywords for searchability and tracking\r\n const keywords: string[] = [];\r\n \r\n // Add signer email if available\r\n if (metadata?.signerEmail) {\r\n keywords.push(metadata.signerEmail);\r\n }\r\n \r\n // Add initials to metadata if available\r\n if (metadata?.signerInitials && metadata.signerInitials.trim()) {\r\n keywords.push(`Initials:${metadata.signerInitials.trim()}`);\r\n }\r\n \r\n // Add audit trail data for compliance and forensics\r\n if (auditTrail) {\r\n try {\r\n // Device/Browser information\r\n if (auditTrail.userAgent) {\r\n keywords.push(`UserAgent:${auditTrail.userAgent}`);\r\n }\r\n \r\n // Screen resolution as device identifier\r\n if (auditTrail.screenResolution) {\r\n keywords.push(`Screen:${auditTrail.screenResolution}`);\r\n }\r\n \r\n // Timezone\r\n if (auditTrail.timezone) {\r\n keywords.push(`Timezone:${auditTrail.timezone}`);\r\n }\r\n \r\n // Language settings\r\n if (auditTrail.language) {\r\n keywords.push(`Language:${auditTrail.language}`);\r\n }\r\n \r\n // Platform information\r\n if (auditTrail.platform) {\r\n keywords.push(`Platform:${auditTrail.platform}`);\r\n }\r\n \r\n // IP address\r\n if (auditTrail.ipAddress) {\r\n keywords.push(`IP:${auditTrail.ipAddress}`);\r\n }\r\n \r\n // Geolocation data\r\n if (auditTrail.geolocation) {\r\n const { latitude, longitude, accuracy } = auditTrail.geolocation;\r\n const lat = latitude.toFixed(4);\r\n const lon = longitude.toFixed(4);\r\n keywords.push(`Location:${lat},${lon}`);\r\n \r\n // Add accuracy if available\r\n if (accuracy !== undefined) {\r\n keywords.push(`LocationAccuracy:${accuracy}m`);\r\n }\r\n }\r\n } catch (auditError) {\r\n logger.warn('⚠️ Error adding audit trail to keywords:', auditError)\r\n }\r\n }\r\n \r\n if (keywords.length > 0) {\r\n pdfDoc.setKeywords(keywords);\r\n }\r\n } catch (error) {\r\n logger.error('Failed to set document metadata:', error);\r\n }\r\n \r\n const finalPdfBytes = await pdfDoc.save();\r\n return finalPdfBytes;\r\n } catch (error) {\r\n logger.error('Error filling PDF with signatures:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Fill form fields and replace signature/initials with actual signature images\r\n * This is used when fields are rendered as overlays on the PDF\r\n * @param pdfBytes - The PDF bytes\r\n * @param formFields - The form fields with their positions\r\n * @param fieldValues - The field values to fill\r\n * @param signatures - The signature images (base64 data URLs)\r\n * @returns The filled PDF bytes\r\n */\r\nexport async function fillFormFieldsWithSignatures(\r\n pdfBytes: Uint8Array,\r\n formFields: EsignFormField[],\r\n fieldValues: Record<string, string>,\r\n signatures: Record<string, string>\r\n): Promise<Uint8Array> {\r\n try {\r\n const { PDFDocument, rgb, StandardFonts } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const pages = pdfDoc.getPages();\r\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\r\n\r\n for (const field of formFields) {\r\n const pageIndex = field.position.page - 1;\r\n \r\n if (pageIndex < 0 || pageIndex >= pages.length) {\r\n continue;\r\n }\r\n\r\n const page = pages[pageIndex];\r\n if (!page) continue;\r\n const { height: pageHeight } = page.getSize();\r\n\r\n // Convert coordinates from top-left (UI) to bottom-left (PDF)\r\n const pdfX = field.position.x;\r\n const pdfY = pageHeight - field.position.y - field.position.height;\r\n\r\n try {\r\n switch (field.type) {\r\n case FormFieldType.TEXT: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n // Use field fontSize if specified, otherwise calculate based on field height\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72 \r\n ? field.fontSize \r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2, // Small padding\r\n y: pdfY + (field.position.height - fontSize) / 2, // Center vertically\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4, // Leave padding\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DATE: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n const fontSize = field.fontSize && field.fontSize >= 8 && field.fontSize <= 72 \r\n ? field.fontSize \r\n : Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.CHECKBOX: {\r\n const value = fieldValues[field.id] || '';\r\n if (value === 'true') {\r\n // Draw a checkmark\r\n const checkSize = Math.min(field.position.width, field.position.height) * 0.6;\r\n const checkX = pdfX + (field.position.width - checkSize) / 2;\r\n const checkY = pdfY + (field.position.height - checkSize) / 2;\r\n \r\n page.drawText('✓', {\r\n x: checkX,\r\n y: checkY,\r\n size: checkSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.SIGNATURE: {\r\n const signatureDataUrl = signatures[field.id];\r\n if (signatureDataUrl) {\r\n // Convert base64 data URL to image bytes\r\n const base64Data = signatureDataUrl.split(',')[1];\r\n if (!base64Data) {\r\n logger.error('Invalid signature data URL format for field:', field.id);\r\n break;\r\n }\r\n const imageBytes = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));\r\n \r\n // Embed the image\r\n const image = await pdfDoc.embedPng(imageBytes);\r\n \r\n // Calculate dimensions to fit within the field while maintaining aspect ratio\r\n const imageSize = image.size();\r\n const fieldAspectRatio = field.position.width / field.position.height;\r\n const imageAspectRatio = imageSize.width / imageSize.height;\r\n \r\n let drawWidth = field.position.width;\r\n let drawHeight = field.position.height;\r\n \r\n if (imageAspectRatio > fieldAspectRatio) {\r\n // Image is wider than field - fit to width\r\n drawHeight = drawWidth / imageAspectRatio;\r\n } else {\r\n // Image is taller than field - fit to height\r\n drawWidth = drawHeight * imageAspectRatio;\r\n }\r\n \r\n // Center the image within the field\r\n const imageX = pdfX + (field.position.width - drawWidth) / 2;\r\n const imageY = pdfY + (field.position.height - drawHeight) / 2;\r\n \r\n // Draw the image\r\n page.drawImage(image, {\r\n x: imageX,\r\n y: imageY,\r\n width: drawWidth,\r\n height: drawHeight,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.INITIALS: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n // Use a cursive font for initials\r\n const fontSize = Math.min(18, field.position.height * 0.8);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n case FormFieldType.DROPDOWN: {\r\n const value = fieldValues[field.id] || '';\r\n if (value) {\r\n const fontSize = Math.min(12, field.position.height * 0.6);\r\n page.drawText(value, {\r\n x: pdfX + 2,\r\n y: pdfY + (field.position.height - fontSize) / 2,\r\n size: fontSize,\r\n font: font,\r\n color: rgb(0, 0, 0),\r\n maxWidth: field.position.width - 4,\r\n });\r\n }\r\n break;\r\n }\r\n\r\n default:\r\n break;\r\n }\r\n } catch (fieldError) {\r\n logger.error(`Error processing field ${field.name}:`, fieldError);\r\n }\r\n }\r\n\r\n return await pdfDoc.save();\r\n} catch (error) {\r\n logger.error('Error filling form fields:', error);\r\n throw error;\r\n}\r\n}\r\n\r\n/**\r\n * Extract field positions and page numbers from a PDF document\r\n * Returns maps for field name -> page number and field name -> position\r\n */\r\nexport async function getFieldPageNumbers(\r\n pdfBytes: Uint8Array\r\n): Promise<{\r\n pageMap: Record<string, number>;\r\n positionMap: Record<string, FormFieldPosition>;\r\n}> {\r\n try {\r\n const { PDFDocument } = await loadPdfLib();\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const pages = pdfDoc.getPages();\r\n\r\n const pageMap: Record<string, number> = {};\r\n const positionMap: Record<string, FormFieldPosition> = {};\r\n\r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n const fieldWithAcro = field as unknown as PDFFieldWithAcro;\r\n const widgets = fieldWithAcro.acroField?.getWidgets?.() ?? [];\r\n\r\n if (widgets.length > 0) {\r\n // Use the first widget to determine page and position\r\n const widget = widgets[0];\r\n if (!widget) continue;\r\n const rect = widget.getRectangle?.();\r\n const pageRef = widget.P?.();\r\n\r\n if (rect && pageRef) {\r\n // Find which page this widget belongs to\r\n const pageIndex = findPageIndexByRef(pages, pageRef);\r\n\r\n if (pageIndex !== -1) {\r\n const pageNumber = pageIndex + 1; // Convert to 1-indexed\r\n pageMap[fieldName] = pageNumber;\r\n\r\n // Store position information\r\n positionMap[fieldName] = {\r\n x: rect.x,\r\n y: rect.y,\r\n width: rect.width,\r\n height: rect.height,\r\n page: pageNumber,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { pageMap, positionMap };\r\n} catch (error) {\r\n logger.error('Error extracting field page numbers:', error);\r\n return { pageMap: {}, positionMap: {} };\r\n}\r\n}\r\n\r\n","/**\r\n * PDF Form Field Extraction Utilities\r\n * Functions for extracting and decoding form fields from PDFs\r\n */\r\n\r\nimport { loadPdfLib } from './pdf-lib-loader';\r\nimport { EsignFormField, FormFieldType } from '../types';\r\nimport { logger } from './logger';\r\nimport type { PDFName as PDFNameType } from 'pdf-lib';\r\n\r\n// Module-level variable to hold PDFName after pdf-lib is loaded\r\nlet PDFName: typeof PDFNameType;\r\n\r\n// Type definitions for PDF field extensions\r\ninterface PDFFieldWithExtensions {\r\n acroField?: {\r\n getWidgets?: () => Array<{\r\n hasFlag?: (flag: number) => boolean;\r\n }>;\r\n dict?: {\r\n get: (key: unknown) => unknown;\r\n };\r\n };\r\n getOptions?: () => string[];\r\n isRequired?: () => boolean;\r\n constructor: { name: string };\r\n getName(): string;\r\n}\r\n\r\n/**\r\n * Extract visible form fields from a PDF document\r\n * @param pdfBytes - The PDF bytes to extract fields from\r\n * @param currentSignerEmail - Optional email of the current signer (for multi-signer filtering)\r\n * @returns Array of extracted form fields\r\n */\r\nexport async function extractVisibleFormFields(\r\n pdfBytes: Uint8Array,\r\n currentSignerEmail?: string\r\n): Promise<EsignFormField[]> {\r\n try {\r\n const pdfLibModule = await loadPdfLib();\r\n const { PDFDocument, AnnotationFlags, PDFName: PDFNameClass } = pdfLibModule;\r\n PDFName = PDFNameClass; // Assign to module-level variable for use in helper functions\r\n const pdfDoc = await PDFDocument.load(pdfBytes);\r\n const form = pdfDoc.getForm();\r\n const fields = form.getFields();\r\n const visibleFields: EsignFormField[] = [];\r\n let hasAnyInitialsFields = false; // For single-signer mode\r\n let hasInitialsFieldsForCurrentSigner = false; // For multi-signer mode\r\n \r\n for (const field of fields) {\r\n const fieldName = field.getName();\r\n \r\n // Get widgets for this field to check visibility\r\n const fieldWithExtensions = field as unknown as PDFFieldWithExtensions;\r\n const widgets = fieldWithExtensions.acroField?.getWidgets?.() ?? [];\r\n \r\n let isVisible = true;\r\n \r\n // Check if any widget is hidden using AnnotationFlags\r\n for (const widget of widgets) {\r\n const hasHiddenFlag = widget.hasFlag?.(AnnotationFlags.Hidden) ?? false;\r\n const hasNoViewFlag = widget.hasFlag?.(AnnotationFlags.NoView) ?? false;\r\n \r\n if (hasHiddenFlag || hasNoViewFlag) {\r\n isVisible = false;\r\n break;\r\n }\r\n }\r\n \r\n if (isVisible) {\r\n // Decode field name to extract label, assigned signer, and placeholder\r\n const decodedInfo = decodeFieldName(fieldName);\r\n \r\n // NOTE: We do NOT filter by signer during extraction in multi-signer mode!\r\n // All fields must be extracted so that:\r\n // 1. useFieldFiltering can properly filter fields for display\r\n // 2. Partial flattening knows about all fields (flatten current signer's fields only)\r\n // 3. PDF viewer filtering can remove non-visible fields from the rendered PDF\r\n // The filtering happens at the display level via useFieldFiltering hook.\r\n \r\n // Determine field type based on pdf-lib field type\r\n let fieldType = FormFieldType.TEXT;\r\n const fieldTypeName = field.constructor.name;\r\n \r\n // CRITICAL: Properly detect signature/initials fields (not checkboxes/radios)\r\n // More defensive than dockmaster - explicitly exclude CheckBox/Radio to prevent false positives\r\n const isActualSignatureField = fieldTypeName.includes('Signature') || \r\n (decodedInfo.decodedFieldName.toLowerCase().includes('signature') && \r\n !fieldTypeName.includes('CheckBox') && \r\n !fieldTypeName.includes('Radio'));\r\n const isActualInitialsField = decodedInfo.decodedFieldName.toLowerCase().includes('initials') &&\r\n !fieldTypeName.includes('CheckBox') && \r\n !fieldTypeName.includes('Radio');\r\n \r\n if (isActualSignatureField) {\r\n fieldType = FormFieldType.SIGNATURE;\r\n } else if (isActualInitialsField) {\r\n fieldType = FormFieldType.INITIALS;\r\n \r\n // Track initials fields for proper sidebar display logic:\r\n // - hasAnyInitialsFields: ANY initials exist (for single-signer fallback)\r\n // - hasInitialsFieldsForCurrentSigner: initials assigned to this signer (for multi-signer)\r\n hasAnyInitialsFields = true;\r\n \r\n // Check if this initials field is assigned to current signer\r\n if (currentSignerEmail && decodedInfo.assignedSignerEmail === currentSignerEmail) {\r\n hasInitialsFieldsForCurrentSigner = true;\r\n }\r\n } else if (decodedInfo.decodedFieldName.toLowerCase().includes('date')) {\r\n fieldType = FormFieldType.DATE;\r\n } else if (fieldTypeName.includes('CheckBox')) {\r\n fieldType = FormFieldType.CHECKBOX;\r\n } else if (fieldTypeName.toLowerCase().includes('dropdown')) {\r\n fieldType = FormFieldType.DROPDOWN;\r\n } else if (fieldTypeName.includes('Radio')) {\r\n fieldType = FormFieldType.RADIO;\r\n }\r\n \r\n // Generate display label - Try TU metadata first, then decoded label, then fallback\r\n let displayLabel = decodedInfo.displayLabel;\r\n \r\n // PRIORITY 1: Try to get label from TU (tooltip/user-visible) metadata\r\n if (!displayLabel || !displayLabel.trim()) {\r\n try {\r\n const tuLabel = extractTULabel(fieldWithExtensions);\r\n if (tuLabel && tuLabel.trim()) {\r\n displayLabel = tuLabel;\r\n }\r\n } catch (tuError) {\r\n }\r\n }\r\n \r\n // PRIORITY 2: Use decoded label from field name encoding\r\n // (Already set above from decodedInfo)\r\n \r\n // PRIORITY 3: Generate fallback label from field name\r\n if (!displayLabel || !displayLabel.trim()) {\r\n displayLabel = generateFallbackLabel(decodedInfo.decodedFieldName, fieldType);\r\n }\r\n \r\n // Create EsignFormField\r\n const esignField: EsignFormField = {\r\n id: fieldName, // Keep original encoded name as ID\r\n name: fieldName, // Keep original for removal later\r\n type: fieldType,\r\n label: displayLabel, // Use friendly label for display\r\n position: { x: 0, y: 0, width: 100, height: 30, page: 1 }, // Default position\r\n required: fieldWithExtensions.isRequired?.() ?? false,\r\n placeholder: decodedInfo.fieldPlaceholder || '', // Use extracted placeholder\r\n assignedSignerEmail: decodedInfo.assignedSignerEmail, // Add assigned signer\r\n };\r\n \r\n // Add options for dropdown and radio fields\r\n if (fieldType === FormFieldType.DROPDOWN || fieldType === FormFieldType.RADIO) {\r\n try {\r\n const options = fieldWithExtensions.getOptions?.() ?? [];\r\n esignField.options = options;\r\n if (options.length > 0) {\r\n }\r\n } catch (error) {\r\n logger.warn('Error extracting options for field:', error);\r\n }\r\n }\r\n \r\n visibleFields.push(esignField);\r\n }\r\n }\r\n \r\n // Add main signature and initials fields at the BEGINNING\r\n // Only create if PDF has these fields OR if explicitly required\r\n const mainFields: EsignFormField[] = [];\r\n \r\n // ALWAYS create signature field - it's attached to the document on submission regardless\r\n mainFields.push({\r\n id: 'signature_field_main',\r\n name: 'signature_field_main',\r\n type: FormFieldType.SIGNATURE,\r\n label: 'Your Signature (will be applied to all signature fields)',\r\n position: { x: 0, y: 0, width: 200, height: 60, page: 1 },\r\n required: true,\r\n placeholder: 'Draw or upload your signature',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n \r\n // Create initials field based on mode:\r\n // - Multi-signer mode (currentSignerEmail provided AND matches assigned fields):\r\n // Only create if current signer has initials fields assigned to them\r\n // - Single-signer mode (currentSignerEmail not provided OR doesn't match any assignments):\r\n // Create if ANY initials fields exist in the PDF\r\n // When present, always make it required\r\n const shouldCreateInitialsField = hasInitialsFieldsForCurrentSigner || \r\n (hasAnyInitialsFields && !currentSignerEmail);\r\n \r\n if (shouldCreateInitialsField) {\r\n if (hasInitialsFieldsForCurrentSigner) {\r\n } else {\r\n }\r\n \r\n mainFields.push({\r\n id: 'initials_field_main',\r\n name: 'initials_field_main',\r\n type: FormFieldType.INITIALS,\r\n label: 'Your Initials (will be applied to all initials fields)',\r\n position: { x: 0, y: 0, width: 100, height: 40, page: 1 },\r\n required: true,\r\n placeholder: 'Enter your initials',\r\n assignedSignerEmail: currentSignerEmail,\r\n });\r\n }\r\n \r\n // Return main fields FIRST, then other fields\r\n return [...mainFields, ...visibleFields];\r\n } catch (error) {\r\n logger.error('Error extracting visible form fields from PDF:', error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Decode a field name to extract label, signer email, and placeholder\r\n * Format: fieldName__LABEL__labelText__SIGNER__email__PLACEHOLDER__placeholderText\r\n */\r\nexport function decodeFieldName(fieldName: string): {\r\n decodedFieldName: string;\r\n displayLabel: string;\r\n assignedSignerEmail?: string;\r\n fieldPlaceholder: string;\r\n} {\r\n let decodedFieldName = fieldName;\r\n let displayLabel = '';\r\n let assignedSignerEmail: string | undefined = undefined;\r\n let fieldPlaceholder = '';\r\n \r\n // Extract label if present\r\n if (fieldName.includes('__LABEL__')) {\r\n const labelMarkerIndex = fieldName.indexOf('__LABEL__');\r\n decodedFieldName = fieldName.substring(0, labelMarkerIndex);\r\n \r\n const afterLabel = fieldName.substring(labelMarkerIndex + 9); // Skip \"__LABEL__\"\r\n \r\n // Extract signer email if present\r\n if (afterLabel.includes('__SIGNER__')) {\r\n const signerMarkerIndex = afterLabel.indexOf('__SIGNER__');\r\n displayLabel = afterLabel.substring(0, signerMarkerIndex);\r\n const afterSigner = afterLabel.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (afterLabel.includes('__PLACEHOLDER__')) {\r\n // Label and placeholder but no signer\r\n const placeholderMarkerIndex = afterLabel.indexOf('__PLACEHOLDER__');\r\n displayLabel = afterLabel.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterLabel.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n displayLabel = afterLabel;\r\n }\r\n } else if (fieldName.includes('__SIGNER__')) {\r\n // Old format without label\r\n const signerMarkerIndex = fieldName.indexOf('__SIGNER__');\r\n decodedFieldName = fieldName.substring(0, signerMarkerIndex);\r\n const afterSigner = fieldName.substring(signerMarkerIndex + 10); // Skip \"__SIGNER__\"\r\n \r\n // Extract placeholder if present\r\n if (afterSigner.includes('__PLACEHOLDER__')) {\r\n const placeholderMarkerIndex = afterSigner.indexOf('__PLACEHOLDER__');\r\n assignedSignerEmail = afterSigner.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = afterSigner.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n } else {\r\n assignedSignerEmail = afterSigner;\r\n }\r\n } else if (fieldName.includes('__PLACEHOLDER__')) {\r\n // Only placeholder present\r\n const placeholderMarkerIndex = fieldName.indexOf('__PLACEHOLDER__');\r\n decodedFieldName = fieldName.substring(0, placeholderMarkerIndex);\r\n fieldPlaceholder = fieldName.substring(placeholderMarkerIndex + 15); // Skip \"__PLACEHOLDER__\"\r\n }\r\n \r\n return {\r\n decodedFieldName,\r\n displayLabel,\r\n assignedSignerEmail,\r\n fieldPlaceholder,\r\n };\r\n}\r\n\r\n/**\r\n * Generate a fallback label from a decoded field name\r\n */\r\nexport function generateFallbackLabel(decodedFieldName: string, fieldType: FormFieldType): string {\r\n let displayLabel = decodedFieldName;\r\n \r\n // Remove \"_signature\", \"_initials\", \"_date\" suffixes added by pdf-lib\r\n displayLabel = displayLabel.replace(/_signature$/i, '').replace(/_initials$/i, '').replace(/_date$/i, '');\r\n \r\n // Handle different naming patterns:\r\n // 1. Pure timestamp fields: \"text_1234567890\" → \"Text\"\r\n // 2. Descriptive fields: \"text_Primary_1\" → \"Text Primary\"\r\n // 3. Custom fields: \"customer_name\" → \"Customer Name\"\r\n \r\n if (/^(text|signature|initials|date)_\\d+$/i.test(displayLabel)) {\r\n // Pattern 1: Pure timestamp fields\r\n if (fieldType === FormFieldType.SIGNATURE) return 'Signature';\r\n if (fieldType === FormFieldType.INITIALS) return 'Initials';\r\n if (fieldType === FormFieldType.DATE) return 'Date';\r\n if (fieldType === FormFieldType.TEXT) return 'Text';\r\n if (fieldType === FormFieldType.CHECKBOX) return 'Checkbox';\r\n if (fieldType === FormFieldType.DROPDOWN) return 'Dropdown';\r\n if (fieldType === FormFieldType.RADIO) return 'Option';\r\n } else {\r\n // Pattern 2 & 3: Convert underscores to spaces, remove trailing numbers, capitalize\r\n displayLabel = displayLabel\r\n .replace(/_/g, ' ') // Convert underscores to spaces\r\n .replace(/\\s+\\d+$/g, '') // Remove trailing numbers (e.g., \" 1\")\r\n .trim()\r\n .split(' ') // Split into words\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word\r\n .join(' ');\r\n }\r\n \r\n return displayLabel;\r\n}\r\n\r\n/**\r\n * Extract label from TU (tooltip) metadata in PDF field\r\n * @param field - The PDF field with extensions\r\n * @returns The extracted label or empty string\r\n */\r\nfunction extractTULabel(field: PDFFieldWithExtensions): string {\r\n try {\r\n if (!field.acroField?.dict) {\r\n return '';\r\n }\r\n \r\n const tuLabel = field.acroField.dict.get(PDFName.of('TU'));\r\n if (!tuLabel) {\r\n return '';\r\n }\r\n \r\n // PDFString has a decodeText() method or toString()\r\n const tuValue = tuLabel.toString();\r\n if (!tuValue || !tuValue.trim()) {\r\n return '';\r\n }\r\n \r\n // Handle PDF string encoding - extract content between parentheses or angle brackets\r\n // PDF strings are encoded as \"(text)\" or \"<hex>\"\r\n if (tuValue.startsWith('(') || tuValue.startsWith('<')) {\r\n const match = tuValue.match(/^\\((.*)\\)$/) || tuValue.match(/^<(.*)>$/);\r\n if (match && match[1]) {\r\n return match[1];\r\n }\r\n }\r\n \r\n // If no special encoding, return as-is\r\n return tuValue;\r\n } catch (error) {\r\n return '';\r\n }\r\n}\r\n\r\n","/**\r\n * PDF.js Configuration Provider\r\n * Manages global configuration for PDF.js worker and viewer paths\r\n * \r\n * COMPATIBILITY NOTE: This module is designed to work with both Vite and Next.js/webpack.\r\n * The worker source URL is computed lazily to avoid issues with webpack's handling of import.meta.\r\n */\r\n\r\nimport type { PdfJsConfig } from '../types';\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\n/**\r\n * CDN paths for PDF.js (exported for manual fallback configuration)\r\n * Note: CDN URLs may cause CORS issues in some environments\r\n * \r\n * @example\r\n * // Manually configure CDN (not recommended)\r\n * setPdfJsConfig({ \r\n * viewerBasePath: CDN_VIEWER,\r\n * workerSrc: CDN_WORKER \r\n * });\r\n */\r\nexport const CDN_WORKER = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@5.3.93/build/pdf.worker.mjs';\r\nexport const CDN_VIEWER = 'https://mozilla.github.io/pdf.js';\r\n\r\n/**\r\n * Internal flag to track if worker source has been computed\r\n */\r\nlet _workerSrcComputed = false;\r\nlet _cachedWorkerSrc: string | null = null;\r\n\r\n/**\r\n * Get the worker source URL (computed lazily to avoid webpack import.meta issues)\r\n * - In browser environments, the bundler resolves the URL from node_modules\r\n * - The worker is loaded from the user's bundle (no CORS issues)\r\n * \r\n * This function uses lazy evaluation to avoid triggering webpack's\r\n * \"Critical dependency: Accessing import.meta directly is unsupported\" warning\r\n * at module load time.\r\n */\r\nfunction getDefaultWorkerSrc(): string {\r\n // Return cached value if already computed\r\n if (_workerSrcComputed && _cachedWorkerSrc !== null) {\r\n return _cachedWorkerSrc;\r\n }\r\n\r\n // Default fallback\r\n let workerSrc = '/pdfjs/build/pdf.worker.mjs';\r\n\r\n // Only attempt import.meta resolution in browser environment\r\n if (typeof window !== 'undefined' && typeof URL !== 'undefined') {\r\n try {\r\n // Check if import.meta is available (ESM environment like Vite)\r\n // Use indirect access to avoid webpack static analysis issues\r\n const meta = (function() {\r\n try {\r\n // This pattern avoids webpack's direct import.meta detection\r\n return new Function('return import.meta')();\r\n } catch {\r\n return null;\r\n }\r\n })();\r\n\r\n if (meta && meta.url) {\r\n workerSrc = new URL('pdfjs-dist/build/pdf.worker.mjs', meta.url).href;\r\n }\r\n } catch {\r\n // Fallback for environments that don't support import.meta.url (Next.js/webpack)\r\n // Use the public path fallback\r\n }\r\n }\r\n\r\n // Cache the result\r\n _workerSrcComputed = true;\r\n _cachedWorkerSrc = workerSrc;\r\n\r\n return workerSrc;\r\n}\r\n\r\n/**\r\n * Default configuration for PDF.js\r\n * \r\n * By default, the package uses:\r\n * - Worker: Loaded from node_modules (bundled by your build tool)\r\n * - Viewer: Served from /pdfjs/ (automatically copied by postinstall)\r\n * \r\n * The postinstall script automatically copies viewer files to your public/pdfjs/ directory.\r\n * If setup fails, run: npx signiphi-setup\r\n * \r\n * NOTE: workerSrc is initialized to null and computed lazily on first access\r\n * to ensure compatibility with Next.js/webpack environments.\r\n */\r\nlet globalConfig: Required<PdfJsConfig> = {\r\n viewerBasePath: '/pdfjs',\r\n workerSrc: '', // Lazy-initialized below\r\n};\r\n\r\n// Flag to track if globalConfig.workerSrc has been initialized\r\nlet _configInitialized = false;\r\n\r\n/**\r\n * Ensure config is initialized (called lazily)\r\n */\r\nfunction ensureConfigInitialized(): void {\r\n if (!_configInitialized) {\r\n globalConfig.workerSrc = getDefaultWorkerSrc();\r\n _configInitialized = true;\r\n \r\n // Initialize PDF.js worker in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Set PDF.js configuration\r\n * @param config - Partial configuration to merge with defaults\r\n * \r\n * @example\r\n * // Use self-hosted PDF.js files\r\n * setPdfJsConfig({ viewerBasePath: '/pdfjs' });\r\n * \r\n * @example\r\n * // Use custom CDN\r\n * setPdfJsConfig({ \r\n * viewerBasePath: 'https://my-cdn.com/pdfjs',\r\n * workerSrc: 'https://my-cdn.com/pdfjs/build/pdf.worker.mjs'\r\n * });\r\n */\r\nexport function setPdfJsConfig(config: Partial<PdfJsConfig>): void {\r\n // Ensure default config is computed first\r\n ensureConfigInitialized();\r\n \r\n if (config.viewerBasePath !== undefined) {\r\n globalConfig.viewerBasePath = config.viewerBasePath;\r\n }\r\n \r\n if (config.workerSrc !== undefined) {\r\n globalConfig.workerSrc = config.workerSrc;\r\n } else if (config.viewerBasePath !== undefined) {\r\n // Auto-update workerSrc based on viewerBasePath\r\n globalConfig.workerSrc = `${config.viewerBasePath}/build/pdf.worker.mjs`;\r\n }\r\n\r\n // Update PDF.js worker if in browser environment\r\n if (typeof window !== 'undefined') {\r\n pdfjsLib.GlobalWorkerOptions.workerSrc = globalConfig.workerSrc;\r\n }\r\n}\r\n\r\n/**\r\n * Get current PDF.js configuration\r\n * @returns Current configuration\r\n */\r\nexport function getPdfJsConfig(): Required<PdfJsConfig> {\r\n // Ensure config is initialized before returning\r\n ensureConfigInitialized();\r\n return { ...globalConfig };\r\n}\r\n\r\n/**\r\n * Reset configuration to defaults (local files)\r\n */\r\nexport function resetPdfJsConfig(): void {\r\n // Clear cached worker src to force recomputation\r\n _workerSrcComputed = false;\r\n _cachedWorkerSrc = null;\r\n _configInitialized = false;\r\n \r\n // Re-initialize with fresh defaults\r\n ensureConfigInitialized();\r\n}\r\n\r\n/**\r\n * Initialize PDF.js configuration\r\n * This is called automatically when the first PDF operation is attempted,\r\n * but can also be called manually to pre-initialize the configuration.\r\n * \r\n * Unlike previous versions, this does NOT run at module load time to\r\n * ensure compatibility with Next.js/webpack environments.\r\n */\r\nexport function initializePdfJs(): void {\r\n ensureConfigInitialized();\r\n}\r\n\r\n","/**\r\n * PDF.js Version Check Utility\r\n * Detects version mismatches between viewer and worker\r\n */\r\n\r\nimport * as pdfjsLib from 'pdfjs-dist';\r\n\r\nexport interface PdfJsVersionCheckResult {\r\n viewerExists: boolean;\r\n versionMatch: boolean;\r\n viewerVersion?: string;\r\n workerVersion: string;\r\n errorMessage?: string;\r\n}\r\n\r\n/**\r\n * Check if PDF.js viewer files exist and versions match\r\n * @param viewerBasePath - Base path for the viewer (e.g., '/pdfjs')\r\n * @returns Version check result\r\n */\r\nexport async function checkPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const workerVersion = pdfjsLib.version;\r\n \r\n try {\r\n // Check if .version file exists\r\n const versionUrl = `${viewerBasePath}/.version`;\r\n const response = await fetch(versionUrl);\r\n \r\n if (!response.ok) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'PDF.js viewer files not found. Run: npx signiphi-setup',\r\n };\r\n }\r\n \r\n const viewerVersion = (await response.text()).trim();\r\n const versionMatch = viewerVersion === workerVersion;\r\n \r\n if (!versionMatch) {\r\n return {\r\n viewerExists: true,\r\n versionMatch: false,\r\n viewerVersion,\r\n workerVersion,\r\n errorMessage: `Version mismatch: viewer=${viewerVersion}, worker=${workerVersion}. Run: npx signiphi-setup`,\r\n };\r\n }\r\n \r\n return {\r\n viewerExists: true,\r\n versionMatch: true,\r\n viewerVersion,\r\n workerVersion,\r\n };\r\n } catch (error) {\r\n return {\r\n viewerExists: false,\r\n versionMatch: false,\r\n workerVersion,\r\n errorMessage: 'Unable to check PDF.js version. Viewer files may not be installed.',\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Log version check warnings to console\r\n * @param result - Version check result\r\n */\r\nexport function logVersionCheckWarning(result: PdfJsVersionCheckResult): void {\r\n if (!result.viewerExists) {\r\n console.warn(\r\n '⚠️ PDF.js viewer files not found.\\n' +\r\n 'The PDF viewer requires viewer files to be installed.\\n' +\r\n 'Run: npx signiphi-setup\\n' +\r\n 'Or reinstall the package: npm install @signiphi/pdf-signer'\r\n );\r\n } else if (!result.versionMatch) {\r\n console.warn(\r\n `⚠️ PDF.js version mismatch detected:\\n` +\r\n ` Viewer: ${result.viewerVersion}\\n` +\r\n ` Worker: ${result.workerVersion}\\n` +\r\n 'Run: npx signiphi-setup to sync versions'\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check version and log warnings automatically\r\n * @param viewerBasePath - Base path for the viewer\r\n */\r\nexport async function checkAndLogPdfJsVersion(\r\n viewerBasePath: string = '/pdfjs'\r\n): Promise<PdfJsVersionCheckResult> {\r\n const result = await checkPdfJsVersion(viewerBasePath);\r\n \r\n if (!result.viewerExists || !result.versionMatch) {\r\n logVersionCheckWarning(result);\r\n }\r\n \r\n return result;\r\n}\r\n\r\n","/**\r\n * Audit Trail Utilities\r\n * Captures device metadata, IP address, and geolocation for compliance and forensics\r\n */\r\n\r\nimport type { AuditTrailMetadata } from '../types';\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Synchronously capture device and browser metadata\r\n */\r\nexport function captureDeviceMetadata(): Partial<AuditTrailMetadata> {\r\n const metadata: Partial<AuditTrailMetadata> = {};\r\n\r\n try {\r\n // User agent (truncated to 100 chars)\r\n if (navigator.userAgent) {\r\n metadata.userAgent = navigator.userAgent.substring(0, 100);\r\n }\r\n\r\n // Screen resolution\r\n if (screen.width && screen.height) {\r\n metadata.screenResolution = `${screen.width}x${screen.height}`;\r\n }\r\n\r\n // Timezone\r\n try {\r\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n if (timezone) {\r\n metadata.timezone = timezone;\r\n }\r\n } catch {\r\n // Timezone unavailable\r\n }\r\n\r\n // Language\r\n if (navigator.language) {\r\n metadata.language = navigator.language;\r\n }\r\n\r\n // Platform\r\n if (navigator.platform) {\r\n metadata.platform = navigator.platform;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing device metadata:', error);\r\n }\r\n\r\n return metadata;\r\n}\r\n\r\n/**\r\n * Capture IP address using public API\r\n */\r\nexport async function captureIpAddress(): Promise<string> {\r\n try {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout\r\n\r\n const ipResponse = await fetch('https://api.ipify.org?format=json', {\r\n method: 'GET',\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (ipResponse.ok) {\r\n const ipData = await ipResponse.json();\r\n if (ipData.ip) {\r\n return ipData.ip;\r\n }\r\n }\r\n\r\n return 'Unknown';\r\n } catch (error) {\r\n return 'Unknown';\r\n }\r\n}\r\n\r\n/**\r\n * Capture geolocation using browser geolocation API\r\n */\r\nexport async function captureGeolocation(): Promise<{\r\n latitude: number;\r\n longitude: number;\r\n accuracy?: number;\r\n} | null> {\r\n if (!navigator.geolocation) {\r\n return null;\r\n }\r\n\r\n try {\r\n const position = await new Promise<GeolocationPosition>((resolve, reject) => {\r\n navigator.geolocation.getCurrentPosition(resolve, reject, {\r\n timeout: 10000, // 10 second timeout\r\n enableHighAccuracy: false,\r\n maximumAge: 300000, // 5 minutes cache\r\n });\r\n });\r\n\r\n if (position.coords) {\r\n const latitude = parseFloat(position.coords.latitude.toFixed(4));\r\n const longitude = parseFloat(position.coords.longitude.toFixed(4));\r\n const accuracy = position.coords.accuracy\r\n ? Math.round(position.coords.accuracy)\r\n : undefined;\r\n\r\n\r\n return {\r\n latitude,\r\n longitude,\r\n accuracy,\r\n };\r\n }\r\n\r\n return null;\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Capture complete audit trail metadata\r\n * Combines device metadata, IP address, and geolocation\r\n */\r\nexport async function captureAuditTrail(): Promise<AuditTrailMetadata> {\r\n\r\n const auditTrail: AuditTrailMetadata = {};\r\n\r\n try {\r\n // Capture device metadata (synchronous)\r\n const deviceMetadata = captureDeviceMetadata();\r\n Object.assign(auditTrail, deviceMetadata);\r\n\r\n // Capture IP address (async, with timeout)\r\n try {\r\n const ipAddress = await captureIpAddress();\r\n auditTrail.ipAddress = ipAddress;\r\n } catch (error) {\r\n logger.warn('Error capturing IP address:', error);\r\n auditTrail.ipAddress = 'Unknown';\r\n }\r\n\r\n // Capture geolocation (async, requires permission)\r\n try {\r\n const geolocation = await captureGeolocation();\r\n if (geolocation) {\r\n auditTrail.geolocation = geolocation;\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing geolocation:', error);\r\n }\r\n } catch (error) {\r\n logger.warn('Error capturing audit trail:', error);\r\n }\r\n\r\n return auditTrail;\r\n}\r\n\r\n","/**\r\n * Custom Error Classes\r\n * Domain-specific error types for better error handling and debugging\r\n */\r\n\r\n/**\r\n * Error thrown when PDF validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * const validation = validatePdfBytes(bytes);\r\n * if (!validation.valid) {\r\n * throw new PdfValidationError(validation.error || 'Invalid PDF');\r\n * }\r\n * ```\r\n */\r\nexport class PdfValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfValidationError';\r\n // Maintains proper stack trace for where error was thrown (V8 only)\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown during PDF processing operations\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * const pdfDoc = await PDFDocument.load(bytes);\r\n * } catch (err) {\r\n * throw new PdfProcessingError('Failed to load PDF document', err);\r\n * }\r\n * ```\r\n */\r\nexport class PdfProcessingError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'PdfProcessingError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, PdfProcessingError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for form field related issues\r\n * \r\n * @example\r\n * ```ts\r\n * if (!field.value && field.required) {\r\n * throw new FormFieldError(\r\n * 'Required field is empty',\r\n * field.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class FormFieldError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fieldName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'FormFieldError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, FormFieldError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown for attachment validation failures\r\n * \r\n * @example\r\n * ```ts\r\n * if (file.size > maxFileSize) {\r\n * throw new AttachmentValidationError(\r\n * `File size exceeds limit: ${file.name}`,\r\n * file.name\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport class AttachmentValidationError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly fileName?: string,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = 'AttachmentValidationError';\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, AttachmentValidationError);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfValidationError\r\n */\r\nexport function isPdfValidationError(error: unknown): error is PdfValidationError {\r\n return error instanceof PdfValidationError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a PdfProcessingError\r\n */\r\nexport function isPdfProcessingError(error: unknown): error is PdfProcessingError {\r\n return error instanceof PdfProcessingError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a FormFieldError\r\n */\r\nexport function isFormFieldError(error: unknown): error is FormFieldError {\r\n return error instanceof FormFieldError;\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is an AttachmentValidationError\r\n */\r\nexport function isAttachmentValidationError(error: unknown): error is AttachmentValidationError {\r\n return error instanceof AttachmentValidationError;\r\n}\r\n\r\n/**\r\n * Extract error message from unknown error type\r\n * \r\n * @param error - The error to extract message from\r\n * @param defaultMessage - Default message if extraction fails\r\n * @returns Error message string\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * // ... operation\r\n * } catch (err) {\r\n * const message = getErrorMessage(err, 'Operation failed');\r\n * logger.error(message);\r\n * }\r\n * ```\r\n */\r\nexport function getErrorMessage(error: unknown, defaultMessage = 'Unknown error'): string {\r\n if (error instanceof Error) {\r\n return error.message;\r\n }\r\n if (typeof error === 'string') {\r\n return error;\r\n }\r\n return defaultMessage;\r\n}\r\n\r\n","/**\r\n * Attachment Validation Utilities\r\n * Validation functions for file attachments\r\n */\r\n\r\nimport type { AttachmentConstraints, Attachment } from '../types';\r\nimport { AttachmentValidationError } from './errors';\r\n\r\n/**\r\n * Default attachment constraints\r\n */\r\nexport const DEFAULT_ATTACHMENT_CONSTRAINTS: AttachmentConstraints = {\r\n maxFileSize: 10 * 1024 * 1024, // 10MB\r\n maxTotalSize: 50 * 1024 * 1024, // 50MB\r\n maxFiles: 10,\r\n allowedTypes: ['image/*', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],\r\n allowedExtensions: ['.pdf', '.jpg', '.jpeg', '.png', '.gif', '.doc', '.docx'],\r\n};\r\n\r\n/**\r\n * Validate a single file against constraints\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFile(file, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * console.error('File validation failed:', result.errors);\r\n * }\r\n * ```\r\n */\r\nexport function validateFile(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate file size\r\n if (file.size > constraints.maxFileSize) {\r\n const maxMB = (constraints.maxFileSize / 1024 / 1024).toFixed(1);\r\n const fileMB = (file.size / 1024 / 1024).toFixed(1);\r\n errors.push(`File \"${file.name}\" is too large (${fileMB}MB). Maximum size is ${maxMB}MB.`);\r\n }\r\n\r\n // Validate file type (MIME type)\r\n const isTypeAllowed = constraints.allowedTypes.some((allowedType) => {\r\n if (allowedType.endsWith('/*')) {\r\n // Wildcard type (e.g., 'image/*')\r\n const prefix = allowedType.slice(0, -2);\r\n return file.type.startsWith(prefix);\r\n }\r\n return file.type === allowedType;\r\n });\r\n\r\n if (!isTypeAllowed && constraints.allowedTypes.length > 0) {\r\n errors.push(\r\n `File type \"${file.type}\" is not allowed for \"${file.name}\". Allowed types: ${constraints.allowedTypes.join(', ')}`\r\n );\r\n }\r\n\r\n // Validate file extension\r\n if (constraints.allowedExtensions && constraints.allowedExtensions.length > 0) {\r\n const fileExt = '.' + file.name.split('.').pop()?.toLowerCase();\r\n const isExtAllowed = constraints.allowedExtensions.some(\r\n (ext) => ext.toLowerCase() === fileExt\r\n );\r\n\r\n if (!isExtAllowed) {\r\n errors.push(\r\n `File extension \"${fileExt}\" is not allowed for \"${file.name}\". Allowed extensions: ${constraints.allowedExtensions.join(', ')}`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate multiple files against constraints\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments to consider for total size/count\r\n * @param constraints - Validation constraints\r\n * @returns Validation result with errors array\r\n * \r\n * @example\r\n * ```ts\r\n * const result = validateFiles(newFiles, existingAttachments, DEFAULT_ATTACHMENT_CONSTRAINTS);\r\n * if (result.errors.length > 0) {\r\n * alert('Some files cannot be uploaded: ' + result.errors.join(', '));\r\n * }\r\n * ```\r\n */\r\nexport function validateFiles(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): {\r\n valid: boolean;\r\n errors: string[];\r\n} {\r\n const errors: string[] = [];\r\n\r\n // Validate total number of files\r\n const totalFiles = files.length + existingAttachments.length;\r\n if (totalFiles > constraints.maxFiles) {\r\n errors.push(\r\n `Too many files. Maximum allowed is ${constraints.maxFiles}, you have ${totalFiles} files total.`\r\n );\r\n }\r\n\r\n // Validate total size\r\n const existingSize = existingAttachments.reduce((sum, att) => sum + att.size, 0);\r\n const newFilesSize = files.reduce((sum, file) => sum + file.size, 0);\r\n const totalSize = existingSize + newFilesSize;\r\n\r\n if (totalSize > constraints.maxTotalSize) {\r\n const maxMB = (constraints.maxTotalSize / 1024 / 1024).toFixed(1);\r\n const totalMB = (totalSize / 1024 / 1024).toFixed(1);\r\n errors.push(\r\n `Total size of all files is too large (${totalMB}MB). Maximum total size is ${maxMB}MB.`\r\n );\r\n }\r\n\r\n // Validate each individual file\r\n for (const file of files) {\r\n const fileResult = validateFile(file, constraints);\r\n errors.push(...fileResult.errors);\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Validate file and throw error if invalid\r\n * \r\n * Convenience function that throws AttachmentValidationError if validation fails.\r\n * \r\n * @param file - File to validate\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFileOrThrow(file);\r\n * // File is valid, proceed with upload\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFileOrThrow(\r\n file: File,\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFile(file, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n file.name,\r\n { file, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Validate multiple files and throw error if invalid\r\n * \r\n * @param files - Files to validate\r\n * @param existingAttachments - Existing attachments\r\n * @param constraints - Validation constraints\r\n * @throws {AttachmentValidationError} If validation fails\r\n * \r\n * @example\r\n * ```ts\r\n * try {\r\n * validateFilesOrThrow(selectedFiles, currentAttachments);\r\n * // All files are valid\r\n * } catch (err) {\r\n * if (err instanceof AttachmentValidationError) {\r\n * alert(err.message);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function validateFilesOrThrow(\r\n files: File[],\r\n existingAttachments: Attachment[] = [],\r\n constraints: AttachmentConstraints = DEFAULT_ATTACHMENT_CONSTRAINTS\r\n): void {\r\n const result = validateFiles(files, existingAttachments, constraints);\r\n if (!result.valid) {\r\n throw new AttachmentValidationError(\r\n `File validation failed: ${result.errors.join('; ')}`,\r\n undefined,\r\n { files, errors: result.errors }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Check if a file type is an image\r\n * \r\n * @param fileType - MIME type of the file\r\n * @returns true if the file is an image\r\n * \r\n * @example\r\n * ```ts\r\n * if (isImageType(file.type)) {\r\n * // Generate preview\r\n * }\r\n * ```\r\n */\r\nexport function isImageType(fileType: string): boolean {\r\n return fileType.startsWith('image/');\r\n}\r\n\r\n/**\r\n * Format file size for display\r\n * \r\n * @param bytes - File size in bytes\r\n * @returns Formatted size string (e.g., \"1.5 MB\")\r\n * \r\n * @example\r\n * ```ts\r\n * const sizeDisplay = formatFileSize(file.size); // \"1.5 MB\"\r\n * ```\r\n */\r\nexport function formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n}\r\n\r\n","/**\r\n * Performance Monitoring Utility\r\n * \r\n * Provides utilities for tracking and measuring performance metrics\r\n * in critical operations like PDF loading, form filling, and signature capture.\r\n * \r\n * Usage:\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer();\r\n * const metrics = monitor.getMetrics();\r\n * ```\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\nexport interface PerformanceMetric {\r\n label: string;\r\n duration: number;\r\n timestamp: number;\r\n}\r\n\r\nexport interface PerformanceMetrics {\r\n [label: string]: {\r\n count: number;\r\n total: number;\r\n avg: number;\r\n min: number;\r\n max: number;\r\n last: number;\r\n };\r\n}\r\n\r\n/**\r\n * Performance Monitor Class\r\n * \r\n * Tracks performance metrics for various operations.\r\n * Maintains history and calculates statistics (avg, min, max).\r\n */\r\nexport class PerformanceMonitor {\r\n private metrics: Map<string, number[]> = new Map();\r\n private enabled: boolean;\r\n\r\n constructor(enabled: boolean = true) {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Start a timer for a labeled operation\r\n * \r\n * @param label - Unique label for the operation\r\n * @returns Function to call when operation completes\r\n * \r\n * @example\r\n * ```typescript\r\n * const endTimer = monitor.startTimer('pdf-load');\r\n * await loadPdf(url);\r\n * endTimer(); // Records duration\r\n * ```\r\n */\r\n startTimer(label: string): () => void {\r\n if (!this.enabled) {\r\n return () => {}; // No-op if disabled\r\n }\r\n\r\n const startTime = performance.now();\r\n\r\n return () => {\r\n const duration = performance.now() - startTime;\r\n this.measure(label, duration);\r\n };\r\n }\r\n\r\n /**\r\n * Manually record a performance measurement\r\n * \r\n * @param label - Unique label for the operation\r\n * @param duration - Duration in milliseconds\r\n * \r\n * @example\r\n * ```typescript\r\n * monitor.measure('pdf-load', 1234.56);\r\n * ```\r\n */\r\n measure(label: string, duration: number): void {\r\n if (!this.enabled) {\r\n return;\r\n }\r\n\r\n const measurements = this.metrics.get(label) || [];\r\n measurements.push(duration);\r\n this.metrics.set(label, measurements);\r\n\r\n logger.info(`[Performance] ${label}: ${duration.toFixed(2)}ms`);\r\n }\r\n\r\n /**\r\n * Get all recorded metrics with statistics\r\n * \r\n * @returns Object containing metrics for all labels\r\n * \r\n * @example\r\n * ```typescript\r\n * const metrics = monitor.getMetrics();\r\n * console.log(`PDF load avg: ${metrics['pdf-load'].avg}ms`);\r\n * ```\r\n */\r\n getMetrics(): PerformanceMetrics {\r\n const result: PerformanceMetrics = {};\r\n\r\n for (const [label, measurements] of this.metrics.entries()) {\r\n if (measurements.length === 0) continue;\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n result[label] = {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Get metrics for a specific label\r\n * \r\n * @param label - Label to get metrics for\r\n * @returns Metrics for the label, or null if not found\r\n */\r\n getMetric(label: string): PerformanceMetrics[string] | null {\r\n const measurements = this.metrics.get(label);\r\n if (!measurements || measurements.length === 0) {\r\n return null;\r\n }\r\n\r\n const total = measurements.reduce((sum, val) => sum + val, 0);\r\n const avg = total / measurements.length;\r\n const min = Math.min(...measurements);\r\n const max = Math.max(...measurements);\r\n const last = measurements[measurements.length - 1] ?? 0;\r\n\r\n return {\r\n count: measurements.length,\r\n total,\r\n avg,\r\n min,\r\n max,\r\n last,\r\n };\r\n }\r\n\r\n /**\r\n * Get raw measurements for a label\r\n * \r\n * @param label - Label to get measurements for\r\n * @returns Array of duration measurements in milliseconds\r\n */\r\n getRawMeasurements(label: string): number[] {\r\n return this.metrics.get(label) || [];\r\n }\r\n\r\n /**\r\n * Clear all metrics\r\n */\r\n clear(): void {\r\n this.metrics.clear();\r\n }\r\n\r\n /**\r\n * Clear metrics for a specific label\r\n * \r\n * @param label - Label to clear metrics for\r\n */\r\n clearLabel(label: string): void {\r\n this.metrics.delete(label);\r\n }\r\n\r\n /**\r\n * Enable or disable performance monitoring\r\n * \r\n * @param enabled - Whether to enable monitoring\r\n */\r\n setEnabled(enabled: boolean): void {\r\n this.enabled = enabled;\r\n }\r\n\r\n /**\r\n * Check if monitoring is enabled\r\n */\r\n isEnabled(): boolean {\r\n return this.enabled;\r\n }\r\n\r\n /**\r\n * Generate a performance report as a string\r\n * \r\n * @returns Formatted performance report\r\n */\r\n generateReport(): string {\r\n const metrics = this.getMetrics();\r\n const lines: string[] = [];\r\n\r\n lines.push('Performance Report');\r\n lines.push('='.repeat(50));\r\n lines.push('');\r\n\r\n for (const [label, stats] of Object.entries(metrics)) {\r\n lines.push(`${label}:`);\r\n lines.push(` Count: ${stats.count}`);\r\n lines.push(` Avg: ${stats.avg.toFixed(2)}ms`);\r\n lines.push(` Min: ${stats.min.toFixed(2)}ms`);\r\n lines.push(` Max: ${stats.max.toFixed(2)}ms`);\r\n lines.push(` Last: ${stats.last.toFixed(2)}ms`);\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * Create a new performance monitor instance\r\n * \r\n * @param enabled - Whether to enable monitoring (default: true in development)\r\n * @returns PerformanceMonitor instance\r\n * \r\n * @example\r\n * ```typescript\r\n * const monitor = createPerformanceMonitor();\r\n * ```\r\n */\r\nexport function createPerformanceMonitor(enabled?: boolean): PerformanceMonitor {\r\n const isEnabled = enabled ?? process.env.NODE_ENV === 'development';\r\n return new PerformanceMonitor(isEnabled);\r\n}\r\n\r\n/**\r\n * Global performance monitor instance\r\n * Can be used across the application for centralized monitoring\r\n */\r\nexport const globalPerformanceMonitor = createPerformanceMonitor();\r\n\r\n/**\r\n * Decorator for measuring function performance\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Function decorator\r\n * \r\n * @example\r\n * ```typescript\r\n * class MyClass {\r\n * @measurePerformance('my-operation')\r\n * async myOperation() {\r\n * // ... operation code ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function measurePerformance(\r\n label: string,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n) {\r\n return function (\r\n _target: any,\r\n _propertyKey: string,\r\n descriptor: PropertyDescriptor\r\n ) {\r\n const originalMethod = descriptor.value;\r\n\r\n descriptor.value = async function (...args: any[]) {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n const result = await originalMethod.apply(this, args);\r\n return result;\r\n } finally {\r\n endTimer();\r\n }\r\n };\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Higher-order function to wrap async functions with performance monitoring\r\n * \r\n * @param label - Label for the performance measurement\r\n * @param fn - Function to wrap\r\n * @param monitor - Performance monitor instance (defaults to global)\r\n * @returns Wrapped function\r\n * \r\n * @example\r\n * ```typescript\r\n * const loadPdfWithMonitoring = withPerformanceMonitoring(\r\n * 'pdf-load',\r\n * loadPdf\r\n * );\r\n * ```\r\n */\r\nexport function withPerformanceMonitoring<T extends (...args: any[]) => Promise<any>>(\r\n label: string,\r\n fn: T,\r\n monitor: PerformanceMonitor = globalPerformanceMonitor\r\n): T {\r\n return (async (...args: any[]) => {\r\n const endTimer = monitor.startTimer(label);\r\n try {\r\n return await fn(...args);\r\n } finally {\r\n endTimer();\r\n }\r\n }) as T;\r\n}\r\n\r\n","/**\r\n * Date Validation and Parsing Utility\r\n * Handles parsing of various date formats and validation\r\n */\r\n\r\nimport { parse, isValid as isValidDate, parseISO } from 'date-fns';\r\n\r\nexport interface DateValidationResult {\r\n isValid: boolean;\r\n date: Date | null;\r\n isoString: string | null;\r\n originalValue: string;\r\n error?: string;\r\n}\r\n\r\nfunction toIsoDateString(date: Date): string {\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, '0');\r\n const day = String(date.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Parse and validate a date string from various formats\r\n * Attempts to parse common formats: ISO, US, EU, timestamps\r\n * \r\n * Format priority:\r\n * 1. ISO 8601 (YYYY-MM-DD)\r\n * 2. US format (MM/DD/YYYY) - assumes US format for ambiguous dates\r\n * 3. EU format (DD/MM/YYYY)\r\n * 4. Timestamp (numeric string)\r\n * \r\n * @param value - The date string to parse\r\n * @returns Validation result with parsed date or error\r\n */\r\nexport function parseAndValidateDate(value: string | null | undefined): DateValidationResult {\r\n const originalValue = String(value || '');\r\n \r\n // Handle empty values\r\n if (!value || value.trim() === '') {\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: 'Date is required',\r\n };\r\n }\r\n\r\n const trimmedValue = value.trim();\r\n const sanitizedValue = trimmedValue\r\n // Remove ordinal suffixes (1st, 2nd, 3rd, 21st, etc.)\r\n .replace(/(\\d+)(st|nd|rd|th)/gi, '$1')\r\n // Normalize commas to spaces for natural language inputs\r\n .replace(/,/g, ' ')\r\n .replace(/\\s+/g, ' ')\r\n .trim();\r\n\r\n // Try ISO 8601 format first (YYYY-MM-DD)\r\n try {\r\n const isoDate = parseISO(trimmedValue);\r\n if (isValidDate(isoDate) && !isNaN(isoDate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: isoDate,\r\n isoString: trimmedValue,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n\r\n // Handle two-digit year inputs like 01/05/24 by assuming 2000-based year\r\n const shortYearMatch = sanitizedValue.match(/^(\\d{1,2})[\\/.\\-](\\d{1,2})[\\/.\\-](\\d{2})$/);\r\n if (shortYearMatch) {\r\n const [, monthStr, dayStr, yearStr] = shortYearMatch;\r\n const month = parseInt(monthStr ?? '', 10);\r\n const day = parseInt(dayStr ?? '', 10);\r\n const year = 2000 + parseInt(yearStr ?? '', 10);\r\n const candidate = new Date(year, month - 1, day);\r\n if (isValidDate(candidate) && !isNaN(candidate.getTime())) {\r\n return {\r\n isValid: true,\r\n date: candidate,\r\n isoString: toIsoDateString(candidate),\r\n originalValue,\r\n };\r\n }\r\n }\r\n\r\n // Try common date formats\r\n const formats = [\r\n // US formats (MM/DD/YYYY - assume US for ambiguous dates)\r\n { pattern: 'MM/dd/yyyy', name: 'US format (MM/DD/YYYY)' },\r\n { pattern: 'M/d/yyyy', name: 'US format (M/D/YYYY)' },\r\n { pattern: 'MM-dd-yyyy', name: 'US format (MM-DD-YYYY)' },\r\n { pattern: 'M-d-yyyy', name: 'US format (M-D-YYYY)' },\r\n { pattern: 'MM/dd/yy', name: 'US format (MM/DD/YY)' },\r\n { pattern: 'M/d/yy', name: 'US format (M/D/YY)' },\r\n { pattern: 'MM-dd-yy', name: 'US format (MM-DD-YY)' },\r\n { pattern: 'M-d-yy', name: 'US format (M-D-YY)' },\r\n \r\n // EU formats (DD/MM/YYYY)\r\n { pattern: 'dd/MM/yyyy', name: 'EU format (DD/MM/YYYY)' },\r\n { pattern: 'd/M/yyyy', name: 'EU format (D/M/YYYY)' },\r\n { pattern: 'dd.MM.yyyy', name: 'EU format (DD.MM.YYYY)' },\r\n { pattern: 'd.M.yyyy', name: 'EU format (D.M.YYYY)' },\r\n \r\n // Full month names\r\n { pattern: 'MMMM d, yyyy', name: 'Month name format (January 1, 2024)' },\r\n { pattern: 'MMM d, yyyy', name: 'Short month format (Jan 1, 2024)' },\r\n { pattern: 'MMMM d yyyy', name: 'Month name format without comma (January 1 2024)' },\r\n { pattern: 'MMM d yyyy', name: 'Short month without comma (Jan 1 2024)' },\r\n { pattern: 'd MMMM yyyy', name: 'EU month format (1 January 2024)' },\r\n { pattern: 'd MMM yyyy', name: 'EU month short format (1 Jan 2024)' },\r\n { pattern: 'd MMM, yyyy', name: 'EU month short with comma (1 Jan, 2024)' },\r\n \r\n // Year first formats\r\n { pattern: 'yyyy/MM/dd', name: 'ISO-like format (YYYY/MM/DD)' },\r\n { pattern: 'yyyy-MM-dd', name: 'ISO format with dashes' },\r\n ];\r\n\r\n const referenceDate = new Date();\r\n\r\n for (const { pattern } of formats) {\r\n try {\r\n const parsedDate = parse(sanitizedValue, pattern, referenceDate);\r\n if (isValidDate(parsedDate) && !isNaN(parsedDate.getTime())) {\r\n // Convert to ISO string format (YYYY-MM-DD)\r\n const isoString = toIsoDateString(parsedDate);\r\n \r\n return {\r\n isValid: true,\r\n date: parsedDate,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Continue to next format\r\n }\r\n }\r\n\r\n // Try parsing as timestamp (milliseconds)\r\n if (/^\\d+$/.test(trimmedValue)) {\r\n try {\r\n const timestamp = parseInt(trimmedValue, 10);\r\n const date = new Date(timestamp);\r\n if (isValidDate(date) && !isNaN(date.getTime())) {\r\n const isoString = toIsoDateString(date);\r\n \r\n return {\r\n isValid: true,\r\n date,\r\n isoString,\r\n originalValue,\r\n };\r\n }\r\n } catch {\r\n // Not a valid timestamp\r\n }\r\n }\r\n\r\n // Lenient fallback using native Date parsing after sanitization\r\n const nativeParsed = new Date(sanitizedValue);\r\n if (isValidDate(nativeParsed) && !isNaN(nativeParsed.getTime())) {\r\n return {\r\n isValid: true,\r\n date: nativeParsed,\r\n isoString: toIsoDateString(nativeParsed),\r\n originalValue,\r\n };\r\n }\r\n\r\n // All formats failed\r\n return {\r\n isValid: false,\r\n date: null,\r\n isoString: null,\r\n originalValue,\r\n error: `Invalid date format: \"${trimmedValue}\". Please use a date picker or format like MM/DD/YYYY.`,\r\n };\r\n}\r\n\r\n/**\r\n * Validate if a string is a valid ISO date (YYYY-MM-DD)\r\n */\r\nexport function isValidISODate(value: string | null | undefined): boolean {\r\n if (!value || typeof value !== 'string') {\r\n return false;\r\n }\r\n\r\n const isoPattern = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n if (!isoPattern.test(value)) {\r\n return false;\r\n }\r\n\r\n try {\r\n const date = parseISO(value);\r\n return isValidDate(date) && !isNaN(date.getTime());\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n","/**\r\n * Usage tracking utilities for signiphi API integration.\r\n * Enables automatic tracking of document sends and signings via API key.\r\n */\r\n\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * Configuration for the tracking API\r\n */\r\nexport interface TrackingConfig {\r\n /** API key for authentication */\r\n apiKey: string;\r\n /** Custom API endpoint (defaults to https://api.signiphi.ai) */\r\n endpoint?: string;\r\n}\r\n\r\n/**\r\n * Data for tracking a document send event\r\n */\r\nexport interface TrackSendData {\r\n /** Email address of the recipient */\r\n recipientEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Data for tracking a document signing event\r\n */\r\nexport interface TrackSigningData {\r\n /** Email address of the signer */\r\n signerEmail: string;\r\n /** Optional document ID for correlation */\r\n documentId?: string;\r\n /** Optional idempotency key to prevent duplicate tracking */\r\n idempotencyKey?: string;\r\n /** Optional additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Response from tracking API\r\n */\r\nexport interface TrackingResponse {\r\n success: boolean;\r\n eventId: string;\r\n idempotencyKey: string;\r\n usage: {\r\n currentMonth: number;\r\n limit: number;\r\n remaining: number;\r\n };\r\n}\r\n\r\nconst DEFAULT_API_ENDPOINT = 'https://api-dev.signiphi.ai';\r\n// const DEFAULT_API_ENDPOINT = 'http://localhost:4000';\r\nconst API_PREFIX = '/api/v1';\r\n\r\n/**\r\n * Track a document send event.\r\n * Call this when a document is sent to a recipient for signing.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-send`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n recipientEmail: data.recipientEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track send failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document send tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document send:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Track a document signing event.\r\n * Call this when a document is signed by a recipient.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n * @returns Tracking response with usage stats\r\n */\r\nexport async function trackDocumentSigned(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<TrackingResponse> {\r\n const endpoint = config.endpoint || DEFAULT_API_ENDPOINT;\r\n const url = `${endpoint}${API_PREFIX}/usage/track-signing`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': config.apiKey,\r\n },\r\n body: JSON.stringify({\r\n signerEmail: data.signerEmail,\r\n documentId: data.documentId,\r\n idempotencyKey: data.idempotencyKey,\r\n metadata: data.metadata,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n logger.error(`Track signing failed: ${response.status} - ${errorText}`);\r\n throw new Error(`Tracking failed: ${response.status}`);\r\n }\r\n\r\n const result = await response.json();\r\n logger.debug('Document signing tracked successfully', { eventId: result.eventId });\r\n return result;\r\n } catch (error) {\r\n logger.error('Failed to track document signing:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document signing event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Signing event data\r\n */\r\nexport async function trackDocumentSignedSilent(\r\n config: TrackingConfig,\r\n data: TrackSigningData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSigned(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n/**\r\n * Silently track a document send event (non-blocking).\r\n * This version catches errors and logs them without throwing.\r\n * Use this when tracking failure should not affect the main flow.\r\n *\r\n * @param config - Tracking configuration with API key\r\n * @param data - Send event data\r\n */\r\nexport async function trackDocumentSentSilent(\r\n config: TrackingConfig,\r\n data: TrackSendData,\r\n): Promise<void> {\r\n try {\r\n await trackDocumentSent(config, data);\r\n } catch (error) {\r\n logger.warn('Silent tracking failed (non-critical):', error);\r\n }\r\n}\r\n\r\n"]}
|