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