Openstatus www.openstatus.dev
at main 156 lines 4.3 kB view raw
1import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 2import * as z from "zod"; 3 4import { notificationProvider } from "./constants"; 5import { notification } from "./notification"; 6 7export const notificationProviderSchema = z.enum(notificationProvider); 8 9export const selectNotificationSchema = createSelectSchema(notification).extend( 10 { 11 data: z 12 .preprocess((val) => { 13 return String(val); 14 }, z.string()) 15 .prefault("{}"), 16 }, 17); 18 19// we need to extend, otherwise data can be `null` or `undefined` - default is not 20export const insertNotificationSchema = createInsertSchema(notification).extend( 21 { 22 data: z.string().prefault("{}"), 23 monitors: z.array(z.number()).optional().prefault([]), 24 }, 25); 26 27export type InsertNotification = z.infer<typeof insertNotificationSchema>; 28export type Notification = z.infer<typeof selectNotificationSchema>; 29export type NotificationProvider = z.infer<typeof notificationProviderSchema>; 30 31const phoneRegex = new RegExp( 32 /^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)])?([-]?[\s]?[0-9])+$/, 33); 34 35export const phoneSchema = z.string().regex(phoneRegex, "Invalid Number!"); 36export const emailSchema = z.email(); 37export const urlSchema = z.url(); 38 39export const ntfyDataSchema = z.object({ 40 ntfy: z.object({ 41 topic: z.string().prefault(""), 42 serverUrl: z.string().prefault("https://ntfy.sh"), 43 token: z.string().optional(), 44 }), 45}); 46export const webhookDataSchema = z.object({ 47 webhook: z.object({ 48 endpoint: z.url(), 49 headers: z 50 .array(z.object({ key: z.string(), value: z.string() })) 51 .optional(), 52 }), 53}); 54export const emailDataSchema = z.object({ email: emailSchema }); 55export const phoneDataSchema = z.object({ sms: phoneSchema }); 56export const slackDataSchema = z.object({ slack: urlSchema }); 57export const discordDataSchema = z.object({ discord: urlSchema }); 58export const googleChatDataSchema = z.object({ "google-chat": urlSchema }); 59export const pagerdutyDataSchema = z.object({ pagerduty: z.string() }); 60export const opsgenieDataSchema = z.object({ 61 opsgenie: z.object({ 62 apiKey: z.string(), 63 region: z.enum(["us", "eu"]), 64 }), 65}); 66export const telegramDataSchema = z.object({ 67 telegram: z.object({ chatId: z.string() }), 68}); 69 70export const whatsappDataSchema = z.object({ 71 whatsapp: phoneSchema, 72}); 73 74export const NotificationDataSchema = z.union([ 75 discordDataSchema, 76 emailDataSchema, 77 ntfyDataSchema, 78 opsgenieDataSchema, 79 pagerdutyDataSchema, 80 phoneDataSchema, 81 telegramDataSchema, 82 slackDataSchema, 83 webhookDataSchema, 84 whatsappDataSchema, 85 googleChatDataSchema, 86]); 87 88export const InsertNotificationWithDataSchema = z.discriminatedUnion( 89 "provider", 90 [ 91 insertNotificationSchema.extend( 92 z.object({ 93 provider: z.literal("discord"), 94 data: discordDataSchema, 95 }).shape, 96 ), 97 insertNotificationSchema.extend( 98 z.object({ 99 provider: z.literal("email"), 100 data: emailDataSchema, 101 }).shape, 102 ), 103 insertNotificationSchema.extend( 104 z.object({ 105 provider: z.literal("google-chat"), 106 data: googleChatDataSchema, 107 }).shape, 108 ), 109 insertNotificationSchema.extend( 110 z.object({ 111 provider: z.literal("ntfy"), 112 data: ntfyDataSchema, 113 }).shape, 114 ), 115 insertNotificationSchema.extend( 116 z.object({ 117 provider: z.literal("pagerduty"), 118 data: pagerdutyDataSchema, 119 }).shape, 120 ), 121 insertNotificationSchema.extend( 122 z.object({ 123 provider: z.literal("opsgenie"), 124 data: opsgenieDataSchema, 125 }).shape, 126 ), 127 insertNotificationSchema.extend( 128 z.object({ 129 provider: z.literal("sms"), 130 data: phoneDataSchema, 131 }).shape, 132 ), 133 insertNotificationSchema.extend( 134 z.object({ 135 provider: z.literal("slack"), 136 data: slackDataSchema, 137 }).shape, 138 ), 139 insertNotificationSchema.extend( 140 z.object({ 141 provider: z.literal("webhook"), 142 data: webhookDataSchema, 143 }).shape, 144 ), 145 insertNotificationSchema.merge( 146 z.object({ 147 provider: z.literal("whatsapp"), 148 data: whatsappDataSchema, 149 }), 150 ), 151 ], 152); 153 154export type InsertNotificationWithData = z.infer< 155 typeof InsertNotificationWithDataSchema 156>;