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