modern-pdf-lib 0.15.0 → 0.19.9
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/README.md +106 -7
- package/dist/batchOptimize-7U_kD3_j.mjs +392 -0
- package/dist/batchOptimize-xo6BXbGZ.cjs +427 -0
- package/dist/{bridge-C7U4E7St.mjs → bridge-DTH5LMAK.mjs} +3 -3
- package/dist/{bridge-DUcJFVsk.cjs → bridge-DYCQzxF7.cjs} +2 -2
- package/dist/browser.cjs +621 -0
- package/dist/browser.d.cts +190 -0
- package/dist/browser.d.cts.map +1 -0
- package/dist/browser.d.mts +190 -0
- package/dist/browser.d.mts.map +1 -0
- package/dist/browser.mjs +212 -0
- package/dist/cli/index.cjs +247 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +248 -0
- package/dist/compressionAnalysis-BBv4BkQP.d.mts +261 -0
- package/dist/compressionAnalysis-BBv4BkQP.d.mts.map +1 -0
- package/dist/compressionAnalysis-Bw2alOxt.mjs +1490 -0
- package/dist/compressionAnalysis-CtJ2X9l2.d.cts +261 -0
- package/dist/compressionAnalysis-CtJ2X9l2.d.cts.map +1 -0
- package/dist/compressionAnalysis-eXYyDsrh.cjs +1525 -0
- package/dist/create.cjs +35 -0
- package/dist/create.d.cts +3 -0
- package/dist/create.d.mts +3 -0
- package/dist/create.mjs +5 -0
- package/dist/deduplicateImages-B5lmzL9j.cjs +113 -0
- package/dist/deduplicateImages-BX3Zg8Qp.mjs +102 -0
- package/dist/{fflateAdapter-DX0VqT5k.mjs → fflateAdapter-CBQpGTlx.mjs} +2 -2
- package/dist/{fflateAdapter-AHC_S3cb.cjs → fflateAdapter-LTAeAhaD.cjs} +1 -1
- package/dist/fieldAppearance-C8PoLFSc.d.mts +136 -0
- package/dist/fieldAppearance-C8PoLFSc.d.mts.map +1 -0
- package/dist/fieldAppearance-CdiGFG5e.d.cts +136 -0
- package/dist/fieldAppearance-CdiGFG5e.d.cts.map +1 -0
- package/dist/fontEmbed-Dsu9fo4U.d.mts +636 -0
- package/dist/fontEmbed-Dsu9fo4U.d.mts.map +1 -0
- package/dist/fontEmbed-LID6yG6g.d.cts +636 -0
- package/dist/fontEmbed-LID6yG6g.d.cts.map +1 -0
- package/dist/{fontSubset-pFc8Dueu.cjs → fontSubset-5SLWMmEw.cjs} +1 -1
- package/dist/{fontSubset-ZpLoOZ2e.mjs → fontSubset-DWpduoY2.mjs} +2 -2
- package/dist/forms.cjs +13 -0
- package/dist/forms.d.cts +3 -0
- package/dist/forms.d.mts +3 -0
- package/dist/forms.mjs +3 -0
- package/dist/grayscaleDetect-C2m-eEXR.cjs +96 -0
- package/dist/grayscaleDetect-C6kFF3dk.mjs +84 -0
- package/dist/imageExtract-B6OvUEp-.mjs +155 -0
- package/dist/imageExtract-PxdBvpHj.cjs +166 -0
- package/dist/index-BtYOx5wh.d.mts +4904 -0
- package/dist/index-BtYOx5wh.d.mts.map +1 -0
- package/dist/index-bpktKzCA.d.cts +4904 -0
- package/dist/index-bpktKzCA.d.cts.map +1 -0
- package/dist/index.cjs +288 -25851
- package/dist/index.d.cts +7 -9151
- package/dist/index.d.mts +7 -9151
- package/dist/index.mjs +17 -25665
- package/dist/layout-BZ8tTeAk.mjs +438 -0
- package/dist/layout-Inbqegsk.cjs +563 -0
- package/dist/{libdeflateWasm-Enus0G1k.cjs → libdeflateWasm-BdiDEJOj.cjs} +2 -2
- package/dist/{libdeflateWasm-82loOtIV.mjs → libdeflateWasm-rLppXytE.mjs} +3 -3
- package/dist/loader-3u6Tw5T-.mjs +328 -0
- package/dist/loader-I4zdkoWc.cjs +393 -0
- package/dist/parse.cjs +24 -0
- package/dist/parse.d.cts +4 -0
- package/dist/parse.d.mts +4 -0
- package/dist/parse.mjs +7 -0
- package/dist/pdfCatalog-CYy4NXEY.cjs +173 -0
- package/dist/pdfCatalog-IImGcMbR.mjs +138 -0
- package/dist/pdfDocument-BSiQdNZq.d.cts +4640 -0
- package/dist/pdfDocument-BSiQdNZq.d.cts.map +1 -0
- package/dist/pdfDocument-DOg240g9.mjs +13685 -0
- package/dist/pdfDocument-Duf9LelM.cjs +14110 -0
- package/dist/pdfDocument-i6U5fQ91.d.mts +4640 -0
- package/dist/pdfDocument-i6U5fQ91.d.mts.map +1 -0
- package/dist/pdfForm-9gd40uz9.cjs +1796 -0
- package/dist/pdfForm-BiyNtYem.d.mts +905 -0
- package/dist/pdfForm-BiyNtYem.d.mts.map +1 -0
- package/dist/pdfForm-Cn-cVicP.mjs +1695 -0
- package/dist/pdfForm-SOXJ72LW.d.cts +905 -0
- package/dist/pdfForm-SOXJ72LW.d.cts.map +1 -0
- package/dist/{pdfCatalog-COKoYQ8C.cjs → pdfObjects-1veop1_d.cjs} +2 -172
- package/dist/{pdfCatalog-BB2Wnmud.mjs → pdfObjects-uEsWlfzU.mjs} +3 -138
- package/dist/{pdfPage-N1K2U3jI.mjs → pdfPage-BacMkrLe.mjs} +3024 -4
- package/dist/{pdfPage-DBfdinTR.cjs → pdfPage-CirlQRzJ.cjs} +3148 -104
- package/dist/{pngEmbed-gaJ9S2Dk.mjs → pngEmbed-BLj2zi-5.mjs} +3 -3
- package/dist/{pngEmbed-10m4CfBU.cjs → pngEmbed-D4X4ZN-3.cjs} +2 -2
- package/dist/src-BLWEEbd7.cjs +11852 -0
- package/dist/src-x0g7wiRq.mjs +11103 -0
- package/dist/streamDecode-Bs0_MT_Q.cjs +4607 -0
- package/dist/streamDecode-CWN-nfPJ.mjs +4596 -0
- package/package.json +33 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/loader-1VJXLlMZ.mjs +0 -164
- package/dist/loader-CKlBOHma.cjs +0 -166
- package/dist/rolldown-runtime-95iHPtFO.mjs +0 -18
package/dist/browser.mjs
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { $ as translate, $t as setCharacterSpacing, A as buildAnnotationDict, At as curveToFinal, B as wrapInMarkedContent, Bt as rectangle, C as parseSvg, Ct as clip, D as AnnotationFlags, Dt as closeFillEvenOddAndStroke, E as parseSvgTransform, Et as closeFillAndStroke, F as beginMarkedContentSequence, Ft as fillAndStroke, G as radiansToDegrees, Gt as setLineWidth, H as degrees, Ht as setFlatness, I as beginMarkedContentWithProperties, It as fillEvenOdd, J as rotationMatrix, Jt as beginText, K as restoreState, Kt as setMiterLimit, L as createMarkedContentScope, Lt as fillEvenOddAndStroke, M as beginArtifact, Mt as ellipsePath, N as beginArtifactWithType, Nt as endPath, O as PdfAnnotation, Ot as closePath, P as beginMarkedContent, Pt as fill, Q as skew, Qt as nextLine, R as endArtifact, Rt as lineTo, S as svgToPdfOperators, St as circlePath, T as parseSvgPath, Tt as closeAndStroke, U as degreesToRadians, Ut as setLineCap, V as concatMatrix, Vt as setDashPattern, W as radians, Wt as setLineJoin, X as scale, Xt as moveText, Y as saveState, Yt as endText, Z as setGraphicsState, Zt as moveTextSetLeading, _ as PdfLayer, _t as setStrokeColorSpace, a as renderMultiPageTable, an as setTextRise, at as grayscale, b as endLayerContent, bt as drawImageXObject, c as qrCodeToOperators, cn as showTextArray, ct as setFillColor, d as linearGradient, dn as showTextWithSpacing, dt as setFillColorRgb, en as setFont, et as applyFillColor, f as radialGradient, ft as setFillingColor, g as markForRedaction, gt as setStrokeColorRgb, h as getRedactionMarks, ht as setStrokeColorGray, in as setTextRenderingMode, it as componentsToColor, j as createAnnotation, jt as curveToInitial, k as annotationFromDict, kt as curveTo, l as buildGradientObjects, ln as showTextHex, lt as setFillColorCmyk, m as applyRedactions, mt as setStrokeColorCmyk, n as PdfPage, nn as setLeading, nt as cmyk, o as renderTable, on as setWordSpacing, ot as rgb, p as tilingPattern, pt as setStrokeColor, q as rotate, qt as stroke, rn as setTextMatrix, rt as colorToComponents, s as encodeQrCode, sn as showText, st as setColorSpace, t as PageSizes, tn as setFontSize, tt as applyStrokeColor, u as buildPatternObjects, un as showTextNextLine, ut as setFillColorGray, v as PdfLayerManager, vt as setStrokingColor, w as parseSvgColor, wt as clipEvenOdd, x as drawSvgOnPage, xt as drawXObject, y as beginLayerContent, yt as drawImageWithMatrix, z as endMarkedContent, zt as moveTo } from "./pdfPage-BacMkrLe.mjs";
|
|
2
|
+
import { a as PdfNull, c as PdfRef, i as PdfName, l as PdfStream, n as PdfBool, o as PdfNumber, r as PdfDict, s as PdfObjectRegistry, t as PdfArray, u as PdfString } from "./pdfObjects-uEsWlfzU.mjs";
|
|
3
|
+
import { a as formatPdfDate, i as buildPageTree, n as buildDocumentStructure, r as buildInfoDict, t as buildCatalog } from "./pdfCatalog-IImGcMbR.mjs";
|
|
4
|
+
import { $ as sha384, A as prepareForSigning, B as buildViewerPreferencesDict, C as encodeSet, D as computeSignatureHash, F as isAccessible, G as PdfOutlineItem, H as buildXmpMetadata, I as summarizeIssues, J as PdfEncryptionHandler, K as PdfOutlineTree, L as PdfStructureElement, M as mergePdfs, N as splitPdf, O as embedSignature, P as checkAccessibility, Q as sha256, R as PdfStructureTree, S as encodeSequence, T as encodeUtf8String, U as createXmpStream, V as parseViewerPreferences, W as parseXmpMetadata, X as verifyOwnerPassword, Y as computeFileEncryptionKey, Z as verifyUserPassword, _ as encodeInteger, _t as serializePdf, a as addWatermark, at as rc4, b as encodeOctetString, c as buildEmbeddedFilesNameTree, ct as base64Encode, d as verifySignatures, dt as isOpenTypeCFF, et as sha512, f as getSignatures, ft as isTrueType, g as encodeContextTag, gt as PdfWriter, ht as PdfStreamWriter, i as embedPageAsFormXObject, it as aesEncryptCBC, j as copyPages, k as findSignatures, l as getAttachments, lt as PdfParseError, m as buildPkcs7Signature, mt as extractMetrics, n as StandardFonts, nt as encodePermissions, o as addWatermarkToPage, ot as md5, p as signPdf, pt as EmbeddedFont, q as loadPdf, r as createPdf, rt as aesDecryptCBC, s as attachFile, st as base64Decode, t as PdfDocument, tt as decodePermissions, u as verifySignature, ut as formatHexContext, v as encodeLength, w as encodeUTCTime, x as encodePrintableString, y as encodeOID, z as PdfViewerPreferences } from "./pdfDocument-DOg240g9.mjs";
|
|
5
|
+
import { _ as PdfField, a as PdfDropdownField, c as PdfTextField, d as generateDropdownAppearance, f as generateListboxAppearance, g as FieldFlags, h as generateTextAppearance, i as PdfListboxField, l as generateButtonAppearance, m as generateSignatureAppearance, n as PdfSignatureField, o as PdfRadioGroup, p as generateRadioAppearance, r as PdfButtonField, s as PdfCheckboxField, t as PdfForm, u as generateCheckboxAppearance } from "./pdfForm-Cn-cVicP.mjs";
|
|
6
|
+
import { t as decodeStream } from "./streamDecode-CWN-nfPJ.mjs";
|
|
7
|
+
import { $ as encodeCode128Values, $t as PdfFreeTextAnnotation, A as readEan13, At as flattenTransparency, B as upcAToOperators, Bt as PdfPopupAnnotation, C as borderedPreset, Ct as generateWinAnsiToUnicodeCmap, D as readBarcode, Dt as SRGB_ICC_PROFILE, E as stripedPreset, Et as buildOutputIntent, F as pdf417ToOperators, Ft as buildTimestampRequest, G as encodeEan8, Gt as PdfLineAnnotation, H as ean13ToOperators, Ht as PdfInkAnnotation, I as dataMatrixToOperators, It as parseTimestampResponse, J as code39ToOperators, Jt as PdfSquareAnnotation, K as encodeItf, Kt as PdfPolyLineAnnotation, L as encodeDataMatrix, Lt as requestTimestamp, M as calculateBarcodeDimensions, Mt as validatePdfA, N as renderStyledBarcode, Nt as isLinearized, O as readCode128, Ot as generateSrgbIccProfile, P as encodePdf417, Pt as linearizePdf, Q as encodeCode128, Qt as PdfUnderlineAnnotation, R as calculateUpcCheckDigit, Rt as PdfFileAttachmentAnnotation, S as applyTablePreset, St as generateSymbolToUnicodeCmap, T as professionalPreset, Tt as getToUnicodeCmap, U as ean8ToOperators, Ut as PdfStampAnnotation, V as calculateEanCheckDigit, Vt as PdfRedactAnnotation, W as encodeEan13, Wt as PdfCircleAnnotation, X as encodeCode39, Xt as PdfSquigglyAnnotation, Y as computeCode39CheckDigit, Yt as PdfHighlightAnnotation, Z as code128ToOperators, Zt as PdfStrikeOutAnnotation, _ as estimateTextWidth, _n as asPDFNumber, _t as parseXmpMetadata$1, a as FieldAlreadyExistsError, an as generateSquareAppearance, at as downscaleImage, b as wrapText, bt as getSupportedLevels, c as ForeignPageError, cn as generateUnderlineAppearance, ct as recompressImage, d as NoSuchFieldError, dn as PDFOperator, dt as generatePdfAXmpBytes, en as generateCircleAppearance, et as valuesToModules, f as RemovePageFromEmptyDocumentError, fn as ChangeTracker, ft as countOccurrences, g as ellipsisText, gn as asPDFName, gt as extractXmpMetadata, h as applyOverflow, hn as asNumber, ht as createAssociatedFile, i as ExceededMaxLengthError, in as generateLineAppearance, it as analyzeJpegMarkers, j as readEan8, jt as enforcePdfA, k as readCode39, kt as detectTransparency, l as InvalidFieldNamePartError, ln as PdfLinkAnnotation, lt as enforcePdfAFull, m as UnexpectedFieldTypeError, mn as saveIncremental, mt as buildAfArray, n as CombedTextLayoutError, nn as generateHighlightAppearance, nt as extractJpegMetadata, o as FieldExistsAsNonTerminalError, on as generateSquigglyAppearance, ot as estimateJpegQuality, p as RichTextFieldReadError, pn as saveDocumentIncremental, pt as stripProhibitedFeatures, q as itfToOperators, qt as PdfPolygonAnnotation, r as EncryptedPdfError, rn as generateInkAppearance, rt as injectJpegMetadata, s as FontNotEmbeddedError, sn as generateStrikeOutAppearance, st as optimizeImage, t as initWasm, tn as generateFreeTextAppearance, tt as PdfWorker, u as MissingOnValueCheckError, un as PdfTextAnnotation, ut as generatePdfAXmp, v as shrinkFontSize, vt as validateXmpMetadata, w as minimalPreset, wt as generateZapfDingbatsToUnicodeCmap, x as applyPreset, xt as isValidLevel, y as truncateText, yt as getProfile, z as encodeUpcA, zt as PdfCaretAnnotation } from "./src-x0g7wiRq.mjs";
|
|
8
|
+
import { _ as LineCapStyle, a as cropPage, b as TextAlignment, c as movePage, d as resizePage, f as reversePages, g as ImageAlignment, h as BlendMode, i as layoutSinglelineText, l as removePage, m as rotatePage, n as layoutCombedText, o as getPageSize, p as rotateAllPages, r as layoutMultilineText, s as insertPage, t as computeFontSize, u as removePages, v as LineJoinStyle, x as TextRenderingMode, y as ParseSpeeds } from "./layout-BZ8tTeAk.mjs";
|
|
9
|
+
import { a as extractText, i as parseContentStream, n as computeImageDpi, o as extractTextWithPositions, r as computeTargetDimensions, t as analyzeImages } from "./compressionAnalysis-Bw2alOxt.mjs";
|
|
10
|
+
import { a as isJpegWasmReady, i as initJpegWasm, n as decodeJpegWasm, r as encodeJpegWasm } from "./bridge-DTH5LMAK.mjs";
|
|
11
|
+
import { n as extractImages, t as decodeImageStream } from "./imageExtract-B6OvUEp-.mjs";
|
|
12
|
+
import { n as isGrayscaleImage, t as convertToGrayscale } from "./grayscaleDetect-C6kFF3dk.mjs";
|
|
13
|
+
import { a as parseIccColorSpace, i as extractIccProfile, n as optimizeAllImages, o as parseIccDescription, r as embedIccProfile } from "./batchOptimize-7U_kD3_j.mjs";
|
|
14
|
+
import { t as deduplicateImages } from "./deduplicateImages-BX3Zg8Qp.mjs";
|
|
15
|
+
import { a as isWasmDisabled, c as loadWasmModuleStreaming, d as resetWasmLoader, i as instantiateWasmModuleStreaming, n as configureWasmLoader, o as isWasmModuleCached, r as detectRuntime, s as loadWasmModule, t as clearWasmCache, u as provideWasmBytes } from "./loader-3u6Tw5T-.mjs";
|
|
16
|
+
|
|
17
|
+
//#region src/browser/serviceWorker.ts
|
|
18
|
+
/**
|
|
19
|
+
* Handle a fetch request by generating a PDF and returning it as a
|
|
20
|
+
* {@link Response} with appropriate headers.
|
|
21
|
+
*
|
|
22
|
+
* This is a convenience wrapper that catches errors from the handler
|
|
23
|
+
* and returns a 500 response with the error message instead of
|
|
24
|
+
* letting the Service Worker fail silently.
|
|
25
|
+
*
|
|
26
|
+
* @param request - The incoming {@link Request} (used for context;
|
|
27
|
+
* currently informational).
|
|
28
|
+
* @param handler - An async function that receives the `modern-pdf-lib`
|
|
29
|
+
* module and returns PDF bytes.
|
|
30
|
+
* @returns A {@link Response} with `content-type: application/pdf`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* self.addEventListener('fetch', (event) => {
|
|
35
|
+
* event.respondWith(
|
|
36
|
+
* handlePdfRequest(event.request, async (pdf) => {
|
|
37
|
+
* const doc = pdf.createPdf();
|
|
38
|
+
* doc.addPage();
|
|
39
|
+
* return doc.save();
|
|
40
|
+
* }),
|
|
41
|
+
* );
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
async function handlePdfRequest(_request, handler) {
|
|
46
|
+
try {
|
|
47
|
+
return createPdfResponse(await handler(await import("./index.mjs")));
|
|
48
|
+
} catch (err) {
|
|
49
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
50
|
+
return new Response(`PDF generation failed: ${message}`, {
|
|
51
|
+
status: 500,
|
|
52
|
+
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Wrap raw PDF bytes in a {@link Response} with the correct
|
|
58
|
+
* `Content-Type` and optional `Content-Disposition` headers.
|
|
59
|
+
*
|
|
60
|
+
* @param bytes - The PDF file contents as a `Uint8Array`.
|
|
61
|
+
* @param filename - If provided, a `Content-Disposition: attachment`
|
|
62
|
+
* header is added so browsers prompt a download.
|
|
63
|
+
* @returns A ready-to-send {@link Response}.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const bytes = doc.save();
|
|
68
|
+
* const response = createPdfResponse(bytes, 'invoice.pdf');
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function createPdfResponse(bytes, filename) {
|
|
72
|
+
const headers = {
|
|
73
|
+
"content-type": "application/pdf",
|
|
74
|
+
"content-length": String(bytes.byteLength)
|
|
75
|
+
};
|
|
76
|
+
if (filename) headers["content-disposition"] = `attachment; filename="${filename}"`;
|
|
77
|
+
return new Response(bytes, {
|
|
78
|
+
status: 200,
|
|
79
|
+
headers
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check whether the Cache API is available in the current context.
|
|
84
|
+
*
|
|
85
|
+
* In Service Workers the Cache API (`caches`) is typically available,
|
|
86
|
+
* but this helper guards against edge cases (e.g., opaque origins,
|
|
87
|
+
* disabled storage, or running outside a Service Worker).
|
|
88
|
+
*
|
|
89
|
+
* @returns `true` if `caches` is defined and accessible.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* if (isCacheAvailable()) {
|
|
94
|
+
* const cache = await caches.open('pdf-cache');
|
|
95
|
+
* await cache.put(request, response.clone());
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
function isCacheAvailable() {
|
|
100
|
+
try {
|
|
101
|
+
return typeof caches !== "undefined" && typeof caches.open === "function";
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/browser/download.ts
|
|
109
|
+
/**
|
|
110
|
+
* Browser utilities for saving and displaying PDF documents.
|
|
111
|
+
*
|
|
112
|
+
* These helpers convert raw PDF bytes into browser-native formats
|
|
113
|
+
* for downloading, embedding, and previewing.
|
|
114
|
+
*
|
|
115
|
+
* @module browser/download
|
|
116
|
+
*/
|
|
117
|
+
/**
|
|
118
|
+
* Trigger a browser file download for PDF bytes.
|
|
119
|
+
*
|
|
120
|
+
* Creates a temporary `<a>` element with a Blob URL and clicks it
|
|
121
|
+
* to start the download. The Blob URL is revoked after the download
|
|
122
|
+
* starts.
|
|
123
|
+
*
|
|
124
|
+
* @param bytes - The PDF document bytes.
|
|
125
|
+
* @param filename - Download filename (defaults to `'document.pdf'`).
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { createPdf, saveAsDownload } from 'modern-pdf-lib/browser';
|
|
130
|
+
*
|
|
131
|
+
* const doc = createPdf();
|
|
132
|
+
* doc.addPage().drawText('Hello!', { x: 50, y: 750, size: 24 });
|
|
133
|
+
* const bytes = await doc.save();
|
|
134
|
+
* saveAsDownload(bytes, 'hello.pdf');
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function saveAsDownload(bytes, filename = "document.pdf") {
|
|
138
|
+
const blob = new Blob([bytes], { type: "application/pdf" });
|
|
139
|
+
const url = URL.createObjectURL(blob);
|
|
140
|
+
const a = document.createElement("a");
|
|
141
|
+
a.href = url;
|
|
142
|
+
a.download = filename;
|
|
143
|
+
document.body.appendChild(a);
|
|
144
|
+
a.click();
|
|
145
|
+
document.body.removeChild(a);
|
|
146
|
+
queueMicrotask(() => URL.revokeObjectURL(url));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Convert PDF bytes to a Blob.
|
|
150
|
+
*
|
|
151
|
+
* Useful for uploading PDFs via `fetch()` or `FormData`, or for
|
|
152
|
+
* passing to other browser APIs that accept Blobs.
|
|
153
|
+
*
|
|
154
|
+
* @param bytes - The PDF document bytes.
|
|
155
|
+
* @returns A Blob with MIME type `application/pdf`.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* const blob = saveAsBlob(bytes);
|
|
160
|
+
* const formData = new FormData();
|
|
161
|
+
* formData.append('document', blob, 'report.pdf');
|
|
162
|
+
* await fetch('/upload', { method: 'POST', body: formData });
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
function saveAsBlob(bytes) {
|
|
166
|
+
return new Blob([bytes], { type: "application/pdf" });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create an object URL for PDF bytes.
|
|
170
|
+
*
|
|
171
|
+
* The returned URL can be used as the `src` of an `<iframe>` or
|
|
172
|
+
* `<embed>` element to preview the PDF in the browser.
|
|
173
|
+
*
|
|
174
|
+
* **Important:** Call `URL.revokeObjectURL(url)` when you're done
|
|
175
|
+
* with the URL to free memory.
|
|
176
|
+
*
|
|
177
|
+
* @param bytes - The PDF document bytes.
|
|
178
|
+
* @returns A `blob:` URL string.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const url = saveAsDataUrl(bytes);
|
|
183
|
+
* const iframe = document.getElementById('preview') as HTMLIFrameElement;
|
|
184
|
+
* iframe.src = url;
|
|
185
|
+
* // Later: URL.revokeObjectURL(url);
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
function saveAsDataUrl(bytes) {
|
|
189
|
+
return URL.createObjectURL(new Blob([bytes], { type: "application/pdf" }));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Open a PDF in a new browser tab/window.
|
|
193
|
+
*
|
|
194
|
+
* @param bytes - The PDF document bytes.
|
|
195
|
+
* @param target - Window target (defaults to `'_blank'`).
|
|
196
|
+
* @returns The opened window reference, or `null` if blocked by popup blocker.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* openInNewTab(bytes);
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
function openInNewTab(bytes, target = "_blank") {
|
|
204
|
+
const url = URL.createObjectURL(new Blob([bytes], { type: "application/pdf" }));
|
|
205
|
+
const win = globalThis.open(url, target);
|
|
206
|
+
setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
207
|
+
return win;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
//#endregion
|
|
211
|
+
export { AnnotationFlags, BlendMode, ChangeTracker, CombedTextLayoutError, EmbeddedFont, EncryptedPdfError, ExceededMaxLengthError, FieldAlreadyExistsError, FieldExistsAsNonTerminalError, FieldFlags, FontNotEmbeddedError, ForeignPageError, ImageAlignment, InvalidFieldNamePartError, LineCapStyle, LineJoinStyle, MissingOnValueCheckError, NoSuchFieldError, PDFOperator, PageSizes, ParseSpeeds, PdfAnnotation, PdfArray, PdfBool, PdfButtonField, PdfCaretAnnotation, PdfCheckboxField, PdfCircleAnnotation, PdfDict, PdfDocument, PdfDropdownField, PdfEncryptionHandler, PdfField, PdfFileAttachmentAnnotation, PdfForm, PdfFreeTextAnnotation, PdfHighlightAnnotation, PdfInkAnnotation, PdfLayer, PdfLayerManager, PdfLineAnnotation, PdfLinkAnnotation, PdfListboxField, PdfName, PdfNull, PdfNumber, PdfObjectRegistry, PdfOutlineItem, PdfOutlineTree, PdfPage, PdfParseError, PdfPolyLineAnnotation, PdfPolygonAnnotation, PdfPopupAnnotation, PdfRadioGroup, PdfRedactAnnotation, PdfRef, PdfSignatureField, PdfSquareAnnotation, PdfSquigglyAnnotation, PdfStampAnnotation, PdfStream, PdfStreamWriter, PdfStrikeOutAnnotation, PdfString, PdfStructureElement, PdfStructureTree, PdfTextAnnotation, PdfTextField, PdfUnderlineAnnotation, PdfViewerPreferences, PdfWorker, PdfWriter, RemovePageFromEmptyDocumentError, RichTextFieldReadError, SRGB_ICC_PROFILE, StandardFonts, TextAlignment, TextRenderingMode, UnexpectedFieldTypeError, addWatermark, addWatermarkToPage, aesDecryptCBC, aesEncryptCBC, analyzeImages, analyzeJpegMarkers, annotationFromDict, applyFillColor, applyOverflow, applyPreset, applyRedactions, applyStrokeColor, applyTablePreset, asNumber, asPDFName, asPDFNumber, attachFile, base64Decode, base64Encode, beginArtifact, beginArtifactWithType, beginLayerContent, beginMarkedContent, beginMarkedContentSequence, beginMarkedContentWithProperties, beginText, borderedPreset, buildAfArray, buildAnnotationDict, buildCatalog, buildDocumentStructure, buildEmbeddedFilesNameTree, buildGradientObjects, buildInfoDict, buildOutputIntent, buildPageTree, buildPatternObjects, buildPkcs7Signature, buildTimestampRequest, buildViewerPreferencesDict, buildXmpMetadata, calculateBarcodeDimensions, calculateEanCheckDigit, calculateUpcCheckDigit, checkAccessibility, circlePath, clearWasmCache, clipEvenOdd, clip as clipOp, closeAndStroke, closeFillAndStroke, closeFillEvenOddAndStroke, closePath as closePathOp, cmyk, code128ToOperators, code39ToOperators, colorToComponents, componentsToColor, computeCode39CheckDigit, computeFileEncryptionKey, computeFontSize, computeImageDpi, computeSignatureHash, computeTargetDimensions, concatMatrix, concatMatrix as concatTransformationMatrix, configureWasmLoader, convertToGrayscale, copyPages, countOccurrences, createAnnotation, createAssociatedFile, createMarkedContentScope, createPdf, createPdfResponse, createXmpStream, cropPage, curveToFinal, curveToInitial, curveTo as curveToOp, dataMatrixToOperators, decodeImageStream, decodeJpegWasm, decodePermissions, decodeStream, deduplicateImages, degrees, degreesToRadians, detectRuntime, detectTransparency, downscaleImage, drawImageWithMatrix, drawImageXObject, drawXObject as drawObject, drawXObject, drawSvgOnPage, ean13ToOperators, ean8ToOperators, ellipsePath, ellipsisText, embedIccProfile, embedPageAsFormXObject, embedSignature, encodeCode128, encodeCode128Values, encodeCode39, encodeContextTag, encodeDataMatrix, encodeEan13, encodeEan8, encodeInteger, encodeItf, encodeJpegWasm, encodeLength, encodeOID, encodeOctetString, encodePdf417, encodePermissions, encodePrintableString, encodeQrCode, encodeSequence, encodeSet, encodeUTCTime, encodeUpcA, encodeUtf8String, endArtifact, endLayerContent, endMarkedContent, endPath as endPathOp, endText, enforcePdfA, enforcePdfAFull, estimateJpegQuality, estimateTextWidth, extractIccProfile, extractImages, extractJpegMetadata, extractMetrics, extractText, extractTextWithPositions, extractXmpMetadata, fillAndStroke as fillAndStrokeOp, fillEvenOdd, fillEvenOddAndStroke, fill as fillOp, findSignatures, flattenTransparency, formatHexContext, formatPdfDate, generateButtonAppearance, generateCheckboxAppearance, generateCircleAppearance, generateDropdownAppearance, generateFreeTextAppearance, generateHighlightAppearance, generateInkAppearance, generateLineAppearance, generateListboxAppearance, generatePdfAXmp, generatePdfAXmpBytes, generateRadioAppearance, generateSignatureAppearance, generateSquareAppearance, generateSquigglyAppearance, generateSrgbIccProfile, generateStrikeOutAppearance, generateSymbolToUnicodeCmap, generateTextAppearance, generateUnderlineAppearance, generateWinAnsiToUnicodeCmap, generateZapfDingbatsToUnicodeCmap, getAttachments, getPageSize, getProfile, getRedactionMarks, getSignatures, getSupportedLevels, getToUnicodeCmap, grayscale, handlePdfRequest, initJpegWasm, initWasm, injectJpegMetadata, insertPage, instantiateWasmModuleStreaming, isAccessible, isCacheAvailable, isGrayscaleImage, isJpegWasmReady, isLinearized, isOpenTypeCFF, isTrueType, isValidLevel, isWasmDisabled, isWasmModuleCached, itfToOperators, layoutCombedText, layoutMultilineText, layoutSinglelineText, lineTo as lineToOp, linearGradient, linearizePdf, loadPdf, loadWasmModule, loadWasmModuleStreaming, markForRedaction, md5, mergePdfs, minimalPreset, movePage, moveText as moveTextOp, moveTextSetLeading, moveTo as moveToOp, nextLine as nextLineOp, openInNewTab, optimizeAllImages, optimizeImage, parseContentStream, parseIccColorSpace, parseIccDescription, parseSvg, parseSvgColor, parseSvgPath, parseSvgTransform, parseTimestampResponse, parseViewerPreferences, parseXmpMetadata, parseXmpMetadata$1 as parseXmpPdfAMetadata, pdf417ToOperators, restoreState as popGraphicsState, restoreState, prepareForSigning, professionalPreset, provideWasmBytes, saveState as pushGraphicsState, saveState, qrCodeToOperators, radialGradient, radians, radiansToDegrees, rc4, readBarcode, readCode128, readCode39, readEan13, readEan8, recompressImage, rectangle as rectangleOp, removePage, removePages, renderMultiPageTable, renderStyledBarcode, renderTable, requestTimestamp, resetWasmLoader, resizePage, reversePages, rgb, rotateAllPages, rotate as rotateOp, rotatePage, rotationMatrix, saveAsBlob, saveAsDataUrl, saveAsDownload, saveDocumentIncremental, saveIncremental, scale as scaleOp, serializePdf, setCharacterSpacing as setCharacterSpacingOp, setCharacterSpacing as setCharacterSqueeze, setColorSpace, setDashPattern as setDashPatternOp, setFillColor, setFillColorCmyk, setFillColorGray, setFillColorRgb, setFillingColor, setFlatness, setFont as setFontAndSize, setFont as setFontOp, setFontSize as setFontSizeOp, setGraphicsState as setGraphicsStateOp, setLeading as setLeadingOp, setLeading as setLineHeight, setLineCap as setLineCapOp, setLineJoin as setLineJoinOp, setLineWidth as setLineWidthOp, setMiterLimit, setStrokeColor, setStrokeColorCmyk, setStrokeColorGray, setStrokeColorRgb, setStrokeColorSpace, setStrokingColor, setTextMatrix as setTextMatrixOp, setTextRenderingMode as setTextRenderingModeOp, setTextRise as setTextRiseOp, setWordSpacing as setWordSpacingOp, sha256, sha384, sha512, showTextArray, showTextHex, showTextNextLine, showText as showTextOp, showTextWithSpacing, shrinkFontSize, signPdf, skew as skewOp, splitPdf, stripProhibitedFeatures, stripedPreset, stroke as strokeOp, summarizeIssues, svgToPdfOperators, tilingPattern, translate as translateOp, truncateText, upcAToOperators, validatePdfA, validateXmpMetadata, valuesToModules, verifyOwnerPassword, verifySignature, verifySignatures, verifyUserPassword, wrapInMarkedContent, wrapText };
|
|
212
|
+
//# sourceMappingURL=browser.mjs.map
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
let node_fs_promises = require("node:fs/promises");
|
|
3
|
+
|
|
4
|
+
//#region src/cli/optimize.ts
|
|
5
|
+
/**
|
|
6
|
+
* @module cli/optimize
|
|
7
|
+
*
|
|
8
|
+
* CLI command: `modern-pdf optimize input.pdf output.pdf [options]`
|
|
9
|
+
*
|
|
10
|
+
* Optimizes images in a PDF file by recompressing them as JPEG,
|
|
11
|
+
* with optional deduplication and grayscale detection.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Parse and execute the optimize command.
|
|
15
|
+
*/
|
|
16
|
+
async function optimizeCommand(args) {
|
|
17
|
+
const parsed = parseArgs(args);
|
|
18
|
+
if (parsed.help) {
|
|
19
|
+
printOptimizeHelp();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!parsed.input || !parsed.output) {
|
|
23
|
+
console.error("Error: input and output file paths are required.");
|
|
24
|
+
console.error("Usage: modern-pdf optimize <input.pdf> <output.pdf> [options]");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const { loadPdf } = await Promise.resolve().then(() => require("../index.cjs"));
|
|
28
|
+
const { initJpegWasm } = await Promise.resolve().then(() => require("../bridge-DYCQzxF7.cjs")).then((n) => n.bridge_exports);
|
|
29
|
+
const { optimizeAllImages } = await Promise.resolve().then(() => require("../batchOptimize-xo6BXbGZ.cjs")).then((n) => n.batchOptimize_exports);
|
|
30
|
+
const { deduplicateImages } = await Promise.resolve().then(() => require("../deduplicateImages-B5lmzL9j.cjs")).then((n) => n.deduplicateImages_exports);
|
|
31
|
+
const inputBytes = new Uint8Array(await (0, node_fs_promises.readFile)(parsed.input));
|
|
32
|
+
const inputSize = inputBytes.length;
|
|
33
|
+
if (parsed.verbose) {
|
|
34
|
+
console.log(`Input: ${parsed.input} (${formatBytes(inputSize)})`);
|
|
35
|
+
console.log(`Output: ${parsed.output}`);
|
|
36
|
+
console.log("");
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
await initJpegWasm();
|
|
40
|
+
} catch {
|
|
41
|
+
console.warn("Warning: JPEG WASM module not available. Images will not be recompressed.");
|
|
42
|
+
}
|
|
43
|
+
const doc = await loadPdf(inputBytes);
|
|
44
|
+
if (parsed.dedup) {
|
|
45
|
+
const dedupReport = deduplicateImages(doc);
|
|
46
|
+
if (parsed.verbose && dedupReport.duplicatesRemoved > 0) console.log(`Deduplication: removed ${dedupReport.duplicatesRemoved} duplicate(s), ~${formatBytes(dedupReport.bytesSaved)} saved`);
|
|
47
|
+
}
|
|
48
|
+
const startTime = Date.now();
|
|
49
|
+
const onProgress = (info) => {
|
|
50
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
51
|
+
const pct = Math.round(info.current / info.total * 100);
|
|
52
|
+
const barWidth = 40;
|
|
53
|
+
const filled = Math.round(info.current / info.total * barWidth);
|
|
54
|
+
const empty = barWidth - filled;
|
|
55
|
+
const line = `\r ${"█".repeat(filled) + "░".repeat(empty)} ${pct}% ${info.current}/${info.total} ${info.imageName} saved:${formatBytes(info.totalSavedBytes)} ${elapsed}s`;
|
|
56
|
+
process.stderr.write(line.padEnd(100) + "\r");
|
|
57
|
+
if (parsed.verbose) {
|
|
58
|
+
let detail;
|
|
59
|
+
if (info.skipped) detail = ` ${info.imageName} (p${info.pageIndex}): SKIP`;
|
|
60
|
+
else {
|
|
61
|
+
const savedSign = info.savedBytes >= 0 ? "-" : "+";
|
|
62
|
+
detail = ` ${info.imageName} (p${info.pageIndex}): ${savedSign}${formatBytes(Math.abs(info.savedBytes))}`;
|
|
63
|
+
}
|
|
64
|
+
process.stderr.write("\n");
|
|
65
|
+
console.log(detail);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const report = await optimizeAllImages(doc, {
|
|
69
|
+
quality: parsed.quality,
|
|
70
|
+
progressive: parsed.progressive,
|
|
71
|
+
chromaSubsampling: parsed.chroma,
|
|
72
|
+
autoGrayscale: parsed.grayscale,
|
|
73
|
+
skipSmallImages: true,
|
|
74
|
+
minSavingsPercent: 10,
|
|
75
|
+
onProgress
|
|
76
|
+
});
|
|
77
|
+
process.stderr.write("\r" + " ".repeat(100) + "\r");
|
|
78
|
+
const elapsedTotal = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
79
|
+
console.log("");
|
|
80
|
+
console.log(`Images found: ${report.totalImages}`);
|
|
81
|
+
console.log(`Images optimized: ${report.optimizedImages}`);
|
|
82
|
+
console.log(`Original size: ${formatBytes(report.originalTotalBytes)}`);
|
|
83
|
+
console.log(`Optimized size: ${formatBytes(report.optimizedTotalBytes)}`);
|
|
84
|
+
console.log(`Savings: ${report.savings.toFixed(1)}%`);
|
|
85
|
+
console.log(`Elapsed: ${elapsedTotal}s`);
|
|
86
|
+
if (parsed.verbose && report.perImage.length > 0) {
|
|
87
|
+
console.log("");
|
|
88
|
+
console.log("Per-image details:");
|
|
89
|
+
for (const entry of report.perImage) if (entry.skipped) console.log(` ${entry.name} (p${entry.pageIndex}): SKIP -- ${entry.reason}`);
|
|
90
|
+
else {
|
|
91
|
+
const pct = ((entry.originalSize - entry.newSize) / entry.originalSize * 100).toFixed(1);
|
|
92
|
+
console.log(` ${entry.name} (p${entry.pageIndex}): ${formatBytes(entry.originalSize)} -> ${formatBytes(entry.newSize)} (-${pct}%)`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const outputBytes = await doc.save();
|
|
96
|
+
await (0, node_fs_promises.writeFile)(parsed.output, outputBytes);
|
|
97
|
+
const outputSize = outputBytes.length;
|
|
98
|
+
const totalSavings = inputSize > 0 ? ((inputSize - outputSize) / inputSize * 100).toFixed(1) : "0.0";
|
|
99
|
+
console.log(`\n${formatBytes(inputSize)} → ${formatBytes(outputSize)} (−${totalSavings}%)`);
|
|
100
|
+
}
|
|
101
|
+
function parseArgs(args) {
|
|
102
|
+
const result = {
|
|
103
|
+
quality: 80,
|
|
104
|
+
progressive: false,
|
|
105
|
+
grayscale: false,
|
|
106
|
+
dedup: false,
|
|
107
|
+
chroma: "4:2:0",
|
|
108
|
+
verbose: false,
|
|
109
|
+
help: false
|
|
110
|
+
};
|
|
111
|
+
const positional = [];
|
|
112
|
+
for (let i = 0; i < args.length; i++) {
|
|
113
|
+
const arg = args[i];
|
|
114
|
+
switch (arg) {
|
|
115
|
+
case "--help":
|
|
116
|
+
case "-h":
|
|
117
|
+
result.help = true;
|
|
118
|
+
return result;
|
|
119
|
+
case "--quality":
|
|
120
|
+
case "-q":
|
|
121
|
+
result.quality = parseInt(args[++i] ?? "80", 10);
|
|
122
|
+
if (result.quality < 1 || result.quality > 100) {
|
|
123
|
+
console.error("Error: --quality must be between 1 and 100.");
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case "--max-dpi":
|
|
128
|
+
i++;
|
|
129
|
+
break;
|
|
130
|
+
case "--progressive":
|
|
131
|
+
result.progressive = true;
|
|
132
|
+
break;
|
|
133
|
+
case "--grayscale":
|
|
134
|
+
result.grayscale = true;
|
|
135
|
+
break;
|
|
136
|
+
case "--dedup":
|
|
137
|
+
result.dedup = true;
|
|
138
|
+
break;
|
|
139
|
+
case "--chroma": {
|
|
140
|
+
const val = args[++i] ?? "4:2:0";
|
|
141
|
+
if (val !== "4:4:4" && val !== "4:2:2" && val !== "4:2:0") {
|
|
142
|
+
console.error("Error: --chroma must be 4:4:4, 4:2:2, or 4:2:0.");
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
result.chroma = val;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "--verbose":
|
|
149
|
+
case "-v":
|
|
150
|
+
result.verbose = true;
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
if (arg.startsWith("-")) {
|
|
154
|
+
console.error(`Unknown option: ${arg}`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
positional.push(arg);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (positional[0] !== void 0) result.input = positional[0];
|
|
162
|
+
if (positional[1] !== void 0) result.output = positional[1];
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
function formatBytes(bytes) {
|
|
166
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
167
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
168
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
169
|
+
}
|
|
170
|
+
function printOptimizeHelp() {
|
|
171
|
+
console.log(`
|
|
172
|
+
modern-pdf optimize — Optimize images in a PDF file
|
|
173
|
+
|
|
174
|
+
Usage:
|
|
175
|
+
modern-pdf optimize <input.pdf> <output.pdf> [options]
|
|
176
|
+
|
|
177
|
+
Options:
|
|
178
|
+
--quality <n>, -q <n> JPEG quality 1-100 (default: 80)
|
|
179
|
+
--progressive Use progressive JPEG encoding
|
|
180
|
+
--grayscale Auto-detect and convert grayscale images
|
|
181
|
+
--dedup Deduplicate identical images
|
|
182
|
+
--chroma <mode> Chroma subsampling: 4:4:4, 4:2:2, 4:2:0 (default: 4:2:0)
|
|
183
|
+
--verbose, -v Print per-image optimization details
|
|
184
|
+
--help, -h Show this help
|
|
185
|
+
|
|
186
|
+
Examples:
|
|
187
|
+
modern-pdf optimize report.pdf report-opt.pdf
|
|
188
|
+
modern-pdf optimize scan.pdf scan-opt.pdf --quality 60 --grayscale --dedup -v
|
|
189
|
+
`.trim());
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/cli/index.ts
|
|
194
|
+
/**
|
|
195
|
+
* @module cli/index
|
|
196
|
+
*
|
|
197
|
+
* CLI entry point for modern-pdf-lib.
|
|
198
|
+
*
|
|
199
|
+
* Usage:
|
|
200
|
+
* npx modern-pdf optimize input.pdf output.pdf [options]
|
|
201
|
+
* npx modern-pdf --help
|
|
202
|
+
*/
|
|
203
|
+
async function main() {
|
|
204
|
+
const args = process.argv.slice(2);
|
|
205
|
+
const command = args[0];
|
|
206
|
+
if (!command || command === "--help" || command === "-h") {
|
|
207
|
+
printHelp();
|
|
208
|
+
process.exit(0);
|
|
209
|
+
}
|
|
210
|
+
if (command === "--version" || command === "-v") {
|
|
211
|
+
console.log("modern-pdf-lib CLI");
|
|
212
|
+
process.exit(0);
|
|
213
|
+
}
|
|
214
|
+
switch (command) {
|
|
215
|
+
case "optimize":
|
|
216
|
+
await optimizeCommand(args.slice(1));
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
console.error(`Unknown command: ${command}`);
|
|
220
|
+
console.error("Run \"modern-pdf --help\" for usage information.");
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
main().catch((err) => {
|
|
225
|
+
console.error(err);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
});
|
|
228
|
+
function printHelp() {
|
|
229
|
+
console.log(`
|
|
230
|
+
modern-pdf-lib CLI
|
|
231
|
+
|
|
232
|
+
Usage:
|
|
233
|
+
modern-pdf <command> [options]
|
|
234
|
+
|
|
235
|
+
Commands:
|
|
236
|
+
optimize Optimize images in a PDF file
|
|
237
|
+
|
|
238
|
+
Options:
|
|
239
|
+
--help, -h Show this help message
|
|
240
|
+
--version, -v Show version
|
|
241
|
+
|
|
242
|
+
Run "modern-pdf optimize --help" for optimize options.
|
|
243
|
+
`.trim());
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
//#endregion
|
|
247
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|