mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 15:35:03 +00:00
Updated Contribute & a little bit of cleanup
This commit is contained in:
parent
45d5f2c533
commit
762fa850f1
@ -8,19 +8,29 @@ This file should introduce you with the concepts and tools used in this project.
|
||||
- [opencv-wasm](https://www.npmjs.com/package/opencv-wasm) - ?-wasm
|
||||
- [pdfjs](https://www.npmjs.com/package/pdfjs-dist) - js
|
||||
|
||||
## Nomenclature
|
||||
|
||||
- API - Probably refers to the “normal“ API of spdf v2 without workflows unless otherwise noted.
|
||||
- Workflow - Either the express-endpoint for running workflows or the user defined workflow-json
|
||||
- Action - A sub-element of a workflow describing what operation should run on the inputted file / output of the last action.
|
||||
- Operation - The actual function that will run on the pdf, including parameters.
|
||||
- Operator - The actual code/implementation of the Operation (e.g. impose.ts) OR The parent class of every Operator.
|
||||
- Validator - A function that makes sure things are as they should be. Every Operator must have one.
|
||||
- Decorator - Explanations and Human Readable names of fields, these will be displayed in the frontend and used to provide better errors for the (workflow-)API
|
||||
|
||||
## Folder structure
|
||||
|
||||
- (abandoned) client-ionic- An old test of
|
||||
- client-tauri - The frontend
|
||||
- (abandoned) client-vanilla - The initial test to see if it is possible to run Operators in the browser environment of the user in addition to having a backend. Will be removed once development on the fronend/client-tauri has started.
|
||||
- server-node - Functions and Classes that are shared between frontend and backend e.g. Operators
|
||||
|
||||
## Basic Setup
|
||||
|
||||
- Install/Update Node (>v20.9.0) & NPM(>10.2.1)
|
||||
- To install all dependecies `npm run update-all-dependencies` (in [root](/))
|
||||
- To test your current setup and boot a complete install of spdf v2 run `npm run dev-all` (in [root](/))
|
||||
|
||||
## Adding a PDF Operation
|
||||
StirlingPDF aims to support as many types of operations as possible, including some that cannot be executed in the client. Because of this, we have decided to move some of the shared functionality into it's own node module so that it can be shared by both client and server.
|
||||
|
||||
### Adding a shared (server + client) operation
|
||||
1. Add the code for the operation to a new file in the [functions folder](/shared-operations/functions/).
|
||||
|
||||
> **NOTE:** many of the functions in these files use **dependency injection** (see impose for an example).
|
||||
>
|
||||
> **Explanation:** Because some libraries need to be imported in different ways. We import the library as needed in the ```pdf-operations.js``` files, then pass the required library objects into the operation function as a parameter.
|
||||
|
||||
2. Now that we have the function code, we need to tell the other modules that it exists. Edit the [server operations](/server-node/src/pdf-operations.js) and the [client operations](/client-ionic/src/utils/pdf-operations.ts) files to add your new operation! (Try to follow existing patterns where possible, keep the added operations in alphabetical order in the files).
|
||||
|
||||
3. If you added a wrapper function to the [client operations](/client-ionic/src/utils/pdf-operations.ts) file, you will also need to add the TypeScript declarations to the [declaration](/client-ionic/declarations/shared-operations.d.ts) file. See the other module declarations for examples.
|
||||
|
||||
### Adding a server only operation
|
||||
> WIP
|
@ -160,9 +160,7 @@ A: Available in the internal API, S: Available on the node server, C: Available
|
||||
|
||||
For initial instructions look at [CONTRIBUTE.md](./CONTRIBUTE.md)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
<!--
|
||||
///// CONVERT 2 pdf
|
||||
file2pdf
|
||||
url2pdf
|
||||
@ -220,4 +218,5 @@ detect/split scanned
|
||||
add image
|
||||
add watermark
|
||||
sign
|
||||
*/
|
||||
*/
|
||||
-->
|
@ -8,7 +8,10 @@
|
||||
"shared-operations"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "concurrently --names \"node,ionic\" -c \"red.bold,cyan.bold\" --kill-others \"npm run -w server-node dev\" \"npm run -w client-ionic dev\""
|
||||
"dev-all": "concurrently --names \"node,ionic\" -c \"red.bold,cyan.bold\" --kill-others \"npm run -w server-node dev\" \"npm run -w client-ionic dev\"",
|
||||
"update-all-dependencies": "npm i --workspace=server-node --workspace=client-tauri --workspace=shared-operation",
|
||||
"update-backend-dependencies": "npm i --workspace=server-node --workspace=shared-operation",
|
||||
"update-frontend-dependencies": "npm i --workspace=client-tauri --workspace=shared-operation"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.2"
|
||||
|
3
server-node/declarations/pdfcpu.d.ts
vendored
3
server-node/declarations/pdfcpu.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
declare module '#pdfcpu' {
|
||||
export function oneToOne(wasmArray: string[], snapshot: Uint8Array): Promise<Uint8Array>;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
|
||||
import Joi from 'joi';
|
||||
import { JoiPdfFileSchema } from '../wrappers/PdfFile';
|
||||
|
||||
export class RecordConstraint {
|
||||
|
||||
record: Record<string, FieldConstraint>;
|
||||
|
||||
constructor(record: Record<string, FieldConstraint>) {
|
||||
this.record = record;
|
||||
}
|
||||
|
||||
toJoiSchema() {
|
||||
const newSchemaObj: any = {};
|
||||
Object.keys(this.record).forEach(key => {
|
||||
newSchemaObj[key] = this.record[key].toJoiSchema();
|
||||
});
|
||||
return Joi.object(newSchemaObj);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export class FieldConstraint {
|
||||
|
||||
displayNameKey: string;
|
||||
type: "file.pdf" | "files.pdf" | "string" | "number" | number[] | string[] | RecordConstraint;
|
||||
required: boolean;
|
||||
hintKey?: string;
|
||||
customSchema?: Joi.Schema;
|
||||
|
||||
constructor(displayNameKey: string,
|
||||
type: "file.pdf" | "files.pdf" | "string" | "number" | number[] | string[] | RecordConstraint,
|
||||
required: boolean,
|
||||
hintKey?: string,
|
||||
customSchema?: Joi.Schema) {
|
||||
this.displayNameKey = displayNameKey;
|
||||
this.type = type;
|
||||
this.required = required;
|
||||
this.hintKey = hintKey;
|
||||
this.customSchema = customSchema;
|
||||
}
|
||||
|
||||
toJoiSchema(): Joi.Schema {
|
||||
if (this.customSchema) return this.customSchema;
|
||||
|
||||
var schema: Joi.Schema;
|
||||
if (Array.isArray(this.type)) {
|
||||
if (this.type.every(e => typeof e == 'string')) {
|
||||
schema = Joi.string().valid(...this.type);
|
||||
} else if (this.type.every(e => typeof e == 'number')) {
|
||||
schema = Joi.number().valid(...this.type);
|
||||
} else {
|
||||
schema = Joi.any().valid(this.type);
|
||||
}
|
||||
} else if (typeof this.type == 'string') {
|
||||
switch (this.type) {
|
||||
case "file.pdf":
|
||||
schema = JoiPdfFileSchema;
|
||||
break;
|
||||
case "files.pdf":
|
||||
schema = Joi.array().items(JoiPdfFileSchema);
|
||||
break;
|
||||
case "string":
|
||||
schema = Joi.string();
|
||||
break;
|
||||
case "number":
|
||||
schema = Joi.number();
|
||||
break;
|
||||
default:
|
||||
throw new Error(`UiConf type '${this.type}' not supported`)
|
||||
}
|
||||
} else if (this.type instanceof RecordConstraint) {
|
||||
schema = this.type.toJoiSchema()
|
||||
} else {
|
||||
throw new Error(`UiConf type '${this.type}' not supported`)
|
||||
}
|
||||
|
||||
if (this.required) {
|
||||
schema = schema.required();
|
||||
}
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
|
||||
import { PdfFile, RepresentationType } from "../wrappers/PdfFile";
|
||||
import { FieldConstraint, RecordConstraint } from '../dynamic-ui/OperatorConstraints'
|
||||
import { Operator, Progress, oneToOne } from ".";
|
||||
|
||||
import * as pdfcpuWrapper from "#pdfcpu"; // This is updated by tsconfig.json/paths for the context (browser, node, etc.) this module is used in.
|
||||
|
Loading…
x
Reference in New Issue
Block a user