@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,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Bundle Size Analysis Script
|
|
4
|
+
*
|
|
5
|
+
* Analyzes the built bundle sizes and generates a detailed report.
|
|
6
|
+
* Compares against defined budgets and warns if exceeded.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node scripts/analyze-bundle.js
|
|
10
|
+
* node scripts/analyze-bundle.js --format=json
|
|
11
|
+
* node scripts/analyze-bundle.js --check-budgets
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const zlib = require('zlib');
|
|
17
|
+
|
|
18
|
+
// Bundle size budgets (in bytes)
|
|
19
|
+
const BUDGETS = {
|
|
20
|
+
'index.mjs': { raw: 200 * 1024, gzip: 60 * 1024 },
|
|
21
|
+
'core/index.mjs': { raw: 50 * 1024, gzip: 15 * 1024 },
|
|
22
|
+
'components/index.mjs': { raw: 120 * 1024, gzip: 35 * 1024 },
|
|
23
|
+
'hooks/index.mjs': { raw: 80 * 1024, gzip: 25 * 1024 },
|
|
24
|
+
'types/index.mjs': { raw: 5 * 1024, gzip: 2 * 1024 },
|
|
25
|
+
'utils/index.mjs': { raw: 100 * 1024, gzip: 30 * 1024 },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get file size in different compression formats
|
|
30
|
+
*/
|
|
31
|
+
function getFileSizes(filePath) {
|
|
32
|
+
if (!fs.existsSync(filePath)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const content = fs.readFileSync(filePath);
|
|
37
|
+
const raw = content.length;
|
|
38
|
+
const gzipped = zlib.gzipSync(content, { level: 9 }).length;
|
|
39
|
+
const brotli = zlib.brotliCompressSync(content).length;
|
|
40
|
+
|
|
41
|
+
return { raw, gzipped, brotli };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Format bytes to human-readable string
|
|
46
|
+
*/
|
|
47
|
+
function formatBytes(bytes) {
|
|
48
|
+
if (bytes === 0) return '0 B';
|
|
49
|
+
const k = 1024;
|
|
50
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
51
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
52
|
+
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if size exceeds budget
|
|
57
|
+
*/
|
|
58
|
+
function checkBudget(filePath, sizes) {
|
|
59
|
+
const budget = BUDGETS[filePath];
|
|
60
|
+
if (!budget) return { withinBudget: true };
|
|
61
|
+
|
|
62
|
+
const rawExceeded = sizes.raw > budget.raw;
|
|
63
|
+
const gzipExceeded = sizes.gzipped > budget.gzip;
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
withinBudget: !rawExceeded && !gzipExceeded,
|
|
67
|
+
rawExceeded,
|
|
68
|
+
gzipExceeded,
|
|
69
|
+
rawPercent: (sizes.raw / budget.raw * 100).toFixed(1),
|
|
70
|
+
gzipPercent: (sizes.gzipped / budget.gzip * 100).toFixed(1),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Analyze all bundle files
|
|
76
|
+
*/
|
|
77
|
+
function analyzeBundles() {
|
|
78
|
+
const distDir = path.join(__dirname, '..', 'dist');
|
|
79
|
+
const files = [
|
|
80
|
+
'index.mjs',
|
|
81
|
+
'index.js',
|
|
82
|
+
'core/index.mjs',
|
|
83
|
+
'core/index.js',
|
|
84
|
+
'components/index.mjs',
|
|
85
|
+
'components/index.js',
|
|
86
|
+
'hooks/index.mjs',
|
|
87
|
+
'hooks/index.js',
|
|
88
|
+
'types/index.mjs',
|
|
89
|
+
'types/index.js',
|
|
90
|
+
'utils/index.mjs',
|
|
91
|
+
'utils/index.js',
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const results = [];
|
|
95
|
+
let totalRaw = 0;
|
|
96
|
+
let totalGzipped = 0;
|
|
97
|
+
let totalBrotli = 0;
|
|
98
|
+
let budgetViolations = 0;
|
|
99
|
+
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
const filePath = path.join(distDir, file);
|
|
102
|
+
const sizes = getFileSizes(filePath);
|
|
103
|
+
|
|
104
|
+
if (!sizes) {
|
|
105
|
+
console.warn(`⚠️ File not found: ${file}`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const budgetCheck = checkBudget(file, sizes);
|
|
110
|
+
|
|
111
|
+
results.push({
|
|
112
|
+
file,
|
|
113
|
+
sizes,
|
|
114
|
+
budgetCheck,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
totalRaw += sizes.raw;
|
|
118
|
+
totalGzipped += sizes.gzipped;
|
|
119
|
+
totalBrotli += sizes.brotli;
|
|
120
|
+
|
|
121
|
+
if (!budgetCheck.withinBudget) {
|
|
122
|
+
budgetViolations++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
results,
|
|
128
|
+
totals: {
|
|
129
|
+
raw: totalRaw,
|
|
130
|
+
gzipped: totalGzipped,
|
|
131
|
+
brotli: totalBrotli,
|
|
132
|
+
},
|
|
133
|
+
budgetViolations,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Generate markdown report
|
|
139
|
+
*/
|
|
140
|
+
function generateMarkdownReport(analysis) {
|
|
141
|
+
const lines = [];
|
|
142
|
+
|
|
143
|
+
lines.push('# Bundle Size Analysis Report');
|
|
144
|
+
lines.push('');
|
|
145
|
+
lines.push(`**Generated:** ${new Date().toISOString()}`);
|
|
146
|
+
lines.push('');
|
|
147
|
+
|
|
148
|
+
// Summary
|
|
149
|
+
lines.push('## Summary');
|
|
150
|
+
lines.push('');
|
|
151
|
+
lines.push(`- **Total Raw Size:** ${formatBytes(analysis.totals.raw)}`);
|
|
152
|
+
lines.push(`- **Total Gzipped:** ${formatBytes(analysis.totals.gzipped)}`);
|
|
153
|
+
lines.push(`- **Total Brotli:** ${formatBytes(analysis.totals.brotli)}`);
|
|
154
|
+
lines.push(`- **Budget Violations:** ${analysis.budgetViolations}`);
|
|
155
|
+
lines.push('');
|
|
156
|
+
|
|
157
|
+
// Detailed results
|
|
158
|
+
lines.push('## Entry Points');
|
|
159
|
+
lines.push('');
|
|
160
|
+
|
|
161
|
+
for (const result of analysis.results) {
|
|
162
|
+
const { file, sizes, budgetCheck } = result;
|
|
163
|
+
const icon = budgetCheck.withinBudget ? '✅' : '❌';
|
|
164
|
+
|
|
165
|
+
lines.push(`### ${icon} \`${file}\``);
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push('| Format | Size | Budget Status |');
|
|
168
|
+
lines.push('|--------|------|---------------|');
|
|
169
|
+
lines.push(`| Raw | ${formatBytes(sizes.raw)} | ${budgetCheck.rawPercent ? `${budgetCheck.rawPercent}% of budget` : 'N/A'} |`);
|
|
170
|
+
lines.push(`| Gzipped | ${formatBytes(sizes.gzipped)} | ${budgetCheck.gzipPercent ? `${budgetCheck.gzipPercent}% of budget` : 'N/A'} |`);
|
|
171
|
+
lines.push(`| Brotli | ${formatBytes(sizes.brotli)} | - |`);
|
|
172
|
+
lines.push('');
|
|
173
|
+
|
|
174
|
+
if (!budgetCheck.withinBudget) {
|
|
175
|
+
lines.push('**⚠️ Budget Exceeded:**');
|
|
176
|
+
if (budgetCheck.rawExceeded) {
|
|
177
|
+
lines.push(`- Raw size exceeds budget (${budgetCheck.rawPercent}%)`);
|
|
178
|
+
}
|
|
179
|
+
if (budgetCheck.gzipExceeded) {
|
|
180
|
+
lines.push(`- Gzipped size exceeds budget (${budgetCheck.gzipPercent}%)`);
|
|
181
|
+
}
|
|
182
|
+
lines.push('');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return lines.join('\n');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Generate JSON report
|
|
191
|
+
*/
|
|
192
|
+
function generateJsonReport(analysis) {
|
|
193
|
+
return JSON.stringify(analysis, null, 2);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Generate console report
|
|
198
|
+
*/
|
|
199
|
+
function generateConsoleReport(analysis) {
|
|
200
|
+
console.log('\n╔════════════════════════════════════════════════╗');
|
|
201
|
+
console.log('║ Bundle Size Analysis Report ║');
|
|
202
|
+
console.log('╚════════════════════════════════════════════════╝\n');
|
|
203
|
+
|
|
204
|
+
console.log('📦 Total Sizes:');
|
|
205
|
+
console.log(` Raw: ${formatBytes(analysis.totals.raw)}`);
|
|
206
|
+
console.log(` Gzipped: ${formatBytes(analysis.totals.gzipped)}`);
|
|
207
|
+
console.log(` Brotli: ${formatBytes(analysis.totals.brotli)}`);
|
|
208
|
+
console.log('');
|
|
209
|
+
|
|
210
|
+
console.log('📊 Entry Points:\n');
|
|
211
|
+
|
|
212
|
+
for (const result of analysis.results) {
|
|
213
|
+
const { file, sizes, budgetCheck } = result;
|
|
214
|
+
const icon = budgetCheck.withinBudget ? '✅' : '❌';
|
|
215
|
+
|
|
216
|
+
console.log(`${icon} ${file}`);
|
|
217
|
+
console.log(` Raw: ${formatBytes(sizes.raw).padEnd(12)} ${budgetCheck.rawPercent ? `(${budgetCheck.rawPercent}% of budget)` : ''}`);
|
|
218
|
+
console.log(` Gzipped: ${formatBytes(sizes.gzipped).padEnd(12)} ${budgetCheck.gzipPercent ? `(${budgetCheck.gzipPercent}% of budget)` : ''}`);
|
|
219
|
+
console.log(` Brotli: ${formatBytes(sizes.brotli)}`);
|
|
220
|
+
|
|
221
|
+
if (!budgetCheck.withinBudget) {
|
|
222
|
+
console.log(' ⚠️ Budget exceeded!');
|
|
223
|
+
}
|
|
224
|
+
console.log('');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (analysis.budgetViolations > 0) {
|
|
228
|
+
console.log(`⚠️ ${analysis.budgetViolations} budget violation(s) detected!\n`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
} else {
|
|
231
|
+
console.log('✅ All bundles within budget limits!\n');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Main function
|
|
237
|
+
*/
|
|
238
|
+
function main() {
|
|
239
|
+
const args = process.argv.slice(2);
|
|
240
|
+
const format = args.find(arg => arg.startsWith('--format='))?.split('=')[1] || 'console';
|
|
241
|
+
const checkBudgets = args.includes('--check-budgets');
|
|
242
|
+
|
|
243
|
+
console.log('🔍 Analyzing bundle sizes...\n');
|
|
244
|
+
|
|
245
|
+
const analysis = analyzeBundles();
|
|
246
|
+
|
|
247
|
+
switch (format) {
|
|
248
|
+
case 'json':
|
|
249
|
+
console.log(generateJsonReport(analysis));
|
|
250
|
+
break;
|
|
251
|
+
case 'markdown':
|
|
252
|
+
console.log(generateMarkdownReport(analysis));
|
|
253
|
+
break;
|
|
254
|
+
case 'console':
|
|
255
|
+
default:
|
|
256
|
+
generateConsoleReport(analysis);
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (checkBudgets && analysis.budgetViolations > 0) {
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Run if called directly
|
|
266
|
+
if (require.main === module) {
|
|
267
|
+
main();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
module.exports = { analyzeBundles, generateMarkdownReport, generateJsonReport };
|
|
271
|
+
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared utilities for copying PDF.js files
|
|
5
|
+
* Used by both postinstall.js and setup.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get the pdfjs-dist version from package.json
|
|
13
|
+
*/
|
|
14
|
+
function getPdfjsVersion() {
|
|
15
|
+
try {
|
|
16
|
+
const packageJsonPath = path.join(__dirname, '../package.json');
|
|
17
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
18
|
+
return packageJson.dependencies['pdfjs-dist'];
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return 'unknown';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the saved version from target directory
|
|
26
|
+
*/
|
|
27
|
+
function getSavedVersion(targetDir) {
|
|
28
|
+
try {
|
|
29
|
+
const versionFile = path.join(targetDir, '.version');
|
|
30
|
+
if (fs.existsSync(versionFile)) {
|
|
31
|
+
return fs.readFileSync(versionFile, 'utf8').trim();
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
// Ignore
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Copy a directory recursively
|
|
41
|
+
*/
|
|
42
|
+
function copyDirectory(src, dest) {
|
|
43
|
+
if (!fs.existsSync(src)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
48
|
+
|
|
49
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
50
|
+
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
const srcPath = path.join(src, entry.name);
|
|
53
|
+
const destPath = path.join(dest, entry.name);
|
|
54
|
+
|
|
55
|
+
if (entry.isDirectory()) {
|
|
56
|
+
copyDirectory(srcPath, destPath);
|
|
57
|
+
} else {
|
|
58
|
+
fs.copyFileSync(srcPath, destPath);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Find the pdfjs-dist package directory
|
|
67
|
+
*/
|
|
68
|
+
function findPdfjsDistPath() {
|
|
69
|
+
// Try require.resolve first (most reliable)
|
|
70
|
+
try {
|
|
71
|
+
const pdfjsPackagePath = require.resolve('pdfjs-dist/package.json');
|
|
72
|
+
return path.dirname(pdfjsPackagePath);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
// Fallback to path searching
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Start from our package's node_modules
|
|
78
|
+
let currentDir = __dirname;
|
|
79
|
+
|
|
80
|
+
// Go up to our package root
|
|
81
|
+
currentDir = path.join(currentDir, '..');
|
|
82
|
+
|
|
83
|
+
// Common locations to check
|
|
84
|
+
const searchPaths = [
|
|
85
|
+
// In the same node_modules (peer)
|
|
86
|
+
path.join(currentDir, '..', 'pdfjs-dist'),
|
|
87
|
+
// In our node_modules
|
|
88
|
+
path.join(currentDir, 'node_modules', 'pdfjs-dist'),
|
|
89
|
+
// In parent project's node_modules
|
|
90
|
+
path.join(currentDir, '..', '..', 'pdfjs-dist'),
|
|
91
|
+
// In parent project's node_modules (one more level up for monorepos)
|
|
92
|
+
path.join(currentDir, '..', '..', '..', 'pdfjs-dist'),
|
|
93
|
+
// Try from process.cwd() (user's project root)
|
|
94
|
+
path.join(process.cwd(), 'node_modules', 'pdfjs-dist'),
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
for (const searchPath of searchPaths) {
|
|
98
|
+
if (fs.existsSync(searchPath)) {
|
|
99
|
+
return searchPath;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Find the user's project root and public directory
|
|
108
|
+
*/
|
|
109
|
+
function findPublicDirectory() {
|
|
110
|
+
// Try process.cwd() first (where user ran npm install)
|
|
111
|
+
let projectRoot = process.cwd();
|
|
112
|
+
|
|
113
|
+
// Verify it's a project root (has package.json or node_modules)
|
|
114
|
+
if (!fs.existsSync(path.join(projectRoot, 'package.json')) &&
|
|
115
|
+
!fs.existsSync(path.join(projectRoot, 'node_modules'))) {
|
|
116
|
+
// Fallback: navigate up from our package location
|
|
117
|
+
let currentDir = path.join(__dirname, '..');
|
|
118
|
+
let searchDir = currentDir;
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < 5; i++) {
|
|
121
|
+
const parentDir = path.dirname(searchDir);
|
|
122
|
+
const nodeModulesDir = path.join(parentDir, 'node_modules');
|
|
123
|
+
const ourPackageDir = path.join(nodeModulesDir, '@signiphi', 'pdf-signer');
|
|
124
|
+
|
|
125
|
+
if (fs.existsSync(nodeModulesDir) && fs.existsSync(ourPackageDir)) {
|
|
126
|
+
projectRoot = parentDir;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
searchDir = parentDir;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Common public directory patterns
|
|
135
|
+
const publicDirCandidates = [
|
|
136
|
+
path.join(projectRoot, 'public'),
|
|
137
|
+
path.join(projectRoot, 'static'),
|
|
138
|
+
path.join(projectRoot, 'dist', 'public'),
|
|
139
|
+
path.join(projectRoot, 'src', 'public'),
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
for (const candidate of publicDirCandidates) {
|
|
143
|
+
if (fs.existsSync(candidate)) {
|
|
144
|
+
return candidate;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Default to public directory (will be created if it doesn't exist)
|
|
149
|
+
return path.join(projectRoot, 'public');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Copy PDF.js files to target directory
|
|
154
|
+
* @param {string} targetDir - Target directory (e.g., public/pdfjs)
|
|
155
|
+
* @param {boolean} force - Force overwrite even if up to date
|
|
156
|
+
* @returns {boolean} Success status
|
|
157
|
+
*/
|
|
158
|
+
function copyPdfJsFiles(targetDir, force = false) {
|
|
159
|
+
// Find pdfjs-dist - try require.resolve first (most reliable)
|
|
160
|
+
let pdfjsPath = null;
|
|
161
|
+
try {
|
|
162
|
+
const pdfjsPackagePath = require.resolve('pdfjs-dist/package.json');
|
|
163
|
+
pdfjsPath = path.dirname(pdfjsPackagePath);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
// Fallback to path searching
|
|
166
|
+
pdfjsPath = findPdfjsDistPath();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!pdfjsPath || !fs.existsSync(pdfjsPath)) {
|
|
170
|
+
throw new Error('pdfjs-dist package not found. Make sure it is installed.');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Check if already up to date
|
|
174
|
+
if (!force) {
|
|
175
|
+
const currentVersion = getPdfjsVersion();
|
|
176
|
+
const savedVersion = getSavedVersion(targetDir);
|
|
177
|
+
|
|
178
|
+
if (currentVersion === savedVersion && fs.existsSync(targetDir)) {
|
|
179
|
+
return false; // Already up to date
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Create target directory
|
|
184
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
185
|
+
|
|
186
|
+
// Copy build directory (contains pdf.worker.mjs and other build files)
|
|
187
|
+
const buildSrc = path.join(pdfjsPath, 'build');
|
|
188
|
+
const buildDest = path.join(targetDir, 'build');
|
|
189
|
+
if (!copyDirectory(buildSrc, buildDest)) {
|
|
190
|
+
throw new Error('Failed to copy build directory');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Copy web directory (contains pdf_viewer.mjs, css, and assets)
|
|
194
|
+
const webSrc = path.join(pdfjsPath, 'web');
|
|
195
|
+
const webDest = path.join(targetDir, 'web');
|
|
196
|
+
if (!copyDirectory(webSrc, webDest)) {
|
|
197
|
+
throw new Error('Failed to copy web directory');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Copy custom viewer.html from our package assets
|
|
201
|
+
// PDF.js 5.x no longer includes viewer.html, so we provide our own
|
|
202
|
+
const customViewerSrc = path.join(__dirname, '..', 'assets', 'viewer.html');
|
|
203
|
+
const customViewerDest = path.join(webDest, 'viewer.html');
|
|
204
|
+
|
|
205
|
+
if (fs.existsSync(customViewerSrc)) {
|
|
206
|
+
fs.copyFileSync(customViewerSrc, customViewerDest);
|
|
207
|
+
} else {
|
|
208
|
+
throw new Error('Custom viewer.html template not found in package assets');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Write version file
|
|
212
|
+
const currentVersion = getPdfjsVersion();
|
|
213
|
+
const versionFile = path.join(targetDir, '.version');
|
|
214
|
+
fs.writeFileSync(versionFile, currentVersion, 'utf8');
|
|
215
|
+
|
|
216
|
+
return true; // Copy successful
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = {
|
|
220
|
+
getPdfjsVersion,
|
|
221
|
+
getSavedVersion,
|
|
222
|
+
copyDirectory,
|
|
223
|
+
findPdfjsDistPath,
|
|
224
|
+
findPublicDirectory,
|
|
225
|
+
copyPdfJsFiles,
|
|
226
|
+
};
|
|
227
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for copy-utils.js
|
|
3
|
+
* Note: These are basic smoke tests. Full integration tests would require actual file system operations.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { describe, it, expect, beforeEach, afterEach } = require('vitest');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const copyUtils = require('./copy-utils.js');
|
|
10
|
+
|
|
11
|
+
describe('copy-utils', () => {
|
|
12
|
+
describe('getPdfjsVersion', () => {
|
|
13
|
+
it('should return a version string', () => {
|
|
14
|
+
const version = copyUtils.getPdfjsVersion();
|
|
15
|
+
expect(version).toBeDefined();
|
|
16
|
+
expect(typeof version).toBe('string');
|
|
17
|
+
// Should be a valid version or 'unknown'
|
|
18
|
+
expect(version).toMatch(/^\d+\.\d+\.\d+$|^unknown$/);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('getSavedVersion', () => {
|
|
23
|
+
const testDir = path.join(__dirname, '__test_temp__');
|
|
24
|
+
const versionFile = path.join(testDir, '.version');
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
// Create test directory
|
|
28
|
+
if (!fs.existsSync(testDir)) {
|
|
29
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
// Cleanup test directory
|
|
35
|
+
if (fs.existsSync(testDir)) {
|
|
36
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should return null if version file does not exist', () => {
|
|
41
|
+
const version = copyUtils.getSavedVersion(testDir);
|
|
42
|
+
expect(version).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return version from .version file', () => {
|
|
46
|
+
fs.writeFileSync(versionFile, '5.3.93', 'utf8');
|
|
47
|
+
const version = copyUtils.getSavedVersion(testDir);
|
|
48
|
+
expect(version).toBe('5.3.93');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should trim whitespace from version file', () => {
|
|
52
|
+
fs.writeFileSync(versionFile, ' 5.3.93 \n', 'utf8');
|
|
53
|
+
const version = copyUtils.getSavedVersion(testDir);
|
|
54
|
+
expect(version).toBe('5.3.93');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('findPdfjsDistPath', () => {
|
|
59
|
+
it('should find pdfjs-dist package', () => {
|
|
60
|
+
const pdfjsPath = copyUtils.findPdfjsDistPath();
|
|
61
|
+
// Should either find it or return null (if not installed)
|
|
62
|
+
if (pdfjsPath) {
|
|
63
|
+
expect(fs.existsSync(pdfjsPath)).toBe(true);
|
|
64
|
+
expect(pdfjsPath).toContain('pdfjs-dist');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('copyDirectory', () => {
|
|
70
|
+
const testSrcDir = path.join(__dirname, '__test_src__');
|
|
71
|
+
const testDestDir = path.join(__dirname, '__test_dest__');
|
|
72
|
+
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
// Create test source directory with sample files
|
|
75
|
+
if (!fs.existsSync(testSrcDir)) {
|
|
76
|
+
fs.mkdirSync(testSrcDir, { recursive: true });
|
|
77
|
+
fs.writeFileSync(path.join(testSrcDir, 'test.txt'), 'test content');
|
|
78
|
+
fs.mkdirSync(path.join(testSrcDir, 'subdir'), { recursive: true });
|
|
79
|
+
fs.writeFileSync(path.join(testSrcDir, 'subdir', 'nested.txt'), 'nested content');
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
afterEach(() => {
|
|
84
|
+
// Cleanup test directories
|
|
85
|
+
if (fs.existsSync(testSrcDir)) {
|
|
86
|
+
fs.rmSync(testSrcDir, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
if (fs.existsSync(testDestDir)) {
|
|
89
|
+
fs.rmSync(testDestDir, { recursive: true, force: true });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should copy directory and its contents', () => {
|
|
94
|
+
const result = copyUtils.copyDirectory(testSrcDir, testDestDir);
|
|
95
|
+
|
|
96
|
+
expect(result).toBe(true);
|
|
97
|
+
expect(fs.existsSync(testDestDir)).toBe(true);
|
|
98
|
+
expect(fs.existsSync(path.join(testDestDir, 'test.txt'))).toBe(true);
|
|
99
|
+
expect(fs.existsSync(path.join(testDestDir, 'subdir', 'nested.txt'))).toBe(true);
|
|
100
|
+
|
|
101
|
+
const content = fs.readFileSync(path.join(testDestDir, 'test.txt'), 'utf8');
|
|
102
|
+
expect(content).toBe('test content');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should return false if source does not exist', () => {
|
|
106
|
+
const result = copyUtils.copyDirectory('/nonexistent/path', testDestDir);
|
|
107
|
+
expect(result).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('copyPdfJsFiles', () => {
|
|
112
|
+
const testTargetDir = path.join(__dirname, '__test_pdfjs__');
|
|
113
|
+
|
|
114
|
+
afterEach(() => {
|
|
115
|
+
// Cleanup test directory
|
|
116
|
+
if (fs.existsSync(testTargetDir)) {
|
|
117
|
+
fs.rmSync(testTargetDir, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should handle missing pdfjs-dist gracefully', () => {
|
|
122
|
+
// This test might fail if pdfjs-dist is actually installed
|
|
123
|
+
// It's mainly to check that the function doesn't crash
|
|
124
|
+
try {
|
|
125
|
+
copyUtils.copyPdfJsFiles(testTargetDir, false);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
// Expected to throw if pdfjs-dist is not found
|
|
128
|
+
expect(error.message).toContain('pdfjs-dist');
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should not copy if already up to date', () => {
|
|
133
|
+
const pdfjsPath = copyUtils.findPdfjsDistPath();
|
|
134
|
+
if (!pdfjsPath) {
|
|
135
|
+
// Skip test if pdfjs-dist is not available
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// First copy
|
|
140
|
+
copyUtils.copyPdfJsFiles(testTargetDir, false);
|
|
141
|
+
expect(fs.existsSync(testTargetDir)).toBe(true);
|
|
142
|
+
|
|
143
|
+
// Second copy should not happen (up to date)
|
|
144
|
+
const result = copyUtils.copyPdfJsFiles(testTargetDir, false);
|
|
145
|
+
expect(result).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should force copy when force flag is true', () => {
|
|
149
|
+
const pdfjsPath = copyUtils.findPdfjsDistPath();
|
|
150
|
+
if (!pdfjsPath) {
|
|
151
|
+
// Skip test if pdfjs-dist is not available
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// First copy
|
|
156
|
+
copyUtils.copyPdfJsFiles(testTargetDir, false);
|
|
157
|
+
|
|
158
|
+
// Force copy should always happen
|
|
159
|
+
const result = copyUtils.copyPdfJsFiles(testTargetDir, true);
|
|
160
|
+
expect(result).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|