Openstatus
www.openstatus.dev
1import { z } from "zod";
2
3/**
4 * The base schema for every event, used to validate it's structure
5 * on datasource ingestion and pipe retrieval.
6 */
7export const baseSchema = z.object({
8 id: z.string().min(1), // DISCUSS: we could use the `${targets.type}:${targets.id}` format automatic generation
9 action: z.string(),
10 // REMINDER: do not use .default(Date.now()), it will be evaluated only once
11 timestamp: z
12 .int()
13 .optional()
14 .transform((val) => val || Date.now()),
15 version: z.int().prefault(1),
16});
17
18/**
19 * The schema for the actor type.
20 * It represents the type of the user that triggered the event.
21 */
22export const actorTypeSchema = z.enum(["user", "system"]);
23
24/**
25 * The schema for the actor object.
26 * It represents the user that triggered the event.
27 */
28export const actorSchema = z
29 .object({
30 id: z.string(),
31 type: actorTypeSchema,
32 })
33 .prefault({
34 id: "server",
35 type: "system",
36 });
37
38/**
39 * The schema for the target type.
40 * It represents the type of the target that is affected by the event.
41 */
42export const targetTypeSchema = z.enum([
43 "monitor",
44 "page",
45 // "incident", // has been removed from the schema
46 "status-report",
47 "user",
48 "notification",
49 "organization",
50]);
51
52/**
53 * The schema for the targets object.
54 * It represents the targets that are affected by the event.
55 */
56export const targetsSchema = z
57 .object({
58 id: z.string(),
59 type: targetTypeSchema,
60 })
61 .array()
62 .optional();
63
64/**
65 * The schema for the event object.
66 * It extends the base schema and transforms the actor, targets
67 * objects into strings.
68 */
69export const ingestBaseEventSchema = baseSchema.extend({
70 actor: actorSchema.transform((val) => JSON.stringify(val)),
71 targets: targetsSchema.transform((val) => JSON.stringify(val)),
72});
73
74/**
75 * The schema for the response object.
76 * It extends the base schema and transforms the actor, targets
77 * back into typed objects.
78 */
79export const pipeBaseResponseData = baseSchema.extend({
80 actor: z.preprocess((val) => JSON.parse(String(val)), actorSchema),
81 targets: z.preprocess(
82 (val) => (val ? JSON.parse(String(val)) : undefined),
83 targetsSchema,
84 ),
85});
86
87/**
88 * The schema for the parameters object.
89 * It represents the parameters that are passed to the pipe.
90 */
91export const pipeParameterData = z.object({ event_id: z.string().min(1) });
92
93export type PipeParameterData = z.infer<typeof pipeParameterData>;
94export type PipeBaseResponseData = z.infer<typeof pipeBaseResponseData>;
95export type IngestBaseEvent = z.infer<typeof ingestBaseEventSchema>;