@signiphi/page-assembly 0.2.0-beta.10 → 0.2.0-beta.11
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 +31 -8
- package/dist/index.d.ts +31 -8
- package/dist/index.js +63 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -22
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css +3 -73
- package/package.json +5 -2
package/dist/index.d.mts
CHANGED
|
@@ -238,15 +238,34 @@ declare function createPdfBlobUrl(pdfBytes: Uint8Array): string;
|
|
|
238
238
|
*/
|
|
239
239
|
declare function downloadPdf(pdfBytes: Uint8Array, filename: string): void;
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
interface PdfPasswordRequiredErrorConstructor {
|
|
242
|
+
new (): PdfPasswordRequiredError;
|
|
243
|
+
readonly prototype: PdfPasswordRequiredError;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Thrown when the PDF needs a non-empty user password, which this package
|
|
247
|
+
* cannot supply. Match it with {@link isPdfPasswordRequiredError} rather than
|
|
248
|
+
* `instanceof` — see the header note on copies.
|
|
249
|
+
*/
|
|
250
|
+
interface PdfPasswordRequiredError extends Error {
|
|
251
|
+
/** Always `'PDF_PASSWORD_REQUIRED'`. The check that survives package boundaries. */
|
|
242
252
|
code: string;
|
|
243
253
|
recoverable: boolean;
|
|
244
254
|
userMessage: string;
|
|
245
|
-
constructor();
|
|
246
255
|
}
|
|
247
|
-
declare
|
|
248
|
-
|
|
256
|
+
declare const PdfPasswordRequiredError: PdfPasswordRequiredErrorConstructor;
|
|
257
|
+
interface UnsupportedPdfEncryptionErrorConstructor {
|
|
258
|
+
new (detail: string): UnsupportedPdfEncryptionError;
|
|
259
|
+
readonly prototype: UnsupportedPdfEncryptionError;
|
|
260
|
+
}
|
|
261
|
+
/** Thrown for security handlers this decryptor does not implement. */
|
|
262
|
+
interface UnsupportedPdfEncryptionError extends Error {
|
|
263
|
+
/** Always `'UnsupportedPdfEncryptionError'`. */
|
|
264
|
+
name: string;
|
|
265
|
+
/** The scheme that is not supported, e.g. `'V5 /R6'`. */
|
|
266
|
+
readonly detail: string;
|
|
249
267
|
}
|
|
268
|
+
declare const UnsupportedPdfEncryptionError: UnsupportedPdfEncryptionErrorConstructor;
|
|
250
269
|
/**
|
|
251
270
|
* Decrypt an encrypted PDF that opens with an empty user password.
|
|
252
271
|
* Returns re-saved, fully decrypted bytes with `/Encrypt` removed.
|
|
@@ -254,11 +273,15 @@ declare class UnsupportedPdfEncryptionError extends Error {
|
|
|
254
273
|
* @throws {PdfPasswordRequiredError} when a non-empty password is required
|
|
255
274
|
* @throws {UnsupportedPdfEncryptionError} for non-standard security handlers
|
|
256
275
|
*/
|
|
257
|
-
declare
|
|
276
|
+
declare const decryptPdf: (pdfBytes: Uint8Array) => Promise<Uint8Array>;
|
|
258
277
|
/**
|
|
259
|
-
* Ingestion gate
|
|
260
|
-
*
|
|
261
|
-
*
|
|
278
|
+
* Ingestion gate — see `@signiphi/pdf-crypto`'s `normalizePdfEncryption`.
|
|
279
|
+
* Returns the bytes untouched (same reference) for ordinary PDFs; decrypts and
|
|
280
|
+
* re-saves encrypted ones so every downstream `PDFDocument.load` (page
|
|
281
|
+
* assembly, field extraction) sees a normal document.
|
|
282
|
+
*
|
|
283
|
+
* @throws {PdfPasswordRequiredError} when a non-empty password is required
|
|
284
|
+
* @throws {UnsupportedPdfEncryptionError} for non-standard security handlers
|
|
262
285
|
*/
|
|
263
286
|
declare function normalizePdfEncryption(pdfBytes: Uint8Array): Promise<Uint8Array>;
|
|
264
287
|
|
package/dist/index.d.ts
CHANGED
|
@@ -238,15 +238,34 @@ declare function createPdfBlobUrl(pdfBytes: Uint8Array): string;
|
|
|
238
238
|
*/
|
|
239
239
|
declare function downloadPdf(pdfBytes: Uint8Array, filename: string): void;
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
interface PdfPasswordRequiredErrorConstructor {
|
|
242
|
+
new (): PdfPasswordRequiredError;
|
|
243
|
+
readonly prototype: PdfPasswordRequiredError;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Thrown when the PDF needs a non-empty user password, which this package
|
|
247
|
+
* cannot supply. Match it with {@link isPdfPasswordRequiredError} rather than
|
|
248
|
+
* `instanceof` — see the header note on copies.
|
|
249
|
+
*/
|
|
250
|
+
interface PdfPasswordRequiredError extends Error {
|
|
251
|
+
/** Always `'PDF_PASSWORD_REQUIRED'`. The check that survives package boundaries. */
|
|
242
252
|
code: string;
|
|
243
253
|
recoverable: boolean;
|
|
244
254
|
userMessage: string;
|
|
245
|
-
constructor();
|
|
246
255
|
}
|
|
247
|
-
declare
|
|
248
|
-
|
|
256
|
+
declare const PdfPasswordRequiredError: PdfPasswordRequiredErrorConstructor;
|
|
257
|
+
interface UnsupportedPdfEncryptionErrorConstructor {
|
|
258
|
+
new (detail: string): UnsupportedPdfEncryptionError;
|
|
259
|
+
readonly prototype: UnsupportedPdfEncryptionError;
|
|
260
|
+
}
|
|
261
|
+
/** Thrown for security handlers this decryptor does not implement. */
|
|
262
|
+
interface UnsupportedPdfEncryptionError extends Error {
|
|
263
|
+
/** Always `'UnsupportedPdfEncryptionError'`. */
|
|
264
|
+
name: string;
|
|
265
|
+
/** The scheme that is not supported, e.g. `'V5 /R6'`. */
|
|
266
|
+
readonly detail: string;
|
|
249
267
|
}
|
|
268
|
+
declare const UnsupportedPdfEncryptionError: UnsupportedPdfEncryptionErrorConstructor;
|
|
250
269
|
/**
|
|
251
270
|
* Decrypt an encrypted PDF that opens with an empty user password.
|
|
252
271
|
* Returns re-saved, fully decrypted bytes with `/Encrypt` removed.
|
|
@@ -254,11 +273,15 @@ declare class UnsupportedPdfEncryptionError extends Error {
|
|
|
254
273
|
* @throws {PdfPasswordRequiredError} when a non-empty password is required
|
|
255
274
|
* @throws {UnsupportedPdfEncryptionError} for non-standard security handlers
|
|
256
275
|
*/
|
|
257
|
-
declare
|
|
276
|
+
declare const decryptPdf: (pdfBytes: Uint8Array) => Promise<Uint8Array>;
|
|
258
277
|
/**
|
|
259
|
-
* Ingestion gate
|
|
260
|
-
*
|
|
261
|
-
*
|
|
278
|
+
* Ingestion gate — see `@signiphi/pdf-crypto`'s `normalizePdfEncryption`.
|
|
279
|
+
* Returns the bytes untouched (same reference) for ordinary PDFs; decrypts and
|
|
280
|
+
* re-saves encrypted ones so every downstream `PDFDocument.load` (page
|
|
281
|
+
* assembly, field extraction) sees a normal document.
|
|
282
|
+
*
|
|
283
|
+
* @throws {PdfPasswordRequiredError} when a non-empty password is required
|
|
284
|
+
* @throws {UnsupportedPdfEncryptionError} for non-standard security handlers
|
|
262
285
|
*/
|
|
263
286
|
declare function normalizePdfEncryption(pdfBytes: Uint8Array): Promise<Uint8Array>;
|
|
264
287
|
|
package/dist/index.js
CHANGED
|
@@ -43,9 +43,7 @@ var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMe
|
|
|
43
43
|
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
44
44
|
var pdfjsLib__namespace = /*#__PURE__*/_interopNamespace(pdfjsLib);
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
48
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
46
|
+
// src/components/PageAssembler.tsx
|
|
49
47
|
function cn(...inputs) {
|
|
50
48
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
51
49
|
}
|
|
@@ -580,9 +578,8 @@ var PdfPasswordRequiredError = class extends Error {
|
|
|
580
578
|
constructor() {
|
|
581
579
|
const message = "This PDF is password-protected. Please remove the password and upload it again.";
|
|
582
580
|
super(message);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
__publicField(this, "userMessage");
|
|
581
|
+
this.code = "PDF_PASSWORD_REQUIRED";
|
|
582
|
+
this.recoverable = true;
|
|
586
583
|
this.name = "PdfPasswordRequiredError";
|
|
587
584
|
this.userMessage = message;
|
|
588
585
|
}
|
|
@@ -591,6 +588,7 @@ var UnsupportedPdfEncryptionError = class extends Error {
|
|
|
591
588
|
constructor(detail) {
|
|
592
589
|
super(`This PDF uses an unsupported encryption scheme (${detail}).`);
|
|
593
590
|
this.name = "UnsupportedPdfEncryptionError";
|
|
591
|
+
this.detail = detail;
|
|
594
592
|
}
|
|
595
593
|
};
|
|
596
594
|
function concatBytes(...parts) {
|
|
@@ -1128,30 +1126,70 @@ async function decryptPdf(pdfBytes) {
|
|
|
1128
1126
|
if (!doc.isEncrypted) return pdfBytes;
|
|
1129
1127
|
return decryptLoadedDocument(doc);
|
|
1130
1128
|
}
|
|
1131
|
-
var
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1129
|
+
var SLASH = 47;
|
|
1130
|
+
var HASH = 35;
|
|
1131
|
+
var ENCRYPT_NAME = "Encrypt";
|
|
1132
|
+
function hexDigit(byte) {
|
|
1133
|
+
if (byte === void 0) return -1;
|
|
1134
|
+
if (byte >= 48 && byte <= 57) return byte - 48;
|
|
1135
|
+
if (byte >= 65 && byte <= 70) return byte - 65 + 10;
|
|
1136
|
+
if (byte >= 97 && byte <= 102) return byte - 97 + 10;
|
|
1137
|
+
return -1;
|
|
1138
|
+
}
|
|
1139
|
+
function matchesEncryptNameAt(bytes, start) {
|
|
1140
|
+
let at = start;
|
|
1141
|
+
for (let k = 0; k < ENCRYPT_NAME.length; k++) {
|
|
1142
|
+
const want = ENCRYPT_NAME.charCodeAt(k);
|
|
1143
|
+
const byte = bytes[at];
|
|
1144
|
+
if (byte === want) {
|
|
1145
|
+
at += 1;
|
|
1146
|
+
continue;
|
|
1137
1147
|
}
|
|
1138
|
-
|
|
1148
|
+
if (byte === HASH) {
|
|
1149
|
+
const high = hexDigit(bytes[at + 1]);
|
|
1150
|
+
const low = hexDigit(bytes[at + 2]);
|
|
1151
|
+
if (high >= 0 && low >= 0 && (high << 4 | low) === want) {
|
|
1152
|
+
at += 3;
|
|
1153
|
+
continue;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
return true;
|
|
1159
|
+
}
|
|
1160
|
+
function containsEncryptMarker(bytes) {
|
|
1161
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1162
|
+
if (bytes[i] !== SLASH) continue;
|
|
1163
|
+
if (matchesEncryptNameAt(bytes, i + 1)) return true;
|
|
1139
1164
|
}
|
|
1140
1165
|
return false;
|
|
1141
1166
|
}
|
|
1142
|
-
async function normalizePdfEncryption(pdfBytes) {
|
|
1167
|
+
async function normalizePdfEncryption(pdfBytes, options) {
|
|
1143
1168
|
if (!containsEncryptMarker(pdfBytes)) return pdfBytes;
|
|
1144
1169
|
const doc = await pdfLib.PDFDocument.load(pdfBytes.slice(), {
|
|
1145
1170
|
ignoreEncryption: true,
|
|
1146
1171
|
updateMetadata: false
|
|
1147
1172
|
});
|
|
1148
1173
|
if (!doc.isEncrypted) return pdfBytes;
|
|
1149
|
-
|
|
1150
|
-
console.info("[PageAssembler] Encrypted PDF detected during ingestion; decrypting");
|
|
1151
|
-
}
|
|
1174
|
+
options?.logger?.info("[PDF_DECRYPT] Encrypted PDF detected during ingestion; decrypting");
|
|
1152
1175
|
return decryptLoadedDocument(doc);
|
|
1153
1176
|
}
|
|
1154
1177
|
|
|
1178
|
+
// src/utils/pdf-decrypt.ts
|
|
1179
|
+
var PdfPasswordRequiredError2 = PdfPasswordRequiredError;
|
|
1180
|
+
var UnsupportedPdfEncryptionError2 = UnsupportedPdfEncryptionError;
|
|
1181
|
+
var decryptPdf2 = decryptPdf;
|
|
1182
|
+
var consoleLogger = {
|
|
1183
|
+
info(message, ...args) {
|
|
1184
|
+
if (typeof process === "undefined" || process.env?.NODE_ENV !== "production") {
|
|
1185
|
+
console.info(`[PageAssembler] ${message}`, ...args);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
function normalizePdfEncryption2(pdfBytes) {
|
|
1190
|
+
return normalizePdfEncryption(pdfBytes, { logger: consoleLogger });
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1155
1193
|
// src/utils/pdf-helpers.ts
|
|
1156
1194
|
if (typeof window !== "undefined") {
|
|
1157
1195
|
pdfjsLib__namespace.GlobalWorkerOptions.workerSrc = "/pdfjs/build/pdf.worker.mjs";
|
|
@@ -1243,7 +1281,7 @@ async function rasterizePdfToPdf(pdfBytes) {
|
|
|
1243
1281
|
sourceDoc = await pdfjsLib__namespace.getDocument({ data: pdfBytes.slice(0), verbosity: 0 }).promise;
|
|
1244
1282
|
} catch (error) {
|
|
1245
1283
|
if (error?.name === "PasswordException") {
|
|
1246
|
-
throw new
|
|
1284
|
+
throw new PdfPasswordRequiredError2();
|
|
1247
1285
|
}
|
|
1248
1286
|
throw error;
|
|
1249
1287
|
}
|
|
@@ -1275,10 +1313,10 @@ async function rasterizePdfToPdf(pdfBytes) {
|
|
|
1275
1313
|
}
|
|
1276
1314
|
async function normalizeUploadedPdfBytes(pdfBytes) {
|
|
1277
1315
|
try {
|
|
1278
|
-
const normalized = await
|
|
1316
|
+
const normalized = await normalizePdfEncryption2(pdfBytes);
|
|
1279
1317
|
return normalized === pdfBytes ? pdfBytes : new Uint8Array(normalized);
|
|
1280
1318
|
} catch (error) {
|
|
1281
|
-
if (error instanceof
|
|
1319
|
+
if (error instanceof PdfPasswordRequiredError2) throw error;
|
|
1282
1320
|
console.warn(
|
|
1283
1321
|
"[PageAssembler] Structural decryption failed; rebuilding document from rendered pages:",
|
|
1284
1322
|
error
|
|
@@ -2751,7 +2789,7 @@ var PageAssembler = React7.forwardRef(
|
|
|
2751
2789
|
dispatch({ type: "ADD_FILE", payload: fileInfo });
|
|
2752
2790
|
} catch (error) {
|
|
2753
2791
|
console.error(`Error processing file ${file.name}:`, error);
|
|
2754
|
-
if (error instanceof
|
|
2792
|
+
if (error instanceof PdfPasswordRequiredError2) {
|
|
2755
2793
|
setUploadError(`${file.name}: ${error.userMessage}`);
|
|
2756
2794
|
} else {
|
|
2757
2795
|
setUploadError(`Failed to process "${file.name}". The file may be corrupted or unsupported.`);
|
|
@@ -3336,17 +3374,17 @@ function debounce(func, wait) {
|
|
|
3336
3374
|
exports.Button = Button;
|
|
3337
3375
|
exports.FormFieldType = FormFieldType;
|
|
3338
3376
|
exports.PageAssembler = PageAssembler;
|
|
3339
|
-
exports.PdfPasswordRequiredError =
|
|
3340
|
-
exports.UnsupportedPdfEncryptionError =
|
|
3377
|
+
exports.PdfPasswordRequiredError = PdfPasswordRequiredError2;
|
|
3378
|
+
exports.UnsupportedPdfEncryptionError = UnsupportedPdfEncryptionError2;
|
|
3341
3379
|
exports.addFormFieldsToPdf = addFormFieldsToPdf;
|
|
3342
3380
|
exports.createPdfBlobUrl = createPdfBlobUrl;
|
|
3343
|
-
exports.decryptPdf =
|
|
3381
|
+
exports.decryptPdf = decryptPdf2;
|
|
3344
3382
|
exports.downloadPdf = downloadPdf;
|
|
3345
3383
|
exports.extractFieldsFromPdf = extractFieldsFromPdf;
|
|
3346
3384
|
exports.getSigniphiMetadata = getSigniphiMetadata;
|
|
3347
3385
|
exports.imageToPdf = imageToPdf;
|
|
3348
3386
|
exports.mapFieldPositionsAfterAssembly = mapFieldPositionsAfterAssembly;
|
|
3349
|
-
exports.normalizePdfEncryption =
|
|
3387
|
+
exports.normalizePdfEncryption = normalizePdfEncryption2;
|
|
3350
3388
|
exports.normalizeUploadedPdfBytes = normalizeUploadedPdfBytes;
|
|
3351
3389
|
exports.pdfToImages = pdfToImages;
|
|
3352
3390
|
exports.rasterizePdfToPdf = rasterizePdfToPdf;
|