infra refactor
This commit is contained in:
1 parent
df707ab194
commit
4dfeb71a9d
14 files changed
+195
-187
No files matched your search
@@ -3,3 +3,5 @@ export * from "./login";
|
||||
export * from "./register";
|
||||
export * from "./monitor";
|
||||
export * from "./pagespeed";
|
||||
export * from "./infra";
|
||||
export * from "./utils";
|
||||
@@ -0,0 +1,74 @@
|
||||
import { z } from "zod";
|
||||
import { urlRegex, durationSchema } from "@/validation/utils";
|
||||
|
||||
export const monitorSchemaInfra = z.object({
|
||||
type: z.string().min(1, "You must select an option"),
|
||||
url: z.string().min(1, "URL is required").regex(urlRegex, "Invalid URL"),
|
||||
secret: z.string().min(1, "Secret is required"),
|
||||
n: z.coerce
|
||||
.number({ message: "Number required" })
|
||||
.min(1, "Minimum value is 1")
|
||||
.max(25, "Maximum value is 25"),
|
||||
notificationChannels: z.array(z.string()).optional().default([]),
|
||||
name: z.string().min(1, "Display name is required"),
|
||||
interval: durationSchema(60000),
|
||||
rejectUnauthorized: z.boolean().default(true),
|
||||
thresholds: z.object({
|
||||
cpu: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "CPU threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "CPU must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "CPU must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
memory: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Memory threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Memory must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "Memory must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
disk: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Disk threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Disk must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "Disk must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
temperature: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Temperature threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Temperature must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= -50 && v <= 150, {
|
||||
message: "Temperature must be between -50 and 150",
|
||||
})
|
||||
),
|
||||
}),
|
||||
});
|
||||
@@ -1,25 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import humanInterval from "human-interval";
|
||||
import ms from "ms";
|
||||
export const urlRegex =
|
||||
/^(https?:\/\/)?(localhost|([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|[a-zA-Z0-9-]+|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?(\/.*)?$/;
|
||||
|
||||
export const durationSchema = (minInterval: number) =>
|
||||
z.string().superRefine((val, ctx) => {
|
||||
const milis = humanInterval(val);
|
||||
|
||||
if (!milis || isNaN(milis)) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: "Invalid duration format",
|
||||
});
|
||||
} else if (milis < minInterval) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `Minimum duration is ${ms(minInterval, { long: true })}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
import { urlRegex, durationSchema } from "@/validation/utils";
|
||||
|
||||
export const monitorSchema = z
|
||||
.object({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import { urlRegex, durationSchema } from "@/validation";
|
||||
import { urlRegex, durationSchema } from "@/validation/utils";
|
||||
|
||||
export const monitorSchemaPageSpeed = z.object({
|
||||
type: z.string().min(1, "You must select an option"),
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { z } from "zod";
|
||||
import humanInterval from "human-interval";
|
||||
import ms from "ms";
|
||||
|
||||
export const urlRegex =
|
||||
/^(https?:\/\/)?(localhost|([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|[a-zA-Z0-9-]+|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?(\/.*)?$/;
|
||||
|
||||
export const durationSchema = (minInterval: number) =>
|
||||
z.string().superRefine((val, ctx) => {
|
||||
const milis = humanInterval(val);
|
||||
|
||||
if (!milis || isNaN(milis)) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: "Invalid duration format",
|
||||
});
|
||||
} else if (milis < minInterval) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `Minimum duration is ${ms(minInterval, { long: true })}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import humanInterval from "human-interval";
|
||||
// humanInterval moved to split schema files
|
||||
import { ChannelTypes } from "@/types/notification-channel";
|
||||
import { MaintenanceRepeats } from "@/types/maintenance";
|
||||
|
||||
@@ -8,25 +8,7 @@ const urlRegex =
|
||||
|
||||
// monitor duration schema moved to client/src/validation/monitor.ts
|
||||
// pagespeed duration schema moved to client/src/validation/pagespeed.ts
|
||||
const durationSchemaInfra = z
|
||||
.string()
|
||||
.optional()
|
||||
.superRefine((val, ctx) => {
|
||||
if (!val || val.trim() === "") return;
|
||||
const ms = humanInterval(val);
|
||||
|
||||
if (!ms || isNaN(ms)) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: "Invalid duration format",
|
||||
});
|
||||
} else if (ms < 60000) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: "Minimum duration is 1 minute",
|
||||
});
|
||||
}
|
||||
});
|
||||
// infra duration schema moved to client/src/validation/infra.ts
|
||||
|
||||
const optionalString = <T extends z.ZodTypeAny>(schema: T) =>
|
||||
z.preprocess(
|
||||
@@ -38,78 +20,7 @@ const optionalString = <T extends z.ZodTypeAny>(schema: T) =>
|
||||
// moved to client/src/validation/monitor.ts
|
||||
|
||||
// moved to client/src/validation/pagespeed.ts
|
||||
export const monitorSchemaInfra = z.object({
|
||||
type: z.string().min(1, "You must select an option"),
|
||||
url: z.string().min(1, "URL is required").regex(urlRegex, "Invalid URL"),
|
||||
secret: z.string().min(1, "Secret is required"),
|
||||
n: z.coerce
|
||||
.number({ message: "Number required" })
|
||||
.min(1, "Minimum value is 1")
|
||||
.max(25, "Maximum value is 25"),
|
||||
notificationChannels: z.array(z.string()).optional().default([]),
|
||||
name: z.string().min(1, "Display name is required"),
|
||||
interval: durationSchemaInfra,
|
||||
rejectUnauthorized: z.boolean().default(true),
|
||||
thresholds: z.object({
|
||||
// Accept both strings and numbers from the form. Enforce required and ranges with clear messages.
|
||||
cpu: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "CPU threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "CPU must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "CPU must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
memory: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Memory threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Memory must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "Memory must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
disk: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Disk threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Disk must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= 0 && v <= 100, {
|
||||
message: "Disk must be between 0 and 100",
|
||||
})
|
||||
),
|
||||
temperature: z.preprocess(
|
||||
(val) => (typeof val === "number" ? String(val) : val),
|
||||
z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, { message: "Temperature threshold is required" })
|
||||
.refine((v) => /^-?\d+(\.\d+)?$/.test(v), {
|
||||
message: "Temperature must be a number",
|
||||
})
|
||||
.transform((v) => Number(v))
|
||||
.refine((v) => v >= -50 && v <= 150, {
|
||||
message: "Temperature must be between -50 and 150",
|
||||
})
|
||||
),
|
||||
}),
|
||||
});
|
||||
// moved to client/src/validation/infra.ts
|
||||
|
||||
export const teamSchema = z.object({
|
||||
name: z.string().min(1, "Team name is required"),
|
||||
|
||||
Reference in new issue
Block a user