65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
const safeRelativePathSchema = z
|
|
.string()
|
|
.min(1)
|
|
.max(200)
|
|
.refine((value) => !value.startsWith('/') && !value.startsWith('\\'), {
|
|
message: 'Path must be relative to the project root',
|
|
})
|
|
.refine((value) => !value.split(/[\\/]+/).includes('..'), {
|
|
message: 'Path must not contain parent directory segments',
|
|
});
|
|
|
|
// Healthcheck Schema
|
|
export const healthcheckSchema = z.object({
|
|
acceptableStatusCodes: z.array(z.number().int().min(100).max(599)).min(1).default([200]),
|
|
timeoutMs: z.number().int().positive().default(5000),
|
|
}).strict();
|
|
|
|
// Service Schema
|
|
export const serviceSchema = z.object({
|
|
id: z.string().min(1).max(50),
|
|
name: z.string().min(1).max(100),
|
|
description: z.string().min(1).max(500),
|
|
url: z.string().url(),
|
|
monitorUrl: z.string().url(),
|
|
category: z.string().min(1).max(50),
|
|
healthcheck: healthcheckSchema.optional(),
|
|
}).strict();
|
|
|
|
// App Config Schema
|
|
export const appConfigSchema = z.object({
|
|
title: z.string().min(1).max(100),
|
|
subtitle: z.string().min(1).max(200),
|
|
description: z.string().min(1).max(500),
|
|
servicesFile: safeRelativePathSchema,
|
|
refreshInterval: z.number().int().min(1000).max(300000).default(30000), // 1s to 5min
|
|
categories: z.array(z.string().min(1).max(50)).min(1),
|
|
theme: z.enum(['light', 'dark', 'auto']).default('auto'),
|
|
loggingLevel: z.enum(['error', 'warn', 'info', 'debug']).default('info'),
|
|
}).strict();
|
|
|
|
// Services Array Schema
|
|
export const servicesArraySchema = z.array(serviceSchema).superRefine((services, ctx) => {
|
|
const ids = new Set<string>();
|
|
|
|
services.forEach((service, index) => {
|
|
if (ids.has(service.id)) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
message: `Duplicate service id: ${service.id}`,
|
|
path: [index, 'id'],
|
|
});
|
|
return;
|
|
}
|
|
|
|
ids.add(service.id);
|
|
});
|
|
});
|
|
|
|
// Type exports
|
|
export type Service = z.infer<typeof serviceSchema>;
|
|
export type Healthcheck = z.infer<typeof healthcheckSchema>;
|
|
export type AppConfig = z.infer<typeof appConfigSchema>;
|
|
export type Services = z.infer<typeof servicesArraySchema>;
|