mirror of
https://github.com/detleph/server.git
synced 2026-09-09 07:56:18 +02:00
Add schema valiation
+ Using zod for validation + Add SchemaError
This commit is contained in:
+2
-1
@@ -31,7 +31,8 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"nodemailer": "^6.7.0",
|
"nodemailer": "^6.7.0",
|
||||||
"redis": "^3.1.2",
|
"redis": "^3.1.2",
|
||||||
"winston": "^3.7.2"
|
"winston": "^3.7.2",
|
||||||
|
"zod": "^3.14.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import ForwardableError from "./ForwardableError";
|
||||||
|
|
||||||
|
export default class SchemaError extends ForwardableError {
|
||||||
|
protected __oid = "SCHEMA_ERROR";
|
||||||
|
|
||||||
|
constructor(message: string) {
|
||||||
|
super(400, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { Schema, z, ZodError } from "zod";
|
||||||
|
import SchemaError from "../Middleware/error/SchemaError";
|
||||||
|
|
||||||
|
// -- Schema definitions --
|
||||||
|
|
||||||
|
const SchemaVersion = z.enum(["1.0"]);
|
||||||
|
|
||||||
|
const TimeUnit = z.enum(["days", "hours", "minutes", "seconds", "milliseconds"]);
|
||||||
|
|
||||||
|
const DurationSchema = z
|
||||||
|
.object({
|
||||||
|
type: z.literal("duration"),
|
||||||
|
min: z.number().int({ message: "min must be an integer (relative to smallestUnit)" }),
|
||||||
|
max: z.number().int({ message: "max must be an integer (relative to smallestUnit)" }),
|
||||||
|
smallestUnit: TimeUnit,
|
||||||
|
higherIsBetter: z.boolean(),
|
||||||
|
})
|
||||||
|
.refine(({ min, max }) => min < max, { message: "min must be smaller than max" });
|
||||||
|
|
||||||
|
const PointSchema = z
|
||||||
|
.object({
|
||||||
|
type: z.literal("points"),
|
||||||
|
min: z.number(),
|
||||||
|
max: z.number(),
|
||||||
|
step: z.number(),
|
||||||
|
start: z.number(),
|
||||||
|
|
||||||
|
unit: z.string(),
|
||||||
|
unitSign: z.string(),
|
||||||
|
|
||||||
|
higherIsBetter: z.boolean(),
|
||||||
|
})
|
||||||
|
.refine(({ min, max }) => min < max, { message: "min must be smaller than max" })
|
||||||
|
.refine(({ min, max, start }) => min <= start && max >= start, {
|
||||||
|
message: "start must be larger than or equal to min and smaller than or equal to max",
|
||||||
|
});
|
||||||
|
|
||||||
|
export type DurationSchemaT = z.infer<typeof DurationSchema>;
|
||||||
|
export type PointSchemaT = z.infer<typeof PointSchema>;
|
||||||
|
|
||||||
|
// -- Parser --
|
||||||
|
|
||||||
|
export function parseSchema(schema: any): DurationSchemaT | PointSchemaT {
|
||||||
|
try {
|
||||||
|
if (schema.type === "duration") {
|
||||||
|
return DurationSchema.parse(schema);
|
||||||
|
} else if (schema.type === "points") {
|
||||||
|
return PointSchema.parse(schema);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ZodError) {
|
||||||
|
const issue = e.issues.at(0);
|
||||||
|
|
||||||
|
if (issue) {
|
||||||
|
throw new SchemaError(`${issue.path}: ${issue.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SchemaError("Unknown error occured while validating the schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SchemaError("type must be either 'duration' or 'points'");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user