···11+import { z } from "zod";
22+import { MonitorSchema } from "../monitors/schema";
33+44+export const CheckSchema = MonitorSchema.pick({
55+ url: true,
66+ body: true,
77+ headers: true,
88+ method: true,
99+ regions: true,
1010+})
1111+ .extend({
1212+ runCount: z
1313+ .number()
1414+ .optional()
1515+ .default(1)
1616+ .openapi({ description: "The number of times to run the check" }),
1717+ aggregated: z
1818+ .boolean()
1919+ .optional()
2020+ .openapi({ description: "Whether to aggregate the results or not" }),
2121+ // webhook: z
2222+ // .string()
2323+ // .optional()
2424+ // .openapi({ description: "The webhook to send the result to" }),
2525+ })
2626+ .openapi({
2727+ description: "The check request",
2828+ });
2929+3030+export const TimingSchema = z.object({
3131+ dnsStart: z
3232+ .number()
3333+ .openapi({ description: "DNS timestamp start time in UTC " }),
3434+ dnsDone: z
3535+ .number()
3636+ .openapi({ description: "DNS timestamp end time in UTC " }),
3737+ connectStart: z
3838+ .number()
3939+ .openapi({ description: "Connect timestamp start time in UTC " }),
4040+ connectDone: z
4141+ .number()
4242+ .openapi({ description: "Connect timestamp end time in UTC " }),
4343+ tlsHandshakeStart: z
4444+ .number()
4545+ .openapi({ description: "TLS handshake timestamp start time in UTC " }),
4646+ tlsHandshakeDone: z
4747+ .number()
4848+ .openapi({ description: "TLS handshake timestamp end time in UTC " }),
4949+ firstByteStart: z
5050+ .number()
5151+ .openapi({ description: "First byte timestamp start time in UTC " }),
5252+ firstByteDone: z
5353+ .number()
5454+ .openapi({ description: "First byte timestamp end time in UTC " }),
5555+ transferStart: z
5656+ .number()
5757+ .openapi({ description: "Transfer timestamp start time in UTC " }),
5858+ transferDone: z
5959+ .number()
6060+ .openapi({ description: "Transfer timestamp end time in UTC " }),
6161+});
6262+6363+export const AggregatedResponseSchema = z
6464+ .object({
6565+ p50: z.number().openapi({ description: "The 50th percentile" }),
6666+ p75: z.number().openapi({ description: "The 75th percentile" }),
6767+ p95: z.number().openapi({ description: "The 95th percentile" }),
6868+ p99: z.number().openapi({ description: "The 99th percentile" }),
6969+ min: z.number().openapi({ description: "The minimum value" }),
7070+ max: z.number().openapi({ description: "The maximum value" }),
7171+ })
7272+ .openapi({
7373+ description: "The aggregated data of the check",
7474+ });
7575+7676+export const ResponseSchema = z.object({
7777+ timestamp: z
7878+ .number()
7979+ .openapi({ description: "The timestamp of the response in UTC" }),
8080+ status: z
8181+ .number()
8282+ .openapi({ description: "The status code of the response" }),
8383+ latency: z.number().openapi({ description: "The latency of the response" }),
8484+ body: z
8585+ .string()
8686+ .optional()
8787+ .openapi({ description: "The body of the response" }),
8888+ headers: z
8989+ .record(z.string())
9090+ .optional()
9191+ .openapi({ description: "The headers of the response" }),
9292+ timing: TimingSchema.openapi({
9393+ description: "The timing metrics of the response",
9494+ }),
9595+ aggregated: z
9696+ .object({
9797+ dns: AggregatedResponseSchema.openapi({
9898+ description: "The aggregated DNS timing of the check",
9999+ }),
100100+ connection: AggregatedResponseSchema.openapi({
101101+ description: "The aggregated connection timing of the check",
102102+ }),
103103+ tls: AggregatedResponseSchema.openapi({
104104+ description: "The aggregated tls timing of the check",
105105+ }),
106106+ firstByte: AggregatedResponseSchema.openapi({
107107+ description: "The aggregated first byte timing of the check",
108108+ }),
109109+ transfer: AggregatedResponseSchema.openapi({
110110+ description: "The aggregated transfer timing of the check",
111111+ }),
112112+ latency: AggregatedResponseSchema.openapi({
113113+ description: "The aggregated latency timing of the check",
114114+ }),
115115+ })
116116+ .optional()
117117+ .openapi({
118118+ description: "The aggregated data dns timing of the check",
119119+ }),
120120+ region: z.string().openapi({ description: "The region where the check ran" }),
121121+});
122122+123123+export const CheckPostResponseSchema = z.object({
124124+ id: z.number().int().openapi({ description: "The id of the check" }),
125125+ raw: z.array(TimingSchema).openapi({
126126+ description: "The raw data of the check",
127127+ }),
128128+ response: ResponseSchema.openapi({
129129+ description: "The last response of the check",
130130+ }),
131131+});
+2
apps/server/src/v1/index.ts
···55import type { Limits } from "@openstatus/plans/src/types";
6677import { handleError, handleZodError } from "../libs/errors";
88+import { checkAPI } from "./check";
89import { incidentsApi } from "./incidents";
910import { middleware } from "./middleware";
1011import { monitorsApi } from "./monitors";
···5657api.route("/page_subscriber", pageSubscribersApi);
5758api.route("/status_report", statusReportsApi);
5859api.route("/status_report_update", statusReportUpdatesApi);
6060+api.route("/check", checkAPI);