omitly-mcp 5.3.0 → 5.5.0

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.
@@ -0,0 +1,50 @@
1
+ /**
2
+ * omitly#1841 phase B: `pdf_info` (design 4.1). Counts and flags only; never
3
+ * text, field values or metadata. Loads with `ignoreEncryption: true`, so it
4
+ * answers for an encrypted file (reporting `encrypted: true`); any fact it
5
+ * cannot read is `null`.
6
+ */
7
+ import { PDFDocument } from "pdf-lib";
8
+ import { formFieldCount, hasComments, hasLayers, hasSignatureField, xfaKind, } from "./docFacts.js";
9
+ export const INFO_PAGE_LIMIT = 500;
10
+ function attempt(fn) {
11
+ try {
12
+ return fn();
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ const finite = (n) => (Number.isFinite(n) ? Math.round(n * 100) / 100 : null);
19
+ export async function pdfInfo(bytes) {
20
+ const doc = await PDFDocument.load(bytes.slice(), { ignoreEncryption: true, updateMetadata: false });
21
+ const pages = doc.getPages();
22
+ const shown = [];
23
+ for (let i = 0; i < Math.min(pages.length, INFO_PAGE_LIMIT); i++) {
24
+ const page = pages[i];
25
+ const mb = attempt(() => page.node.MediaBox()?.asRectangle());
26
+ const rot = attempt(() => page.node.Rotate()?.asNumber() ?? 0);
27
+ shown.push({
28
+ pageNumber: i + 1,
29
+ widthPt: mb ? finite(Math.abs(mb.width)) : null,
30
+ heightPt: mb ? finite(Math.abs(mb.height)) : null,
31
+ // Normalised to 0/90/180/270; the raw value if it is not a multiple of 90.
32
+ rotation: rot === null || !Number.isFinite(rot) ? null : rot % 90 === 0 ? ((rot % 360) + 360) % 360 : rot,
33
+ });
34
+ }
35
+ const fields = attempt(() => formFieldCount(doc));
36
+ return {
37
+ pageCount: pages.length,
38
+ pages: shown,
39
+ pagesTruncated: pages.length > INFO_PAGE_LIMIT,
40
+ encrypted: attempt(() => doc.isEncrypted),
41
+ hasForm: fields === null ? null : fields > 0,
42
+ formFieldCount: fields,
43
+ hasSignatures: attempt(() => hasSignatureField(doc)),
44
+ hasComments: attempt(() => hasComments(doc)),
45
+ hasXfa: attempt(() => xfaKind(doc)),
46
+ hasLayers: attempt(() => hasLayers(doc)),
47
+ byteSize: bytes.length,
48
+ };
49
+ }
50
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/pdf-edit/info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * omitly#1841 phase B: `merge_pdfs` (design 4.3).
3
+ *
4
+ * Starts from a fresh document; for each input: load it once, copy ALL its pages
5
+ * with one copier, merge its form with `mergeAcroFormOnAppend`, drop it, and move
6
+ * on; save once. Every page of every input is kept, so nothing is excluded and the
7
+ * #1004 path does not arise, and the cost is linear in the inputs (unlike calling
8
+ * `appendPdf` repeatedly, which reloads the growing result each time). Signatures
9
+ * are removed in each SOURCE before its pages are copied.
10
+ */
11
+ import { PDFDocument, PDFObjectCopier, PDFPage, PDFPageLeaf } from "pdf-lib";
12
+ import { LAYERS_WARNING, RENAME_WARNING, FONT_RENAME_WARNING, SIGNATURE_WARNING, clearSigFlags, isEncryptedError, scrubDestinationSignatures, sourceFacts, stripSignaturesFromSource, } from "./docFacts.js";
13
+ import { mergeAcroFormOnAppend } from "./pageOps.js";
14
+ import { EditRefusal } from "./refusals.js";
15
+ export async function mergePdfs(count, getBytes) {
16
+ const dst = await PDFDocument.create({ updateMetadata: false });
17
+ const lost = new Set();
18
+ const warnings = new Set();
19
+ const pageCounts = [];
20
+ let renamed = 0;
21
+ for (let i = 0; i < count; i++) {
22
+ const inputIndex = i + 1;
23
+ try {
24
+ const src = await PDFDocument.load(getBytes(i).slice(), { updateMetadata: false });
25
+ const facts = sourceFacts(src);
26
+ if (facts.xfa === "dynamic")
27
+ throw new EditRefusal("xfa");
28
+ if (stripSignaturesFromSource(src))
29
+ warnings.add(SIGNATURE_WARNING);
30
+ await src.flush();
31
+ const copier = PDFObjectCopier.for(src.context, dst.context);
32
+ const copied = [];
33
+ for (const srcPage of src.getPages()) {
34
+ // By ref, so a widget's /P back-reference lands on this same copy (#884).
35
+ const ref = copier.copy(srcPage.ref);
36
+ const node = dst.context.lookup(ref);
37
+ if (!(node instanceof PDFPageLeaf))
38
+ throw new Error("page did not copy");
39
+ copied.push(PDFPage.of(node, ref, dst));
40
+ }
41
+ copied.forEach((p) => dst.addPage(p));
42
+ const merged = mergeAcroFormOnAppend(src, dst, copier);
43
+ renamed += merged.renamed;
44
+ if (merged.fontRenameFailed > 0)
45
+ warnings.add(FONT_RENAME_WARNING);
46
+ pageCounts.push(copied.length);
47
+ // The result starts from an empty catalog, so each of these is dropped.
48
+ if (facts.outlines)
49
+ lost.add("outlines");
50
+ if (facts.info)
51
+ lost.add("info");
52
+ if (facts.pageLabels)
53
+ lost.add("page_labels");
54
+ if (facts.xfa === "static")
55
+ lost.add("xfa");
56
+ if (facts.layers) {
57
+ lost.add("layers");
58
+ warnings.add(LAYERS_WARNING);
59
+ }
60
+ }
61
+ catch (e) {
62
+ if (e instanceof EditRefusal)
63
+ throw new EditRefusal(e.code, { ...e.detail, inputIndex });
64
+ if (isEncryptedError(e))
65
+ throw new EditRefusal("encrypted", { inputIndex });
66
+ throw new EditRefusal("failed", { inputIndex });
67
+ }
68
+ }
69
+ clearSigFlags(dst);
70
+ // Backstop: anything the source scrub missed, just before the bytes are written.
71
+ if (scrubDestinationSignatures(dst))
72
+ warnings.add(SIGNATURE_WARNING);
73
+ if (renamed > 0)
74
+ warnings.add(RENAME_WARNING);
75
+ const bytes = await dst.save();
76
+ return { bytes, pageCount: dst.getPageCount(), pageCounts, lost: [...lost], warnings: [...warnings] };
77
+ }
78
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/pdf-edit/merge.ts"],"names":[],"mappings":"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"}