Openstatus
www.openstatus.dev
1import { z } from "zod";
2
3import { selectIncidentSchema } from "./incidents/validation";
4import { selectMaintenanceSchema } from "./maintenances";
5import { selectMonitorSchema } from "./monitors";
6import { selectPageSchema } from "./pages";
7import {
8 selectStatusReportSchema,
9 selectStatusReportUpdateSchema,
10} from "./status_reports";
11import { workspacePlanSchema } from "./workspaces";
12
13// TODO: create a 'public-status' schema with all the different types and validations
14
15export const selectPublicMonitorSchema = selectMonitorSchema.omit({
16 body: true,
17 headers: true,
18 method: true,
19 otelEndpoint: true,
20 otelHeaders: true,
21});
22
23export const selectStatusReportPageSchema = selectStatusReportSchema.extend({
24 statusReportUpdates: z.array(selectStatusReportUpdateSchema).default([]),
25 monitorsToStatusReports: z
26 .array(
27 z.object({
28 monitorId: z.number(),
29 statusReportId: z.number(),
30 monitor: selectPublicMonitorSchema,
31 }),
32 )
33 .default([]),
34});
35
36export const selectMaintenancePageSchema = selectMaintenanceSchema.extend({
37 maintenancesToMonitors: z
38 .array(
39 z.object({
40 monitorId: z.number(),
41 maintenanceId: z.number(),
42 monitor: selectPublicMonitorSchema,
43 }),
44 )
45 .default([]),
46});
47// TODO: it would be nice to automatically add the monitor relation here
48// .refine((data) => ({ monitors: data.maintenancesToMonitors.map((m) => m.monitorId) }));
49
50export const selectPageSchemaWithRelation = selectPageSchema.extend({
51 monitors: z.array(selectMonitorSchema),
52 statusReports: z.array(selectStatusReportPageSchema),
53});
54
55export const selectPageSchemaWithMonitorsRelation = selectPageSchema.extend({
56 monitorsToPages: z.array(
57 z.object({
58 monitorId: z.number(),
59 pageId: z.number(),
60 order: z.number().default(0).optional(),
61 monitor: selectMonitorSchema,
62 }),
63 ),
64 maintenances: selectMaintenanceSchema.array().default([]),
65 statusReports: selectStatusReportSchema
66 .extend({ statusReportUpdates: selectStatusReportUpdateSchema.array() })
67 .array()
68 .default([]),
69});
70
71export const legacy_selectPublicPageSchemaWithRelation = selectPageSchema
72 .extend({
73 monitors: z.array(selectPublicMonitorSchema).default([]),
74 statusReports: z.array(selectStatusReportPageSchema).default([]),
75 incidents: z.array(selectIncidentSchema).default([]),
76 maintenances: z.array(selectMaintenancePageSchema).default([]),
77 workspacePlan: workspacePlanSchema
78 .nullable()
79 .default("free")
80 .transform((val) => val ?? "free"),
81 })
82 .omit({
83 // workspaceId: true,
84 id: true,
85 });
86
87export const selectPublicPageSchemaWithRelation = selectPageSchema
88 .extend({
89 // TODO: include status of the monitor
90 monitors: selectPublicMonitorSchema
91 .extend({
92 status: z
93 .enum(["success", "degraded", "error", "info"])
94 .default("success"),
95 })
96 .array(),
97 lastEvents: z.array(
98 z.object({
99 id: z.number(),
100 name: z.string(),
101 from: z.date(),
102 to: z.date().nullable(),
103 status: z
104 .enum(["success", "degraded", "error", "info"])
105 .default("success"),
106 type: z.enum(["maintenance", "incident", "report"]),
107 }),
108 ),
109 openEvents: z.array(
110 z.object({
111 id: z.number(),
112 name: z.string(),
113 from: z.date(),
114 to: z.date().nullable(),
115 status: z
116 .enum(["success", "degraded", "error", "info"])
117 .default("success"),
118 type: z.enum(["maintenance", "incident", "report"]),
119 }),
120 ),
121 statusReports: z.array(selectStatusReportPageSchema),
122 incidents: z.array(selectIncidentSchema),
123 maintenances: z.array(selectMaintenancePageSchema),
124 status: z.enum(["success", "degraded", "error", "info"]).default("success"),
125 workspacePlan: workspacePlanSchema
126 .nullable()
127 .default("free")
128 .transform((val) => val ?? "free"),
129 })
130 .omit({
131 // workspaceId: true,
132 // id: true,
133 password: true,
134 });
135
136export const selectPublicStatusReportSchemaWithRelation =
137 selectStatusReportSchema.extend({
138 monitorsToStatusReports: z
139 .array(
140 z.object({
141 monitorId: z.number(),
142 statusReportId: z.number(),
143 monitor: selectPublicMonitorSchema,
144 }),
145 )
146 .default([]),
147 statusReportUpdates: z.array(selectStatusReportUpdateSchema),
148 });
149
150export type StatusReportWithUpdates = z.infer<
151 typeof selectStatusReportPageSchema
152>;
153export type PublicMonitor = z.infer<typeof selectPublicMonitorSchema>;
154export type PublicPage = z.infer<
155 typeof legacy_selectPublicPageSchemaWithRelation
156>;