Cleared up client and shared modules

This commit is contained in:
Saud Fatayerji 2023-11-10 21:08:07 +03:00
parent 97e4eab7bb
commit 55f55afed2
11 changed files with 203 additions and 168 deletions

View File

@ -1,53 +1,4 @@
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<Uint8Array>;
}
declare module '@stirling-pdf/shared-operations/functions/extractPages' {
export async function extractPages(snapshot: string | Uint8Array | ArrayBuffer, pagesToExtractArray: number[]): Promise<Uint8Array>;
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<Uint8Array>;
}
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<Uint8Array>;
}
declare module '@stirling-pdf/shared-operations/functions/rotatePages' {
export async function rotatePages(snapshot: string | Uint8Array | ArrayBuffer, rotation: number): Promise<Uint8Array>;
}
declare module '@stirling-pdf/shared-operations/functions/scaleContent' {
export async function scaleContent(snapshot: string | Uint8Array | ArrayBuffer, scaleFactor: number): Promise<Uint8Array>;
}
declare module '@stirling-pdf/shared-operations/functions/scalePage' {
export async function scalePage(snapshot: string | Uint8Array | ArrayBuffer, pageSize: {width:number,height:number}): Promise<Uint8Array>;
}
declare module '@stirling-pdf/shared-operations/functions/splitPDF' {
export async function splitPDF(snapshot: string | Uint8Array | ArrayBuffer, splitAfterPageArray: number[]): Promise<Uint8Array>;
declare module '@stirling-pdf/shared-operations/wasm/pdfcpu/pdfcpu-wrapper-browser.js' {
export async function oneToOne(wasmArray: any, snapshot: any): Promise<Uint8Array>;
}

View File

@ -1,53 +1,12 @@
// Import injected libraries here!
import SharedOperations from '@stirling-pdf/shared-operations'
import * as pdfcpuWrapper from "@stirling-pdf/shared-operations/wasm/pdfcpu/pdfcpu-wrapper-browser.js";
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);
async function impose(snapshot: any, nup: number, format: string) {
return SharedOperations.impose(snapshot, nup, format, pdfcpuWrapper)
}
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);
export default {
...SharedOperations,
impose,
}

129
package-lock.json generated
View File

@ -3982,6 +3982,12 @@
"node": ">= 10"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
"dev": true
},
"node_modules/@types/archiver": {
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.4.tgz",
@ -4038,6 +4044,25 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
"dev": true,
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/busboy": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.3.tgz",
"integrity": "sha512-YMBLFN/xBD8bnqywIlGyYqsNFXu6bsiY7h3Ae0kO17qEuTjsqeyYMRPSUDacIKIquws2Y6KjmxAyNx8xB3xQbw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/chai": {
"version": "4.3.9",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz",
@ -4053,6 +4078,15 @@
"@types/chai": "*"
}
},
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/downloadjs": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@types/downloadjs/-/downloadjs-1.4.5.tgz",
@ -4065,6 +4099,40 @@
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true
},
"node_modules/@types/express": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"dev": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"node_modules/@types/express-fileupload": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.4.4.tgz",
"integrity": "sha512-kxCs5oJ40JPhvh3LpxCeGfuSZIl8/6bk85u1YqNcIbfQCmUm3u+Ao1oOiSt/VdbEPs+V3JQg8giqxAyqXlpbWg==",
"dev": true,
"dependencies": {
"@types/busboy": "*",
"@types/express": "*"
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.17.41",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
"dev": true,
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*",
"@types/send": "*"
}
},
"node_modules/@types/fs-extra": {
"version": "8.1.4",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.4.tgz",
@ -4079,6 +4147,12 @@
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA=="
},
"node_modules/@types/http-errors": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
"dev": true
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
@ -4145,6 +4219,21 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true
},
"node_modules/@types/multer": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.10.tgz",
"integrity": "sha512-6l9mYMhUe8wbnz/67YIjc7ZJyQNZoKq7fRXVf7nMdgWgalD0KyzJ2ywI7hoATUSXSbTu9q2HBiEwzy0tNN1v2w==",
"dev": true,
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/node": {
"version": "18.18.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.7.tgz",
@ -4164,6 +4253,18 @@
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz",
"integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g=="
},
"node_modules/@types/qs": {
"version": "6.9.10",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
"integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==",
"dev": true
},
"node_modules/@types/range-parser": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
"dev": true
},
"node_modules/@types/react": {
"version": "18.2.32",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.32.tgz",
@ -4242,6 +4343,27 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz",
"integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw=="
},
"node_modules/@types/send": {
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
"dev": true,
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-static": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
"dev": true,
"dependencies": {
"@types/http-errors": "*",
"@types/mime": "*",
"@types/node": "*"
}
},
"node_modules/@types/sinonjs__fake-timers": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
@ -13673,6 +13795,13 @@
"multer": "^1.4.5-lts.1",
"opencv-wasm": "^4.3.0-10",
"pdf-lib": "^1.17.1"
},
"devDependencies": {
"@tsconfig/node10": "^1.0.9",
"@types/express": "^4.17.21",
"@types/express-fileupload": "^1.4.4",
"@types/multer": "^1.4.10",
"typescript": "^5.2.2"
}
},
"shared-operations": {

View File

@ -1,5 +1,5 @@
export async function impose(snapshot, nup, format, pdfcpuWraopper) {
return await pdfcpuWraopper.oneToOne([
export async function impose(snapshot: any, nup: number, format: string, pdfcpuWrapper: any) {
return await pdfcpuWrapper.oneToOne([
"pdfcpu.wasm",
"nup",
"-c",

View File

@ -1,7 +1,7 @@
import { PDFDocument } from 'pdf-lib';
import { detectEmptyPages } from "./common/detectEmptyPages.js";
export async function removeBlankPages(snapshot, whiteThreashold) {
export async function removeBlankPages(snapshot: string | ArrayBuffer | Uint8Array, whiteThreashold: number) {
const emptyPages = await detectEmptyPages(snapshot, whiteThreashold);

View File

@ -1,6 +1,7 @@
import { PDFDocument } from 'pdf-lib';
import PDFJS from 'pdfjs-dist';
import jsQR from "jsqr";
import { detectEmptyPages } from "./common/detectEmptyPages.js";
import { getImagesOnPage } from "./common/getImagesOnPage.js";
@ -10,8 +11,7 @@ import { TypedArray, DocumentInitParameters } from 'pdfjs-dist/types/src/display
export async function splitOn(
snapshot: string | ArrayBuffer | Uint8Array,
type: "BAR_CODE"|"QR_CODE"|"BLANK_PAGE",
whiteThreashold: number,
jsQR: (arg0: any, arg1: number, arg2: number) => any) {
whiteThreashold: number) {
let splitAtPages: number[] = [];
switch (type) {
@ -86,7 +86,7 @@ export async function splitOn(
return pagesWithQR;
}
async function checkForQROnImage(image) {
async function checkForQROnImage(image: any) {
// TODO: There is an issue with the jsQR package (The package expects rgba but sometimes we have rgb), and the package seems to be stale, we could create a fork and fix the issue. In the meanwhile we just force rgba:
// Check for rgb and convert to rgba

View File

@ -0,0 +1,28 @@
// Import injected libraries here!
import { editMetadata } from "./functions/editMetadata";
import { extractPages } from "./functions/extractPages";
import { impose } from "./functions/impose";
import { mergePDFs } from './functions/mergePDFs';
import { organizePages } from './functions/organizePages';
import { removeBlankPages } from './functions/removeBlankPages';
import { rotatePages } from './functions/rotatePages';
import { scaleContent} from './functions/scaleContent';
import { scalePage } from './functions/scalePage';
import { splitOn } from './functions/splitOn';
import { splitPDF } from './functions/splitPDF';
export default {
editMetadata,
extractPages,
impose,
mergePDFs,
organizePages,
removeBlankPages,
rotatePages,
scaleContent,
scalePage,
splitOn,
splitPDF,
}

View File

@ -1,7 +1,7 @@
{
"name": "@stirling-pdf/shared-operations",
"version": "0.0.0",
"main": "index.js",
"main": "index.ts",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,18 @@
export function organizeWaitOperations(operations) {
export interface Operation {
values: {id:any};
type: string;
operations?: Operation[];
}
export function organizeWaitOperations(operations: Operation[]) {
// Initialize an object to store the counts and associated "done" operations
const waitCounts = {};
const doneOperations = {};
// Function to count "type: wait" operations and associate "done" operations per id
function countWaitOperationsAndDone(operations) {
function countWaitOperationsAndDone(operations: Operation[]) {
for (const operation of operations) {
if (operation.type === "wait") {
const id = operation.values.id;

View File

@ -1,5 +1,17 @@
import { organizeWaitOperations } from "./organizeWaitOperations.js";
import { extractPages } from "../functions/extractPages.js";
import { impose } from '../functions/impose.js';
import { mergePDFs } from '../functions/mergePDFs.js';
import { rotatePages } from '../functions/rotatePages.js';
import { scaleContent} from '../functions/scaleContent.js';
import { scalePage } from '../functions/scalePage.js';
import { splitPDF } from '../functions/splitPDF.js';
import { Metadata as dependantEditMetadata } from '../functions/editMetadata.js';
import { organizePages } from '../functions/organizePages.js';
import { removeBlankPages} from '../functions/removeBlankPages.js';
import { splitOn } from "../functions/splitOn.js";
/**
* @typedef PDF
* @property {string} originalFileName
@ -11,10 +23,9 @@ import { organizeWaitOperations } from "./organizeWaitOperations.js";
*
* @param {JSON} operations
* @param {PDF|PDF[]} input
* @param {import('./functions.js')} Functions
* @returns {}
*/
export async function * traverseOperations(operations, input, Functions) {
export async function * traverseOperations(operations, input) {
const waitOperations = organizeWaitOperations(operations);
/** @type {PDF[]} */ let results = [];
yield* nextOperation(operations, input);
@ -74,13 +85,13 @@ export async function * traverseOperations(operations, input, Functions) {
case "extract":
yield* nToN(input, operation, async (input) => {
input.fileName += "_extractedPages";
input.buffer = await Functions.extractPages(input.buffer, operation.values["pagesToExtractArray"]);
input.buffer = await extractPages(input.buffer, operation.values["pagesToExtractArray"]);
});
break;
case "impose":
yield* nToN(input, operation, async (input) => {
input.fileName += "_imposed";
input.buffer = await Functions.impose(input.buffer, operation.values["nup"], operation.values["format"]);
input.buffer = await impose(input.buffer, operation.values["nup"], operation.values["format"]);
});
break;
case "merge":
@ -88,20 +99,20 @@ export async function * traverseOperations(operations, input, Functions) {
return {
originalFileName: inputs.map(input => input.originalFileName).join("_and_"),
fileName: inputs.map(input => input.fileName).join("_and_") + "_merged",
buffer: await Functions.mergePDFs(inputs.map(input => input.buffer))
buffer: await mergePDFs(inputs.map(input => input.buffer))
}
});
break;
case "rotate":
yield* nToN(input, operation, async (input) => {
input.fileName += "_turned";
input.buffer = await Functions.rotatePages(input.buffer, operation.values["rotation"]);
input.buffer = await rotatePages(input.buffer, operation.values["rotation"]);
});
break;
case "split":
// TODO: A split might break the done condition, it may count multiple times. Needs further testing!
yield* oneToN(input, operation, async (input) => {
const splitResult = await Functions.splitPDF(input.buffer, operation.values["pagesToSplitAfterArray"]);
const splitResult = await splitPDF(input.buffer, operation.values["pagesToSplitAfterArray"]);
const splits = [];
for (let j = 0; j < splitResult.length; j++) {
@ -117,24 +128,24 @@ export async function * traverseOperations(operations, input, Functions) {
case "editMetadata":
yield* nToN(input, operation, async (input) => {
input.fileName += "_metadataEdited";
input.buffer = await Functions.editMetadata(input.buffer, operation.values["metadata"]);
input.buffer = await editMetadata(input.buffer, operation.values["metadata"]);
});
break;
case "organizePages":
yield* nToN(input, operation, async (input) => {
input.fileName += "_pagesOrganized";
input.buffer = await Functions.organizePages(input.buffer, operation.values["operation"], operation.values["customOrderString"]);
input.buffer = await organizePages(input.buffer, operation.values["operation"], operation.values["customOrderString"]);
});
break;
case "removeBlankPages":
yield* nToN(input, operation, async (input) => {
input.fileName += "_removedBlanks";
input.buffer = await Functions.removeBlankPages(input.buffer, operation.values["whiteThreashold"]);
input.buffer = await removeBlankPages(input.buffer, operation.values["whiteThreashold"]);
});
break;
case "splitOn":
yield* oneToN(input, operation, async (input) => {
const splitResult = await Functions.splitOn(input.buffer, operation.values["type"], operation.values["whiteThreashold"]);
const splitResult = await splitOn(input.buffer, operation.values["type"], operation.values["whiteThreashold"]);
const splits = [];
for (let j = 0; j < splitResult.length; j++) {
splits.push({