Openstatus
www.openstatus.dev
1import { Tinybird as Client, NoopTinybird } from "@chronark/zod-bird";
2import { z } from "zod";
3import { monitorRegions } from "../../db/src/schema/constants";
4import {
5 headersSchema,
6 timingPhasesSchema,
7 timingSchema,
8 triggers,
9} from "./schema";
10
11const PUBLIC_CACHE = 300; // 5 * 60 = 300s = 5m
12const DEV_CACHE = 10 * 60; // 10m
13const REVALIDATE = process.env.NODE_ENV === "development" ? DEV_CACHE : 0;
14
15export class OSTinybird {
16 private readonly tb: Client;
17
18 constructor(token: string) {
19 if (
20 process.env.NODE_ENV === "development" ||
21 process.env.NODE_ENV === "test"
22 ) {
23 this.tb = new NoopTinybird();
24 } else {
25 // Use local Tinybird container if available (Docker/self-hosted)
26 // https://www.tinybird.co/docs/api-reference
27 const tinybirdUrl = process.env.TINYBIRD_URL || "https://api.tinybird.co";
28 this.tb = new Client({
29 token,
30 baseUrl: tinybirdUrl,
31 });
32 }
33 }
34
35 public get homeStats() {
36 return this.tb.buildPipe({
37 pipe: "endpoint__stats_global__v0",
38 parameters: z.object({
39 cronTimestamp: z.int().optional(),
40 period: z.enum(["total", "1h", "10m", "1d", "1w", "1m"]).optional(),
41 }),
42 data: z.object({
43 count: z.int(),
44 }),
45 // REMINDER: cache on build time as it's a global stats
46 opts: { cache: "force-cache" },
47 });
48 }
49
50 public get legacy_httpListDaily() {
51 return this.tb.buildPipe({
52 pipe: "endpoint__http_list_1d__v0",
53 parameters: z.object({
54 monitorId: z.string(),
55 }),
56 data: z.object({
57 type: z.literal("http").prefault("http"),
58 latency: z.int(),
59 statusCode: z.int().nullable(),
60 monitorId: z.string(),
61 error: z.coerce.boolean(),
62 region: z.enum(monitorRegions).or(z.string()),
63 cronTimestamp: z.int(),
64 trigger: z.enum(triggers).nullable().prefault("cron"),
65 timestamp: z.number(),
66 workspaceId: z.string(),
67 }),
68 opts: { next: { revalidate: REVALIDATE } },
69 });
70 }
71
72 public get httpListDaily() {
73 return this.tb.buildPipe({
74 pipe: "endpoint__http_list_1d__v1",
75 parameters: z.object({
76 monitorId: z.string(),
77 fromDate: z.int().optional(),
78 toDate: z.int().optional(),
79 }),
80 data: z.object({
81 type: z.literal("http").prefault("http"),
82 id: z.string().nullable(),
83 latency: z.int(),
84 statusCode: z.int().nullable(),
85 monitorId: z.string(),
86 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
87 region: z.enum(monitorRegions).or(z.string()),
88 cronTimestamp: z.int(),
89 trigger: z.enum(triggers).nullable().prefault("cron"),
90 timestamp: z.number(),
91 timing: timingPhasesSchema,
92 }),
93 opts: { next: { revalidate: REVALIDATE } },
94 });
95 }
96
97 public get legacy_httpListWeekly() {
98 return this.tb.buildPipe({
99 pipe: "endpoint__http_list_7d__v0",
100 parameters: z.object({
101 monitorId: z.string(),
102 }),
103 data: z.object({
104 type: z.literal("http").prefault("http"),
105 latency: z.int(),
106 statusCode: z.int().nullable(),
107 monitorId: z.string(),
108 error: z.coerce.boolean(),
109 region: z.enum(monitorRegions).or(z.string()),
110 cronTimestamp: z.int(),
111 trigger: z.enum(triggers).nullable().prefault("cron"),
112 timestamp: z.number(),
113 workspaceId: z.string(),
114 }),
115 opts: { next: { revalidate: REVALIDATE } },
116 });
117 }
118
119 public get httpListWeekly() {
120 return this.tb.buildPipe({
121 pipe: "endpoint__http_list_7d__v1",
122 parameters: z.object({
123 monitorId: z.string(),
124 fromDate: z.int().optional(),
125 toDate: z.int().optional(),
126 }),
127 data: z.object({
128 type: z.literal("http").prefault("http"),
129 id: z.string().nullable(),
130 latency: z.int(),
131 statusCode: z.int().nullable(),
132 monitorId: z.string(),
133 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
134 region: z.enum(monitorRegions).or(z.string()),
135 cronTimestamp: z.int(),
136 trigger: z.enum(triggers).nullable().prefault("cron"),
137 timestamp: z.number(),
138 timing: timingPhasesSchema,
139 }),
140 opts: { next: { revalidate: REVALIDATE } },
141 });
142 }
143
144 public get legacy_httpListBiweekly() {
145 return this.tb.buildPipe({
146 pipe: "endpoint__http_list_14d__v0",
147 parameters: z.object({
148 monitorId: z.string(),
149 }),
150 data: z.object({
151 type: z.literal("http").prefault("http"),
152 latency: z.int(),
153 statusCode: z.int().nullable(),
154 monitorId: z.string(),
155 error: z.coerce.boolean(),
156 region: z.enum(monitorRegions).or(z.string()),
157 cronTimestamp: z.int(),
158 trigger: z.enum(triggers).nullable().prefault("cron"),
159 timestamp: z.number(),
160 workspaceId: z.string(),
161 }),
162 opts: { next: { revalidate: REVALIDATE } },
163 });
164 }
165
166 public get httpListBiweekly() {
167 return this.tb.buildPipe({
168 pipe: "endpoint__http_list_14d__v1",
169 parameters: z.object({
170 monitorId: z.string(),
171 fromDate: z.int().optional(),
172 toDate: z.int().optional(),
173 }),
174 data: z.object({
175 type: z.literal("http").prefault("http"),
176 id: z.string().nullable(),
177 latency: z.int(),
178 statusCode: z.int().nullable(),
179 monitorId: z.string(),
180 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
181 region: z.enum(monitorRegions).or(z.string()),
182 cronTimestamp: z.int(),
183 trigger: z.enum(triggers).nullable().prefault("cron"),
184 timestamp: z.number(),
185 timing: timingPhasesSchema,
186 }),
187 opts: { next: { revalidate: REVALIDATE } },
188 });
189 }
190
191 public get legacy_httpMetricsDaily() {
192 return this.tb.buildPipe({
193 pipe: "endpoint__http_metrics_1d__v0",
194 parameters: z.object({
195 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
196 interval: z.int().optional(),
197 monitorId: z.string(),
198 }),
199 data: z.object({
200 p50Latency: z.number().nullable().prefault(0),
201 p75Latency: z.number().nullable().prefault(0),
202 p90Latency: z.number().nullable().prefault(0),
203 p95Latency: z.number().nullable().prefault(0),
204 p99Latency: z.number().nullable().prefault(0),
205 count: z.int(),
206 ok: z.int(),
207 lastTimestamp: z.int().nullable(),
208 }),
209 opts: { next: { revalidate: REVALIDATE } },
210 });
211 }
212
213 public get httpMetricsDaily() {
214 return this.tb.buildPipe({
215 pipe: "endpoint__http_metrics_1d__v1",
216 parameters: z.object({
217 interval: z.int().optional(),
218 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
219 monitorId: z.string(),
220 }),
221 data: z.object({
222 p50Latency: z.number().nullable().prefault(0),
223 p75Latency: z.number().nullable().prefault(0),
224 p90Latency: z.number().nullable().prefault(0),
225 p95Latency: z.number().nullable().prefault(0),
226 p99Latency: z.number().nullable().prefault(0),
227 count: z.int().prefault(0),
228 success: z.int().prefault(0),
229 degraded: z.int().prefault(0),
230 error: z.int().prefault(0),
231 lastTimestamp: z.int().nullable(),
232 }),
233 opts: { next: { revalidate: REVALIDATE } },
234 });
235 }
236
237 public get legacy_httpMetricsWeekly() {
238 return this.tb.buildPipe({
239 pipe: "endpoint__http_metrics_7d__v0",
240 parameters: z.object({
241 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
242 interval: z.int().optional(),
243 monitorId: z.string(),
244 }),
245 data: z.object({
246 p50Latency: z.number().nullable().prefault(0),
247 p75Latency: z.number().nullable().prefault(0),
248 p90Latency: z.number().nullable().prefault(0),
249 p95Latency: z.number().nullable().prefault(0),
250 p99Latency: z.number().nullable().prefault(0),
251 count: z.int(),
252 ok: z.int(),
253 lastTimestamp: z.int().nullable(),
254 }),
255 opts: { next: { revalidate: REVALIDATE } },
256 });
257 }
258
259 public get httpMetricsWeekly() {
260 return this.tb.buildPipe({
261 pipe: "endpoint__http_metrics_7d__v1",
262 parameters: z.object({
263 interval: z.int().optional(),
264 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
265 monitorId: z.string(),
266 }),
267 data: z.object({
268 p50Latency: z.number().nullable().prefault(0),
269 p75Latency: z.number().nullable().prefault(0),
270 p90Latency: z.number().nullable().prefault(0),
271 p95Latency: z.number().nullable().prefault(0),
272 p99Latency: z.number().nullable().prefault(0),
273 count: z.int().prefault(0),
274 success: z.int().prefault(0),
275 degraded: z.int().prefault(0),
276 error: z.int().prefault(0),
277 lastTimestamp: z.int().nullable(),
278 }),
279 opts: { next: { revalidate: REVALIDATE } },
280 });
281 }
282
283 public get legacy_httpMetricsBiweekly() {
284 return this.tb.buildPipe({
285 pipe: "endpoint__http_metrics_14d__v0",
286 parameters: z.object({
287 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
288 interval: z.int().optional(),
289 monitorId: z.string(),
290 }),
291 data: z.object({
292 p50Latency: z.number().nullable().prefault(0),
293 p75Latency: z.number().nullable().prefault(0),
294 p90Latency: z.number().nullable().prefault(0),
295 p95Latency: z.number().nullable().prefault(0),
296 p99Latency: z.number().nullable().prefault(0),
297 count: z.int(),
298 ok: z.int(),
299 lastTimestamp: z.int().nullable(),
300 }),
301 opts: { next: { revalidate: REVALIDATE } },
302 });
303 }
304
305 public get httpMetricsBiweekly() {
306 return this.tb.buildPipe({
307 pipe: "endpoint__http_metrics_14d__v1",
308 parameters: z.object({
309 interval: z.int().optional(),
310 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
311 monitorId: z.string(),
312 }),
313 data: z.object({
314 p50Latency: z.number().nullable().prefault(0),
315 p75Latency: z.number().nullable().prefault(0),
316 p90Latency: z.number().nullable().prefault(0),
317 p95Latency: z.number().nullable().prefault(0),
318 p99Latency: z.number().nullable().prefault(0),
319 count: z.int().prefault(0),
320 success: z.int().prefault(0),
321 degraded: z.int().prefault(0),
322 error: z.int().prefault(0),
323 lastTimestamp: z.int().nullable(),
324 }),
325 opts: { next: { revalidate: REVALIDATE } },
326 });
327 }
328
329 public get httpMetricsByIntervalDaily() {
330 return this.tb.buildPipe({
331 pipe: "endpoint__http_metrics_by_interval_1d__v0",
332 parameters: z.object({
333 interval: z.int().optional(),
334 monitorId: z.string(),
335 }),
336 data: z.object({
337 region: z.enum(monitorRegions).or(z.string()),
338 timestamp: z.int(),
339 p50Latency: z.number().nullable().prefault(0),
340 p75Latency: z.number().nullable().prefault(0),
341 p90Latency: z.number().nullable().prefault(0),
342 p95Latency: z.number().nullable().prefault(0),
343 p99Latency: z.number().nullable().prefault(0),
344 }),
345 opts: { next: { revalidate: REVALIDATE } },
346 });
347 }
348
349 public get httpMetricsByIntervalWeekly() {
350 return this.tb.buildPipe({
351 pipe: "endpoint__http_metrics_by_interval_7d__v0",
352 parameters: z.object({
353 interval: z.int().optional(),
354 monitorId: z.string(),
355 }),
356 data: z.object({
357 region: z.enum(monitorRegions).or(z.string()),
358 timestamp: z.int(),
359 p50Latency: z.number().nullable().prefault(0),
360 p75Latency: z.number().nullable().prefault(0),
361 p90Latency: z.number().nullable().prefault(0),
362 p95Latency: z.number().nullable().prefault(0),
363 p99Latency: z.number().nullable().prefault(0),
364 }),
365 opts: { next: { revalidate: REVALIDATE } },
366 });
367 }
368
369 public get httpMetricsByIntervalBiweekly() {
370 return this.tb.buildPipe({
371 pipe: "endpoint__http_metrics_by_interval_14d__v0",
372 parameters: z.object({
373 interval: z.int().optional(),
374 monitorId: z.string(),
375 }),
376 data: z.object({
377 region: z.enum(monitorRegions).or(z.string()),
378 timestamp: z.int(),
379 p50Latency: z.number().nullable().prefault(0),
380 p75Latency: z.number().nullable().prefault(0),
381 p90Latency: z.number().nullable().prefault(0),
382 p95Latency: z.number().nullable().prefault(0),
383 p99Latency: z.number().nullable().prefault(0),
384 }),
385 opts: { next: { revalidate: REVALIDATE } },
386 });
387 }
388
389 public get httpMetricsByRegionDaily() {
390 return this.tb.buildPipe({
391 pipe: "endpoint__http_metrics_by_region_1d__v0",
392 parameters: z.object({
393 monitorId: z.string(),
394 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
395 }),
396 data: z.object({
397 region: z.enum(monitorRegions).or(z.string()),
398 count: z.int(),
399 ok: z.int(),
400 p50Latency: z.number().nullable().prefault(0),
401 p75Latency: z.number().nullable().prefault(0),
402 p90Latency: z.number().nullable().prefault(0),
403 p95Latency: z.number().nullable().prefault(0),
404 p99Latency: z.number().nullable().prefault(0),
405 }),
406 opts: { next: { revalidate: REVALIDATE } },
407 });
408 }
409
410 public get httpMetricsByRegionWeekly() {
411 return this.tb.buildPipe({
412 pipe: "endpoint__http_metrics_by_region_7d__v0",
413 parameters: z.object({
414 monitorId: z.string(),
415 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
416 }),
417 data: z.object({
418 region: z.enum(monitorRegions).or(z.string()),
419 count: z.int(),
420 ok: z.int(),
421 p50Latency: z.number().nullable().prefault(0),
422 p75Latency: z.number().nullable().prefault(0),
423 p90Latency: z.number().nullable().prefault(0),
424 p95Latency: z.number().nullable().prefault(0),
425 p99Latency: z.number().nullable().prefault(0),
426 }),
427 opts: { next: { revalidate: REVALIDATE } },
428 });
429 }
430
431 public get httpMetricsByRegionBiweekly() {
432 return this.tb.buildPipe({
433 pipe: "endpoint__http_metrics_by_region_14d__v0",
434 parameters: z.object({
435 monitorId: z.string(),
436 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
437 }),
438 data: z.object({
439 region: z.enum(monitorRegions).or(z.string()),
440 count: z.int(),
441 ok: z.int(),
442 p50Latency: z.number().nullable().prefault(0),
443 p75Latency: z.number().nullable().prefault(0),
444 p90Latency: z.number().nullable().prefault(0),
445 p95Latency: z.number().nullable().prefault(0),
446 p99Latency: z.number().nullable().prefault(0),
447 }),
448 opts: { next: { revalidate: REVALIDATE } },
449 });
450 }
451
452 public get httpStatusWeekly() {
453 return this.tb.buildPipe({
454 pipe: "endpoint__http_status_7d__v0",
455 parameters: z.object({
456 monitorId: z.string(),
457 }),
458 data: z.object({
459 day: z.string().transform((val) => {
460 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
461 return new Date(`${val} GMT`).toISOString();
462 }),
463 count: z.number().prefault(0),
464 ok: z.number().prefault(0),
465 }),
466 opts: { next: { revalidate: REVALIDATE } },
467 });
468 }
469
470 public get legacy_httpStatus45d() {
471 return this.tb.buildPipe({
472 pipe: "endpoint__http_status_45d__v0",
473 parameters: z.object({
474 monitorId: z.string(),
475 days: z.int().max(45).optional(),
476 }),
477 data: z.object({
478 day: z.string().transform((val) => {
479 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
480 return new Date(`${val} GMT`).toISOString();
481 }),
482 count: z.number().prefault(0),
483 ok: z.number().prefault(0),
484 }),
485 opts: {
486 next: {
487 revalidate: PUBLIC_CACHE,
488 },
489 },
490 });
491 }
492
493 public get httpStatus45d() {
494 return this.tb.buildPipe({
495 pipe: "endpoint__http_status_45d__v1",
496 parameters: z.object({
497 monitorIds: z.string().array(),
498 }),
499 data: z.object({
500 day: z.string().transform((val) => {
501 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
502 return new Date(`${val} GMT`).toISOString();
503 }),
504 count: z.number().prefault(0),
505 ok: z.number().prefault(0),
506 degraded: z.number().prefault(0),
507 error: z.number().prefault(0),
508 monitorId: z.string(),
509 }),
510 opts: { next: { revalidate: REVALIDATE } },
511 });
512 }
513
514 public get httpGetBiweekly() {
515 return this.tb.buildPipe({
516 pipe: "endpoint__http_get_14d__v0",
517 parameters: z.object({
518 id: z.string().nullable(),
519 monitorId: z.string(),
520 }),
521 data: z.object({
522 type: z.literal("http").prefault("http"),
523 latency: z.int(),
524 statusCode: z.int().nullable(),
525 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
526 monitorId: z.string(),
527 url: z.url(),
528 error: z.coerce.boolean(),
529 region: z.enum(monitorRegions).or(z.string()),
530 cronTimestamp: z.int(),
531 message: z.string().nullable(),
532 headers: headersSchema,
533 timing: timingPhasesSchema,
534 assertions: z.string().nullable(),
535 body: z.string().nullable(),
536 trigger: z.enum(triggers).nullable().prefault("cron"),
537 timestamp: z.number(),
538 workspaceId: z.string(),
539 id: z.string().nullable(),
540 }),
541 // REMINDER: cache the result for accessing the data for a check as it won't change
542 opts: { cache: "force-cache" },
543 });
544 }
545
546 public get httpGetMonthly() {
547 return this.tb.buildPipe({
548 pipe: "endpoint__http_get_30d__v0",
549 parameters: z.object({
550 monitorId: z.string(),
551 region: z.enum(monitorRegions).or(z.string()).optional(),
552 cronTimestamp: z.int().optional(),
553 }),
554 data: z.object({
555 type: z.literal("http").prefault("http"),
556 latency: z.int(),
557 statusCode: z.int().nullable(),
558 monitorId: z.string(),
559 url: z.url(),
560 error: z.coerce.boolean(),
561 region: z.enum(monitorRegions).or(z.string()),
562 cronTimestamp: z.int(),
563 message: z.string().nullable(),
564 headers: headersSchema,
565 timing: timingSchema,
566 assertions: z.string().nullable(),
567 trigger: z.enum(triggers).nullable().prefault("cron"),
568 timestamp: z.number(),
569 workspaceId: z.string(),
570 }),
571 // REMINDER: cache the result for accessing the data for a check as it won't change
572 opts: { cache: "force-cache" },
573 });
574 }
575
576 // FIXME: rename to same convension
577 public get getResultForOnDemandCheckHttp() {
578 return this.tb.buildPipe({
579 pipe: "get_result_for_on_demand_check_http",
580 parameters: z.object({
581 monitorId: z.int(),
582 timestamp: z.number(),
583 url: z.string(),
584 }),
585 data: z.object({
586 latency: z.int(), // in ms
587 statusCode: z.int().nullable().prefault(null),
588 monitorId: z.string().prefault(""),
589 url: z.url().optional(),
590 error: z
591 .number()
592 .prefault(0)
593 .transform((val) => val !== 0),
594 region: z.enum(monitorRegions),
595 timestamp: z.int().optional(),
596 message: z.string().nullable().optional(),
597 timing: timingSchema,
598 // TODO: make sure to include all data!
599 }),
600 opts: { cache: "no-store" },
601 });
602 }
603 // TODO: add tcpChartDaily, tcpChartWeekly
604
605 public get legacy_tcpListDaily() {
606 return this.tb.buildPipe({
607 pipe: "endpoint__tcp_list_1d__v0",
608 parameters: z.object({
609 monitorId: z.string(),
610 }),
611 data: z.object({
612 type: z.literal("tcp").prefault("tcp"),
613 latency: z.int(),
614 monitorId: z.coerce.string(),
615 error: z.coerce.boolean(),
616 region: z.enum(monitorRegions).or(z.string()),
617 cronTimestamp: z.int(),
618 trigger: z.enum(triggers).nullable().prefault("cron"),
619 timestamp: z.number(),
620 workspaceId: z.coerce.string(),
621 }),
622 opts: { next: { revalidate: REVALIDATE } },
623 });
624 }
625
626 public get tcpListDaily() {
627 return this.tb.buildPipe({
628 pipe: "endpoint__tcp_list_1d__v1",
629 parameters: z.object({
630 monitorId: z.string(),
631 fromDate: z.int().optional(),
632 toDate: z.int().optional(),
633 }),
634 data: z.object({
635 type: z.literal("tcp").prefault("tcp"),
636 id: z.string().nullable(),
637 latency: z.int(),
638 monitorId: z.coerce.string(),
639 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
640 region: z.enum(monitorRegions).or(z.string()),
641 cronTimestamp: z.int(),
642 trigger: z.enum(triggers).nullable().prefault("cron"),
643 timestamp: z.number(),
644 }),
645 opts: { next: { revalidate: REVALIDATE } },
646 });
647 }
648
649 public get legacy_tcpListWeekly() {
650 return this.tb.buildPipe({
651 pipe: "endpoint__tcp_list_7d__v0",
652 parameters: z.object({
653 monitorId: z.string(),
654 }),
655 data: z.object({
656 type: z.literal("tcp").prefault("tcp"),
657 latency: z.int(),
658 monitorId: z.coerce.string(),
659 error: z.coerce.boolean(),
660 region: z.enum(monitorRegions).or(z.string()),
661 cronTimestamp: z.int(),
662 trigger: z.enum(triggers).nullable().prefault("cron"),
663 timestamp: z.number(),
664 workspaceId: z.coerce.string(),
665 }),
666 opts: { next: { revalidate: REVALIDATE } },
667 });
668 }
669
670 public get tcpListWeekly() {
671 return this.tb.buildPipe({
672 pipe: "endpoint__tcp_list_7d__v1",
673 parameters: z.object({
674 monitorId: z.string(),
675 fromDate: z.int().optional(),
676 toDate: z.int().optional(),
677 }),
678 data: z.object({
679 type: z.literal("tcp").prefault("tcp"),
680 id: z.string().nullable(),
681 latency: z.int(),
682 monitorId: z.coerce.string(),
683 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
684 region: z.enum(monitorRegions).or(z.string()),
685 cronTimestamp: z.int(),
686 trigger: z.enum(triggers).nullable().prefault("cron"),
687 timestamp: z.number(),
688 }),
689 opts: { next: { revalidate: REVALIDATE } },
690 });
691 }
692
693 public get legacy_tcpListBiweekly() {
694 return this.tb.buildPipe({
695 pipe: "endpoint__tcp_list_14d__v0",
696 parameters: z.object({
697 monitorId: z.string(),
698 }),
699 data: z.object({
700 type: z.literal("tcp").prefault("tcp"),
701 latency: z.int(),
702 monitorId: z.coerce.string(),
703 error: z.coerce.boolean(),
704 region: z.enum(monitorRegions).or(z.string()),
705 cronTimestamp: z.int(),
706 trigger: z.enum(triggers).nullable().prefault("cron"),
707 timestamp: z.number(),
708 workspaceId: z.coerce.string(),
709 }),
710 opts: { next: { revalidate: REVALIDATE } },
711 });
712 }
713
714 public get tcpListBiweekly() {
715 return this.tb.buildPipe({
716 pipe: "endpoint__tcp_list_14d__v1",
717 parameters: z.object({
718 monitorId: z.string(),
719 fromDate: z.int().optional(),
720 toDate: z.int().optional(),
721 }),
722 data: z.object({
723 type: z.literal("tcp").prefault("tcp"),
724 id: z.string().nullable(),
725 latency: z.int(),
726 monitorId: z.coerce.string(),
727 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
728 region: z.enum(monitorRegions).or(z.string()),
729 cronTimestamp: z.int(),
730 trigger: z.enum(triggers).nullable().prefault("cron"),
731 timestamp: z.number(),
732 }),
733 opts: { next: { revalidate: REVALIDATE } },
734 });
735 }
736
737 public get legacy_tcpMetricsDaily() {
738 return this.tb.buildPipe({
739 pipe: "endpoint__tcp_metrics_1d__v0",
740 parameters: z.object({
741 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
742 interval: z.int().optional(),
743 monitorId: z.string(),
744 }),
745 data: z.object({
746 p50Latency: z.number().nullable().prefault(0),
747 p75Latency: z.number().nullable().prefault(0),
748 p90Latency: z.number().nullable().prefault(0),
749 p95Latency: z.number().nullable().prefault(0),
750 p99Latency: z.number().nullable().prefault(0),
751 count: z.int(),
752 ok: z.int(),
753 lastTimestamp: z.int().nullable(),
754 }),
755 opts: { next: { revalidate: REVALIDATE } },
756 });
757 }
758
759 public get tcpMetricsDaily() {
760 return this.tb.buildPipe({
761 pipe: "endpoint__tcp_metrics_1d__v1",
762 parameters: z.object({
763 interval: z.int().optional(),
764 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
765 monitorId: z.string(),
766 }),
767 data: z.object({
768 p50Latency: z.number().nullable().prefault(0),
769 p75Latency: z.number().nullable().prefault(0),
770 p90Latency: z.number().nullable().prefault(0),
771 p95Latency: z.number().nullable().prefault(0),
772 p99Latency: z.number().nullable().prefault(0),
773 count: z.int().prefault(0),
774 success: z.int().prefault(0),
775 degraded: z.int().prefault(0),
776 error: z.int().prefault(0),
777 lastTimestamp: z.int().nullable(),
778 }),
779 opts: { next: { revalidate: REVALIDATE } },
780 });
781 }
782
783 public get legacy_tcpMetricsWeekly() {
784 return this.tb.buildPipe({
785 pipe: "endpoint__tcp_metrics_7d__v0",
786 parameters: z.object({
787 interval: z.int().optional(),
788 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
789 monitorId: z.string(),
790 }),
791 data: z.object({
792 p50Latency: z.number().nullable().prefault(0),
793 p75Latency: z.number().nullable().prefault(0),
794 p90Latency: z.number().nullable().prefault(0),
795 p95Latency: z.number().nullable().prefault(0),
796 p99Latency: z.number().nullable().prefault(0),
797 count: z.int(),
798 ok: z.int(),
799 lastTimestamp: z.int().nullable(),
800 }),
801 opts: { next: { revalidate: REVALIDATE } },
802 });
803 }
804
805 public get tcpMetricsWeekly() {
806 return this.tb.buildPipe({
807 pipe: "endpoint__tcp_metrics_7d__v1",
808 parameters: z.object({
809 interval: z.int().optional(),
810 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
811 monitorId: z.string(),
812 }),
813 data: z.object({
814 p50Latency: z.number().nullable().prefault(0),
815 p75Latency: z.number().nullable().prefault(0),
816 p90Latency: z.number().nullable().prefault(0),
817 p95Latency: z.number().nullable().prefault(0),
818 p99Latency: z.number().nullable().prefault(0),
819 count: z.int().prefault(0),
820 success: z.int().prefault(0),
821 degraded: z.int().prefault(0),
822 error: z.int().prefault(0),
823 lastTimestamp: z.int().nullable(),
824 }),
825 opts: { next: { revalidate: REVALIDATE } },
826 });
827 }
828
829 public get legacy_tcpMetricsBiweekly() {
830 return this.tb.buildPipe({
831 pipe: "endpoint__tcp_metrics_14d__v0",
832 parameters: z.object({
833 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
834 interval: z.int().optional(),
835 monitorId: z.string(),
836 }),
837 data: z.object({
838 p50Latency: z.number().nullable().prefault(0),
839 p75Latency: z.number().nullable().prefault(0),
840 p90Latency: z.number().nullable().prefault(0),
841 p95Latency: z.number().nullable().prefault(0),
842 p99Latency: z.number().nullable().prefault(0),
843 count: z.int(),
844 ok: z.int(),
845 lastTimestamp: z.int().nullable(),
846 }),
847 opts: { next: { revalidate: REVALIDATE } },
848 });
849 }
850
851 public get tcpMetricsBiweekly() {
852 return this.tb.buildPipe({
853 pipe: "endpoint__tcp_metrics_14d__v1",
854 parameters: z.object({
855 interval: z.int().optional(),
856 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
857 monitorId: z.string(),
858 }),
859 data: z.object({
860 p50Latency: z.number().nullable().prefault(0),
861 p75Latency: z.number().nullable().prefault(0),
862 p90Latency: z.number().nullable().prefault(0),
863 p95Latency: z.number().nullable().prefault(0),
864 p99Latency: z.number().nullable().prefault(0),
865 count: z.int().prefault(0),
866 success: z.int().prefault(0),
867 degraded: z.int().prefault(0),
868 error: z.int().prefault(0),
869 lastTimestamp: z.int().nullable(),
870 }),
871 opts: { next: { revalidate: REVALIDATE } },
872 });
873 }
874
875 public get tcpMetricsByIntervalDaily() {
876 return this.tb.buildPipe({
877 pipe: "endpoint__tcp_metrics_by_interval_1d__v0",
878 parameters: z.object({
879 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
880 interval: z.int().optional(),
881 monitorId: z.string(),
882 }),
883 data: z.object({
884 region: z.enum(monitorRegions).or(z.string()),
885 timestamp: z.int(),
886 p50Latency: z.number().nullable().prefault(0),
887 p75Latency: z.number().nullable().prefault(0),
888 p90Latency: z.number().nullable().prefault(0),
889 p95Latency: z.number().nullable().prefault(0),
890 p99Latency: z.number().nullable().prefault(0),
891 }),
892 opts: { next: { revalidate: REVALIDATE } },
893 });
894 }
895
896 public get tcpMetricsByIntervalWeekly() {
897 return this.tb.buildPipe({
898 pipe: "endpoint__tcp_metrics_by_interval_7d__v0",
899 parameters: z.object({
900 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
901 interval: z.int().optional(),
902 monitorId: z.string(),
903 }),
904 data: z.object({
905 region: z.enum(monitorRegions).or(z.string()),
906 timestamp: z.int(),
907 p50Latency: z.number().nullable().prefault(0),
908 p75Latency: z.number().nullable().prefault(0),
909 p90Latency: z.number().nullable().prefault(0),
910 p95Latency: z.number().nullable().prefault(0),
911 p99Latency: z.number().nullable().prefault(0),
912 }),
913 opts: { next: { revalidate: REVALIDATE } },
914 });
915 }
916
917 public get tcpMetricsByIntervalBiweekly() {
918 return this.tb.buildPipe({
919 pipe: "endpoint__tcp_metrics_by_interval_14d__v0",
920 parameters: z.object({
921 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
922 interval: z.int().optional(),
923 monitorId: z.string(),
924 }),
925 data: z.object({
926 region: z.enum(monitorRegions).or(z.string()),
927 timestamp: z.int(),
928 p50Latency: z.number().nullable().prefault(0),
929 p75Latency: z.number().nullable().prefault(0),
930 p90Latency: z.number().nullable().prefault(0),
931 p95Latency: z.number().nullable().prefault(0),
932 p99Latency: z.number().nullable().prefault(0),
933 }),
934 opts: { next: { revalidate: REVALIDATE } },
935 });
936 }
937
938 public get tcpMetricsByRegionDaily() {
939 return this.tb.buildPipe({
940 pipe: "endpoint__tcp_metrics_by_region_1d__v0",
941 parameters: z.object({
942 monitorId: z.string(),
943 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
944 }),
945 data: z.object({
946 region: z.enum(monitorRegions).or(z.string()),
947 count: z.int(),
948 ok: z.int(),
949 p50Latency: z.number().nullable().prefault(0),
950 p75Latency: z.number().nullable().prefault(0),
951 p90Latency: z.number().nullable().prefault(0),
952 p95Latency: z.number().nullable().prefault(0),
953 p99Latency: z.number().nullable().prefault(0),
954 }),
955 opts: { next: { revalidate: REVALIDATE } },
956 });
957 }
958
959 public get tcpMetricsByRegionWeekly() {
960 return this.tb.buildPipe({
961 pipe: "endpoint__tcp_metrics_by_region_7d__v0",
962 parameters: z.object({
963 monitorId: z.string(),
964 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
965 }),
966 data: z.object({
967 region: z.enum(monitorRegions).or(z.string()),
968 count: z.int(),
969 ok: z.int(),
970 p50Latency: z.number().nullable().prefault(0),
971 p75Latency: z.number().nullable().prefault(0),
972 p90Latency: z.number().nullable().prefault(0),
973 p95Latency: z.number().nullable().prefault(0),
974 p99Latency: z.number().nullable().prefault(0),
975 }),
976 opts: { next: { revalidate: REVALIDATE } },
977 });
978 }
979
980 public get tcpMetricsByRegionBiweekly() {
981 return this.tb.buildPipe({
982 pipe: "endpoint__tcp_metrics_by_region_14d__v0",
983 parameters: z.object({
984 monitorId: z.string(),
985 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
986 }),
987 data: z.object({
988 region: z.enum(monitorRegions).or(z.string()),
989 count: z.int(),
990 ok: z.int(),
991 p50Latency: z.number().nullable().prefault(0),
992 p75Latency: z.number().nullable().prefault(0),
993 p90Latency: z.number().nullable().prefault(0),
994 p95Latency: z.number().nullable().prefault(0),
995 p99Latency: z.number().nullable().prefault(0),
996 }),
997 opts: { next: { revalidate: REVALIDATE } },
998 });
999 }
1000
1001 public get tcpStatusWeekly() {
1002 return this.tb.buildPipe({
1003 pipe: "endpoint__tcp_status_7d__v0",
1004 parameters: z.object({
1005 monitorId: z.string(),
1006 }),
1007 data: z.object({
1008 day: z.string().transform((val) => {
1009 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
1010 return new Date(`${val} GMT`).toISOString();
1011 }),
1012 count: z.number().prefault(0),
1013 ok: z.number().prefault(0),
1014 }),
1015 opts: { next: { revalidate: REVALIDATE } },
1016 });
1017 }
1018
1019 public get legacy_tcpStatus45d() {
1020 return this.tb.buildPipe({
1021 pipe: "endpoint__tcp_status_45d__v0",
1022 parameters: z.object({
1023 monitorId: z.string(),
1024 days: z.int().max(45).optional(),
1025 }),
1026 data: z.object({
1027 day: z.string().transform((val) => {
1028 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
1029 return new Date(`${val} GMT`).toISOString();
1030 }),
1031 count: z.number().prefault(0),
1032 ok: z.number().prefault(0),
1033 }),
1034 opts: {
1035 next: {
1036 revalidate: PUBLIC_CACHE,
1037 },
1038 },
1039 });
1040 }
1041
1042 public get tcpStatus45d() {
1043 return this.tb.buildPipe({
1044 pipe: "endpoint__tcp_status_45d__v1",
1045 parameters: z.object({
1046 monitorIds: z.string().array(),
1047 days: z.int().max(45).optional(),
1048 }),
1049 data: z.object({
1050 day: z.string().transform((val) => {
1051 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
1052 return new Date(`${val} GMT`).toISOString();
1053 }),
1054 count: z.number().prefault(0),
1055 ok: z.number().prefault(0),
1056 degraded: z.number().prefault(0),
1057 error: z.number().prefault(0),
1058 monitorId: z.coerce.string(),
1059 }),
1060 opts: { next: { revalidate: REVALIDATE } },
1061 });
1062 }
1063
1064 public get httpWorkspace30d() {
1065 return this.tb.buildPipe({
1066 pipe: "endpoint__http_workspace_30d__v0",
1067 parameters: z.object({
1068 workspaceId: z.string(),
1069 }),
1070 data: z.object({
1071 day: z
1072 .string()
1073 .transform((val) => new Date(`${val} GMT`).toISOString()),
1074 count: z.int(),
1075 }),
1076 opts: { next: { revalidate: REVALIDATE } },
1077 });
1078 }
1079
1080 public get tcpWorkspace30d() {
1081 return this.tb.buildPipe({
1082 pipe: "endpoint__tcp_workspace_30d__v0",
1083 parameters: z.object({
1084 workspaceId: z.string(),
1085 }),
1086 data: z.object({
1087 day: z
1088 .string()
1089 .transform((val) => new Date(`${val} GMT`).toISOString()),
1090 count: z.int(),
1091 }),
1092 opts: { next: { revalidate: REVALIDATE } },
1093 });
1094 }
1095
1096 public get tcpGetBiweekly() {
1097 return this.tb.buildPipe({
1098 pipe: "endpoint__tcp_get_14d__v0",
1099 parameters: z.object({
1100 id: z.string().nullable(),
1101 monitorId: z.string(),
1102 }),
1103 data: z.object({
1104 type: z.literal("tcp").prefault("tcp"),
1105 id: z.string().nullable(),
1106 uri: z.string(),
1107 latency: z.int(),
1108 monitorId: z.coerce.string(),
1109 error: z.coerce.boolean(),
1110 region: z.enum(monitorRegions).or(z.string()),
1111 cronTimestamp: z.int(),
1112 trigger: z.enum(triggers).nullable().prefault("cron"),
1113 timestamp: z.number(),
1114 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
1115 errorMessage: z.string().nullable(),
1116 }),
1117 // REMINDER: cache the result for accessing the data for a check as it won't change
1118 opts: { next: { revalidate: REVALIDATE } },
1119 });
1120 }
1121
1122 public get tcpGetMonthly() {
1123 return this.tb.buildPipe({
1124 pipe: "endpoint__tcp_get_30d__v0",
1125 parameters: z.object({
1126 monitorId: z.string(),
1127 region: z.enum(monitorRegions).or(z.string()).optional(),
1128 cronTimestamp: z.int().optional(),
1129 }),
1130 data: z.object({
1131 type: z.literal("tcp").prefault("tcp"),
1132 latency: z.int(),
1133 monitorId: z.string(),
1134 error: z.coerce.boolean(),
1135 region: z.enum(monitorRegions).or(z.string()),
1136 cronTimestamp: z.int(),
1137 trigger: z.enum(triggers).nullable().prefault("cron"),
1138 timestamp: z.number(),
1139 workspaceId: z.string(),
1140 }),
1141 // REMINDER: cache the result for accessing the data for a check as it won't change
1142 opts: { next: { revalidate: REVALIDATE } },
1143 });
1144 }
1145
1146 /**
1147 * Region + timestamp metrics (quantiles) – aggregated by interval.
1148 * NOTE: The Tinybird pipe returns one row per region & interval with latency quantiles.
1149 */
1150 public get httpMetricsRegionsDaily() {
1151 return this.tb.buildPipe({
1152 pipe: "endpoint__http_metrics_regions_1d__v0",
1153 parameters: z.object({
1154 monitorId: z.string(),
1155 interval: z.int().optional(),
1156 // Comma-separated list of regions, e.g. "ams,fra". Keeping string to pass directly.
1157 regions: z.string().array().optional(),
1158 }),
1159 data: z.object({
1160 region: z.enum(monitorRegions).or(z.string()),
1161 timestamp: z.int(),
1162 p50Latency: z.number().nullable().prefault(0),
1163 p75Latency: z.number().nullable().prefault(0),
1164 p90Latency: z.number().nullable().prefault(0),
1165 p95Latency: z.number().nullable().prefault(0),
1166 p99Latency: z.number().nullable().prefault(0),
1167 }),
1168 opts: { next: { revalidate: REVALIDATE } },
1169 });
1170 }
1171
1172 public get httpMetricsRegionsWeekly() {
1173 return this.tb.buildPipe({
1174 pipe: "endpoint__http_metrics_regions_7d__v0",
1175 parameters: z.object({
1176 monitorId: z.string(),
1177 interval: z.int().optional(),
1178 regions: z.string().array().optional(),
1179 }),
1180 data: z.object({
1181 region: z.enum(monitorRegions).or(z.string()),
1182 timestamp: z.int(),
1183 p50Latency: z.number().nullable().prefault(0),
1184 p75Latency: z.number().nullable().prefault(0),
1185 p90Latency: z.number().nullable().prefault(0),
1186 p95Latency: z.number().nullable().prefault(0),
1187 p99Latency: z.number().nullable().prefault(0),
1188 }),
1189 opts: { next: { revalidate: REVALIDATE } },
1190 });
1191 }
1192
1193 public get httpMetricsRegionsBiweekly() {
1194 return this.tb.buildPipe({
1195 pipe: "endpoint__http_metrics_regions_14d__v0",
1196 parameters: z.object({
1197 monitorId: z.string(),
1198 interval: z.int().optional(),
1199 regions: z.string().array().optional(),
1200 }),
1201 data: z.object({
1202 region: z.enum(monitorRegions).or(z.string()),
1203 timestamp: z.int(),
1204 p50Latency: z.number().nullable().prefault(0),
1205 p75Latency: z.number().nullable().prefault(0),
1206 p90Latency: z.number().nullable().prefault(0),
1207 p95Latency: z.number().nullable().prefault(0),
1208 p99Latency: z.number().nullable().prefault(0),
1209 }),
1210 opts: { next: { revalidate: REVALIDATE } },
1211 });
1212 }
1213
1214 public get httpUptimeWeekly() {
1215 return this.tb.buildPipe({
1216 pipe: "endpoint__http_uptime_7d__v1",
1217 parameters: z.object({
1218 monitorId: z.string(),
1219 fromDate: z.string().optional(),
1220 toDate: z.string().optional(),
1221 regions: z.enum(monitorRegions).or(z.string()).array().optional(),
1222 interval: z.int().optional(),
1223 }),
1224 data: z.object({
1225 interval: z.coerce.date(),
1226 success: z.int(),
1227 degraded: z.int(),
1228 error: z.int(),
1229 }),
1230 });
1231 }
1232
1233 public get httpUptime30d() {
1234 return this.tb.buildPipe({
1235 pipe: "endpoint__http_uptime_30d__v1",
1236 parameters: z.object({
1237 monitorId: z.string(),
1238 fromDate: z.string().optional(),
1239 toDate: z.string().optional(),
1240 regions: z.enum(monitorRegions).or(z.string()).array().optional(),
1241 interval: z.int().optional(),
1242 }),
1243 data: z.object({
1244 interval: z.coerce.date(),
1245 success: z.int(),
1246 degraded: z.int(),
1247 error: z.int(),
1248 }),
1249 });
1250 }
1251
1252 public get tcpUptimeWeekly() {
1253 return this.tb.buildPipe({
1254 pipe: "endpoint__tcp_uptime_7d__v1",
1255 parameters: z.object({
1256 monitorId: z.string(),
1257 fromDate: z.string().optional(),
1258 toDate: z.string().optional(),
1259 regions: z.enum(monitorRegions).or(z.string()).array().optional(),
1260 interval: z.int().optional(),
1261 }),
1262 data: z.object({
1263 interval: z.coerce.date(),
1264 success: z.int(),
1265 degraded: z.int(),
1266 error: z.int(),
1267 }),
1268 });
1269 }
1270
1271 public get tcpUptime30d() {
1272 return this.tb.buildPipe({
1273 pipe: "endpoint__tcp_uptime_30d__v1",
1274 parameters: z.object({
1275 monitorId: z.string(),
1276 fromDate: z.string().optional(),
1277 toDate: z.string().optional(),
1278 regions: z.enum(monitorRegions).or(z.string()).array().optional(),
1279 interval: z.int().optional(),
1280 }),
1281 data: z.object({
1282 interval: z.coerce.date(),
1283 success: z.int(),
1284 degraded: z.int(),
1285 error: z.int(),
1286 }),
1287 });
1288 }
1289
1290 public get getAuditLog() {
1291 return this.tb.buildPipe({
1292 pipe: "endpoint__audit_log__v1",
1293 parameters: z.object({
1294 monitorId: z.string(),
1295 interval: z.int().prefault(30), // in days
1296 }),
1297 data: z.object({
1298 action: z.string(),
1299 id: z.string(),
1300 metadata: z.string().transform((str) => {
1301 try {
1302 return JSON.parse(str) as Record<string, unknown>;
1303 } catch (error) {
1304 console.error(error);
1305 return {};
1306 }
1307 }),
1308 timestamp: z.int(),
1309 }),
1310 opts: { next: { revalidate: REVALIDATE } },
1311 });
1312 }
1313
1314 public get httpGlobalMetricsDaily() {
1315 return this.tb.buildPipe({
1316 pipe: "endpoint__http_metrics_global_1d__v0",
1317 parameters: z.object({
1318 monitorIds: z.string().array(),
1319 }),
1320 data: z.object({
1321 minLatency: z.int(),
1322 maxLatency: z.int(),
1323 p50Latency: z.int(),
1324 p75Latency: z.int(),
1325 p90Latency: z.int(),
1326 p95Latency: z.int(),
1327 p99Latency: z.int(),
1328 lastTimestamp: z.int(),
1329 count: z.int(),
1330 monitorId: z.string(),
1331 }),
1332 opts: { next: { revalidate: REVALIDATE } },
1333 });
1334 }
1335
1336 public get tcpGlobalMetricsDaily() {
1337 return this.tb.buildPipe({
1338 pipe: "endpoint__tcp_metrics_global_1d__v0",
1339 parameters: z.object({
1340 monitorIds: z.string().array(),
1341 }),
1342 data: z.object({
1343 minLatency: z.int(),
1344 maxLatency: z.int(),
1345 p50Latency: z.int(),
1346 p75Latency: z.int(),
1347 p90Latency: z.int(),
1348 p95Latency: z.int(),
1349 p99Latency: z.int(),
1350 lastTimestamp: z.int(),
1351 count: z.int(),
1352 monitorId: z.coerce.string(),
1353 }),
1354 opts: { next: { revalidate: REVALIDATE } },
1355 });
1356 }
1357
1358 public get httpTimingPhases14d() {
1359 return this.tb.buildPipe({
1360 pipe: "endpoint__http_timing_phases_14d__v1",
1361 parameters: z.object({
1362 monitorId: z.string(),
1363 interval: z.int().optional(),
1364 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
1365 }),
1366 data: z.object({
1367 timestamp: z.int(),
1368 p50Dns: z.int(),
1369 p50Ttfb: z.int(),
1370 p50Transfer: z.int(),
1371 p50Connect: z.int(),
1372 p50Tls: z.int(),
1373 p75Dns: z.int(),
1374 p75Ttfb: z.int(),
1375 p75Transfer: z.int(),
1376 p75Connect: z.int(),
1377 p75Tls: z.int(),
1378 p90Dns: z.int(),
1379 p90Ttfb: z.int(),
1380 p90Transfer: z.int(),
1381 p90Connect: z.int(),
1382 p90Tls: z.int(),
1383 p95Dns: z.int(),
1384 p95Ttfb: z.int(),
1385 p95Transfer: z.int(),
1386 p95Connect: z.int(),
1387 p95Tls: z.int(),
1388 p99Dns: z.int(),
1389 p99Ttfb: z.int(),
1390 p99Transfer: z.int(),
1391 p99Connect: z.int(),
1392 p99Tls: z.int(),
1393 }),
1394 });
1395 }
1396
1397 public get httpMetricsLatency1d() {
1398 return this.tb.buildPipe({
1399 pipe: "endpoint__http_metrics_latency_1d__v1",
1400 parameters: z.object({
1401 monitorId: z.string(),
1402 fromDate: z.string().optional(),
1403 toDate: z.string().optional(),
1404 }),
1405 data: z.object({
1406 timestamp: z.int(),
1407 p50Latency: z.int(),
1408 p75Latency: z.int(),
1409 p90Latency: z.int(),
1410 p95Latency: z.int(),
1411 p99Latency: z.int(),
1412 }),
1413 });
1414 }
1415
1416 public get httpMetricsLatency7d() {
1417 return this.tb.buildPipe({
1418 pipe: "endpoint__http_metrics_latency_7d__v1",
1419 parameters: z.object({
1420 monitorId: z.string(),
1421 fromDate: z.string().optional(),
1422 toDate: z.string().optional(),
1423 }),
1424 data: z.object({
1425 timestamp: z.int(),
1426 p50Latency: z.int(),
1427 p75Latency: z.int(),
1428 p90Latency: z.int(),
1429 p95Latency: z.int(),
1430 p99Latency: z.int(),
1431 }),
1432 });
1433 }
1434
1435 public get httpMetricsLatency1dMulti() {
1436 return this.tb.buildPipe({
1437 pipe: "endpoint__http_metrics_latency_1d_multi__v1",
1438 parameters: z.object({
1439 monitorIds: z.string().array().min(1),
1440 fromDate: z.string().optional(),
1441 toDate: z.string().optional(),
1442 }),
1443 data: z.object({
1444 timestamp: z.int(),
1445 monitorId: z.string(),
1446 p50Latency: z.int(),
1447 p75Latency: z.int(),
1448 p90Latency: z.int(),
1449 p95Latency: z.int(),
1450 p99Latency: z.int(),
1451 }),
1452 opts: { next: { revalidate: REVALIDATE } },
1453 });
1454 }
1455
1456 public get tcpMetricsLatency1d() {
1457 return this.tb.buildPipe({
1458 pipe: "endpoint__tcp_metrics_latency_1d__v1",
1459 parameters: z.object({
1460 monitorId: z.string(),
1461 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
1462 fromDate: z.string().optional(),
1463 toDate: z.string().optional(),
1464 }),
1465 data: z.object({
1466 timestamp: z.int(),
1467 p50Latency: z.int(),
1468 p75Latency: z.int(),
1469 p90Latency: z.int(),
1470 p95Latency: z.int(),
1471 p99Latency: z.int(),
1472 }),
1473 });
1474 }
1475
1476 public get tcpMetricsLatency7d() {
1477 return this.tb.buildPipe({
1478 pipe: "endpoint__tcp_metrics_latency_7d__v1",
1479 parameters: z.object({
1480 monitorId: z.string(),
1481 fromDate: z.string().optional(),
1482 toDate: z.string().optional(),
1483 }),
1484 data: z.object({
1485 timestamp: z.int(),
1486 p50Latency: z.int(),
1487 p75Latency: z.int(),
1488 p90Latency: z.int(),
1489 p95Latency: z.int(),
1490 p99Latency: z.int(),
1491 }),
1492 });
1493 }
1494
1495 public get tcpMetricsLatency1dMulti() {
1496 return this.tb.buildPipe({
1497 pipe: "endpoint__tcp_metrics_latency_1d_multi__v1",
1498 parameters: z.object({
1499 monitorIds: z.string().array().min(1),
1500 fromDate: z.string().optional(),
1501 toDate: z.string().optional(),
1502 }),
1503 data: z.object({
1504 timestamp: z.int(),
1505 monitorId: z.coerce.string(),
1506 p50Latency: z.int(),
1507 p75Latency: z.int(),
1508 p90Latency: z.int(),
1509 p95Latency: z.int(),
1510 p99Latency: z.int(),
1511 }),
1512 opts: { next: { revalidate: REVALIDATE } },
1513 });
1514 }
1515
1516 public get dnsGetBiweekly() {
1517 return this.tb.buildPipe({
1518 pipe: "endpoint__dns_get_14d__v0",
1519 parameters: z.object({
1520 id: z.string().nullable(),
1521 monitorId: z.string(),
1522 }),
1523 data: z.object({
1524 type: z.literal("dns").prefault("dns"),
1525 id: z.coerce.string().nullable(),
1526 uri: z.string(),
1527 latency: z.int(),
1528 monitorId: z.coerce.string(),
1529 error: z.coerce.boolean(),
1530 region: z.enum(monitorRegions).or(z.string()),
1531 cronTimestamp: z.int(),
1532 trigger: z.enum(triggers).nullable().prefault("cron"),
1533 timestamp: z.number(),
1534 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
1535 errorMessage: z.string().nullable(),
1536 assertions: z.string().nullable(),
1537 records: z
1538 .string()
1539 .transform((str) => {
1540 try {
1541 return JSON.parse(str) as Record<string, unknown>;
1542 } catch (error) {
1543 console.error(error);
1544 return {};
1545 }
1546 })
1547 .pipe(z.record(z.string(), z.array(z.string()))),
1548 }),
1549 // REMINDER: cache the result for accessing the data for a check as it won't change
1550 opts: { next: { revalidate: REVALIDATE } },
1551 });
1552 }
1553
1554 public get dnsListBiweekly() {
1555 return this.tb.buildPipe({
1556 pipe: "endpoint__dns_list_14d__v0",
1557 parameters: z.object({
1558 monitorId: z.string(),
1559 fromDate: z.int().optional(),
1560 toDate: z.int().optional(),
1561 }),
1562 data: z.object({
1563 type: z.literal("dns").prefault("dns"),
1564 id: z.coerce.string().nullable(),
1565 uri: z.string(),
1566 latency: z.int(),
1567 monitorId: z.coerce.string(),
1568 requestStatus: z.enum(["error", "success", "degraded"]).nullable(),
1569 region: z.enum(monitorRegions).or(z.string()),
1570 cronTimestamp: z.int(),
1571 trigger: z.enum(triggers).nullable().prefault("cron"),
1572 timestamp: z.number(),
1573 records: z
1574 .string()
1575 .transform((str) => {
1576 try {
1577 return JSON.parse(str) as Record<string, unknown>;
1578 } catch (error) {
1579 console.error(error);
1580 return {};
1581 }
1582 })
1583 .pipe(z.record(z.string(), z.array(z.string()))),
1584 }),
1585 opts: { next: { revalidate: REVALIDATE } },
1586 });
1587 }
1588
1589 public get dnsMetricsDaily() {
1590 return this.tb.buildPipe({
1591 pipe: "endpoint__dns_metrics_1d__v0",
1592 parameters: z.object({
1593 interval: z.int().optional(),
1594 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
1595 monitorId: z.string(),
1596 }),
1597 data: z.object({
1598 p50Latency: z.number().nullable().prefault(0),
1599 p75Latency: z.number().nullable().prefault(0),
1600 p90Latency: z.number().nullable().prefault(0),
1601 p95Latency: z.number().nullable().prefault(0),
1602 p99Latency: z.number().nullable().prefault(0),
1603 count: z.int().prefault(0),
1604 success: z.int().prefault(0),
1605 degraded: z.int().prefault(0),
1606 error: z.int().prefault(0),
1607 lastTimestamp: z.int().nullable(),
1608 }),
1609 opts: { next: { revalidate: REVALIDATE } },
1610 });
1611 }
1612
1613 public get dnsMetricsWeekly() {
1614 return this.tb.buildPipe({
1615 pipe: "endpoint__dns_metrics_7d__v0",
1616 parameters: z.object({
1617 interval: z.int().optional(),
1618 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
1619 monitorId: z.string(),
1620 }),
1621 data: z.object({
1622 p50Latency: z.number().nullable().prefault(0),
1623 p75Latency: z.number().nullable().prefault(0),
1624 p90Latency: z.number().nullable().prefault(0),
1625 p95Latency: z.number().nullable().prefault(0),
1626 p99Latency: z.number().nullable().prefault(0),
1627 count: z.int().prefault(0),
1628 success: z.int().prefault(0),
1629 degraded: z.int().prefault(0),
1630 error: z.int().prefault(0),
1631 lastTimestamp: z.int().nullable(),
1632 }),
1633 opts: { next: { revalidate: REVALIDATE } },
1634 });
1635 }
1636
1637 public get dnsMetricsBiweekly() {
1638 return this.tb.buildPipe({
1639 pipe: "endpoint__dns_metrics_14d__v0",
1640 parameters: z.object({
1641 interval: z.int().optional(),
1642 regions: z.array(z.enum(monitorRegions).or(z.string())).optional(),
1643 monitorId: z.string(),
1644 }),
1645 data: z.object({
1646 p50Latency: z.number().nullable().prefault(0),
1647 p75Latency: z.number().nullable().prefault(0),
1648 p90Latency: z.number().nullable().prefault(0),
1649 p95Latency: z.number().nullable().prefault(0),
1650 p99Latency: z.number().nullable().prefault(0),
1651 count: z.int().prefault(0),
1652 success: z.int().prefault(0),
1653 degraded: z.int().prefault(0),
1654 error: z.int().prefault(0),
1655 lastTimestamp: z.int().nullable(),
1656 }),
1657 opts: { next: { revalidate: REVALIDATE } },
1658 });
1659 }
1660
1661 public get dnsUptime30d() {
1662 return this.tb.buildPipe({
1663 pipe: "endpoint__dns_uptime_30d__v0",
1664 parameters: z.object({
1665 monitorId: z.string(),
1666 fromDate: z.string().optional(),
1667 toDate: z.string().optional(),
1668 regions: z.enum(monitorRegions).or(z.string()).array().optional(),
1669 interval: z.int().optional(),
1670 }),
1671 data: z.object({
1672 interval: z.coerce.date(),
1673 success: z.int(),
1674 degraded: z.int(),
1675 error: z.int(),
1676 }),
1677 });
1678 }
1679
1680 public get dnsMetricsLatency7d() {
1681 return this.tb.buildPipe({
1682 pipe: "endpoint__dns_metrics_latency_7d__v0",
1683 parameters: z.object({
1684 monitorId: z.string(),
1685 fromDate: z.string().optional(),
1686 toDate: z.string().optional(),
1687 }),
1688 data: z.object({
1689 timestamp: z.int(),
1690 p50Latency: z.int(),
1691 p75Latency: z.int(),
1692 p90Latency: z.int(),
1693 p95Latency: z.int(),
1694 p99Latency: z.int(),
1695 }),
1696 });
1697 }
1698
1699 public get dnsMetricsRegionsBiweekly() {
1700 return this.tb.buildPipe({
1701 pipe: "endpoint__dns_metrics_regions_14d__v0",
1702 parameters: z.object({
1703 monitorId: z.string(),
1704 interval: z.int().optional(),
1705 // Comma-separated list of regions, e.g. "ams,fra". Keeping string to pass directly.
1706 regions: z.string().array().optional(),
1707 fromDate: z.string().optional(),
1708 toDate: z.string().optional(),
1709 }),
1710 data: z.object({
1711 region: z.enum(monitorRegions).or(z.string()),
1712 timestamp: z.int(),
1713 p50Latency: z.number().nullable().prefault(0),
1714 p75Latency: z.number().nullable().prefault(0),
1715 p90Latency: z.number().nullable().prefault(0),
1716 p95Latency: z.number().nullable().prefault(0),
1717 p99Latency: z.number().nullable().prefault(0),
1718 }),
1719 opts: { next: { revalidate: REVALIDATE } },
1720 });
1721 }
1722
1723 public get dnsStatus45d() {
1724 return this.tb.buildPipe({
1725 pipe: "endpoint__dns_status_45d__v0",
1726 parameters: z.object({
1727 monitorIds: z.string().array(),
1728 }),
1729 data: z.object({
1730 day: z.string().transform((val) => {
1731 // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00)
1732 return new Date(`${val} GMT`).toISOString();
1733 }),
1734 count: z.number().prefault(0),
1735 ok: z.number().prefault(0),
1736 degraded: z.number().prefault(0),
1737 error: z.number().prefault(0),
1738 monitorId: z.coerce.string(),
1739 }),
1740 opts: { next: { revalidate: REVALIDATE } },
1741 });
1742 }
1743
1744 public get dnsMetricsLatency1dMulti() {
1745 return this.tb.buildPipe({
1746 pipe: "endpoint__dns_metrics_latency_1d_multi__v0",
1747 parameters: z.object({
1748 monitorIds: z.string().array().min(1),
1749 fromDate: z.string().optional(),
1750 toDate: z.string().optional(),
1751 }),
1752 data: z.object({
1753 timestamp: z.int(),
1754 monitorId: z.coerce.string(),
1755 p50Latency: z.int(),
1756 p75Latency: z.int(),
1757 p90Latency: z.int(),
1758 p95Latency: z.int(),
1759 p99Latency: z.int(),
1760 }),
1761 opts: { next: { revalidate: REVALIDATE } },
1762 });
1763 }
1764}