diff --git a/.gitignore b/.gitignore index 60ea030a..9f0a174e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ *.code-workspace +.idea/ \ No newline at end of file diff --git a/client-ionic/declarations/shared-operations.d.ts b/client-ionic/declarations/shared-operations.d.ts new file mode 100644 index 00000000..7d910b50 --- /dev/null +++ b/client-ionic/declarations/shared-operations.d.ts @@ -0,0 +1,53 @@ + +declare module '@stirling-pdf/shared-operations/functions/editMetadata' { + export type Metadata = { + Title: string | null | undefined; // The title of the document. + Author: string | null | undefined; // The author of the document. + Subject: string | null | undefined; // The subject of the document. + Keywords: string[] | null | undefined; // An array of keywords associated with the document. + Producer: string | null | undefined; // The producer of the document. + Creator: string | null | undefined; // The creator of the document. + CreationDate: Date | null | undefined; // The date when the document was created. + ModificationDate: Date | null | undefined; // The date when the document was last modified. + } + export async function editMetadata(snapshot: string | Uint8Array | ArrayBuffer, metadata: Metadata): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/extractPages' { + export async function extractPages(snapshot: string | Uint8Array | ArrayBuffer, pagesToExtractArray: number[]): Promise; + export async function createSubDocument(pdfDoc: typeof import("pdf-lib").PDFDocument, pagesToExtractArray: number[]) +} + +declare module '@stirling-pdf/shared-operations/functions/mergePDFs' { + export async function mergePDFs(snapshots: (string | Uint8Array | ArrayBuffer)[]): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/organizePages' { + export async function organizePages( + snapshot: string | Uint8Array | ArrayBuffer, + operation: "CUSTOM_PAGE_ORDER" | + "REVERSE_ORDER" | + "DUPLEX_SORT" | + "BOOKLET_SORT" | + "ODD_EVEN_SPLIT" | + "REMOVE_FIRST" | + "REMOVE_LAST" | + "REMOVE_FIRST_AND_LAST", + customOrderString: string): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/rotatePages' { + export async function rotatePages(snapshot: string | Uint8Array | ArrayBuffer, rotation: number): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/scaleContent' { + export async function scaleContent(snapshot: string | Uint8Array | ArrayBuffer, scaleFactor: number): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/scalePage' { + export async function scalePage(snapshot: string | Uint8Array | ArrayBuffer, pageSize: {width:number,height:number}): Promise; +} + +declare module '@stirling-pdf/shared-operations/functions/splitPDF' { + export async function splitPDF(snapshot: string | Uint8Array | ArrayBuffer, splitAfterPageArray: number[]): Promise; +} diff --git a/client-ionic/package.json b/client-ionic/package.json index 01841cd8..a5696900 100644 --- a/client-ionic/package.json +++ b/client-ionic/package.json @@ -17,14 +17,15 @@ "@capawesome/capacitor-file-picker": "^5.1.1", "@ionic/react": "^7.0.0", "@ionic/react-router": "^7.0.0", + "@stirling-pdf/shared-operations": "*", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", "ionicons": "^7.0.0", + "pdf-lib": "^1.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router": "^5.3.4", - "react-router-dom": "^5.3.4", - "@stirling-pdf/shared-operations": "*" + "react-router-dom": "^5.3.4" }, "devDependencies": { "@testing-library/jest-dom": "^5.16.5", diff --git a/client-ionic/src/pages/Home.tsx b/client-ionic/src/pages/Home.tsx index 9b0ab963..24708a73 100644 --- a/client-ionic/src/pages/Home.tsx +++ b/client-ionic/src/pages/Home.tsx @@ -1,23 +1,28 @@ import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton } from '@ionic/react'; -import ExploreContainer from '../components/ExploreContainer'; import './Home.css'; -import "../../../server-node/public/wasm/pdfcpu-wrapper-browser.js" -import { splitPDF } from '../utils/pdf-operations.js'; +import { rotatePages } from '../utils/pdf-operations.js'; import { FilePicker } from '@capawesome/capacitor-file-picker'; -async function testFunction() { - console.log("Test Function for Button Click"); - console.log(splitPDF); +console.log(rotatePages); +async function rotate90() { + console.log("Test rotate 90 with Button Click"); - const result = await FilePicker.pickFiles({ - types: ['application/pdf'], - multiple: true, - }); + const pickedFiles = await FilePicker.pickFiles({ + types: ['application/pdf'], + multiple: false, + }); + const file = pickedFiles.files[0]; + + const buffer = await file.blob?.arrayBuffer(); + if (!buffer) return; + + const rotated = await rotatePages(buffer, 90) - console.log(result); + console.log(rotated); } + const Home: React.FC = () => { return ( @@ -32,7 +37,7 @@ const Home: React.FC = () => { Blank - Default + Rotate 90 ); diff --git a/client-ionic/src/utils/pdf-operations.js b/client-ionic/src/utils/pdf-operations.js deleted file mode 100644 index 4974b1e4..00000000 --- a/client-ionic/src/utils/pdf-operations.js +++ /dev/null @@ -1,48 +0,0 @@ -// PDFLib gets importet via index.html script-tag -import * as pdfcpuWraopper from "../../../server-node/public/wasm/pdfcpu-wrapper-browser.js"; - -import { editMetadata as dependantEditMetadata} from "@stirling-pdf/shared-operations/functions/editMetadata.js"; -import { extractPages as dependantExtractPages } from "@stirling-pdf/shared-operations/functions/extractPages.js"; -import { impose as dependantImpose } from '@stirling-pdf/shared-operations/functions/impose.js'; -import { mergePDFs as dependantMergePDFs } from '@stirling-pdf/shared-operations/functions/mergePDFs.js'; -import { organizePages as dependantOrganizePages } from '@stirling-pdf/shared-operations/functions/organizePages.js'; -import { rotatePages as dependantRotatePages } from '@stirling-pdf/shared-operations/functions/rotatePages.js'; -import { scaleContent as dependantScaleContent} from '@stirling-pdf/shared-operations/functions/scaleContent.js'; -import { scalePage as dependantScalePage } from '@stirling-pdf/shared-operations/functions/scalePage.js'; -import { splitPDF as dependantSplitPDF } from '@stirling-pdf/shared-operations/functions/splitPDF.js'; - -export async function editMetadata(snapshot, metadata) { - return dependantEditMetadata(snapshot, metadata, PDFLib); -} - -export async function extractPages(snapshot, pagesToExtractArray) { - return dependantExtractPages(snapshot, pagesToExtractArray, PDFLib); -} - -export async function impose(snapshot, nup, format) { - return dependantImpose(snapshot, nup, format, pdfcpuWraopper); -} - -export async function mergePDFs(snapshots) { - return dependantMergePDFs(snapshots, PDFLib); -} - -export async function organizePages(snapshot, operation, customOrderString) { - return dependantOrganizePages(snapshot, operation, customOrderString, PDFLib); -} - -export async function rotatePages(snapshot, rotation) { - return dependantRotatePages(snapshot, rotation, PDFLib); -} - -export async function scaleContent(snapshot, scaleFactor) { - return dependantScaleContent(snapshot, scaleFactor, PDFLib); -} - -export async function scalePage(snapshot, pageSize) { - return dependantScalePage(snapshot, pageSize, PDFLib); -} - -export async function splitPDF(snapshot, splitAfterPageArray) { - return dependantSplitPDF(snapshot, splitAfterPageArray, PDFLib); -} diff --git a/client-ionic/src/utils/pdf-operations.ts b/client-ionic/src/utils/pdf-operations.ts new file mode 100644 index 00000000..83716144 --- /dev/null +++ b/client-ionic/src/utils/pdf-operations.ts @@ -0,0 +1,53 @@ + +// Import injected libraries here! + +import { Metadata, editMetadata as dependantEditMetadata} from "@stirling-pdf/shared-operations/functions/editMetadata"; +import { extractPages as dependantExtractPages } from "@stirling-pdf/shared-operations/functions/extractPages"; +import { mergePDFs as dependantMergePDFs } from '@stirling-pdf/shared-operations/functions/mergePDFs'; +import { organizePages as dependantOrganizePages } from '@stirling-pdf/shared-operations/functions/organizePages'; +import { rotatePages as dependantRotatePages } from '@stirling-pdf/shared-operations/functions/rotatePages'; +import { scaleContent as dependantScaleContent} from '@stirling-pdf/shared-operations/functions/scaleContent'; +import { scalePage as dependantScalePage } from '@stirling-pdf/shared-operations/functions/scalePage'; +import { splitPDF as dependantSplitPDF } from '@stirling-pdf/shared-operations/functions/splitPDF'; + +export async function editMetadata(snapshot: string | Uint8Array | ArrayBuffer, metadata: Metadata) { + return dependantEditMetadata(snapshot, metadata); +} + +export async function extractPages(snapshot: string | Uint8Array | ArrayBuffer, pagesToExtractArray: number[]) { + return dependantExtractPages(snapshot, pagesToExtractArray); +} + +export async function mergePDFs(snapshots: (string | Uint8Array | ArrayBuffer)[]) { + return dependantMergePDFs(snapshots); +} + +export async function organizePages( + snapshot: string | Uint8Array | ArrayBuffer, + operation: "CUSTOM_PAGE_ORDER" | + "REVERSE_ORDER" | + "DUPLEX_SORT" | + "BOOKLET_SORT" | + "ODD_EVEN_SPLIT" | + "REMOVE_FIRST" | + "REMOVE_LAST" | + "REMOVE_FIRST_AND_LAST", + customOrderString: string) { + return dependantOrganizePages(snapshot, operation, customOrderString); +} + +export async function rotatePages(snapshot: string | Uint8Array | ArrayBuffer, rotation: number) { + return dependantRotatePages(snapshot, rotation); +} + +export async function scaleContent(snapshot: string | Uint8Array | ArrayBuffer, scaleFactor: number) { + return dependantScaleContent(snapshot, scaleFactor); +} + +export async function scalePage(snapshot: string | Uint8Array | ArrayBuffer, pageSize: { width: number; height: number; }) { + return dependantScalePage(snapshot, pageSize); +} + +export async function splitPDF(snapshot: string | Uint8Array | ArrayBuffer, splitAfterPageArray: number[]) { + return dependantSplitPDF(snapshot, splitAfterPageArray); +} diff --git a/client-ionic/tsconfig.json b/client-ionic/tsconfig.json index 7a0abb4b..2bc4a5fb 100644 --- a/client-ionic/tsconfig.json +++ b/client-ionic/tsconfig.json @@ -16,6 +16,9 @@ "noEmit": true, "jsx": "react-jsx" }, - "include": ["src", "../shared-operations/packages/wasm", "../server-node/public/utils/pdfcpu-wrapper-node.js"], + "include": [ + "src", + "declarations/*.d.ts" + ], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/package-lock.json b/package-lock.json index 90fc19b4..4bfa655a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "version": "0.0.0", "dependencies": { "@capacitor/core": "^5.5.0", + "@capacitor/filesystem": "^5.1.4", "@capawesome/capacitor-file-picker": "^5.1.1", "@ionic/react": "^7.0.0", "@ionic/react-router": "^7.0.0", @@ -26,6 +27,7 @@ "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", "ionicons": "^7.0.0", + "pdf-lib": "^1.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router": "^5.3.4", @@ -1967,6 +1969,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/@capacitor/filesystem": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@capacitor/filesystem/-/filesystem-5.1.4.tgz", + "integrity": "sha512-10EM1KvFMs+pTzxkcflspzxBWcX9sOnS9nTP5Afjr5hn4OxLrwTFySw2Z12Uv6jdN4OnhY3jXtDKXPljXvXILg==", + "peerDependencies": { + "@capacitor/core": "^5.1.1" + } + }, "node_modules/@capawesome/capacitor-file-picker": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@capawesome/capacitor-file-picker/-/capacitor-file-picker-5.1.1.tgz", diff --git a/shared-operations/functions/editMetadata.js b/shared-operations/functions/editMetadata.js index 05669944..2703c5b6 100644 --- a/shared-operations/functions/editMetadata.js +++ b/shared-operations/functions/editMetadata.js @@ -1,5 +1,6 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument, ParseSpeeds } from 'pdf-lib'; + /** * @typedef {Object} Metadata @@ -17,13 +18,12 @@ import PDFLib from 'pdf-lib'; * * @param {Uint16Array} snapshot * @param {Metadata} metadata - Set property to null or "" to clear, undefined properties will be skipped. - * @param {PDFLib} PDFLib - * @returns + * @returns Promise */ export async function editMetadata(snapshot, metadata) { // Load the original PDF file - const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { - parseSpeed: PDFLib.ParseSpeeds.Fastest, + const pdfDoc = await PDFDocument.load(snapshot, { + parseSpeed: ParseSpeeds.Fastest, }); if(metadata.Title !== undefined) diff --git a/shared-operations/functions/extractPages.js b/shared-operations/functions/extractPages.js index cd88753a..5e229b87 100644 --- a/shared-operations/functions/extractPages.js +++ b/shared-operations/functions/extractPages.js @@ -1,15 +1,15 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument } from 'pdf-lib'; export async function extractPages(snapshot, pagesToExtractArray) { - const pdfDoc = await PDFLib.PDFDocument.load(snapshot) + const pdfDoc = await PDFDocument.load(snapshot) // TODO: invent a better format for pagesToExtractArray and convert it. return createSubDocument(pdfDoc, pagesToExtractArray); }; export async function createSubDocument(pdfDoc, pagesToExtractArray) { - const subDocument = await PDFLib.PDFDocument.create(); + const subDocument = await PDFDocument.create(); // Check that array max number is not larger pdf pages number if(Math.max(...pagesToExtractArray) >= pdfDoc.getPageCount()) { diff --git a/shared-operations/functions/mergePDFs.js b/shared-operations/functions/mergePDFs.js index 39094e8b..3799d9fc 100644 --- a/shared-operations/functions/mergePDFs.js +++ b/shared-operations/functions/mergePDFs.js @@ -1,12 +1,12 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument } from 'pdf-lib'; export const mergePDFs = async (snapshots) => { - const mergedPdf = await PDFLib.PDFDocument.create(); + const mergedPdf = await PDFDocument.create(); for (let i = 0; i < snapshots.length; i++) { - const pdfToMerge = await PDFLib.PDFDocument.load(snapshots[i]); + const pdfToMerge = await PDFDocument.load(snapshots[i]); const copiedPages = await mergedPdf.copyPages(pdfToMerge, pdfToMerge.getPageIndices()); copiedPages.forEach((page) => mergedPdf.addPage(page)); diff --git a/shared-operations/functions/organizePages.js b/shared-operations/functions/organizePages.js index f63327b9..b92d975c 100644 --- a/shared-operations/functions/organizePages.js +++ b/shared-operations/functions/organizePages.js @@ -1,5 +1,5 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument } from 'pdf-lib'; /** * @typedef {"CUSTOM_PAGE_ORDER"|"REVERSE_ORDER"|"DUPLEX_SORT"|"BOOKLET_SORT"|"ODD_EVEN_SPLIT"|"REMOVE_FIRST"|"REMOVE_LAST"|"REMOVE_FIRST_AND_LAST"} OrderOperation @@ -14,8 +14,8 @@ import PDFLib from 'pdf-lib'; * @returns */ export async function organizePages(snapshot, operation, customOrderString) { - const pdfDoc = await PDFLib.PDFDocument.load(snapshot); - let subDocument = await PDFLib.PDFDocument.create(); + const pdfDoc = await PDFDocument.load(snapshot); + let subDocument = await PDFDocument.create(); const copiedPages = await subDocument.copyPages(pdfDoc, pdfDoc.getPageIndices()); diff --git a/shared-operations/functions/rotatePages.js b/shared-operations/functions/rotatePages.js index ca684a12..73bcb481 100644 --- a/shared-operations/functions/rotatePages.js +++ b/shared-operations/functions/rotatePages.js @@ -1,17 +1,17 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument, ParseSpeeds, degrees } from 'pdf-lib'; -export async function rotatePages (snapshot, rotation) { +export async function rotatePages(snapshot, rotation) { // Load the original PDF file - const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { - parseSpeed: PDFLib.ParseSpeeds.Fastest, + const pdfDoc = await PDFDocument.load(snapshot, { + parseSpeed: ParseSpeeds.Fastest, }); const pages = pdfDoc.getPages(); pages.forEach(page => { // Change page size - page.setRotation(PDFLib.degrees(rotation)) + page.setRotation(degrees(rotation)) }); // Serialize the modified document diff --git a/shared-operations/functions/scaleContent.js b/shared-operations/functions/scaleContent.js index e61b330f..6fc21edb 100644 --- a/shared-operations/functions/scaleContent.js +++ b/shared-operations/functions/scaleContent.js @@ -1,10 +1,10 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument, ParseSpeeds } from 'pdf-lib'; export async function scaleContent(snapshot, scaleFactor) { // Load the original PDF file - const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { - parseSpeed: PDFLib.ParseSpeeds.Fastest, + const pdfDoc = await PDFDocument.load(snapshot, { + parseSpeed: ParseSpeeds.Fastest, }); const pages = pdfDoc.getPages(); diff --git a/shared-operations/functions/scalePage.js b/shared-operations/functions/scalePage.js index 567f1106..cfe5d621 100644 --- a/shared-operations/functions/scalePage.js +++ b/shared-operations/functions/scalePage.js @@ -1,10 +1,10 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument, ParseSpeeds } from 'pdf-lib'; export async function scalePage(snapshot, pageSize) { // Load the original PDF file - const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { - parseSpeed: PDFLib.ParseSpeeds.Fastest, + const pdfDoc = await PDFDocument.load(snapshot, { + parseSpeed: ParseSpeeds.Fastest, }); const new_size = pageSize; diff --git a/shared-operations/functions/splitPDF.js b/shared-operations/functions/splitPDF.js index 24695cf6..0b1b8656 100644 --- a/shared-operations/functions/splitPDF.js +++ b/shared-operations/functions/splitPDF.js @@ -1,10 +1,10 @@ -import PDFLib from 'pdf-lib'; +import { PDFDocument } from 'pdf-lib'; import { createSubDocument } from "./extractPages.js"; export async function splitPDF(snapshot, splitAfterPageArray) { - const pdfDoc = await PDFLib.PDFDocument.load(snapshot) + const pdfDoc = await PDFDocument.load(snapshot) const numberOfPages = pdfDoc.getPages().length;