Nodemon Fixes, PdfFile cleanup

This commit is contained in:
Felix Kaspar 2023-11-14 20:22:37 +01:00
parent 02957f7757
commit 7bf100daff
8 changed files with 89 additions and 106 deletions

6
server-node/nodemon.json Normal file
View File

@ -0,0 +1,6 @@
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --trace-warnings --experimental-specifier-resolution=node --loader ts-node/esm ./src/index.ts"
}

View File

@ -6,7 +6,7 @@
"scripts": {
"build": "npx tsc",
"start": "node dist/index.js",
"dev": "nodemon --watch './**/*.ts' --exec node --experimental-specifier-resolution=node --loader ts-node/esm ./src/index.ts"
"dev": "nodemon"
},
"keywords": [],
"author": "",

View File

@ -1,7 +1,7 @@
import Operations from '../../utils/pdf-operations';
import { respondWithPdfFile, response_mustHaveExactlyOneFile } from '../../utils/endpoint-utils';
import { PdfFile, PdfFileSchema, fromMulterFile, fromMulterFiles } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile'
import { PdfFile, PdfFileSchema } from '@stirling-pdf/shared-operations/src/wrappers/PdfFile'
import express, { Request, Response, RequestHandler } from 'express';
const router = express.Router();
@ -18,14 +18,14 @@ function registerEndpoint(endpoint: string,
router.post(endpoint, fileHandler, async function(req: Request, res: Response) {
const body = req.body;
if (req.file) {
body.file = fromMulterFile(req.file);
body.file = PdfFile.fromMulterFile(req.file);
}
if (req.files) {
if (Array.isArray(req.files))
body.files = fromMulterFiles(req.files);
body.files = PdfFile.fromMulterFiles(req.files);
else {
const flattenedFiles = Object.values(req.files).flatMap(va => va);
body.files = fromMulterFiles(flattenedFiles);
body.files = PdfFile.fromMulterFiles(flattenedFiles);
}
}

View File

@ -111,4 +111,9 @@
"src",
"declarations/*.d.ts"
],
"ts-node": {
"experimentalSpecifierResolution": "node",
"transpileOnly": true,
"esm": true,
},
}

View File

@ -1,5 +1,3 @@
import { PdfFile, fromPdfLib } from '../wrappers/PdfFile';
export type ImposeParamsType = {
file: any;
nup: number;

View File

@ -1,22 +1,19 @@
import { PDFDocument } from 'pdf-lib';
import { PdfFile, convertAllToPdfLibFile, fromPdfLib } from '../wrappers/PdfFile';
import { PdfFile } from '../wrappers/PdfFile';
export type MergeParamsType = {
files: PdfFile[];
}
export async function mergePDFs(params: MergeParamsType): Promise<PdfFile> {
const pdfLibFiles = await convertAllToPdfLibFile(params.files);
const mergedPdf = await PDFDocument.create();
for (let i = 0; i < pdfLibFiles.length; i++) {
const pdfToMerge = await pdfLibFiles[i].getAsPdfLib();
for (let i = 0; i < params.files.length; i++) {
const pdfToMerge = await params.files[i].pdflibDocument;
const copiedPages = await mergedPdf.copyPages(pdfToMerge, pdfToMerge.getPageIndices());
copiedPages.forEach((page) => mergedPdf.addPage(page));
}
return fromPdfLib(mergedPdf, params.files[0].filename);
return new PdfFile(params.files.map(f => ), mergedPdf, params.files[0].filename);
};

View File

@ -1,6 +1,6 @@
import { degrees } from 'pdf-lib';
import { PdfFile, fromPdfLib } from '../wrappers/PdfFile';
import { PdfFile } from '../wrappers/PdfFile';
export type RotateParamsType = {
file: PdfFile;
@ -10,8 +10,7 @@ export type RotateParamsType = {
export async function rotatePages(params: RotateParamsType): Promise<PdfFile> {
const { file, rotation } = params;
const pdfDoc = await file.getAsPdfLib();
const pages = pdfDoc.getPages();
const pages = (await file.pdflibDocument).getPages();
if (Array.isArray(rotation)) {
if (rotation.length != pages.length) {
@ -29,5 +28,5 @@ export async function rotatePages(params: RotateParamsType): Promise<PdfFile> {
});
}
return fromPdfLib(pdfDoc, file.filename);
return file;
};

View File

@ -1,106 +1,84 @@
import { PDFDocument } from 'pdf-lib';
import * as PDFJS from 'pdfjs-dist';
import { PDFDocumentProxy } from 'pdfjs-dist/types/src/display/api';
import { PDFDocumentProxy as PDFJSDocument } from 'pdfjs-dist/types/src/display/api';
import { PDFDocument as PDFLibDocument } from 'pdf-lib';
import Joi from 'joi';
export class PdfFile {
byteArray: Uint8Array | null;
pdfLib: PDFDocument | null;
pdfJs: PDFDocumentProxy | null;
private representation: Uint8Array | PDFLibDocument | PDFJSDocument;
originalFilename: string;
filename: string;
constructor() {
this.byteArray = null;
this.pdfLib = null;
this.pdfJs = null;
this.filename = "";
}
async convertToByteArrayFile(): Promise<PdfFile> {
if (this.byteArray) return this;
var byteArray: Uint8Array|null = null;
if (this.pdfLib) {
byteArray = await this.pdfLib.save();
} else if (this.pdfJs) {
byteArray = await this.pdfJs.getData();
}
return fromUint8Array(byteArray!, this.filename);
get uint8Array() : Promise<Uint8Array> {
switch (this.representation.constructor) {
case Uint8Array:
return new Promise((resolve, reject) => {
resolve(this.representation as Uint8Array);
});
case PDFLibDocument:
return (this.representation as PDFLibDocument).save();
case PDFJSDocument:
return (this.representation as PDFJSDocument).getData();
default:
throw Error("unhandeled PDF type");
}
}
async convertToPdfLibFile(): Promise<PdfFile> {
if (this.pdfLib) return this;
const byteFile = await this.convertToByteArrayFile();
const pdfLib = await PDFDocument.load(byteFile.byteArray!, {
updateMetadata: false,
});
return fromPdfLib(pdfLib, this.filename);
}
async convertToPdfJsFile(): Promise<PdfFile> {
if (this.pdfJs) return this;
const byteFile = await this.convertToByteArrayFile();
const pdfJs = await PDFJS.getDocument(byteFile.byteArray!).promise;
return fromPdfJs(pdfJs, this.filename);
set uint8Array(value: Uint8Array) {
this.representation = value;
}
async getAsByteArray(): Promise<Uint8Array> {
const file = await this.convertToByteArrayFile();
return file.byteArray!;
get pdflibDocument() : Promise<PDFLibDocument> {
switch (this.representation.constructor) {
case PDFLibDocument: // PDFLib
return new Promise((resolve, reject) => {
resolve(this.representation as PDFLibDocument);
});
default:
return new Promise(async (resolve, reject) => {
resolve(PDFLibDocument.load(await this.uint8Array, {
updateMetadata: false,
}));
});
}
}
async getAsPdfLib(): Promise<PDFDocument> {
const file = await this.convertToPdfLibFile();
return file.pdfLib!;
set pdflibDocument(value: PDFLibDocument) {
this.representation = value;
}
async getAsPdfJs(): Promise<PDFDocumentProxy> {
const file = await this.convertToPdfJsFile();
return file.pdfJs!;
get pdfjsDocuemnt() : Promise<PDFJSDocument> {
switch (this.representation.constructor) {
case PDFJSDocument:
return new Promise((resolve, reject) => {
resolve(this.representation as PDFJSDocument);
});
default:
return new Promise(async (resolve, reject) => {
resolve(await PDFJS.getDocument(await this.uint8Array).promise);
});
}
}
set pdfjsDocuemnt(value: PDFJSDocument) {
this.representation = value;
}
constructor(originalFilename: string, representation: Uint8Array | PDFLibDocument | PDFJSDocument, filename?: string) {
this.originalFilename = originalFilename;
this.filename = filename ? filename : originalFilename;
this.representation = representation;
}
static fromMulterFile(value: Express.Multer.File): PdfFile {
return new PdfFile(value.originalname, value.buffer as Uint8Array)
}
static fromMulterFiles(values: Express.Multer.File[]): PdfFile[] {
return values.map(v => PdfFile.fromMulterFile(v));
}
}
export const PdfFileSchema = Joi.any().custom((value, helpers) => {
if (!(value instanceof PdfFile)) {
throw new Error('value is not a PdfFile');
}
return value;
}, "PdfFile validation");
export function fromMulterFile(value: Express.Multer.File): PdfFile {
return fromUint8Array(value.buffer, value.originalname)
}
export function fromMulterFiles(values: Express.Multer.File[]): PdfFile[] {
return values.map(v => fromUint8Array(v.buffer, v.originalname));
}
export function fromUint8Array(value: Uint8Array, filename: string): PdfFile {
const out = new PdfFile();
out.byteArray = value;
out.filename = filename;
return out;
}
export function fromPdfLib(value: PDFDocument, filename: string): PdfFile {
const out = new PdfFile();
out.pdfLib = value;
out.filename = filename;
return out;
}
export function fromPdfJs(value: PDFDocumentProxy, filename: string): PdfFile {
const out = new PdfFile();
out.pdfJs = value;
out.filename = filename;
return out;
}
export async function convertAllToByteArrayFile(files: PdfFile[]): Promise<(PdfFile)[]> {
const pdfPromises = files.map(s => s.convertToByteArrayFile());
return await Promise.all(pdfPromises);
}
export async function convertAllToPdfLibFile(files: PdfFile[]): Promise<(PdfFile)[]> {
const pdfPromises = files.map(s => s.convertToPdfLibFile());
return await Promise.all(pdfPromises);
}
export async function convertAllToPdfJsFile(files: PdfFile[]): Promise<(PdfFile)[]> {
const pdfPromises = files.map(s => s.convertToPdfJsFile());
return await Promise.all(pdfPromises);
}
}, "PdfFile validation");