From a91dd0e502d54f037545af0b61c1cde7ef00c8f5 Mon Sep 17 00:00:00 2001 From: Felix Kaspar Date: Sun, 12 May 2024 20:54:34 +0200 Subject: [PATCH] extract, comma seperated list fields in Joi & genericField --- .eslintrc.js | 64 ------------------ .../src/components/fields/GenericField.tsx | 65 +++++++++++++++---- client-tauri/src/pages/Dynamic.tsx | 2 + .../src/functions/extractPages.ts | 26 +------- .../src/functions/scaleContent.ts | 1 - .../src/wrappers/CommaArrayJoiExt.ts | 27 ++++++++ shared-operations/src/wrappers/PdfFileJoi.ts | 2 +- 7 files changed, 85 insertions(+), 102 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 shared-operations/src/wrappers/CommaArrayJoiExt.ts diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 3d0e38f78..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,64 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic-type-checked" - ], - "overrides": [ - { - "env": { - "node": true - }, - "files": [ - ".eslintrc.{js,cjs}" - ], - "parserOptions": { - "sourceType": "script" - } - } - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module", - "project": [ - "./client-tauri/tsconfig.json", - "./server-node/tsconfig.json", - "./shared-operations/tsconfig.json" - ] - }, - "plugins": [ - "@typescript-eslint" - ], - "ignorePatterns": [ - "node_modules/", - "**/*.js", - "**/*.jsx" - ], - "rules": { - "indent": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always", - { - "omitLastInOneLineBlock": true, - "omitLastInOneLineClassBody": true - } - ] - } -}; diff --git a/client-tauri/src/components/fields/GenericField.tsx b/client-tauri/src/components/fields/GenericField.tsx index 24c861c0d..58f815002 100644 --- a/client-tauri/src/components/fields/GenericField.tsx +++ b/client-tauri/src/components/fields/GenericField.tsx @@ -2,18 +2,25 @@ import Joi from "@stirling-tools/joi"; import { Fragment } from "react"; interface GenericFieldProps { - fieldName: string - joiDefinition: Joi.Description; + fieldName: string, + joiDefinition: Joi.Description +} + +interface Flags { + label: string, + description: string, } export function GenericField({ fieldName, joiDefinition }: GenericFieldProps) { + const flags = joiDefinition.flags as Flags; + switch (joiDefinition.type) { case "number": var validValues = joiDefinition.allow; - if(validValues) { // Restrained text input + if(validValues) { // Restrained number input return ( - + {joiDefinition.allow.map((e: string) => { @@ -24,17 +31,22 @@ export function GenericField({ fieldName, joiDefinition }: GenericFieldProps) { ); } - else { - // TODO: Implement unrestrained text input - return (
{JSON.stringify(joiDefinition, null, 2)}
) + else { // Unrestrained number input + // TODO: Check if integer or not. + return ( + + + +
+
+ ); } break; case "string": - var validValues = joiDefinition.allow; - if(validValues) { // Restrained text input + if(joiDefinition.allow) { // Restrained text input return ( - + {joiDefinition.allow.map((e: string) => { @@ -47,11 +59,38 @@ export function GenericField({ fieldName, joiDefinition }: GenericFieldProps) { } else { // TODO: Implement unrestrained text input - return (
{JSON.stringify(joiDefinition, null, 2)}
) + return (
string, unrestrained text input is not implemented
) + } + break; + case "comma_array": + if(joiDefinition.items.length == 1) { + const item: Joi.Description = joiDefinition.items[0]; + + if(item.type == "number") { + if(item.rules.length == 1) { + return ( + + + +
+
+ ); + } + else { + return (
comma_array, item rules are empty or bigger than one, this is not implemented.
); + } + } + else { + return (
comma_array, other types than numbers are not implemented yet.
); + } + } + else { + // TODO: Implement multiple items if necessary + return (
comma_array, joi items are empty or bigger than one, this is not implemented
); } break; - default: - return (
Field "{fieldName}":
requested type "{joiDefinition.type}" not found
) + console.log(joiDefinition); + return (
GenericField.tsx:
"{fieldName}": requested type "{joiDefinition.type}" not found. Check console for further info.
) } } \ No newline at end of file diff --git a/client-tauri/src/pages/Dynamic.tsx b/client-tauri/src/pages/Dynamic.tsx index a58892516..0595a4704 100644 --- a/client-tauri/src/pages/Dynamic.tsx +++ b/client-tauri/src/pages/Dynamic.tsx @@ -30,6 +30,8 @@ function Dynamic() { LoadingModule.then((Module) => { const Operator = Module[capitalizeFirstLetter(selectedValue)]; const description = Operator.schema.describe(); + console.log(Operator.schema); + console.log(description); activeOperator.current = Operator; // This will update children diff --git a/shared-operations/src/functions/extractPages.ts b/shared-operations/src/functions/extractPages.ts index a16e5bcae..7a65b2dd2 100644 --- a/shared-operations/src/functions/extractPages.ts +++ b/shared-operations/src/functions/extractPages.ts @@ -1,4 +1,3 @@ - import { PdfFile, RepresentationType } from "../wrappers/PdfFile"; import { Operator, Progress, oneToOne } from "."; @@ -9,26 +8,7 @@ import i18next from "i18next"; import { getPages } from "./common/getPagesByIndex"; import { parsePageIndexSpecification } from "./common/pageIndexesUtils"; - -export interface ExtractPagesParamsType { - file: PdfFile; - pageIndexes: string | number[]; -} -export async function extractPages(params: ExtractPagesParamsType): Promise { - const { file, pageIndexes } = params; - const pdfLibDocument = await file.pdfLibDocument; - - let indexes = pageIndexes; - - if (!Array.isArray(indexes)) { - indexes = parsePageIndexSpecification(indexes, pdfLibDocument.getPageCount()); - } - - const newFile = await getPages(file, indexes); - newFile.filename += "_extractedPages"; - return newFile; -} - +import CommaArrayJoiExt from "../wrappers/CommaArrayJoiExt"; export class ExtractPages extends Operator { static type = "extractPages"; @@ -39,9 +19,9 @@ export class ExtractPages extends Operator { protected static inputSchema = JoiPDFFileSchema.label(i18next.t("inputs.pdffile.name")).description(i18next.t("inputs.pdffile.description")); protected static valueSchema = Joi.object({ - pageIndexes: Joi.array().items(Joi.number().integer()).required() + pageIndexes: CommaArrayJoiExt.comma_array().items(Joi.number().integer()).required() .label(i18next.t("values.pageIndexes.friendlyName", { ns: "extractPages" })).description(i18next.t("values.pageIndexes.description", { ns: "extractPages" })) - .example("3").example("4").required() + .example("1").example("1, 2, 3, 4").example("4, 2, 4, 3").required() }); protected static outputSchema = JoiPDFFileSchema.label(i18next.t("outputs.pdffile.name")).description(i18next.t("outputs.pdffile.description")); diff --git a/shared-operations/src/functions/scaleContent.ts b/shared-operations/src/functions/scaleContent.ts index 6a97ee748..682e3c04a 100644 --- a/shared-operations/src/functions/scaleContent.ts +++ b/shared-operations/src/functions/scaleContent.ts @@ -1,4 +1,3 @@ - import { PDFPage } from "pdf-lib"; import { PdfFile, RepresentationType } from "../wrappers/PdfFile"; diff --git a/shared-operations/src/wrappers/CommaArrayJoiExt.ts b/shared-operations/src/wrappers/CommaArrayJoiExt.ts new file mode 100644 index 000000000..3f30864df --- /dev/null +++ b/shared-operations/src/wrappers/CommaArrayJoiExt.ts @@ -0,0 +1,27 @@ +import Joi from "@stirling-tools/joi"; + +export default Joi.extend((joi) => { + return { + // e.g. "'1', '2', '3', '10', '100', 'hello'" + type: 'comma_array', + base: joi.array(), + messages: { + 'million.base': '{{#label}} must be a comma seperated list', + }, + coerce: { + from: 'string', + method(value, helpers) { + + if (typeof value !== 'string' || !/(\d+)(,\s*\d+)*/.test(value)) { + return; + } + + try { + return { value: value.split(",").map(v => v.trim()) }; + } + catch (ignoreErr) { } + } + } + + } +}); \ No newline at end of file diff --git a/shared-operations/src/wrappers/PdfFileJoi.ts b/shared-operations/src/wrappers/PdfFileJoi.ts index cdc6ab2be..efcb46802 100644 --- a/shared-operations/src/wrappers/PdfFileJoi.ts +++ b/shared-operations/src/wrappers/PdfFileJoi.ts @@ -20,7 +20,7 @@ export const JoiPDFFileSchema = Joi.custom((value: Express.Multer.File[] /* <- a throw new Error("an invalid type (unhandeled, non-file-type) was provided to pdf validation process. Please report this to maintainers."); } } -}, "pdffile validation"); +}, "pdffile"); function isPdfFileArray(value: any[]): value is PdfFile[] { // "is" is a ts-typeguard - https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates return value.every((e) => e instanceof PdfFile);