Openstatus www.openstatus.dev

๐Ÿ”ฅ On-demand test (#1046)

* ๐Ÿšง on demand test

* ๐Ÿšง on demand test

* ci: apply automated fixes

* ๐Ÿ’ฝ migrations

* ci: apply automated fixes

* add result endpoint

* ci: apply automated fixes

* ๐Ÿ™ fix build

* ๐Ÿ˜ check limit

* ci: apply automated fixes

* chore: update pricing table

* ๐Ÿคฃ limit per month

* ci: apply automated fixes

* ๐Ÿ”ฅ updaet tb

* drop migration

* apply migration

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>

authored by

Thibault Le Ouay
autofix-ci[bot]
Maximilian Kaske
and committed by
GitHub
abfc2f7e 665bd08a

+2780 -67
+9 -1
apps/checker/handlers/checker.go
··· 31 31 Headers string `json:"headers,omitempty"` 32 32 Assertions string `json:"assertions"` 33 33 Body string `json:"body,omitempty"` 34 + Trigger string `json:"trigger,omitempty"` 34 35 Latency int64 `json:"latency"` 35 36 CronTimestamp int64 `json:"cronTimestamp"` 36 37 Timestamp int64 `json:"timestamp"` ··· 81 82 assertionAsString = "" 82 83 } 83 84 85 + var trigger = "cron" 86 + if req.Trigger != "" { 87 + trigger = req.Trigger 88 + } 89 + 84 90 var called int 91 + 85 92 op := func() error { 86 93 called++ 87 94 res, err := checker.Http(ctx, requestClient, req) ··· 113 120 Timing: string(timingAsString), 114 121 Headers: string(headersAsString), 115 122 Body: string(res.Body), 123 + Trigger: trigger, 116 124 } 117 125 118 126 statusCode := statusCode(res.Status) ··· 277 285 Error: 1, 278 286 Assertions: assertionAsString, 279 287 Body: "", 288 + Trigger: trigger, 280 289 }, dataSourceName); err != nil { 281 290 log.Ctx(ctx).Error().Err(err).Msg("failed to send event to tinybird") 282 291 } ··· 294 303 } 295 304 296 305 c.JSON(http.StatusOK, gin.H{"message": "ok"}) 297 - 298 306 }
+1
apps/checker/request/request.go
··· 56 56 Method string `json:"method"` 57 57 Status string `json:"status"` 58 58 Body string `json:"body"` 59 + Trigger string `json:"trigger,omitempty"` 59 60 RawAssertions []json.RawMessage `json:"assertions,omitempty"` 60 61 CronTimestamp int64 `json:"cronTimestamp"` 61 62 Timeout int64 `json:"timeout"`
+120
apps/server/src/v1/monitors/results/get.ts
··· 1 + import { createRoute, z } from "@hono/zod-openapi"; 2 + 3 + import { and, db, eq, isNull } from "@openstatus/db"; 4 + import { monitor, monitorRun } from "@openstatus/db/src/schema"; 5 + import { OSTinybird } from "@openstatus/tinybird"; 6 + 7 + import { flyRegions } from "@openstatus/db/src/schema/constants"; 8 + import { HTTPException } from "hono/http-exception"; 9 + import { env } from "../../../env"; 10 + import { openApiErrorResponses } from "../../../libs/errors/openapi-error-responses"; 11 + import type { monitorsApi } from "../index"; 12 + import { ParamsSchema } from "../schema"; 13 + 14 + const tb = new OSTinybird({ token: env.TINY_BIRD_API_KEY }); 15 + 16 + const timingSchema = z.object({ 17 + dnsStart: z.number(), 18 + dnsDone: z.number(), 19 + connectStart: z.number(), 20 + connectDone: z.number(), 21 + tlsHandshakeStart: z.number(), 22 + tlsHandshakeDone: z.number(), 23 + firstByteStart: z.number(), 24 + firstByteDone: z.number(), 25 + transferStart: z.number(), 26 + transferDone: z.number(), 27 + }); 28 + 29 + const getMonitorStats = createRoute({ 30 + method: "get", 31 + tags: ["monitor"], 32 + description: "Get a monitor result", 33 + path: "/:id/result/:resultId", 34 + request: { 35 + params: ParamsSchema.extend({ 36 + resultId: z.number().int().openapi({ 37 + description: "The id of the result", 38 + }), 39 + }), 40 + }, 41 + responses: { 42 + 200: { 43 + content: { 44 + "application/json": { 45 + schema: z.object({ 46 + data: z.object({ 47 + latency: z.number().int(), // in ms 48 + statusCode: z.number().int().nullable().default(null), 49 + monitorId: z.string().default(""), 50 + url: z.string().url().optional(), 51 + error: z 52 + .number() 53 + .default(0) 54 + .transform((val) => val !== 0), 55 + region: z.enum(flyRegions), 56 + timestamp: z.number().int().optional(), 57 + message: z.string().nullable().optional(), 58 + timing: z 59 + .string() 60 + .nullable() 61 + .optional() 62 + .transform((val) => { 63 + if (!val) return null; 64 + const value = timingSchema.safeParse(JSON.parse(val)); 65 + if (value.success) return value.data; 66 + return null; 67 + }), 68 + }), 69 + }), 70 + }, 71 + }, 72 + description: "All the metrics for the monitor", 73 + }, 74 + ...openApiErrorResponses, 75 + }, 76 + }); 77 + 78 + export function registerGetMonitorSummary(api: typeof monitorsApi) { 79 + return api.openapi(getMonitorStats, async (c) => { 80 + const workspaceId = c.get("workspaceId"); 81 + const { id, resultId } = c.req.valid("param"); 82 + 83 + const _monitorRun = await db 84 + .select() 85 + .from(monitorRun) 86 + .where( 87 + and( 88 + eq(monitorRun.id, Number(resultId)), 89 + eq(monitorRun.monitorId, Number(id)), 90 + eq(monitorRun.workspaceId, Number(workspaceId)), 91 + ), 92 + ) 93 + .get(); 94 + 95 + if (!_monitorRun || !_monitorRun?.runnedAt) { 96 + throw new HTTPException(404, { message: "Not Found" }); 97 + } 98 + 99 + const _monitor = await db 100 + .select() 101 + .from(monitor) 102 + .where(eq(monitor.id, Number(id))) 103 + .get(); 104 + 105 + if (!_monitor) { 106 + throw new HTTPException(404, { message: "Not Found" }); 107 + } 108 + // Fetch result from tb pipe 109 + const data = await tb.getResultForOnDemandCheckHttp()({ 110 + monitorId: _monitor.id, 111 + timestamp: _monitorRun.runnedAt?.getTime(), 112 + url: _monitor.url, 113 + }); 114 + // return array of results 115 + if (!data) { 116 + throw new HTTPException(404, { message: "Not Found" }); 117 + } 118 + return c.json({ data }, 200); 119 + }); 120 + }
+192
apps/server/src/v1/monitors/trigger/post.ts
··· 1 + import { createRoute, z } from "@hono/zod-openapi"; 2 + import { and, eq, gte, isNull, sql } from "@openstatus/db"; 3 + import { db } from "@openstatus/db/src/db"; 4 + import { monitorRun } from "@openstatus/db/src/schema"; 5 + import { monitorStatusTable } from "@openstatus/db/src/schema/monitor_status/monitor_status"; 6 + import { selectMonitorStatusSchema } from "@openstatus/db/src/schema/monitor_status/validation"; 7 + import { monitor } from "@openstatus/db/src/schema/monitors/monitor"; 8 + import { selectMonitorSchema } from "@openstatus/db/src/schema/monitors/validation"; 9 + import { getLimit } from "@openstatus/db/src/schema/plan/utils"; 10 + import type { httpPayloadSchema, tpcPayloadSchema } from "@openstatus/utils"; 11 + import { HTTPException } from "hono/http-exception"; 12 + import type { monitorsApi } from ".."; 13 + import { env } from "../../../env"; 14 + import { openApiErrorResponses } from "../../../libs/errors/openapi-error-responses"; 15 + import { ParamsSchema } from "../schema"; 16 + const triggerMonitor = createRoute({ 17 + method: "get", 18 + tags: ["monitor"], 19 + description: "Trigger a monitor check", 20 + path: "/:id/trigger", 21 + request: { 22 + params: ParamsSchema, 23 + }, 24 + responses: { 25 + 200: { 26 + content: { 27 + "application/json": { 28 + schema: z.object({ 29 + resultId: z 30 + .number() 31 + .openapi({ description: "the id of your check result" }), 32 + }), 33 + }, 34 + }, 35 + description: "All the historical metrics", 36 + }, 37 + ...openApiErrorResponses, 38 + }, 39 + }); 40 + 41 + export function registerTriggerMonitor(api: typeof monitorsApi) { 42 + return api.openapi(triggerMonitor, async (c) => { 43 + const workspaceId = c.get("workspaceId"); 44 + const { id } = c.req.valid("param"); 45 + const limits = c.get("limits"); 46 + 47 + const lastMonth = new Date().setMonth(new Date().getMonth() - 1); 48 + 49 + const count = ( 50 + await db 51 + .select({ count: sql<number>`count(*)` }) 52 + .from(monitorRun) 53 + .where( 54 + and( 55 + eq(monitorRun.workspaceId, Number(workspaceId)), 56 + gte(monitorRun.createdAt, new Date(lastMonth)), 57 + ), 58 + ) 59 + .all() 60 + )[0].count; 61 + 62 + if (count >= getLimit(limits, "synthetic-checks")) { 63 + throw new HTTPException(403, { 64 + message: "Upgrade for more checks", 65 + }); 66 + } 67 + 68 + const monitorData = await db 69 + .select() 70 + .from(monitor) 71 + .where( 72 + and( 73 + eq(monitor.id, Number(id)), 74 + eq(monitor.workspaceId, Number(workspaceId)), 75 + isNull(monitor.deletedAt), 76 + ), 77 + ) 78 + .get(); 79 + 80 + if (!monitorData) { 81 + throw new HTTPException(404, { message: "Not Found" }); 82 + } 83 + 84 + const parseMonitor = selectMonitorSchema.safeParse(monitorData); 85 + 86 + if (!parseMonitor.success) { 87 + throw new HTTPException(400, { message: "Something went wrong" }); 88 + } 89 + 90 + const row = parseMonitor.data; 91 + 92 + // Maybe later overwrite the region 93 + 94 + const monitorStatusData = await db 95 + .select() 96 + .from(monitorStatusTable) 97 + .where(eq(monitorStatusTable.monitorId, monitorData.id)) 98 + .all(); 99 + 100 + const monitorStatus = z 101 + .array(selectMonitorStatusSchema) 102 + .safeParse(monitorStatusData); 103 + if (!monitorStatus.success) { 104 + throw new HTTPException(400, { message: "Something went wrong" }); 105 + } 106 + 107 + const timestamp = Date.now(); 108 + 109 + const newRun = await db 110 + .insert(monitorRun) 111 + .values({ 112 + monitorId: row.id, 113 + workspaceId: row.workspaceId, 114 + runnedAt: new Date(timestamp), 115 + }) 116 + .returning(); 117 + 118 + if (!newRun[0]) { 119 + throw new HTTPException(400, { message: "Something went wrong" }); 120 + } 121 + 122 + const allResult = []; 123 + for (const region of monitorData.regions) { 124 + const status = 125 + monitorStatus.data.find((m) => region === m.region)?.status || "active"; 126 + // Trigger the monitor 127 + 128 + let payload: 129 + | z.infer<typeof httpPayloadSchema> 130 + | z.infer<typeof tpcPayloadSchema> 131 + | null = null; 132 + // 133 + if (row.jobType === "http") { 134 + payload = { 135 + workspaceId: String(row.workspaceId), 136 + monitorId: String(row.id), 137 + url: row.url, 138 + method: row.method || "GET", 139 + cronTimestamp: timestamp, 140 + body: row.body, 141 + headers: row.headers, 142 + status: status, 143 + assertions: row.assertions ? JSON.parse(row.assertions) : null, 144 + degradedAfter: row.degradedAfter, 145 + timeout: row.timeout, 146 + }; 147 + } 148 + if (row.jobType === "tcp") { 149 + payload = { 150 + workspaceId: String(row.workspaceId), 151 + monitorId: String(row.id), 152 + url: row.url, 153 + status: status, 154 + assertions: row.assertions ? JSON.parse(row.assertions) : null, 155 + cronTimestamp: timestamp, 156 + degradedAfter: row.degradedAfter, 157 + timeout: row.timeout, 158 + }; 159 + } 160 + 161 + if (!payload) { 162 + throw new Error("Invalid jobType"); 163 + } 164 + const url = generateUrl({ row }); 165 + const result = fetch(url, { 166 + headers: { 167 + "Content-Type": "application/json", 168 + "fly-prefer-region": region, // Specify the region you want the request to be sent to 169 + Authorization: `Basic ${env.CRON_SECRET}`, 170 + }, 171 + method: "POST", 172 + body: JSON.stringify(payload), 173 + }); 174 + allResult.push(result); 175 + } 176 + 177 + await Promise.all(allResult); 178 + 179 + return c.json({ resultId: newRun[0].id }, 200); 180 + }); 181 + } 182 + 183 + function generateUrl({ row }: { row: z.infer<typeof selectMonitorSchema> }) { 184 + switch (row.jobType) { 185 + case "http": 186 + return `https://openstatus-checker.fly.dev/checker/http?monitor_id=${row.id}&trigger=api`; 187 + case "tcp": 188 + return `https://openstatus-checker.fly.dev/checker/tcp?monitor_id=${row.id}&trigger=api`; 189 + default: 190 + throw new Error("Invalid jobType"); 191 + } 192 + }
+1 -1
apps/web/src/app/api/checker/cron/_cron.ts
··· 15 15 } from "@openstatus/db/src/schema"; 16 16 17 17 import { env } from "@/env"; 18 - import type { httpPayloadSchema, tpcPayloadSchema } from "../schema"; 18 + import type { httpPayloadSchema, tpcPayloadSchema } from "@openstatus/utils"; 19 19 20 20 const periodicityAvailable = selectMonitorSchema.pick({ periodicity: true }); 21 21
-31
apps/web/src/app/api/checker/schema.ts
··· 1 - import { z } from "zod"; 2 - 3 - import { base } from "@openstatus/assertions"; 4 - import { monitorMethods, monitorStatus } from "@openstatus/db/src/schema"; 5 - 6 - export const httpPayloadSchema = z.object({ 7 - workspaceId: z.string(), 8 - monitorId: z.string(), 9 - method: z.enum(monitorMethods), 10 - body: z.string().optional(), 11 - headers: z.array(z.object({ key: z.string(), value: z.string() })).optional(), 12 - url: z.string(), 13 - cronTimestamp: z.number(), 14 - status: z.enum(monitorStatus), 15 - assertions: z.array(base).nullable(), 16 - timeout: z.number().default(45000), 17 - degradedAfter: z.number().nullable(), 18 - }); 19 - 20 - export type HttpPayload = z.infer<typeof httpPayloadSchema>; 21 - 22 - export const tpcPayloadSchema = z.object({ 23 - status: z.enum(monitorStatus), 24 - workspaceId: z.string(), 25 - url: z.string(), 26 - monitorId: z.string(), 27 - assertions: z.array(base).nullable(), 28 - cronTimestamp: z.number(), 29 - timeout: z.number().default(45000), 30 - degradedAfter: z.number().nullable(), 31 - });
+1 -1
apps/web/src/app/api/checker/test/http/route.ts
··· 4 4 import { monitorFlyRegionSchema } from "@openstatus/db/src/schema/constants"; 5 5 6 6 import { checkRegion } from "@/components/ping-response-analysis/utils"; 7 - import { httpPayloadSchema } from "../../schema"; 7 + import { httpPayloadSchema } from "@openstatus/utils"; 8 8 import { isAnInvalidTestUrl } from "../../utils"; 9 9 10 10 export const runtime = "edge";
+1 -1
apps/web/src/app/api/checker/test/route.ts
··· 4 4 import { monitorFlyRegionSchema } from "@openstatus/db/src/schema/constants"; 5 5 6 6 import { checkRegion } from "@/components/ping-response-analysis/utils"; 7 - import { httpPayloadSchema } from "../schema"; 7 + import { httpPayloadSchema } from "@openstatus/utils"; 8 8 import { isAnInvalidTestUrl } from "../utils"; 9 9 10 10 export const runtime = "edge";
+8 -10
apps/web/src/components/marketing/pricing/pricing-table.tsx
··· 112 112 {label} 113 113 </TableCell> 114 114 </TableRow> 115 - {features.map(({ label, value, badge }, _i) => { 115 + {features.map(({ label, value, badge, monthly }, _i) => { 116 116 return ( 117 117 <TableRow key={key + label}> 118 118 <TableCell className="gap-1"> ··· 122 122 ) : null} 123 123 </TableCell> 124 124 {selectedPlans.map((plan, _i) => { 125 - const limitValue = plan.limits[value]; 125 + const limitValue = 126 + plan.limits[value as keyof typeof plan.limits]; 126 127 function renderContent() { 127 128 if (typeof limitValue === "boolean") { 128 129 if (limitValue) { ··· 137 138 ); 138 139 } 139 140 if (typeof limitValue === "number") { 140 - return ( 141 - <span className="font-mono"> 142 - {new Intl.NumberFormat("us") 143 - .format(limitValue) 144 - .toString()} 145 - </span> 146 - ); 141 + return new Intl.NumberFormat("us") 142 + .format(limitValue) 143 + .toString(); 147 144 } 148 145 if ( 149 146 Array.isArray(limitValue) && ··· 159 156 // biome-ignore lint/suspicious/noArrayIndexKey: <explanation> 160 157 key={key + value + _i} 161 158 className={cn( 162 - "p-3", 159 + "p-3 font-mono", 163 160 plan.key === "team" && "bg-muted/30", 164 161 )} 165 162 > 166 163 {renderContent()} 164 + {monthly ? "/mo" : ""} 167 165 </TableCell> 168 166 ); 169 167 })}
+9 -3
apps/web/src/config/pricing-table.ts
··· 1 - import type { LimitsV2 } from "@openstatus/db/src/schema/plan/schema"; 1 + import type { LimitsV1, LimitsV2 } from "@openstatus/db/src/schema/plan/schema"; 2 2 3 3 export const pricingTableConfig: Record< 4 4 string, 5 5 { 6 6 label: string; 7 - features: { value: keyof LimitsV2; label: string; badge?: string }[]; 7 + features: { 8 + value: keyof LimitsV1 | keyof LimitsV2; 9 + label: string; 10 + badge?: string; 11 + monthly?: boolean; 12 + }[]; 8 13 } 9 14 > = { 10 15 monitors: { ··· 32 37 features: [ 33 38 { 34 39 value: "synthetic-checks", 35 - label: "Number of synthetic API checks", 40 + label: "Number of on-demand checks", 41 + monthly: true, 36 42 }, 37 43 { value: "private-locations", label: "Private Locations" }, 38 44 ],
+9
packages/db/drizzle/0038_foamy_stardust.sql
··· 1 + CREATE TABLE `monitor_run` ( 2 + `id` integer PRIMARY KEY NOT NULL, 3 + `workspace_id` integer, 4 + `monitor_id` integer, 5 + `runned_at` integer, 6 + `created_at` integer DEFAULT (strftime('%s', 'now')), 7 + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE no action, 8 + FOREIGN KEY (`monitor_id`) REFERENCES `monitor`(`id`) ON UPDATE no action ON DELETE no action 9 + );
+2277
packages/db/drizzle/meta/0038_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "e284ec98-e715-4599-9f79-ecbf022ca7a2", 5 + "prevId": "09d93b56-dcc3-4148-934a-a490ab04bab9", 6 + "tables": { 7 + "status_report_to_monitors": { 8 + "name": "status_report_to_monitors", 9 + "columns": { 10 + "monitor_id": { 11 + "name": "monitor_id", 12 + "type": "integer", 13 + "primaryKey": false, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "status_report_id": { 18 + "name": "status_report_id", 19 + "type": "integer", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "created_at": { 25 + "name": "created_at", 26 + "type": "integer", 27 + "primaryKey": false, 28 + "notNull": false, 29 + "autoincrement": false, 30 + "default": "(strftime('%s', 'now'))" 31 + } 32 + }, 33 + "indexes": {}, 34 + "foreignKeys": { 35 + "status_report_to_monitors_monitor_id_monitor_id_fk": { 36 + "name": "status_report_to_monitors_monitor_id_monitor_id_fk", 37 + "tableFrom": "status_report_to_monitors", 38 + "tableTo": "monitor", 39 + "columnsFrom": [ 40 + "monitor_id" 41 + ], 42 + "columnsTo": [ 43 + "id" 44 + ], 45 + "onDelete": "cascade", 46 + "onUpdate": "no action" 47 + }, 48 + "status_report_to_monitors_status_report_id_status_report_id_fk": { 49 + "name": "status_report_to_monitors_status_report_id_status_report_id_fk", 50 + "tableFrom": "status_report_to_monitors", 51 + "tableTo": "status_report", 52 + "columnsFrom": [ 53 + "status_report_id" 54 + ], 55 + "columnsTo": [ 56 + "id" 57 + ], 58 + "onDelete": "cascade", 59 + "onUpdate": "no action" 60 + } 61 + }, 62 + "compositePrimaryKeys": { 63 + "status_report_to_monitors_monitor_id_status_report_id_pk": { 64 + "columns": [ 65 + "monitor_id", 66 + "status_report_id" 67 + ], 68 + "name": "status_report_to_monitors_monitor_id_status_report_id_pk" 69 + } 70 + }, 71 + "uniqueConstraints": {} 72 + }, 73 + "status_report": { 74 + "name": "status_report", 75 + "columns": { 76 + "id": { 77 + "name": "id", 78 + "type": "integer", 79 + "primaryKey": true, 80 + "notNull": true, 81 + "autoincrement": false 82 + }, 83 + "status": { 84 + "name": "status", 85 + "type": "text", 86 + "primaryKey": false, 87 + "notNull": true, 88 + "autoincrement": false 89 + }, 90 + "title": { 91 + "name": "title", 92 + "type": "text(256)", 93 + "primaryKey": false, 94 + "notNull": true, 95 + "autoincrement": false 96 + }, 97 + "workspace_id": { 98 + "name": "workspace_id", 99 + "type": "integer", 100 + "primaryKey": false, 101 + "notNull": false, 102 + "autoincrement": false 103 + }, 104 + "page_id": { 105 + "name": "page_id", 106 + "type": "integer", 107 + "primaryKey": false, 108 + "notNull": false, 109 + "autoincrement": false 110 + }, 111 + "created_at": { 112 + "name": "created_at", 113 + "type": "integer", 114 + "primaryKey": false, 115 + "notNull": false, 116 + "autoincrement": false, 117 + "default": "(strftime('%s', 'now'))" 118 + }, 119 + "updated_at": { 120 + "name": "updated_at", 121 + "type": "integer", 122 + "primaryKey": false, 123 + "notNull": false, 124 + "autoincrement": false, 125 + "default": "(strftime('%s', 'now'))" 126 + } 127 + }, 128 + "indexes": {}, 129 + "foreignKeys": { 130 + "status_report_workspace_id_workspace_id_fk": { 131 + "name": "status_report_workspace_id_workspace_id_fk", 132 + "tableFrom": "status_report", 133 + "tableTo": "workspace", 134 + "columnsFrom": [ 135 + "workspace_id" 136 + ], 137 + "columnsTo": [ 138 + "id" 139 + ], 140 + "onDelete": "no action", 141 + "onUpdate": "no action" 142 + }, 143 + "status_report_page_id_page_id_fk": { 144 + "name": "status_report_page_id_page_id_fk", 145 + "tableFrom": "status_report", 146 + "tableTo": "page", 147 + "columnsFrom": [ 148 + "page_id" 149 + ], 150 + "columnsTo": [ 151 + "id" 152 + ], 153 + "onDelete": "no action", 154 + "onUpdate": "no action" 155 + } 156 + }, 157 + "compositePrimaryKeys": {}, 158 + "uniqueConstraints": {} 159 + }, 160 + "status_report_update": { 161 + "name": "status_report_update", 162 + "columns": { 163 + "id": { 164 + "name": "id", 165 + "type": "integer", 166 + "primaryKey": true, 167 + "notNull": true, 168 + "autoincrement": false 169 + }, 170 + "status": { 171 + "name": "status", 172 + "type": "text(4)", 173 + "primaryKey": false, 174 + "notNull": true, 175 + "autoincrement": false 176 + }, 177 + "date": { 178 + "name": "date", 179 + "type": "integer", 180 + "primaryKey": false, 181 + "notNull": true, 182 + "autoincrement": false 183 + }, 184 + "message": { 185 + "name": "message", 186 + "type": "text", 187 + "primaryKey": false, 188 + "notNull": true, 189 + "autoincrement": false 190 + }, 191 + "status_report_id": { 192 + "name": "status_report_id", 193 + "type": "integer", 194 + "primaryKey": false, 195 + "notNull": true, 196 + "autoincrement": false 197 + }, 198 + "created_at": { 199 + "name": "created_at", 200 + "type": "integer", 201 + "primaryKey": false, 202 + "notNull": false, 203 + "autoincrement": false, 204 + "default": "(strftime('%s', 'now'))" 205 + }, 206 + "updated_at": { 207 + "name": "updated_at", 208 + "type": "integer", 209 + "primaryKey": false, 210 + "notNull": false, 211 + "autoincrement": false, 212 + "default": "(strftime('%s', 'now'))" 213 + } 214 + }, 215 + "indexes": {}, 216 + "foreignKeys": { 217 + "status_report_update_status_report_id_status_report_id_fk": { 218 + "name": "status_report_update_status_report_id_status_report_id_fk", 219 + "tableFrom": "status_report_update", 220 + "tableTo": "status_report", 221 + "columnsFrom": [ 222 + "status_report_id" 223 + ], 224 + "columnsTo": [ 225 + "id" 226 + ], 227 + "onDelete": "cascade", 228 + "onUpdate": "no action" 229 + } 230 + }, 231 + "compositePrimaryKeys": {}, 232 + "uniqueConstraints": {} 233 + }, 234 + "integration": { 235 + "name": "integration", 236 + "columns": { 237 + "id": { 238 + "name": "id", 239 + "type": "integer", 240 + "primaryKey": true, 241 + "notNull": true, 242 + "autoincrement": false 243 + }, 244 + "name": { 245 + "name": "name", 246 + "type": "text(256)", 247 + "primaryKey": false, 248 + "notNull": true, 249 + "autoincrement": false 250 + }, 251 + "workspace_id": { 252 + "name": "workspace_id", 253 + "type": "integer", 254 + "primaryKey": false, 255 + "notNull": false, 256 + "autoincrement": false 257 + }, 258 + "credential": { 259 + "name": "credential", 260 + "type": "text", 261 + "primaryKey": false, 262 + "notNull": false, 263 + "autoincrement": false 264 + }, 265 + "external_id": { 266 + "name": "external_id", 267 + "type": "text", 268 + "primaryKey": false, 269 + "notNull": true, 270 + "autoincrement": false 271 + }, 272 + "created_at": { 273 + "name": "created_at", 274 + "type": "integer", 275 + "primaryKey": false, 276 + "notNull": false, 277 + "autoincrement": false, 278 + "default": "(strftime('%s', 'now'))" 279 + }, 280 + "updated_at": { 281 + "name": "updated_at", 282 + "type": "integer", 283 + "primaryKey": false, 284 + "notNull": false, 285 + "autoincrement": false, 286 + "default": "(strftime('%s', 'now'))" 287 + }, 288 + "data": { 289 + "name": "data", 290 + "type": "text", 291 + "primaryKey": false, 292 + "notNull": true, 293 + "autoincrement": false 294 + } 295 + }, 296 + "indexes": {}, 297 + "foreignKeys": { 298 + "integration_workspace_id_workspace_id_fk": { 299 + "name": "integration_workspace_id_workspace_id_fk", 300 + "tableFrom": "integration", 301 + "tableTo": "workspace", 302 + "columnsFrom": [ 303 + "workspace_id" 304 + ], 305 + "columnsTo": [ 306 + "id" 307 + ], 308 + "onDelete": "no action", 309 + "onUpdate": "no action" 310 + } 311 + }, 312 + "compositePrimaryKeys": {}, 313 + "uniqueConstraints": {} 314 + }, 315 + "page": { 316 + "name": "page", 317 + "columns": { 318 + "id": { 319 + "name": "id", 320 + "type": "integer", 321 + "primaryKey": true, 322 + "notNull": true, 323 + "autoincrement": false 324 + }, 325 + "workspace_id": { 326 + "name": "workspace_id", 327 + "type": "integer", 328 + "primaryKey": false, 329 + "notNull": true, 330 + "autoincrement": false 331 + }, 332 + "title": { 333 + "name": "title", 334 + "type": "text", 335 + "primaryKey": false, 336 + "notNull": true, 337 + "autoincrement": false 338 + }, 339 + "description": { 340 + "name": "description", 341 + "type": "text", 342 + "primaryKey": false, 343 + "notNull": true, 344 + "autoincrement": false 345 + }, 346 + "icon": { 347 + "name": "icon", 348 + "type": "text(256)", 349 + "primaryKey": false, 350 + "notNull": false, 351 + "autoincrement": false, 352 + "default": "''" 353 + }, 354 + "slug": { 355 + "name": "slug", 356 + "type": "text(256)", 357 + "primaryKey": false, 358 + "notNull": true, 359 + "autoincrement": false 360 + }, 361 + "custom_domain": { 362 + "name": "custom_domain", 363 + "type": "text(256)", 364 + "primaryKey": false, 365 + "notNull": true, 366 + "autoincrement": false 367 + }, 368 + "published": { 369 + "name": "published", 370 + "type": "integer", 371 + "primaryKey": false, 372 + "notNull": false, 373 + "autoincrement": false, 374 + "default": false 375 + }, 376 + "password": { 377 + "name": "password", 378 + "type": "text(256)", 379 + "primaryKey": false, 380 + "notNull": false, 381 + "autoincrement": false 382 + }, 383 + "password_protected": { 384 + "name": "password_protected", 385 + "type": "integer", 386 + "primaryKey": false, 387 + "notNull": false, 388 + "autoincrement": false, 389 + "default": false 390 + }, 391 + "show_monitor_values": { 392 + "name": "show_monitor_values", 393 + "type": "integer", 394 + "primaryKey": false, 395 + "notNull": false, 396 + "autoincrement": false, 397 + "default": true 398 + }, 399 + "created_at": { 400 + "name": "created_at", 401 + "type": "integer", 402 + "primaryKey": false, 403 + "notNull": false, 404 + "autoincrement": false, 405 + "default": "(strftime('%s', 'now'))" 406 + }, 407 + "updated_at": { 408 + "name": "updated_at", 409 + "type": "integer", 410 + "primaryKey": false, 411 + "notNull": false, 412 + "autoincrement": false, 413 + "default": "(strftime('%s', 'now'))" 414 + } 415 + }, 416 + "indexes": { 417 + "page_slug_unique": { 418 + "name": "page_slug_unique", 419 + "columns": [ 420 + "slug" 421 + ], 422 + "isUnique": true 423 + } 424 + }, 425 + "foreignKeys": { 426 + "page_workspace_id_workspace_id_fk": { 427 + "name": "page_workspace_id_workspace_id_fk", 428 + "tableFrom": "page", 429 + "tableTo": "workspace", 430 + "columnsFrom": [ 431 + "workspace_id" 432 + ], 433 + "columnsTo": [ 434 + "id" 435 + ], 436 + "onDelete": "cascade", 437 + "onUpdate": "no action" 438 + } 439 + }, 440 + "compositePrimaryKeys": {}, 441 + "uniqueConstraints": {} 442 + }, 443 + "monitor": { 444 + "name": "monitor", 445 + "columns": { 446 + "id": { 447 + "name": "id", 448 + "type": "integer", 449 + "primaryKey": true, 450 + "notNull": true, 451 + "autoincrement": false 452 + }, 453 + "job_type": { 454 + "name": "job_type", 455 + "type": "text", 456 + "primaryKey": false, 457 + "notNull": true, 458 + "autoincrement": false, 459 + "default": "'http'" 460 + }, 461 + "periodicity": { 462 + "name": "periodicity", 463 + "type": "text", 464 + "primaryKey": false, 465 + "notNull": true, 466 + "autoincrement": false, 467 + "default": "'other'" 468 + }, 469 + "status": { 470 + "name": "status", 471 + "type": "text", 472 + "primaryKey": false, 473 + "notNull": true, 474 + "autoincrement": false, 475 + "default": "'active'" 476 + }, 477 + "active": { 478 + "name": "active", 479 + "type": "integer", 480 + "primaryKey": false, 481 + "notNull": false, 482 + "autoincrement": false, 483 + "default": false 484 + }, 485 + "regions": { 486 + "name": "regions", 487 + "type": "text", 488 + "primaryKey": false, 489 + "notNull": true, 490 + "autoincrement": false, 491 + "default": "''" 492 + }, 493 + "url": { 494 + "name": "url", 495 + "type": "text(2048)", 496 + "primaryKey": false, 497 + "notNull": true, 498 + "autoincrement": false 499 + }, 500 + "name": { 501 + "name": "name", 502 + "type": "text(256)", 503 + "primaryKey": false, 504 + "notNull": true, 505 + "autoincrement": false, 506 + "default": "''" 507 + }, 508 + "description": { 509 + "name": "description", 510 + "type": "text", 511 + "primaryKey": false, 512 + "notNull": true, 513 + "autoincrement": false, 514 + "default": "''" 515 + }, 516 + "headers": { 517 + "name": "headers", 518 + "type": "text", 519 + "primaryKey": false, 520 + "notNull": false, 521 + "autoincrement": false, 522 + "default": "''" 523 + }, 524 + "body": { 525 + "name": "body", 526 + "type": "text", 527 + "primaryKey": false, 528 + "notNull": false, 529 + "autoincrement": false, 530 + "default": "''" 531 + }, 532 + "method": { 533 + "name": "method", 534 + "type": "text", 535 + "primaryKey": false, 536 + "notNull": false, 537 + "autoincrement": false, 538 + "default": "'GET'" 539 + }, 540 + "workspace_id": { 541 + "name": "workspace_id", 542 + "type": "integer", 543 + "primaryKey": false, 544 + "notNull": false, 545 + "autoincrement": false 546 + }, 547 + "timeout": { 548 + "name": "timeout", 549 + "type": "integer", 550 + "primaryKey": false, 551 + "notNull": true, 552 + "autoincrement": false, 553 + "default": 45000 554 + }, 555 + "degraded_after": { 556 + "name": "degraded_after", 557 + "type": "integer", 558 + "primaryKey": false, 559 + "notNull": false, 560 + "autoincrement": false 561 + }, 562 + "assertions": { 563 + "name": "assertions", 564 + "type": "text", 565 + "primaryKey": false, 566 + "notNull": false, 567 + "autoincrement": false 568 + }, 569 + "public": { 570 + "name": "public", 571 + "type": "integer", 572 + "primaryKey": false, 573 + "notNull": false, 574 + "autoincrement": false, 575 + "default": false 576 + }, 577 + "created_at": { 578 + "name": "created_at", 579 + "type": "integer", 580 + "primaryKey": false, 581 + "notNull": false, 582 + "autoincrement": false, 583 + "default": "(strftime('%s', 'now'))" 584 + }, 585 + "updated_at": { 586 + "name": "updated_at", 587 + "type": "integer", 588 + "primaryKey": false, 589 + "notNull": false, 590 + "autoincrement": false, 591 + "default": "(strftime('%s', 'now'))" 592 + }, 593 + "deleted_at": { 594 + "name": "deleted_at", 595 + "type": "integer", 596 + "primaryKey": false, 597 + "notNull": false, 598 + "autoincrement": false 599 + } 600 + }, 601 + "indexes": {}, 602 + "foreignKeys": { 603 + "monitor_workspace_id_workspace_id_fk": { 604 + "name": "monitor_workspace_id_workspace_id_fk", 605 + "tableFrom": "monitor", 606 + "tableTo": "workspace", 607 + "columnsFrom": [ 608 + "workspace_id" 609 + ], 610 + "columnsTo": [ 611 + "id" 612 + ], 613 + "onDelete": "no action", 614 + "onUpdate": "no action" 615 + } 616 + }, 617 + "compositePrimaryKeys": {}, 618 + "uniqueConstraints": {} 619 + }, 620 + "monitors_to_pages": { 621 + "name": "monitors_to_pages", 622 + "columns": { 623 + "monitor_id": { 624 + "name": "monitor_id", 625 + "type": "integer", 626 + "primaryKey": false, 627 + "notNull": true, 628 + "autoincrement": false 629 + }, 630 + "page_id": { 631 + "name": "page_id", 632 + "type": "integer", 633 + "primaryKey": false, 634 + "notNull": true, 635 + "autoincrement": false 636 + }, 637 + "created_at": { 638 + "name": "created_at", 639 + "type": "integer", 640 + "primaryKey": false, 641 + "notNull": false, 642 + "autoincrement": false, 643 + "default": "(strftime('%s', 'now'))" 644 + }, 645 + "order": { 646 + "name": "order", 647 + "type": "integer", 648 + "primaryKey": false, 649 + "notNull": false, 650 + "autoincrement": false, 651 + "default": 0 652 + } 653 + }, 654 + "indexes": {}, 655 + "foreignKeys": { 656 + "monitors_to_pages_monitor_id_monitor_id_fk": { 657 + "name": "monitors_to_pages_monitor_id_monitor_id_fk", 658 + "tableFrom": "monitors_to_pages", 659 + "tableTo": "monitor", 660 + "columnsFrom": [ 661 + "monitor_id" 662 + ], 663 + "columnsTo": [ 664 + "id" 665 + ], 666 + "onDelete": "cascade", 667 + "onUpdate": "no action" 668 + }, 669 + "monitors_to_pages_page_id_page_id_fk": { 670 + "name": "monitors_to_pages_page_id_page_id_fk", 671 + "tableFrom": "monitors_to_pages", 672 + "tableTo": "page", 673 + "columnsFrom": [ 674 + "page_id" 675 + ], 676 + "columnsTo": [ 677 + "id" 678 + ], 679 + "onDelete": "cascade", 680 + "onUpdate": "no action" 681 + } 682 + }, 683 + "compositePrimaryKeys": { 684 + "monitors_to_pages_monitor_id_page_id_pk": { 685 + "columns": [ 686 + "monitor_id", 687 + "page_id" 688 + ], 689 + "name": "monitors_to_pages_monitor_id_page_id_pk" 690 + } 691 + }, 692 + "uniqueConstraints": {} 693 + }, 694 + "workspace": { 695 + "name": "workspace", 696 + "columns": { 697 + "id": { 698 + "name": "id", 699 + "type": "integer", 700 + "primaryKey": true, 701 + "notNull": true, 702 + "autoincrement": false 703 + }, 704 + "slug": { 705 + "name": "slug", 706 + "type": "text", 707 + "primaryKey": false, 708 + "notNull": true, 709 + "autoincrement": false 710 + }, 711 + "name": { 712 + "name": "name", 713 + "type": "text", 714 + "primaryKey": false, 715 + "notNull": false, 716 + "autoincrement": false 717 + }, 718 + "stripe_id": { 719 + "name": "stripe_id", 720 + "type": "text(256)", 721 + "primaryKey": false, 722 + "notNull": false, 723 + "autoincrement": false 724 + }, 725 + "subscription_id": { 726 + "name": "subscription_id", 727 + "type": "text", 728 + "primaryKey": false, 729 + "notNull": false, 730 + "autoincrement": false 731 + }, 732 + "plan": { 733 + "name": "plan", 734 + "type": "text", 735 + "primaryKey": false, 736 + "notNull": false, 737 + "autoincrement": false 738 + }, 739 + "ends_at": { 740 + "name": "ends_at", 741 + "type": "integer", 742 + "primaryKey": false, 743 + "notNull": false, 744 + "autoincrement": false 745 + }, 746 + "paid_until": { 747 + "name": "paid_until", 748 + "type": "integer", 749 + "primaryKey": false, 750 + "notNull": false, 751 + "autoincrement": false 752 + }, 753 + "limits": { 754 + "name": "limits", 755 + "type": "text", 756 + "primaryKey": false, 757 + "notNull": true, 758 + "autoincrement": false, 759 + "default": "'{}'" 760 + }, 761 + "created_at": { 762 + "name": "created_at", 763 + "type": "integer", 764 + "primaryKey": false, 765 + "notNull": false, 766 + "autoincrement": false, 767 + "default": "(strftime('%s', 'now'))" 768 + }, 769 + "updated_at": { 770 + "name": "updated_at", 771 + "type": "integer", 772 + "primaryKey": false, 773 + "notNull": false, 774 + "autoincrement": false, 775 + "default": "(strftime('%s', 'now'))" 776 + }, 777 + "dsn": { 778 + "name": "dsn", 779 + "type": "text", 780 + "primaryKey": false, 781 + "notNull": false, 782 + "autoincrement": false 783 + } 784 + }, 785 + "indexes": { 786 + "workspace_slug_unique": { 787 + "name": "workspace_slug_unique", 788 + "columns": [ 789 + "slug" 790 + ], 791 + "isUnique": true 792 + }, 793 + "workspace_stripe_id_unique": { 794 + "name": "workspace_stripe_id_unique", 795 + "columns": [ 796 + "stripe_id" 797 + ], 798 + "isUnique": true 799 + }, 800 + "workspace_id_dsn_unique": { 801 + "name": "workspace_id_dsn_unique", 802 + "columns": [ 803 + "id", 804 + "dsn" 805 + ], 806 + "isUnique": true 807 + } 808 + }, 809 + "foreignKeys": {}, 810 + "compositePrimaryKeys": {}, 811 + "uniqueConstraints": {} 812 + }, 813 + "account": { 814 + "name": "account", 815 + "columns": { 816 + "user_id": { 817 + "name": "user_id", 818 + "type": "integer", 819 + "primaryKey": false, 820 + "notNull": true, 821 + "autoincrement": false 822 + }, 823 + "type": { 824 + "name": "type", 825 + "type": "text", 826 + "primaryKey": false, 827 + "notNull": true, 828 + "autoincrement": false 829 + }, 830 + "provider": { 831 + "name": "provider", 832 + "type": "text", 833 + "primaryKey": false, 834 + "notNull": true, 835 + "autoincrement": false 836 + }, 837 + "provider_account_id": { 838 + "name": "provider_account_id", 839 + "type": "text", 840 + "primaryKey": false, 841 + "notNull": true, 842 + "autoincrement": false 843 + }, 844 + "refresh_token": { 845 + "name": "refresh_token", 846 + "type": "text", 847 + "primaryKey": false, 848 + "notNull": false, 849 + "autoincrement": false 850 + }, 851 + "access_token": { 852 + "name": "access_token", 853 + "type": "text", 854 + "primaryKey": false, 855 + "notNull": false, 856 + "autoincrement": false 857 + }, 858 + "expires_at": { 859 + "name": "expires_at", 860 + "type": "integer", 861 + "primaryKey": false, 862 + "notNull": false, 863 + "autoincrement": false 864 + }, 865 + "token_type": { 866 + "name": "token_type", 867 + "type": "text", 868 + "primaryKey": false, 869 + "notNull": false, 870 + "autoincrement": false 871 + }, 872 + "scope": { 873 + "name": "scope", 874 + "type": "text", 875 + "primaryKey": false, 876 + "notNull": false, 877 + "autoincrement": false 878 + }, 879 + "id_token": { 880 + "name": "id_token", 881 + "type": "text", 882 + "primaryKey": false, 883 + "notNull": false, 884 + "autoincrement": false 885 + }, 886 + "session_state": { 887 + "name": "session_state", 888 + "type": "text", 889 + "primaryKey": false, 890 + "notNull": false, 891 + "autoincrement": false 892 + } 893 + }, 894 + "indexes": {}, 895 + "foreignKeys": { 896 + "account_user_id_user_id_fk": { 897 + "name": "account_user_id_user_id_fk", 898 + "tableFrom": "account", 899 + "tableTo": "user", 900 + "columnsFrom": [ 901 + "user_id" 902 + ], 903 + "columnsTo": [ 904 + "id" 905 + ], 906 + "onDelete": "cascade", 907 + "onUpdate": "no action" 908 + } 909 + }, 910 + "compositePrimaryKeys": { 911 + "account_provider_provider_account_id_pk": { 912 + "columns": [ 913 + "provider", 914 + "provider_account_id" 915 + ], 916 + "name": "account_provider_provider_account_id_pk" 917 + } 918 + }, 919 + "uniqueConstraints": {} 920 + }, 921 + "session": { 922 + "name": "session", 923 + "columns": { 924 + "session_token": { 925 + "name": "session_token", 926 + "type": "text", 927 + "primaryKey": true, 928 + "notNull": true, 929 + "autoincrement": false 930 + }, 931 + "user_id": { 932 + "name": "user_id", 933 + "type": "integer", 934 + "primaryKey": false, 935 + "notNull": true, 936 + "autoincrement": false 937 + }, 938 + "expires": { 939 + "name": "expires", 940 + "type": "integer", 941 + "primaryKey": false, 942 + "notNull": true, 943 + "autoincrement": false 944 + } 945 + }, 946 + "indexes": {}, 947 + "foreignKeys": { 948 + "session_user_id_user_id_fk": { 949 + "name": "session_user_id_user_id_fk", 950 + "tableFrom": "session", 951 + "tableTo": "user", 952 + "columnsFrom": [ 953 + "user_id" 954 + ], 955 + "columnsTo": [ 956 + "id" 957 + ], 958 + "onDelete": "cascade", 959 + "onUpdate": "no action" 960 + } 961 + }, 962 + "compositePrimaryKeys": {}, 963 + "uniqueConstraints": {} 964 + }, 965 + "user": { 966 + "name": "user", 967 + "columns": { 968 + "id": { 969 + "name": "id", 970 + "type": "integer", 971 + "primaryKey": true, 972 + "notNull": true, 973 + "autoincrement": false 974 + }, 975 + "tenant_id": { 976 + "name": "tenant_id", 977 + "type": "text(256)", 978 + "primaryKey": false, 979 + "notNull": false, 980 + "autoincrement": false 981 + }, 982 + "first_name": { 983 + "name": "first_name", 984 + "type": "text", 985 + "primaryKey": false, 986 + "notNull": false, 987 + "autoincrement": false, 988 + "default": "''" 989 + }, 990 + "last_name": { 991 + "name": "last_name", 992 + "type": "text", 993 + "primaryKey": false, 994 + "notNull": false, 995 + "autoincrement": false, 996 + "default": "''" 997 + }, 998 + "photo_url": { 999 + "name": "photo_url", 1000 + "type": "text", 1001 + "primaryKey": false, 1002 + "notNull": false, 1003 + "autoincrement": false, 1004 + "default": "''" 1005 + }, 1006 + "name": { 1007 + "name": "name", 1008 + "type": "text", 1009 + "primaryKey": false, 1010 + "notNull": false, 1011 + "autoincrement": false 1012 + }, 1013 + "email": { 1014 + "name": "email", 1015 + "type": "text", 1016 + "primaryKey": false, 1017 + "notNull": false, 1018 + "autoincrement": false, 1019 + "default": "''" 1020 + }, 1021 + "emailVerified": { 1022 + "name": "emailVerified", 1023 + "type": "integer", 1024 + "primaryKey": false, 1025 + "notNull": false, 1026 + "autoincrement": false 1027 + }, 1028 + "created_at": { 1029 + "name": "created_at", 1030 + "type": "integer", 1031 + "primaryKey": false, 1032 + "notNull": false, 1033 + "autoincrement": false, 1034 + "default": "(strftime('%s', 'now'))" 1035 + }, 1036 + "updated_at": { 1037 + "name": "updated_at", 1038 + "type": "integer", 1039 + "primaryKey": false, 1040 + "notNull": false, 1041 + "autoincrement": false, 1042 + "default": "(strftime('%s', 'now'))" 1043 + } 1044 + }, 1045 + "indexes": { 1046 + "user_tenant_id_unique": { 1047 + "name": "user_tenant_id_unique", 1048 + "columns": [ 1049 + "tenant_id" 1050 + ], 1051 + "isUnique": true 1052 + } 1053 + }, 1054 + "foreignKeys": {}, 1055 + "compositePrimaryKeys": {}, 1056 + "uniqueConstraints": {} 1057 + }, 1058 + "users_to_workspaces": { 1059 + "name": "users_to_workspaces", 1060 + "columns": { 1061 + "user_id": { 1062 + "name": "user_id", 1063 + "type": "integer", 1064 + "primaryKey": false, 1065 + "notNull": true, 1066 + "autoincrement": false 1067 + }, 1068 + "workspace_id": { 1069 + "name": "workspace_id", 1070 + "type": "integer", 1071 + "primaryKey": false, 1072 + "notNull": true, 1073 + "autoincrement": false 1074 + }, 1075 + "role": { 1076 + "name": "role", 1077 + "type": "text", 1078 + "primaryKey": false, 1079 + "notNull": true, 1080 + "autoincrement": false, 1081 + "default": "'member'" 1082 + }, 1083 + "created_at": { 1084 + "name": "created_at", 1085 + "type": "integer", 1086 + "primaryKey": false, 1087 + "notNull": false, 1088 + "autoincrement": false, 1089 + "default": "(strftime('%s', 'now'))" 1090 + } 1091 + }, 1092 + "indexes": {}, 1093 + "foreignKeys": { 1094 + "users_to_workspaces_user_id_user_id_fk": { 1095 + "name": "users_to_workspaces_user_id_user_id_fk", 1096 + "tableFrom": "users_to_workspaces", 1097 + "tableTo": "user", 1098 + "columnsFrom": [ 1099 + "user_id" 1100 + ], 1101 + "columnsTo": [ 1102 + "id" 1103 + ], 1104 + "onDelete": "no action", 1105 + "onUpdate": "no action" 1106 + }, 1107 + "users_to_workspaces_workspace_id_workspace_id_fk": { 1108 + "name": "users_to_workspaces_workspace_id_workspace_id_fk", 1109 + "tableFrom": "users_to_workspaces", 1110 + "tableTo": "workspace", 1111 + "columnsFrom": [ 1112 + "workspace_id" 1113 + ], 1114 + "columnsTo": [ 1115 + "id" 1116 + ], 1117 + "onDelete": "no action", 1118 + "onUpdate": "no action" 1119 + } 1120 + }, 1121 + "compositePrimaryKeys": { 1122 + "users_to_workspaces_user_id_workspace_id_pk": { 1123 + "columns": [ 1124 + "user_id", 1125 + "workspace_id" 1126 + ], 1127 + "name": "users_to_workspaces_user_id_workspace_id_pk" 1128 + } 1129 + }, 1130 + "uniqueConstraints": {} 1131 + }, 1132 + "verification_token": { 1133 + "name": "verification_token", 1134 + "columns": { 1135 + "identifier": { 1136 + "name": "identifier", 1137 + "type": "text", 1138 + "primaryKey": false, 1139 + "notNull": true, 1140 + "autoincrement": false 1141 + }, 1142 + "token": { 1143 + "name": "token", 1144 + "type": "text", 1145 + "primaryKey": false, 1146 + "notNull": true, 1147 + "autoincrement": false 1148 + }, 1149 + "expires": { 1150 + "name": "expires", 1151 + "type": "integer", 1152 + "primaryKey": false, 1153 + "notNull": true, 1154 + "autoincrement": false 1155 + } 1156 + }, 1157 + "indexes": {}, 1158 + "foreignKeys": {}, 1159 + "compositePrimaryKeys": { 1160 + "verification_token_identifier_token_pk": { 1161 + "columns": [ 1162 + "identifier", 1163 + "token" 1164 + ], 1165 + "name": "verification_token_identifier_token_pk" 1166 + } 1167 + }, 1168 + "uniqueConstraints": {} 1169 + }, 1170 + "page_subscriber": { 1171 + "name": "page_subscriber", 1172 + "columns": { 1173 + "id": { 1174 + "name": "id", 1175 + "type": "integer", 1176 + "primaryKey": true, 1177 + "notNull": true, 1178 + "autoincrement": false 1179 + }, 1180 + "email": { 1181 + "name": "email", 1182 + "type": "text", 1183 + "primaryKey": false, 1184 + "notNull": true, 1185 + "autoincrement": false 1186 + }, 1187 + "page_id": { 1188 + "name": "page_id", 1189 + "type": "integer", 1190 + "primaryKey": false, 1191 + "notNull": true, 1192 + "autoincrement": false 1193 + }, 1194 + "token": { 1195 + "name": "token", 1196 + "type": "text", 1197 + "primaryKey": false, 1198 + "notNull": false, 1199 + "autoincrement": false 1200 + }, 1201 + "accepted_at": { 1202 + "name": "accepted_at", 1203 + "type": "integer", 1204 + "primaryKey": false, 1205 + "notNull": false, 1206 + "autoincrement": false 1207 + }, 1208 + "expires_at": { 1209 + "name": "expires_at", 1210 + "type": "integer", 1211 + "primaryKey": false, 1212 + "notNull": false, 1213 + "autoincrement": false 1214 + }, 1215 + "created_at": { 1216 + "name": "created_at", 1217 + "type": "integer", 1218 + "primaryKey": false, 1219 + "notNull": false, 1220 + "autoincrement": false, 1221 + "default": "(strftime('%s', 'now'))" 1222 + }, 1223 + "updated_at": { 1224 + "name": "updated_at", 1225 + "type": "integer", 1226 + "primaryKey": false, 1227 + "notNull": false, 1228 + "autoincrement": false, 1229 + "default": "(strftime('%s', 'now'))" 1230 + } 1231 + }, 1232 + "indexes": {}, 1233 + "foreignKeys": { 1234 + "page_subscriber_page_id_page_id_fk": { 1235 + "name": "page_subscriber_page_id_page_id_fk", 1236 + "tableFrom": "page_subscriber", 1237 + "tableTo": "page", 1238 + "columnsFrom": [ 1239 + "page_id" 1240 + ], 1241 + "columnsTo": [ 1242 + "id" 1243 + ], 1244 + "onDelete": "no action", 1245 + "onUpdate": "no action" 1246 + } 1247 + }, 1248 + "compositePrimaryKeys": {}, 1249 + "uniqueConstraints": {} 1250 + }, 1251 + "notification": { 1252 + "name": "notification", 1253 + "columns": { 1254 + "id": { 1255 + "name": "id", 1256 + "type": "integer", 1257 + "primaryKey": true, 1258 + "notNull": true, 1259 + "autoincrement": false 1260 + }, 1261 + "name": { 1262 + "name": "name", 1263 + "type": "text", 1264 + "primaryKey": false, 1265 + "notNull": true, 1266 + "autoincrement": false 1267 + }, 1268 + "provider": { 1269 + "name": "provider", 1270 + "type": "text", 1271 + "primaryKey": false, 1272 + "notNull": true, 1273 + "autoincrement": false 1274 + }, 1275 + "data": { 1276 + "name": "data", 1277 + "type": "text", 1278 + "primaryKey": false, 1279 + "notNull": false, 1280 + "autoincrement": false, 1281 + "default": "'{}'" 1282 + }, 1283 + "workspace_id": { 1284 + "name": "workspace_id", 1285 + "type": "integer", 1286 + "primaryKey": false, 1287 + "notNull": false, 1288 + "autoincrement": false 1289 + }, 1290 + "created_at": { 1291 + "name": "created_at", 1292 + "type": "integer", 1293 + "primaryKey": false, 1294 + "notNull": false, 1295 + "autoincrement": false, 1296 + "default": "(strftime('%s', 'now'))" 1297 + }, 1298 + "updated_at": { 1299 + "name": "updated_at", 1300 + "type": "integer", 1301 + "primaryKey": false, 1302 + "notNull": false, 1303 + "autoincrement": false, 1304 + "default": "(strftime('%s', 'now'))" 1305 + } 1306 + }, 1307 + "indexes": {}, 1308 + "foreignKeys": { 1309 + "notification_workspace_id_workspace_id_fk": { 1310 + "name": "notification_workspace_id_workspace_id_fk", 1311 + "tableFrom": "notification", 1312 + "tableTo": "workspace", 1313 + "columnsFrom": [ 1314 + "workspace_id" 1315 + ], 1316 + "columnsTo": [ 1317 + "id" 1318 + ], 1319 + "onDelete": "no action", 1320 + "onUpdate": "no action" 1321 + } 1322 + }, 1323 + "compositePrimaryKeys": {}, 1324 + "uniqueConstraints": {} 1325 + }, 1326 + "notifications_to_monitors": { 1327 + "name": "notifications_to_monitors", 1328 + "columns": { 1329 + "monitor_id": { 1330 + "name": "monitor_id", 1331 + "type": "integer", 1332 + "primaryKey": false, 1333 + "notNull": true, 1334 + "autoincrement": false 1335 + }, 1336 + "notification_id": { 1337 + "name": "notification_id", 1338 + "type": "integer", 1339 + "primaryKey": false, 1340 + "notNull": true, 1341 + "autoincrement": false 1342 + }, 1343 + "created_at": { 1344 + "name": "created_at", 1345 + "type": "integer", 1346 + "primaryKey": false, 1347 + "notNull": false, 1348 + "autoincrement": false, 1349 + "default": "(strftime('%s', 'now'))" 1350 + } 1351 + }, 1352 + "indexes": {}, 1353 + "foreignKeys": { 1354 + "notifications_to_monitors_monitor_id_monitor_id_fk": { 1355 + "name": "notifications_to_monitors_monitor_id_monitor_id_fk", 1356 + "tableFrom": "notifications_to_monitors", 1357 + "tableTo": "monitor", 1358 + "columnsFrom": [ 1359 + "monitor_id" 1360 + ], 1361 + "columnsTo": [ 1362 + "id" 1363 + ], 1364 + "onDelete": "cascade", 1365 + "onUpdate": "no action" 1366 + }, 1367 + "notifications_to_monitors_notification_id_notification_id_fk": { 1368 + "name": "notifications_to_monitors_notification_id_notification_id_fk", 1369 + "tableFrom": "notifications_to_monitors", 1370 + "tableTo": "notification", 1371 + "columnsFrom": [ 1372 + "notification_id" 1373 + ], 1374 + "columnsTo": [ 1375 + "id" 1376 + ], 1377 + "onDelete": "cascade", 1378 + "onUpdate": "no action" 1379 + } 1380 + }, 1381 + "compositePrimaryKeys": { 1382 + "notifications_to_monitors_monitor_id_notification_id_pk": { 1383 + "columns": [ 1384 + "monitor_id", 1385 + "notification_id" 1386 + ], 1387 + "name": "notifications_to_monitors_monitor_id_notification_id_pk" 1388 + } 1389 + }, 1390 + "uniqueConstraints": {} 1391 + }, 1392 + "monitor_status": { 1393 + "name": "monitor_status", 1394 + "columns": { 1395 + "monitor_id": { 1396 + "name": "monitor_id", 1397 + "type": "integer", 1398 + "primaryKey": false, 1399 + "notNull": true, 1400 + "autoincrement": false 1401 + }, 1402 + "region": { 1403 + "name": "region", 1404 + "type": "text", 1405 + "primaryKey": false, 1406 + "notNull": true, 1407 + "autoincrement": false, 1408 + "default": "''" 1409 + }, 1410 + "status": { 1411 + "name": "status", 1412 + "type": "text", 1413 + "primaryKey": false, 1414 + "notNull": true, 1415 + "autoincrement": false, 1416 + "default": "'active'" 1417 + }, 1418 + "created_at": { 1419 + "name": "created_at", 1420 + "type": "integer", 1421 + "primaryKey": false, 1422 + "notNull": false, 1423 + "autoincrement": false, 1424 + "default": "(strftime('%s', 'now'))" 1425 + }, 1426 + "updated_at": { 1427 + "name": "updated_at", 1428 + "type": "integer", 1429 + "primaryKey": false, 1430 + "notNull": false, 1431 + "autoincrement": false, 1432 + "default": "(strftime('%s', 'now'))" 1433 + } 1434 + }, 1435 + "indexes": { 1436 + "monitor_status_idx": { 1437 + "name": "monitor_status_idx", 1438 + "columns": [ 1439 + "monitor_id", 1440 + "region" 1441 + ], 1442 + "isUnique": false 1443 + } 1444 + }, 1445 + "foreignKeys": { 1446 + "monitor_status_monitor_id_monitor_id_fk": { 1447 + "name": "monitor_status_monitor_id_monitor_id_fk", 1448 + "tableFrom": "monitor_status", 1449 + "tableTo": "monitor", 1450 + "columnsFrom": [ 1451 + "monitor_id" 1452 + ], 1453 + "columnsTo": [ 1454 + "id" 1455 + ], 1456 + "onDelete": "cascade", 1457 + "onUpdate": "no action" 1458 + } 1459 + }, 1460 + "compositePrimaryKeys": { 1461 + "monitor_status_monitor_id_region_pk": { 1462 + "columns": [ 1463 + "monitor_id", 1464 + "region" 1465 + ], 1466 + "name": "monitor_status_monitor_id_region_pk" 1467 + } 1468 + }, 1469 + "uniqueConstraints": {} 1470 + }, 1471 + "invitation": { 1472 + "name": "invitation", 1473 + "columns": { 1474 + "id": { 1475 + "name": "id", 1476 + "type": "integer", 1477 + "primaryKey": true, 1478 + "notNull": true, 1479 + "autoincrement": false 1480 + }, 1481 + "email": { 1482 + "name": "email", 1483 + "type": "text", 1484 + "primaryKey": false, 1485 + "notNull": true, 1486 + "autoincrement": false 1487 + }, 1488 + "role": { 1489 + "name": "role", 1490 + "type": "text", 1491 + "primaryKey": false, 1492 + "notNull": true, 1493 + "autoincrement": false, 1494 + "default": "'member'" 1495 + }, 1496 + "workspace_id": { 1497 + "name": "workspace_id", 1498 + "type": "integer", 1499 + "primaryKey": false, 1500 + "notNull": true, 1501 + "autoincrement": false 1502 + }, 1503 + "token": { 1504 + "name": "token", 1505 + "type": "text", 1506 + "primaryKey": false, 1507 + "notNull": true, 1508 + "autoincrement": false 1509 + }, 1510 + "expires_at": { 1511 + "name": "expires_at", 1512 + "type": "integer", 1513 + "primaryKey": false, 1514 + "notNull": true, 1515 + "autoincrement": false 1516 + }, 1517 + "created_at": { 1518 + "name": "created_at", 1519 + "type": "integer", 1520 + "primaryKey": false, 1521 + "notNull": false, 1522 + "autoincrement": false, 1523 + "default": "(strftime('%s', 'now'))" 1524 + }, 1525 + "accepted_at": { 1526 + "name": "accepted_at", 1527 + "type": "integer", 1528 + "primaryKey": false, 1529 + "notNull": false, 1530 + "autoincrement": false 1531 + } 1532 + }, 1533 + "indexes": {}, 1534 + "foreignKeys": {}, 1535 + "compositePrimaryKeys": {}, 1536 + "uniqueConstraints": {} 1537 + }, 1538 + "incident": { 1539 + "name": "incident", 1540 + "columns": { 1541 + "id": { 1542 + "name": "id", 1543 + "type": "integer", 1544 + "primaryKey": true, 1545 + "notNull": true, 1546 + "autoincrement": false 1547 + }, 1548 + "title": { 1549 + "name": "title", 1550 + "type": "text", 1551 + "primaryKey": false, 1552 + "notNull": true, 1553 + "autoincrement": false, 1554 + "default": "''" 1555 + }, 1556 + "summary": { 1557 + "name": "summary", 1558 + "type": "text", 1559 + "primaryKey": false, 1560 + "notNull": true, 1561 + "autoincrement": false, 1562 + "default": "''" 1563 + }, 1564 + "status": { 1565 + "name": "status", 1566 + "type": "text", 1567 + "primaryKey": false, 1568 + "notNull": true, 1569 + "autoincrement": false, 1570 + "default": "'triage'" 1571 + }, 1572 + "monitor_id": { 1573 + "name": "monitor_id", 1574 + "type": "integer", 1575 + "primaryKey": false, 1576 + "notNull": false, 1577 + "autoincrement": false 1578 + }, 1579 + "workspace_id": { 1580 + "name": "workspace_id", 1581 + "type": "integer", 1582 + "primaryKey": false, 1583 + "notNull": false, 1584 + "autoincrement": false 1585 + }, 1586 + "started_at": { 1587 + "name": "started_at", 1588 + "type": "integer", 1589 + "primaryKey": false, 1590 + "notNull": true, 1591 + "autoincrement": false, 1592 + "default": "(strftime('%s', 'now'))" 1593 + }, 1594 + "acknowledged_at": { 1595 + "name": "acknowledged_at", 1596 + "type": "integer", 1597 + "primaryKey": false, 1598 + "notNull": false, 1599 + "autoincrement": false 1600 + }, 1601 + "acknowledged_by": { 1602 + "name": "acknowledged_by", 1603 + "type": "integer", 1604 + "primaryKey": false, 1605 + "notNull": false, 1606 + "autoincrement": false 1607 + }, 1608 + "resolved_at": { 1609 + "name": "resolved_at", 1610 + "type": "integer", 1611 + "primaryKey": false, 1612 + "notNull": false, 1613 + "autoincrement": false 1614 + }, 1615 + "resolved_by": { 1616 + "name": "resolved_by", 1617 + "type": "integer", 1618 + "primaryKey": false, 1619 + "notNull": false, 1620 + "autoincrement": false 1621 + }, 1622 + "incident_screenshot_url": { 1623 + "name": "incident_screenshot_url", 1624 + "type": "text", 1625 + "primaryKey": false, 1626 + "notNull": false, 1627 + "autoincrement": false 1628 + }, 1629 + "recovery_screenshot_url": { 1630 + "name": "recovery_screenshot_url", 1631 + "type": "text", 1632 + "primaryKey": false, 1633 + "notNull": false, 1634 + "autoincrement": false 1635 + }, 1636 + "auto_resolved": { 1637 + "name": "auto_resolved", 1638 + "type": "integer", 1639 + "primaryKey": false, 1640 + "notNull": false, 1641 + "autoincrement": false, 1642 + "default": false 1643 + }, 1644 + "created_at": { 1645 + "name": "created_at", 1646 + "type": "integer", 1647 + "primaryKey": false, 1648 + "notNull": false, 1649 + "autoincrement": false, 1650 + "default": "(strftime('%s', 'now'))" 1651 + }, 1652 + "updated_at": { 1653 + "name": "updated_at", 1654 + "type": "integer", 1655 + "primaryKey": false, 1656 + "notNull": false, 1657 + "autoincrement": false, 1658 + "default": "(strftime('%s', 'now'))" 1659 + } 1660 + }, 1661 + "indexes": { 1662 + "incident_monitor_id_started_at_unique": { 1663 + "name": "incident_monitor_id_started_at_unique", 1664 + "columns": [ 1665 + "monitor_id", 1666 + "started_at" 1667 + ], 1668 + "isUnique": true 1669 + } 1670 + }, 1671 + "foreignKeys": { 1672 + "incident_monitor_id_monitor_id_fk": { 1673 + "name": "incident_monitor_id_monitor_id_fk", 1674 + "tableFrom": "incident", 1675 + "tableTo": "monitor", 1676 + "columnsFrom": [ 1677 + "monitor_id" 1678 + ], 1679 + "columnsTo": [ 1680 + "id" 1681 + ], 1682 + "onDelete": "set default", 1683 + "onUpdate": "no action" 1684 + }, 1685 + "incident_workspace_id_workspace_id_fk": { 1686 + "name": "incident_workspace_id_workspace_id_fk", 1687 + "tableFrom": "incident", 1688 + "tableTo": "workspace", 1689 + "columnsFrom": [ 1690 + "workspace_id" 1691 + ], 1692 + "columnsTo": [ 1693 + "id" 1694 + ], 1695 + "onDelete": "no action", 1696 + "onUpdate": "no action" 1697 + }, 1698 + "incident_acknowledged_by_user_id_fk": { 1699 + "name": "incident_acknowledged_by_user_id_fk", 1700 + "tableFrom": "incident", 1701 + "tableTo": "user", 1702 + "columnsFrom": [ 1703 + "acknowledged_by" 1704 + ], 1705 + "columnsTo": [ 1706 + "id" 1707 + ], 1708 + "onDelete": "no action", 1709 + "onUpdate": "no action" 1710 + }, 1711 + "incident_resolved_by_user_id_fk": { 1712 + "name": "incident_resolved_by_user_id_fk", 1713 + "tableFrom": "incident", 1714 + "tableTo": "user", 1715 + "columnsFrom": [ 1716 + "resolved_by" 1717 + ], 1718 + "columnsTo": [ 1719 + "id" 1720 + ], 1721 + "onDelete": "no action", 1722 + "onUpdate": "no action" 1723 + } 1724 + }, 1725 + "compositePrimaryKeys": {}, 1726 + "uniqueConstraints": {} 1727 + }, 1728 + "monitor_tag": { 1729 + "name": "monitor_tag", 1730 + "columns": { 1731 + "id": { 1732 + "name": "id", 1733 + "type": "integer", 1734 + "primaryKey": true, 1735 + "notNull": true, 1736 + "autoincrement": false 1737 + }, 1738 + "workspace_id": { 1739 + "name": "workspace_id", 1740 + "type": "integer", 1741 + "primaryKey": false, 1742 + "notNull": true, 1743 + "autoincrement": false 1744 + }, 1745 + "name": { 1746 + "name": "name", 1747 + "type": "text", 1748 + "primaryKey": false, 1749 + "notNull": true, 1750 + "autoincrement": false 1751 + }, 1752 + "color": { 1753 + "name": "color", 1754 + "type": "text", 1755 + "primaryKey": false, 1756 + "notNull": true, 1757 + "autoincrement": false 1758 + }, 1759 + "created_at": { 1760 + "name": "created_at", 1761 + "type": "integer", 1762 + "primaryKey": false, 1763 + "notNull": false, 1764 + "autoincrement": false, 1765 + "default": "(strftime('%s', 'now'))" 1766 + }, 1767 + "updated_at": { 1768 + "name": "updated_at", 1769 + "type": "integer", 1770 + "primaryKey": false, 1771 + "notNull": false, 1772 + "autoincrement": false, 1773 + "default": "(strftime('%s', 'now'))" 1774 + } 1775 + }, 1776 + "indexes": {}, 1777 + "foreignKeys": { 1778 + "monitor_tag_workspace_id_workspace_id_fk": { 1779 + "name": "monitor_tag_workspace_id_workspace_id_fk", 1780 + "tableFrom": "monitor_tag", 1781 + "tableTo": "workspace", 1782 + "columnsFrom": [ 1783 + "workspace_id" 1784 + ], 1785 + "columnsTo": [ 1786 + "id" 1787 + ], 1788 + "onDelete": "cascade", 1789 + "onUpdate": "no action" 1790 + } 1791 + }, 1792 + "compositePrimaryKeys": {}, 1793 + "uniqueConstraints": {} 1794 + }, 1795 + "monitor_tag_to_monitor": { 1796 + "name": "monitor_tag_to_monitor", 1797 + "columns": { 1798 + "monitor_id": { 1799 + "name": "monitor_id", 1800 + "type": "integer", 1801 + "primaryKey": false, 1802 + "notNull": true, 1803 + "autoincrement": false 1804 + }, 1805 + "monitor_tag_id": { 1806 + "name": "monitor_tag_id", 1807 + "type": "integer", 1808 + "primaryKey": false, 1809 + "notNull": true, 1810 + "autoincrement": false 1811 + }, 1812 + "created_at": { 1813 + "name": "created_at", 1814 + "type": "integer", 1815 + "primaryKey": false, 1816 + "notNull": false, 1817 + "autoincrement": false, 1818 + "default": "(strftime('%s', 'now'))" 1819 + } 1820 + }, 1821 + "indexes": {}, 1822 + "foreignKeys": { 1823 + "monitor_tag_to_monitor_monitor_id_monitor_id_fk": { 1824 + "name": "monitor_tag_to_monitor_monitor_id_monitor_id_fk", 1825 + "tableFrom": "monitor_tag_to_monitor", 1826 + "tableTo": "monitor", 1827 + "columnsFrom": [ 1828 + "monitor_id" 1829 + ], 1830 + "columnsTo": [ 1831 + "id" 1832 + ], 1833 + "onDelete": "cascade", 1834 + "onUpdate": "no action" 1835 + }, 1836 + "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk": { 1837 + "name": "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk", 1838 + "tableFrom": "monitor_tag_to_monitor", 1839 + "tableTo": "monitor_tag", 1840 + "columnsFrom": [ 1841 + "monitor_tag_id" 1842 + ], 1843 + "columnsTo": [ 1844 + "id" 1845 + ], 1846 + "onDelete": "cascade", 1847 + "onUpdate": "no action" 1848 + } 1849 + }, 1850 + "compositePrimaryKeys": { 1851 + "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk": { 1852 + "columns": [ 1853 + "monitor_id", 1854 + "monitor_tag_id" 1855 + ], 1856 + "name": "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk" 1857 + } 1858 + }, 1859 + "uniqueConstraints": {} 1860 + }, 1861 + "application": { 1862 + "name": "application", 1863 + "columns": { 1864 + "id": { 1865 + "name": "id", 1866 + "type": "integer", 1867 + "primaryKey": true, 1868 + "notNull": true, 1869 + "autoincrement": false 1870 + }, 1871 + "name": { 1872 + "name": "name", 1873 + "type": "text", 1874 + "primaryKey": false, 1875 + "notNull": false, 1876 + "autoincrement": false 1877 + }, 1878 + "dsn": { 1879 + "name": "dsn", 1880 + "type": "text", 1881 + "primaryKey": false, 1882 + "notNull": false, 1883 + "autoincrement": false 1884 + }, 1885 + "workspace_id": { 1886 + "name": "workspace_id", 1887 + "type": "integer", 1888 + "primaryKey": false, 1889 + "notNull": false, 1890 + "autoincrement": false 1891 + }, 1892 + "created_at": { 1893 + "name": "created_at", 1894 + "type": "integer", 1895 + "primaryKey": false, 1896 + "notNull": false, 1897 + "autoincrement": false, 1898 + "default": "(strftime('%s', 'now'))" 1899 + }, 1900 + "updated_at": { 1901 + "name": "updated_at", 1902 + "type": "integer", 1903 + "primaryKey": false, 1904 + "notNull": false, 1905 + "autoincrement": false, 1906 + "default": "(strftime('%s', 'now'))" 1907 + } 1908 + }, 1909 + "indexes": { 1910 + "application_dsn_unique": { 1911 + "name": "application_dsn_unique", 1912 + "columns": [ 1913 + "dsn" 1914 + ], 1915 + "isUnique": true 1916 + } 1917 + }, 1918 + "foreignKeys": { 1919 + "application_workspace_id_workspace_id_fk": { 1920 + "name": "application_workspace_id_workspace_id_fk", 1921 + "tableFrom": "application", 1922 + "tableTo": "workspace", 1923 + "columnsFrom": [ 1924 + "workspace_id" 1925 + ], 1926 + "columnsTo": [ 1927 + "id" 1928 + ], 1929 + "onDelete": "no action", 1930 + "onUpdate": "no action" 1931 + } 1932 + }, 1933 + "compositePrimaryKeys": {}, 1934 + "uniqueConstraints": {} 1935 + }, 1936 + "maintenance": { 1937 + "name": "maintenance", 1938 + "columns": { 1939 + "id": { 1940 + "name": "id", 1941 + "type": "integer", 1942 + "primaryKey": true, 1943 + "notNull": true, 1944 + "autoincrement": false 1945 + }, 1946 + "title": { 1947 + "name": "title", 1948 + "type": "text(256)", 1949 + "primaryKey": false, 1950 + "notNull": true, 1951 + "autoincrement": false 1952 + }, 1953 + "message": { 1954 + "name": "message", 1955 + "type": "text", 1956 + "primaryKey": false, 1957 + "notNull": true, 1958 + "autoincrement": false 1959 + }, 1960 + "from": { 1961 + "name": "from", 1962 + "type": "integer", 1963 + "primaryKey": false, 1964 + "notNull": true, 1965 + "autoincrement": false 1966 + }, 1967 + "to": { 1968 + "name": "to", 1969 + "type": "integer", 1970 + "primaryKey": false, 1971 + "notNull": true, 1972 + "autoincrement": false 1973 + }, 1974 + "workspace_id": { 1975 + "name": "workspace_id", 1976 + "type": "integer", 1977 + "primaryKey": false, 1978 + "notNull": false, 1979 + "autoincrement": false 1980 + }, 1981 + "page_id": { 1982 + "name": "page_id", 1983 + "type": "integer", 1984 + "primaryKey": false, 1985 + "notNull": false, 1986 + "autoincrement": false 1987 + }, 1988 + "created_at": { 1989 + "name": "created_at", 1990 + "type": "integer", 1991 + "primaryKey": false, 1992 + "notNull": false, 1993 + "autoincrement": false, 1994 + "default": "(strftime('%s', 'now'))" 1995 + }, 1996 + "updated_at": { 1997 + "name": "updated_at", 1998 + "type": "integer", 1999 + "primaryKey": false, 2000 + "notNull": false, 2001 + "autoincrement": false, 2002 + "default": "(strftime('%s', 'now'))" 2003 + } 2004 + }, 2005 + "indexes": {}, 2006 + "foreignKeys": { 2007 + "maintenance_workspace_id_workspace_id_fk": { 2008 + "name": "maintenance_workspace_id_workspace_id_fk", 2009 + "tableFrom": "maintenance", 2010 + "tableTo": "workspace", 2011 + "columnsFrom": [ 2012 + "workspace_id" 2013 + ], 2014 + "columnsTo": [ 2015 + "id" 2016 + ], 2017 + "onDelete": "no action", 2018 + "onUpdate": "no action" 2019 + }, 2020 + "maintenance_page_id_page_id_fk": { 2021 + "name": "maintenance_page_id_page_id_fk", 2022 + "tableFrom": "maintenance", 2023 + "tableTo": "page", 2024 + "columnsFrom": [ 2025 + "page_id" 2026 + ], 2027 + "columnsTo": [ 2028 + "id" 2029 + ], 2030 + "onDelete": "no action", 2031 + "onUpdate": "no action" 2032 + } 2033 + }, 2034 + "compositePrimaryKeys": {}, 2035 + "uniqueConstraints": {} 2036 + }, 2037 + "maintenance_to_monitor": { 2038 + "name": "maintenance_to_monitor", 2039 + "columns": { 2040 + "monitor_id": { 2041 + "name": "monitor_id", 2042 + "type": "integer", 2043 + "primaryKey": false, 2044 + "notNull": true, 2045 + "autoincrement": false 2046 + }, 2047 + "maintenance_id": { 2048 + "name": "maintenance_id", 2049 + "type": "integer", 2050 + "primaryKey": false, 2051 + "notNull": true, 2052 + "autoincrement": false 2053 + }, 2054 + "created_at": { 2055 + "name": "created_at", 2056 + "type": "integer", 2057 + "primaryKey": false, 2058 + "notNull": false, 2059 + "autoincrement": false, 2060 + "default": "(strftime('%s', 'now'))" 2061 + } 2062 + }, 2063 + "indexes": {}, 2064 + "foreignKeys": { 2065 + "maintenance_to_monitor_monitor_id_monitor_id_fk": { 2066 + "name": "maintenance_to_monitor_monitor_id_monitor_id_fk", 2067 + "tableFrom": "maintenance_to_monitor", 2068 + "tableTo": "monitor", 2069 + "columnsFrom": [ 2070 + "monitor_id" 2071 + ], 2072 + "columnsTo": [ 2073 + "id" 2074 + ], 2075 + "onDelete": "cascade", 2076 + "onUpdate": "no action" 2077 + }, 2078 + "maintenance_to_monitor_maintenance_id_maintenance_id_fk": { 2079 + "name": "maintenance_to_monitor_maintenance_id_maintenance_id_fk", 2080 + "tableFrom": "maintenance_to_monitor", 2081 + "tableTo": "maintenance", 2082 + "columnsFrom": [ 2083 + "maintenance_id" 2084 + ], 2085 + "columnsTo": [ 2086 + "id" 2087 + ], 2088 + "onDelete": "cascade", 2089 + "onUpdate": "no action" 2090 + } 2091 + }, 2092 + "compositePrimaryKeys": { 2093 + "maintenance_to_monitor_monitor_id_maintenance_id_pk": { 2094 + "columns": [ 2095 + "maintenance_id", 2096 + "monitor_id" 2097 + ], 2098 + "name": "maintenance_to_monitor_monitor_id_maintenance_id_pk" 2099 + } 2100 + }, 2101 + "uniqueConstraints": {} 2102 + }, 2103 + "check": { 2104 + "name": "check", 2105 + "columns": { 2106 + "id": { 2107 + "name": "id", 2108 + "type": "integer", 2109 + "primaryKey": true, 2110 + "notNull": true, 2111 + "autoincrement": true 2112 + }, 2113 + "regions": { 2114 + "name": "regions", 2115 + "type": "text", 2116 + "primaryKey": false, 2117 + "notNull": true, 2118 + "autoincrement": false, 2119 + "default": "''" 2120 + }, 2121 + "url": { 2122 + "name": "url", 2123 + "type": "text(4096)", 2124 + "primaryKey": false, 2125 + "notNull": true, 2126 + "autoincrement": false 2127 + }, 2128 + "headers": { 2129 + "name": "headers", 2130 + "type": "text", 2131 + "primaryKey": false, 2132 + "notNull": false, 2133 + "autoincrement": false, 2134 + "default": "''" 2135 + }, 2136 + "body": { 2137 + "name": "body", 2138 + "type": "text", 2139 + "primaryKey": false, 2140 + "notNull": false, 2141 + "autoincrement": false, 2142 + "default": "''" 2143 + }, 2144 + "method": { 2145 + "name": "method", 2146 + "type": "text", 2147 + "primaryKey": false, 2148 + "notNull": false, 2149 + "autoincrement": false, 2150 + "default": "'GET'" 2151 + }, 2152 + "count_requests": { 2153 + "name": "count_requests", 2154 + "type": "integer", 2155 + "primaryKey": false, 2156 + "notNull": false, 2157 + "autoincrement": false, 2158 + "default": 1 2159 + }, 2160 + "workspace_id": { 2161 + "name": "workspace_id", 2162 + "type": "integer", 2163 + "primaryKey": false, 2164 + "notNull": false, 2165 + "autoincrement": false 2166 + }, 2167 + "created_at": { 2168 + "name": "created_at", 2169 + "type": "integer", 2170 + "primaryKey": false, 2171 + "notNull": false, 2172 + "autoincrement": false, 2173 + "default": "(strftime('%s', 'now'))" 2174 + } 2175 + }, 2176 + "indexes": {}, 2177 + "foreignKeys": { 2178 + "check_workspace_id_workspace_id_fk": { 2179 + "name": "check_workspace_id_workspace_id_fk", 2180 + "tableFrom": "check", 2181 + "tableTo": "workspace", 2182 + "columnsFrom": [ 2183 + "workspace_id" 2184 + ], 2185 + "columnsTo": [ 2186 + "id" 2187 + ], 2188 + "onDelete": "no action", 2189 + "onUpdate": "no action" 2190 + } 2191 + }, 2192 + "compositePrimaryKeys": {}, 2193 + "uniqueConstraints": {} 2194 + }, 2195 + "monitor_run": { 2196 + "name": "monitor_run", 2197 + "columns": { 2198 + "id": { 2199 + "name": "id", 2200 + "type": "integer", 2201 + "primaryKey": true, 2202 + "notNull": true, 2203 + "autoincrement": false 2204 + }, 2205 + "workspace_id": { 2206 + "name": "workspace_id", 2207 + "type": "integer", 2208 + "primaryKey": false, 2209 + "notNull": false, 2210 + "autoincrement": false 2211 + }, 2212 + "monitor_id": { 2213 + "name": "monitor_id", 2214 + "type": "integer", 2215 + "primaryKey": false, 2216 + "notNull": false, 2217 + "autoincrement": false 2218 + }, 2219 + "runned_at": { 2220 + "name": "runned_at", 2221 + "type": "integer", 2222 + "primaryKey": false, 2223 + "notNull": false, 2224 + "autoincrement": false 2225 + }, 2226 + "created_at": { 2227 + "name": "created_at", 2228 + "type": "integer", 2229 + "primaryKey": false, 2230 + "notNull": false, 2231 + "autoincrement": false, 2232 + "default": "(strftime('%s', 'now'))" 2233 + } 2234 + }, 2235 + "indexes": {}, 2236 + "foreignKeys": { 2237 + "monitor_run_workspace_id_workspace_id_fk": { 2238 + "name": "monitor_run_workspace_id_workspace_id_fk", 2239 + "tableFrom": "monitor_run", 2240 + "tableTo": "workspace", 2241 + "columnsFrom": [ 2242 + "workspace_id" 2243 + ], 2244 + "columnsTo": [ 2245 + "id" 2246 + ], 2247 + "onDelete": "no action", 2248 + "onUpdate": "no action" 2249 + }, 2250 + "monitor_run_monitor_id_monitor_id_fk": { 2251 + "name": "monitor_run_monitor_id_monitor_id_fk", 2252 + "tableFrom": "monitor_run", 2253 + "tableTo": "monitor", 2254 + "columnsFrom": [ 2255 + "monitor_id" 2256 + ], 2257 + "columnsTo": [ 2258 + "id" 2259 + ], 2260 + "onDelete": "no action", 2261 + "onUpdate": "no action" 2262 + } 2263 + }, 2264 + "compositePrimaryKeys": {}, 2265 + "uniqueConstraints": {} 2266 + } 2267 + }, 2268 + "enums": {}, 2269 + "_meta": { 2270 + "schemas": {}, 2271 + "tables": {}, 2272 + "columns": {} 2273 + }, 2274 + "internal": { 2275 + "indexes": {} 2276 + } 2277 + }
+7
packages/db/drizzle/meta/_journal.json
··· 267 267 "when": 1729533101998, 268 268 "tag": "0037_equal_beyonder", 269 269 "breakpoints": true 270 + }, 271 + { 272 + "idx": 38, 273 + "version": "6", 274 + "when": 1729579461221, 275 + "tag": "0038_foamy_stardust", 276 + "breakpoints": true 270 277 } 271 278 ] 272 279 }
+1
packages/db/src/schema/index.ts
··· 14 14 export * from "./applications"; 15 15 export * from "./maintenances"; 16 16 export * from "./check"; 17 + export * from "./monitor_run";
+1
packages/db/src/schema/monitor_run/index.ts
··· 1 + export * from "./monitor_run";
+17
packages/db/src/schema/monitor_run/monitor_run.ts
··· 1 + import { sql } from "drizzle-orm"; 2 + import { integer, sqliteTable } from "drizzle-orm/sqlite-core"; 3 + import { monitor } from "../monitors"; 4 + import { workspace } from "../workspaces/workspace"; 5 + 6 + export const monitorRun = sqliteTable("monitor_run", { 7 + id: integer("id").primaryKey(), 8 + 9 + workspaceId: integer("workspace_id").references(() => workspace.id), 10 + monitorId: integer("monitor_id").references(() => monitor.id), 11 + 12 + runnedAt: integer("runned_at", { mode: "timestamp" }), 13 + 14 + createdAt: integer("created_at", { mode: "timestamp" }).default( 15 + sql`(strftime('%s', 'now'))`, 16 + ), 17 + });
+6 -6
packages/db/src/schema/plan/config.ts
··· 1 1 import type { WorkspacePlan } from "../workspaces/validation"; 2 - import type { Limits, LimitsV1, LimitsV2 } from "./schema"; 2 + import type { Limits } from "./schema"; 3 3 4 4 // TODO: rename to `planConfig` 5 5 export const allPlans: Record< ··· 8 8 title: "Hobby" | "Starter" | "Growth" | "Pro"; 9 9 description: string; 10 10 price: number; 11 - limits: Limits & { "private-locations": boolean }; 11 + limits: Limits; 12 12 } 13 13 > = { 14 14 free: { ··· 17 17 price: 0, 18 18 limits: { 19 19 monitors: 1, 20 - "synthetic-checks": 1000, 20 + "synthetic-checks": 30, 21 21 periodicity: ["10m", "30m", "1h"], 22 22 "multi-region": true, 23 23 "max-regions": 6, ··· 44 44 price: 30, 45 45 limits: { 46 46 monitors: 5, 47 - "synthetic-checks": 10000, 47 + "synthetic-checks": 100, 48 48 periodicity: ["1m", "5m", "10m", "30m", "1h"], 49 49 "multi-region": true, 50 50 "max-regions": 35, ··· 107 107 price: 100, 108 108 limits: { 109 109 monitors: 15, 110 - "synthetic-checks": 50000, 110 + "synthetic-checks": 300, 111 111 periodicity: ["30s", "1m", "5m", "10m", "30m", "1h"], 112 112 "multi-region": true, 113 113 "max-regions": 35, ··· 170 170 price: 300, 171 171 limits: { 172 172 monitors: 50, 173 - "synthetic-checks": 150000, 173 + "synthetic-checks": 500, 174 174 periodicity: ["30s", "1m", "5m", "10m", "30m", "1h"], 175 175 "multi-region": true, 176 176 "max-regions": 35,
+1 -1
packages/db/src/schema/plan/schema.ts
··· 37 37 38 38 export type LimitsV2 = z.infer<typeof limitsV2>; 39 39 40 - const unknownLimit = z.discriminatedUnion("version", [limitsV1]); 40 + const unknownLimit = z.discriminatedUnion("version", [limitsV1, limitsV2]); 41 41 42 42 export function migrateFromV1ToV2({ data }: { data: LimitsV1 }) { 43 43 return {
+23
packages/tinybird/pipes/get_result_for_on_demand_check_http.pipe
··· 1 + VERSION 0 2 + 3 + NODE get_result_for_on_demand_check_http_0 4 + SQL > 5 + 6 + % 7 + SELECT 8 + latency, 9 + monitorId, 10 + error, 11 + region, 12 + statusCode, 13 + timestamp, 14 + url, 15 + workspaceId, 16 + timing 17 + FROM __ttl_45d_all_mv__v1 18 + where 19 + cronTimestamp = {{ String(cronTimestamp, '1') }} 20 + and monitorId = {{ String(monitorId, '1') }} 21 + and url = {{ String(url , 'https://www.openstatus.dev') }} 22 + 23 +
+47
packages/tinybird/src/os-client.ts
··· 460 460 } 461 461 }; 462 462 } 463 + 464 + getResultForOnDemandCheckHttp() { 465 + const parameters = z.object({ 466 + monitorId: z.number().int(), 467 + timestamp: z.number(), 468 + url: z.string(), 469 + }); 470 + return async (props: z.infer<typeof parameters>) => { 471 + try { 472 + const res = await this.tb.buildPipe({ 473 + pipe: "get_result_for_on_demand_check_http", 474 + parameters, 475 + data: z.object({ 476 + latency: z.number().int(), // in ms 477 + statusCode: z.number().int().nullable().default(null), 478 + monitorId: z.string().default(""), 479 + url: z.string().url().optional(), 480 + error: z 481 + .number() 482 + .default(0) 483 + .transform((val) => val !== 0), 484 + region: z.enum(flyRegions), 485 + timestamp: z.number().int().optional(), 486 + message: z.string().nullable().optional(), 487 + timing: z 488 + .string() 489 + .nullable() 490 + .optional() 491 + .transform((val) => { 492 + if (!val) return null; 493 + const value = timingSchema.safeParse(JSON.parse(val)); 494 + if (value.success) return value.data; 495 + return null; 496 + }), 497 + }), 498 + opts: { 499 + next: { 500 + revalidate: MIN_CACHE, 501 + }, 502 + }, 503 + })(props); 504 + return res.data[0]; 505 + } catch (e) { 506 + console.error(e); 507 + } 508 + }; 509 + } 463 510 } 464 511 465 512 /**
+31
packages/utils/index.ts
··· 5 5 6 6 import type { MonitorFlyRegion } from "@openstatus/db/src/schema/constants"; 7 7 8 + import { base } from "@openstatus/assertions"; 9 + import { monitorMethods, monitorStatus } from "@openstatus/db/src/schema"; 10 + 11 + import { z } from "zod"; 8 12 // export const vercelRegionsDict = { 9 13 // /** 10 14 // * A random location will be chosen ··· 428 432 // export const availableRegions = [...vercelRegions, ...flyRegions] as const; 429 433 430 434 // export const regionsDict = { ...vercelRegionsDict, ...flyRegionsDict } as const; 435 + 436 + export const httpPayloadSchema = z.object({ 437 + workspaceId: z.string(), 438 + monitorId: z.string(), 439 + method: z.enum(monitorMethods), 440 + body: z.string().optional(), 441 + headers: z.array(z.object({ key: z.string(), value: z.string() })).optional(), 442 + url: z.string(), 443 + cronTimestamp: z.number(), 444 + status: z.enum(monitorStatus), 445 + assertions: z.array(base).nullable(), 446 + timeout: z.number().default(45000), 447 + degradedAfter: z.number().nullable(), 448 + }); 449 + 450 + export type HttpPayload = z.infer<typeof httpPayloadSchema>; 451 + 452 + export const tpcPayloadSchema = z.object({ 453 + status: z.enum(monitorStatus), 454 + workspaceId: z.string(), 455 + url: z.string(), 456 + monitorId: z.string(), 457 + assertions: z.array(base).nullable(), 458 + cronTimestamp: z.number(), 459 + timeout: z.number().default(45000), 460 + degradedAfter: z.number().nullable(), 461 + });
+3 -1
packages/utils/package.json
··· 6 6 "scripts": {}, 7 7 "dependencies": {}, 8 8 "devDependencies": { 9 + "@openstatus/assertions": "workspace:*", 9 10 "@openstatus/db": "workspace:*", 10 11 "@openstatus/tsconfig": "workspace:*", 11 - "typescript": "5.5.2" 12 + "typescript": "5.5.2", 13 + "zod": "3.23.8" 12 14 }, 13 15 "keywords": [], 14 16 "author": "",
+15 -11
pnpm-lock.yaml
··· 124 124 version: link:../../packages/utils 125 125 '@scalar/hono-api-reference': 126 126 specifier: 0.5.131 127 - version: 0.5.131(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2) 127 + version: 0.5.131(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2) 128 128 '@t3-oss/env-core': 129 129 specifier: 0.7.1 130 130 version: 0.7.1(typescript@5.5.2)(zod@3.23.8) ··· 1084 1084 1085 1085 packages/utils: 1086 1086 devDependencies: 1087 + '@openstatus/assertions': 1088 + specifier: workspace:* 1089 + version: link:../assertions 1087 1090 '@openstatus/db': 1088 1091 specifier: workspace:* 1089 1092 version: link:../db ··· 1093 1096 typescript: 1094 1097 specifier: 5.5.2 1095 1098 version: 5.5.2 1099 + zod: 1100 + specifier: 3.23.8 1101 + version: 3.23.8 1096 1102 1097 1103 packages: 1098 1104 ··· 2247 2253 2248 2254 '@esbuild-kit/core-utils@3.3.2': 2249 2255 resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} 2256 + deprecated: 'Merged into tsx: https://tsx.is' 2250 2257 2251 2258 '@esbuild-kit/esm-loader@2.6.5': 2252 2259 resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} 2260 + deprecated: 'Merged into tsx: https://tsx.is' 2253 2261 2254 2262 '@esbuild-plugins/node-resolve@0.1.4': 2255 2263 resolution: {integrity: sha512-haFQ0qhxEpqtWWY0kx1Y5oE3sMyO1PcoSiWEPrAw6tm/ZOOLXjSs6Q+v1v9eyuVF0nNt50YEvrcrvENmyoMv5g==} ··· 12105 12113 dependencies: 12106 12114 tailwindcss: 3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)) 12107 12115 12108 - '@headlessui/tailwindcss@0.2.0(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))': 12109 - dependencies: 12110 - tailwindcss: 3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)) 12111 - 12112 12116 '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))': 12113 12117 dependencies: 12114 12118 tailwindcss: 3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)) ··· 13654 13658 optionalDependencies: 13655 13659 rollup: 2.78.0 13656 13660 13657 - '@scalar/api-client@2.0.45(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2)': 13661 + '@scalar/api-client@2.0.45(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2)': 13658 13662 dependencies: 13659 - '@headlessui/tailwindcss': 0.2.0(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2))) 13663 + '@headlessui/tailwindcss': 0.2.0(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2))) 13660 13664 '@headlessui/vue': 1.7.22(vue@3.4.31(typescript@5.5.2)) 13661 13665 '@scalar/components': 0.12.28(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(typescript@5.5.2) 13662 13666 '@scalar/draggable': 0.1.4(typescript@5.5.2) ··· 13692 13696 - typescript 13693 13697 - vitest 13694 13698 13695 - '@scalar/api-reference@1.24.70(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2)': 13699 + '@scalar/api-reference@1.24.70(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2)': 13696 13700 dependencies: 13697 13701 '@floating-ui/vue': 1.1.1(vue@3.4.31(typescript@5.5.2)) 13698 13702 '@headlessui/vue': 1.7.22(vue@3.4.31(typescript@5.5.2)) 13699 - '@scalar/api-client': 2.0.45(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2) 13703 + '@scalar/api-client': 2.0.45(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2) 13700 13704 '@scalar/components': 0.12.28(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(typescript@5.5.2) 13701 13705 '@scalar/oas-utils': 0.2.26(typescript@5.5.2) 13702 13706 '@scalar/openapi-parser': 0.7.2 ··· 13781 13785 transitivePeerDependencies: 13782 13786 - typescript 13783 13787 13784 - '@scalar/hono-api-reference@0.5.131(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2)': 13788 + '@scalar/hono-api-reference@0.5.131(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2)': 13785 13789 dependencies: 13786 - '@scalar/api-reference': 1.24.70(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.8.0)(typescript@5.5.2)))(typescript@5.5.2) 13790 + '@scalar/api-reference': 1.24.70(postcss@8.4.38)(storybook@8.2.1(@babel/preset-env@7.24.8(@babel/core@7.24.8))(bufferutil@4.0.8)(utf-8-validate@6.0.4))(tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2)))(typescript@5.5.2) 13787 13791 hono: 4.5.3 13788 13792 transitivePeerDependencies: 13789 13793 - '@jest/globals'