diff --git a/package-lock.json b/package-lock.json index b27ea0b38..90fc19b4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3568,6 +3568,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/arch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", @@ -4053,9 +4058,7 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "peer": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/busboy": { "version": "1.6.0", @@ -4352,6 +4355,47 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/concurrently": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", @@ -5533,17 +5577,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express-fileupload": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.1.tgz", - "integrity": "sha512-9F6SkbxbEOA9cYOBZ8tnn238jL+bGfacQuUO/JqPWp5t+piUcoDcESvKwAXsQV7IHGxmI5bMj3QxMWOKOIsMCg==", - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -7568,11 +7601,21 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mlly": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", @@ -7590,6 +7633,23 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -9542,6 +9602,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", @@ -10191,6 +10256,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10277,7 +10350,7 @@ "@wasmer/wasmfs": "^0.12.0", "archiver": "^6.0.1", "express": "^4.18.2", - "express-fileupload": "^1.4.1", + "multer": "^1.4.5-lts.1", "pdf-lib": "^1.17.1" } }, diff --git a/server-node/index.js b/server-node/index.js index cf6c87add..a0b5fecbe 100644 --- a/server-node/index.js +++ b/server-node/index.js @@ -1,19 +1,21 @@ -import api from './routes/api/index.js'; +import operations from './routes/api/operations.js'; import express from 'express'; const app = express(); + const PORT = 8080; - + // Static Middleware app.use(express.static('./public')); - + app.get('/', function (req, res, next) { // TODO: Use EJS? res.render('home.ejs'); }); -app.use("/api/", api); - +app.use("/api/operations", operations); +app.use("/api/workflow", workflow); + app.listen(PORT, function (err) { if (err) console.log(err); console.log(`http://localhost:${PORT}`); diff --git a/server-node/package.json b/server-node/package.json index bc3332d29..bfa18e2e6 100644 --- a/server-node/package.json +++ b/server-node/package.json @@ -8,12 +8,12 @@ "author": "", "license": "ISC", "dependencies": { + "@stirling-pdf/shared-operations": "*", "@wasmer/wasmfs": "^0.12.0", "archiver": "^6.0.1", "express": "^4.18.2", - "express-fileupload": "^1.4.1", - "pdf-lib": "^1.17.1", - "@stirling-pdf/shared-operations": "*" + "multer": "^1.4.5-lts.1", + "pdf-lib": "^1.17.1" }, "type": "module" } diff --git a/server-node/public/index.html b/server-node/public/index.html index f1cf9669c..5b78f039c 100644 --- a/server-node/public/index.html +++ b/server-node/public/index.html @@ -4,30 +4,14 @@ Document - - - - - - - - - - - - - - - - +

Rotate

+ +
+ +
+ +
\ No newline at end of file diff --git a/server-node/public/index.js b/server-node/public/index.js deleted file mode 100644 index 8558dcbc9..000000000 --- a/server-node/public/index.js +++ /dev/null @@ -1,43 +0,0 @@ -import { scaleContent } from "./functions/scaleContent.js"; -import { scalePage, PageSize } from "./functions/scalePage.js"; -import * as exampleWorkflows from "./exampleWorkflows.js"; -import { traverseOperations } from "./traverseOperations.js"; -import * as Functions from "./pdf-operations.js"; - -(async (workflow) => { - const pdfFileInput = document.getElementById('pdfFile'); - const doneButton = document.getElementById("doneButton"); - - doneButton.addEventListener('click', async (e) => { - console.log("Starting..."); - - const files = Array.from(pdfFileInput.files); - console.log(files); - const inputs = await Promise.all(files.map(async file => { - return { - originalFileName: file.name.replace(/\.[^/.]+$/, ""), - fileName: file.name.replace(/\.[^/.]+$/, ""), - buffer: new Uint8Array(await file.arrayBuffer()) - } - })); - console.log(inputs); - - const traverse = traverseOperations(workflow.operations, inputs, Functions); - - let pdfResults; - let iteration; - while (true) { - iteration = await traverse.next(); - if (iteration.done) { - pdfResults = iteration.value; - console.log(`data: processing done\n\n`); - break; - } - console.log(`data: ${iteration.value}\n\n`); - } - - pdfResults.forEach(result => { - download(result.buffer, result.fileName, "application/pdf"); - }); - }); -})(exampleWorkflows.imposeOnly); \ No newline at end of file diff --git a/server-node/public/wasm/pdfcpu-wrapper-browser.js b/server-node/public/wasm/pdfcpu-wrapper-browser.js deleted file mode 100644 index c716b5e2a..000000000 --- a/server-node/public/wasm/pdfcpu-wrapper-browser.js +++ /dev/null @@ -1,98 +0,0 @@ -let wasmLocation = "/wasm/"; - -let fs; -let Buffer; - -configureFs(); -loadWasm(); - -async function configureFs() { - BrowserFS.configure( - { - fs: "InMemory", - }, - function (e) { - if (e) { - // An error happened! - throw e; - } - fs = BrowserFS.BFSRequire("fs"); - Buffer = BrowserFS.BFSRequire("buffer").Buffer; - - window.fs = fs; - window.Buffer = Buffer; - } - ); -} - -function loadWasm() { - import("../../../server-node/public/wasm/wasm_exec.js"); -} - -const runWasm = async (param) => { - if (window.cachedWasmResponse === undefined) { - const response = await fetch(wasmLocation + "/pdfcpu.wasm"); - const buffer = await response.arrayBuffer(); - window.cachedWasmResponse = buffer; - window.go = new Go(); - } - const { instance } = await WebAssembly.instantiate( - window.cachedWasmResponse, - window.go.importObject - ); - window.go.argv = param; - await window.go.run(instance); - return window.go.exitCode; -}; - -async function loadFileAsync(data) { - console.log(`Writing file to MemoryFS`); - await fs.writeFile(`/input.pdf`, data); - console.log(`Write done. Validating...`); - let exitcode = await runWasm([ - "pdfcpu.wasm", - "validate", - "-c", - "disable", - `/input.pdf`, - ]); - - if (exitcode !== 0) - throw new Error("There was an error validating your PDFs"); - - console.log(`File is Valid`); -} - -export async function impose(snapshot, nup, format) { - -}; - -export async function oneToOne(wasmArray, snapshot) { - await loadFileAsync(Buffer.from(snapshot)); - - console.log("Nuping File"); - let exitcode = await runWasm(wasmArray); - - if (exitcode !== 0) { - console.error("There was an error nuping your PDFs"); - return; - } - - await fs.unlink("input.pdf"); - const contents = fs.readFileSync("output.pdf"); - fs.unlink("output.pdf"); - console.log("Your File ist Ready!"); - return new Uint8Array(contents); -} - -export async function manyToOne() { - //TODO: Do this of neccesary for some operations -} - -export async function oneToMany() { - //TODO: Do this of neccesary for some operations -} - -export async function manyToMany() { - //TODO: Do this of neccesary for some operations -} \ No newline at end of file diff --git a/server-node/public/wasm/pdfcpu-wrapper-node.js b/server-node/public/wasm/pdfcpu-wrapper-node.js deleted file mode 100644 index 7d4e2710b..000000000 --- a/server-node/public/wasm/pdfcpu-wrapper-node.js +++ /dev/null @@ -1,144 +0,0 @@ -import { WasmFs } from '@wasmer/wasmfs'; -import path from "path"; - -let webWasmLocation = "/wasm/"; -let nodeWasmLocation = "./public/wasm/"; - -let fs; -const wasmfs = new WasmFs(); - -(async () => { - await loadWasm(); - await configureFs(); -})(); - -async function configureFs() { - // Can't use BrowserFS: https://github.com/jvilk/BrowserFS/issues/271 - fs = wasmfs.fs; - global.fs = fs; - - console.log("InMemoryFs configured"); -} - -async function loadWasm() { - global.crypto = (await import("crypto")).webcrypto; // wasm dependecy - await import("./wasm_exec.js"); -} - -const runWasm = async (param) => { - if (global.cachedWasmResponse === undefined) { - const buffer = (await import("fs")).readFileSync(nodeWasmLocation + "/pdfcpu.wasm"); - global.cachedWasmResponse = buffer; - global.go = new Go(); - } - const { instance } = await WebAssembly.instantiate( - global.cachedWasmResponse, - global.go.importObject - ); - global.go.argv = param; - await global.go.run(instance); - return global.go.exitCode; -}; - -async function loadFileAsync(data) { - console.log(`Writing file to Disk`); - fs.writeFileSync(`input.pdf`, data); - console.log(`Write done. Validating...`); - let exitcode = await runWasm([ - "pdfcpu.wasm", - "validate", - "-c", - "disable", - `input.pdf`, - ]); - if (exitcode !== 0) - throw new Error("There was an error validating your PDFs"); - - // // Get logs of command - // wasmfs.getStdOut().then(response => { - // console.log(response); - // }); - - console.log(`File is Valid`); -} - -export async function oneToOne(wasmArray, snapshot) { - await loadFileAsync(Buffer.from(snapshot)); - - console.log("Nuping File"); - - let exitcode = await runWasm(wasmArray); - if (exitcode !== 0) { - console.error("There was an error nuping your PDFs"); - return; - } - console.log("Nuping Done"); - - await checkExistsWithTimeout("/output.pdf", 1000); - console.log("Write started..."); - - - // TODO: Make this more elegant, this waits for the write to finish. - // Maybe replace wasmfs with https://github.com/streamich/memfs - let fileSize; - while (true) { - fileSize = fs.statSync("/output.pdf").size; - await new Promise((resolve, reject) => { - setTimeout(() => { - resolve(); - }, 50); - }); - if(fileSize > 0 && fileSize == fs.statSync("/output.pdf").size) // Wait for file Size not changing anymore. - break; - } - - console.log("Could be done?"); - - fs.unlinkSync("input.pdf"); - - const data = fs.readFileSync("/output.pdf"); - if(data.length == 0) { - throw Error("File Size 0 that should not happen. The write probably didn't finish in time."); - } - fs.unlinkSync("output.pdf"); - console.log("Your File ist Ready!"); - return new Uint8Array(data); -} - -export async function manyToOne() { - //TODO: Do this if necessary for some pdfcpu operations -} - -export async function oneToMany() { - //TODO: Do this if necessary for some pdfcpu operations -} - -export async function manyToMany() { - //TODO: Do this if necessary for some pdfcpu operations -} - -// THX: https://stackoverflow.com/questions/26165725/nodejs-check-file-exists-if-not-wait-till-it-exist -function checkExistsWithTimeout(filePath, timeout) { - return new Promise(function (resolve, reject) { - - var timer = setTimeout(function () { - watcher.close(); - reject(new Error('File did not exists and was not created during the timeout.')); - }, timeout); - - fs.access(filePath, fs.constants.R_OK, function (err) { - if (!err) { - clearTimeout(timer); - watcher.close(); - resolve(); - } - }); - - var dir = path.dirname(filePath); - var watcher = fs.watch(dir, function (eventType, filename) { - clearTimeout(timer); - watcher.close(); - resolve(); - }); - }); -} \ No newline at end of file diff --git a/server-node/public/wasm/pdfcpu.wasm b/server-node/public/wasm/pdfcpu.wasm deleted file mode 100644 index fc7855d3f..000000000 Binary files a/server-node/public/wasm/pdfcpu.wasm and /dev/null differ diff --git a/server-node/public/wasm/wasm_exec.js b/server-node/public/wasm/wasm_exec.js deleted file mode 100644 index 0c8a1044c..000000000 --- a/server-node/public/wasm/wasm_exec.js +++ /dev/null @@ -1,872 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -(() => { - // Map multiple JavaScript environments to a single common API, - // preferring web standards over Node.js API. - // - // Environments considered: - // - Browsers - // - Node.js - // - Electron - // - Parcel - // - Webpack - - console.log("imported") - if (typeof global !== "undefined") { - // global already exists - } else if (typeof window !== "undefined") { - window.global = window; - } else if (typeof self !== "undefined") { - self.global = self; - } else { - throw new Error("cannot export Go (neither global, window nor self is defined)"); - } - - let logFS = false - var handler = { - get: function (target, property) { - if (property in target && target[property] instanceof Function) { - return function () { - if (logFS) { - console.log(property, 'called', arguments); - } - // 将callback替换 - if (arguments[arguments.length - 1] instanceof Function) { - var origCB = arguments[arguments.length - 1]; - var newCB = function () { - if (logFS) { - console.log('callback for', property, 'get called with args:', arguments); - } - return Reflect.apply(origCB, arguments.callee, arguments); - } - arguments[arguments.length - 1] = newCB; - } - return Reflect.apply(target[property], target, arguments); - } - } else { - return target[property] - } - } - } - - if (!global.require && typeof require !== "undefined") { - global.require = require; - } - - - if (!global.fs && global.require) { - - //const fs = require("fs"); - if (typeof fs === "object" && fs !== null && Object.keys(fs).length !== 0) { - global.fs = fs; - } - - } - - const enosys = () => { - const err = new Error("not implemented"); - err.code = "ENOSYS"; - return err; - }; - - if (!global.fs) { - let outputBuf = ""; - global.fs = { - constants: { - O_WRONLY: -1, - O_RDWR: -1, - O_CREAT: -1, - O_TRUNC: -1, - O_APPEND: -1, - O_EXCL: -1 - }, // unused - writeSync(fd, buf) { - outputBuf += decoder.decode(buf); - const nl = outputBuf.lastIndexOf("\n"); - if (nl != -1) { - console.log(outputBuf.substr(0, nl)); - outputBuf = outputBuf.substr(nl + 1); - } - return buf.length; - }, - write(fd, buf, offset, length, position, callback) { - if (offset !== 0 || length !== buf.length || position !== null) { - callback(enosys()); - return; - } - const n = this.writeSync(fd, buf); - callback(null, n); - }, - chmod(path, mode, callback) { - callback(enosys()); - }, - chown(path, uid, gid, callback) { - callback(enosys()); - }, - close(fd, callback) { - callback(enosys()); - }, - fchmod(fd, mode, callback) { - callback(enosys()); - }, - fchown(fd, uid, gid, callback) { - callback(enosys()); - }, - fstat(fd, callback) { - callback(enosys()); - }, - fsync(fd, callback) { - callback(null); - }, - ftruncate(fd, length, callback) { - callback(enosys()); - }, - lchown(path, uid, gid, callback) { - callback(enosys()); - }, - link(path, link, callback) { - callback(enosys()); - }, - lstat(path, callback) { - callback(enosys()); - }, - mkdir(path, perm, callback) { - callback(enosys()); - }, - open(path, flags, mode, callback) { - callback(enosys()); - }, - read(fd, buffer, offset, length, position, callback) { - callback(enosys()); - }, - readdir(path, callback) { - callback(enosys()); - }, - readlink(path, callback) { - callback(enosys()); - }, - rename(from, to, callback) { - callback(enosys()); - }, - rmdir(path, callback) { - callback(enosys()); - }, - stat(path, callback) { - callback(enosys()); - }, - symlink(path, link, callback) { - callback(enosys()); - }, - truncate(path, length, callback) { - callback(enosys()); - }, - unlink(path, callback) { - callback(enosys()); - }, - utimes(path, atime, mtime, callback) { - callback(enosys()); - }, - }; - } - - if (!global.process) { - global.process = { - getuid() { - return -1; - }, - getgid() { - return -1; - }, - geteuid() { - return -1; - }, - getegid() { - return -1; - }, - getgroups() { - throw enosys(); - }, - pid: -1, - ppid: -1, - umask() { - throw enosys(); - }, - cwd() { - throw enosys(); - }, - chdir() { - throw enosys(); - }, - } - } - - if (!global.crypto && global.require) { - const nodeCrypto = require("crypto"); - global.crypto = { - getRandomValues(b) { - nodeCrypto.randomFillSync(b); - }, - }; - } - if (!global.crypto) { - throw new Error("global.crypto is not available, polyfill required (getRandomValues only)"); - } - - if (!global.performance) { - global.performance = { - now() { - const [sec, nsec] = process.hrtime(); - return sec * 1000 + nsec / 1000000; - }, - }; - } - - if (!global.TextEncoder && global.require) { - global.TextEncoder = require("util").TextEncoder; - } - if (!global.TextEncoder) { - throw new Error("global.TextEncoder is not available, polyfill required"); - } - - if (!global.TextDecoder && global.require) { - global.TextDecoder = require("util").TextDecoder; - } - if (!global.TextDecoder) { - throw new Error("global.TextDecoder is not available, polyfill required"); - } - - - const isNodeJS = global.process && global.process.title === "node"; - - if (!isNodeJS) { - // console.log("ini browser fs") - // var myfs = global.BrowserFS.BFSRequire('fs'); - // global.Buffer = global.BrowserFS.BFSRequire('buffer').Buffer; - // global.fs = myfs; - - global.fs.constants = { - O_RDONLY: 0, - O_WRONLY: 1, - O_RDWR: 2, - O_CREAT: 64, - O_CREATE: 64, - O_EXCL: 128, - O_NOCTTY: 256, - O_TRUNC: 512, - O_APPEND: 1024, - O_DIRECTORY: 65536, - O_NOATIME: 262144, - O_NOFOLLOW: 131072, - O_SYNC: 1052672, - O_DIRECT: 16384, - O_NONBLOCK: 2048, - }; - - let outputBuf = ""; - - global.fs.writeSyncOriginal = global.fs.writeSync - global.fs.writeSync = function (fd, buf) { - if (fd === 1 || fd === 2) { - outputBuf += decoder.decode(buf); - const nl = outputBuf.lastIndexOf("\n"); - if (nl != -1) { - console.log(outputBuf.substr(0, nl)); - outputBuf = outputBuf.substr(nl + 1); - } - return buf.length; - } else { - return global.fs.writeSyncOriginal(...arguments); - } - }; - - global.fs.writeOriginal = global.fs.write - global.fs.write = function (fd, buf, offset, length, position, callback) { - // (corresponding to STDOUT/STDERR) - if (fd === 1 || fd === 2) { - if (offset !== 0 || length !== buf.length || position !== null) { - throw new Error("not implemented"); - } - const n = this.writeSync(fd, buf); - callback(null, n, buf); - } else { - // buf: read buf first - arguments[1] = global.Buffer.from(arguments[1]); - return global.fs.writeOriginal(...arguments); - } - }; - - - - global.fs.openOriginal = global.fs.open - global.fs.open = function (path, flags, mode, callback) { - var myflags = 'r'; - var O = global.fs.constants; - - // Convert numeric flags to string flags - // FIXME: maybe wrong... - console.log("open dir?", path, 'flag', flags, myflags) - if (flags & O.O_WRONLY) { // 'w' - myflags = 'w'; - if (flags & O.O_EXCL) { - myflags = 'wx'; - } - } else if (flags & O.O_RDWR) { // 'r+' or 'w+' - if (flags & O.O_CREAT && flags & O.O_TRUNC) { // w+ - if (flags & O.O_EXCL) { - myflags = 'wx+'; - } else { - myflags = 'w+'; - } - } else { // r+ - myflags = 'r+'; - } - } else if (flags & O.O_APPEND) { // 'a' - console.log("append error") - throw new Error("Not implmented"); - } else { - // 打开文件 - myflags = 'r+'; - console.log("open dir?", path, 'flag', flags, myflags) - } - - - return global.fs.openOriginal(path, myflags, mode, callback); - }; - - global.fs.fstatOriginal = global.fs.fstat; - global.fs.fstat = function (fd, callback) { - return global.fs.fstatOriginal(fd, function () { - var retStat = arguments[1]; - delete retStat['fileData']; - retStat.atimeMs = retStat.atime.getTime(); - retStat.mtimeMs = retStat.mtime.getTime(); - retStat.ctimeMs = retStat.ctime.getTime(); - retStat.birthtimeMs = retStat.birthtime.getTime(); - return callback(arguments[0], retStat); - - }); - }; - - - - global.fs.closeOriginal = global.fs.close; - global.fs.close = function (fd, callback) { - return global.fs.closeOriginal(fd, function () { - if (typeof arguments[0] === 'undefined') arguments[0] = null; - return callback(...arguments); - }); - } - - // global.fs.renameOriginal = global.fs.rename - // global.fs.rename = function (from, to, callback) { - // console.log("rename a0", arguments[0]) - // global.fs.renameOriginal(from, to); - // callback(arguments[0]) - // } - - // global.fs.renameSyncOriginal = global.fs.renameSync - // global.fs.renameSync = function(fd, options) { - // console.log("Sync") - // } - - - global.fs = new Proxy(global.fs, handler); - } - - // End of polyfills for common API. - - const encoder = new TextEncoder("utf-8"); - const decoder = new TextDecoder("utf-8"); - - global.Go = class { - constructor() { - this.argv = ["js"]; - this.env = {}; - this.exit = (code) => { - this.exitCode = code; - if (code !== 0) { - console.warn("exit code:", code); - } - }; - this._exitPromise = new Promise((resolve) => { - this._resolveExitPromise = resolve; - }); - this._pendingEvent = null; - this._scheduledTimeouts = new Map(); - this._nextCallbackTimeoutID = 1; - - const setInt64 = (addr, v) => { - this.mem.setUint32(addr + 0, v, true); - this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true); - } - - const getInt64 = (addr) => { - const low = this.mem.getUint32(addr + 0, true); - const high = this.mem.getInt32(addr + 4, true); - return low + high * 4294967296; - } - - const loadValue = (addr) => { - const f = this.mem.getFloat64(addr, true); - if (f === 0) { - return undefined; - } - if (!isNaN(f)) { - return f; - } - - const id = this.mem.getUint32(addr, true); - return this._values[id]; - } - - const storeValue = (addr, v) => { - const nanHead = 0x7FF80000; - - if (typeof v === "number" && v !== 0) { - if (isNaN(v)) { - this.mem.setUint32(addr + 4, nanHead, true); - this.mem.setUint32(addr, 0, true); - return; - } - this.mem.setFloat64(addr, v, true); - return; - } - - if (v === undefined) { - this.mem.setFloat64(addr, 0, true); - return; - } - - let id = this._ids.get(v); - if (id === undefined) { - id = this._idPool.pop(); - if (id === undefined) { - id = this._values.length; - } - this._values[id] = v; - this._goRefCounts[id] = 0; - this._ids.set(v, id); - } - this._goRefCounts[id]++; - let typeFlag = 0; - switch (typeof v) { - case "object": - if (v !== null) { - typeFlag = 1; - } - break; - case "string": - typeFlag = 2; - break; - case "symbol": - typeFlag = 3; - break; - case "function": - typeFlag = 4; - break; - } - this.mem.setUint32(addr + 4, nanHead | typeFlag, true); - this.mem.setUint32(addr, id, true); - } - - const loadSlice = (addr) => { - const array = getInt64(addr + 0); - const len = getInt64(addr + 8); - return new Uint8Array(this._inst.exports.mem.buffer, array, len); - } - - const loadSliceOfValues = (addr) => { - const array = getInt64(addr + 0); - const len = getInt64(addr + 8); - const a = new Array(len); - for (let i = 0; i < len; i++) { - a[i] = loadValue(array + i * 8); - } - return a; - } - - const loadString = (addr) => { - const saddr = getInt64(addr + 0); - const len = getInt64(addr + 8); - return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len)); - } - - const timeOrigin = Date.now() - performance.now(); - this.importObject = { - go: { - // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) - // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported - // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). - // This changes the SP, thus we have to update the SP used by the imported function. - - // func wasmExit(code int32) - "runtime.wasmExit": (sp) => { - sp >>>= 0; - const code = this.mem.getInt32(sp + 8, true); - this.exited = true; - delete this._inst; - delete this._values; - delete this._goRefCounts; - delete this._ids; - delete this._idPool; - this.exit(code); - }, - - // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) - "runtime.wasmWrite": (sp) => { - sp >>>= 0; - const fd = getInt64(sp + 8); - const p = getInt64(sp + 16); - const n = this.mem.getInt32(sp + 24, true); - fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n)); - }, - - // func resetMemoryDataView() - "runtime.resetMemoryDataView": (sp) => { - sp >>>= 0; - this.mem = new DataView(this._inst.exports.mem.buffer); - }, - - // func nanotime1() int64 - "runtime.nanotime1": (sp) => { - sp >>>= 0; - setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000); - }, - - // func walltime1() (sec int64, nsec int32) - "runtime.walltime1": (sp) => { - sp >>>= 0; - const msec = (new Date).getTime(); - setInt64(sp + 8, msec / 1000); - this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true); - }, - - // func scheduleTimeoutEvent(delay int64) int32 - "runtime.scheduleTimeoutEvent": (sp) => { - sp >>>= 0; - const id = this._nextCallbackTimeoutID; - this._nextCallbackTimeoutID++; - this._scheduledTimeouts.set(id, setTimeout( - () => { - this._resume(); - while (this._scheduledTimeouts.has(id)) { - // for some reason Go failed to register the timeout event, log and try again - // (temporary workaround for https://github.com/golang/go/issues/28975) - console.warn("scheduleTimeoutEvent: missed timeout event"); - this._resume(); - } - }, - getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early - )); - this.mem.setInt32(sp + 16, id, true); - }, - - // func clearTimeoutEvent(id int32) - "runtime.clearTimeoutEvent": (sp) => { - sp >>>= 0; - const id = this.mem.getInt32(sp + 8, true); - clearTimeout(this._scheduledTimeouts.get(id)); - this._scheduledTimeouts.delete(id); - }, - - // func getRandomData(r []byte) - "runtime.getRandomData": (sp) => { - sp >>>= 0; - crypto.getRandomValues(loadSlice(sp + 8)); - }, - - // func finalizeRef(v ref) - "syscall/js.finalizeRef": (sp) => { - sp >>>= 0; - const id = this.mem.getUint32(sp + 8, true); - this._goRefCounts[id]--; - if (this._goRefCounts[id] === 0) { - const v = this._values[id]; - this._values[id] = null; - this._ids.delete(v); - this._idPool.push(id); - } - }, - - // func stringVal(value string) ref - "syscall/js.stringVal": (sp) => { - sp >>>= 0; - storeValue(sp + 24, loadString(sp + 8)); - }, - - // func valueGet(v ref, p string) ref - "syscall/js.valueGet": (sp) => { - sp >>>= 0; - const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16)); - sp = this._inst.exports.getsp() >>> 0; // see comment above - storeValue(sp + 32, result); - }, - - // func valueSet(v ref, p string, x ref) - "syscall/js.valueSet": (sp) => { - sp >>>= 0; - Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); - }, - - // func valueDelete(v ref, p string) - "syscall/js.valueDelete": (sp) => { - sp >>>= 0; - Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16)); - }, - - // func valueIndex(v ref, i int) ref - "syscall/js.valueIndex": (sp) => { - sp >>>= 0; - storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); - }, - - // valueSetIndex(v ref, i int, x ref) - "syscall/js.valueSetIndex": (sp) => { - sp >>>= 0; - Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); - }, - - // func valueCall(v ref, m string, args []ref) (ref, bool) - "syscall/js.valueCall": (sp) => { - sp >>>= 0; - try { - const v = loadValue(sp + 8); - const m = Reflect.get(v, loadString(sp + 16)); - const args = loadSliceOfValues(sp + 32); - const result = Reflect.apply(m, v, args); - sp = this._inst.exports.getsp() >>> 0; // see comment above - storeValue(sp + 56, result); - this.mem.setUint8(sp + 64, 1); - } catch (err) { - storeValue(sp + 56, err); - this.mem.setUint8(sp + 64, 0); - } - }, - - // func valueInvoke(v ref, args []ref) (ref, bool) - "syscall/js.valueInvoke": (sp) => { - sp >>>= 0; - try { - const v = loadValue(sp + 8); - const args = loadSliceOfValues(sp + 16); - const result = Reflect.apply(v, undefined, args); - sp = this._inst.exports.getsp() >>> 0; // see comment above - storeValue(sp + 40, result); - this.mem.setUint8(sp + 48, 1); - } catch (err) { - storeValue(sp + 40, err); - this.mem.setUint8(sp + 48, 0); - } - }, - - // func valueNew(v ref, args []ref) (ref, bool) - "syscall/js.valueNew": (sp) => { - sp >>>= 0; - try { - const v = loadValue(sp + 8); - const args = loadSliceOfValues(sp + 16); - const result = Reflect.construct(v, args); - sp = this._inst.exports.getsp() >>> 0; // see comment above - storeValue(sp + 40, result); - this.mem.setUint8(sp + 48, 1); - } catch (err) { - storeValue(sp + 40, err); - this.mem.setUint8(sp + 48, 0); - } - }, - - // func valueLength(v ref) int - "syscall/js.valueLength": (sp) => { - sp >>>= 0; - setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); - }, - - // valuePrepareString(v ref) (ref, int) - "syscall/js.valuePrepareString": (sp) => { - sp >>>= 0; - const str = encoder.encode(String(loadValue(sp + 8))); - storeValue(sp + 16, str); - setInt64(sp + 24, str.length); - }, - - // valueLoadString(v ref, b []byte) - "syscall/js.valueLoadString": (sp) => { - sp >>>= 0; - const str = loadValue(sp + 8); - loadSlice(sp + 16).set(str); - }, - - // func valueInstanceOf(v ref, t ref) bool - "syscall/js.valueInstanceOf": (sp) => { - sp >>>= 0; - this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0); - }, - - // func copyBytesToGo(dst []byte, src ref) (int, bool) - "syscall/js.copyBytesToGo": (sp) => { - sp >>>= 0; - const dst = loadSlice(sp + 8); - const src = loadValue(sp + 32); - if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { - this.mem.setUint8(sp + 48, 0); - return; - } - const toCopy = src.subarray(0, dst.length); - dst.set(toCopy); - setInt64(sp + 40, toCopy.length); - this.mem.setUint8(sp + 48, 1); - }, - - // func copyBytesToJS(dst ref, src []byte) (int, bool) - "syscall/js.copyBytesToJS": (sp) => { - sp >>>= 0; - const dst = loadValue(sp + 8); - const src = loadSlice(sp + 16); - if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { - this.mem.setUint8(sp + 48, 0); - return; - } - const toCopy = src.subarray(0, dst.length); - dst.set(toCopy); - setInt64(sp + 40, toCopy.length); - this.mem.setUint8(sp + 48, 1); - }, - - "debug": (value) => { - console.log(value); - }, - } - }; - } - - async run(instance) { - if (!(instance instanceof WebAssembly.Instance)) { - throw new Error("Go.run: WebAssembly.Instance expected"); - } - this._inst = instance; - this.mem = new DataView(this._inst.exports.mem.buffer); - this._values = [ // JS values that Go currently has references to, indexed by reference id - NaN, - 0, - null, - true, - false, - global, - this, - ]; - this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id - this._ids = new Map([ // mapping from JS values to reference ids - [0, 1], - [null, 2], - [true, 3], - [false, 4], - [global, 5], - [this, 6], - ]); - this._idPool = []; // unused ids that have been garbage collected - this.exited = false; // whether the Go program has exited - - // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. - let offset = 4096; - - const strPtr = (str) => { - const ptr = offset; - const bytes = encoder.encode(str + "\0"); - new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes); - offset += bytes.length; - if (offset % 8 !== 0) { - offset += 8 - (offset % 8); - } - return ptr; - }; - - const argc = this.argv.length; - - const argvPtrs = []; - this.argv.forEach((arg) => { - argvPtrs.push(strPtr(arg)); - }); - argvPtrs.push(0); - - const keys = Object.keys(this.env).sort(); - keys.forEach((key) => { - argvPtrs.push(strPtr(`${key}=${this.env[key]}`)); - }); - argvPtrs.push(0); - - const argv = offset; - argvPtrs.forEach((ptr) => { - this.mem.setUint32(offset, ptr, true); - this.mem.setUint32(offset + 4, 0, true); - offset += 8; - }); - - this._inst.exports.run(argc, argv); - if (this.exited) { - this._resolveExitPromise(); - } - await this._exitPromise; - } - - _resume() { - if (this.exited) { - throw new Error("Go program has already exited"); - } - this._inst.exports.resume(); - if (this.exited) { - this._resolveExitPromise(); - } - } - - _makeFuncWrapper(id) { - const go = this; - return function () { - const event = { - id: id, - this: this, - args: arguments - }; - go._pendingEvent = event; - go._resume(); - return event.result; - }; - } - } - - if ( - typeof module !== "undefined" && - global.require && - global.require.main === module && - global.process && - global.process.versions && - !global.process.versions.electron - ) { - if (process.argv.length < 3) { - console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"); - process.exit(1); - } - - const go = new Go(); - go.argv = process.argv.slice(2); - go.env = Object.assign({ - TMPDIR: require("os").tmpdir() - }, process.env); - go.exit = process.exit; - WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => { - process.on("exit", (code) => { // Node.js exits if no event handler is pending - if (code === 0 && !go.exited) { - // deadlock, make Go print error and stack traces - go._pendingEvent = { - id: 0 - }; - go._resume(); - } - }); - return go.run(result.instance); - }).catch((err) => { - console.error(err); - process.exit(1); - }); - } -})(); \ No newline at end of file diff --git a/server-node/routes/api/index.js b/server-node/routes/api/index.js deleted file mode 100644 index be18148c6..000000000 --- a/server-node/routes/api/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import express from 'express'; -import workflow from './workflow.js'; -import fileUpload from 'express-fileupload'; - -const router = express.Router(); -router.use(fileUpload()); - -router.get("/", function (req, res, next) { - // TODO: Implement root api endpoint - res.status(501).json({"Error": "Unfinished Endpoint. This sould probably send some api docs?"}); -}); - -router.use("/workflow", workflow); - -export default router; \ No newline at end of file diff --git a/server-node/routes/api/operations.js b/server-node/routes/api/operations.js new file mode 100644 index 000000000..d8392c784 --- /dev/null +++ b/server-node/routes/api/operations.js @@ -0,0 +1,25 @@ + +import { rotatePages } from '../../src/pdf-operations.js' + +import express from 'express'; +const router = express.Router(); +import multer from 'multer' +const upload = multer(); + +router.post('/rotate-pdf', upload.single("pdfFile"), async function(req, res, next) { + console.debug("rotating pdf:", req.file) + + const rotated = await rotatePages(req.file.buffer, 90) + + // add '_rotated' just before the file extension + const newFilename = req.file.originalname.replace(/(\.[^.]+)$/, '_rotated$1'); + + res.writeHead(200, { + 'Content-Type': "application/pdf", + 'Content-disposition': 'attachment;filename=' + newFilename, + 'Content-Length': rotated.length + }); + res.end(Buffer.from(rotated, 'binary')) +}); + +export default router; \ No newline at end of file diff --git a/server-node/routes/api/workflow.js b/server-node/routes/api/workflow.js index 9e61b391d..15858e60f 100644 --- a/server-node/routes/api/workflow.js +++ b/server-node/routes/api/workflow.js @@ -2,8 +2,10 @@ import express from 'express'; import crypto from 'crypto'; import stream from "stream"; import Archiver from 'archiver'; +import multer from 'multer' +const upload = multer(); -import * as Functions from "../../public/pdf-operations.js"; +import * as Functions from "../../src/pdf-operations.js"; import { traverseOperations } from "../../public/traverseOperations.js"; const activeWorkflows = {}; @@ -11,6 +13,7 @@ const activeWorkflows = {}; const router = express.Router(); router.post("/:workflowUuid?", [ + upload.any(), async (req, res) => { if(req.files == null) { res.status(400).json({"error": "No files were uploaded."}); diff --git a/server-node/public/organizeWaitOperations.js b/server-node/src/organizeWaitOperations.js similarity index 100% rename from server-node/public/organizeWaitOperations.js rename to server-node/src/organizeWaitOperations.js diff --git a/server-node/public/pdf-operations.js b/server-node/src/pdf-operations.js similarity index 65% rename from server-node/public/pdf-operations.js rename to server-node/src/pdf-operations.js index 8e11bb687..175ca7511 100644 --- a/server-node/public/pdf-operations.js +++ b/server-node/src/pdf-operations.js @@ -1,9 +1,6 @@ -import PDFLib from 'pdf-lib'; -import * as pdfcpuWraopper from "./wasm/pdfcpu-wrapper-node.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'; @@ -12,37 +9,33 @@ import { scalePage as dependantScalePage } from '@stirling-pdf/shared-operations import { splitPDF as dependantSplitPDF } from '@stirling-pdf/shared-operations/functions/splitPDF.js'; export async function editMetadata(snapshot, metadata) { - return dependantEditMetadata(snapshot, metadata, PDFLib); + return dependantEditMetadata(snapshot, metadata); } export async function extractPages(snapshot, pagesToExtractArray) { - return dependantExtractPages(snapshot, pagesToExtractArray, PDFLib); -} - -export async function impose(snapshot, nup, format) { - return dependantImpose(snapshot, nup, format, pdfcpuWraopper); + return dependantExtractPages(snapshot, pagesToExtractArray); } export async function mergePDFs(snapshots) { - return dependantMergePDFs(snapshots, PDFLib); + return dependantMergePDFs(snapshots); } export async function organizePages(snapshot, operation, customOrderString) { - return dependantOrganizePages(snapshot, operation, customOrderString, PDFLib); + return dependantOrganizePages(snapshot, operation, customOrderString); } export async function rotatePages(snapshot, rotation) { - return dependantRotatePages(snapshot, rotation, PDFLib); + return dependantRotatePages(snapshot, rotation); } export async function scaleContent(snapshot, scaleFactor) { - return dependantScaleContent(snapshot, scaleFactor, PDFLib); + return dependantScaleContent(snapshot, scaleFactor); } export async function scalePage(snapshot, pageSize) { - return dependantScalePage(snapshot, pageSize, PDFLib); + return dependantScalePage(snapshot, pageSize); } export async function splitPDF(snapshot, splitAfterPageArray) { - return dependantSplitPDF(snapshot, splitAfterPageArray, PDFLib); + return dependantSplitPDF(snapshot, splitAfterPageArray); } diff --git a/server-node/public/traverseOperations.js b/server-node/src/traverseOperations.js similarity index 99% rename from server-node/public/traverseOperations.js rename to server-node/src/traverseOperations.js index ca42138bc..f69711484 100644 --- a/server-node/public/traverseOperations.js +++ b/server-node/src/traverseOperations.js @@ -4,7 +4,7 @@ import { organizeWaitOperations } from "./organizeWaitOperations.js"; * * @param {*} operations * @param {*} input - * @param {import('./pdf-operations.js')} Functions + * @param {import('../src/pdf-operations.js')} Functions * @returns */ export async function * traverseOperations(operations, input, Functions) { diff --git a/shared-operations/functions/editMetadata.js b/shared-operations/functions/editMetadata.js index 3e437243d..056699443 100644 --- a/shared-operations/functions/editMetadata.js +++ b/shared-operations/functions/editMetadata.js @@ -1,3 +1,6 @@ + +import PDFLib from 'pdf-lib'; + /** * @typedef {Object} Metadata * @property {string | null | undefined} Title - The title of the document. @@ -14,10 +17,10 @@ * * @param {Uint16Array} snapshot * @param {Metadata} metadata - Set property to null or "" to clear, undefined properties will be skipped. - * @param {import('pdf-lib')} PDFLib + * @param {PDFLib} PDFLib * @returns */ -export async function editMetadata(snapshot, metadata, PDFLib) { +export async function editMetadata(snapshot, metadata) { // Load the original PDF file const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { parseSpeed: PDFLib.ParseSpeeds.Fastest, diff --git a/shared-operations/functions/extractPages.js b/shared-operations/functions/extractPages.js index 20dee1503..cd88753a3 100644 --- a/shared-operations/functions/extractPages.js +++ b/shared-operations/functions/extractPages.js @@ -1,11 +1,14 @@ -export async function extractPages(snapshot, pagesToExtractArray, PDFLib) { + +import PDFLib from 'pdf-lib'; + +export async function extractPages(snapshot, pagesToExtractArray) { const pdfDoc = await PDFLib.PDFDocument.load(snapshot) // TODO: invent a better format for pagesToExtractArray and convert it. - return createSubDocument(pdfDoc, pagesToExtractArray, PDFLib); + return createSubDocument(pdfDoc, pagesToExtractArray); }; -export async function createSubDocument(pdfDoc, pagesToExtractArray, PDFLib) { +export async function createSubDocument(pdfDoc, pagesToExtractArray) { const subDocument = await PDFLib.PDFDocument.create(); // Check that array max number is not larger pdf pages number diff --git a/shared-operations/functions/impose.js b/shared-operations/functions/impose.js deleted file mode 100644 index d7aa9da08..000000000 --- a/shared-operations/functions/impose.js +++ /dev/null @@ -1,12 +0,0 @@ -export async function impose(snapshot, nup, format, pdfcpuWrapper) { - return await pdfcpuWrapper.oneToOne([ - "pdfcpu.wasm", - "nup", - "-c", - "disable", - 'f:' + format, - "/output.pdf", - String(nup), - "input.pdf", - ], snapshot); -} \ No newline at end of file diff --git a/shared-operations/functions/mergePDFs.js b/shared-operations/functions/mergePDFs.js index 109efc66c..39094e8b0 100644 --- a/shared-operations/functions/mergePDFs.js +++ b/shared-operations/functions/mergePDFs.js @@ -1,4 +1,7 @@ -export const mergePDFs = async (snapshots, PDFLib) => { + +import PDFLib from 'pdf-lib'; + +export const mergePDFs = async (snapshots) => { const mergedPdf = await PDFLib.PDFDocument.create(); diff --git a/shared-operations/functions/organizePages.js b/shared-operations/functions/organizePages.js index a6b3950ae..f63327b97 100644 --- a/shared-operations/functions/organizePages.js +++ b/shared-operations/functions/organizePages.js @@ -1,3 +1,6 @@ + +import PDFLib 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 */ @@ -10,7 +13,7 @@ * @param {import('pdf-lib')} PDFLib * @returns */ -export async function organizePages(snapshot, operation, customOrderString, PDFLib) { +export async function organizePages(snapshot, operation, customOrderString) { const pdfDoc = await PDFLib.PDFDocument.load(snapshot); let subDocument = await PDFLib.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 c42b28862..ca684a125 100644 --- a/shared-operations/functions/rotatePages.js +++ b/shared-operations/functions/rotatePages.js @@ -1,4 +1,7 @@ -export async function rotatePages (snapshot, rotation, PDFLib) { + +import PDFLib from 'pdf-lib'; + +export async function rotatePages (snapshot, rotation) { // Load the original PDF file const pdfDoc = await PDFLib.PDFDocument.load(snapshot, { parseSpeed: PDFLib.ParseSpeeds.Fastest, diff --git a/shared-operations/functions/scaleContent.js b/shared-operations/functions/scaleContent.js index 52847af90..e61b330f4 100644 --- a/shared-operations/functions/scaleContent.js +++ b/shared-operations/functions/scaleContent.js @@ -1,4 +1,7 @@ -export async function scaleContent(snapshot, scaleFactor, PDFLib) { + +import PDFLib 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, diff --git a/shared-operations/functions/scalePage.js b/shared-operations/functions/scalePage.js index 3696280f7..567f1106d 100644 --- a/shared-operations/functions/scalePage.js +++ b/shared-operations/functions/scalePage.js @@ -1,4 +1,7 @@ -export async function scalePage(snapshot, pageSize, PDFLib) { + +import PDFLib 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, diff --git a/shared-operations/functions/splitPDF.js b/shared-operations/functions/splitPDF.js index dac378ce1..24695cf6a 100644 --- a/shared-operations/functions/splitPDF.js +++ b/shared-operations/functions/splitPDF.js @@ -1,6 +1,9 @@ + +import PDFLib from 'pdf-lib'; + import { createSubDocument } from "./extractPages.js"; -export async function splitPDF(snapshot, splitAfterPageArray, PDFLib) { +export async function splitPDF(snapshot, splitAfterPageArray) { const pdfDoc = await PDFLib.PDFDocument.load(snapshot) const numberOfPages = pdfDoc.getPages().length; @@ -11,13 +14,13 @@ export async function splitPDF(snapshot, splitAfterPageArray, PDFLib) { for (let i = 0; i < numberOfPages; i++) { if(i > splitAfter && pagesArray.length > 0) { - subDocuments.push(await createSubDocument(pdfDoc, pagesArray, PDFLib)); + subDocuments.push(await createSubDocument(pdfDoc, pagesArray)); splitAfter = splitAfterPageArray.shift(); pagesArray = []; } pagesArray.push(i); } - subDocuments.push(await createSubDocument(pdfDoc, pagesArray, PDFLib)); + subDocuments.push(await createSubDocument(pdfDoc, pagesArray)); pagesArray = []; return subDocuments;