From a5060f0fd348b39337298958f571bcc4e417bdb8 Mon Sep 17 00:00:00 2001 From: Felix Kaspar Date: Mon, 20 Nov 2023 21:04:49 +0100 Subject: [PATCH] rewrote impose to use new Operator class, dependencies (pdfcpu) can be made environment-aware using tsconfig.json --- package-lock.json | 28 +++++- .../{PdfcpuWrapper.d.ts => pdfcpu.d.ts} | 2 +- server-node/nodemon.json | 6 -- server-node/package.json | 6 +- server-node/src/routes/api/api-controller.ts | 8 +- .../src/routes/api/operations-controller.ts | 6 +- .../src/routes/api/workflow-controller.ts | 5 +- server-node/src/utils/pdf-operations.ts | 16 ---- server-node/tsconfig.json | 8 +- shared-operations/declarations/pdfcpu.d.ts | 3 + shared-operations/src/functions/impose.ts | 94 +++++++++++++------ shared-operations/src/functions/index.ts | 58 ++++++++++++ shared-operations/src/index.ts | 60 ------------ ...er-browser.js => pdfcpu-wrapper.client.js} | 0 ...apper-node.js => pdfcpu-wrapper.server.js} | 0 .../src/workflow/traverseOperations.ts | 67 +++---------- shared-operations/tsconfig.json | 8 ++ 17 files changed, 188 insertions(+), 187 deletions(-) rename server-node/declarations/{PdfcpuWrapper.d.ts => pdfcpu.d.ts} (51%) delete mode 100644 server-node/nodemon.json delete mode 100644 server-node/src/utils/pdf-operations.ts create mode 100644 shared-operations/declarations/pdfcpu.d.ts create mode 100644 shared-operations/src/functions/index.ts delete mode 100644 shared-operations/src/index.ts rename shared-operations/src/wasm/pdfcpu/{pdfcpu-wrapper-browser.js => pdfcpu-wrapper.client.js} (100%) rename shared-operations/src/wasm/pdfcpu/{pdfcpu-wrapper-node.js => pdfcpu-wrapper.server.js} (100%) create mode 100644 shared-operations/tsconfig.json diff --git a/package-lock.json b/package-lock.json index a98c8b512..12c5f9c8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9466,7 +9466,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -12496,7 +12495,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } @@ -13020,6 +13018,19 @@ "strip-json-comments": "^2.0.0" } }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tsconfig/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -14548,15 +14559,26 @@ "jsqr": "^1.4.0", "multer": "^1.4.5-lts.1", "nodemon": "^3.0.1", - "pdf-lib": "^1.17.1" + "pdf-lib": "^1.17.1", + "tsconfig-paths": "^4.2.0" }, "devDependencies": { + "@types/archiver": "^6.0.1", "@types/express": "^4.17.21", "@types/multer": "^1.4.10", "ts-node-dev": "^2.0.0", "typescript": "^5.2.2" } }, + "server-node/node_modules/@types/archiver": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-6.0.1.tgz", + "integrity": "sha512-F2+JkmDYvtQrtb2YldwL0apRB1/WB6ub+1zVF/bKp3TOygUMFqfOLuw5Fj62Q+DPwJUFz1eocMxJMu7yVpplZA==", + "dev": true, + "dependencies": { + "@types/readdir-glob": "*" + } + }, "shared-operations": { "name": "@stirling-pdf/shared-operations", "version": "0.0.0", diff --git a/server-node/declarations/PdfcpuWrapper.d.ts b/server-node/declarations/pdfcpu.d.ts similarity index 51% rename from server-node/declarations/PdfcpuWrapper.d.ts rename to server-node/declarations/pdfcpu.d.ts index f0e2e814f..a444033a5 100644 --- a/server-node/declarations/PdfcpuWrapper.d.ts +++ b/server-node/declarations/pdfcpu.d.ts @@ -1,3 +1,3 @@ -declare module '@stirling-pdf/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-node.js' { +declare module '#pdfcpu' { export function oneToOne(wasmArray: string[], snapshot: Uint8Array): Promise; } \ No newline at end of file diff --git a/server-node/nodemon.json b/server-node/nodemon.json deleted file mode 100644 index 55fcade2b..000000000 --- a/server-node/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["src", "../shared-operations/src"], - "ext": "ts,json", - "ignore": ["src/**/*.spec.ts"], - "exec": "node --trace-warnings --experimental-specifier-resolution=node --loader ts-node/esm ./src/index.ts" -} \ No newline at end of file diff --git a/server-node/package.json b/server-node/package.json index 9ee1af42d..c7f172ec1 100644 --- a/server-node/package.json +++ b/server-node/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "npx tsc", "start": "node dist/index.js", - "dev": "nodemon" + "dev": "npx tsx watch src/index.ts" }, "keywords": [], "author": "", @@ -21,9 +21,11 @@ "jsqr": "^1.4.0", "multer": "^1.4.5-lts.1", "nodemon": "^3.0.1", - "pdf-lib": "^1.17.1" + "pdf-lib": "^1.17.1", + "tsconfig-paths": "^4.2.0" }, "devDependencies": { + "@types/archiver": "^6.0.1", "@types/express": "^4.17.21", "@types/multer": "^1.4.10", "ts-node-dev": "^2.0.0", diff --git a/server-node/src/routes/api/api-controller.ts b/server-node/src/routes/api/api-controller.ts index f832e235b..77e03872f 100644 --- a/server-node/src/routes/api/api-controller.ts +++ b/server-node/src/routes/api/api-controller.ts @@ -1,8 +1,8 @@ import express, { Request, Response } from 'express'; import workflow from './workflow-controller'; -import operations from './operations-controller'; -import conversions from './conversions-controller'; +// import operations from './operations-controller'; +// import conversions from './conversions-controller'; const router = express.Router(); @@ -11,8 +11,8 @@ router.get("/", (req: Request, res: Response) => { res.status(501).json({"Error": "Unfinished Endpoint. This sould probably send some api docs?"}); }); -router.use("/operations", operations); -router.use("/conversions", conversions); +// router.use("/operations", operations); +// router.use("/conversions", conversions); router.use("/workflow", workflow); export default router; \ No newline at end of file diff --git a/server-node/src/routes/api/operations-controller.ts b/server-node/src/routes/api/operations-controller.ts index cceda0722..7a0ae2b89 100644 --- a/server-node/src/routes/api/operations-controller.ts +++ b/server-node/src/routes/api/operations-controller.ts @@ -1,9 +1,7 @@ -import Operations from '../../utils/pdf-operations'; import { respondWithPdfFile, respondWithPdfFiles, response_mustHaveExactlyOneFile } from '../../utils/endpoint-utils'; import { PdfFile, /*PdfFileSchema*/ } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile' //import { ScalePageSchema } from '@stirling-pdf/shared-operations/src/functions/scalePage' -import { OperatorType } from '@stirling-pdf/shared-operations/src'; import express, { Request, Response, RequestHandler } from 'express'; const router = express.Router(); @@ -14,7 +12,7 @@ import Joi from 'joi'; function registerEndpoint(endpoint: string, nameToAppend: string, fileHandler: RequestHandler, - operator: OperatorType + operator: any ): void { router.post(endpoint, fileHandler, async function(req: Request, res: Response) { const body = req.body; @@ -79,7 +77,7 @@ registerEndpoint("/remove-pages", "", upload.single("file"), Operations.removePa pageSelector: Joi.string().required(), }).required()); */ -registerEndpoint("/impose", "", upload.single("file"), Operations.Impose); +// registerEndpoint("/impose", "", upload.single("file"), Operations.Impose); /* registerEndpoint("/scale-pages", "", upload.single("file"), Operations.scalePage, ScalePageSchema.required()); diff --git a/server-node/src/routes/api/workflow-controller.ts b/server-node/src/routes/api/workflow-controller.ts index 169f84317..185e58d95 100644 --- a/server-node/src/routes/api/workflow-controller.ts +++ b/server-node/src/routes/api/workflow-controller.ts @@ -3,7 +3,6 @@ import crypto from 'crypto'; import multer from 'multer' const upload = multer(); -import Operations from "../../utils/pdf-operations"; import { traverseOperations } from "@stirling-pdf/shared-operations/src/workflow/traverseOperations"; import { PdfFile, RepresentationType } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile'; import { respondWithPdfFiles } from '../../utils/endpoint-utils'; @@ -33,7 +32,7 @@ router.post("/:workflowUuid?", [ if(req.body.async === "false") { console.log("Don't do async"); - const traverse = traverseOperations(workflow.operations, inputs, Operations); + const traverse = traverseOperations(workflow.operations, inputs); let pdfResults; let iteration; @@ -74,7 +73,7 @@ router.post("/:workflowUuid?", [ } }); - const traverse = traverseOperations(workflow.operations, inputs, Operations); + const traverse = traverseOperations(workflow.operations, inputs); let pdfResults; let iteration; diff --git a/server-node/src/utils/pdf-operations.ts b/server-node/src/utils/pdf-operations.ts deleted file mode 100644 index 3ff6f9574..000000000 --- a/server-node/src/utils/pdf-operations.ts +++ /dev/null @@ -1,16 +0,0 @@ - -import SharedOperations, { OperatorsType, OperatorParametersType } from "@stirling-pdf/shared-operations/src" -import { PdfFile } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile" - -// Import injected libraries here! -import * as pdfcpuWrapper from "@stirling-pdf/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-node.js"; - -async function impose(params: OperatorParametersType["Impose"]): Promise { - return SharedOperations.Impose.exec(params, pdfcpuWrapper); -} - -const toExport: OperatorsType = { - ...SharedOperations, - Impose: {exec: impose, spec: SharedOperations.Impose.spec}, -} -export default toExport; diff --git a/server-node/tsconfig.json b/server-node/tsconfig.json index 30e670b92..907983c38 100644 --- a/server-node/tsconfig.json +++ b/server-node/tsconfig.json @@ -28,8 +28,10 @@ "module": "ES2020", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ "moduleResolution": "Node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + "baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */ + "paths": { + "#pdfcpu": ["../../shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server"], + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ @@ -110,7 +112,7 @@ "include": [ "src", "declarations/*.d.ts" - ], +, "../shared-operations/src/wasm/pdfcpu/PdfcpuWrapper.d.ts" ], "ts-node": { "experimentalSpecifierResolution": "node", "transpileOnly": true, diff --git a/shared-operations/declarations/pdfcpu.d.ts b/shared-operations/declarations/pdfcpu.d.ts new file mode 100644 index 000000000..a444033a5 --- /dev/null +++ b/shared-operations/declarations/pdfcpu.d.ts @@ -0,0 +1,3 @@ +declare module '#pdfcpu' { + export function oneToOne(wasmArray: string[], snapshot: Uint8Array): Promise; +} \ No newline at end of file diff --git a/shared-operations/src/functions/impose.ts b/shared-operations/src/functions/impose.ts index a5a45f7fe..fddda60d5 100644 --- a/shared-operations/src/functions/impose.ts +++ b/shared-operations/src/functions/impose.ts @@ -1,6 +1,9 @@ import { PdfFile, RepresentationType } from "../wrappers/PdfFile"; import { FieldConstraint, RecordConstraint } from '../dynamic-ui/OperatorConstraints' +import { IOType, Operator, Progress } from "."; + +import * as pdfcpuWrapper from "#pdfcpu"; // This is updated by tsconfig.json/paths for the context (browser, node, etc.) this module is used in. export type ImposeParamsType = { file: PdfFile; @@ -10,36 +13,69 @@ export type ImposeParamsType = { format: string; } +export class Impose extends Operator { + static type: string = "impose"; + + static mayInput: IOType = IOType.PDF; + static willOutput: IOType = IOType.PDF; + + /** PDF-Imposition, PDF-N-Up: Put multiple pages of the input document into a single page of the output document. - see: {@link https://en.wikipedia.org/wiki/N-up} */ + async run(input: PdfFile[], progressCallback: (state: Progress) => void): Promise { + return this.nToN(input, async (input, index, max) => { + // https://pdfcpu.io/generate/nup.html + const uint8Array = await pdfcpuWrapper.oneToOne( + [ + "pdfcpu.wasm", + "nup", + "-c", + "disable", + 'f:' + this.actionValues.format, + "/output.pdf", + String(this.actionValues.nup), + "input.pdf", + ], + await input.uint8Array + ); + + const result = new PdfFile( + input.originalFilename, + uint8Array, + RepresentationType.Uint8Array, + input.filename + "_imposed" + ); + + progressCallback({ curFileProgress: 1, operationProgress: index/max }) + + console.log("ImposeResult: ", result); + return [result]; + }) + } + + validate(): { valid: boolean; reason?: string | undefined; } { + let baseValidationResults = super.validate(); + if(!baseValidationResults.valid) + return baseValidationResults; + + // TODO: This should be ported to SaudF's RecordValidator + if(this.actionValues.nup) { + if(![2, 3, 4, 8, 9, 12, 16].includes(this.actionValues.nup)) { + return { valid: false, reason: "NUp accepted values are 2, 3, 4, 8, 9, 12, 16 - see: https://pdfcpu.io/generate/nup.html#n-up-value"} + } + } + else + return { valid: false, reason: "nup is not defined" } + + if(!this.actionValues.format) { + return { valid: false, reason: "format is not defined" } + } + // TODO: Format should be checked for all acceped formats + + return { valid: true } + } +} + export const ImposeParamConstraints = new RecordConstraint({ file: new FieldConstraint("display.key", "file.pdf", true, "hint.key"), nup: new FieldConstraint("display.key", [2, 3, 4, 8, 9, 12, 16], true, "hint.key"), format: new FieldConstraint("display.key", ["A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","A10","Letter","Legal"], true, "hint.key"), -}) - -/** PDF-Imposition, PDF-N-Up: Put multiple pages of the input document into a single page of the output document. - see: {@link https://en.wikipedia.org/wiki/N-up} */ -export async function impose(params: ImposeParamsType, pdfcpuWrapper: any): Promise { - // https://pdfcpu.io/generate/nup.html - const uint8Array = await pdfcpuWrapper.oneToOne( - [ - "pdfcpu.wasm", - "nup", - "-c", - "disable", - 'f:' + params.format, - "/output.pdf", - String(params.nup), - "input.pdf", - ], - await params.file.uint8Array - ); - - const result = new PdfFile( - params.file.originalFilename, - uint8Array, - RepresentationType.Uint8Array, - params.file.filename + "_imposed" - ); - - console.log("ImposeResult: ", result); - return result; -} +}) \ No newline at end of file diff --git a/shared-operations/src/functions/index.ts b/shared-operations/src/functions/index.ts new file mode 100644 index 000000000..f883f2b04 --- /dev/null +++ b/shared-operations/src/functions/index.ts @@ -0,0 +1,58 @@ +import { Action } from "../../declarations/Action"; + +export enum IOType { + PDF, Image, Text // TODO: Extend with Document File Types +} + +export interface Progress { + /** 0-1 */ + curFileProgress: number, + /** 0-1 */ + operationProgress: number, +} + +export class Operator { + /** The type of the operator in camelCase (impose, merge, etc.) */ + static type: string; + + // This will most likely be needed in the node Editor + static mayInput: IOType; + static willOutput: IOType; + + actionValues: any; + + constructor (action: Action) { + this.actionValues = action.values; + } + + // TODO: Type callback state, it should give updates on the progress of the current operator + async run(input: any[], progressCallback: (progress: Progress) => void): Promise { + return []; + } + + validate(): { valid: boolean, reason?: string } { + if(!this.actionValues) { + return { valid: false, reason: "The Operators action values were empty."} + } + return { valid: true }; + } + + protected async nToOne (inputs: I[], callback: (input: I[]) => Promise): Promise { + return [await callback(inputs)]; + } + + protected async oneToN (inputs: I[], callback: (input: I, index: number, max: number) => Promise): Promise { + return this.nToN(inputs, callback); // nToN is able to handle single inputs now. + } + + protected async nToN (inputs: I[], callback: (input: I, index: number, max: number) => Promise): Promise { + let output: O[] = [] + for (let i = 0; i < inputs.length; i++) { + output = output.concat(await callback(inputs[i], i, inputs.length)); + } + + return output; + } +} + +// TODO: Export Operators? \ No newline at end of file diff --git a/shared-operations/src/index.ts b/shared-operations/src/index.ts deleted file mode 100644 index 6d55983a9..000000000 --- a/shared-operations/src/index.ts +++ /dev/null @@ -1,60 +0,0 @@ - -import { arrangePages, ArrangePagesParamsType } from './functions/arrangePages' -import { extractPages, ExtractPagesParamsType } from "./functions/extractPages"; -import { impose, ImposeParamConstraints, ImposeParamsType } from "./functions/impose"; -import { mergePDFs, MergeParamsType } from './functions/mergePDFs'; -import { removeBlankPages, RemoveBlankPagesParamsType } from "./functions/removeBlankPages"; -import { removePages, RemovePagesParamsType } from "./functions/removePages"; -import { rotatePages, RotateParamsType } from './functions/rotatePages'; -import { scaleContent, ScaleContentParamsType} from './functions/scaleContent'; -import { scalePage, ScalePageParamsType } from './functions/scalePage'; -import { splitPagesByPreset, SplitPageByPresetParamsType } from './functions/splitPagesByPreset'; -import { splitPdfByIndex, SplitPdfByIndexParamsType } from './functions/splitPdfByIndex'; -import { updateMetadata, UpdateMetadataParams } from "./functions/updateMetadata"; -import { FieldConstraint, RecordConstraint } from '@stirling-pdf/shared-operations/src/dynamic-ui/OperatorConstraints' -import { PdfFile } from "./wrappers/PdfFile"; - -import { Override, ValuesType } from '../declarations/TypeScriptUtils' - -// Import injected libraries here! - -const toExport = { - /*arrangePages, - extractPages,*/ - Impose: {exec: impose, spec: ImposeParamConstraints}, - /*mergePDFs, - removeBlankPages, - removePages, - rotatePages, - scaleContent, - scalePage, - splitPagesByPreset, - splitPdfByIndex, - updateMetadata,*/ -} -export default toExport; - -type OperatorsBaseType = typeof toExport; -export type OperatorsType = Override Promise; - spec: RecordConstraint; - }; -}>; - -export type OperatorType = ValuesType; - -export type OperatorParametersType = { - /*arrangePages: ArrangePagesParamsType - extractPages: ExtractPagesParamsType;*/ - Impose: ImposeParamsType; - /*mergePDFs: MergeParamsType; - removeBlankPages: RemoveBlankPagesParamsType; - removePages: RemovePagesParamsType; - rotatePages: RotateParamsType; - scaleContent: ScaleContentParamsType; - scalePage: ScalePageParamsType; - splitPagesByPreset: SplitPageByPresetParamsType; - splitPdfByIndex: SplitPdfByIndexParamsType; - updateMetadata: UpdateMetadataParams;*/ -} diff --git a/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-browser.js b/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.client.js similarity index 100% rename from shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-browser.js rename to shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.client.js diff --git a/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-node.js b/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server.js similarity index 100% rename from shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper-node.js rename to shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server.js diff --git a/shared-operations/src/workflow/traverseOperations.ts b/shared-operations/src/workflow/traverseOperations.ts index 82b192c6f..c77bc766c 100644 --- a/shared-operations/src/workflow/traverseOperations.ts +++ b/shared-operations/src/workflow/traverseOperations.ts @@ -1,9 +1,11 @@ import { organizeWaitOperations } from "./organizeWaitOperations"; import { Action, WaitAction } from "../../declarations/Action"; -import { OperatorsType } from "../../src/index"; import { PdfFile } from "../wrappers/PdfFile"; +import { Progress } from "../functions"; +import { Impose } from "../functions/impose"; -export async function * traverseOperations(operations: Action[], input: PdfFile[] | PdfFile, Operators: OperatorsType): AsyncGenerator { +// TODO: Fix Operators Type +export async function * traverseOperations(operations: Action[], input: PdfFile[] | PdfFile): AsyncGenerator { const waitOperations = organizeWaitOperations(operations); let results: PdfFile[] = []; yield* nextOperation(operations, input); @@ -31,7 +33,7 @@ export async function * traverseOperations(operations: Action[], input: PdfFile[ } } - async function * computeOperation(action: Action, input: PdfFile|PdfFile[]): AsyncGenerator { + async function * computeOperation(action: Action, input: PdfFile[]): AsyncGenerator { console.log("Input: ", input); yield "Starting: " + action.type; switch (action.type) { @@ -59,10 +61,12 @@ export async function * traverseOperations(operations: Action[], input: PdfFile[ }); break;*/ case "impose": - yield* nToN(input, action, async (input) => { - const newPdf = await Operators.Impose.exec({file: input, nup: action.values["nup"], format: action.values["format"]}); - return newPdf; - }); + let impose = new Impose(action); + if(impose.validate().valid) { + impose.run(input, (state: Progress) => { + console.log(state); + }); + } break; /*case "merge": yield* nToOne(input, action, async (inputs) => { @@ -117,53 +121,4 @@ export async function * traverseOperations(operations: Action[], input: PdfFile[ throw new Error(`${action.type} not implemented yet.`); } } - - /** - * - * @param {PdfFile|PdfFile[]} input - * @param {JSON} action - * @returns {undefined} - */ - async function * nToOne(inputs: PdfFile|PdfFile[], action: Action, callback: (pdf: PdfFile[]) => Promise): AsyncGenerator { - const input = Array.isArray(inputs) ? inputs : [inputs]; // Convert single values to array, keep arrays as is. - - const newInputs = await callback(input); - yield* nextOperation(action.actions, newInputs); - } - - /** - * - * @param {PdfFile|PdfFile[]} input - * @param {JSON} action - * @returns {undefined} - */ - async function * oneToN(input: PdfFile|PdfFile[], action: Action, callback: (pdf: PdfFile) => Promise): AsyncGenerator { - if(Array.isArray(input)) { - let output: PdfFile[] = []; - for (let i = 0; i < input.length; i++) { - output = output.concat(await callback(input[i])); - } - yield* nextOperation(action.actions, output); - } - else { - const nextInput = await callback(input); - yield* nextOperation(action.actions, nextInput); - } - } - - async function * nToN(input: PdfFile|PdfFile[], action: Action, callback: (pdf: PdfFile) => Promise): AsyncGenerator { - if(Array.isArray(input)) { - console.log("inputs", input); - let nextInputs: PdfFile[] = [] - for (let i = 0; i < input.length; i++) { - nextInputs = nextInputs.concat(await callback(input[i])); - } - console.log("nextInputs", nextInputs); - yield* nextOperation(action.actions, nextInputs); - } - else { - const nextInput = await callback(input); - yield* nextOperation(action.actions, nextInput); - } - } } \ No newline at end of file diff --git a/shared-operations/tsconfig.json b/shared-operations/tsconfig.json new file mode 100644 index 000000000..918680ec7 --- /dev/null +++ b/shared-operations/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */ + "paths": { + "#pdfcpu": ["../../shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server"], + } + } /* Specify a set of entries that re-map imports to additional lookup locations. */ +} \ No newline at end of file