Openstatus
www.openstatus.dev
1import type { ThemeKey } from "@openstatus/theme-store";
2import { THEME_KEYS } from "@openstatus/theme-store";
3import { createInsertSchema, createSelectSchema } from "drizzle-zod";
4import { z } from "zod";
5
6import { pageAccessTypes } from "./constants";
7import { page } from "./page";
8
9const slugSchema = z
10 .string()
11 .regex(
12 /^[A-Za-z0-9-]+$/,
13 "Only use digits (0-9), hyphen (-) or characters (A-Z, a-z).",
14 )
15 .min(3)
16 .toLowerCase();
17
18const customDomainSchema = z
19 .string()
20 .regex(
21 /^(?!https?:\/\/|www.)([a-zA-Z0-9]+(.[a-zA-Z0-9]+)+.*)$/,
22 "Should not start with http://, https:// or www.",
23 )
24 .or(z.enum([""]));
25
26const stringToArray = z.preprocess((val) => {
27 if (val && String(val).length > 0) {
28 return String(val).split(",");
29 }
30 return [];
31}, z.array(z.string()));
32
33export const insertPageSchema = createInsertSchema(page, {
34 customDomain: customDomainSchema.prefault(""),
35 accessType: z.enum(pageAccessTypes).prefault("public"),
36 icon: z.string().optional(),
37 slug: slugSchema,
38}).extend({
39 password: z.string().nullable().optional().prefault(""),
40 monitors: z
41 .array(
42 z.object({
43 // REMINDER: has to be different from `id` in as the prop is already used by react-hook-form
44 monitorId: z.number(),
45 order: z.number().prefault(0).optional(),
46 }),
47 )
48 .optional()
49 .prefault([]),
50 authEmailDomains: z.array(z.string()).nullish(),
51});
52
53export const pageConfigurationSchema = z.object({
54 value: z
55 .enum(["duration", "requests", "manual"])
56 .nullish()
57 .prefault("requests"),
58 type: z.enum(["absolute", "manual"]).nullish().prefault("absolute"),
59 uptime: z.coerce.boolean().nullish().prefault(true),
60 theme: z
61 .enum(THEME_KEYS as [ThemeKey, ...ThemeKey[]])
62 .nullish()
63 .prefault("default"),
64});
65
66export const selectPageSchema = createSelectSchema(page).extend({
67 password: z.string().optional().nullable().prefault(""),
68 configuration: pageConfigurationSchema.nullish().prefault({}),
69 accessType: z.enum(pageAccessTypes).prefault("public"),
70 authEmailDomains: stringToArray.prefault([]),
71});
72
73export type InsertPage = z.infer<typeof insertPageSchema>;
74export type Page = z.infer<typeof selectPageSchema>;