···1/// <reference types="next" />
2/// <reference types="next/image-types/global" />
3-import "./.next/types/routes.d.ts";
45// NOTE: This file should not be edited
6// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
···1/// <reference types="next" />
2/// <reference types="next/image-types/global" />
3+import "./.next/dev/types/routes.d.ts";
45// NOTE: This file should not be edited
6// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
···13 .number()
14 .max(5)
15 .optional()
16- .prefault(1)
17 .openapi({ description: "The number of times to run the check" }),
18 aggregated: z
19 .boolean()
···87 .optional()
88 .openapi({ description: "The body of the response" }),
89 headers: z
90- .record(z.string(), z.string())
91 .optional()
92 .openapi({ description: "The headers of the response" }),
93 timing: TimingSchema.openapi({
···131});
132133export const CheckPostResponseSchema = z.object({
134- id: z.int().openapi({ description: "The id of the check" }),
135 raw: z.array(TimingSchema).openapi({
136 description: "The raw data of the check",
137 }),
···13 .number()
14 .max(5)
15 .optional()
16+ .default(1)
17 .openapi({ description: "The number of times to run the check" }),
18 aggregated: z
19 .boolean()
···87 .optional()
88 .openapi({ description: "The body of the response" }),
89 headers: z
90+ .record(z.string())
91 .optional()
92 .openapi({ description: "The headers of the response" }),
93 timing: TimingSchema.openapi({
···131});
132133export const CheckPostResponseSchema = z.object({
134+ id: z.number().int().openapi({ description: "The id of the check" }),
135 raw: z.array(TimingSchema).openapi({
136 description: "The raw data of the check",
137 }),
+1-4
apps/server/src/routes/v1/incidents/put.test.ts
···60 });
6162 const result = (await res.json()) as Record<string, unknown>;
63- // expect(result.message).toBe("invalid_date in 'acknowledgedAt': Invalid date");
64- expect(result.message).toBe(
65- "invalid_type in 'acknowledgedAt': Invalid input: expected date, received Date",
66- );
67 expect(res.status).toBe(400);
68});
69
···60 });
6162 const result = (await res.json()) as Record<string, unknown>;
63+ expect(result.message).toBe("invalid_date in 'acknowledgedAt': Invalid date");
00064 expect(res.status).toBe(400);
65});
66
+1-1
apps/server/src/routes/v1/maintenances/schema.ts
···37 monitorIds: z
38 .array(z.number())
39 .optional()
40- .prefault([])
41 .openapi({ description: "IDs of affected monitors" }),
42 pageId: z.number().openapi({
43 description: "The id of the status page this maintenance belongs to",
···37 monitorIds: z
38 .array(z.number())
39 .optional()
40+ .default([])
41 .openapi({ description: "IDs of affected monitors" }),
42 pageId: z.number().openapi({
43 description: "The id of the status page this maintenance belongs to",
+1-1
apps/server/src/routes/v1/monitors/run/schema.ts
···23export const QuerySchema = z
4 .object({
5- "no-wait": z.coerce.boolean().optional().prefault(false).openapi({
6 description: "Don't wait for the result",
7 }),
8 })
···23export const QuerySchema = z
4 .object({
5+ "no-wait": z.coerce.boolean().optional().default(false).openapi({
6 description: "Don't wait for the result",
7 }),
8 })
+62-52
apps/server/src/routes/v1/monitors/schema.ts
···20 description: "The comparison to run",
21 example: "eq",
22 }),
23- target: z.int().positive().openapi({ description: "The target value" }),
000024 })
25 .openapi({
26 description: "The status assertion",
···90 }),
91});
9293-const PeriodicityEnumHonoSchema = z.enum([...monitorPeriodicitySchema.options]);
94-95export const MonitorSchema = z
96 .object({
97 id: z.number().openapi({
98 example: 123,
99 description: "The id of the monitor",
100 }),
101- periodicity: PeriodicityEnumHonoSchema.openapi({
102 example: "1m",
103 description: "How often the monitor should run",
104 }),
···109 regions: z
110 .preprocess(
111 (val) => {
112- let parsedRegions: Array<unknown> = [];
113- if (!val) return parsedRegions;
114 if (Array.isArray(val)) {
115- parsedRegions = val;
116 }
117 if (String(val).length > 0) {
118- parsedRegions = String(val).split(",");
000000000000000000119 }
120- return parsedRegions;
0121 },
122 z.array(z.enum(monitorRegions)),
123 )
124- .superRefine((regions, ctx) => {
125- const deprecatedRegions = regions.filter((r) => {
126- return !AVAILABLE_REGIONS.includes(
127- r as (typeof AVAILABLE_REGIONS)[number],
128- );
129- });
130- if (deprecatedRegions.length > 0) {
131- ctx.addIssue({
132- code: "custom",
133- path: ["regions"],
134- message: `Deprecated regions are not allowed: ${deprecatedRegions.join(
135- ", ",
136- )}`,
137- });
138- }
139- })
140- .prefault([])
141 .openapi({
142 example: ["ams"],
143 description: "Where we should monitor it",
···161 return String(val);
162 }, z.string())
163 .nullish()
164- .prefault("")
165 .openapi({
166 example: "Hello World",
167 description: "The body",
···185 ]);
186 }
187 },
188- z.array(z.object({ key: z.string(), value: z.string() })).prefault([]),
189 )
190 .nullish()
191 .openapi({
···211 }
212 }, z.array(assertion))
213 .nullish()
214- .prefault([])
215 .openapi({
216 description: "The assertions to run",
217 }),
218 active: z
219 .boolean()
220- .prefault(false)
221 .openapi({ description: "If the monitor is active" }),
222 public: z
223 .boolean()
224- .prefault(false)
225 .openapi({ description: "If the monitor is public" }),
226 degradedAfter: z.number().nullish().openapi({
227 description:
228 "The time after the monitor is considered degraded in milliseconds",
229 }),
230- timeout: z.number().nullish().prefault(45000).openapi({
231 description: "The timeout of the request in milliseconds",
232 }),
233- retry: z.number().prefault(3).openapi({
234 description: "The number of retries to attempt",
235 }),
236- followRedirects: z.boolean().prefault(true).openapi({
237 description: "If the monitor should follow redirects",
238 }),
239- jobType: z.enum(monitorJobTypes).optional().prefault("http").openapi({
240 description: "The type of the monitor",
241 }),
242 openTelemetry: z
243 .object({
244- endpoint: z.url().optional().prefault("http://localhost:4317").openapi({
245- description: "The endpoint of the OpenTelemetry collector",
246- }),
247- headers: z
248- .record(z.string(), z.string())
249 .optional()
250- .prefault({})
251 .openapi({
252- description: "The headers to send to the OpenTelemetry collector",
253 }),
000254 })
255 .optional()
256 .openapi({
···310]);
311312export const ResultRun = z.object({
313- latency: z.int(), // in ms
314- statusCode: z.int().nullable().prefault(null),
315- monitorId: z.string().prefault(""),
316 url: z.string().optional(),
317- error: z.coerce.boolean().prefault(false),
318 region: z.enum(monitorRegions),
319- timestamp: z.int().optional(),
320 message: z.string().nullable().optional(),
321 timing: z
322 .preprocess((val) => {
···407 },
408 z.array(z.enum(monitorRegions)),
409 )
410- .prefault([])
411 .openapi({
412 example: ["ams"],
413 description: "Where we should monitor it",
···415 openTelemetry: z
416 .object({
417 endpoint: z
0418 .url()
419 .optional()
420 .openapi({
···434435const httpRequestSchema = z.object({
436 method: z.enum(monitorMethods),
437- url: z.url().openapi({
438- description: "URL to request",
439- examples: ["https://openstat.us", "https://www.openstatus.dev"],
440- }),
000441 headers: z
442 .record(z.string(), z.string())
443 .optional()
···20 description: "The comparison to run",
21 example: "eq",
22 }),
23+ target: z
24+ .number()
25+ .int()
26+ .positive()
27+ .openapi({ description: "The target value" }),
28 })
29 .openapi({
30 description: "The status assertion",
···94 }),
95});
960097export const MonitorSchema = z
98 .object({
99 id: z.number().openapi({
100 example: 123,
101 description: "The id of the monitor",
102 }),
103+ periodicity: monitorPeriodicitySchema.openapi({
104 example: "1m",
105 description: "How often the monitor should run",
106 }),
···111 regions: z
112 .preprocess(
113 (val) => {
114+ let regions: Array<unknown> = [];
115+ if (!val) return regions;
116 if (Array.isArray(val)) {
117+ regions = val;
118 }
119 if (String(val).length > 0) {
120+ regions = String(val).split(",");
121+ }
122+123+ const deprecatedRegions = regions.filter((r) => {
124+ return !AVAILABLE_REGIONS.includes(
125+ r as (typeof AVAILABLE_REGIONS)[number],
126+ );
127+ });
128+129+ if (deprecatedRegions.length > 0) {
130+ throw new ZodError([
131+ {
132+ code: "custom",
133+ path: ["regions"],
134+ message: `Deprecated regions are not allowed: ${deprecatedRegions.join(
135+ ", ",
136+ )}`,
137+ },
138+ ]);
139 }
140+141+ return regions;
142 },
143 z.array(z.enum(monitorRegions)),
144 )
145+ .default([])
0000000000000000146 .openapi({
147 example: ["ams"],
148 description: "Where we should monitor it",
···166 return String(val);
167 }, z.string())
168 .nullish()
169+ .default("")
170 .openapi({
171 example: "Hello World",
172 description: "The body",
···190 ]);
191 }
192 },
193+ z.array(z.object({ key: z.string(), value: z.string() })).default([]),
194 )
195 .nullish()
196 .openapi({
···216 }
217 }, z.array(assertion))
218 .nullish()
219+ .default([])
220 .openapi({
221 description: "The assertions to run",
222 }),
223 active: z
224 .boolean()
225+ .default(false)
226 .openapi({ description: "If the monitor is active" }),
227 public: z
228 .boolean()
229+ .default(false)
230 .openapi({ description: "If the monitor is public" }),
231 degradedAfter: z.number().nullish().openapi({
232 description:
233 "The time after the monitor is considered degraded in milliseconds",
234 }),
235+ timeout: z.number().nullish().default(45000).openapi({
236 description: "The timeout of the request in milliseconds",
237 }),
238+ retry: z.number().default(3).openapi({
239 description: "The number of retries to attempt",
240 }),
241+ followRedirects: z.boolean().default(true).openapi({
242 description: "If the monitor should follow redirects",
243 }),
244+ jobType: z.enum(monitorJobTypes).optional().default("http").openapi({
245 description: "The type of the monitor",
246 }),
247 openTelemetry: z
248 .object({
249+ endpoint: z
250+ .string()
251+ .url()
00252 .optional()
253+ .default("http://localhost:4317")
254 .openapi({
255+ description: "The endpoint of the OpenTelemetry collector",
256 }),
257+ headers: z.record(z.string()).optional().default({}).openapi({
258+ description: "The headers to send to the OpenTelemetry collector",
259+ }),
260 })
261 .optional()
262 .openapi({
···316]);
317318export const ResultRun = z.object({
319+ latency: z.number().int(), // in ms
320+ statusCode: z.number().int().nullable().default(null),
321+ monitorId: z.string().default(""),
322 url: z.string().optional(),
323+ error: z.coerce.boolean().default(false),
324 region: z.enum(monitorRegions),
325+ timestamp: z.number().int().optional(),
326 message: z.string().nullable().optional(),
327 timing: z
328 .preprocess((val) => {
···413 },
414 z.array(z.enum(monitorRegions)),
415 )
416+ .default([])
417 .openapi({
418 example: ["ams"],
419 description: "Where we should monitor it",
···421 openTelemetry: z
422 .object({
423 endpoint: z
424+ .string()
425 .url()
426 .optional()
427 .openapi({
···441442const httpRequestSchema = z.object({
443 method: z.enum(monitorMethods),
444+ url: z
445+ .string()
446+ .url()
447+ .openapi({
448+ description: "URL to request",
449+ examples: ["https://openstat.us", "https://www.openstatus.dev"],
450+ }),
451 headers: z
452 .record(z.string(), z.string())
453 .optional()
···4export { ParamsSchema };
56export const SummarySchema = z.object({
7- ok: z.int().openapi({
8 description:
9 "The number of ok responses (defined by the assertions - or by default status code 200)",
10 }),
11- count: z.int().openapi({ description: "The total number of request" }),
00012 day: z.coerce
13 .date()
14 .openapi({ description: "The date of the daily stat in ISO8601 format" }),
···4export { ParamsSchema };
56export const SummarySchema = z.object({
7+ ok: z.number().int().openapi({
8 description:
9 "The number of ok responses (defined by the assertions - or by default status code 200)",
10 }),
11+ count: z
12+ .number()
13+ .int()
14+ .openapi({ description: "The total number of request" }),
15 day: z.coerce
16 .date()
17 .openapi({ description: "The date of the daily stat in ISO8601 format" }),
···20 description: "The id of the subscriber",
21 example: 1,
22 }),
23- email: z.email().openapi({
24 description: "The email of the subscriber",
25 }),
26 pageId: z.number().openapi({
···20 description: "The id of the subscriber",
21 example: 1,
22 }),
23+ email: z.string().email().openapi({
24 description: "The email of the subscriber",
25 }),
26 pageId: z.number().openapi({
+3-2
apps/server/src/routes/v1/pages/schema.ts
···43 example: "status.acme.com",
44 }),
45 icon: z
046 .url()
47 .or(z.literal(""))
48 .transform((val) => (val ? val : undefined))
···51 description: "The icon of the page",
52 example: "https://example.com/icon.png",
53 }),
54- passwordProtected: z.boolean().optional().prefault(false).openapi({
55 description:
56 "Make the page password protected. Used with the 'passwordProtected' property.",
57 example: true,
···60 description: "Your password to protect the page from the public",
61 example: "hidden-password",
62 }),
63- showMonitorValues: z.boolean().optional().nullish().prefault(true).openapi({
64 description:
65 "Displays the total and failed request numbers for each monitor",
66 example: true,
···43 example: "status.acme.com",
44 }),
45 icon: z
46+ .string()
47 .url()
48 .or(z.literal(""))
49 .transform((val) => (val ? val : undefined))
···52 description: "The icon of the page",
53 example: "https://example.com/icon.png",
54 }),
55+ passwordProtected: z.boolean().optional().default(false).openapi({
56 description:
57 "Make the page password protected. Used with the 'passwordProtected' property.",
58 example: true,
···61 description: "Your password to protect the page from the public",
62 example: "hidden-password",
63 }),
64+ showMonitorValues: z.boolean().optional().nullish().default(true).openapi({
65 description:
66 "Displays the total and failed request numbers for each monitor",
67 example: true,
···22 status: z.enum(statusReportStatus).openapi({
23 description: "The status of the update",
24 }),
25- date: z.coerce.date().prefault(new Date()).openapi({
26 description: "The date of the update in ISO8601 format",
27 }),
28 message: z.string().openapi({
···22 status: z.enum(statusReportStatus).openapi({
23 description: "The status of the update",
24 }),
25+ date: z.coerce.date().default(new Date()).openapi({
26 description: "The date of the update in ISO8601 format",
27 }),
28 message: z.string().openapi({
+1-1
apps/server/src/routes/v1/statusReports/post.ts
···32 id: true,
33 statusReportUpdateIds: true,
34 }).extend({
35- date: z.coerce.date().optional().prefault(new Date()).openapi({
36 description:
37 "The date of the report in ISO8601 format, defaults to now",
38 }),
···32 id: true,
33 statusReportUpdateIds: true,
34 }).extend({
35+ date: z.coerce.date().optional().default(new Date()).openapi({
36 description:
37 "The date of the report in ISO8601 format, defaults to now",
38 }),
+2-2
apps/server/src/routes/v1/statusReports/schema.ts
···30 .array(z.number())
31 .optional()
32 .nullable()
33- .prefault([])
34 .openapi({
35 description: "The ids of the status report updates",
36 }),
37 monitorIds: z
38 .array(z.number())
39 .optional()
40- .prefault([])
41 .openapi({ description: "Ids of the monitors the status report." }),
42 pageId: z.number().openapi({
43 description: "The id of the page this status report belongs to",
···30 .array(z.number())
31 .optional()
32 .nullable()
33+ .default([])
34 .openapi({
35 description: "The ids of the status report updates",
36 }),
37 monitorIds: z
38 .array(z.number())
39 .optional()
40+ .default([])
41 .openapi({ description: "Ids of the monitors the status report." }),
42 pageId: z.number().openapi({
43 description: "The id of the page this status report belongs to",
+1-1
apps/server/src/routes/v1/whoami/schema.ts
···9 .optional()
10 .openapi({ description: "The current workspace name" }),
11 slug: z.string().openapi({ description: "The current workspace slug" }),
12- plan: z.enum(workspacePlans).nullable().prefault("free").openapi({
13 description: "The current workspace plan",
14 }),
15 })
···9 .optional()
10 .openapi({ description: "The current workspace name" }),
11 slug: z.string().openapi({ description: "The current workspace slug" }),
12+ plan: z.enum(workspacePlans).nullable().default("free").openapi({
13 description: "The current workspace plan",
14 }),
15 })
···16import { z } from "zod";
1718const schema = z.object({
19- email: z.email(),
20});
2122type FormValues = z.infer<typeof schema>;
···16import { z } from "zod";
1718const schema = z.object({
19+ email: z.string().email(),
20});
2122type FormValues = z.infer<typeof schema>;
+1-1
apps/web/next-env.d.ts
···1/// <reference types="next" />
2/// <reference types="next/image-types/global" />
3-import "./.next/types/routes.d.ts";
45// NOTE: This file should not be edited
6// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
···1/// <reference types="next" />
2/// <reference types="next/image-types/global" />
3+import "./.next/dev/types/routes.d.ts";
45// NOTE: This file should not be edited
6// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
···23export const preferencesSchema = z
4 .object({
5- combinedRegions: z.boolean().nullable().prefault(false).optional(),
6 // ... other settings to store user preferences
7 // accessible via document.cookie in the client and cookies() on the server
8 })
···23export const preferencesSchema = z
4 .object({
5+ combinedRegions: z.boolean().nullable().default(false).optional(),
6 // ... other settings to store user preferences
7 // accessible via document.cookie in the client and cookies() on the server
8 })