@signiphi/page-assembly 0.2.0-beta.13 → 0.2.0-beta.14
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/dist/index.d.mts +68 -14
- package/dist/index.d.ts +68 -14
- package/dist/index.js +70 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -53
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css +6 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
|
14
14
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
15
15
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
16
16
|
import * as pdfjsLib from 'pdfjs-dist';
|
|
17
|
-
import { PDFDocument, PDFTextField, PDFCheckBox, PDFDropdown, PDFRadioGroup, StandardFonts, rgb,
|
|
17
|
+
import { PDFDocument, PDFName, PDFTextField, PDFCheckBox, PDFDropdown, PDFRadioGroup, PDFHexString, StandardFonts, rgb, PDFString, PDFDict, PDFArray, PDFInvalidObject, PDFObjectParser, PDFRawStream, PDFObjectStreamParser, PDFRef, PDFBool, PDFNumber } from 'pdf-lib';
|
|
18
18
|
|
|
19
19
|
// src/components/PageAssembler.tsx
|
|
20
20
|
function cn(...inputs) {
|
|
@@ -1372,6 +1372,51 @@ function downloadPdf(pdfBytes, filename) {
|
|
|
1372
1372
|
a.click();
|
|
1373
1373
|
URL.revokeObjectURL(url);
|
|
1374
1374
|
}
|
|
1375
|
+
function toCombinedPage(entry, page) {
|
|
1376
|
+
if (!entry.position && !entry.radioPositions && !entry.radioOptions) return entry;
|
|
1377
|
+
const carried = { ...entry };
|
|
1378
|
+
if (entry.position) carried.position = { ...entry.position, page };
|
|
1379
|
+
if (entry.radioPositions) carried.radioPositions = entry.radioPositions.map((p) => ({ ...p, page }));
|
|
1380
|
+
if (entry.radioOptions) {
|
|
1381
|
+
carried.radioOptions = entry.radioOptions.map((o) => ({ ...o, position: { ...o.position, page } }));
|
|
1382
|
+
}
|
|
1383
|
+
return carried;
|
|
1384
|
+
}
|
|
1385
|
+
function mergeSourceMetadata(sources) {
|
|
1386
|
+
const merged = { version: "1.0", fields: {}, fieldIdIndex: {} };
|
|
1387
|
+
let radioLabelsBaked;
|
|
1388
|
+
let textLabelsBaked;
|
|
1389
|
+
for (const source of sources) {
|
|
1390
|
+
const meta = source.metadata;
|
|
1391
|
+
if (!meta || source.fields.length === 0) continue;
|
|
1392
|
+
if (meta.radioLabelsBaked === false) radioLabelsBaked = false;
|
|
1393
|
+
else if (meta.radioLabelsBaked === true && radioLabelsBaked === void 0) radioLabelsBaked = true;
|
|
1394
|
+
if (meta.textLabelsBaked === false) textLabelsBaked = false;
|
|
1395
|
+
else if (meta.textLabelsBaked === true && textLabelsBaked === void 0) textLabelsBaked = true;
|
|
1396
|
+
}
|
|
1397
|
+
for (const source of sources) {
|
|
1398
|
+
const meta = source.metadata;
|
|
1399
|
+
if (!meta) continue;
|
|
1400
|
+
const sourceTextLabelsBaked = meta.textLabelsBaked !== false;
|
|
1401
|
+
for (const { name, page } of source.fields) {
|
|
1402
|
+
const key = `${name}_p${page}`;
|
|
1403
|
+
const entry = meta.fields?.[name];
|
|
1404
|
+
if (entry) {
|
|
1405
|
+
const carried = toCombinedPage(entry, page);
|
|
1406
|
+
merged.fields[key] = textLabelsBaked === false && sourceTextLabelsBaked ? { ...carried, textLabelBaked: true } : carried;
|
|
1407
|
+
}
|
|
1408
|
+
const fieldId = meta.fieldIdIndex?.[name];
|
|
1409
|
+
if (fieldId) merged.fieldIdIndex[key] = fieldId;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
if (radioLabelsBaked !== void 0) merged.radioLabelsBaked = radioLabelsBaked;
|
|
1413
|
+
if (textLabelsBaked !== void 0) merged.textLabelsBaked = textLabelsBaked;
|
|
1414
|
+
const hasEntries = Object.keys(merged.fields).length > 0;
|
|
1415
|
+
const hasMarkers = radioLabelsBaked !== void 0 || textLabelsBaked !== void 0;
|
|
1416
|
+
if (!hasEntries && !hasMarkers) return null;
|
|
1417
|
+
if (Object.keys(merged.fieldIdIndex).length === 0) delete merged.fieldIdIndex;
|
|
1418
|
+
return merged;
|
|
1419
|
+
}
|
|
1375
1420
|
function getSigniphiMetadata(pdfDoc) {
|
|
1376
1421
|
try {
|
|
1377
1422
|
const infoRef = pdfDoc.context.trailerInfo.Info;
|
|
@@ -1387,12 +1432,17 @@ function getSigniphiMetadata(pdfDoc) {
|
|
|
1387
1432
|
if (!metadataObj) {
|
|
1388
1433
|
return null;
|
|
1389
1434
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
jsonStr = metadataStr
|
|
1435
|
+
let jsonStr;
|
|
1436
|
+
if (typeof metadataObj.decodeText === "function") {
|
|
1437
|
+
jsonStr = metadataObj.decodeText();
|
|
1438
|
+
} else {
|
|
1439
|
+
const metadataStr = metadataObj.toString();
|
|
1440
|
+
jsonStr = metadataStr;
|
|
1441
|
+
if (metadataStr.startsWith("(") && metadataStr.endsWith(")")) {
|
|
1442
|
+
jsonStr = metadataStr.slice(1, -1);
|
|
1443
|
+
} else if (metadataStr.startsWith("<") && metadataStr.endsWith(">")) {
|
|
1444
|
+
jsonStr = metadataStr.slice(1, -1);
|
|
1445
|
+
}
|
|
1396
1446
|
}
|
|
1397
1447
|
const metadata = JSON.parse(jsonStr);
|
|
1398
1448
|
return metadata;
|
|
@@ -1585,7 +1635,7 @@ function setSigniphiMetadata(pdfDoc, metadata) {
|
|
|
1585
1635
|
}
|
|
1586
1636
|
const infoDict = infoObj;
|
|
1587
1637
|
const metadataString = JSON.stringify(metadata);
|
|
1588
|
-
infoDict.set(PDFName.of("SigniphiMetadata"),
|
|
1638
|
+
infoDict.set(PDFName.of("SigniphiMetadata"), PDFHexString.fromText(metadataString));
|
|
1589
1639
|
} catch (error) {
|
|
1590
1640
|
console.error("Failed to set Signiphi metadata:", error);
|
|
1591
1641
|
throw error;
|
|
@@ -2898,7 +2948,7 @@ var PageAssembler = forwardRef(
|
|
|
2898
2948
|
setIsLoading(true);
|
|
2899
2949
|
setProcessingStatus("Assembling PDF...");
|
|
2900
2950
|
try {
|
|
2901
|
-
const { PDFDocument: PDFDocument5, PDFName: PDFName4
|
|
2951
|
+
const { PDFDocument: PDFDocument5, PDFName: PDFName4 } = await import('pdf-lib');
|
|
2902
2952
|
const loadedPdfs = /* @__PURE__ */ new Map();
|
|
2903
2953
|
const fileMap = /* @__PURE__ */ new Map();
|
|
2904
2954
|
const pdfFiles = state.files.filter((f) => f.type === "pdf" && f.originalBytes?.length > 0);
|
|
@@ -2977,11 +3027,7 @@ var PageAssembler = forwardRef(
|
|
|
2977
3027
|
}
|
|
2978
3028
|
console.log("[PageAssembler] Starting multi-PDF assembly with field preservation");
|
|
2979
3029
|
const allExtractedFields = [];
|
|
2980
|
-
const
|
|
2981
|
-
version: "1.0",
|
|
2982
|
-
fields: {},
|
|
2983
|
-
fieldIdIndex: {}
|
|
2984
|
-
};
|
|
3030
|
+
const metadataSources = [];
|
|
2985
3031
|
const filePageUsage = /* @__PURE__ */ new Map();
|
|
2986
3032
|
for (const file of state.files) {
|
|
2987
3033
|
for (const page of file.pages) {
|
|
@@ -3006,28 +3052,12 @@ var PageAssembler = forwardRef(
|
|
|
3006
3052
|
}
|
|
3007
3053
|
console.log("[PageAssembler] Page mapping:", Object.fromEntries(pageIdToNewPageNumber));
|
|
3008
3054
|
const extractAndMapFields = async (fileId, fileName, pdfBytes2, sourcePdf) => {
|
|
3009
|
-
|
|
3010
|
-
if (sourcePdf) {
|
|
3011
|
-
|
|
3012
|
-
const sourceInfoRef = sourcePdf.context.trailerInfo.Info;
|
|
3013
|
-
if (sourceInfoRef) {
|
|
3014
|
-
const sourceInfoDict = sourcePdf.context.lookup(sourceInfoRef);
|
|
3015
|
-
if (sourceInfoDict && typeof sourceInfoDict.get === "function") {
|
|
3016
|
-
const metadataObj = sourceInfoDict.get(PDFName4.of("SigniphiMetadata"));
|
|
3017
|
-
if (metadataObj) {
|
|
3018
|
-
const metadataStr = metadataObj.toString();
|
|
3019
|
-
let jsonStr = metadataStr;
|
|
3020
|
-
if (metadataStr.startsWith("(") && metadataStr.endsWith(")")) {
|
|
3021
|
-
jsonStr = metadataStr.slice(1, -1);
|
|
3022
|
-
}
|
|
3023
|
-
sourceMetadata = JSON.parse(jsonStr);
|
|
3024
|
-
}
|
|
3025
|
-
}
|
|
3026
|
-
}
|
|
3027
|
-
} catch (metadataError) {
|
|
3028
|
-
console.warn(`Could not read metadata from PDF ${fileName}:`, metadataError);
|
|
3029
|
-
}
|
|
3055
|
+
const sourceMetadata = sourcePdf ? getSigniphiMetadata(sourcePdf) : null;
|
|
3056
|
+
if (sourcePdf && !sourceMetadata) {
|
|
3057
|
+
console.warn(`[PageAssembler] No readable SigniphiMetadata in "${fileName}"`);
|
|
3030
3058
|
}
|
|
3059
|
+
const placements = [];
|
|
3060
|
+
metadataSources.push({ metadata: sourceMetadata, fields: placements });
|
|
3031
3061
|
console.log(`[PageAssembler] Extracting fields from "${fileName}"`);
|
|
3032
3062
|
const extractedFields = await extractFieldsFromPdf(pdfBytes2);
|
|
3033
3063
|
console.log(`[PageAssembler] Found ${extractedFields.length} fields in "${fileName}"`);
|
|
@@ -3061,13 +3091,7 @@ var PageAssembler = forwardRef(
|
|
|
3061
3091
|
};
|
|
3062
3092
|
allExtractedFields.push(trackedField);
|
|
3063
3093
|
console.log(`[PageAssembler] Mapped field "${field.name}" from page ${originalPage} to page ${newPageNumber}`);
|
|
3064
|
-
|
|
3065
|
-
if (sourceMetadata?.fields?.[field.name]) {
|
|
3066
|
-
mergedMetadata.fields[metadataKey] = sourceMetadata.fields[field.name];
|
|
3067
|
-
}
|
|
3068
|
-
if (sourceMetadata?.fieldIdIndex?.[field.name]) {
|
|
3069
|
-
mergedMetadata.fieldIdIndex[metadataKey] = sourceMetadata.fieldIdIndex[field.name];
|
|
3070
|
-
}
|
|
3094
|
+
placements.push({ name: field.name, page: newPageNumber });
|
|
3071
3095
|
}
|
|
3072
3096
|
}
|
|
3073
3097
|
}
|
|
@@ -3145,21 +3169,15 @@ var PageAssembler = forwardRef(
|
|
|
3145
3169
|
}
|
|
3146
3170
|
}
|
|
3147
3171
|
}
|
|
3148
|
-
|
|
3172
|
+
const mergedMetadata = mergeSourceMetadata(metadataSources);
|
|
3173
|
+
if (mergedMetadata) {
|
|
3149
3174
|
try {
|
|
3150
|
-
|
|
3151
|
-
if (newInfoRef) {
|
|
3152
|
-
const newInfoDict = combinedDoc.context.lookup(newInfoRef);
|
|
3153
|
-
if (newInfoDict && typeof newInfoDict.set === "function") {
|
|
3154
|
-
newInfoDict.set(
|
|
3155
|
-
PDFName4.of("SigniphiMetadata"),
|
|
3156
|
-
PDFString4.of(JSON.stringify(mergedMetadata))
|
|
3157
|
-
);
|
|
3158
|
-
}
|
|
3159
|
-
}
|
|
3175
|
+
setSigniphiMetadata(combinedDoc, mergedMetadata);
|
|
3160
3176
|
} catch (metadataError) {
|
|
3161
3177
|
console.warn("Could not write merged metadata:", metadataError);
|
|
3162
3178
|
}
|
|
3179
|
+
} else {
|
|
3180
|
+
console.warn("[PageAssembler] No source metadata survived the merge; the assembled document will read as unprepared downstream");
|
|
3163
3181
|
}
|
|
3164
3182
|
let pdfBytes = await combinedDoc.save();
|
|
3165
3183
|
if (allExtractedFields.length > 0) {
|