@signiphi/page-assembly 0.2.0-beta.12 → 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 +112 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -67
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css +12 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -309,24 +309,78 @@ interface ExtractedField {
|
|
|
309
309
|
signer?: string;
|
|
310
310
|
}
|
|
311
311
|
/**
|
|
312
|
-
*
|
|
312
|
+
* One field's metadata entry, as stored in the block.
|
|
313
|
+
*/
|
|
314
|
+
interface SigniphiFieldMetadata {
|
|
315
|
+
fieldId?: string;
|
|
316
|
+
label?: string;
|
|
317
|
+
signer?: string;
|
|
318
|
+
placeholder?: string;
|
|
319
|
+
required?: boolean;
|
|
320
|
+
options?: string[];
|
|
321
|
+
acknowledgements?: Array<{
|
|
322
|
+
id: string;
|
|
323
|
+
title: string;
|
|
324
|
+
description: string;
|
|
325
|
+
}>;
|
|
326
|
+
/**
|
|
327
|
+
* TEXT_LABEL only: this entry's text is already in the page stream, so the
|
|
328
|
+
* sign-time pass must not redraw it. See `mergeSourceMetadata`, which sets it
|
|
329
|
+
* when a source that had baked its labels is merged with one that deferred.
|
|
330
|
+
*/
|
|
331
|
+
textLabelBaked?: boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Persisted geometry, written by `document-prepare` for RADIO and TEXT_LABEL
|
|
334
|
+
* fields only. Declared here for ONE reason: its `page` is the SOURCE
|
|
335
|
+
* document's page number, and the merge has to rewrite it to the combined
|
|
336
|
+
* one. Nothing in page-assembly reads x/y/width/height.
|
|
337
|
+
*/
|
|
338
|
+
position?: SigniphiFieldPosition;
|
|
339
|
+
/** Radio-only, per-option. Re-paged alongside {@link SigniphiFieldMetadata.position}. */
|
|
340
|
+
radioPositions?: SigniphiFieldPosition[];
|
|
341
|
+
/** Radio-only bound list (options ↔ circle positions); its pages are re-paged too. */
|
|
342
|
+
radioOptions?: Array<{
|
|
343
|
+
label: string;
|
|
344
|
+
exportValue: string;
|
|
345
|
+
position: SigniphiFieldPosition;
|
|
346
|
+
}>;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* A persisted field rect, as `document-prepare` writes it. `page` is 1-indexed
|
|
350
|
+
* and scoped to the document it was written in — which is exactly why the merge
|
|
351
|
+
* cannot carry it across unchanged.
|
|
352
|
+
*/
|
|
353
|
+
interface SigniphiFieldPosition {
|
|
354
|
+
x: number;
|
|
355
|
+
y: number;
|
|
356
|
+
width: number;
|
|
357
|
+
height: number;
|
|
358
|
+
page: number;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* SigniphiMetadata structure stored in PDF Info dictionary.
|
|
362
|
+
*
|
|
363
|
+
* Exported because `getSigniphiMetadata` / `setSigniphiMetadata` are public
|
|
364
|
+
* (`utils/index.ts`) and a caller cannot name their argument otherwise — which
|
|
365
|
+
* is what pushed the call sites here into `as never` casts that would have
|
|
366
|
+
* silenced any future shape mismatch.
|
|
313
367
|
*/
|
|
314
368
|
interface SigniphiMetadata {
|
|
315
369
|
version: string;
|
|
316
|
-
fields: Record<string,
|
|
317
|
-
fieldId?: string;
|
|
318
|
-
label?: string;
|
|
319
|
-
signer?: string;
|
|
320
|
-
placeholder?: string;
|
|
321
|
-
required?: boolean;
|
|
322
|
-
options?: string[];
|
|
323
|
-
acknowledgements?: Array<{
|
|
324
|
-
id: string;
|
|
325
|
-
title: string;
|
|
326
|
-
description: string;
|
|
327
|
-
}>;
|
|
328
|
-
}>;
|
|
370
|
+
fields: Record<string, SigniphiFieldMetadata>;
|
|
329
371
|
fieldIdIndex?: Record<string, string>;
|
|
372
|
+
/**
|
|
373
|
+
* Document-level: radio group and option text is already drawn into the page
|
|
374
|
+
* stream, so the sign-time pass must not redraw it. Absent on legacy PDFs,
|
|
375
|
+
* which pdf-signer reads as "draw".
|
|
376
|
+
*/
|
|
377
|
+
radioLabelsBaked?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Document-level: `false` means TEXT_LABEL text was deliberately NOT baked
|
|
380
|
+
* (multi-signer), so the sign-time pass redraws it per signer. Absent/`true`
|
|
381
|
+
* means it is already in the page stream.
|
|
382
|
+
*/
|
|
383
|
+
textLabelsBaked?: boolean;
|
|
330
384
|
}
|
|
331
385
|
/**
|
|
332
386
|
* Extract SigniphiMetadata from a PDF document
|
package/dist/index.d.ts
CHANGED
|
@@ -309,24 +309,78 @@ interface ExtractedField {
|
|
|
309
309
|
signer?: string;
|
|
310
310
|
}
|
|
311
311
|
/**
|
|
312
|
-
*
|
|
312
|
+
* One field's metadata entry, as stored in the block.
|
|
313
|
+
*/
|
|
314
|
+
interface SigniphiFieldMetadata {
|
|
315
|
+
fieldId?: string;
|
|
316
|
+
label?: string;
|
|
317
|
+
signer?: string;
|
|
318
|
+
placeholder?: string;
|
|
319
|
+
required?: boolean;
|
|
320
|
+
options?: string[];
|
|
321
|
+
acknowledgements?: Array<{
|
|
322
|
+
id: string;
|
|
323
|
+
title: string;
|
|
324
|
+
description: string;
|
|
325
|
+
}>;
|
|
326
|
+
/**
|
|
327
|
+
* TEXT_LABEL only: this entry's text is already in the page stream, so the
|
|
328
|
+
* sign-time pass must not redraw it. See `mergeSourceMetadata`, which sets it
|
|
329
|
+
* when a source that had baked its labels is merged with one that deferred.
|
|
330
|
+
*/
|
|
331
|
+
textLabelBaked?: boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Persisted geometry, written by `document-prepare` for RADIO and TEXT_LABEL
|
|
334
|
+
* fields only. Declared here for ONE reason: its `page` is the SOURCE
|
|
335
|
+
* document's page number, and the merge has to rewrite it to the combined
|
|
336
|
+
* one. Nothing in page-assembly reads x/y/width/height.
|
|
337
|
+
*/
|
|
338
|
+
position?: SigniphiFieldPosition;
|
|
339
|
+
/** Radio-only, per-option. Re-paged alongside {@link SigniphiFieldMetadata.position}. */
|
|
340
|
+
radioPositions?: SigniphiFieldPosition[];
|
|
341
|
+
/** Radio-only bound list (options ↔ circle positions); its pages are re-paged too. */
|
|
342
|
+
radioOptions?: Array<{
|
|
343
|
+
label: string;
|
|
344
|
+
exportValue: string;
|
|
345
|
+
position: SigniphiFieldPosition;
|
|
346
|
+
}>;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* A persisted field rect, as `document-prepare` writes it. `page` is 1-indexed
|
|
350
|
+
* and scoped to the document it was written in — which is exactly why the merge
|
|
351
|
+
* cannot carry it across unchanged.
|
|
352
|
+
*/
|
|
353
|
+
interface SigniphiFieldPosition {
|
|
354
|
+
x: number;
|
|
355
|
+
y: number;
|
|
356
|
+
width: number;
|
|
357
|
+
height: number;
|
|
358
|
+
page: number;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* SigniphiMetadata structure stored in PDF Info dictionary.
|
|
362
|
+
*
|
|
363
|
+
* Exported because `getSigniphiMetadata` / `setSigniphiMetadata` are public
|
|
364
|
+
* (`utils/index.ts`) and a caller cannot name their argument otherwise — which
|
|
365
|
+
* is what pushed the call sites here into `as never` casts that would have
|
|
366
|
+
* silenced any future shape mismatch.
|
|
313
367
|
*/
|
|
314
368
|
interface SigniphiMetadata {
|
|
315
369
|
version: string;
|
|
316
|
-
fields: Record<string,
|
|
317
|
-
fieldId?: string;
|
|
318
|
-
label?: string;
|
|
319
|
-
signer?: string;
|
|
320
|
-
placeholder?: string;
|
|
321
|
-
required?: boolean;
|
|
322
|
-
options?: string[];
|
|
323
|
-
acknowledgements?: Array<{
|
|
324
|
-
id: string;
|
|
325
|
-
title: string;
|
|
326
|
-
description: string;
|
|
327
|
-
}>;
|
|
328
|
-
}>;
|
|
370
|
+
fields: Record<string, SigniphiFieldMetadata>;
|
|
329
371
|
fieldIdIndex?: Record<string, string>;
|
|
372
|
+
/**
|
|
373
|
+
* Document-level: radio group and option text is already drawn into the page
|
|
374
|
+
* stream, so the sign-time pass must not redraw it. Absent on legacy PDFs,
|
|
375
|
+
* which pdf-signer reads as "draw".
|
|
376
|
+
*/
|
|
377
|
+
radioLabelsBaked?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Document-level: `false` means TEXT_LABEL text was deliberately NOT baked
|
|
380
|
+
* (multi-signer), so the sign-time pass redraws it per signer. Absent/`true`
|
|
381
|
+
* means it is already in the page stream.
|
|
382
|
+
*/
|
|
383
|
+
textLabelsBaked?: boolean;
|
|
330
384
|
}
|
|
331
385
|
/**
|
|
332
386
|
* Extract SigniphiMetadata from a PDF document
|
package/dist/index.js
CHANGED
|
@@ -1399,6 +1399,51 @@ function downloadPdf(pdfBytes, filename) {
|
|
|
1399
1399
|
a.click();
|
|
1400
1400
|
URL.revokeObjectURL(url);
|
|
1401
1401
|
}
|
|
1402
|
+
function toCombinedPage(entry, page) {
|
|
1403
|
+
if (!entry.position && !entry.radioPositions && !entry.radioOptions) return entry;
|
|
1404
|
+
const carried = { ...entry };
|
|
1405
|
+
if (entry.position) carried.position = { ...entry.position, page };
|
|
1406
|
+
if (entry.radioPositions) carried.radioPositions = entry.radioPositions.map((p) => ({ ...p, page }));
|
|
1407
|
+
if (entry.radioOptions) {
|
|
1408
|
+
carried.radioOptions = entry.radioOptions.map((o) => ({ ...o, position: { ...o.position, page } }));
|
|
1409
|
+
}
|
|
1410
|
+
return carried;
|
|
1411
|
+
}
|
|
1412
|
+
function mergeSourceMetadata(sources) {
|
|
1413
|
+
const merged = { version: "1.0", fields: {}, fieldIdIndex: {} };
|
|
1414
|
+
let radioLabelsBaked;
|
|
1415
|
+
let textLabelsBaked;
|
|
1416
|
+
for (const source of sources) {
|
|
1417
|
+
const meta = source.metadata;
|
|
1418
|
+
if (!meta || source.fields.length === 0) continue;
|
|
1419
|
+
if (meta.radioLabelsBaked === false) radioLabelsBaked = false;
|
|
1420
|
+
else if (meta.radioLabelsBaked === true && radioLabelsBaked === void 0) radioLabelsBaked = true;
|
|
1421
|
+
if (meta.textLabelsBaked === false) textLabelsBaked = false;
|
|
1422
|
+
else if (meta.textLabelsBaked === true && textLabelsBaked === void 0) textLabelsBaked = true;
|
|
1423
|
+
}
|
|
1424
|
+
for (const source of sources) {
|
|
1425
|
+
const meta = source.metadata;
|
|
1426
|
+
if (!meta) continue;
|
|
1427
|
+
const sourceTextLabelsBaked = meta.textLabelsBaked !== false;
|
|
1428
|
+
for (const { name, page } of source.fields) {
|
|
1429
|
+
const key = `${name}_p${page}`;
|
|
1430
|
+
const entry = meta.fields?.[name];
|
|
1431
|
+
if (entry) {
|
|
1432
|
+
const carried = toCombinedPage(entry, page);
|
|
1433
|
+
merged.fields[key] = textLabelsBaked === false && sourceTextLabelsBaked ? { ...carried, textLabelBaked: true } : carried;
|
|
1434
|
+
}
|
|
1435
|
+
const fieldId = meta.fieldIdIndex?.[name];
|
|
1436
|
+
if (fieldId) merged.fieldIdIndex[key] = fieldId;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (radioLabelsBaked !== void 0) merged.radioLabelsBaked = radioLabelsBaked;
|
|
1440
|
+
if (textLabelsBaked !== void 0) merged.textLabelsBaked = textLabelsBaked;
|
|
1441
|
+
const hasEntries = Object.keys(merged.fields).length > 0;
|
|
1442
|
+
const hasMarkers = radioLabelsBaked !== void 0 || textLabelsBaked !== void 0;
|
|
1443
|
+
if (!hasEntries && !hasMarkers) return null;
|
|
1444
|
+
if (Object.keys(merged.fieldIdIndex).length === 0) delete merged.fieldIdIndex;
|
|
1445
|
+
return merged;
|
|
1446
|
+
}
|
|
1402
1447
|
function getSigniphiMetadata(pdfDoc) {
|
|
1403
1448
|
try {
|
|
1404
1449
|
const infoRef = pdfDoc.context.trailerInfo.Info;
|
|
@@ -1414,12 +1459,17 @@ function getSigniphiMetadata(pdfDoc) {
|
|
|
1414
1459
|
if (!metadataObj) {
|
|
1415
1460
|
return null;
|
|
1416
1461
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
jsonStr = metadataStr
|
|
1462
|
+
let jsonStr;
|
|
1463
|
+
if (typeof metadataObj.decodeText === "function") {
|
|
1464
|
+
jsonStr = metadataObj.decodeText();
|
|
1465
|
+
} else {
|
|
1466
|
+
const metadataStr = metadataObj.toString();
|
|
1467
|
+
jsonStr = metadataStr;
|
|
1468
|
+
if (metadataStr.startsWith("(") && metadataStr.endsWith(")")) {
|
|
1469
|
+
jsonStr = metadataStr.slice(1, -1);
|
|
1470
|
+
} else if (metadataStr.startsWith("<") && metadataStr.endsWith(">")) {
|
|
1471
|
+
jsonStr = metadataStr.slice(1, -1);
|
|
1472
|
+
}
|
|
1423
1473
|
}
|
|
1424
1474
|
const metadata = JSON.parse(jsonStr);
|
|
1425
1475
|
return metadata;
|
|
@@ -1612,7 +1662,7 @@ function setSigniphiMetadata(pdfDoc, metadata) {
|
|
|
1612
1662
|
}
|
|
1613
1663
|
const infoDict = infoObj;
|
|
1614
1664
|
const metadataString = JSON.stringify(metadata);
|
|
1615
|
-
infoDict.set(pdfLib.PDFName.of("SigniphiMetadata"), pdfLib.
|
|
1665
|
+
infoDict.set(pdfLib.PDFName.of("SigniphiMetadata"), pdfLib.PDFHexString.fromText(metadataString));
|
|
1616
1666
|
} catch (error) {
|
|
1617
1667
|
console.error("Failed to set Signiphi metadata:", error);
|
|
1618
1668
|
throw error;
|
|
@@ -1972,6 +2022,7 @@ function mapFieldPositionsAfterAssembly(fields, pageMapping) {
|
|
|
1972
2022
|
return pageMapping.has(mappingKey) || pageMapping.size === 0;
|
|
1973
2023
|
});
|
|
1974
2024
|
}
|
|
2025
|
+
var VISIBLE_PAGE_ROWS = 2;
|
|
1975
2026
|
var isMultiSelectModifier = (event) => {
|
|
1976
2027
|
return event.ctrlKey || event.metaKey;
|
|
1977
2028
|
};
|
|
@@ -2298,21 +2349,48 @@ var ReorderablePageGrid = ({
|
|
|
2298
2349
|
newPages.splice(hoverIndex, 0, draggedPage);
|
|
2299
2350
|
onReorderPages(file.id, newPages);
|
|
2300
2351
|
}, [file.id, file.pages, onReorderPages]);
|
|
2301
|
-
|
|
2302
|
-
|
|
2352
|
+
const gridRef = React7.useRef(null);
|
|
2353
|
+
const [maxHeight, setMaxHeight] = React7.useState(void 0);
|
|
2354
|
+
React7.useEffect(() => {
|
|
2355
|
+
const grid = gridRef.current;
|
|
2356
|
+
if (!grid || typeof ResizeObserver === "undefined") return;
|
|
2357
|
+
const measure = () => {
|
|
2358
|
+
const firstThumbnail = grid.firstElementChild;
|
|
2359
|
+
if (!firstThumbnail) return;
|
|
2360
|
+
const rowHeight = firstThumbnail.getBoundingClientRect().height;
|
|
2361
|
+
if (rowHeight <= 0) return;
|
|
2362
|
+
const rowGap = parseFloat(getComputedStyle(grid).rowGap) || 0;
|
|
2363
|
+
setMaxHeight(Math.ceil(rowHeight * VISIBLE_PAGE_ROWS + rowGap * (VISIBLE_PAGE_ROWS - 1)));
|
|
2364
|
+
};
|
|
2365
|
+
measure();
|
|
2366
|
+
const observer = new ResizeObserver(measure);
|
|
2367
|
+
observer.observe(grid);
|
|
2368
|
+
if (grid.firstElementChild) observer.observe(grid.firstElementChild);
|
|
2369
|
+
return () => observer.disconnect();
|
|
2370
|
+
}, [file.pages]);
|
|
2371
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2372
|
+
"div",
|
|
2303
2373
|
{
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2374
|
+
ref: gridRef,
|
|
2375
|
+
className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4 overflow-y-auto overflow-x-hidden",
|
|
2376
|
+
style: { maxHeight },
|
|
2377
|
+
children: file.pages.map((page, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2378
|
+
DraggablePageThumbnail,
|
|
2379
|
+
{
|
|
2380
|
+
page,
|
|
2381
|
+
fileId: file.id,
|
|
2382
|
+
index,
|
|
2383
|
+
isSelected: selectedPageIds.includes(page.id),
|
|
2384
|
+
onSingleSelect: onSingleSelectPage,
|
|
2385
|
+
onToggleSelect: onTogglePageSelect,
|
|
2386
|
+
onRangeSelect: onRangeSelectPage,
|
|
2387
|
+
movePageInFile,
|
|
2388
|
+
isDraggingPageRef
|
|
2389
|
+
},
|
|
2390
|
+
page.id
|
|
2391
|
+
))
|
|
2392
|
+
}
|
|
2393
|
+
);
|
|
2316
2394
|
};
|
|
2317
2395
|
var FileDropZone = ({
|
|
2318
2396
|
targetIndex,
|
|
@@ -2897,7 +2975,7 @@ var PageAssembler = React7.forwardRef(
|
|
|
2897
2975
|
setIsLoading(true);
|
|
2898
2976
|
setProcessingStatus("Assembling PDF...");
|
|
2899
2977
|
try {
|
|
2900
|
-
const { PDFDocument: PDFDocument5, PDFName: PDFName4
|
|
2978
|
+
const { PDFDocument: PDFDocument5, PDFName: PDFName4 } = await import('pdf-lib');
|
|
2901
2979
|
const loadedPdfs = /* @__PURE__ */ new Map();
|
|
2902
2980
|
const fileMap = /* @__PURE__ */ new Map();
|
|
2903
2981
|
const pdfFiles = state.files.filter((f) => f.type === "pdf" && f.originalBytes?.length > 0);
|
|
@@ -2976,11 +3054,7 @@ var PageAssembler = React7.forwardRef(
|
|
|
2976
3054
|
}
|
|
2977
3055
|
console.log("[PageAssembler] Starting multi-PDF assembly with field preservation");
|
|
2978
3056
|
const allExtractedFields = [];
|
|
2979
|
-
const
|
|
2980
|
-
version: "1.0",
|
|
2981
|
-
fields: {},
|
|
2982
|
-
fieldIdIndex: {}
|
|
2983
|
-
};
|
|
3057
|
+
const metadataSources = [];
|
|
2984
3058
|
const filePageUsage = /* @__PURE__ */ new Map();
|
|
2985
3059
|
for (const file of state.files) {
|
|
2986
3060
|
for (const page of file.pages) {
|
|
@@ -3005,28 +3079,12 @@ var PageAssembler = React7.forwardRef(
|
|
|
3005
3079
|
}
|
|
3006
3080
|
console.log("[PageAssembler] Page mapping:", Object.fromEntries(pageIdToNewPageNumber));
|
|
3007
3081
|
const extractAndMapFields = async (fileId, fileName, pdfBytes2, sourcePdf) => {
|
|
3008
|
-
|
|
3009
|
-
if (sourcePdf) {
|
|
3010
|
-
|
|
3011
|
-
const sourceInfoRef = sourcePdf.context.trailerInfo.Info;
|
|
3012
|
-
if (sourceInfoRef) {
|
|
3013
|
-
const sourceInfoDict = sourcePdf.context.lookup(sourceInfoRef);
|
|
3014
|
-
if (sourceInfoDict && typeof sourceInfoDict.get === "function") {
|
|
3015
|
-
const metadataObj = sourceInfoDict.get(PDFName4.of("SigniphiMetadata"));
|
|
3016
|
-
if (metadataObj) {
|
|
3017
|
-
const metadataStr = metadataObj.toString();
|
|
3018
|
-
let jsonStr = metadataStr;
|
|
3019
|
-
if (metadataStr.startsWith("(") && metadataStr.endsWith(")")) {
|
|
3020
|
-
jsonStr = metadataStr.slice(1, -1);
|
|
3021
|
-
}
|
|
3022
|
-
sourceMetadata = JSON.parse(jsonStr);
|
|
3023
|
-
}
|
|
3024
|
-
}
|
|
3025
|
-
}
|
|
3026
|
-
} catch (metadataError) {
|
|
3027
|
-
console.warn(`Could not read metadata from PDF ${fileName}:`, metadataError);
|
|
3028
|
-
}
|
|
3082
|
+
const sourceMetadata = sourcePdf ? getSigniphiMetadata(sourcePdf) : null;
|
|
3083
|
+
if (sourcePdf && !sourceMetadata) {
|
|
3084
|
+
console.warn(`[PageAssembler] No readable SigniphiMetadata in "${fileName}"`);
|
|
3029
3085
|
}
|
|
3086
|
+
const placements = [];
|
|
3087
|
+
metadataSources.push({ metadata: sourceMetadata, fields: placements });
|
|
3030
3088
|
console.log(`[PageAssembler] Extracting fields from "${fileName}"`);
|
|
3031
3089
|
const extractedFields = await extractFieldsFromPdf(pdfBytes2);
|
|
3032
3090
|
console.log(`[PageAssembler] Found ${extractedFields.length} fields in "${fileName}"`);
|
|
@@ -3060,13 +3118,7 @@ var PageAssembler = React7.forwardRef(
|
|
|
3060
3118
|
};
|
|
3061
3119
|
allExtractedFields.push(trackedField);
|
|
3062
3120
|
console.log(`[PageAssembler] Mapped field "${field.name}" from page ${originalPage} to page ${newPageNumber}`);
|
|
3063
|
-
|
|
3064
|
-
if (sourceMetadata?.fields?.[field.name]) {
|
|
3065
|
-
mergedMetadata.fields[metadataKey] = sourceMetadata.fields[field.name];
|
|
3066
|
-
}
|
|
3067
|
-
if (sourceMetadata?.fieldIdIndex?.[field.name]) {
|
|
3068
|
-
mergedMetadata.fieldIdIndex[metadataKey] = sourceMetadata.fieldIdIndex[field.name];
|
|
3069
|
-
}
|
|
3121
|
+
placements.push({ name: field.name, page: newPageNumber });
|
|
3070
3122
|
}
|
|
3071
3123
|
}
|
|
3072
3124
|
}
|
|
@@ -3144,21 +3196,15 @@ var PageAssembler = React7.forwardRef(
|
|
|
3144
3196
|
}
|
|
3145
3197
|
}
|
|
3146
3198
|
}
|
|
3147
|
-
|
|
3199
|
+
const mergedMetadata = mergeSourceMetadata(metadataSources);
|
|
3200
|
+
if (mergedMetadata) {
|
|
3148
3201
|
try {
|
|
3149
|
-
|
|
3150
|
-
if (newInfoRef) {
|
|
3151
|
-
const newInfoDict = combinedDoc.context.lookup(newInfoRef);
|
|
3152
|
-
if (newInfoDict && typeof newInfoDict.set === "function") {
|
|
3153
|
-
newInfoDict.set(
|
|
3154
|
-
PDFName4.of("SigniphiMetadata"),
|
|
3155
|
-
PDFString4.of(JSON.stringify(mergedMetadata))
|
|
3156
|
-
);
|
|
3157
|
-
}
|
|
3158
|
-
}
|
|
3202
|
+
setSigniphiMetadata(combinedDoc, mergedMetadata);
|
|
3159
3203
|
} catch (metadataError) {
|
|
3160
3204
|
console.warn("Could not write merged metadata:", metadataError);
|
|
3161
3205
|
}
|
|
3206
|
+
} else {
|
|
3207
|
+
console.warn("[PageAssembler] No source metadata survived the merge; the assembled document will read as unprepared downstream");
|
|
3162
3208
|
}
|
|
3163
3209
|
let pdfBytes = await combinedDoc.save();
|
|
3164
3210
|
if (allExtractedFields.length > 0) {
|