From 57c9e0efbcf0e6e8607ebaaddf9a1687f288d64e Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Thu, 25 Jun 2026 21:17:58 +0200 Subject: [PATCH 01/69] chore: include resolved in email subject (#2313) --- .../emails/src/client.integration.test.tsx | 26 +++++++++++++++++++ packages/emails/src/client.tsx | 11 +++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/emails/src/client.integration.test.tsx b/packages/emails/src/client.integration.test.tsx index caf8671d..9733456f 100644 --- a/packages/emails/src/client.integration.test.tsx +++ b/packages/emails/src/client.integration.test.tsx @@ -5,6 +5,7 @@ import { describe, expect, test } from "bun:test"; import { render } from "react-email"; import StatusReportEmail from "../emails/status-report"; +import { statusReportSubject } from "./client"; describe("Status Report Email - Unsubscribe Link in Body", () => { const unsubscribeUrl = @@ -83,6 +84,31 @@ describe("Status Report Email - Unsubscribe Link in Body", () => { }); }); +describe("Status Report Email - Subject Line", () => { + const reportTitle = "API Outage"; + + test('prepends "RESOLVED:" only when status is "resolved"', () => { + expect(statusReportSubject({ status: "resolved", reportTitle })).toBe( + `RESOLVED: ${reportTitle}`, + ); + }); + + test('does not prepend "RESOLVED:" for any non-resolved status', () => { + const nonResolved = [ + "investigating", + "identified", + "monitoring", + "maintenance", + ] as const; + + for (const status of nonResolved) { + const subject = statusReportSubject({ status, reportTitle }); + expect(subject).toBe(reportTitle); + expect(subject).not.toContain("RESOLVED:"); + } + }); +}); + describe("Status Report Email - Email Content Validation", () => { test("should include all required email fields", async () => { const props = { diff --git a/packages/emails/src/client.tsx b/packages/emails/src/client.tsx index 61775152..ce7b7a68 100644 --- a/packages/emails/src/client.tsx +++ b/packages/emails/src/client.tsx @@ -17,6 +17,15 @@ import TeamInvitationEmail from "../emails/team-invitation"; import type { TeamInvitationProps } from "../emails/team-invitation"; import { monitorAlertEmail } from "../hotfix/monitor-alert"; +export function statusReportSubject(req: { + status: StatusReportProps["status"]; + reportTitle: string; +}): string { + return req.status === "resolved" + ? `RESOLVED: ${req.reportTitle}` + : req.reportTitle; +} + // split an array into chunks of a given size. function chunk(array: T[], size: number): T[][] { const result: T[][] = []; @@ -176,7 +185,7 @@ export class EmailClient { const manageUrl = `${statusPageBaseUrl}/manage/${subscriber.token}`; return { from: `${req.pageTitle} `, - subject: req.reportTitle, + subject: statusReportSubject(req), to: subscriber.email, react: ( Date: Fri, 26 Jun 2026 08:44:56 +0200 Subject: [PATCH 02/69] cbore: extend component impact (#2314) * cbore: extend component impact * fix: remove unused changed prop * fix: review --- apps/web/next-env.d.ts | 2 +- .../src/channels/webhook.test.ts | 70 +++++++++++++++++-- .../subscriptions/src/channels/webhook.ts | 60 ++++++++++------ packages/subscriptions/src/dispatcher.ts | 21 ++++++ packages/subscriptions/src/payload.ts | 68 ++++++++++++++++++ packages/subscriptions/src/types.ts | 24 ++++--- 6 files changed, 209 insertions(+), 36 deletions(-) create mode 100644 packages/subscriptions/src/payload.ts diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index c4b7818f..9edff1c7 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/packages/subscriptions/src/channels/webhook.test.ts b/packages/subscriptions/src/channels/webhook.test.ts index acb94676..640e933d 100644 --- a/packages/subscriptions/src/channels/webhook.test.ts +++ b/packages/subscriptions/src/channels/webhook.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { webhookPayloadSchema } from "../payload"; import type { PageUpdate, Subscription } from "../types"; import { buildGenericPayload, @@ -306,15 +307,24 @@ describe("buildGenericPayload", () => { message: "Looking into it.", date: "2026-04-21T09:59:58Z", updateId: 42, - pageComponentsWithId: [{ id: 7, name: "API" }], + componentsWithImpact: [ + { id: 7, name: "API", impact: "major_outage" }, + { + id: 8, + name: "Dashboard", + impact: "degraded_performance", + }, + ], }); const payload = buildGenericPayload(update, sub, links) as { + version: string; type: string; data: { status_report: Record }; subscription: { manage_url: string; unsubscribe_url: string }; }; + expect(payload.version).toBe("1"); expect(payload.type).toBe("status_report"); expect(payload.data.status_report).toMatchObject({ id: 12, @@ -325,8 +335,20 @@ describe("buildGenericPayload", () => { message: "Looking into it.", created_at: "2026-04-21T09:59:58Z", }, - page: { id: 42, name: "Acme", slug: "acme" }, - components: [{ id: 7, name: "API" }], + page: { + id: 42, + name: "Acme", + slug: "acme", + url: "https://acme.openstatus.dev", + }, + components: [ + { id: 7, name: "API", impact: "major_outage" }, + { + id: 8, + name: "Dashboard", + impact: "degraded_performance", + }, + ], }); expect(payload.subscription).toEqual({ manage_url: links.manageUrl, @@ -347,10 +369,12 @@ describe("buildGenericPayload", () => { }); const payload = buildGenericPayload(update, sub, links) as { + version: string; type: string; data: { maintenance: Record }; }; + expect(payload.version).toBe("1"); expect(payload.type).toBe("maintenance"); expect(payload.data.maintenance).toMatchObject({ id: 17, @@ -358,11 +382,47 @@ describe("buildGenericPayload", () => { message: "Rolling primary.", starts_at: "2026-04-22T02:00:00Z", ends_at: "2026-04-22T03:00:00Z", - page: { id: 42, name: "Acme", slug: "acme" }, - components: [{ id: 7, name: "API" }], + page: { + id: 42, + name: "Acme", + slug: "acme", + url: "https://acme.openstatus.dev", + }, + // maintenance has no per-component impact: falls back to operational + components: [{ id: 7, name: "API", impact: "operational" }], }); expect(payload.data.maintenance).not.toHaveProperty("status"); }); + + test("output satisfies the canonical webhookPayloadSchema contract", () => { + const sub = makeSub({ pageId: 42, pageName: "Acme", pageSlug: "acme" }); + const report = buildGenericPayload( + makeUpdate({ + id: 12, + status: "investigating", + updateId: 42, + componentsWithImpact: [ + { id: 7, name: "API", impact: "partial_outage" }, + ], + }), + sub, + links, + ); + const maintenance = buildGenericPayload( + makeUpdate({ + id: 17, + status: "maintenance", + startsAt: "2026-04-22T02:00:00Z", + endsAt: "2026-04-22T03:00:00Z", + pageComponentsWithId: [{ id: 7, name: "API" }], + }), + sub, + links, + ); + + expect(webhookPayloadSchema.safeParse(report).success).toBe(true); + expect(webhookPayloadSchema.safeParse(maintenance).success).toBe(true); + }); }); // ─── buildTestPayload ───────────────────────────────────────────────────────── diff --git a/packages/subscriptions/src/channels/webhook.ts b/packages/subscriptions/src/channels/webhook.ts index 25b09e1c..94d0402f 100644 --- a/packages/subscriptions/src/channels/webhook.ts +++ b/packages/subscriptions/src/channels/webhook.ts @@ -2,12 +2,14 @@ import { COLORS, COLOR_DECIMALS } from "@openstatus/notification-base"; import { assertSafeUrl } from "@openstatus/utils"; import { z } from "zod"; +import { WEBHOOK_PAYLOAD_VERSION } from "../payload"; import type { PageUpdate, Subscription } from "../types"; export type WebhookFlavor = "slack" | "discord" | "generic"; const SLACK_PREFIX = "https://hooks.slack.com/services/"; const DISCORD_PREFIX = "https://discord.com/api/webhooks/"; +const TIMEOUT_MS = 5000; // 5 seconds /** * Classify a webhook URL by its incoming-webhook origin so we can emit @@ -60,19 +62,20 @@ function statusColor(status: PageUpdate["status"]): StatusColor { } } +const webhookConfigSchema = z.object({ + headers: z + .array( + z.object({ + key: z.string().min(1), + value: z.string(), + }), + ) + .optional(), + secret: z.string().optional(), +}); + export async function validateWebhookConfig(config: unknown) { - const schema = z.object({ - headers: z - .array( - z.object({ - key: z.string().min(1), - value: z.string(), - }), - ) - .optional(), - secret: z.string().optional(), - }); - const result = schema.safeParse(config); + const result = webhookConfigSchema.safeParse(config); return { valid: result.success, error: result.error?.message }; } @@ -99,7 +102,7 @@ export async function sendWebhookVerification( token: subscription.token, verifyUrl, }), - signal: AbortSignal.timeout(10000), + signal: AbortSignal.timeout(TIMEOUT_MS), }); if (!response.ok) { @@ -255,10 +258,19 @@ export function buildGenericPayload( id: subscription.pageId, name: subscription.pageName, slug: subscription.pageSlug, + url: resolveStatusPageOrigin(subscription), }; const components = - pageUpdate.pageComponentsWithId ?? - pageUpdate.pageComponents.map((name, i) => ({ id: i, name })); + pageUpdate.componentsWithImpact ?? + pageUpdate.pageComponentsWithId?.map((c) => ({ + ...c, + impact: "operational" as const, + })) ?? + pageUpdate.pageComponents.map((name, i) => ({ + id: i, // synthetic id: legacy bare-names path has no real pageComponentId + name, + impact: "operational" as const, + })); const subscriptionBlock = { manage_url: links.manageUrl, unsubscribe_url: links.unsubscribeUrl, @@ -266,6 +278,7 @@ export function buildGenericPayload( if (pageUpdate.status === "maintenance") { return { + version: WEBHOOK_PAYLOAD_VERSION, type: "maintenance" as const, data: { maintenance: { @@ -282,7 +295,12 @@ export function buildGenericPayload( }; } + if (pageUpdate.updateId == null) { + throw new Error("status_report webhook payload requires updateId"); + } + return { + version: WEBHOOK_PAYLOAD_VERSION, type: "status_report" as const, data: { status_report: { @@ -360,11 +378,9 @@ export async function sendWebhookNotifications( "User-Agent": "OpenStatus-Webhooks/1.0", }; - if (config.headers) { - for (const header of config.headers as { - key: string; - value: string; - }[]) { + const parsedConfig = webhookConfigSchema.safeParse(config); + if (parsedConfig.success) { + for (const header of parsedConfig.data.headers ?? []) { headers[header.key] = header.value; } } @@ -375,7 +391,7 @@ export async function sendWebhookNotifications( method: "POST", headers, body: JSON.stringify(payload), - signal: AbortSignal.timeout(10000), + signal: AbortSignal.timeout(TIMEOUT_MS), }); if (!response.ok) { @@ -468,7 +484,7 @@ export async function sendTestWebhookRequest(input: { method: "POST", headers, body: JSON.stringify(buildTestPayload(flavor)), - signal: AbortSignal.timeout(10000), + signal: AbortSignal.timeout(TIMEOUT_MS), }); if (!response.ok) { diff --git a/packages/subscriptions/src/dispatcher.ts b/packages/subscriptions/src/dispatcher.ts index f06aab70..08e51301 100644 --- a/packages/subscriptions/src/dispatcher.ts +++ b/packages/subscriptions/src/dispatcher.ts @@ -5,6 +5,7 @@ import { pageSubscriber, statusReportUpdate, } from "@openstatus/db/src/schema"; +import { currentImpactsFromUpdates } from "@openstatus/db/src/schema/page_components/constants"; import { getChannel } from "./channels"; import type { PageUpdate, Subscription } from "./types"; @@ -18,9 +19,15 @@ export async function dispatchStatusReportUpdate(statusReportUpdateId: number) { with: { statusReport: { with: { + // Membership: the full set of components on the report (id + name). statusReportsToPageComponents: { with: { pageComponent: true }, }, + // All updates' impact rows — current state is reconstructed from the + // delta history, not from any single update's rows. + statusReportUpdates: { + with: { statusReportUpdateToPageComponents: true }, + }, }, }, }, @@ -40,6 +47,19 @@ export async function dispatchStatusReportUpdate(statusReportUpdateId: number) { (i) => i.pageComponent, ); + const currentImpacts = currentImpactsFromUpdates( + update.statusReport.statusReportUpdates.map((u) => ({ + id: u.id, + date: u.date, + componentImpacts: u.statusReportUpdateToPageComponents, + })), + ); + const componentsWithImpact = pageComponents.map((c) => ({ + id: c.id, + name: c.name, + impact: currentImpacts.get(c.id) ?? "operational", + })); + await dispatchPageUpdate({ id: update.statusReport.id, pageId: update.statusReport.pageId, @@ -54,6 +74,7 @@ export async function dispatchStatusReportUpdate(statusReportUpdateId: number) { id: c.id, name: c.name, })), + componentsWithImpact, }); } diff --git a/packages/subscriptions/src/payload.ts b/packages/subscriptions/src/payload.ts new file mode 100644 index 00000000..aeba254e --- /dev/null +++ b/packages/subscriptions/src/payload.ts @@ -0,0 +1,68 @@ +import { pageComponentImpactSchema } from "@openstatus/db/src/schema/page_components/validation"; +import { statusReportStatusSchema } from "@openstatus/db/src/schema/status_reports/validation"; +import { z } from "zod"; + +/** Bump on any breaking change — external consumers (statuspage-socials-notifier) pin to this version. */ +export const WEBHOOK_PAYLOAD_VERSION = "1" as const; + +const componentSchema = z.object({ + id: z.number().int(), + name: z.string(), + impact: pageComponentImpactSchema, +}); + +const pageSchema = z.object({ + id: z.number().int(), + name: z.string(), + slug: z.string(), + url: z.url(), +}); + +const subscriptionSchema = z.object({ + manage_url: z.string().nullable(), + unsubscribe_url: z.string().nullable(), +}); + +export const statusReportWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("status_report"), + data: z.object({ + status_report: z.object({ + id: z.number().int(), + title: z.string(), + update: z.object({ + id: z.number().int(), + status: statusReportStatusSchema, + message: z.string(), + created_at: z.string(), + }), + page: pageSchema, + components: z.array(componentSchema), + }), + }), + subscription: subscriptionSchema, +}); + +export const maintenanceWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("maintenance"), + data: z.object({ + maintenance: z.object({ + id: z.number().int(), + title: z.string(), + message: z.string(), + starts_at: z.string().optional(), + ends_at: z.string().optional(), + page: pageSchema, + components: z.array(componentSchema), + }), + }), + subscription: subscriptionSchema, +}); + +export const webhookPayloadSchema = z.discriminatedUnion("type", [ + statusReportWebhookSchema, + maintenanceWebhookSchema, +]); + +export type WebhookPayload = z.infer; diff --git a/packages/subscriptions/src/types.ts b/packages/subscriptions/src/types.ts index 908f0fca..f0c95d7c 100644 --- a/packages/subscriptions/src/types.ts +++ b/packages/subscriptions/src/types.ts @@ -1,17 +1,19 @@ // Core types for the subscription system +import type { PageComponentImpact } from "@openstatus/db/src/schema/page_components/constants"; + export interface Subscription { id: number; pageId: number; - pageName: string; // For templates - pageSlug: string; // For management URLs - customDomain?: string | null; // For custom domain URLs + pageName: string; + pageSlug: string; + customDomain?: string | null; componentIds: number[]; // Empty = entire page - // Channel (only ONE identifier populated based on channelType) + // Only ONE identifier populated based on channelType channelType: "email" | "webhook"; - email?: string; // For email channel - webhookUrl?: string; // For webhook channel + email?: string; + webhookUrl?: string; channelConfig?: string; // JSON string for headers, secrets, etc. token?: string; @@ -34,8 +36,8 @@ export interface PageUpdate { | "resolved" | "maintenance"; message: string; - pageComponentIds: number[]; // For subscription matching - pageComponents: string[]; // Component names for display + pageComponentIds: number[]; + pageComponents: string[]; date: string; // can be single string or "from - to" // Optional fields consumed by the prepared (staged) generic webhook payload. @@ -43,6 +45,12 @@ export interface PageUpdate { // builders, which key off the fields above. updateId?: number; // statusReportUpdate.id (status reports only) pageComponentsWithId?: { id: number; name: string }[]; + // Current impact per component as of this update (not the raw delta). + componentsWithImpact?: { + id: number; + name: string; + impact: PageComponentImpact; + }[]; startsAt?: string; // maintenance only, ISO endsAt?: string; // maintenance only, ISO } -- 2.51.2 From 3a8ab6b959fe7b8608637a0673ca70b725cfca14 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:04:15 +0200 Subject: [PATCH 03/69] fix: dashboard subscribers notify (webhook only) (#2315) * fix: dashboard subscribers notify * chore: include idempontency key on resend emails * chore: minor changes * chore: include effect retry on webhook * chore: enable generic webhooks * wip: * refactor: mutateAsync to mutate --- .../status-pages/[id]/maintenances/page.tsx | 10 +- .../[id]/status-reports/[reportId]/page.tsx | 4 +- .../status-pages/[id]/status-reports/page.tsx | 8 +- .../status-report-updates/data-table.tsx | 6 +- .../status-reports/data-table-row-actions.tsx | 6 +- .../src/components/forms/subscriber/form.tsx | 18 +- packages/analytics/src/events.ts | 8 + packages/api/src/router/email/index.ts | 37 ---- packages/api/src/router/maintenance.ts | 16 ++ packages/api/src/router/pageSubscriber.ts | 7 +- packages/api/src/router/statusReport.ts | 26 ++- packages/emails/src/client.test.ts | 115 ++++++++++++ packages/emails/src/client.tsx | 35 +++- .../services/src/page-subscriber/create.ts | 6 - .../services/src/page-subscriber/internal.ts | 1 - .../services/src/page-subscriber/update.ts | 8 +- packages/subscriptions/package.json | 1 + .../subscriptions/src/channels/email.test.ts | 19 ++ packages/subscriptions/src/channels/email.ts | 10 ++ packages/subscriptions/src/channels/retry.ts | 67 +++++++ .../src/channels/webhook.test.ts | 166 ++++++++++++++++-- .../subscriptions/src/channels/webhook.ts | 89 +++++----- packages/subscriptions/src/payload.ts | 16 +- packages/subscriptions/tsconfig.json | 10 +- pnpm-lock.yaml | 7 +- 25 files changed, 538 insertions(+), 158 deletions(-) create mode 100644 packages/emails/src/client.test.ts create mode 100644 packages/subscriptions/src/channels/retry.ts diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx index 46d93092..62d01edd 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx @@ -32,17 +32,17 @@ export default function Page() { }), ); const sendMaintenanceUpdateMutation = useMutation( - trpc.emailRouter.sendMaintenance.mutationOptions(), + trpc.maintenance.notify.mutationOptions(), ); const createMaintenanceMutation = useMutation( trpc.maintenance.new.mutationOptions({ onSuccess: (maintenance) => { - // TODO: move to server + refetch(); if (maintenance.notifySubscribers) { - sendMaintenanceUpdateMutation.mutateAsync({ id: maintenance.id }); + sendMaintenanceUpdateMutation.mutate({ + id: maintenance.id, + }); } - // - refetch(); }, }), ); diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx index a9ba537d..8bd09525 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx @@ -42,14 +42,14 @@ export default function Page() { ); const sendStatusReportUpdateMutation = useMutation( - trpc.emailRouter.sendStatusReport.mutationOptions(), + trpc.statusReport.notify.mutationOptions(), ); const createStatusReportUpdateMutation = useMutation( trpc.statusReport.createStatusReportUpdate.mutationOptions({ onSuccess: (update) => { if (update?.notifySubscribers) { - sendStatusReportUpdateMutation.mutateAsync({ id: update.id }); + sendStatusReportUpdateMutation.mutate({ id: update.id }); } refetch(); queryClient.invalidateQueries({ diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx index 0cd1b7c5..b860305f 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx @@ -34,18 +34,16 @@ export default function Page() { trpc.statusReport.list.queryOptions({ pageId: Number.parseInt(id) }), ); const sendStatusReportUpdateMutation = useMutation( - trpc.emailRouter.sendStatusReport.mutationOptions(), + trpc.statusReport.notify.mutationOptions(), ); const createStatusReportMutation = useMutation( trpc.statusReport.create.mutationOptions({ - onSuccess: async (statusReport) => { - // TODO: move to server + onSuccess: (statusReport) => { if (statusReport.notifySubscribers) { - await sendStatusReportUpdateMutation.mutateAsync({ + sendStatusReportUpdateMutation.mutate({ id: statusReport.id, }); } - // refetch(); queryClient.invalidateQueries({ queryKey: trpc.page.list.queryKey(), diff --git a/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx b/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx index 75a63056..1d452e02 100644 --- a/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx +++ b/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx @@ -49,16 +49,14 @@ export function DataTable({ const { id } = useParams<{ id: string }>(); const queryClient = useQueryClient(); const sendStatusReportUpdateMutation = useMutation( - trpc.emailRouter.sendStatusReport.mutationOptions(), + trpc.statusReport.notify.mutationOptions(), ); const createStatusReportUpdateMutation = useMutation( trpc.statusReport.createStatusReportUpdate.mutationOptions({ onSuccess: (update) => { - // TODO: move to server if (update?.notifySubscribers) { - sendStatusReportUpdateMutation.mutateAsync({ id: update.id }); + sendStatusReportUpdateMutation.mutate({ id: update.id }); } - // queryClient.invalidateQueries({ queryKey: trpc.statusReport.list.queryKey({ pageId: Number.parseInt(id), diff --git a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx index 34f19eb9..50f586df 100644 --- a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx @@ -55,7 +55,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { const currentImpacts = currentImpactsFromUpdates(row.original.updates); const nextStatus = getNextStatus(row.original.status); const sendStatusReportUpdateMutation = useMutation( - trpc.emailRouter.sendStatusReport.mutationOptions(), + trpc.statusReport.notify.mutationOptions(), ); const updateStatusReportMutation = useMutation( trpc.statusReport.updateStatus.mutationOptions({ @@ -79,11 +79,9 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { const createStatusReportUpdateMutation = useMutation( trpc.statusReport.createStatusReportUpdate.mutationOptions({ onSuccess: (update) => { - // TODO: move to server if (update?.notifySubscribers) { - sendStatusReportUpdateMutation.mutateAsync({ id: update.id }); + sendStatusReportUpdateMutation.mutate({ id: update.id }); } - // queryClient.invalidateQueries({ queryKey: trpc.statusReport.list.queryKey({ pageId: row.original.pageId ?? undefined, diff --git a/apps/dashboard/src/components/forms/subscriber/form.tsx b/apps/dashboard/src/components/forms/subscriber/form.tsx index a9af1623..4f923987 100644 --- a/apps/dashboard/src/components/forms/subscriber/form.tsx +++ b/apps/dashboard/src/components/forms/subscriber/form.tsx @@ -2,6 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { detectWebhookFlavor } from "@openstatus/subscriptions/client"; +import { Badge } from "@openstatus/ui/components/ui/badge"; import { Button } from "@openstatus/ui/components/ui/button"; import { Form, @@ -70,12 +71,6 @@ const formSchema = z path: ["webhookUrl"], message: "Please enter a valid URL", }); - } else if (detectWebhookFlavor(data.webhookUrl) === "generic") { - ctx.addIssue({ - code: "custom", - path: ["webhookUrl"], - message: "Only Slack and Discord webhook URLs are supported.", - }); } } }); @@ -297,8 +292,15 @@ export function FormSubscriber({ /> - Only Slack and Discord webhook URLs are supported for now - - more channels to come. + + Slack and Discord URLs receive channel-native messages; + any other URL receives a generic JSON payload. + + {/^https?:\/\//.test(field.value) ? ( + + {detectWebhookFlavor(field.value)} + + ) : null} diff --git a/packages/analytics/src/events.ts b/packages/analytics/src/events.ts index c71a76a4..e28573eb 100644 --- a/packages/analytics/src/events.ts +++ b/packages/analytics/src/events.ts @@ -104,6 +104,10 @@ export const Events = { name: "report_update_deleted", channel: "report", }, + NotifyReport: { + name: "report_notified", + channel: "report", + }, CreateMaintenance: { name: "maintenance_created", channel: "maintenance", @@ -116,6 +120,10 @@ export const Events = { name: "maintenance_deleted", channel: "maintenance", }, + NotifyMaintenance: { + name: "maintenance_notified", + channel: "maintenance", + }, CreateNotification: { name: "notification_created", channel: "notification", diff --git a/packages/api/src/router/email/index.ts b/packages/api/src/router/email/index.ts index 636626ba..3dea10a3 100644 --- a/packages/api/src/router/email/index.ts +++ b/packages/api/src/router/email/index.ts @@ -5,14 +5,11 @@ import { selectWorkspaceSchema, } from "@openstatus/db/src/schema"; import { EmailClient } from "@openstatus/emails"; -import { notifyMaintenance } from "@openstatus/services/maintenance"; -import { notifyStatusReport } from "@openstatus/services/status-report"; import { getChannel } from "@openstatus/subscriptions"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { env } from "../../env"; -import { toServiceCtx, toTRPCError } from "../../service-adapter"; import { createTRPCRouter, protectedProcedure, @@ -122,40 +119,6 @@ export const emailRouter = createTRPCRouter({ return { success: true }; }), - /** - * PROTECTED: Send status report update notifications via dispatcher - */ - sendStatusReport: protectedProcedure - .input(z.object({ id: z.number() })) - .mutation(async (opts) => { - try { - await notifyStatusReport({ - ctx: toServiceCtx(opts.ctx), - input: { statusReportUpdateId: opts.input.id }, - }); - return { success: true }; - } catch (err) { - toTRPCError(err); - } - }), - - /** - * PROTECTED: Send maintenance notifications via dispatcher - */ - sendMaintenance: protectedProcedure - .input(z.object({ id: z.number() })) - .mutation(async (opts) => { - try { - await notifyMaintenance({ - ctx: toServiceCtx(opts.ctx), - input: { maintenanceId: opts.input.id }, - }); - return { success: true }; - } catch (err) { - toTRPCError(err); - } - }), - sendTeamInvitation: protectedProcedure .input(z.object({ id: z.number(), baseUrl: z.string().optional() })) .mutation(async (opts) => { diff --git a/packages/api/src/router/maintenance.ts b/packages/api/src/router/maintenance.ts index 12b46da7..697d523f 100644 --- a/packages/api/src/router/maintenance.ts +++ b/packages/api/src/router/maintenance.ts @@ -4,6 +4,7 @@ import { createMaintenance, deleteMaintenance, listMaintenances, + notifyMaintenance, updateMaintenance, } from "@openstatus/services/maintenance"; import { z } from "zod"; @@ -65,6 +66,21 @@ export const maintenanceRouter = createTRPCRouter({ } }), + notify: protectedProcedure + .meta({ track: Events.NotifyMaintenance }) + .input(z.object({ id: z.number() })) + .mutation(async ({ ctx, input }) => { + try { + await notifyMaintenance({ + ctx: toServiceCtx(ctx), + input: { maintenanceId: input.id }, + }); + return { success: true }; + } catch (err) { + toTRPCError(err); + } + }), + new: protectedProcedure .meta({ track: Events.CreateMaintenance }) .input( diff --git a/packages/api/src/router/pageSubscriber.ts b/packages/api/src/router/pageSubscriber.ts index 9af4c3ca..1e8c4750 100644 --- a/packages/api/src/router/pageSubscriber.ts +++ b/packages/api/src/router/pageSubscriber.ts @@ -13,7 +13,6 @@ import { upsertSelfSignupSubscriber, verifySelfSignupSubscriber, } from "@openstatus/services/page-subscriber"; -import { detectWebhookFlavor } from "@openstatus/subscriptions"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -30,11 +29,7 @@ const webhookHeadersSchema = z .max(20) .optional(); -const supportedWebhookUrlSchema = z - .url() - .refine((url) => detectWebhookFlavor(url) !== "generic", { - message: "Only Slack and Discord webhook URLs are supported.", - }); +const supportedWebhookUrlSchema = z.url(); // Public (status-page-facing) procedures use the same allow-list as // the protected procedures going through `toTRPCError`. Single source diff --git a/packages/api/src/router/statusReport.ts b/packages/api/src/router/statusReport.ts index 156df7f4..8074282c 100644 --- a/packages/api/src/router/statusReport.ts +++ b/packages/api/src/router/statusReport.ts @@ -10,6 +10,7 @@ import { deleteStatusReportUpdate, getStatusReport, listStatusReports, + notifyStatusReport, updateStatusReport, updateStatusReportUpdate, } from "@openstatus/services/status-report"; @@ -66,8 +67,9 @@ export const statusReportRouter = createTRPCRouter({ .input(createStatusReportTRPCInput) .mutation(async ({ ctx, input }) => { try { + const serviceCtx = toServiceCtx(ctx); const { initialUpdate } = await createStatusReport({ - ctx: toServiceCtx(ctx), + ctx: serviceCtx, input: { title: input.title, status: input.status, @@ -78,8 +80,8 @@ export const statusReportRouter = createTRPCRouter({ message: input.message, }, }); - // Preserve the original "return the initial update row with - // notifySubscribers merged in" shape the dashboard consumes. + // Notification is a separate, client-driven step (statusReport.notify) + // so creation and dispatch stay split. return { ...initialUpdate, notifySubscribers: input.notifySubscribers }; } catch (err) { toTRPCError(err); @@ -91,8 +93,9 @@ export const statusReportRouter = createTRPCRouter({ .input(createStatusReportUpdateTRPCInput) .mutation(async ({ ctx, input }) => { try { + const serviceCtx = toServiceCtx(ctx); const { statusReportUpdate } = await addStatusReportUpdate({ - ctx: toServiceCtx(ctx), + ctx: serviceCtx, input: { statusReportId: input.statusReportId, status: input.status, @@ -110,6 +113,21 @@ export const statusReportRouter = createTRPCRouter({ } }), + notify: protectedProcedure + .meta({ track: Events.NotifyReport }) + .input(z.object({ id: z.number() })) + .mutation(async ({ ctx, input }) => { + try { + await notifyStatusReport({ + ctx: toServiceCtx(ctx), + input: { statusReportUpdateId: input.id }, + }); + return { success: true }; + } catch (err) { + toTRPCError(err); + } + }), + updateStatusReportUpdate: protectedProcedure .meta({ track: Events.UpdateReportUpdate }) .input(updateStatusReportUpdateTRPCInput) diff --git a/packages/emails/src/client.test.ts b/packages/emails/src/client.test.ts new file mode 100644 index 00000000..cde4f7bf --- /dev/null +++ b/packages/emails/src/client.test.ts @@ -0,0 +1,115 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + +import { EmailClient } from "./client"; + +// sendStatusReportUpdate early-returns in development; force the real send path. +process.env.NODE_ENV = "test"; + +function makeSubscribers(n: number) { + return Array.from({ length: n }, (_, i) => ({ + email: `user-${i}@example.com`, + token: `token-${i}`, + })); +} + +function baseReq( + overrides: Partial[0]> = {}, +) { + return { + subscribers: makeSubscribers(1), + pageSlug: "demo", + pageTitle: "Demo", + reportTitle: "Outage", + status: "investigating" as const, + date: "2026-04-21T09:59:58Z", + message: "We are investigating.", + pageComponents: [] as string[], + ...overrides, + }; +} + +// biome-ignore lint/suspicious/noExplicitAny: test doubles for the Resend batch result +const ok = { data: { data: [] }, error: null } as any; +// biome-ignore lint/suspicious/noExplicitAny: simulated Resend application error +const fail = { data: null, error: { name: "application_error" } } as any; + +describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { + let client: EmailClient; + // biome-ignore lint/suspicious/noExplicitAny: bun spy handle + let batchSend: any; + + beforeEach(() => { + // zero backoff so the retry test doesn't wait on the real exponential sleep + client = new EmailClient({ + apiKey: "re_test_123", + retryBackoff: "0 millis", + }); + batchSend = spyOn(client.client.batch, "send").mockResolvedValue(ok); + }); + + afterEach(() => { + batchSend.mockRestore(); + }); + + test("passes the base idempotency key suffixed with the batch index", async () => { + await client.sendStatusReportUpdate( + baseReq({ idempotencyKey: "status-report-update:5" }), + ); + + expect(batchSend).toHaveBeenCalledTimes(1); + const [, options] = batchSend.mock.calls[0]; + expect(options).toEqual({ idempotencyKey: "status-report-update:5:0" }); + }); + + test("gives each 100-recipient chunk a distinct key and its own slice", async () => { + await client.sendStatusReportUpdate( + baseReq({ + subscribers: makeSubscribers(250), + idempotencyKey: "status-report-update:9", + }), + ); + + expect(batchSend).toHaveBeenCalledTimes(3); + const keys = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([, o]: [unknown, any]) => o?.idempotencyKey, + ); + expect(keys).toEqual([ + "status-report-update:9:0", + "status-report-update:9:1", + "status-report-update:9:2", + ]); + const sizes = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([payload]: [any[]]) => payload.length, + ); + expect(sizes).toEqual([100, 100, 50]); + }); + + test("omits the option entirely when no base key is provided", async () => { + await client.sendStatusReportUpdate(baseReq()); + + const [, options] = batchSend.mock.calls[0]; + expect(options).toBeUndefined(); + }); + + test("reuses the same key across a retry so Resend dedupes the resend", async () => { + batchSend.mockResolvedValueOnce(fail).mockResolvedValueOnce(ok); + + await client.sendStatusReportUpdate( + baseReq({ idempotencyKey: "status-report-update:7" }), + ); + + // failure → retry: the second attempt must carry the identical key, or + // Resend would treat the retry as a fresh batch and double-send. + expect(batchSend).toHaveBeenCalledTimes(2); + const keys = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([, o]: [unknown, any]) => o?.idempotencyKey, + ); + expect(keys).toEqual([ + "status-report-update:7:0", + "status-report-update:7:0", + ]); + }); +}); diff --git a/packages/emails/src/client.tsx b/packages/emails/src/client.tsx index ce7b7a68..275293ef 100644 --- a/packages/emails/src/client.tsx +++ b/packages/emails/src/client.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource react */ -import { Effect, Schedule } from "effect"; +import { type Duration, Effect, Schedule } from "effect"; import { render } from "react-email"; import { Resend } from "resend"; @@ -37,9 +37,13 @@ function chunk(array: T[], size: number): T[][] { export class EmailClient { public readonly client: Resend; + // Base delay for the per-batch send retry. Overridable so tests can run the + // retry path without the real ~1s exponential sleep. + private readonly retryBackoff: Duration.DurationInput; - constructor(opts: { apiKey: string }) { + constructor(opts: { apiKey: string; retryBackoff?: Duration.DurationInput }) { this.client = new Resend(opts.apiKey); + this.retryBackoff = opts.retryBackoff ?? "1000 millis"; } public async sendFollowUp(req: { to: string }) { @@ -161,6 +165,10 @@ export class EmailClient { subscribers: Array<{ email: string; token: string }>; pageSlug: string; customDomain?: string | null; + // Base key for Resend idempotency. The per-batch retry below would + // otherwise re-send the whole chunk if a request succeeds server-side + // but the response is lost. Must be stable across retries. + idempotencyKey?: string; }, ) { const statusPageBaseUrl = req.customDomain @@ -176,7 +184,14 @@ export class EmailClient { return; } - for (const recipients of chunk(req.subscribers, 100)) { + const chunks = chunk(req.subscribers, 100); + for (let i = 0; i < chunks.length; i++) { + const recipients = chunks[i]; + // suffix the chunk index so a multi-batch send doesn't collide its + // own chunks on a single shared key + const batchKey = req.idempotencyKey + ? `${req.idempotencyKey}:${i}` + : undefined; const sendEmail = Effect.tryPromise({ try: () => this.client.batch.send( @@ -196,6 +211,7 @@ export class EmailClient { ), }; }), + batchKey ? { idempotencyKey: batchKey } : undefined, ), catch: (_unknown) => new Error( @@ -209,7 +225,7 @@ export class EmailClient { ), Effect.retry({ times: 3, - schedule: Schedule.exponential("1000 millis"), + schedule: Schedule.exponential(this.retryBackoff), }), ); await Effect.runPromise(sendEmail).catch(console.error); @@ -345,6 +361,7 @@ export class EmailClient { from: string; to: string; pageComponents: string[]; + idempotencyKey?: string; }) { const statusPageBaseUrl = req.customDomain ? `https://${req.customDomain}` @@ -359,7 +376,12 @@ export class EmailClient { return; } - for (const recipients of chunk(req.subscribers, 100)) { + const chunks = chunk(req.subscribers, 100); + for (let i = 0; i < chunks.length; i++) { + const recipients = chunks[i]; + const batchKey = req.idempotencyKey + ? `${req.idempotencyKey}:${i}` + : undefined; const sendEmail = Effect.tryPromise({ try: () => this.client.batch.send( @@ -384,6 +406,7 @@ export class EmailClient { ), }; }), + batchKey ? { idempotencyKey: batchKey } : undefined, ), catch: (_unknown) => new Error( @@ -397,7 +420,7 @@ export class EmailClient { ), Effect.retry({ times: 3, - schedule: Schedule.exponential("1000 millis"), + schedule: Schedule.exponential(this.retryBackoff), }), ); await Effect.runPromise(sendEmail).catch(console.error); diff --git a/packages/services/src/page-subscriber/create.ts b/packages/services/src/page-subscriber/create.ts index f845ec42..6eb1d5b1 100644 --- a/packages/services/src/page-subscriber/create.ts +++ b/packages/services/src/page-subscriber/create.ts @@ -5,7 +5,6 @@ import { pageSubscriberToPageComponent, selectPageSubscriberSchema, } from "@openstatus/db/src/schema"; -import { detectWebhookFlavor } from "@openstatus/subscriptions"; import { assertSafeUrl } from "@openstatus/utils"; import { emitAudit } from "../audit"; @@ -64,11 +63,6 @@ export async function createPageSubscriber(args: { // outside avoids holding the SQLite write lock across a network call. if (input.channelType === "webhook") { await assertSafeUrl(input.webhookUrl); - if (detectWebhookFlavor(input.webhookUrl) === "generic") { - throw new ValidationError( - "Only Slack and Discord webhook URLs are supported.", - ); - } } return withTransaction(ctx, async (tx) => { diff --git a/packages/services/src/page-subscriber/internal.ts b/packages/services/src/page-subscriber/internal.ts index c98c6bd9..a2f9986a 100644 --- a/packages/services/src/page-subscriber/internal.ts +++ b/packages/services/src/page-subscriber/internal.ts @@ -134,7 +134,6 @@ export const SAFE_SUBSCRIPTION_MESSAGES = new Set([ "Some components do not belong to this page", "A subscriber with this email already exists for this page.", "A subscriber with this webhook URL already exists for this page.", - "Only Slack and Discord webhook URLs are supported.", "Subscriber not found", "Subscriber is not a webhook channel", "Self-signup subscribers manage their own subscription; use the unsubscribe action instead.", diff --git a/packages/services/src/page-subscriber/update.ts b/packages/services/src/page-subscriber/update.ts index 0f572abc..4beb9413 100644 --- a/packages/services/src/page-subscriber/update.ts +++ b/packages/services/src/page-subscriber/update.ts @@ -6,7 +6,6 @@ import { pageSubscriberToPageComponent, selectPageSubscriberSchema, } from "@openstatus/db/src/schema"; -import { detectWebhookFlavor } from "@openstatus/subscriptions"; import { assertSafeUrl } from "@openstatus/utils"; import { emitAudit } from "../audit"; @@ -40,14 +39,9 @@ export async function updatePageSubscriberChannel(args: { // `assertSafeUrl` does a DNS lookup to block private/internal targets; // keep it outside the tx so we don't hold the SQLite write lock across - // a network call. Flavor check is pure and stays here for symmetry. + // a network call. if (input.webhookUrl !== undefined) { await assertSafeUrl(input.webhookUrl); - if (detectWebhookFlavor(input.webhookUrl) === "generic") { - throw new ValidationError( - "Only Slack and Discord webhook URLs are supported.", - ); - } } await withTransaction(ctx, async (tx) => { diff --git a/packages/subscriptions/package.json b/packages/subscriptions/package.json index 64824e69..c50cc3b9 100644 --- a/packages/subscriptions/package.json +++ b/packages/subscriptions/package.json @@ -22,6 +22,7 @@ "@openstatus/emails": "workspace:*", "@openstatus/notification-base": "workspace:*", "@openstatus/utils": "workspace:*", + "effect": "catalog:", "zod": "catalog:" }, "devDependencies": { diff --git a/packages/subscriptions/src/channels/email.test.ts b/packages/subscriptions/src/channels/email.test.ts index d289ade2..6772aceb 100644 --- a/packages/subscriptions/src/channels/email.test.ts +++ b/packages/subscriptions/src/channels/email.test.ts @@ -141,4 +141,23 @@ describe("sendEmailNotifications", () => { const [args] = sendStatusReportUpdateMock.mock.calls[0]; expect(args.pageComponents).toEqual(["API", "Database"]); }); + + test("derives the idempotency key from the status-report update id", async () => { + const sub = makeSub(); + await sendEmailNotifications([sub], makeUpdate({ updateId: 77 })); + + const [args] = sendStatusReportUpdateMock.mock.calls[0]; + expect(args.idempotencyKey).toBe("status-report-update:77"); + }); + + test("falls back to a page-update key when there is no update id (maintenance)", async () => { + const sub = makeSub(); + await sendEmailNotifications( + [sub], + makeUpdate({ id: 17, updateId: undefined, status: "maintenance" }), + ); + + const [args] = sendStatusReportUpdateMock.mock.calls[0]; + expect(args.idempotencyKey).toBe("page-update:17:maintenance"); + }); }); diff --git a/packages/subscriptions/src/channels/email.ts b/packages/subscriptions/src/channels/email.ts index b82397b6..6e2cc6ba 100644 --- a/packages/subscriptions/src/channels/email.ts +++ b/packages/subscriptions/src/channels/email.ts @@ -24,6 +24,15 @@ export async function validateEmailConfig(config: unknown) { return { valid: email.success, error: email.error?.message }; } +// Stable per status-report update / maintenance so Resend dedupes the email +// retry path. Status reports key off the specific update; maintenance has no +// update row, so fall back to its id + status. +function idempotencyKeyFor(pageUpdate: PageUpdate): string { + return pageUpdate.updateId != null + ? `status-report-update:${pageUpdate.updateId}` + : `page-update:${pageUpdate.id}:${pageUpdate.status}`; +} + function hasEmailAndToken( sub: Subscription, ): sub is Subscription & { email: string; token: string } { @@ -76,5 +85,6 @@ export async function sendEmailNotifications( message: pageUpdate.message, date: pageUpdate.date, pageComponents: pageUpdate.pageComponents, + idempotencyKey: idempotencyKeyFor(pageUpdate), }); } diff --git a/packages/subscriptions/src/channels/retry.ts b/packages/subscriptions/src/channels/retry.ts new file mode 100644 index 00000000..c720ea7f --- /dev/null +++ b/packages/subscriptions/src/channels/retry.ts @@ -0,0 +1,67 @@ +import { Effect, Schedule } from "effect"; + +export class WebhookSendError extends Error { + readonly httpStatus?: number; + + constructor( + message: string, + opts?: { httpStatus?: number; cause?: unknown }, + ) { + super(message, { cause: opts?.cause }); + this.name = "WebhookSendError"; + this.httpStatus = opts?.httpStatus; + } +} + +// Network errors and timeouts (no status) are transient; 5xx and 429 may clear. +// Other 4xx are client errors that won't succeed on retry. +const isRetryable = (err: WebhookSendError): boolean => + err.httpStatus === undefined || + err.httpStatus >= 500 || + err.httpStatus === 429; + +const retryPolicy = { + schedule: Schedule.exponential("200 millis").pipe(Schedule.jittered), + times: 3, + while: isRetryable, +}; + +/** + * POST to a webhook with exponential-backoff retries on transient failures. + * Rejects with `WebhookSendError` once retries are exhausted. + */ +export function postWebhookWithRetry(opts: { + url: string; + headers: Record; + body: string; + timeoutMs: number; +}): Promise { + const send = Effect.tryPromise({ + try: (signal) => + fetch(opts.url, { + method: "POST", + headers: opts.headers, + body: opts.body, + signal, + }), + catch: (cause) => new WebhookSendError("Webhook request failed", { cause }), + }).pipe( + Effect.timeoutFail({ + duration: `${opts.timeoutMs} millis`, + onTimeout: () => + new WebhookSendError(`Webhook timed out after ${opts.timeoutMs}ms`), + }), + Effect.flatMap((response) => + response.ok + ? Effect.void + : Effect.fail( + new WebhookSendError(`Webhook returned ${response.status}`, { + httpStatus: response.status, + }), + ), + ), + Effect.retry(retryPolicy), + ); + + return Effect.runPromise(send); +} diff --git a/packages/subscriptions/src/channels/webhook.test.ts b/packages/subscriptions/src/channels/webhook.test.ts index 640e933d..a10a9b41 100644 --- a/packages/subscriptions/src/channels/webhook.test.ts +++ b/packages/subscriptions/src/channels/webhook.test.ts @@ -161,7 +161,7 @@ describe("sendWebhookNotifications", () => { expect(urls).toContain("https://hooks.slack.com/services/T2/B2/bbb"); }); - test("drops subscriptions with non-Slack/Discord URLs", async () => { + test("sends a generic JSON payload to non-Slack/Discord URLs", async () => { fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const generic = makeSub({ id: 101, @@ -169,11 +169,61 @@ describe("sendWebhookNotifications", () => { }); const slack = makeSub({ id: 102, webhookUrl: SLACK_URL }); - await sendWebhookNotifications([generic, slack], makeUpdate()); + await sendWebhookNotifications( + [generic, slack], + makeUpdate({ updateId: 42 }), + ); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url] = fetchMock.mock.calls[0]; - expect(url).toBe(SLACK_URL); + expect(fetchMock).toHaveBeenCalledTimes(2); + const byUrl = new Map( + fetchMock.mock.calls.map(([url, init]: [string, RequestInit]) => [ + url, + JSON.parse(init.body as string), + ]), + ); + expect(byUrl.get("https://example.com/webhook").type).toBe("status_report"); + expect(byUrl.get(SLACK_URL).attachments).toBeDefined(); + }); + + test("the status_report body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); + + await sendWebhookNotifications( + [sub], + makeUpdate({ + status: "investigating", + updateId: 42, + componentsWithImpact: [ + { id: 7, name: "API", impact: "partial_outage" }, + ], + }), + ); + + const [, init] = fetchMock.mock.calls[0]; + const sentBody = JSON.parse(init?.body as string); + const result = webhookPayloadSchema.safeParse(sentBody); + expect(result.success).toBe(true); + }); + + test("the maintenance body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); + + await sendWebhookNotifications( + [sub], + makeUpdate({ + status: "maintenance", + startsAt: "2026-04-22T02:00:00Z", + endsAt: "2026-04-22T03:00:00Z", + pageComponentsWithId: [{ id: 7, name: "API" }], + }), + ); + + const [, init] = fetchMock.mock.calls[0]; + const sentBody = JSON.parse(init?.body as string); + const result = webhookPayloadSchema.safeParse(sentBody); + expect(result.success).toBe(true); }); test("applies custom headers from channelConfig", async () => { @@ -191,14 +241,15 @@ describe("sendWebhookNotifications", () => { expect(headers["X-Custom-Header"]).toBe("my-value"); }); - test("continues sending to remaining webhooks when one fails", async () => { - fetchMock - .mockRejectedValueOnce(new Error("Network error")) - .mockResolvedValueOnce(new Response(null, { status: 200 })); + test("continues sending to remaining webhooks when one keeps failing", async () => { + const failUrl = "https://hooks.slack.com/services/T1/B1/fail"; + fetchMock.mockImplementation(async (url: string) => + url === failUrl + ? Promise.reject(new Error("Network error")) + : new Response(null, { status: 200 }), + ); - const sub1 = makeSub({ - webhookUrl: "https://hooks.slack.com/services/T1/B1/fail", - }); + const sub1 = makeSub({ webhookUrl: failUrl }); const sub2 = makeSub({ webhookUrl: "https://hooks.slack.com/services/T2/B2/succeed", }); @@ -207,7 +258,34 @@ describe("sendWebhookNotifications", () => { sendWebhookNotifications([sub1, sub2], makeUpdate()), ).resolves.toBeUndefined(); - expect(fetchMock).toHaveBeenCalledTimes(2); + const calls = fetchMock.mock.calls.map(([url]: [string]) => url); + expect(calls).toContain("https://hooks.slack.com/services/T2/B2/succeed"); + }); + + test("retries transient failures then succeeds", async () => { + let attempts = 0; + fetchMock.mockImplementation(async () => { + attempts += 1; + return attempts < 3 + ? new Response(null, { status: 503, statusText: "Service Unavailable" }) + : new Response(null, { status: 200 }); + }); + + await expect( + sendWebhookNotifications([makeSub()], makeUpdate()), + ).resolves.toBeUndefined(); + + expect(attempts).toBe(3); + }); + + test("does not retry non-retryable 4xx responses", async () => { + fetchMock.mockResolvedValue( + new Response(null, { status: 400, statusText: "Bad Request" }), + ); + + await sendWebhookNotifications([makeSub()], makeUpdate()); + + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); @@ -288,6 +366,49 @@ describe("sendWebhookNotifications (flavor detection)", () => { const stringified = init?.body as string; expect(stringified).toContain("https://status.partner.com/manage/tok-123"); }); + + test("Slack payload links to the event details and the page origin", async () => { + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + const sub = makeSub({ pageSlug: "demo", pageName: "Demo" }); + + await sendWebhookNotifications([sub], makeUpdate({ id: 99 })); + + const [, init] = fetchMock.mock.calls[0]; + const body = JSON.parse(init?.body as string); + const stringified = init?.body as string; + // title stays in a plain_text header block + expect(body.attachments[0].blocks[0]).toMatchObject({ + type: "header", + text: { type: "plain_text", text: "Test Incident" }, + }); + expect(stringified).toContain( + "", + ); + expect(stringified).toContain(""); + }); + + test("Discord embed url points at the event; maintenance uses the maintenance path", async () => { + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + const sub = makeSub({ + webhookUrl: DISCORD_URL, + pageSlug: "demo", + pageName: "Demo", + }); + + await sendWebhookNotifications( + [sub], + makeUpdate({ id: 7, status: "maintenance" }), + ); + + const [, init] = fetchMock.mock.calls[0]; + const body = JSON.parse(init?.body as string); + expect(body.embeds[0].url).toBe( + "https://demo.openstatus.dev/events/maintenance/7", + ); + expect(body.embeds[0].fields[1].value).toBe( + "[Demo](https://demo.openstatus.dev)", + ); + }); }); // ─── buildGenericPayload (staged, not yet reachable in production) ──────────── @@ -329,11 +450,12 @@ describe("buildGenericPayload", () => { expect(payload.data.status_report).toMatchObject({ id: 12, title: "API degraded", + url: "https://acme.openstatus.dev/events/report/12", update: { id: 42, status: "investigating", message: "Looking into it.", - created_at: "2026-04-21T09:59:58Z", + occurred_at: "2026-04-21T09:59:58Z", }, page: { id: 42, @@ -379,6 +501,7 @@ describe("buildGenericPayload", () => { expect(payload.data.maintenance).toMatchObject({ id: 17, title: "DB upgrade", + url: "https://acme.openstatus.dev/events/maintenance/17", message: "Rolling primary.", starts_at: "2026-04-22T02:00:00Z", ends_at: "2026-04-22T03:00:00Z", @@ -438,13 +561,22 @@ describe("buildTestPayload", () => { expect(payload.embeds).toBeInstanceOf(Array); }); - test("generic flavor returns type='test' JSON", () => { + test("generic flavor returns enveloped type='test' JSON", () => { const payload = buildTestPayload("generic") as { + version: string; type: string; - message: string; + data: { test: { message: string; timestamp: string } }; }; + expect(payload.version).toBe("1"); expect(payload.type).toBe("test"); - expect(typeof payload.message).toBe("string"); + expect(typeof payload.data.test.message).toBe("string"); + expect(typeof payload.data.test.timestamp).toBe("string"); + }); + + test("generic output satisfies the canonical webhookPayloadSchema contract", () => { + expect( + webhookPayloadSchema.safeParse(buildTestPayload("generic")).success, + ).toBe(true); }); }); diff --git a/packages/subscriptions/src/channels/webhook.ts b/packages/subscriptions/src/channels/webhook.ts index 94d0402f..c0921277 100644 --- a/packages/subscriptions/src/channels/webhook.ts +++ b/packages/subscriptions/src/channels/webhook.ts @@ -4,6 +4,7 @@ import { z } from "zod"; import { WEBHOOK_PAYLOAD_VERSION } from "../payload"; import type { PageUpdate, Subscription } from "../types"; +import { postWebhookWithRetry } from "./retry"; export type WebhookFlavor = "slack" | "discord" | "generic"; @@ -35,6 +36,16 @@ function resolveStatusPageOrigin(subscription: Subscription): string { : `https://${subscription.pageSlug}.openstatus.dev`; } +// Deep link to the specific event on the status page, mirroring the path +// shape used by the Slack app integration (apps/server slack/page-urls.ts). +function resolveEventUrl( + pageUpdate: PageUpdate, + subscription: Subscription, +): string { + const kind = pageUpdate.status === "maintenance" ? "maintenance" : "report"; + return `${resolveStatusPageOrigin(subscription)}/events/${kind}/${pageUpdate.id}`; +} + function buildManagementLinks(subscription: Subscription) { if (!subscription.token) { return { manageUrl: null, unsubscribeUrl: null }; @@ -120,6 +131,8 @@ function buildSlackPayload( links: ManagementLinks, ) { const color = statusColor(pageUpdate.status); + const eventUrl = resolveEventUrl(pageUpdate, subscription); + const pageOrigin = resolveStatusPageOrigin(subscription); const blocks: Record[] = [ { @@ -139,7 +152,7 @@ function buildSlackPayload( }, { type: "mrkdwn", - text: `*Page*\n${subscription.pageName}`, + text: `*Page*\n<${pageOrigin}|${subscription.pageName}>`, }, ], }, @@ -175,17 +188,17 @@ function buildSlackPayload( ], }); + const footerLinks = [`<${eventUrl}|View details>`]; if (links.manageUrl && links.unsubscribeUrl) { - blocks.push({ - type: "context", - elements: [ - { - type: "mrkdwn", - text: `<${links.manageUrl}|Manage> · <${links.unsubscribeUrl}|Unsubscribe>`, - }, - ], - }); + footerLinks.push( + `<${links.manageUrl}|Manage>`, + `<${links.unsubscribeUrl}|Unsubscribe>`, + ); } + blocks.push({ + type: "context", + elements: [{ type: "mrkdwn", text: footerLinks.join(" · ") }], + }); return { attachments: [ @@ -203,6 +216,8 @@ function buildDiscordPayload( links: ManagementLinks, ) { const color = statusColor(pageUpdate.status); + const eventUrl = resolveEventUrl(pageUpdate, subscription); + const pageOrigin = resolveStatusPageOrigin(subscription); const descriptionParts: string[] = []; if (pageUpdate.message) descriptionParts.push(pageUpdate.message); @@ -221,6 +236,7 @@ function buildDiscordPayload( embeds: [ { title: pageUpdate.title, + url: eventUrl, description: descriptionParts.join("\n\n") || undefined, color: COLOR_DECIMALS[color], fields: [ @@ -231,7 +247,7 @@ function buildDiscordPayload( }, { name: "Page", - value: subscription.pageName, + value: `[${subscription.pageName}](${pageOrigin})`, inline: true, }, ], @@ -244,21 +260,21 @@ function buildDiscordPayload( } /** - * Prepared (staged) generic webhook payload. Currently unreachable in - * production — the input gate rejects non-Slack/Discord URLs, and the - * dispatcher filters the same at send-time. Exported for unit-test coverage - * so the contract stays green while generic webhooks are held back. + * Generic JSON webhook payload, sent to any non-Slack/Discord URL. + * Shape is pinned by `webhookPayloadSchema` in `../payload`. */ export function buildGenericPayload( pageUpdate: PageUpdate, subscription: Subscription, links: ManagementLinks, ) { + const origin = resolveStatusPageOrigin(subscription); + const eventUrl = resolveEventUrl(pageUpdate, subscription); const page = { id: subscription.pageId, name: subscription.pageName, slug: subscription.pageSlug, - url: resolveStatusPageOrigin(subscription), + url: origin, }; const components = pageUpdate.componentsWithImpact ?? @@ -284,6 +300,7 @@ export function buildGenericPayload( maintenance: { id: pageUpdate.id, title: pageUpdate.title, + url: eventUrl, message: pageUpdate.message, starts_at: pageUpdate.startsAt, ends_at: pageUpdate.endsAt, @@ -306,11 +323,12 @@ export function buildGenericPayload( status_report: { id: pageUpdate.id, title: pageUpdate.title, + url: eventUrl, update: { id: pageUpdate.updateId, status: pageUpdate.status, message: pageUpdate.message, - created_at: pageUpdate.date, + occurred_at: pageUpdate.date, }, page, components, @@ -344,18 +362,7 @@ export async function sendWebhookNotifications( subscriptions: Subscription[], pageUpdate: PageUpdate, ) { - // Defense-in-depth: the input gate (tRPC + service layer) already rejects - // non-Slack/Discord URLs at save time. Drop any that slip through so the - // unreachable generic payload never ships to an unapproved destination. - const validSubscriptions = subscriptions - .filter(hasWebhookUrl) - .filter((sub) => { - if (detectWebhookFlavor(sub.webhookUrl) !== "generic") return true; - console.warn( - `Dropping webhook subscription ${sub.id}: generic URLs are not currently supported`, - ); - return false; - }); + const validSubscriptions = subscriptions.filter(hasWebhookUrl); if (validSubscriptions.length === 0) return; await Promise.allSettled( @@ -387,19 +394,12 @@ export async function sendWebhookNotifications( try { await assertSafeUrl(subscription.webhookUrl); - const response = await fetch(subscription.webhookUrl, { - method: "POST", + await postWebhookWithRetry({ + url: subscription.webhookUrl, headers, body: JSON.stringify(payload), - signal: AbortSignal.timeout(TIMEOUT_MS), + timeoutMs: TIMEOUT_MS, }); - - if (!response.ok) { - console.error( - `Webhook notification failed for ${redactWebhookUrl(subscription.webhookUrl)}: ${response.status} ${response.statusText}`, - ); - throw new Error(`Webhook returned ${response.status}`); - } } catch (error) { console.error( `Failed to send webhook notification to ${redactWebhookUrl(subscription.webhookUrl)}:`, @@ -455,9 +455,14 @@ export function buildTestPayload(flavor: WebhookFlavor) { }; case "generic": return { - type: "test", - message: "Your openstatus webhook is configured correctly.", - timestamp: new Date().toISOString(), + version: WEBHOOK_PAYLOAD_VERSION, + type: "test" as const, + data: { + test: { + message: "Your openstatus webhook is configured correctly.", + timestamp: new Date().toISOString(), + }, + }, }; } } diff --git a/packages/subscriptions/src/payload.ts b/packages/subscriptions/src/payload.ts index aeba254e..df509aee 100644 --- a/packages/subscriptions/src/payload.ts +++ b/packages/subscriptions/src/payload.ts @@ -30,11 +30,12 @@ export const statusReportWebhookSchema = z.object({ status_report: z.object({ id: z.number().int(), title: z.string(), + url: z.url(), update: z.object({ id: z.number().int(), status: statusReportStatusSchema, message: z.string(), - created_at: z.string(), + occurred_at: z.string(), }), page: pageSchema, components: z.array(componentSchema), @@ -50,6 +51,7 @@ export const maintenanceWebhookSchema = z.object({ maintenance: z.object({ id: z.number().int(), title: z.string(), + url: z.url(), message: z.string(), starts_at: z.string().optional(), ends_at: z.string().optional(), @@ -60,9 +62,21 @@ export const maintenanceWebhookSchema = z.object({ subscription: subscriptionSchema, }); +export const testWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("test"), + data: z.object({ + test: z.object({ + message: z.string(), + timestamp: z.string(), + }), + }), +}); + export const webhookPayloadSchema = z.discriminatedUnion("type", [ statusReportWebhookSchema, maintenanceWebhookSchema, + testWebhookSchema, ]); export type WebhookPayload = z.infer; diff --git a/packages/subscriptions/tsconfig.json b/packages/subscriptions/tsconfig.json index 0b8670d6..868037cf 100644 --- a/packages/subscriptions/tsconfig.json +++ b/packages/subscriptions/tsconfig.json @@ -1,5 +1,13 @@ { - "extends": "@openstatus/tsconfig/react-library.json", + "extends": "@openstatus/tsconfig/base.json", + "compilerOptions": { + "lib": ["ES2022", "DOM"], + "module": "ESNext", + "target": "ES2022", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "types": ["bun"] + }, "include": [".", "src"], "exclude": ["dist", "build", "node_modules"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c362b6d..4fcd3756 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1195,7 +1195,7 @@ importers: version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-intl: specifier: 'catalog:' - version: 4.12.0(next@16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) + version: 4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) next-plausible: specifier: 'catalog:' version: 3.12.5(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -2601,6 +2601,9 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../utils + effect: + specifier: 'catalog:' + version: 3.21.2 zod: specifier: 'catalog:' version: 4.1.13 @@ -18056,7 +18059,7 @@ snapshots: next-intl-swc-plugin-extractor@4.12.0: {} - next-intl@4.12.0(next@16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3): + next-intl@4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3): dependencies: '@formatjs/intl-localematcher': 0.8.1 '@parcel/watcher': 2.5.1 -- 2.51.2 From aeaa75134cd42583e70629f5a3bc81e08ca8fbe6 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 26 Jun 2026 15:24:27 +0200 Subject: [PATCH 04/69] fix: dashboard subscribers notification runtime (#2316) * fix: runtime * fix: nullish --- .../status-pages/[id]/maintenances/page.tsx | 2 +- .../[id]/status-reports/[reportId]/page.tsx | 2 +- .../status-pages/[id]/status-reports/page.tsx | 2 +- .../status-report-updates/data-table.tsx | 2 +- .../status-reports/data-table-row-actions.tsx | 2 +- apps/dashboard/src/lib/trpc/shared.ts | 1 + packages/api/src/lambda.ts | 2 + packages/api/src/router/maintenance.ts | 16 ------- packages/api/src/router/statusReport.ts | 21 ++------- .../api/src/router/subscriber-notification.ts | 44 +++++++++++++++++++ packages/subscriptions/src/payload.ts | 6 +-- 11 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 packages/api/src/router/subscriber-notification.ts diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx index 62d01edd..250b4514 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx @@ -32,7 +32,7 @@ export default function Page() { }), ); const sendMaintenanceUpdateMutation = useMutation( - trpc.maintenance.notify.mutationOptions(), + trpc.subscriberNotification.maintenance.mutationOptions(), ); const createMaintenanceMutation = useMutation( trpc.maintenance.new.mutationOptions({ diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx index 8bd09525..3e24d35b 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx @@ -42,7 +42,7 @@ export default function Page() { ); const sendStatusReportUpdateMutation = useMutation( - trpc.statusReport.notify.mutationOptions(), + trpc.subscriberNotification.statusReport.mutationOptions(), ); const createStatusReportUpdateMutation = useMutation( diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx index b860305f..a9608cd8 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx @@ -34,7 +34,7 @@ export default function Page() { trpc.statusReport.list.queryOptions({ pageId: Number.parseInt(id) }), ); const sendStatusReportUpdateMutation = useMutation( - trpc.statusReport.notify.mutationOptions(), + trpc.subscriberNotification.statusReport.mutationOptions(), ); const createStatusReportMutation = useMutation( trpc.statusReport.create.mutationOptions({ diff --git a/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx b/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx index 1d452e02..01b908cc 100644 --- a/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx +++ b/apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx @@ -49,7 +49,7 @@ export function DataTable({ const { id } = useParams<{ id: string }>(); const queryClient = useQueryClient(); const sendStatusReportUpdateMutation = useMutation( - trpc.statusReport.notify.mutationOptions(), + trpc.subscriberNotification.statusReport.mutationOptions(), ); const createStatusReportUpdateMutation = useMutation( trpc.statusReport.createStatusReportUpdate.mutationOptions({ diff --git a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx index 50f586df..b449ac83 100644 --- a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx @@ -55,7 +55,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { const currentImpacts = currentImpactsFromUpdates(row.original.updates); const nextStatus = getNextStatus(row.original.status); const sendStatusReportUpdateMutation = useMutation( - trpc.statusReport.notify.mutationOptions(), + trpc.subscriberNotification.statusReport.mutationOptions(), ); const updateStatusReportMutation = useMutation( trpc.statusReport.updateStatus.mutationOptions({ diff --git a/apps/dashboard/src/lib/trpc/shared.ts b/apps/dashboard/src/lib/trpc/shared.ts index 7d94f8fe..23187324 100644 --- a/apps/dashboard/src/lib/trpc/shared.ts +++ b/apps/dashboard/src/lib/trpc/shared.ts @@ -40,6 +40,7 @@ const lambdas = [ "apiKeyRouter", "integrationRouter", "blob", + "subscriberNotification", ]; export const endingLink = (opts?: { diff --git a/packages/api/src/lambda.ts b/packages/api/src/lambda.ts index 6b993f2d..5a48f3dc 100644 --- a/packages/api/src/lambda.ts +++ b/packages/api/src/lambda.ts @@ -3,6 +3,7 @@ import { blobRouter } from "./router/blob"; import { emailRouter } from "./router/email"; import { integrationRouter } from "./router/integration"; import { stripeRouter } from "./router/stripe"; +import { subscriberNotificationRouter } from "./router/subscriber-notification"; import { createTRPCRouter } from "./trpc"; // Deployed to /trpc/lambda/** export const lambdaRouter = createTRPCRouter({ @@ -11,6 +12,7 @@ export const lambdaRouter = createTRPCRouter({ apiKeyRouter: apiKeyRouter, integrationRouter: integrationRouter, blob: blobRouter, + subscriberNotification: subscriberNotificationRouter, }); export { stripe } from "./router/stripe/shared"; diff --git a/packages/api/src/router/maintenance.ts b/packages/api/src/router/maintenance.ts index 697d523f..12b46da7 100644 --- a/packages/api/src/router/maintenance.ts +++ b/packages/api/src/router/maintenance.ts @@ -4,7 +4,6 @@ import { createMaintenance, deleteMaintenance, listMaintenances, - notifyMaintenance, updateMaintenance, } from "@openstatus/services/maintenance"; import { z } from "zod"; @@ -66,21 +65,6 @@ export const maintenanceRouter = createTRPCRouter({ } }), - notify: protectedProcedure - .meta({ track: Events.NotifyMaintenance }) - .input(z.object({ id: z.number() })) - .mutation(async ({ ctx, input }) => { - try { - await notifyMaintenance({ - ctx: toServiceCtx(ctx), - input: { maintenanceId: input.id }, - }); - return { success: true }; - } catch (err) { - toTRPCError(err); - } - }), - new: protectedProcedure .meta({ track: Events.CreateMaintenance }) .input( diff --git a/packages/api/src/router/statusReport.ts b/packages/api/src/router/statusReport.ts index 8074282c..480e5101 100644 --- a/packages/api/src/router/statusReport.ts +++ b/packages/api/src/router/statusReport.ts @@ -10,7 +10,6 @@ import { deleteStatusReportUpdate, getStatusReport, listStatusReports, - notifyStatusReport, updateStatusReport, updateStatusReportUpdate, } from "@openstatus/services/status-report"; @@ -80,8 +79,9 @@ export const statusReportRouter = createTRPCRouter({ message: input.message, }, }); - // Notification is a separate, client-driven step (statusReport.notify) - // so creation and dispatch stay split. + // Notification is a separate, client-driven step + // (subscriberNotification.statusReport) so creation and dispatch stay + // split — dispatch must run on lambda, this router is Edge-served. return { ...initialUpdate, notifySubscribers: input.notifySubscribers }; } catch (err) { toTRPCError(err); @@ -113,21 +113,6 @@ export const statusReportRouter = createTRPCRouter({ } }), - notify: protectedProcedure - .meta({ track: Events.NotifyReport }) - .input(z.object({ id: z.number() })) - .mutation(async ({ ctx, input }) => { - try { - await notifyStatusReport({ - ctx: toServiceCtx(ctx), - input: { statusReportUpdateId: input.id }, - }); - return { success: true }; - } catch (err) { - toTRPCError(err); - } - }), - updateStatusReportUpdate: protectedProcedure .meta({ track: Events.UpdateReportUpdate }) .input(updateStatusReportUpdateTRPCInput) diff --git a/packages/api/src/router/subscriber-notification.ts b/packages/api/src/router/subscriber-notification.ts new file mode 100644 index 00000000..2f2cffaa --- /dev/null +++ b/packages/api/src/router/subscriber-notification.ts @@ -0,0 +1,44 @@ +import { Events } from "@openstatus/analytics"; +import { notifyMaintenance } from "@openstatus/services/maintenance"; +import { notifyStatusReport } from "@openstatus/services/status-report"; +import { z } from "zod"; + +import { toServiceCtx, toTRPCError } from "../service-adapter"; +import { createTRPCRouter, protectedProcedure } from "../trpc"; + +// Subscriber dispatch fans out across every channel (email + webhook), so it +// must run on the lambda runtime: the email channel (Resend + react-email +// render) can't run on Edge and would silently drop emails while webhooks +// still go out. Kept off the statusReport/maintenance routers, which are +// Edge-served — see the `lambdas` list in the dashboard tRPC client. +export const subscriberNotificationRouter = createTRPCRouter({ + statusReport: protectedProcedure + .meta({ track: Events.NotifyReport }) + .input(z.object({ id: z.number() })) + .mutation(async ({ ctx, input }) => { + try { + await notifyStatusReport({ + ctx: toServiceCtx(ctx), + input: { statusReportUpdateId: input.id }, + }); + return { success: true }; + } catch (err) { + toTRPCError(err); + } + }), + + maintenance: protectedProcedure + .meta({ track: Events.NotifyMaintenance }) + .input(z.object({ id: z.number() })) + .mutation(async ({ ctx, input }) => { + try { + await notifyMaintenance({ + ctx: toServiceCtx(ctx), + input: { maintenanceId: input.id }, + }); + return { success: true }; + } catch (err) { + toTRPCError(err); + } + }), +}); diff --git a/packages/subscriptions/src/payload.ts b/packages/subscriptions/src/payload.ts index df509aee..d5c43338 100644 --- a/packages/subscriptions/src/payload.ts +++ b/packages/subscriptions/src/payload.ts @@ -8,7 +8,7 @@ export const WEBHOOK_PAYLOAD_VERSION = "1" as const; const componentSchema = z.object({ id: z.number().int(), name: z.string(), - impact: pageComponentImpactSchema, + impact: pageComponentImpactSchema.nullish(), }); const pageSchema = z.object({ @@ -19,8 +19,8 @@ const pageSchema = z.object({ }); const subscriptionSchema = z.object({ - manage_url: z.string().nullable(), - unsubscribe_url: z.string().nullable(), + manage_url: z.string().nullish(), + unsubscribe_url: z.string().nullish(), }); export const statusReportWebhookSchema = z.object({ -- 2.51.2 From 9a4ae2fa571aa7699431f2f0782bb6294cbb8aa5 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Sun, 28 Jun 2026 19:33:59 +0200 Subject: [PATCH 05/69] fix: notify subscribers early return (#2320) * fix: notify subscribers early return * refactor: use workspace.get * chore: drop getWorkspace --- apps/dashboard/src/components/forms/maintenance/form.tsx | 7 +++---- .../src/components/forms/settings/form-api-key.tsx | 4 +--- .../forms/status-report-update/form-status-report.tsx | 7 +++---- .../src/components/forms/status-report-update/form.tsx | 9 +++++---- .../src/components/forms/status-report/form.tsx | 7 +++---- packages/api/src/router/subscriber-notification.ts | 6 ++++++ packages/api/src/router/workspace.test.ts | 4 ++-- packages/api/src/router/workspace.ts | 9 --------- 8 files changed, 23 insertions(+), 30 deletions(-) diff --git a/apps/dashboard/src/components/forms/maintenance/form.tsx b/apps/dashboard/src/components/forms/maintenance/form.tsx index c9e59df2..f23f1671 100644 --- a/apps/dashboard/src/components/forms/maintenance/form.tsx +++ b/apps/dashboard/src/components/forms/maintenance/form.tsx @@ -79,9 +79,7 @@ export function FormMaintenance({ onSubmit: (values: FormValues) => Promise; }) { const trpc = useTRPC(); - const { data: workspace } = useQuery( - trpc.workspace.getWorkspace.queryOptions(), - ); + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const mobile = useIsMobile(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const form = useForm({ @@ -92,9 +90,10 @@ export function FormMaintenance({ startDate: new Date(), endDate: addDays(new Date(), 1), pageComponents: [], - notifySubscribers: true, + notifySubscribers: !!workspace?.limits["status-subscribers"], }, }); + const watchEndDate = form.watch("endDate"); const watchMessage = form.watch("message"); const [isPending, startTransition] = useTransition(); diff --git a/apps/dashboard/src/components/forms/settings/form-api-key.tsx b/apps/dashboard/src/components/forms/settings/form-api-key.tsx index 0873fce9..83486abd 100644 --- a/apps/dashboard/src/components/forms/settings/form-api-key.tsx +++ b/apps/dashboard/src/components/forms/settings/form-api-key.tsx @@ -114,9 +114,7 @@ export function FormApiKey() { }, }); - const { data: workspace } = useQuery( - trpc.workspace.getWorkspace.queryOptions(), - ); + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const { data: apiKeys = [], refetch } = useQuery( trpc.apiKeyRouter.getAll.queryOptions(), ); diff --git a/apps/dashboard/src/components/forms/status-report-update/form-status-report.tsx b/apps/dashboard/src/components/forms/status-report-update/form-status-report.tsx index dd6312e4..b596c0fe 100644 --- a/apps/dashboard/src/components/forms/status-report-update/form-status-report.tsx +++ b/apps/dashboard/src/components/forms/status-report-update/form-status-report.tsx @@ -100,9 +100,7 @@ export function FormStatusReportUpdateCard({ }) { const { reportId } = useParams<{ id: string; reportId: string }>(); const trpc = useTRPC(); - const { data: workspace } = useQuery( - trpc.workspace.getWorkspace.queryOptions(), - ); + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const mobile = useIsMobile(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const form = useForm({ @@ -112,9 +110,10 @@ export function FormStatusReportUpdateCard({ message: "", date: new Date(), componentImpacts: undefined, - notifySubscribers: true, + notifySubscribers: !!workspace?.limits["status-subscribers"], }, }); + const watchMessage = form.watch("message"); const [isPending, startTransition] = useTransition(); const { setIsDirty } = useFormSheetDirty(); diff --git a/apps/dashboard/src/components/forms/status-report-update/form.tsx b/apps/dashboard/src/components/forms/status-report-update/form.tsx index 798728df..eefef755 100644 --- a/apps/dashboard/src/components/forms/status-report-update/form.tsx +++ b/apps/dashboard/src/components/forms/status-report-update/form.tsx @@ -87,9 +87,7 @@ export function FormStatusReportUpdate({ allowUnsetImpacts?: boolean; }) { const trpc = useTRPC(); - const { data: workspace } = useQuery( - trpc.workspace.getWorkspace.queryOptions(), - ); + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const mobile = useIsMobile(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const form = useForm({ @@ -99,9 +97,12 @@ export function FormStatusReportUpdate({ message: defaultValues?.message ?? "", date: defaultValues?.date ?? new Date(), componentImpacts: defaultValues?.componentImpacts, - notifySubscribers: defaultValues?.notifySubscribers ?? true, + notifySubscribers: + defaultValues?.notifySubscribers ?? + !!workspace?.limits["status-subscribers"], }, }); + const watchMessage = form.watch("message"); const [isPending, startTransition] = useTransition(); const { setIsDirty } = useFormSheetDirty(); diff --git a/apps/dashboard/src/components/forms/status-report/form.tsx b/apps/dashboard/src/components/forms/status-report/form.tsx index b17eff8b..a0f89469 100644 --- a/apps/dashboard/src/components/forms/status-report/form.tsx +++ b/apps/dashboard/src/components/forms/status-report/form.tsx @@ -101,9 +101,7 @@ export function FormStatusReport({ items: CheckboxTreeItem[]; }) { const trpc = useTRPC(); - const { data: workspace } = useQuery( - trpc.workspace.getWorkspace.queryOptions(), - ); + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); const mobile = useIsMobile(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const form = useForm({ @@ -114,9 +112,10 @@ export function FormStatusReport({ message: "", date: new Date(), pageComponents: [], - notifySubscribers: true, + notifySubscribers: !!workspace?.limits["status-subscribers"], }, }); + const watchMessage = form.watch("message"); const watchPageComponents = form.watch("pageComponents"); const [isPending, startTransition] = useTransition(); diff --git a/packages/api/src/router/subscriber-notification.ts b/packages/api/src/router/subscriber-notification.ts index 2f2cffaa..7b1eb7a2 100644 --- a/packages/api/src/router/subscriber-notification.ts +++ b/packages/api/src/router/subscriber-notification.ts @@ -16,6 +16,9 @@ export const subscriberNotificationRouter = createTRPCRouter({ .meta({ track: Events.NotifyReport }) .input(z.object({ id: z.number() })) .mutation(async ({ ctx, input }) => { + if (!ctx.workspace.limits["status-subscribers"]) { + return { success: false }; + } try { await notifyStatusReport({ ctx: toServiceCtx(ctx), @@ -31,6 +34,9 @@ export const subscriberNotificationRouter = createTRPCRouter({ .meta({ track: Events.NotifyMaintenance }) .input(z.object({ id: z.number() })) .mutation(async ({ ctx, input }) => { + if (!ctx.workspace.limits["status-subscribers"]) { + return { success: false }; + } try { await notifyMaintenance({ ctx: toServiceCtx(ctx), diff --git a/packages/api/src/router/workspace.test.ts b/packages/api/src/router/workspace.test.ts index 9c1eb5ec..02b14002 100644 --- a/packages/api/src/router/workspace.test.ts +++ b/packages/api/src/router/workspace.test.ts @@ -18,7 +18,7 @@ test("Get Test Workspace", async () => { }); const caller = edgeRouter.createCaller(ctx); - const result = await caller.workspace.getWorkspace(); + const result = await caller.workspace.get(); expect(result).toMatchObject({ id: 1, @@ -47,7 +47,7 @@ test("by default we get the first workspace", async () => { }); const caller = edgeRouter.createCaller(ctx); - const result = await caller.workspace.getWorkspace(); + const result = await caller.workspace.get(); expect(result).toMatchObject({ id: 1, diff --git a/packages/api/src/router/workspace.ts b/packages/api/src/router/workspace.ts index feaf1b19..71ac0fa8 100644 --- a/packages/api/src/router/workspace.ts +++ b/packages/api/src/router/workspace.ts @@ -1,6 +1,5 @@ import { Events } from "@openstatus/analytics"; import { - getWorkspace, getWorkspaceWithUsage, listWorkspaces, updateWorkspaceName, @@ -11,14 +10,6 @@ import { toServiceCtx, toTRPCError } from "../service-adapter"; import { createTRPCRouter, protectedProcedure } from "../trpc"; export const workspaceRouter = createTRPCRouter({ - getWorkspace: protectedProcedure.query(async ({ ctx }) => { - try { - return await getWorkspace({ ctx: toServiceCtx(ctx) }); - } catch (err) { - toTRPCError(err); - } - }), - get: protectedProcedure.query(async ({ ctx }) => { try { return await getWorkspaceWithUsage({ ctx: toServiceCtx(ctx) }); -- 2.51.2 From 1e95ec4bcfb5911c1ffc49f7e2b38be8749a3cc3 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Mon, 29 Jun 2026 20:12:04 +0200 Subject: [PATCH 06/69] chore: statuspage socials notifier (#2317) * chore: statuspage socials notifier * fix: wording * chore: changelog --- .../status-page-socials-notifier.png | Bin 0 -> 394516 bytes .../bsky-settings-create-app-success.png | Bin 0 -> 263307 bytes .../bsky-settings-create-app.png | Bin 0 -> 256991 bytes .../bsky-settings-security.png | Bin 0 -> 367269 bytes .../bsky-settings.png | Bin 0 -> 338084 bytes .../openstatus-subscribers-webhook.png | Bin 0 -> 477818 bytes ...eveloper-console-app-oauth-key-success.png | Bin 0 -> 691557 bytes .../x-developer-console-app-oauth-key.png | Bin 0 -> 349050 bytes .../x-developer-console-apps.png | Bin 0 -> 280383 bytes ...x-developer-console-create-app-success.png | Bin 0 -> 512464 bytes .../x-developer-console-create-app.png | Bin 0 -> 524855 bytes apps/web/src/content/docs.config.ts | 4 + .../status-page-socials-notifier.mdx | 16 ++ ...-to-deploy-statuspage-socials-notifier.mdx | 174 +++++++++++++++ .../pages/docs/reference/subscriber.mdx | 200 ++++++++++++++++++ 15 files changed, 394 insertions(+) create mode 100644 apps/web/public/assets/changelog/status-page-socials-notifier.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app-success.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-security.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/openstatus-subscribers-webhook.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-app-oauth-key-success.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-app-oauth-key.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-apps.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-create-app-success.png create mode 100644 apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-create-app.png create mode 100644 apps/web/src/content/pages/changelog/status-page-socials-notifier.mdx create mode 100644 apps/web/src/content/pages/docs/guides/how-to-deploy-statuspage-socials-notifier.mdx diff --git a/apps/web/public/assets/changelog/status-page-socials-notifier.png b/apps/web/public/assets/changelog/status-page-socials-notifier.png new file mode 100644 index 0000000000000000000000000000000000000000..43761b9fd8c2f387263111d89978a25b83f04615 GIT binary patch literal 394516 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

r+opd)Z)J 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 Ls30by0F(^D} z^sSlo=p&z(sw&a5)|{EK@%psllTqjXysA+xT66RmYyK_GqY5Xd2drBEiRE?i(iTgx zLud0XI$kDU2`J_Z`*HA>jpo+Zce0zACr=mY<(-(>XIU64XqjrMe}A3xTIGJd|b%P$T#b(;%j!__Z!Zv|75pu&hx$N^c;R(v-$8e zGB{>^ue6wq{;bym*TvsNg{x0XZme!+-u)^k|K^ul|G(akiq3ldhtE9m;j`=?SI*Y# zNh*1_AZ(6#MWT9jymZUeKI6{^8K#M|w}rmpSa130hx@j5t-{lDo(9U^E-2Kyb-nzW zO5sJ}_ukjU>mEk){JMIeF+Emx&R)IrzG-i371mromhkZS!|fZS=I2VR`IUUnH22(@ z?t6kiCD>k61$M36S+y_IwofcwQ)aql+1km*qKjG8{G|$3zLGItx3O!@l&QhWQdKuC z*2!eJp62XR*V}4!&i0#j=k>OnGfh^nrxu5KtgSYAe(QAw8h_e8Cy08h z%RM}7=*lY~sxQ-QeC_+@ljUo9Z@>M?VP)2{Qg)67+yB4s>(9^fIydLNT2aDw-K9@0 zPVKdy^E^Tze)=y)+4`qvHqNh-UfohNZ?0w2*R)qcr`||<%huM_H?v;f*<9X#Say1~ zb7W@oJz=MElj~lm?ujqTx?}(Ug3R`lYJ1ifzb#h%ZpA6EhU@F|>FPQ?XK%$7&-?qT zO7ODH!B9rdC7+mo8^M87)H{hCQX(;)tRc-*=7jn8WJ zvb$~++q_6QnRxn6QQh+!%h`S`kLT6nx@7rjtAMm@b)7uV`hRVzJIN%J%M*ME=Y!0xk_92eHF+VL|o-+|-J z?`a9)Jaevyn%$e~?zd|n+gL0zv;XAt-{A1m)U;!{=WNr|D%`pDwK>ECLEo# zv}}9&cNs@5rZZ)`}pZMHYyUgaz&Oq&2#m5Wd=FYyJ(O@~T86xP0Dy~fs9{7UzZzYIp%hl=D@t*>)c-{EIvqaP zJmYNPanW_5+Q(&l<}H8dxu(-_XWqNT=bFz->l(xywm8BjQ#zkPP3_yNJwG%}ex30x zI&Su{a!KNk8~KN3&Z|;QOR7D(Ozelhb@H{ZCWZ^&bMIc~o6wpx+fs=AJ6r9?j9=5g zYd3Cqs^EP2(WV66gJt!{`?58!AL%ST+GM@)%=&9=g&*T2bnbUX{>WT?#EO01pA$2` zE}RjX{C>Sr%4x;E&TS$u4VB|FcZdHvyZyVTQ1;;q_gT&rm?k}q%hA3#cYLktY7Vt@$cX9($>e~q@|Ki-+0b>)2{Y^_?Z`-KkfhUU;Z(#vgw&_*uInH ziJhHu^lu#D>A#Y>9nix0$uF z`xADGeMwz2SN7Wzr*p#0KaK4FD)gJa{qHDan|5XLM`vf(dFf|vRPk4ASpIJ1)5!E! zbAQkLUQ%;wW4Z_Xo}L^F+0R!bO}D-(_W3@~FjSrSQG2-aySr!BU!PVry=k^aTCn(U z^H0SQKW^L?HamCa!*lWHJLi|g1{&8aILYtLDDi0C+v8qUQia)lyUx3D?6-K9YJ7BK z)J7qR>OT*f+W+5~tj2XyNc!x$-lrR`vwbb9E&2OD@%Eh8EA+FncJMzryYqACx*zS5 zl~o2C=C2i!uAEnq_rQ7bkz<>C_tiCYo$Y*QVb^K>dv`9Y;9rFJ^h0Ww>0GM|Jz~0FB%~oU{aLKVs)utT<<}W2 zrmue^bNK(2154v-_gQav{JZb){OFDA#O-4qNt)F?j4AX!Y)kqUv-|t{w+DYkUDeE} zidQr~-YLua?c`MBc~9rEsINZQarf7ULW3L6*|(VcWT&q?a=7mBtp(5Y1kLLBb#;%ZhX(L_ka7>|9ig2#n#PwBz0-Jen9U|hFa6Y z35wgc9zWdkw_)*R>uK7Bu|4qz4;^Xlzq?73_l9)S-h{;ON2XhB_DtMaVs-J`6yGc} z-a~oLE%V-+@mtDlnh`RiT{C}zQSsVm4<+~KJ`{DkKhf-6=XB}jdCMvm=xWVTS@PaN zwz^4jKOaxC#LeYxdB-dsKPcI^L5_E2Z$7)I^X(OJeKkj0MD0GYIaZtSPu@A*_inz; z@yr=Y3NGOa++D)n7RSN{*&UqW1C#xqt*|M?7XdBP@w09Rx>%J`G zI2*l2^ys7CAF{7cx~pILJiLy5(XK|><&_c1eY%kqa%mM3F1JD+J)V`H+;FbCyGQzP zr)&T99T(?h_C5OjEPVM<_RGoEb zl?|7>6vfwEZ&O|B>D6~#KH|?z+vMw(KN8qWj-Q(SzJ5~nlfwHw$x`AOWh}k6Q7=WZ z_w(F1;Q8RivHG`v8Tr58|0r_W*8ayV6Z1}%edaxf{>AReO)}>%On7E4@!9dHn}O2w zZ`N&>pM5D^|2cE|My3zTB^GDindA57n#GNck#`06tMH*b7fyC>pt{F`FgvO4{`&fZ`*(Ce9%9@2T&&|GWUbErcch2nMXWJtV zM(cMrr5xZ$S1ioo-u?Zi?)s-KQW8({wk6O1yf^XMF{8N^&+o|oU_QO||MI_+-)W>g zvf-a|_f>#!&dmGv{~t^j+fuZ1e*`CcVUP0l>JFbn7KOjs%Pggvv)5giTcE7U(!T%e zp2Yp#j|v++;|{4FQNHJNU`LKT(kefl?WI1>%tt>j|vnfXV-kLxo&agw-5UxyC$~X zC9%@8;@|9XTM;h3!#rZmo9{>D&K%o&nCnlI?VnxO*tb0ts4VV{7C&ut+a}3uR^W$U z4`*{!_-)tW>Yv-hJ?HYP?qdDK@798OhflxoT698q`SYAdD{PmUhWD?1+z@T~@bd57 z>;8+nZ@mBa{}!hE@-hGXPyerczW3z1cD=g_bsrWR=K$SEoNji171L_;Z4F;{-*0oAJp0!jx2H2Kq_c}|&i0g-`gcLv=T6Dy z^|g5glQ-Z0@L_W7&xyJb4)rU`_eiOSRZl!`*704!{$7S;MKRyG8yj!mFuZtq>ff$o z@(dY$A6{Cl5H0L+zkefb-zT-V#u1N%nLmDbyZr32Idb2SwZs) zZ`t%_$lTCM`}eZ(A49{;(kw|^drm&jKPGicB7&v=7pKeBJd}#{(*82~;jiQ=2is#)i+P>x2Q}ZnXitO_vUT$0eZmWL8 z%^S;;miPNVEKtz;p2jo(=%(KX-MrUcc_W^D{e*kJZ^OY!-bNAC7b5Og9p$bp+V@HJ zxpvw+$3Mp!-?MLC#(1Q)fayi*JLb~{-`f&qzP_SYymt~$@C%`q<41aGpNR?<9@n?C z-k$NMOg1R`oAvp?3C*nTJNm?4XouCws24le{+xE-c>jZ^?WIC(so^?z(iGBa&F_^* zSVq>_A6k^1Tzl31pQg?0vTN6_bbWYrIa&6A!1j%&Cf~O>$G-LC*3xZzv!6aX_Lir2 zYDPF#cymY z*FOJy-dp&)=o}f9*;bR&U%xTDer(O;srMhAF->EB82$09+@7raGY(ED@17dWC200x z)p`D`)Y&UH`$a#W#bj{)){ZUfD%O2=^VaCJER#5%{eh2Zs&whss%i0dPS5V#KN2W& z?^Vqq)|@wQWaSe*)feU&M3%i*u$n))*{v+~{*R-R`8eB!`@_%Fp0j%OCgP)|p}!XM z-Jib>Yrf!HlYI1hg8%*_5&QowZ9N!hdh1Zb_5(@1wQ2VM)Yqn;Ia{7{D0tlij~m(D z@^UX$ntV@A`PB1z*3r99Usyi+rRw(h;Kbs%(?1?G_65hC-M({c*o%zv>-(EpbEn&W zZu!6MU3}-$XFE-&e>_$BZT7J_NxZk8+_uq4wRdF-`7$etcV`Fn9OM!1)UM`}c1KmtW_y z{`#5hcoI0G^Sjb*le6@BQX|jrX1ejeo&U({SqHV-V`0Qb!3>mm&X?VS0FWyQ|fledg(}CiC;p+i;ROC+VTh&!y`gd}qI# zwjuYk{qv0HOzc0dR8IR@Arb!SjeFto>g2vX5jK~E?(!Ts^Of({9yf*0?0Y7uZCly> z&e}Tdr^eKoA1};!cX=eXWDYmue+?ibE8_dF0^ z_E|1{L)>4zoIAfGr2S^;8`L+f$i5LDbNHOI+vDqIub*7s@GS4#k89#v&$b6!&2POD z@iJFA!T!aZlxuSHtLp`xObFc3oqO(@Y~9B1{70lGUp}_#YtM_PygllIg2++aqmshefaMJ^PQFD7Royo38vK^Xw3WaBSu9r+R)c% zPO~B3jZd7~%O_au;?N5IANhvq9$WeTKAHbrH)G$<4fa;0G0`DgTw zU*n#=P|`NteXZLpujd^rDvnKLd;WQ4@uQ%=aP|f4&TsUX4a^PxHU20F@tg2%!<+LF zLd+5WE7dnJ9n-Zpyl`T+N>EWZTi&M)BKxayd8169t>8RSa53U*Pwc+=8`Nz1j;xu^ z-6(NpVcDMLET6V9zs`>Q)EaB^M4Dk&jlj&Gy30z|M=&sMPrLD9%S8Um5-S7c-@K?? zS@|x#hfmYz#MvACkMAYKe*XB@GAZZHIre!K-uDg5a{X_tU3>MN`YsNU+2!U8RmV>4 z77h6{<^5CnmycM>k36vYU1!WtXxc=u1WKVn6H{Cn`JJoK0NpC^Z| ze%+)uUGcQ&($zlG1J^HERkiT!&;5;CtM!t0-)H=gcvf=r|9vcl8fyD4y_S(l;8i-` z*0}PquBzF+#+=q)`3bHIcbuxe)@;M~Y-8lPx6*&xBgB;p1?P1?n!%s9{MBLg&wm-T z#n*1UD|q)x(RInQYo`f1p4oouN$AdsnC$G}W|`v$cBon3dB4HP+b8~DUi9@1cjSMh z#zl44aWvk4`n&0CXN04s@x3E2etl$rrE==*+0q=D%|_v%NZjiEXz*8$*-nT8r-;OFrjUHLcx$^md0+;>R05na?(hYyJMq zs#Edz@tWwh31QOD>pChv>^_xp_pZW5L-x7K@ky+X?>Byu)!6$u({2;zyo8Ld(xg*A zt=Fs*E_Rdu&v8Kh$*hiJVzD_ZYW~bh`MJm8JZIZa^{rleY}>Y{A5A-^?R&rCWw88{ zv%9Yc6*q0avodsN`Mj-_YmXY6{b#ur$NDx(Vcx#NTX!N7FIN=J+j+vGO14(_vU28` zqgrNlPhYP(_47*QYd@W!+76l1lg&1@UUj&CB-TXHI*+$v^A=M@Z?7Y&bKXC6ZJI1F zr)IMD?h|)+PBc3s9eiQWh9wVYuMhRsF5O^bW_PTy{b3m1u&kL9s? z?kZ&Zi*@>=ApO^i_P&ptmUnzvO}p#PqDvN^4>R=MYT=%D>*?=T=6A0BlGTYiY}eZw zrm^?Atl0BcJKA`5{yp-wt6RX@{pg}Qp~swjziNC55$i7csWD@oRhF&9+r+79z3*3= zevGr>e_mAM@K*fJjRi(!Iad6=C%0|7vgrB^+pv`LET_v2>$O7$g* zORv?as>$b8zY5=T_+rDpF4b+H<^`&!c|Hh_nO<~MU_3V@Ny4>F#vUScS54x*TfAN*QytaRv zl+WXJ=db;AIQlceQgfO7syJ;!Rh#0ngoTaUD^%WZ`1*g6{+_UFN_*6tS|gT3`i6gt zVLy1c(tNqWvxMBhlXH}^?j$aqHtA-=SGl-FhUFXku4`*=G4y!Elzx^sZ0`KSj}l6L zxHEp-^I%5VuT~{$flUTeZ9Mj%$a$0inlxweA8zm?f%&9v;l44f!AP{@z(Lf8#W(J=t?PEAKl)w-`pH_q>J?Qv5 zE7_oq;b?Hj+tWpB*7MHYs9bioN4(*@)Q*jh6hg!|JpJ11W>$CDF6{LBP^)4m4PGzv zJDle^7R!p)JpNH~KSuic{e!zQ{(LwjSGM-eME>c=-oF#xo_+RU@0@kpY}Kzm>z=-c zQDTPGn|1jjr?%#P;JtSLwEC|fF;7+4j~`T4_l?|{kbYHV?gszZM=Zs+%6xiWWPF`z zx9Qi~+TSJhK;dQq^pIKUQ&DGHQT~_DfW8B$1N@DhUv!Uqt5FN zUTL}SCvYe2%N5(I6K`Ul%eGg$_u9|M}w)pK{kO zd~xqnu#Ux~(CEVRPJcMEUo(4atxdhY@$+PxFR9yCcU~2Yc2HfH?cFp*z2Wf;o6;7c zy4t7vlKLM83iQd}b!^F9uikw!@!8RD{>4`;&ecfwmvqbTeq3`>bz8iFu<_x`*ETl1 zJu0#FY(t8H@}CJc+`U1Y{)#ks-Me_2=YHPhpZjzfmv1|`p1DKPefNV0{$^KB##{7m zI{JERfQoJDwTqKm=6`JM`u0M&eM{2y$Vbwq8^7)9Vl6q^cmA1{-s^o`u|Kl!th-*M z6;%7)MtD2xjV&R`^#`Xh8w)4YS^Q;vv(9DCmHb}pwRduVvae9*4HJ6+*PA3^&mAekn_H@mb=O`wRNFAs zH|AGHOL*A9XZC(=n`2|r+BR0TzZH)9{Pt_{H4A%(Er(^RWh3WU#BDgmKXdE3uRk_? zKj1i3LUN_xo;T;8MJ<&28Co6Tw>H+artj1r^K*-eY@b9OdLp|m=IF)e<_B60POzWX zw)%Z#77Tt+Ut~iyKI|23-lD~FICyHB~<$rOZGKo=j%6T z$7N-7-@5;6k+0VL)Bks5X7pAcxqml*-GT4y)A#RuP=7quY*(Do?1!O3bM?17TTZ{v zmQ}JMzbNy|T<`nS|GS>|+^{j(`QaSi$@<6s?G}B0d7?Rg{Hp_d*;`p}Dzft)TzgRZ z>dHT^Z_2c@D0;YPR@;6p8oqOTe(?Q(Q5POH3tPh zOQ(G(kI9^$Rd%kpaO?EhPxh@7td1)_db27(O2BB}?V5X&Uv}E|`wQyqKgQ|kzafkL z>f@cQ-ivR^l>X5&>y!TY{Nj%I&xtp*uUYEfRY{Neq|3;D5+(|MUtM8X($o%kC zU8}U8vHR>Y2Rk19JpbF`OC7@B{NnxN`|je-XRlVPRm*AZ{J!~Kp?%>oC#I)UR#>Ek ze3=yfr^#0E^sa)9o@O^3inqjs{f#f_T&X8kp;B)7{El61#KwG)#h*T34|sQ`P3dYw zhQ)HzeVfm%)i3JTdL_x|0?JBLea z`X`!(nw^`>@aE<0kF%UhzE%BH_|OtBBj4ri^5{)v@h2J2eeX(xR|j30_c>{s-=@x+ zo7C5QW|$qm@tx<5-}gM0>&2RP&$8;#+riykI^AN4-1gHK3izC7?Vq~$igAS8d#?G` zG5(h}&#m>^zs3E`QMvu<@2alt`up<6SH0s(y{x;EZrLXaU!GT<;}!Y)+Ux_XmE)=d z{(oA&fGuOcML_gx_2uh62ggM77M{D8=pK9GmH+;pnbrS=BUsM{ecW3jq}adSWOg-k z`+}<$l1~aPuFo@km9YJAFn^o)_rhD(dgZ&zk8ZPj^1fzK>}T=I&A(sYSokAzdc`E~ zK6&Sulbh#gwsmj%aOwW~21qie0}>ywaCTUds}Sn*TihR@}Bp# z=ae^F4!0b$QP{se{r05y4aI~6{^{ZsXi^#>;G-*(mPe?97bMJ>0j9)77W&=0NE`+Mol!ApOQ z!dSYRzMac|-nI4lo#dRJ&!OjD=SOvQ&3RY$%uLCYtAZtX`K>K+%i~|wn*E+S|7&@s z|I=Ka{MSD5b?JYM+}(8_NbYxwEIq6HYVWdFzs?-p@UwsGs`l+SLUJ-y`qNyk>M!%? zZ?RE6qBTk8aDb)JTg&bIiFU`PS^Hf1;s5iUe{ZjE#;o`onKF~ltWcW!_o{kIi0U%# z?mg=x%Fg|EjQPI%`Tp3l4_tCTv8tu)0Z%$fWbm zdp6GSb-bj$eJ|UAiw^?Di@wVJ*z+U7E$@V+D3fUc_v{-#)ZZ)&by<8Y+-vQ@05&sq zmGaE!dld)5PbqAz>eV!xyVzRaaDP(v)*qd&PWR7$Se+1kzjgYbFLf(FHnwKHeD!;C z1iQ*(3)A!8EI&P5?srYmF1pq$OsDqM^c(MP94$`p_d2%LedAw$@#(P}pA?+_z9sQY zssD|g{Bm34+Nv+?m}qi!ouF9E<69klQ#Ok~nN#if==MR^7p|TMvNj(q-u5j2*+R?p z46|PUQCs?vMg3j3zerj6k0~ee9+ojznNc-qzchcHVH-HI2QiM3(z33F584 z&i-xnxfL?&wmkl`I)dYeK>A;Ap&uXjPd>QR_>+FbPaVUrhv$2me>`Us@hwE}@xuL@ zt~;->ubN$z@UCm^$ytk69?#tEVqX7LW1H&!nU(*vt^a@1mcOv%+RCHfPW};;tX;xw z-+V6c_r{{_sZV|9$All-9me>&;%nwcm!l7>p5C(Dm2mNT`U^juWzzBYTsN>8%-PXn zf9%%#qur72oaU`8>6_aM^)#r@lPDztzPq zH?j0yMV0TIAJ-QA?bPqv_e;22wuBBCV$X3e0zZJM`-JDe-He$$}3PuXZ!MHTs;M)4VNSyPRR+Z@YiX zxN7PPe$M9lyT4@e+iBfF;>!1rGy9ZIeSg|q`t#Ey`8DRp-boZ2rf~e!^E3SH|1qpHyjyy-NtvzjG|#&`U$#9<5nuL}Gu!V? zU|iw!9dRYArt82#Ya}>9*sE|UVTF0r=;Mo-JkbA_MSIGc<-iv66yEP z7FkZV{^@_e_i4JJxcnRW|3Ckqu?k$O-j=$tEBfTk`G!Z;H?Di_p53MY{D~Cn>g|_} zC492ay!6}|b9CME*voS^pSyD}DLDLg$Lt$Bw3w|oNL<-|geSOMdGV{Qi+$+u^*j9&Y7U<5{2MP4(Y3gdarbM>Gw}hyT_WskZ#2 zTMJc}n?HIxKO*VK|E^c^0k5`vw6>pH&b#+cv-!o-CrX)Kb8P;;@7inDG{=q6)oUe- zy*@wP(0lF0W6P+t{$^os#i(@Y)48?Z|LA<_-1}_T>zFzA3$Az?&ScI0zA!WT=H$Th zn&)#?Jly$X&Cf$d4lAaovaxzAKA%^7a{Hdue2PzJ-1qtJ(0;$#+m7x6-zQ7uA;pZ#w?IeasbKkH=YeVy+&;?{hKS8QBiDYwMpMUM~ivpWE*#nLJD=Q3D2XHiM= zQ{8rbX3VSOQFH$szfmd8>DBd0B=~;8Gz+nIU(r|k5p$o{N8V#QJkQ0|Fm=;G?rrwH zX8LL@s;iG3lT3UeAbH(>Nz&Ktn~F9bd>3}x<3Q5(uSeHd-qUhV2(F2mr@ZZGWX*@U z#T8#`10 z`zs=T^$DB9Sq(pB8CGAMpuc9SvES`Ff1Ss7%jTKaG~I5?E_uKjc*T1&8~+WLe_dzq zJ9?)*C_fW^Pggzu{}IP|4=;QFv)T2t^`MU7#@xCM>MOr(tvC_rwf!yo1ee_oYP+BP z?zx-jP>`!0YqH*~{HOLZvGWn_cNILoN*$W>b=KY@N$rWBP0Fr4^;BA{U1jm4_#sEt zhsPWG?j^kyJ(Iv2vG2)5)%o+~Q}T=)4YT)Iy*AA`Dl_lV+Pd>UkIhQ1X|AoDCTwA$ zHSOAe&)ezj)4o>bf3MJskZgXjR@`2^`s(qIJ+gPw&&elkOij9SP4vMm^JCwhq;EbM zoE&d_kdL)bc+F3i8y`&f9g#aF)7~}tK$HEE)4MiCY~Z#|O75L3~U=x#g`tT9aD?vFzZZ@w4wr{Ut*tk1s{e(+K zw&}Au`zVdqY9cCx|-nh?rZC;0bG z{#`P==xwCM|D_Xa`(8Dr^Vx{|xL>b{@SlHhy7cbLpI`szyDMh=T*zS8y0~d6VaBzO z9hu_CIT3w~PO?tKwVgk9n8Hm#?$?b!+~AlZP%* z@4JnH4E9MB+ph1P$-O-$BFa|0woKG|%Xy7d``y03FY7G|16JI|++p_!BU%_+1CSPm1B<ydf%sPy8kNWdB*Mj zhr)bUHJ>j(H~**ltFN(Zet$f^>&DepPqY8~CqA8~9Z(v?cunW3e3Vp`Y~&Q>L-zVl zt{N{oW-#w;@oU$;ub-AC>?%sr&xos?T=7X~zVH#t{mbu4@_%|{buT+<($1#*^d~zX z|J!}zSX9lNmfz0;me1@zvUls#8VHjrf9s~KGgm9-Y6&V`=FXC3TUEFJ z=cZSp6^G~jpS?4Q$t3r;`el>qCFd-T?v#nXzOStPzPe73J_^2v>C2H~RX1T6k0?H>bvr zLFe_%S+S>gJa{3M+|V2R^`X?}tInGi9%IVc+kPOT$S>~T-RuMHFRv9GSo$kxztvCA z>Vrw^t>&N4S3hdW{@eWEQ-hUE^L~HmJoTeXHR6+M#4!Pl&741tYB~O{Wqx+yEdLg3 z{>nbLj~Cj6eecXXxUaMG+CBArzGGQ|W@hb6oy?!HdN;h@!o05a^UR}PD;Td^{Y`z> z|N5bEgmJ*8pC2}!u|K>`EbhG5w0ZMmznRCbZeRaZ|NG7NUlm`TIheljHT&8tpEz%~ z7QA?UyHqXh=7av9R)4R(TUmZigXL8%k4}7D-0X-h+scpJ?|5Eb5&wKAINij@C|hg2 z`fcm<=PS4EZ)$yfF8*Hi{hiA}J2<0vcl)UKMc3LHcqexI>&6Hi-e$9@=vPkG*5z%M z_r<+83h2u4*{o+d@WyU?`HjZ?38(ARSKHVY|9-XIEdJ;&Hq9HdRcEii?vm>Hzx(Tz zhoC}h*lE$;8;g!9C{Z%Xl6ntrdS=v#05_wt!nE4OVj|7oqpAG2}2 zV4e5Bx8P=Pe)tdh2j5wrzD|p`)SrD~;q|4j*)ROgpJXZ$U$XC~XHd*#el`3fIbysL_LZDdP;Uw|to>^7{IuWm@Eq9(TK~e<@kh8E zeZOYi9{%gA`Bc+K(dtB(`!8{a$E{vBywM`HuWv+|zsp^G z)jB-vUk$UN?-+TVI zpI`bIa4k7A|5)Gl>@zFBuF$I!ZhW<2id0Ni>0!OyojwN^NNciH*DT9E8)Uen!gcL7 zp0v8-&sMPReEQ3K@5hM~{B?GGN)DGzer6j{y=B#}XWV5ekE1)jt0p`?77EBX4!J{;yQ_oe4ZQCBL6ypL!8EZp-&|Axc0jr+oN`QI2-8UGMnQ#{A= z!>$SO=A}Oq!uTDIw+p{GalW@??&fnF&L>XUo&EQ=yYdsIMIn#HwfKE^c<^maovZxk ze8{_~>?8YJGt~7Di003f{yt~&;q(nh>YjhAEZ+6;R=F@+^?&PI5)Bu-5ALpU&yGH3 z@<(mnoWsT2u5sP0?F&0|bc=jbt7=+D{;wIX73+^5y7gjKaMH4fa3_O0-T#{c>b_U? z{Mr~TGnZRw`|Ka5Ok(~zU8%UOK0ir5RyWb`ZFKjy(*nyWRzOXi9+0C4%ck-2dbjq<4SGGK7 zel455i{pL7pIEsv`$JiZ^XkOIBog}C@BCOaUp%{C{F7+0*jKCRS*C9?-o7`i*4^#) z@X50D?4QLd@6_eQ+09IQr`OM&H-9$Ik+d7OTi=G?V18inbXQf$_ZbftpZofMYK?t! z>AxQru1BUPFaNjP|H;uE;eVDq$+Y}Df7Z?;kNhUHd;PsIXSe4vxuRKXnoV;Kcz6ll zpL4S6k!^O*>N$_Af7=({xM0ICd9Uy2QuQ-6D}?v|Hz_-Qf5!cvs_E79|MC1zH_X@h zUz$_w-}}W{t)}Duva8Qm`uXZj`kd0Me`C&#@8>FK?&F)Ho&6~1$lug8_04?q<|exr zyp{O=M~R2$j%nMk@T2QLZaneE^{>SP`!!jsuRRyNoL;y~@5ya`y@K0+9v6GC3&q^L z{61#gC(!`SH}faUdTc0{dCna4e2(Fq85gaNT~e@+`nDz1_|@5+7CbNapS|W;Z2I8H zfranS)m~e-rrR(u@a6RT;yS;QI+GuFOtJWDT9{Owzw)x;dxMqt&gwtk`|jP&xSnS$ zyXrK;YX7@soWE@y&nR{1SXIjAr1Lv7<_0a(ZoIy5f~UUeYI~cX=f5Zzyb-=}u2Lb+ z>8Y|8cVB7f`CW=yZ9mVh`nBoj4;6XsX zn{SOjWuwn=RvvANH4jhGwXoj(Qabzh(y)Yt>#Gm87tSm# zI4B=cqsFEq?wR;bJnZX&No&6zeNnc_VCw(eH%GQSnp4p!I`w(S*Nx9-e5|}Da7SP6 zT-)q=PpkTNkvTp#@dr=d-|>k-q$=^|_xE*0b?e?&?=71XdEK)Aey4ih+4uZQpDV>| zwJ$pQMegu{{k!i6fcmNR&J*jewrWoMrcoapDH)|dZ#`i=inj=6g0E?s)y z-HNDUKcAI{>uz|i5&m>2!Ta~!h_h#8f zmH*ptJ?4O7#?!#VON)O#P;dYD=rHT~wV`|m4J`5u4<^W-_~Ap?BRHjY%=e$J{-08o%WoEc z&@1>{Qnsg1q<$Uqmu4|O>)+dTc5%m9*gvR}ODRcU{1hr_@q0te*9Y^hUn@S}T&Jic z7H-1KE>-iSa^B{Nr82Ynb@^gSgf~3;vpeEP@bca9J1Up9eaTHf_j5wd>kTXa$%@tf zIre?(?zl_eop)SGJkHWKr*rSFFVgvMqNLBJ?fLm{!4B7z8O!?5eSUXZ+SYDu8S9+P zjVCTXul}-0L2s{g`}dxc+FISW<~-xwd;aX&njcBa8GEF5Uf;uZ>eg!w(=F^Ld$ufm zf6*$xS9Xp?;p?cC`DeQ2=YQVh{>N%v#q&>F>#zN0iQW6OPi{8PnfEi|uBR5LaXwGD zZJT)gTH^C_C-xniyKu#+w^ahgubcYJRU|C@6lkw#%=q|p8{4|$v)YdZ8-HE5wR=uPx>-)3j9!=?_vw3&AIx1`c>C?A>KWA?vX$?u zcWbBqOVND0_FSaGfyWQ}wn|Lx{9b#s!%yL*oCGCA^U;_Xx|aWmQ3n@?U>eC0g-=jmI8HplO` z^%W*1_t@=pD^AMpzGow3q3(aee?zfi+|J|eR-a-OUqAVD_`;0dds8DFzP)_FXE`+` z_pH1Sf%e9aQgX* zvwtUj7T@@{`pCKCmFm;39WDv(znp)3ZQ%Kz4Mv+4It%_T6#mnD^{b5X^F4naRWE$r z>^h@)ZQs3*w_24GzU}>9pjsq2@7JS0&$s*#*jn-D)onxLATUcTtg)xTK&yBEC7 z%UtYtcB^7X1o!_rA^GM`oy?mJSKdo*{@W#8Q$H)V_>VAG{3De#vseF5El-|&#=i9D zmNe%}8saNSnNd+gJ8{N-3I z^+9!sVQl!Bul!ek9Or*EXOBneyvWDbRp(d={X74E)wM&3XZ_dyQ+W2X>Hod3ea&xY z&*l!>ck<=Euruspt3$Q_G#$;~C%d~?(IKU4>-8qTvNKm&=4?#9`SNsSh?~JKKHL4p zx@)ZF%PS?j2ke&Ke@JfMN7uD4-AB42Tu>_QBCK5 z`kw#i)2dDPMYGw2j3+)zjNALYq4h`K)Ghxc>=OT9`t?Bn!{Wp5P2-(z)m<#?(#f8* z=WDd&kE^quSS?vt{>HBO!0SCX>}zcWCcj!^>S_8Zy6%U9e1S~)-0r`x_y3>jX2%j; zJ@>83g!fl&6?}}|l2kVLpw~mwwKI(SVgqEP%|9QmIV-dL%;fB(WontSf4H{AERV0K zOkKY?Zl!+d=_n@Gbx&Lthozr6vEpj=nuD8^zO6g?F7n6O?CYzF=j>2Azt3UsCc7a1 z_vfcuiJyKW^!bNcTKwUUuXoP>J9m%4VxFIqwd>`jpQLDATBDtmx9>_}^9Wv|ZvCux!Wc>k_%tB;#yC%@9Uz!+P|K0E5+{22#};uH6)#y#J4*R8GiWKj0i zo7bn@yRj+1A}>9xN1WC6_qI=uytNNU+;?wXdR5<6UuxDp{`ie=roYi`PWAn_Bgr?R z%J`<)`G_+czsc^5{4ScbIsRtQ<<7Yk(*DoQ>r$7;{5|urDO6YSdwEC9>YI=C4d+KN zZdmRATXjxy?A?uZVZ~_&t8N_TT^;$BaZ@3ywc znpw?S`t{M0?~d`@FH&D;cg_gak6F*J-|Hq~Y5wqz_w$51z^JzJS~e>z%Hl(u8mAFI3#Z!R)DxyKN;KJ|yyf%Iq7 zt+FR}c0XTYvp@NKRKfP|I+snJy_VbiXOkZ5l&RBu6&HTIST}R|N%7iw7dyU7cJt0T z_^x`=#$9aR_6kTZu`^KU-5&AdSKZS&;R!GNBG>)>|7%}b)X~S)FYD_HX1V!Vhxz}s zINu(1CUDD#wE4dK9Q@`?u9&QUWA8HK!-rQ@Jl!&(*-97)8^p&qEp4K~?ssH{O&+AdyEL-2R@8eg$ek?qLqh!j0pPS}gO#Ur?UFc8c zn}}zL-1fpp?+C2Fzc}-9YV^0?Z8sNhY@a``=KM9A|EFyw_Qy^BI@@wzvfrQYKklyu zjVAujtNm|S7JuhW(&o~liyI_Mnm-;6T4!*xK=9PJGD9Jr+Xm*x>NbeRt@)h#;;R%} z+S+ZIzt6PU^FPUWlGVEG^YUvIl@j065+~%XYA>8 zDAD-wWLipEZp^pU5+62SzN?%+A%V^P?1pEJr{7C#nK(D%xV2;RS?9?lxt*$3Fi|zd6$L{W~{8;r8=g+cS z0c*p`%WC-#YPYA%*}CoE=6s{a(&F|zf;--S3h3ppmGtzPu>g-9C7w(Ov=;QS$2C4$i0gb?0Lu^u;C;3@k-sqq%|EsA57ks^=fmi#@vrJ z9TzPAp0nP$aJTu7U-KW76|Gx^ys&etvK_4YhJq^@i|@>SVV-seNZA3ka6H(U0t z5HI}9*3enx*q>o+`ev*>rZnk?G`fa9ol3q~1 z@w%m~uN}_Bw0~YWqo67*cy)8?3&z4Z8%^#Xk@5NX)3@_U`Z52+nc>$YIFc4GZ@uk& ze74nN^UsrNPX6vWe?oP3yG!A(#EaL1vbSdM@0>C4}4gp zcxu;zbHC38%GAD5dnl~a`rUK?!&!f0>uTRJ9p-0u4BfaodBc_0tl1Y>xo;JoFn_1c zd%XL9#YL%0Umw^WFIM`vw^97Zrt?B#*C*xFx?1=?GcR;$He36;tMumHI~zBeHS+Y; z9Aw+S@lENmThgDK51%o#Rhg?U{7S~s^16A>o|lepwn^^%`*>Y9t~t5J+u`2xM_Q$( zXN*%^9&dB`_U3Bc=S7D9ZdkvW-kf~E|BmJT9i@Br)o(6;(LLk;V*BC;20Q(4NH2F^ z>$hh8a%S!7=QW3KeZOLxoOI4u>iNCuqt!dj1z0wIe!9fq3G280H`P^tIDdBbczsVH z`grxa{$o9E71vbE_Nvb{6};+w*#7#V`v;w_ReR01uCo7}uO9JD@K1`{|w^$4W2kJXdx9LY0JmwZYN3yZmI! z&a8j#VY&R{;e|hH+n2H(sZH8@{9M$U`=bA!u-Io7bgg?Gb?N`|l8b6-y;8iFs*TIm zJv?%v>&kWh0QbZ^hd;mWDd=pxK7ao7sQBa~2b*?meYf$T*UG(mb@^@l%kL(4uRZ_S z_`snP2lgm?oZ0!`U1k4snTazTF7G{B##=Gp?pm8AtDW&Nv(jt7F4)f5R#+Vy^|6S- z`g`5`snWmOD|Xv8n5vzBtkd@{a*w#0+Puw+7M*`>Yxeq6pD4G$#t5x zm$N6#+U;`V!(rzQJ=2%^omSPzC@S4|%lg{pNpgp#$G+YF`+gj_D_MQ=|FXj|?Ynjv zeOUUOd&=wnZh<(y;;UExJ=2?>V|V3Xi+THN$HEQS-S!qbuXmaW-@27jt*ZQPwNZ3Z zOm$w{pD)gJTN^K$zmec|FU*N~>XH_B;?b$)Tlao_@n?@vasHMQn_@E+?!7KH>|0j3 zqB(!TtsN@wP8U1G%;V-+*%$HrtOFCDLa=cE1K%VTb(8QircT+I)5))&M18zq`gIa( z#M@V?2GO6B^M0vStmS7<*j(D7VOa2nx8ojvc5L#K<%X8O)0*rAXLM(D+>3AC=*ZW% zG47E~x~#PBoaENiG9NE+S;sT`=`h{=Xj>=EZeg(ezS2g+j15Lbdmnrd&)T}^qVfBe zZk8hD`=9j|Ki=!pAaCGT^ZBVSL%hwN7uj16ewR7_`k7>l#*S$ZL^nNQws^Sr*aLI^ z9~;ZVx2vz{yK4RV;=zxiZ{}?_K3DMI_P_f-_9msS)|dPA>CwZmpB2R!8&s4w)kI6k zr=O|rVf?U<$AVuo@6*z2YbQ4v)=2NV`s2~Ufa3HGoXmSLZ?4g*||(N{&tW} zzW7U}YTi7bYP*(K2Xfy?2`!rSIo0>?%v#gWBC&n!`%I1oEfs&G!7Fz_@sy2v-2LjO z*GfYl9N~LpV9y+xdBP~(udK+x%Ol@x_QP}6fBh+Wzk|8cWlQB@qwjg&bU5Bxvwi2k zI&s@o^XF}$A1B|FV~HrCOmB_x-@oqqi}UA}7N7elDO+gl^+&hll+Tjg56*c{`{<5VRrtMpQ?5`#(NbpOox9BRHEg?9H(gRSo(UImhkZPd=sm(0}&Ck4JZjR3=$8 z{K&l^^jJRR){)&C)=XS$`i}S7ypz-U|EEm;{X>1DQSlu0X_k4rkM23b6Z7~aW6yc^ z>LXES_U6}C$=-Z>aO3xzvi!>PWy>B;yuwnhKPNtY)~+VQ$%*bu4P`&yXmA%%oK~0j z!Ax52xbWupkNtudTzdKU5^`@^em($C*DfPPDw`7xD&3gWi91QZmPT5apo85a$enrEP`~xT1 z8y?T)I57XGljif9n=36#BF;9pB-Q*5KXSG*VdIJKPH7WjBpyHK^iFwVF{Syu73f%k?}Ft#LsV?a^F&|^99SdTUiq>Pj-FQX}T!e zu{3U9SLpu^Q4781w|0wLHTybWe(B!4c&DG;^z^eQ`~N4u57^sTU$^<`yX()7JU#GH zE;`B0onMak&%xw9ujg_ec8hrWdV|dR8!i0TE}6RX6};}E~mdhHKV@9&5e zoxEV}7TYde{YWT(;t{{qZ_jVIKFcHl7M`Ew^KZ`k9nA;Da`v2Zcs}ze^K0K$-Muc?hP_~mJ?gj_2ODg^~nRje~F7l-mh4x#qIugLB`ob{ARB& z8G4+*ck~AD50#pSK{*9Cr`->m@V8#X+Q6MBjpJIt^V{V~=j{J?ueCg;U$$H~WP0(< z()$m0-Mg`d`SII$i{|PVU-uP%VP|}N{pqCqYfYa;b?n^^c_!O!IJ7hDlIgx5V(s%; zC*5W}{r5}H&$iMVleP+S-`~0ZNtHs(v$MW2Utj(x&G_@B&hOH_d)1fRBV>LuU$zT= z)c&_NDXr=Htyf3CBCcsMWdAKEKZC)>dBM72@;0V8Ouv{o^vb_AYxL zkua^STL)GoQ^&yiyP8r?f%Ozr@zj4L>zg5^WJK~J% z#scPT&b*(xbH3f*d$`hjQhMXu^%*6TDh(V8Tuco9FE_4Zo_=jc?Xu>_xp!mOXYVxA zzAt@EtT}hzkpQVL+}eq?W-F4;6h8<$dgMgiclWmIfz4T3#Sk3L%T+3D;3r2ZJi54RSCDK!+X^`3I$THT+yh5?NG?Jrk3 z{8gOB(C*x}?(VP628`13+aE9e#*t~2-*ayLoDYWEPD<-|&3t2dX^vc7b9?fKZfzr_ zW32D*ZoDe`=H7Qskt1pvf)G0%0r+!z)6Ui(mFW#Q_{@4xNV{_ywU)A#Fs-2ZUg z^~STc4ctNTVvApGoqzhmGIcgaiLl}b~uz~z;!>wr0w=>U6#vDZkr?jF!%Da$NDGx>vGtgCtAq7pc#Oy6$dWH7~wW{Ty=z&%%#szn$ej+&E?! z{lz^%>*c1$eEa|K@RwE2IbD}(c%|oe*9%&| z5sf;u@AqFTv)5+Vne4t#3UR6_I69kM=wY+4Q^7u)JqFXVCi$$NY?*Iq;5{=iKs&KE z`KzRy;mn`U(oS{8ISb^RlU{u;;Z_8*-|>^odEa<`+dLO%GW}Asb#3LO6Y@6}1jy7n zznO9Dk8aq6qnc~v7cE>^r+ckAKBIi@2L7<5{?e3`K38L_Pm6D^?7K(;eWZ$ecF{G?&t0QckX??eoncv__tkGcq*TXSw{TY za>cVaCGzLR`x|D7@0)RdThheXiO%g0HQq%$ssG^kmi@*xgMUKSTlYL!{n_Qpj#Co- z3E2lNA}p_)%OARM`;yI*#sltW?miOU_@wHi8`JVlTk=1@zVr73?Y*X3>F&n=uS;@Felb|&}j z>};QR5lgJ6XYV_e`ARq>>9Cyj_QT6x_uQHOL4AW#L*a}~a))PqZDC@rxv_3qa!JWP z^@V!NY#q9rQ{xUVjoZ0VZ0n-0iu_?$Q{I@`21zUBNyo)IPb#$wcplZU=Gn)2#<$P8 z9$;tmwwiNvi9z$8mo@UKnG*zZe^~j?lMiWj&NH4Ex1PQG`oS`z*w5N$qjOG*&#EXY zdKUflQ}n@C$D232Zq|O;=B1pJHorFY=(5jOq;zgc?)koZf_N|fR&B;&TpzSO(H{OqCdw>;-FN30ER-#^PHzk04Z`!tE)arz(AaxLu+Y*Nks zcZVza`cAv{n$XrAy0fEnU7sZ+cFX%EeLwx~$;{%Y+G-8IZ*zY-+%)@eXT!O~ACiwZ z7fu%L-M8>!c~9(ZR&AG1`NZzF{HxxNZ7%Z#o$B__*?#%!KcR`wkN&LdG2N%4l(v&Bj=gI0T!-vR((~%N5bn@oncmd zUbFimv+d5n>g5mE#O~!VKV*HrU;p3%=_5b3DVg1iuq+Rly+3d5rYbXur0>qRw-tEQ zK3-k1E$za$*cqIDQI=2h-lml7Stz?HuWH@r*V6Hyir#d+6#YGU#?D4xi}xFz&7UK5 zbDr|EMHkEDR`3?>>$q7YU07iBZtGO_d%g;#UmSNUO`mg0n`wLY8Ko@U3-_)sUFm7| z_W2Dqwcq?3FW%7R&4$$M$W?)_cB!Y4@&JzHWTPd@mt4WB={)QX4P3x8*Yrv+=F_ zEjsI%Oj_Tn>q_qa3P;*(BG$}0Eh%o6e%tI|Tbj-mSdr?+1HTKld?eE!7K zT>hM2o#gh5N$&dCd6JWTV`$oAfw-0O8*B{L$M3YSsp4%cwMYtZVlUnCb-{aci)(YE z1bgrQb2~7v+oI5CQ=xQT*0HJ_Tes6LYiBJmE^|DtFPnX{>X`V9ETV!wXx6P|9T_hIR*pozl$JlfkAwr#hZ-!JkYw>sg~_B+?)y%!7r zNX@w%^1gD4zh!yM--k&%JvV$@7qdjimAhc(V`t7~6*UZd7K^X%`n+kK3UmG$+3G7^ zZv7EY;__LnUSBGFQS!4l>vrSC?t;uE!T;x2U;h~UvrGCy!a~EMR})_=R_)m>c=?6p z`E>3def$0x_Pt+fTz0@{drihh^RkA{RPFcIoh@_qHY=-4zwoBbSp534pHrLHJkR)e zHatnHtU~?fTH)&-wh7oDzE=IWDDK{?7q?GVbGf(xB z@@0;@N9I`xFP!t4=V-vGpQRnQW#(G&%*~z4vik9#H*ebJ&N#9+No^X7S%k&%qZ;Zx zoE4^7d;IPt*@iDy{P?SGy8MmZe2X&ArA_(ks5|*`{^6;tii{KLBJXT?@nd?>v)LBA z>bh3``|{F4Zo}UV`yy_?Echf|{pywQ&GiYVIoa)mi(gIES^p;e@B7j@3+~po9CeTQ zzU$CuRrRZ@J_pR-JEdpqyoQe|$JTMSU0S%z)xFP}#oxPv*Eu?SD&AGi}o*zrkmruf>KW;oQ@b7CZt=Tt|xzfIW>tUDOHTE~_9Zm@m6;)cVa2_FxsRbKz0du_Hxn|kx!)||fVy4d8ozH@_L{^C9N zS;OnsqdoG;W}my4+V*L;dtKvMW_$FGMeo{$zjmMR-*CY1&-o2U=16uNKA-eh{kl-* zaxu$m%U?U)n%92KR4!*{!NnvUb!;ceEAyB`#~pJaA5Y)dXEo=% z`06>EcJC9^nbvVTLSOIFne0U$XDvDBr*At=P+^ObO2@((rHuxf$J7j?P9;WtJQ5N4 zqrC2fbn)BUi?z40tlw6y7m&HX&v)Mj({~H!RldBrG%P~<;gdT%_`Sv7#bic*m%BbI z#Wv@N+}wy`amroM9l0eu=V!=j8(RCHKhe|7Ru(hK>b6UH&V}2m%Jz4-g{~aCb*e7d zc>e8m(_)%WHqNojT9Ll=`23#DZv8i2SJn9KTBcgQnp-M**XOgGb)S^x9TBljjy}CF zIk7DX ziTR1d{7Byg!NEn(nP1kqZtnjWTe51lZgyAlqTKpEnf1lfwrFxslPGH0SzLYWS;dLz z`Pb&p*|zOQX-xh54V$KPZV66*EaClz$E5C{lT^fu@H5Md3Tl5Oa~pFqdGzKzI~DGC zB}{X|m+gzsp7)=A;kRX#lj1pcot%5(&+cw{U3umB&b8SOneVgMTF(F4ahh3u_B_-3 zYrNejMO|x<>6l%2t8&`cz+UaGCpMn8a;`TzvM=KJg&qCBY_4)GnLdT@0ejgG&hOSb z2_HmG#kNiVa4%8+?)h;vo@2UW?!KU&?~L1UOL@qr)PUEeNOXMFR(%>IFpOH%x`%qP3Vb}#-R_jeh%QlHKBS37Uh#jlfY z`mCSyqUNWk<@EfPeGRoc?{XOIIaU1g)SHrkJt^M#Y8#~E@89OU^{P3g*l^jOZ~eU| zw>r*yVY}|W@se_w2oi6K{OfKU{Q~{qmmeYN5R~;X6Wi-gaO2 zSi+_Lmu~U(8oBVwWT)bt(*M5L@@|?}JZ*<|w*E_|wT_IJ_fHo89Vb8EeAgzaZ-!;Z z&3?*7d~1I_OL_UHt@gFAvu12LySn-NjMy&b`FFD7rycoxWUo$`?fvAZ7er>OE6Zx{ zI^q&hZF=nT*E{L^xL&o2I|6d2O_Z__HTHzOSmEs1~m2%ig_3BhAPB z^c@$|kDO^UIrO_$hgVDwWmmY@!@n`NZ-?JisrKh7(OSG=G2T0L%h#@GT=ea`itgsR z8J-f`T+i3p$9I2{VOXAPZuyhtTg?1#3lBZzP3MSpuQ)oj(xoojXx9$Ab8A*^Dx6oa z!F`T(r^MsW=jsmehnpA9jXU!Ch-RUJ@WJxp5AA^t+e6wj2Vl zzm(o>DLgBFTa|^%E(u?r z%~wC;ZOwce`{wwKH{P0d@B8VJYFUPlP@gmnPBhp#H7QE zql>52oE7eB7Ar`Sc#2C6?0E+UHv6UTia&( zbSu9z4-=C%Hb=&vTKi|ir3sfO%--mKdfKZATZ~tneX*}gH}%(#*mUzkTTd^`smOnxTxXAX`P-fCEctx9BN+O-%W=V6#TmmUFK@vG@HA z-|+jpNsIAM7KV!#4|OV(E)x6yvd(hCu^T)7U)lPqewTjI>%IU_-rYN{6mp%jOuH7@ z#cRDiEGGx$4C6Cw`$~ zmo~qjv7z!|&4=K_6NG|oe#cn7zb~@p+Y0M{B4Pi!#kc=AIZ)_tvG}-o=_Z~tH(v#B zN_r98e5CfEnc1Vz(=}-^e>C;4)d!oVSzgn(c`8$D+5I$FqMg@`b^n!3bJA^;vsZoC zvD2?C=E~CibD~XLW);gWc7NaGutDmRUgGbo zozI=R{_PF<$7;^Y^=E_q&l(T^J+ar+Ir=x|DL!!EIX#a(+c$;nb*V+vhxB;?Zl`2g z&Ce{q|Ms`+w*G0J$2XU_RJSZpRGe#PY*!mDe`kuu=O?$^=GD*RwenQkCR={J;i)QP z6yJ5Nm~)o(_KTW+T)uf~r$ul|uCd^^dHXjfzjI}nCR`&Q@n~B`$&D>+Z*vzg@0;yj z*!Htv?Pu;Vv#EDCYU@?xtzDW``R`KocW>!t&)2IS>AZ~Ex4|e+_BQ(sjz-QG2g)R8 z@6MEt=sn?g-&@8>e)jvFOCOj2=bZO6>nLl%&+Jd^&%b}TzaG4DqOSM9y4<(ax*hYo z?+V#l$jxrhKX6lk?al00jQ5>8j=gwt=Th#e6=n`>r^@Q`e0FTF`j_eF>zi_hL3hSs z#akPjOsacstQ9bg^HzO)JhxqDkGads+ty*{LRWu^ZjWEHKte9~<~6M=nV~&5KB;PF z`z+k_?}$|h-;Eav(u>a=bS#{2z3J_Sy<1Q9I&Wt)cb=PMot6Kn&~Eltk>&ftzx==N zwL|h}Tj>-3SJ}2czAwT!-L_5Icm3yu&BqSzTqgD9@cq+T7Pay>j{d*+;K(h%iP6U# zeeb5Ob(xjC@l$2zaf2xhS8b1$oUlLAwZPuzpe8@}k?>R2W_-t&xh2mn-I*NAFQo0! zG^^}L_{D5_b{YOBb9A1I-;9e^ULiZU6E%uHAgDYikBy`nk@}rq@=V?cCRYe#d0}8|wSZRrcL{ z`11PKIhVsPN9&$1{rP=EvFxefk7t*ZmI-XH*cN~EOgrC;%8OnTHXnZ+JvnsCkw-~1K zebv1_eWz8q zX1AZslJ1gGt&T8JH@T9(p}ULc>ayKxe_V5B6tP5|3qJQ_F5hqU>B~P%EB;*Da`*4I zKgSw>1pknJm%HO@@}tCkiGgz~*4&%QeY^U%$hU*)HtOHb?LJ@b@_k3y+IQiTFNEz& zGH2trJUz?aMDE+4cct#v1gG7KJXCHzzc{biU-yRFr>w%|)mwi|`y(y-+S+zIJ9<)ZMgzxWE z{CQ{PXZu5M=hy1k@4GDDA|+LQ;&Xe?!?XEUYkEqBx+m1mzF!hC|TpH{z8e^$IMaQ_mermqt$DkL)1%_e=! zwGQ>V@kHtE%iYJe*B#Z3-oJ76zyIwUc{lF8{`H9WxtaH-uUdDjGVk}Y3tQ{9nwrmP ze-%_+AhA&X{_1Hb@^ceYZ<}BE%fGEh_`L8wtIM3H>w}8TzKG9uuAKh8z9Lq0WkC6C z-sx$QTF-vp7Z$!GC~qeI#xC-P=H-Qg%^y_{E`L=e5tOBTLd48S8&6kTG^WV#V*=f5Z`1dvGhByXUza*}0 zX4181#eY65IMWw2-=X(>O?&5`e5rYVQT{*eW&FN#9c#AzwzRU|eo^vJ z=cyl}*(u3|XV$OyAYXL(MS(?eZ>itjz5Z8Y(#+;R7Gi$RGXKMm+mmKV{7_v}`_NXy zZi|Ie%%10_-%5D(|2VxlD11$({rx>-Gq05vOFF%~zRpgRkiF5e@9mnpL)Vt5zP4mA zeYB-x*SXy%XYF}n)78r9`s@j3bxgMDTOq6S`dh#M3G+Vn`Qew2sPNPMuhY&RWtPjh zeE-bauO2xcvP%2SuW7Y>TI;_)v+~8S7`vzwsym)Oj(9BG=RJWxB4bv4?&Ih#&bx+x zS!P#ppS)lCRX>-J<6!Z=3bk)rPS)^V9hiUK9B0X+^m6 zHb$N1^$GbGj$S-?F4oR}d2+#egMBAo%P|{0*ZymJ@7JRJk5?Tot)2Vh+6P&_np}zb zH~I~3T=LU--rM+b@7$VlnQisbze9c$*2SCuls~@uj@|hiZq~1>+_!G5US$4mU)_00 z&d0&$F0NU9+HUf>Z-Fs&3no;|37=FflvweVv;O19ueE<-!FjD5bVB8a4KKRguV3BA zb6@z^wMFOUUWlKY{q3HH!|io*uDL(!4!pkd>#MzuJ+fA({lD)!!F!_hjOn^-y~}Ht zoOgFVWo!5Gb7_vj{NsLiK3xr)|90YTwY8$pZ~U(Q9`gNjoi7*blXIWnCw|YjpZn42 zwp&cmgUi2)|9t)#Qut-w{WtGg`6>`?D3}+%#n}k`M6buZ*olQ z-lO@sMDBWT&gX(xrzB_1Z&^N1x>hzeOY`#PxNz@f^*i`opDDgR`S96-$KQUpG$&nM zwa4>%g#XXgyPxiy^X}lwZu1Gt@2A#C$830!7GKe>I=QVVX>&;Hr`hM{zCU}{%621% zxt*G(v#sm1p9ih)|LZsSq|C26E9SUvM7(z6UYU=v|1}=g#$7&P{^y9H-m<^jYNQ?p z7ZwI+FZ(N;bh@cDtV#Uxzb&T^r_}7w>ay4Sxjc6x%lEFkI?1ZDubi~_yZ+Jh{Cn4y z8Q#4Zt;eSseC*d<*Ie6mKaAtQopKcZo>-Bjz1`e0Cw`5`zLvkI-ye%UUbxEXmiqN; ze>7*v_SrtF$WeRVS$n%z?jVbAy8qEt`aM53=N+rNcHT%q&APQ<7Kbk{=aCOp0nMAI zAFF&QocxSqFaPp~hHmV9fxnV&$se2kP@&wXurqx3o^z94re?ddywDNKe`IDE@G@@0 z>0*;Noy)Z3f5jhldf;YX=x5GV9=ZCl{QNSTTHe;luIIz#by6)#4m0|H>e8EOwk+XH zr&Lds9rvEwy6F4iH$#;v-Y;)yuSjaG8(Ush4 zHXGdu59dXFTK=imKI~h@TUEKsN44)<-Kzg>rMbSG=>cYmth+nJ)ZWQD{Qq>^Kz3iv z-nXUt51ytz-TbWXTba(8zl>#-foHG9uMT+;e#YR%w(c`_wdwD$ z==867A#+Y<(I37wtN-w=j#^jGeEnVdn-9OFcOH4YT~qw?Z^y!3$!-0UMX=nmK2-cIG_~vHW}YxqWBtr~0D#$rYJjdRP9PeAm^?!e75`nZVKGrGJ`l ze>&TFCw<-GaB(Hmcgue#X^NedG@i4rpqeM|t*qER^_;)=@5EHLmh3XWCx6H(LH$*_ z+`Bn*uBZQcvifG!1$CcP{TnKO#D1>}`xt)i%a48Sy!$@y+u16nKk@UU*E!{pf8LcA z->U2T|Cg(#uHfhU>p$|1zbq=WzgKf|PWY3JmWj{#rGE)O+xnaJO?RJSh2Djo35)-J z+bF(Ux1Q;=Z=_&XdAf@P-}O$_w&G@|qNjhYBZArtZMUA9dvej~hnpM|)oxeEs6SY@ z`&iAVN8W}q#Xrh7r1SKI-#OF&dQQ#zGXLk(XBaYM?cnR0zTx&h^R(Ok`_}$FI+5qk zhHF2?k8fiBqZ~2&y+Y^2In(TaAIrS;D7DU7zP!#yK84$Q-@C65_U!Mqc9ro~JX(6J zG|70G#N^|>zm?-QeDm&S|N8OrBej-aJ3gUEr_!)yO9EIKD`oV-lo zf6TdKQnfAr6VF)eGfE>3VavM4VR^~3sdpM<9&6dD zgvfAcR=p<>k3j5Uuq#0hR@Vl7RL|ih< zHw@3K_&DQQ#Pgh^dki?wWG&{?aXje1IR5)ZUz=M`3SuMV6Ur;T-F1F6?b8FAY8#n(jp9W@h__bqOl`~6#K*)4_Jd*;Uf zim2EBR@oPHuzb(6bwMuL>#Ai_HUdvG(=R^%Cu}dzL7#oiPv?lAoipqB+~V&uUWk|d5pvjglsjfE^P0NEz|VV3=Nz3` zyrA}&mYJDM|Ft`+S$EDwellLp{4q`AQuLYh9DjusvRVOga}LaIHjaMHboI*q+8RDR z_0w&^XWrhoOE%CuHfuue!{SGo*>g`{-B;B`R;LEa!Q?z3`Cx{`(Ct?sjF`KN9ZdcxU{~u=u;k=WET@ z=Snuc-uSfV)XO+-&C*@Be)Jg0*<}mP3AvOyZ_3`k2_G3G5*}yHw^?5}{qeoS&R_S7 z-z#p!IWIfGu{c{g(N`Cyn zktJG6dbWAamp=zi)XzJp(9nAI<T%)eZ`lz^Vv8`W<8!~e|qJXuNzN_i3x3arY>)B^YA4@ zjeWIA^S)~CjWycOzjot4_h=96kEhHBx8y(V zj@sCEL0^Jv~0=bEr+-V@A)S-{l)V2)IwOvhpZjIfBxr zH=b1W&onjN>czGDn(m}IJ+B_!x}1FWnv!)w{)7(?yPEfXojuQPvO)2a%iq}*j^znw zeOi1Yd(PLX**aFD=Vn{8mK=C>XpW`CO^4I#uPSa{eNOF2ul=I;|JxR9K9kk=SgVAE zalV;l!0Ug#^E=h&nCtkpto@>S?bDhW%O%!6?vwu)b^o`)mE*FnCGICk%iehOCidIk zvz1T&&5Jo5x9{6g{oB``H&%ZPlC7N^5&pGrD?i`H{GPS-$&38w@?GK!UUvCQs*lVT z_5I?>hh`L-^p5_^k7P z90I&@&hNUr!R_|Rb5g4!yQE^Ji;BK2JEq3+ zZ2T?1e24!x4(T|{4eLonegOeyU+7m z|9`gQqpQ?}$;lP{+~R+h&-tgG^~PW9RrTG651Kam-gzhGZt>y!jRQ3%VGVDlEqiWUFU7peL-=3KSRnqPC^is!#z`T6~UpO?1VK00!+BJtzG$q65iOWi1& z_CQ(bJ9oE`&gbXvW79v2spvlczMt*J*JBsAZv``U?`X zzLalxtgNYauJ7T=UpGwMza6@7p;kWWAII%qL9wrb?e2t>KX(eQ|bw-u^*HNbpYi4K5)_(gR#cF52DGk(*#BAqgY;?|tv;cJxTWRs8mnGZV)fM>0E zV)fjn`B7%mr+)VR{@+yRL9oe_EAzD=qbIy!yQEbe-VC!^Iln$7U%MId6OYw!EO=@|@?k z@gn>;V(v}8%w4uh@ebqO4_2F&KH+6@(K@x|%7*lln&~qS3*V3Oow>55bESLs2~$4S zO|RbiFWA%hB4=Hzqhtoy#Bb%qgvIkv-Gcd^BVC9?4BDDvi?_;-ODnk z-kCQtVz|G?{=5AD+R|z3_xyM^JLcny2NDr6HQyrMq~$KSmzcQLw4vE{|JUxGuZ-me zvzDu`v2W>UO5XFZ;+f;2bAPX$UX`6cC-3g}#Q(o0W$)O@^)#aLviIsgJu`0v8Emk! zp0aME%c)!0!hb$7_O-=*eIRP<u9LH&WyPKM_#yDWc7J%>e61F|0(_7i@B3U{!R|t&9J-a zSoe|}HwsI>H73ux`umsaL&wma8`o%O_ttdFZg2Kqb0BE*nfb!9<|TbM3xx&ZS>~jL z`EPonvMJQ)MCq*sz1Clzu36uE)MH-w+O}e@r#AXqO|I_XbhKyrC}|p}a`rfnj9%gI zf0d6-bDcKrou7WX>`BehTN^8Tr`Nvr*uPHk=hp}$#Tt3N`;qHIwR;XcnGm-rbn=Sn zy-znUXDDUTYvZ3b!=inTdBU2NM~{dtSL?s~Lbx(1D^6m~jBMM&a00Of)MNT5{>=WudFY)0h^f{Qpb$^iuX^*Pn#(r)+4i&W{ERIvs+)hb=ARdwcXf?a+!djZXQexflAO;R zDBeFg%IG-j6^k$Dcs5k7|9qfsX3hDU1&fZ_SKT*D`sZ>{Yq{kv`6 zbDOX*`FYGq^A7y=&*1&u*{uEf0ps$S_TOG)UfZ8A`TL>1wUsA3^An}QYjyXs*mtiz z|Lup`t*`s*l_N@@saU3}h&DUdA4{3-e0=BYR9C*f+h$i3b{_J-z3V~O()>MdBZc?v z3t#)@VA;{1?P`2C-i6;-_?7KJOvuZp`)_=6tdpw`1s5ZsQ~$A7?2;@{{IuYixn0cJ zpbu=5!}TKcu4iw)bN&CZUrx`HuJq1e@BGIj{pKa3j{cjozuV2K&9YDKuluQ$m-%zM z-HnVi;pso~^!KcI5ORc@d%4u^)>)PxmrtAha{mAC?)T=-YOnabOe$`6YV+j_7sa&e zk5nCvt4x%OvSxa}Ea2at&-}^fqb6?7J#vvhd!xC2L~Y{xDo%g@+!H51yX4eNF5G8# zY*A|8jK|W~3gy_Joqg@R=kI}|7IqCYuA8Z|IdvY3IC^TAQohi``(D3(ZT)#`*5Rd% z<@+A}yPWOpxzhC6r$_(qU6}d3Z>s-}{nDqIPuOtmICs=9$A6E={NrMubj`B8)~q@G zRa(SJyX3f1z0{J<{!&pLbKh%IlfKQ8Q(mq!SMU=<+_@FgH?9%hyJ=o%`pZgIh6+XY z)uxu$?e^$L{5Egi_-ym;kDAkuYIn#Q?@5r&|CrQX_vFEYFZ-08kDvM)zsBdFaB$+e zR10&n>f`UfM=^%`m}q=FuW58%@Q;=I_tdx621{A9(~>8ON!KL(d$o0mTZTL4iBawApi1Xa8$aAy#zO6ZOr{-tw!6SPLQ;)jV z{M&rvicz)6N2}z*gVOu{T?=`2#%AMv)wGgzrYE(^3ara=J{W!%eJ-a*AM5KK52K{q|Mv9LKV~crfBPbQ1Hx)ikWwP!#mGUj@4(s|K4zfXZmBl z#yy@DA7(MgCS@I+6|*O1_nGs3mfv@gMZKbBVi{O-$Vru*+|n?LdUCAvH7tM8h< z{=CAU=iU+-w>Di$Q*X`ZyU(uO zPJ135_gtm=oAz2iz53@KMZGiT{9N=i&a8S1ugdvS7PGSH&)E~j;ue03({le-nH29W z5_El5c6re|o0^9|d%imEg0RzzYM3&AG$JSN`KVyGgmC_=C1#i@l0#iv)Mm*rk>+nw^Qz5tGVfB_xD@R ztl!sMVe_buf7-7Y$v6Ahi{_py5Z>!M4SH$4CK{AQ8qPx~3WO=8lo zsTH^0i@3S&b-*U!=Lz{gzc~jd?-c8Mtr+pif9~wlyT0w5*7kjkc;Wm?BX|2=(aMdH z(<9G+t$(g-ZrjMd`q!D#E9v4-?Z=02RWFR& zPuXlt{X18$<7}y@ezo8CK2hV>mG72bdARwnx#*8S4?gW*`I~=pmGA}ErQUw`cg@(j z;^v+!iywcjk1tjHcqDXnJ9l@k*d6)$4{CuCd-uKiS|8u<%V7TFG57rszog#ss>ydv z{l5Kv#bMJW4RTSB{|4{5b9)D8@#prtH`sZU9x0@KxOrgG`Z7D?#@34uZytZv{&;<* z@>^dY>4~3%*41&=9L>|;;k9Ro?&O+C-TNjn*6XS$=d2D*Y#?^Z7Nug2?=2 zQ8RhHll6yoe>j!-%xTWfgD($vPxYQ0vi?SxGe6&oA3OG}+q1%`e$PvzvWyQ46Zy`S zuT%XIdHcrc@+`BuGjkbE&5q)omK~wjJGI>I07vW0HoN3Q%RcUST=VmRv%Ws(r$`2ApAZO`3&x@OJV?>GK*Zn;sTo4W2(L;D*!i zeO2>KFPk0Bu9Q7Gas4Czo)1il#}j3|z7+P~FOTS%T%GfQ^}Vo}oss?%&TWS2>xA+* zMv3o}+jM`T`L`!tywRV3+}J0yd5?F?UHLVhes?-duh%_av8&)X*XLS$Zv9zLTx&Xa zM{owPtx>*FT>o6YG~#2D*S#alr`OKCF*AN0=bIhoUlvNyVb@|#^^>&CMZdn#m$lD-+YCmjoar+rFV=`HJwi-)Ao30L3L-dX>t zabeHjW9k9Pl6i4ICkqx&srI=(_nXeV%NtbF72k5JJQw5*v(JhBUHxrkY5oM=ofYqR ztv5`n&XtX*nZMDp;WndmQRyA~j-#QkkNlOEzhnJ1hL(F@7iM=pXIr~=P0x)-^;u~WMeRYY zw2O6LYo*V9kh*dB#GKc=%+G9ocxh^`!(q|-(kWjrT7}=LvdZI()_(ob_-yf!T|qp# z_Yaj_i{HTYru(%S%aeynbN6+sek_Si-unKo+Z^L3N-nE7*iZi!`_X$fuKS<)z555h zFRRRRJ@@(4v2(UZ&+FwkD5ur$+n0YqYT~=?rH*@!SNC7tDj)YL|IB)c-z9DrE6)e6 zJF2wzj3BFMhLv*kQQ_OB7rtx7N~a0Vc(pb0b=AtSH&eIt&bHltOy4%*sP)fB+i$Gv zFEUq~zj?#i*)f&+GHW(Xe0AF9d|l66+t+QPw*voZhzV@G{4Rof;_KU6gWjAGd~CNr znR#7hQC;p$M{EBZiTQfRHn+zZS}rzwmO5Yd-mw?eJCtvqcsf04)usp4ypPoFE84B+ zTV4sbN!WY)(b99m#<%W2+uWS{)AE8?{8Y{j65__b?E&hBR>CI32 z{vY5H`4O1BAzb+LPMN9qE&Sgd%gt-7ExFU7GH(5C&(^|m@#IBI@PeGFh!8VceiRcyE-K)-?zN}DvoOikF+tRZO7Zje> ztgzcq^6!XU>2BlQC6AeXq`vi(osT@#b3C@-xBK>Y|D8DB)IXPvYq;EV`$E^{>jAdT z%I<6}?gtI3KXjR9eA{giVaDCge(>YjQrGO*7uMVE+9xc0FE3la>a>3Riu>(OnRT`+HeJcO8>x{LD*ugd z`kbwLjtBnyjVSnO<~gVK#P%u8uWfd+|G#kVk7Rq==Xo3U?f+P+aa*|ib@-cuoEZ)J z76-DfEdSp2MDFMD;~`>2b`{Di#NQn3)&EhR@?_QL*3@;|t{Iv?lor!2)?K4I$?tbV z`PEkks^;BGm_CDX=cThZp4&})&>{LYxcH35hsW=G;?=$|%&+M+j>z~H5{k}h9`t9=v_s2D!=hyrHRp`Gl%ifdg`1St;U#pe;dgxo}3g@@t z)$3Co|2(h0wdc>lCFlOC@7(3^m#v23qk%%{$MwE(dvX$MH@}-7RBbKXWSbE8*WuW^ zBaF|qBR>9MZ~wfY;+XD>JUM@{2cqliUtgGgCa3Phxn;#pZ(WKOpFZo)D{l5t;B8Ir zy=0f1KQ|fv#@C}{na;kZr9~odDcfCzN<E#UnC{Q6^bZHMjvVMITl>?v_n^?K*Lumf_a1$A);@dn{;vW#pB6@3 z(cZYMTy~jALBQ;!&y3I3aryiqFpU&=}QmgkwGQ_lZs|2{AN;Y{_9FP^^M zUwDfB&X1}?eyfU#kFz~C?JIj_CA%f>cg&ft-{0@g6t{@ppENT$=S8sk@i!JLL%+$E z962pDo%=V}c7xTozZVF%WyJt#J-KY&64_A_9kB` zji^5&bmvG^vh%*)qdF5-2CkS;6*BLWl8O3Op~B}UN~PX;b8OPPw(rdY-fPuBK(fE`RhZ zQfJ>u@3;kDC+=M=vnW(&+SMPE#=R6ehFJYzQz^) zeDnJ2qTin$Tsx=zvPITW@zQHDxp7DJC5y}p*Gloui_l75f5la$vE^}pU7_EakE&PR z%v73@o;dIGruSRezSS0(^j+G#tHb>K#Yu-wchA_Xr?&5xMbd$D*^bxuuUeMBc6X$9 z-_31DI@z}N{e7Ax&?P$S$erSv*yv)1C|!xV-Iwhq1~b?4FFi8h*O>*jXJ(mv z%=gL(O@ZuDuWFLTHcS%k?va_LfBu4XmQMe(U1w&!skUCZd)ai=1(VJST#Vwbn{iAb zd##N6<|!(V@)Aqi_l&zsUKEW2sHvAbYZZIq_%g7e?zhd%h+eER>IFZcax@^;>v zR+5-meU4qAT{^y_*mbUi&jrQJF|+&a+fM&IDZc4%lE(dgc^l_+U)i;D*W1SS>6YwH zr`aZ~zA5c;#L_D#&Ww4^?8J4oFZVpWaQo#op~BnuOtiX7B~nxSq86{7o8>BZZt14- zh&Mv+_7zXvmaV<~Q&#Wn_Qyx_Yt~n&R6bI5%E>A3j5KN~e0*zjqI<)`m-c6pqdIaf zcl>;Pr$;+GUZubGuY=mg7Y}n@9hradyZsb~>o&Km^6L!I)|z3XV48F4{Lf1# zubwlH_>#UmSvp|RjEFXK3$1I~B7bj0%uJb-{Y3L};fJA7J`^DUxT-`B_tVYFBvO$T;M&{W~ZB$4&n+{ol2ebz-iS z%GPgJ+ovw8I+kP?v$7Mk5!c{S)cQ|Jlcgp^UUT@?e`E3XcvYvLH(vi;)b}FeX+Zq{ zj*Z2?ts`Va{3m`nYWH?VX^>r2+_{H7vu0T6`CKKny3`pylb?LP{-xj#4N-u}tA zTx6Z`fqjdAh=ob`cpaTxn3}V0=>doP8&@w)+5U|GO2FsX<;_R8d<>FbU0T4Kx?cO> z`HOb(7hmLvnSAp;Gb3%`qR=yY{MHmcwm&A_C)*n}vog2*L*!QebFGK7ljkpqIXJ=P z&4aj&67p{zsYZW`C~4ovvu(CT*jcH~3`gFk2VK6)oM%%QJO6F5?6)|N6J?LAs(WAG z*;KfDuX1|-InxU}K6Lv&Kj}8@$orGOTTJV^=0$ukGd#&}(F50qZEo0vooKGPcJJ>To%`3;8-IR&pYN|(*}^Bm zTRLr5S1TQLI<<1D-<>&&-R4zWFATe7{e`)uTKU%@TlqQ7Ujr?A|1Nx~ePPe!JpJa~ zSD*jfAJb@;_UE+8{CEHTSg*0Z?0)sZL|lFP?d~q^Zy7rSig*6p^ku3hv-8f5T*Hop zzYlVl3naYGO)sBp==w%B;oc9=>8IsbEWZ5gT)NRRZQd&#r!?b_R95j1g!8q!*kvLtYzTucQa0gS_U57 zcI4Iu&Etk8sgt)e&)@AQ7rDE} zy@X--uaz5@6O!P zWAD>WC3hc^T5*2$@@HFiUCp$!NIy{VX>HuHZ#+HuTVKzbQdYCeuX%HCY}2=d123y$ zu5T~YpX%pxX#PHboh#Z`)b{WQecG|^%HHeOPO)G7wCRhS#mjJ6{x^G%dCgY!wQY&n zXYF4hJ@?nv*H=vUHfTO=P%V;Onmt!<>k=)cQr<0W=4Nx|EG&bul*CZo}ugV(GrG07DpML%=^UmtpuJ@L{_pEI0 z@+XfiA2d(Z6q{S0ebMuzW9*_ChCN?7<2PQL+`eH?0>hRs9v2k1_00-GAG%Dl&5oo>ocgi$Ly-PTnd0i6S^7rTBVWJ!!2Pdp<-UDu(=TU8&%fWRnzHX| z%<;MFcE{G3KXA@}OmcXhTA#Rrq-Z`<&g`K4e{(xkxa*W)#1Vzc*|YYQISe)qxVj@#a(iCcC~lTXUl{O*~P@$R+y z)>U6yZe8x3+W)I_QgP9_+H0m$4pkg=_4@Z*Y??aD%4FA-i~4?Xt?&C874wamLFeZs zHF>)UvYkh-9?w6O^;cSFf$;gA8z0XvuDE?+uIY;R!S`=WFqJ!2zUJ$VkamZ#8$0uk zQhc{4@AAft`P@A`=fs$PXxIL|bo>q<+mjb-Gkg|G%X2ZD`I+|a zrOi2??ycqqNfn#+{;oRoEKKcePS;%v^;=IKn(R`1l$sRwUpH>e#)YQ$ul!2ZnUQyG zALsAhYfn1)+OyWCKDs{Be$VasebW__P<@;7i|B zA9dcod+PCfC*C}odEI=+%9B@}6rTF@P29fdTovn6X=AZ(g3@pFuUO1Fb|=oJBsQ`6 zW{LRh*0X<1v}`q>^qzR}@a$Lnrp3i`p3W;m|$0N@L5$(j@A1D6W3Xli5r7erke{*%&m6&Efu%Z>($pc<$hcB#6BHc zPv}QkDuI=_0PBF?fa6se%o`Yqu2AE{*_!KA^N3HdcF1a z*E@PYPL{voQG2|gabrl? zZFTi)@(MYNO*i$vX3tB`O}KaDeep`^&5sl8FLckb%L+W6cK3W+*3r0E59gE!xB0Dk zchr1a!EyP&g6g8PW>_sh$!q;cL-L)qU(L}-0pEw$sGqdA!QU9zZy2npg zzMs)uUVk{u?R}|2O?Aqa(8v56`hFcTTW+eDqO17n;?18jG0V?|ikjK?^e6hhXx@9Y zHX&9#we(q_%}%{Pclx7lSI<3Y(at#kMvL0pHJZOaD0LZrx}{)f)*Rcf{OsCF`73uf zezPi;H7|&sb@*w@>AgLFoxkXwF5Z%U;iENsjr>1}Dy`?vxsTKrZw|Y2K6oK>#f2wA zht$@JKGbUc!S zoLQ-Sua-{ft$t8glQ2Dj?Z)=7uYvDwP22wbt^P;7g>1ZCibtnCUU%^q*Lwr2h({iN zrLAutu1flT`h= zj@%HJaJZaP-*@m?&Ce%a7;pbzn`?D^%c85dm&#bjc-~JGe_)gl$L8&S=Ec?R$9(OR zvX)H~(L+?T?L_pYNE)bBZ6A_`@OA z@v%TqdFzg&R(X^4_pF;9sb}iB^!%Tp4~u{AEjq5Yo%dJr|(IE_!zM<+{V)KO5=K-fZ#9>-AOpry@3fAmUNp?cGqJs-XGN#H z0LT0q_4NO2YM#x#uM9tB6vu3xvh@CuH;eABJN&15+V^UOjccL|_ZS|!bf4#Km4^Mc z+Q}g^9~b&rO^`n;V%xdmc#HJiyN@)dJ=iek_00AkR@T3Cd&|6b=|nB#cqi8~tt0B} z>+W?y$wua(D~@4x=_=Bu}t%`2b3_2AFy zH5~bRMXQpZPM`7Q%qp$JW%DX?Lp}(8TX)!WU+fvHj{l#3`0c;;L^|UY_rY(|1a{cD zN62>d8QLE^exXmSOtf+x>sWXtswa*ieer>SLUaGM-=I&&T z_LJ^+|Ehj< z_?|mkD5QU9PviBIL8%|Y{~n_&PixLA%s6hiO#NVHzO&}V z`E#`2NmScvE_fc%(8qr!f8pJY7xrx7YOOuan07rnPWFATPvLzh^QpCcFHe8&duny# zzIRIJbKYq&>#zS8&5yHtc&Yt@_P1wRhQHPwUcO`fy>;oF)lAN%KUDRq<-bPt3ohQZ zCD>o)dc=yaj1DV5KPygpTX&%R=SuCLcbDxcuiWVSv18e~d*5#S+I#NIduyGacdob1 z_4@Z|;q02Zs+yILU+?5znWDFK7wd)+?h>8{?^gc#vR7`?qk#P%lyVFu?@LA0)M($A zKC|4uMfKV8lY1=7bWVir(|$es>Fbx;Vzc+AX*zoe&R=(RZ-U{Ct#LmdA5PoDHNE6f zLzF?5@1dNswyfave$mOlWx8x#<{yp^0cW|uh5z}^&i@sh9dEF?vEZl7?T1CRr-~KN zwZ`4~!f-9^qVU%h6PxGGWy)P&vhJD5m5%2n{3-%sb8mC&vt07px1FJPM<-W8+^>HT z*&IpLKc@PI$ndY3lasgd%DfHbm7k7Uyb!(pAvs@cuD-03=@U2GV|QL8o&MOfe9w8q z{G5E5gum&z#)0*Rd~6>_lx+_;lcT%`&~) z@iSlP{_C-|`||H<#H-Es*Sx)96U2AM{rZB>ai+J6a{TYwrau?CepW~&stX*#Z=IoD=FmNy4)&1=ERzhaqFCSdhL;xmP-=UYK#o2*(2Y@P;%tB zHs9C%?Y?(@_^&xK=frTdarFUgmA+b<>mKZTQL zjs3G;xBFi$0^Q5~1lk^dJH8=S`m4{p4_WNt*JBppk65NzrzY-Zl@^t(}X z_SbEW*TgcPpYIHt8pk&CeAug1ZMU{A=bAF3cyG_a%8$W^7wvvlt0((=O~UPe?HerE zZPw2DQIQcT@51TF#$IwXyHG@1{^Yz3-;86l-!rdId}U~4EMMIH@5$3Ec9JV@F0Xpb z5fm+_Z=(iaboy1o2mMn9f+70F8hAe_-;~ta+cwGvVL5?$l>0%FLz6OIPZSZ_Py;x-sIU^ z1MYHfn412fX8PsYWa}Ntn{U38Ir=z$gST|K;-<6W$`=X&_kv3 z-kg}f>r$dawr^3|UspX_yMGfdY!z7-@cYpJn*mC@IxSsYQ|4OFjf>u>99#CdyEv}D zu50SsL%s7uoY`t3>z8gl+{~{A_C2e#Q`X(`|Ki$Dwmu5QM(phW^CtQ1sQdrtGynRPhPSevtDJjFHK$#^{v$Ba z;@Ig=b`Jh~zPIdaJ$&A{?0A#!pJja?cVCpdv z`KDS~__-G!HyS8!%0KqvPO8B?2g&J(}AN~l5Q!No!w}8Sn~JjD9OlAX9We# z)~;rrnlqn2BjxkX>tg#J9(}OxR!?KK-TbC|_wM(_ZFqcVtH7#{!OM>X`o`W{?5roP z`r@?9zk-`>_Sb_9z8BBk9{2X9q!^!j?2HSRld9HeRd;UP*7>i6txW5THj8&Zz%Chse0EHmB$NbE?Z}Q;hpI6 z_}978E5A2BZmN6Kn=HF9GTf$+!RArp?MH7fd~5eSqk2KDxa07phNST5 z?=Lbpd9GAj?@^m`ckeQVBl7pvta#o&wv{_GOF7|3K=juWFP}!dYdzZT-^4uI{Km(S z4Yg(>iGSXkg{_qPd-U0|$wj9B*Dn?F+2Iy#nVo%l;;Gk-XY1!BytZ7h=T^>Jwr^H5 zbGCc#y|LxnkKoWghiiBGJ_M}&A(fu}=6=fr+imln9Zt+$P`}+zZA)qI_c=B9x39fz zd4KKpv!R=x9-UWstn9sI_QAEkwx^}c;gZ$VKL57*PDbKhJyh&5@?yfXiLqp+Z__7PKf-s$X?8duv3!u2;EE`B>> zk@gC)o%4)OTtC`e$F%Mvvsmco?K^X3EEaxg zwddfq(%-$T0{YWyvMp-w8u_1<4ONcV*!ws6JM)cSv2`s^BQ;;QM7d1fcTx9sthNi& z-2ayRrAqfEKVJM}?&rXllZzj(J6ZTF;qFhKlSlSGzFV<+J-guZS$y|asO81qJ}Rel)wg}S@+h1o=EUo!wt`}@>lK{`>z*&<-&wl( ze@yZ*^Y}osy3e!n@6R#gbDNS`u5;;#E!$So)hq-S@g&gd=vDEB$6|HiI!?z%QT%rdV+F1a8{8>%$Cf#`VwXL-WR!_HoQ}QtGt-t5zFZBvf_c~|9zqfvN`JYU_&THAT z#@k-6|EdtT{~EjLl~q3sB#eLesjdaJ@ufh=g7BPd~eoV(auN4tMm9o~8*w`P;N)w8Lqa~}M0%-M0%|G=YUiLkZi+c`_T)`YEQPj>k| z>$F0c;DcG$q%M@-Z9H#(zFBl$x%oY1qxG`ZA_aTRE!d*xw(I(yIruA%h1byf<&jx4 z4p>O`<)xolyy>jN>la<__dT_w9C0+N?6KT7FfTuHB(^QMQS;{6(hw zrU!QirT<^sx8e16P5;H_$w{j5`=SEZ57tPjxC(?rFZLJ&fdG4g_W|KmFo@|^Kax@SNHm~?bm}7-iNNg zvgX@@^B-mNvo|cPwA^=C=$`PlfA9OW%Hx>+nOx(R`y^ZJwe|UfC-?SrO2ox)#i`~7v{dv^c{KI-NAC}*r8)WgZ^Iy*L{3qJKqvd*k9;xfAj|I1X zOSk^ZToz~Z_VtURi?Y%@Wp}Pk+q>@UZ`Pd~F8y5o^rmi)rM%AR&^?94Ypd6ASAD$l z;|}+Z2mRgq_|5AcT$SGD99m*#X0kYE&D+HVK}Iv%(?1<(KFS!E|_ixZ5AFYBT)*tnx%Y;qwebvpz|gIaLvd-wT%iyyJb&zqIq^(sRv=n}6r5-JE*l zYm&m*1iuxJOCoyGcy(>2O@2M$?q9QS+xINfP5y16{oPpXcCs(~ratjCOPL)v5o0ZPb$gu|$2Tkc*R@A$u3uG8=U!9z zaidn785RA@T#V8@i^+Pgb?Z4OMIaWZ;e?-!Ma0rxjO_hgw{%l~f<`*j|l+vXJ?tp#`G zed87rzjjpcagMfM-RRUa1nbccWYlyhey=APL4zc%u|Mc^sXnLM z-*uT=Z~6UB+wU&cUF%yW|6E=1mG7&i-ffSo^B>;%yf*&!-K>XIjkPPH|8A4>|Iz*C zS@p+9^JngT?cMNg+3nBSi@Wz3rZ3}HczV%%ZaR0I_Lue3kXw!E&J{3q<%zHRE?PR-}}EC0wR=Ik!e zj^>Tx*CI9hij+Tc&)uh;|NljL%eT<^_YYLHJ+PG#i@$jCq{YXcZ|WPlymLQKGcKCH zc22J4p2Jda1WP_%-JX{ICh{x$ies;SzpqHHKPuzKf0$ceeS6iM375-%UQoZiW@-P2 z9)+n8j~gw=G$HTK`7r%Yg=8 zFW#6HyjExbm32F!-qaoK{X5g0TlaEzJ?q^2Y(KTmmgar9HA8}({rfZjb0Q2mAJp0I zUn#}c*n+kRf$&Q@_Fxn`r-snb7fzn_zyU416}%}nd93r*+Ed7HdU z#dLDI_M`gSd!%DGJWhK4ozJxBruM7ui{}$QJ3f5bzDw=p702ZJ9MS24S_J|Z=ii83 ze(tv9f6ZBAe@Aw$3XaZt zJAb9h&+Ij)XR^6R8sx4K3!fg+UG>KKa`nQjj^u}*)Yos;d(FN-c(&E&VxON{TW0c@ zs<#zQID5;?B9L2*@1n}J~Xa0C1 zZCzW;`_*pQ{q_Bt`%Ih87e~vVkk#i&%o8Pxl)AfOI!~a`HHN2O z>r@Wj-j*%1-0oGuuR8X)kG~Qt);O)_5X!GkN~`(Tu;kA3dY+(lpUmH$F?_vB?2Ms$ zG(%hdKhIX1>pk;^|?#9hdj32F>{R;NFc7w-@rA_#J(7s_FB2^*wu^ zl^@TO?=dqkdw6f_Pq{a%eY1|8KVUpNbx!fq>p!-uE&i3ofA3<$#ToqDisJWI@2k?f zcj=&1V&0PXAGudo9r&vk_IuvpLm@vV-}sfeW{3BZD?O*bRQ7dg|9z$Y{fS`y*4+7) z`bsuW^YfR~hz7r&BY(X^@=6%IUn&qYI6RRH*S9o_~+MsR{GHSc-7JM`z;0M z2fXvIkZM^;ojy`Jh<$e}ipLc$BPIE(f8J>oLDNKMzqWaOc%kpw z_d6G5@B4Di{)zY5nBU6xAC$=4zq0i6>6lW!Q}2z8+pDG)v+68P+W1=L;bz^}VoR^x zS!hvQ)WbUGMx^-)v+rkK+uoPBdOE838ROnRUQV`t_r1k`tTg_7soq{pe&z9lx{~=q z3*6GTTN&u7|4%#>dHUKEn<(#fv5)y?6rJ67Yg4oGhbg^`+4gjt89sv)ycEde_avr{`Y5JDUbf8ZGS9v)348% z;8K3nZ2nsHA4hYqq!{gK`MD~5U6jyKh4>BW54Zd#=XN5sYcIW+5fU-{=ie4ac~8fAo!(aRW68GXGKngs zVT|gZ>>`d$uQ}U&UwNMOv?T$n=l=Y{Z2!%ByXYmJ6;D^(+Afk&lz+qSWA6WDr)^l4 z`>cs(S$*wX;gR&5b<2N5KVQ4}+y?#gO0D7T$E^3>_4*eZVe@E{oyi@GZq=RZ`#JBJ zO6@t$x03Hs`Gz&~|7^D1EBAr1?2}?#P0O8oKlrWnb4y}(AH8+>A^VwCqD3|5x0jyy zBAa$4{N1|JV*A98_SerGx;3Ncfm+_#M70c)mv4S|e2qH!{_wn=Thjh5_`7EMBfIGA z)-^L;NpJ1(JPtbxKzQTh+4XrH`-g8nr z$2b4KzP|qT9Vfm^zpa*>+w{IX|89rtd6fy(=lYm;T;ZSnuYvrGSbMR(R~9cnkKnXE6(y;0WUxwfR!zvuV=v>4m# zzTWSx&hE@O>Cfk&=T_?Bd8;l>pB~lxTWwnJ`~HNFYpsNJ<<*w@6&&*SHGQWkG`IQh zWBz+LwA8MiG&Hxnxuj8j$`N1I8!J{$z21H$PCEU}vP+B^5035jyQ7odTTu6~HTiE? zV`go}T-nW!O7(W+opH~Ro+=n}SMZ?cTPbVtW4Vqq?Uejm_r%^gVN={ik@W_mv*;_#@8@ z_f;k?*|skJ^Rs1HYrbq{7Sjta`;$*v z7jJnjkau=L>6@vmF2}T63G-Xs==RkOdLH9_bkghV>^aYL<~%%qIQhFy7W1{=bB~{t zwA^#D^!kJu*83w0bl<#g{CPCK;9C2Eu5*Tl?9y>+Cu)R#Z_f#dk9ytuS34}bd+Wj* z>m!_-xAXrjIdf#~{~w35SO4T&|062>Irsj3XS9#r(pGK$yt=aW=n9#0w+-HF|6o3E z+gcSU^i1r}uK9_F?>uVPzwXF@|gN^#8CK86KWp%52Xo`03Lxxi_}mGgeOh zX8rs4uGd|Kw}hw7D2~4<<7~O-NO|UuxikI;^+qZ`6FPBy!EXhd@5j8`W0L$Pmis1g z?z_(PbrWxq&>Sg&zNeej4qm>OC~a=>`+{J3ea8ByGu1U;y?EVtBR6AGkznD|e#7j# zxz`gu#+z^0Cd#evXz}deCjJe288@a1OP}k0D%W^ZTkOd-)3#%0Z~eG0ze}v;?5zh< zUUwAaXXnIMYKp#={Bz|M!}=<(v^9@XeJ`)L`2N=YX6|ivGWweh^=kh%m9AxYZe_Cm z&y6qN*0`Mgp*1Z|eNv%rfv#%&j&;5Yrk6O)UI%e{tcclf6rTTy^@`Prdlg50-f5>j zi!keQ&^eM~by{wtQAhN<_Jm@7gRG|Q`yZZ_QB6B`FzxS{~X_~>d)4sfAfmU zzH0gEx3+faj->U~Pr1V+<+qeI-am3@>p_|Mdt#Yq$Y(sfm$<*~V*B)6s-?U$GWgDL ze%ki#?G?%QwPsKDZJA~8!eOiX@gMwe!=L{a+w=z+>(U1ykA_vr~geq;>}Sm zmUqAY#O1t|-?(quqvG?z)6N`Uckz%G$NKc6ueVy7mFIjcQ}IcfVe3Apc3aB&-~0dn zj(xq_tdq66BJA>vnw67(bH6{P_gnHwq}$GdzmJ?hFIoJ({P>wT&h2k5UKZ1TE)v`O z`@#Qz-|eT&yUzVhZnfb2_V`dxU#C8F>3=nT@lrFU*pOWlc1^qxeLQsqyF_ea+M`Ra zk4ETB*Sh`T(5pkwnEnOVhkXj=kKA$M>70a(xwmgrGC%eWuZY{jc(6dPqQ6$_?umk{ z?P_NBPwHQ)E%yIha=1f2l1KU2VV(3Nug`W%w;sDUqvC*!SJH%u_YzLY>a|zfa9oxy zk_#xEK0&rHxpLd2M~|acALB9GYV?}RIIgKYPwHE9_pviOjZ^g)Z^RS||9*H9yY9=V*6Q{7zRS*Lmh_=IXr<4)Z2IzPj40Z>f1o&c1)9dwyN` zde2YiJI{1paK@bp!kc-TL`6S8T9$W}ud(FAtl3*%yf*mC+N^7NS9;gK&ME6v zZ6zi%8`h`hJ&US3WF>X=($-1&_Gh?nSAMm5Y4t~M&7-4z7QU;u&TLm`HAwu-D7x## z#O}#anRT*Lbc ztZJK6T zx%6Jb&%AXHj~Qi8EDe=TnWw_m{-|KE^q(4;`pd`YwI#`o+$(cfR{xJ`kSXubJ>IWBJIp9*5#aV_+rrNopKeMmrbiQWp>e*kbc?V zzfQhb{yW=~J(t$COkL!Crb~Lw>v_MwiJuL={=%a2<*%Njf2G&F_xzDkx8mtV8GfUE z4=-|`d$)Pb>isp*4BmUf|2#bP^!2^KxGyyuYV#{1??}zQ`PpUPP3s-hFQv2TrZHf1+#azavHY3Aq{k8QOjG%8myK zukU4kogJ3Vb^9w%pLa~o^}e|#8#s^%^Q$NtKuz8KRVx(Dx{)qif|{jHXn>$>M(;cIqJcTWBA z*XPGEo_|K}A|VT2vUQ4Q`K%*ef#vk-a0Q+zwzX*uo&qd^%+ML zH{S2}I~P&9{*ThUV|_Awv;Lk`e|~rKx6jraPaTipf4VQ3)#TpKU-uaDH&hATvyrOR z7Zccc+3(&l@AoxFYp>0$);zC$bn5x0(~LGZdebMT=0Cr=V$S1NO*WO4`aH)sJ-4f? z_U}4ZWqrElx0O-Y_y0bvg`3XA@GI{yZjWiMzMmME`A=1U!~D1QYe9$G{m=Ya-%z7x zWxs+aC;muG3x{P-;#e_F->aefEm$#^_j&l)I5ETT$mntqhOEY15Lk*9T%smC!6WkM)z$^d6DK^7*i%B{!P2S zZo#p#njmc`+V7=olm@rkDNW5pCIFHx4`7%L+!6(Ga4RUsk5H; zC6{?qVpm(`lAWh5uC7YGvbN~rx#SH!j}?psXA569+?(@L=vsDA?T4VVzc!eDG5NB| zed{&jM~_q6li%MmxVC4x^0v%w@%fd?Z~wfO-pqWu;wsb5eYVHb&pehYoxOU&SHI}O zuKul$EU(R&#*v$1eeM6#!xP%x?OMWT0>SpRwG|Ad}{#L^L zvws7)4$ql;?8xbe+Z&?4&w2B)z-!H6?$R^g3!Mz#AGuXnBWLH5_5YLYmec+(YD)I4 zw>*92puPv&k5A?|wmp;-du~;DZBgw8%in41Sbg_zRNp=&e}~?O&e`TWt9D#8({ud1 zczypayK|exK3?xyYWspu)IIew%ol_0I|X z&s~(R+4=XleCxZtk9~jd-1oOG%L;h03D0PoUEa`J>39CzKDP%E+1C4ZvaeN>d|mW& zy3+N=l*#3vrY3#h{%tWM=H$%q?5_>Eb3$`}Kk2Sc`pB*!Vaoqm?5S|On9cWCNxu3m z*B9U2@a+kckJLt^Tej&7RW9`?Esi@PrsJOcyt4WC?$3Q2D*s_Q7X;m zTH8(L)7KNP~Nc&DHkQ{yo~4PBX~p zKfX}IUHwV!#@9bQ`&K@BFH^ivs;$@h@v3(djLqFomn!7dYqat=&6B!ze7BtO^Ec^- zcP{&rv*M>j(xS?&gRQrJSyUUe<6BbNbjHF0VZhy-ryAUAj)tqr7NKzlCb0EB#kT#s5w^tFG|%HNXD`pOt;TTT)hQ zZOWhX&G=7v+vhhu%OffubH^{wJbpYTG9-G(m8Rd+ zdw%em%)Xw}xp#x*(QV%X%HEuRRdVjw)B8~q+|sKb*Boe)H|GDlT=AYs_gUAs?EEvf zFn%biaeKqOC;rQ2vG{*nw(?9W?0Y1&YreX9o!wbKbzWW5M>nPVZCi6b&ryEUvoyW< z(=k<%8#kxSQkd9scFDG{@1?EcSD*RblH2>1Dfs8N`7$%6x8MFCx%#8K?u{c3Z%pbn zwtc#r@ycxXzbi`H;_Jol&;Rr=Q_8Nla>kTn@>%yzx7pZRPMKS&{%mFBo3k$%=4|#m zzB~De`pZ90E(Dc6X^OqCBPOfUvvN-HHUBA*@_F3a@@q7cu6G~Xm@OIkN>ztH<3R=Q zdxt&SRG3a4>@9w-J+uC|crxd~MX#gWa^77K&$IsUFG1kUhotrM8Px-#nU5q|y*cH5 zU*^Huo%d6i85XDg3lx^A-*hJGk@~B?#-FohY;0eAcFVWPJD;DA{4;x!h5EaPs`smZ z>%BQxeN_9^&Gj88EcwOn&i(GU|GenquA7S7t7}t^?u}e;8PFWle&bQUT|P%h@Z96` zbZV2_=Pa#bzg8#Io@=Xo<@2pWjXjo+4zKytW?k9-+hty1@?+D|Kg*o&&3RYhU;QX^ zZBOd_3;CP!BNv^q+?L{T`_qxDH9OfJPp(>8b~NWtk@3Eu@Q>ewm^o8%)NB^i7FEM>qBWqsTRakxE+{WZGhP5&NglC%C_Y^J_GX*!dX&6|CG6K<${7S>BStR4H9 zdwWI8Rrf_Juka@X;NI>|5?Y2zg2n~Y%ScOUaoj}*1t32`?x=N3Q;Bx1|65cKg3@>$$!Bh1X`Slj@yrsoqwsE6D!b!tC0?0;_D9eVJR6`}1vH z-`rq$?Z>rz9hab0)!lO=I_Fqq{JmVC@*v{!im)>~wq!oiJ6Afd`UAIq-_fnF&RD*k z(AsW0>u1~J2eQ%0Hq+GayFX*Z+zCRh7|b+^c6>*AOygmx|kex7i|39&BB<@pSm(mz`lec^glER$=<1 zxY};!(P_yWU(}0m@A`PaVa|t(liZKZoGrb%Vd|V4M+^-6*IQf(Ywh0amEYB}y=C6B>G57J zi7QWe&F7hC99{Tok)q9h|D*<=ySKDYihp^MyY$@c$Mb*w{9AsvIrYZhRll0WuB87y z3O)%-T>MY^iy}$3m#2NjA5=-$$}Bql^u_5f7w&Axk+1CEo?~}t(c@luR`VCznNDZ)#N8%{c&jR?N9nTsq@S)hi>QprTDDy)8ZS)c;@&{6VGnBUzTu2 z-0UC2#pNuswmq@pop$z@$C|I3+7sSTzqGow1ed z3wLz;didD{R@w@0-t+3Lh5r2`Nfs|}H>!3^2hLy7`t*K9v1+Nu$s;eeZtP0Ce=K=% z_>Gb)HW$|!K4O1!tev4U%V%wk?F+9h`nx^<{3z~zeP(-sby}7wzxLKpf1Y%iKJmZ) ziHt)0iLVaKeDu;;XrXIY+eJI(^p!6C5vyM-%1EzY!8~7Tn)t#p-3&MRzO%mj{$3Vm z+P*SpZ+zwP%gpmnO)K8{N#7T@Q_;A#1)8jwUs$-Qt{V7I6wqE;1-v8b!@0|TXUVTgV-MP)K`%=FK$nH3()Mc@;$Z3!A?GqeL(m`*& zcr9J>z1`7CLSB0PPs`)iD&4kLEX>*Z@bEcb&Ig;$d);s6EsZ*w)Wt#AIU zHu3*La{E5I7w_}5Z8|v1dD2nIw@-fviXBc`$$w>y=y7GfwHf!Na?HCghi!Ar@9noU zDbsxLbn2a?mtTWtJGu({RU7v&nxr)4Q^DaGJ6;!W&SqH`QI+TQ>1~Da_H-MEx&9N@ zmmW))^;V6qa@!Zd?5nm9jxcDPD72C_jGuq;L~Qot1N;tcCthppteQXd!t3;!q$Hc? zB1O#}w{-XXIDFnwC3mBCpK|&q`;8yfW>s!`SNXeTb=KKAjc3bsWNt}R#~hTr{A5nG z!NzlYE1o<#V!-?Vw@mrDKGT!&C2K>BGu9pR+Hyr`!RMVDD*HnZEu2*M(9q_}(M^2v z_vhOt9)J5vB**SZUrWrbzC_pS5BPK5FXv|79=KA}`P|=pA@1ovXFe~#{kBT$A+z?C zBB{f+`-453mc95=vpVteuLaIsTQ}M~Pw@ZEAkCt-`CBXF`|l4N*DL=!yrwbs`2YUo zqk-!mrIre;`aa93V@1s5b%NzFEuA;}c^Yz#FsiTod?=JR;ME7O)A>hw&Kx@EHbc2| zBPV0!j2)HhwmeWcm~ytjV~?InT<>dxsWTidBp4VLSM7N6W%J)f;AN)WTz|_muCcyc z{p^E@`11A3K6g#_G~D{m_15RO8|Nd|d{gC|c2+;=WMJ>C_Ai&We{b0NFv`w?x#8G> zeIDv{&yQ&?w`os|p8rSl&7no&a&rs$I-QeFseNwP>Y8)rrL$zuw4-^vlH4`N^1ry* z=EgiRU2FO9=K9W?()V zt7RjWES}7J>sqtdQ|&6{*46iPf@x zcF#{pXgz#V^5M>LA?r^Y&sAMfFE4%db@KPka^X5T~|{ZOhLK-+$fNHTm=N4M*mN2pMm7;#nPcW)iPdc-GaDW?gf$-D1~gtX`aU zW3oTnZTFI&C#x!xPaB%vvz))^9Yy7V(N<01>XYX-N&@3!;p5h!gJ#D*P#GI-FE1%UgnHF`q9+xW9Rb1~aVqA8H zQ)kh^UoBtv*Sz04dB=m(FRFAp7qX;pwJ*7?bvpjzZ3U}E!7F|~Iaz0M<1uT^>S;Vp zGADLyomz10_fF?u&go|xb@TUz%d^|JtLFUpnYYq(%YoN<-{u@kox7%buFd_stoE-r zp4M0rch%8qzv%N)rAe=D*}t=Xkn!nu)Q^~=>qpcVhX-vn%*o+6S;VHiyWr7o*20O~ zo~!57UU`1(k$uFvrLR;=_r`WzR4#6I=&k7Nly~@hG=BYxxj%}`j4b@)PBY(*=$D!F zz;PGLtmn(RPimJnym%8VCcORMPm9l1+n8Th`RQG~d3s|0W7qu_(w`geR#galZ?yDY z`y^$`)OY(ncRvZz7FVzoX4acmBmO={&8#N$-oN?B)D${|l;^BgoLx2Vb9>!M+psI{ zXGA9Q7yU@o{Au#cPXGC?WkQ=SavS`(QujvqCXD~BoXlN!H;$2S+xRhw4wv3K#2 znxxdkr0l2FJ4%1`9M!XW{zcJjn@qH}x6A#iBT8FO?bu_>J#DkgTE?xnUg^4<-oJ6f zj`i-fBhk`dKdxN7Z<-tPv2~AcM6kbqkiIBw{*3WNts_1-szYsp>M{O>P;yi_%)Xj$cl?d7^0B zp^)txer#V?Emc?Q`g3RE@iS5L^cQ?{-PgFR+_89rzxPM}d_%T+xw=$VJNq4fre6IQ zsTY4?7e_yTt6E9PYcjU;p+gxfB-+fR&Iz{^QOlhT@9J!vI?y{<8Nw1~bmsa=Z z_TDJyOy8d)GY1H8V{9nTff~dfvO_%7L$KT-sNDUO3|EEif%2+2MA2 zOx0}bU9H=femE@?Z>hOHf7LUd;4KFYzJ1bSf45xq*~4S%*Z*x4d-(CIzGQvazJDKo zvb?b=Y?XiX`p@jk|H`KI-ux!gq5o&a-Hi**E&V9BnoB_Z+=I^(ZEWTot~_MJt1n>N zIzOV}$fnzsLOG=m=DaszoL!Uk*k;a)bEdnFNUyVCxcy6&(eQ@sen*ynAF@vLP2Jj2 zcl_Rhb2ADrNUW~6y{~h0+K;Q>VitGqe9@bG=WOZmieu3+zt%n1y}MJbeeKB=KbM?a zd-R`x#JYVOg`C(b4er*NrGH+#Zr^!{Ro!np=W3OgUilC;@Bj3@n*;kFUu%5hTXX+^ z=laQOgIkqu+S+cCRX_KxZjp(vSpyT7!teAb<(Cl)*7cj!Tog$?*25ItuJYdGYK@;Y zzd%Zv%e<%Amm`IzZtd^064)BSr1t8=gPH~UYpV7cdl!73rBU&5!$siVh z)vo-V$9AuN^O0lK^6S?tdncVR`lUYSYw+^^4ShC-E9dU}%jAE$ChgA_-??WKRYGwde1Wf7xM?b%oSMfsVQ$T1%TIm&Hk*=G zo0qBXSRyClJ@vHt@xnJ&dGT8ce>}M+^iOKJ)z$_hw)Jm&cCIen`djXe(;X)9*A}NU z_)kpLzxB7>FkyaVvUlHurnRY$zb0-uU1+h8$4$g)*RGw^(#hK;0 zuD*X`@1~fPsg{O&4$MDX)oQXXb}JLhZZmfg^(qDb2!Xxb4dsR>=I&vanxvfk^~Uw* zEB2nVJ7lDvcWC?7`_qoB|N6l$Y2G&NvagRXe3U$IqqFxhEU%_Sm`aU&J(@U$5SEYQ0$-|AN{JSMIJ> zk&>Tbdq`*3o1Q13ZI5KlmOD8&$FrNV*YLmjsBqo8Y{dlKbGEBxZd||7F0cIb$AY~{ zJZr7%USDLn-CgAOq5Z$~`MED&zYzT07XB#j=`)f2?=8<~e#)I|9j2k3R@Y=N3DsI4K)X@)gmzyW#z8Czhk`vvv7( zex|Zr%JY5}ea$?k{p5`KlNOcFPZgiN`>F8s-YXgp1otk|-?n`&_ZOctW##d^Gs0u$ zEMhHu)}*G9%f4?znY|&;wV$VU?>c(-*^YqVrK+pnKTR%qmo_;$v&nQtiL|ky|Agc3 zpB&BV)!{4uuzlldhBmeN6_tnb{yw`q<4Ks$?^iF@N63Xdv$-QBws`8&h4(AA#5`6r zv_H3fPgS3ObJE`X0bipNpKjl=>ksMA zjJo?lr1i) zirZ?{vR35ZpLuT5@y?yf_O{>c65pyF?K$rH>h}im7b@KI=dF${-5E9A>xax8TM@p$ z>#iz2tc(}_&Lnbc-*LJ77KhG>dp^nET=wFrb#?acfXDYu?fe2P*YP{`+R9zKb*b)I z`t3ujzH6E7Po5hh6T9*8;g?mxi?1Y#7o0XdWvTM*S?G$#$F@YrXsrS}rtvk@zQ1P+z+}8!X+t%<$KDW5-=cjXSQFxui{issW`?;(3pWf&m zKHcU2y|%UT|7Py_Q^R~i;&e|E&%)NJfy--e3O>J+Xmi6m?zCsm^ml!-e~iT2?FwAN zWYY8t*}cDCIq>N5(})8SvOf>~U05qTJM>di&u(+O)VDHi)0_4`c;8gSe*Nnv&CPL- znQz*by`6rZ@!g7}pAYh_iKvz`U{92K!S~{Cfmd#0YTT=@O*$)o{Jit;5?77gjz3GE z{>wi2shq2I?&7J3)!VOKy|4NGpq+j5r-R?aHy-u%cS(A#Chs@9+5d>0pvU_8LC>8k zC0O1Ff3wn@la*NA6|r;O4kH_Xqg!t?Qx?YTmLd&h&^LWJOUpW}} zXR+NEwWoV@(~CdN4brVmp7XaqdGh&B_UHDP@gJW)%i~?CLDlPb7OzyVn|#@7 zS$IwMb@N}*?LSV6&z+s!X~et#o94v-2hS@`e|0ToNyXEqOULJ={5xWt_quB8)6#ie z-(?shURNIas~~3YvT&)4`bVKn*US`8sx#lX`z!X;ql>9EU%PE~%u`yUpTE*gy5{Mv z#cwT*8m|bnzUkqXIGOe1d*K3KyNe67yxexn8Lw)S7j~A|JEZ+a9 z>%aDmr(tymj~`b_RNc6#UvJ|BnY^=_yB_)7TOU!hEbdS8tYhA_Qu_-P82-6`x?6Kv zx+Xg%yfpj$?}!Pap$@yZoe5H9vChrSEI` zCV%8W#+%sneX4eg?{9puV!QnsYs1r%?Os3Z(DnTDQoQn&vXtgO#DF?qv2-NL;IY0g(N7ry<-8f|JZ zYe${FSn=}goDXZXjjtV>RM@@NRO6wwm%Q-jg72z&0+RD;1TW4pw0m{GQ1+)l($8B$ zpC>#|uwao?6R+ut6n>m7HtHFE5|Cxh%!- z#x9FfGd^iLq)z{TFYdsO6}*N&f4>duR$9K~#WR@&bFZzim55w=`P$Tiq@&Buncmo8 z_-T>3ftqM`f7HX9N)wx=|24mpI9sx#+tNFaNw7YzK9JQ;KIY#dr~f%KN(*Y2FP7;u z{HOWGYT}X8pQ^1FOe{|LeJ_LW*R3L@lSe0AKChwPzvJY#8$WhQFwEKP{lu=5r@him z{QQTj)Bo#D^eGnNzxKx>u$Onw8Q!p8A^|hMIwmNk&i;^UUE}z}`ozNGhdXN$oN`L{ zWWJIw-9N`7dyh=0LG4rBDb2yfPjzPgUVKgK@UF*+tnq=G;PQPJE>Aef z`1#bLlQABp+u9iJndNC zwd(V^bN;(YpNNA&VH58eR4kMf#c@YPtLurcb0i~{lXd<>lxN% zl6E|PZ^B<5{&~l1#i5|r*Q$HeW~azpyWS&zNYz2%(0WH7_I+8!RvY|gN3Q19p1s*G zGWl`&hvoa{1s^-x7x2n&iS^=nv7g+1bFTf!lGW3xGBvyUa?c?H{u$A2T84H}O)^Yt z*;BH_kL-MWV`F67q_;o6<~!(LmFl_Ayi&+)-UaPr5`OJ76sy+vs;#b_-LawiJ-^4d zb)cUte+ubnm>Q`fS+p3$+pdF$Fon!BRb#H%m& zU>Ir{VEBd!A@N zVVhgV-y};mr1y!gowwnr&O@GiFM_5E>ikNPgt;I1mS^41@!7cP zTf*zf3*&CIuHJre{x$oo-`;6T zCwyFf{`^P#_{Q_>)Bo4>)>|FgWzoA_?pOKo<$wBCzRe7l{Hs}i=ov$;osamm$9Ky^ ziYjED*cu8R-*@q0*FTFy{WV8&)vt+1iyX3e*2}j~_MW<&<$Ph?ZQst`zo59{sp5tm zkHutjcfFC>D*3bX;I)1HcTVoKv(Rksd(@?pUlhZ<n^nIKCzw=dJ{L38iCpf~ZI5W7P`~ErmwoB`O?qHaB zT)KGMHI;vT3VjuC=IhzyAD!1F8GkcwuF1DYwNEzwTsL*sj->ZxJB;hKg+9tY?~bYa z#6S1LvGm5S)Cvptwc9pc{K}sr&y)O>%XUNAQd7@8I>%?6-p!t~DJ?!fkLRS@o$DJb zI=1t-e7ahE<;H=lf`9xbNbAi!)Bj`g-inhCY|^5*Qr6G;@a@Vh|B{dD?9;#Tbzi); z_t=`rxxt>lbpMM@yHmFA>6~BQ%H+s7BzrB|e~uP^YvbJkexX8k(R z!s&|(FIUNNJ(^{_=@n=74Vk=C$CYNXbN5|Oh}*C>_?rKr3HovCZaj~A7-eS=&Rl-% zYIM5i(!Ixz3T*tsD?0h1;L6%{XFnw-G=*9g3P(Fx%RY6?d*0wEy3zYwbL8EtYDp=a zA9^NM6~^}27;LgC-uG&Ad9SBm-3*n|?dMoPW;z$!-7Vdk<3@C!V|i?uOBJlXEXij&G|LTdBA4!#uOi z=?AR1R!x}}^;YH7?eE2#oXV??Y+8Bz%P~yPklV=&Y!hsZ)O=AwI|0|K0EYmhQaC7N*&wNb1pwZPfEk&%K_vGLHT6Y(3q@)@2u0-Ml#2_}8bt&-Z!BxR3wv_jR=euPk0W zeqFuMvb$i@&UrBjF@7)AXU{q-x!AldV}8w=GyHc>&Ai-q-tb_a&9RGX&AA^<7mh4> zYPLp3Ix;8hO6|EVyFXgKvfj30-glqMqpg>|@t1w(6{`L(>-_b_^an{VckAJyy>!*cL+sCP&59H5Hn$}?Y^tblL>k+%}6=?3i zw64d0bGVyq@N(V6D=|vGcOU6r-*kraYqszCsCVX?Ps8`70ax3HF|}SDq%~) zwrUFf*Va4K-Du+&Yt-%Q^Lvu2I>Q#jg1KvY>Jk@k?`Pm`W ze2(jFFW$ZVjE!kjjjV+2Paos8Le&Sfo}CKbV0Wp&uPE@z%ge>tkBl0Y?_0tAHz`x+}9zPa{^>HQ<;WaJ_kSd0u_OyyVCb*XYSX1>YXX*0_(;`8kv zW|x2MeBQNZtyS_HYyK7246`l?FJExg{a(eFzn?XaCcnCB*IBuDib3`zw$A};ULJWd zvHYjhGt;|G3W1UTn9Tk>jr@3UcJQ6b=-NzWmAQX}m#k5jmP=(SF4|gW_TtTCha+dw zX4Z(C1>`@x`>bo$oF9t&Uu?<0cXGn(Yn^NRm)q&_F7tS(lm6i1#TT#N8~r!)ICoL_ zyW2TACo$RM+t)W7+7qvH7piw>UqcC`eqisyx1S@ zwB%t$3%CB#^ck~!6J|Htrz{oRUmEc;{r_sM4?iD#3J?9I{^&=;CBsY1tJYOrsQho? znQ;E(9g8XdHKt8YK4;L|{bc1-{k`XT%`QK)_;=RY-}cS28A~?u3LD?HJ7fL#PWD#6 z5Q&G!z6Rx3Y>2;pO)z)+S5KbV%nZ|Jf8#dmGXHF%e&JU}O!eioNBf>=?@Z;4e*NXy zo}Y70UFNr37Gxcpv;EDhKeFGx#OK)L@qXT(Re9vDnDx8<#D^O9zuvre>4?g<=dUgZ zUM~)f+ff+J958!x$@i_rC%=ApThY8UZJYHM;f$+0f4`O8e*JdzouiePd3-|7KVx_7 zx?n!RyZqK&i`psgySV4wIHtE={#sVzahvP^jTv3-D(05%OSpb=VMM{fZ^1Jar|*1K zmAn6DnaUgQxgTpMB<9zh;t`KZI(Pro)J*w9^Y-Mv@ZGs>dwcZ06RVczPn>vpRdUVx zt1JIkZ+KF8O{e(sER}z+Wz5XJHeB91_n%pqsO;@4CYA61tNE?j^C~xaVuQS$*@It& zymiNx_RMv@KBZlI@3I?rk6GP5y{M*r?yei#JyX7lytdolB>whwS+SIj#EK;{-Nt3F zXN8&Pe>%!K|4ydc+~6lWY@?m`UU~JbI&scw^M#gt2hHzon#)*td4{pu?N37DXS=#} zKS%o{Tv_;5R*ZZ9#t&(0RQDvTJaX`E)b3^HEH0S;lIF{Q|7ekM$p`x;T@}6$Q?3;) zX|t8v5Vl5ZbMhf?waMi__Z_veh}s$}$E*JC%Ii7K$ExdEtHrNxP3b+eyg|0b;Bm>f z%c}dmWBzE}IQNn<^9Hlnl#L(%iCmoJaF|nhZw)W&YgfTPm&I26Z89uavqU4^;)zA0 z|Cj82d$gC#4RM!0+`5%NtMQ@5!JZxB1&@=0Z(HP_`Lyf9(di0TQ^WVXb^gQ|`L{gr z;i~sZA9v0QeJFZ!;^iYQesez69htWwb%Ep4x2ty_-}~DCMQnMJr1r+tM zwp-4jwR~RT*VFTVZW5pWcIDB|qh}W8{@-=*{Z6|*d=JfcT&VjhV0Xmr`i!^nkLOJ4 z?KP>npZxxFbWQENs$(Y;!(Uwq?lHdqtK!w7oh5nrUqm?YD!uYtN*?MPeMeN1w z^@g{_FV{(y85Hi0j`{8{^Z0}0Tj@2mC!R=3%f~VEF8WvfDDU%?RlkpJtD8Dq|M#L_ z+kTqw49S1ve=eVKaYoGhP0BX>A9dxWcWugzzccIkB;|jNzh(Yei~gu7`1$_I-}Xgz zvMcNsl>8`s_r=hZJyrJihpOTh*4dNuH$G?md3=M_$&beh_@4J~u=TWk8hkH3e%{o| zcuT>+28s>Gk@byMOlQ?1<3TqgJ2yXNAnElC!Zi`+DVS z=G8j^Z!0&7&%F2fh2{yHJJ(+vvN@8gQ)80;;=sn-hl2foBIHbWe@kEUv|Ga5Smsru z%>I4p_qgs=thPVN@o#NSC&RXw^Bwp5=hj;kHpMEloIG4JHK1~l=N@+u6=-T)A~p>i&PSZmnx|ekW{r%aWet_wVDK++_3k4+Z*mh1s=l>v^}` znOy!lTJ6K0V!yZDt5bjfxM}h2r1`h%dqM62R}4z?*QV;cTsLuTOqSWo%G9~y-|lZ+ z^Z3ytX1lXLW%+(;n-zZ(5ua%^)7`XJ`2BCjw|&=sJm-&k_uT9H+1F2_`ddQ-?0RiQ z+wund_J<~^?9_Yns7UU+rC!jr z?4p{CkehEN$m-cgm&)%=NZpWiq~p*P{yNilcMje7Z?Nbi-}8?T*BY*SKR-UnK8DwN zqtU7GM@NoZw6Z<#yZKj6$1u13{_muu-1WtRBAg4ZZ~2#-yqLvU?A>jaB3rm`R`#EQcORMijq|Qgd4A^T4j0q=PxOBFerDaB zC?|UPpRSmz{l4lSJLLJ-HRdeLn5E^E&A8_0)z-)7_G9;>X&DVyu_SUTiy-{Fe?B^HWy$F7~7Tm1ZA&(>p)?yfl~IDf~}!1-T} zZm};tcjLyBx>xfyY+Y3D^S@d0*^9^3o!&W*8r2(;s}DTesQc#0pDB-JcNm2Jaeedm z{i%DF=I@Q=9vANyx#RzC^B&br$5a1zCCBwgJ!EOzedVt8X3c%IZ~bQXtxSIV;{H|B zi-#KPHClAD*MIu8;{N%6*F!-q*7d8u#`j%eeqwV#XEt-D}9) z3twCQqM6^_roFbFS9tGv=UZ3A&i%9UQ|mVWvD5JY-y7HG43=vjG`HO|OZd2U`qSD2 ztu;9luiK|Dds_YE#?mCGyN zeeBP#y6@4R2R_d)-TAJH+U zb<@{BK6mU+;i<#cDJ(&G_MPyvqaiqKY*!5{O6TYS``q8<*YR&&G8W(3y4?H*f z|Fq89jXQ4d2;TS1Q_Y6q*Qcl4d12l2_Zc>p)GU*^K6`#s*UiehIr)WO{Y=DydZK8JM)Z8j$Ow2WtLxlFW775xAwk`mVuA@ zi=gzoetu>Vs|;RM9=@>J@%kSB9M81Ixn~n1yRGm4Wn1@?!Rdb3&t1<#F2r1Tn?L=+%i;p#5Z?qHhyYtD0!S*1#_=XRHUlrHL@9;bK@5J*n zzJI4X2j}hic6IywDGj?1UNO8Xe%Vg!rj_ywxkKDyy!W{twC}N+KCix;TejH!vAk5} zn%L_{FRVQNGX98|_|K^`Zy$Q}zI}t!sr0O?b~Q5}o4R*9Kf6%uqEnx3%p3|9!hU=S=nGa+l{l8=po;zFE~7GF{Cl$z|5h zR2`MBtH%4by_k6O!l|u%Dv!=zd-5=+X<1y)>)DAL9<15Uacxrm_G=5*-`T6I^>qG` zTfG@S+m(cc=l^AydY$L>L9<_uJjWLVe>zrReCjNTy=T*)y)`$=S)S7H&snl1|7-2B+FK24`9J5yeLDSfU84WozkV^l<$V4g%DCDkJ;(We z#2Ll4b=Lmp+U8sobiVQQdq?Jn=g+2td$0Ps-_Nr@b~(y;ob?|2oPI6aqzkjf_gQQx zTCw-oCO>nAgugGF*>%#{k9-f)5$BA5(fw7r@$a#f8S`B%)}DL6F;eed{PVM#|9)tG ze;;3Dr17q&o3~f`-0>aFUw7WNpL?CNWAf=M9D6E**V})ZpA#N)ZqAPUO`NGWJC(nM zC!RcRDt6BN&y%CuA3sttmrS_5A~?&ntp4BgZifB!l^xbH56+rz?1;#%9MWm7+EUkg1YQ&JnSe&x)KlY-Ne zH!k$smGP5Tbl*f@&QgOEU$eZ8pO^8~bL(IDq*;@vXMB8vQ~9yjuj(`QCm)`(Gc0{y zLM6k+9h=VI@v8gO+COdQ=g@QU|CgJ`sE0j1c618c9qFrz$Lr29J}Et}v{<$5i+tkF zgAW}U>ewm{Dy2!TtFinpQ>cH#>O*CZ>>sxK(v^Ljv#uMzj$&KeDta%+uJ?9wXT`eB z=c6CitQXfialB46fBt5n>GMBK|E_H|=ls@9ZtlkB@R!N3vj8Ib6JpcPMf!B! znr?Z2;qEODrO$Q#ZGY6%?%k)n_N0oLVgHIJO6?v(=GUFL9M9aZPw(4UkvDxuG4C;> zh_Hm0Z%FgJ2Xw=&rSWrtS|q6^STGGst$(cew4Gk;e97A z{MbG3mP51l#5T z>-|5mZY<}^vGZMhL)iF+r3KqVtBF^yFdFrpE?hCK_{};~qa9lt%ZpCTj4w9h{QYHX zz`n@&PcBx8^3S+%a9NyQho$zqEFLpO;p_aV6J~$DB6+W?e{S|#srrW&Dgw{>m2Pv| zsmiXgJiE&!f9i&_(btY8Jx_aaCE(k$wOdo~UuvvAbm~%#e(Am=XSY7wuf3kreNW29 z4_AJut}D=9H_1bf$^Y{m?|*{R3~tyaKkfLryRb|*^85ywHK%)0{wzGKu77Uxm8Na$ z(|b~z3l6-wyv(>Pmb4iGUL06@sAI^&RH3}X#2Ho6J@vliB+$Bw7%>^-r9>lYo30s zvE5(n8=bqM@7RrG>+dq?7!fO6*2uO}9 zN}KDMJNblp*ny8fTXN@>>pb_YX((OWxAp3dqe3>xPi>DkZ9LT@`PGo){lgd=+fCft zo_lSusxx(-UUP8Iwt3Hk)<2uQwe^2;AAdoTwyVYNYj-wh_`bfArSn|2cct&An+f4F zYkF>P4ced`_WOJ3&b>8#|6X!|=E|3A|1tl0U!AE>bFRm;1Bp`l zTOV%|-mCxY(^=km=W2eRRr>SXH}{71hg0s$_2)0BV0bw>msxAw&siM@=X|pfBW;4C`zR%p!V{PWsZSH(lfAOJF*`mC62j8vd&-iv$W%<7T z<#29x_N=x#=GspS%NlBx7g!eE+1c^`7;~w#wBA%(3-Ke3tKxQTRMk_;i;}3hxc)lp ztQ+49W|*eUpU`#Q>f=X+i_`BnZM~bzEdN|zX2!jc-)ARXZ_&B(`13uPI*U6S<5#F= z&;NXYd0NV+Y`-g3mcjk&IO}TrcLaTUJIylPBj8rT&X#H6Dy@F>-kyqtrrIp0`?KzD zTsQTa+r}GhpW}}%dv;}#+gjnxJ452mMQNCvD_y63+z=y%pZ>-1Z3^q^pGmndx?d-3d=sU%A#!%{pNGXquNpSS zu5bRff5YUB8y8&qb}PWf{z!9qambyc)>~Oydo0gpUo*b09Dja`U5(U)-kW^oFQ#=r z*(rHm`q!@|%T?9>NqQSxSJl2bw^+7vxt_4|$MT+t$EVG{DYqAK^@Yz#o<3)?`0wj6 zZ>Qw+@XBdlV|w2DAynk(fi^db;JR5~(r=|~$dIT*{0(cguY2v{ z-!Pkd@toCr)LOq*eKIu3?y%tRjhSI~y=&{r8pSQ^@5ae4nQ9huaB18h21ASWx*Ikf z>&ZT&y0h@2-si=ipZsCC;P{2_{`P5ir0W)!+O``%?>Y9@Y+CmFuGJO=oX^A8JiW9{ zXzx7JydTTXt?TS}?VFjBKZnbWC+^7G8I?(nbF&|7zPUw-0rWv zC;h8^e7m`xL=yk~&oh~=;zKLy3btI+t2{8{as9ehE3vI}?tc5d`N$gX$1C>lo0We( ztVS#E{%z4OH~(vc$79w{`MaLg)}K!%=FWqc8>Sh{{f}e) zIr}!gXjUzG)@!SN@%|_6vSlhW^AtTbZt%#Q;MdfQS;x)!&N%B)QCaL~C2>Ya?fARP z&Fy0?>K?OoM0}e4bMw{I$1(}VmC5|Bao=i=?NxXym9pW*fpuYVs?x6C4Qh`bJ9uv8 zHR_`|vv^k2BBy)onR^8b{;H~*_0HOvxqW7Y=+{dRxvwY7+L)~oEx)>9 zasK+Xo%)Qa$1fD$j>`Vuf8VtJYt;^e=^KsHN{)C{_r9LNwWa8)Mc7fEO{PuDKbiNj zdsUuSQFfik_h!}ktE^&XhtK^vK0Wy2joity2Uq`KjXrIDgJtc+s#iRBJ7?azIyva? zi;B&M>z+M5V9z)Ez-poYoeOtJeMwupRXr|R-fxlj<6hN@Z(r3;Cz)OCzd3u|w~hbo z&Rm_k`fWw`rK=Cl##zk!dC2m)X4V`l^Y2F|cNV_32{2}PDEIq@h;((<6hT|7$_u{A zpN~sljY_pUym-cq!0M>1yE~-Yk8eA6EI%%Jz3jfe2IiYLo~Bvo?wQz}ukc+y;ot*@ z-hGb`G+AF*ej|CI!#C^Q3~jS}*IaY^>L^-zF1Y@cUrfHU&HOzxPgc5^85Q-K7TCVY z$e;A|$llL##?SJva?LD%ULkX4$-9c@74B8Cb64)o$`_iH+pOp4C%Nl(-SY!~*kA8_ zxN=f%d*iXS6R!*Z({B}*kTi6kzNd#lz+1}d6K85}12)NU5sPS=M_>P(Kbw?gL zyqj^f>xk?5dp;c-jkoKXdu1!rrAhKZC^UANW81n7+ER zcWrIM!>?z}_NX84-xw+S-1O4dK!yJS{u>_@b!zWhpku$IMQ)?{$;)g$`(EjFKGx*b zS^RC{wO1Ph%p}*FsVtgvW$BlU=3e#p$G&c3R{AR2{Wi@uZ(rk9{v1D@>>GP@VoX03 zU0U}2*~67<&lr7EIIOIG{$k+s>oo`Mx1W38xiU5D>fS_UF5c24+h_B#E56>@c=5Yn z+l}Svcg!NsP?=>|Htdv+o1Y}UfTs94dwPp&tAm3)b!HthmWHD<$^Aq+oZkZ z_Nn@B>%%tg%YlnT{jaYp7{*A@V)>q?}85j6T&A%S= zZuuXB*sTRIF?Sm0|NidGi7-uUT*InG|cPM>W*Q{DLP zcaUCMO%}&a{wH%dYyKI2D>`)6Ga*rQ^87#ZBWgSnBJ~fX{1E!izTv^gn=yY2D?T2n zw_Gp1AiyLgS1;mk%unVw!h7oeXj|BK{*9ggDQZq^c4hd5Ys)v@GM+rg7l?rEkS=P8ZY{F)Zi5F-zQf^>M>rE1Mn8@0gozayY(kAHR0>O(Fi@dWO$cJwIFJ=FHvb@uYLVqFkw6sm6?IyMq&= zZaNeeeZ0>&m;L1GLY`kgxAt*<%DVII#GkaTIQ^b5AIBJd&-(2}$8G!V156(LEIsyd z;nuJ5Pv2HOnCg^x-ScCd*}486FP6-xFLN0U7B;w2Frhf&o1jeEIDp9Q7L!QXO)c`TD>0~e<8Kn=Geg_r&5L^k3mxH~Wp{v19YCKB-$b=hp7y*Jl4bF{n7L>5i1X&AeBx>uPkKmjAD?%2wVO zef#Y11^PUtdS>=dEnoYs$zHv`;N<%BM)vAszI!{aO5L^JdNtWmUT|jnBb$_Yb6C&V zKULUutmCP-pg@Q5^T@*Qma`H!vZyQzl$4&GoRPe7V$W6`d+jxQw}-84k2za7!@@`K z<6i;BHI`fTBFfJ=$G-LVI+AfN>D{jNJ3f@2lbgXh`$yisSN~tgnBH%RxY5v&Rrh9- zn&tUV2c}r5-Jh`QfkBw_wKm=P4gV)st*&h`%}NZ7PK=bdQ{&;=_q8ymS~ZfQ>?(0U)*(ZAou0+Mx%-5Z>zt?oxzcW2C6N`AV6!u?; z-g!UimvH_p9*YXrlQXQE*RIKCjaR=PcF6vh+S<6uG5moWe5ALUPS^HN-}~v9c;SiN zXA5tt>K(eaitX}qMu$hyDm*`LU4M{2VQcllbH1;h6|$(P)tdZfPuP+9`svf> zFSYn?yuRqm{6i1sn47-*`yzYooL>dgHY)6_E0lkG*XGROt7{JK6?y2^t@`w))$ zj`9LG$J&XW5_8K1c32vJ{Hk7FY@zd}tJ}GL|G`fu_ex(Y6g_Cl%$>@yqAvBlmG_xR zW&dWyv&}Hw#*!s8fotn}-37m{Bs{f#_Tcs5R0*A*?@TrJ-#;L9xOB5>O#EX$L8WRB zp5to#+?!jK=kGh8UvXlJe3rFgM%0An`7<(lU9S zeNoENHaSM_!NxDo9xhC-*|4plw&L=;>;IA#=jQHmx6i(^=m?9mx13~qahA!lmBBol zU3RRCkaSyj^@kQ)b5U&K`2|Hsx8*PHM8n9aU< zW^3!V<4yIay?*zuZtOjn`zCVv#?XDz-8#j7LeJX8ADz70Qu^-5$={K4qf;kUPdg}Q z8TUzkXJxV9w_@g`cROY-?(}?f_0Zq0rDb798Vp%U#JScH)rX zk0dev$eVt%zus|BSGIUQ<61)$=ZmV$nrA#>$vOX5|2)dJH@D!^&3|9Py}j$pA6RpI z>6m-Z-td{i6PH8N`IlJ=)LIlZ6gMy~c$%=eweZdNmezmDI=?nDbnEM_TK%^;!sfSd z+L153(>qP(PK}e0u{`~!>uGL7-i|2u9sZed8^Y!m{#Vm6Jo;MBe2w$6Il94};^`aC zooL=QBeM6+mKV-DSZqwS|3vF#pWOd%w@%c;vkfNaw(0B>ex0*Z!lX^cYF(Z0Ez=2~ zXUg$!`yZnH`maIIoqZb*r@s|da=Wa5@78&B9hnMQ_od8SOs&$}%{~gvyTkE>>Cf$& zq%#o@`11G#S&w}U+WAdYr%=a-H!N?#1xy^B^$H8bndjTZ5MxV94Q zxWA_Lwsu*O*h0I4v%HqmPZsH2yLfYj=ycnh^*_V>`se@J^?22E_q-c7_HNnV#7HhS@rN6LqkizqO_GJnxyn+Fv3JnLM2*19YpjRh-)mxc)6^>Cb$-Ty913 z9DG+#Y#CoI~v4Cf7B(|BCz)^7m;J@R+&XDB?C^t7nbAKiB{FWk0!)32eptudlJx`lZRN zd~sIrvlV~*c5|0?_2?Xa^77~2xy!nXWpY2fyf)*+k)5wMzmhmuyS??U((K=7zgON< zWN}DZQGMtk)8x`o#j#dO`*nYUy4w@&%$x&$e?7q@NJIaEzk%97VS)cln{%Ocm;M?BE1PdW0z zW0~Vc6C$q5r!1{wQDD-YD5mfEXL&+^=1iZ!+~fN>R%wmE~p9ho-Vee+x8ps_|!f zvCFTcJ%5kl`QL2skNo2`U;w z1Qo3_$xFVyU1sv4(B~Cv=3cgbQz1UBRP_6ofF-)}JzJUmeM3ZU=r>Q*-Ed>2`urOj z@q*`G^2wWhW}Cd#>O^kH*BiGizO|*6B)#8t{%?E`Xo=o#k1X$hy!@3+kxZsc zp4}6RSD%v4iE5}f)_PxSHeqAS&UkRY>*!LywcW@2kJKLerINDj@XgMjXC?}tx4Nvc zuJp;2$(M}9RM$K@d~C1p}L>*Wm+%GS){OkOV6F3j?J%6!3+x|ilss};X6mPOwD^(CA4tHv$Gr}t|M z7!B1=&i)%3^vWRZ%Fd!cH(wWqU(MNY^40<2um@(_{%zweJMzSBVqo&BbDyUEth~4*g;p)k)ubcGD4u;yF zYQ4La>H4gr2nBuBq?`&cxzIEezbSY?c_o{RG zhi=L){~411>E=E6&Uy|%*$dWkpN`E{=Q$c?|7w3~U$II(^f9HDb<9i;i>OTGPw$-L>MjyNNzpV)0*LLUA#DiVD z^J>&DM6Y?)9{IRIqilhb)n{2@^)u-n{pqD0%arGR{QmpqM$VE5%N)_N!jtBc)*jEd z*m;@l+=*pJ4}6@>ZJRW^(&4N}dBYbW1?lhZcJ0MEYCaoR#xw>c1#B<4JU#G!V`^_g zeSYlvk82qoMZbEuX8-#W4r}+kV$S*at#(JhP38a49PUqnF~thT|0QP|Eq=1o|JJ0Q zr1?ho>b)C0qqb`s`Ct2~E4xQ>w$RdP!Kn>atI7{Cn!y zy<^XfDh`E z+TaymVZYUrUKVgw?V4vlq4@C5FPm<$C-J%YsVw(3Jds(iJ?+Kogn$2beE5*LdWv&S zakG~G{F;Egdk_BAAG6vX%lUlY=cNhq*DJ$MU057;zj^PXdYyO1X8hZBe_L?B@YjYr zw~u|!{;V!gUJD9{KNNxc(RZN5??&Yoy3m+~oZ#mCt9+E-qfo4rukn|=NB+2e(+U(2hGH(b{_(!YUO z#OB7)%gl=Wjn8+UTVCF49e$Pb@*bTiyQ~Rz5fTE?`sdFci>tU_)1)akLq6&J-si0D zD?0Ocmd)1w@%6#-fBezc-B>#`qK_YazAXFyHmePhtJRGJ7Mu)~t$FKSHe;S$?vA4` z9-I!Be0fP)qTurt!>3kkF}tU(-!SLrg!PaAO0>Ua*_M9H>2UVf1mW{)7Edfvj-NbY zKj{FQ{kgN8!L>85uhQ@6P2KZsy6o1Z&Fu#!?d5LI1SsPyIa{!(J?#b#>>i;*|d<)h!HCy6qkxVLxn} zaINRdABR^3hjx79S#`TMX%fHg-W1b(`I(}N~On~%C>Lc zwz(hPS!@#b{>GYbA2#Zn9r{qPeb3%UZz`_c>v4Sg&h@Y0kCkDZ_GLyV)N@#c1XkGE zuH|hwk-B}}OeNzj9xT@P-_+*Smx9M6UUmI%t$2Op^v2H@iY)GlY_ny2Zo&SZ_hIas zPib$q*dM=t;L%f?%{N}(vnjfpHDBf2-8oI$m#8~GS$#_rckb+) zU*=7Fedo%f->?4UC+@T>klcOjea+TC-o58cfl567fe%%A*h(oV_G-sTY>IJa({bTfDUq1>|u zD-UkpP=5T!*7VjpR^Bc*CQbEt(|1A2?c0)_H%?w;E}i}4hR2$-4)dN~`Tgqk{$Fzb z+H74?iZ;h&<36u0sf=K*sW)*y{UI@7&6An0S3AD0nflK5xr^NQm~EY(H_3iceEEJ) z<^8lErR$bmGwyd~--+ydf8f-UjZ5>Qcki^DvD)Kx+4CO#;No>TyKnm~IqiI0H;E}>Pw_Kd#CettLwd=McHr3wwruk8n)hYmhIY^o$CTztd)+nxNhaz z#v7Mi>MV6EP3htO$AUAz^QK)*FszTgY_9%zwd}X=ulur#jvf53r1oS@W{pIB3q$wY zqx%jv1a16fS1{v`#<$oWQNI629vz*tVgaA!r!~!~ZyR;n!q=;wb}IV+faBl|ow=?O zE}sOymG(7oo;aNKH}?LN=XZ`h7k=0CKTpOhXXU{u$rWy^UTlt+_c1)1q}|@X>vGxE zf0oTb8UYl zw`ckrPMtOKPqyuN%zpV%lyHpM{-<0u*Nh((k>@2AXrDKa z_$@hmb^ivA9K-E9W7l6SP0%x|IC^E1RB<@N_3l|OQf2GEFLJxocV&_F{Nquk6RQ6_ zTEnksylh_0+OliU54nC@%)K;+|H&o&c*x!B?9=zJxl(T{VE@*df8OQGg;8^yYgO!C zG;P|;=N0A0-hSuOoC58$oja-<{#m|hDKGE5J>&9mzd1FFC);%8@{0Wv)XokH(t6(c znpK*4zR&CXf6pgz);{^97jx5^mbGovRGaDbzPjOt)jiI7ax4|G2&gH^sTfP-2VJ}=_*nYdi2BjfZXTIje=2^eV>NQ+}bZK9T(-_GUwOZIQPkN4d(tipByA_ zPu_m;+eDd*t-q^to|&3nULN{GrT4F}a>b%MpYQ$?{`^ErwqingPD&u({jL|%#f^)f z%=lP!+$H|aWvROhyH55^Q7lMel?^G$)_tU*6ujdZciNQZye9>hu6>@Id|_J7lgT&M z)}HG;aawBoW5;jP$~Na*P%kUm7R=b_R>u&&=78|>ADs+FsoVH%md>4FeE(wK)yAnQ zUOCqvZePr+@MTM{+nm{}O>f&(%u(CE&i=`@iF^gubFMKM?foRs-w`a_9jFjo9I-y{qSbHT z%Xgi8g4=rEh0yv}bsXFuXEM)UZuOkAGDp}XtK+$1Gw*}luM)2|?&i}k?p}4{WT({L z?4#FIw!A&CRktsGdF*^1=Z^Q8GygwbxYC$)dfWR`U5WEwr_|kzk<5;fJ`n8om2*ew zjidL}WQkyp0Mw))s=slxhT-8pVAPaS1=mz}kG+UH|auKl|F{gFnF zoORBE?3ROjHP~wNkk&W+_ zTf6Su<@N{cd_T7d@Mk(EvbB@jL`C(VMl~Mm^*Ybz?|9{SpD|~Y=B7EtJ zjBZmI^~{|c({#4vSoM3_*B!qy_vzuehigwQsgt{R!*q6d&WZRvZ|6>)FO%N8>ewgg zxPoMPj@cj9GVj3-wZl6-zsbcTv;& zZ;0L3$1?=~-v7aWIqvfHs)+4fS7)7;`<3@(o@~nQX^ZRLv;?ks(A9c;Z(qY=afjri z?k3UeQ_Bo1o8mS|-<@51NN{suZL_URQBHrd{Sozm<|)QTHA~`ePv$rL@#}H@vzN*9 z%(oufIM=jGSiGR}WWt==lV+)wl&pSm!vCm)XseWJ)D7$P;g_Q?yuZ^rMf&)iHOggv3vEPd1KtWKkFj)r@f4~JiAMQJ?Ke9zMb8C3vth9?7G{MeT!o=_8#bc?|OL0 zo162$9=x+r&D7z?%%@j&$4n4X*8Q6BCUfcb$(&y1+rj(X4i+v2UD)`vyS z((TulyXh&CD*#$e7t0y_W=* zAGhum)@`kscwqO|`oKDGgOa)Wj~_PfU!r<2D#B>RS>5HbX>zBG+J!cC{d@BMg(crU zwPP8UX+?joB>qaf@^k6;szZ&nf`*^@{Y$>tjju`zj!li#$-5cucuwOm|Kr&*t3SS7 z#54blcZ@}TL9Oea+DA_M3%=cxD0n4t#?tP`qFoQt<$o@1-2d>x{=-V;d0!%)-ri(7 zE$um1^y8@2qeoiYmom~I3;3T6>Q0K$v-=>FvmTBv2e!eergnhc1)t;J$pD#{6 zw47wguyLo^>)M2KjaIK(FW2d<4VS52es-np)Bhab&fa|3!##ibjpv?kWuNaCwO0M_ zUAVuo_4&-ts`ryNE1e6u{v-eRK0W>OjD=F!@hs1R3}zht`(dL&jO~>m=g2B?mh3y; zx2w)_`=DzHBX@2;UTz17vM$7HOwl+H9 zM~?n(GI}s2=Gtt7fBw5p=j!a;8+5l$D?Z}BRuB7>s@~p}vil~6Uu*C2&Yhsd|4r+D z_37sP1J~~Dn!o$Z=A9Zz&9~0pySey>z8SyYOs;!MOSh#mq}^X~u)NwcHCR(JT`GxRY%p^ro)=|ZNv8*Ja)L^QeWaW-US9qG3Op{zo2bqGWSBktaq)igWM;- z{b+uaPiEn_U)D_3JHB7%KYK4}>4cr~kNgZ}#l^k8w0_?aXZCgVpQ1Cj<}Ot)GggW- zQr1gd*!KO?j$^tdvh1@uen{A6Gs^b{M({jT{%>?o>}t>I){;~DF?z){4*r!tzuQRa z-Qx2sE^s`4Z~||5>Vt#5mBLm@RTU>{WjL<=c=6rY^X;A;dm5IOeVs8W_12zS#{II^ zbvv16rOEYdU$N@C+@HkoH>$_9wI&^0x8+Ux`JCxo_FJ;7GrX2;by)W6-LKAn3N2I1 zYOigZ{ZVy(&z^PeB}Ht-@67G~I=WXMkz#+N+qB*4Hs3x4nMma~d%s%z7F+Z8^np36 z{m;n0PkK3bZSXqXWu`~>C22)wc4TijdLT~bnS=`4`st;i?ypvRuXT+(v!d$D z^^@8AH(DO4K6I=7zxJ|8|FbvDN%`|v{L^3W8&_;TJG_wZ{2jhwl|}lQnfK*8PsjXB z`8)YW=>5g#=GM#2nkrmBdE?ruN3#z%n(7NxWqw*BJ!MHY|F#45dRo_`%J;70zO*Cf zO$7h43mbpN+P~G_XM6C#wlwYc&Ck}zcFZ7cp{KHeqw z&HwOz*3-q)oAc{_ zObNXm{pL`@>=|GFOfcVfZb$Xqy!}r$7IWTz;M;L?W7Tbu-?!q6kG;2VElrI%a7ANJ z@#6j&TkF<+4_|ju{di)<|Bvkrh3TI^Cw`ds`NxAHee3GKdyiuaKb}t8dglMS zQ$ZC8ep06W!mqVvhOJ!}@l8mSo$t*REC1aQkN-E6vsL_fG9y4QH>s*`-s8B9y|(A> zC%lc4IeYfVC(rlKcFQ$2?icdUo%XvRYKP+A2yHK;=ckQ@r+caInY->B^QObcGtCwC zgC13_d#z?UzxBE7TS*J#PX3ze+{<1e zr+3=S%BSqZqt4iUUzYRc-PSS>kN<6H?_m|=z4M!Y?WLp5Nlpn-*O!_G3x`afaqImr zi5sousc-KmRsRdnJhgX5dF^YTzNNKE>0V-gu2klJoqQ?jjoIAe7JIBarhd*ncXqj+ zf#dTCRnr}>ro}Z)4nEtU`(IsMI>T(ocLVchJ6CLO4;A^bUcc)I|Gui%MaR;rDzDxT zRcBq@?DuvHC*RS&^u-&E-K6(rB>3MKJNHblef!5dS9a|^U4F$q{LaCgk9KF|+PPOB zoGaWAdfxH+vQL}WudA)`S8Toi=|orTQ90=?S4A(&NnPC;KG9bCt>KQX+i%>uyWwkm z>F-k~yLXmWADH)XLt=e$`n-epH+=iPAyf8pbM>)ZtBjQ5k{j%;#O` zyuSTX(N*Siw)+bwESI`geBRc-rMHu2su+uW|!gE#M;eV=*x<2S+1 zjgd^IH}^hyQF|%;y#Ipp*Gyw?e(RO>TOPf^bi;iKoBX${pS^m0yXIK=)v;$Ep?T*dl|$HfcgExNq@uTaXZmB#f{orma7mP`p3Lr>SUt(LDK^ z&&_vSYS|q5>)N9{`DiZR?DIP+jve`U?eUF=f40~kujk+PNBGMb=QneHUx>WxUTD~~ zI7edVg3HQtqn>WB{iT*HTAXMau-dNrTV~C-_ghan2PgIZm1+p_{=j&+NHWWPW1s2v zxqle8-4VGi8er2GD!=~HPNg6dy}!HIW>4*T_At%EX{VoRW%JP{`z`Nt<`mycSaU;z zFQ?Z2>x@V5Ro?}kR-d!kdc`$01LMgalB>^6pR#7vKQZwmUD~rv-Ot^yJbUb6%>8EP zjTPUoq&>c4#je7ga`n`_b30rto^eY3vbw!AEXYL9%(|>BZbLW2wM^;#lMUaA{f^!D z?a_hG_iwG=@NKNvEoYI~Fuyz^=ZapjO`*8h-nlnIk}P8xm5lEtZCQMr|7}O^+l>_~ zf@}GW_OYk`$(a`a?c>7*yh#ru7L{Mv%fI^TgO>v0e5t>C*3G%G`-p47ljgZ!JC27} z`((QBI?ZNT=I-J0&9~kEv*7xxYI(`K&yD>HV%7m31 z@4nAEkoI`}R!;K8 zw(RKAvI^;3_Rab8?jH~mc&~otB8%U-$8Va~{kSFmpYch8>xY5^ayrlXUfoDuYWu5v zt>JC)%l}xH&+xar{_cpOnt5qv{)V&izlG!HGyiMc@%)eQpHq_cM@r5W+THfLHT}m? z5B~2?&XR1jehht|M@lNNIdKHg2>c@Yl~O494XrW@y5o7JD(n{`L=%< z_+&`mx%GNoeRJ(Rc3OX0+3>jiagh5hyA4Sv<)_+3^I!O8+wy%q=UL6?KmRt?d= zzU21y$q`r6>HW={n{KH+i#tC3=U3Jn2Y6>q>~HLR`lHwU&s=uL%*XbJWrgLBEjnKE zC(%7SZpX&%!{=XKzQNG6v;Ss)ajtC2*RYL^+yBMgR-L|-rS@pync4NlM_P}4FJ{!+ zC$7C=&HCqji`6Uj`{g^TlcJSt=IGA(DLpSZU;F5fwD2=g)mOOnj?d~nD;&1z&e;JClW{=N7)yRJZ?Wdtc|z5=a{~J%^C9Uo#$)WYY${afA7-^IpJ>eTu?H2&H)r%-zZb@|)c&)KB@%vf5yvO2Zs=}x=H*6(~Ky)K)%A^n{G@eKww zwtM%!-7_V z^9yCHT{rY88b5y9Gy9M@uK;VZ@STskH}~-+&)*to|F-*V-HQY1!d^OGCO%Z(x23;h z*Tt5^kc^y;)7fF#$+vUz8vFRm`mWvh+WP*^`<%s-Ur$rhySPs}`+0>y;^PmoHMQn( zzfZBhJW%eF+qKZ%c$pg4lUqO7<(|b}$&R0%DY^0#pZ|NXH4 z`N>;$pAXgCesT9^>8-i%PtLTsG5@2){NGCh?x(-?yKAiW)zVP?zOmVlBKz9VvSV7) zZ_T}Nx$pkI)w-=-doDLUex6ctwf5cL&7wbQ3Vxoy_C5dOy=Lv@-aD^+eAL`FZ?@Q6 zhj;8R|1PLnUvK-v?oinEfAb#1)*V~B?(cuy2+_|)LgjO7kKIvUUOuOu?{vt!U;iWS z)N{N(y7lwE^MO~QiepYKbMr5bxw*IBUTmFP*~Y&=uIrXt=6K0mKQUo#&Y$vMjPK3u z3s~1px4fGq+}z%}g*&}-&10ojDSO|T#p*I*xwQf z`CZ!B-?eXK+HlQtYWxrTpH|T>llJdUi|?O2_w}(GjD9MU>f{Ps6B7RkFYYcm`riCN z^tl+*H2EW`|F-dNTpzJl_M%OdSHH`L&$(-~jD&COc$*l1cjkM+q~$9wcK%l1z2xeD>tg!^$kdH{a&YDYy0Czb8?n&qlvFHCa z^<|l5K$!7+-k0Tfn6)>3_|0McedA-pO7-UnPb*$tb66>``EAeLo%!*zukv4uJ8t^p z7sGV%7>CT}x`K-<&jt5Cc(fv7F;CsmS?vF8Zb)y~@-4dg&7IR0ced><-CB6*CspE2Hi#=P8uHW|}bK3VG_mftOp86GcyE!&s z@nU9+{in_e{J%I$zfPyK;#2NDv)a2R-)fF6|GGV1W|i;rk2^ExR=)9^b+Y`p_g-@) z(S^r2z20y1vEe`K&Zz5OVO??T*!Q31uOHp&E@GG4&+(uq`rfC@>uXj@Zjq9fjW_N; zS^8zu$t`{hQ@u}by&K0UE$_SSh5PQueFwiMoKfL$LCDC8PHyq%+S;tY4JLjjF*Y*36@2{;kTfWZd7k63FyXF60 zHP@`;pKE;n!RzgNpX>MCjGAAyL?gS-U3~VM`K_)i*be=_;aOX$l>hox;{SE=5o!vP zKV&`LW2XP7qTec|;l)zZ>sse-ym+O&aAndu$D@h$ed2Ku>mpt_-84?Pw{`!$-|zQy z&Wz$UyCD8%x_-Qmwc)Y<2|pjMQRRyB>%D#N!TGcLtHF)duvh!l1=x%1+=Ii9=SWeVtD%>xwU48u(bB=}lnWy&)?67`2Dl*{5k&G=c2R!q)hs% zvBccsS#3pZn3SZy#Y0_{=tDgKE6qiaRaec9^c;xzjZL@rJ(q_otpe z{n7f_R*xZRbD;7X^ZU)bDH~2+UHQO2#`yT>XQ_{V?f+rbarmZQ;lbwJiBml+|LcXv z%AY8TYj(-`aCyg(W0B9kcfXF*G26ZO;3Taz28Os`8wV^?Z*2o^HqiwJW*=_afuDCg>JZd*C*joPAG5d3Fht{;~kKgaFFRW3zFe|@uqkpsTk28jIp8v5s zZol*DI=hOXHrag@OWVGz^ncxJyYJzYij~5TADr89^w}+e{~y@o`Fh{)U{Aj?J)8Mi z)7!@%X8mu!-p2g;=Ow$3Re6W?pGWq&M?E?e`37pId+9Sx^7w z+Q0X&pPBq5-eiCGbT+hIhW+~M za-HvHpJ&hc|KsuM*X}%z{%(8Zwm(qv7 zZ++OM6#qe{x%k{l-?#RMs_ORJ6il1^$jCiuk~-SiznkGDKr7&Je@ zQf}X?iUyS(a^64cvRt0;zP_@+F6-$Ii4S*I+@5^;=ufYWwLEGMuVioNxOFC+@$5|5 zmj_y_c}{*ledXpK25;AzXT1CJPE@U%!gpK7d$V0u#`cph*G#?6wy|3@{@#b{YKDh0 zm6nBF*;#0MY+m?t&gf4IuZHJd+k5Vb4zs-X(Iob3-@XaRzxmH0mhrb@jZ9?l{>pWq znzwzfX|KQS`F>gK`qHZg#gmJ3J_)7EHt+vGtzDV1WVWYieT|P@{QkPDyZ)?_TDnjB z{-Ima!7`Qt-|MTEs>NM4cAq1*S1mUC5tsSxf^)Nuw3qHXfAe|Y=k1?z7VxGXko~dd zw0cfXSLXl45yhe%`_>;*{dRr*|Kh(jwwDbz&f0NSCo=wL)cJMpucu~b=6dkuJaZ3J zTzhTD%IItE&osWS>h0aUx$A1Oyw1Pxh84$)=J>1=E|2GKKHBhl=K0d@+lyX)*tada zB z<-Yg-IhlCFUfnJIu^aA`XY@V0b->c__^W5HGve6!dYr!V>}k0=>D|WrzyF1=YySNP zbaT6W%)d!S|6?Y|&6uN6#CEOIg*{BZ=Em-G>ihqOs|(jY4VgW|w($qc!JU2UOC6XV zMXUGdTWT6CGkta_`SA2dzgpJc+r=#HZ@%X5!_5&7EjtT>N~~TzUy^C`$-BC5wRyJi zbos7BUj?m;N}lYp)Lysm-{Rlxy{Rp|huzMV`7P?dVP9(eu=rVj!qfP|{T$lgRbKQR zXh}P7x!V1ZcnIjzhUNi@ijGK-eGroZgZB#73N3e)s!}U>pd?RK3yVl zMz*-jG=}i(H(W9K@djT$1es^oCN#|5yy(J(3oKRdOpeXhH##-7X5~)3>_c42vf|uQ ziND`0iYPc*Jn`dU=H$(G2WJ}VeJQH=sV&d4xA7qVasIL`sgv(|#5nVEde7Un^Xu%S z&Z5UmdSA`lv$%rnDpMb>5bE>JiItcdlE)MxdhgB23Hs*C+u8ptYqR+B=hZQ>Ui~A@ zjNR|6ji){8^xsg){K+=LT}*6$ocyVoJ5ziu+-K}PBKz-|@0n*hOj%D}@8{i8QJyE_ zTRQcIevs$d23Y$OaF|fPUx%Ah}`!+ig+BTk-Zc3Pa_@R>X(MP^-yIxyZ z@m+7MaD8xGEzR}L%y^6Foc+?__2sa$0QSsq|B+S8 zaah{4=E3&-j??`bH!k`~hIFOIYHRy#y4@CWB4xU%_q|*5%Z{&my?`@s%~|h+iXRmd z!fPJbFFzF{-Ql^XT6tUHC)U1j3vIFMQy=c$Ak?C}=kRfhr@!p)tyrkqvrB)Ep`7$1 zx1QFP%NFT{`=Sa{pH$u1ui6x#%7-~3Va z?16B+#7W1;D?b+3`LC^-cXgry^M>Moj0!o0JIaIiTb#G-{%oBc>Fx5N;Mo-ZV^h5* z_C`mX6+F|``s9#M)OvTFIeE6<+P*zPx!%TFI;xeVeP+;wKFXD zyFdRK=<}cJtIC_2?%xcjTQ?Zaoo&D!ZL@dQ<4x<1+(_R+ADXMr z%d573+&aG3RXr`!!P>ztX*{5!tx`HG3L{i-dOb*4{Szvg*C*}hFXW2E1( zDojh1TEhKcE5|#*(>ooGd*uCjDAThy-V>IuYZ|rJ6 zpKy5lp6XuJiTRqVDytUGLS*-^iY0rX~Aa zv*>K4+18^^%+F2bkEl5se@*JR{_~2;i`A{fB)Fj$X7hy>Lcs!$gebAS8iwi zKMK5zEqm$ze+R5Y{yyDoXCT`kGtF*)#vA4d%CbB2UTl0eyLSJTwQYOLrtw;vY$(du zSte_k-Zp2+gtMNF(zRP$=Ru}*MV}J4H_KVEsSz&c@-1eV7 zZ8>{+*^gIG(*JS=r@lMgD?mk;n z`mZ{fOH<*_2`eURe%|{Bt5h0#N(@iBO2{vEe{=NP0~Xo%7eB+^&*<41sj|(gN}u!W z{_ol*X@8QIi|?s5e*a_Q(fXS2mnVPdj<*ojFu(L{!Hs7Vvo|xVuzI%p@7&dI^yg$_ zZOp2~d1?I{PU+2!v(-B{zh>9B)9p4-qMtqPJ@=zldCBdH-$&~$Rg(_!8d>L9%1xgy zxL?9G@8gYGwtJo*J7{B2-7I_lG9%BlpK}h|nA-BJ|76i;%db;;xNQyN&X-s3xo(^L z)?($Kd-u)S-rY?$$#&+qjy`>>>g{Qxt>=3GG5XB&3zyz{!}#33R{5Nu=3CqTGkjR2 z-Z@2bVv)#9NHnE*eJ+InWIk)TS zGGR&SKK)};1Eb?^Rrs3enQf8%ys3M2rQ~|qeM(!N=J3_D&$xI+xLkR4$FKhzzMH+8 z`1shQZ@293|God=*7I(2C1#JHrSs-(Oh5N-Gp{GhjG2NznHy53dfokc_Lk#g_Oj#t ze9FOrl?vP6o9{7sd)z+lo96wU_dFNnuMhlqtLL+b)>gq~`xy=_xc>cEy!igB=F#`N zD<3vLHfuM`ZWn)ZCGASA`I+5|<2M|tUsnHv`GRF-^Y)rYRkL$+mRen(c58Zb@!GXD zx?*3pMketee9`{tkK&rf2kkD;XP&#V)o$Of`4-DR#6SD)eTL)1MYTN})+jwYlOMFQ z{oHHMXD>cnGSfb{JYgwcs;@=;7KL4Qx%zuIe))B zd)9KAyVs6`YRA?60xiC&vFMy^D9lwX2-X)ZG~++=U}Hw_o73NT4S(n!H;dnDI639| z^t)BQvuY$-m2711D4Vi8{Ipo{d);px)on9m&)d2$3)?N9;D4pmZbqz9&7Qwa+03u% z?;A|#TyMWyoU`nx*_>We_K;8`m3!jX%B*S*h8gaC9-i{N^x~!ZgV&xfc@%u@-ThxV z4J=Q!4;-y*zws^oX7&xKl)W!}Ha$5pyWQ&f&dB?f%Vha>y`Pn{SK>v=^Xe({+e@1g zqOO(fXxtN>%#pHzd;i<+{cp_K-`q2J)1A5h=OgKD)3?12c$6XWBHc1=f7$uAbmMxt z_#J5vW#6QC)Gp}S|7~Yj%sxip#?W*1uuVitWcv_`Q~Wl#>L+)1*(;Q zv#p-Ua^v|Sg9YN#&YoD_wn4kBzR4l!^^2Vo{&shBv}GNP%9;J|nd&W>_pR)|8Kro7 z_f>3US;|*)Ro-yBWxAh0qBhTbiy!a*iGAQtTB!2uhpc}7esiAVFYfD{U!To4?agw# zf=g$1G)#1IlP3kxP{hlVDx&7{^+uqvmQk8K1ww&y-bQQO&=De$?<>?5=G$x3FX75C?8*Im1F zg{k26)m>%(F1)QhVA)$$efEO?+Il(d`p7jax98ofxzzYAdB5ka3mf;D*OfT&`zNo{ zeg0z6wR=~;w%N<4_5E8KAEVO#;vma<9q)vCnGWF?yHvrrXR}TmwB6Wy++%r!j{ZF1 z%^N-MSLE26?)Y?a|NO)IlF$Dtn6k)!?TX{eW6Z^7`$r`GY3Y^eaXYj2wX5z$h5r0c z&v}!6{W^Ti;>a<_L-Ri_3A>-z?Ro#s7ftQjSN8ciN7rYT9*BSB`CfcmAHPmwa5BHl zg|FOZ6_1X&@yKyyR;~9;+Wv1RKclq0MBD+RngmgX`6bKV+WtA<XzPh4$@AcjL z7{AF*3s@0Yv7Nt3U^S25nN3I4AC<4&uxzIH^|}8q?QNNHMqYh?@6@|9#ZT?1?biJ| zX-}olynPufr_pc9aX&3`77sbp_}>lHycl@?v`p? zX}e){0FJf45l9-e&RA zdviV~YfJCFXm$Sk6LvGRe4VXT3m%GXtT%ZUytMMH(EPeyvwgA*ZAu;{(*i=ScWr*s z>tXcQBrlrFB(XF3QS^-N)VZ5iK4LxXenx)7&VB4ocVB()j5QTop8OnEe`Ojq0Z9lV>doAbJUfg^ASIn2AyUc7f8W*2C z6r}aX%&nxI+xqsa%q!d8?0)ik*6wqY*ISl7*=*+$pd((f&irVe{f}Dnq%V6N_x-fh z?RnB|ll!}RasAx?H^JrC{Md*8CI0VQv7z&Z*Z-$y=jvX0yqxzdr?t3s?5YH#iAi^* zr9^ID>9M-fSHJpbPky-VcTvv+O}_H-bvK-sb|);(;;%n$RQP(Qewj^z-|9Vo+B6B`ENC;btNK4%)1OX*ED>{ z=Xw79tb>|lw%#qq-%h}K^ zltr7{o2|uZ++zREMfg+@vvF-;~CI(kggv{_3k=C1WDXRC4U;*a?GPfnVtz$a_H_Lms*-!Gjf`};V)u-F&8R@N}&qG3sZyQ^_l7VY|ZOKkVfW4St(4Ns#k#mF44*d5C(C?#ilFXm$4^WL*bviF`( zz3l$H>g)Nn({?7WKHDZ)x$$iIY?(F1u~O%3<0n2n%Jq85??X>MRWWb0eRQ(7`256I zPu;?czwYm3wg0|IbNwAZ5OZW*`-^D?D!SK zYGW;F5bc(XOc)WLlQ%;$R{mIZ@`&X%)bFKX19Rdpbuh_QeZedtEHF=N0(-U67 zulL@6BF1y}P?CquWhcR5j^(DVR%9GkTFxw_4n92V+P$G3gzkg3~vHSBwv z-PA89(;c{=>`41wm zaTk_72YmOTBTcb%r5Zju%^Q#O91jiL`Nwj9J>N9* z6F=l*0>+TsD49m6m>7RSMy`smn1Ow zwxv^(KWE~}>h*@nC2<$HYd${gdw1&OiRwP9Q@OFm?(;WVWXkqzyZ%6^{F(WWQ>U|& zSJ^&USy&VP{HDOy@*6jv-mrYMX3o|8*py!D^yvS^H+t2tANhOaUQEaTYXUm}_AxRVTd6;<;9ca$w(e-Cc*xZ`P5oZ2_m&8(t53q)tN&TAdEA_l=s7)1=P`TT)9ky&liAphuX4V|{xK%5I4QVhO6mIv zS6e!Jz9vV1~~zuz-+^9c6v7ya2&7s=dy zmTd1ni}9&PN~ng`pWpuR0fGJ1^6F{(I-WZnzEc$<-~4Hrd%4t|;!nEU*x08u7CX7G zS$!;HcD_#W9kadflb=_dQnY*ibk5_7$ERZdCB0TJGW0o9&+@uyjZki0h3D6QQysRf zQ`*>HXa7uP+Lf7+%Fl$&CHAE(d6?<0&snjB(^HCHO5q0c=LHeny{pAC#Et#GrUeA?x$K$M6c@MuNX+T^N2l$cbL5!ttLawDB2JgvE;Wxc`(S!K zs^skz_D{LNYn}#Lt^ZSL|JmfkO2zLt&xZaz8QCnKSh%q^Z+}_OK08x8%e9tsjxv8a zGuhuleA~ylGmaHpyd~pxegm)I#Py+z_h%=c4z$~-XkjL-yW{+MN96ixVL83hRU}e9#|cmQF$yqmh(ounc2Q$MIL8=y#5d#`rx|s z^!m`H|9S22eE6$2zl=BD56v^X4eyem?zP}|{@WyZ3Xt4<_|@XY3RIy}sTnZQijt_RjH_12+7AE&Thg-uJy?Ie)*d zoVee?AZW?;0^av`tX$+Dna+?;)?Zqz=-z2$zRr(F?%%pShF9lbPYo7ZR`u)oU!Gfv zseF%Bi%n<6eO~i=VcT2vICkBb#}2-=D;eZNAK$6WELku~(dSI?QZ4p;zR7JrkHq+A zGp5)*X5GDcU;E~HhgItNbrv3Jdc00FvF=dS-C}`-UmqVg?l{9Ht-WynWoy>NZFj%d z)yr8YYS_CzeQjr|#%&=I%ll#N`pefooN!=d+uka_Vb2j3Uol)2KUb(kg#C8$@978mH!eHzYii<-Q#WU%JbqSV8kHX< zwZK94kgbQp`(AH>whPZ3reD4B%OdRkVpb!)=ksKLf7h6mDiyzK_S_qLKhHbyi2rxx z{;hSYfjM*4{hYeiynSryp7q$HBPN^YsFn7#e{Y&YB~F`Fd=!b^bxv7R>UsIhWA~pW z^h~UaTI>2cF}d>e>(ACQ-|SnD+HYgA-zceWS^Z6!{o^V>W?d_rXBQ57dFXs&Y>B^o z(fi)7`$pbOB^~$oO>8$~d%=HA+Av|aOL^?`>D>Z9tfuVY6Z3wv{xSQty4B6ag^!c> zbEcWLXIjT~$K9Ciz+nAMJuEvuer0FU)z5Yx-&I-@xzjNz59i;HC>w>`0`RIX2c_)*<2aMjf7ABD8-HEIHK zvm4ePx9Z7R$tGOG>!*7^qHwmH{pE^g^ZhZm);yN~E!$x*r!3At-spS&nsd|dMIN%Y zl%Ly?+u5-33!~SB{LMdnFCMQ=o%mns-%ChaKJL-~hURx#WxMk%Hct-w-`oEvp#G5F z-+R~YUTGIy!?8nsS#EarDi8hY;({^*|HyUb^a}z zbJq6r!cW;YUkm)Z)4$@M-tXq;kMGop-22+lpUQMUwg1tc18;r59C4k)Y^S)sLoEN! z6UFBTlxyZ(TlceQ{;x|%X4_}}UsU)ep*#BG2F`t3)~et69Ps&Q5zCLfbEnzftUNl& zzU{x5nVejW-A})NTS{!-$X6O_dSsowb0Ke{6}#AZM%@=ltE_J{)*m`%#`9e@XGAmo$Qc(Coy>UYstgun|m4WyI{o)Y?OWw^)9K8W7tB-L{kuQ3)faRUEtNoE9Ul(7q_}4Wz zp;EDd{Y)@My@6=A4TQ%j(k@jCte!l#7KZ5XIj3$^MSWuY6=1cs%K$RsEC|`)()a)IQ`6m)&;Tj<2XDdH?3yGmcmMd^^uM zzA$(Dx=oiSU+unYtah2{Zj(cj__hws^*{0RmO^{P>|>IppW~7gVG;dpPKE69i}8Hw)AeTw)_e%RoU}Pl_`XZ#8}YZM!-*==MwQ)NNt-@ji=#A!HJ9N{JpVRxc z^Vqknk1huhJ(*(N$<|6jGVbn3bKKWcCLK>n2&jp z_V2mNBkO~H`P;NJ)ZV|M$cu_YEp2#J16G$`)`uF1=QUC^s=s8B|3Yv zT&KBw?~6EtQ$N{mRBAQJNgubcG*Lgj^s%zeGfj`O-gk=A|JnCl?VVe{;L$eDPm0dF zpHA-2IbojB*L5!K<@x1Fs@hV^Hn&>_8ZR?jwA0f4hwL_Qg<`?g>srtG+Z3qmJ7#OA zT6w$j?i7g`w~xmCd-b9F-(9W#^N%*{`m*(>rOu9Lv;I93X8UnSzP|JKYQ3`aJM5Eh zwpV_8eTPf+)@PP(hUPmev}l^z(g<*6NEW?ckI7qb}Z`a9Ra?87sq#goL|Em9pqdo{br&>!cp=0W)AYFk9>Dv zJAUz@Tz^~5U2f~;M=c*MtGVOb;+z*R)AZ&KC(l3Exwr0AaQ*9O4fcCm{`p4u-v{MM z%Qi>-tJh+O#s1MwMDsCmUMq zv;3%Xy|7{J>p!j_?e%-X|RgO2&czo#R*05`dJ8n6f??`?=W4fU;`&ow* z*X=JhuiCgggij**c<{YnN7NoJ@;nfIJ^je51vh`Ohn@4cZ4>{UFTL@WdL82uS-!bO z+j@O;)<-(|t~0j#Ic>$KdF$_)-m3aIZ_kF?yIMD&a?N`qeEo*SG4W}dEI~P+Hy-$D zvhqevwaD@PCAt5tzh68kSZsf!^jR%O)bU?sM{1uJJJT)EGFaqj=tal5yEKIxjAGb{U>^QXUj**_o1ZC&8^>t_D7 zM_pF}-ip0Dv6g8&Z`vPD?*k7`_Er4+c-4{R;nNor*P7)oxw^4`-L*@`{Bu;7W!r9X z_|kkW!-DPmzjW88ySont2(F0Vr~9Myhqu;;*S)9rFFEs{Q$6R+&AL~g0^aJT7rj0kL##Pcm{ ztL0&#+cJhe()_lqo4CGT6~Df(=sVY^SnUH_HJ8;stykS<7ybCyrS7EUohO$IY`gs7 z760Xs`<+r{&lp#z8yY`pkKE7fxG>=C;nX>{8|@CS_7HN~!Naq_@VT3cp2b(;-vD9k0HkZcsy~s|#E)yX8yhmtKXqa7m zfx@ATTOX|pd6o8@KKCq;P5xT0L&X}As=UeZ2{rJ>37yUSXG8vs|O=q_0(@)i@xVK|kxO2XIz>o4b zy_45u);Z_xo@K+w1ysKQ34r z_CBiS6!-j-lAn|IY=2%adtP5iD%zs_%y|pT<`tD{8t;P}_e3w1&ir&#=H!GvcF&}z zdWWX3zE~c&{P+uNoocqZ_Js+%IYX06&dEpp+^y1gYJ+ulcmdv$0xw3N22HwR* zzAei(K9??LU{71+Tr>6K?9VZe*Pm-VA*w&=XYlSl`D*ipr+c4W$mA$_P9*1}QtaVn zhKmy752e0ac;$AIQ)P6mo&1}FJQJV4c(Ub2zoH%Uvh#OVfA{rXmtwyC)a&oU+p>d? z9i6pW@}#TxN&Ow$&d-RsQ~D*b<-O-)!~L80^%R_uQ8RCOaH~hWs$$QjRre>yRKHf> zUT~e^k;mS)eGz94+-W&%@-OQ7rTI5{vK1E3y?oBGxb0W!N?U8bg4z?t7PI~t8$EEn zwA0Emao>R#A0z(+&HPcDXK_euyQ%cyTi>h1CwVpA-B|kgZn22t(ce0cSxb*_-THgt zyp6xn@j0f}p7;H&)t=uH`Mu(@%ZGh@lZ?)b$MHS7yWeBkgs)qh_lf?SHO+bU4Ev0F zjjAg@+ouJUoikC%-(RU1dGxIDE$IuguFbP`YS+$XoZeioJ=65*Esr1De;)nvu5Q^&8|_UG&q+_2;pv-uxVPbiK-|9Hcc$N1F4_g5B)xHe&^q}%=@OFUscB){db#s`E$+0*M?KqME(+SPL3#;zt42n(*^6w z^;@}Jp7dn!{+GS{t=6)+QrECv$}Sz2R3%h{w(X!Gt0v8-Z}M%KYz38Ygy~| z7XG|`{ZD!Io1=%f_kH)9`T6&S!k0Jm5{ge--VS1$cx6-iy?L80cSrJ{lCH3{@7nOQ zEywBSX1#3%!p-^&lYS=_{#>8G;M@HLVf8r=TBphP_RHKpJl9a^we+T{bCVy(cc}8k zKB;>#eUIH1|F1VJ7nkQ&J1$k*`)mIXCH>@QCw|<@eWN|^M@)plCd;&AN;w-ZhH8Hi z)xU5m!!B2fRzgkb$mfXg@J4fcdmHi8yp5iL@(-B+dfBXM2THu{}j635x ztM79>7yHe03uc}xwYb9V@y^rg8nr>+zb4-H&AxZ!;$<82SEo}iSZ?HG z_kMTqlm5THt!!U;x9z*Ae7%2T&(WJT6SlI=xV7?`P=)0N!!?Ds3-~nFoUQzS*<4xX zcZEg7&(~3fv2Dj=|KxeDJewZBIQB-D@cTJyk1Ad7KlW3v|L~ThcWezAnh!bqU0KnY zd_HrP&}NTyd%o_ylWce}BJL@lTiW{y{qIK<9gCj63KVK-NWOccsO;$+YqOhX$NbHv z@qTU2E?B(j=JcJGEl-M)-F)uUJ)UIs>i63C3-WyaZ~TABC#}-?_WeiM9o2vb_Y>ud zifm_Cdw7;TsMfKbEA^8p|IXp_OYIixt-SR%)8UwZF5ih}i(b9QZ^b7U*%cN)n=||T zvHC4y;ZILhyp7c7Te;4z%+%iSM*KBVvHnV?GyOSP_w91NbMVdmdEYPf+p({6_#LIK zL-=ccuA8l|ydn2LpBUd`?{BZ9^&h?6oVLGJw=KgquJG{2pZw`UuU?Ap-+spb{li1S zPghMnDH{oS>%qOaJbvh}UL*a|IX{8?QgcGCL#8mXIiTl)H0tvAIt+wTWA zsy}D{d0(B7U-|uSLs#$0_4fp-6+b<@;(X*^uSv}9ZEL1B&V8FB`ssU`-m<^aw{7=r zOna)I)w#U>oB@mbcH8cj_3pEyOy*5qFT8i!(W`vEn^(R0AM&QNRBho-6YK83>8__7 z)So=`+WNxu&!uG1Gj$68j5n-VC|th0;L}f`YaHil8s^5_N^Y_<51o5PN^XVqG`u=DA|IQ0UIxAh*DgG(AbYRQX{9os9+_Lg_7M7o} zX7<<47Q? zyP994xafKElI4Dt6?cBJ{TB_tC#_%Ik?ZnV>hy)D(?idfExUNuX=3gBTQCj8m(?{Mpm{8tNC{m+bt&8RO5PBdtQdCsmLKYx=D0R zZIx~RCBy8THNRTg5_nn!p0B$v``%LSv;JL|S0Qg}v&4_zznWcH?(;;otMiqySodLd zVXuSk?!l8hc~%tJmaVVQPM4M1zs}m?|K5l=_exv&oJ$AS8Y>;kJicAFKhEm(L1Bm4 zmv=sRWo2IQ`S~)FB(}NJtZZr)ORf6jxoPXS=YM~Ev9UQ{vB#~gF++TnGw%A z&edHtpKorr%zCv-;+qNLpBG!@$36?66WqP_c5==8;@R9HF$aF!Gn+hXw{Cq>b@9)r z^}Y8W|2VU{Z_1DD8;|c#E?X-4`wz1lm(1Uv!Ec_f+3~LVZus$*O0`Kh9K-$Jn|eO@ zA^-akUjlEJ>y}zMA4{=ihx0dHf3QmIdOpD^?@Ekw9{e5esa#QWW zX^-!=ud-nL{P#dPZ)5F`ITljYU+iWb|60HICGWm(Zyhhllrsx_uXGN1+#X-He!Xm= zu*bE~8P869);e|do@vag_`~}bfU_cZ*Pr*hE`0kW-Cuh^XTJHGb!_RzzmgX6o^`wI z=3ZaIda+pdndj~M@#dr9|-;d#*H=SkYo;pj(n#UVA zIhC+61l@ito_9Rw)_x{$kK#bT3S)WebGGwlY_v6f<+<+IsXuIdQ})agH97F9r|3^g zbN{rW+wYJxIk86m#O32xxQpAifBx~?>bjBT@79eUot3`!Z+H_~)Y+?4m3aS!tnp*> z?aj9Anf||c>>?k3kdRe5&>iY2bHjX__|%K;Zvrbf?9|_5C+(lLV|})`_}!UnHtb7s z+wu0n+n?7A*X193@_O;{gMWC;Wc=66P?!DnqV3w%aq^!sLn~=_oMue{UJ5K z<)Nhgvs=b8$~m0HU+%dV_wO~F zKaqXkxl&)1PQwC)v{zdx=2y9hhe!F+aM+-LRq;r(|Cugv}ROs3|(fae+hxd)veNIw!(k>3A6Zf16lQeD><~li^L_JFce`MX|j(=)|0D=6d&@rO5}uYJPi8y@cL>vN>sg)SkY*>~!k5 z_L7QHADJoVTcgBRC{4Qc-`6osZAUP#U%Z27U;av)&H9t4C7tlwUb{=|nu?i5)9n}D zH5(3#o&A2}{U_c(k^DIi?eCpaxb`(RM|p0*wuv4qJa+t8&aug?%#Z)dV;1e*Y|A$W zN6HDKW_}aR=D&LFj1K$j*)q;Mo+Yva#^oPEbH?OyqR`aU_C`w8_=!X1CM&iH>;?avGLb4gZqpOuB%9rkj3 zyDD?O;6Q7y<*{$~4?g1B_s4A4{F@mJpPc?w{C*(r`^fjqM#F@HC(LH^iw^DMjoC1X z3JczTQFvG2!X>QmSJpLc)XjxRpE`}f|hH~Sr) zxboTAmu@fq?|3^e>r1p@df$ns!K?efZ0yKoSX=(3VC%Ki(@~Nst@Dx%)?KfEK3P0& z{_Tq!>-b*P8~?YCIR4>a{_{^OU)|aNU9j@}z7K3+d3S=VYs0wK)LZ;tRh0_3bC}{ti+6haLM8s~6p> zR(#GWrazr?{iF}JGFO&u?UH?7v1>)2*|v)4N&4TCBYrDS2z-0H+D?SIcH@H&vVT%H z-aq)iZj_H=3Mfk#E!S8%`WT0J>i2tll2Sv{9gaw zHSPSvs?rl1H?REW@=W>IkB4*q7o1)z^J@Khi_E)w!lv~XC^TsAE6U&D)_FN}w^M(U zrrD|IRv%@2|J*jO`#g6Z%lFdb+x%jxw#p}6yx%JSTl3bj$b$#<=GO&3h}aP({CRDE z!aS9tvM-<8z9q=9n8)pC>W-bz9BFu6edE@@iaE=6i_8mF*GX!(m-=m;eDt+vUE@;z zWjFp@ZSm#*X6^IZ)VA`Z$=#y{QJS~s-#;?j^sdy8tyfQ1Ja@2IYiu}wzmCJY2HDR= zUyd~`zgv^c^X_%sj*sk9A4~tg(P6@b_==k7qxGzO!upc;osz>zu!Sm(o_|{(cszSJiL2^~>D0 zTYC$q{(trV57(cn$Dhux|5$&<**t`EXUpcwA0L-KeB-ySRrz{b_HVv^Ih&d--`jM~ znQg9~Z}#IyPwV@F(=GP7MK0QUdTMD3X%$XWyV+PSzY>;C;(B!~dhb)EoI7ogqvN+E z*jnxUXQ(67m6rAC_a8Rx4Qwo@f95`Y(%bpDq4(A@s~tXe5+yaK7ntg}M{cyV;#l_g z_{NG%-?VuvD_u^%f5CD1+Y)1ol)3ib{Yonq7VOQtc%u7%M$+RNBleOS)9bMxdUf~h z)sy>lb^NdQn>jg`@Ytg7r|PtS@mz{=UKj%S;F>v;ckgI zj!%p9m)sByHhW)eUHj|VWcHN($+v#&6AZs^{VwTZ=)R4;58ZG4>OFgQYs8|}=Qe+t zyp_rQw}0|v<2`BimA7Z|_5S{~c1>}pH^&dhcS}}T7#-rq9Y^?mTm$zEj#x=Io22t4m%leR-==FuhAnt*GXA>(|z`Cy%kY?>k%hbAIWE zt>@Nhw6FIy`gGF1`_mJjxl89qndN-8w%}X!Gm_zov5|~n>z*CLuXRldud9Ew$ow*Y zqtAt(_b(}`h83(&+dk>-jCeIW+lb={+lvj1**%het4**df39(2%8tyC4LAPopSw#g ztoNSVfv|In^WP*+>7BIcOx3+NzScJi>z*xl_{zSz@c(6wEBtGmKHMqxZ>lLe*!OJC zE;Z@*Myux8eU`g(@Q~%6{QYU$qj`k#*IiG_{<~Sx@63&x>4l9-bzAlr{yTH^<3#;C z&5Mb7d~u=&vJ1; zchU6TkL|atzEnKkeSX*d#J_4E%0y?aJUVB^XZ@_|tXChxxBNb`)F$OpjNR3nnt@r8 zmd{RJtmy5&d#6^{!E#`wjT2x_SG^)mbjMo%_4*)w#{ZPiJ~| zSueLUWxa7^+uyjl$DNrEON}C2`E(e4&it5{-Tox)>Q2GS$7?q9*XZldnZLn8Z{9`? z%UkM;*RS2$@yz{3u(r(R_riWVm`i-tO+WX3SK*T5rLR15oE3U?+n5ix)Mks`f2f)F zIltyfyX)5l)8aQqL`-Kq-g#4be*H1E??r8vhTnHCu$p{k;m4w1*Cyw$YpqhE{E>*1aq->$FUdMSRktp4MqTh)Cff0y}J26KM-TA94x%0_mLzL&?m zwG~UgUYC>H`ib2%sUW8-yZ=}C@7It~-VT|5#hBulMOI=6BXQ+j_-y*4FJmDrEeB-%<6Py!qPTyr_Aip^(jYlAf> z|1NvGa%*hc_r_M4HP5!bzWMQC@XnhRDXUdPh`KniY{j+rb zyK7!^?lynZWfFD{mhYJVY({5=C#j_Gr4xE0_-0nr=5?OzVOCOZGi;;yKlrJpX^CEC!OWF zE_?BR=ckwTbIj+-C+>e#$L;O+n1U5g05{LIzvqIr1{+x@*$EO-58 zw6Xv2pF^8pJ#2l=QP;N*m**$<@Mi_?Pxv@-Mse-_8!rz0cKw)ezV>Lu%ZTt*Q$HV? zpYX5b!WrIAzy9_o9=*BM@lUViPZfX9K+F42Y`z;Geg0eWw}67-<&J1siz6ll(zDIk zFNmusYp`)Yd&a%5+8{q>SJ?6O4aXju>h7DlSUgNZ>W9g*IfCp-Jtn1Wr)ByOh|UzvA?FPwxxbyzY(p^@Q^i3wN3~Oqiw2{`^UV#lpDQ=~jyKu1QKC z54ZmE;n9{&y;EmoZ<(*1oxJsJ?kSXr0+PNw$U_ukefnU488Y~3fH zQGT{ja{BVa<}34cN`D`>|L1MLzO*!8R9#G5GWZO=b*Zf8+)`aBQzoypIn7R<5V z`XjCG$Hs1-5F>f9W0XyjfSeHuz5E+<7y8%k;$> zKK*g^e<^tJMtu0|{~hYNUw1YXTs+%5)pyD1KmUKl&+^TW%9~fb^4PszKWX`$`YQW4 zo*v{}bN_~*zjsr+mi9f`;PUUqx_tvmG2_w9_g<`sHwTlW7|-t)~evF@XGqy9Bv z{eO4=+3~0DYEX6E<8!V1^vGU<4^Jky=vn*9$~&iN_CzV1^+V`WOfgyh=h z($9yNZg_HKxntNq`mA;+z{e0S)Y?lolm_u_ziPMvDm(Rhvfe~k`q?T?(8`DqfMt$j!EctdQOsu&CKWZn(60y z=So%A?%q+c*_7FIN96e{^Gto$9;uX@_UN{u^s-s9HvFzjdYJaqiCFV9ZrsW5+bdhW zKKOA{>At?1;xjtm=G!djI$FHQt~X*rWAu$miQ~B?Zw}sQ@~&|`nZ{qY-L&k__@fA(73HOptO#ODd$??+ueS>0f4 ze)QtVNxK{dn?;(B*wkJ|24}b*L(F^1tTVFDJ|mxzuv5G3@J{o~`BWYq0c*ysfB&$tL5{Xx%FWGtEaDJ^|RV9*EL&we^M}`;o(}* z>VWt@|5x=Np69)qcyWg9v4U+6&lfL|%lx#4*LKtX+w45Yl;+gzUY7W-N{8JpYW3l@ zzk7@4)U4b(d)it1M`ymP+@J74@##UY`&QMt6W33rGQ*~`>eOh1k`FRUU{XP^HH3UUmn>=6onfUaW z`gJoxcU z?$&ebPp<#ss~$hOd*a!TYd7Z2Onw$#TOv_tKY1%-%M2&+?jN03XBMTzHmSUx!Z&B; z8P>Q1$9FxF5{jOgaiLUb$pZtAeH+t#wbSBSj>mu7`L^fO!ieL$zfCF@no@c-{r?i4 z`88@!CrnuTXo=td+11TeIVY!O$JHj>iQ37t(CgfxC;NmR?OXX(u=~H5Yx19}Sk1ay z+arEz%NHa)Jf7V=LsTT+?$T|)#qP7Lma}r(?fc2#_~ifmSGF8AiL2Lp=mlqey}JJG z@%@~o2iX5j(z|}@Wcf9dvY)K{W;@@B{9akUwq@yZ$<_1Hx0Gl9Ir;Eh;l`ckwuMDp zj_`c+*}sJ4Znff#2aB7Puf-@!wyC=te$=%o{&N2R-~G9#W)~XD*3GZA-Er>6wZ9tY z53T9_k^Lrr%Jr#945#On?^%;6X?87XH`~UgdpGV0vpoO4xc7E`SEJ^)Jr~pVpZd;h zwy}SH>)QB*}}uzsXgz*ZKeXW1mm|?$=t-J7aCnME^TadwM&kt(Dt7?{(0F z^?@Fm+IdfYePesZ6fpZhu2qO+@smZ5Hh;-q^Y`Fc*0fqlCCRu;Z!D7Bb*f`S{B9fe zgl^pS>8S5?1-~zkGrnv|Ss!p-{DNJ?M}|M;ac?y7bULqX`Zh~-n?Gx2_1oK5?KtCiX^)+U*!rU{ z?kqg9`?J@3X<%GYer(8@5pQwQ z^k^YR--#2aTj&2yU2wpoZd>91-`DTk&TN`sobAQ)EAhkc<`uFWrrIHK~zTI}hKg{400=U4a31z8mw)%z&ocAZ^O7$K+em!%2MfLilN4DLzH~3r8XZoQl=;6&sM(?jpS48uteY1MM zYf}Fd+0A;k({z5T<$Rz1V*2OjZim-qUEKBV{G3m1Hw7-<_d3^cqvPY<3A#V~H?I9N z;g5i|q0D}L9g)Z4zS$|-i52g@eZHA8sk(OF@x*n1U5bjH%ka&r{_{NKIR8)OxfXM* zzx`Txar)t=`&J^`H?lMTPXBM%sULkJGkM+rV-+vrm=_-u{c-8P)!+Fm!5df7U;X>N zC+qrCwIjz)Pp{v6BrnN*)#IZc+cI+YD!N~vy?f#w&gb`~?wFVKJk|8)y`7i#c+cat zpAPQVy|~`H##d_pkNv)JC2@Vno_9~J`7nFZ|8M!1)SjI@ST{ZYaod){&(czNC+WUD z%e#C2;kf;MPt*ULYGY6QpH`XlFE--g-_E1GbCUw)>%Xckwy7vvH0A3@R_`-e(%GEt zGqban?w(v%ed2ij=jX!dbxXCbeM@sryJndjSHk>xxyelLy0l!*{C^u$dhR)PAI=y1 z6uqT$v%XS}U!BFQ8qOItiOaU0t5rT&m+mX{n%P_K*QwbuYtq+pF8y6ztJV9g=47L= z?Vra+{N2+m+K<)V+tL!)rmns~J*?xH`reE;@pfJA|Dz*v)HJTYNZ+_p;N#4LH|!qt z9w~0SYyGUSVuQ;}bKb4;N1j^+YZpnefB91)x1RrM`2JMYcds4_Jw3!O?b9Er{{1rF z_52!(qTjE(3!a5BP203Hve~9!Zp4%DtnHlDB_$$Sr`CAZd7rw~Ve>Ot{9R8`4zJef zuYBtgg7pjL*cbnm)Y+4-Gbdl?y4D=C-Lr7ZJm;*XNMmhY9xKoCIk!ERujX@f{U3?dc6NvR-#!(P|9XY>fSJ+8_)iamHRlwc zZJc5jQGNa3evXZiU+mk@-s6jZu5k15>isb%trYEE%52!nmX`SRRcmtXv&r>yw9}i^ z?^$^*o9t{iv-MkCa`MjWDi5x3pMJ5>cze~Sua?yg@v+ikdO1BumNHI#bbPDOJNaMT zj74hg*LK?V&OSW%@sr~+kNcn1r1#y6aG%RLJ$0Sxzs-;JBT{e7P}FtXbVO7q`M6*2 zb9Kp?|E`_vQ}p6~S9j=;sB&7Z_4dcVSw;S&Z>%^Z=J)yh9uvPmE!v-twd{zK%Q%xi z{|oQ7n0ww=xGaC3o5SvO_K4*-HbLh28|RkyMp{oze7se~&f=EQmB9NqmL1Dz@7{Cg z*rw0Mm&$(si`_qW{jHko@;bi*;`<_Z{@&O3dk0_4zvPL_mmbrZ@OGQOlkd6N35zD! z3an3m8WDC~^62V=58{PZnJ=&Uy()Qr`<2&T&y8%}PV;q|*_i5Z?CkWN&f>Ql_^%sO z)}i+CpcjdO>{p@SuYhHXx@DyR^HsAR5*S^11 zYnrKQX3YO%dPqUnLgyRvv;BWg>fIDN9+N&d`E~S(S0`oHyngXK za-nYb`_xs6U%hQ7%CGsxxBtx^qYatYt5{YS&-@e)8*8TRHE&_`&}A zul?4Sl?u(73!YBYExVF+efNzkGdI7!T+A1Dw#@2F@Zk&7)gzL;Yoxz(cJse8{yHB0pWTeGaobQo!S{05 zm$Y}5wPx8W_Zs&7$nAbE@jH&=!DfD+C&y>s@7I?ue#@EK&T@~RWzu(6CBu~4$1m9} z=$D)aU(OZl-^ zUud(%j3R^Wt9;bY9oqih^3DQ*->uA9w^zjf5$t#RRJ75~FZ%Erb?LU_R%eaoNNo@M zT3F-tmsNZ5p3bS#=G)Y-J(f{8fA{fYfq3TMDQm;sb-wE;pX`%c`*`cZ$N$>%|M;2| z^&QLDu+i#dcgP)%PsTSke`Ns{R}^DJ^Fb{SllrG&EL(6Z*GgM^uHbM*Y7kj zBd_vJ;v4_w1+&VYop`>seS(sy6Z?AaxG>UtX=1m*8Doz z%{`x&pWFCXGDrEqHvY2f*2;fszgFf>`TYJ+TlVuwTW6Z{=JTB2d64}#!=1k_X>mX9 zM7+}|o?;a+d&}9GQL8_(yU3V_A30bVw{&%WcF8&Jy)Uw6N2zZA@yv>Sy-o6yY3!e7 zrte%4e*1<`yJ5QjpS&E|mHDzdK{DTZoqPKyf4s0`w)ro&-ktXolx`iXkjUHf;?FY? ztG%nvZ57%tZn*$*p=WZo2a6R>Srmuh{jEF{SgL-}?Bckov!z z-F$i{8+NNruWHlR+2{TwB87EZow?mFiD150bAM=d_zApPt}oK1zL38bA?|&b= zpRIc-(JMdyfzk{6rdFlOj>Gq5j#&Ix;kEjaEPOjzKXZ1ia9iCUH+C*Bg>~#&G*(j)|Kzi~l_6j#}F86o2E4wBona>CNpvyuXj{z3(L3k@!gAnLqE( z{tXAZOKm31_#Bu1`G`{8arx#a*5?FQHopI?VfcIIl=x{!JbRKdqT8&qK1{pW|6v!e z@tv((4_dO!ecaocy(>=qe!<(+M-dT^1+tyDvc2D1aK^NtX487zhjmA$?MS$JahCg| z-ZjVfWlkz)m@N9**7c-8cNWu>JmuqwP`G)gG_E zF=)rVvAC{-R{?BbMA<3*lD%*qvvt`7iShdud@#|ThMCj=;u?hn721c zDen9==Y6?rBHI0LyjlM+P-foZg9rRS_0BXjdiFgzTkaH}#@qA_W=G2vz7=xqPua8Z zT3Xzk2gQGcq(9DH&&cs$M!it=kB2SJ_V?N~w4@iuYIkp#A0ah=i|*`;%yma=a(yKPvuk6EAZsr#Ds^Mm>p zreA;O-}a34^sD5)9~Y0!6=3|N9I!9<|LYI-!Hx0xG5^kA`CDH3*7z329jTbQk;zbw&oO41+W zWu7bU=T}u2SS96^7Bj5k=-FW%j(H{rs;2N`+V*3 z@f$ZpCtE3Kr++z8UOI7Z(vOnY`w!of5~=vc)J6$!6q+cWdK zgsb=$eu#f9)3;Bc`kBc7uYa#B4SVtFSmTe`TvJR+cyI5@PPh|z>f0)wzk*_SZOo*1 z+~1H~KW+AH={*b28S05%FRYY})^gp_ytyhl)W^fkZ~09Qw@=r!x?^rREWW_4?in1@C_|7fl=x=K~%blDpwfSvn!TT3Bc6-7mOk=j#Rlct* z=j{=bVreC zw@*`l#ufMXYVrHLGlqwBe^vMQ$6r!g_hZY{;+t2FnQCaBik-c-{!D!BKelO`e$M|A zSyrGv|EKxyW!tVV*Of63d|ZBBpX*7U)SUl&-10yDUMggC*C%`OoFL;r-zL9adZSWs z*-ggNnSa=_d4CBdFVdHq&iLG9qvGAVgP%UjUbF1|l)mA|63ZzcB|H0$)cVb{>yKzw zH}m`{{+OxxesTPq%A@ad%8ZO&+}gRX+v~scn?t+B9FD}VOVX8_d-rp^BV_VLpE?7bb`*J@V3m!7S#LiX3KEz=yFZ*CPW`68)5U97<}`_iQIH`w{^ zFW?Ae-({1onD6&u_2$;(=Jxm#(ZWp?Tbo}?Pkqm=z07>uhieCySv?4Ezf#|_HPh$C zZ%4`9Wp|EP{y6ye)xTZfDeU#Dzsi4ma-XYubID@fg;f@-gMS$o@Rt z-Re&MXJ#B(vn@a8>4JlS4^E2PhaFclf4_N0&h+M29}dh+{PM7Y@!45-x%syO694*K zJQf{R^GWymxt)*e9+~{x_@||`<GTdeT0N@3xk9be7nw|%^RU#sAr#pCxCJ5xk=uJ?b= zyM9SmlgIkIQg)AzN@PbF*dM!PaIJwYyGr(y2=i*ec~v$wiy8R)H+bqdT7BE;U#Pv* zRQ}A{llvyGf1M$%y?r)E+v1OpW?icYG)@=0eoagx&0wckcS+u7b+iAoXKnf%WcsF| zcH48a?379E54Y}{{+Rt5$HlU?m8Z+EpIYMCYx-#S!#N$kvf<^Nao1Py%JMyYcAMw^ zZ`pdr*@uN?ewqf;ks)vlj=bD~u;gr$G7xmZ@Hxc$1Be2;Id%<;Ru zCLt>QN_E_~9acYn8m@DHw$k_AS^JH%oXd{gRO@=6>M_HyzCBmYPo?sfGW)gdmL1wA zc0$Y9dRsRdhWVY7d%Ylf##bu~KV6GQ$#=>=I4A85i1q&X*g>tYTi5-R%4`;$-8ZaH zNybkXKmUhCTa7K~?w)^+*Py!ih4%MGiNbB=wA`YGw1W36_trFai_^|OpWx6S8V?yEDfzAs(;>0gs> z=Py~~F!eyp)uf~R**m$+5O-5pyi{&SMhA&Awq{JTGc}1as}Dc`J{W&)q3+&AIYn9%$e1eqO2H39qkj>=%B{ zJdJZI^d)3wwzs|5WqzG!?!T=1LhvRDaq&O>J1&3w=#~^+ZKHBCvt)}%S!*5mA2(^!|%$I8x{0c?_}AjaVK2;^ktsyZ#TGn z4yZY*SUF=tFzeg-8{Dt)PyTPcq2BGnaF(Iv-)*U;CmuNor==gG&!G54^R!Ds$73_qO^v#vRSt`Xb6}--ig@41e>t z_;mu?PXB#9v5R+3t36wL{2%MAUwqp>ZZmrs`dnYXKwT@4eRJi>m3Fu7zdo$J{`%U# zmB;Hp)SW2yJ^1WaL3Wh9;l3HCE-RP!uKcUL$1(2b+{+gthb2vWEJw5r^v3nx3!m2rH`Z+J=|1_=L$@aUV`PI|^wN*dW z8C1`Uf1Yb8{{t4@gJS}x z=zMuqe95Zi?lqH6$V@vN!Bcj-uAW^iLT~D9g(Gq1x7#Z|n_c-a@79^6Wl3=ifuA(r z$i9^9-+lhPPJD9YnwziHf?W5_*vB&G+oRQr-_+X_zeb%}lW(4WXXmB|uK$ni5{s8@ z@xF2Hq2m9v3D4X7f3gOM^DSrRtc_nS6kMaFas21jh|c2`r?xci=bydeT42b!+d_Zm zDK4y9Co}2f7dAm2&TA_**5^9^Fx&pAIzRr}R-f5cZ=Ol)cp5zaP7 z!d3let#cZM4|1GN|E*9ZdE(LA9G$MC_a#qH^I!ANNBi00waI>J$KUa++n?lrj)N__ zc>Ug$^HYtFiQHlC4)~RHa&P{Dy&GrL9oiLlx?QtYBJ8^G!K~hXIa~X}ifczIi>nUy z{eR4V@`vQ^=QmmN-?ZMZ$<;i1Ox`DxZ$ndy9}mB1>757dpQ_*7QB2)%(28}xgRI#W+{T6*FSup-UCONYt=;-xG+d|WSBvg3tEVS^6=d5L-)fJpF0s1(QetKCmtMt2 zceT06YI6Fk)$Q`i?>x*g{g)hJ`{fh=kNe+z4|Q4bMpv4rJid@OJ0iU7700iHlZ#CC z$_j$D&&|8B+`r^%eB3`9bDO)j=juP%d#_jBrl&SJBc8j)?D^~UbB=qZi+AxCBPFb?JyvvC8a_Qb{dl#~_Wwp9(@w76T&Vu^khNK)igbzL zd+zhf2hs{&CPn<&IyogMxBhP9&qCR*LXjDMHl6RQHvd~u%`56~zwt=;-m^KbkqbW< zggw6}lB~dWeBI8zCrsTNHy>2lb@74RpZ5pk&Z)Wcv)6C^bbfh$%}x17t3Iq0o9A-a za&ggR_LmE6uN|z4S2p<-o)Tdt5>y8b3>uaE11hMiykFiFq1yS_X@ZBC+8l;ll58L`tRes(RcUgGei z#&X?9!Hk2VVjti9-P3%TE$fE*nv|N;e7O;CZ~kAIup}tK`23-Z$L?QKzteeJK*IJ% zN3YSZBxU8U?zs#4ESs-oFMqLB)p0`Cnw`uOWWwHf_s$TL*{S}U{T!Rw?~01#*yV2( zrksyBr6Oy0zWCFztIuZNtLqf6dvSYDlb zVi|Yo*O;mUUxbcy-`v?ZM`D%!GmQheLE2J{ekO003lEz+{ zEt9<#&TO9^|7daTIdiF^Jeza=kE8`#^ty5`CEvG_I=yi1Kg;VkD!qN@cP;O4?=GI( zc*8K;r|jR=zXem`b=E$8*KBU_>*LI-KKWAhyms;50p`2X&nOk&Id04RLTt-ML-> za1hgOtL2*Bc(A8)S9*-Mwey$qzWKj;dpED~d=#!$`!JPDRz$$?wN;(JTo z|JNPz_x*78KmWhTH}>BAtPbCjho|-^^!vAODdOG#XLfng+~0nGP6o0yzUtVjeN|+C zOYYiaSJn5&lP1huCODhl+%@L&K~IC%`hC+YjQsQi6eDZdS0=q=YuM&;v8Q-`@Rs~<<)xW+y2p`9OR zNmSvN4&L7_v3J^L6$^65@O4Pt{pp|k>VjWU(tTz7kH7v%wYC>;)js$0^^3hHT~?UJ z%$Hc_TzYwNF>m|5?4*);!5e>wi(HboemObaQLR(@)WN3PYnKaOD34&zc_UHvu|?x^ z`RdS9yBOVW@XbBk$GG!kI&Y!gq1paLuZw#u3l*%*A8$PQOXBs96=!E$G8H?fqg);C z!}C^n;?u`Y4Rc=e}Z6lhIP0F7Bm!(_TdVd~j=0MNVXG?$lU2 zlZSlMK0nzzCrR1pbBvMC{si4UT=VPN*WNT{itk#Y5BtlJiFa?S{o$)U@Fsqt{j`}^;CW*Nlklb^rLgF{-fGhZ}X5{A#d%UmS10J z_~646Yw_E{N3J|iTs^~I`tRD`*?UhEB)|TDga6-$%z~04;je{B2QP}3Tsgnv$9aQo zYmdMG8q*i*xPkv^<_C9_+2b9Rs8nn$M2Z0ZP$CQGKFF7i3nlovWt~H)1i+U#ZfU1 zuIzFwY4?NQOZJ(wg*|z*@PWHP`AXf_e-F;Qv3vU8W8H7cWtr+5{m!=CxqD<^){oCO z&R+g_Tm4h;3#pa=X9d4%_#=G0scJ=*=CkZuABA^k&o%tY_f1m#$FZ5>F;}NQ{&kpr z+eUS^TDv97Ik$wY&A#6H#PxJ?&UL{V@%d0lRwLjolyEK za+*t z=g(WiXl>@MF#CwGOUkiRSFQxg{5oN###U?=IQRaM`OP`~=i40f&4WK5j=z7v?u_h;)Fl4B z?_^o`b=b0h|ET_^LH67clg1g{&HwK{DHiKLaBjA+lyK|%i_RWvYUaK;#e4q8mb_yf zdn>-}l$;Pf`>?e2Z03)K$qEOL7cJCkua0$KezdQf(&wBS}HgDy} zxdvq$_Z{B%61qXl6&EK%4f2aG?14V!P z-@pC-d}Bmj&B^(-JCdvCn-`t?_{#FM<)$ZV{#{AGy0Xp9hX4N4yS9aEo~G!xn&-{G z{do<4vecLE#|7&TcJBI-l=}Gtf7(kvzRHa~`!nBHd~SPM(Xjo_m&5E=j}`ul3qO&O zzxzbZlLuuRP9Iml6S4ZXXhnZEj4n*DnJnL8{$ul9hIS!VG=%jxp*A)gw`*GC%4dRUHfHb z|A;y)9scAG|K0a9Rz9zNyy4^WWhaZTGurODru=R0WNZF2Z|BCxoyq4ZJGy0AqSpJh z#^3wAZhFfa@2yPy$IAJ1X1p@XugoH3^yd0=FTMBO2}|aC zn$=$_|Nq2e)(rk@GLs%mH#A*+cE+=sC!Z|r9^an-$Fc49&#q2g$z$_o*c?0EWqs-K z<0H03o8L8@D6SKj{A{7!jPD1giQW7EHteF@J>v=nW#3pPwW-$bXMZrxn%wQWK;i4V z3EEAEnhoc?`|xUy@qwt%bvxecE}moA)vkV8T08gN+`gOJBbZLTNv(Yxp7_gQhxzkk zX-+v|Mpsk$liZc%<;85w&KtGCz%swq`r9H zbiAN+ZOiK?rj?tIzWEV5*wpZSrroYZ!q8Ax8>KCk|fu!+jstr{O^0`Xq*2G zvD|Mh>p$LKp8eleBKyDIWc~-jscXFUzpmMIG47P~^v4CiTT|v=U-|1_r0Jq(pEvxK zjo5voPA+1jw>#fD@nVz54vXR!)>_+G{8(O^yI}Fd#XsLv=RVWe*M0NXf?}QU)P&D& zHiEB(*S*?zIB%!3k=QbpAICTBz432f)Yqxk`d{rSRy8{}cfE7onZy%yU2>(-#eTi( z?>$#?wdZM_voGS;m6=he^9|qfKjQ0hEvk86zxZ?O+Ow%AP82=!T&{l3zCksO_0f&~ ze)IQ%M?&143v%x3??3&=@QClm9Z!$1ZI#*PN-xl!5w7>S-`Ux{+i@yI< zJooJ6x)kXm-3=?vHpsi}o~Zg~)5mXZaZf&MP~E)t=_~$3PQ!zLPUNqdbmMEZ=1-f+ z-&(yse(_y0-RdOsa@`l}Cckd3dYP;5D*r(Kr}xf}2ka8h9!&gr=08HKiz+Nlubw@rp)MMIs^of!OhH`PmfZcF zqFk?K9BU6mY1Qpt*(JYGF5U6@ACBe!tft@ExibGu-_-DjGcGUmR^&Wz)>OxhWyUsE z{hn3<59MgSncq`m`z{O=jkEsxbM_61Ny#zF0i744Vy6HrZoZ{`aT3etkdN zo(Nj)yYP_dzMS}w}`8F@BH$vS)R+=e;Q^};vd`9 zP4{nKX6b2RWi;WRXwk9^rs~%^W_mhLZqF$`yGSm@+4=cFOP9PR<<|#3A79ve!z!#k zu)Jm0gr`?EYMS{UKZ;$mUwSul)V{X??e6;?|8Y2{aIMdyea+f`o2&|hg3l**-qubC ztKP7&_m!*O!mW=SH*Y<ENqp$b z`orgMKG`>~;KKH@&}|||am%lOZthHUa=i>XLehcIiy{-QC z|9Q9CUC*t!@<&zbuAisA8^5=xdVbr$Z?4>quS--#xSb!;e+_U%k|wy(9LyMK`D8wzqdo>Wcr$z4_~Y#@X*pS!n%b zVcWWQF}9C$GuG+Kta*M%)9-B0`|cvkSCul;7>g~xme0A~H}9ETjh}wN;`_&(7`|!$ zNZwmrfZs2dLc-{O^s#$5-6z}wHHv9Vc z{s$jspDy@a;o15K3)y=X8~>;C6l|+KW&AOb`CXFq{bO$mEia2t|9Ahm-Svy-e=P0# zd2{03JD=t6CS3le8ULqg=jYkQ2GZ80^KU(46x#Qod{6bAsO{&jXnroz|(a$n2bx5VYq1{Jq72J<->vzPWqy-+%piD#5F{T!UWa z9j}~cTDWzM=C{P9&<3|{UJ4?b02p_219D*VCQ zg$JMAnaf{r%)drpb@h1{qvvO@Eq7IWQocd@;)<@F_dNXHJej;_l77vRgo@>-H^$ul zFL13p>G+wKlXooJ^*H(YwK~7^>xyfxWi5Mc@_Bw~e2&}eH@p0FX4jmq{PoM`G2`Q? zMRWH>8vf)f^s$LO>)iA!(>6PQ&D-Pb+rIJ72<+?4ZuE6jYp6Zdur>Sj%bsi8r;bdq zd-q5wp!ez1#N4C3ytX?1U;4Cbsx#(Y-#>Fr^(Vm+88w;0*2z_SBjjr<@?y>%Hs0xE z$2n(X&xDP&c{}z_%dRe7mUP&-?$GgiIlGv!^7H0=({6oUJ>y4ZhI*J+vBjGQ-1oL? zzLYHY`yg8F7XH82a%smuU7hZX7jthI)k&H!ZHstty7wG+*%z5}KYO2Ku^;=$e%a9C z(>s~pwxu@(>Xf7(PH=y4gjf`)178%q}hR!fKwKPR@kXj}{R#f>~F}AF2BLAbG=_=k|qPb;8%|yP10L z+~>(mKd$jeznHVFNBMZyuDmT98J#mWM4w-=@0K$2^lS4rztP^BeP*)16Kk;i@-uO2 z`5%m@RD8ZSXX2sr?hEpI?|<(9_dfK&d?x&Uc$VS~LFVwbnD&W1j3? zP~`YbX+QgO`CjvTJ63PASn{^4>Vgv9g1_XqtvI_>YhM`qtTOZPPE zoBdd@^V%P=6~A6C?!EVTV|-Emv4^GS5>>2DsmciLUhyUW{Qdy`8?t+D99vS}v(kBa zr-_ub^!4Od9_Nk*x7$rQ%xAr?+cx!@YU}I5r0^f#H!3~2BT_llD@Snh#NV54*IrLm zIluAtEY(eOep`9^*xtz9n0z$)!>0HDD)nVf z7{6xzyDf9xmxNo7C3bI--9Bma`uVl&+v9nX@@+OqUt?2Nv%5Zh@8j!^7H@_5*%p4;V|B-YL4up#`uss6TS5r%Q||4n_MEq%T~E&9jp`3KgP|KWU@FWYhQ zI+yhM_lHhJX0={_n(%6xN8kIu0nd9SuNH6@T`wq5bZcNbnK2V{yVUCCi_Jk4~a9bdToYwdd`nSw=eO}JjSD0 z{rtn0*3V)4dwtJb7W@&uf5N9(GLO6OPYj(eRQhevms`^3)^AvG|B#fra+TIo*G0)$ zvd`7`efsjS(9$bV-%)+v-_wFS*2jO9-+c7t5mklkT^$uimXv+?By;Upg~jT#*8k_G z-_tp6rx>(ZID39jlyQw>T8K>F{e!2X*KgjwVVP0Iv4yj?9{-u_ynU(ozK(|`_J1y0 zu54vGGp}*oSI-+COiMnLq;Iyh6ZDJM`8!Gf{*{ee@60>nz5JRY-_M8L3Z1OdaS3Z0 z_qTCpX9`TW>faNaeb6%EyWKwi*9(r@J03ZG^VyvpkKbLIYVPDd_r{#T=Uae zwOMY?ZWZJCJ96XF*Y#-UzxT>|znp*W%631g$$J;?zpv9bW6P}xffFWvpYdb%`OfpT ztV?D+3JstC_Vw$<|E)!TR6PFl{>snkiwh2ZS@e+WnbTR3=IiH=emD@cGW6@TzB?TUt)< zYP=pDk^Ic@Q1M4Uooz>h^ees{Wt5TL{O7t1@AIVB?DLu|_X~UXt-Ct$ef35knXk{? z_C0HqlKr`_YxlLy9%VzpG?~kqs=S#0Uaq{|tM}qS9TNlm`c9T=TZyTOqSO4#N#2fkO!iR@VCzw|~ zm{ueG{nYk(X7lg&p0!!MZ@QJKUTukW-o1vCf7JEY9Qb_s*3dw);C}e$QQ$aX#qH z!C$Q6`Fv-%br&6de&v<#nw5LGZ&!TPmGW^vv^nkPtg6y~Vf*HF-@NZ>q?tC4Z=ck< zoyBuQi;JF~zW>;M`J|tTwx4}+qLP2zTec%+``vPv2`ev@?^`#gb8fakPPRThP{a^Pzox-&jih0*XZL~AmeDj+ zGk=Dz{nE-G5U1a{=I0rkY3&;)RoYHozfWfRYo`C}XUW8G{F(Cf(V5bPgddKs zZF<^1=Vz+d{8ER5v!6*y?Aa(Hy0aj5`n<(OV)4ljpXnbpR$`yt{gP7mv+pNe^&Y@Ib6rWTv9Q8u5D8KJoftIUO76y zQ#SrM5}#D`_W3V%@9zE^FC@+#`dvDyDy8xs$GJJoPb@w@(tfn2SHG$)zOY(W>f;}V zxo_UbUpd~EofykMH-2@J!@k+YkIeLs=f%7_8gpcAf1}xb`NLMLWLiE)-?$-@7@o7^ zfa!P9!plECr@yuO)wr9_I+^L>qz&yhyX!BWw~c@Gv`zQd9NqbLwj0(4zqWaHz3<15 z=Jj>^zVA|;v!m_Nv7Z?;UfX4J`zBw$&X#lh#)iDi{)m@0`y;2{uz2^7TV-EN_R}-7 zU;3*4etJyLrummb_+NqQ`2Rcq7t7AKnY?*{u(0{s@aGb9Eq~uL_?&XM_Q3Le#eeHo_dqlf2(*lW0$4;(_7bNZkWF7`fm6m8(a>p zpZe=L^HZgHzP{lT^Plb0xY@Aj;KzoazSRxeCdQ-+ud9lmaOhRgm!oHzb4%x|{(oNl z=lP+zXZ`J@q|3RU`u5K@l)2FOS4U^}nfHedP4t(3!e}s?qvmG8O&d|q{3x&WEqfPk zUM<6G8(%Y7*}ngV&7Yo`_IDa$rGJE`Cr#ErcI4`GrQ7xke{=NTG2L-wZd4=dB3|=i z7NeaO>ztaOx7t2Gx4m>)OuqZt8#^9d5nhyc_Tq`1j!WVazeOJX^{3w~$97GlYF!+M zN}c8IH~t&Woi6@kHm&{0v8T^2h<7a7ag8nc*3z&$3NzG`UbnMN`!9LkJnZZ0x0;*y zpX{3{f8*YaKNGaHE8{-!#bnPFnBE?||HH+~jq6@Ai`l2yJw3lm>-qML*H6?kJd8>* znw|dqQud+=SGBiYbC+NCH=w7FJATic zNQLK#o%VMhI4)Xi`np@_Nu}U~8!r|+&treAx3<^!Tz=wz#rW%NtFN@qi? z#{LsWq|t*eGc^zur@=^L37Xsplk?{9fDD`gtqYzt?_n#{6T$gGIcu+m03LW~{jz>K4=9 z;`O8{V);UW{l~bR*UHGpt0*ad%lxGvWO(mTgL3wwh$WzYj5^B;GcyIu=CE;do-h0^lW4!%&uCY| zTKH?}CV z74~1-aiTKr!Msi1y!7f!ubH0R_Nue+80%>n(Qa9ro$a4<80w`g%r6?mxl4W8s`vEG z&FoGE%C3_q@&fVzjT%%AVo>X2rIm z)210Zifrs}lT^3aTo2mt=Dya(9y2i>!%f>yD_5OXxqeF}|JM`c71xX3J#;z2zvGWW z(b^TJzqi!hUYdJKe#y!g0Xmg)t~*yGy6(9>Pip$4=JTA@d^4^@ev6tsFG;NLXX5nQ ziyYnQ|69J_k^bO#`rp0kf~FAm%IhqLr{7qtH={S+Mt9AzzSFye>er{n+RuNsZ_=L! zIqX(T6y2xQl=604?+jdBs(&TY$dOh2>!y|GpPl~NFejdGvt0!Doc&pymfr&{`t$EQ z+pz6cvfq(;ryy+Z)O?H7`;`nbP0J%*{-0_4+Mtx})V27yXf25!$IjY$+a?L?OuN#+ z<>J0@?{l7Me-6(1acYjKu<_ZgkA6L!dAN9q0XztGhn9)%@E(8*cx3n?IHHJoflhr*o$`USpbtr@d*$ zRioo?A~$c_Atu5d^Y~?nX~`Zw=j%Upr?H-0Rn_HN@ci_jw7wb3&*)psoB8jdTa8K0 zSNDYV;#qghmtVZN$36ST=N%R`nKP;*-z|N1X6pm}$m#RjPFmMJKECDX)OdzvVMjdI zy@}lV>&5?IaM@`e`cuARHn(;|j`8ydX~yXOeH$NJIyLuPEf;>ldQSO)`Q8gZmr1YK zcDI%Ff0#1cdf$D8kFPJgAkLd}<=&dLQ`!&vn{{%m3G+QzRzN~*A>ijWG zG8Sh1w&JAly>qe8zlZHKJs@I#BOxwPmU;hY*0f~Rxe;Igo4n)Aj(_%Mg}&wW>6Q+A z&ReaUd2VZQQ0Mwd^EIQjSU(5Wo%oTG74Hz>ez)n#Bs z4ZlV>Dhu&Qzce{H|F09L_ms|u4heIswYpe&bE4ieFpAYv7eL5o%`)Yx5@q*9$BA>@G<(-RD zmtpsqUT7&Uec#5WAo!S{_t84(yEiNqpOnbG{>K>ILhvj(Hh^!RyKRCrrBKBsi!h!(wkmuR9l0#tyY;}Yr&oU84lnz@W_Rn<+G`HKUcF7= ztJv)S=S2MeX=jhbKA(Qjv4*72bwNTWmXjYudGMxAJQ*_=s=5IIE z);<3{!TyTmjf35VSswLTBFUyG zw0mv*o%y})o4vnYRqT!IUioeB$$w%qcb@d;stcB1{v-9~v*6`tB5h_(F6lg7y6U=n zRfAILX+HUCi&n*L&y%ukoXSqjFN%+-xy$ueJEBr~-t`|pGVh*U%Pw}Fi~G^WxtCJA zZgQ4x(Vn(z>$mXBJ+QL?QhjQL&wXy4^y7VI``y-0)*Eho<~e$1^R^&Kr}sD1udhCR zqrm3OdNuj<{}Z`t_7wh<*Zl3zGPhP?cCMb=f361q=$EHH<(EpzNFP(>s(ABds=cMn zy*rnjSL&y%yCA-{@Zj&pef;08+>al&{JWELj>Mg3tfvD^o_A`??r6QLSD2@B?}f@| z=>qNhxtlkvy|~9xll%D`d(Cj3si&067T)Z!O+Q z$ArwqH_kt5JM7%sR`#?YW{!3Kl~ey@YX#iRYy5N;Jz3qZDt=2lWyNFm{?A?q*OlGz zX9|8_=XJEw((Rd5gu}Vn2_nlM2 zblu};vn!SV{ZnD8G`()|OHRzDF!?*rZqC#?VR6lfsG=48U-uMzzLoD+pcej2M8^L3 zpHp*wJWQDWTA;3GS90gQ#-)6jM~Z5nG+h1BSy!Q*b@qzz{^bwve*NS5JGNqizWvkJ z6Zs;U=Lj~xf3tbgZ}aGajD1G4Vx-qq?w5~#_UNj4%9CrApE9>x6Vf`h)&4{9w31BY zH9UJd*8jcx&%>>(@}ca3x%&T#h8l-T`saSrQ#B-|~L%el~hw>4=dNI4;!!z*-CN*FEt8^3?1ss9{>4-?&;t2bY$p0eTE!G@?6b6;O-3T|^q zyJx+}ll^SzP7Ci4`Mo@kBBR5Qov|_M?T&wwqYF-0J~upQ zYsYb-Hj_zOyRSxRs_m?*>+u_p8006HDD1O3zqF$6T6|i~C4Jum8~;C*V}F%#tfN1v zTCOGjyv)A!6OLEr&zNDLF0=E@-zhg@rFW|DJvM1yKJS$Sr`2Uz3w*Ernh~}B64!IL z_fwQ_Sh_uodg#5phT(DO%XS+#Yc8qmFHZYw|;w65|{Gg{C^^`*NjW;HeNgK z)n+8OeIK9cKa={CLiLM}JeNMWIbY+R$gzkM_L(0SKejkB&GMbx^f}F`wokqLqP{4` zzTa0?;(o;c@umG&bB>!X|5|hGt7&bLVWme*fdgm7$;SxJHGu}qo+q%|r8Q;Gv8?LNb7~`I>k>A|lkIyb4=NU6r z^?vjG#%tG}UtbW{)>&!W#(ig3`a=F`RhAo6W`7p_U-->j>%+%mPw%hzl;3f1>GoOc zWc3!*ml{5sbn8~%IbH^tPx~HxULLHpWzNIBZ@EKe8E-LLcu(Zun$t7RJ~mn7oT&X= zv5oi5r3;%c%H$rE+qhFZ-hRQU=48JF_q`7bug>WCcznKfh5hCR=bU*C^AnyYvIYpV z)i3S+_I$&YgnKzh*(KYGo7Pr6xNkVublEmj^_mx_jXquNf65+z<=&Irt^5zJ-Fm=w ze7^QPUnQH{qOX2-Idrvz`rKX8=WjQaf1QomKZ);q>}Kijo4(h5zj*e2KeZ+IrOhpW zhcC)Ruc21M3 z{{1a~{n3M`o7lGnZdHF49Z^)gmWAQ)@=tq&Ouj`OKDbn{VU93|^#931RRv1RkEPy` z(Jx4!WwXI|U+s%ks=sc8OtRZ3`Cmrt$vV;g>fgZ~Pv`yADc^je^Yz52LfNVDuM*BD zPuKhO%W*x&XM?Kq)1!{wKXyntCMx(m`|mGTbUzEv{rn^XNwC=O}rYFx96?+ zG{&-3LM&g{gsW26i>50k+UTEqdN+cxSCqfzw?oKU_j#_J%MP4uHSH4obz@teg{1k# zlX|aM2*5jE9_kaIA<92{Q-i_&A(WkTAYxbR( zwC@g^SFZO-CH(_8KIZqit4WjzH}80wkyy%pO@Gz#eU&#j8?4su7kVIb?$3_6PjJZ=X7Qb8~EQ+1fcfBFYTN0L-LpA%Nc7+cgFVFKXbi4>E4=@ zOw0bG_iviKQI&K0%%+|3w>f|H8q4r~8+U#B`)A&fd&kn`-~LNEm+E1$)-Q8aVKe*nadXheqbEf-3e6Nw`Z-~z^~M&~`s3HstF}IKW|g_V z-(rSM(xc==ZL^@_o0hXTAMxaXx8JiD)y=;l zD?MvZin7;x?yJ|u7jMZiI^L>gDEF)Be6%IMb5&@{dFfZY3CiihlKXS`_9!eX{5UQ2 zcgDAmUuvJ`d@%j?!?ddA_cB9i{*AjWId>%O=1SnNF<)xLS$2+ZjpDtfSu^*1n|a6T zo%{i(8R^fSooX?@uT7eqUR$PeP*5d*>PRkZ{hY2`?*g0R;qF5z2Q5x?S4&m6t;j;EeftSvh(q?Ml_ zS}|Lb{pnGgY3HM_>rKA#W8ze6i$Cu2@h|+A3;#c1esSCRIl-%y6}jURgI7O#alifS zo%k2Bg=YETbyt_wznfC=Vc+MjH2L7k*IrH0f3b>v=aogJK7aNUI32Hil(hTjX11Ws zXEnbaS$8*--LCkG`GsBV4JFna=G~KV+xjoqX%zT zJQs9zd{pDVkA3;AYwT0@Z0+^^aYnl3=-o>0%TZQx8>`}v-rtoNHQV#B;eE~nA}e1S z>^r-BN8rVu{xjK=#bdvJdRkVnc_x2*fLmk!fjDRO`Gw`>Q92pV6h6!UznZ&3_nYR= zNn2)J7yWQCN{c-%e$&R7BRTRNx);^o9hqKoRbY3a$8%FBoBHD?najRd*xx+FFYnf< zuGjj>eAeAhHDyPmz3q5}qS&O{kL__UKh~H2MRF#`VdnlxrMK>M=iB_*Zo9i}dfuGm zf*7GGPgUVnOPZVS7W;bqsUvr@7i?D37_=I%7!H!0l4t?ZgJUyAv%<2roX zCteZ17^Pn99>3|WxoUrp>+*o3*Ot`vn-~;veeLG8KXyytT#b6d_uc9HrvKj@z!f+D z=|{C|N3wTreELTu`V(_^ZeQBnru^;3?8f3oOZSQ2y5jiF!Qb+u<^DaHMn-#<^xjv# zcT#%(%BgSkA~xqPoo>G4W3KL=f(33{e%vkGDE0Nmo@0|bYHth84_|Y1TG51cOjXI+ zH!M0+XG!Va+tu)w?fQ)EVyUtEZ&#ZyHkOnODL)vOBP1PvW}@Zh#t)kD*Ke^%d+jL; z`?j)u!l^rp-2!z^96XZuLB;Ouq{oVT=1iCSBPf19_n6$T^oZLHlJW~mkKSUPbK!Z; zb*81Ii+k<~$amd-Abum{%8VlI^zRuft{OB%zEZKQSzEmP^1bOQ`FiV)_T?Jp_x)Ob zY0`B2jkzbzyq}<^UYrzQw9eh%E#I$KH`>&=EYPgtW8cZ+AN3)#$&~?A!Y6$K6~Ha_fenPgw6XbHtDzJ)&;)0dq7OISo6HZpCcP@ ztC!8_%PTzGBmYuI+Sc#&?0LPZi9C!ZW|DDV0$9^eZ9D(-<>A7&sY&M}43aPFSBd}M z&wYEsyZ#+h)7SOgQ4jyJveW(H>V?^+Pm-!uPfnV1$5H+KHLm8&CZV0#T=z|`7nCH= z%)2J=uXplZdr^hTYq2{d>>X;V7VED+{9bZ*VV(N4qZ_Av;Xk%iq>h92`IZ_1U&AGQ zB8gjz=hSp^zZ2bN{(ZIlpR!yvH~YOEvG)WP$2Xc@_;c3v!ad=<$v2Yn^2KG?&To9a z%R1RtqI#cP+xA_?=|3K6*C$OaEKoK2ocwU6{;%&>BomV2-`2~Und-(1#~NOIJIh4P zY-RNtbF*#IlW*nS-mBJR^HF`<|7|zoq?g+kH=O@Bd+Li%kLF#BQ=XHXcRu-e-O;eM zj%R!xD&+3I_|wkNul>X*beQAz&p77u@hF*< zl`_v~goUqrpwxZjabcFt%q?q9d<~ZWVVu-`8r4Z#Ux|Pqk{eF ze#bv{nig%?B5N*j{_iGEi5s@>ymc%FjB)^wwQm&Ma)tK4Uz>1S)!(7(w;=gtnY?o!u{4veAa#nH3x!H4e@txn8 ze3sF2?TwF0od4E-YAn3p;8^g=!hdG4@VU!BipzU{{fXW9OICdEBEI|=5$3ivvyvYk zEtAEgo|E>{zy;Yz2oOJhZj`NOfkDTg0z5jjCbn~OfJ@5bd_bp#%c=C1V z?gajK_RXa~MYGOM|6#WN85jST`?K#~Vc%_Fey`8;{O3-)7xU^i9=RvLyDGXStw?JA z%>M_*lvM&ofwf*pq&}>6^Nz=9TlJ z8%7z$7v{aWx8C%emG{&Yx0l86ceblvlj&59?~&&7JLy)J-*<85=I;-C5AJ-uZ&Dp| zclmGIs)y!Vih{rGF^<|A)t0=xSYkf!|E>A^Wjs%Y=c_7&AG30FPu?FH(VJNtcI?!1 zyKe?HC9ljw^!ekr{(SM@jn(enjz7|&|E@~xY2@w_E}RPN)B@VWU8I#bP)E}G?QnR2eke%mX%&s(2;-PR}GZD)T- zelBU(PY(OAO8pt@mlfLE3g16F@%zxjneX(h&)2iQzPWd=W8nSuJHq_;UpuGyt9)$nZC2RT{bn=_{7`_(~Z|O?YD5dJ)as~X}u;ps{rqm(Q91GQzfsRFnV1hVQJL%Q_2h%=vU&LM7<&H{P1}7oQ(J7aJ_U-bRPdpXc2!&9&Di-!NJ) zYQwhoSGio|XFn`FH9Eel~{ledL!*e;lX0{r$C5`Nua z<>`C*vQE4|TWtENJD=y^t68~y_RX!4*A9!`-Jz|vXRk!t_SaH8m2>W#|9Ca~+=a*X zm$ko1O=euJ1(AOO4`!?_|!pLx7MwD-yXiPH2O#M8Tn&&A3EyW z_qyzve?-aV(UPsJQfn{7A39K}YH&^HYTv%Ko96AFk??f!uHAp<9=9!fJF)!DzcBBl zdmEqCZr+{nzVhLdGvC8EeASgd(h_~`#kuB!Ek~=5T5s+>8}zh9R(_-RR<`d_`mXH$ zbK3Xq_{>*4yG2`W(<2}A&BC_7Q$JZH+aEpUKGE^v^!FZ|%z4SCSus=O->we>FF}iX zH=q02f7y=>&o9TpTYegsUo#F^eYQz{>$bQXH%wN&l-g+^vC1^>srtDW zv-1r+zZd@fWA*LC=k~{O8|OS_Kek1E@)w2hV+WR<3$wp*V)FC0ePT1U6Au11W^&Y< zeM?B;P%r!Q1E!~bNxqqSIXdEO! z-M*vHFOzuiLd%Q5wSja0h1EUyu|w=Pi}pEkH@imjKJm?}%i6xu z?l@bd98+9e!jbwLddozY$rNw-;I`J3pTX_+0#W9;eJ}iX?#$ljC$rB_I%d)NuS)5^ zp3OIYs2}`8gKt}0wD7LiJod*7U$|EU^?cmF*eJ{A*8>>|^-TQ@>3cSoq~BO`_LOw< zXW824w|8XcK0KoNJHUL}LGJqWnlo>&A3S(V>D%Jy>+M%3PboEDlk$LfTjU(0>9NIc z4P)n6POP<4T;8aDpYKA??m5$~i!*DkFT1k#YUFZ@j&)lX@wLpTUmJ2tIgD|A)wAP& z9=Pgyn_v9xKP4g9ZUU!j9< zba?S*-gD`(-W9jvk|tj2ezxPV?Brt+&+J>awzDo(n|7eq+t!P3<>v1135Cou%M)&X z2r~Y6Hu0S3!g@vXtx;QL?psf-`PKicsW?}1)yHn3CySk=S>4;N-0XbFd-$KThQxwt zG8=o{r|Ioz{44TpM_-Tp{`}HsT5}G!ty^$duhr!8C9CK1GoPNb4AeMysQ;c)_u8i= zp(n&Asann1y68kljmy=*4IRe&B|OU$9+v#7?VS6khu!#WMX&V4eLHXE7v7NHV^PaL ztv+h;oOdxFFP8O3-@khK`m-r>KmA%>Zue|<{XO>GuOxSS=3CD-xwp<(EMvQC?kdaI zfp>m(-hZN7v+t|-#2>5N|2!!Exaiu}nR3$GFYY~Z?cL)4NGmzka&H!&vQ9y+^qlYI z|1*pgpK<9Q^S^)Mx@+ZuYg1P+K8`v1s>u6E;1PbWUHnSuD{zBgb(~_F} z+Silho?dG-knO&}8r>ZbdM2~gtku1C!i|O9wa-__sXbeF>xirVvtvO=Wv|atES)NK zi8(E6tH*r%`d2@$7|Sj9tmzPykG-b;_|!qu?cY9#Jzm}U*6-%JlgDmqOtZ2pG+ZE*XMMu!<$JzWy7$hniRyoL=f>LffQ_j#JHNm5o@;daTHJz9%k!@}8C(hf|KR7J z!(VRe7ru_3u+Xu;_L-b*-vdYM`%~2FuFEWV;(W)I;cvrXvsHqL6RexN(2it2dtxTv_vL zp8eZa?=u!3YINe(zT>s5y8g1`wPjR9BHvtFnO#YD7f;Ev-F~LxrCYwdRm_GX4~~AF zm3?4q$bG}wpDWhC7ri{;@{4E58+v=E)x_%ezP|NQ?b$WaIV)t=M&B_xaWu>F+SW+B zCEw+gE+3uAX&3E(dvW%QV{882cv89i(93T74H@qq=J?)SE_&^AMoG#C*UK%;(k~5? z{Pee8s9YtY@4$O&qpHl#`NJ=d+Nc9DC!=hbhsmh#^|Q|pV(w)zJA`?~w*Hue{8>w`bV?C})sQL zr_7qS$Hfc1R==K5Wm1=_{qAA%&yxv-kGHI?tBHHZ72(JGZfm%b(Yb;(UDk8tmPNd7 z_t?2F``W$l*?x0!)^HY_<@M_hUC?Xosq&RE;k?bqpmp~zcI%X1uS^*8XYK7&$j+9X*8B0QSoIYy(T}&MTyIunb7TH4a(Bkoz506}S{*+3z4`I72EEUzy56OeH`+(XY*^E};(!Z(f&0BA zw`tr3b1%<7C}wP^er9j6rigy!!q&I@9!~lf+TQ!hnJ;^x{tWhn50jXie{rbyU5hqW z*GpsBJ}Ejv?qT&;f!LqBmx;t3Pc>BRmuQqjw zrn1F`&w14S`NpA#^XsyTww(68&R3i8_KNa@=hwuZ&#tlT{Zl2|X35{qe^%+EEUU%y zY`dv)J}R%6b#85Xb0crcmWRA)=5{?Qk7Z5!nl7nlpGs5MyPU=5(C1qgd3hf%9!R$^ z+?BBCwY1lYj@PgKwPyG2{W)PmH2dV{U0zv%zh2j{-BY%HKFRjM2I>0APZjd#Huy#U znfFVgxMqvV>Ar(=VlD_5T-~SW?ILk|`+B)}`;OeXz0!IW+iPAJev>XK&HE{#e}?(? zrl>grQ?}Pm+Ou!>d84D(Ys+>UlwEVk-m3H}Dl4<+!JOCJ_5VC>TzmK9lI?D`w+;uQ zwevd9TjhUODL5%Ev`}{O=ek1v{-ctX$$gTR-s>aR-|JMKa%HvJ6T7Pwo2O|{l;n|g z_u3)4ecAaR^IF-%u>oWg=Zd;jX9_f2)8DkFZeVwxLKch~_fvJv}iXYTVj$c2js<1W5>)oWs9KF^D zj)~awh500YxcGUqPp@IX{A2G5{4Rc(Yih80;}xD?GSd!}*F4X4l$sJZVc~3H+4)bq zSAO($TJd?-+UZN#3bLcik1F-AkF~hBZ7cuQ_eleOw-@UCFUc{&v^Qr%=BHA z9MAU_s&U`m8h+~dTvtoIA5up?-`$t>-QDkL;!nZfN%w_co}cyemOPJId$h72pE_Ua zwb^I&+IQb|&5YqUKg+T_C|oXPxw>%D{SB{6-YhwO{_eY)n=CA^Po&j}wO2RHx&PPp zS=9%dw(>iRejEOH3|?T=KmEsb<|pPIl?^9cr>=fpBpD?ly^STxY~kMo^XVT8FYhW^ zy+1E*PwmTIr+qK`v%fK|xl{Ob$;bc35pfCkW?B5K-+V2v?D}2HV419%?KytS)31B) z7LVUH{qv&_52ZQy`mg<%$Yr@(e#f2}tJ|4P4&U!g{oa1K|43_F;Gs{)wr#xp`p9DM zZOYEgHiB2V_viB&{SwTv-;gk)vCq3Fd-b|G7x{M2KT;K&vwg}1`_t=%Z`L=x?wH=x z!o1^!pWVd5{@M%fOBZX|eRO=574P->-Z8eA*_wYobuNElvj5*%*1)#MPp*CbVA1uF zrFv%a9Q)j_2e&%>Ir7^-;rxvApR(Vry|~xE>P%qqE_Ioo|5RRGxi+`tU)_o?{JZhMkXgxuIySmx}OzVElxztEhSl`CH^*}DEt zr1djD<*5?uvU?|`2E6TFYx`;Mc{8R+q3zE_9GJ?D*KvJZ6KIg#Bj;0lV%f%xi*?0s z^zbX>mKoN)+Wubl`m@sb_a9&U4~;u^?xdE{`m+y$+@%b=*hh8roE@` z9ap={Xwhce#1G(zRB-XmNeX6BslN; zLHXB@)Hgo7Wo6%guV#++o#hGzEBX#Ku3NWe_4+@TmLE9CxIoTb?sf3|_WO^{hHU$@ z>PMt<-eyg;{W_Dr3T}_M-6M1JP|+mz0=M^vju~t{kZ+&ad;Z#Dv-Q8GSY!(sy+3s5 z{(*xVPld^T@>jI!{=Owl@xg&3am**bOFyf=tM;z;pE0|gA77ktnfUs$walem+dt0i z;QzX*Y_`O`pKI6m|9cPV6i2_0@7lKg=#H1E(>Je8-4a)^NwPwDXY7{ZllL~-O<$>h zrc&zmyn2;&IeQED=)ar#xq8En{`cBuKigg&3{TpB_ga+9og0&%O@Gi`Z2mhhVC~jq zJ)I!W0*B3u`IL3+E=?{zqZ_|td)C+LjcMB-O}jg_dg}QpZ)@YayejzfIKT`N{I*`##Nj<-p>%G$+a9K&x)L zcmJ0X%TtFe|H_&DczatklR;Bo%Gz)5BXhwnPMwR}<8!(aV-CGt{CvmlmDZoH{!{(F zmo2&eY}s%3?%J>R-MZpelSHlUroT?^&6WICxw!mbSku!jEYGCgh2K9`wO^Efwb?Ym zUv_&`ugAW=@~WrstE}&5>(@HIbNOo~9A0=L$u~(yGP^?M@9qsN_s`XC`DLLtBe_`R z`Ra44?tIUQy!|;&qvuHE+l|jN?2q;29PNI4hi$FT8AqA2+wPD0)aR@Zvp;hD-e-%- zlCzfEYi~sSww$Bu%if#4q4oHcD<^7qhV6JA_~y06`@?+VrN&XI9``!m%n@A`sO)%nkh?hZ}i5 zp8dS=XppM%8O9iCt9>@=LDR!y?GoNTl6wEeqsMxF@c(N&O!q#%zDs4gkhQFD)cGWR zop0+icbk>pe}8b-vaa}?SL!R-F0O1k|7ezRyL)Y|L2SbJ*)gRodJ&hbq$3_BMf$yX zd)(?=)6s2rdZcq=&80XZmp!gvdVb|mXLj_=+00eiwJ9Z4pDf>nN#C*he@D%UlKy^eR#s5pQ3weKO@^+{V!9z7lSc$3k&kI6wl znZG>x-^OkGAH?%N&`$?f=CeF;9|J zV+|M%UfOUXZlXq^>f0QFji(F?r;8uom-EZx2IJ>iC*hlg!ZR)G`&&QfO#0-^ch5&A z^|a!HKPt=BU)o4aQ?}@_h`Ak-_0cUlCt3XWhECJ--ww?>ZhUTG5$C^%=i)#Atv|eq z@66++E2H9qUe+c*zItd=a^FwO)Y1=jZ#GTq{&6v?z(>u2`Tkua_rL=eH(Thm8DC#h z`0>Oq!z*>o4ccq1WHyvtGW&Osf9lTUZlz_FN-O%m^ck1!UL0rH?Vr=#Y|LkQzbwMM zZo>18H@@KwNCtB03&aO8@_{9nw{*g0K5GTHmE{;tj8 zdpOmv?$a}jFE0LJmD@Ah`IYpU$h1E>LS3adZ(B@{V$Znfr^j*n;A^*t8%c*bV&2ws zSwHw?!2W!d&foWseAlY$8D{iF1)RS+J-fO%%<#p}sN%mouT!@7hu=6>)+5Fnl+`OMBKfzS1?7WZLn&z{On=_>v7EWEwRxGFKuAH)a!s&w#-XY=wh-dBOjB!+G|eOU{4YSkm|4 zp#8%Kzs!z(sh+3gvG0dc{?2JXKGwDEJJDk)cG>R6iR(5e=N~_Oaf3pm;8rE~h}RM; zW#*Z#T4;Eb@6H>w;|`oPsj+{$xVM@4Z#ccLSvk#ehMnDJUevtaLY>y8K2 zMt^5Vh&?DM%Q^PU{fx2R{(z7xkqMpkYqQ@@Kiuq|@Id>F)eFrVTTCOiX)imlOgrGs zc3tK7+smBhT;ZN4J6YcQ-zTe+dL=j3rSPxrZSSaT+Mc*b@RVusnb(SyLbp90>lHHZ zYkGEuBWa)T?w_ynA0GJN+{pGmUUEh?lg;BfGyb`+=ac#Nv((ve-NO${qGKd~-+yKG zNWM(=8vpaN`9D86bS3L`Ewi}}9@l zy2VeG?+NP-&5w#O?$2Dq?)PG%&;CbB(Z{;qpIrWxZT7T31rgR&#ohw_8+EVk)l<4M zJNnVJ;}-0yyU*^lV=%INd;a6G`ksIAxtXI9e}DYi)$!!KxpJ(}?@jyJ9xj^YeYvYw z_UEPe!a1zFZS!*;`~ByTeG~S_cg^Cg;!D>yo9T8r*!?;GW?J#$RlLkw!%nGNB|JBa zeL6MNKVHXBNB(|k;rgdX#qUgO@3c02TmD7d$N%5-q?HkMA#Y9XSBWKMz1-*O6(3u0 zqK++^r@k%Fzw@|!f5p3xIzc~;dnXj<$ameJ6CwR{&pP3Q-?$|zzv;_&<@WQJyo^si ztX?WqW@qOVu|E9Mg^GtCv;20eH|gXw&+k3kd*{~74)-@x^JDDiEB_HWZ((RW=~!WT z{Lgpw?Az>CxYr9M>TBIom{oFiyTrfaSy5Rxci#UjZNDwzaKiTY$188_I>-3nis8qO z>PL_EyjDwpI(zej-p|^L3PQuetdrCtpIcw=y<2?IiRI**6@QJcB}(hrG9C$?csS^J z`nhVph{=Z^e^E$E2)E|iwBd!}%03C<%{#7exT?%!m*t6$V19dA%6IbbgE80JOAeW< z#2FqIEvkx2T|PHipL3O~)iZT=@Y zCuLhi&54~C*Yb$jwj9%c{Ht`Xjy~VvgSWC0*sqB_`qpvu^;*kq{G3%Q&Q9C#t+uyw zW_C=J`E_aS?YkB}IHdOGA`i#P?AhL56gQ~YoZqsu?eYDu#vY3ctM-Ro3qE}$=CgA9 zgT3#T$7!a{Ssu6S*#!^(91G_?XWaVZpFdtxyy==-?$XbD^`5UOb-%hWsjl(-Y@zQv zDq;%b04eTCucIbDPnx&sE2sT{vkI-g361O2gPC|7Yx1 zp6<^_(|2n<_d54e{Ymiui;OEXGGSTaAZmhoGeb4mo0^xtYI#t)$ zCL90boVoK=Y2TBLw$HkKyJqcFo-bUk`=j&wtXS?Ph2|AcpT=yTQ}OiG4XebysME$( z$1YCHE`0f%*IM#vl;im)8&|F1jSKW!pZHPP?d6U+_GTr~RR@)hz0cg>8^|U-!L;Dj z>}hAe2E~4s+uyE#Tc&Q- zJ^e~&_O(?Kw|n|O+}5{B2>b5iyW#q4mYUja{&qDL*{=)_UYNc<`=ok$;hJq#y}6GM zyqFOmo%814^;!D@m|oB3=P8Tbu+X&ZoLyi2W+wUkn15%p{yXXDxy1MEs@svUV`6dO z)1+yB{QJM#8@_7&+9B#CegFQkS>LN4S2dqhdt!6)r)|Wm!})sb{%4M*e*WqHzl{Iu zk1vt7?;S2KTgKCU`M}%P)7P)u`bXiB|H2>aOU%Q9o+&-!_Rl>VUVJ1*^mgT{|EBH= zHvPspBekDd z>OY&87#g(IT5Qj=>91exj`%QBd3yZ1b5Y94u{TcLsR}MlI9=V~y|MSaI`f`&2R7+V z^{P)4j7c(PJALcZ;ax>c<;R1PrM8~v_ZJtF|CADYJuG*z@hvk)q3Plr@&BH8ujBkw zI``*hw~w_)#I|0~Dpu9o%JV*<{LG^bGuaDS|3%-3x&L%d)b_Bs_0PK8&ZTGbPFNZi z8GZhf?z&3*B;(^Z7A_9!^^Yj{Glj{vEb_E8cimdvmm6>I_^^LZMZ$ioZ#Qd_RI8WW zyI7$0e75G(T)WNJZ`xny%AWN#u_&R`_e}oghhKS4Us|zeZ_LD9hpib8xEH@!+5U0* z4v8S`;P`#IvOVh;E3eDGJL5{uhG&L_Z~d#?J}*08mA8-2JEi_(TEP0rNwMiy*Hl)` z+c8bX*`4RCvr(4C+Tt^&iNY_fjvETTyY?uw*jw+7>>;JY?>k%H?)_^pZPrQ8&xhjI z$G>9Xye3na+~IiXXxT%xRD*S*H!e=!{94I+TmBAn_1{x<&-1B=o%{dX`1<>(=?Aan z7d}+(@46|!;V;Yd$B*RwCQ18$k(@s#vGZ{$TBe**vIdCvHyJBjWw(PXqLTl z=$Wg(qad~4EIo1M=jZ3=@BQ}X40{D%`JzzoT=1jR*`c*H_1gNs5tC9 zzE@G8B(o*w-7~FsbC+N7`dOrV;<)-z#jmH_A3IIcbyU>u zuN3|EBi=$fq2x#{`?n*fm;Oz?f3o&QNt$nBbaj&TlLU@8HKLoVbKiWt`C1_V;q!xq z2Vx&z`(7!}`-x#qqRCFaXHwIQuX}zqV!wIr%H4pcd)6!S=tUGw+t0q|P}^rw?>(l+ z{U1G&KlVfUeBAzN`wt0m$R%8rw!Y5vL)iPx)wb>0DlyXEH|hV%oO`-5aign#!|UTe zAJ`thRQZ3x|D@@24ZddoDOetHFs1guQ`2b`5l7no?Tx6}X4t<)IC|cj_gijlmrs0h zCBNeS>lpiO*B4rH|7iFs-LmA!zMi^ksyA9!D}R4;Hh8@$|7Lgj8{97H53iJ(W_w#} zM)zKS(x|%bdHNg)>+2uHV-H{Z%{D3f#UB3qmdne6wG-#$hrPVDc;n8;@BY}I`=0|| zma+Nk-?#UQFFr~7W5mDWgx%}cx6|{Ae)5;jV|~YZ-1n>Gw6h-3M~zpQ3*|HHn_2&n zt?F3npH-%M{60CezTDY$>ZfMeoy6nYT;2$ue*DIMetPm&^ECt$EnN2Ovwec_a+#O6^&(!akvC7Yzq{e+mj9tToW;SpXNAnow_khpr0Q6z zPwj7kLqF5+&iL^?c*$4c_$CNT(Bc(E&^Ql|3o}=J!rA^x{z)5liT5zSMv7AIaM5(_fpw^z5ekd>cz9o1wOtN?>1jE zt@4`W>!bD$gZAzDdE&-RA%XtVLylIXtrUsLSwSUHD%{jJ7Zo66%jj_4OzsOvux++MSpU&(f3!KvmywtCaH zytOWzT>N-j+m{dg%Z?vY`+F|XVzWPI^Z&06UB0il!sqWk|LRW0%Z`w91r8T>+|y>?{VgLob;|qc5jOSLqGIx^ zHht^#O8EKWSAox=T?sEc&u{$@`MoXwu%u25=bSUOkA5Wl4S1WqFyAI=edV?5Od9LD zgdP;?%)9rM&2!$3-_`CVVkefbjp{VMzMy_$S%0@~@&3e9+jnO5P0`-?z0Q0itFs?- zmfxqvPZfT?k=``K`gf<;C$}BFsrBdU9*fU#uUmIJ z(D_+=%)5x+&+X3N3*7X~#?+xE;o#)Ztgq{@ZM6`y?zepwrFY3(&-Al?_J-?fXTLgl z=WPtWGH0>Sv}}dzm->G5bm#tk;H+*T@;&D8k&m_oSw>k$ra#-zwkqsO_P0nmt3St7 z9kw31;82*^8+-0SQT~ajYe%PSwfwO_uK&qt{mN?D12-eymv+XA7|NDUT6pfkFQ2S6 zJ)ie1X1w11Eoq&1y{NwE4IA?U{=0Lk<#T5 z3$C-i_L8xC`R}aho4wt8`lbk%fBO?Dy-vJ(?YX^c8VdB6P*8S_+Z@$m^EvM6RV)E+_d5dTF7VMo>&-TEE{st2xN!Dl_YT#TxsQHE7#@t9+=PjSM>DO19sia z*QUL?$$RF&nuos>_`WYbCuk|y?H-x-N`CFz%?n@i7xsML+xR!$-lvn{|0%z=ZMGk) z=luL?>v>(UdOnA?-p)^(b?5iWgl8Yh4$5AWUpCENCUfrMbUVA0`gP#;)6QG}+|KVT zeC0LOzitOd<>!9isT*hAf9f!)SJiB1L~?=ct4a57ER~9X{pacenYfqpPj~LTWf-&R zJ73G*A6dM7Hl+_6Pf2%|DOR1%vz}%wSNkyh{?vUhT2qtlW@mTz$o$;+OI^rrqdjAL zaPd#cAGakYJ!03cD>}C-NhT+ES6#JV{GDTL?R{al!*4{y_IK{8&CgwCn_uzt*a{B5 zqtaJaO_J9r4rZ1AU9?jETHvuY>T*nf4jkuBIWoV*_m}YA@|cewrR5J6Czon}HN0CW zaG={xzwS@d17X9U-L;F4r_Bnvc5UJjp5M*>(FyGjoxRtkul?o5`Rz>uW7F8jJ{Mx6aA$ zHu+VZXZfCc+BL1u0(~ED*%`^-_*^jEG|lbP-oMBDyDN{(d-&=?{yf3Qi)*GolsXah zSkAV_bS1s-SyalrH%4_I zYt7CdTp`0hzhX*`vE2Oh-W+vlAO7n+0%}he;!X3keU_#NqL=4 zWutmwv46{s3;6x@Zl=lO zuWix{g#|u8<9_nV&rUxzzvAX1(Qr9~?^0JgzP{h8lo+;;UEA+kNXfUh#m3+GJ{BE` zv3kM(sK8@iocEzy{7!FKbN?(l)4#ogv*`5Vviz?P!eZ~6ZMjxx@~AcY^<$}XQGGsP zVy7n5J=L?k-d6f*`=Nc7=XrDwoOrpR{+`?q`469XKUI}geKvLH``mnPr%a*$ms7=G z%K4VBeQaQ!Gb6ouxl4AQ`*)t-OG4I7`!0L7)jO-av(bOv(OLYp^TQv-ABpXBOXG zKJQ~qcr42v{m)0gugLb^Tf%c>s{es31A7knXk9%i^)q{&etu=28CAUdM!esK$=7GZ zn|v2evftLJ+#3IT-ScFfc!j=*3s0_OJ1kz9d#|D*qj_m^-sjWTYz|M(e!l0t^aD+8 zpBZo0Y%E{O9pXEu<#4{G+rPp;`6~|`m!AG#*Z8BH+&+oTh93;h=wGb(e@L3~`Hu%( zwzmss>00w&I{3`-nz{Fd_P0fbn}lEAUs8WrHdG+~&if-(%^&mm>+Qca?qYey<8J%n z!|ZGR{+8yOr*34=DKptn({%iX<@Yo-TQUB^iK44J6DOyx%lL81O(W-LGz{_`XZ$(A7sa@S+6_iAlIMf8*9GS zKDK&nbWHV3ZOomAo1Q!BTyN%!`E`MLS#hiHUxnoh4^MNO-|lmEYqvu7(ZlhdH!tK@ zQ?0o-;}HM09~FJN{SO{3+BjLda$5PHrD~mfm5rUwtFwP{T2q;Gzo7DJ)74oaeK!i@ z&Yd^-7}~z^>GrwY+BSEhmrs7bHSeVPwj-hY*r)B>nfy@A`}U{Zv31Tpyq}b#FR#=6 zmfKc*cXQ}Vl{u2-wU6_Q_1Eovd`3q3b!E~LwWoLLZco(TC$0S>K|c9Vv($q2^6O5Y zSWjE|=AH2SeXJ~0Y??&l54+2|B&6S6I;Hlw_3AFAf2^~eqB?38H?vF6tF9I3+YuMN z(09k(f=3p@@vkq=zxRFi&nMmCJYU|1i*DTgxi#n8^E3L4M*fHHJ)UH3v~yEFZ*2P9 z+Na`T38tA3?so9DEm_+$Ls>21|5fpN)r&LMm3~ySm$-Sm|Nh~Zb<<6ID?di8pTS)E ztYAli`T1J^TM@}0MBCSI!9Mb{<4ReYyRZewUp+3y>X%D{Zq-)*UvvoeA@e7_O$8o_WC>Ju|9f7cVAC@ zZoEfi{?_xWmg(+2)?2I}{PbM^>qh^nAD*%%nLBoGkN$1B^z*Og%^!Z0$MnwrpZLq* z&DIZcYo15TP0D@rWU@h|^3NxWp0(}TT=xE?+{IW`(OZ?bmaBYN|M{?(f8;#tpU>93 z$-QaYUZqx&bNZ&!`f9};ZCjUZ`208HT6yl?c}qXvc_14eAbijC>EeQh+Ic%St<{@* zgx%onfu`kgRZ)yt^(VSmAKrNNcjj^7)3+jCbLD)pvur+|Z)W2+DLc9Lvfb>DZ1!Ax?aUI1NZ$23*)N!57~U2+IVc+C`q6>qZoa`*KEzwY%%;@Y-1?mW5m z`qXFFuU{!RSNw(d!sUl&R~o+BZ<+V0w$=BWRoa6+HTEgzt{iGFUAnC4Y4>EOdk0oc z*g1_&{>I^pTa)Z&D&OD#{9oD1&&+3;Ee;QujCWTbL>Qcxjq3Z`;W| z52w4`3!XLSKgYGNMmdR+D(m{@-CuWjZ`_8)LwSeK>k#e$sNj zL$}3WyY~KVUBBGd;*e{S9_%at_qTfwaw}#VeeV9Aon4b%@}czba`rz}f_k4a&I#E* ztp56~@S8ehjn0~P`JdjNo^tlE{-Gkn-(A<*_D1VJc)4-?q_auKc50M9nR~i=^4!}u zK3`uwy_a!@Ud-Q(Q_g(YvQ_r$qvQUmJ%<0~zTIiAlb&|r(Hr*1;&bAU$*!^Y`rn|c zc{ST>+Gfk;CRs=Rn(9R7&)F)+`F-Aw{o>ws&mLUZ`?LM{o2Tc#3-dod{4+@Ag3)us zWs-rrd$0B;$!+WS$`w6#`m0sNa(Tkxes@0w1pNM1dD$ptg5ZAsnHz7;DY9JASGSe< z^RK?tyhS_vJ{3gsC*>QMXC8AF;h${$$%f^;bC~awM@JrQG<~&o>gPQlXIdQ;+-m?j<_e*cJT(b6n-%KX!2batEZ{uRCL zAKK_|`Dw!>o2IUsm=&jOa_ra2mc5a-dZk_*9`ant)H`?m*Vl(N^h+Gx)@+L{{AIkY zIpp|T>Ee5ivnquaTWqRt+iRcF_g(77#&W)G=4{q%olMj0x0OYzYG*4dANFyUnxY@U zx$mdr`wQ7SHa<>HYTTMvW5{pvJvq7Y?HWP(CT>%i3C|dX9UMQtNzsVwU`o*`8IeV@c$cl;g%5R)}-NGo%y0+`-W!?`LzCViSh%Atp`}z8h8pXKi zqF7T?m5bMJEvs7psaF5mWEHDVo3GD#^hBB~^7t2l*IyO>rk^d`o?o=}UYYw@w~XED zH}1t-v7hY?c(x(#&r!jzkB-jzzcx?&#pJ4<7iTBZ7Q{6Atfq0}V0P@C?PwTCo6Re;kXE@Po-HtVxd$+7PvGeZ6)oc;IYds9BH`F|7+2pe}`s0SDJo0}` zdEIUZUoH$}vWdzr?mDgbDYT~G#Bhu5=!=)%=S};GxLPZ&yVXiIQMc?C#|2s z@$^ci$Ma}rudSEMfA*cKlAo85y}Q>$>!aW`{x7xmi=Vxgy6tiM>W;jcc}E`H*t@Cb z_T(k@8Qboz6)fC6Z+Zap6B8!`J170QuU+rde@&ai!=o8+D*fl=efFj1g(pRKTTg4y z6YW}@COawmzok^gytQV_dkUYP->`7**9$k+%@=uara!J`zOCe=dea?ePqLn#r8A@H z)Vbn!=35zfxc~K$N#t@)uN2Sihq<{^Ndc-fOBS=FEvn&Rntcz*+k}is%09GTZv7#p?LKx}J(h zUY+fQ373uE$^I_q*6C#vKCfs=F4*tT zD5Zb<5ubFv$EJ&?jihB(wKAV?dolZ<;LX{sg&!;=-_Gdk?Je&+e9Z9V)Up$$Vf+5e z-e|ttUl8W^b6(dz>DNtv!V`;6tM=c172tO!EIN;GV`TQGQ}zvS&%W5RQ^0)V!=vY) z%{4btTr$;k%fV^eUE5NhCUzF3^S+Z5JDl)`Q$W#d`v!#vKW+9tW_!IjX*&1w%wF+B z`{LX$OU#}AVp4v|!8pSL>*pM^f8?!=OT0L}T%r6;@wtPc=8={2SLcLRoIm?)%V(R7 zpO+hp9bElwtL6E{?ZuV(^QCv6+HlSNlWc$U*_(E8*^-tPZZFU8IJv%9>a}ft!MWzB zXGyQW%Xn@+d0Q@aXME|C*_NNW>+jgE4)!*kBfRy-yhht&QnM~|>$H5~d9^J;swMqr zo3z`*wN;rpGx&Fk>+RX=`7mGlNF1Bvwfguoyq{hji2KEMx#*?1nBf=GnxqxmUvum{ z;;XA7Z=Jem_KNgQ@ci@N>O;4s8NR)B>gGsiz!pY_IHhu{3m9|dz` z{v!n^W>2t!CuIWi zUZ*POnw?$w@c!z<|0K87z3{J_dV9a$iB`9`6W5HVecp3!Jb|EuO#^OAL{?+?|K`zcIf`^zQ-FdZ$w@pyjze9!Mv-ADUm(;rVd zS6BQlLuv0~yW^5&3DL~o7pAs%%G{T^*lwF>-BtJV#f7fZ_RIS*H?31FZFAl}@AEcuOelARv}J#Ce$XJF5(RdP)`@^!!L&I317 zUY(3!=fD5oeB;T&>z(P7bj<^AEg} zKHYcQTz%$h7JcoULo?Zr?z>p}X_NTVCp8DFT_*^B`(ncO;?|Cb&-VPi#vXp;+eaDc zzhBQ=C~2#^#@l=-{B)^1e(!nbxaZAG-+q?FJw4cZ@LTpv|K!Q_I~+HBwLLlS@v*z5 zeU{6*>jzn_K2FeFx35WL|K&GFJ3qIq&pr68^*HNazBk5sUwgB^e0#~d zAcJqlygRn>U6*%!xn6zg+SJvBo3hV7y5D)DfAcGogt8z0YgI1%GE^;o@=oLZjd^RI zuMOt7(G;!oD*dOv_;TB1E@R902}%Ep=JzsxD!nT+A#v5#tg9{$j6HcSWwY4%xwdcL zC~>Q3kBZKD{&oFxtnTL}ayI=|&f9TK&i$e1{lZ9zU%?SIzgT@={QCRr>kVesEVGTm zM-N{AVCT_$)=KMluBrL8!p^-}ay=i-v=vQ87&;G+)$Jo=Kl{S>TKO|(`meBi*LHzdtd$Y?WmxBM_&eX{5-h0ve{C<~&=$s$R z(td4X*IpEFD7xs^<}jV6JHH#aqkOX3byXZhmCEP;fr@+2b>k=GD0|g()ZfKU`7!_03>e?~f?& zlf8!*ES;pdt@FL$t*5EK&l=B_q+I)nAnZaVi#0hPd?|rtKdM{!=w8*1xlped%^am zuIR6(PTaxyDQ?diwm07|*>`i^)-69DEjI4G?RT!M@ot#<_o-i4v&0`fc3$v4LAp5Y z`-=6e7A=GJSTD%8FE=ZDvxliyxu%b2a-a8LEx zQQ7=#^^cj`7G|7VEN^45RQLP)qio;qH`?y7m^$^0YvHm}YCqTPT^G8h@vp|V!Vho7 zEktGhuHIq#vs7o^Jk`HG*H#?-qWFJG+8^tUGw0qppSH{@@s(uT@w9`!+4uiv#q3RA zrT%JlxGMjx=@px-O4%zO$vfEGO8qNV-5Wjo%hB!j$|*Iy^}pDPf7zAx*Ol%2@XPMo zPv-yG^IVSP-V4Zmr{4cP;h=f{Zd?A-xBnXzcbrkYk-c}_96z(`RWYU)1?^=XO*Xvq zDQS6ag~EF)F1IH0=%UV(b3aRdpY?p3`#TRi6}ww5*A1Hk_YXj~q(0~Eei!}t(K_|q?aD_!mFnAVYoB}ksCVhA z?6MWY>9R{d&RX*{DC2`q*=6Iv@;bMDy{iA8e9!nEFk5-a=Y~%;mXTkI9@{3DoUf6v z-d6IXLsrVIKW4+?z2d*$cGny@xc>mhH_7#~))T{Dh-%#Un7}qW{>P%*M)NJypD6yh zGV`iT&(geUdrtgaS|L*M~+DT{oT129HpzRI&8j+ ze0)(gzcl*Y)%W2G{c-~r1^n5+Iem+1o&}4n{t~Uf3ejG#_q3l<+aKRGIf3EZyp3~j z$caabv^T}wGwJr7>>#OIFwMLk$=Oz41`^!Qji*xr5**)O6-eiBW^8Do^m6sA9|DIW^`LE!}7n%7NY?d#HSf8V0Kc~03 z`5nuJGhQcVw@tUVU*2c_JmF(UE|=_ogTyUom8WNHJ+^hCzg(`IDtDcOO{7k z6X*Nc+Szi3-0}UBQ7vU4ms7lc*FT|rrLHTQ?{EB_yFn(l;vd(xC3$~U-_4qFn8R=C z{U4&Q|22I1zE05dwe8=yxy8LQ3B1yI`is6N*1px*Aal3VSK^w{syES*{EMqRwengY zi_d3zHs`hL^GboO-1Fs1AKCauH1VlFiEjTBaK>PVjP9-WU{#G8y?c7U`X}3mgELD^ zZvE`^f7|zDzdl+Nm$^Jg?^@hi@ei5hS`!}UC(AEB_N=FieVf99iemcg_mTZqKIy*cl=pu%uke`u zrz1LiXI3qK{mU-LE|hbBw(ZB#U&rj%8od(HDO?vJt@kckJZH!8XID~v;;sg+e-aY= z`1rFszh_ndj4fOnT5Er8)g8I(pO5`B{vW3KlCL=J;FOoUr%%Z(O}@0HPU3aN<1L0C zV*j7p$~xm!hx`*y`$pKaos^J{nh@5y}<7f;U473A}9>kLw3 zlZdLn%Cqsqjo|GSj8eyr{f?=>)b^6k{SNaUozw1eOP(Fq*Wl?3thl4>Ex}2)yLP(;gimpD4f`O^?}WLyA4n8)MW3hd3@gFk+9G0%+1$!Db4+4Ef)T#Fz&x6 z!?Sk%{WDuO#>=Q4Iw{=wwqfkkD%2lwe67n`H6vv1h@;m}FGf>qxxM{F{#S^L^pHfa|7nU00> z|6eZu|2=-MjrjG+;`kBtI;%bCeNv$)aSBYfxhUDwcmVtu{I+6!OZN-mBp-xPo6 z*y?Q4$(4`R)Ctumto*ocLH}2aP5Psqiu0SA|Ec~@y>%pn z_onG4ds7>;f>q0|&3k%s=lo5{sg0}qh1<20mwp$LTB9D`_FOvrS>=(Kh~E>Y?{oHQ zC^rjVX<^W2_vm-}tKUrlHXWz8{4w7XDtUK@?Q?map8_X;Y&=-Mc>ko?%wL7lK3Zm# z&OcurlW@8%YVHjU%U!ldv(8JU{(4;TP^a?q<~ciKKX-4MdF{noMR#?dWx zo(VPciW^UF*&Aok?p~RyaPT1K?Cnx>^!MC1`gh^)HSpPz(Wif=&w2Xjf~&dsmg?BT z>ucw1z7vyJxPL*F;^RZ&uUoTfo*(^JX_$67_6Dn+Z9}V1ivHt&hHEz0&V7G*$7cJP zpJwKFeJa~$-(b3RbJ)RMF|%5y>DZe}SSuS^> z?LFiCTEB_DPeKl|G5i(vEZ!_}(O0^5Q>;bLsZ*@8gRb4GWqm(7!CXoGi>$l0UvkZzXuQ=rHzQ2mY~J(5(tF=-iHx`&m3$>Wc)efs4%=Y9 zx#mx2?foKroBwTFc&=3X+l%~DB^Bk9&zIjyEa{lW`y+YI;Q*t@sZV3L?tE&U$@r|U zyXNU#Dzh9NVsMMJj-kNaV|}w1sXu4De@SV1(cRyF zt~~lvZ1hcY`kM6{0_$Jh^pMlc5i0s7Y`>vzmMG4D+E`+-souFD_3`yFZTJgr<>w8s@`~UKrWHrFm})S zS%TG%bZ36~7P;^6`d{z-?|qBDmmGg?ZuHsHpKdXQSYJ>0toiScOVJu$gOk$cVdD2s z&3Ml=Det)Bw3r2a%t>PVkGM}bGvB&+o#pH(+n#JosjW`3RzGw5*!OO~yM6~#zI;sG zQP%%C4=p(JQ^ZBO_tbu={+U$GU{*5ifvC9sjr7KEDO+vN9GZJ~=Y-yiol7=NPCxXo z?1bvDhsmBb=%=zxx@XQwyKkR?dY0u|JH4HNX=jE1lS{G;W zsXedqaM-*nA*o|n3H{G;h{@0z6YGrfDyzx^nY zzwGVY6SwAXT|1XOU4GA^?bpj+i$9)vrm?rDBK*I)_L=<|IT~O7OkI2=hgT{2wD0_F zW_@SZ{Z?m z%iCU6ZWoH|Kfm*(lzn2%>c5uUr@hZ{GE5g~eX{xTJh}C=zs>j|aV3-Q^s}aY2~Tgo z+iJP61QZMffj$MaORBb3*DN%diqW?5iF$W{z zA4ZJr_cJ!$>UFUE^yiAmf$6V}6KnH=>#J|RXtR7AZC#`3zEb~+t$Wa{^5b`ob8no> zQ7zwBqLg`jWpQ!$eD|0SuDZFad%Q)$Ll!XoPM&=0O-!MI!s_J5w^X07yla&Go}gZo zAj@bs+56swf_EMHlLNkgI>vl;hne5;+}YWxo9$PuiSQ4(RvD~fn)C5y?aXI4-fXtZ zNo^>+cjGAEnP#t=oAen5QRr>)*N;Nrf62y`2^va)y1jhI?=B zwVR^*D|`P4`APgdu)+_j_uxL;J6oXt$Xekw5^kSg z-| zZ`+<-_ZQBal;74z1QZ31GWnAGxqrN{W#w!P8cVJV=Z(dYli zHaR%r!0XztwQo${J8Wz@y~_O2gk|NK-#3yJ2&t$a(s_ z?I$&2lm*spGrpkR#^a~+*Di%MI{u6CiSX*v=Y1b1)SbF&pS;M)-{!bWfl2a1tD3-> z&mZo8*8fLL`S!KbU!~W`zghkM_@7OCpGN-pbiYr+#O8PO?%T|uP5!(;D8lcAaiL8^ zzR^DQZOQZgTCNZBd*)xt_vGx`J5CXAr1s_ZU2~s#e(vOs2fcb#(v_QY18%Foob-9A z>U-V0wrB2%?7n{6){ir17km7UpN$W_Wc(uQ1xt0?&R3j#_io$P3y)>(&nqqO({Fh7 zzH#;Mnuv}q3Ykr&2dc#?@ zY#oh%;s@USkaqn+4!}q?8~jG{ARmFC95B^sKmd^ei*}T@FOL8W{=<8jjJ}_ zK6ET;k9)f(H`jTAZobfJwZ!D(G4fo__KCM*_x~z?yn5ZYefJ(K%>OrWT1430w3=?4 zycb*loje`-gC`Sw5o|sQ*@5A`tYZZ3t!I(ivFp!=IjjNCzhp;R<^8P%)|D! zhx>ueHb*mA`Mz1_kA5@VP`LJOF3*Onb*EqKxvcU@V4P1E@tChu*YCY@b>-t9S4|gv z?K&(M`}ISxrknZ(_FDlDPWe&8r>X&fK)IP}kp9$Z|b#?~b`UIKMy1d-`k1(deVoL&3Rl z&8fP^y1fp4lUddk3(ZJf&Mp63S1j#ZeB_eYh}fRH)ib4~Y)XBFmRM?KuKj9K)RgS+{>A_1_N#91JGlI*w70;@tLcZ+_*BxK$31V==O}vJ zUi2(9?}(H(tA1Yp%@=F6+iZ(^^RMiXxc@G5bD_tbH-9v9dY6eUf84NDH|(B%;rrxl z=NoG_YsY_{?!V_!(s|~!Z*9JI)ZKpbxZu^tW3EBxuik&>|95(Ou58(t>;2V9*5;4c z_pN+B?f$RceRkh=^6_s^4%GR5CF$`7_jS`luSXTO7~(Jn3x3p?!>D%YM!4{kBZlZ`sjfY!XYq zUYD}$TE+IJw`<|ntFB7|Bh)HaboSqfF#oHl^z=o@j~Bov=~OB9`!d-zwGw9-J#(bbU+V$?fsS|5#aC%QJ61$ba^SOiO;=zcW`J zt=(Lk>7FAf{d-;BlIis`g6}@~Q2$7;BFF!~)xOiQY2q?`t*i6-Qa_w3o3d&->+RrA zOIPk{`aCJNblX0llATiZCLx3mG1z`M#tmVddoIw&zCvI&Dnn&H?On!Hkakq z{#BChcRK&>vZ&d|xvj=u@4;>{-*Ss1$Lvl;E1 zpP$TadgSBm{ST$ea?bCV*fe?J!;kWRV!Zpmdw$KHwo|I=h$WW*71p~_w083;p+Z-(>c}g`*Oa@6(>AZ*IL>_N|})pWi6A)N)}u-=4a) zapI?AUfP^K^Sb7ZT;_4b;%r~@^NY_&J-YZwIOF>kM)S`XlY49)d#}%(@c2=W^~6@* z<4@lII5V+XeAA~@_phvpxXHbFV?=9w;oa?WamuC7{uUe-SP^CLbWTihp)B*wEAttr zpFMVSDQEsZmX|x?6YPGx?c;s?Wa=)LOLJDayL;QMoLiT8TfX+TY0o~(;L8i5ZWq_} zs9EQCXRopCKOpMe^Xu);t%Z-*{IJ|5x2|3*L4I*?O3WLzdtEb<-x^J|=zDYI){Ca6 z4>qixU%~zT^1nCiX{Vo5aC|uRFmu0C@7(gq>#~KIS$_|8b zFZMn1xJlQp`ke&di)Gnr#~OVN)sH=KX1Hn2Cunr9jm^1S#_HOi4d)dYr|-=bY7bz{ zJ@27$;+**1Bi0uAEptA|ruRA5+~E6k$oAe%rfSnh=#(R|QC@7p798->l% z0YCKaN$tLBu%y&q{!fv@GP`?hbGeVi8opIByK>r6K2gtf#o9Bc?5+ zKQi%ApSjORskn0RsH>KK+Iz(HdZo@0-S59lo=y8KeB;lq+KHR>#k>}konzFIy8fwg zP3%VR1$=c^!gBiyU9S}$dS(`%vL&f_%G>mVWh>q%&R%}}C5OqEzy7&=8+Skd5u`14 zcjCO?-MdB17P>K>i?gqp(sSB#L+Z~T6$$1)HZ(n7?EmXz=%=ilP>I8mQ~pY;95J!Z z*Y`}w4LGLtSzCGP9W$}>+VOmS(>5F_KfmW(eC@H*xpxlbZ+w{5;&beNVNJzOH6>|J*RHRL8Nz|;!Z1YdT?TqSd&F_s4zpw1v zd&Fd2q5R?dN$CtBv#$JDy?(0l`kfzNCNH_U@!8q*<7shsAI-F$Ir)0|*FB#7dwze| zb1wblwHmkkm45%btRI){d$gaQ`GfTRqow`4yMELM>lA+OXFh!Pr<}cP&;7IJmcpA0 zs}G)&VwInFvDxQ#O=sl(r?IQwy?(r1UhLgm?bO+|mh+P@aBldVBb)dAiax(y@Z(p} z&yT&5xg{f1e!82z@T%fL{Tn7-}952u9*LR@GNn4U+bFaw@<%UOfPQP z(p$gu%B0F6Z$M~;V!?w;p5TmW>W0$`PVQXSvtjSa<1GI z&vQR|!gtOwmwM1?z2iXBRF2HDFUQoCmbmZQ=)CVt`0T6rWoeezR^BNbR;Jt9v^Jh`SGl-w{reE^`$Buo%zoJZb2wgJ ze9-0W;*vJArysV--Ejz)?Wy6_ao88ieZIF?VC|xLh3{o|DU{5tn#jQjWVl;dFg?C&Zw%q zb)`9PmT%ZCX5l|qn9nY&&>{cmH%IeJxAQi5`#k3pyH~g3c(ZNgo6_1|p~|bz9~@N3 zi%wQ`e0|`@?1YWUGC2pP$K-!Gd-eCL8`(V$`-QA+k{4I$+zYt1QTg7^Db>mT5zkXX z7KpC@d+221?<;He^G-IM#NO`T7yNM}Jfk)ze=kpIhIv+dt^spWw@zgHXP6i02py+d+-(YZYh=9NFx_t){Av#_-M ze9Zm$*57Ad&Uw8kJ@4%fM`QiT=KsvhKF{2lY56&{ScvaOLe2(X9-GuZ8;`~wU$M{F zZDw@D3& zS-kGOzIwx+z!$TFpDz-+YF_A(_Sw(pxNOY%%PD_WWlx%OD?jGgbMI^GyQkKe9@8{<_?3BxZ6wp&_f_l|(Vm_1kRaChNO->vQ@4wVY=D+%F%u zPi5J&yT#WIn%rDfWP8hWN=sq>T0;xV-Pg8pe!sSJoz41pG169IKV}E%>^mv$dhEy3 z)6-ez7PCK=<~w*QBV+xIZ$D=kzy2>*_Hfp}BdYoKE*~u0ccyyV&v|VSyW!B%F#Wyl z^B-HT)3MB${MPoKeEpwKjb9VIZx-y&PCU*Th9N;z+!oJtJ1nSKkrBD;;(W4O1L4$ zYcH$m|G%Me&QhneH@n2Fn50dWUU4heK7RG2hev15%Vh7AN7A};Hp=jPoAx<4V*c$; z&)*_CYJIkq+EYKc7B;t@|NQ*?_PV4Q>eHicJ&1L`y85|x$V};z+&pGe(zk{uM7qau z2TzaIsjIl#{riq--{%`^I*x5QH^uJxi=Jjdx!dQwy&fs}8B0H!6r8lb=44fXp~?$W z&1{J`f44n0T3_OOQ2ytk-`gBtJ<=$BQgifAllRAms_~z0K0GL^_uzTdLg7BUw{qWv z_*TT7I4~#TxLEpeS?RZWZ{@bxod20P;g7Jo{SBkn9Y?2s4z)CYw>0i(Q^3019^Tg- zuQhpjif=_szI`(;X|lE*f6n7+_Wurf_Nl2@-Flsr&A;rg`9ZPEdpRu4s&_oyS9@-% z)&CC3Rd-Y?*D-P3>!BYgxrQYWscL6y{iOpE0@5y7=@A#aJCP z5m`OS`)7Wfdp>XZ!Al#o&3+zozA-aAMy}?*zwNU>eX+&8({r@rBYwIaTm5xcyLIiJ zxAi+kD}F!tbb9T3@pp5-&YiqA&#$!bv4wbu-!)6ivWJzb-Hzh2DSwWIbX$rayO&{e z{p375b-QW*=N?m&Jd+6?O0J z)SbSTS$(GH^$5MZVyEwha~^KkdH?XSwr-caB)Q}V1--vF=GD|RYyCf8s(gO=*{UGB z$CBSIH}pR$a=gyncjv|1|EtQ+3d_7bBObHijP72^`IEoR)IS_#%3|hr zdlPSeExmBlz%Ic^Jznbej)U{BeK9WUo&A;J`JS7nU7yaCe0(FHKm3iP`0Tg|JANLl zFG};T?)e*$ZNTqqqW{dd=5?c24((-cFUazTJR_e0qN%xxdR~oC9l%0@#yr+oyP_=2zvb^3owW&=f*<^my z&J#^t+gZM;O}%VFHP5Nm*{|+R`0W-|dHKY*GSvd*FxIb?D`(i2PndkJY}R=>)!QqX zisJ<3Cp~qY{5YXCTuDrP zEbnFZKP+B)?yJu8HP?5UalDT*c01!~Sw6S&fYtRwKh&L~EH~>A;n<2d&S|^cZ3cY z?9ln$$=!JE+GpoInRO?$@7uiaJttPZ`Olq%gNGl6MyTslJu|F$Hud?m4Od>t*4DnY z2p68RYhIz})WXxInuQ1L#IGf*o;g+es4(W{Y5$1&Ri@9&KURG6aXV7KE;>*4@&9dt z`}fPm>ijIqtFYVmk^j0`GGF?Q_gh8Qcx;~YX8Dfl-^XIMKAOYgr$7HS|AkYfMIURz z)`{yRTHZXhthBN6bq`aDJDs2=Dh( z=E<`^$DA*JX7b$X`MEzHo1Wc_x_kKBo`YMDl*z3)BfM6E)$jhl2flOv&U0qJWcz&A zAydzj%e8vkh3ij&G;b>b#L|O$oW?4&%=FeqEwya_A~tFHW#l8 zS=aymFRwvfe$#h;#wo@z5#N2D`|r5Fh{1o0se1gr4^b`8jh}Pr^Ivnib$*AEdele# zxIG1Oa~ALZmt45ncEy&kH<<^8!jI%jeY7e1bbhbbW3k=O+Id!{FAGf*SL~fCb4T~u zV{40K>ECH{dM;ahwds~D%zS=l!-KToH{7w!r)TbXaPe;TGp6)USG!+lygOKa=h@sj zllAvqtC?MM@M&FHa;Jaxxu+kqbgn+xRU{uB|Ksh>ORwXPpSQcV=S%RMYdyBf^9uuy z8&CaSzixU_-1p5r{8i`AuC9GG#gwyr)y=I9^3R>uvU|@l+fZwmx#M4X%~{7PqgwZB z$#qeZ>mSEzFOGe@=lG?K=S)+6ocW${a%W-m>(4W+p8o3#SQ9^Y^A<6V+S_L7pU%yB z_mfXH;>q^1?REF$>VHB?!Sx@fOEg|R&YG@oGRfLj1 zmhPWeAYngSeABt@#dU_}51aq$>KpiPecRpbu79Yv{FD9Tq}djglO68tkz%)f`{Z(z za<`wj+ua{?Zd|h$+qQ{cE}?!AyV$|3{OYX9%=d$@l}J=hnR?WZk%%q4zp;rH}6sk>VwZ~qFK8T(vj z`8wI-td>?+l76??=ttdqay|c<#%En~7a8MYGR4U;_WL~3`W`qQ`f<(ioI%N*C6QGI zGo`yUbDyz%ed>C9>oU9CmDlXn)jalla&40G_StUtn&&Tbx8FE*yTQMQji1ALo_5aO z^tF-YiAP-3{&(zkcSJrVbW7*79NVCIE!!xJbiyTg5 zUW|VhEmB>*!}e`Vvg*|Ah%?swmW%q&rmhj`Gyj#leE+E%^RGVpG4HOjq|MX+GMATc zI3dX|CiA)J($g5N^^e|8|NA!Cz~5XldH&g>Jr+Nb??(lQ$DKGhu=RFK&H)=lna*b&3xzue@Bj`P<43OWZ!?Kl`y^pX;HUpZ#vWje5quU#4F0 z?3RZ%dwwri9V0YhWV*5?<@*H=G?d;Dus|f%#|z$Vw90z=dT-zU zWs{frU)~cOVAt!r&*Xl>uQWj$^_R1Sx1Rs<;k3V(tpA+M@HMXG=Bw95sh*D$woa5a zPj=e#ck-6vIeE=RxeEMQ4`y|4sXyux^zF(mu}#@~*Htc`*89=)-k#N8BjRe#$fx+- zXVgueY zp2_t&=PRe~h`8{|+xELAtDOY@wAin2jQyLduZpd?$9>y9dCrZqg1W_zKA0sl$xGFo zdiZhAkCL3nVyE}LeIu;DZSHxgOCImHdbCt&S@q2s+;y$j&%b|rIJ4rzQi0H# zIH~p(9mcixHdhXNC+!MbHMe-v!3Sq!BV^m6pRw&bd)wyQ&choI3Ovu*w79ZHbZOP^ zBgbFl2ROainKw`FaYSV-uR#4*PnqZgimLv7>|*gJ-M2O8zR@pbj-E3bdsoK#yHbjQ@cT;#hzMq->l<`hP;l4SGgR7H0Tk=2UI22rt(LVRqC+)`x`K|lgUDwK=Jkqgt$H!O8 z>)$0xN4K48Og7kd)z|&p)$2RVWX@e$QMkbBMRsDW^rtS@>{d#Z z%Y5gC0b6!^nDG5#cAc%4#LJE-udUXN3DQ1y`TUNy0H*6RwRH~^+8;E05&A{mHNY&J+CF^TyJdXK&TM*Hu4Ea_U})$ek=N)-j7J zI(hh*oc*zPr9U{ld2Q_vZMKW?eY(xAc6N)c`bN%YXUsgVJ8V05bL+tf{a4GAZ*^|v zTKL7}Jo`FMt7pNJ)-C)t-8AQP&Z)V|HWl}Nrz}^lD6mb+y=lKwt*)R`(tn1*K1(Nm zpa0W3YUUJX?f-V+>h)ReDo1BFXHR;pclzo|`!BU$ZEinK+PL;_(T8oHr-nXw+kATc znk)0w1H_EETjgH&v3}_>|0MI+O3ltN!&5PEwSjuutwJR&v$7xF{kG~tf9~t~r2PGQ z?sECYjmIx0iOLtx;8s$9BYWD`k4gL-W5hM{>{G3iujP9CL^4^{G|YWoHmSZe!s3Y| zPfeV<-qvGfMFny)%I7_2@7jLs^t%&Zk6eClG54$1yxKb7X%&*%`J&qkJ601l_6&)#IZUhG>vOIC&akWSW$TxhJDhKB^;@`c@3oUxHzYo<|D$;Sae!pu z?znY@g@rt6Hhyn|v+wOJ@w$IlY4^37;%{el%!MD9TLnLtoBMnDh8r%|Yy3lg<@bH{ z&sNtgJEL27<6=bb#6M{hqfgArjN7^^*8Ro$IsWfHcG}fF>i3Q{sF2MnxxVN9`U@iB zu{kTvEnV8?|9DlOdPZhKNK(q#nTG4mCFG~Aeau?@|AXdV##euAbU2J_ckN-wRLcst z>nLcM^s{H0xuDgK1l0}9C)4@QS4W&qnOuCx;^5D$opxK)I;OwflzT!C4t#FA zb#95Fb-P@&Wkk<&OQx-#rPbd2bezp{Le07Qp$6yf<-UIsUz=BnuCLvx>-fOEMxWn8 z|M)?jy7psnd^&&Ttlv;$l-fJ9^8Jjn_Z62M?wcmRVB&MefFG&r<4h*`Xq`Ex{<+pU z=WyR^foBOX1XkCUvpxtuU~){hW@CX_zIN`U_9tJ}qmPL@Y88cS8JrT?}U2R}8m z`Y)0@D;O=29N-ldBs0x;VW5xAFS~VX56ArdyzBx$<4n2S84Z$ivP14}jKAURCbvDJ zXhEgF`0R&g)?d67#VlW}ANvEiL-R>_8b^?d!{ z8%tSdshw=aG1k`o?H@E`*E=rEww!(A=^weiyJ~JlYu?;>eE6Zs^yt^m!t2~m2*0Y^ zxYpL`*Yl0M>g>PLbe130+Hm|}q=`nDutep<{3g?9Eb?_{Hu`relx{h;YK7r*F_qUV z%r_fF{oEFCcHwWULtz$oIg3|+DG^@B?`c?6^Y-_Hvs*)TPD?M|ddcu{`AXG)U#jl0 zy!yZr{_IUk8>|ChUCF>|{9S zXX&@l@}J&UKlUUlrAf=L6}}#SZgW}c>(s4D4+u(?^IvxKl1T!K{C3D)d~#V~@uQCSHXm-xalCM-z4rFkl+Kc5ORoH?{h|?U zr;b`k6gPYI=4V-&y4K0wFY5oh*vfjnq`FUk;e!bW9|gzA-oB>&xZCRSd@EJ96yM|f z-aPNooGCniiZ<-@%*;6-l>6<+qCn*xQ!g%!6P)w;{I+``)1wr$mYF(U`+A{b zt@*>sKkN5?F6{{K(SnxjPc?=bn~N?)1#N{p@q{Oz+}-2R@hC zPB~W*Iw|`A{=9C)y3@h>80YMeYZ6nVA2Znfdi7}cXX{i`6DxmA2TpGFnGE+hA??b^5+yMpDJA!*89ElUzx($ zqL;lFW1jbJoM>d?ekkYyhyJd@1bvmH`wq*Wb9hFlckkFVXK;w?WHw%hsLq-!ye|?d-4T zs=qiy_dlA@_;k*$Pf0abHE)uHBc`)aO;mUn4er*f$`fan}L~iplzXMAr$0my@ zKS+KfD}STBraSR|*{`)dwaNDnSFQ1}+`6Lww&554wzkV_`Fsld%GVh8`Ty0O7WHs< zX3708{%@YTNFM+0)$3-sck8@A3rnPbKgqdpqj7EDM7?=lw_f*D8#KqfHrd$S{n9r~ z$jtu2kLS`eKR;!=|9PTpL|k(Pb52de(wo1ps7}gzE4hEd+#T8Z$|WVs`rci8U!W(a zT{FYHt$XKY1Fv18m)Y#9l+5_t`gLUlG9O1RG|CUTxN>{calwOsZ!E6hx_u+v?!*_Z z)yCnETEe&fC{GDFm{GHOZ}(Qk&v~~BR>v=&o#J=BQ~Sgr(e-;b%4iq7NYTkIx^{BY z>^;R6YtAkYOuKhuyM_O{H|0K0cQ1HQmec*W&FuYY#q0Oq6t=Rik?()^Bc4xvo#o@o zF9#c3D|WXzFEcw@)<5UizJI&c-(kx)kFNwTra0yO?-}FX4O`kGy6aB1PJeJG-A0kZs}v3_Kig(*3NW`c+Ld2M}`|pA90G!KXQv(E1KcBeNKJZEX(Yix*+virrnCoSa?iH1t zd=ysfG*_Qzwa=Wx$>$!1>@-@wTIST+tr2&^mw!EAe(2-F*eu60M|$O~@69Na(N#VE z@K|46((-=a+QU!9c9$Np>Z(6j7?6{*Zd-m+tN6b?AOF32edXf)Li6tlkJE4G|2-CZ zZN||j!M*8ox63cKwds{T_m%Pc*_~fC)L-?p8>rW{`1EBy-{IQQ|H8U$rSPU}-1~Ri zuiL{s`Npl++V_r>O0IlvxGo{PhuMDB@d(XrKc7DMy7ALH)+X&80y#fc&iB8k=-y_P9|~@hYKk-Qkl3o)s-|97Y*4{X{o4@3R^*h~n8;%>7b*^R3 znd`q{`_@N0e$FfWu=&;x^RRt)wX)Z$l=w`UAuv76y7WQm#JdS=WhX!3y2rQe{Kd!1 z6<>tk@!xdd=^5Q`({vPm95;+NTwk!LO?=kpiOkGu% z^ow|Z;L;|3JE3hqy88aU6wiIMYkSF!iybYmEp4jgDt+#p+i|q$Zt0rRzv>mWXYJiI z3oAX(mHyDmv6L4LxlokyKKql>r5PV{uV_E&;z*HUiC;VYIKOyvX{=h?;^)G`2h~D0 zaAtTOpWp1gFLnRCa=}QmdqPG#tJcp@UoYXMCLJFow!A? zV|V-hqlXS#^0(P-+O>bFVC=J-TfV#8P*lA;N55TJ@)V!{y!p@ZDp#PnSbS2=N0eC zSQ=L}`%$rhS;+juvRMy=<`g;ab6N9Ocvp6p|M4eoLQ1>e8J66wR4>T%WV*ff)*QpB z%ej-}S$6k5FSxOzL*er?<@e{N=QUp0Stvhy^8d`5FZ_3AN%L8lwacBH*`D0-{_CHh z`{oC_uE+g4{j*3@&v4t6xGv`QXXRJpf8Ko+mHA1h{I6iAAh=UUCz(MU5}MoexKQFevD7f?%AE1z64)h z(b`#`7cl32+Wd(v{`b`Uxs7wnuC3a1`X5hC;FE;jeyfj1n=^Ws#cetF`>5iEg8S;5 zy=?uoFB;45e68*{|Ir)ED@#_MmHn@MVXxoDOKW%CyY=vUpi%q9E2qtVSQl+LZ<$xi z_vBTboQ~hC-7g=kf1UkeZA6KLvs}O>iEVzGeb)P&r32g2kCm52L|ykSl$rm}LXWNT zv66lC$0wUUvRTv>UHPaH{i^%z%YfQPhc3z6Sd^^qHf>?>eel6i{QmrVLb`e{-iOsZ z^L*ExllW+{ZL)XBnQxb5RCn&0u5>N2;OM<`-?>9}9II@xEqPjSFsx$p_Wch(huG#T zy#BCt!-q?&>*uk4ICXK3{N_7LLs{4}w`rGn?_j;Gy-joNoHq93-?s6{?VNDH@j4&( zpIyHebFEr!>CU!5{lF2&%QdTwewH?@oO?U(2BY;dUehBJj~33)+jh2fM|sra`+<8! z|B8iyy65)~J=&l5LQn3RhW7dFGu(w?i;wJEBj3G##<2>nZg%~Oc30QDSk6g=8>`K!u2(udOrne_s!L=G7*hPv{SKOMm{m;pCskyr5n>lOGFWa_T?Ca#&+%xW7 zzWZzM*37l}Pdlf_Yv(VqZCe{?de?k;%o_Ri%U@;Jzgu0+RekH;xAhTQ&bGHl?4GyQ z{#*KMi?;rno@Z+PEO=)lGqwW7v4oYl$Yw;t0Z~pO$&+B{(zD|xxigR(oBQ0n?Plz@9|van z+z>tN81=ZPwY5`b%~PiMuL7M@|3>rMKG`h)zi;2M0H?zSi;}}0SI^Mdf1$T7`A2AE z@AO(9hHA;(Hy3`inHKv``dy20%JHucZ(YgEa>)pnn!mW|VPw10V!M)EGJ3n2t395s z{J5>&r9Vl-ZlBlVEBf+>wuWsrHvhA>Jt?DXchbc765EWX-J3YQ-{+EAwz16YOOKd`DfK0mv4=b2kE{@rdT z_+)0^Zu@Qh`r)JRM}94CdYtm--mX0|;-}-De7~X1G<{~Y*9XhV2VE@sC;pPQ56t_h zoHqUQ9kU-g5%s5{x7LfyuaTSR|G|gTLOw;VbgJskAm{B@FJ3(6R{!c)jM?|nznATA z2qq^7|Cbf6YroYudpZA-J1=?;|D6%c{b}vt>WDdE?-_3H=$ji}{-yop(%l7WC)G@k zYUCZ7*Z!~8+|4#h`2X%%w+)@@J0~?Kt=e^k^I_v^-MWJJ{yIsEuN55Qe!T4Oox;?0 z?yug)=KRle{McUm*Sx)G!ybz__RM1PAD;Qwo4LnSF1r6QTr_fjmF|txi+v5wYGfUX zSjV?>D*K)n=IXqE~m~UI5XY+BEuKMa97E9lXUw?cyTIkP|S$ym29Ce<~ z-4S@a>20gXgNJY4$==`A@rnC@oR7WxoxbyXt@y95Joz|ERsPu9qut{C@Av&)cl^Tt z1Q+o$<@5F{|2*CP{8xFceC>~mhpjIK8~;;e{+<3$`HudPSaF5>YaZ*Hp5=HgFt={& zXVriAD);@H*?e4+nfFBQRcE~!#w)Cke|Tu|=ILvzBA4vlec7fTZ3WY&Gu}IK##7*@ zm2J?Wr^ydbmQ~!W_+4~w)#~)0Pb6muBp>^ybMR;I_qC^gm@T>Q!<8HK%x}cKG-f!a+IH;U(r3;8X9gT=Soxvv8T)*`Lw|05F1NLNa@OY8tpACg z$>;0ZXA8YP=4BVZZ;G*H;k!SxI<5ZnhW$5pJ$}cbj<>bab56_;V9%Zp)~8-F(H_n+z=MVm99vUtVXadvYc7%=b%|J$~7|`g%sNQ816=!}mY- zO!Crwb?@@?2dS2JOFDi8^x5p${A$DUv=95tIQb%{`g>1E+L-gVw1R zvA&K`QTzL={0wt<-Oj1AkFI>UYx~0-KFK_W|i6V#eOJDsCQYSM~q7GjCU+;2aV4?Q`Rc zr=?Vggzw)b8=ETIetCK6{Yn)mAFA9^Gf-&}6Tb|>dR z^768cmdW>D-<+{*3{D{cYf7cS6y&+>+hw~eXGOF=e#z)oSc=WR4lfXuTZMW zyrSTuyR2HslFxfTH8K|*+!J}q*x%$VGxM+IrXpv)JW1WXX8Rs@Ya1?sKRKm$_S{?_ zC75$dbN}-7cW?il9u3|nbmv!{Fh08S+gz46Tgcn?w)aOnsnCvRF;WvJFTB+vl;0v*j{<}Ft5k%&I*e=JMaI>($za= z&c5~Ms*QTKq7_sAFLjvydYb>K{!^QePmQsw`*|ooqr&0qJUNqni`m`p)b9WN&RR;@ zHs+D1XnlELy!`$-5x@BYw{bG)&-(ASIA^C}^~z4>w*OlE^>TKF&bj)xVrG68c(e1v zk(17bKkU!DE2^qj7AhX&%&~v?*yP~`l{W!r4of|r$b0VB!@j)jg&EelNg7{&+-ZAf zx%!q8SgJfs^`9X{}0aCuiG}quyWncgFEUL?fkSg{k**0j|a`|`E{>jdp{pO>|Q1CZ*6|< zu=vP zwL5nISfn4G33N*jFc6A3(ssq&K1g1;{BTtI%{ZwdmQD9mx3E@NUpS|AGtujQVNFA? zY|oym-5Z{+T{3I$_Hx;C|B5UuO?tR?9(r_OTjzV{^M|b*oT?v1Y`eJOt{qQeaYxR= z+S`dj3`9zP}G{J(sh&_=)VgjMUN>xhAuhKUwbk`&;+?x7$=#o_xcvd^7Ic>gLk9?UTzd zuP;2aMK*k{?vXrs`EQR`7=8J}ZGZcQ=UV=(t@0C_?;O=*KK}9WXU;2ufXBzvVkSHA`Wb~xH#awDK3_S(^N{%2 zcWP{v&)!$LPM4VRyV$$zUxsb(%D=w%`?$|FZa>R;_2`uvgPFf7l`Ido#@$ezdG1Mi z{jCF6uO`oV%`{u`aQ50V*;n6W_McdBvUTl|E5H4M=bYM|&b$5ELavhudp9SpvCZRE zy`!C7+s1Cpxbm{H%(k!9kF@q5mE->TamPKY8^_aQey!6pXUP21b&b`#5b1ghc}f5U5!efW_ar|9(gA8>d6>GdDQ?h)LlxVNfzy-P3kK5nV1 z-ZHP^(@OP}pz})HeUCpsImonS`OP_2igTL{wPznm?ViJyR@m!tn>jl^79tuih|4=vMmNpD8l)XFXnc!Cl|JrsDtK^{<7e$^QzTQTIWE;hX*!PqY7l zHL@F?9~68)``pJ*G6#O_NLo<8jy?L{mU;KnUmDK(@cx6Qm0XJ-^R!7#*IE7e_uu>d ztGdo3?Vg?#qqD|zn`b!zg_G;#3%;5ik=uE(=VDIk>-^j`61n$p$ZmV`K>ztRW!ut= z5B(jNbGAnB7plL^d);u&MLU^oT2nKoMPEJG_a%6P&A;xaC%3;(@0;>u`NR}{7cV=L zpKoT`d9K_w!SSE=W+Rb}&)?f#SC@(ZarS}v{*U{9$=mJueQx)y)t_$k7q9y%%dJ+g z)fjL4Cu9bH{f~!-tKYv8k4ic394I#>`TL{RKYN$^|JoPAX5(_brFv!i)LF7KovqGo z{#qmSWifyKi=8~B;U0D}=1(Vu@GiZzr}q8Azsc96SN2@yG_k!n%doWN+wSiy+taSz z`nY7i`TgbYA?qf7GJC!>M%HW5j8pYloZq(`Sz}Ri@y=nsl(${H>x=GsNNTNn&T%B@ zXu(5)xt)apZ{4Jo_8wPLtIkf9b1Kg<@{*2!?6Ik|wPUsZ{>mdBTE7?M`@IYalk-@c z{&@OAG2`=YOXdn%<~dG1p8NK&#|Lh)>xaCzed$c7uRHPNamMR?YSr;3g@u-LPF&G4 z+j?`w7cG6U;5i<7qIa^2kGk!;{>-XX)O>?*Y})P1>q0Y<1@HMEKf1W!mg)7&`o*8G zMqJu`Y^mSTiadF~-!C`6GB4kJ;fP6Ux4-mrXWiwY%TI7$E^X<2dfP@rR{!Uh&nvIa zSr~h}`FBgy?qeEz6@EThZtZX?@=|r~oi6t4QHw2VzgPqv){A8<=Ucu@c-Ec* zjn!8#NVfl&@cP2CoR-3-U;_IVd_vXx=Y|9J(Rw9Yuhx@9e&1sCuP~M zo}0IE$5hXj+Dh~J-FJm8_SB`VsWD5-c>RLUJn2q0x3c|A@uWI-`I$As{<9x^uyB=o zzWr;?nP1O#7@nQOy;S=8w&RWdGHFMxo;Nn_>SitYu_r+~{MYe7M!USeNSRmXJN6c| z-q(A^)zy1hI`+EYrq=mCu8P)(|7Ho#IsfPPyhm|4w@=pXFU~yjru*rNIX@D2-S(Ba z?Xr2>(}y>XF5KH58XME?Xq}$YytyygdUECwB_I6ld*rKC-h6F~?z_tyt1kV!$eH+hja1znyHn|rHB#5w zEPlLg-fO$Fv}VDs%RA5i>^}C(d5YBW_&-PMKYS?v_wD}28~ZP;Z~K0Ix1_dQ(7$>2 zfB%;I_d@>fclmwG{Cz&Xeq{SHZQYI&*@u~ZkInW!vUhp6#&^pY;R=Ue3*{RAeQ39@ z`Czyt^a@jkD76J;zF4}8|}Zz+x+>_|9?k%mwwtE%>bD=qmSL@Yq(sNX6#L< zPEv~C;=5AtmhbcI$9E)drix6OYuQKtN(iF+rsi|#!i+PKCe;$ly{qej0|9ksCf6o7ntxI_&E%MC4&Tw|= zSN8vJ>z_a5|2xtCP0aqkZ}aVH{^<{ru$zLO0J8I397sM z`+5Dlbosi6;&lf-jIYc&;otp}<>leS^8X+Ie|UKR$LhNGhuf=8@J%njU#)*9Hb?PO z?w-r1)sB0=G@kZYoz3!jD*LuF)0p*Ve$KS+Gkcf3Df#BjmaIFM(>CqBbZr_-- z`qmt&Jl3t1N|$Y!dN#jmN|4@P_n805E3VEIj;9YkEOcKZcw1riuee2*udm+l>HIFu zdprAto#tQnJ|cNr)OBuQUDqA?d*VMmxsK|73)_ECeZ4|=YJb^$_PuIsQT>tJ?Pn!# zyKP)^-EH3!?bKIOW_&rz{o<0SWSEi1?u+_43*0py?XK&5Kck~R%r@{)mUKk>+ar9> znQNMF?(>`d@cm_ZF<+M11wQAbi??#FUh8}Q@q*V6ET0$L<*+fx-}f|kKkxp_J#+6! zz3%=I@~9|J;(@G9kKR7#z~`_3TsYl+wD7`>&GsArS}(}n*D!f*?tycLv9~5Yzi|86 z>t^G3iI>;;a~BsZv7W?uI9UJBCs&`(lXuzcuzt|UOO~&AGw)H({W}JYzvo0G-MMEh z^n06Q@3n$=uaCVwQm!*=b1%2auU(cKuj=SDoo`|-5*p~`;N}O zuf6d>e^`jC`O_6Y-u)}xSP(PiYP^MJ*nE!Z&DM$sgHBto`h7^^-sbZ+)S|cTnReIF zLM&XiY?}7USHdq}uC0B4uqszZ?)2%`p2yGpJrxu2XWrH&H)P7+??~)gk$c68MgQnZ z8D-~}mp7h#vZiicrnq%OGJAaH+}EkH`qEpn`sV71{9!&GsHnQ=i1l;l^p_vDRV1;c ze^|i2e?y6f#-9!9t`hpfI`6Kq+^$~xxcQxL!S|ZIQ)>%FL3=~GS3eDZ;K^MOmhesH z!y}Ok*Y^4Gy!D#u%5FE~a=(1huMmZ~`_8jU$y?kyy+1-}k$$sqcXjqN{wi2pmi{^7&;f2Zr`#oxXv zdSZUZWrmLlFZlmIv|q&Dx&QaW`~RBj4dzz`8}9UowfkkCU-su(z^>=}x?bjT^Y2bM zzua2z?<@WPpAN_W%m07ru>apD{lUn%8i_=o+`kQ1n!M@N`+bvHfPpSW$ z|8L8)l(w!Y=H@Wy{z*8ThT(%bgNzw-Zk?Z14O{{K|`Mds7*?Q8!2EjP`Z z6+VAY%+7Sy?dLu%+IVG4z`vSX8u@H9+G}oolK*$O{>O*s|L@GN{&BzlTl!zm*rEr* z^LjY>m;Ws7zyJOBzdwij|G$&JKBZ!1`?O!BAInYl$Gr$XtpDYE#QtliFP*yLSv_Zt zec0W14=f(1;Henn0GhSC$E~M4ZS+fy&6)F2HI75}Vm!NdC66cX%UR}$2fh2*_PtSG^~lSv z)X8nLd_m36JM-#3erqv|m_NN&V!bfGeQ)>KuHC=Y938eAc*$^Vnb&*r-!^%hOAo^K zojma8&7T`r+?C888+u6H{uS_hj*9Q1+vLn4BetVm|%vr~{cgJiSg@0eR zNPf1X|7Bg)KJ{s(73(W~PVCMq%-LRHp=8>Ba;vJ{=e6~3x^|ujO6cw??ood9I%zJy z%R}RoGyY27^tSF4N?g}!wavzW@i?EbY01aJFoj*WcQ%&TT}VrK)g0ou%ry41u{g(z z>W?=HPn~At<`+_6s$0`$mV8ibrfrTv+pO*PD$laWA3XOqGiL&?rpdV{_d9MT7wf-E zKk8T2q<;U*NzbM`e0+Vill6_Bugngt*()cu`k0iRAqb8oQaA5o@AgQs%Sx4(9rw`9fs*3k6i z+(#Mx7BP>6`2F8}G^y@9BY078<oT3v+Y(nv_ufjBWYx2%dLG|BC2n=#|79h#fk+w=`zXRmblkcg&C41wX8;`1$w! z{|67R*Z-Bb|FgONoB!8>!1;Nf54#x^8~ksc_rC7Cy4=45`@gcsoPYl7xvkBPLx-3w zoP*ZR`6(h>SMhN>$Hw%3fB&5Sf9LT1KQH%x{E)r>(`m*E>x{P*9$yc#-#@?n;~zFl ze*c5d61Bvet{gO9ZoR>_l<$|5U}vOMN`l4mV=GIaxvH^$+9T91^V+!Y+mC`bQw3g3 z^xq{`ekrmfp)_ZIenYHlov+Ti%7n)kGw13|K2{vg?%CBBZNa^`uwt2EicI{Ahfml4 zJGDN-Klg-W`Jc%$a!LOt*MIVtt9zvWZ+g4^*X92{x4*Cb|C|5)PvHqWBZSrC4@}mn zSMEA?Ct=S|Q}_9^pZv-HyLNu%kL>!l>VH=H<{U_3Hmgtn`tafFPv`I3{EfJ?@88$; zzk~P4*XJZXOOtWA?NOfOuCo4Ge@OC^jTfpqWNfG1X0J+_T7K?F`1HBgo?Mu5&$xVY zaY3k>{I!jLKXsPX$bZ}r^ZBu7Y>ji4v2Rbp()!kOk2MtH{P?x?K1m<{SGs~hrlV?U zTBr7-Edv`ac|E2oM zmFk1+pnY@v6I@a*w z-U;z3Tg1LD*Rb*{%~q{yeEVOlyyxO#Lyi2x&G(bk=Uw@B^5@z4rzY>)oBRDLC#IS{oWp5sr@lnx%dzLZx4nJaK6CNv_U3NXY(IH(>ElRSv%hx_gz8vJ z*mdpya^T{_pJJ=Et?fBnZED0)pKn!I7bqX}Xyw~Ach_ybroh%MUFvk;#^(AvU96nb z-Y(u~chJb{_10G%*(Es{Pf7#bdhUISwwuo>t)5*Ytdv~%qujDD`8m(oi8G5cwXa`$ zGVlKKl9q4x^VghD=DE;Votu-*@!^5zU8mv`xAfh9#JyCASZk=wvG#%SnuAT}_zi_8 zL|kmQuGo<7E3?^car+0&^Ua?`SaUwyaHv>U?(MfGaTVX)Pj{1#{9#;GEW1o`s-50M z-fdYHk#Be_Z=TxpI_-JSo{cZ{_s?&#HGEjp+q?d1O3vGZ;&)GF^GH`e%qfwNp8Y9f zU2Xg;!vilmI(?JN^6e*mFFE#6YQOXv_O&}DI;uCy?e6)h!S{FZj;kA=@16R-TlvWG zQ?7NVKR;6T>^9zb{N`D{->Y6NR`U*T)=InoLv(%Bfn#;w|7^^AxJ*vwaBjsmJ-+2z z8H|giVv60~y*_p2#*UAS*Y-Tw{%@E5{olV_4w*OGyqng~{q2GA-O~{vW$(J}Q}chv z`-0b2Wxe{->S8IboxkjNn{|DLRlWOKv#3|EpG-XMB5vC~vwqtl`IUV-KmMFj|Dku{ zUc~WqznD1&l@WzU{c~JUPqR z!LBInt*h}-aC?O2huQ1}1@CM|M!32-v8e9 zLBiHMDte~=>pRWtEm!l=KXyfj+=Q(EtM~uX=C60ItNSbef7TO&-DcqvK3-ct^K*ZV zQG3GDT^{QKQkH)|!PnKapk{q#>+vHZ=0~>(-U-O)o_^&N)58PlJrft~zLw=$n)BSN zX6pl?`N@|*-6;}zJy*E!uiLyOzc0Lc(o=VQ?O7F#9=Ts!$Gc@td{-4ODlGR?pJrYo zVG*1ccihc3WyOluKOK6_J6Cd6{S246_oV*EMgG5<9&ai;I@eE^-@l=L&%TO<(%C2L zejJv!`E%3$cl?X+9shqEF0Xsy{zv;x#P4jjD7`nccl0bh9)6?z-oxvXM}xQge`)`> zUhd!T{}1<9|2W9MZ~6Y_Q}zr&HfLGmkMhxdZzb@9+NgkpFXo z&DO&<$*-e0`PBRMZFd9;{8V-Sv{X}_I)MsCRqDz@|9ZTd$<4;>9F> zFN^d!8yQ|tKfn1!vpf3{$XyL8^&eD zZ|A7XovpqpoH zPUGgDnB_k-#6Qb1#kE_d&r+3m_H<7B?}nX~^JQYvuW3wXDcLypa-a0vuOW?lu9`hx z^YB>AR!Qkc(_Y)^?6c6fzJId4qlNMK&(@BozIW!7=bei@quqEx`hD(VVb`+}Cr?DW z-ALCJ%~qamb+5pH@#b%vPU+vz<{aIbx8a1)4ViOR3h8l@_GSsYuYG9r-*MTF|C+b4 zbBbMO_x&E{>&(t~p2b+ssOj`CURxT^ke?$KR+V$1f92bQpFc@d$SymlVXwVyt3~$I zgioG39tuTf-6&q$QIS{q_BP+@4`ux|>Wp6VKkv5II5N|84|l6(X@cK8-5a&4 zI+sUmz5ehO`|PNC-#hOU=gQ1rxLI{?$C-3hPx@Kpp z-rwWD;mXf{maiLjMbH1hdYW5u{jq($m9HPa{Wv`uHc|HQ-qyA~6MlTT?R~dlgGFS( zo|n&$E}hTnm0Xy*@Z$TXX9us{DOq{gHFSE>Tg%)WogaE(-%QS3+$&-JPJRB1#OAuQ z!PmBJf0)ztT;P5G#;!H((aY~Te0(Mxv+>EPlU2uSZFL&;BYuiLRn`-H!0+rHTX=EC z=DMld%&X?xJZJQ_OrCh_!s7W=&t8a~R%ZA5xpnk+3 zFxNEo#os<#qwv4~%Y#o(51)S(US9u5{onO=`_JkBdMb>befEzo31(SuyiPvnb-rlb z@7wpM&8=$K%AD>->)ec1!UMQtYz&$LY3f2i!-YyBcF{`tiEE-)Hl`qxr{LimbMM zJAMBO*Spa;JK2A;y<^3Lx1VLV&0=0Hx#H}a-wU1u#V1q-u1_jG6!7NA!LB`Ji}h7D z9(={ICqJn4h{aRK-!2!=*}nNHckV}X{yA-_>RQdv|GM$FZ`|?l2|s5SFy~Bq@5E=* z^_tIA{r2Aw!J59I;%NA%x0TB)U*1u)%{O_Rl4X_m;IMb*tEr#e?*9?-t#pHv9F);mPOS*T2dIRe{|oGr|o&c z(_4=^73ObzklFn?IO4gA^V9}Q!E-zBGv3dZ{`a#a=I^{Y-DkHd7C!vhw{J%D(MSFJ z;_YtC?lCsKJm*MD)THp=Ws`nIEK9DNntL^}IN1H%_nqs1OKPX&-3mNis-sx@%%nbf zmfP9`m!g90T}8ij&5k--wPEk4t6C{lFJ+wBcCU@`V2?l3d+^csndg=}%->&pM9yN4 z_;lgZmQlW^?^Pa*mA%=vyRd6>(&=qmAMH_{dVcXA-MnL^M-3cp+|zdU{c(#ae)Y%E zX32Lemcw7ukL};1s_LH9{B+JS%UM>Xd8TY;4`=^YSyACPI|$dfWTCpcs3B*WDG0y_NF{XI1yj>@J8a6g~Vo$>2y1^Zl<3>NP)aDG1eE zRPoBr;TD$8dHpeR!;Vis-9GMUkDAlDRDVBj;g_P9KfNl8-(8;G=JC9I?#k;mdWp=< zWqHBc^R=sGy=;xQoxH*SZP~i752U!KM{#Pq)>XTH4ZL$r>zfrW+#&+h)1!nqYnV{yDYhCMfRU{$>-lXI*W< zmz(0J@BQGs5q10iqcc$g(=2s&yGPtysgXVB+uzu%QvT}qcNklb-?$@PWNY<)bND{a zw~n&{i`72Z+&3?x71e9y3SFXlhju5{w% zNwsqi=RQ|qx;^LP$Di-`zDaFQ-gCbE!HU~!?@pGvr?qbjR{?Lu?YiS(4=i@uOmy}S zvbFrsc9dVFChgRt6vJ=5oxf$|xwmke{g%uHKYx^Mj{gb&A3I+E zwwt#3>f;~Rg`c?A3tykv)BpCh=nv(28z1K;G-8f3UjA>D43mX+N*V*X7>*9~gD~<683= ztDB$wYj=F8`EZ#3kEY0dpOfEqz6&bd{q;l8{$qc9>W_bX{Y(G4{#VX}{uLU_X8c*6 z^~KBQ^XJw_FBUCNIFl(isdh!ZQ_K1@SN|9*{&INWbGYr+fo5&V!hqT}R(k_<{2KnH zC>W|#yEERa5C1>&FZ18_>^!#8gQ1C6uDga+BG=rNzPw(+q3lkJsFqUikmt_y70X_b=GLcxL7CImHgL&zFhp**xu#xzVKh z1@&LPoc+H4;jcZ*e}3zH6u4M?mHzzPMdxQ2h)c-7`WI9DTsr>xVfJ3tIW)x0S5ax$;@eH*WH_2u>P z{1aBnzJ4M7KHF|X-W2x#J31^+RXzF9dhDg`(+Q>@78WapKjW$2b5|zy{>HSpj|~!! z);O~LjXj#wu<_y1S(*Ru-E&Myc9xfsKK3)iYIfz>jqi*&*RkEMPnyTS%tqhz+0!j| z4)s@ZT-+?%9{aqmql`CGuFgQw&*9T0u`Vf_dmP%U?oC(wjW>c74S#~Vn=Gccb&%bEQnEh2I#Nd;DYWW%2BF*%q ziQ%7~@xEA{{k8Ih(Bk}KCvC5TfY_8 zuQT8NcFo_l?|l2L`OZY1k5+v!@u7sf?~3CcUs&&(XMO$bwm|=$gj9ij{K}iBQ@uY{m-gRD!K2MDHXPG~ZPrak}>|xmr>xwqq`FnmG;n&;$`|f+YKQHb7E>Bgje>6qfTvl`1Z~59!A9mMW-~aDJqg+(o zW7j3CG00Pp|s$ z<=*bTgZ1XmCs*6lJW}twk@S7;`xDutl1G`3KKt<|6xmr^`ZPe$4Ls z!Ss9f{-3j7zt9s?LUfzCh%`eCG??iu{d*N4szV`U8!}j|t6)lt5 zpYz+-ENu5%`Ig&u#%KHE3(FpTUcBlg|6fgKTZ<|Ef21a}1)VyxdZx0F;n@eiXDcU6 z^*?5qx4Ez2h38D0>)Spr`W^V;!|2`dt~Bx zJ;{GRg#XnsiM{{-{a!TTj)e55_v*$6>w@{)eroFe&w0WAYyI;NKc1QIfB139Ka1tp zuDp=`bky1E*n`{me{GYWaA^81;r@^Ru5I6!`v1p2!@tU!&tz2>&3kfy*HC7~!T!HD z`m=JrD8xrpfNH8|hx`AWC{H=g&+uu($LRb2rsd3=J$qS4#nJ2i8GaAjrOlqLdft*` z82|88&6CF0-}il=eXjHI``7P#lK%S^rqpFsu1LLScb)n3nZ&b)^R>(i52ZghHhtWC z?{}5LoUcF66n~AiP5FOO{%@eY#&h8-w$cx0#z>mIIWedmUfK_#k86 za&|G%eYNK<-P_lCeBCzoJIPBn-L#*-Wm%x~d09S@EfK$+mZjOs9KC+$$$tJR7b+!E zj~{lIWBRn>I6w3BzHITb80kqf&)>ZCyx@mbl-btD9CI?V{=bZf_UTDl$a`Pru(Qk6 zvUPSoXAhoBox0;-n(wZ#E0ur5`DcAxAD`ti-}0Bnx{_nsJs&%zn94-nSn91b^t&&! z`wvI<_sQ0^{TnMfc9!0_v`anj_XV4u`^>g|Y{_4h@blHrE2Z8U$20czF)D5_KfCMU zyPYT0*+oz5_qxtnV-mJ!R`T6~HybZjow((FcXwZQd4B)*=rv5$edT-nWjaO53uhYxtH3EM2*J>VocIgLT|S`h8Mw_b&E(<5in?MAhr1OPy!GE=qZ?sH_}6>+?0c*X57pj=CAVs*boW*lvDS_0cb5{?hYv4FCSWQO&<$ z_qtE_idUX4ny6ELdfTksg$G%49=G|P5Kw6KVNy{PC^A<3YV^JGQu-&G>DBp6=95`w zn6y_jH#TG*V-r8{pvmyv-5sZ2{O@b_hTor8s+3eSZIktycd{P3(|%9+vo8H6FP~lRBAa*7rYs@53(bxn z+jhkH__US3F1(%Rb7AkqisbrV4WDw@9dsj2c64oe^ZSbC$v;v%FKoZH>uiYCSEsx6 ztZ6FSwnnmC<8@Mfa^!p8iY-&5m+r8tnfrWp(^lI@vojs?QaZzT5nF1r`W|7NGXe|?JGAM<6~OK)te zJZrN-x8Ucjon@zu^Q;AoA4srBG}1K&_^uzj>goag%e#5*hkUzHJWuafp`sFldGfC^ zzBg;GTC*3HpPP3l@7S45k2boW4vm`mYv1p8Q+v<+QU0*Z>bh;eQ~e~Dz3$a24NgiC zUJrr|XKp%naQ{}W9R{<59JN{HIm7lYiR`~|oagNGFLLLmn>ZK!ew#iueSYlIo82sY z@k!HW=sOF#B&A79q)jwT)=$5=@bHYSx&ar*7?+K8trOlR(FP;5P*`2JYRv!`!l%XH@d{jxlE z`Gr7xl{e|v)U@0V_x_QPPmx~L&1U~eFD&EXNuH2biPfy#*Z1w%wkCAL@5*VMy^~>Q z0i0CSI6mDjr#|sgF`vV^TY1x7EWf3`Sw!W?aTbY*2dDR?&#yjb^|=0$&sA>5vNsK7 z$7Rbk&ab$)-2d{TpjFOIRV-OAtzXzXzn#BLZGE=c;+(MmH{uR@|6=%iWZR0`wT01% zY8iV2gL0ppiBAbuJyUW_FKybR>ZZPs58qy?pSL~#T6D%*OV5MXI8JPOWc@ri%V5sU zlV_Zc?!TO2|A{xZ+v`a4KH%nycO8?!L?$6IMZBBUp7`J$`fSOTheP`)|EjcW;X2QKRVQhxdP57U=HEQj?XGFAO`; zQ6{@;^89~&f4U~IYCXRH{i4;2oYf*tk@jzk&oqiwR-Ussb$`Yd){TF4yjLxLrNjHf z$@kQrF!oQ2_Guj7a$#o8^u!${Dw6W;SL-jhv)$<9TW$K`z{=Ccju+DY=5cMC8tLjS z`0t_r+{vfeSe>3{>9I0%-kM^2!u*5bF@A?P!p|elB}C3kl=}0-agNEf@&LCw11Ir! zkC~4Djoae6CLoPr%iAwccRbsqzQL|%X@$eK44>71jyN^v2yMA(rnLP2EEdzKgkr0n zt$MzdMN0J@u6GWfyvHg0PsZ`V1LeOS>%KicVEHU5TPm!Od7p^=uYK{B7dqVRmv?R5 zXH{n!VSQs$%Fb`!dXJxqlGhAwx@h?|ZGO>Q^Oja|%^yb#yUP{-)Fd3r+jDx&o$W>^ zx$_qKe=5Iyq5tp)W&L37&F6cUIjwa(EnFl$%PQ~V$@bbum*aAl%zM!t(G;;^?U^In zBQkWZ^D@USs#nqdy`|D({o!4|PetAAxntIQC}`f#FZTmAPrFaeJ$>6sE@QD)wEH77 z&Dn1mtrC~LF`0Ng!NGlT$XzSGNmu6Xvu<28EuS-IMT?Khk&?@5-pZ$ z3(D@6UZ0x1es9=&qnh2!(=Us%%v$3Rb>@$f!g7Y$P3D(pOjNIGs{4L#_mY?|bMt>Q z9a-OAlg8mL(ElKQo91@swS2s73BC8T7d=>Uzg0Iie* z|8-jQ>AB_i9ww-BpUPQ3GsQZC?e@Rl@&R$*cO5?UZuk4ZXJ=;ST2DCIW1klONVv)W z%!1R>u4yHkxU9YfowHn>X8-d@*QW=~-%n4g-g@GKGoQ)3EtlVH%DDJwQ^m(en_lPb zo@)F3#_BiQ@7K-S=-D7Tf5L}{fBALvwZqn2ICDC3Uf|D7O!X`mDr9P>$Chb+7T3AL zD-*x)iFuu^nuDrN|6Tpcgqamu7nUW6mK9g3bDRjRd%ySj)V<$s-Hu4{%=|s`dvnp& z+Fvi1pFUjWBOm+0v@A(@a{|BBiv(7WnVeF*jQiamEt0Pkd*pK~@YzABSvQJ<8S}l? z?|n9_=;zb>`ssU~=3bj>lqS7M{Ff59<%?!L8@AfxbM1BF{~x>lwmeN?nH|gj3CYo{ zeGeAiYG-O@Sy>s%xLLtG=Yi~;9%Y+d>u2+vj9EQ%m%rUlm!1FrJx%R=^=6&*`yhwv zttKungPy&!34fbhX!+uS^Qk|7zv)_Q{Mb`=HR|k^xi5FQuVa3ibz5e!ag|^|`ZE2^ zCdM5*la4;-I``jWlbnY4`{*dS`bUK?xBD@^mOYi1CC)BeQxLf$VPSgOxw*T$U%4~J zyxg00RqO1YD?UkQ)8clOtYlt&#kgpN{Pmf)UN*6E%gD^Pbl$9x%9yLbbl`^d(mNHG zdAH49u(Em8Bi}{5@3-HtIXPE*CYP4Rj$ezKrk+{0rT^%giSF{c_P;Ln-%+2@X>~NW zepR~G`<>V4&HL-aaOJClyuga(?^k@&RgP{s|3v+H@gt_(75Tw#(HlQ&8-2EHt^Z^q zq2ZymRrmSnxt4BrNBQg|_~$pUh^c%z6>>jme(q_VJIAIYvu8F>9a{MCC|t!R&~c=eC_C2LX^rAR5~{F$W4=X~b)hjmXKgr?={eqV9z z=M9%o^OS2T`>g!zm%I}RKK5J5de$vHsfwpcdyHGJ+5O5B?T(r~ zPlJVSp1kmTTTVne<93a(@HKv|IqWNWzJ1u(KcRbLnB}L-anIE~s<+?Fx?T|Z$>-C< zPn{c1$i3jdxlL;`V~zz^`cHSR>!#OPZ%zAj%VlrUjPDmdU%#+qt}feNW_Qtcd!5yX z*_uCY2whZJVxpYNo_dO}UNPF}XY!m-CHvF6+)`(`w8cu8ae3R-KTe$NePhlyHl+=+ zt+}T*m&xa?i{M)2^LCDgx$m4P>DQ+#ZwYaQtod|yG1IKMk*n5B_LQ_K*`Lhwy@|Ir zoZWQ&(cAH%hOe!h(z@phX#WfJ-&>F@y?c|&=gaDg3)aTGIhEp*EB%DEf0<0>h2?ix zoVw?0X+&JwR@KBf(^UFyLh6!V5l;hh-+p{{`vt4bzF>~Pk8jwYD$OZcyteq4(vz^v zJCg%e?@NCzQfzB%R`O$=M$e|bkKPugUR*V~UUlsat@xRTt%~1AOqFAwJ?B^LtHX9r zpUSP$c`taoZ`(BXZLE6Rr!9|fo%2SaWY!xC9+`PdL-(gVb!d`!Av`(BTvU5Y6X#zB zhB^^3D}F`8Z7(bg49gVdpJe3J8S>2aUF!RSr_bMCn5pV_!X5rC3z)g}TJj`yYJ&N! zRNkL^;Fovm{nI>2ojU&6zpC7qPY|~|_pRZGS?jiirjCqE`Dack34Cf`D!3kBpKJNi zSABY<^_j8*EeG!3GPP;ieXKviy2B;GOMHs@ysAYprB_3r_T7G8a5u#vXYP-m8)xr% z@t{79UF*N<*>|)23N9YhxcN}wS=%PRM&WBkRS$Qj%R1Qp-}6~iW%r&n6@LoP$Eb81 zO=38s;qrXtEZc3*<*GG0%G@e%->zFFQ~PFPYPGI}%Lb$Sp(m7&&Ffswt!Ml#Nlod! zNzKiE{rKXyrcXC{>s{@+sC_Ef-%ibZX?e*DefN#=J2EDw&M7?h^63F)KAq}!Tc^Ku zdOczwdiKJt<7EXXWEnO2)7Def(N{dj6l2^LM=C zU~r3{5%O(9UHrdK(@!U{zF+jVk#)x3{^aw#)Oc4lW5(<2t}cFLEW&bi&FM{Xjn72;e{N;Ff5pjudTdo@WlQLrt7RW$9WC;F z9(`QEoBG}Mn~weWV*AzScb{TnU7);T?RST)Yie2v@)lp_FFSTT=YHud+tX)`Jmt4p zA$el@bZ-4U8}1a`oyr$sy+U1~exddL0DrA+F+HvP+Sk#iHJ8te>a%!s!l?Y+xjJ#x z_giCjKl}OV=lOcS_dotr`%L05VeUI?YVkL{{#*T&`#Gd>-R?~_FP!(UY6PpZfnVmx{-i9Nyn9Us&<;u>HTsMZaDyzr5&A7i*Z+ve-|o6R*cV5KpTLIH%rU zyQo;`r;54fpQhlcZ)SI$?O9@a+-Bj1M;|h0J~^gXBcHPU-o9xwgE=-cEKodOtu6VL zDRm3;RP#+WH|9iN3^-WD!k6P8;u^4I%Fo_A8Y|W;viZn6yKut?LAU>x?%a7>eom@j zO3TZf%kRFVwu`dYUz9%-mb*4nyk=8`*`uJV9`AGYEwb-biQm0R z5?^nd(Lm;0pgae& zxXy=6_m_`%i06H7TJU}6hEJuhu0FS3{+Orz#6`!ck*&8T9C4id>wA#2PQfcPk-DQ1 z^R~TsC4KhI^m)3Qg4JI)-aO%Rcdq4*mv5xcy!+y-&oBDBq&so;ugQ^f&l`WZd8_4Y z?%!>t{Xu2MrQGwQBzDJnByFjOL5;m`|J4 zO73zpKePQ+z~|p(Hipw8rzZxU@QEpE&pvf6af#Nc-N%;kb)Pk@m+0=?#_snxadXaz z^1Pab2M?6(s5`s;XxOVOta~@Rsw&@K%*o7am1eXo_=Z;c#P2tHRvZY)dFoiqa!TFI z(fomWvFFU@>e&jh0qUjZ+QuT@!W;6R7XNKHpi%t2E%<5hq-|-6-#Pw#)i`$h0fX-; zzUYNYtflYuSy{8)l;U6|_``*84lsmS~ioLdv@$jbP z2Mx>Q9h%egk|*%ZoGJc0y!|Nui@k+AJ+i;@$?vPm`5^mR`;+I|Gbc{wCU8`}*>-!~ z(@ypISD4gT6kodrFrJi;`Pf|aOVU2l&+4ZM``=|6{SF+PFN(CA)bf1OpMKo*^oKv6 z&rP2elzUH243x_1DemO25ADFl2;w1 z-CBM6{j~d+d*?A7nbqm(z!|+f!|ajpqWGfow%?2ohBXDf=;Vvpw*UX%)2Gk>Idi@u zO-3uyeCo#+Zx;942EL0d>aSeLdeD#k!;!~Fg#85E-backRLyuL-e z&u}1qgVHls29ag`D{E_B1^wPgTwEMW*^R#?+bqV|H;g4>!!Ri{>8J|P5$DVo0Y%MY_|O|D_q7vdCJWLQ$D{t z_hl{bl>DBnyPf5$UL4%?e&6S-=PS~+v^Tjw_#J8ctM>QX?YmnKXfL}Ky&^``{bXay{;6zTC$j^szS-+ebg{lN(eBSj ze`)p8>Tf(mop;{cc}MlG+A%qalE{O>k{@`!*=|T%y5XO73jg~)r{!&h;g{rkwB)B= zPdaA5tj}%vhQ^}bIV=|q%mi*dN-z6$INmlk;DFYj4(aHhCl_A2s&p=D)sen{mDjf( zHj?|AA^&~3EcYj44w1J?T~Rk5C$8QWdRi{=_v$x%w_jZ46hC5fzLs!+XiAGe-;-503i-&P{8eErTW-|pN^pABBApWm|n4|~b^q?ZoW%BgpMsFYql z$*}I~)})Kqt)wk>7@Ae?_0q{b|9H7e!s2!F5~FjinSX81QV6$-a4*UHVz6wU`g^fi z$D?I$zv!sUoxAP$%J|*=pV}I^*bSRg6E^>LoNj+?yN%^C9($MS3llT7L)Ru-9N$}X zcKr^E#U%ze%~E-jC#||(t$f2op|LdoO2i9+t1m9|Mc?MjU7Fqe_{8E|$>(L)xVNnr z2>xpl^oT=8=73TCves{Nl<$`qh!#dqD~ehpd5!5)w9d`NAEwsanQN$#<;=dMxBFz% zk-k^^Yv+sj3okp?$v5$DWc`)UK#q*Fd`iDpJvCpmz45UXORcu6e#wIj9lKk*KgGJl z2L&xFRb8)@yH<2+(} zY;Ezs%*<2#*#w=_@{&Jr?@TOyb)@d|28Fnlcg`M{x@eh`T=aW(c)`S1z9I9MbP24D z`#Yz3PWj!^>3>!}5OkDT&inMm;(pE3)AWl!2r4jIvabj^ceF|2WYyl~hUu|JlRtfv zzZd!M<9qu^y}$3wzutJidD?NUGeM`12Y;!sI%v;iz_Rm?owsao-S4;Cr?S_738-{A zsKeCV{r!GC<4Vma7mxQcArs!XvIcTW9GcGB@$XswzioGl&8yrGv_%$l37<5p2?_pN zlp)1BKVoL(RpZsC?*ILJf2wurXZb$|<)=9FSsp3kvwm}-=*7bJDc<^(E(x}Fwy~=n zv=z?m)_=d}vEP2_i>sS&xBa+u@{C&&1scShw?6mc5mIbpIh^ z?SOfoedey@IwNTEOfd7+SRMwr}?{?3Z+kZc_@uv2h;`{%&Ws;p)*nC$XxFxdp^c2bc-tTvBpHunl z{Pb<|$3+|sbyI_9woYDF#yOXcK z*gG#|;Y)2k8^?mUg&$rl?*A#uX5-~I`}_j7zsV;jspfg>aJbHWBzeN2}f*v7HE7k)x5#}%vR337KZ73Y(e_VljBZ1pZD8VR6X_Kyf3=D zSBY;5;kjlx;hNGH$)%nm=BcaJ_2n_;JgTyG(u*qH7H(7dVT&)X|EG)Vw_dF@-Ov4n z>%^1elSe-1}&J#H2f{NVg_mG_|s z&y_vx^s4$&R8{Z9?K%5|@>2gtYqqPu%{ncd9CClh5!V+|F~;YY@$5TRm|)+T9K7#j zgz>uBM^3L`+#4%1_2Hju8HuZYoOAzSsL|U<99dNHD;z|02Ef44ZIl~pb zna9@S!4F}xb;5=h9!}n(&yno?ub}?rspGqL>0kP~c=FmihI`^o%_KIontz`$ZF$dy zNZuoSZ$fUpa5V9>V9T#wwetTo$CTy4n_IH&e--HcH@opAF<{Yp&sWF1UPp+9Ow$$P z`SIj*zC4_gvgXyPOqWWLp1XVxH0B9(>npshHG0v1YW}B@@CmpVt@MT{>^uJ&sd_`_68@cWB9(-o%C8Hs7~)b~o3}{^#-gX0x$b z;e_Qmec7Ark8QlKvT3!K-wC(xH^qa#^BJhze|l@e-Jc;x?$}%1R506mHu#u23ybIC zYS-Q)vm-JVENq(@o%blgPj^**zxv7r2eLA_ZzhxI+*qJ+FnfSJ?#wA?UmzD)S z^)%1o*W0-G)b^))%j8b{`+dvv#<5E7iUnmaPOX%0est*21E*J?Uru9{`$^qIg=aL`725jisEj_hA8G=-Z(9ewZXS`w_rf(MeKcEIq~X!Um+bN}?^qK! zu2i_qZc?>bcdAFPNqJB5hdagRSHAU>yEs?cSn>G_+j@7+f}N}H+0NYcVwGzQ%eyL> zspUU5PTKxNYk^U4_i~-x-`{<*Klf+<>80ZFPp0mceX+%?p>?RvH?aPp!pkSO2-IZXfq<=WD*TOV&kB zV<}0|ca(4CeyyIO)uk<4s$*-cab%6X+{Jy5e&5%Y|9^YG-uAmylk+28he)OE@TmJsi?>!v?MjmfuYMzA57p>B% zdUy$Ey8L%hEb{Yj$kxyUDzT zdFxB9X5$Ti-6gGN?>@cm>5a$tG{v^Y8cRr%jWm?0U~M`_%o!<(6Ds@^NK1OT%w>`(5eXSNU^JKf{!BYk z)_=BEJ0J4#zJ1uc=%Vdnbybcc5lXAS#9i{NdY;B||D)6W zut)8}ucAE71Ty}-E8idc?{@v~j$2PAr|uFHe{}Inu)pP5M-iqg7q>q()^s$Od|>JQ z%GAA)DV+}Qw|uhw+h7p-mh;^Qb&H<6GQxl2cjc_Sm-sVbi{wY9cL&zi>~k?&Q}HM8 zzr%y@nuvoz->zEQ_gj4O*y?UurSI@7ebuie&9jYW?%Cnbx}^WMy4>pLSvFUso_{oT zJpM%TbcJM{a`S$VTbJt+-P`)5tzODhOqCS+qrLSs4|8nd$y*k4Th?6RS@JLIzSqS}^@eY&NUw(D&FwbFYR@3^gW zy?*8Pb8}X`J2~x*TTc6T$KZw|W=mu5t!B71P3`pLou`j5?Y_$~F}gInFwdYj=Eddk zxwdnawggIilwWY?@Z{I4e+R6#O7YD9ImhDg&#AqtOU_-}KKbV9BC$VglVo$^OMYyN z*>ucdS5fxepN22la#W1D4{SZYZL)7o)0Vf#_jc-CR?A2bnZbLBzvcXv!uzYLe{-I) zVQ+iCfc=8n=V{N@=5Lnq@Qt{0b>q@i3&OQd{`zZir+n(U zxn=5$a)IwkwMQz?7SEQ_dY9q$G~esqhCQ7IFIIl~^PuMSJDVu(@X0?O1nCK`Q+Vr| z74=3vasBEG=^HuiO}SWCJessj-~ZQ_*bi?`H%?BnUs0X#(fV7*h2K>^vXz;qcGx$$ zf6DtFu>HB_&8+CWP=$|gUK=*mzA4U~^C7)LW5Pz)V-+j4GYbyi=v!v=@Xq(`G9C)0 zGvqx^$Zc3X(SFYSJ?e+}KOZS8`Lg`fwuhl+Pk&}U-CFr!%e#B6N6&f3Zrv_>>dl|& zsiKpucuts27Mv{>{qf(y7A|S8mBp`azg?JJ8@uu4dquNryD#6pu(0aTu{8`+w|^@; zJ~i`}l#=_)n2#T1!dT``jQ^i?*7Eq0ulp`MU6h;teDd*~PoGVnR`p%(`wx%gD;>7S z|2agz_hdf9!u~7!e){7(QY}*7+%x>E&s>q){_jlDx7<4K`)zUK$UXKn`~72G z1x2e!gGI%~_sVzJ$j!e0$RR&7Cqv}+mGp>b6-CESzh}Q$wxPA^#~d4>pEvGJ+kV_L z`O(6&{rqNstRs#a?O}6FQaHY&>hV$~J(e@;YK~jiFPl?;aC=gkO8l8E23*ZQ@6I|| zdNnkB3hU?Zm(T3I$t9I#nyxRm`JAI_llz%dPXe#xB(u14Sjc_-wfJ-+yL{BTJ+HE+ zzElg*K6g=tvu;s$dWoml=DRz7R=(;ye(L)EZ&Qm-x{7OQeCx@K%xRJSbaK|t<4x-7 z^NWfi_hf7o6P+13FLGe=-8x=uO%`DHsXtFQT;1@5aknT)y}>cr+RpBK5ZHTzvjW!x8;Eh4S^dpg*|1ov1u_SZe0k;%ok zZw14n&9jbnyw%YqvY+Olg>w`m`=O>;5`{<7z@$?H!a4kt~UFECmCWnlT+zkz@2z7@~^ z+~gW*e));b(Z{Fm{eBbfSNZwn)7j$l^y@E}w+1$TU2^u-9Q(9~`!={~Z}(ogdH<)M zMdxnDZ!vtKG2u<;f+upT)|+b_IF;nWazAWk-n*+lhvj1mThms*x;u-@%zf4q(L?*| z&h32qfSF(Gebx2d3CTRA)u(;Ur=G9-cDYKXc4o?FzmTorHxItK_%-U}^lwJ__iWCK zwchWpI`ik>)9=~GlFw|K>aKgNZW{0XoiApm{y+Np^!$G>=T|$fyzFnkxaOsI{I%Ul z^M&=pe)Ihj?Y9q;3yR&h;`l+%EuXVk@7>?!wYhoyLjIG6TNcjH4bZ-9x-?<0So)*C z)6b|pyUOtT%DTUL0TW}3UY0NIf7MgBWS`%m_0_LKx!SX~L(Ehik#m@JibKJTa zSpf{M7w(lmKI!07wW3cA#=k0Gom{viD86x3^r_o(7Wix3ia*cf_-AtTZ7b2~o~dVV z3fxz5>V4t=F8f2UY-HPk2c^%xT~M}ADu0v`8nx-$j>cn;>qCPt^1O=SJbth*ka=$H z+I$w18xL%QoR~BCq;s^=>X-LS36D&(o$1^i>UL$~g{<-qN)zraZ4>*a@?vuQGt2#_ z`c~ytJX!dF*ZT7-GvCI_#qIy*+%SFm%aKdeJ{bO!;)8=hfw{K>|A5pttZ-@F1uee{_za_x>@cyk(wi3w=8>h8co1B}S z{-JbYY0eLA;}1_3wugS$x9Jn#&fae6@TQg5t3Sm2)}37KwcyKoKhDom*QS3?{HJ#1 zn9Z8vXG`||wRD&DEN|F;qm{r(xX?mT^D!AZ`l@8Z0TR1 z#qB!3?eA38yE~Tje9Sm@+F$PWx9H>Gq2J@@*L!irH|%CS?0okH-_7#U()h3UWn8u; z9xt}9t5Mz8bpOBghS#6HpK}Ovo?26p(|T|9c7Myiy7`*_f4%fy?R(_Fxw5rQWzTE> zN=VDqzV}LTQ|K?cU-S8Fo&U2_>GM|ZIiPVvX;-kH<<>uE&i`A}ROmi^ z@77&r{k5B;J}-{aoq6C&y4_#>D)%RMj~y+|Y`!mE@$F{3uDjgNUqv1FoKGqre;rq| zv*yd<`j?@HIiI-jW@^j(hHiM#z|60cU;W!!q{Q|V_v#I^jQe@*mo2!GIz8^0!rjkN zg1g?kyB<9K{OgUMsZT#B$Hm|KJ1<_ZU9K!5a!bX;bWf-D{*8@)eYv^>&$#Fr-{qKM zm^^jnj2|b&Gj~KAG9CCibydc-N8eA&XDW(ja2N>|RJl2xm;d*{OmUHZ^Wr&G7LQIS zpL%n1bL_Re1%>ywFV5opbj-8jT~5@`;W_{^DiwvRX#0w zi-u6@M>)5(eCs8*uuRkc^=*61bCy++zH=P3-b>Veo_+t#_vX5n-SIC}+V2*=y18wW z@qURrMW=P28qfb3zW$4!K#SQHztS!_mdyI6;rGJt{W$jc>yPjI__{vdJN5MRbjugt z`Tu|T&iCQdJ-0K<_~a^|Oe{M1^ZE4TrQe%aKdU}Z-TwUZx!-MZ;RWq)B9<%c73&Y0 zU>3VI;o+iBpSenmf(y^Rv5Z?=J2%WuJ)`2N=>6}zgJv>%7l=ncDtyh$)$%Xe^52ii zr(Q0fzfN)|yT*r|+iyJ(+SzU9S1WArMthjZZ35vRj2Rp6_9V8=Ahr-dOm)~h5ilY z=azq(Qj^>+@ps~!)x5jdS~o8aQ3<>^W#Qw1E<@Luy7A^NPj_C@JiN{^=fviM{YfE`Cyo< zpc%EMc=skRCcl-B1()Ay;<0adfyWm4_OzuxUW;to!!-4*HK1yBK{cB~CrdLh3YCQvgv?a&Q zOkD0AYvSI2x^gAbZ(3L7E1%%Zdf&$9oNs9Ue}RFmQ|^Sa za~Yf(o3Aj&9Iukm`PQ~{>egfB>JiayuP19{ZGWl%S)k2K^3R7zZ_AH`KeXyhOjT=y z`t`gtyOXbL{#@2=HuGzaRbq6N!ICrG4Y@C7eJg)DyZfwsX<@{xoJ?i2DT|A9%>3+| zSoe9&y?l+)=#NpKTr|t-YWbJMNmfbzUR>{>)VrAOhB|jx(fA8tjpSDWTNx$v6dE(wLV3YmIvN(xL#&> z>`p`f&2JW6EnWW&OBNeht(hXVTHo@8@XGHS&pBuAdHZ-<-bxK+ZQpM5?MJfmcZp24 zno)Zq)!R_Ba+3JcT1g}2B{`S!nA4Wr^JP{4&!YO?=6um}^}a)H_m|w2xc2nW&H6XS z4~4mAui4h&wA=S-#r9UUyDMsUNZtFz@uY4>(xQO$+WkkuS2}%BoVv@GP26XiW+V?M=I?3|#&kuHknKjGPg6}O_ z@Mw{1x5?$e_nk4n7c~WK{PgK+c>K}>r{)R@1U7$i^%GxpnBRVn%=(*+Iv$4}?~D1s zv8fji z|*x%auJ#S15Xo6Lvp4$vqThXI(0+NL?}79uyFU;4U&qc4pL%t5l9^7?0iEk> zPQR~xU;Wg8HD~$Dz>F7<*%J4PpRWwr_fYKUX3e9sDd2J_=?S|7uToT|2b^0lV9;zdTY~9pN$jZMLp8P z^z3fLA3V1A+pW!izU9}RIOvdKz}-{cEyS}oW|w}{7sj(EYCXHH?*^>fBP1Pun(wM^ z|IyWJgZkO!Dhhr+w*PDY_1?9`q7ipOH!WR!i@p4~PC@aV!s9#d*?-@8K5O9|`IDD8 zY>Y3LZ%q@JU-@k2(~z}h`{v%eS~*9|WS9T@Eh>U1o|>}$_`GlF_snlkf>XKx&}jW=h05q~xH!QacXGGErIcHMrzW3j*vn-33~vtsiKe%|Gh+r2Kw z;@s_k8FQ@TxE;XGEu_69-~Q_UU2Be9opYr0 zk@cZC9jOD3Icz~UuBHUqC3xKmdb+rM=9TQFKUu#&ar!B-Z|}FMYeb#GKAgXiI<0M2 zv)A`;ZFg2h{xEI~^_uqav+MDt)(sjJJ2o6_I<3!{s6XX~jLWlZyMt>Qql%Jh79F}E zskP5!L3e>eY}%^4$*FU7{>Ua-&9d=`dVg|FNu^wowRUxr)}E`@m8$QLJgYP+ue&9p z)*1a`M%nUrYoBNp^_*Rqed^`YuxHn-{;=KG;oshHE&lSeMK+&wgpc(ul)bluLugj^ z+UOGxUrwpZ|L|ec+(@x0QpbwSx+Jf}yftH-y>IIczb!dw1{ojb#@UvO@(YAK^o?`w zK5u0D?AjU)mYWkx*&UO9o;qEX_w}UFYGt*R;og@|mSw(WPgy3@lCL%GAk&=ki*`EF zb<*CgTBSwtrcq zGk?{q-}*}gZk_zNrRgPGWz*ZI-+CI|B)=#Xy*h2l8#Api?)2)WYnEo$R4<-0+JEGm z8DnYA3gsrXiEO2}j@&HBe733H^v1OO6aG_w)fui3=kxBi(w)*6eeB8dDp|#Ui*4N& z#i}j4y_~5i=+ewx&%S?GKB!#y;%UfhR-O6lY`l)=#Lm0XCFyM9cT6q$Vf@>|>Pv>z z)t7vJZEMu<;g}j?VRCGlR`02ctXYmp);51$u?wAc-4-e}#k*2P`|9bo#!02?UFRrw zFS6@aern-7TO}aw#;m7P4)W`HSryFxW;tb{_#V#-lJd)MeXC+ukyKrz{H5{hx=7~a z;|e!VYz}XhJy{U_Ozfk>-=8JjA8s9cV*1J99>b39;gavp+}gq{c-K1U?GGsnx8!J< z;|sQln58~@aEV`Sp*C~iDfwyEcGsMzhsgA%_S8JRA;BTs@3;4y^yJ^KHm>}wJ#n_g zm)z2K=Q)hdURmRw#x-x5d-=+oCT~fO=*2U$pJxe*g_)_%FbO?qCwH{&-OZ~{<4rCL z{?>JU^UyV*_4q=5n+Fd2lP5`beVX&vK2$qnGKZAllG!WWx6hP3w(6O9e9cCtlv#Jx zqSCA;ZJWI{_UG65|D~+D{e=#1SkInmx&E2!#@Sh>-i>p&^0DlFs(vr%-sgGWE81k9 z28%9va_qh9*=c+Jd^-JC!!&os%@X|=8xxxvPkct1X(S^Z(lro(;K zFV_Wrn);q$&bJHimom_dWO*XCb&e7XDV?4xZN+}q@IPG$Dj{$RPOBUAcPb$Wzr7+3$zHvR0>4|h+U&r;Lt zzu+HkFoUJWdTV-Gj*!dTt$)`PUGh|)e*Z`B{|7~KiOXsQzN9oRe4W4J+~zn=g}BnE zQ?E($H>mfWscV-_*S7d|{OOj$1_Niw6dD9LWZk!6ZTwMAtBt0sJPy$LvW%sAGMnL+le^xRtS~yu6!m0P-LZs) zpX;AC-mN*|6Eihk@dRf>;W=lH4+#%-%oMd#v-l62sj7YVjZE5kZA(>qMy7-G+gIl2 zg7>MKervmOW7)f7kIlD#jr({+sr&(!G1mi0w%PMq20zf)K2-p};=w~jXVZJKjM`sdfnoBZY8-2M`kc-XygziHjy zXQq{F)^Ex!@SpncTmO5J5aAVJS=WAN86UlwAG7+@i%N~I^tolmMSoYQ(MUohvX_^$=UU)QP>_N-0* z$`^3Tf9eIj(y#koy?yNV`Qf&XoH?c)ygyg^pYq80rFnX$#`aed{@L*~4g| z%kPslZ>?u;wUyl3dE?(L*-cS7x3X_9-n7<9*(xRb&I7wGqMW_C>%K18T)4sa_9`B> znza8ZvhCbKb+=?UtzQ3O;$&@K_d>t2OTROXC;r|e{dvm78>bG*%qrxsl3rQ+!71Rz zR4e!Yi~YC0JleS$^GWR@_J^h#5zK1vZ#@+rFeI7hsaQ^!G2%-3xyE~=%E*{*x z_;}pi4U0R93O>H%D*13L>7o6^JB~k_t@`_0^^R@7_bm6u#sruVJn&Z{dAPk5(( z?^l@Zv0dvwnf&;D%;j#p-`;PtR-cxgRrzy~*pkGfN%tC$^Bk7W-*K_=_>+@If0WLu zE$fogPD_(CX5(CP;mr=a4NOHRdX8soJ}We1m$&h;O|pym=L?HIu>5ktx%99gqcl@; z4F}gJ4)e|Dc2pSs{={+iQ_PNng{g+S`y-2NHdP<~di|$hLSB?!xI(XuT;wwK4@*<8 zeY4KEcJJa-k+W^H7e-cTyt2Rl;K+3ETcZ7G!V`Wy{l3?qd-j`jTPOdt_j}hIpEP~C z^_C)wI_p;}l=mi?TCne^F+4g|`jqbWdr5b9e0(hU^LF0l#rHIvh32L|(e&6cKc!+@ zJnx%8e({)s#`KM!IE;<`-|zk&$2wttDFd^`rYGBqw%pTybzr$p=e{*gQx*z&Soy`f zw;BI-mS^SNoMs&HOM3s${Z}7s;5fn+&6#$;>~-$bS=s9*zWJaVr1$HaYu)zLD}^l5 zg7)RpV^8V-zodV1+n2Rs2A4MG%dA<{vE;sqz1RMGxqYDvw7<*l0JUA8-uZr6#=C%@JM8U}?+5n%wtcVrJ7a4}Q#;F^!*3_c<~-k+ zo7OK>a>x7q43=)?i?jcJNK|F|HR_VVM$#eG(%-ZIzxC~p?m z-sQbnJM!Z^{bU`!(z~VCqu7i*BTRf5rBzpg5vDm7Hv&NKc#Q+*)y62Ox;|N7e3YA=TQ8IC-z(q zX777*s@k~cvFI*x#lqYf_JV)(V_6pwN_lUTW9Ac#^nKfzZqWNu|T@lS9tT?opRAT znfD#|_T>7Tsn@U8ce{4Z(zve?wuRX&mu2>z;{2Sg=AVo1e>~fh)*tt8`o1fV3z%+S z%})-#RQmUgXhQV8lltEyuf2>*O^;pp<=89pjbrIQ}7iI|P z%&*eDx^eT(fa6+U+V@>}+5I5nN8r8brQeNKO0PX)VQA*1t6uqfPSuN_X)`_7MtoqG zuJEc+o44-pmGw?Z;ic}MCM zp0=7B9Urh?vDK>l!z8o&+}|diz9fIja0#=QT7=!AlUH8LByW6c8hWCndhL;GJ73MK z_%?I?*V~`+Pfva~H6i-Uw#RE9H|F+t<;&XVGisK+kodM~^2d8-zbyam|DE*m-~s0Y z95Ww$e)e$d0i{inAFOzfO+L+V<<5it14b4%<6Q$t;y+=e3`<)AxVi-XEZ*sc>@D^F50%O;44RoqS>M*B8HEZ^<~d zdDg`$S;uhOZEsYpD?_T6rY(QB=kqzP7`y0o`~S6RY~FW=$LCVdzPqOnw#&Tv?y+yh zcl}5Ht;b|i4u{ux+*qFb`DAg?SMgUj^3vW0Zol$BGvCga`&CSWUBRQ+x&7-S7C!i9 z+B$PRx0ud{H+Q`C{`Gy+KH{0{aOm1vWe4-n&4vB?>{*O+#i#n(3Vv`_%54?hveG!s zBxpIyn~;!q7j;5!@fnv~Usd-a`N~;e^Sd#2KeFXZ1aAI4^zCSq-=3sXcH!1Xo@vfn z>AB(dzOaJH35qrIDjt3Ov>{Df=s`_Lu1emGjBQfkOCFbTh5dh)Uw7i)EW6}gUljs; zh0Wr(IydcR@$o$VqINcmSmk~-?(YH`UwD#V)=y6hdGvkn_j}9dd|5X6wD@@|Z!e(^ zLF3G0{LJ4^U3=VT>F4-U_SDtuF{`Vd&0V!|hUmeHrZ4JR5!LrEE!}p|PKfpG-(RoS zUwv~iUZ?uq#@WAK+$#Ed_4*2xKL>n*TP~MztZCo((W1I<;}=Vzw;WMX?$^^woc!+a z6eoK{ez^Aj&a%}8$!Ax5GWP#al+kzf$sUTP)>84+OWl?Cz5HdOXkMo#qSoi3cVex?d6J$>WrMtk)_{ zlYia~X{!*a7qgcn{pPj#^=rwi%U3tPxV)YB%BHsqeUG&9F5LXqH2%pk{=-wsuN!}7 zzu2`sHK0vMBW7~_gp@O@PPOj+BznU~biT&7XX*B=VmtmGxp9y^=c%Qe*`F^9|F@kF z)clqIOETxxlA!EMw`L!7=3?8hjOXu(^Clgw=9}6#Y*o4_zU1Pm(|g}eI9n^r|FS3i zk^PaTtH;Z3+?$a7Tyy{1_R!?t3e7BRu(JSsT(9w}O}SoNdw1I+-U-)#t;!d-?OXhDgKnM88-?Y$>FcMmZ)4Sq*FK+@xUWRY?p4^k z3341J!X36hk1UV4qL|@SQMOKOcD&C_*C`Rl1nM~r|Mw;)yIoP3=GekLrCs4Q`}B=P z?HkW5>Y6S1#_M*Jj?IOc(p$sQGi_SlvTvAj`d;((w1kU_9}{}R8(O=Se@d18)hMXx zd?K^+UY0S_YH7y%CO7wWZhRm)rFg+JwL{|DyLuU|Z#$k6)e>>&JgD;3Y{k5vlUycb z-?P!Z^!b_bDbcDuv&v(Ie4bo7kaL*Z^!EGf_CMrLt=s)>m3z7Tmn730=W^Cf7hyS4 zCU(#=j(f?67dr1}Jo#JqLW8l;@j~6DCnwU))Qs8ZSN)Q-J@;#m#}j+gEnm6PCKgC; z=8P1yIu~eG(%4rnbZOZR#UR~Xa-aS>#U(~>`O)cqefpj1{7Oeg{iYO~ZD)ARm^jXy zn`eBx(dpK?&)H$wp&um!_aE|~YjoH#s%fFkynj7!?zkGWMY0@g^gf%FoOZWr zf7`vAY}Ov%|NUyuw!L3hn1AD3RJQZnrkBp)v87XMzwK#i)XCZ$_2r`8mZ|*WdJ!*< zMn}lbo_dF~WmoNrH<_%u@;m<5eNI(-En9v^&Qw2sa{zCA&w=-QzuSDglzi{CN%e)l z3$|I`oN|ztS@ovx=DfEr(hl?NzdFgj`uWYeaLxBwe=g+z?PH#v6ngtn)&AF?pGD_= zvsQY3c6Ru_&vV~fY;Zd;-Rktd4SU6&{@i>2|KCknTbnj!vHwVK3oBecZ<*Eyx7Z+l zrV2JiW2Wul2d3Pdv&E6=?uuDo&cFWnQ@qaQ_ln2fy2S~zs={U`JyYDaE}UVei@am` zCk}^A2Ly5p+hxD}VtyN|rr2a9xW)Fz1LrG!X{U~}By7#-zhz$Ps!+0tX>#_JZ5f9* zf5~E&OHEhP=wH2f{qOca4j=xTv99F2_ip2HIj%hUWk+kb{OG?`$R^Lpbbn348~?vo ztnZvVXZ!umyXCW9M)hQzo%NN==G?{Pd+I;F^6mNj_2u$;+va`gl+XJ1E;vhh#`dbO zo9C(a&fDXCmF;!K_q*l#>e(B0nYOYR?+l!ro!Y;S_ohY&Q@`0k_5Cxd=7_fDe{xyz zYLh*a>hVYW#m;P$x!pT`Rr;~lnl&mi_d49{EG#BGuSs5Mf6J{Vvnin~tU~^n)2tmi z&reL*@Z!5nv*=y6t>*vc2&_;_nLNq;#pzzd$1`qiJeA?6qcbg6s_Hbu@#U}PM#NQK zNX%TGCBMvY>%qNePc`TNm?`~JV)duATh$pK#5--1CENE!F3)|Oer(PTGY9TIDbMQP zw^r^t;Ql{y|J~{0AAN7K)LdFF)^X-aDvR0Q2YXADRc$|APS;x@{i#MaT;5r))5^_! zg9TU4C&g}?FTT|WzeGr-^)Fp>wfpm*Aa4FA%lAr}G^Ry_KUvQEO*DC$P;G!{%(4^n zmu23!5BsVxKPCF^vag4Ga~M`HTX^L=d-=aCV^x(Wi;Qb8Tn|gOJ>^~gSHd~gO!Mv5 zh>C~FPl{sMUN`pbYiYXV_cbPT3-1H>B-P|ibp;EnuFU+k&2ek$?3Vd7#`B5muJz^~JLvOY@tWz=P3vT8awji(mEvl7 zebRwP>Gd}6LaZctWUoh^ZgBLSd+x@q#Kp0J#||{tw{N_&{l~u@6T5q4-ZN?MbxX)y zCA!Wl#6Ei8pH_ag*K$^I`;{60rO)wLdU)Ly#os}{vYI!Z~F6+=mYh zcfI`I={t4f?Bru7GA`e7H$Hai{HN0U^MW5vM-fxSN z{^SoQdN&H)oO8K7!+T?XYOBrlR&BYNe|H#X2FWrf99pg>|Fm+xZOhuC)q5v=^z1$x zWV!Et=x(m+m;dkl=31RC`S*IglG!?|U58J}e_1Hj-Sy`|=KM~BoWt>oH>+ke_Pu$0 z@7|G1%hYf059s%srnz_LeW!GxuZ!>hG4E=f_S>TW{VL^}-Hs8*A|{nS6WDf1@T{_b z$s||%g58VwSL>|jwLG`{TH?l2tM}HVpL###-?TWyJJnQXQTUD$%4p;_V1F~OmONbKCV5YOPeg&@jzLzRNk@a-Z#9`sQm@ zX9Y^$UR$)U!r^!C=X1pm-prh;eOk9_yNbDl!H30Ht?KrQ#YXNZSok8c!lVDl^`aF= zde(m4adh+j6J_si@P0EqJ+VRV)AsAXmH00`(tlrZ+`7kicl;G=|M&6RLf(h$S-d9j z_m6{5?-xIaKKDUfuBK^1`QP>S@q7UeWviN|UeT>nEokp$iQ}AN{jhlM;?G&EmOlgD z`#n0`Yi7PUPy5kZ>5!}QYZa?C58DZS^LUs|zunp| zA5wW~>Vdj@4u>zB&s(J4uP<^%*ZkR*+m^*;-z>{6zPk`CeR9d(EV1Rc&MUUdJi2bI zAZ}&%;%s%$$L~^m_kV5Qem9Ew=j5*()jB7(^vivG7Rsu#q4&gfhu6JLJ{dZ32eP?{USf}Nn*B7gU z`87rlMCJTf-3Z^|zhJT6BeqhJt+P)uG=K4ZcX8!!rCy=jNd`OGWDm|anuWo>)1|UpQq;5Br6^ zlUUB}3y|*ICVhR&6W7Y;yH}OpYOGz9R1d};i?z2QQ* z(P^pV%PvM|wFRByxsFcF{##JI>HQA2D@>=4FaNb zCH8Wu9!ggHU!F{o(EPUck4x#17lB{>)2nJ4*4i;gKgR~a+3KEu=B(Op;U;!6>+$1T@*56Sy@(Tuwd!8DK8NSdiL{22n2aAeJiqq z@yJ8I6TXgLB&$mAH#X^6MR47+n3kx<7HObcD`zZmO#LZao5EoQGreDjYnWzN@g@7} z?i5b``E^2k_~Cm~X5XkQ@t&)x_;dQE-X!Mzo)MD5%o)EbO{O)jy*jhlZt;c~$6Jm! zn-`UQpr_@H;P^^o&M|Ygqod79v%$u z=MX$1r;w$hVPswvd?tAu`T)90_VuHLxD>v(JjSsFe#AGB2pH6qwr2I!$EO zJmzignNy3z`ggwHr~0fh??;Qim-nFnrZ_np(d7Qnv>Vf|G zx|@x<6`x=0?|b;eYpu_}MSb~uzh2AG-lW}>x94^7@=XZ`4{dtPXYF||WWKPDbN=>1 z7t_u^S0bHeO|nqA;BJu9{Ne-ezdMD?WlvYvKdpUwTfFvme2+}UyzXwk&PGmV;F+x6Q?UHv4{h zr?Y6SOqSH#_KRcsw}gi&bziUUaJZ23t0$AsKxo3!-j8~oX`zdR?LO&0dE_dY+rRBV zuXUr((L;NGT>5-|ePO}H_YtD!zs|~a{N0dtmOI;o`;#Vnz?#WDi+f+Ml})X-efCyz zSJvh;HBYYc@Y{b1P@fzre0uu*_^`E6EB_juUw1a@pibHvxz+ntI-gy2_qO(p%|W*P ziyv!W;;;YV{Q6i-K+tfHE;?rv9HQs-Xa-weK z|5@zjzhd!~*^)^r=YDekx^mq$dBfkWiW~OL^L##~@!U)!{qrBW%|0!id*$b)DzhTj z_RNi@D>EKjW%+8ZpRaLs+ounfq4G)zkMcG+CV!LIc_3g?{o9|9>m^oq9FEX=m$l(U z>E6W^YA-#i0~~K$o~z#YO|0{R1>dP33p;ckZ*4D^VeZK8`D%K`$EsenZSUVFws)qi z(%_4ZU$pr1Dw*3%yf<&Wx-{YO;k3zBOZs%Ly><1m+E{tv2d8a}`I)ey+X8`Cldo9Z z?bycqIC-<+myVqI57Unvv2|bdc%S3k#4VFuF8j-S10_S>{afo%h<>D7j01oBd5wxah@)I_6Nh+{U$adxAAfpV+${ENqoAz(^~Dm){yb>;;&CD6c9GumX_iu_|2jn_=#;*$=aH80w#iCZ5Zib(w9PC2 zSX|2Wji;@mFCPoP`Xny>;nYVqT-DKsPn|n2oUpOgL@`VyH`>EqvOSf>^FsK4Bgc0y z)=O{bf6vLKl-=Vt>wWdAGg@+C*AB9m3O`=*XI=K6Ctp8F)*W;I(7sPq&g$K3ai4&1 zHJc>jI_2fm z1V?`RS98tO@7v_RwmjYTeWm`-%=~8?<)@yBXWh4b-8YrD24=sU3Owa!XxB}g|HAE! zr*NWXd-yi#jK9j7wSk%&?Jh2x>MeKh+5(=aefbTFs%GcsM!x-2cvnSs`If}j&9b5F z=iIkuJrBEkmv7^(9U0P7_m(Rkx%F(v_0Hc3+Zi9;E;BoEcwU*9*dp`qGv8bkj0?P; zxW9JkpAG6d9qNor=l^^3FZ$c7^L7W~KHi8h%00EVD&c>{jSulJvU769Pdv1-pR@d& z%;dI>o&G+%`HyUSyMH=p+~ogWoBv%;FMV7rT(zpyoJaj|-GP&H>i(bFcypzsiQ2T& z2_`EJPdjvM?mdJ5j*)xUo^?=}`?#%2J2^Cv=fjS2xu!RGjOXki7bn^DQMA;l%2hcefwgj`15OOj=e9e0iCZgr~2H@cdtL(Ur<*3`|Wnk zjBU5L@2b=vzbtb2-_-B*3v?oO9B_25*lNYgu~wahd*az@@5<-T%lCivoo=8#dA5bz zT({plcfWmA=2S3y+bZjjT9w#}ys-3B({-9u-d8_+a{6_AkV45a`OnL8&%|$V;MRQm z`rF~fxA%xkRA02N)42J-bpqc79oM58wv$<1w+X+!WjgCf+%3aKDmqnJu7QGkR zJNwJbuIGZ9XZ7Y;1%I{f&zPH+r#`jv_q$*|`$r#&9=1M@zW?Dkn|)E;`Mcj&-ZFc5Y#`HtR=UxSS zYHdrB(#csow`ujCmf2b-?Yeb3!z@+&uI!sx@@Dhe-)dDyEN1UgYo8Z>O1%1~-}XeIegm!}_3yUHh`p7PwJr1X_{DK^=8NXNx`79F9L`?oBQ84o z$u`5=9`7_;bnI?U`xq=!t|PTm)>;0-{e#8-O(HJMHNSB!zLDF$*mTLdw%U8IX5M)? zv44#-zuwDTR!uv&oY%Uwp4qnM$Gr)2e%E^6e_p0z-X|+0RkqT$?c&_IFYJsu^G?iF zE3TH~pWHLy;<8hx-?|=Od*)pH!;o0>yO*5Go(k{E_F=#MLH2-_z0b7gKiFs6l)m}? zC%rag--bo^HodzMT|CvAe~vxNr;POGveF%^f~N(S2NccwI(y615{I;Bnw#_04?T;R zS+lVDyuo_D^NnAh&QjU6Y+jU{Zf#V`yc_8|PxNJHbZ4h7ua(tzUMVm8pfH4 ze^KL?{PR<+d!I^xL-ijGoju0&d&*`$T`N~PC$%#-*LPO#@A`QD9PXHZzkk(FUef>8 zf@h9HvixQN$sH#?ADcUGbD-vrymL`Hx1~OK^oa3)V)g&}uC@C-`k&kV zJ*V)eDedaV7aHdC^j`>GJ^K6odWPeYvji(9i|Zd;Zqwyu@NtcP&B3e3S({xH3jFtO z?w>k+=GGl$y4?$p^p>BJ*sA{E&~NGVGjl@AuAVuP$z`zj%;V?3n9sjCvbe9R_UDQE zpX;OEJlC*)mfa(_ICY!MK_|JLuG_a(y_uzN!m@f?d-AHD_N^VIGUy}3VHqIlNZyp%OXd5xL;4% zl=bvg(YNq@Ns~F)_AYQ=ytBb~zTM_Gn||j-JxSlDch6?m??rO6>w|YjbYHRgW6)@v zs@1sDt$W=Y^ZJ7h6Q*urpO-Gexm8KBnO6|J{WPrdc}A%r!VL;}OHd6jryt zCni)BIJ<86_WbLO@8$bG=braTIi~&dOw69|_o`#dPbl@fe~T1&_Wf&~cbL=id6i#g z-Ru`uZQ|6)Yp&h1PoY_AUgQeNzB6hz?|6?--T&vs@l%dfZ)QcyZ%=%iT()Xq+>Fkf zvoD({H!HmG+1vg}mGye0qTJ@nRK{wt7dJ!S>$|?6VYzVEratLY;phKl{rqhIzj(WJ z)4V0@!tt)3)etOKvE|Vbl<>=Aw@84f@Ow)~43sDi%kL@HSD!t5T|1Zk_Vf>nb%WF#6qazbHe?ng$+)o&Jn+K{;LF^vg=yB zx6pyn{QCp5zO`JE61y0=*UZ*9^K;9}RTJK*~sa#yhrCa2)iG9^m)nGds$hJ>*rtj zbU|87<%!y~Nly|NyCL6|GVdx!p5)rpT2mTjl58KK1PO z^NNT+snODN6Vtcd3rWr1`BQ5?gWLQMuJzYge@>ZN7MzuRa8@-#)ZEFS^UlRdh8bnrG6D9dR=7kt^Mm#ERzH6huer9U&-3K!`_bkf zGJ|zDP0{Vm{c|(zx#Mo?zZIKu`q}c-#Oiszv~OG75gwiP@9KX$ zxec0JPWe}N)Cw>&x8Jz6sqD7${xqlgU-Rw-_2|hoPCnAsbA&B6r`qnsx=-1Ax77%9 z*S^Sby?Er)$?gZsZ!ODc(l64M-BT;`JTh`lC``lDRE(fj7NQeBgld-J~&vzF+WFr`iL5%{1!GxzV;Njmk{S4Ma_>xJ~{TkUPy|F&V~vBeLh ze%j7+D*RA!RDbD|4J+R=%N+W-VDr;iOj^q?nD1onjgR47{e6zDn8%AVfiJEnpHyZ& zezo5wd z+xp(p11}EBtuX6L74XinS7`YC{qU!!_D}e4uU@Fhw!X0R-+#4jySq%jS{JMcoIkUb zrS00wje$+gEa~@3E_ueuS~kgj>M&#KvF?wh(^nkLSvLK;=7y3(oa(;> z)0nh=%vx~5rPD#8|JI@T$KxV>XDbL8E1yvAIQ;m+p3VIY67$oyOyGSx%{B0oY^T1) z0q5qu&)@An?J6D{BA1w&an(>>ZxKt<&c#m+v%>bWxj#62-9+<8Q`qx;KaWYD;?Li^ z)F-^4+tc2rPo}?8Y?&EI?4kzH1$Z)1XB zf8_jvL!5Og67~ko0(U>&jV-?$xNo`S+JBpL%vYsao!GwqUi^;h^Qw3Lf3W{>zs06E zyMD_ZOH|&c`v3R+|8bE;=kGpLkKJ?f@G|Ca_6l;w*Dbf~+pz8Wzgy-zHE&E|nRmSF z=cLp9jOXoECv0S@yZyTO03-Xf$Eos+HZi)~u8SKMy=pt!;ju+^!}~uk=a)6)PJ4Cx zeelsrVU^QYS95d33H`D8^i}{IrdkzzBz7U!M0nE z&VEY&n0)61Xrc0!_gC3hl!rChduz9T<_mr`|C`gHd2iFsXf2;pH7h;m*H!jY_y0Hi zJss%2|K6t!m*dTrzPYs2`*g4Q9ff;)PEUQd+H6I*ypG+6h9>^Z!)Ff6v7axwt=;o_ z9N%W0{U3YR|1K<*^H#q&o#WH|C3dook9RzDPIK5eJ@1HJMPqRR^J3#blRpb}6c-&0 zb7pz{VS~pkF?&8SxiqC)S58(R`<8O$gQt{us7~#weH@i`Q#8Bg zXy3kdAzM;|0zG>72;?!xgnxU@v9oAWZS(Eh{_FSjoteM4IQen%mp=Yf&D)z?QunuP z?A@!zGv`*}k1ClpqFJ?96I6Bo-g~!pPD$2hD_ad8+tvGh=S%-w;Qe-^k+c7+6S7L@ ztdnFzs$Si&w@EC#dcW>qyR%h$c0r9nmsw!pRP%`6JAR$oW8if1OB;LIjb~4yPc|!m zxuktBJF@WWyrt*4gYuoPq$R92RQOPO-A-$S{dd-%hV?FY=QVd*IkmoNe|9Z*k=DoX>8W!MKaZ(i#855iemBlVYSODP zlVzLtO%43j@#`wPdelX$8%&s+W)=2M=84JPAJ*AB>)FLQ&W&9^o0C>Ze|_?A z-RtO2UFFJM&QE*i9J&3?V(q7$W=_)o?pjRSc;HS`{aXH%pYHA-8#ktAF~8j~U!&V! zmU&5aQuSQr8OA+pSFzV;aqe9iZA@rfBeUHdiUl_rJRElZ2{x z&JT;%p3m297QC^F`P|`UA9Oc8WL)=7*Sb&e?(4IW51jV1O~0{j@0U2~3)Whel1J-~ zOjD@rek`$fw~DMMbJZ1_Pt`ia zp5mKc&phqy|L0EM=ehT#f37S)@$H1{uGz9JKRe&dn^(AVyY!}W=2trHx5o3loMTh9 zcjNNo(dV!1J=|8?d}CSN1rasnZ|AP01#i4)URA&Sht0ih_p9VC#6H^g+66)(Q`d3d-BEn{h&7A2e%zYlLH^%f9b-wCc(60z(+{&|OXjWXOj5tcmTSMS zzQ5jzV`a3rec8H)vjywd%$_CFr1e3u;*i%akoId~One8!XBv?0psq;DOceGCKd8~@Pn?X3E(M>NUhU%-K;Z8~aPRy__&x_oU zF)@8|lJd5*GmVcQ3}9-|IP&Uh&CaKL+idLoWE)gsNcbS*}fBm>a=f{+4sk*_oSz zE8kb&&z3ynbVU5FlFeg}HhD*nS8WW6-J%<#YHxM1)O=YIb|LL)ZkSO{lDwvqWjCvSQ-bEU-+%#A6DO2CjCBoX_#c zeHwhTbc}-X)PouRD{h`V+h>yNg$CDnyA$h9_$^u4Ug9gY$vs&*Qh@j2!o_L}|Gl>SVgARLDofVRG)xg$UK6zLeDl<&64w$Y#i|;bRW9k!k-oP-DCa@a z?blLwV#BSrbV&y;xVm}u<1W*>h{UpuI3lEu&(;;QKfD8%t&}SzakrpZ ze1hqmCmj-7zVbP+hFr^BCOtW7nYKjHthA2UFK@eL6izMRGJa)a>{wHA{=vqonD09t z_k}vN#QQ6I2=j+6KK`RKf!kPp`S}~?xG&8qdbRRtkZsuC7mNAL#jktLtNmtP|Mz;7 z#*4`F45|^6wPWwEZ}rK$yynbj)5CANkpq!|bOUMg6D52O4~x66~kF`^?>| z2Uk!3a_)HW{hC=#8`YxvBAM8s5gRAG+`{ z(AMqDdJ9jtoeXY%|Gq5w$_gk*rN}vDr_VYLYU&sGzc^Yv$ha}{@O3(;7yayYP0v*^=V%h{q)3|S@ryR{tqti_kaKX|KCg5_dkwaX1DuLcd$aC z-|Wj1{>PvE|9!Oo=Jr+mWqDYo#f8Jaem3@JUY>IH$oBt-Zu{B)T5P}SKG$E(o%Q?8 zt?ECU*M0tCzW;sxynUav_j^gN*54-mT)Ta@e2zYu@)i2Vd5{uf6~BdHuiVdoq9S-v8aY zuXnd!?L-aUoE`ta{{OW8^+Owd8{373PxS)K6n^gdp)9rC|62H!pMN8Yc%R*WWu9_U zvFzmG<96SsJo|Ha`TA?`qYo*RB~>mo`*3pu+y8mr|NNU1FJE#0x2^df#;DFTyFH&o z*MCvl@s-!+@!@AHd{#x=`qnvfQun&ekxGe2)Tg?MFi1+67aRC<+~(-|nOl85vE4pl zUCmbk>C?M%V|E7g{Q9uuNsL^Z?+P>jPko_B7JGX*TIx$zCHNXzY)W~#tW5CgGl!s% zxrf7c$N9WHa{s6G441~gzgDcP3^L3NzI%a@W$yE*nF+JM^VEO2o>%!T#rXLi3pGoF z*r=VW@{g{!@#!@+ytRC!%M^nz-2AvaKITP0n5V{^{fn0TyK>*r zZ2u3ezNSBq^!4UYsq+I(=4OlkPDpxPsfAHQtqkvvhA;QQ%v zy~SDf$cU<3e9A~yF zSZif}?(e2^j|A4eWeT;HUnCv9@0sgg&HEEh<^J$KduFexy8g*2$98qxU(*{De4Kkn zq;tT+w?$9(7K-1iaq<3;IX~Ic^WsU?BFo3@7dI-Ddwjc_x^Tf!eRH1fv%XtZ&)5s; z=I)mbQ8xIwtUY;-x#;$W&#LnC_`Y4!xifj!RGvGxckG#}Q+p?Mm%`=+<>ggEyEe>g zm$)%ct>ja{=KX?_jUOT=T%8(x^1-ZF$qfs)_uc)_yn6k_)o*XqmTlPBx$dss-@D&J z=TD4y`ncbh@B7Eddl$3%GUY$V%-bOJh<(}48z<%#R$8Y&W}dfV`SUE{kA`=7kI!bC zo%`ZZ-}dmmzXbE2eGr(*|HAWDPRWGex0Nrm_wZ*uesc8IiJyA;>k8ConLD*iPx|Xz zwukrT&I_(d?#K3Rwmc<$-FcVxr|x?njxNvtH7(!v@A_Z9?s8R54<8!)*F0Igy!_v( z|K-2r|NZ`du6)kNE4llU{w3yWe42V^{;!ksKfU)cipt@zTgcC7|M{~0;@*SbHKwue zEo}SueE);Q|7H*C|MJ&4lxO_=^fLB+&Gbi4R*U_6xBHz+jZeJwKYPFYzpeAH$4=_6 zGM>8o<3E>p)&FzLKksgQf906Q?7+%`?xq4B{#V;|_y5Y?=T|OYxB5HF&)&2BFCTSr z*A$(5AM?rN`S+LGO|0YUy05Y78Yw2?#%){@P zuN_ZQlMdWtSfu!UNsjH3-8%6r?;rbf#lK!N{>HcPHS@2?*6=H-%PyJI&ALAEyOGlk zH~)QN=YKpo=b0Z-gn*&|)~&AIuB;5S?TtNZ-<<4?@CEy?YA{aso9!kq`- zjpeUh-@ZSlJm!-~$*o-5D3XZOs|&_{m7j*OI=f0Ih;n(LUSt)KSzv-{1GsrBb8`|6f|x_Es~+~>&k zSC6TFRxZC#^j%fDr^nRv^NY*&k5iYs$NgPVeC$=%`S0`PDxU=YFMC>j|F_)JfN4vo z^LzJL&A%V{kl*e{%-=7E<1ZYZ8u#Ys(Lc`W$*(F8Mtr!>sGgN{fRFX3_R=J?swYj_ zY3_aN|V;vRYKf9dy0PDZD8&Bk!JSFauHM8Pwz(^sbc+>?R&f)Nj_k{H;2ph zlh5}EkIRbZ8ox1S)(gnEElRzyXmW(_y4B9#znCY99h}_7+oUbemi(0S(5BbLmFmxx z`1kbo&2f;LW_7YH#8@!c(kfYsC**Ol;xtj?SxVMdj;x&&vt9V7OXX3|!)xn1gtc2I zmRvs9abec7PyNNlB^6BUtfNvblU6+cLdLkr)Tp^ z=1f!;+VfYYPqyaRycZFVTs8If%6zoFZdr4#BldW4nux5m-K0gP4;Qz^?J>Nj9B&wY z^Hr1EPPXi8ZTT|Ca@cELNW3ws71~|9OQk69G{WR#+Oxb_OuLhc6|HXxY=b9O5EM{+>fVC?s5Jo z`)20}$wzVD`BER;JN8u8>&@oXX56Y)ky_RD+qX;$^tZ?f+SdDI>d_9f)wef#|L^Nv z`f0-RBY}U9PM3cvmu+5}GGA_+l>XK5-0SaDUn;*X+wf!m>Gy9l_TGCJ`sS*P`ScgJ zic3Xj-wydPj?I$$?|$>|e|y{S|10(S zPhZ;e>vzv9TYF#d%H8~$t5b!4NZ-kzT5Kq zdDSM9*_A)LvY&?r87z|iY|g(iaq_EV`D&l?m`|ZmKNp|9dj8*>>vR7d+;v;V9T#Hp_ui5`O{C)1dZ`|*TYm_+J`D0eR$dJtFNtgTc`Iz}W&+_tr z&u>Ni@>zJ(;;HujTU(}{5Z?52mAjm!?WY&%nV&!3ecWq3J8$QQ)X5XoC)=;N|D)#U z%gOdnm#W;8Klfvo(d^(F-(Q=*-k!Pt`|ka#BR;hhA3J9D!RPJtSLKHB>(|TdcaWZQ zL{opu!&aZV#~VH$Pqr(1wZcS>UrX)&UXI4)6SM>Fx34xN?~$N({!X;H=TIfRCj=n^RIOMaGsU-Y$l+2*tzGbZ1+>3R9Q?pge8zE69M+&{RT^N!{cv|G^odA)t@|L^~8 zdp|ng>!^8f@Oh$db(>j5)f2(HnycI2{JC@f-<(hDK03AL{M_!m)S92M>fg)L```5b zVm|!&PI`-kG1vapzh+&p*;Xg_F#WE2_00~s{l=@+#W&mSe<;2G=GVtnk1Sr_`Z>Yy zjOF7Z_y7D$V;IeM)oj<5m91$ppTqfQvUelr_!bwc zmWAhDakM+Il2@AfxPbhr%Kc}UuFRidEd6nJ!|Uwxis?DQ8*a~iVkq^NUs7(L(Q!^= z>#`ZGDfS0nZOvbFS4R7<-F@EFwQt%@_~RbW-5QZC@w(*Tjz;Ch{j-kF(#@!@)Bm-R zd99Jx$Hg~(i5y)mUi)R~l6?wKKK7cpALHPE+y6H#-pKO0Lc%wTH(iHzKl=XRrd0WV zem{=vAD7Anj_y-6vJ-Fjs4M4LmX$QwD~$JjdSBv;q{nABMs57TdX@EJw&>+t;rQES zo;&_<>g<)dSibN?*~_(m9k?=O{y(>n;=QRa8?r-L+WzlzOOMb;%d8gn*R#vFzp3om z-2Z9Df>NE?vZs^NHfOhY-+dXnGI}UJ%P_2Op1DM+5PNV>8^E)-+zdnc=HM8 z;^(4S532v2GJdkadQ#}tq>0CL&Aa{T*p-{#TPD=Je5JsDdr9-&3lGj3SxqRjmi=;; z*Hc3)#@Nv7)OIOp*Na!|W=*`+e`8j}k@ZLC9T&WE@p|g{Rkx;QoUc`kJ$5TrcAH4r zp9B0#Mhg}@^8P$6x`%sT{!-hNOzCR1W{c}`-(Q=5T7G9j;=3E?X672mMX#H=PWw>F zV}XgyZ@KMcu843KZmykh(|Y#4nbT({yxm`LqBz%vdt1A2#tJ+8*->SiJ?oFpSbtdY znd1??`7%VQm=rRaH>w+R*S+XD&g~3AN(kNvQgo8 z665DbN2Z61nW!&b6Kvv|cJ)HpJ_~2{IZw}jS{?CZLc~6MR|eDljL)`EYl=l%)uw<@~G z|F_O8ICb{7^eo|z)&DR5fAgg@|7TVGQpxBu59>~VuGyG&`Tnoy`rluk+kO8mn*V4@ zdRKJCTGh_qu0Bsz?mSRlA+qn^@2&B_w=UoR`|thr>wW4wlM;>nXSZHD-mdwnL1$;p z>F9fl+V|PSOCQ?U`u>|cM~dA`)%i75Ul;dBh}kFUZ#0sN|9mxmt&FX^*$sxAcVANS z%<4nqR<55}e^9)}@l&$&pETuthvfO9H@)2`_v6CynvYo@e{49YW8Gt)?DFv3{!@nQ z&Pdk$UE^+l+FtWR&C%z7Ds%j9wfwzuIsV`2`|EZW#hb*OaEtofuJ_LFOYHJX=kH`X z>d&6DY7Tc%>tA=d$}e9I+yCMJE6k8{%+a6EO7D*2>1Wyp1exU*-hI|&DOPdnXLwftKIaWIK)gB6evFgJ?anp06 zmR^1{`Qz8`4*dVn{!hN2e*I5vANOe=&%`A1y(riEs#5jruX^1h^_$z$7Jlwnez!s8 z+WMcf%wNC$VDqD+H(xT$=givaFR~x4umAhnPygo<|7qDX4}W+x{g|KMKA&&)?(x^3 z%Q(p06j4(%`_$QAKfSB+(ei}g^?_<^+g?7@^(hGWtyH=7xXk@{kAsgN&H8MTtA6|2 zwAk|J3uh_M|6Kj)f5`@0bJK0Letwg)j%XRHmhqQAyt;Ik&7m8~rPW8Wa~_xKU7TOP z`)p8dOwY5M(&kTIiEWVGcl+?QPoG|P9G_WntHx4awTo3&@N#G9=WUkVw|%co*r{0d zol-=h%Crnqx96W*V=qlSaP33t?CTy!*Y$lZe{3xG z_2SoK*2fneXPvNC_3dQ7%X=1|eRlX#b9_zGmay#pH7ZY6pHEJXOIlp#_N!uz+>--U zf3te7T5{c6GJWfTpSLRH@lmpy&JqHg7`z>Vh*eU#gfoZq7Pe%TG_8}lN5<{Do8F?;vQ zum=xME_y!a#iYlq``%Cd`aJB_f!3>Y*63YlI((a3t@doh?X+imT`#?x`ab4;!q!IF zXEQUl#anW|saSL`*Gl}7gQ9oeO=PcCtA12{ z=90SU4Fw5%#{V&SO>-Iu@Ej+UL&mxyER z`{-MLc1>#Hsl_cyvbtYye(m|uu{B3A;kVSsTfGY}6ubX5Bn zj7|0H`ta-2r+%JIzh5_)tlv>oRP@SH~gJNw)QUu)Hxxnfsz zmwkPkIJr4#wf)Ah@)R-swMkLa`)j>k$jj&0c+|~W{o~5U{(9^6bed|n)v90f@1^fA-xKnG7Rp~* zcD?+^cg^`%)Oe&P<=EBw%r-k;`yz3xY^%Q5jTMj9N=jATU$B18|GV%1ulK9}x_kfg zFG;ng(-!Pp-QR20RrN3HS9#s_^0{>n*y}FDFH}`C^Z4u5lK0bRcEzV{>n|^O^ZWJv zQ@6RlI7sdL_nX=Nhx4w-AAIk16v@3|=lHbIZ*Km-TjtfwqOS`MKkl7!_QZ3G?RPBO z&o1Ax^T;zX%g;T*f2aQ1RVjbq(BZU>qx(*Ue)_X%`d%OYsg;%wf1b6>U-Kt)cCY3i z3FiDx8Jjq%)pcKO;%%qZ3VGg%JOAS#^YoJEtKKoRepiTp7{+&F&yjP^w<`Vx<(ky* zGxKZIa(Mn~^_QzpuJ3!c_1o`V1e*Vjy!|8m48|J_{ao1T)7HRM086@T3Gyxabx>hk^HuK(jc z+b?gk_uFRsnhI5p zU-;qKc1}O(=<@6PzHME8{z~vg%_E(A`mUXiy%hibYyQReb#`y;Ui&S4W%?#~yFdr~ z1?NeJkGbhQ_IUGHwTt`0G~*s&mAh*5KeMG>&(;oqqA+KFR)EZD_9r*QvZE{>ooD^v zpsJ-dd0p-8zR8xwTOH0OxaB2^ALCm5)}}p4_HxCR9=_fm0ztCR72-ABQ~uuGpx|Za zEMBefc!n?6lm9ErRUbTiCbuz{tsz*<^qBYjJ<`uo7BFw!r){Cu6hB$k{*_*ed z2G{53?AG<$)5Wo)Idc8mgTn2_*~xcHeK{YWpSs}lkM*B6Z@U;F_i~nw)P-MG26s5$ zxqZC7OXQ1lM)HhZiw@m=_V`6%6~~nP#Db%z8b8hByY?%uOu|vFDE@bu>$JTm=l|;3 z++VS3gz9-e&BJuCMh=mJRRj8K)&o2zOkzO0{>O=7RFWb7Kt1h%| z(#qM-(fjy}anjW2nke_$hjSn2q(88>Z)TR?-E1quvwqrym)o0;ZnK@swf+}xYW>j{ zOCR%Y_+eYTJ#qQn-eu47^7G?^3SHzj#_i_N2>4|9*}ZyC$V~UxTRZRU zSf8)hak9I_Jl1^Qg~RRU8}3~F`rz;5cMfLZC-nc{So23iy7S zso8DtJfe0sz3y51kME}Se~#Dx`EuF*^W{1V{&Im$m7SmOu_;zeef~00Xa4f_Ud8NB zX77Ked&}jw)BU3dj%B>7QE{vFxU!7@-zLUyi^TWd*l+zqa+mez^e?8j<^OM#xBmO+ z_We~q{@wWX_1)aBlR`51-|YMN<@0)*+S~PCa+jOeJe2PU|0_Q2xvwfYHzWC6&(9@Y z_Zgq++0ARax7%gs<^HpoW-L=Pj(>>xJMFpqmy~b)8G0XQFZ`3IG<$jt?;q2u6&Ggj zd$ii`|9ky?&it1yHdn`eaQgpDefFArHmSnCJ1ZJ$PPotap2Bp?hPCz{Ylq?A*RMU)ZFjKf-ju7(vu;dCtxN3o{i1I7W65)y^3DIQ`2Srp z|H@zP{HvE=&9C5DZ}aZY)L85FJ6_I+TVrkc|4?}C*O$`!UrPUFdGCMmeS#4?N9S&t znYVMIKK)+I|MEHajPEs~f3}{wzdG)3*59z_x0lT1t$nvj#s0|uhUaFFXYcmz?BBVP zC2N~uyq)*{i9cV3+ZX+M8voB+sh77r=;RMg_4~`_S64L3JvkhF?V#cR+UswAST;>8 zI1+w;htGEOA<}AvcdgRW&oU`AT?A`k# z_u+%y4IgrgXLyUa-j4k3Q}E%})rcc|FZFWIFt{Z3kZ1feHW))mQH-W$I-iVdz+f{gVY*s*~YsTZ*LsaxxBn?K@(H%O|ETHYvV1h z3(C(>y>3~xMfzb&*WX*yo;mPWnO!}uw&}+GqPB+f#Z%9`+_CrN>pn%hq=J}BH>;Z5 z78l+Vn&w%&P(pjYWZTs19GC2uA7tG8c)?9~DJ}N@&Rn^ty=%AI94p^>Y~STP@!kA$ zzOeM&ub%yb!%kHoW9gcz{7Kr>#Ea98dYQ z*Bf(_9xrxFNR`r&`jk|6F~;oWwRM57t{f4R=6xRVK_r*504_f2abp07M}>`laz zfO5v}be!H{nigEn8faBBpOtUiip2Q!wc>7PFsp5!KGV8GmPUXiQK;u?R8 z-Sf6o|GC^^`>Z3P!}2l1`yD>t?|h!!^x^*l{(ld?Wbgl$ot&&aJNZuS(YX=vYt)nK z17>ICtocwCGutI+)rQW`g0;4yw|?LMUuXaDccHz`)1SZY9zB1pIV$c&ucA?#{)y+` zWw+KY=QWwP|CHXpkp0P@S@qKe_TRkmXyuvySK8Os*FBkd zS^G=rjp_UUJgvKByz9n;M|m!F&Xdnxd|tR*N!qkZJe|42OxmKq`}{H?|4IMW-v8Bm zdHugv`#&BI`{&_rnEtqLM%=HJ^Q)?kYR5la|D`Bhy8M;xnqHNfbYXq|4VC9!7T&x# zZPGtW_DF^)-FvU-@$RT)B(SM6KAUrJkjboyYqa_(bXl#?`i)@$(7S+i8EXF!8Tre ze_EYK|6bAGYed(mdWhuYiq4lE$W{Qu%99Q{dKe4>>c}md@HZ0k?C)FnEbtTef8bW_4Dojd^jw( z__WTJm*gf`!`+uqXp8t2+^Jly3-p0<7uU{ik(!TCk-~FPRtE=PQE}!)| zugNlFUphar>Q7}m79=DGD( zfra0f>d)W9sV(>UajSmS$(OzPHO*#nUm0{S8Xe2|SM2`gWcHWq^?$GX|BvIp@QBf2 zp7kk3n|~1>e_h`nSH8jS&HU5@=>>N*PgkY9D?282K%w`M^^!tA)#o!VHY(V^so)bh z_W#Pi)qkHbHpt4A*=%>6y^UR-`)^L;|J5>9-93JycW$1(eDK`f_On;s-M_S7Z*}|6 ziQS5U@fVD5^>m(IwtLUIkIPQ)T-Ud-XnmSo`J)TJdp49NyhxpwcE@$Xzng9G|FgdH zysp%ZJIYh&&i?Arw#KF_g)KEl*2SHVTzm0uq1AcSJ{1gsW!81^FV^H=c(#+3`B5R??6PeB8k-$i8H;ax zpSkB?h1HG1Pc!WD&DLd`#r-(CQ|{Yq>92C$g=_h5B(8}FD%c$nGUxTZ%nuypH(Rxx z7wrdy4dC3yLC${dp-4a!!@}PZLvgfp$rQh~m z`|((j%SXHJv%6P;?oJ8i!gmjRH+0AT4S4ictgOQ>@7u)NZ+TZXFXLzlu7BAn_rkF% zV@Fi%$8a zIPQmGg=zewtM}uW8)n~_IH!4kbDH^v&0lZd`FK5X<_){>KJJ^^WpB4%Eaq7hFZQ_P z?8lZ`*L?|#_s)__$DlX+ABSHHm`R*{*Eg{D7Ux@9k_A{}|@#*uCLb__@L7+|7L_!YA*%+~+GfPvuybvdtAWlNPOJ`#WTn=i7Lb<${trCMX!hwsFF)7yjgJ%G>!fU+WN~xJ7vYnp zewu6EPo8gfE_ThC>UV5k)lBxSnqZ%^*J1YSCwdr16bZULp2<2KDnQ zl**qj>gPXdDgP?ZXYE}67m9&BmR2VXXa70!aglgkleyvFttFAkb2VRo@{Q-Mx0$_B z;&^_I^Kx_dtNwp}on%?-{jBG&==_a;l<#_0-T%w)+4ec%nz+%Eo%>(jD0S00U-_Z# zZsK3T*DU?@J;u4uv>6|p@6UgEe^-ibZq@AFS7t?QYPJ10(fR(ww{tRhzVyq?)|Z^Q zz3$Oz*5VBYWjeK;uU&2O6bwEw1y|*Wx0Ymuo9<%YRyMI|-}Dm(`wq&S-+cNxbJ+@u zq@~e6H~mYz{yeHBWKF!O?Vp7gV~(ml_OTOL{o^e6jbm@vRy3M>o4wv#I%##|{f$pV ztKD;sRs1~jo4MG~?)tm48_wz{=g60A@Y`J{yn7Pk{GW}-lXVR2PJM|sY14nc=0kpq z?mENC@qb>ig>5Wq_-}kZ{L$2vk7TC*x}I1ld2c6Q%`?}Cqd~zFa`(Nsp8vUR|MRk5 zQJJdBV^-4^ZjU&Bx-jqhjZO1p^de+}Y@g3wsBv!3D|sD>`Rfw*_cw1|-ow83Na*~J zCoAQGuD-vMFx|$3UH`S@&W4Bc+Z+=W zROV&b8?nnChwRy`%HAWs?CT+~POA&+k2Y?&uOZg}m;<&R%~>qv^s6<4hj{IN*d zyWnhbiw-xBPRE?%Mq*cQO4Uj({?y!jPiX7TV@%J#TE9uN6$mYg+C3}vOd(w%sPuJF&=shlRSUxvgx<1nVNz0>( zji-MzFSQK3ylZ`e^}n6h&O8@Y2|s9;`siw#*zV@%5!b7Ky!)K0Q+C~QQQ61;GTi@a z_B9<{yXQaO?!)UVju;lkbcgosICneOYP&Ok?xm+6WZ$0>-BsP^*7oSL^Q>!?g4(u6 zcHI^YTA`76@A$g(-NgqjcfD?`+<4n}osry(ePXL8GiT2~-*zLvFPWA9$@Ir-V@r&- zANg3__adRaN3clRR`=P;=5>{Gk4TB;{;a92Ik@f3d+iJBjvtdxX-cnoH2Lo&uji-j z9*1)oeK*r{H+q*;`hNAJa>JYc*F(fDO0SuzN16GoC>DC?GKsrWFKSxY^y`~?Y%KD_ zI?g9uDY|y@{BoAB({MvSDm*uQ(v+8ytddop=>>ikG2b9zCYsfIi#BQ=Y++Vl%Ktp=vN3*kC5NeSyUJ{bJF0E-<$oMt-}3U)1aq%9 zQu}&&m+f1*ap%W9&uwR{SIUmtu<}rB^!v-QGjdYwrdvx(CQLmpUwx;1=U0|z2;k{*PK$X{`}PTedYU? zm79*Ysg_^c_>xON{)DFVWd1wz&l;H7boTc~Kl@Bh!g*Yo5rh5CCcQ}jwUR31Ghu_OAD-T>zcKKvY~3Bz*URT>*XP``J7yDL!(;T>!t%NHEB{}9 z-p?e>Zq7Nn{*LO3UW<4M+XrXeD}J=i&$0Ntd*+?k*n#H=Ede{+Utn%==zX^AhrJ)J2s4 zde!;uOt9@V+w6on%_sOj|M}NG?{VdG-pWMzWBDfy#3hYCos?a^{I}ev2%C0GKEXY= zP{_=}>>auuBj27E9TdRW`Gf)0WlHHW}yTL5{y!W-7bLK~0 z8lAsryZ>=+P2yUmWiz!dF1G7$-EgAl;9XyqrCu9fKDseu#tXsNlltZJn{J-Jc;@Ar zpD(4uPWGPaYdu!^uwtI>wM)l*)_m-go^{{dbomEq^N&9@W#2^ql`DIB?fDXg$L}gk zpGPjg=dk6$iS`XgEyP}W^hG3}UN`^HDXZu4#}ChYd~E@5PEuNPmpR*+Q}OpEYnc~> zOfF+Q9kX)nJbA0OB%l3DTM}&6-FVWVM$#Ea+WT)OG9*k(7?E2-==6@gM zHwCQv;_nmpZVvHg$5$S_pz%ev;8#L~_qnMrzH1-b8OjhFPr(v$7`15*3V1w<9c4q&$gI(f6x+Nm0z7ZuV0Mu zfAQDfaWh{qo7-R8FgC602Ug9Dzr-4L^U^G>vK1Dqvo7yElz!6w>y)I_Flp|6`}jV5 zNngYI>5PP@$$nkg-Qv3WM=ag0CzPL_q4NG7%Osn+;=iqY6+hQ3wmfey_~zq@k4K#3 zE8}jgiNE*Xy6;BnF~!}}Z@saUvb+~QW5)N_e`;kW%Sy&t-p{P5ln;5h>#?P+|D)*{ zFG?IFTXbF{M1vXt;I|4amC)w55Dekm*aKso`sKvu6_0``}wMNy=7HjT~L{= zbwtmJgzNiuPu*F?Ded{&I;OPdTk(qpo80EQSM{aUoUFd@|3=?3bJLxUV+oe`*A}x! z%zepMmdh&t)M&oo>dS=XzL%_GZ}GjjciEIEw$(?1b|<`_x_f$Kwe<9I{p;s11c_;QU8_8}y!GPsMM2X` z=WN~cWcQ5bWI?xOwXc#Mt3>#9ygnj6^F}w%+gl6n3hC^ z$Gq>IN`E#XZr#>@tiNVF`{X?9dr}1Z#)8DE`CshaP3kTkh%i&US|1}lWr_Lcpz_68 zYfi{-i@bc+benvA&+g)zC)DbDjLXee>#m=?QCpM7rmd(Ghs%{pN-Ue}$}Kax3l>cb+b1KTd` zbh|r!E9aGe2C`S$%%|BsXFJRJU03yyMSS&L#l_;GkHTjkS#6O1M`?Q3<&UooibXdj zupis8?cwXzed?uoJN@OKWiPf$Vf5hI^e4IJ;EHeW*-piK^V-e*Vex{ev(j>XWAdNc z>&|of&NFXMzSy9j^z-PR2l4tZu5RI9S3Kd)hVJXk9p`@W++@9HdbC(AShKkIr%vk3 z@@zlJKK^HNqPNtNO>!oi-|K#Hd;P-ylel-+{00bh&2shb8y;Bi#QSXJbuwyIi~L@V<>w@?GbH^S(}~ z@SONpS2A|CT}6(T0Jrp`d8@PB%UR!UELwiS} zwZ`BT3#ER&sOSsZpCYbbbXlx1XvIb6ji*v47n^=Mk`=EkDlP1C>T~{d$we#I%s(8u zvpb@5Quw{<;@S;AJKT0j9(%D}-^}ROk*@b2tt~C&7k5~NHhr_vp72FK=CQi(Ip$5u z>ZWetnU#S!ssaq){==2%Cr%zW-D z^JLam37xBs(kxA~KcX1U%RK(v^Yr2O(1qDqPtIS7RgT;=w?qEesrqNz|0wpEj*_aD1#&_NiO;*YfvAjN>iun_Q2P zKW0|d`at#O*2Jzdlfcxs{e6WU@0S+Nu$i%=b^V2;>F1+%t-AU<`|par&odU)NjTom zaNBo@Jt@>ur2I%)T%j^k{f`X24R2?tJMsE_m{fCav%&G2J5Tej$Q3@mx=wy~_5Vp- zvp;r!l#(ng{qvx3-sfr|OZAWY^uA6oTBCJV@@@6gyj0M#-@B*27;l(-^!QX4F;72{ zniVdZrz_`ry!`D__)?{5Ntm?!uJRmnjeP!YeJjP!iYK&xguPMfzkEIM=|Kxm&kXI2 z2i;utI?8t+R7q2Kl05auX|?NZrF@gT-@J`*TFITz=`a6q`CZrBZ;vgztnl*KfuoA@ zSNB+&9@E&UKYQX?iEFQKe0b1TW0?1ILAdlqW~FTxnf1-OeR~dmYkp*Ce@$W1Mk|wh zSGIDS-7__Rx%TlV%lrieM(4%KJZE>i>^ZK-W@0W^v%yX~-#X#Pi|*9+1M1sPZBkUX zew;Jytk~*w(;rHA>fUo*UH1Cti#tz!4Q?pj2s!EZPgU*AB7Je?O|SR59-Dc+k|D|W*`SF7Vjem6R8ram^XFv||N^%wlJ{KmTf3w+)cU);Fi zh-l3lsYW*OH>HbN*1Xpf=G~vGzmD(a%b!PX^`%TO4YMfGi`6g8rRQdEB zpIu1PNwr{>H=n-<za~t26=xQ!OFUYp{W|FY*Zhd444$ns zKfZ0vv|~;4J!-yXyF_$rlCbjc_<0e#6qYvR{`0xP_pM^Z(cQ;RvgIbfSSDlO^7Q5j zYmUqV`~Lkt{N{mRcYK3eVU6=OQFg9^ts7&1e=Pr?T>7zt>%8{WSUt(jvy%fQtXHwB zNj+QqcTdJ!k1w&RGYYxf_Vjihi3^s}&RKuE@x0|jCXQI;IkMh&415m1i##EH#%r>6 z%Z)G7cW@lcIw#P=ReF23)rNCZkF2=qqfy3StKMaMF7u?(HlZ_>Udg(x*TfgIuklQ_ z$w+^;|O|kC68`BMbv3&j|AF;*c z*-AcXVec!KBI4JXOIK`ciag$CyF=#iY>3lzz{fzusp0p|F z6o2gb;_Ix$eDqJ8jkw9m6{|1ro5THX!9}*o_9}`te;t#y5y2Exl=UV-9FW#&#Z_C!7;ch(rey33Fg$hakJHNu~ zSMHwXQg-rp#w{6X_T2vW)3y}9(c8Ttu*Ukvu~!u=+s_xD?K|1ZXz}Q~%-Q$hvtPw* zG;<4B7H3<_cN&*wTkP;Ur}kvy|uRZ(HYL|RwSd#1?`W266-#h1DhX3Ian$d@-c>r1Y%E7v*k z1BXK7Ft`dKiu5r>y(s0Govj)zcrPfoumLKO`8o1Z= zLZi*+thgYBnL%s*@3A}BT$#M)^Hj!Zdo~^JSHWMi%pbC9Ilc?i5HY#& z@!{$j3Pmkx^|{k~D;l3y7?gSUiQQdZvV3{AY;!N?nXDzsEgQPtITx&*nP*jhwR9hQ z*i`d^p2!Yfko>1{Sj`-uuVVjyobng_lw0`+uE56xLI%-eWakXis zQ}P0janzlgdQxy_$Gj)@W=;p6Pfd?KS=1RZ?N#*gB6pMc^k~<&WvQ1c2vp9%G}J?<%FnZEY(wJ+z-=}alT%HNVQV|R;V)O^o*2Hab=9;oi* zdi|a4L&6s)-N(mq zkFBYBN7Dc7yZH0n%mnveS=Y9HJ*ieEx%ls_!#g)c*ZwaL5RTtJGyF--@hFbH%KXA6 zQszgMzWZ!w^FFwuP}OysYg)%1zR1>Hr@5q9ce&?%dAW7M>JP>HUb6}Qv3yq~6?;Oj z@>9Fdly$pLF0w2Zy7x(Wj?8qqk`0<=bEbUd-1%8(%`tbU+P6jfymW}mvLzWHIk>#?yjPdD%Uz4P?tW8(hu zPpkIz=Q-V2uP=S`Z1gcTOZJM5FTQ_$(>Qz1+}pPIGmNLjaNoAsx-T#8*}1)Ew4Zzb zxTU$RHbyJA{Cpk9b4lA{pC`@v$h_mW>$Xp81rNVF_)RiwK~722@g3}W9Jy0V`{pdx z|90%y;>T z`QOg-O%ryl-F5Hz>9YSi37wry>wkL|=IX8gc(QYSM34ISc55&lnn~TkR&$Vgw z*R8v56il@F)*joFd|Q5k%laoxw|Bc_?-yPjaL(QQ_&39tpRunG&aZE`eo}aJ_Q%iR zA9L=WnV9-hx!uZq*8eMIC-Q^5Io;-cUn(qLI5JPKIn?0lrz3jEf^GYm89iCX8{~Dq$o9W$-gc35ji97yK|#es z@h^cco8o3aTCmamz?a3o0^7X*b>u%;vMOrvynxw{F9pALW}m(Ko9b)X*%dr}P1CE_ zT=*6fW$eT}xuQug@21$@ePPQj4&9Ravf`md_r_qgCo9E&6_{kN`15Lh*0LDQtB&>k z$9F#3F!h$kODmm|w<@QpKVb@e|0h#i=0R?~s>IVHyq~tzFqv(uhyRvVOp4jg%=V3APLE;aWltNuE(o;1mA6V}Jp%!zW{ zww~$A_h%PpEaaH^?1^8(>-(y=zi#*@-EPRW^`Epg^ZY)4uUv;4j~CW+cJI}l%yU%7 zN7E~#CbTrUt<)l^`fjSX-tmGt{p$ma{k{ml`6)5;9OJu-?~IR{=}B*Wb!O@-RsTQA zV)c9D@~*I^yy=hqmUvF{NQ}b!owttjyP6+Xdw8|%Oz3At*>BSggJv6jHu=?T@o~l3 zuj6d%Uoq>jxCejP_ypu zf__8Jy&wA{{_Jg8E1r<){>(2)^vYCIi?o@Kx8_<3m%GK9pWj#(ne44Q&%7$HMc4n) zRsL&co{KG3SSLqNKuSUP;S6tT~U5h#dX+ ziJjx$%E4FW*A1=Oo>frpULZ80}enqNP9=kIo zc(-)z(yQCvZfZOsFLI?ZZf2%%s)S_f^UpW+>bnoDU+jB?-)dFD;^?<0^1t5W*#7xK ztk3JY{Jb-NHPk;9KKtU<`+{}fxBsdBI`{N}y}hTcr{7NZHI`@FdAR54WLNjIO3~_T zbhhZM*V#8`Nx`FzrRNvz?h#Gbd9b5i^fXg{--~aChw9rlvP{_V%|`h7*~hX6SHF6x zJ7o^Xb)6N|rF{&cI?xv^eq^MB{5R}GF|n0ft9#Wz{U6OPBtxZG~YznOi^J<_SM8wC?b+PXT6uc|7ay zY}^05Oh4hf&6=}jjOt;to&*>B&b8eCXz#?kGqo#I*Bp2FDXF>3P;4WI-U#MrFR|Wf1R?A zclOF!6Mmz8h2^~0%=>CPFZ9-~^ZC0p{`Qva+1t8v-qxrmpPzrX@4ee(z5d!sX*!?2 zRjz0Wm32_IDwy~%g2&YA?*7L&{%kafd!qOASK_S?yPto3IbHT#BKOroxA4BJPepnw zv-v6mH0@>OpD(mYp1p-P_@Amy--GLYxzaH;&vtnkA9x?^W%8xjsN(Y6g0}k?_n-AV z9jd>GagzQ&#%|w=6Qw;br-wh?*xmMPbF%XOoNzX)rO8v}cIEDk6$}e-*O?b}aLV5w zNy7U#tIvO3R@C@hyU+I74<8Q6^ErF^C$LCgag_M^$)dCU(@cFG?enHRZXa`g)+G7l z?m9KmC*SVIiS4a#<$Jo1Yvmn%(9FW}YhwMpUgn!Zmw?XmLveQCEf(&guLpI1M& zR$t7ozc1+e?q7Xo&&nUo{Mlla;wV$txjnh3UhL_EHjc+p!f!=Bc-vLH2;U$uC;Ct1 zKBe11wqL4^T>=jGt3 zx;M*|Pn#`3BtEZGCNAUJ_mT~}yYrH5_Z>aX^&mTE;^d1mEgpV9-yT|i?`+iyx9jtw zH>|F|kf-r!qdseCX7;y33`_2BXq&v{@3Cc82Hrg7S;cW-S%MKs+LpszdK@&_uF}%y^+is`!V^t zLB-L?h8v5M%Q75(-#l$^^Ws;F z4|Y2po6C3k?1so~y|v3I|W4b%<%sr-gi5m+I ztW+vLT+>RA+?L$^`dZqm8;fFY3;eUXoSsn1F1N3^QqS`C2 zc@Njyh_@f7vA_MmSarnUy!IX0y*~wGtzBoe#oo8wzWYvDll_aC-|`uyCu+?;vAWD$ z@J|lUV_sc{nu&9sCyC#9cK?j%C1(b77bcg=%rA@wk^cIM=UqCV+w zuc8}I-|4CMh+C&+|LTl>=d?OW(X7-w(e62a=9;Z>b@?yvm9^ecOK(=o_Gk62LDg%_ zf;MlRxbBwB8R^92&rSQ&Bi@wil}gCGa4Vm1EHgwl>s4u3=cTr{e}22jSM?oTr2EtA zj3#HQo+|Uym2FR>HCMU1Ocu0?NV{?ODgWEV>dTvY1OH_0F+aTU@b!pK4KZ(?`X#?z zEL4}b-7aDN8N4jmHyq=;+p)t>n(Rs<%PWDf*WmR8XPCgK7ZRF*CteW z);hs0{di3KQO1%v(-Xh7mF06rA3Yp@eAC5G#}^54Y`v+U`#IktwO-hwxp=8dj%(=L zxZg>7=R{v9@N{zVNxMx;J6Zf#dh^*%(F5BOTRP)+xAln^89aNL@MF$-UF)PB*2-M{ z$!C=fuXJt;)_=O|S6HwAbg$y5d#_G&{o}f}z9&AYP_ygRuJHRe!6&b5{#hHgcuhGnF<=_J_O&YNvv&CI?vCx0`J9rh@vVFRzhy_}A6Wdn zDo5aWL~7-e6L~Iwdu|sOMl8}Yv+GXSe$w&JityHucdu?Vure3b$}Zh8`|8faBD-(O zD5m|cdUqfoWdGX@I`1~^v}SQ^{CWPEO_j=)0=144lbI*Zd~|HZ^iBE8qGLZXUEUe6 z-G1@ZJ<2WbHY-J~Jem0Qi*{gvc4ODx-gQ@xe|lHE<59lSjSWYQqiW40rK=31zOu#Y z2D`C*p1S{qtJ5uW`MJHmC;Qg!JHx-=ncRosb5Wls-Q4K?cjnup8!G-b<%msg7Fy0% zCS7s8n#Iy8xG3_*j@LDOqGHxR_89lbnyoaexh=~sqAKhB!fb=9MO>-G`-Vc(r=hEY)1F(Kq0Spi3>%v|~zFpGQnOb6YTIi0^D;lY{{%rBok?Xv#y%gkq)k~lk))sl@~ zXOFzwIi)?|gtDy}cihhdM?O7wi%?lyy!~fR;@ZDD)0S2r4Z8ioif8G<#ZTQLQcmsf z*?J_P)b!cGf>PG}{ciJY1-BKpY;Sxo6Xy2qXR&sf>@vRF5?A)uUf#5&?V`=O18!$N zsGpaWHM=`OL)Q7$T?c2LH|MOkOTST^t(3Z^#qMy@u06*415#psGF$I@P^QyWzPeFd z+V@B8fru3wo7T0pN-K%4c9zrkit*pmr8@7Ikp0Kf^QO1v=fa_m%(&Rn_f&6}&Y#b&H(6)g^3K~aTlmPO&5sug-`!?# zPIae6Z_L|6=cV3t3f9$T^k?34dLo0a9Z@rBu;AIf4L{?{hDXFh!$th(U5O}<%R&b(KDm-ywBu`*6ibk41? zR9Jj3AjaSJ-#ZuYw^HeAqAWW0TODxUUE6B2QK(G%prmKc^mkHAJ6zJ=K5e>k;b_0> z_r=y{Wm=ap&P08}M;im}>2HnyimuD6S*UCOR?I9*pUZNW z#HP;+9=%_&c+%u?2alT)TX znfcB2sK9->H`{Nd7SKdR|5C`_Sog|obJSnZEH0-%?{cOd{BVBt|Z;_qt!d{f=_HGV`Z|b?VueQdt)V_1{xV!lL zM)#N%Gx?WEnSJ}o|0kjPiJVI1>$ZyxZWU5?PHRsuOP($x8GgSoO*6<^_Qc7_rUE5W z&p$QSE?s3|vGPmB>Ep?M>lRGo-8v_IL+OS(zPa4Jy$9FC7HwteTl>u6N-b|%%;E#t z5k+hJxo$;^HQAo)E!NR9>vg%hDLH*jv*drbnjK-R%52$!ygR=hzctlZ;YMs~q=d0j zr5oSE!WjZ@=3Jg|n19Oa1Zfl1?VmJv{WMtcdxi7M)oqX2XIv=IET}R}zERw|?p18r z>g21F)!Q%Z`QvqOS$5ln=x>Yn&-m5zpm&4vapsu$y_>TBc1pxe%`a4N?)0Bof5Yng zO``|yKD`?)v?ce*%5U~KIZ<+1U|WcPjo-dA7Zk$<&a|Ikj`uhuSz;ai#$eH^nk9Vk z-^JEdO^ExcB{qADa(Ir$>2}4r8?GFT&-paV=4V>;;p@Lto?c$}_PTnKSr! zVJh41XyxCf`uX<@|B4QEen!6E0e5raEw}Q%c;Q?n5R<+~Dfrig6E~Ji`fLnJ`X%A) zk|d;MXL&2AT_>z~VoCCwNzUtQr+!Lkk3F$SR$i(h^yJCqp6-52Z@lQ@S6X)CqlX~h zk7)}p-VIQW;ViOL4zm8_dR%XBMeLMcm(!#_1-w}!nlZK2;+9as>9T-XyQSDm4<9)F z-g4E#a~fBTe`lUqf64Ft)SHnyx87d85{p<^PJzWSSGVP_9 zweFSix_nRjb`8+*Tt+CPJ!@09_V!YMYuH2qteJoMq#+L_MN?9$Y`z+kH=5Unu?0=14 zi+#)Io;bbz=haud^FOb+Hor-E-!H54vM)C7|H^%6((3&eUR|!#TTq>=>GBJ=d^PlPBNmp7dmE zL+J13nY-rPv`Y6;j{Ds&C$wGF6R! z9$UZg?0&D){moM*sK3^_Yq#AvYqwy$z`SDLH_->*T|Y8We^u$9xG-n)KK3nF{e+&( z;mNxyyn=8v>WHH{;H_Se_?TapYOtey08E0UteEX zxvXBN`I2IxxvY8VhmL-WGmU}mt9bUkky4Iwowc}YrgGX-wOXM`|N9P3{<~{3OaICq z)?-r>Io{vVl$qJJeC12oN5_^01}d}Ve7E1Gcf;cHod;cW>+*kcs+4t>9_#LjTljFk zY>(G1aqcf0^G?fKly^&iRJvUna{I4u#phMcRS6SshlU-g3$O27tDpGvRaerF-aRSa z-_Jikvm{jV>(x8b!8%`AV`}7YJ^btxw*J`rjY0o|b|#6wQFVN6lgv{;M}6au zFB+Aebt@4mURGFITO{y8=h>Wvs%p{y-j+K}JO0zz?fIFDHQvKQUSI+KK$T|JPR(xr6#WQ}zf;>M~ zj{Dl>+RWe0^xlUpn?G^xR;z1O=^uMPH;Yf_-z2mvzue*mPrdH5S2}r|<$=>T87$rK zBePg3c1tPW8vdz^?M~ejc%AL?(|pQx7P;?EJ51I%pD#^Kb}|r}s(sBa?!m(4OC^3? zv*mvz;LhrvyV{I_eV=BYvB$>F52vE0tPH}$2-^S!lAZ$9t(a-k=^kKbpfb7YLn{AaJCeU7CUTxc#%Kb9&h78hu8t>q5?w!^Ph zNJZCfDEe|k<<7#8B~fyGG8M-bf9A0^My-!bZ zB&=f&O<%k?`_qHZR*#i0Pl{-n;B!1NQY`$-f$5XZ*>5-)9-Z_4&n>pSUlwitwLr+^ z+wq@S8>XGPWcKsfea9j~H`pvAdbbyQsF<<(=Qm#APM6guW6k%6T#)d-lZ5e|67u&kXyR6Lj@@gzTh6 z;m^W0$UT?ceABKX?$?Qn=VpJ?Qa=3b^O5YW>h;AO_kVw4xv`c-Mjh6r1Qc34($7ydVcC^bM&lxd}LY6u@3oaRXXwf$O|LVTN@T@dh+gfP zpD=xI!sqEdCqmRq{nZ*jsxk1+owEAI2iNPZXuV%dC) zrI$Y0XecJO_l8W~?fI)>tPZWux4zquXr0^lb^5Mt8zZY!KXz{8U-eqPw4z)7-nyiZ z7Xo$4`u@$*j@t0?rO~%LdM6&d<12fjtS1x{muKMd$A8_Em6ccad9=ug>D?E*w!^wd zRiu4k^WoQ3^U8E5T26W^_m@tID39x7_r4&zD_)d^UcpJ|l0lj1Igs2OH+H$y*+VZnL?X`Y3hQm@Q7n8A*b35S{XzTDe&^kl1ej|vHqqfWP-339JN|kv3 z-re74?Y`ErEp|UM@4m|JJlT^+HI81aHQNw4J7ux-+^g0;x9k!RF2DD8We@w08W}cW zpVM0-c3v0f75{FO~-cE10@eU2;kS71Qd({D2#w)XW+t^b|A#&*WPNdlj< zHZF7IZ_}17dalSMag&AZ+rN+hyv%Rh*zPaz`iIbhr$!q$3HMKX|DY}O_pFM?F{Ovy z^{(7n8ouQ0lM96sOJ=%%Z;$m8Idsm~gGaV#YmHP^lCRmOyVfq*Ewf0jje{}zQCAaH< zD0kZN@88qP_k9g>&&{toIRAA|+|PZQ>Pr94^6)*Ac=vM3&j&rSTqy}DPjuovx|8?W zZatgnY;&sMH_z-lZ?YwB&eVV0)b4k)Qtr4G-|atcJ2qdq6e95Lob-j0%j>sDb=pop zdS~_f8n$=2G53DT*k_CF+Hp?&bkvUQ%v8a3b#pnwmJ66hY|(k4=V|bK*FneE$ArD_ zM$ElA;eAqmug$MZ@!y&o+4ot!)R$eH9{u`AYhOZGZ2h#ksqxFt+}zo7bpJ7t*@rjX zjkR-j4NX};`C$7m@tLcS|JqsHH{<1|BO`Azq!3OmJ$a7m&PZ3 zk^3C-^H=EY@V7d5uZF)_HT(XL-gQqB5~shBx_(RT{g&C=Wq03R66^C?wpw|2Isa=P zzwOD>6Q>=QiTQJt<*2vq@o!$6^7=xTtx4|9{j&J-vAl%uWgEUuk9CS)60tva`@yHb zSa%<>c(ks(_4mtz{_~8jx2=_Y+!<1R!=dwK@;x8Z^l#@jbO=`O`?TcTfy$Z}J^OUy znr$siVm|*eHJhbyzHsAe8M9Vq_tNYezV{Ejd*1W(yI8}UkNyAeJuJ0<;FY^vb~pRo zN0+ZF{xsPbBXZux!~E8o!WCQ1C6>q^UN`Hga#=%{?57t6b4)^Zt-BCu`|t&a+tQuR z|4sbQG|R8N>N{_ZL51x4goimlZr=HGU{>QM~P&uI;|^XuDj_DhsZ< z!v|Ow{@8W<*7c2o&es`wUonYQTf8#*vDiH{PW4%hT%mQ^T=o^c*A#UR1e$EzeP8w6 zrzgotmp1&9eSXJH&rChxm(=Rh{6)rp<;?QhdOts}EITGU|MS|g>>RW3ZT6pb1)2A1E(3T2)eF;vZti@VwUY^ASmjUp<-|Or_RrFIyF~zi~$`uXyv1 zYcV(d|2@!p6T`p7cSYZo9}PQ`7VfHL-*7MHScA9D?PCm5z*ThmR_&aP5&u5cQwCS<+|D$Eqham4BfA*A1miY znjdgm_BcF#ebU6k>*BI>&puJMi#hn~tdMxuQd!y4?itSWMLzhSYrD~K#XGnx!)5N@ zjt6CX1j~eH+wsr(t0{JCgYDx``#?5_>WZCzcwZ}R(|Psk;IdMl-Sea`WO2*4$sdhB zMo&jl$lBU*b6nxowL-Uu#)-v*M$h*t4{ZuS(vM|M;(*xcVY@$Hu*N#u3JbHnUyvY$-eC`{|w!P>K_ zC_Z&z@gAe|OLI=XztNhxI%0QKXz9@(s+#RaoLLs7SE@|;eal~KFNi(3_nRza;(FRG z>xCBT4LXZ!E}VOmlo=THyjORNOn*`G#%P(jN8fTx%L=c0TW0wFi{8tm)6QnwxzFvF z3ro4OGvP)q`|QaF3_S!eP&)@JQDyvV=S?1J?CLyuG9YOmD%HTe5#3Y+i*{``l^GasM3 z{c=lr+@DAx<1jh3smCAOe17Bbx2rJ^g1`Fw3E=$e&p$2Z>$!E&-)9DVTW-&NGciDK zX>rd)XEj&9$;USJeB#}0S@z!{M%1vfeZ%FC7Pl-dbMro0MXU`yuJ+MX-`2Q9;&bwy z)H#)oPG=sy_<8+jQXBumG z2Jd+)`JnC{Lk#P+%8;5F(%U;q_m%H{;hy_^TII)b-7Oz>cCScI*zT6Zt2+I_f|sWD z935ADyO(#%Uf)!vWoWD(Vv%siE_p87!4L8Oe>uub+xg)#@W6g+ZrkM#XI6PLz+(eL#?vAA1_v^$1PE>%->+>d`Iop%x8?o z+qbRd-+Lmr>iCW5uqVv?(uLY3hs&OB?DzX8f9k+ZC7aLZThG`gy?$R>wov)9&Ei=V zU+!mT9(Qgt&&X0_34CP0e!t|%kz&WT{}W$I^|q`~uD|lS%|Kdk*K30tJbGSB?_Q65 zkX-&fw@-i3?A%=vXc@uHl_b*F!aG;^;r3|!1B z`N_7_ZNlQ28zm%-F2%S#xOx1Md##k-gA)>M6LWs=X**Ws&* zd82`V%t5yK5g!k_zImkXIb&|yUadkq_TuR`H*R?x|ED8%N{Y>z#SMGKR^)3>kk)^D zr1+##%+$uOt2z&#`~J?{>RZHx`1n7f30LBqr!vkkUiVDsvZnU>XS}vwXTMlqW&cRF z=kE4jsm;d!BY$f!9nzSXo>cZ$WOLtK*84MaUTnzyyRCFyy3&Lt|8DD@+UE3LsO60lt1DZn-gQPk;BM6%``B^WX5-ofLR{O8V#( z!=&!L3!|0#PM+Juyn_1&cb%nnSl)WAM-@D(8z%026<-oHy*v3<#Pkgrd5dI&ljSXr zO$^d`<7i}iXUUqklABfE$-YYi*WhP!?0utk6vRTrMAi5HIeMGh{miF#&&#d$DC~W6 z>`-*gnZ@0c%u$%jzwNP1$pJR`{Tptd^(^?XDF4chr}JN&{?@zkx7x&u z!rbeA9>|aTDn4KH=FfFs;f-TPX&IoHKKImkbc<$KHP~7yT?K@n_IJ3GtF6Wus3t4po+2yykyu4_5&G5PZs%x)*YRs8DwXkQml=|)7_uApH z$s0_MJz)Ou<6`0*K7O5vtJWQ~Y&&G=$Hskl-W-#~ow^?{ymUynGqV43e%>kl_3=E? ztG_e+Ev|mTWvMLDZaDws*)NvMrpfX|T2Ey;_%i;viA~P0?Nc^1W>50mX_|Aq@OaW; z!@?6ZOt@W&u&-VX)VYTT#pNaT~ z-RBvN_x(7-p{BmQxpa;7G@IA=4KjsKIepUo>gg;r@vFg`L&Vk8mcR!y0^TlfKBVO}DqvLwkDW`NB3)eoDuQiyno~ifk>kY!&Z>Hv* zC^d;({d~(Yuep_V?XPz(tC)TKMy#E>|Ebbcy(86qU++x0J2Sb+*N^?0Uqc4 z85uoOwR~4uc0FJ9$65RN+$SGfq-#b#;jW!GT~_@|a-7fO53Nau*DO79x*|k>pZ~}ag{CUas$*+!RN_yYQUOdq_PJNDD zPIJbI&G%XJIA?#o9TRsC>|NG}RR}`N}Fui`EI5T72qilZpFTv8jsiF7IZ#Y*i=GWu2LnLFV^X=NU`QM!$Et?*c z^ZWa&-IKvvDb>%PpCzhm>9_pS^llEZ>Cv03f&JlM+S?BI)-d!R=8&%Rl`@ew&ipDKgQ=6~?im>u<-Gh)#%UH!93rIcfcWk6q`B9ac{A5nybX=(@@wH8k@1k)(-C z@kg(w|6ll_!v1ST_J#X_8_v$q?D=}Q-F?TA^8E5 zynBD+!x=Y*2vr8rPsuqC6<4(%W=g_wbf1S?(9;|CCgc&VtSJ_JkpJ6@LGRIrTg!gZg zPOPe&s#9F+)=SxZpD#qr_!*Hb=9G2Kb^f*Z#LwkR4`r~J-uRWd|IPlY+V!t**LD8Y zte?!ax}tS=qV}`awXaWqemVKyHt&@*udgV$DWkopq_*|0v*-yK4GH`6 z+^37V*PQs_r{kY=c4=K+<59EE0l8%r8HfC5KHKK$KSqwEp}R9H-%gDSF`J} zTZNJ7uis0aPtO&)nX99*Z2E>X%##ioy}QAkI<4@I-Q7vHM`O-=)@VQ5FF~b>YfaHrdYxC`NI<_X(`V0k`)>2KFw$a`{d=w{K1;Y;`zO~R^t8TNNAt%|b52S9-5O^uu=Ssu)*h=n8?4jfZa=)9{dD@F zYgcu39C|-UPTR2|ecorO-kmMN8*B`1-Lh=AZ*kkaZN_=o;*_u zvz$}c-D|FvUi-6r@_ycBr;?vpy*l-9_bi93!-#_bg%;Rq>OVeL3a_`KSW;~spXg~kwZT_RbW~XW9Yfym^j4qNbjmw01wQ>GVIl=9|vi z|2H&SE~Zw`ICc7SHpBXVpZ$v!_kTDfym`+SBQc3ax4@#`XJbATI~y9usJSG6RS!(~ zeEf!lcG~%`e%U1tzsMZ4Q}tV&xvuGK)XSf`YZ!t;au}0O)+?@Q@a)}w%tydx`-e{6 zpBtpk*Bw2P>Av{qEuE~Rgi{_x;=Zq@VJ>x7eqwq^Z{O%7YKX+ri9PP>n5 ze+HDUySRDA>i$ncVsY8OURZ`+^*q_QIcC|bf^`?~b+6bNP%r$}`CiN1!@rFUq^G|> z|5Ly6i_;6wsh(%=q!$@KEcu?OUpA}Zme#Q%{TIjjes|<+-_n=aA^yM9xoVR8 z`~}&6N?)}M?%&sM zkZ^Rru_|?Y?*4|OCf5Vbp9u@qnPi}MX2BJ!cP<%)$)ZZNU%g+R%C%DcTzvXI-;3wd zR~+uOSm`!#&xQ*JB};F56gjCpbo(#E5Vq&{tT6HCRZdgxW}QyxonL6DGh?;5kGj=2}T&&_N9v2gu!+0EKjJ&c$8yu?y9 zc0D+MR`$!A<+{a1A~}K6;^)sYpA%-!xxV5_<(<~TlX|@>+$Gm{&JTNa)ly4DUF_kV88kp=BEDXM?D)K zMzT(o`);+qP06YxWwGLmhsR%^tGiop?`-F}&Xb=TZ+vw~{JAXB{=-baFJDx)>7V4U zP42$G%Pio`;Tu+Rc2C4-pU}u!bn}*Ea%tgNP0zBA6H|h29h}F=lVp=IbQJ@M$>L;CweyS2-2@o@KiS$w!ubAQ#{K%-@;M<*3VT;IlW zX5riBtIr~?o)Nyi>FrW48LOAC#d3O|&%SZ(a`B3fJZp}`O2ii)T*$Rg)j`qj^`Xnz zbCb4Sufuf?PkZB4aE53RNde5GeNlBMQkoVYz%#pAWOZBofin=KC8R^NA9nl77DcPo3-Jn4@Yl(Wu>dY=iM zo81^+7vXIuKF@ICYKFpRA~ildIb;yZR${8++M?)x9%s zwImgDnv}i~%B*0Cm+jr0pS$EM+vHyXj_)nBlxn=*9lq&S#JROZQ>J>!jIz$8t4H3u zf7cbQNKSbc7?z_U6{>6?mzZ;LnMzdl$4jf29t7I`{M~Ms`%75L;^gXQRu{zj*Q)=` z3J#w4S9a{q@|J0$ZI5b-raqclnn^ zEw3q@E4lWu*4uC5ceZD(meS_ix3uOp_xz6Y-z=X=yDWd!_;vlYzP|dCv)CU+U4LOv zlqpy4A`KPHsyFkxl!j{ zi#ZWu@#}Bew;gT!&(L%~!pQje87HTmzrM=5J&DWs$CbTjrvdxMZr-~Smx&+#*82W~ zh~EWk??;M}k5skw4`^JuvHNk-`z?+sTE?*D#*3I@ugY9XkEe73iD|*>UpH4e;8g9+HopEukP=aO+mLrH~&+Kl! zUUqZ4{R}>%cNJMHEA~iy_%HWVSW!Y~h5L4S__3=h^tonJz&pBr{F;C@oj@dX_V&}T0lV_~n zo3ys#$HVJkR{|#QJo5k0OMP$ccihuHUg;0Kf9zQQhfmRZtJkI5pL@GG>GWsIx{^3M zjmnAn@4i`FiDX|dYn_&RY>Lgk=JS;WS1zp$cr?8*ut=}REoGNuh8zYX3|C)B;-Hmq<4yKH)x;)8(({`6z z-Mo^PnRzmNW%izx(SB>hb^c4PYSOi_@VlN>Zt?s{x>RQHgb3~_uX|-5F)we|QQBJj zDn{8%X@}kY=CuzRW-Z^e{;c1%UB4D)%*m2ve{_MZA$d`|;inMMpdZJk=`BoqvrDYk zv~R!Tv)RSR6rvAYi+DM4<}SI^9`7i(i;jN5P1HZbCz~vkj0?U7@g#69j;B|A=L5;eC-h6j$vB=Hww)1nd5*Lf_ z+xDI<%=OIgpA6+cO6`CAQRvybpw%_L{Ga*zvzAs;`Tgp1)-Kufrt|ipr0_eU-~PBi z*(BJ0R(^S8`c>6;zvjzr^=Q%mI<-D1FrTk7p`9DY4O7P zr?NJo-QV9$yMK)R;(49VXJj{oO1wX0cD-druct|ck-kn$qi*c+J9Y92qULf|nMXzT z*_c0x+qgsZndroGowDlgoY!WF3T|8V;?}xZ6`jAjT&JgsS=w*fYOqmIM=VF$xH9fo zeuZ1~dDUElDf8Igd~90yW9LIt@k=(xE9Ql+Z2q9ebyDlV*BXs=wsyy=WiJP*NUIjWqrnWjPV;| zlygqJk$V3x`~3GU=q=~jskT}# z^!tSemPZ#od~RyxU;556=5J_|vf8Ob)AZh*F@3yl$IRv#A z_VfYc8rK)=cGr2cJ&C?y%O*YjU83E`MbnR8)Qv2eaQR#8Q&G-6_7dxB-yK|_6!Wt9 z?#qWZ0Xx1l-_v}5_CQX|KJ&-+5BoijE-5_Aa!Tb@Z2zX2oS~OJg}Kaqbj~$DeG|Un z!Pln6<{e4>zf$+Vd;H^X#Qw7fKUNzi?q%Eme@F5~>u^c+(jBWNUW@R2VU+gyAuE^8 z_C2@DK0Lhe{6)a4)-C_SDi&_zJJR-CC&p6TV@~sCyZQr4&#Qi@{ClxbcIWxG=K5QD z${smd8y?sDxTIk3=S9hI0u#55L^dt9ozK>i7+*%Ci|5j);D= z`4GKh`{7yIk31s{|1XVCHkB${bju}f%CURv-d{gc++6oF|Ia+>cb4;mCry#NE^cdo zoQLOKkTKgD&ug_a< zm$TjGdub53~l8X zcZU5|Tr0Qzy+Pu>jeJ&mGgoi3-^7sH^|9;6qjtOX3zb;T8hwbpk$fj&p@!wt+*_+n z!XJ4q7WRCU`|`&BLuNKQYkju}aZK+!)GqGxaogkSi=P+QHcw-_GgYbff#9p$!sD}A z=e|EQ?cSlJEzT#3gP3Ye!Z%fZSoSl(BF<;|ns-?(>iXdl-yaxOuDe*&E&c1S_WU`Y zYg8jI^_7N}>(r%+9{;1o;Hk3xt{dmB$lEJ{dqNJ|MVZ*kyqd$sU+=-Jab^OP@t z-MTwyRZy<|?7Ia;p(j)4eiNNCE5miJeaxZP3+$q#ti8T+pZ_pn(d#(%UALb~iY=)$ z4(}HGh+35L~5XWnVkJVKT^>t*=TK_V-YFZzCe);BK zi=x#`n^tZAx~VnD_RQ6#%O8JDUu78%%cSIut4sjW`# zA3f&_emHUeS60|Xdz(}H-&~GutPoz1s#^6fI%{dvuI<;S3hemz@%p*m^f~uVB(Le* z`A`Qyyuy(fH*oh~i> z*CP7*UaeZ5!9JgrhDTffdg`1L{mcKOb+OaSpVyL=yN=9>2!8*%Ni13S->Pf&%pcZtdpmS{ zbxQwiF5B2=qxE7ze$V4o>C<-V-iZ`RY?qKv|G(vad*jU=HS+W7Pj>%*Fu&XGSyj^3 zRR2Y`FC)Xhx%`b>^Y-hk>+?R`KD+8p`S;UbzA+W(vGx6|-uV0I1i_!quQoq_T>AfX zH|O63+3DgZto66m%0*t0`F_k+YV+GXxsJo#%T7k=$7Cn&`;?jgVsi7+%lh-~K5v~` zw&6!%j9l=#;HzI>r>uYV%4f|g%P$6UMS=hJ^GoZ=On!7JzO*>!oP^i$>W|e)Ynw%j zpJr>U=BoIvto-d#z+~sh=L$Kp*Xl2QlJU?z;2j~UyQWt=?PlKp{BBj#70=y|PKyZs zzcoJj=O5$09j}!Zd#`JZ=$auV=b~7DV)5R;`7)bcEJ{zEcYI%%&HCIQLdLUFEtXw3 zos|6jWTB(5`8CZ1y?-11dDOSvdhqGc?=QJ~e75@8&tJtX{fT{B-MLMFOi?b2zH zJiA-?4Gx}?`!P9v!B(}k9!X4$xvV+&x$oZ!65Tg9Z0jGUXWQd!YA(rJ{raF=DBp9q zZ$7`>^}vFvm_x1SRK!;Kg+B@3C-P_eh97r$E*0hcoipv}FX`S7I!8k1%z0#*wxjNa z`0Q#O!|er1uk`zb?M#kI>nYVM!YvU*n^SCjMax7~g|Sz2koSfbm{ZgqW`Ugsb+Tl4sT zR&O!pb#K*pj@11YFFGbel|2&p zJNL$sqP4RRD?ODmzxXTv^u7*B?OKuK%?~-bH_D!QHp@=#Ppr_&-t(q58)mE%T2pv? zyX75=?Dwy~OLT8Jez{OO{U_H-zxltnp7XBzyXE$qh0|wzT=~4j`t(=#x?fA8#SWaB zTd2W0xxVdoNaj>Mi62}1KcA|Ud%>1Jr~lR#8>WuFf)!WpUpf(Vxm^F(b2+D9uO5~@ zT(|YS|NiF{sk>{AG21;h&-mScOm2FT-tm{3FPz_8>u@bTE@}2izx2sPyQeRMeOgn0 z{8+l=+s$tii{p*w?``=U(LCdqt>lc})8A8mtJlV=dz`nqX?6Ry#V?<2v-+Y}Tw7Vc zZTqd_oG(H7ckdS6Pu4N4kr%6$doB6B)Asi5-G&F<`ttr2c>oM*H1owRR84C z)bno-8k!yc-nle)r}(MWy}bvsf5|X1MMdV^&JVl2?D>|x$D<7HW(G`hR#ZNkm$bC+ zfR+9}IXY{O zmE6!Ru8P~%n;x+{+C8@Y$QR=qhkiu;Yq_5u!CLT8BYbgHOxB*BPQzpRvRjPxYt|)~ zewg#=GgnZp>}iMT)_jlmNh?^D^ZdPi{pI8xA~9Ew#Clwv7G0JkdWP!>>l$5=3gd+z z7o1D@QvWe)Reayu@RR&r-)2jwH1z*k`TbpnPP%;g^Hu&`tw;NgU1du6>a_ok?i(rX z8}mG}-|$w49BlQ@oF2>T&h%(e;~lGqH@E&azZaI|t9*@=EzRzlTb*-aonf}g)BNmh!YmIPt#+)lz2@xx$$9-Ots5(gK5ac7Eqi*~ zlxg>--Tt6FPgw5T(b>&cR`Pw6m19|Pm~+axZ;m;SdezH*os#giUE9d*e|VkWyoo2= zjw{uviX?Efw+3QLt|TsfBH8`UuFe!|MD2QR8mYB>3I;tsyf zaGeX0`;Ud3XFM0t`aYY*?MFBN?yA}~$(Ji?F9_7ue&2Cx_b-!ON8BF7$oER>N`2L+ zY@0d5-$VG@>j;}uAHJ>Dxb^c>q*LLUXTjXfi{B+Oga*dnUJ!i4#(am>riruaVmBTV zlMme$y*5{E4oiFdt=|1NrbvGMZF#Be_6$qjby?LxF_%=*eBL;Jedz6%Ge>#ToKoqI znyL%0{tD(a_U7-_Pki}pLOIX8cCMN+Uh3n$^^LbIe)kN&Ijg)oo~Pfa z%KO;T|EKTk?yme}}_`+xbodAq&zY2nT1vHVkCT&+CyN&9GBT=@25SMEIxo)Nd*+kBsF zeogh9Lt-n=dtEQS8h622^PD4 zbz9$S_fIe8o4(b2e;m|}kiWkFiRR=?>5oU;=bhaC``Z%dZ{>;SEAIR&I}={3pCA3L z_D1o-kI}6g1futPUETS$rtVYu^Db6{O~r{vvI<_hPZPR%NI|1~;$ro{{kv=)clN%} zk^Wb_^kGE2RK%`Zu1z1yo>>@|b^HI36yCPwedWPN$5}rf(-VLBS5N1Zs3H6H=ao%2 zA9}U(D!-fnoUboF_`0KOx2fbXfe}mMz z<7+nR%{9BY?X}O1JqDh4y621kVYK)8@y3YfxR7;jo8aRh)qN=^UP;D+RS=gm{#l z^x3`f*uE!*4=v=AbDuSZo;iM(|E^(=oJ)S7qt>F*=9kC$2P zEV!h3q0`mloKQCVw2H5LtWt_3<3m?Zd0Y25hWk|PYl%}Albsa}j-S1Kd&lC-mv*n- zlro#~<(XSw)>zB&oBmwa{LgK{{f#>!)t^@g#%)O5eNJ-ssfXcl?;{?}6!~#+D|_S* z@jtKb3UAalpCi&<8vDq+Cc!f|=i?KPmmi8=?c>OQk)Pzf{g>mTy?eJte%EF7ytr{b zkMu`XvvZ~uGN11h+~M25=R-~6n%L&)yZF81Kgk$`+8~!kZyWtVd`()Z4tFr2Qx_b(@)js-TCDt0;9x&;1 z>nlT}u>O_vw$>?M49XRqySw&l;=Fa6Y}PZdo-g*X`*l*RE_w37H5Oj(%DFy|VjWNF zDeLd|)@V65ZB37I?DMs|lj0(zjxE+cZ`}*8k^Ql4`|%YU z%j|o7@y;X*O%YF!L4t!%jf;`^)XY8>?^N}JTrUuie>lBJ=5h5ip~G0F~|5` zZ?)LwKW`K3F1s_W!TXH=LTb-i~?K z>Rn~W|8AhL~oVR)UKBM;nJCYXtGg)kwywm;T8!4F;>B;uL zmi^qubLQC7+n;`GUHdHQSnc~!Q!sb(-{%|V9lLF2w@KsP-*@}u zzh~>X=bKe|{@6F;eZ;x%PUXFKKb_cC+izTR%c)Ot{rTpvk~@TVmtKhe=EbTTClMzW zymI&Cf16oeyIR;jW6gedoZVyb`fb~f{{3^HZ{x9}_i7dY%jG2PN`C8n{Og`AJpqr+ z%NM=WyuIws^vT-cub9_w{IqIk(*1|}c2cpiyNyL8yZ>|@eIjSLS3fa2yWDs|enRe# zMIWCE3$LO(^a*DabK#b|O))cw2E!I|C$w>}7{*G0PJ$1!YuwUkNy zzTBE)Ywz+i@?R|yk&jU>4|i5fJoq=SH2?L=d9> zfyU0h`-iO5e#cx7Pnfx&x?g-{m%cDCKZ}Ab$Vl zo}(g$Th~2Q_L;Izm^)p*cy-l=(D@tZJl^?3H^-vL^v0?~%8=?#|rIJkPLwzYY7B zKiO+ie!SC2)h<)*FTEa~bF#zxP+3gGPwU4!W?i^>RR4OzrvvX_p7(lMw6=VWrMZsR z_KzC#*yi8ZS}(HSA-_;Qwmp8zyx(WPe!io-Uftr~Z>yqNubuXMUD;ArmmqiaZW`bB zy?yrG)zYVC)N|Z+j=52H^TCSKWq(hpK2Cffm2~Y-$;4=wz1s%dF$_rx&q!J*$tcA;&Q)N-#uNi{_hL< z!!d~mwuag6uu;q?&@J$?v|gm;Z~Ydt zu5Nmql_M!7k~q!q*ZXAi`0o`xR|U0A_U&F{!G9#v{%xwM%r-j{;ml_&>O8zZy;Ysv zpHKWhy+FC%mM!h^r>{F|ti7{^3|DWF$w&&lyfsZq_*`fEvwxdsewTP1S#>xm;b%%j z#V4gHoqC`9|17He`1fzb&YHHjH&z8dE>)>eRJ!W0B_uxS-rvmJxrajEY@EKaDE-Lu z^K~B=^E2xm*72!}+#CPlhPK`I|D}#16ZsdZd#XB`30SgDY^hT8_+5GOkavHf=-Jvi zh8jD1UvGY<_v}{Y?atmCHlhCWm(MZ#6}d(}d1-0;%R9fGU5UB#f5Tge)Tb6-Cs-=w zFs-Uwal)Oi(p&fW>~(jUBy!e(nzi~jY`A;BN!;DG{cyVV-Mar=-E$xGcGbFXN}YK7 z^UM2hzr5bXd|KGyZs&HJYTeD*6~+9a?{Xmf>6vG}odmLEe%Us71RYPSIey`(&9U>l zc;0vi3Lf9bV;p`+J~wjh;k@kHEIXTXFJfNzy6*ei%dlFGpSb6jG#T2|eQU;L(S)m{0%@{*w4GIb)S=QhY?yVV$muRB%mq%n2P z!h&k0HJ984_dAO3?RfgE=u^Y%($+P1Uxhrky6JG=biLgpmZBT#9YR9(_8V(nT|D=> zi?{E`i5b=1tKZB~KE(g@!&blBZly=tZcNkKsN*UXdZB#n<=JP&H?|t~Bp)x_-kWG0 zQv0^<&Gh%H`z?<%n-sRMPOyGdCjYnK#81n6e^x)WyVuh3uWsLMeIxcG7VGP-2Jd^C zzt+|x*6jbpgyu&LA9t^-^*mkm^^M)iZx7`@-*o@Ib>pvh_L9dobt}IX*5dr8uy4zv zeNU~jo-?d>ac5q1weRnb-4i}*-Pl)`?o)BB%-Vjv{h{Z1va##lGMRZx=dX!&2553+wvpA6N5UD=2B`c$#m%u6A2{T(PEWNgZqV zMC*SO@AH`Mi+vs?aQkHA8okY{10OxOP!VUAFFm>cAd~l+Pmx`Je%vX0W54OMrNjQe zm%Pqw(cJlMc6`Yt^@ zcog`Oan3^l{<{y3^3GLV&~@+7ai80rH=pkQy}U{uly_?@{;BGJt-s&;J*s5B?U^k> z4_nnjZTpr!n|-4+{7h%?)JjfpJqw!-4k`x^VIqTTZ3auU0;8g zd}GUxFE>s0*e#>&?h53dxMUviy6-u}$?nEJoJmfLN)DLtzuc;nn-)6Q=Q z=udv|{pdOo8RK59^S?hn-}l~fUiY_~`;y{~GJf{|*nMkn-_v{FuRquC{~B$$Q$N{C zug>~Uc8=0-(VRcW#bVxk+gsZE^WJaU2!npvJAa?;{C}rg^}GFs@IS?VZ??^UI9(uW zdx}{8o1@PT$xPIZTvT(feB;H|VjyYKazdAt_U$2;^^ovzduJ1Fxh zFD@a_`ql5!fa``6p8xH6IPt3P?Yq%sJJvk&{#2}6<@tQ$pDA{I{T%Q9#4nz7jBlTH zv!$)g@mSTRznNcI-;-xh-6i_Ic+Kv4r&((q|4gsVUXc1=d2S8!Z{69azx$iqJN3@L z#b`pJ1J94{i|sv$2@(=)b;4{X+jQg~){jrq z8kiVD>^EJL3h7$aw_u0#j;x+vt`{$Lw+8p|%wL_K886+#x_3|AJ=X87e0hQA5OGValrPbdn-}QghvG<>R z4fwhKg}?j1rvC9|QEjQ&c{)b&ld2{9cJ_6P9r)2H=%>2*z^8lLRG;m7TzU$&REWQN z&C9_5J}WeftywAvMDwth0NrNycK#M7N(3%?%=TX0|0xO;lr)y22Dxq0T4FQ3=b z!rdrU|1J4q{_&*8oAUPS^Ucd*{5Svq+*V>`3nU(w9J>UQ^B($+?a126l{s+m2@yw$UWRvs40*|XC6tq7g}(~m9{7wVnDc!z8Dw8--> zzO_9q-n;zPhClD^|L=ac<E!cwpWYp)|M&U6mjBwbr~m)GFaK};|KI<0SI67`>Hq)3{prS( zN9MJksp zDjMCty|GUUnsXQ}H9&&H;KN*=3D3Q!-npvlcXR$__gSHTL*BFf>A!X0&-(v=7N^wL z{rG&|-u}IvmipIq&yH|=w|ryj8G%VyA@ff7sp!oSDoZn{zNs6u$s|7`{fD?QFFdBtw-IB)V_ zNwJv6GndEh>3N>})V@3QxnIQDs%yq#QU5Qb1y-MY|2-+OuW(aS!pwNlSz8Z1IBt74 zP;`E%=DsW8dt3i6VU?D3i0kQ`dw%nu=llQPW`DQuh*`wW%;M9Myg$rhzIGk;Dwbix zC_li3ZfE1UsK4h9>wo>rUD_$)%Ka{7;_l*Yi<1rx};Tr*kN( zI-=o$2Y(;zEP!=4eu-@iKVY=*yF)- z-7mLJ#;dk4K&c{WW87oi+5TU7bE;l%KXZNIFU|jd@BfdLp8oZ1&R5@D9+%nERG*jC zocfn9erC~v`&Jk7rE#ad!#oz-pRh^ZmwjwAx%g95-hqdX^StBEL?8RV`Ww@URQtL= z{pTjn-I>K4@SE-5vk&X1e*PbL(pb7^dehrmTbz4xm+soy=>G5Q^eaIhj?Oz6{BshM zmpk8{Z`xj3`=2~$P0d&McOdv$o$K?5`iU3!=0~xePE)DLU|-~XFs7zk{=?VWmo<-f z)h2A5dUN-Mf35jE%6?|LlIzWEv-i}zcWrEaz+mKV`usy4&zWOScL)Cc+-Ee=*mJAm z%gEr#y*r;+bIgpm_VLlO#bV8-r)6A{Ehp-(UeEAyUuW3-ua?``MEegv+y3E29e20# zyRs>zN$(9eCS)3}^bOZl@$NIPz7nu8es$H3OKNFfKR4gumasV(Ef%|H*M=RNDm&Ny zh{<7i)nxl8k5jg5m+3Mo?5T0z^u}{~I}M-B%6MgSbGf5A zOX>PaMpvI4IW=E(b@QZW(Kb)D&0qh>^P6*9I%3nE&)HcM12>#!dvtx*!dG#Nn*Zc9 zTb_TvW4GO|Cm*KdBt@~$G>`PWEIRRU)a>bAzXI14EuFkM?A^XOOPBrL{O6iP_Wq+e z37MzvgX;HxvTOeLoZot&;?jnl?%tF4J)0}OG}&rX#}s+rJ>55E&pGpP{h#NJ^NW=> z8LYh-WmT$VvD#7eT^P$}&ZR$Tv_+>-#ew``)h5xaFq6G2X?Oc zbcy|C>ZQ;xp65@ds|F`k=WrCQ`^&Uym$wkZu7-*Nt)A@nsyF0nGhPImRb*SX{)v`f zp4QKO|5;!0ZTJ5=x7n-N>Xz7Vba^glR(o-3@43Ip#}7Z2owiTVEBS?C_c<$roZAzQ zFdubz`S5V^lPk{;Xx^L4acz_3K6&QNg+J?J{%=zEUu$*k$wPbTU(37HYG>~A)tHl7 zR6hNW@xuxAul}Fdz*%|FXksM8hTCQ}+-BXG zvN`0ch}K(u6S>GY5zL*bFEY&Bhv8$2T=Sv;S1%$@yRVP9B>hU2x0%#g%V2*V;^V{=Clpz48t1+Z7@OC#HJlZ-3=opY>W* zZS{%wm-d-mn*J+K{kiB7))g61F5&sgYpNdJ*^yX%dCO8;qqzrlf3v0Ah<})~#}X9t z&qVe&HP0&jbG+r`is?UP*y)* z{d>iu=u);|hF@F58}#3D-?2FMVoG^pf|=g^)@R`bLBc1tR~vJmj1xlM2XUB1S<@N)3?!2c((R?TgV(O9pYD3zwrGLOFWFh?_jul2=?%|~yA-)&Yvsw88`%?N_N^;QNVhax{^!;A zH#gr3drSMg68_(@Ncl?chUg=6ChcvX6Fk2zbvIv|%mHD8w=hp$FFeF@wPfYtsFo{Q zmFEu>E7^UYb@EztxlvG*>b@^i{><5M{okeK`|CD+_$xZi;)3Uy`cBuMG9G`n`fy(p zoZ=QNf8=4{!_?0q>T=wx!*4s5iS>#~}nA+;a$7G57vv#)>cL?d#{fe0=NFwPQkzKi_pN z`TXiqrPj)OO&+

Ah4h&x6DE3XUg}8q6+>y?$ab zy@2oiAy5~V`|SP~M~XKt5A;*>y;-o}zSR^5!^`}AO+2nQ zbv8bE_oc`=e(JS&BgyLr|CWZ#>DY3ry2mP)_m)}9MpG@%;thW1mdRnu@e*uxJ&k_x z)~9VZp0Az~=KUs`f9LE=m4#2&TwN)%H8C^&b6)L3T|KWCJazSQ%My8)$ycX7`E%&D zvBxjX^top}ORqev%iC$^8T``he&4#k0i`9@WfP}zD|zMI-FkRMUtfgSocrbzZd~r3 ztH0G*q5ewPc|qx0QVf^y#qPgubuh9SFOMl~P1=T6DP5BhI$j5G7@6PE-*W;E8r#!zf zH8osLFQ(|{I_2XbpK5NM=zV(TDR+Lj{i(h7u?Oocze}!~yryoda=rVxw4|MHHc45% z54gND>-Os2aLEsTOeggBEZvv&UH|LVg!u<%uULDrFJ9_Aliy=sP=C#Q;n%6Xb~6I! zEwj5dd)tF`eV1!z_ufBd*753q?d%0t*KeUe{!

R$*ZbSN5Y~1z++E4H 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app-success.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app-success.png new file mode 100644 index 0000000000000000000000000000000000000000..7aeded1292a79ee8ff6b1115c5643aed1abd4acd GIT binary patch literal 263307 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

_WFoel48Q;`=7sw0%`l9JqVvv)#cs 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

eiCG=o&f3ag~iCYcF~WzuX=J<+S*v= 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

_WFoel48Q;`=7sw0%`l9JqVvv)#cs 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

eqZd-2QaSu5DrWuYCX5J$?P9<5#c7 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-security.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-security.png new file mode 100644 index 0000000000000000000000000000000000000000..0dd97526bbc4b879bcb3c2397f9c60b8699a9da1 GIT binary patch literal 367269 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

    2LB6%=fy$@Mz7c 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
    J2^G=NSZ6U+L|deI2;tZ(D3!d2@mTPxzT2) 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

    vn%E`(C{9=K4OnPX@LhPt^KtDBs1|^uqqhd})!a zb5}*K?^eFnVeI(Y{BFTkKdXlk>93)?WM8C6t==j2J1%+uQl2lrd!-Wd;wp~LjIw6l z`~3Vxug@h7e6qJ*yM1&~elO-+Ed3b=8|Smf=vbtK1R=CkG}uj8{GU8vn!xRZ05zIK>vLBlDg!=kxO z-Q3+qPhJPF3iU3&y0dyt&DpcpR9)?UJzP9fYWw|&r%&^PG9y>+e7M`g$nkR`W8nOI{&l0zpLZ`8`7Lr}#fps2_k*|me6QhtGjis+_tUq1`=zA3SR^;E z=A@5*cwF4q_gl7=^{$nbm%De$hIheSFYm6cij{jmTW>hFX5-q=f6kn>x_B}7j4$_W zv)NDgFSOl~m)rE*_dxB^pS$%`EpMuL7}T?yE&4IDg==H(<1@U>fnGN!thsY%j@y|e z4$$bTgSWtqyZ_5Wy?^xVaATR}4PG^SDP=*vUg9-Zc-{dI2i#C)&1v}Zw*21u@AiLO z+GVRIu<^YB9q?jR{Wtp_)7ih-`#AUf_3Pbv@ebRu_vX(G=GMLHlrpMVaNTP2|2eC- z-}~wC^4Y~h)|>v=SAS=e3!VCn@sGXfWY70|9bO1HP2^MRy20JG_xrto$iVNx*YAdg z$Ckg{yM1f&L8tc$vQy+PRr{-@8ojlC-X>|3>7&4@`Tw!;%ZKYzS7{6F)|k2Rl`eDreI%aic$=k%i!4&FC%h`Fb7A>@x)5@%Tsb*s{7Bs zwr1s-1ij`jYae;9UcdjR-1Ha|Y4t9K&&wFUoO|=RsNud#*zZ2Q@Ar$_wJZL$&#yc9 z-}d8_+nOmK{@$tVKcsf8`s!2h7{$WSJ*t83-iwWa}%t1pqqD3Lx25&dwq0jDINk8y;A86oo;%Z@=fzkh?Ts~bb4(O`xA%YIk)ua6X8xbt&VQKqdR(jdy}JD$ zi>zvP@89w9@h$211-mnkDs4Jd`|D@87u&CT+p7i4$7ftrj^B=i(RB$h`?cf96t!}EDil;AfW4V_7MQg^YoPgJ+92`cAE`>Dy z`C@dX`+n}U|N9sX109v}?s3grdMo~Yb5tqsw|Az>AuP+ny4QSaU8=fb^NpkTS-yDq z-tA}XWPYfBZsz2 z-}VOFQTgywJU;pJw6|-|y}f>a+M{pL`3*c?ecio|VP$=**BTqt{r+aZq2eW%YD3+t zDV>kHD|(}kt&&tXWw{?7em&vqE#7tiWH%~qt~tB&gH5W2q{jaTe~w4Ve!KZRKIGZf ztglfyKWd9tzm2PY9J~ENWxDg`n?3z@KbiV%OvD-g{qtH-9aYu#`Ges7?5wQ9?|0fo z9{r)_@wx2l`6X}rygbXe7rgKITJ}`pllK$r_p{qm_t)~*+uJ`izI2oE%O|#u zYx915*tlci)6W01*WZay%Ab>nc8S!5sZ3$3C2!uG`6#nOYGQ39YlJJq-i}rJC$yUt z9r))4>ek7xZHrsqel@B2Xjb67NzayESG;hVJy9vRrsV|B`}d2(jY6tfS-LIC*+a6V z&so2Z37Il=;i^Sk8$}&o*e5ic(2>+Zi%w%c;N+fO}gn7=;oPh5&i$`65z z1P4byU7xM47o@TTg}9cyi&u%bV$l8hcPG!cgNmF57B;89+?hHL%Qf>4B0zU{>r}n* zMvrHa7t5GduFSMZ|CXwhQKzA|JB9C@&EpUkw-)Wqyquh2n>L>Ad1G{Y-?7JhJlCw^^mq8_NE^Kedf#(zKg5&2#T9d-Hlr)QJUE zktxr9|N7Ne>+(Hf;#YecpPJqJr_S%!3EH$<+gkUJhK|-T=YEqE`TU0)R%czF*0yuE zmQ?PEoY}N=| z|2Jo|Uwe&Al6U0SyJD3+*0arWb4ytyFX*qIIj4Qk%odbm*F_dMgmaxZ@bgd;mtc?H zrk&kCDw}^SyQjG6K(vlS?Nm;;wS4#X)fvppdMGe+R%sOPDqqv2F0l-mEEhIbMJpX9 zH+|7ZE(&{PobRoP3yNA}b5uu5iDlZWs1-SUf+q598#)wbxP(YVsBm~zI&R9+%D&B!a|Q? z9(#OF)-76VWL=-V)QiQ$qWj{Dw|8t-eLrx3;pt~{mzsYc~o3`&O3kG8_z7x%@*IYmp6CYV@I?ST~;?? zV?>~G-imeR(Fq@}9Ta%Qz1mHc=~n568E-Z8)->+hB^MW0l@TH(Vahf|?CODqo0Kl- zvotEQNz`n)(D~!{h6f50*X|QrdUWZB?_XP|pX2T{oEWh)$#RwUs-u%HYc06WE8zIC zafNxP#>HRDW@UX0F|j?f_0gZIUW+*8V+ISiY;j6Cx_$AUHBKwP8~*4rb5-Kp%VsFp zEFd(kVNufe{o*BCc#kheIx!opai2dv<)rWt@wZYZc6ACLbJX5+`uf$YiHDD!^?LnOJ6t>2PgwH# z{Qu{*z3z4ft82f%RP^zZXuI3n9os*AFu0yjZKcokleiwM;M;hx$nRIR%sGO9yS*-=sxh1p}zjaecPw+ zuPs$gi#QuLvGQJg%GB$JLLyrm1mbVVmQ9>`k11Z?{z`Xz@L4nNRj*bB1gbN=yxMqS zHP4CDr(FvJIbXR3)VYMPT)KSe;o{33JfGaw#BJrfXjs_c*VD2rinn(Hd;?KCjlT zyYaNIy58>-+cx#TxgB(1FOP=5oZ+6#@a?tr_VzZPF2wx#^*Fqvudm3u%%(gg?8E10 zF^!_DuW4PDFfrg{p7hIn_NDdR)3i#9WETgyY1|H0_Yb+3I<0Q=%{4jeBX+t~%3G&R z`Eh8U;_mIn4RL9k^mTQE`^um2@2*&~ck_!%{ZerW2@Meh*gQ(u5>Z{ zk_nlm6{uaOet&Pe`L*@Y?XLTEoe~QLnVOh4K7SCGb91Zk&(xzHXMNoBTs6Cnynia1 zI`xBb+oJe897m4#wQT3O#Lw}eEp*Q6Ww)Bq$a~m}5Gmnp5hjBmR6o;qj^Q)MQDk8O+?%j?~k-r(y_xza`kaqEJ`(jE4k znWuMp($jY13u{FWelb$s>&LRG-#(G&&k^M(!F;TDteZbf^^^Ufynn$3(_0e`GRNM& zTbO)k$Hr5=5=D8gN007!JdfQl;RdJ0-#Og{w`0F|tIO_bY2B~mwDg32PHvh0W3pRa9^pZ$TmL7C42Pd z)ba(nnWaRRmrY3yxqjur|9KUsBA4#@|NeCT$J>umJ2?2A^YZMzRN1oe%QbikAA5Lf zwVrcEM#t*fniw6s-yd}682>g3>C)e0y{pGZt}p%H#~DU%UTuB-v48ph+9SacYuh)U zU}a%3$<8+lP5yd|cZOlDmYT0jd-?tUEQi~918?cZmRU5!r7eozoX6}p(@<8}Rbijs z`r^AAKHOfEdiL1cjxOev?6HSSzB5#1KG*qv=f8o}ZOhkBt4m5!9>;Ef+ZXZvqr~CL zTp2$0py11Qu07#d!Oz1J@bB)*_3O*6-`$a%I_b@wC)Q~3ET^WBFHv?tanla|E?>98 zgN`olyodH(d8?tnzA2P*-gRXo4W})e4u+&Q#j4)wuGi9fov`h?^Xf|njz8dE9oo8S zQ<2N@BMUa|5xV;G=nM6KY=VN1*ynB+Kc%IeusQm|`g)s1M}j|uXqj%}IyGT_FkAB} zj>QMrTU%Q@EA8Ji&GCnkMqJ-kHTlCu-j_g9hkETvc z5jeE#>;COluRPWLGQUQ+ui3u(xQCpbi28gJ-^j~ty|W+k%qZ6jx_3gUyJna3r;df^ zUZuT{tvws{`;6&q32n4`NG8ys&X|A7)R09>4r$f>H&oEkVY7R5GPi1?<~=>WYDpdr zK0ddK3XPh-DSPFnK5F|mXOEDGXlVC6HXg}oO!of+u5?QGXCD=Qa7bBc!jvg3Re}Zi zB9TuP?`1YD{h<+4_UxvFcAftBOD`wJ2edruvTA8NuB2rW#&XX3$k}&M5_|R@wcML< z;kV;@KBrF$I$wy}hNK+lcdINEJk`yWuySP+U)sfM+|zzVrSg7qV-Q1+ViUf% zbsu8*#m4>*>Apg6vE3M_W{~lK;m_Yr_d8)zXHV}pKEIpge$DsA(Y4;zM%H_Cw11oE z75P|hQ(t;2Md;u!elzYx_TS$a7yMciY$LfSHaF$Ke&fwM9czC6TfbbcegFLU?&K2< zPpjYW5>20D7Hp~aThCI2;r^E9GaK}~*Z1@5?N903w72A@*3-Qo`JeA}@Ao>^QkXo| z`P_rw$KKl9)zi$}(dd}=efs)or`Y9dmxY|(x%bok^o18Y(r=k-My+N0FK}JgMn`1x zd28;kV&0R*=I-B}ci8Qzijl$X%*$Wa7g~4sg0J7MGTgJ5x8m*7=L;{t zoMLKm{&t1qZ9diur+2x_S20-Ser{L2S9rU3hEb){0!FUphdk=}PwM+=34E9XDNH?UpLM6O=A`^BJ$w@7;kc>)N}QKlXL- zX!uckW8v|CSA3pKoxW(pE+NTEOO3S}?Ow}U_wS$2F-hNj){50D%olEoW4W_Bbi)4o zPr7-&NzOca;>{wvBBJRrfUReP3r2j$ToVbDvOnnm)gdDK0K< zUFfNVZ>QJq<9sPObKNfGTyXR0wGJrGmrJgCTW0-kp0&Jn*}s=EPL=b^|KFACe|YU9 zhjsn$=bImSe+pVU^^D&Bq?7#<7*D95w-EIFD_r>K%E=vHm%aY*cDnq-h3xM|8K3jk zOa1tL`TSzPlnvP{pFDfkssFuPyZxM9@w89-QhuIF^EEcwT<{@b*QB3ymyQ&kDop=S zyZM-0$e*3r{i~<$DNOvd!My;O+C|8fAD9zvW|%hr=GmEn(I!tqIX8l zwb4tJuid_x%)-u|c_sqJ#p&X#aB+BKjVMD ze&LN1uWLTe`TX%!_xXqGKg%CD6fb7_`nII#yqafLkN3!+-fr~bF4L#*y`MIDiF7>p zdg_%F%P$E*L7}D-6AX^H9#c4>&+yMpUSjJ$4wE*86B1f|?aGQ)Y!eSIk*ye@@4W7aB8G`D&avfA~NnbK$$6&z;{d6{>vf zdaY_Rr>N3}eTxlTmCEqPh;OJrc z;x?t5;g|BCUAK1YD}=kFw&fa__WCVQTzh?C$(Ox(r7;2+$;-1b*l*rFozvf&`EA>5 ztG{o*?fh+GZM^u*EpuJd1g1Za&}nM2)%^PC9}L8F|6CK@V3+eEVWMXq%eLJ6 zFHZ`{ZJ+pgZsjx9iuY%yPf7T^;sl2(!_KXYYs{qQ{kqQmGoIdbb@Nm1< zZKDfyZ+G2~&e>malk1KS)7Ml@@%U5!_Z4p5RBK{y_vc4(O#NHYj=ruVmg#fX?RjFc z{r=yE*P2XbhX1qk_b|)v{ch!^#((@v=H#j2-p`}Arpe~*Eza|9x7w?xzn|gLGd4*c zIT4W+EN!PJ-^wYwo_V8F*B@MiMC`26eYYn)t~-0u|GYChzeMT$ z_$BP(){^|BBT-K}y}k6c`J?^%`x}k@?XN~&&3q3^7H^-(%s{@7N#w;=rbl-5OK+?# zYjN*AaN&o8;DosTH)oh4)@li^u@g#sX!q#j$EqpQuP2><7cx=gK*Ng(0as>g8CF~n zU}14tur03F)!Tfb$NSc-0MIbI+feD_4JaDE#%2_*;8%f4xxCqD6(D zb+0Sy{#D4z&Qf^yB>dK`w|p;3vjk1@#h+hPHn~%Z52esevq_tuSx zwNE8_y)PG=*j>A{?aY?F6)%gnJ1_58^I>k_r%#^>-?fH6czXTbp>MMF2Xf5Jt$lrc zb?ah&Xs2~1{0@(+-hK1qGSOb+lcyj2yte78er%bA@!v^HwU11Hw{4ko<(~M+&{l5! zooyF#>orG4Df ztJm)zkSXuTPK)HS#s}kf4b!R$>E;J(d7H%dEDV%P*tSYgK%(!$h5#4$V@gIkGIe#1kIJJQq?MRn z>hig?yKC-${BPrP{xvr@@vYvLe{5E6w4jJ&|HH#=3-{e)T;E{OGs{9!*}ebR0Y^^> zg93v|lh_v4?^ii;#7$YrMx<)3-<}#lDJhP#2`QvxZidY-QBWo!bsy2D`I}hpWaix;;{vA(Vmv&$82j}*? zrTeq@Z#LT!#XITOcVWrbY+d@-vt1`tc24Tuzg6MKxmm|I_N>1AQb1mOaZ1klGpE{O zQ%+{Dd~u}oy}r?d<42DkQra|o`OKmHBgcLnu_ z9PW!uh(C4O<%_Z3oR%Xq3|!bV1Hsjpl1CvUyJW&8T|d*yQc;YD{}Si}GL(k(@A z+#BcVE6f+sKm9PHY2JRdbs+CS(|kb9oL?TlxEVegeMp5%F0q$Am(*UfW5 zzWh*zPVBx{9hO!})bb zE=Rb0DD#iVF7)I~Y5SL~E4%UDJEOMCPWL`sknLJNf9E@c@Ni?WBV6Wd*;I}-;hnQPJ|~Fz`>tNGvVHvtJN-kq11ANu?p0&j{q5?)YhnD& z`}vian*zgfTBq0BcySvGNIl@Kzn}2M-^-<-fFtXu@bhooYd)$fO|E^==%XT8`!N4Y zqvQM5DS?d=W;T*LEpMJUai{;z9hs+`#rHNiGMiq>`WU>_aqWq?`N3h`bH4DfUbFoE zZv7ca%r3Hxa00{LbiW)|cz8oQ3brl^c6R4-ms$V6@pN0gj&+evI>TO>uizVF-l;oW_CqbU3Bd*WD5u6`&ywZ$>1s2ODOQFCxI7kc>9rtU~AK#rw|dL?a)bv;EC;Vx!dbWzQ!apZD|mV>#CI>mzqF zo(@}+XCt#6rP&P$;TOzIv$y?Y3=Y-x`FgLQC%G<9&Ph4 zirY0lydeG8#b7r_$@Xgw>o*?oPU$JPc(veqX3E-0lKWPz6Ek{rZ^1@oD=Rs-difcl zW-cynN^vP0^>wrl9+AAf@wdY^p@R6()RrjarYCE^t|(p+m@oD?!{kE76{W*_y;xpn zCvLS!SXr!Kq9pdT`Ax*ma?P^0cUw1k2`Gd|*h>b3 zqT z_C|rIgw6fi_PsIk=w4MXcu^k9cH#S8@AIN)so}*}ruF+i@;Ny-7ryqrUV17jzW%lC ziQ+9GVI6C}d^+j`N$}vp0M5K66tO>5eb3*+3opMmSX4iSqc8lV!7t~V4_!a(xyH9U zly`2JI@9Z`8?IebwlHAOJjpEZWNm9C%kJMl+ZJuv;$hRfUZ}IvQ%NH(ZO(QjMLR~r zi-sS>-fmHPT+@0YE`RguL~+M2S!+*Z#pk!it`>Wo6%ZEJ8XunLmX^jQ_UDIpbnr7n zj9l-qULb*?cKwc?7#39DGjf@TZMglm;?K$S4Jj|Z&e*-z>5-h<&Z{e|vR5>|lGim8W?_)7e>o`z3v9``*f4~bDHJh2D z_ZD6{blSVWYUBG2ojD)NwEr+O8D?E6VEL6LpcHf^e5!SVKyFcSk$|i)v%Gx#jiVL? zD_lS96|?H)IJCWU;}*UvQD>A4?kjA%866Ox-*z`qyzzHbNZ70m8DHJr+}_T9zxMy$ z8Owc+s?Se9j~O2?_A>D-c)$1hG;Oq5rVGzmQx;e^-~IjPcmo4+_60{~<2%g<1sami zr|U-doSeLT(XM4|o`wfG_&&6{rL=9g)>1TEuxa&!^e;y{o}{#}t$w(8d)I+Vb|0;Y z3*%T0&2|m=bL8Y?7q?$lFG{Nf8{!owaolhB|CKu9R_-sy~Cf+769 z%$YBZA`i%=ER#FX&n>QX^K~j;jcVJz>aN1DyD<(+#pZ|p7bxU!lMS8v^pSC@eV(zI z1ka;of?JFJ-MS^!|Lo!0+>l#0WzA;1K67eYk#X0L@2d*ux;K|TcKg&R7WZgBtFCAz zbN|tx`vbI8-!@1Wzy`!jp@ueV=ic%u`!TAQnQfZ^AUs71RpkjxOg*R)#i=`KLdIs>;xJet0cCRewg-G z$LzryKAocCtt-h(NrRHr>FFtQvv2QK+vE;R!ENw1InI2qBOoxx82Q4<)d`m||U-wXB z?CikMz*|w*{Z`K}yL56!?Zcy|e!SoN^_O7t_T&CDTC(%^xMu!8+5SH9>?+Yy-_ArX ze|+a=@r2oPd-vOa%vgSQyEc1YXYb)Z`|U2i(tMqj9XMfr`+f6{Co0<0H2sfeZ2c(6 z7gKn3tAs&@!Ln|JUthkMh=_{GEM(_LE;|-vvq(7HH$7*AInNEMWRUU=l)1o_aiWe~ z{hM2@Yu@NAS<>T}nabki+$<n}*}ZsZ+0NtS?;<7TT{M-+N*muV6v^@|08C zqI5O1#E-u=2{_!epn)M{tJR8EIZ6v|GR-~L7j^Mlf?MASoB6$yCNZsv_#@5L-Q_Z^ zK+s%&@$=B6=2oV+A{@OPuBUcPJ`&6?#q|7asp+Y0e){uj1jKp|XeQp+R>yhDYqwcJ z)yMVw6P}z1^pLXPm>yFn`t9xA=B}I(zqQ@=9rmZ@h7Xg-7_{e$%g75xG)Fj=FUFe2xpK&OB?N~4GU{obI=n77`$+nxD9MvAq#K?HFFSnSo+DXp ze%ICReQh^mszuT*cj@u9%gXQhZ6;Uw##7?xWvO*Lep&7Lb&2~dTX5&j_~N_022y)n z8_GrP{yn&xmRnVPR9k;v!?>b-ks5t8L2dSgqK;M>5KbJV)J5i8uKhA&lW?AGUwacf0@k^}RS>ZtJSr9|iMtFkc zqs_*br%rz}afS)QMpR9>1wTZVc2_eO-kjqs1$=* zPNPeFN^cJ^Ugw+}`8-zi&VmDm94#$wntQvsi|;f&pX+?<$Ydd}?#}{(b2~14xS_|t zVEX3><#{hA7-jWL@~k~~bb8|UieFBVnVm*QJ32h(=rbKjjoe-(x-I|qq8#~`?hz3d zLPEa}pTFQA`mmE~9 z_m$k)`nq52_6gIL?&&(!-`_aZ?oI!kQMf^E>i&O!l>MxphOl(ZE_)Iq#eSjRLyq<5 zlb&XFehtPS_wKpzNLtBUe3U8q`ubW|&%%jDQ57yMN=l0Y)Hj`fpRYXO-pfbIMh~V> z6H~TTUK=`H?Xt`Mf1VvZU2O*w93121j5Zr3tXh?IYt7AlQES7ViOrwDu=mC6>2rJM z%*nZO?V3sUX)Z)-rSYEn0ft}q%6)e#Aq24{U09Lu;vrMJ@sZQI?3aT1HP$bV4m&K- ze%xkP;EiskURI;aWy;#M`dX*Dq{DaTMz0l1jbCkB_fS*5{)67XUq9?0JbvDNdi^f3 z^?$xs3jSGpDD?VWjZKeVyKX2q-1q0cdfw-}O!wuNAHRB?ci={$@EyL{T1S0#=GXU} zl{VjT)%;#(XXnwY*YCIN_|bCg>W15IZtO}`wyXL-H|^m2e~gVgUT(9V@-2VwKcj7V z_nuq}fB&>~_q$q#g9{hl*jX!G_U^{BvOUUWMwc&7m}BI{a)G}<`rS0^cTH}K4|1Qk zYjr6!K3FLpr!uc*Vc4xDOPB3pdU3o*w!Jw0yyH3!zyH65`*-y!mftG6xvf-q-;X!K zAz@)Auhq4eJiU7TUdN0b7TX_xYHNOQ}r>S@vTs&`1`>=(Pnw*S>{YhOR=f`u`-L4+p~_BuE`>$Q)OdT)88@3U&s zo7klnpDo<=%yiwcI|~j3a)~@iQ?OU(-D@;oI{0 zd)9xEv{RB??ACvDiRR@C@hq*@Z}@6HoSUuWTorpexvSy#>h*i$IOmyPzm|A=+Sx~( z{F$frH|$dq{%d;ueh(uv+g1y=gaCtgd!E;Yf2c{Uv)h(;t7F!ytQDqNsb^m2?>Z~m z@J_~s?OOhw4RJU3{@AoSLFDF5>FJ--y+x2IiDLgGpeo8v*n9e>~L z^!l)8PuolO;Eg}Oe_gR^O^e%|HHFVCpFe!}TP`GTO2)0qM@uw!c*{&a`1#Ybc3)|; zgsWXoHS~2`{q9Ur$lo->^7WTxcXuFlpDvtc>ASDHZ!gcJ)5w)2w6TCuQi0;CWShfd zoli>3wjaIZRoa~!>DhQrsH0DwW3fNO8zl~F{oe`cbB`@9O#Sxl{`Iv-e|SzVyr>%P zusWM#dgPbaPBIo7-ghLs96#c)Z{P1<-a3(Av~$c>Uvg(FzhCe<7gY6|-!BuNSNSS` z-J92&8n^X8$@6Cq&R&mqtczQBDO|bfc{{JaSmd+!$4&$;En`akb4^BZP-5MW_p(`tM*zwU~FhJN#Zf2*G&OK<+S`@7<*&f9Z^ecx;s#@8>+ zURA;5=AHU1bGdfo>-lwG7_(kyMQ2?~ijCIW)EsmFZTVT(3Ky2N^E+AI@BOOuiwKldF4YjzMmUEB@^8^)9}?z0vU~IYW*yZNYon>yxyJ zjgWu_rsJ^(UOa9;c=)*H=My$Nq)nG~J+@o^zxJD9R(7_ah|ro8d3`;tL;T$PzE;E; zz5bKG|IZVydDCT2pFZtU@Ll@U4kO{eUnWa6-J07xPswPe`|)F4c4kZG8dt>0ZNK^E z#?EBxx*y-Pm;T)H()hyq`bnEtf6`;#VQ)7jw(ivy;fWJ&_@7)=_i<^sQ;x$ui4B1% zaqoMSHg7nsP#Vd%O~^t2_5Ir4XUka6pZ<8OsBqrte%NE9(fsiG`sn7T-eTIh=k5P1Z9nsmk+E@|I^&x7-KRut)|-ggi`9GwHELpQ zzF!gMnODB(!(4d7UEPDLM7^gb7k=c-%k{HJ+_Pza z-P^2`)YM(F#qV^)B;R^>dr!H$vHg~H|H<$6<$1?vg=$Y}`04FB?U!fpGDSN>!DXkk zYQA+=ANzIeug%SCo!KhuCx3qWUcTYU#Ki?4mxe!R>edTw`{B&;Q~t*O?MEM$<=s|m zy6{$4E_?MQ;px5m^AGSUgjp~!I52p+IEL)mS^ju$`MrQVhl0N8Gj2=}t)FX9nl`Uo zu6W=2n0o>a@1N#6WJJu^ELECT_?JI*&U}l?Sw+T8uNT~yU~YBd%;%p!fA+54>5C|M zFL1L;&GWpKV_t(%U)ub%v{;O5lxrY*lxMp?Z=lcWqj-^Ru`F4_Gik)tzK_e_4o9+B|0{4 z%3o)keEM0hgmPZUjH*W^JW?hRcm8bPss8rHDbMd*;9Z^vR)XfBQV&{pRZU@Feo=kp z>7x`Z1ClsuFo*BL6C6)#K2GaU_-df~pz8InqbpXgd?zN%%fWHvX?X1NGpR2h-4~FN zX$n+Y@ULt2`ojm0^KF@R@{Z-tNsp8wbl2YJm@s|zViQxTy@EngY&Y#3Qi{u`?YYy& zQ2o5_^7lP=VtQmur5YRCf1Bh5hljVb-mh(aowp}+kp z_3_=Q-gUy}4iVNlIhFy{F|+2~IDS3+N1N8w%gfF;)X1)MIWb#en|$8am+tSK*NT}} zb-dQkFWB*6(&;J9rdLgG?91g2TN~5%rFmt$bwM{g?*%Lf2XzX<UwIo*6_8Hoz3`yOn{-+u^H zj=njBv;m|sPUFJ2{|mn#VlDP0a%=;f@nqEvR4SR2l7Amm{P(l?w3di?O6i>k$1N^> zku;u~P-%H)x%}StTeqa1Zhdfjy`g)G{PdY8)P3eO@xH#krAqBT!+$g8Yl{~xp1M!; z>C+W!)`V=+);^`Ebdhl?*G0pPH#Yx1A9lRIt26UOeBi~T*(=rOwLDY~4p8iSo|2Xj z@yR2m?C8~s=WDM==e*BMb&Zrfb#%_|OKd+e?X!LapF_qKE%{~dWKa9_&B zZfT)oJ(i5i=T@32DJ?Fz_r~(Z*XMpI>8VvVa?(g+zh871OV7{JOUGPxh9jRauxeb0 zWtqg*?-aBD;Hi>tIr05}=4^RqWU4ChtI1Ma`*Y;}G*eL7G3)jw)oxJFEA{`Q)9YOV z3OZg#cuRl$*r^+;UE29~(v+fW#KJDIFe=fW#=@7qpA=T5m zV!_Ek1r-w>@wk$iLHi%P*8gzwxcq@6v*b5FIwjQOY}Z!2T6FoPVZw!k43l=}*(vwe zI6J=O?Cg}?_ND6K&bqr&dwxCQKIO}=wUw)xo&W8IkCsR)ARN96Tl}e?c{e|Ajv#Wk z5R~GP5aQ_T?IzZ*R{w-eml((k6JT8@K#@hyL5!w=Z;CeDJIJJ*K&F z{g)mk)qMPUJkQxermW_}yJ&;!*ACvkEgc?P-RvQ@z9{>0Mf$m=;SOxO&2^dCcn%#o z89epXmy++Z+0F7ImS5?&Otfk1Uh`3RD!1MqiMoIPydHd8)+>Ey){2m_AB-v# zb-yk+F=@Y8>QdE+AD8*Pc6;mXmuhr8m{(hMs83zb==Hxl?9U&|pZ~*NRmeLx^>W+S zQ_nabt1H?qoWJ?jTieVB2{wP~>ksE7W}E!l(Z?%2v8VdkIpO2;N~AB}To7{O+V$uu zcUP@yQ|Gkk|A?r-0~VBnc4m~v`mbvvp%B^Skm6&{<2i4^9Cdqj+18zsAIyGj{Wa;} zgL8|nS3f=yDW3T0e~OG zQoBDqm$#m}YqiUL!{p7vUfM$y*kc|==V0>Q!n`O zU!nT`tsO-6hQax_kxwk3JK@K}HYFzSro4A+jLlI;bqel(f$sv zBlqU+-+p!L-Q$xcu_ay0OxOCGvZ3hY26ow(TTaTB-Rv3d6YT^t?v zMgKn2Q}X8KX71;6>KXlJ7%(1fZT;~1bNlq|j+x=PMh~}6|JQtLSJd`8v)Quw`#&1J ztNxI9dJ1s5O zZOk>3wyXM|3z}t8VE&&f@Nbi9cg*qKzumI+EO%OR@N$;2ZhL=sFZcc0&r5F?J-Kzi z=CA6R+622t!or2mYxxgkZPc*)r!=`fp}^Vg->OqyHUCbwuba*HMBx)#YpC}0-l&t8 z{{1b#zvafd!l&x;``Ck1MN8u1c0BtvTVeA8b6xxYUu^dYMm~C-l`SYG_l|3xzqjvE zZT)}JM~}Ap?$-GI%*r_K@B7a;Hq@=1DX{mMd^VA97`IGA6>woTyj_-9_oU(0t z?q(z754ZL0cgaq--V}FFM&a~N@tBs56B?3T0kVe=vH>8$r_TEpY24(k5i zQ=I!X%{Z>^W96FItwLfG=f-f)%V=5wL*-fzh+ ze_ek2+oq+(mPks#%nN*tCw4S?z5cW2@7otgmx0AF_HK&2h-$p|uYAqD9d#SdEn<7z z#GQ*|OMm|KsfPZ}`}2aL!@GSZKAm$k_CZ8UidognOuOT?9{t~ZmTArSX8dr4 zdqj>4+?cAF4u_4G_x)QLwYR4kHdye5uW_>fthS@}_1*Wy>YATCbiTb;<7WLy{rj?| z|I6l2kR?#*VN2ez3Ku3c?&J155)7*%FO)K!|Nr`ZM^{gP-;bZi-z%ivF^O0^&;H-X zh~MRRy(-lZg&8A}%!cPoJPW?x>C%NZ<87T3EG$ll+UTq27)TshtYSO=*T!$(|M<+? zI>)q_?a!YY+w40|+LKpG?bnOCb!g(fNK=KC_CaoZ;bP%oag9q)hkZNOS`>;L+}I-l zRkY8kf$@ub<1sym#>RI#0^-t-&GxQ&BXc8XUiy6dYya}p-#5%X{{NT2ukYR#uO=E9 zZT=O)@b}E*<&Qt^|L6Mg*3aj9Y!~Fes<+EReF8CxU^q11(^&AXxBJm7XbjaxE?CO& z<6DJH_Wy5lx^qc03~XDh<^i5Bu`ACOLwk+892E4{d9wXlGpB6s*NETSU#Gmy(b@d+ z|ITdx-BqGuqT5&7N+VBY5$Y{~Q-i~M(FBIt_j|X+NP^o|UjiF{+)!iua`WcfNfy`s zy|s$8me!BlCd6<1$;G;Qqa|1oSSPlmh9#`NR5G>;1Tem`<9B3$q$LM^;f`D(hxwYD zwryWdLGUOkG(AsEWJ6kJ|AnLRxCj<{0CLIa55_0`Pf9!72=2^3DCCklb#&i+X9XMS7 zLJu^9t{2|)8J0&Dc(aCRiR$h8U~{MLG_QnFMMC%UxSdtH&(7A%yp)`&E0@1=lku^y zpT8c>-5%5bdfh%5N5{sqe!Ej&m))uR-u!mf^5O~I&*${BKfl+yM`{Lv(=ZOV!Cch9WE<*mH(32#B{bpwT67>@u1@Cmw)Zygyr&mW zD1N!}=;_nk`Fp>~@A>h5c{K05>DktWuTpg4zw8y-vo1{jXZ>uekfBM(>We`{qCz<_Lq)r z{APdY$K8iJc)0$5X*R#xbhfzY(}%-{;wMa;$=f_#u9=PRK;`o}oQp3?vo$mJ+ZyqI z{ra`y`QHBMSf})!*YBUV%kTTivvK3ab)Ut=rzbpI-#u~KJjQ&(?FXCL9-O)C-+CtK z|FP5mk6pk2_d(X}Ysakf_jE)Wr|+0`Vz$!0KWU9g4`jZ#Wv>ru`o{d{@5gtu^%FmR zx!kXHdhctMJBU~y7)@XW1#?&>9O~!jGx+;MBKL(y*MGcPUh(3hdO&dSYn!#7N4pKW@c+I;7Z&7G3ldv)cCc`sxnUuyZdZg0<-HE9PwpKC69TVMNU z{<&D6*+!lxPrP6CfXJD4a7qQG>P9)W13X`B-!v8Of_i8hOVVtX3+bs_^_l-}{Fa}c zCtLXDllOCneKxw>brBuW?`FKts(WXden2v0fBO5nJH`JG7g)%wd+ckzsko@{d2Rhc z_4oT1%2>Vb2^JKUyr{!no8D9X?q<5f(yS8-@v*VZv)}LFPuslnrAX}W-~3A+Ep(rE zpj+SO?W*itWfheZr5fhu_qX1?)Mj!ByFHxPOl4%kf+H4`<44PkTP6bl2-U`*q{4r8(@{{P2_L>btji zWhOkac~bShr|`U0^0e$f@paKnSFV^`ugjK>ulYN7lI8xbkI(%&mfY**=@#_g<@rLf z`{p@!&OG=jmKxy+w;X@D3w8b%6VT}S7VTp{p)R~7U~!G%NAlbI$F5jCnQ%rdfAh`T zUyJ5NEWVg<=f=fzu{k$)-Q9ZkTHD#Q!}n_0V|>|oUOc}w4U}yBmLCRfu6;i7<|kX- z>Tj|;-_9zPPS_YRMKRUwA8UMVQ}((&B8-gx=FMxvy21-37@^$8U%FL##+Cb9bBh)uGj7h7X(06=*NEb|6OZump%A?-#q#6``H`n4y%RC^vUfz+Dvk~m;@S5 zzI63b479lu8{LyCpea9ZDo}Oy< z$C0!|5wJiVv}apA-u4`HnC61Vg9zpa{afo7uPiz3JJsuIPMneV|BchmNnB6cywmse z>C>lk_phD%ZAJCmo4-&Zjq?vw9rz^y}Gj`$zix_UC%O z+*l+ytBX5J>^VY5|p&Pkj&ll!>mXna^II%)PL{xOqk{v5< zpINQ$@3Q!!lA4*A)mpyDn=@C4bI!6_T~Tdr)4O}$y`E+FmzQ3%wA4d12OZvvfEto} z*2Rc|1;03g>xR(u^yfR?%4a?YC!xo+dp2D7+rJ?F{63M{X8G37GE0x`aCJSJ_gTuQ zLgAadN9pS9-1HL*8rRBZZM4(h&#->qzrIggyqpJHJ|-K~-HDh}b&BW9`{@r}6*qEh zn*Q|LZux?%h0O#8w|=mgLm7JR{l_~50eo*Mj#mRekPPe}E z{(sC5o(naJCFBS;_CXnAB0REb)L%K`%P$D-px0O`ew*$7afWjOFwH}gGI#! zVb({sWrbi-s4yJwitgn8$R+;lAy9?sVvC z|BUSpIg=TFty%Leb%Fi0e{bg%h?h_3FTAs-)cRPj?Ake&symaJURWo`tiIZod%Ha8 z%ZiDoV%m9S-%Ol#W`|+M1BU)vaw{k9x%uFEy!he`D>&?HzuSj@HeBqU)LoE*G+Klu zgDlABW?^ehKJsEEmy>6q+_#+g_F1pAQsdWuKQ>`XXGcfZ@d<*$0l}e-lNRmKWA&D@ zkSM=XY#)*(`l-11!%KI0h1ir?+oN_>Sa{el^;Rcn$>F+P-`GOJ!XBKTYaLU3 zC971zaFgQ33;y;s&sV*FExr9t-S(o#jfdYII3zEgaQ4+y4Sj9VnGdge`1l;U@KD*{ z^%rBqga-+vESQ z&;FfZcI%aX^X~b-u5(9h%zAr~r}oY-ogaw{wHy8|c^NDyDA(3>Xp!0T#lrnke{Uy$ zJ}Muwc|+}S`5XH_^G~!~dTy}r(NDXGID41>|@rmx97O0g_%8ioHX^7Mp{JXnZvnU zUo0C>Se&2Vaq)S*U~v~S*c_9y_~Yxg^ zHLf4HIsthsOymU{sAI(@-WUvZVTIO*GxqZCNltr~pS4~)m*>Is;+Yn?Vaw+(HfHP|*_N(6x9&`kqxgvZ1#F?U8g5`nsf~zkBwT#X`Pm>eiXm5T#SBbAZ zmgVeoEygd34=0{`rB~hW?GbWrYwBgS?GJt)6P|E?_MdOBo#vEW@{!oHcVW=V2e~Fn znwbhrOw6&qlY`w3-?w+Td4G3#dH3U=zkX>(UT=1GN?f(dB`!{H)8;%}s*h z;_VkU6r6a!xa-sBjrsTGPN=hO4{=lJ7b<4G#JB8F$|@(13<)-V$*uCe& zlT*{p_$6!Wi3t6?7!L04hWY#DwY0U4%=)f%^G&qujl;}EYbOR?G?3uYIB{C|UVowE%);z z)&G53|M=eT=gOedQ`C1(G%8|=t9@yydSTzXb$&mS7eqI^S%2bRo4^0N;J<%Al)c^_ ze$>e(skHmwq4<E2Uj1J7j zC~YW*^Fj}VMRtFy`nxgps-XXht1qUQtv%8xzwy7JsYOXpy#0N%_M5vZg`b>`T$G%2 zwA}r>Rr%EK#^>#>Z~cE{G5^8^3ir3_H@{1dui#vE-a^vqqsoJ0s@^QC>%X0B_wcvA zvE$ZOSrMV0&FAO!a!y|Ez&6EPPc$|4$EW)FNvEIn_O71#Hu~KT?;8Cj2fNSz=U({m z;f^Ppv=<8A&$T?wDA@7uQ1ST=!^Yxs`vo@pSqpm|`MZ!!Y+~>Ksnh>A*H)KV@2>dr z&Z1;-iyP0Ix5+Jk;#MtvRABMpm-bqF-ReU}PFg&E^I72Dlat5!b~9UV%RkEge&5Yk zH+1Koj}%vD`m=uDH@71lvjwHZXYUAnbbWsPA$|M*9IJoq>qgmw+5Z3iOfguPl~gzG zxA|l7th*t7CgZ<~X}Pz{AFZt4TVS)i;L7v5|A+kzlYfPrnPurLnfz)>=Z#;#xpbm8 zO08tSoM3i6*&(RDN67J|p<%o6`qO9Lpa1)OYS{VPl8^U&c$97Nb;{%q|KHqYuMrKs zb^K#})k1bBCr^bh_p0-mn6wmpMMPtcwrP}wf4>@gebcnNS4+bST?Kb%i@UnAGBRdf zvSx8oP~KRpUn)@oqhYd?1lB)!}R_- zcGpENv#tKFsc;}(cb56olXm&1?wzRpwOzF2{~hD{ZRcg}k8JTT`up*q`}|jp)$fC@ zYK1;|{CKhD=J;z?+QNS~J=K2u;Ez<8+tf5)>FggD4wmgsUJ>bE@{Q5s}?28wle;uS2{BzgU)gfD> zOilA{oslb6v5WhyRD3UBj(NtPuGPn~PHcEswtvaw&Rg4ZH&5ljDMey+6a2E?u7a`53QW zvaEVqt@8REUcbM;4gS)ou{G!FF{yB8-&v;N&-Lz#h{>%x-PRwFb4Ky)&8^JPo%ToMZ0%#w zuP^Rh-Pbq&EA!dJ>Aa`5^9kRudpk`s>)x8oecSekc6NG7nf{X6`{~mCE89x7ckfJY zFEg6o0Rvy!`gpO|1`~7iRY?$MwU5Da&q&+4iuGceRbnF7u)ttQV?o(6v#%=l4vQ z?0R>OHPee?{jKin?WF8Jaakw)UTYqA`Bmut$b&a68J|wo3cuD<{VsgRRMFZ`Q&#>u zE!?l6YkJnQ=8zJwA5+y z&CC1t>KorkIV@ju)1X(@-ZR{Pk6UBdgn#_p`!1%>uX!@Z+QcN}yWNKsT9Gq^F zTEXyZ#fraCdyAItDtW)|-e0zegFkxToOvg`cFo6^FJGR^-eJwbxpr}(u-eVDYOnwA z&fmZC$rF|I@84vtUq5?UzM}H z!QO>x(Z|lk?*4i~e*T3euk$V)Y<_-jPn^tWIr~B<;dOgG`E7rtzr8I#wcp}!)!8T4 z@7F9pIKBVcwOs2@TX(O%v9Wmi)Xe0jxT@4`kJhZwWEBnG|6#eSlv$R{!OyIWf$gC4 z-of_&{UEeMbQ z+3pv$Kl|gSPnRYvJpA>BaQ#)``r5F`YW{(%!*bXB;^v=i$j{|7r)2Kl?(=p(16J2X zKjfKbK2>e^uh;*7P7hkc@N+?wX{yos=X&z>U*eVn09I@b&ez8;xGR-`;MXA@MM8R?XMi-~1tWe|=rs^ZBFR!OzPU8%A!dnJM;n z#|1g_sxKAW=lxV$#soV*-C@BW&WMAbmrZE2JKksyxkXarGE?F;{+6QYE121f=Fj_V z@&3o(r5X+U!v7~ekNMwP_9OM>dZYPKrrE0s7q_hnU*A_#Tl?1GOYZG*t+T%#K53n@ zXx{adHx;jQU$?J#U$;W7SNV#9jnCE9;g_$iy`6e(=ERvVW0sv1s^2&B(b*l#=ha^P zcV$K3-E(pIGJLXK7nhxlF11+q;6T;$qZZ&3s&Ns1+$?NiVNbQL&Xt=vQ!=dK3#WF( z&6Z^;7O%ZOC7fQ?`|I@ozk#*C`2)`1`x~Nd5pi&<^Be#Djm>W#{K|h`zf!eZTvPk? znfKA>(t8(%nSth%QzQ51M}7(RD=52H$oaAG)~3R}R^_i3{`z`2c9!pi-6uQVubX2t zbF$;z>*ue><>&bPOYz@b_RN3XluXt5TN`Ukm#Z~09(mDifi z?BAUvS7D&4bLZ;m*!tl68xoawSN>e@J$L5w&)@#1UUcG>usO0X{n`724{yjc@A+%t z&H#(e6%tIAj9=7bZDEJ#pIYM(F(aGp*CDn8&t>Cp@O(=Zd-vtgV_~5byQt7D)|#&> zecOJ&wJy6ke^Knpk}od|*GB9-^-tvMoiq3{+SB-iQ1TI29bE3`R8d&|CA z+up1>cGf!U?E3pJZ%jNqokh{`D)3JVG$-P}x@Xefa0hgA0{~TM%pjo1C;sQ=?t9zc(_1rb(!TnvSo6o2lY?u_a zC1BQwb8ccHrBI!0?ss@9nbgELoX1 z;~Ts7gWva`?_KhNP4L{l%lY#k+LV-fva*XGUAUL~5%4d!5N&|I}>0@cSuOMf}E^ zo0j5_3r}tJp1+T|#u}jf`q4wyG^KXPe z*>!;ocSS`0Bu{VeVAa>99m`~FL>4Q%_lad4UwQ4dwCrR4qesN5Y8L9brNd1CX+saD zMlQt(Q!1QRYI=U+U$I2%YWCDs3{}T@BYwUPvTnGSVw*1@xG>gwoAs=7ziRJr?JT|Et-_G8C@%HU#VfFZQ_Vf97_e6evwr^pwd;gA-)q)|HpYG9_tD>%&`MB-t zt4n)#&oaq;7PE`9&-~zL$(Jvy{?FZMHJ_b-PV-%vIR@VkR_$(B6F=+UmJjT@v71i# z`mcgiBjAX%P<~MPY=Sb>4;tM}&rI8d*Uw$nJ9~S^uy9YUmv=A+vdMhrgHwP@m?}j_wE!>_O2@Z&c=H7y27H3d)6pa z1>05C$L)Ji863a<-p%W|zowM@yewS5)i;0N*K@^jRy)cz+*SX5Me?$m@9f*9udlBy zmbR&1_j~I1L(j_R1_u6q`-+WM`dRKX8H76+X$Rc23;u07eLU;L z)8sFg7pb9Pj zQ(M!cm2=Wkll518d2x01f>+*A+pE56-QH4r+;3Ir>od*lmEx(J&Y5>)q=dh}yZ7|X zIn$}J^%S?s`eYZ*j-<@9CH`Bv45lJp8qH2|65}i z?jMklu$1X{KqtI`7f{H;v0%N$_gQn5z(of^LR>dtQ`d2so-NN;USBZtR_V+2UZJa^ z9iPlAQ`pJblYeW~=BO>N6Te%QnfQI&cv0_q?xjtWtN5kX)*V(mVZR`QdDi8%3%+d4 z4!?Q*_08S=dGibVeG0ZMPxqVAGk^d5Sti-*e#=+-to3K#_J7L<>!nY)a?B5Y^z7{X zCKJ2+>jtBjzjv;&Kh3q_|NGVJPwdg%mHl0A*Rx&Hq9P%eZyt|HKD6ZZm4(6SrEl)I zMuyqDTNWsIb*lT_TCTR>_Vw%6FD^OYHPxi@R7mNoOJ^g)qxi1<+2(Zf=FM%7o%`+9 z-K+h5`?cw7V}5}vYed&PRCddJR?C0O+s|s|ilg@bU&Q>oraSxXSl*Sn?SwZQI>2Q$sv2db>nC%%n=^hWXG%<cB>?V{4Y+lo|EfZ_~G83?MvPS zze;4iuzh3Gle5QJcB{{`Sog{_YYyj?ZP$JuT|WQCZr1qcyWdQT7rV*$@NV_jZA`az zYaN#Qf2sR?*8hDTyWelijsEg&&UMqb&tAT|yng>*OQHD-o=j0`ZD~36yd>ezq@(uP zr>FUz``LT(JNL8fH!YrJANHQ~tAFvpk(K3#_7=a`>Rj$;^-CWruP^A+$Z@U5YNLG{S-+kVd)TMkWGvqtA^-PhE!yWS_Zn&+&re!tUy z<~3;!J~#K(tG1qd<>>gWByFzzp5NR4mTximd|4b`mMoCrobf+0$#%0RL#^em z9@2%bh`2zoG&mdIywS;x+#hpXh;MaXMR4d!xs=qu-!|&cojP-+@Nr=gap9%4ySGP_ zt~>a7S#ZdcFw^X-p(`~zyR0Qr`?XKm`!IaHo&Ptyy6pWX9o7+ z+v|_!i)HC2}I);@S}`pw3$o*h!rl4oQYzocDw6&e;+rmg(HV`BKK zyuZJ=R)q#To;vALZ($ZT|L^<5OwZ$g9A=W;+;sf7|EwJL#qK6~IqMZIEnVkFCtq6| z9s7#u#aX8EcQ@88|Np68%D!-ul9cI2o9r8}&2w)?UYpIC#FzPf-P~_-Md@G6->S{{ zcXRpt3%%yP;j7JZMPsaw{F|}u>}<1FwXYYpD?00&FK^X*nVI?Py0?DDml+?wIdeXX zo1IVvDiBkfzT5wMVLQ{DI{*=&S{n|$6ql>yk*QkxcYn~foV#(2rZ=qMc?6tM8mt>H zY*~qDhJaz@5DUOH%hX<3mr+lBEJhk;ND@)kK>D#AI@{_Y)uXF$2y?tR}KX_ih z_xs22d(l7cr!QZwycHJqW5F!b(iZ_+`qX4B-+Nb7RA{{@5&Nv{E_COeuEq(jdFw+@ zbE%xaq^SM7@*YD`x%iquV~^5TS1wOvdA+dtu;HmqOczgkajpsR{JNIs)617HyZX9< z+}wUu>fXJ5-2LH0-Z$GtWwva(I-6apYt@fmKQ%3OY@1taXQ$`)F)ZzO@HJ;X5lCev z!<72)erVs;PrVFGuG$w?r50B^8C?)xtGyXAG(fOC77bER{h6}x+uWIzbqBAt&bs3J z{7sIw^{<7^-;Vo=Z@;Sc!%9){UheM22U)Jq_D}5Qe5UW?P@ni*|J*;d#lQPeINHv5Wi_PhydN){5qXZl;L=n#g6dL}?IG8}%rUX5N z-h7|J&&c%R^zqshada8P7#v>KsQshiKbrnVZvK16;`h`~3X}48a(bO{;K0FKo2#dX{oS_6W!j6EFE#D$|1+(hI&os&-RozVZtJBk-M)Q$ zO-;?zS}pI)m6@$kUi%rFMP+2x%&+_7=-#g)lBF{j(H%TB&B2f1@5_=eso5{rh{2mS z@FpZurHK$*u!Ykk=aQRmRN1EKQ!760nD+lqWoGoEce{Q&x|-xIxvCwWb*}z@@T+Un z%N?)#?F($s5r*clbAf5dnE+1sEe&%eHEfBEqEJdJ{TZ`S0lN+h3nDd|dM30Hf{CBa5HgMsF6=HGO$Yv+TcC=&Dz1EjOR9 z){#Z>&Af)?d!Jl>`Qr4wPmzX1)6$ zU&>wI-F>?!uc3ayp+kq)tofm9QgA`QH1pP(Q?LFv{QLQ6vzNbr`8RECcFvE5RbLKP zi-v4o_U)bJ=JT62)m=lXqb(SjUT{Bmg^!vcA{HyFk%{G1i|IC|3C>d|&RjQRg)LWi zMxcZKDm|A6S61e{y|wYLQ=8by8CRa9sH&=2JvTc3@nieeyth)a9k z<7RiQGE)C)w!Z0hGuT-GESfqxK3kizwT-pC3k?l#ZA_lMY4c|8J5g^Z2(-3b2@DEa z^zF?(RegPb)BKxJywYYtUS3^hk&RCa+mq)e*Vfiv-QgMB+U~AlYU{eY{9VYGMrNaf zpDMeP--T%Z{&Q|K%O!V{tTh*`N}s-ezy5}E`xg7G`9l8l&REAzoTneZ%|+QgcIkqs zt#AH{h&a4|`Eq5OV6TXb%p$GO)h~{Gd_3)GnXGlylR4Rj$-UVX&1|2xek(m;)YWH~ zFjH-QagL*G)YiQ0yVClpscBiDzL8$;t+EO2?OW>Omv}4eJ#1(Aafz{YZA1mLX@*4N z|JWOQvzI3&^I1NB2oF++1z)%Y9O8ey7u0q^2;yUTZFMl#uDEyny1#qB%(cc^Ytf5q za#zN^zbO{JIBkMkuhimqd#g^fZa0c_sxIj3dpao-}7OO(4)sOuPl+0>|CaG|4-@9%}xo0WqCp+{nC&H zX$7)ZSKdEyZqB~1-=AL7@}GKX>b&Ymwc_8lo8^Me+tt2(@KZxu`sb&m-doDP=3A9L z=~#7jMIw92_PpEY{-%UUeSW?C?xG79tfIE3ZQYi0XTh5_IhDVEWW3qYxhiVwtar5! z`d5Xm-DQ@4YelH`G;K@Eqx06sw)gESymj{7bG-#i-2!~?)?L@JuDHjt)cxJfwWj;m zUI6u+pT1oy7#_29_q(0_|5MJkDvFS zy!_4zMd$YC`|d>cyZ6iHv!9<`{qfoB^;v)4XP>`iU%$9LZ|7gVtr<7HE(QjEtG&Iw zeEr?E%cj=WKU>58rg~Prj42|Fm-;IF-*4xAn=6tZy>M66NvNB6Wp%pw*B94Z-`?ID zxO}h=d3AYC zNYJB=Mtd)JUiS%Hdu!{|S(6r7uHV1RSGvCZ-SO*OxAr9;(=pAx7jsxoe(Bk;gc`@C zj?HaWB?eLdzrSeq^7GoXJ7jCqf%nxf3|p_PTwN_+a?(si!E~nJ* zzsGeV|I(J3zj$Sq9JT-Z!f2m{UrkNT)eVU)wo^HK%BKjtW^4jYN-uxr*i?SM?s8Rt z!tui)+uq-ZG>?w_HG6wb=KB2K+jRRDe*1nv(fR4amx-w}<3TsZpZ@vz#`m??Hir9O znecFW_Ky>*zr4N_zov3>?6GIIl7&Yzc=y&UIm66We1A^t18J5|eJ88)uFae?Wlj40 zDyQFT*|lYsdS92DRra~$Di>c^|Ge5ScbnGB`qm&ia#PG0KWo>$-WkO7!uxh_qAem? z!K~>a3knyvRef9EzuN!3+|O%*QbEzq?L1pvPuGiH$S(KO{_V}(`tkN!*dk6~g$7ga z?Cs$W38~rz|60DiyA$zj``?f5?=z40<$BpvUQ(^Nm!o5=>&w0W|1rJ={QUVD=_}5k zJ9ln-`sB=iZ_WR|=9ylbnJ!E~K}p2=%?z8u`@{N>*5e9PwNzSUu2)As%O6U-}R zbY`CU9WIaidy98xT4leyUBBSfwe{;;epF0anxuL!xZ})4tpR7M_?=6cg>npM_bJMr`-xIYxFPnAh`S3Kiw#6s^#qH1Q zUBv$;e8$%Uj?CHncQU{5E&I3O16$dC(fxXbZ0D`jemwg8UsLVdgl}(d6`p(WbKzn4 ztSeI&^L9KtTkE_!Y+Zp*@Qe4`@7LT_t+?m2q3SAE>6<%8|FxLsM7*$+MD(TunwaD) zuPZg|V>!E11T`l)yc9EteE$4wW$08b)_KJX)eih?&$qigC3E|$>reO3-E1$5H3Bs9 znL<}x3ur!OnV)}WQ{7I{8FNFQZOKO(Re7 zM@hc;JWY4D`Ax;jfw&(Nle%a8k3ly%d4*$Q0>4mgePRjYsf37b*cjj}Y z`oGkRPSy?gSa#0VdD)&^yy@Qax8>VD7YeIKOTIgwGX48@rsuCC8-JI+zBajk>dgBr z%j^F1VEaQGT*`C~s=UC)rVxkw8zS3HerrX-mwkr2F-?`dfzkXTu z7t707R~=EkarlACRtgKa!FFd_HQTE>D&m~zt)35zeR}0>&d39B2@bA94pUXF7 z+1T35{km{rslG_QW%xfEd|0)xx4_KRE+Lf^+ zEce!}vvzjtre&_ojM|+x)vEO6GP}ROR!44r7RL5}{?^>vVzNDb+iE_i|0|C<{_*bl zQ|IjKE~Whbvf1D6(k0by8DH@)vhw8-X|b%L$D0{KSA}SJe;IWW{}?pD-c zXM_uaSPw37?D=tL@~XJKvrZqa|5Lf~*}2~i(q?(vUfAf9L)^BVk{0b^_ zj^IO0D-I{Qd0t$PuC4xFvhzdy{K`Q6|JB>PV}0Hv*6#n1es;%SvA-V|MxHY>zIJBg zi|MK7toX3!+x1L!j8m^HarN8wdG72m?bBR3-%d<@dgsmUiC^!etSH|yca!mk`6my> z#n{c=T^6pZeYo<@!wBo{%EWb-m%nF-O=gX&j*xt?dGjXGt@ZO4EnXy&o+@u&Vi5K5 zV`0@3|9ZVMQ;uG{e*OA+%krMB+fLL@JXc)K-kzL%*L3dIe{*-{XMKNX%=l&5=h)41 z0o~Kqnxwoa_`B(ax~kf|l9`J)P3^5ccK5rc&Ys5D`4x|rC@FuBko=G=l6`k}ZT0sR z{~Hdzy19J)X^Z2YMMay^{y$Hxu1VJxuKg^wR^-}(My9pq&EMYKb+@hhc1?W#U;q31 zGu}%)`ZRaSj1_->e_NUQ`r50j+vh8-eI1)4RyCcwpb47&I1~cXKy!qfxA(OoYA

  1. T0k>m8F_ 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

    KTOB$ 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Í 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 P3=9mOu6{1-oD!M<_n4Ke literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/openstatus-subscribers-webhook.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/openstatus-subscribers-webhook.png new file mode 100644 index 0000000000000000000000000000000000000000..8c5d6c49ab5eb2d70874dbd7f0b5093010898008 GIT binary patch literal 477818 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�{;tKbAcNl44EU6&|E))#2}=fUuHkN5@i%f}v8)*ZXOe#b&>eQC~n z-m0JW&C?XD)ydmF<;3moN{@c^UlA_;Uc&c&&v@Y<806m(8Mr84@u5j{O}=J_Z}ja| z-aFNwpDk&gF7YHRBJF2M$^N*1FBbRTiO%2qboo4p z9Rb3OU)is;G)Yox1Sd$NxV1^F1~a<9`=s-9=jAA^(~&WHyc=x_YhDHgEl+y8h-J;0y25qSLZ_Dmr`yWu zzgSOn6@pahp(F-}egT8CHQL$PZGvAn$IpK(rX!laTYRtkt>VeYXLH!i`L(0T&X%XY zIIyp^t@xtN)2gqwGav78GOXMAL%mO5?|AVvvw6RwmP}635ij0r`h?m1wf*{(B`@bK z*nYq6_TF!|vhyx3a-FH2a9{ZUL3a6+W9HEcUu$2l-G1lJ&f?drK3Bir`~35{`S$zW z&2t|fYJKOBZs0nMFr#q@>goHsVt zOG{t8^{VvC-d(oE&-XuTTeBx7r2Xhc`ZCgxBPzT;Wpl4VRgTf^ERJ*c0ca3zEl7IcYJ(Vbo6X#)2u1d#%VptbqAYR-z}S+ zS9IR)_nO}?7WdakN2E>-y`wfe=aJd1jKxdrI`--Bd?M7&FsH2O03-X3sbNu?o!e)I z$Jbtst^4`3uCP;e+J~26F@>((de(ox@BjaH-Hu0G@#;eB_W%2pxBKlj?UT(3|K?S{ zD>P0&_oZ~>iKWxyZe1^5y>{ED+o=y9PH|-Uez$yn^`lPpKii`29Jl*sxcyev>YcjV zZXDv3x4YAnJ?mc4Y2CbEUtZdspP=Y`XW#F4ufrk|TbK0Q+?>8!GkDpLs@sn4Pgbp7 z_sZ;cj`8+~ZPIF)rbMSa@7Vq6{xLT`qj1L2l%s7c zKR-XYGhwHhdGWnBe_TqBD9o#WKDS&Z>Em&^>NBymU$1sn%zGqoMp?<-q+jCSqHevS z%gcPdS)OiTbop?^{_B-sPhNq8%Bz;=*zAw5e!F$&RM^YQJPo(a_RIt_y7MZ zH%~s+;}>6<;BesU_4xOdhy1a2ez2A|SOqWCviMBDca3N9>-gUf_UD~^I_>Mcr)Q^I zJAJ+}zvhd1(D7jZl=l&DGWWgcwEL)kKd7UV$*OvBKkK)B4GVg9c+6Mi+WP5n$eM)$ zBJ3h!i#>(T)Z`S#MW33lSJvFdSG4}j+~;;rubuD@OFzRdU-LkqZ2g{3r|wPu{pqy+ z`+4>MD)px=_i*{_+|E~8{On9&_WHfsexFIVdwf&Lz}&E2cYNm5+DmVQ;U;pp%bo-B;{yQ!%c2_Tan)dAc{P#ycb6nVHdM)Cx z?+k;5Pr5lO3if|ICN0cp#q@jYwW!n81@1EcA2jn<8e9F)q7s8S}o&a zU~_Ks-ZkxwY#g5i&pmGZzv;AIvAbO5693>JhjWLV`E8$A3iPJ`+xzX-Y2(dLK0iDA zIqs{k%>S4E^|!89Us&MyF8=?o>D6B@y8lgRP@i9OX=DGfUg`8mQ!EuKwi4@w8q?Ve z_V;{eFT>XPbYRgEc(9jYznSpzaF6@B7vI-f+~3L*yC}d;sB-eYQe3xh`r}KFDpS5j=rr`7{>m6wsoU|scHW_?#X4#?{arqZ2t2_eCFQ

    6P(J5_Lv%}v! z^_0l`ybli!+Rg1f_o30U-e=3dTiNS>icHyhzwY-=)oB~H38c@lD$RQIQ7-U*BfDHg zkkW0(y_)?8899Cno=Wa`BDg8}O6L9A@1TP8^XWe~OD_A~of;lDvtrwE=~~lA^_T9J z-Ok-7bLwvG_q)PjERWv)zvQj&+w$A`-Hyf5mPJea&&$6$^FF`+_iXWthxyn4ePce8 zvU<|tG3SEcPp@}%&6{~|)AacItGYYiT&nw8sJlkb%yr4R{Shp4&xjv7A#wcHmE|RC zFSg8Iny-82rqRzs2Jenu*s_nGyTx>i zuE&*bj9rK0UPx81f&UfMhVe!qWT@c@7CwodUHo2T2iZ{Iz){GMgc zx6fCy=aydcJaksrj`9EB_w|!MJe?N3&c()`<#*MU6@htMuZDeos(fgD%I37QpKklz zHP|-uAp63HAMfvZ^?0Ja$oXiiYdb$4lm6{mp>S$Cg~L@P`i$=z@3CCCyL;7}OZQ_f z?(-I&cAI$ORB~XEMfext{s`MoLh`P^EL;BD@jso^9}{6CKfR^H?vtB;j7WgSLI204 zNA5j)EF&hge6fo5{)nVKeMbXl>ay~GFSPnM>u6@q$z@^lD=g#QOUv)gy~sOv-JVaU z=AMd9Y!#ifVWD$-RbrJ;zzoClZ*}(l`}O)|#`}|UivJ$>+rJZ71+Kr(n&1EOQeb2L zj)!e?Kc%qVDLBlVcdSR!j_csxBb~x`gS>UGYHBil*ST0T(l3MeU|x{l}YLGy-lv(Q`T8d+c^8m+#MD3EGM6FH~MuWcu)A! z-Ag@kt;|Jk*(yLj4WlOvx*Tfd6T-g?eLM^E*4e$2J@ zwcMK*@0O6_dboCl>hzdPX~lbwD6cU;EgkZ4=lR-mXXn}8-uv;GbZ3Q}{>Nu??|pji zo4@~WnR)K5Eh<%SZfxY!|8!MC?ooWzOV#hMRxR^M%UJ?8S-eZOAa`~0U%d)yDW(%Kp=I{*Un&m9=nZqM6(ugg3(YJ7`|Cf?zW-&` z>*PMmV+*C%9nIVQ)~x*5%=D_c-!qrbefCQ9;q^`DsxDRWf7xrvwLi5$=U)GuUiS@; zeI4TDx}Q!wl`NK2^tIyVo{Psjecs7EH{`6#R++zDVEy9dZ!%ofj_FT%a$Rt`z?*RacwH2a5Fo9nRM=!iMv0a zvz{E9v*+V6J(2tBf-7gH&#%3n8|BB~=nEe$ycUXll&%qMr7t}d#7#lfNtceob+xh%ta;m|7pESN>)v*rt87C$* za36Xfu|V$p)T;UFiQbC$Sl%ts7riw5&ODKg759#O@!9Lj^jU2Ewf@h?EEh@0r#_?P_=Jezj`#9McGwck= IyTN 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�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�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

    jOfD4` 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 z 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ඃGz@?cR&U~`{zA!xb>O!3hUfL%!!qQIWy|Ib&=qRjzq~BAu zJ?Gx?jy30lV#_+N)}_VWnq61om}EU?)^q8}b6h8hPPfXr__E)}=;FZw|JPL(@n7|e zAKy#iDcSp^H{-1L*Sp3$k8Q3=h(EYmRQ!9Qh4%G3PFbq6o(Gu9nP{!|U%pxG`EMaF zvG)nB-RZgY9E_}`4nZ>}^q-6~bz^W8{Z;GdJlrtAN%-Rt$^ z|5Wh2%=!JK+-=3B(=HdUk=L8^XcmUM&eyf4|B?tFA`x%-8*cg33~ z+z{PA|M%8=#?RY-UF>$Qm8^@a4}H7z4)^^;ix8iGTXbxLoTn9B;Z%7q`f~BFQ(T#a z_azU+%|D*Gt7OKN^b6`=zC2fcG0nd-=VD0qzD-N`ZY;VVCU(cC=jdnC6CPpD?(Ilk zH)Z9{WB2+4QaGk?@qhkeloEU-_rmk@zE7rRm7cj+eD&sc*PmKPyZ8Jqbzk%R#cswO zBI&n(C(WI{H^4(Q;@a(Rli%xTe--Kcyu7^i`tz+_jwaU^c1-b}-(A$@v`~-3O+iyz z;d;ZyV{@> zcl2Euwlr@~_3u~nSSJ0kRhW`pKi&1o@hGp@-+M!zuXWkCOyJJZ(8%P7&9|Mn4U_H{ z@K|;7+IrQ6yQkW(+$S^XPWmf>|L539YPoSJe5&WxK)+N2|IhrV zZ*MtSWO}DKJih;1*?JrK82#vj*WaDCHIz+wT(WY4#I8iMC!g0GwvT%MJ8~mq`1#(K zOj19+p161Zh!N%rJNsI$=%Gb%{S@)eb+WQ+?)D_!J~DNIDu;JpNaO)^?~liJ2RbE& zT2-w$y6X3)^=F+JAKPBxUUlKi2BBT0iFH#W{ypSby4rEk!_`ds(-LlNEVp>KcVE;k z%a^Banp|1vA>LV8$shTB{~;C6LYu?>?-+jH=e8-jzANKw!nvq#`8v<@jo91vFTJyW zZ_VD6zt%ZFm;L{KzkcdJ?c@3TUz@L}fBv6WqVngX?KeLL*}DF#s+9RMmpyllvw@Xp zm+-3}poV)$g;beff4gfg@x5y{KDnZ8Z?H}MTyBcrEz4KWvv>Sl zWM5xw=lkpJPt_mh=bZ}|O4Tl9@bHm+#~NW6`qX9dkLVXagY4s%O`p0?WSNCfhy*@Vm>E^mir?2Z@yxgDvRqD=QGX~KHaV)x~js~>|wLW zvxWTWb~hh1N88nWWOR0sYS9(HdRFsrQJv?fIp-!^wtBt)aFLwO%6Xov?T=*!eW`n- zF@^24ta)rw*7<|4mmOXGJk;e1OPF`F#UcBZ`?|#T&v7hRKVwUL+hVT-nX>!y)(cE% z-KG2|VNEEP_?cNh+jcWOwL83dzWAMv&f>Kjwrp&*P0e1>8PD;BCuni`_IL#qmjwrJ zvut`BS(ba%D9Oz5$CG<=0v_4F-My}!<-YIyEAM{lUpsu^wc#u8|Ld#SmKIb!yx`g> zH(k%>eddo~y#t$&tBaUB7*$orSj5i78~R_UuWE z_Y}>)mt9UF||E*GmSg^K=$MFY$sGsoITl<6J@k@eOc+l zE#fW{&oHfh+VgYUrtG~<>dUy&_&V)8&HBaTW{&tneor(rLBjJ%Bx!faXYWi z*YDXU_x)OBrNd;PvR@W~IEPcEhYw-Xm$-D~rG{hYnuW)$6Z+QG5zsjKv+Y0FqI zu69{38|}LFw)yRKZ#b8z=88ARTI3x2pp&`$wh6mwSJSh%)vKys%T6zQ@oN3wh=3&r zb&kp1{UmgyH1Fj8Wjn4syHu(^TXrX3sPU<?PRWr*E>emzw``QGxFSA5|gc+&Odh zz2;hUz4?Owx%qegloZE3|KOcHt@4}=Yf|3T89PLrWluZ}xqI{0%84~R`7*rIn?uib zFs%tmwP^D{yE9FAU0>qcGcWH*_VH-UyIW*1@y|1vV%_3j*H(*PC_cMdTqT5S?uxa{ z%Tje$@`^>p26{IYe}6x#!S=pxj^-3So87INnBE^b;j_x^UH3Mv`*^3I zy=^7;v4g+&hk2G2o%Bjie*f(|n?m^Gxd*h)P4%y__-YsYZ;rvE9Xc1&W=v$!e)7#l z{BwNYx{n_e9`MQ@Fux~#`CwI`J(p!##9xPyuZkaIeqWXPrN463vyy|t&!sBw2OJP@ zd&6ibqIt2r{ZfeD)u=Y3nZZX+I#2ti=QU&6)SC+yTD&*@9nu`b;(XwGS7b zX`GJu;YeNvoxKIMXHWgevuoaQw76U$ZXa6==i^n<1rlDojH`co_bsXRY-^g!tsVQ| z>&D35Nq?P})#~3lFtvTTN>!wY;qK1?;tvXz%PMciR{uz|p5f?ep zM6BQDcO1Ltvdz$fy`N2$$Mnk;USIotjVIE&*P!sq=_@rirSywGr)KTf z=oepI-~2Xw-;}fB&+C7m&#%b*C;jBU!e`d1f6sp0um344FMPxL&n4fU*C)3>{CWGu zer?VAecSpuQ!jN|_pLfq<9hX5y3INn28nE*?~=+dj7~0?v~$m-N|J&_f*M23+W-gvHF?(+Q zjjuv>uh-?DTev@vM`IvTN03 zEYv^WabD+(PrJH?1kb|7e4R`u_uD);?K~&JSj^_t>Ovdin~GkWjC7yRefxoFQG4K= z(?z^1<)`xAe&HDz8~yb47Tr6?*40?&oxR-gNBNLaTmaybKDZ^$~Msn+2P(K z_+jy#?p#l$w=T>79=g#c9BCudc3SCNZg%3#phH=D%eQqbi@EW;@qm`V^}hINJVM`g zrG@xRpUAmYk@5DAd%GRIEtT%AHfP}rDAoMPrYgLE{jaEH)o$zXB};;??``Av`rdJU zR`r@9(Jk+^?yQ{WHZj%DShJ&f*RzUHmyUBCt?`o#v-2+W|4}zvGxw>l@v?5qGp(N| zD$gksF-{ct`#|RIsu^{e%M(|+G(1vEemU`k`)!Hvd)1vkuGWhgzk2X$W?y&8ojvnh zPM+81*z=7eZDsa~C0`n*+x3+)`)*HB<*e*jq7kI5a@?JR|EKP|bk&=_&ceOIn(@~I z{xJUvTl4ADI))8X%fIw*>(7i8ob3B1?s}}|iRJn(KTj`M<9yNVyzJ45pIKGza#n(&eFdpT2^H*IlXA3opr;{9o3a7`FHcV%}#l|*FLTpq>^xUo=Qm1 zQJ&pJS_ikXsbAm8rTbIHEiqE~{lbDxY&AC{inr6m}zS<%t1^uK%AZycX>c166{ zyg9pG23~@v$4P`TbgZQTDvX7$uLt@~#(H;;x;4_PG1!o+BsU z$gN2@?qho*Gdt2x`Q40lIU7VCwr;P^_P-L-{itgrcgKMls~UdKDh^{fyJhy|z1v;V zwc@6!Ui{yDJn->#OWB35f*!37$~&RIZ1FtTQpa`k7*pPhF5b6r-J4{kE&E^JJNb9r z?nkjJChbp<`=Pk5DBh#CcmIduceL+631w&V+?&2)YCh|BUA6uhJFlHk>5Msj%U_xKl=Bj+$p2R&JJ~nw64?B$EqB+stn~(}U-x|rI-D>| z>F_VPU1z6jT>mpKsq&<1?@vj;!{U5yFVl}_i7wt=oxT0So)~GlQ)-e7HB&3^*d=sM zY$maXaLN*^OD*KDSu9bd0AY zc_%Au+4HCTlJ1+NJreI$-1?^Yi$Uhqwy(2A4s}MK-J)K1KV6cuyXT{i+386Bz9@6| zg>1T;9CoG6KAr8`9=S8)F~>q5w--IZCXQ0++7ELV1#OXfkRj5#YvK;Qrju{0&oP;` zGCsZ&bNJg~r4wcQx*4xnKQfzs=+5oMi&@|Mzn`A-?*0kY!k6B+v|rTRW-73~wU}Y` z?%edQZ(6~BBZ?k6N2L{KD^H(bW6cI@6nfh>QwL33!Ssh-T7fr!T)UGT*gA(@Ty>og#|^-qK?4 zd?gknO!M3-Q+X_Oe}k&22vgy&Ig<@-TVr?j^4L9Y-M}laEcJ`S{vP8R-g>_)zVlzZ z%)S5T?Bfc~f7VZaDt&!_|Iea5@pGPYfBxb7xx(>x_`Zt2ug!bz|NDG<{r-oG8Ry*b zsd)KYe2>Su>6@>sEp47JT;V8lUEuOO_QS3Y^Vbj}_IV}Zdw+WB zw|@0VOjR|W`}y1bMn1KBv%eZ|E8AcH-=@C#k9@_%f49xgzvchJFzNTHlaFTCm-Osh z&bRDJ{v3BlnauL_Cbid(C4AiBbm@a@)#d85e`Y`Xsbmws=zIO01OE>=>YqwJyQAz6 zzoNyzwy(=QJ;AFnmvv)L?o?P5`Q z$w>*1Pb(kWet5K3;@#w!f6k0zS2oUjpS#3>S0v@KS?iSDinHWBdwKFCc-)rE<(_yV z^=I~ykO^sr}dsi=%J;3(htOarB$cA>#tZ) zJEcN^XXC0Bmf`Pn_uSwA)o0i0{Y6{354}vCcljHW{*6O=Cx4v&H`_${^wYY49g_R2 zUh1T;d(&~sriz#Upp=$ywMW9_Ee}3etv{W)_U;zn4R02AoRpV;{^0(!S(4W4?b;RA zSt?1zuL-)Y7&>7^R-1x@)MSU}2M%xj`0wq{nRnBzR3ARs=d|1>yXKLAR?4Hh{$JD| zzg&4^Mr?pdZ|{yDWq!48hD}>vGS8U0NM7MXe&e*@IX`8l8~LSoov!2B)~&_t6)3kd zWQFt*!_gMub&(>A1`}|)t6kzYW|lvQL5RkZq@CHLS~Ow={$41ShKD%%OfH2 z?Iqp$K8};FZ#8I$|FWdaOY2Y2{zs)=sox)~D{!T(uZ;Q7o_O|RhW}57*5$to51;-p z>!(zh;N*#xpFeN-y*OdMTVI4I_wOe&vgPNv-+w-h_wTo+FJC?G9~1p>w8D^OWnrb_ zRsKJBmj5~)ZMidi&Ykb`MFo|j+iE)w-syF%F0GZ=&oHTAR&~Ou?XgOAX-gkB7@`6_qwnNz`o z^7;Hy*pn?A3B~{l~m>%AI$6yc*{* zuit#f-&j-WUEj>4({~?){yB2$tW9roK*0Hw$`!wh^Ad$5zJ0sS@7q__KZUg|VP?_B z;MsDojvL+)Yj3>ZY`ciRlzls!qtUD>cKcM;De&8T-sQ%A?9R>X^~!smJn1>@RVhFOV1eWa}+IW$gQm2w?Mzm_>c1e$$($`l=T+ua4(+XxmWi~ufEM& zCI9Ihs(TEsed2r|%dcSnJ>li+!Zn7SV(SY}miNt7JGq@d_*hvW*I9SR&+Qv{kClgT zGgj3k#$CSmF!bo^70f1msO-s_4ARTnm#XO$|yu;bt1 z$E`1tZmiJ1*PYnBeNy$)Cg&_xS&8E4vNm&%nB8pevx=V2a{BP@<%bWu(k zH{xs2)Y6bsx&I2zl%09Ubo`IX|y zA-6)d1ZMACv)uXOInOtLdFro5N>1OV^4avYZ*d!c;=FsCbTgk{37N+EG+yV^xxaTl zUGsmIB9`v8PuMzmuBqRB<^R62D@>KGudCg!Df}fJzhK>cyZ_p$dwSMRU;TP%&fbz( z{qwI=-{e;;l+#cBY<}VYC+j$+@}{LH0mUu9gG-ZLS2|FPSLtZo=T`g!)g zO@F*Y|Nn#o^V?TXU(;Lv{q)xhTl<7gs!GlI!d~lGZW6w4ivQaBYr$sod=A8YFu%Ka zvE0_M*H3@$G5J4tfA2i~v&m=o6+f{m`upRo_$$fj8!dPE)oI#SD=V*_)&AUExBm~M zVBfzSbX0P^f4uxPlrkRD5%|A}@596n`3D<5oNnf{&3&jWYB$r+Oju+ZfAXsf%y$o6 zKH{#|Z7J3_-~L$fd@d`U_ET$SXKK~lGYR@U^FmEPO1MM8xf_Dl7b&oN*k&Dx=KHt! zs?C~pT;=(S)2rM5ZK#Qyf3lxxTGf}YuE)I3wm(dsHg)3J*|UP*wZt5*jQPQTfYH6H zJN44bL>1mu$aTnKO8NtdfYxZ0#@&;Drt-1j}KZ<(4nf~iCe;8l-x0T_5Cy^gtEc7DLrNg{CIe6LX8x zE#uv8J^s5Umhbb$-)WJDRG(+wxV@7p-qZchIw$SJQO~)P3@?ZNwEZ#5pdn_%sfmT} z-`{=nJtynpDfO2wGVesb2vr}EeA+K8ep(d`VbK_HvGS z*Z;b^G32yPc)DA~dfogdE3ZfD{|i!TlLdgeRUvu$4bL*YS5`a0?3 z0e&@kQjs&4T4%iW{LC{=Y_8?}-7!AJeO){LeXhGvw|^a<;!+lm2zP z(=$`0%c~ar&kGK?AKzA=8hfco|91G2Nc$bnp6^z(`Pmrz%JTB>C6nviZ*2bY?)L8E zHGIa&VY}z9zn*NVc4zu~jjYa&@8OScHr`ynTXO9WuGwttQy%N>3f?PX#3M`XY{SNkB>U6(dXjb%DcyZ?FGNs9iLXmwIAeryy5(AkwPmj z@0njS=Tx3%GxB^Y^sXw&ruzA=N8vo)jkcCAjH3j*gy*@5>N-{&RiBo&o8|hKf>SXo zv)3M2DE{JO^o#wUU8~mIeE;?Kv!9!6;wSunyZ!&~^Z#Go{`LQ2f9d0>S5JTLaXEkA zWxnb9!2j+|8}%c6zImkdSuWGxmR@58zRx87X5(|#U;8)B=D!ZvEC-sP1-HXNrEq;B z`;QNf`~^P_H1&rZV-~S>JT&Kv!qVq%XYyt;RGv7gZg?~`O~~hyT8;LbnPs`pOiw=C zpUn2eWhMLVJIqnVI|4Y13_NXfrXM(5aA57RAB*DUcl7hfubTeV@<;hsSKk*|1#>?b z+)g;Qd=A1fX$S+yR$XZ*b_3hk; z#)psgvDD32sH`%lCH+U=zO3{=qJHde z8xK>hKli;nxmEY@OPl6}%j@U9b(L#h)qIp`X1wcz3JD4S8+SKe-K-hQ&KWdWv+T~2 z)LDO;|D68H68ZnI>-6OwadB2v{0gD_A9L_q{C#% z?+E*$$oKdEEc*Rc+f8@LPea?1kuYcgq*$ zHD4{AO%3+kI)7*72XU1vwe!<&)1&4o!|Et-) zYKP|*FRLXkb9p=WK4`zCvN8O}!nlO>yl*QNTYk3wX5PF_G+U+jn3lxh)xQ(cbrPdb zm#KYx*89^TMOj(^q_&Z))=NS%jCjZix$bnXZFZ<^e^WCl4!@)(Lz#CHp(l|Bbe+ z&g_d_=ZdBpw~6lXY~9rB`LkK3pJ%IC?_|F8pS;I@{=aQ4e(YLcY_H$#+W-Ig?KWFa z=hqQn+W#qQ(z-dB42ql^75s9te}}Ycy=>WPee-#ha7FXRcgNQ6U;p{T$;N-d`+xtF zmc8Q<^jP=bw!Y?Ng(*)SY&+vVf8MF^$y1geu#w>V_~hS$DSKQxYo8UZS-9EcYh3fm zth=*sx`v)ah?8>PxOJt@O7T^E$>~*j^M}14fHQ)NOxW&8Xg{>>AGI`M_FqFP zRZlH{lI=a`{M#kpKTds874mDj-SOP*tJgh#biH2lZs5+(FYD*8{Is(tz4OaWr@C30 zX%ny9(!ScBoHI$}=(255lV3g9ez*b^dSWx~$(u<`vBhED8nbOez=dOB%dWWMJfQU|=Bpv6)WsT5yT zWFCB~b#_uEUH>T%zHsjIDCbT9n=tKPPKspq}2 zSFitWl&$*u=)ni-Z%cM_M76ILow;?Y&OCSi&4T@>*L^8p`tzd2XM=g(vfIPLVrRB_ zOxqRv#ZUM3np!`F{)L(DYNco6FDk5y-_rGKXyU%2<(J&Q}Zd{U>>KHvMb zOZK{y(ch$|3#v+Xray4GbZW}mLyNO zwd$-|$^*3&7JDHMhesEE4Ub^dLv%IyoTVJ-^ z-gSHLTxIUP9Km<4njMNbqcnL@{+jCh+Z0#%U(c=Svd?_dJ2UdvlVdf?>yJ$>*|YiR zk)3Z>$C-aOaa_C9Yy0!Nd%UmOv0q&ze|Wpt?ZDugIafmW{#>(f>8)k<*QJ(3URaX5 z%Ga#>;f^&wGxu#@GyC7HYYPNfuJxGLY_=C~dAYWCv-eH$JnkqBm#4a7l`tVx9 z_sZlGeTz?S`ZN9NmgPa`gVwvBdZpC=m~FFdgy^bNeal->eGTqcSI5oF<2-YHwbQC2 zH)`i!eVd#nzen@fk|~@^&%H9{T%uilvZ%i5^wO6%6}~Z_yw!fnCg|##wIM6dkx&h<$maYFd1DmQ{qQ{@e1$m)6^TUa%`}-D<8~v6Dr1eY>(^#=8<- zufrW@fADQJUi?$_-Ol-+CN1m}>;1FICv%%;cF3F{jg6vD|GaB16>GNOz3nzFY1U1n zWlwhAl8sl15n1w2Wxe7eje^NJSIw@Q^`=PVMyH2MUy+%|N~-pLxpj6~(%eV09`D={ zY`T4!ozMQrvVYOvmCEYwX3X`yE+JF0ci+YK?a9~qjP4!H+PmBAG25xdI{ChPjK96o zD7iDM;o8}F{@`fO%T={YQhxji`P~0h^Gg*|ZPlw9zZw3XU+OPkKJ!1+Xzx6``6c#2 zkM;w`Tfqu?cd9}oKyYw_A5v5bk0rMyv$3pJb8(! z_uKbh_+`8f{jUEhZ~bKXx!0MWrs=F#`T2jT>1qGD`d{aG=+B(zroUJ9;lJpzO!*i7 z{`05TADwvH+qQkmt33(~j2wSh7=>QcH(4b+K?^-l`S;)^#}jVhw@jt`R!mtJdgZj} zE`!kIYe#!;d5D@ut)KOC-pcTge=n82ntSWgi#y)i^jG9ax3}wGZ=Q9pro=R? zdnMxJlY1a0`|Qya0gLdJ`V5o5-P&-pV0ZcP8@;yc&+W}WyYRbl247R$|B^j_+2-W* zzh!K{_h7xtbB!gdvbT2kWIibqESVYnV@=Dvs=&x25{Fna?Uy{kaue3w`XfOINMkcs2d-w3}axH|z^CtKVBQ zGw^zD@3Zv}BA=`@;Qe{&5=)Ket(?t$+fN+3*KBfYwNB}q>%G0plH(OzwfF9RJU=D3 zG+6s)YVgXZ7D3*>6)kltExW%>IvLn?MSp&ks_oA$hM`lJ|I*uES^t!=DE?*W)}9-; z(=K=4-}Ij8WlR6W_};*fOEK2_694AxlPZweRk?~W^=b{Q@aspS9^G_s zwX2N(YIxCBg^O=`XwEW5r{()Dg_li^FgM@2Y;T10-o9_s?wXwGUb5|)k66(*ojE^s zcb!&vR$`VWdp>kd+)6XYeTLI!J5D=OeE-hb8ri=!!4J+Qe-iz^sCZ9M?zdvruhLyB z3~!_zRCs%)r&KWSby?e1!RHm{+?U^Fe;je`VA0WM@>jYi#rNOKx%KK;yvdpROf}x+ zPgX_7d@l~#wz=)4L-&Q-`7a~m<-0wjEq|PDQj?Y3YFGI(`sjN3&9!o0BKflKZk$&+ z>&N`nTRG>hyL;#1OO7)M9VspOtJaF-Na`Kmx2Ijq{a$=npm~sD3~Mx1xHSZt^EQoJ`Nx}wCY`?TaLtGP$rmrs^@D?dxuuPvY1zO3(nNc*NA zdB2*QSacWMv6Xq;RCzySb?$;oS#S5G+{}LUl6P{6K+4&hw+qj9mKuD!{~&UAbVFrG zp4&;6<0n&PLbdj9v;Qn{>16H7N&kcYCr$6(^8T!^UTQ#GseWkS+8L)F7HyDWxfmLp zvDGzQV9o7g^R7)3o?SWl+O4p1*7&Wvy`En4ESJjctufi#Z#Uyo(XFkk=6yP~=-Qb> zuZnN-r%FBCkVr&({mE|KiBSs}}0`^p`PF;{=STU;iqzH0jiLq7A0 zvrS66R~;7@3ss-~GkZ(TJ#j5hnQ7YfY*y_H4WDZ+HFGn#nZp+rd11-lui>5TYx9=2Y55!LNB>k-4Sdb{MZSKjO8mc~ zPkSc4DBTmTwAahF(JnXdZ`8$z$~_^c)^9sG|Iae^i_5p=Y>B?~v;R%^zGL2Bb;{=p zg@<0hy8g-HnzU}?z4a-MoyO-E^vx{)@NB}Y`Eg4%z9uF7^YYgF9I-NJUHkLZeM^n^ zs)xLtdUwfoo#> z%kf#a&aRF?*Ifaj(%wtIra5MP6WTg!;&*x5-naKI->6@BWM}EsqcbP(c-5*bYvA47 zQs`v-c*{uMoL&sFXUw3{v1>>+Nw*7Wx8xx4>F zdTzK@F>|rhKZO;xtEY1Ngw_5Ha5ryV7szCE@r3o)^kaG-@)+MN-m;D1Twc^#W&djT zg)jSUpQ}9o)1tY2;iA1;)sKH(u={;>wOZwpi=DVe^=VJGiP%x7HmQ8JgL&GL zCGVGnT-+g)vUjNlSL&b0n9~tuhWnsTaC!OzZwF3n{+(tNYEY zjb~PWp4eZ%?(KDD-@F+A&wwmm@ z@6NP&f92$yrQF^yXZ=3z)7)tK*Zq8mXwO&w@A08A>qCAoNxHp0>v%-*?u^RatL}$> z+w^4FQw9bb8&4O<5Yw(I>C)RtySGc)b6y zjb|=we6e8pd*SGwC688JO>nuhW!tY+&3nCyw=cJRt8e(l@7Ru6E8lBt{Fx`+uYb2N z`mluk+mlap#AnW_`>o2lKm7LwF9G97?);$Fyjj^ZJ;d)P*-oDMc+#D~C^OO5r&B*g zAJ=GFSG|5>?(`eqO1gg=L~)#YJm(j8^3)gNtDi*OYd*bFn)A1ZkAX+{Tm82$+)niR z1wEeiSMJrdsI=25p(VASCf${~xZ|8yt;FtpwWVqqTaTKpX|1f;SJbhGzi|2P@V+_8 z@BMcF-qU-0{twyfYoq!uU)$UhJn8tI8FinRZ=6;3sibJ$C#xAb7B^oMG5&h>;BL8{ zZ|$7xes|6}{C7ARxAxkbxvv&o`*kL7^_g1-Ju||JxtGeRPg-y^tGE9;8l@M79Ik46w#xf?dg$|IveS8Y zZ2K=dt8e*6pl~nCIISQ#(x;%~x8G zyuHr&mSN1&Ny|znE&Bic(EIoQ|NXoYeB!e3i~W~_AOEjgrha@m%WHqtHh!!{&>#kzZ!gL`@iphr_Q(gzf`5_Z>{!6JJn~;U4A`@zi+T| zuD#*csNex1y2=v)6SrQ&aL`~Il;Pc^@M&HSVp7}xp1Yes*)=}fz|i@$uHKhI_T z*0_IPzWltgZD%A8*O^z>w!8Q-GIBUP$Yb$XuwOb##u>TPu;hHP=D}A*pGp$X zoYkwhY(`oASJ&&Cuf<=@h<$p@R`=Y|!VZ0te4AZ*UtFd;3N+lco+oj(%=(DbtlQh{ zFI%@*=sE0Zvxr`zTCrd1*BOzG7Bpb{HEaVndeTKY|h$m!o4GAiR}}Iw139W{hlS4J!%i19yz6O`pI&muQ`q< z?>4)B3%{;(GrX7OVp)9HtiG8gHOE$ntZvRJ{Tf~N{F!NV|E0G{+XLs$?F^Bdwcgw! zp#So_8?g!Y(WeWo3a>CTt4_75ua)xKArW$3VtL{9E7>-li4uo>GuNKqyw2*cQLi2-X@-eF}zTIx!^C_#zR;8~0>CV&}(`)9t7*#8~ z|GmBa^ghYQGi0;3yKVn_{o6eIeJ^$&ik|-Q%(8DGOF#X7ajkmmxuTU<{I3dh^o567 zw_m?ir<8tv{VShv?aC_#+os(9v3l9k#YSh`?rvN^f8yuIxsz_3H;^+>TWINSAN=-N zC_`U#I_I5l%b#a%607}aai;XamEJpNrr#3s%3AwFda+E6jg!HdB!M?B7xQO0T9)y@ zW51yOty*I3+SK|#A7@(~yByPUBFNZd)~c*T`!91RhZThN+b^?vm=OCur0?>V>{Mgk z4L)yXs=IHSwzjM;^32v#Hm@Wey!&|F=hZ*&CaY$V%|~Az*ZR83wCwMM6#YeCcgBc) zFqn5Rrug}Hhf6z4ZL$x`O>V#0^2|{F{L-iUwRJb`a*?Z>m7V!&dtr6!(=6G`v$oIC zx)U4me4E*%`Nfww&mLSgJ1}oYvh&+DQxD$bPRoAydu6=8L(l6%o1LF?S8G@Pdi~ma z@6P=;opH}CRULolS8?sFdBOQbUjF|xebud}|4+L4Y2gLG3I2cm{pW=nef$3Z@6YG` zlQ!-D_viE1@1N(t*H^tzKXv)_IjQGg4m85D)bf`Kr}6GyBuexkAss^2>NF+C5KhearVxUw%wd zh!=Vs`knJjl~QdT*WQ1EEx*2q{F;(6e}2^Z<>#||gJ#aRTfcR)z3YZ6#TI)&_5BY; zCY1~S1uEKF8CXDlBk(xT0e_(jM<+gwI``1vmg~$kN#XsMw)Ra8-y9iuLvX#-y^Y*= z5Bg@XJ!Lmx-XPz<+|P1Nct+UPt)~noI&Mg-G_UMa_;62dP5;gruadGiXU*rFtUK55 zc-5{=<#TtjIWGU#*SkrsFs=8n;k}FZZdG$9RBhLaz7t+)^Dynssf#ymwYpx+@AT>_ z{!*w{C9N3!)?)R1(eI4EILyw*ckW!dZJyz~C9|(i_WQLyV%4f`QG4Is@SC(INbgQH zldH_zy~oP-&cFAx&ZO((Y4hr7iN4!pkEZTb{r0aS+-7Ozj+HxJr829oo;UfsdT*E5>1DdnM(+!dZEyH(35(fnjogIDTZi&g&V;s{F~XcmAusvOcx2NGB&blwEK4>luZex=j{|(!TPy z@`C5_?Y?~X=8az^hlG36_OEf*DzaM6eJHd!J^HYc+_&n8{!;scYfagk9TR3}Ltdvd)!aHy%7# z^5D;(&kP53Ow5y4>`G3({m$ZuuYHM}@`A@d-k2{+xfVXp;r-v2+ZPLMR`ve+W&iml z^ZzbcyLNrc)9i&3nZ8^3r`(zQ>i^PDzt4wzE%E2PuW9-JwRfu5y#KQ&JrB11y@}=5 zQXl6hg-@^eHR+0@1Lfb&OWPnWk|hK()wSqvsl+17FiRs zt7~n|vj3_xg`Pci=KM1A?W7NRCqLiMT=;LhP3XUP)#JNas=Vj@zrTN)%lhS4ZVSKg z{mDb@~r)|FL#UfhK4a)~1Vr^Gm&_JfNV53d4A0fj z53b!H&vNk*>#giPu`j+c#=2bo`})fJP}%K|H-C8lSmH5{OHX?Kv?*+k1~xZJ7|+fYe0@IcY+~omuhS&D?;EwLd_43gZg<7cncpRDOSsNio4MuZ ztdzZ1q*h$7|2OA;Na@;AbMNzYXUuQM>P}1C)x6;4y-nM4qU@vo-JSX*blL;6x_KL! zCWgK4J$pCcvqI^Tl~pnQH|9yL`s-(Qw~5$yUrP+MeeiuQZ)U3WEfw#ZGg|xRK3jEIcDMGf*WU|2 zO}w_!<-xplGg-v0P7FM@R4$TdlH&%WAdVxm+>gb4tXR5(<=t`p=O63Ve`EM-U!!^7 z%B)-DR3KmMmD_Gx&BL>_t1Z6Yef0ba>jSAgJ-@1lN38gF^X}*H+&TZ{tgVl7XZ_M( zG0$$B{pnd@aPA9}s$`z&m2=j<&#C|A?7(uN|IYR{P8CP_-~0YuaTj^F>t<+&-2Ekc z&sd8VGi_Tu?d7wy%ORWN*Q>lRbI#)9dVXQ+MUxph)+a5~%`fe%WNAL^SdjYUWc<(k z%k{nTMx6(D8 z{r@&!+rH_SQqaShtMoUY^xB!YHB2qDHf8&M%sr_k>;+f2#3X z6fgAn|KIpZroa2WFYTH1daB3#|7+$=diM3o&p*@uJXwBTKXu*nuRe?QKSpM53<3@I zRj4ouy^!~uy%Ap3f%?BbEG3CbF%rA{E8a5o{`o(BK37f3l6&tuj^>v9DxCh>e0yQ7 zuzqb#^Xa+o9PK&WJ{LUIH(C8N!GdE|R=DMgYd39T7yBmNxPNT*N}Y@RP05>gU3fF& zv-lM*`3r*mx(DvvaXX!~F>U{{{pRN;e`lZ9-ybG^_V$X+(oen`Pn)K;zR%oa+0LDt za&DGh*naVkYgPRAf7dl+_jEJoWnajvnR%bZEHpd&&`*xtg`8&|A9b`}yYTtM%4H{i z-!waB#(IBt%EHVj_tQCY4Zmmf{c_}Ix_i*_;f9hI6VIg1{&wx(u^oC7x9q&~UamO# z`2G(+H@#bZ+U(2KbzRM~t?%@o-t75&j%w4Vc^{V+J9TH3dCmImqu77Vv@1n`x9P9N zQo%D$pJ()2Xa7tt|6BWn>8gF-_VATE{a)|b^u^oC!FykAPdK0GnSA@{1_yd)*Y5fF z<&*Pf z*>01Fd+!r-|9sSX{l-P~%;YkOk|g_EK2xkN?mO@I_qxfv?$Z@HFTUS?diqoF=Qqb~ z_vh=+|9EFpfBL%3ig%6q|1O*<)Bcs`tktKCh~4jkD}OY6&U}+I;p^v>J9j_6q(1Zi z$A*hFLQG|6uDy4-y4GZ;(8Fk^TCauwcdKmGpI<9lCb8k|`XJAHKRI852eH?yT>Kvx zR940HclkV*|8r06f9d&U{>pVKzfAV2UV7c`d1|r$(e%<`|@+urS-9KVVK(_iL9 zV-ZB-jDcldZ-buCoV_zE|H}NCI{WqBhY#en<*v8iq z&elc0-~L64|NrjODXoo#e!Ag%JI<#R{@SSbsY{SWrg1KF!)2SWy<7JuFP6K`^|AF? zq5b}l&2p1Z9bEe$df$2BNw@YkrN8-qmph>U`L|Y`JkCkArCXvV&AxDBo}0PU206CR z88?k(e#(CRELFA5{(AlUAC*6NZxtKqeooIlm9Bnaee&J++Q+reF57-%Ui{batLGxZ zm9_Gn8@|@hUV28D^R?ux_ommY&#)ydI`zJ-`pw$gKelZBxKuS@y5Onc7oRV`P>rZl z%SwO!JHE_oPPovvN$G`{V((d3*HC0@H!@Xwx|MTli=Vz~F|9v_?&3|cr zqTPE*_@SDAb7%dT{>x~_|46NgtP@^u+{&@N>w&%r`{{?mGAxFgJ8kV-=lrtrPx$`?MfKC&`S9MJKH=xDX8B%O%nRyA^Dqj%IDf%O95Vk3sq^za9{gZ!|7X;{ z|Nqyvh#8k=3!Rw$Y#Mh-`|=gsYul#=+ITOB@7v<^!LGI7!SuDa`}Tg{xGUyeoYTAJ z%+CdmTTVoMuUjjv8XMyu_hr8H`YfH~wY|Y#=d3+u|1Wlj{MyVGMU$@5xf-R(&s%=Q zhUmT%>NtD)cqxBf`An~Zs>wTKJCwam`!ch0<^)ezC*@>!<;|JggM1NvtL83$bnt9= zlX9`0!I!(Cr|zhIwzMsp@v&@kmAso=V))(QsT<^0Z*ykw{G9M+wO#z0#qRSORLU3+ zcAtGAdibq*Qlzjo+q9o0Qadkt&MUig_}?y#OWTzBYq$J%yd3Vn>HL4ov~^X19_Lo@ zl+Qf;aQFLj^Y`nWy7NLMFHHLC29DfPvz&WNR^N~MbzJXxy8W7+H(2c7{%>E@usf}P zFXyk>KFO!*t`|o?-r%!)TD!%2HusxG~ddjbm zQ+9t(E}wd|-g`m*#?=gO>Y{W`f~ z*W(UbNp0>8|0?ddgDrgb$~)5zoT#7hhJOWjSK>jrt@YoUt8;sA9*vJZSsQ+D+wZ)s z^~?TznzmtL$z;dtfAUR}_TRsD{QcKgSAVL6rCdKgdC!#pzZx&u=&p==yk_sNeLqsS zrIk3;%{a~&@9SzV`0MNL%SGE1!?R^A_pezkcK%M`=C4K79xdnI=db;EezH_@1gDmU z-RqB5Ei)O`pLuTb>p^G$uju!iQ=7j|dh@4l&Y6+~tBaM!7jM0b{#~}O?APY6*3UM(u1ei?vg$qW zAMWpm)+SZ{qP7at_Tz1U%O@TE2B3l zjVe_qK7Lzhtlxa|&+X;EcPY5lm>nvu+qh4+aqImawQ#1bs^?cviP`k=>r~fQ*S);m zzpj7E`Q?87KmF5o|7-q!cJI99HRu1Y;Q4mzU8;UwpZr|6^WWpokLRnLj5o5nZ-dGV+I zm{b+UPP+g9)yvOSulA&PZ>sT}6F%wBB$N5Srr7*n8&vhuzx3yceW6)3(#b2o7iurF zEBksr3rqaupY%Anjdk+!>i6>>AKbg_*|VeP&7Zt2zpwl4yxRT^s_zPG z?2PL;)Z>5bJN@1DmifHRy$@3@#on%$-oNhQMtQIO$%l?7-=3E-C1_*$0NdL3tAj3zWcG&*7~E(!(Xu$7ehCnJ^x#O#(ymd zt30QK;`&(2L)vxok7(w9+Ijf-`+dj%|ErKX)E``b^4qnly@%^+zAVbA{r!FSOS6f& zYwzC_jCjBKh}`=6t5xmHH*~)}4*mFK^N+Gt-InhaJM=9c{rG!bjq&`kM}b=({@B0K z;eExPub=my{iwQbj=bWxi*;s9+m0u%Ov$R|@bXzSJ@23Qvo%dfbU**DU&o8IzxvjpZRPk@F z^{ssQ_toy(F*=Vv>{Zw7r{b%gryk9i+{ACBB%DR&zke6SAd3TcbGE@y?E~{@gJpo>B>@4cvwhme(tTm zPZtZ#P5Hj-n`w_ZhsUD*&*dZw^u?dAlM1%Gvv{`2vAy5UhZgQ@__&aJVg8Zo8~vHR z>u%b&|7fi(IQ{su>f`o;PrMVV>*Mbzos;;!=I@NcU$Vk>a+^0ySSwI*q$;zg`u+Q< zFXxJ7>wjJEc%l4!RHE~@-KA*-_BVZ>6_-}bJHTqQUe4a?M(6X+Yx-_=xxX(w|J(b# zUf2H3c21dF@wfHLs^ee&R`Gi#FkiavpIq^u@5e8Hx0-LiDQ^89`N#kEl>a`ly?+1f zb=@yc{F*D<_|?w)P2n%|$oI45>iggPu(kWEuGF$U{m<&($KUT4WVdlw`#y+#G=})C;z+3{vGG=oG|lQQKeH&l(6c>=TFL2 zPwSU@FSxJ$^~%qj#YSsqzWTI0=YLe6{2KuaUvLSp?!ff-@l0bSZzX7 zyxr`@b+32V_5F2KZfE`d@^A4)nYfcL&Q{u2{kOUO@#mz9cXOxIc>47J_V{Y8R%7!{ zqHVY9mcqjt?%#JTcxQ3{_71yk)8Cv7+b(&z`enKItDWC(vHU;$!)`}>V7(cW^~XQo zzW#pu`G4p6B|;Km$7IX0Bj$^4-YzQt+b;0majA>97g%4c~FMC~c_wcX0*M$}KM_Ji&nBgw-GUeD`kt$8JFdEY7gIpf*D#^ICHpVU zpR|7ez9~=E9{IWS-`sgk^X6HsXZbZrWBxp|`Sa}lPn`Vh^yTMMZPwe(t*z6T7}vZ^ zLZtm_aaK*Hj*;fp>$l!tTlUd->%(GEmd+^OMd6{mqBHB0W?i~5F_?T^6y=|D2F>y_3Qpzm#xaiN9)szaN^fH7f>>-!{g3 zB$WL%`~UB9KEvGQJMJ@io%-ivRKGX;o290m>hb9yw{bynQlVZ>o;|&fbOFt_H81 zesrSr>DxZfey;=l}CLuljN;ju`n+P+stNYIr~Sx89K{?{6ypw6pZ)sRfC`O<$nm zS$;kL^3TqHf?tmZEz^0`;~9QrO3vDrO4WqdsbxQ_a=oTq_b&bW^hlLzhIZq>_vKYw zfA6c_{P%hOe)-eFFHHO9+0FO1ZQS?cOr5HCebv=XTR!dH?-I_U|Lxw~LsQ%Cy}ebg zCwzR0{`?lNJpJ0LUHkoOwyRWncWpOPKij=u=<#$T``)sz?Le~w!c%(QFwraL*O%A=Nfar6sch+WM+ z`9lTyVo@gpBZmpo;jgz#>XJOa>{^#` zJ*BkQT>YYYuxi@t%ug$W*8lbL|1`&D{gI#kwxw}z)qekoo@eua=HwUCpHyDG{M78{ z`Rfy>8^t#UyH{QP9<);E^_oXI74x<~%+cj4(VG#!^vdp!=a$Y$Tc~<*`;+qjUn*43 zL@(O&dGPxeKS;phOug zAR1S5-Z=Vwwd}(OMohZ|54~<NWGc=NGSe|9v=b-uK?LTV^)@RLhHXp3Bbf^7QZgI!)#N ztJfz#$J%tM?hl%@*DG7>;p@G-Uw3wvbjRPB9+o!mR#bD)7L}^xHBWxTl&AX4`TqA= zu+`3a$AV_EZ`h?hJwO9Ao@B$yDD+}}k|YNc*4z*C7K&S8t*Q@lEK@x0s;<>8yzT32 z`P!@Jyp<;7@AZ=&O=qdv9J*iK$o&u^1XnyH;#y>`0l)#%JkcOs>B-a0x>C4Y+Z z{O8k!Z-xdt?e2;R{Z!*wa6VUcpY=|mhfCvyAH~ML7Wn-{`?iJr%2~%(JoXld+jstY zvlO@mZdl>wU%-Z>_e%?~oF ze)(_ttw}#xs=Vv|N4%T(Z~2m+Q|_!)`PIL_zWCD~q3x^hO{&n}KPl2^?^e~$t^&tU+W+X{m z%sS4-t-mLmzKlHi-s^%Gzv?#qub*sweljWcUb21DFP~rEuKY@xSEG9K{*;vY@7JH& z{`}4Dm3iyKj8DFvYG}Im)76k^N4~C6-gk}fYoyZNm&aOuJ=*p?)oAL!RJ%PsUrj5o zSYO(=biMN9h0Kf`d+Zp6Uc}e)&SXSX;0N?o7j!d3cYfVxf305AXc=g10B@3EVC1lA zXxQKX@_p#9g_~_S{{<)QRxQ@|d}le+`s>O5ze~ORW=!XwT)TVMlS>=-DH_&&ocpz_ zX!R;Hi7$8kZ+G4N{Bpi>$s*OnxR2dCr^fE(D6Us8|255Jeck2GeVaZ%J^MQ6&(36ldZ0vJNd0_e+cKtU&e=TOuO@4-_GZ+>}kEiIN=zf z2i{x1N+oNry?<-poU4oX-TG$qck8y3p>B6Ig7?3S$o#f3x5x`rnz(aJaHww)vO-S0 z6-rFI1QNu%&$X5IzP-8e0&rL%`D0?@}8>y^Ric0CcpZ8TK#mp z%Fj6_^HZv>KKXU$(OHY=OqVrlFTHxTdDm36&u?EOugxvePPbc=zkbiLvh(JD1sV># zS8!nZ`#vH)jT4$sL8H%3EG3)r#aq(EC+BD_dwzS>?A})2ii9^5*NT-)3pL^OUQ9tjY!H1wmo^vef*Rt`OP1?PZm$ z{^?UMbx$ST{!(LkdE%MV$z-aw(d$&7R z?54HbUhcVI!YPWJ3}DL8%7_X_rhofVdG5a}b=!F}qJGc+nO~>o?3GCSyL9cYlZ)@) z@%#HN%XIRdx|z@KF}{#0Z3>;WclRc|Q3Sx3=^KP5u#eUAm`t`StL-r?0=d_{`&WO=PCo z#@tVPFWvt6Yo07PPL)7$8kL{MjTEPgSl%4D7yspBsc&{!qes!rS?gYUoZ}`Uz#0x1 z3vBqkuRN#RtndkNlo}ZQJiT8*4SuUiSB)=eZs7W`149)srJL|6MV=85a91?))1~P&zupF~PxpaT5=6bohHXsQ+Fq zULCZj%o&wVd@)yrRvh%3hCH6C~)x4i%KyUwbaS9gkMsp#o%m&p4XYqjX-mY}+j z?{97IFUx*9&kmeg)Ig~vu09Q^b@pKiOG!|^cx_GW!>HSSf0mk0p7}1P>sj@+b`&Qf z1s)3XfWPpD-wQWeZ2Oh=>%_cnhnW45w^R1TthT@Yrh|=1pn{c2<--0$T7t?*DdD!j z1*3vnVmR&ssB!P_%h`X`!ZS-Re#zB0zhpe~ z>)NT)Z>;(0#K*|7M-EiM<)7`4Km_uGqntN7f6P=Vy*Xpw)mlxJefCP5>?TL^THIxCktnW27=zGOTc8s{U?2 z-!LsHN?qXk;^UIcVC-*6RG^UGoitL=Qqxm zlYW0&>U{3cjTzHap zqM`%SU&$zx0`I{=mJ-GT>W8E69@qnG`>LQ-DzsrZ~pf6v*=A4+qX@<^tE*JQcwlB!L@1Q;>L?aTQ#X+|9;uOQS+x>TmQ``?Ju~@=@U|D z{HLM$1>_cJx>4BR=%D`6Zsy(9d0#8{?)`P9KUQYL#io@*7x6Q4{E-1|MCr3tMy}En)HnZr^37Jos?hxJ)?GCP zP5a#^)gf2KFt=frixq54(cib%-jDiwLT1lf!P@o3y=%Wa%Q6X6$bpu4pN|sYL^$|> zwD1Mat*ZNuXWlybE$Y9|{gS=$@$+w1%)D7G37$tFq98c1m-B}0r@e)H?nV9W>7Tjo zyY*{#Hb#y;pich%;@Fv@NY)7pUFiHC_UKpK{`r%xZxyckxoy|=P}{!U%f#PiAp0L@ zCTw6}dFPq%`d{gr?zd}qd@K3>YwvsGUHAH|SQI|Y0aY>QN)@$`1L}>?2H_I#zU|w1 zeAE1D?ytH3MFXi!K#pdNp!}{P@ILNuWZc zQThAY{ugH+-Q7I<>-?!_zoc(eXl7uU*U!ND<@|Ov7Z!LXRruh@R zYWlB{Yfe7M76H{aT35prfdkS$Pgu& zT##DF7!iY%DEH50_qlC3 z5!o6Z21pSDXDSHocy9Y{=KGmGhLt_E=nvBvrmEG4u^nM$y7u zaMHFU|MBajC%4^Sy+1Xz((!@0fI{Ox^EF1rpb8S2M|N;C&NaC0xp}HohHqZ2SkHFD zn{kz$XXp9!$hHtGE1`_GfB@pf-zwfzS`*t_i4V*v&!x zn7q9FwK>zWt<<((>Z!ebeQo{vDZIp%3k)oMf*-!$tc|^PZJSY5%;f65%2sjnK_&TS zmI|i7=Rc*FAY#5zTw#ImU1jy%amQb6-12f(Om6)4I&d!^p3?B8_jT$I-k|K-u5d;I~5e zqwO`;!;_xWW=?pMa_4rmJZLZnQHS8O<~hfW+KT+tO%b#DPG0?1`g(Z_1IxW;2F@?< zH};)DO5YDWIbN{bQa>0S`!F)z=478$bnwSr(N!pIHe6l-IrrX7hdtl-nTB898nkPl z-0h9|r_Dhz^coaHU$6BbXWw~q8s>Uv-;6Dt|HbZgw^j6IATS>7B-e2=NaLOjd<X~G z&2XSlg4=r_Uv)!SeXLE*{PopgaqnKorH9!sw%!bCdi~J>H7TdrFGgxo?NMN~7POn> zp&xrWdh_R^)zV^{L#@Bf0E4i9QM zCpi4ymwoySJb)Qkrm)}4aI^8=8*!VRiLG}U4p=en{+}ncG51r1 z+|}-~Es6|{*FinA?6u+-k(vQ}1Q_Q=L>K)DyHUoJx9i%yO$+%E4J0fMMF->O;8ZM(RQhU1)>83)Bd)GxjoTJf7j2n5C+daB5B9PyfdNUZvFm+ z-Z730O!+PiEWga7e3l_+jT)AcpgJ?fdBQ)RN4qP5W_s{uXK-*fepfwE`|EpbbQ)Wu zB%{!a^pFWCoy9hmH!i<(l>YKMA3*Am;BC1uFf}&ZJ|0DJ*jXUX{P;r~y(2foysf->mWPsWwV=0UR$QUb)w+}{ow-b-IQ zQxnk=J0L9ZAbx}WK_vkugdjdo{>fsxv-|(m)90TkemE~Lf$D^Q)dQVBk}Hj+h%*bS zxrf1jfw>U4H;vc*NT~>&`QaKUv%h|tT7)h`I3XZXT>^{8s6$YqE`jBreC3&v*n3gN Rx(o~q44$rjF6*2Ung9-cF0B9n literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-app-oauth-key.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-app-oauth-key.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf4dd998d7dcb9aae37faaa8e48a95a8fe19d0a GIT binary patch literal 349050 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

    a27&f0r=D>Gk~Tc5dWZ)vKUzxNw= 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¥rHe{kH> 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

    &ua(R@6bH(dSmS_ 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

    5jZx?)yz=?1grmnO->E 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-create-app-success.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/x-developer-console-create-app-success.png new file mode 100644 index 0000000000000000000000000000000000000000..32c713f7d31978a78e936f406c4da712b8813465 GIT binary patch literal 512464 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⪼8&Ba}<{nyR~e^yu?wOw6$&i31^ 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

    XU*}FdzNET0NA|~r?(#bSz9s8D%?fjt{5cX6 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

    &AxA6JMGlN*)?0`a=%6L{ah5gi|=cv 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%0DjDa`p|&gJK`tUpft zIuFz}hc&5@*=BP=b8%mIB*Hw_Y^*2<&$XK}wa2U`HTd$~9jS{e7W{EAe>Sl`+`i9K zUH;!jecNwO*SD>GoBMWhyWy`R7t&*dqNiLsZD)9~Z|#&qyO&2E9Ji=VdD*^K?dfWp zCtVwFh_uJ+vYY)pUh(FJ%0<&Q`=I2)a}wu^)sGqa)#Un^eLBS-pY!B^{

    Fc1`@T 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%0D9M-^4ep}awXW?%pW_E6RaV=cp_=*O8XRB=$ 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 XBe(b6vp5w71_lOCS3j3^P6`. | +| `BLUESKY_IDENTIFIER` | No | Your Bluesky handle or email (e.g. `acme.bsky.social`). | +| `BLUESKY_APP_PASSWORD` | No | A Bluesky App Password (not your account password). | +| `X_API_KEY` | No | X app API key (OAuth 1.0a). | +| `X_API_SECRET` | No | X app API secret. | +| `X_ACCESS_TOKEN` | No | X user access token. | +| `X_ACCESS_SECRET` | No | X user access token secret. | +| `POST_ON_STATUSES` | No | Comma-separated statuses to post on (e.g. `investigating,resolved`). Defaults to all. | +| `POST_MAINTENANCE` | No | Set to `true` to also post scheduled maintenance. | +| `PORT` | No | Server port. Defaults to `3000` (ignored on serverless platforms). | + +## Step-by-step guide + +### 1. Generate a webhook token + +Pick any sufficiently random string — this is the shared secret between openstatus and your service. It is not required but recommended to keep the endpoint authenticated. For example: + +```bash +openssl rand -hex 32 +``` + +Save it as `OPENSTATUS_WEBHOOK_TOKEN`. You'll reuse the same value when you create the subscriber in step 5. + +### 2. Create a Bluesky App Password + +App Passwords let an app post on your behalf without exposing your real password. + +1. In Bluesky, open **Settings**. + +Bluesky settings menu + +2. Go to **Privacy and Security** and click **App passwords**. + +Bluesky Privacy and Security settings + +3. Click **Add App Password** and give it a name (e.g. `openstatus-notifier`). + +Naming a new Bluesky App Password + +4. Copy the generated password — Bluesky won't show it again. + +The generated Bluesky App Password + +Set `BLUESKY_IDENTIFIER` to your handle (e.g. `acme.bsky.social`) and `BLUESKY_APP_PASSWORD` to the value you just copied. + +### 3. Create an X app and access tokens + +1. Open the [X Developer Portal](https://developer.x.com) and go to **Apps**. + +X Developer Console apps list + +2. Click **Create App**, give it a name, and pick an environment. + +Creating a new X client application + +3. On creation, X shows your **Consumer Key** and **Secret Key** once — copy them to `X_API_KEY` and `X_API_SECRET`. + +X application created with consumer and secret keys + +4. Open the app's **Keys & Tokens** tab. Under **User authentication settings**, enable **OAuth 1.0a** with **Read and write** permissions, then generate an **Access Token and Secret**. + +X app keys and tokens with OAuth 1.0a access token + +5. Copy the **Access Token** and **Access Token Secret** to `X_ACCESS_TOKEN` and `X_ACCESS_SECRET` — they're shown only once. + +X access token and secret generated + +Make sure the access token is generated **after** you set Read and write permissions — otherwise posts will fail with a permissions error. + +### 4. Deploy the service + +Fork or clone the [repository](https://github.com/openstatusHQ/statuspage-socials-notifier), then deploy it to your platform of choice. + +#### Vercel + +1. In Vercel, click **Add New → Project** and import your fork. +2. Add every variable from the table above under **Settings → Environment Variables**. +3. Click **Deploy**. Your webhook endpoint will be available at `https://.vercel.app/webhook`. + +#### Fly.io + +The repo ships a preconfigured `fly.toml`. Set each variable as a secret, then deploy: + +```bash +fly secrets set OPENSTATUS_WEBHOOK_TOKEN=... BLUESKY_IDENTIFIER=... BLUESKY_APP_PASSWORD=... \ + X_API_KEY=... X_API_SECRET=... X_ACCESS_TOKEN=... X_ACCESS_SECRET=... +fly deploy +``` + +#### Railway + +Import the repo (Railway auto-detects the Dockerfile) and add the environment variables in the project dashboard. + +> These platforms scale to zero, so the first request after an idle period incurs a ~1–2s cold start. That fits inside openstatus' 5s webhook timeout, and failed deliveries are retried up to 3 times with exponential backoff — so a cold start may delay, but won't drop, the first post. + +### 5. Add the webhook subscriber in openstatus + +1. In the dashboard, open your status page and go to **Subscribers**. +2. Add a subscriber with channel **Webhook** and set the URL to your deployed endpoint, e.g. `https:///webhook`. +3. Add a request header `Authorization` with value `Bearer ` (the token from step 1). + +Adding a webhook subscriber with URL and Authorization header in openstatus + +Because the destination isn't a Slack or Discord URL, openstatus sends the [generic JSON payload](/docs/reference/subscriber#generic), which the notifier knows how to parse. + +### 6. Test it + +Use the subscriber's **Send test** action to verify connectivity — openstatus delivers a `type: "test"` payload, which the notifier ignores (it only posts real events), so check your service logs for the received request rather than your social accounts. + +To verify end-to-end posting, publish a status report on your page. Within a couple of seconds you should see the update appear on both your X and Bluesky accounts. + +## Related resources + +- **[Subscriber reference](/docs/reference/subscriber)** — how subscribers and webhook payloads work. +- **[statuspage-socials-notifier](https://github.com/openstatusHQ/statuspage-socials-notifier)** — source code and configuration reference. diff --git a/apps/web/src/content/pages/docs/reference/subscriber.mdx b/apps/web/src/content/pages/docs/reference/subscriber.mdx index cfe556e8..d9bea51a 100644 --- a/apps/web/src/content/pages/docs/reference/subscriber.mdx +++ b/apps/web/src/content/pages/docs/reference/subscriber.mdx @@ -37,6 +37,206 @@ Status page administrators can manage their subscriber lists, including: - **Adding/removing subscribers** — manually adding or removing subscribers. - **Communication** — sending ad-hoc notifications to the subscriber list (if supported by the platform). +## Adding subscribers from the dashboard + +Beyond public self-subscription, administrators can add subscribers directly from the dashboard. This is useful for onboarding partners, internal teams, or automation that should receive updates without going through the public opt-in flow. Each manually added subscriber uses one of two channels: + +- **Email** — delivers updates to a contact address. By adding an email here you confirm the contact has consented to receive status updates; no confirmation email is sent. +- **Webhook** — POSTs each update to a URL. Slack and Discord URLs receive channel-native messages; any other URL receives a generic JSON payload. + +For both channels, you can optionally: + +- **Set a display label** — shown in place of the raw destination in the dashboard (e.g. `Supabase #incidents`). +- **Scope to page components** — leave empty to notify for the entire page, or select specific components to only notify on matching reports. + +![openstatus](/assets/logos/openstatus.jpeg) + +## Webhook subscribers + +A webhook subscriber receives a POST request for every status report and scheduled maintenance update. openstatus inspects the destination URL and emits a payload tailored to it. + +### Slack + +A URL starting with `https://hooks.slack.com/services/` is treated as a Slack incoming webhook. The payload uses Slack [Block Kit](https://api.slack.com/block-kit) attachments — a colored header (red/yellow/green/blue by status), status and page fields, the update message, affected components, and footer links to view, manage, and unsubscribe. + +### Discord + +A URL starting with `https://discord.com/api/webhooks/` is treated as a Discord webhook. The payload uses a Discord embed with a status-colored sidebar, a title linking to the event, status and page fields, the update message, affected components, and manage/unsubscribe links. + +### Generic + +Any other URL receives a versioned, channel-agnostic JSON payload. Use this to forward updates into your own systems. The body is shaped as: + +```json +{ + "version": "1", + "type": "status_report", + "data": { + "status_report": { + "id": 123, + "title": "Database connectivity issues", + "url": "https://acme.openstatus.dev/events/report/123", + "update": { + "id": 456, + "status": "investigating", + "message": "We are investigating elevated error rates.", + "occurred_at": "2026-06-26T10:00:00.000Z" + }, + "page": { + "id": 1, + "name": "Acme Status", + "slug": "acme", + "url": "https://acme.openstatus.dev" + }, + "components": [ + { "id": 7, "name": "API", "impact": "major_outage" } + ] + } + }, + "subscription": { + "manage_url": "https://acme.openstatus.dev/manage/", + "unsubscribe_url": "https://acme.openstatus.dev/unsubscribe/" + } +} +``` + +`page.url` is the canonical status page origin, while `status_report.url` (and `maintenance.url` below) is the deep link to that specific event. Each entry in `components` carries an `impact`, which may be `null` when no impact is associated with the component for this update. + +Scheduled maintenance is delivered with `type: "maintenance"` and a `data.maintenance` object carrying `starts_at` / `ends_at` in place of the `update` block. The `version` field is bumped on any breaking change, so pin to it when consuming the payload. + +The **Send test** action emits the same envelope with `type: "test"` and a `data.test` object — use the `type` discriminator to ignore it (it carries no real event): + +```json +{ + "version": "1", + "type": "test", + "data": { + "test": { + "message": "Your openstatus webhook is configured correctly.", + "timestamp": "2026-06-26T10:38:00.132Z" + } + } +} +``` + +You can attach **custom request headers** to every webhook request — for example, a shared secret or an authorization token your receiver verifies. + +#### Timeout and retries + +Each webhook request is given **5 seconds** to complete. If your endpoint has not responded within that window, the request is aborted and treated as a failed attempt. + +Failed attempts are retried with **jittered exponential backoff** (≈200 ms base delay), up to **3 retries** (4 attempts total). Only transient failures are retried: + +- **Network errors and timeouts** (no HTTP response). +- **`5xx` responses** — a server-side error on your end that may clear. +- **`429 Too Many Requests`** — your endpoint asked us to back off. + +Any other `4xx` response (e.g. `400`, `401`, `404`) is treated as a permanent client error and is **not** retried, since replaying the same request would fail again. Make your receiver **idempotent** — a retried delivery is identical to the original, so deduplicate on the update `id` if you act on each request. + +#### Example: post updates to X / Bluesky + +[`statuspage-socials-notifier`](https://github.com/openstatusHQ/statuspage-socials-notifier) is a reference receiver that consumes the generic payload and cross-posts each update to your X (Twitter) and Bluesky accounts. Point a generic webhook subscriber at its endpoint to mirror your status page on social media — it doubles as a worked example of validating and handling the payload. + +#### Validating the payload + +The payload shape is defined in [`packages/subscriptions/src/payload.ts`](https://github.com/openstatusHQ/openstatus/blob/main/packages/subscriptions/src/payload.ts). Copy this zod schema to validate incoming requests in your own receiver: + +```ts +import { z } from "zod"; + +export const WEBHOOK_PAYLOAD_VERSION = "1" as const; + +const impactSchema = z.enum([ + "operational", + "degraded_performance", + "partial_outage", + "major_outage", +]); + +const statusSchema = z.enum([ + "investigating", + "identified", + "monitoring", + "resolved", +]); + +const componentSchema = z.object({ + id: z.number().int(), + name: z.string(), + impact: impactSchema.nullish(), +}); + +const pageSchema = z.object({ + id: z.number().int(), + name: z.string(), + slug: z.string(), + url: z.url(), +}); + +const subscriptionSchema = z.object({ + manage_url: z.string().nullish(), + unsubscribe_url: z.string().nullish(), +}); + +const statusReportWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("status_report"), + data: z.object({ + status_report: z.object({ + id: z.number().int(), + title: z.string(), + url: z.url(), + update: z.object({ + id: z.number().int(), + status: statusSchema, + message: z.string(), + occurred_at: z.string(), + }), + page: pageSchema, + components: z.array(componentSchema), + }), + }), + subscription: subscriptionSchema, +}); + +const maintenanceWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("maintenance"), + data: z.object({ + maintenance: z.object({ + id: z.number().int(), + title: z.string(), + url: z.url(), + message: z.string(), + starts_at: z.string().optional(), + ends_at: z.string().optional(), + page: pageSchema, + components: z.array(componentSchema), + }), + }), + subscription: subscriptionSchema, +}); + +const testWebhookSchema = z.object({ + version: z.literal(WEBHOOK_PAYLOAD_VERSION), + type: z.literal("test"), + data: z.object({ + test: z.object({ + message: z.string(), + timestamp: z.string(), + }), + }), +}); + +export const webhookPayloadSchema = z.discriminatedUnion("type", [ + statusReportWebhookSchema, + maintenanceWebhookSchema, + testWebhookSchema, +]); + +export type WebhookPayload = z.infer; +``` + ## Related resources - **[Status page reference](/docs/reference/status-page)** — detailed information on managing and configuring status pages. -- 2.51.2 From ce2e51e41466b2e83a16f8e46d57a0fe9831e38c Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Tue, 30 Jun 2026 15:47:31 +0200 Subject: [PATCH 07/69] Deno build (#2323) * deno try * deno * merge conflict * deno * deno * deno * deno * ci: apply automated fixes * fix check * ci: apply automated fixes * // tests * fix tests * fix tests * pr * ci: apply automated fixes * improve test * fix build * fix: smaller build output * fix: cleanup / revert some things * fix: use import alias * fix(workflows): smaller docker image * fix build * fix check * fix pr --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: finxol --- .github/workflows/check.yml | 39 ++ .github/workflows/dx.yml | 6 +- .github/workflows/test.yml | 8 +- apps/dashboard/env.ts | 3 +- apps/screenshot-service/package.json | 1 + apps/server/.gitignore | 4 + apps/server/Dockerfile | 30 +- apps/server/bunfig.toml | 2 - apps/server/deno.jsonc | 6 + apps/server/docker-compose.yaml | 2 + apps/server/dofigen.lock | 126 ++-- apps/server/dofigen.yml | 28 +- apps/server/env.ts | 3 +- apps/server/package.json | 18 +- apps/server/src/index.ts | 58 +- .../libs/middlewares/require-scope.test.ts | 4 +- .../src/libs/middlewares/validate-key.test.ts | 3 +- .../src/libs/test/doubles/analytics.mock.ts | 26 + .../src/libs/test/doubles/page-urls.mock.ts | 10 + .../src/libs/test/doubles/slack-agent.mock.ts | 8 + .../src/libs/test/doubles/slack-test-state.ts | 33 + .../libs/test/doubles/slack-web-api.mock.ts | 26 + apps/server/src/libs/test/doubles/state.ts | 49 ++ .../libs/test/doubles/subscriptions.mock.ts | 11 + .../src/libs/test/doubles/tinybird.mock.ts | 59 ++ .../src/libs/test/doubles/upstash.mock.ts | 36 + .../test/doubles/workspace-resolver.mock.ts | 6 + apps/server/src/libs/test/preload.ts | 3 +- apps/server/src/routes/mcp/adapter.test.ts | 4 +- apps/server/src/routes/mcp/adapter.ts | 2 +- apps/server/src/routes/mcp/handler.test.ts | 7 +- apps/server/src/routes/mcp/index.ts | 7 +- .../routes/mcp/tools/register-scoped.test.ts | 4 +- .../server/src/routes/mcp/tools/tools.test.ts | 4 +- apps/server/src/routes/public/status.test.ts | 9 +- apps/server/src/routes/public/status.ts | 2 +- apps/server/src/routes/rpc/adapter.test.ts | 4 +- .../maintenance/__tests__/maintenance.test.ts | 223 +++--- .../monitor/__tests__/monitor.test.ts | 50 +- .../monitor/converters/regions.test.ts | 20 +- .../src/routes/rpc/handlers/monitor/index.ts | 5 +- .../handlers/monitor/response-logs.test.ts | 4 +- .../__tests__/notification.test.ts | 6 +- .../status-page/__tests__/status-page.test.ts | 9 +- .../__tests__/status-report.test.ts | 86 ++- .../interceptors/__tests__/tracking.test.ts | 43 +- .../src/routes/rpc/interceptors/auth.ts | 2 +- apps/server/src/routes/slack/blocks.test.ts | 4 +- .../routes/slack/confirmation-store.test.ts | 3 +- apps/server/src/routes/slack/handler.test.ts | 150 ++-- apps/server/src/routes/slack/index.test.ts | 3 +- .../src/routes/slack/interactions.test.ts | 72 +- apps/server/src/routes/slack/oauth.test.ts | 3 +- .../slack/presenters/presenters.test.ts | 17 +- .../src/routes/slack/registry-runner.test.ts | 4 +- .../src/routes/slack/system-prompt.test.ts | 3 +- apps/server/src/routes/slack/verify.test.ts | 3 +- .../src/routes/v1/check/http/post.test.ts | 4 +- .../src/routes/v1/incidents/get.test.ts | 3 +- .../src/routes/v1/incidents/get_all.test.ts | 4 +- .../src/routes/v1/incidents/put.test.ts | 3 +- .../src/routes/v1/maintenances/get.test.ts | 3 +- .../routes/v1/maintenances/get_all.test.ts | 4 +- .../src/routes/v1/maintenances/post.test.ts | 8 +- .../src/routes/v1/maintenances/put.test.ts | 46 +- .../src/routes/v1/monitors/delete.test.ts | 3 +- .../server/src/routes/v1/monitors/get.test.ts | 3 +- .../src/routes/v1/monitors/get_all.test.ts | 3 +- .../src/routes/v1/monitors/post.test.ts | 5 +- .../src/routes/v1/monitors/post_dns.test.ts | 3 +- .../src/routes/v1/monitors/post_http.test.ts | 3 +- .../src/routes/v1/monitors/post_tcp.test.ts | 3 +- .../server/src/routes/v1/monitors/put.test.ts | 3 +- .../src/routes/v1/monitors/put_dns.test.ts | 3 +- .../src/routes/v1/monitors/put_http.test.ts | 3 +- .../src/routes/v1/monitors/put_tcp.test.ts | 3 +- .../routes/v1/monitors/results/get.test.ts | 36 +- .../src/routes/v1/monitors/run/post.test.ts | 87 +-- .../routes/v1/monitors/summary/get.test.ts | 6 +- .../src/routes/v1/monitors/summary/get.ts | 5 - .../routes/v1/monitors/trigger/post.test.ts | 4 +- .../src/routes/v1/notifications/get.test.ts | 3 +- .../routes/v1/notifications/get_all.test.ts | 4 +- .../src/routes/v1/notifications/post.test.ts | 4 +- .../routes/v1/pageSubscribers/post.test.ts | 4 +- apps/server/src/routes/v1/pages/get.test.ts | 3 +- .../src/routes/v1/pages/get_all.test.ts | 4 +- apps/server/src/routes/v1/pages/post.test.ts | 4 +- apps/server/src/routes/v1/pages/put.test.ts | 3 +- .../routes/v1/statusReportUpdates/get.test.ts | 3 +- .../v1/statusReportUpdates/post.test.ts | 7 +- .../routes/v1/statusReports/delete.test.ts | 3 +- .../src/routes/v1/statusReports/get.test.ts | 3 +- .../routes/v1/statusReports/get_all.test.ts | 4 +- .../src/routes/v1/statusReports/post.test.ts | 8 +- .../subscriber-filtering.integration.test.ts | 4 +- .../v1/statusReports/update/post.test.ts | 3 +- .../routes/v1/statusReports/update/post.ts | 3 +- apps/server/src/routes/v1/whoami/get.test.ts | 3 +- apps/server/src/serve.ts | 13 + apps/server/src/utils/audit-log.ts | 2 +- apps/server/test.importmap.json | 16 + apps/server/tsconfig.json | 10 +- apps/status-page/env.ts | 3 +- apps/status-page/package.json | 7 +- apps/status-page/src/app/(public)/client.tsx | 17 +- apps/status-page/src/app/(public)/layout.tsx | 6 +- .../[domain]/[locale]/(auth)/layout.tsx | 6 +- .../login/_components/section-magic-link.tsx | 12 +- .../login/_components/section-password.tsx | 8 +- .../[domain]/[locale]/(auth)/login/actions.ts | 4 +- .../[domain]/[locale]/(auth)/login/page.tsx | 3 +- .../[locale]/(auth)/restricted/page.tsx | 2 +- .../[domain]/[locale]/(public)/client.tsx | 22 +- .../(public)/events/(list)/layout.tsx | 2 +- .../[locale]/(public)/events/(list)/page.tsx | 9 +- .../events/(view)/maintenance/[id]/layout.tsx | 8 +- .../events/(view)/maintenance/[id]/page.tsx | 10 +- .../events/(view)/report/[id]/layout.tsx | 8 +- .../events/(view)/report/[id]/page.tsx | 12 +- .../[locale]/(public)/events/layout.tsx | 2 +- .../[locale]/(public)/feed/[type]/route.ts | 6 +- .../[locale]/(public)/feed/json/route.ts | 4 +- .../[domain]/[locale]/(public)/layout.tsx | 6 +- .../[locale]/(public)/llms.txt/route.ts | 9 +- .../(public)/manage/[token]/layout.tsx | 6 +- .../[locale]/(public)/manage/[token]/page.tsx | 10 +- .../[locale]/(public)/manage/layout.tsx | 2 +- .../(public)/monitors/[id]/layout.tsx | 2 +- .../[locale]/(public)/monitors/[id]/page.tsx | 21 +- .../[locale]/(public)/monitors/layout.tsx | 2 +- .../[locale]/(public)/monitors/page.tsx | 6 +- .../[locale]/(public)/search-params.ts | 2 +- .../(public)/unsubscribe/[token]/layout.tsx | 2 +- .../(public)/unsubscribe/[token]/page.tsx | 4 +- .../(public)/verify/[token]/layout.tsx | 2 +- .../[locale]/(public)/verify/[token]/page.tsx | 4 +- .../[domain]/[locale]/layout.tsx | 6 +- .../src/app/(status-page)/[domain]/layout.tsx | 14 +- .../src/app/api/auth/[...nextauth]/route.ts | 2 +- .../src/app/api/markdown/[[...path]]/route.ts | 12 +- .../src/app/api/status/[[...path]]/route.ts | 16 +- .../src/app/api/trpc/edge/[trpc]/route.ts | 4 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 4 +- apps/status-page/src/app/global-error.tsx | 2 +- apps/status-page/src/app/layout.tsx | 5 +- apps/status-page/src/app/not-found.tsx | 4 +- apps/status-page/src/app/robots.ts | 6 +- apps/status-page/src/app/sitemap.ts | 8 +- .../chart/chart-area-percentiles.tsx | 3 +- .../src/components/chart/chart-bar-uptime.tsx | 3 +- .../components/chart/chart-legend-badge.tsx | 2 +- .../components/chart/chart-line-regions.tsx | 5 +- .../src/components/common/link.tsx | 2 +- .../src/components/date-fns-provider.tsx | 2 +- .../src/components/date-picker.tsx | 4 +- .../forms/form-manage-subscription.tsx | 2 +- .../components/forms/form-subscribe-email.tsx | 2 +- .../i18n/status-blocks-provider.tsx | 2 +- .../src/components/layout/embed-shell.tsx | 2 +- .../src/components/locale-switcher.tsx | 2 +- .../status-page/src/components/nav/footer.tsx | 12 +- .../status-page/src/components/nav/header.tsx | 8 +- .../src/components/password-wrapper.tsx | 2 +- .../status-page/floating-button.tsx | 2 +- .../components/status-page/floating-theme.tsx | 3 +- .../src/components/status-page/status-bar.tsx | 4 +- .../components/status-page/status-blank.tsx | 2 +- .../status-page/status-calendar.tsx | 6 +- .../components/status-page/status-events.tsx | 2 +- .../components/status-page/status-feed.tsx | 7 +- .../components/status-page/status-updates.tsx | 6 +- .../src/components/themes/theme-provider.tsx | 4 +- .../src/components/themes/theme-sidebar.tsx | 4 +- .../ui/data-table/data-table-toolbar.tsx | 4 +- .../src/content/markdown/generators.test.ts | 3 +- .../src/content/markdown/match-route.test.ts | 3 +- .../src/content/status-json.test.ts | 4 +- .../src/content/status-vocab.test.ts | 3 +- apps/status-page/src/data/metrics.client.ts | 5 +- apps/status-page/src/hooks/use-embed.ts | 4 +- .../src/hooks/use-pathname-prefix.ts | 6 +- .../src/lib/alternates-metadata.ts | 4 +- apps/status-page/src/lib/alternates.test.ts | 3 +- apps/status-page/src/lib/auth/index.ts | 5 +- apps/status-page/src/lib/auth/providers.ts | 3 +- apps/status-page/src/lib/formatter.test.ts | 3 +- .../src/lib/http/client-ip.test.ts | 3 +- apps/status-page/src/lib/http/etag.test.ts | 3 +- .../src/lib/http/markdown-response.test.ts | 9 +- .../src/lib/http/markdown-response.ts | 6 +- .../proxy/apply-page-locale-override.test.ts | 3 +- .../src/lib/proxy/build-external-path.test.ts | 3 +- .../src/lib/proxy/compose-page-action.test.ts | 4 +- .../src/lib/proxy/detect-markdown.test.ts | 3 +- .../lib/proxy/evaluate-markdown-gate.test.ts | 3 +- .../src/lib/proxy/is-ip-allowed.test.ts | 3 +- .../lib/proxy/markdown-cache-control.test.ts | 3 +- .../resolve-custom-domain-rewrite.test.ts | 3 +- .../lib/proxy/resolve-default-rewrite.test.ts | 3 +- .../proxy/resolve-email-domain-action.test.ts | 3 +- .../status-page/src/lib/proxy/resolve-gate.ts | 9 +- .../resolve-ip-restriction-action.test.ts | 3 +- .../lib/proxy/resolve-locale-action.test.ts | 3 +- .../lib/proxy/resolve-password-action.test.ts | 3 +- .../lib/proxy/sanitize-redirect-param.test.ts | 3 +- .../proxy/strip-prefix-for-external.test.ts | 3 +- .../src/lib/resolve-pathname-prefix.test.ts | 3 +- .../status-page/src/lib/resolve-route.test.ts | 3 +- apps/status-page/src/lib/resolve-route.ts | 3 +- .../src/lib/status-blocks-labels.test.ts | 4 +- apps/status-page/src/lib/trpc/client.tsx | 2 +- apps/status-page/src/proxy.ts | 5 +- apps/web/env.ts | 3 +- apps/web/package.json | 6 +- apps/web/src/app/(ai)/llms-full.txt/route.ts | 6 +- apps/web/src/app/(ai)/llms.txt/route.ts | 4 +- apps/web/src/app/(ai)/mcp/route.ts | 2 +- .../src/app/(docs)/docs/[[...slug]]/page.tsx | 26 +- apps/web/src/app/(docs)/layout.tsx | 6 +- apps/web/src/app/(landing)/[slug]/page.tsx | 10 +- .../src/app/(landing)/blog/[slug]/page.tsx | 14 +- .../(landing)/blog/category/[slug]/page.tsx | 12 +- .../src/app/(landing)/blog/category/page.tsx | 7 +- .../src/app/(landing)/blog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/blog/page.tsx | 11 +- .../app/(landing)/changelog/[slug]/page.tsx | 14 +- .../changelog/category/[slug]/page.tsx | 12 +- .../app/(landing)/changelog/category/page.tsx | 7 +- .../app/(landing)/changelog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/changelog/page.tsx | 11 +- .../src/app/(landing)/compare/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/compare/page.tsx | 11 +- .../src/app/(landing)/content-box-image.tsx | 4 +- apps/web/src/app/(landing)/content-box.tsx | 2 +- .../src/app/(landing)/content-category.tsx | 2 +- apps/web/src/app/(landing)/content-list.tsx | 4 +- .../src/app/(landing)/content-metadata.tsx | 4 +- .../src/app/(landing)/content-pagination.tsx | 2 +- .../app/(landing)/customers/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/customers/page.tsx | 11 +- .../src/app/(landing)/guides/[slug]/page.tsx | 14 +- .../(landing)/guides/category/[slug]/page.tsx | 12 +- .../app/(landing)/guides/category/page.tsx | 7 +- apps/web/src/app/(landing)/guides/page.tsx | 11 +- apps/web/src/app/(landing)/layout.tsx | 6 +- .../src/app/(landing)/oss-friends/page.tsx | 5 +- apps/web/src/app/(landing)/page.tsx | 10 +- .../(landing)/play/checker/[slug]/client.tsx | 7 +- .../(landing)/play/checker/[slug]/page.tsx | 18 +- .../app/(landing)/play/checker/api/route.ts | 10 +- .../src/app/(landing)/play/checker/client.tsx | 9 +- .../src/app/(landing)/play/checker/page.tsx | 18 +- .../src/app/(landing)/play/checker/utils.ts | 4 +- apps/web/src/app/(landing)/play/curl/page.tsx | 14 +- .../(landing)/play/mcp-health/[id]/client.tsx | 3 +- .../(landing)/play/mcp-health/[id]/page.tsx | 16 +- .../(landing)/play/mcp-health/api/route.ts | 4 +- .../app/(landing)/play/mcp-health/client.tsx | 7 +- .../app/(landing)/play/mcp-health/page.tsx | 16 +- .../(landing)/play/mcp-health/utils.test.ts | 3 +- .../app/(landing)/play/mcp-health/utils.ts | 10 +- apps/web/src/app/(landing)/play/page.tsx | 5 +- .../(landing)/play/severity-matrix/client.tsx | 2 +- .../(landing)/play/severity-matrix/page.tsx | 14 +- .../app/(landing)/play/uptime-sla/page.tsx | 14 +- .../[id]/[component]/component-detail.tsx | 21 +- .../status/[id]/[component]/page.tsx | 11 +- .../app/(landing)/status/[id]/incidents.tsx | 6 +- .../src/app/(landing)/status/[id]/page.tsx | 13 +- .../(landing)/status/[id]/report-issue.tsx | 3 +- .../status/[id]/service-components.tsx | 3 +- .../(landing)/status/[id]/service-detail.tsx | 9 +- .../(landing)/status/[id]/user-reports.tsx | 2 +- .../(landing)/status/external-status-grid.tsx | 5 +- apps/web/src/app/(landing)/status/page.tsx | 9 +- .../src/app/(landing)/tooling/[slug]/page.tsx | 13 +- apps/web/src/app/(landing)/tooling/page.tsx | 11 +- .../app/(landing)/use-case/[slug]/page.tsx | 14 +- apps/web/src/app/(landing)/use-case/page.tsx | 11 +- apps/web/src/app/api/checker/cron/_cron.ts | 2 +- .../src/app/api/checker/test/http/route.ts | 3 +- apps/web/src/app/api/feedback/docs/route.ts | 4 +- .../src/app/api/markdown/[[...path]]/route.ts | 6 +- .../src/app/api/og/_components/background.tsx | 2 +- .../app/api/og/_components/basic-layout.tsx | 3 +- .../app/api/og/_components/status-check.tsx | 2 +- .../src/app/api/og/_components/tracker.tsx | 4 +- apps/web/src/app/api/og/checker/route.tsx | 5 +- .../src/app/api/og/external-service/route.tsx | 9 +- apps/web/src/app/api/og/monitor/route.tsx | 5 +- apps/web/src/app/api/og/page/route.tsx | 5 +- apps/web/src/app/api/og/post/route.tsx | 3 +- apps/web/src/app/api/og/route.tsx | 3 +- apps/web/src/app/api/og/status/route.tsx | 7 +- apps/web/src/app/api/search/route.ts | 4 +- apps/web/src/app/api/test/timeout/route.ts | 2 +- .../web/src/app/api/trpc/edge/[trpc]/route.ts | 2 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 2 +- apps/web/src/app/api/webhook/stripe/route.ts | 2 +- apps/web/src/app/layout.tsx | 12 +- apps/web/src/app/not-found.tsx | 4 +- apps/web/src/app/sitemap.ts | 4 +- .../web/src/components/dev-mode-container.tsx | 2 +- .../src/components/icon-cloud-provider.tsx | 2 +- apps/web/src/components/loading-animation.tsx | 2 +- apps/web/src/config/socials.ts | 2 +- apps/web/src/content/cmdk.tsx | 8 +- apps/web/src/content/docs-feedback.tsx | 2 +- apps/web/src/content/docs-footer.tsx | 5 +- apps/web/src/content/docs-sidebar.tsx | 3 +- apps/web/src/content/docs-sub-nav.tsx | 3 +- apps/web/src/content/docs-toc.tsx | 3 +- apps/web/src/content/footer-status.tsx | 2 +- apps/web/src/content/footer.tsx | 7 +- apps/web/src/content/header.tsx | 3 +- apps/web/src/content/highlight-text.tsx | 2 +- apps/web/src/content/image-zoom.tsx | 2 +- apps/web/src/content/latency-chart-table.tsx | 3 +- apps/web/src/content/link.tsx | 2 +- apps/web/src/content/mdx-components/aside.tsx | 2 +- apps/web/src/content/mdx-components/card.tsx | 2 +- .../content/mdx-components/custom-image.tsx | 5 +- apps/web/src/content/mdx-components/grid.tsx | 2 +- .../web/src/content/mdx-components/subtle.tsx | 2 +- apps/web/src/content/simple-chart.tsx | 2 +- apps/web/src/content/status-markdown.ts | 4 +- apps/web/src/content/sub-nav.tsx | 3 +- apps/web/src/content/theme-toggle.tsx | 2 +- apps/web/src/content/utils/search-index.ts | 3 +- .../src/content/utils/search-match.test.ts | 3 +- apps/web/src/data/content.ts | 2 +- apps/web/src/data/trigger-dictionary.ts | 4 +- apps/web/src/lib/checker/mock.ts | 4 +- .../web/src/lib/external-report-escalation.ts | 2 +- apps/web/src/lib/mcp/health-check.test.ts | 3 +- apps/web/src/lib/metadata/shared-metadata.ts | 2 +- apps/web/src/lib/metadata/structured-data.ts | 3 +- apps/web/src/lib/stripe/client.ts | 2 +- apps/web/src/lib/tb.ts | 2 +- apps/workflows/.gitignore | 4 + apps/workflows/Dockerfile | 66 +- apps/workflows/deno-migration-plan.md | 437 ++++++++++++ apps/workflows/docker-compose.yaml | 11 +- apps/workflows/dofigen.lock | 204 +++--- apps/workflows/dofigen.yml | 68 +- apps/workflows/package.json | 13 +- apps/workflows/src/build-docker.ts | 81 --- apps/workflows/src/checker/alerting.test.ts | 175 ++--- apps/workflows/src/cron/checker.ts | 2 +- apps/workflows/src/cron/index.ts | 2 +- apps/workflows/src/index.ts | 50 +- apps/workflows/src/lib/sentry.ts | 2 +- apps/workflows/src/serve.ts | 15 + apps/workflows/start.sh | 2 +- apps/workflows/tsconfig.json | 1 - deno.lock | 277 ++++++++ package.json | 1 + packages/analytics/package.json | 4 +- packages/analytics/tsconfig.json | 1 - packages/api/.env.test | 1 + packages/api/env.ts | 3 +- packages/api/package.json | 11 +- packages/api/src/router/blob.test.ts | 3 +- .../api/src/router/effective-status.test.ts | 3 +- packages/api/src/router/import.test.ts | 12 +- packages/api/src/router/maintenance.test.ts | 4 +- packages/api/src/router/monitor.test.ts | 214 +++--- packages/api/src/router/notification.test.ts | 4 +- packages/api/src/router/page.ts | 4 - packages/api/src/router/pageComponent.test.ts | 4 +- .../api/src/router/privateLocation.test.ts | 126 ++-- .../api/src/router/statusPage.e2e.test.ts | 5 +- .../src/router/statusPage.unsubscribe.test.ts | 4 +- .../api/src/router/statusPage.utils.test.ts | 4 +- packages/api/src/router/statusReport.test.ts | 4 +- packages/api/src/router/stripe/utils.test.ts | 4 +- .../api/src/router/tinybird/index.test.ts | 4 +- packages/api/src/router/workspace.test.ts | 3 +- packages/api/src/test/preload.ts | 12 - packages/api/src/test/upstash.mock.ts | 18 + packages/api/src/trpc.ts | 2 +- packages/api/test.importmap.json | 5 + packages/api/tsconfig.json | 5 +- packages/assertions/package.json | 4 +- packages/assertions/src/v1.ts | 2 +- packages/assertions/tsconfig.json | 3 - packages/db/env.ts | 3 +- packages/db/package.json | 22 +- packages/db/script/region-migration.test.ts | 4 +- .../src/schema/page_components/validation.ts | 2 +- packages/db/src/seed.mts | 30 +- packages/db/src/test/factories.ts | 50 ++ packages/db/src/utils/api-key.test.ts | 3 +- packages/db/tsconfig.json | 1 - packages/emails/package.json | 10 +- .../emails/src/client.integration.test.tsx | 5 +- packages/emails/src/client.test.ts | 49 +- packages/emails/tsconfig.json | 8 +- packages/error/package.json | 4 +- packages/header-analysis/package.json | 8 +- .../src/parser/x-vercel-cache.test.ts | 17 +- packages/icons/package.json | 1 + packages/importers/package.json | 7 +- .../src/providers/betterstack/client.test.ts | 16 +- .../src/providers/betterstack/mapper.test.ts | 3 +- .../providers/betterstack/provider.test.ts | 8 +- .../src/providers/instatus/client.test.ts | 18 +- .../src/providers/instatus/mapper.test.ts | 13 +- .../src/providers/instatus/provider.test.ts | 3 +- .../src/providers/statuspage/client.test.ts | 18 +- .../src/providers/statuspage/mapper.test.ts | 13 +- .../src/providers/statuspage/provider.test.ts | 3 +- packages/locales/package.json | 4 +- packages/notifications/base/package.json | 6 +- .../base/src/utils/duration.test.ts | 3 +- .../base/src/utils/incident.test.ts | 5 +- .../notifications/bird-whatsapp/package.json | 6 +- .../bird-whatsapp/src/index.test.ts | 36 +- .../notifications/bird-whatsapp/tsconfig.json | 4 +- packages/notifications/discord/package.json | 6 +- .../notifications/discord/src/index.test.ts | 40 +- packages/notifications/discord/tsconfig.json | 4 +- packages/notifications/email/package.json | 5 +- .../notifications/email/src/index.test.ts | 49 +- .../notifications/email/src/test-preload.ts | 10 + packages/notifications/email/tsconfig.json | 4 +- .../notifications/google-chat/package.json | 6 +- .../google-chat/src/index.test.ts | 35 +- .../notifications/google-chat/tsconfig.json | 4 +- .../notifications/grafana-oncall/package.json | 6 +- .../grafana-oncall/src/index.test.ts | 54 +- .../grafana-oncall/tsconfig.json | 4 +- packages/notifications/ms-teams/package.json | 6 +- .../notifications/ms-teams/src/index.test.ts | 28 +- packages/notifications/ms-teams/tsconfig.json | 4 +- packages/notifications/ntfy/package.json | 6 +- packages/notifications/ntfy/src/index.test.ts | 64 +- packages/notifications/ntfy/tsconfig.json | 4 +- packages/notifications/opsgenie/package.json | 6 +- .../notifications/opsgenie/src/index.test.ts | 36 +- packages/notifications/opsgenie/tsconfig.json | 4 +- packages/notifications/pagerduty/package.json | 6 +- .../notifications/pagerduty/src/index.test.ts | 46 +- .../notifications/pagerduty/tsconfig.json | 4 +- packages/notifications/slack/package.json | 6 +- .../notifications/slack/src/index.test.ts | 47 +- packages/notifications/slack/tsconfig.json | 4 +- packages/notifications/telegram/package.json | 6 +- .../notifications/telegram/src/index.test.ts | 54 +- packages/notifications/telegram/tsconfig.json | 4 +- .../notifications/twillio-sms/package.json | 6 +- .../twillio-sms/src/index.test.ts | 35 +- .../notifications/twillio-sms/tsconfig.json | 4 +- packages/notifications/webhook/package.json | 6 +- .../notifications/webhook/src/index.test.ts | 76 +- packages/proto/package.json | 3 +- packages/regions/package.json | 4 +- packages/services/package.json | 6 +- packages/services/src/__tests__/retry.test.ts | 3 +- .../__tests__/with-test-transaction.test.ts | 4 +- .../src/__tests__/with-transaction.test.ts | 3 +- .../src/agent-tools/__tests__/docs.test.ts | 16 +- .../__tests__/shape-equivalence.test.ts | 3 +- .../__tests__/status-report-impacts.test.ts | 4 +- .../src/api-key/__tests__/api-key.test.ts | 18 +- .../src/audit/__tests__/audit.test.ts | 4 +- .../src/auth/__tests__/matches-scope.test.ts | 4 +- .../src/auth/__tests__/require-scope.test.ts | 3 +- .../external-service-component.test.ts | 4 +- .../__tests__/internal.test.ts | 3 +- .../external-service-incident.test.ts | 4 +- .../__tests__/record.test.ts | 4 +- .../__tests__/external-service.test.ts | 4 +- .../import/__tests__/incidents-phase.test.ts | 4 +- .../src/import/__tests__/unit.test.ts | 4 +- .../src/incident/__tests__/incident.test.ts | 4 +- .../__tests__/install-slack-agent.test.ts | 8 +- .../invitation/__tests__/invitation.test.ts | 18 +- .../maintenance/__tests__/maintenance.test.ts | 17 +- .../src/member/__tests__/member.test.ts | 6 +- .../monitor-tag/__tests__/monitor-tag.test.ts | 6 +- .../src/monitor/__tests__/monitor.test.ts | 26 +- .../src/monitor/__tests__/reads.test.ts | 4 +- .../__tests__/stream-monitor-preview.test.ts | 15 +- .../__tests__/notification.test.ts | 4 +- .../__tests__/get-daily-summary.test.ts | 4 +- .../__tests__/page-component.test.ts | 4 +- .../__tests__/page-subscriber.test.ts | 37 +- .../services/src/page/__tests__/page.test.ts | 4 +- .../__tests__/status-report.test.ts | 17 +- .../src/workspace/__tests__/workspace.test.ts | 16 +- packages/services/test/helpers.ts | 3 +- packages/services/tsconfig.json | 3 +- .../status-fetcher/__tests__/fetch.test.ts | 17 +- .../__tests__/fetchers/atlassian.test.ts | 20 +- .../__tests__/fetchers/betterstack.test.ts | 15 +- .../__tests__/fetchers/components.test.ts | 8 +- .../__tests__/fetchers/custom.test.ts | 3 +- .../__tests__/fetchers/edge-cases.test.ts | 4 +- .../__tests__/fetchers/html.test.ts | 8 +- .../__tests__/fetchers/incidentio.test.ts | 20 +- .../__tests__/fetchers/instatus.test.ts | 15 +- .../__tests__/fetchers/uptimerobot.test.ts | 13 +- packages/status-fetcher/__tests__/helpers.ts | 5 +- .../__tests__/integration.test.ts | 4 +- .../status-fetcher/__tests__/utils.test.ts | 3 +- packages/status-fetcher/package.json | 8 +- packages/status-fetcher/tsconfig.json | 1 - packages/subscriptions/package.json | 6 +- .../subscriptions/src/channels/email.test.ts | 52 +- .../subscriptions/src/channels/index.test.ts | 4 +- .../src/channels/webhook.test.ts | 131 ++-- packages/subscriptions/src/dispatcher.test.ts | 63 +- packages/subscriptions/src/test-preload.ts | 13 +- packages/subscriptions/tsconfig.json | 4 +- packages/test-utils/package.json | 20 + packages/test-utils/src/index.ts | 27 + packages/test-utils/src/matchers.ts | 95 +++ packages/test-utils/src/mock-fn.ts | 112 +++ packages/test-utils/src/runner.ts | 58 ++ packages/theme-store/package.json | 4 +- packages/tinybird/package.json | 3 + packages/tracker/package.json | 6 +- packages/tracker/src/mock.ts | 4 +- packages/tracker/src/tracker.test.ts | 20 +- packages/tracker/src/tracker.ts | 2 +- packages/tracker/tsconfig.json | 3 +- packages/upstash/package.json | 3 + packages/utils/package.json | 6 +- packages/utils/src/ssrf.test.ts | 3 +- pnpm-lock.yaml | 659 +++++++++++------- pnpm-workspace.yaml | 14 +- turbo.json | 1 + 534 files changed, 4804 insertions(+), 2975 deletions(-) create mode 100644 .github/workflows/check.yml delete mode 100644 apps/server/bunfig.toml create mode 100644 apps/server/deno.jsonc create mode 100644 apps/server/src/libs/test/doubles/analytics.mock.ts create mode 100644 apps/server/src/libs/test/doubles/page-urls.mock.ts create mode 100644 apps/server/src/libs/test/doubles/slack-agent.mock.ts create mode 100644 apps/server/src/libs/test/doubles/slack-test-state.ts create mode 100644 apps/server/src/libs/test/doubles/slack-web-api.mock.ts create mode 100644 apps/server/src/libs/test/doubles/state.ts create mode 100644 apps/server/src/libs/test/doubles/subscriptions.mock.ts create mode 100644 apps/server/src/libs/test/doubles/tinybird.mock.ts create mode 100644 apps/server/src/libs/test/doubles/upstash.mock.ts create mode 100644 apps/server/src/libs/test/doubles/workspace-resolver.mock.ts create mode 100644 apps/server/src/serve.ts create mode 100644 apps/server/test.importmap.json create mode 100644 apps/workflows/deno-migration-plan.md delete mode 100644 apps/workflows/src/build-docker.ts create mode 100644 apps/workflows/src/serve.ts create mode 100644 deno.lock delete mode 100644 packages/api/src/test/preload.ts create mode 100644 packages/api/src/test/upstash.mock.ts create mode 100644 packages/api/test.importmap.json create mode 100644 packages/db/src/test/factories.ts create mode 100644 packages/notifications/email/src/test-preload.ts create mode 100644 packages/test-utils/package.json create mode 100644 packages/test-utils/src/index.ts create mode 100644 packages/test-utils/src/matchers.ts create mode 100644 packages/test-utils/src/mock-fn.ts create mode 100644 packages/test-utils/src/runner.ts diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..19510a39 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,39 @@ +name: Check +on: + push: + branches: + - "main" + pull_request: + branches: [main] + +jobs: + check: + name: 🔍 Check + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.TURBO_TEAM }} + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v6 + + - name: Set up pnpm + uses: pnpm/action-setup@v6 + + - name: ⎔ Setup node + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: "pnpm" + + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + + - name: 📥 Download deps + run: pnpm install + + - name: 🔍 Check + run: pnpm check diff --git a/.github/workflows/dx.yml b/.github/workflows/dx.yml index 24e16afa..766bae46 100644 --- a/.github/workflows/dx.yml +++ b/.github/workflows/dx.yml @@ -41,10 +41,10 @@ jobs: - name: 📥 Download deps run: pnpm install - - name: 🔥 Install bun - uses: oven-sh/setup-bun@v2 + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 with: - bun-version: latest + deno-version: v2.x - name: 🔥 DX task run: pnpm dx diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 60003b7a..915d6aa7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@v6 - name: Set up pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v6 - name: ⎔ Setup node uses: actions/setup-node@v6 @@ -38,10 +38,10 @@ jobs: node-version: 24 cache: "pnpm" - - name: 🔥 Install bun - uses: oven-sh/setup-bun@v2 + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 with: - bun-version: latest + deno-version: v2.x - name: 📥 Download deps run: pnpm install diff --git a/apps/dashboard/env.ts b/apps/dashboard/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/dashboard/env.ts +++ b/apps/dashboard/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/screenshot-service/package.json b/apps/screenshot-service/package.json index 63c73984..4bd7feb4 100644 --- a/apps/screenshot-service/package.json +++ b/apps/screenshot-service/package.json @@ -2,6 +2,7 @@ "name": "@openstatus/screenshot-service", "version": "0.0.1", "scripts": { + "check": "deno check --sloppy-imports .", "dev": "bun run --hot src/index.ts", "start": "NODE_ENV=production bun run src/index.ts" }, diff --git a/apps/server/.gitignore b/apps/server/.gitignore index 3c3629e6..c1fbf070 100644 --- a/apps/server/.gitignore +++ b/apps/server/.gitignore @@ -1 +1,5 @@ node_modules +app +src/_serve.bundle.mjs +.deno_compile_bundle_*.mjs +app.tmp-* diff --git a/apps/server/Dockerfile b/apps/server/Dockerfile index f4c19c32..178df222 100644 --- a/apps/server/Dockerfile +++ b/apps/server/Dockerfile @@ -3,9 +3,9 @@ # See https://github.com/lenra-io/dofigen # install -FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install +FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install LABEL \ - org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ + org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ @@ -48,14 +48,14 @@ RUN \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <({ const logger = getLogger("api-server"); const otelLogger = getLogger("api-server-otel"); +const openapiYaml = await Deno.readTextFile( + new URL("../static/openapi.yaml", import.meta.url), +); + /** * Configure logging asynchronously without blocking module initialization. * This allows tests to import `app` immediately. */ -const defaultLogger = getOpenTelemetrySink({ - serviceName: "openstatus-server", - otlpExporterConfig: { - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env.AXIOM_TOKEN}`, - "X-Axiom-Dataset": env.AXIOM_DATASET, - }, - }, - additionalResource: resourceFromAttributes({ +// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` +// includes it. Letting @logtape/otel create the exporter triggers a dynamic +// import of a bare specifier, which the compiled --node-modules-dir=none binary +// can't resolve. +const loggerProvider = new LoggerProvider({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: "openstatus-server", [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env.NODE_ENV, }), + processors: [ + new BatchLogRecordProcessor( + new OTLPLogExporter({ + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env.AXIOM_TOKEN}`, + "X-Axiom-Dataset": env.AXIOM_DATASET, + }, + }), + ), + ], +}); + +const defaultLogger = getOpenTelemetrySink({ + loggerProvider, }); await configure({ @@ -166,7 +187,7 @@ app.use("*", async (c, next) => { // Console logging only for errors in production if (env.NODE_ENV !== "production" || c.res.status >= 500) { logger.info("request", { - request_id: requestId, + request_id: reqId, method: c.req.method, path: c.req.path, status_code: c.res.status, @@ -263,13 +284,6 @@ app.route("/mcp", mcpRoute); * create incidents, and send notifications. */ -const isDev = process.env.NODE_ENV === "development"; -const port = 3000; - -if (isDev) showRoutes(app, { verbose: true, colorize: true }); - -logger.info("Starting server", { port, environment: env.NODE_ENV }); - -const server = { port, fetch: app.fetch }; - -export default server; +if (process.env.NODE_ENV === "development") { + showRoutes(app, { verbose: true, colorize: true }); +} diff --git a/apps/server/src/libs/middlewares/require-scope.test.ts b/apps/server/src/libs/middlewares/require-scope.test.ts index 05818307..f1f0962a 100644 --- a/apps/server/src/libs/middlewares/require-scope.test.ts +++ b/apps/server/src/libs/middlewares/require-scope.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Scope } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import type { Variables } from "@/types"; diff --git a/apps/server/src/libs/middlewares/validate-key.test.ts b/apps/server/src/libs/middlewares/validate-key.test.ts index 28527fb1..58f5355a 100644 --- a/apps/server/src/libs/middlewares/validate-key.test.ts +++ b/apps/server/src/libs/middlewares/validate-key.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { validateKey } from "./auth"; diff --git a/apps/server/src/libs/test/doubles/analytics.mock.ts b/apps/server/src/libs/test/doubles/analytics.mock.ts new file mode 100644 index 00000000..dfe71343 --- /dev/null +++ b/apps/server/src/libs/test/doubles/analytics.mock.ts @@ -0,0 +1,26 @@ +// Test double for @openstatus/analytics, swapped in via --import-map. Keeps the +// real Events/parseInputToProps but replaces setupAnalytics with a spy (exposed +// on globalThis.__analyticsSpies) so tests assert tracking without OpenPanel. +export { + type EventProps, + Events, + parseInputToProps, +} from "@openstatus/analytics-real"; + +import { mock } from "@openstatus/test-utils"; + +const g = globalThis as Record; +if (!g.__analyticsSpies) { + const track = mock(() => Promise.resolve()); + g.__analyticsSpies = { + track, + setupAnalytics: mock((_props: unknown) => Promise.resolve({ track })), + }; +} + +const spies = g.__analyticsSpies as { + track: ReturnType; + setupAnalytics: ReturnType; +}; + +export const setupAnalytics = (props: unknown) => spies.setupAnalytics(props); diff --git a/apps/server/src/libs/test/doubles/page-urls.mock.ts b/apps/server/src/libs/test/doubles/page-urls.mock.ts new file mode 100644 index 00000000..b4e18132 --- /dev/null +++ b/apps/server/src/libs/test/doubles/page-urls.mock.ts @@ -0,0 +1,10 @@ +// Test double for src/routes/slack/page-urls.ts (which hits the db), swapped in +// via --import-map so slack presenter tests get deterministic URLs. +export const getPageUrl = (_pageId: number): Promise => + Promise.resolve("https://example.openstatus.dev"); + +export const getReportUrl = ( + _pageId: number, + reportId: number, +): Promise => + Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`); diff --git a/apps/server/src/libs/test/doubles/slack-agent.mock.ts b/apps/server/src/libs/test/doubles/slack-agent.mock.ts new file mode 100644 index 00000000..ef4990b4 --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-agent.mock.ts @@ -0,0 +1,8 @@ +// Test double for slack/agent.ts (pulls in the AI SDK), swapped in via +// --import-map so handler tests don't run the real agent. +import { slackTestState } from "./slack-test-state.ts"; + +export const runAgent = () => { + if (slackTestState.runAgentOverride) return slackTestState.runAgentOverride(); + return Promise.resolve({ text: "Here is my response", toolResults: [] }); +}; diff --git a/apps/server/src/libs/test/doubles/slack-test-state.ts b/apps/server/src/libs/test/doubles/slack-test-state.ts new file mode 100644 index 00000000..9d19743e --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-test-state.ts @@ -0,0 +1,33 @@ +// Mutable per-test config shared by the slack module doubles below. Replaces +// the per-file bun `mock.module` closures (handler.test / interactions.test): +// each test sets the fields it needs in beforeEach and reads `calls`. +type SlackCall = { method: string; args: Record }; +type Override = ((args: Record) => Promise) | null; + +export interface SlackTestState { + resolveWorkspace: (teamId: string) => Promise; + calls: SlackCall[]; + postMessageOverride: Override; + updateOverride: Override; + postEphemeralOverride: Override; + runAgentOverride: (() => Promise) | null; + repliesImpl: () => Promise; +} + +const g = globalThis as Record; +if (!g.__slackTestState) { + g.__slackTestState = { + resolveWorkspace: () => Promise.resolve(null), + calls: [], + postMessageOverride: null, + updateOverride: null, + postEphemeralOverride: null, + runAgentOverride: null, + repliesImpl: () => + Promise.resolve({ + messages: [{ user: "U1", text: "test message", ts: "1.1" }], + }), + } satisfies SlackTestState; +} + +export const slackTestState = g.__slackTestState as SlackTestState; diff --git a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts new file mode 100644 index 00000000..fd8d3c93 --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts @@ -0,0 +1,26 @@ +// Test double for @slack/web-api (only WebClient is used), swapped in via +// --import-map. Captures chat calls into the shared slack test state. +import { slackTestState as s } from "./slack-test-state.ts"; + +export class WebClient { + chat = { + postMessage: (args: Record) => { + if (s.postMessageOverride) return s.postMessageOverride(args); + s.calls.push({ method: "postMessage", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + update: (args: Record) => { + if (s.updateOverride) return s.updateOverride(args); + s.calls.push({ method: "update", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + postEphemeral: (args: Record) => { + if (s.postEphemeralOverride) return s.postEphemeralOverride(args); + s.calls.push({ method: "postEphemeral", args }); + return Promise.resolve(); + }, + }; + conversations = { + replies: () => s.repliesImpl(), + }; +} diff --git a/apps/server/src/libs/test/doubles/state.ts b/apps/server/src/libs/test/doubles/state.ts new file mode 100644 index 00000000..ec223907 --- /dev/null +++ b/apps/server/src/libs/test/doubles/state.ts @@ -0,0 +1,49 @@ +// Shared test-double state, set on globalThis so tests can assert on spies and +// configure mock data — same interface the old bun `mock.module` preload +// exposed. Imported (for side effect) by every double module below. +import { mock } from "@openstatus/test-utils"; + +type Mut = Record; +const g = globalThis as Mut; + +if (!g.__subscriptionSpies) { + const sendVerification = mock(() => Promise.resolve()); + g.__subscriptionSpies = { + dispatchStatusReportUpdate: mock(() => Promise.resolve()), + dispatchMaintenanceUpdate: mock(() => Promise.resolve()), + sendVerification, + getChannel: { + id: "email", + sendVerification, + sendNotifications: mock(() => Promise.resolve()), + validateConfig: mock(() => Promise.resolve({ valid: true })), + }, + }; +} + +if (!g.__testRedisStore) { + g.__testRedisStore = new Map(); +} + +if (!g.__tinybirdMockData) { + g.__tinybirdMockData = { httpListBiweekly: [], httpGetBiweekly: [] }; +} +if (!g.__tinybirdMockCalls) { + g.__tinybirdMockCalls = { httpListBiweekly: [], httpGetBiweekly: [] }; +} + +export const subscriptionSpies = g.__subscriptionSpies as { + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; + sendVerification: ReturnType; + getChannel: Record; +}; +export const testRedisStore = g.__testRedisStore as Map; +export const tinybirdMockData = g.__tinybirdMockData as { + httpListBiweekly: unknown[]; + httpGetBiweekly: unknown[]; +}; +export const tinybirdMockCalls = g.__tinybirdMockCalls as { + httpListBiweekly: unknown[]; + httpGetBiweekly: unknown[]; +}; diff --git a/apps/server/src/libs/test/doubles/subscriptions.mock.ts b/apps/server/src/libs/test/doubles/subscriptions.mock.ts new file mode 100644 index 00000000..aaf5f297 --- /dev/null +++ b/apps/server/src/libs/test/doubles/subscriptions.mock.ts @@ -0,0 +1,11 @@ +// Test double for @openstatus/subscriptions, swapped in via --import-map. +// Re-exports the real module, overriding only the dispatch fns and getChannel +// with spies (exposed on globalThis via state.ts) so route tests can assert +// notification side effects without sending anything. +export * from "@openstatus/subscriptions-real"; + +import { subscriptionSpies as spies } from "./state.ts"; + +export const dispatchStatusReportUpdate = spies.dispatchStatusReportUpdate; +export const dispatchMaintenanceUpdate = spies.dispatchMaintenanceUpdate; +export const getChannel = () => spies.getChannel; diff --git a/apps/server/src/libs/test/doubles/tinybird.mock.ts b/apps/server/src/libs/test/doubles/tinybird.mock.ts new file mode 100644 index 00000000..2cf71dab --- /dev/null +++ b/apps/server/src/libs/test/doubles/tinybird.mock.ts @@ -0,0 +1,59 @@ +// Test double for @openstatus/tinybird, swapped in via --import-map. Overrides +// OSTinybird with a no-network stub backed by `__tinybirdMockData/Calls`, while +// re-exporting the real Tinybird/AuditLog/etc. for code that imports them. +export * from "@openstatus/tinybird-real"; + +import { + tinybirdMockCalls as calls, + tinybirdMockData as data, +} from "./state.ts"; + +const empty = () => Promise.resolve({ data: [] }); + +export class OSTinybird { + get legacy_httpStatus45d() { + return empty; + } + get legacy_tcpStatus45d() { + return empty; + } + get httpListBiweekly() { + return (params: unknown) => { + calls.httpListBiweekly.push(params); + return Promise.resolve({ data: data.httpListBiweekly }); + }; + } + get httpGetBiweekly() { + return (params: unknown) => { + calls.httpGetBiweekly.push(params); + return Promise.resolve({ data: data.httpGetBiweekly }); + }; + } + get httpMetricsDaily() { + return empty; + } + get httpMetricsWeekly() { + return empty; + } + get httpMetricsBiweekly() { + return empty; + } + get tcpMetricsDaily() { + return empty; + } + get tcpMetricsWeekly() { + return empty; + } + get tcpMetricsBiweekly() { + return empty; + } + get dnsMetricsDaily() { + return empty; + } + get dnsMetricsWeekly() { + return empty; + } + get dnsMetricsBiweekly() { + return empty; + } +} diff --git a/apps/server/src/libs/test/doubles/upstash.mock.ts b/apps/server/src/libs/test/doubles/upstash.mock.ts new file mode 100644 index 00000000..b4dc5fb2 --- /dev/null +++ b/apps/server/src/libs/test/doubles/upstash.mock.ts @@ -0,0 +1,36 @@ +// Test double for @openstatus/upstash, swapped in via --import-map. Backs the +// Redis client with the in-memory `__testRedisStore` Map so tests can assert +// on stored state without a real Upstash instance. +import { testRedisStore as store } from "./state.ts"; + +const client = { + get: (key: string) => Promise.resolve(store.get(key) ?? null), + set: (key: string, value: string) => { + store.set(key, value); + return Promise.resolve("OK"); + }, + del: (key: string) => { + const existed = store.has(key) ? 1 : 0; + store.delete(key); + return Promise.resolve(existed); + }, + getdel: (key: string) => { + const value = store.get(key) ?? null; + store.delete(key); + return Promise.resolve(value); + }, + incr: (key: string) => { + const next = Number(store.get(key) ?? 0) + 1; + store.set(key, String(next)); + return Promise.resolve(next); + }, + expire: () => Promise.resolve(1), +}; + +export const redis = client; + +export const Redis = { + fromEnv() { + return client; + }, +}; diff --git a/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts b/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts new file mode 100644 index 00000000..8766b79e --- /dev/null +++ b/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts @@ -0,0 +1,6 @@ +// Test double for slack/workspace-resolver.ts (hits the db), swapped in via +// --import-map. Delegates to the per-test resolver in the shared slack state. +import { slackTestState } from "./slack-test-state.ts"; + +export const resolveWorkspace = (teamId: string) => + slackTestState.resolveWorkspace(teamId); diff --git a/apps/server/src/libs/test/preload.ts b/apps/server/src/libs/test/preload.ts index a2efeadb..232bf7f9 100644 --- a/apps/server/src/libs/test/preload.ts +++ b/apps/server/src/libs/test/preload.ts @@ -1,9 +1,8 @@ -import { mock } from "bun:test"; - // Import the real module BEFORE mock.module runs so we can spread real // service functions (createSubscription, updateChannel, etc.) into the // replacement while still stubbing the dispatch-side spies. import * as realSubscriptions from "@openstatus/subscriptions"; +import { mock } from "@openstatus/test-utils"; // Subscription dispatch spies — accessible in tests via globalThis.__subscriptionSpies const dispatchStatusReportUpdateSpy = mock((_id: number) => Promise.resolve()); diff --git a/apps/server/src/routes/mcp/adapter.test.ts b/apps/server/src/routes/mcp/adapter.test.ts index b5944189..b1a00d1a 100644 --- a/apps/server/src/routes/mcp/adapter.test.ts +++ b/apps/server/src/routes/mcp/adapter.test.ts @@ -1,7 +1,7 @@ -import { describe, expect, test } from "bun:test"; - import type { Workspace } from "@openstatus/db/src/schema"; import { ForbiddenError, NotFoundError } from "@openstatus/services"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { mapError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/mcp/adapter.ts b/apps/server/src/routes/mcp/adapter.ts index b19ede15..2f3d2a7d 100644 --- a/apps/server/src/routes/mcp/adapter.ts +++ b/apps/server/src/routes/mcp/adapter.ts @@ -1,5 +1,5 @@ -import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js"; import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { type ServiceContext, ServiceError } from "@openstatus/services"; import { ZodError } from "zod"; diff --git a/apps/server/src/routes/mcp/handler.test.ts b/apps/server/src/routes/mcp/handler.test.ts index baa6efc0..46ba666c 100644 --- a/apps/server/src/routes/mcp/handler.test.ts +++ b/apps/server/src/routes/mcp/handler.test.ts @@ -1,14 +1,13 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { sentry } from "@hono/sentry"; import { db, desc, eq } from "@openstatus/db"; import { auditLog, page, statusReport } from "@openstatus/db/src/schema"; import { SEEDED_WORKSPACE_TEAM_ID } from "@openstatus/services/test/fixtures"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { requestId } from "hono/request-id"; -import { handleError } from "@/libs/errors"; - +import { handleError } from "../../libs/errors"; import { mcpRoute } from "./index"; /** diff --git a/apps/server/src/routes/mcp/index.ts b/apps/server/src/routes/mcp/index.ts index 419f324c..822c47f4 100644 --- a/apps/server/src/routes/mcp/index.ts +++ b/apps/server/src/routes/mcp/index.ts @@ -1,10 +1,9 @@ import { StreamableHTTPTransport } from "@hono/mcp"; import { Hono } from "hono"; -import { handleError } from "@/libs/errors"; -import { authMiddleware } from "@/libs/middlewares/auth"; -import type { Variables } from "@/types"; - +import { handleError } from "../../libs/errors"; +import { authMiddleware } from "../../libs/middlewares/auth"; +import type { Variables } from "../../types"; import { toServiceCtx } from "./adapter"; import { createMcpServer } from "./server"; diff --git a/apps/server/src/routes/mcp/tools/register-scoped.test.ts b/apps/server/src/routes/mcp/tools/register-scoped.test.ts index f853a8f7..3b5eae6f 100644 --- a/apps/server/src/routes/mcp/tools/register-scoped.test.ts +++ b/apps/server/src/routes/mcp/tools/register-scoped.test.ts @@ -1,8 +1,8 @@ -import { describe, expect, test } from "bun:test"; - import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { Workspace } from "@openstatus/db/src/schema"; import type { ServiceContext } from "@openstatus/services"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { registerScopedTool } from "./register-scoped"; diff --git a/apps/server/src/routes/mcp/tools/tools.test.ts b/apps/server/src/routes/mcp/tools/tools.test.ts index 0d64855a..3e4e82b3 100644 --- a/apps/server/src/routes/mcp/tools/tools.test.ts +++ b/apps/server/src/routes/mcp/tools/tools.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { db, eq } from "@openstatus/db"; import { @@ -21,6 +19,8 @@ import { readAuditLog, withTestTransaction, } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { toServiceCtx } from "../adapter"; import { registerMaintenanceTools } from "./maintenance"; diff --git a/apps/server/src/routes/public/status.test.ts b/apps/server/src/routes/public/status.test.ts index 49c71237..679c461e 100644 --- a/apps/server/src/routes/public/status.test.ts +++ b/apps/server/src/routes/public/status.test.ts @@ -1,15 +1,14 @@ +import { db, eq } from "@openstatus/db"; +import { expect } from "@std/expect"; import { afterAll, beforeAll, beforeEach, describe, - expect, test, -} from "bun:test"; - -import { db, eq } from "@openstatus/db"; +} from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../index"; const testRedisStore = (globalThis as Record) .__testRedisStore as Map | undefined; diff --git a/apps/server/src/routes/public/status.ts b/apps/server/src/routes/public/status.ts index 04941603..dc115266 100644 --- a/apps/server/src/routes/public/status.ts +++ b/apps/server/src/routes/public/status.ts @@ -7,7 +7,7 @@ import { endTime, setMetric, startTime } from "hono/timing"; const logger = getLogger("api-server"); import { Status, Tracker } from "@openstatus/tracker"; -import { redis } from "@/libs/clients"; +import { redis } from "../../libs/clients"; // TODO: include ratelimiting diff --git a/apps/server/src/routes/rpc/adapter.test.ts b/apps/server/src/routes/rpc/adapter.test.ts index d5f02493..381bfa33 100644 --- a/apps/server/src/routes/rpc/adapter.test.ts +++ b/apps/server/src/routes/rpc/adapter.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { Code, ConnectError } from "@connectrpc/connect"; import type { Workspace } from "@openstatus/db/src/schema"; import { @@ -14,6 +12,8 @@ import { loadSeededWorkspace, withTestTransaction, } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { toConnectError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts index 874d96f6..bfedbb0d 100644 --- a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts +++ b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -7,14 +5,19 @@ import { page, pageComponent, pageSubscriber, + workspace, } from "@openstatus/db/src/schema"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { nanoid } from "nanoid"; -import { app } from "@/index"; +import { app } from "../../../../../index"; const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -40,6 +43,14 @@ async function connectRequest( } const TEST_PREFIX = "rpc-maintenance-test"; +// Scoped to a dedicated workspace+page so parallel suites mutating the +// shared seed workspace 1 / page 1 can't delete our fixtures mid-run. +// dev/test `validateKey` maps `x-openstatus-key` to the workspace id. +const WORKSPACE_LIMITS = + '{"monitors":50,"synthetic-checks":150000,"periodicity":["30s","1m","5m","10m","30m","1h"],"multi-region":true,"max-regions":35,"data-retention":"24 months","status-pages":20,"maintenance":true,"status-subscribers":true,"custom-domain":true,"password-protection":true,"email-domain-protection":true,"white-label":true,"notifications":true,"sms":true,"pagerduty":true,"notification-channels":50,"members":"Unlimited","audit-log":true}'; +let testWorkspaceId: number; +let authKey: string; +let testPageId: number; let testPageComponentId: number; let testMaintenanceId: number; let testMaintenanceToDeleteId: number; @@ -51,26 +62,39 @@ let testPage2Id: number; let testPage2ComponentId: number; beforeAll(async () => { - // Clean up any existing test data - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-main`)); - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-to-delete`)); - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-to-update`)); - await db - .delete(pageComponent) - .where(eq(pageComponent.name, `${TEST_PREFIX}-component`)); + const ws = await db + .insert(workspace) + .values({ + slug: `${TEST_PREFIX}-ws-${nanoid(8)}`, + name: `${TEST_PREFIX}-workspace`, + plan: "team", + limits: WORKSPACE_LIMITS, + }) + .returning() + .get(); + testWorkspaceId = ws.id; + authKey = String(testWorkspaceId); + + // Primary page for the suite (replaces shared seed page 1). + const mainPage = await db + .insert(page) + .values({ + workspaceId: testWorkspaceId, + title: `${TEST_PREFIX}-page`, + slug: `${TEST_PREFIX}-page-slug-${nanoid(8)}`, + description: "Primary test page for maintenance tests", + customDomain: "", + }) + .returning() + .get(); + testPageId = mainPage.id; - // Create a test page component (using existing page 1 from seed) + // Create a test page component on the suite's page const component = await db .insert(pageComponent) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, type: "static", name: `${TEST_PREFIX}-component`, description: "Test component for maintenance tests", @@ -84,9 +108,9 @@ beforeAll(async () => { const page2 = await db .insert(page) .values({ - workspaceId: 1, + workspaceId: testWorkspaceId, title: `${TEST_PREFIX}-page-2`, - slug: `${TEST_PREFIX}-page-2-slug`, + slug: `${TEST_PREFIX}-page-2-slug-${nanoid(8)}`, description: "Second test page for mixed-page tests", customDomain: "", }) @@ -97,7 +121,7 @@ beforeAll(async () => { const component2 = await db .insert(pageComponent) .values({ - workspaceId: 1, + workspaceId: testWorkspaceId, pageId: testPage2Id, type: "static", name: `${TEST_PREFIX}-component-2`, @@ -112,8 +136,8 @@ beforeAll(async () => { const maintenanceRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-main`, message: "Test maintenance message", from: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day from now @@ -133,8 +157,8 @@ beforeAll(async () => { const deleteRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-to-delete`, message: "Maintenance to delete", from: new Date(Date.now() + 48 * 60 * 60 * 1000), @@ -148,8 +172,8 @@ beforeAll(async () => { const updateRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-to-update`, message: "Maintenance to update", from: new Date(Date.now() + 72 * 60 * 60 * 1000), @@ -168,8 +192,8 @@ beforeAll(async () => { const notifyRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-for-notify`, message: "Maintenance for notify tests", from: new Date(Date.now() + 96 * 60 * 60 * 1000), @@ -188,7 +212,7 @@ beforeAll(async () => { const subscriber = await db .insert(pageSubscriber) .values({ - pageId: 1, + pageId: testPageId, email: `${TEST_PREFIX}@example.com`, token: `${TEST_PREFIX}-token`, acceptedAt: new Date(), @@ -248,6 +272,14 @@ afterAll(async () => { .delete(pageComponent) .where(eq(pageComponent.name, `${TEST_PREFIX}-component-2`)); await db.delete(page).where(eq(page.title, `${TEST_PREFIX}-page-2`)); + + // Tear down the dedicated page + workspace last (FK order). + if (testPageId) { + await db.delete(page).where(eq(page.id, testPageId)); + } + if (testWorkspaceId) { + await db.delete(workspace).where(eq(workspace.id, testWorkspaceId)); + } }); describe("MaintenanceService.CreateMaintenance", () => { @@ -262,10 +294,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Scheduled maintenance for system upgrade.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [String(testPageComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -303,8 +335,8 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", - pageComponentIds: ["1"], + pageId: String(testPageId), + pageComponentIds: [String(testPageComponentId)], }); expect(res.status).toBe(401); @@ -321,10 +353,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: ["99999"], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -341,13 +373,13 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [ String(testPageComponentId), String(testPage2ComponentId), ], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -368,10 +400,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test pageId mismatch with components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", // This doesn't match testPage2ComponentId's page + pageId: String(testPageId), // This doesn't match testPage2ComponentId's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -397,7 +429,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: String(testPage2Id), // Matching the component's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -441,10 +473,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Maintenance without components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -474,11 +506,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Notifying subscribers about this maintenance.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [String(testPageComponentId)], notify: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -519,11 +551,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "No notification for this one.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], notify: false, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -551,10 +583,10 @@ describe("MaintenanceService.CreateMaintenance", () => { to: new Date( Date.now() + 7 * 24 * 60 * 60 * 1000 + 3600000, ).toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -573,10 +605,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test with invalid date range.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -598,7 +630,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: "99999", pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -616,7 +648,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(testMaintenanceId) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -646,7 +678,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "99999" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -670,7 +702,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -683,7 +715,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -693,7 +725,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: " " }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -705,7 +737,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -720,7 +752,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -749,7 +781,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -763,7 +795,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res1 = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data1 = await res1.json(); const totalSize = data1.totalSize; @@ -773,7 +805,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res2 = await connectRequest( "ListMaintenances", { limit: 1, offset: 0 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data2 = await res2.json(); @@ -781,7 +813,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res3 = await connectRequest( "ListMaintenances", { limit: 1, offset: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data3 = await res3.json(); @@ -795,16 +827,16 @@ describe("MaintenanceService.ListMaintenances", () => { test("filters by page_id", async () => { const res = await connectRequest( "ListMaintenances", - { pageId: "1" }, - { "x-openstatus-key": "1" }, + { pageId: String(testPageId) }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); const data = await res.json(); - // All returned maintenances should have pageId 1 + // All returned maintenances should belong to the filtered page for (const record of data.maintenances || []) { - expect(record.pageId).toBe("1"); + expect(record.pageId).toBe(String(testPageId)); } }); @@ -826,7 +858,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -851,7 +883,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-updated-title`, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -874,7 +906,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), message: "Updated maintenance message", }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -890,21 +922,22 @@ describe("MaintenanceService.UpdateMaintenance", () => { }); test("updates page component associations", async () => { - // Use existing seeded page component 1 const res = await connectRequest( "UpdateMaintenance", { id: String(testMaintenanceToUpdateId), - pageComponentIds: ["1"], + pageComponentIds: [String(testPageComponentId)], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); const data = await res.json(); - expect(data.maintenance.pageComponentIds).toContain("1"); + expect(data.maintenance.pageComponentIds).toContain( + String(testPageComponentId), + ); }); test("returns 401 when no auth key provided", async () => { @@ -920,7 +953,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "99999", title: "Non-existent update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -930,7 +963,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "", title: "Empty ID update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -940,7 +973,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: " ", title: "Whitespace ID update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -964,7 +997,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: String(otherRecord.id), title: "Should not update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -981,7 +1014,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: ["99999"], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -998,7 +1031,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { ], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1024,7 +1057,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), from: newFrom.toISOString(), }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1055,7 +1088,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-title-only`, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1104,7 +1137,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageComponentIds: ["99999"], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1136,7 +1169,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageId: "999", }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1154,8 +1187,8 @@ describe("MaintenanceService.UpdateMaintenance", () => { const tempRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-clear-pageid`, message: "Temp maintenance for clear test", from: new Date(Date.now() + 24 * 60 * 60 * 1000), @@ -1177,7 +1210,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: [], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1209,7 +1242,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(testMaintenanceToDeleteId) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1236,7 +1269,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "99999" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -1246,7 +1279,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1256,7 +1289,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: " " }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1280,7 +1313,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); diff --git a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts index 7b9e19d9..2a6c33c7 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts @@ -1,12 +1,3 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { auditLog, @@ -14,10 +5,23 @@ import { pageComponent, privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; import { monitorStatusTable } from "@openstatus/db/src/schema/monitor_status/monitor_status"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -499,20 +503,17 @@ describe("MonitorService.DeleteMonitor", () => { }); test("cannot delete monitor from another workspace", async () => { - // Create a monitor for workspace 2 - const otherWorkspaceMon = await db - .insert(monitor) - .values({ - workspaceId: 2, - name: `${TEST_PREFIX}-delete-other-ws`, - url: "https://other-ws-delete.example.com", - periodicity: "1m", - active: true, - regions: "ams", - jobType: "http", - }) - .returning() - .get(); + // Isolated workspace (fresh, unique id) so this never collides with seed + // data or another suite mutating workspace 2 in parallel. + const otherWorkspace = await createWorkspace(); + const otherWorkspaceMon = await createMonitor(otherWorkspace.id, { + name: `${TEST_PREFIX}-delete-other-ws`, + url: "https://other-ws-delete.example.com", + periodicity: "1m", + active: true, + regions: "ams", + jobType: "http", + }); try { // Try to delete with workspace 1's key @@ -536,6 +537,7 @@ describe("MonitorService.DeleteMonitor", () => { expect(stillExists?.deletedAt).toBeNull(); } finally { await db.delete(monitor).where(eq(monitor.id, otherWorkspaceMon.id)); + await db.delete(workspace).where(eq(workspace.id, otherWorkspace.id)); } }); diff --git a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts index bce0efdc..c617b766 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts @@ -1,7 +1,7 @@ -import { describe, expect, test } from "bun:test"; - import { Region } from "@openstatus/proto/monitor/v1"; import { AVAILABLE_REGIONS, RAILWAY_REGIONS } from "@openstatus/regions"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { regionToString, @@ -20,13 +20,17 @@ describe("region converter", () => { ["railway_asia-southeast1-eqsg3a", Region.RAILWAY_ASIA_SOUTHEAST1], ]; - test.each(cases)("stringToRegion(%s) → enum", (db, proto) => { - expect(stringToRegion(db)).toBe(proto); - }); + for (const [db, proto] of cases) { + test(`stringToRegion(${db}) → enum`, () => { + expect(stringToRegion(db)).toBe(proto); + }); + } - test.each(cases)("regionToString(enum) → %s", (db, proto) => { - expect(regionToString(proto)).toBe(db); - }); + for (const [db, proto] of cases) { + test(`regionToString(enum) → ${db}`, () => { + expect(regionToString(proto)).toBe(db); + }); + } test("validateRegions accepts all Railway DB codes", () => { expect(validateRegions([...RAILWAY_REGIONS])).toEqual([]); diff --git a/apps/server/src/routes/rpc/handlers/monitor/index.ts b/apps/server/src/routes/rpc/handlers/monitor/index.ts index 3e7fda8a..e6a4522b 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/index.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/index.ts @@ -30,9 +30,8 @@ import { listResponseLogs, } from "@openstatus/services/monitor"; -import { env } from "@/env"; -import { getCheckerPayload, getCheckerUrl } from "@/libs/checker"; - +import { env } from "../../../../env"; +import { getCheckerPayload, getCheckerUrl } from "../../../../libs/checker"; import { toConnectError, toServiceCtx } from "../../adapter"; import { getRpcContext } from "../../interceptors"; import { diff --git a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts index 575dc685..315eb4df 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts @@ -1,6 +1,6 @@ -import { expect, test } from "bun:test"; - import { redactSensitiveHeaders } from "@openstatus/services/monitor"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; test("redactSensitiveHeaders returns an empty object when headers are missing", () => { expect(redactSensitiveHeaders(null)).toEqual({}); diff --git a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts index 87c9dde4..bf640a35 100644 --- a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts +++ b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts @@ -1,12 +1,12 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). diff --git a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts index 6daf779f..d153fd31 100644 --- a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNull, sql } from "@openstatus/db"; import { auditLog, @@ -11,8 +9,11 @@ import { statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -1720,7 +1721,7 @@ describe("StatusPageService.UpdateComponentGroup", () => { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - sendVerification: ReturnType; + sendVerification: ReturnType; }; describe("StatusPageService.SubscribeToPage", () => { diff --git a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts index 57e03d4c..03f4c58a 100644 --- a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, @@ -9,14 +7,18 @@ import { statusReportUpdate, statusReportUpdateToPageComponents, statusReportsToPageComponents, + workspace, } from "@openstatus/db/src/schema"; +import { createWorkspace } from "@openstatus/db/src/test/factories"; import { PageComponentImpact, StatusReportStatus, } from "@openstatus/proto/status_report/v1"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; - +import { app } from "../../../../../index"; import { dbImpactToProto, protoImpactToDb, @@ -25,8 +27,8 @@ import { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -781,36 +783,64 @@ describe("StatusReportService.ListStatusReports", () => { }); test("respects offset parameter", async () => { - // Get total count first - const res1 = await connectRequest( - "ListStatusReports", - {}, - { "x-openstatus-key": "1" }, - ); - const data1 = await res1.json(); - const totalSize = data1.totalSize; + // Isolate in a dedicated workspace so concurrent inserts from other suites + // can't shift the pagination window mid-test. In dev/test the + // `x-openstatus-key` header is the workspace id. Distinct createdAt values + // give the `desc(createdAt)` order a deterministic sequence. + const ws = await createWorkspace(); + const key = String(ws.id); + const now = Date.now(); + const inserted = await db + .insert(statusReport) + .values([ + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-1`, + status: "investigating", + createdAt: new Date(now - 2000), + }, + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-2`, + status: "investigating", + createdAt: new Date(now - 1000), + }, + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-3`, + status: "investigating", + createdAt: new Date(now), + }, + ]) + .returning(); - if (totalSize > 1) { - // Get first page - const res2 = await connectRequest( + try { + const total = await connectRequest( "ListStatusReports", - { limit: 1, offset: 0 }, - { "x-openstatus-key": "1" }, + {}, + { "x-openstatus-key": key }, ); - const data2 = await res2.json(); + expect((await total.json()).totalSize).toBe(inserted.length); - // Get second page - const res3 = await connectRequest( + const page1 = await connectRequest( + "ListStatusReports", + { limit: 1, offset: 0 }, + { "x-openstatus-key": key }, + ); + const page2 = await connectRequest( "ListStatusReports", { limit: 1, offset: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": key }, ); - const data3 = await res3.json(); + const data1 = await page1.json(); + const data2 = await page2.json(); - // Should have different reports - if (data2.statusReports?.length > 0 && data3.statusReports?.length > 0) { - expect(data2.statusReports[0].id).not.toBe(data3.statusReports[0].id); - } + expect(data1.statusReports).toHaveLength(1); + expect(data2.statusReports).toHaveLength(1); + expect(data1.statusReports[0].id).not.toBe(data2.statusReports[0].id); + } finally { + await db.delete(statusReport).where(eq(statusReport.workspaceId, ws.id)); + await db.delete(workspace).where(eq(workspace.id, ws.id)); } }); diff --git a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts index d79ebb00..234213c1 100644 --- a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts +++ b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts @@ -1,35 +1,26 @@ -// @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) -// are incompatible with bun:test mocks. All runtime behavior is correct. -import { beforeEach, describe, expect, mock, test } from "bun:test"; - import type { Interceptor } from "@connectrpc/connect"; import { Events } from "@openstatus/analytics"; +// @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) +// are incompatible with bun:test mocks. All runtime behavior is correct. +import { + beforeEach, + describe, + expect, + mock, + test, +} from "@openstatus/test-utils"; import { RPC_CONTEXT_KEY } from "../auth"; import { RPC_EVENT_MAP, trackingInterceptor } from "../tracking"; -// Mock analytics -const mockTrack = mock(() => Promise.resolve()); -const mockSetupAnalytics = mock((_props: unknown) => - Promise.resolve({ track: mockTrack }), -); - -mock.module("@openstatus/analytics", () => ({ - Events, - parseInputToProps: (json: unknown, props?: string[]) => { - if (typeof json !== "object" || json === null || !props) return {}; - return props.reduce( - (acc, prop) => { - if (prop in json) { - acc[prop] = (json as Record)[prop]; - } - return acc; - }, - {} as Record, - ); - }, - setupAnalytics: (props: unknown) => mockSetupAnalytics(props), -})); +// @openstatus/analytics is swapped for a double (test.importmap.json) whose +// setupAnalytics/track spies are exposed here on globalThis. +const { track: mockTrack, setupAnalytics: mockSetupAnalytics } = ( + globalThis as Record +).__analyticsSpies as { + track: ReturnType; + setupAnalytics: ReturnType; +}; type NextFn = Parameters>[0]; diff --git a/apps/server/src/routes/rpc/interceptors/auth.ts b/apps/server/src/routes/rpc/interceptors/auth.ts index ef72d8a6..72171178 100644 --- a/apps/server/src/routes/rpc/interceptors/auth.ts +++ b/apps/server/src/routes/rpc/interceptors/auth.ts @@ -7,7 +7,7 @@ import { import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { nanoid } from "nanoid"; -import { lookupWorkspace, validateKey } from "@/libs/middlewares/auth"; +import { lookupWorkspace, validateKey } from "../../../libs/middlewares/auth"; /** * RPC context containing workspace and request information. diff --git a/apps/server/src/routes/slack/blocks.test.ts b/apps/server/src/routes/slack/blocks.test.ts index 65cd22be..ceac36c3 100644 --- a/apps/server/src/routes/slack/blocks.test.ts +++ b/apps/server/src/routes/slack/blocks.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { agentTools } from "@openstatus/services/agent-tools"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildConfirmationBlocks, diff --git a/apps/server/src/routes/slack/confirmation-store.test.ts b/apps/server/src/routes/slack/confirmation-store.test.ts index 4964d393..93e7a211 100644 --- a/apps/server/src/routes/slack/confirmation-store.test.ts +++ b/apps/server/src/routes/slack/confirmation-store.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import { consume, diff --git a/apps/server/src/routes/slack/handler.test.ts b/apps/server/src/routes/slack/handler.test.ts index 86e01f69..0bfcfbad 100644 --- a/apps/server/src/routes/slack/handler.test.ts +++ b/apps/server/src/routes/slack/handler.test.ts @@ -1,84 +1,20 @@ -import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; +import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; -import * as agentModule from "./agent"; +// workspace-resolver / @slack/web-api / agent are swapped for doubles via the +// test import map; behavior is driven through this shared mutable state. +import { slackTestState } from "@/libs/test/doubles/slack-test-state"; + +import { handleSlackEvent } from "./handler"; +import { verifySlackSignature } from "./verify"; const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; process.env.AI_GATEWAY_API_KEY = "test-key"; -mock.module("./workspace-resolver", () => ({ - resolveWorkspace: (teamId: string) => { - if (teamId === "T_KNOWN") { - return Promise.resolve({ - workspace: { - id: 1, - name: "Test Workspace", - slug: "test", - plan: "free", - limits: {}, - }, - botToken: "xoxb-test", - botUserId: "UBOT", - }); - } - return Promise.resolve(null); - }, -})); - -let slackMessages: Array<{ method: string; args: Record }> = - []; -let postMessageOverride: - | ((args: Record) => Promise<{ ts: string }>) - | null = null; -let updateOverride: - | ((args: Record) => Promise<{ ts: string }>) - | null = null; - -mock.module("@slack/web-api", () => ({ - WebClient: class { - chat = { - postMessage: (args: Record) => { - if (postMessageOverride) return postMessageOverride(args); - slackMessages.push({ method: "postMessage", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - update: (args: Record) => { - if (updateOverride) return updateOverride(args); - slackMessages.push({ method: "update", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - }; - conversations = { - replies: () => - Promise.resolve({ - messages: [{ user: "U1", text: "test message", ts: "1.1" }], - }), - }; - }, -})); - -let runAgentOverride: - | (() => Promise<{ text: string; toolResults: never[] }>) - | null = null; - -mock.module("./agent", () => ({ - ...agentModule, - runAgent: () => { - if (runAgentOverride) return runAgentOverride(); - return Promise.resolve({ - text: "Here is my response", - toolResults: [], - }); - }, -})); - -const { handleSlackEvent } = await import("./handler"); -const { verifySlackSignature } = await import("./verify"); - function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); app.post("/slack/events", verifySlackSignature, handleSlackEvent); @@ -112,10 +48,26 @@ describe("handleSlackEvent", () => { const app = createTestApp(); beforeEach(() => { - slackMessages = []; - postMessageOverride = null; - updateOverride = null; - runAgentOverride = null; + slackTestState.calls = []; + slackTestState.postMessageOverride = null; + slackTestState.updateOverride = null; + slackTestState.runAgentOverride = null; + slackTestState.resolveWorkspace = (teamId: string) => { + if (teamId === "T_KNOWN") { + return Promise.resolve({ + workspace: { + id: 1, + name: "Test Workspace", + slug: "test", + plan: "free", + limits: {}, + }, + botToken: "xoxb-test", + botUserId: "UBOT", + }); + } + return Promise.resolve(null); + }; }); test("responds to url_verification challenge", async () => { @@ -202,11 +154,11 @@ describe("handleSlackEvent", () => { await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - slackMessages = []; + slackTestState.calls = []; await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events from unknown teams", async () => { @@ -225,7 +177,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores message events from bots", async () => { @@ -244,7 +196,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel message without bot mention", async () => { @@ -264,7 +216,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("processes DM messages without bot mention", async () => { @@ -285,7 +237,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); // DM should trigger a response (postMessage for "Thinking...") - expect(slackMessages.length).toBeGreaterThan(0); + expect(slackTestState.calls.length).toBeGreaterThan(0); }); test("ignores events without channel", async () => { @@ -303,7 +255,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events without timestamp", async () => { @@ -321,7 +273,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events without team_id", async () => { @@ -339,7 +291,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores unsupported event types", async () => { @@ -354,7 +306,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel_join system messages", async () => { @@ -374,7 +326,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel_leave system messages", async () => { @@ -394,7 +346,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events with no event payload", async () => { @@ -406,12 +358,12 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("falls back to top-level message on cannot_reply_to_message", async () => { let callCount = 0; - postMessageOverride = (args: Record) => { + slackTestState.postMessageOverride = (args: Record) => { callCount++; if (callCount === 1) { const err = new Error("An API error occurred: cannot_reply_to_message"); @@ -421,7 +373,7 @@ describe("handleSlackEvent", () => { }); return Promise.reject(err); } - slackMessages.push({ method: "postMessage", args }); + slackTestState.calls.push({ method: "postMessage", args }); return Promise.resolve({ ts: "fallback.ts" }); }; @@ -441,14 +393,14 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const fallbackPost = slackMessages.find( + const fallbackPost = slackTestState.calls.find( (m) => m.method === "postMessage" && !m.args.thread_ts, ); expect(fallbackPost).toBeDefined(); }); test("returns early on non-recoverable postMessage error", async () => { - postMessageOverride = () => { + slackTestState.postMessageOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", @@ -473,12 +425,15 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const updateMessages = slackMessages.filter((m) => m.method === "update"); + const updateMessages = slackTestState.calls.filter( + (m) => m.method === "update", + ); expect(updateMessages.length).toBe(0); }); test("shows error message when runAgent throws", async () => { - runAgentOverride = () => Promise.reject(new Error("agent exploded")); + slackTestState.runAgentOverride = () => + Promise.reject(new Error("agent exploded")); const res = await signAndPost(app, { type: "event_callback", @@ -496,7 +451,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const errorUpdate = slackMessages.find( + const errorUpdate = slackTestState.calls.find( (m) => m.method === "update" && typeof m.args.text === "string" && @@ -506,8 +461,9 @@ describe("handleSlackEvent", () => { }); test("does not throw when both runAgent and error update fail", async () => { - runAgentOverride = () => Promise.reject(new Error("agent exploded")); - updateOverride = () => { + slackTestState.runAgentOverride = () => + Promise.reject(new Error("agent exploded")); + slackTestState.updateOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", diff --git a/apps/server/src/routes/slack/index.test.ts b/apps/server/src/routes/slack/index.test.ts index 54983660..89c34b80 100644 --- a/apps/server/src/routes/slack/index.test.ts +++ b/apps/server/src/routes/slack/index.test.ts @@ -1,6 +1,7 @@ -import { beforeEach, describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; const SIGNING_SECRET = "test-signing-secret"; diff --git a/apps/server/src/routes/slack/interactions.test.ts b/apps/server/src/routes/slack/interactions.test.ts index a056ce6d..98be8198 100644 --- a/apps/server/src/routes/slack/interactions.test.ts +++ b/apps/server/src/routes/slack/interactions.test.ts @@ -1,8 +1,15 @@ -import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; +import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; +// workspace-resolver / @slack/web-api are swapped for doubles via the test +// import map; behavior is driven through this shared mutable state. +import { slackTestState } from "@/libs/test/doubles/slack-test-state"; + +import { handleSlackInteraction } from "./interactions"; +import { verifySlackSignature } from "./verify"; + const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; @@ -22,34 +29,13 @@ const basePending = { createdAt: Date.now(), }; -mock.module("./workspace-resolver", () => ({ - resolveWorkspace: (teamId: string) => { - if (teamId === "T_KNOWN") { - return Promise.resolve({ botToken: "xoxb-fallback" }); - } - return Promise.resolve(null); - }, -})); - -let slackCalls: Array<{ method: string; args: Record }> = []; - -mock.module("@slack/web-api", () => ({ - WebClient: class { - chat = { - update: (args: Record) => { - slackCalls.push({ method: "update", args }); - return Promise.resolve(); - }, - postEphemeral: (args: Record) => { - slackCalls.push({ method: "postEphemeral", args }); - return Promise.resolve(); - }, - }; - }, -})); - -const { handleSlackInteraction } = await import("./interactions"); -const { verifySlackSignature } = await import("./verify"); +function configureSlackDoubles() { + slackTestState.calls = []; + slackTestState.resolveWorkspace = (teamId: string) => + teamId === "T_KNOWN" + ? Promise.resolve({ botToken: "xoxb-fallback" }) + : Promise.resolve(null); +} function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); @@ -133,14 +119,14 @@ describe("handleSlackInteraction (dispatch)", () => { const app = createTestApp(); beforeEach(() => { - slackCalls = []; + configureSlackDoubles(); redisStore.clear(); }); test("returns ok for non-block_actions", async () => { const res = await signAndPost(app, { type: "message_action", actions: [] }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("returns ok for unknown action_id prefix", async () => { @@ -153,7 +139,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "unknown_action" }], }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("cancel updates message to cancelled", async () => { @@ -167,7 +153,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "cancel_pending-123" }], }); expect(res.status).toBe(200); - const cancelCall = slackCalls.find( + const cancelCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -185,7 +171,9 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_pending-123" }], }); expect(res.status).toBe(200); - const ephemeral = slackCalls.find((c) => c.method === "postEphemeral"); + const ephemeral = slackTestState.calls.find( + (c) => c.method === "postEphemeral", + ); expect(ephemeral).toBeDefined(); expect(ephemeral?.args.text as string).toContain("Only the person"); expect(redisStore.has("slack:action:pending-123")).toBe(true); @@ -201,7 +189,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_unknown-id" }], }); expect(res.status).toBe(200); - const expiredCall = slackCalls.find( + const expiredCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("expired"), ); @@ -218,7 +206,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_some-id" }], }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("approve_flag parses flag=true; approve parses flag=false", async () => { @@ -254,7 +242,7 @@ describe("registry-runner execution paths", () => { const app = createTestApp(); beforeEach(() => { - slackCalls = []; + configureSlackDoubles(); redisStore.clear(); }); @@ -269,7 +257,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackCalls.find( + const successCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes( @@ -293,7 +281,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_flag_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackCalls.find( + const successCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("subscribers notified"), @@ -312,7 +300,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "cancel_maint-001" }], }); expect(res.status).toBe(200); - const cancelCall = slackCalls.find( + const cancelCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -330,7 +318,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad" }], }); expect(res.status).toBe(200); - const errCall = slackCalls.find( + const errCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:") && @@ -354,7 +342,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad-time" }], }); expect(res.status).toBe(200); - const errCall = slackCalls.find( + const errCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:"), ); expect(errCall).toBeDefined(); diff --git a/apps/server/src/routes/slack/oauth.test.ts b/apps/server/src/routes/slack/oauth.test.ts index 8d6bc847..19624dd0 100644 --- a/apps/server/src/routes/slack/oauth.test.ts +++ b/apps/server/src/routes/slack/oauth.test.ts @@ -1,6 +1,7 @@ -import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { handleSlackInstall, handleSlackOAuthCallback } from "./oauth"; diff --git a/apps/server/src/routes/slack/presenters/presenters.test.ts b/apps/server/src/routes/slack/presenters/presenters.test.ts index 4161a12e..1878a698 100644 --- a/apps/server/src/routes/slack/presenters/presenters.test.ts +++ b/apps/server/src/routes/slack/presenters/presenters.test.ts @@ -1,20 +1,13 @@ -import { describe, expect, mock, test } from "bun:test"; - import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; +import { describe, expect, test } from "@openstatus/test-utils"; import { z } from "zod"; -// page-urls.ts hits the db; stub before the presenters module loads. -mock.module("../page-urls", () => ({ - getPageUrl: (_pageId: number) => - Promise.resolve("https://example.openstatus.dev"), - getReportUrl: (_pageId: number, reportId: number) => - Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`), -})); - -const { defaultPresenter } = await import("./default"); -const { renderToolResult } = await import("./index"); +// page-urls.ts hits the db; it's swapped for a deterministic double via the +// test import map (see test.importmap.json). +import { defaultPresenter } from "./default"; +import { renderToolResult } from "./index"; const fakeCtx = { workspace: { id: 1 }, diff --git a/apps/server/src/routes/slack/registry-runner.test.ts b/apps/server/src/routes/slack/registry-runner.test.ts index dd1e7494..a5dad44e 100644 --- a/apps/server/src/routes/slack/registry-runner.test.ts +++ b/apps/server/src/routes/slack/registry-runner.test.ts @@ -1,8 +1,8 @@ -import { describe, expect, test } from "bun:test"; - import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { z } from "zod"; import { diff --git a/apps/server/src/routes/slack/system-prompt.test.ts b/apps/server/src/routes/slack/system-prompt.test.ts index 0b23f798..42835ee7 100644 --- a/apps/server/src/routes/slack/system-prompt.test.ts +++ b/apps/server/src/routes/slack/system-prompt.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildSystemPrompt } from "./system-prompt"; diff --git a/apps/server/src/routes/slack/verify.test.ts b/apps/server/src/routes/slack/verify.test.ts index 83b0650c..4640216e 100644 --- a/apps/server/src/routes/slack/verify.test.ts +++ b/apps/server/src/routes/slack/verify.test.ts @@ -1,6 +1,7 @@ -import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { verifySlackSignature } from "./verify"; diff --git a/apps/server/src/routes/v1/check/http/post.test.ts b/apps/server/src/routes/v1/check/http/post.test.ts index 586b8454..ab47edfa 100644 --- a/apps/server/src/routes/v1/check/http/post.test.ts +++ b/apps/server/src/routes/v1/check/http/post.test.ts @@ -1,12 +1,10 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/incidents/get.test.ts b/apps/server/src/routes/v1/incidents/get.test.ts index c7f23e00..9de6b293 100644 --- a/apps/server/src/routes/v1/incidents/get.test.ts +++ b/apps/server/src/routes/v1/incidents/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/get_all.test.ts b/apps/server/src/routes/v1/incidents/get_all.test.ts index 618ff95b..19cb2dc1 100644 --- a/apps/server/src/routes/v1/incidents/get_all.test.ts +++ b/apps/server/src/routes/v1/incidents/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/put.test.ts b/apps/server/src/routes/v1/incidents/put.test.ts index 309e41d5..8bf5f059 100644 --- a/apps/server/src/routes/v1/incidents/put.test.ts +++ b/apps/server/src/routes/v1/incidents/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get.test.ts b/apps/server/src/routes/v1/maintenances/get.test.ts index c7927a23..69a4a248 100644 --- a/apps/server/src/routes/v1/maintenances/get.test.ts +++ b/apps/server/src/routes/v1/maintenances/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get_all.test.ts b/apps/server/src/routes/v1/maintenances/get_all.test.ts index b5682afd..2eb76192 100644 --- a/apps/server/src/routes/v1/maintenances/get_all.test.ts +++ b/apps/server/src/routes/v1/maintenances/get_all.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -7,6 +5,8 @@ import { monitor, pageComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/post.test.ts b/apps/server/src/routes/v1/maintenances/post.test.ts index dbb51799..d4fd15fe 100644 --- a/apps/server/src/routes/v1/maintenances/post.test.ts +++ b/apps/server/src/routes/v1/maintenances/post.test.ts @@ -1,7 +1,7 @@ -import { beforeEach, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -245,7 +245,9 @@ test("create a maintenance calls dispatchMaintenanceUpdate", async () => { const result = MaintenanceSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchMaintenanceUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBe( + "number", + ); if (result.success) { await db.delete(maintenance).where(eq(maintenance.id, result.data.id)); diff --git a/apps/server/src/routes/v1/maintenances/put.test.ts b/apps/server/src/routes/v1/maintenances/put.test.ts index bf462424..1400f196 100644 --- a/apps/server/src/routes/v1/maintenances/put.test.ts +++ b/apps/server/src/routes/v1/maintenances/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -96,7 +97,7 @@ test("update only the message", async () => { expect(result.data?.message).toBe("Only Message Updated"); }); -test.todo("update only the dates", async () => { +test.ignore("update only the dates", async () => { const from = new Date(); const to = new Date(from.getTime() + 7200000); // 2 hours later @@ -120,24 +121,27 @@ test.todo("update only the dates", async () => { expect(result.data?.to).toEqual(to); }); -test.todo("update maintenance with `from` date after `to` date should return 400", async () => { - const to = new Date(); - const from = new Date(to.getTime() + 3600000); // from is 1 hour after to - - const res = await app.request("/v1/maintenance/1", { - method: "PUT", - headers: { - "x-openstatus-key": "1", - "Content-Type": "application/json", - }, - body: JSON.stringify({ - from: from.toISOString(), - to: to.toISOString(), - }), - }); - - expect(res.status).toBe(400); -}); +test.ignore( + "update maintenance with `from` date after `to` date should return 400", + async () => { + const to = new Date(); + const from = new Date(to.getTime() + 3600000); // from is 1 hour after to + + const res = await app.request("/v1/maintenance/1", { + method: "PUT", + headers: { + "x-openstatus-key": "1", + "Content-Type": "application/json", + }, + body: JSON.stringify({ + from: from.toISOString(), + to: to.toISOString(), + }), + }); + + expect(res.status).toBe(400); + }, +); test("remove all maintenance monitors", async () => { const res = await app.request("/v1/maintenance/1", { @@ -158,7 +162,7 @@ test("remove all maintenance monitors", async () => { expect(result.data?.monitorIds?.length).toBe(0); }); -test.todo("empty body should return 400", async () => { +test.ignore("empty body should return 400", async () => { const res = await app.request("/v1/maintenance/1", { method: "PUT", headers: { diff --git a/apps/server/src/routes/v1/monitors/delete.test.ts b/apps/server/src/routes/v1/monitors/delete.test.ts index 503883c0..9e9adec8 100644 --- a/apps/server/src/routes/v1/monitors/delete.test.ts +++ b/apps/server/src/routes/v1/monitors/delete.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get.test.ts b/apps/server/src/routes/v1/monitors/get.test.ts index 9a26b26a..15209292 100644 --- a/apps/server/src/routes/v1/monitors/get.test.ts +++ b/apps/server/src/routes/v1/monitors/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get_all.test.ts b/apps/server/src/routes/v1/monitors/get_all.test.ts index f7b286dc..97c7dbed 100644 --- a/apps/server/src/routes/v1/monitors/get_all.test.ts +++ b/apps/server/src/routes/v1/monitors/get_all.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post.test.ts b/apps/server/src/routes/v1/monitors/post.test.ts index 235329cf..84ba06e5 100644 --- a/apps/server/src/routes/v1/monitors/post.test.ts +++ b/apps/server/src/routes/v1/monitors/post.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { createErrorSchema } from "@/libs/errors"; @@ -123,7 +124,7 @@ test("create a monitor with deprecated regions should return 400", async () => { expect(res.status).toBe(400); expect(errorSchema.success).toBe(true); - expect(errorSchema.data?.message).toMatch( + expect(errorSchema.data?.message).toContain( "Deprecated regions are not allowed: hkg, waw", ); }); diff --git a/apps/server/src/routes/v1/monitors/post_dns.test.ts b/apps/server/src/routes/v1/monitors/post_dns.test.ts index 70223677..5a5b3d81 100644 --- a/apps/server/src/routes/v1/monitors/post_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/post_dns.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_http.test.ts b/apps/server/src/routes/v1/monitors/post_http.test.ts index 9caa0bef..7ac84591 100644 --- a/apps/server/src/routes/v1/monitors/post_http.test.ts +++ b/apps/server/src/routes/v1/monitors/post_http.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_tcp.test.ts b/apps/server/src/routes/v1/monitors/post_tcp.test.ts index 7958913b..650a79dc 100644 --- a/apps/server/src/routes/v1/monitors/post_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/post_tcp.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put.test.ts b/apps/server/src/routes/v1/monitors/put.test.ts index 5b0357de..3fa45af3 100644 --- a/apps/server/src/routes/v1/monitors/put.test.ts +++ b/apps/server/src/routes/v1/monitors/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_dns.test.ts b/apps/server/src/routes/v1/monitors/put_dns.test.ts index e985b8af..3561dc06 100644 --- a/apps/server/src/routes/v1/monitors/put_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/put_dns.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_http.test.ts b/apps/server/src/routes/v1/monitors/put_http.test.ts index f042b7d2..4ae822a2 100644 --- a/apps/server/src/routes/v1/monitors/put_http.test.ts +++ b/apps/server/src/routes/v1/monitors/put_http.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_tcp.test.ts b/apps/server/src/routes/v1/monitors/put_tcp.test.ts index fa1c2f35..80ff9029 100644 --- a/apps/server/src/routes/v1/monitors/put_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/put_tcp.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/results/get.test.ts b/apps/server/src/routes/v1/monitors/results/get.test.ts index 67ea10dc..511ec1bf 100644 --- a/apps/server/src/routes/v1/monitors/results/get.test.ts +++ b/apps/server/src/routes/v1/monitors/results/get.test.ts @@ -1,10 +1,11 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { ResultRun } from "../schema"; -test.todo("get monitor result with valid id should return 200", async () => { +test.ignore("get monitor result with valid id should return 200", async () => { const res = await app.request("/v1/monitor/1/result/1", { method: "GET", headers: { @@ -60,20 +61,23 @@ test("get monitor result from different workspace should return 404", async () = expect(res.status).toBe(404); }); -test.todo("get monitor result with valid TCP monitor should return 200", async () => { - const res = await app.request("/v1/monitor/4/result/2", { - method: "GET", - headers: { - "x-openstatus-key": "1", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - const result = ResultRun.array().safeParse(json); - expect(result.success).toBe(true); -}); +test.ignore( + "get monitor result with valid TCP monitor should return 200", + async () => { + const res = await app.request("/v1/monitor/4/result/2", { + method: "GET", + headers: { + "x-openstatus-key": "1", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + const result = ResultRun.array().safeParse(json); + expect(result.success).toBe(true); + }, +); test("get monitor result with non-matching result id should return 404", async () => { const res = await app.request("/v1/monitor/1/result/999998", { diff --git a/apps/server/src/routes/v1/monitors/run/post.test.ts b/apps/server/src/routes/v1/monitors/run/post.test.ts index 26547105..b0a1f756 100644 --- a/apps/server/src/routes/v1/monitors/run/post.test.ts +++ b/apps/server/src/routes/v1/monitors/run/post.test.ts @@ -1,5 +1,4 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; @@ -8,7 +7,6 @@ import { TriggerResult } from "../schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); @@ -144,44 +142,47 @@ test("run TCP monitor with valid id should return 200", async () => { } }); -test.todo("run monitor with multiple regions should return array of results", async () => { - mockFetch.mockReturnValue( - Promise.resolve( - new Response( - JSON.stringify({ - jobType: "http", - status: 200, - latency: 100, - region: "ams", - timestamp: 1234567890, - timing: { - dnsStart: 1, - dnsDone: 2, - connectStart: 3, - connectDone: 4, - tlsHandshakeStart: 5, - tlsHandshakeDone: 6, - firstByteStart: 7, - firstByteDone: 8, - transferStart: 9, - transferDone: 10, - }, - }), - { status: 200, headers: { "content-type": "application/json" } }, +test.ignore( + "run monitor with multiple regions should return array of results", + async () => { + mockFetch.mockReturnValue( + Promise.resolve( + new Response( + JSON.stringify({ + jobType: "http", + status: 200, + latency: 100, + region: "ams", + timestamp: 1234567890, + timing: { + dnsStart: 1, + dnsDone: 2, + connectStart: 3, + connectDone: 4, + tlsHandshakeStart: 5, + tlsHandshakeDone: 6, + firstByteStart: 7, + firstByteDone: 8, + transferStart: 9, + transferDone: 10, + }, + }), + { status: 200, headers: { "content-type": "application/json" } }, + ), ), - ), - ); - - const res = await app.request("/v1/monitor/5/run", { - method: "POST", - headers: { - "x-openstatus-key": "1", - "content-type": "application/json", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - expect(Array.isArray(json)).toBe(true); -}); + ); + + const res = await app.request("/v1/monitor/5/run", { + method: "POST", + headers: { + "x-openstatus-key": "1", + "content-type": "application/json", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + expect(Array.isArray(json)).toBe(true); + }, +); diff --git a/apps/server/src/routes/v1/monitors/summary/get.test.ts b/apps/server/src/routes/v1/monitors/summary/get.test.ts index 4bf601d2..300271c1 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.test.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.test.ts @@ -1,12 +1,12 @@ -import { expect, test } from "bun:test"; - import { z } from "@hono/zod-openapi"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { SummarySchema } from "./schema"; -test.todo("return the summary of the monitor", async () => { +test.ignore("return the summary of the monitor", async () => { const res = await app.request("/v1/monitor/1/summary", { headers: { "x-openstatus-key": "1", diff --git a/apps/server/src/routes/v1/monitors/summary/get.ts b/apps/server/src/routes/v1/monitors/summary/get.ts index 6ae9cba3..22320e12 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.ts @@ -8,11 +8,6 @@ import { OpenStatusApiError, openApiErrorResponses } from "@/libs/errors"; import type { monitorsApi } from "../index"; import { ParamsSchema, SummarySchema } from "./schema"; -// TODO: is there another better way to mock Redis/Tinybird? -if (process.env.NODE_ENV === "test") { - require("@/libs/test/preload"); -} - const getMonitorStats = createRoute({ method: "get", tags: ["monitor"], diff --git a/apps/server/src/routes/v1/monitors/trigger/post.test.ts b/apps/server/src/routes/v1/monitors/trigger/post.test.ts index 7442da5b..028a0a71 100644 --- a/apps/server/src/routes/v1/monitors/trigger/post.test.ts +++ b/apps/server/src/routes/v1/monitors/trigger/post.test.ts @@ -1,5 +1,4 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; @@ -8,7 +7,6 @@ import { TriggerSchema } from "./schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/notifications/get.test.ts b/apps/server/src/routes/v1/notifications/get.test.ts index 3e967ba5..8759de39 100644 --- a/apps/server/src/routes/v1/notifications/get.test.ts +++ b/apps/server/src/routes/v1/notifications/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/get_all.test.ts b/apps/server/src/routes/v1/notifications/get_all.test.ts index 0c92e23f..5f2f580e 100644 --- a/apps/server/src/routes/v1/notifications/get_all.test.ts +++ b/apps/server/src/routes/v1/notifications/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/post.test.ts b/apps/server/src/routes/v1/notifications/post.test.ts index 5208aec5..b90369af 100644 --- a/apps/server/src/routes/v1/notifications/post.test.ts +++ b/apps/server/src/routes/v1/notifications/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pageSubscribers/post.test.ts b/apps/server/src/routes/v1/pageSubscribers/post.test.ts index 7d1bc085..80de79fa 100644 --- a/apps/server/src/routes/v1/pageSubscribers/post.test.ts +++ b/apps/server/src/routes/v1/pageSubscribers/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { and, db, eq, isNull } from "@openstatus/db"; import { pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get.test.ts b/apps/server/src/routes/v1/pages/get.test.ts index 2c197d62..4335e569 100644 --- a/apps/server/src/routes/v1/pages/get.test.ts +++ b/apps/server/src/routes/v1/pages/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get_all.test.ts b/apps/server/src/routes/v1/pages/get_all.test.ts index 155ed2cb..6c948552 100644 --- a/apps/server/src/routes/v1/pages/get_all.test.ts +++ b/apps/server/src/routes/v1/pages/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/post.test.ts b/apps/server/src/routes/v1/pages/post.test.ts index ec8999c6..e57a260c 100644 --- a/apps/server/src/routes/v1/pages/post.test.ts +++ b/apps/server/src/routes/v1/pages/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/put.test.ts b/apps/server/src/routes/v1/pages/put.test.ts index 3d327ca1..0c76046d 100644 --- a/apps/server/src/routes/v1/pages/put.test.ts +++ b/apps/server/src/routes/v1/pages/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts index 2a90e6bf..510c03b8 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts index 575b169e..d07c2f31 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -315,5 +316,7 @@ test("create a status report update calls dispatchStatusReportUpdate", async () const result = StatusReportUpdateSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( + "number", + ); }); diff --git a/apps/server/src/routes/v1/statusReports/delete.test.ts b/apps/server/src/routes/v1/statusReports/delete.test.ts index 2532be01..b0760725 100644 --- a/apps/server/src/routes/v1/statusReports/delete.test.ts +++ b/apps/server/src/routes/v1/statusReports/delete.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get.test.ts b/apps/server/src/routes/v1/statusReports/get.test.ts index a833c20a..61980dfd 100644 --- a/apps/server/src/routes/v1/statusReports/get.test.ts +++ b/apps/server/src/routes/v1/statusReports/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get_all.test.ts b/apps/server/src/routes/v1/statusReports/get_all.test.ts index 22135471..93e057df 100644 --- a/apps/server/src/routes/v1/statusReports/get_all.test.ts +++ b/apps/server/src/routes/v1/statusReports/get_all.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, @@ -8,6 +6,8 @@ import { statusReportUpdate, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/post.test.ts b/apps/server/src/routes/v1/statusReports/post.test.ts index 77154186..94c8d905 100644 --- a/apps/server/src/routes/v1/statusReports/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/post.test.ts @@ -1,11 +1,11 @@ -import { beforeEach, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { pageComponent, statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -202,7 +202,9 @@ test("create a status report calls dispatchStatusReportUpdate", async () => { const result = StatusReportSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( + "number", + ); if (result.success) { await db diff --git a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts index 743cfd1c..95d14722 100644 --- a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts +++ b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * Integration tests for subscriber filtering in status report email queries. diff --git a/apps/server/src/routes/v1/statusReports/update/post.test.ts b/apps/server/src/routes/v1/statusReports/update/post.test.ts index 2ec28aca..cf13fc17 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/update/post.ts b/apps/server/src/routes/v1/statusReports/update/post.ts index 5c19a0aa..6f899172 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.ts @@ -114,8 +114,9 @@ export function registerStatusReportUpdateRoutes(api: typeof statusReportsApi) { .all(); const validSubscribers = subscribers.filter( - (s): s is typeof s & { token: string } => + (s): s is typeof s & { token: string; email: string } => s.token !== null && + s.email !== null && s.acceptedAt !== null && s.unsubscribedAt === null, ); diff --git a/apps/server/src/routes/v1/whoami/get.test.ts b/apps/server/src/routes/v1/whoami/get.test.ts index 91f49c78..a0a7aa1b 100644 --- a/apps/server/src/routes/v1/whoami/get.test.ts +++ b/apps/server/src/routes/v1/whoami/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/serve.ts b/apps/server/src/serve.ts new file mode 100644 index 00000000..b280c1cf --- /dev/null +++ b/apps/server/src/serve.ts @@ -0,0 +1,13 @@ +import { getLogger } from "@logtape/logtape"; + +import { env } from "./env"; +import { app } from "./index"; + +const port = 3000; + +getLogger("api-server").info("Starting server", { + port, + environment: env.NODE_ENV, +}); + +Deno.serve({ port }, app.fetch); diff --git a/apps/server/src/utils/audit-log.ts b/apps/server/src/utils/audit-log.ts index 1c2f3783..6c659698 100644 --- a/apps/server/src/utils/audit-log.ts +++ b/apps/server/src/utils/audit-log.ts @@ -1,6 +1,6 @@ import { AuditLog, Tinybird } from "@openstatus/tinybird"; -import { env } from "../env"; +import { env } from "@/env"; const tb = new Tinybird({ token: env.TINY_BIRD_API_KEY }); diff --git a/apps/server/test.importmap.json b/apps/server/test.importmap.json new file mode 100644 index 00000000..e2cdceab --- /dev/null +++ b/apps/server/test.importmap.json @@ -0,0 +1,16 @@ +{ + "imports": { + "@/": "./src/", + "@openstatus/upstash": "./src/libs/test/doubles/upstash.mock.ts", + "@openstatus/tinybird": "./src/libs/test/doubles/tinybird.mock.ts", + "@openstatus/tinybird-real": "../../packages/tinybird/src/index.ts", + "@openstatus/subscriptions": "./src/libs/test/doubles/subscriptions.mock.ts", + "@openstatus/subscriptions-real": "../../packages/subscriptions/src/index.ts", + "@openstatus/analytics": "./src/libs/test/doubles/analytics.mock.ts", + "@openstatus/analytics-real": "../../packages/analytics/src/index.ts", + "./src/routes/slack/page-urls": "./src/libs/test/doubles/page-urls.mock.ts", + "./src/routes/slack/workspace-resolver": "./src/libs/test/doubles/workspace-resolver.mock.ts", + "./src/routes/slack/agent": "./src/libs/test/doubles/slack-agent.mock.ts", + "@slack/web-api": "./src/libs/test/doubles/slack-web-api.mock.ts" + } +} diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index d2c9d74a..e0efb05d 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -8,9 +8,15 @@ "moduleResolution": "bundler", "jsxImportSource": "react", "allowJs": true, - "types": ["bun-types"], + "types": [], "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@modelcontextprotocol/sdk/server/mcp.js": [ + "./node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts" + ], + "@modelcontextprotocol/sdk/types.js": [ + "./node_modules/@modelcontextprotocol/sdk/dist/esm/types.d.ts" + ] } } } diff --git a/apps/status-page/env.ts b/apps/status-page/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/status-page/env.ts +++ b/apps/status-page/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/status-page/package.json b/apps/status-page/package.json index cd336827..58a35fa7 100644 --- a/apps/status-page/package.json +++ b/apps/status-page/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "bun env.ts", + "env": "deno run -A env.ts", "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint", - "test": "bun test", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -77,13 +77,14 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", "@types/dom-speech-recognition": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "shadcn": "catalog:", "tailwindcss": "catalog:", "tw-animate-css": "catalog:", diff --git a/apps/status-page/src/app/(public)/client.tsx b/apps/status-page/src/app/(public)/client.tsx index 38d02ffd..9d8568e9 100644 --- a/apps/status-page/src/app/(public)/client.tsx +++ b/apps/status-page/src/app/(public)/client.tsx @@ -26,7 +26,7 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { Link } from "@/components/common/link"; +import { Link } from "../../components/common/link"; import { Section, SectionDescription, @@ -34,14 +34,13 @@ import { SectionGroupHeader, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { recomputeStyles } from "@/components/status-page/floating-button"; -import { StatusComponentStatic } from "@/components/status-page/static/status-component-static"; -import { ThemePalettePicker } from "@/components/themes/theme-palette-picker"; -import { ThemeSelect } from "@/components/themes/theme-select"; -import { monitors } from "@/data/monitors"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../components/content/section"; +import { recomputeStyles } from "../../components/status-page/floating-button"; +import { StatusComponentStatic } from "../../components/status-page/static/status-component-static"; +import { ThemePalettePicker } from "../../components/themes/theme-palette-picker"; +import { ThemeSelect } from "../../components/themes/theme-select"; +import { monitors } from "../../data/monitors"; +import { useTRPC } from "../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; const MAIN_COLORS = [ diff --git a/apps/status-page/src/app/(public)/layout.tsx b/apps/status-page/src/app/(public)/layout.tsx index 9297bb8a..68c07985 100644 --- a/apps/status-page/src/app/(public)/layout.tsx +++ b/apps/status-page/src/app/(public)/layout.tsx @@ -8,12 +8,12 @@ import { NextIntlClientProvider } from "next-intl"; import PlausibleProvider from "next-plausible"; import { Suspense } from "react"; -import { Link } from "@/components/common/link"; -import { ThemeProvider } from "@/components/themes/theme-provider"; +import { Link } from "../../components/common/link"; +import { ThemeProvider } from "../../components/themes/theme-provider"; import { SidebarTrigger, ThemeSidebar, -} from "@/components/themes/theme-sidebar"; +} from "../../components/themes/theme-sidebar"; const SIDEBAR_WIDTH = "20rem"; const SIDEBAR_WIDTH_MOBILE = "18rem"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx index 62448552..4dce7e67 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx @@ -1,9 +1,9 @@ import { cn } from "@openstatus/ui/lib/utils"; import { Suspense } from "react"; -import { EmbedShell } from "@/components/layout/embed-shell"; -import { Footer } from "@/components/nav/footer"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { EmbedShell } from "../../../../../components/layout/embed-shell"; +import { Footer } from "../../../../../components/nav/footer"; +import { getQueryClient, trpc } from "../../../../../lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx index 6da92191..0030f867 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx @@ -11,16 +11,18 @@ import { EmptyStateContainer, EmptyStateDescription, EmptyStateTitle, -} from "@/components/content/empty-state"; +} from "../../../../../../../components/content/empty-state"; import { Section, SectionDescription, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { FormEmail, type FormValues } from "@/components/forms/form-email"; -import { generateServerActionPromise } from "@/lib/server-actions"; - +} from "../../../../../../../components/content/section"; +import { + FormEmail, + type FormValues, +} from "../../../../../../../components/forms/form-email"; +import { generateServerActionPromise } from "../../../../../../../lib/server-actions"; import { signInWithResendAction } from "../actions"; export function SectionMagicLink() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx index 32b13e97..af1bbba9 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx @@ -11,10 +11,10 @@ import { SectionDescription, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { FormPassword } from "@/components/forms/form-password"; -import { createProtectedCookieKey } from "@/lib/protected"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/content/section"; +import { FormPassword } from "../../../../../../../components/forms/form-password"; +import { createProtectedCookieKey } from "../../../../../../../lib/protected"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export function SectionPassword() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts index 46056921..bef7b0a3 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts @@ -5,8 +5,8 @@ import { AuthError } from "next-auth"; import { getExtracted } from "next-intl/server"; import { isRedirectError } from "next/dist/client/components/redirect-error"; -import { signIn } from "@/lib/auth"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { signIn } from "../../../../../../lib/auth"; +import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; export async function signInWithResendAction(formData: FormData) { const t = await getExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx index 554c8146..0368b670 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx @@ -3,8 +3,7 @@ import { useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; - +import { useTRPC } from "../../../../../../lib/trpc/client"; import { SectionMagicLink } from "./_components/section-magic-link"; import { SectionPassword } from "./_components/section-password"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx index 2e6e8b90..cbdecf1d 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx @@ -5,7 +5,7 @@ import { ShieldAlert } from "lucide-react"; import { useExtracted } from "next-intl"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function RestrictedPage() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx index f650dcf9..0dc50174 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx @@ -27,8 +27,8 @@ import { skipToken, useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; import { useMemo } from "react"; -import { Link } from "@/components/common/link"; -import { useStatusPage } from "@/components/status-page/floating-button"; +import { Link } from "../../../../../components/common/link"; +import { useStatusPage } from "../../../../../components/status-page/floating-button"; import { StatusBanner, StatusBannerContainer, @@ -37,23 +37,23 @@ import { StatusBannerTabsContent, StatusBannerTabsList, StatusBannerTabsTrigger, -} from "@/components/status-page/status-banner"; +} from "../../../../../components/status-page/status-banner"; import { StatusBar, StatusBarSkeleton, -} from "@/components/status-page/status-bar"; -import { StatusComponentGroup } from "@/components/status-page/status-component-group"; +} from "../../../../../components/status-page/status-bar"; +import { StatusComponentGroup } from "../../../../../components/status-page/status-component-group"; import { StatusEventAffected, StatusEventAffectedBadge, StatusEventTimelineMaintenance, StatusEventTimelineReportUpdate, -} from "@/components/status-page/status-events"; -import { StatusFeed } from "@/components/status-page/status-feed"; -import { useEmbed } from "@/hooks/use-embed"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../components/status-page/status-events"; +import { StatusFeed } from "../../../../../components/status-page/status-feed"; +import { useEmbed } from "../../../../../hooks/use-embed"; +import { usePathnamePrefix } from "../../../../../hooks/use-pathname-prefix"; +import { updatesWithImpactChanges } from "../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../lib/trpc/client"; export function Client() { const prefix = usePathnamePrefix(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx index 32ea5a79..6a5704cb 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx index 0d64d5c6..7e7134de 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx @@ -12,7 +12,7 @@ import Link from "next/link"; import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { StatusBlankEvents } from "../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -25,10 +25,9 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "@/components/status-page/status-events"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../../../../../../components/status-page/status-events"; +import { updatesWithImpactChanges } from "../../../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx index 140e18c5..4caf455c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx @@ -1,8 +1,12 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../../../lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx index a4eafcd5..58a9ce95 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { ButtonBack } from "../../../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; +import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -16,8 +16,8 @@ import { StatusEventDate, StatusEventTimelineMaintenance, StatusEventTitle, -} from "@/components/status-page/status-events"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../../../components/status-page/status-events"; +import { useTRPC } from "../../../../../../../../../lib/trpc/client"; export default function MaintenancePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx index 124f989e..0977d1bf 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx @@ -1,8 +1,12 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../../../lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx index 1387487c..6f300055 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { ButtonBack } from "../../../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; +import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -17,9 +17,9 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "@/components/status-page/status-events"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../../../components/status-page/status-events"; +import { updatesWithImpactChanges } from "../../../../../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../../../../../lib/trpc/client"; export default function ReportPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx index faa8e4e0..1d913d44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts index a3fbb463..f8ea2279 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts @@ -1,9 +1,9 @@ import { Feed } from "feed"; import { notFound, unauthorized } from "next/navigation"; -import { auth } from "@/lib/auth"; -import { getBaseUrl } from "@/lib/base-url"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { auth } from "../../../../../../../lib/auth"; +import { getBaseUrl } from "../../../../../../../lib/base-url"; +import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; const STATUS_LABELS = { investigating: "Investigating", diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts index 885246ea..600d02f7 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts @@ -1,7 +1,7 @@ import { notFound, unauthorized } from "next/navigation"; -import { auth } from "@/lib/auth"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { auth } from "../../../../../../../lib/auth"; +import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; export const revalidate = 60; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx index 582ebac0..3e5c45e3 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx @@ -4,9 +4,9 @@ import { } from "@openstatus/ui/components/blocks/status-page-shell"; import { Suspense } from "react"; -import { EmbedShell } from "@/components/layout/embed-shell"; -import { Footer } from "@/components/nav/footer"; -import { Header } from "@/components/nav/header"; +import { EmbedShell } from "../../../../../components/layout/embed-shell"; +import { Footer } from "../../../../../components/nav/footer"; +import { Header } from "../../../../../components/nav/header"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts index 060d94fc..32ff7998 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts @@ -2,9 +2,12 @@ import { db, sql } from "@openstatus/db"; import { page } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { escapeLinkLabel, type OverviewPage } from "@/content/markdown"; -import { getBaseUrl } from "@/lib/base-url"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { + escapeLinkLabel, + type OverviewPage, +} from "../../../../../../content/markdown"; +import { getBaseUrl } from "../../../../../../lib/base-url"; +import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx index f90f987a..d7759e1a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx @@ -1,4 +1,8 @@ -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx index 9bc7aef7..fefbeaaf 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx @@ -18,7 +18,7 @@ import { useExtracted, useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { toast } from "sonner"; -import { ButtonBack } from "@/components/button/button-back"; +import { ButtonBack } from "../../../../../../../components/button/button-back"; import { FormCard, FormCardContent, @@ -27,16 +27,16 @@ import { FormCardFooterInfo, FormCardHeader, FormCardTitle, -} from "@/components/forms/form-card"; -import { FormManageSubscription } from "@/components/forms/form-manage-subscription"; +} from "../../../../../../../components/forms/form-card"; +import { FormManageSubscription } from "../../../../../../../components/forms/form-manage-subscription"; import { StatusBlankContainer, StatusBlankContent, StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx index faa8e4e0..1d913d44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx index 5a45b960..36dafd6d 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx @@ -1,7 +1,7 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx index 5efcc37e..964d2a63 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx @@ -15,27 +15,27 @@ import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; import { useMemo } from "react"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; +import { ButtonBack } from "../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../components/button/button-copy-link"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "@/components/chart/chart-area-percentiles"; +} from "../../../../../../../components/chart/chart-area-percentiles"; import { ChartBarUptime, ChartBarUptimeSkeleton, -} from "@/components/chart/chart-bar-uptime"; +} from "../../../../../../../components/chart/chart-bar-uptime"; import { ChartLineRegions, ChartLineRegionsSkeleton, -} from "@/components/chart/chart-line-regions"; -import { StatusBlankMonitors } from "@/components/status-page/status-blank"; +} from "../../../../../../../components/chart/chart-line-regions"; +import { StatusBlankMonitors } from "../../../../../../../components/status-page/status-blank"; import { StatusChartContent, StatusChartDescription, StatusChartHeader, StatusChartTitle, -} from "@/components/status-page/status-charts"; +} from "../../../../../../../components/status-page/status-charts"; import { StatusMonitorTabs, StatusMonitorTabsContent, @@ -44,14 +44,13 @@ import { StatusMonitorTabsTriggerLabel, StatusMonitorTabsTriggerValue, StatusMonitorTabsTriggerValueSkeleton, -} from "@/components/status-page/status-monitor-tabs"; +} from "../../../../../../../components/status-page/status-monitor-tabs"; import { formatMillisecondsRange, formatNumber, formatPercentage, -} from "@/lib/formatter"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../../../../../../lib/formatter"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx index 61d96811..b793c90a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx index 48aef75d..6bc56d9c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx @@ -18,9 +18,9 @@ import { useParams } from "next/navigation"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "@/components/chart/chart-area-percentiles"; -import { StatusBlankMonitors } from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../components/chart/chart-area-percentiles"; +import { StatusBlankMonitors } from "../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function Page() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts index 2edef64c..fb02a69a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts @@ -1,6 +1,6 @@ import { createSearchParamsCache } from "nuqs/server"; -import { embedParser } from "@/lib/embed-params"; +import { embedParser } from "../../../../../lib/embed-params"; export const embedSearchParamsCache = createSearchParamsCache({ embed: embedParser, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx index c77dbc68..41485a1e 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function UnsubscribeLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx index 53bea954..d4f0aded 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function UnsubscribePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx index faa8e4e0..3c061636 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx index c27dd097..cf71d1f2 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankContent, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx index 79d21b24..1bab2f44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx @@ -2,9 +2,9 @@ import { NextIntlClientProvider, hasLocale } from "next-intl"; import { setRequestLocale } from "next-intl/server"; import { notFound } from "next/navigation"; -import { DateFnsProvider } from "@/components/date-fns-provider"; -import { StatusBlocksProvider } from "@/components/i18n/status-blocks-provider"; -import { routing } from "@/i18n/routing"; +import { DateFnsProvider } from "../../../../components/date-fns-provider"; +import { StatusBlocksProvider } from "../../../../components/i18n/status-blocks-provider"; +import { routing } from "../../../../i18n/routing"; export default async function LocaleLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx index 3b6b86ff..5dbcf293 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx @@ -4,16 +4,16 @@ import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { defaultMetadata, ogMetadata, twitterMetadata } from "@/app/metadata"; -import { PasswordWrapper } from "@/components/password-wrapper"; +import { PasswordWrapper } from "../../../components/password-wrapper"; import { FloatingButton, StatusPageProvider, -} from "@/components/status-page/floating-button"; -import { FloatingTheme } from "@/components/status-page/floating-theme"; -import { ThemeProvider } from "@/components/themes/theme-provider"; -import { statusPageAlternates } from "@/lib/alternates"; -import { getQueryClient, HydrateClient, trpc } from "@/lib/trpc/server"; +} from "../../../components/status-page/floating-button"; +import { FloatingTheme } from "../../../components/status-page/floating-theme"; +import { ThemeProvider } from "../../../components/themes/theme-provider"; +import { statusPageAlternates } from "../../../lib/alternates"; +import { getQueryClient, HydrateClient, trpc } from "../../../lib/trpc/server"; +import { defaultMetadata, ogMetadata, twitterMetadata } from "../../metadata"; // Canonical schema — guarantees concrete enum output (never null/undefined). diff --git a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts index c55a45ed..9f1bce8e 100644 --- a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts +++ b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts @@ -1,3 +1,3 @@ -import { handlers } from "@/lib/auth"; +import { handlers } from "../../../../lib/auth"; export const { GET, POST } = handlers; diff --git a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts index 43a151d4..5f8868af 100644 --- a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts @@ -10,12 +10,12 @@ import { generateReport, matchMarkdownRoute, parseMarkdownPath, -} from "@/content/markdown"; -import { getBaseUrl } from "@/lib/base-url"; -import { resolveClientIp } from "@/lib/http/client-ip"; -import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; -import { type GatePage, resolveGate } from "@/lib/proxy/resolve-gate"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +} from "../../../../content/markdown"; +import { getBaseUrl } from "../../../../lib/base-url"; +import { resolveClientIp } from "../../../../lib/http/client-ip"; +import { resolveMarkdownResponse } from "../../../../lib/http/markdown-response"; +import { type GatePage, resolveGate } from "../../../../lib/proxy/resolve-gate"; +import { getQueryClient, trpc } from "../../../../lib/trpc/server"; // Match the feed route: getQueryClient/httpBatchLink needs Node, not Edge. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/status/[[...path]]/route.ts b/apps/status-page/src/app/api/status/[[...path]]/route.ts index 37255f80..6ee8bb27 100644 --- a/apps/status-page/src/app/api/status/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/status/[[...path]]/route.ts @@ -8,14 +8,14 @@ import { toStatus, toSummary, toUnresolvedIncidents, -} from "@/content/status-json"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveClientIp } from "@/lib/http/client-ip"; -import { computeETag, isNotModified } from "@/lib/http/etag"; -import { resolveGate } from "@/lib/proxy/resolve-gate"; -import { resolveRoute } from "@/lib/resolve-route"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +} from "../../../../content/status-json"; +import { getBaseUrl } from "../../../../lib/base-url"; +import { stripHostPort } from "../../../../lib/domain"; +import { resolveClientIp } from "../../../../lib/http/client-ip"; +import { computeETag, isNotModified } from "../../../../lib/http/etag"; +import { resolveGate } from "../../../../lib/proxy/resolve-gate"; +import { resolveRoute } from "../../../../lib/resolve-route"; +import { getQueryClient, trpc } from "../../../../lib/trpc/server"; // trpc httpBatchLink needs Node, matching the markdown route. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts index 9dd8225b..c05e3b01 100644 --- a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,8 +3,8 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "@/lib/auth"; -import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; +import { auth } from "../../../../../lib/auth"; +import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; export const runtime = "edge"; diff --git a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts index 944ea4af..f17aa817 100644 --- a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,8 +3,8 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "@/lib/auth"; -import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; +import { auth } from "../../../../../lib/auth"; +import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/status-page/src/app/global-error.tsx b/apps/status-page/src/app/global-error.tsx index 6d4ad424..758c1809 100644 --- a/apps/status-page/src/app/global-error.tsx +++ b/apps/status-page/src/app/global-error.tsx @@ -4,7 +4,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import * as Sentry from "@sentry/nextjs"; import { useEffect } from "react"; -import { Link } from "@/components/common/link"; +import { Link } from "../components/common/link"; export default function GlobalError({ error, diff --git a/apps/status-page/src/app/layout.tsx b/apps/status-page/src/app/layout.tsx index 600b276d..bc1a2aec 100644 --- a/apps/status-page/src/app/layout.tsx +++ b/apps/status-page/src/app/layout.tsx @@ -6,9 +6,8 @@ import { Geist, Geist_Mono } from "next/font/google"; import LocalFont from "next/font/local"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { TailwindIndicator } from "@/components/tailwind-indicator"; -import { TRPCReactProvider } from "@/lib/trpc/client"; - +import { TailwindIndicator } from "../components/tailwind-indicator"; +import { TRPCReactProvider } from "../lib/trpc/client"; import { ogMetadata, twitterMetadata } from "./metadata"; import { defaultMetadata } from "./metadata"; diff --git a/apps/status-page/src/app/not-found.tsx b/apps/status-page/src/app/not-found.tsx index 47cd00e2..a1042a9a 100644 --- a/apps/status-page/src/app/not-found.tsx +++ b/apps/status-page/src/app/not-found.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/navigation"; import { NuqsAdapter } from "nuqs/adapters/next/app"; import { Suspense } from "react"; -import { Link } from "@/components/common/link"; -import { ThemeProvider } from "@/components/themes/theme-provider"; +import { Link } from "../components/common/link"; +import { ThemeProvider } from "../components/themes/theme-provider"; export default function NotFound() { return ( diff --git a/apps/status-page/src/app/robots.ts b/apps/status-page/src/app/robots.ts index 4df99d6d..dc3db8ba 100644 --- a/apps/status-page/src/app/robots.ts +++ b/apps/status-page/src/app/robots.ts @@ -3,9 +3,9 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveRoute } from "@/lib/resolve-route"; +import { getBaseUrl } from "../lib/base-url"; +import { stripHostPort } from "../lib/domain"; +import { resolveRoute } from "../lib/resolve-route"; // trpc/db lookup needs Node, matching the sitemap and other content routes. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/sitemap.ts b/apps/status-page/src/app/sitemap.ts index b6e31bef..857cfbe7 100644 --- a/apps/status-page/src/app/sitemap.ts +++ b/apps/status-page/src/app/sitemap.ts @@ -3,10 +3,10 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveRoute } from "@/lib/resolve-route"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { getBaseUrl } from "../lib/base-url"; +import { stripHostPort } from "../lib/domain"; +import { resolveRoute } from "../lib/resolve-route"; +import { getQueryClient, trpc } from "../lib/trpc/server"; // One sitemap per host: a custom domain must never enumerate other tenants' // pages. trpc httpBatchLink needs Node, matching the other content routes. diff --git a/apps/status-page/src/components/chart/chart-area-percentiles.tsx b/apps/status-page/src/components/chart/chart-area-percentiles.tsx index 78f62b7c..0e4ac7b4 100644 --- a/apps/status-page/src/components/chart/chart-area-percentiles.tsx +++ b/apps/status-page/src/components/chart/chart-area-percentiles.tsx @@ -13,8 +13,7 @@ import { useState } from "react"; import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; import type { AxisDomain } from "recharts/types/util/types"; -import { formatMilliseconds } from "@/lib/formatter"; - +import { formatMilliseconds } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/chart/chart-bar-uptime.tsx b/apps/status-page/src/components/chart/chart-bar-uptime.tsx index 81df7d41..c4565542 100644 --- a/apps/status-page/src/components/chart/chart-bar-uptime.tsx +++ b/apps/status-page/src/components/chart/chart-bar-uptime.tsx @@ -12,8 +12,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { useState } from "react"; import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"; -import { formatNumber } from "@/lib/formatter"; - +import { formatNumber } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; const chartConfig = { diff --git a/apps/status-page/src/components/chart/chart-legend-badge.tsx b/apps/status-page/src/components/chart/chart-legend-badge.tsx index 6d6d84c8..ef0d13f3 100644 --- a/apps/status-page/src/components/chart/chart-legend-badge.tsx +++ b/apps/status-page/src/components/chart/chart-legend-badge.tsx @@ -12,7 +12,7 @@ import * as React from "react"; import type * as RechartsPrimitive from "recharts"; import type { Payload } from "recharts/types/component/DefaultLegendContent"; -import { getPayloadConfigFromPayload } from "@/lib/chart"; +import { getPayloadConfigFromPayload } from "../../lib/chart"; export function ChartLegendBadge({ className, diff --git a/apps/status-page/src/components/chart/chart-line-regions.tsx b/apps/status-page/src/components/chart/chart-line-regions.tsx index 71c9de48..f216e6b1 100644 --- a/apps/status-page/src/components/chart/chart-line-regions.tsx +++ b/apps/status-page/src/components/chart/chart-line-regions.tsx @@ -20,9 +20,8 @@ import { YAxis, } from "recharts"; -import { regions } from "@/data/regions"; -import { formatMilliseconds } from "@/lib/formatter"; - +import { regions } from "../../data/regions"; +import { formatMilliseconds } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/common/link.tsx b/apps/status-page/src/components/common/link.tsx index 0d2c16cc..9a4d75c0 100644 --- a/apps/status-page/src/components/common/link.tsx +++ b/apps/status-page/src/components/common/link.tsx @@ -4,7 +4,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { type VariantProps, cva } from "class-variance-authority"; import NextLink from "next/link"; -import { useEmbed } from "@/hooks/use-embed"; +import { useEmbed } from "../../hooks/use-embed"; export const linkVariants = cva( "focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]", diff --git a/apps/status-page/src/components/date-fns-provider.tsx b/apps/status-page/src/components/date-fns-provider.tsx index 046a5147..f6d1f35a 100644 --- a/apps/status-page/src/components/date-fns-provider.tsx +++ b/apps/status-page/src/components/date-fns-provider.tsx @@ -3,7 +3,7 @@ import { dateFnsLocales } from "@openstatus/locales"; import { setDefaultOptions } from "date-fns"; -import type { Locale } from "@/i18n/config"; +import type { Locale } from "../i18n/config"; export function DateFnsProvider({ locale, diff --git a/apps/status-page/src/components/date-picker.tsx b/apps/status-page/src/components/date-picker.tsx index 751cc163..608fc8e8 100644 --- a/apps/status-page/src/components/date-picker.tsx +++ b/apps/status-page/src/components/date-picker.tsx @@ -10,8 +10,8 @@ import { useExtracted } from "next-intl"; import { useState } from "react"; import type { DateRange } from "react-day-picker"; -import { Kbd } from "@/components/common/kbd"; -import { formatDateForInput } from "@/lib/formatter"; +import { formatDateForInput } from "../lib/formatter"; +import { Kbd } from "./common/kbd"; type DatePickerProps = { range: DateRange; diff --git a/apps/status-page/src/components/forms/form-manage-subscription.tsx b/apps/status-page/src/components/forms/form-manage-subscription.tsx index 039398d5..ac055e4c 100644 --- a/apps/status-page/src/components/forms/form-manage-subscription.tsx +++ b/apps/status-page/src/components/forms/form-manage-subscription.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "@/components/status-page/status-blank"; +} from "../status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/forms/form-subscribe-email.tsx b/apps/status-page/src/components/forms/form-subscribe-email.tsx index 5bc5549e..7e233c37 100644 --- a/apps/status-page/src/components/forms/form-subscribe-email.tsx +++ b/apps/status-page/src/components/forms/form-subscribe-email.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "@/components/status-page/status-blank"; +} from "../status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/i18n/status-blocks-provider.tsx b/apps/status-page/src/components/i18n/status-blocks-provider.tsx index b1678e22..afa5e7b8 100644 --- a/apps/status-page/src/components/i18n/status-blocks-provider.tsx +++ b/apps/status-page/src/components/i18n/status-blocks-provider.tsx @@ -12,7 +12,7 @@ import { formatDateRange, formatDateRangeParts, formatDateTime, -} from "@/lib/formatter"; +} from "../../lib/formatter"; // Status-page timestamps render in UTC; the suffix tells viewers which zone. const withUTC = (value: string) => `${value} (UTC)`; diff --git a/apps/status-page/src/components/layout/embed-shell.tsx b/apps/status-page/src/components/layout/embed-shell.tsx index 2de6e875..c7a960ee 100644 --- a/apps/status-page/src/components/layout/embed-shell.tsx +++ b/apps/status-page/src/components/layout/embed-shell.tsx @@ -2,7 +2,7 @@ import { cn } from "@openstatus/ui/lib/utils"; -import { ALL_EMBED_SECTIONS, useEmbed } from "@/hooks/use-embed"; +import { ALL_EMBED_SECTIONS, useEmbed } from "../../hooks/use-embed"; export function EmbedShell({ children, diff --git a/apps/status-page/src/components/locale-switcher.tsx b/apps/status-page/src/components/locale-switcher.tsx index 234cd097..ba82b8a1 100644 --- a/apps/status-page/src/components/locale-switcher.tsx +++ b/apps/status-page/src/components/locale-switcher.tsx @@ -13,7 +13,7 @@ import { defaultLocale as globalDefaultLocale, localeTranslations, locales, -} from "@/i18n/config"; +} from "../i18n/config"; export function LocaleSwitcher({ className, diff --git a/apps/status-page/src/components/nav/footer.tsx b/apps/status-page/src/components/nav/footer.tsx index a98cd31b..1a2be081 100644 --- a/apps/status-page/src/components/nav/footer.tsx +++ b/apps/status-page/src/components/nav/footer.tsx @@ -13,12 +13,12 @@ import { Clock } from "lucide-react"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { Link } from "@/components/common/link"; -import { TimestampHoverCard } from "@/components/content/timestamp-hover-card"; -import { LocaleSwitcher } from "@/components/locale-switcher"; -import { ThemeSwitcher } from "@/components/themes/theme-switcher"; -import { useEmbed } from "@/hooks/use-embed"; -import { useTRPC } from "@/lib/trpc/client"; +import { useEmbed } from "../../hooks/use-embed"; +import { useTRPC } from "../../lib/trpc/client"; +import { Link } from "../common/link"; +import { TimestampHoverCard } from "../content/timestamp-hover-card"; +import { LocaleSwitcher } from "../locale-switcher"; +import { ThemeSwitcher } from "../themes/theme-switcher"; export function Footer({ className, diff --git a/apps/status-page/src/components/nav/header.tsx b/apps/status-page/src/components/nav/header.tsx index 03439456..6f5b1cd0 100644 --- a/apps/status-page/src/components/nav/header.tsx +++ b/apps/status-page/src/components/nav/header.tsx @@ -30,13 +30,13 @@ import { useParams, usePathname } from "next/navigation"; import { useState } from "react"; import { toast } from "sonner"; -import { Link } from "@/components/common/link"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { useTRPC } from "../../lib/trpc/client"; +import { Link } from "../common/link"; import { type StatusUpdateType, StatusUpdates, -} from "@/components/status-page/status-updates"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../status-page/status-updates"; type Page = RouterOutputs["statusPage"]["get"]; diff --git a/apps/status-page/src/components/password-wrapper.tsx b/apps/status-page/src/components/password-wrapper.tsx index 41e2eee3..cb364ada 100644 --- a/apps/status-page/src/components/password-wrapper.tsx +++ b/apps/status-page/src/components/password-wrapper.tsx @@ -4,7 +4,7 @@ import { useParams } from "next/navigation"; import { parseAsString, useQueryState } from "nuqs"; import { useEffect } from "react"; -import { createProtectedCookieKey } from "@/lib/protected"; +import { createProtectedCookieKey } from "../lib/protected"; export function PasswordWrapper({ children }: { children?: React.ReactNode }) { const [password, setPassword] = useQueryState("pw", parseAsString); diff --git a/apps/status-page/src/components/status-page/floating-button.tsx b/apps/status-page/src/components/status-page/floating-button.tsx index c19e8a75..c538dd26 100644 --- a/apps/status-page/src/components/status-page/floating-button.tsx +++ b/apps/status-page/src/components/status-page/floating-button.tsx @@ -35,7 +35,7 @@ import { parseAsString, useQueryState } from "nuqs"; import type React from "react"; import { createContext, useContext, useEffect, useState } from "react"; -import { ThemeSelect } from "@/components/themes/theme-select"; +import { ThemeSelect } from "../themes/theme-select"; export const IS_DEV = process.env.NODE_ENV === "development"; diff --git a/apps/status-page/src/components/status-page/floating-theme.tsx b/apps/status-page/src/components/status-page/floating-theme.tsx index 4e68f165..bbf8b90f 100644 --- a/apps/status-page/src/components/status-page/floating-theme.tsx +++ b/apps/status-page/src/components/status-page/floating-theme.tsx @@ -21,8 +21,7 @@ import { Check, ChevronsUpDown, Palette } from "lucide-react"; import { useEffect } from "react"; import { useState } from "react"; -import { ThemeSelect } from "@/components/themes/theme-select"; - +import { ThemeSelect } from "../themes/theme-select"; import { useStatusPage } from "./floating-button"; export const COMMUNITY_THEME = THEME_KEYS; diff --git a/apps/status-page/src/components/status-page/status-bar.tsx b/apps/status-page/src/components/status-page/status-bar.tsx index 9b43257a..dcad7aa6 100644 --- a/apps/status-page/src/components/status-page/status-bar.tsx +++ b/apps/status-page/src/components/status-page/status-bar.tsx @@ -5,8 +5,8 @@ import { StatusBarEvent, } from "@openstatus/ui/components/blocks/status-bar"; -import { Link } from "@/components/common/link"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { Link } from "../common/link"; export { StatusBarSkeleton } from "@openstatus/ui/components/blocks/status-bar"; diff --git a/apps/status-page/src/components/status-page/status-blank.tsx b/apps/status-page/src/components/status-page/status-blank.tsx index e4ea5977..5d5ec21e 100644 --- a/apps/status-page/src/components/status-page/status-blank.tsx +++ b/apps/status-page/src/components/status-page/status-blank.tsx @@ -3,7 +3,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import { cn } from "@openstatus/ui/lib/utils"; -import { Link } from "@/components/common/link"; +import { Link } from "../common/link"; export { StatusBlankContainer, diff --git a/apps/status-page/src/components/status-page/status-calendar.tsx b/apps/status-page/src/components/status-page/status-calendar.tsx index 9b38d522..19992ddd 100644 --- a/apps/status-page/src/components/status-page/status-calendar.tsx +++ b/apps/status-page/src/components/status-page/status-calendar.tsx @@ -20,9 +20,9 @@ import { import { useLocale } from "next-intl"; import { useCallback, useMemo } from "react"; -import { Link } from "@/components/common/link"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import type { Locale as AppLocale } from "@/i18n/config"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import type { Locale as AppLocale } from "../../i18n/config"; +import { Link } from "../common/link"; type Page = NonNullable; type ReportInput = Page["statusReports"][number]; diff --git a/apps/status-page/src/components/status-page/status-events.tsx b/apps/status-page/src/components/status-page/status-events.tsx index 42ff846c..4a01ead1 100644 --- a/apps/status-page/src/components/status-page/status-events.tsx +++ b/apps/status-page/src/components/status-page/status-events.tsx @@ -6,7 +6,7 @@ import { StatusEventTimelineReportUpdate as BlockStatusEventTimelineReportUpdate, } from "@openstatus/ui/components/blocks/status-events"; -import { ProcessMessage } from "@/components/content/process-message"; +import { ProcessMessage } from "../content/process-message"; // Re-export pass-through primitives that don't need glue. export { diff --git a/apps/status-page/src/components/status-page/status-feed.tsx b/apps/status-page/src/components/status-page/status-feed.tsx index 5f21632e..bbd3f934 100644 --- a/apps/status-page/src/components/status-page/status-feed.tsx +++ b/apps/status-page/src/components/status-page/status-feed.tsx @@ -4,10 +4,9 @@ import { StatusBlankAction } from "@openstatus/ui/components/blocks/status-blank import { StatusFeed as BlockStatusFeed } from "@openstatus/ui/components/blocks/status-feed"; import { useExtracted } from "next-intl"; -import { Link } from "@/components/common/link"; -import { ProcessMessage } from "@/components/content/process-message"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; - +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { Link } from "../common/link"; +import { ProcessMessage } from "../content/process-message"; import { StatusBlankLink } from "./status-blank"; const renderMarkdownMessage = (message: string) => ( diff --git a/apps/status-page/src/components/status-page/status-updates.tsx b/apps/status-page/src/components/status-page/status-updates.tsx index f1a38198..7ba925e4 100644 --- a/apps/status-page/src/components/status-page/status-updates.tsx +++ b/apps/status-page/src/components/status-page/status-updates.tsx @@ -26,12 +26,12 @@ import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; import { useState } from "react"; +import { getBaseUrl } from "../../lib/base-url"; +import { createProtectedCookieKey } from "../../lib/protected"; import { FormSubscribeEmail, type FormValues, -} from "@/components/forms/form-subscribe-email"; -import { getBaseUrl } from "@/lib/base-url"; -import { createProtectedCookieKey } from "@/lib/protected"; +} from "../forms/form-subscribe-email"; export type StatusUpdateType = "email" | "rss" | "ssh" | "json" | "slack"; diff --git a/apps/status-page/src/components/themes/theme-provider.tsx b/apps/status-page/src/components/themes/theme-provider.tsx index 5c56dc14..cfd1d8a8 100644 --- a/apps/status-page/src/components/themes/theme-provider.tsx +++ b/apps/status-page/src/components/themes/theme-provider.tsx @@ -4,8 +4,8 @@ import { ThemeProvider as NextThemesProvider } from "next-themes"; import { useQueryState } from "nuqs"; import type * as React from "react"; -import { useEmbed } from "@/hooks/use-embed"; -import { embedThemeParser } from "@/lib/embed-params"; +import { useEmbed } from "../../hooks/use-embed"; +import { embedThemeParser } from "../../lib/embed-params"; export function ThemeProvider({ children, diff --git a/apps/status-page/src/components/themes/theme-sidebar.tsx b/apps/status-page/src/components/themes/theme-sidebar.tsx index 2b43361a..3293962e 100644 --- a/apps/status-page/src/components/themes/theme-sidebar.tsx +++ b/apps/status-page/src/components/themes/theme-sidebar.tsx @@ -58,8 +58,8 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { searchParamsParsers } from "@/app/(public)/search-params"; -import { recomputeStyles } from "@/components/status-page/floating-button"; +import { searchParamsParsers } from "../../app/(public)/search-params"; +import { recomputeStyles } from "../status-page/floating-button"; type ThemeBuilderColor = { label: string; diff --git a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx index bb18066f..e945965b 100644 --- a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx +++ b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx @@ -5,8 +5,8 @@ import { Input } from "@openstatus/ui/components/ui/input"; import type { Table } from "@tanstack/react-table"; import { X } from "lucide-react"; -import { DataTableFacetedFilter } from "@/components/ui/data-table/data-table-faceted-filter"; -import { DataTableViewOptions } from "@/components/ui/data-table/data-table-view-options"; +import { DataTableFacetedFilter } from "./data-table-faceted-filter"; +import { DataTableViewOptions } from "./data-table-view-options"; export interface DataTableToolbarProps { table: Table; diff --git a/apps/status-page/src/content/markdown/generators.test.ts b/apps/status-page/src/content/markdown/generators.test.ts index 05c074d5..0bfd7274 100644 --- a/apps/status-page/src/content/markdown/generators.test.ts +++ b/apps/status-page/src/content/markdown/generators.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { escapeCell, diff --git a/apps/status-page/src/content/markdown/match-route.test.ts b/apps/status-page/src/content/markdown/match-route.test.ts index 7000f38d..4a4175fd 100644 --- a/apps/status-page/src/content/markdown/match-route.test.ts +++ b/apps/status-page/src/content/markdown/match-route.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchMarkdownRoute, parseMarkdownPath } from "./match-route"; diff --git a/apps/status-page/src/content/status-json.test.ts b/apps/status-page/src/content/status-json.test.ts index 70e450c2..d0fe2da1 100644 --- a/apps/status-page/src/content/status-json.test.ts +++ b/apps/status-page/src/content/status-json.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { RouterOutputs } from "@openstatus/api"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchEndpoint, diff --git a/apps/status-page/src/content/status-vocab.test.ts b/apps/status-page/src/content/status-vocab.test.ts index 5769f458..da2f5bb6 100644 --- a/apps/status-page/src/content/status-vocab.test.ts +++ b/apps/status-page/src/content/status-vocab.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { componentStatus, diff --git a/apps/status-page/src/data/metrics.client.ts b/apps/status-page/src/data/metrics.client.ts index 790dc19c..9db66b9e 100644 --- a/apps/status-page/src/data/metrics.client.ts +++ b/apps/status-page/src/data/metrics.client.ts @@ -3,9 +3,8 @@ import type { RouterOutputs } from "@openstatus/api"; import { monitorRegions } from "@openstatus/db/src/schema/constants"; -import type { MetricCard } from "@/components/content/metric-card"; -import { formatDateTime, formatMilliseconds } from "@/lib/formatter"; - +import type { MetricCard } from "../components/content/metric-card"; +import { formatDateTime, formatMilliseconds } from "../lib/formatter"; import type { RegionMetric } from "./region-metrics"; import type { Region } from "./regions"; diff --git a/apps/status-page/src/hooks/use-embed.ts b/apps/status-page/src/hooks/use-embed.ts index 2369e961..1c202b4f 100644 --- a/apps/status-page/src/hooks/use-embed.ts +++ b/apps/status-page/src/hooks/use-embed.ts @@ -2,13 +2,13 @@ import { useQueryState } from "nuqs"; -import { embedParser } from "@/lib/embed-params"; +import { embedParser } from "../lib/embed-params"; export { ALL_EMBED_SECTIONS, type EmbedSection, type EmbedState, -} from "@/lib/embed-params"; +} from "../lib/embed-params"; export function useEmbed() { const [state] = useQueryState("embed", embedParser); diff --git a/apps/status-page/src/hooks/use-pathname-prefix.ts b/apps/status-page/src/hooks/use-pathname-prefix.ts index 46a898d3..fb0f6b0a 100644 --- a/apps/status-page/src/hooks/use-pathname-prefix.ts +++ b/apps/status-page/src/hooks/use-pathname-prefix.ts @@ -5,9 +5,9 @@ import { useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { defaultLocale as globalDefaultLocale } from "@/i18n/config"; -import { resolvePathnamePrefix } from "@/lib/resolve-pathname-prefix"; -import { useTRPC } from "@/lib/trpc/client"; +import { defaultLocale as globalDefaultLocale } from "../i18n/config"; +import { resolvePathnamePrefix } from "../lib/resolve-pathname-prefix"; +import { useTRPC } from "../lib/trpc/client"; export function usePathnamePrefix() { const trpc = useTRPC(); diff --git a/apps/status-page/src/lib/alternates-metadata.ts b/apps/status-page/src/lib/alternates-metadata.ts index ae4d6655..192b7e58 100644 --- a/apps/status-page/src/lib/alternates-metadata.ts +++ b/apps/status-page/src/lib/alternates-metadata.ts @@ -1,7 +1,7 @@ import type { Metadata } from "next"; -import { statusPageAlternates } from "@/lib/alternates"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternates } from "./alternates"; +import { getQueryClient, trpc } from "./trpc/server"; export async function statusPageAlternatesMetadata({ domain, diff --git a/apps/status-page/src/lib/alternates.test.ts b/apps/status-page/src/lib/alternates.test.ts index 900502ee..320be3b7 100644 --- a/apps/status-page/src/lib/alternates.test.ts +++ b/apps/status-page/src/lib/alternates.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { statusPageAlternates } from "./alternates"; diff --git a/apps/status-page/src/lib/auth/index.ts b/apps/status-page/src/lib/auth/index.ts index 40d655e6..80fad5f0 100644 --- a/apps/status-page/src/lib/auth/index.ts +++ b/apps/status-page/src/lib/auth/index.ts @@ -4,9 +4,8 @@ import type { DefaultSession } from "next-auth"; import NextAuth, { AuthError } from "next-auth"; import { headers } from "next/headers"; -import { getValidCustomDomain } from "@/lib/domain"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; - +import { getValidCustomDomain } from "../domain"; +import { getQueryClient, trpc } from "../trpc/server"; import { adapter } from "./adapter"; import { ResendProvider } from "./providers"; diff --git a/apps/status-page/src/lib/auth/providers.ts b/apps/status-page/src/lib/auth/providers.ts index 8ff8d930..45967066 100644 --- a/apps/status-page/src/lib/auth/providers.ts +++ b/apps/status-page/src/lib/auth/providers.ts @@ -1,9 +1,8 @@ import { EmailClient } from "@openstatus/emails"; import Resend from "next-auth/providers/resend"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; - import { getValidCustomDomain } from "../domain"; +import { getQueryClient, trpc } from "../trpc/server"; export const ResendProvider = Resend({ apiKey: undefined, diff --git a/apps/status-page/src/lib/formatter.test.ts b/apps/status-page/src/lib/formatter.test.ts index d9e59b03..bcba4dde 100644 --- a/apps/status-page/src/lib/formatter.test.ts +++ b/apps/status-page/src/lib/formatter.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { formatDate, diff --git a/apps/status-page/src/lib/http/client-ip.test.ts b/apps/status-page/src/lib/http/client-ip.test.ts index 684c07a5..45b2f7c4 100644 --- a/apps/status-page/src/lib/http/client-ip.test.ts +++ b/apps/status-page/src/lib/http/client-ip.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveClientIp } from "./client-ip"; diff --git a/apps/status-page/src/lib/http/etag.test.ts b/apps/status-page/src/lib/http/etag.test.ts index 66e86bd8..66d584e3 100644 --- a/apps/status-page/src/lib/http/etag.test.ts +++ b/apps/status-page/src/lib/http/etag.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { computeETag, isNotModified } from "./etag"; diff --git a/apps/status-page/src/lib/http/markdown-response.test.ts b/apps/status-page/src/lib/http/markdown-response.test.ts index c519398e..00976f94 100644 --- a/apps/status-page/src/lib/http/markdown-response.test.ts +++ b/apps/status-page/src/lib/http/markdown-response.test.ts @@ -1,8 +1,9 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; -import { withPoweredBy } from "@/content/markdown"; -import { computeETag } from "@/lib/http/etag"; -import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; +import { withPoweredBy } from "../../content/markdown"; +import { computeETag } from "./etag"; +import { resolveMarkdownResponse } from "./markdown-response"; const PUBLIC_CACHE = "public, max-age=60, s-maxage=60, stale-while-revalidate=300"; diff --git a/apps/status-page/src/lib/http/markdown-response.ts b/apps/status-page/src/lib/http/markdown-response.ts index ae27ed3e..41cb8b1f 100644 --- a/apps/status-page/src/lib/http/markdown-response.ts +++ b/apps/status-page/src/lib/http/markdown-response.ts @@ -1,6 +1,6 @@ -import { withPoweredBy } from "@/content/markdown"; -import { computeETag, isNotModified } from "@/lib/http/etag"; -import { markdownCacheControl } from "@/lib/proxy/markdown-cache-control"; +import { withPoweredBy } from "../../content/markdown"; +import { markdownCacheControl } from "../proxy/markdown-cache-control"; +import { computeETag, isNotModified } from "./etag"; const MARKDOWN = "text/markdown; charset=utf-8"; diff --git a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts index f6821af1..c04f0fe6 100644 --- a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts +++ b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { applyPageLocaleOverride } from "./apply-page-locale-override"; diff --git a/apps/status-page/src/lib/proxy/build-external-path.test.ts b/apps/status-page/src/lib/proxy/build-external-path.test.ts index e809f6da..df5444bb 100644 --- a/apps/status-page/src/lib/proxy/build-external-path.test.ts +++ b/apps/status-page/src/lib/proxy/build-external-path.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildExternalPath } from "./build-external-path"; diff --git a/apps/status-page/src/lib/proxy/compose-page-action.test.ts b/apps/status-page/src/lib/proxy/compose-page-action.test.ts index 92c33732..f3778b40 100644 --- a/apps/status-page/src/lib/proxy/compose-page-action.test.ts +++ b/apps/status-page/src/lib/proxy/compose-page-action.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Page } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { type ComposeInput, composePageAction } from "./compose-page-action"; diff --git a/apps/status-page/src/lib/proxy/detect-markdown.test.ts b/apps/status-page/src/lib/proxy/detect-markdown.test.ts index 10dbc1f9..75d0c613 100644 --- a/apps/status-page/src/lib/proxy/detect-markdown.test.ts +++ b/apps/status-page/src/lib/proxy/detect-markdown.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { detectMarkdown } from "./detect-markdown"; diff --git a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts index 02c7f46b..2386573a 100644 --- a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts +++ b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { evaluateMarkdownGate } from "./evaluate-markdown-gate"; diff --git a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts index d96101df..c963ca31 100644 --- a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts +++ b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { isIpAllowed } from "./is-ip-allowed"; diff --git a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts index 9b6f9053..0f8cd54f 100644 --- a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts +++ b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { markdownCacheControl } from "./markdown-cache-control"; diff --git a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts index 06eec605..67a2c1f4 100644 --- a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveCustomDomainRewrite } from "./resolve-custom-domain-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts index 57f39dd2..5aff1bca 100644 --- a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveDefaultRewrite } from "./resolve-default-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts index b6f87852..0a47a7ef 100644 --- a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveEmailDomainAction } from "./resolve-email-domain-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-gate.ts b/apps/status-page/src/lib/proxy/resolve-gate.ts index 7e56564e..fb6ca343 100644 --- a/apps/status-page/src/lib/proxy/resolve-gate.ts +++ b/apps/status-page/src/lib/proxy/resolve-gate.ts @@ -1,10 +1,9 @@ import type { Page } from "@openstatus/db/src/schema"; -import { auth } from "@/lib/auth"; -import { createProtectedCookieKey } from "@/lib/protected"; -import type { getQueryClient } from "@/lib/trpc/server"; -import { trpc } from "@/lib/trpc/server"; - +import { auth } from "../auth"; +import { createProtectedCookieKey } from "../protected"; +import type { getQueryClient } from "../trpc/server"; +import { trpc } from "../trpc/server"; import { evaluateMarkdownGate, type MarkdownGateResult, diff --git a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts index 0405f812..58987fb9 100644 --- a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveIpRestrictionAction } from "./resolve-ip-restriction-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts index 946ea0b6..ef78a82c 100644 --- a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveLocaleAction } from "./resolve-locale-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts index 5904bdf9..382f8137 100644 --- a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolvePasswordAction } from "./resolve-password-action"; diff --git a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts index a50c54eb..5a3c6989 100644 --- a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts +++ b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { sanitizeRedirectParam } from "./sanitize-redirect-param"; diff --git a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts index b4447230..041ad0a4 100644 --- a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts +++ b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { stripPrefixForExternal } from "./strip-prefix-for-external"; diff --git a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts index 867c64cc..85e9d9b7 100644 --- a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts +++ b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolvePathnamePrefix } from "./resolve-pathname-prefix"; diff --git a/apps/status-page/src/lib/resolve-route.test.ts b/apps/status-page/src/lib/resolve-route.test.ts index fa1f8e71..39046b50 100644 --- a/apps/status-page/src/lib/resolve-route.test.ts +++ b/apps/status-page/src/lib/resolve-route.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveRoute } from "./resolve-route"; diff --git a/apps/status-page/src/lib/resolve-route.ts b/apps/status-page/src/lib/resolve-route.ts index 88f8760c..2e280487 100644 --- a/apps/status-page/src/lib/resolve-route.ts +++ b/apps/status-page/src/lib/resolve-route.ts @@ -1,5 +1,4 @@ -import { type Locale, defaultLocale, locales } from "@/i18n/config"; - +import { type Locale, defaultLocale, locales } from "../i18n/config"; import { getValidSubdomain } from "./domain"; export type RouteType = "hostname" | "pathname"; diff --git a/apps/status-page/src/lib/status-blocks-labels.test.ts b/apps/status-page/src/lib/status-blocks-labels.test.ts index e3d5c223..f6878d61 100644 --- a/apps/status-page/src/lib/status-blocks-labels.test.ts +++ b/apps/status-page/src/lib/status-blocks-labels.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { defaultStatusBlocksLabels as labels } from "@openstatus/ui/components/blocks/status.utils"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; // Status-page timestamps render in UTC, so the user-facing labels carry a // trailing "(UTC)" to tell viewers which zone they are reading (see #2302). diff --git a/apps/status-page/src/lib/trpc/client.tsx b/apps/status-page/src/lib/trpc/client.tsx index 296c0c42..51ecd68c 100644 --- a/apps/status-page/src/lib/trpc/client.tsx +++ b/apps/status-page/src/lib/trpc/client.tsx @@ -6,7 +6,7 @@ import { createTRPCClient, loggerLink } from "@trpc/client"; import { createTRPCContext } from "@trpc/tanstack-react-query"; import { useState } from "react"; -import { endingLink } from "@/lib/trpc/shared"; +import { endingLink } from "./shared"; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext(); diff --git a/apps/status-page/src/proxy.ts b/apps/status-page/src/proxy.ts index ab8511f2..b93550f9 100644 --- a/apps/status-page/src/proxy.ts +++ b/apps/status-page/src/proxy.ts @@ -2,9 +2,8 @@ import { db, sql } from "@openstatus/db"; import { page, selectPageSchema } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { auth } from "@/lib/auth"; -import { resolveClientIp } from "@/lib/http/client-ip"; - +import { auth } from "./lib/auth"; +import { resolveClientIp } from "./lib/http/client-ip"; import { createProtectedCookieKey } from "./lib/protected"; import { applyPageLocaleOverride } from "./lib/proxy/apply-page-locale-override"; import { composePageAction } from "./lib/proxy/compose-page-action"; diff --git a/apps/web/env.ts b/apps/web/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/web/env.ts +++ b/apps/web/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/web/package.json b/apps/web/package.json index e7fb85bb..ebf0045d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -3,13 +3,13 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "bun env.ts", + "env": "deno run -A env.ts", "dev": "next dev", "build:registry": "turbo run registry:build --filter=@openstatus/ui", "build": "pnpm build:registry && next build", "start": "next start", "lint": "next lint", - "test": "bun test", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -98,6 +98,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", diff --git a/apps/web/src/app/(ai)/llms-full.txt/route.ts b/apps/web/src/app/(ai)/llms-full.txt/route.ts index 75e06708..f4751861 100644 --- a/apps/web/src/app/(ai)/llms-full.txt/route.ts +++ b/apps/web/src/app/(ai)/llms-full.txt/route.ts @@ -1,15 +1,15 @@ -import { convertMdxToMarkdown } from "@/content/convert"; +import { convertMdxToMarkdown } from "../../../content/convert"; import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "@/content/llms-context"; +} from "../../../content/llms-context"; import { type MDXData, getHomePage, getProductPages, getToolingPages, getUnrelatedPages, -} from "@/content/utils"; +} from "../../../content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/llms.txt/route.ts b/apps/web/src/app/(ai)/llms.txt/route.ts index 6bc1cf36..069076c1 100644 --- a/apps/web/src/app/(ai)/llms.txt/route.ts +++ b/apps/web/src/app/(ai)/llms.txt/route.ts @@ -1,7 +1,7 @@ import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "@/content/llms-context"; +} from "../../../content/llms-context"; import { type MDXData, getBlogPosts, @@ -14,7 +14,7 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "@/content/utils"; +} from "../../../content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/mcp/route.ts b/apps/web/src/app/(ai)/mcp/route.ts index dc30e23c..26cd2883 100644 --- a/apps/web/src/app/(ai)/mcp/route.ts +++ b/apps/web/src/app/(ai)/mcp/route.ts @@ -1,6 +1,6 @@ // Discovery endpoint for /mcp. JSON clients receive the server card inline // (no domain coupling); browsers get redirected to the human-readable page. -import { GET as serverCardGET } from "@/app/.well-known/mcp/server-card.json/route"; +import { GET as serverCardGET } from "../../.well-known/mcp/server-card.json/route"; export function GET(request: Request) { const accept = request.headers.get("accept") ?? ""; diff --git a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx index fc9dc97a..e80ed59a 100644 --- a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx +++ b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx @@ -5,34 +5,34 @@ import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { ContentPagination } from "@/app/(landing)/content-pagination"; +} from "../../../(landing)/content-box"; +import { ContentPagination } from "../../../(landing)/content-pagination"; import { getDocs, getDocsPage, getDocsPagination, gitLastModified, validateDocsNav, -} from "@/content/docs"; -import { DocsFeedback } from "@/content/docs-feedback"; -import { DocsSubNav } from "@/content/docs-sub-nav"; -import { TableOfContents } from "@/content/docs-toc"; +} from "../../../../content/docs"; +import { DocsFeedback } from "../../../../content/docs-feedback"; +import { DocsSubNav } from "../../../../content/docs-sub-nav"; +import { TableOfContents } from "../../../../content/docs-toc"; import { type DocsNavNode, docsNavTree, findDocsNode, findDocsTrail, getDocsContainerSlugs, -} from "@/content/docs.config"; -import { CustomMDX } from "@/content/mdx"; -import { Grid } from "@/content/mdx-components/grid"; -import { extractHeadings } from "@/content/toc"; -import { JsonLd } from "@/lib/metadata/json-ld"; +} from "../../../../content/docs.config"; +import { CustomMDX } from "../../../../content/mdx"; +import { Grid } from "../../../../content/mdx-components/grid"; +import { extractHeadings } from "../../../../content/toc"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; import { BASE_URL, getPageMetadata, getSocialMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -41,7 +41,7 @@ import { getJsonLDItemList, getJsonLDOrganization, getJsonLDTechArticle, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(docs)/layout.tsx b/apps/web/src/app/(docs)/layout.tsx index 153bdd8b..1664fe19 100644 --- a/apps/web/src/app/(docs)/layout.tsx +++ b/apps/web/src/app/(docs)/layout.tsx @@ -1,6 +1,6 @@ -import { DocsFooter } from "@/content/docs-footer"; -import { DocsHeader } from "@/content/docs-header"; -import { DocsMobileNav, DocsSidebar } from "@/content/docs-sidebar"; +import { DocsFooter } from "../../content/docs-footer"; +import { DocsHeader } from "../../content/docs-header"; +import { DocsMobileNav, DocsSidebar } from "../../content/docs-sidebar"; export default function DocsLayout({ children, diff --git a/apps/web/src/app/(landing)/[slug]/page.tsx b/apps/web/src/app/(landing)/[slug]/page.tsx index 1713d307..41c0ecb1 100644 --- a/apps/web/src/app/(landing)/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/[slug]/page.tsx @@ -1,10 +1,10 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getMainPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../content/mdx"; +import { getMainPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getPageMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -13,7 +13,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/blog/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/[slug]/page.tsx index 2d400a23..a230288f 100644 --- a/apps/web/src/app/(landing)/blog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getBlogPosts } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx index 553c7cf1..64e66988 100644 --- a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getBlogPosts } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/blog/category/page.tsx b/apps/web/src/app/(landing)/blog/category/page.tsx index 266e2986..6d917999 100644 --- a/apps/web/src/app/(landing)/blog/category/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getBlogPosts } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getBlogPosts } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Blog Categories"; diff --git a/apps/web/src/app/(landing)/blog/feed.xml/route.ts b/apps/web/src/app/(landing)/blog/feed.xml/route.ts index e8122942..82a77083 100644 --- a/apps/web/src/app/(landing)/blog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/blog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getBlogPosts } from "@/content/utils"; +import { getBlogPosts } from "../../../../content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/blog/page.tsx b/apps/web/src/app/(landing)/blog/page.tsx index 18bd6d31..0da5f407 100644 --- a/apps/web/src/app/(landing)/blog/page.tsx +++ b/apps/web/src/app/(landing)/blog/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getBlogPosts } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx index 01a9ef56..a0071eb2 100644 --- a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getChangelogPosts } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx index d970a69d..269532c2 100644 --- a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getChangelogPosts } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/changelog/category/page.tsx b/apps/web/src/app/(landing)/changelog/category/page.tsx index d9472c13..65b4a27c 100644 --- a/apps/web/src/app/(landing)/changelog/category/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getChangelogPosts } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getChangelogPosts } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Changelog Categories"; diff --git a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts index d48b54bc..78422c9c 100644 --- a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getChangelogPosts } from "@/content/utils"; +import { getChangelogPosts } from "../../../../content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/changelog/page.tsx b/apps/web/src/app/(landing)/changelog/page.tsx index ad57acd8..c7d07e67 100644 --- a/apps/web/src/app/(landing)/changelog/page.tsx +++ b/apps/web/src/app/(landing)/changelog/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getChangelogPosts } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/compare/[slug]/page.tsx b/apps/web/src/app/(landing)/compare/[slug]/page.tsx index f3002f40..95bcf03f 100644 --- a/apps/web/src/app/(landing)/compare/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/compare/[slug]/page.tsx @@ -1,11 +1,13 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { ContentPagination } from "@/app/(landing)/content-pagination"; -import { CustomMDX } from "@/content/mdx"; -import { getComparePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getComparePages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,7 +16,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; +import { ContentPagination } from "../../content-pagination"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/compare/page.tsx b/apps/web/src/app/(landing)/compare/page.tsx index 7bc2f2b1..f4f01e1e 100644 --- a/apps/web/src/app/(landing)/compare/page.tsx +++ b/apps/web/src/app/(landing)/compare/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getComparePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getComparePages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/content-box-image.tsx b/apps/web/src/app/(landing)/content-box-image.tsx index 4d1ff74a..2e32b42e 100644 --- a/apps/web/src/app/(landing)/content-box-image.tsx +++ b/apps/web/src/app/(landing)/content-box-image.tsx @@ -1,7 +1,7 @@ import type React from "react"; -import { CustomImage } from "@/content/mdx-components/custom-image"; -import { cn } from "@/lib/utils"; +import { CustomImage } from "../../content/mdx-components/custom-image"; +import { cn } from "../../lib/utils"; export function ContentBoxImage({ className, diff --git a/apps/web/src/app/(landing)/content-box.tsx b/apps/web/src/app/(landing)/content-box.tsx index 6cfbdea2..a66a914a 100644 --- a/apps/web/src/app/(landing)/content-box.tsx +++ b/apps/web/src/app/(landing)/content-box.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function ContentBoxLink({ href, diff --git a/apps/web/src/app/(landing)/content-category.tsx b/apps/web/src/app/(landing)/content-category.tsx index 826a7c5d..91ca45da 100644 --- a/apps/web/src/app/(landing)/content-category.tsx +++ b/apps/web/src/app/(landing)/content-category.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import { Fragment } from "react"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export function ContentCategory({ data, diff --git a/apps/web/src/app/(landing)/content-list.tsx b/apps/web/src/app/(landing)/content-list.tsx index 1a3e08fb..1f6c40ab 100644 --- a/apps/web/src/app/(landing)/content-list.tsx +++ b/apps/web/src/app/(landing)/content-list.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { type MDXData, formatDate } from "@/content/utils"; -import { cn } from "@/lib/utils"; +import { type MDXData, formatDate } from "../../content/utils"; +import { cn } from "../../lib/utils"; export function ContentList({ data, diff --git a/apps/web/src/app/(landing)/content-metadata.tsx b/apps/web/src/app/(landing)/content-metadata.tsx index 02fd8bea..aa9ebb23 100644 --- a/apps/web/src/app/(landing)/content-metadata.tsx +++ b/apps/web/src/app/(landing)/content-metadata.tsx @@ -1,5 +1,5 @@ -import { type MDXData, formatDate } from "@/content/utils"; -import { getAuthor } from "@/data/author"; +import { type MDXData, formatDate } from "../../content/utils"; +import { getAuthor } from "../../data/author"; export function ContentMetadata({ data }: { data: MDXData }) { return ( diff --git a/apps/web/src/app/(landing)/content-pagination.tsx b/apps/web/src/app/(landing)/content-pagination.tsx index 710feed5..91f98721 100644 --- a/apps/web/src/app/(landing)/content-pagination.tsx +++ b/apps/web/src/app/(landing)/content-pagination.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export function ContentPagination({ prev, diff --git a/apps/web/src/app/(landing)/customers/[slug]/page.tsx b/apps/web/src/app/(landing)/customers/[slug]/page.tsx index ee02d501..b4d0b714 100644 --- a/apps/web/src/app/(landing)/customers/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/customers/[slug]/page.tsx @@ -1,18 +1,21 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { CustomImage } from "@/content/mdx-components/custom-image"; -import { getCustomerPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { CustomImage } from "../../../../content/mdx-components/custom-image"; +import { getCustomerPages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/customers/page.tsx b/apps/web/src/app/(landing)/customers/page.tsx index b810b8aa..707baddb 100644 --- a/apps/web/src/app/(landing)/customers/page.tsx +++ b/apps/web/src/app/(landing)/customers/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getCustomerPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getCustomerPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/guides/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/[slug]/page.tsx index 22583577..2db3fd5b 100644 --- a/apps/web/src/app/(landing)/guides/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getGuides } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx index 10f79591..1041fb8d 100644 --- a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getGuides } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/guides/category/page.tsx b/apps/web/src/app/(landing)/guides/category/page.tsx index 9660aa4c..cd19b69e 100644 --- a/apps/web/src/app/(landing)/guides/category/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getGuides } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getGuides } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Guides Categories"; diff --git a/apps/web/src/app/(landing)/guides/page.tsx b/apps/web/src/app/(landing)/guides/page.tsx index a66d5158..b4770986 100644 --- a/apps/web/src/app/(landing)/guides/page.tsx +++ b/apps/web/src/app/(landing)/guides/page.tsx @@ -1,20 +1,19 @@ import type { Metadata } from "next"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getGuides } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/layout.tsx b/apps/web/src/app/(landing)/layout.tsx index 2933a24a..e8b074eb 100644 --- a/apps/web/src/app/(landing)/layout.tsx +++ b/apps/web/src/app/(landing)/layout.tsx @@ -1,6 +1,6 @@ -import { Footer } from "@/content/footer"; -import { Header } from "@/content/header"; -import { SubNav } from "@/content/sub-nav"; +import { Footer } from "../../content/footer"; +import { Header } from "../../content/header"; +import { SubNav } from "../../content/sub-nav"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/web/src/app/(landing)/oss-friends/page.tsx b/apps/web/src/app/(landing)/oss-friends/page.tsx index ed292882..9e58bc7a 100644 --- a/apps/web/src/app/(landing)/oss-friends/page.tsx +++ b/apps/web/src/app/(landing)/oss-friends/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; import { z } from "zod"; -import { components } from "@/content/mdx"; +import { components } from "../../../content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../lib/metadata/shared-metadata"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/page.tsx b/apps/web/src/app/(landing)/page.tsx index b9cab94f..6576990f 100644 --- a/apps/web/src/app/(landing)/page.tsx +++ b/apps/web/src/app/(landing)/page.tsx @@ -1,9 +1,9 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getHomePage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { defaultMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../content/mdx"; +import { getHomePage } from "../../content/utils"; +import { JsonLd } from "../../lib/metadata/json-ld"; +import { defaultMetadata } from "../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -12,7 +12,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../lib/metadata/structured-data"; export const metadata: Metadata = defaultMetadata; diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx index 1f23b684..6b979138 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx @@ -19,15 +19,14 @@ import { } from "@openstatus/ui/components/ui/tabs"; import { useState } from "react"; -import { IconCloudProvider } from "@/components/icon-cloud-provider"; +import { IconCloudProvider } from "../../../../../components/icon-cloud-provider"; import { type CachedRegionChecker, getTimingPhases, regionFormatter, timestampFormatter, -} from "@/lib/checker/utils"; -import { cn } from "@/lib/utils"; - +} from "../../../../../lib/checker/utils"; +import { cn } from "../../../../../lib/utils"; import { handleExportCSV } from "../utils"; const STATUS_CODES = { diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx index 8cc463d0..f07f70f0 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx @@ -1,22 +1,24 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { mockCheckAllRegions } from "@/lib/checker/mock"; +import { CustomMDX } from "../../../../../content/mdx"; +import { getToolsPage } from "../../../../../content/utils"; +import { mockCheckAllRegions } from "../../../../../lib/checker/mock"; import { getCheckerDataById, latencyFormatter, regionFormatter, -} from "@/lib/checker/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/checker/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../../lib/metadata/structured-data"; import { Table } from "./client"; function formatDate(date: Date) { diff --git a/apps/web/src/app/(landing)/play/checker/api/route.ts b/apps/web/src/app/(landing)/play/checker/api/route.ts index a9ce8c99..14230857 100644 --- a/apps/web/src/app/(landing)/play/checker/api/route.ts +++ b/apps/web/src/app/(landing)/play/checker/api/route.ts @@ -3,17 +3,17 @@ import { AVAILABLE_REGIONS } from "@openstatus/regions"; import { after } from "next/server"; import { z } from "zod"; -import { mockCheckRegion } from "@/lib/checker/mock"; +import { mockCheckRegion } from "../../../../../lib/checker/mock"; import { type Method, checkRegion, getTimingPhases, storeBaseCheckerData, storeCheckerData, -} from "@/lib/checker/utils"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; -import { iteratorToStream, yieldMany } from "@/lib/stream"; -import { wait } from "@/lib/utils"; +} from "../../../../../lib/checker/utils"; +import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; +import { iteratorToStream, yieldMany } from "../../../../../lib/stream"; +import { wait } from "../../../../../lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/(landing)/play/checker/client.tsx b/apps/web/src/app/(landing)/play/checker/client.tsx index 471ad579..1db7ed7c 100644 --- a/apps/web/src/app/(landing)/play/checker/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/client.tsx @@ -25,17 +25,16 @@ import { useTransition, } from "react"; -import { IconCloudProvider } from "@/components/icon-cloud-provider"; +import { IconCloudProvider } from "../../../../components/icon-cloud-provider"; import { type Timing, is32CharHex, latencyFormatter, regionCheckerSchema, regionFormatter, -} from "@/lib/checker/utils"; -import { toast } from "@/lib/toast"; -import { cn, notEmpty } from "@/lib/utils"; - +} from "../../../../lib/checker/utils"; +import { toast } from "../../../../lib/toast"; +import { cn, notEmpty } from "../../../../lib/utils"; import { searchParamsParsers } from "./search-params"; import { handleExportCSV } from "./utils"; diff --git a/apps/web/src/app/(landing)/play/checker/page.tsx b/apps/web/src/app/(landing)/play/checker/page.tsx index 7e53f3ee..f8a6dbd1 100644 --- a/apps/web/src/app/(landing)/play/checker/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/page.tsx @@ -1,18 +1,20 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { mockCheckAllRegions } from "@/lib/checker/mock"; -import { getCheckerDataById } from "@/lib/checker/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { mockCheckAllRegions } from "../../../../lib/checker/mock"; +import { getCheckerDataById } from "../../../../lib/checker/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { CheckerProvider, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/checker/utils.ts b/apps/web/src/app/(landing)/play/checker/utils.ts index 057b6134..410cf7a2 100644 --- a/apps/web/src/app/(landing)/play/checker/utils.ts +++ b/apps/web/src/app/(landing)/play/checker/utils.ts @@ -1,7 +1,7 @@ import { type Region, regionDict } from "@openstatus/regions"; -import { type Timing, getTimingPhases } from "@/lib/checker/utils"; -import { toast } from "@/lib/toast"; +import { type Timing, getTimingPhases } from "../../../../lib/checker/utils"; +import { toast } from "../../../../lib/toast"; export type CheckerRow = { region: string; diff --git a/apps/web/src/app/(landing)/play/curl/page.tsx b/apps/web/src/app/(landing)/play/curl/page.tsx index ed05a6f8..c7cc3fff 100644 --- a/apps/web/src/app/(landing)/play/curl/page.tsx +++ b/apps/web/src/app/(landing)/play/curl/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { Form } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx index 5df37359..1fba7fa6 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx @@ -1,7 +1,6 @@ "use client"; -import type { HealthCheckReport } from "@/lib/mcp/health-check"; - +import type { HealthCheckReport } from "../../../../../lib/mcp/health-check"; import { ResultTableStatic, ToolsTableView, VerdictBarStatic } from "../client"; export function Table({ data }: { data: HealthCheckReport }) { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx index d1d9678e..33daf4af 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx @@ -1,17 +1,19 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { getHealthReportById } from "@/lib/mcp/health-check"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../../content/mdx"; +import { getToolsPage } from "../../../../../content/utils"; +import { getHealthReportById } from "../../../../../lib/mcp/health-check"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../../lib/metadata/structured-data"; import { VERDICT_LABEL, formatTimestamp } from "../utils"; import { Table } from "./client"; diff --git a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts index fb81a631..71ced0d5 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts @@ -9,8 +9,8 @@ import { runMcpHealthCheck, storeHealthReport, toPersistedReport, -} from "@/lib/mcp/health-check"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; +} from "../../../../../lib/mcp/health-check"; +import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; export const runtime = "edge"; // Worst-case 16s of step time + metadata fetch + analytics; give some slack. diff --git a/apps/web/src/app/(landing)/play/mcp-health/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/client.tsx index 70efd99d..b42d585f 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/client.tsx @@ -32,10 +32,9 @@ import type { HealthCheckReport, StepResult, ToolInfo, -} from "@/lib/mcp/health-check"; -import { toast } from "@/lib/toast"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/mcp/health-check"; +import { toast } from "../../../../lib/toast"; +import { cn } from "../../../../lib/utils"; import { searchParamsParsers } from "./search-params"; import { STEP_REQUEST_BODIES, diff --git a/apps/web/src/app/(landing)/play/mcp-health/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/page.tsx index c6fff2e6..69da93cb 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/page.tsx @@ -1,18 +1,20 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { getHealthReportById } from "@/lib/mcp/health-check"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { getHealthReportById } from "../../../../lib/mcp/health-check"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDHowTo, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { AuthChallengeCallout, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts index 228c78b5..ba080c63 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { formatResponseBody, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.ts index 2080daa3..73c088b6 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.ts @@ -1,6 +1,12 @@ -import type { HealthCheckReport, StepResult } from "@/lib/mcp/health-check"; +import type { + HealthCheckReport, + StepResult, +} from "../../../../lib/mcp/health-check"; -export { STEP_REQUEST_BODIES, type StepKey } from "@/lib/mcp/protocol"; +export { + STEP_REQUEST_BODIES, + type StepKey, +} from "../../../../lib/mcp/protocol"; export const VERDICT_LABEL: Record = { healthy: "GOOD", diff --git a/apps/web/src/app/(landing)/play/page.tsx b/apps/web/src/app/(landing)/play/page.tsx index 7f27849d..a7d54da9 100644 --- a/apps/web/src/app/(landing)/play/page.tsx +++ b/apps/web/src/app/(landing)/play/page.tsx @@ -1,12 +1,11 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; +import { components } from "../../../content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../lib/metadata/shared-metadata"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx index 0a794ce8..bf8e8b85 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx @@ -7,7 +7,7 @@ import { Label } from "@openstatus/ui/components/ui/label"; import { Slider } from "@openstatus/ui/components/ui/slider"; import { useState } from "react"; -import { Details } from "@/content/mdx-components/details"; +import { Details } from "../../../../content/mdx-components/details"; type SeverityLevel = "SEV0" | "SEV1" | "SEV2" | "SEV3"; diff --git a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx index e3d57b2d..b4af063a 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { SeverityMatrixBuilder } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx index aa88a7c7..2214ce25 100644 --- a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx +++ b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { Calculation } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx index 6e6d88db..9e47b6bd 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx @@ -2,22 +2,21 @@ import { REPORT_WINDOW_MINUTES } from "@openstatus/api/src/router/effective-status"; -import { - ContentBoxDescription, - ContentBoxLink, - ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { Grid } from "@/content/mdx-components/grid"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL } from "@/lib/metadata/shared-metadata"; +import { Grid } from "../../../../../content/mdx-components/grid"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { BASE_URL } from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; -import { api } from "@/trpc/rq-client"; - +} from "../../../../../lib/metadata/structured-data"; +import { api } from "../../../../../trpc/rq-client"; +import { + ContentBoxDescription, + ContentBoxLink, + ContentBoxTitle, +} from "../../../content-box"; import { ExternalServicePill } from "../../external-service-pill"; import { formatRelative } from "../../utils"; import { HistoryBars } from "../history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx index 6906aeb7..c5f7e78d 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx @@ -2,18 +2,17 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; -import { cachedGetExternalComponentBySlug } from "@/lib/external-service-cache"; +import { ButtonLink } from "../../../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../../../content/mdx-components/custom-link"; +import { cachedGetExternalComponentBySlug } from "../../../../../lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/incidents.tsx b/apps/web/src/app/(landing)/status/[id]/incidents.tsx index 4ee5276c..2a4c6d60 100644 --- a/apps/web/src/app/(landing)/status/[id]/incidents.tsx +++ b/apps/web/src/app/(landing)/status/[id]/incidents.tsx @@ -1,12 +1,12 @@ "use client"; +import { Grid } from "../../../../content/mdx-components/grid"; +import { api } from "../../../../trpc/rq-client"; import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { Grid } from "@/content/mdx-components/grid"; -import { api } from "@/trpc/rq-client"; +} from "../../content-box"; function impactClass(impact: string | undefined): string { switch (impact) { diff --git a/apps/web/src/app/(landing)/status/[id]/page.tsx b/apps/web/src/app/(landing)/status/[id]/page.tsx index ea21922e..20594bf5 100644 --- a/apps/web/src/app/(landing)/status/[id]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/page.tsx @@ -3,19 +3,18 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; -import { getServiceEscalation } from "@/lib/external-report-escalation"; -import { cachedGetExternalServiceBySlug } from "@/lib/external-service-cache"; +import { ButtonLink } from "../../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../../content/mdx-components/custom-link"; +import { getServiceEscalation } from "../../../../lib/external-report-escalation"; +import { cachedGetExternalServiceBySlug } from "../../../../lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx index d3ed1de2..705129f0 100644 --- a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx +++ b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx @@ -12,8 +12,7 @@ import { } from "@openstatus/ui/components/ui/select"; import { useState } from "react"; -import { api } from "@/trpc/rq-client"; - +import { api } from "../../../../trpc/rq-client"; import { buildSections } from "../external-service-components"; const WHOLE_SERVICE = "all"; diff --git a/apps/web/src/app/(landing)/status/[id]/service-components.tsx b/apps/web/src/app/(landing)/status/[id]/service-components.tsx index bbaf6a57..ff0fe13d 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-components.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-components.tsx @@ -1,7 +1,6 @@ "use client"; -import { api } from "@/trpc/rq-client"; - +import { api } from "../../../../trpc/rq-client"; import { ExternalServiceComponents } from "../external-service-components"; export function ServiceComponents({ diff --git a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx index 7a92deb7..4ca6c477 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx @@ -2,17 +2,16 @@ import { Suspense } from "react"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL } from "@/lib/metadata/shared-metadata"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { BASE_URL } from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDService, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; -import { api } from "@/trpc/rq-client"; - +} from "../../../../lib/metadata/structured-data"; +import { api } from "../../../../trpc/rq-client"; import { ExternalServicePill } from "../external-service-pill"; import { formatRelative, getStatusAnswer, isStale } from "../utils"; import { HistoryBars } from "./history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx index 96b5ea5d..b22c8150 100644 --- a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx +++ b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx @@ -9,7 +9,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Bar, BarChart, XAxis } from "recharts"; -import { api } from "@/trpc/rq-client"; +import { api } from "../../../../trpc/rq-client"; const chartConfig = { total: { label: "Reports", color: "var(--color-warning)" }, diff --git a/apps/web/src/app/(landing)/status/external-status-grid.tsx b/apps/web/src/app/(landing)/status/external-status-grid.tsx index 070b4dcb..0a4a74c0 100644 --- a/apps/web/src/app/(landing)/status/external-status-grid.tsx +++ b/apps/web/src/app/(landing)/status/external-status-grid.tsx @@ -3,9 +3,8 @@ import { useQueryState } from "nuqs"; import { useMemo } from "react"; -import { Grid } from "@/content/mdx-components/grid"; -import { api } from "@/trpc/rq-client"; - +import { Grid } from "../../../content/mdx-components/grid"; +import { api } from "../../../trpc/rq-client"; import { ContentBoxLink } from "../content-box"; import { ExternalServicePill } from "./external-service-pill"; import { filterServices } from "./filter-services"; diff --git a/apps/web/src/app/(landing)/status/page.tsx b/apps/web/src/app/(landing)/status/page.tsx index 61656351..ef16c8e0 100644 --- a/apps/web/src/app/(landing)/status/page.tsx +++ b/apps/web/src/app/(landing)/status/page.tsx @@ -1,17 +1,16 @@ import type { Metadata } from "next"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; +import { ButtonLink } from "../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../content/mdx-components/custom-link"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx index 55e79dc4..3a677a21 100644 --- a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx @@ -1,10 +1,13 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolingPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolingPages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -12,7 +15,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/tooling/page.tsx b/apps/web/src/app/(landing)/tooling/page.tsx index 837eae5f..bd643023 100644 --- a/apps/web/src/app/(landing)/tooling/page.tsx +++ b/apps/web/src/app/(landing)/tooling/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getToolingPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getToolingPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx index a7855b95..6d4cdcd6 100644 --- a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getUseCasePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getUseCasePages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/use-case/page.tsx b/apps/web/src/app/(landing)/use-case/page.tsx index f298ea2c..d1e5b3ba 100644 --- a/apps/web/src/app/(landing)/use-case/page.tsx +++ b/apps/web/src/app/(landing)/use-case/page.tsx @@ -1,20 +1,19 @@ import type { Metadata } from "next"; -import { getUseCasePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getUseCasePages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentList } from "../content-list"; const TITLE = "Use Cases"; diff --git a/apps/web/src/app/api/checker/cron/_cron.ts b/apps/web/src/app/api/checker/cron/_cron.ts index d0385fa7..370077d6 100644 --- a/apps/web/src/app/api/checker/cron/_cron.ts +++ b/apps/web/src/app/api/checker/cron/_cron.ts @@ -22,7 +22,7 @@ import { import type { NextRequest } from "next/server"; import { z } from "zod"; -import { env } from "@/env"; +import { env } from "../../../../env"; const periodicityAvailable = selectMonitorSchema.pick({ periodicity: true }); diff --git a/apps/web/src/app/api/checker/test/http/route.ts b/apps/web/src/app/api/checker/test/http/route.ts index 5bf9f961..653c0c84 100644 --- a/apps/web/src/app/api/checker/test/http/route.ts +++ b/apps/web/src/app/api/checker/test/http/route.ts @@ -3,8 +3,7 @@ import { httpPayloadSchema } from "@openstatus/utils"; import { NextResponse } from "next/server"; import { z } from "zod"; -import { checkRegion } from "@/lib/checker/utils"; - +import { checkRegion } from "../../../../../lib/checker/utils"; import { isAnInvalidTestUrl } from "../../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/feedback/docs/route.ts b/apps/web/src/app/api/feedback/docs/route.ts index 1c0b313a..d99408b9 100644 --- a/apps/web/src/app/api/feedback/docs/route.ts +++ b/apps/web/src/app/api/feedback/docs/route.ts @@ -1,8 +1,8 @@ import { redis } from "@openstatus/upstash"; import { z } from "zod"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; -import { hashIP } from "@/lib/utils"; +import { getClientIP, ratelimit } from "../../../../lib/ratelimit"; +import { hashIP } from "../../../../lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/markdown/[[...path]]/route.ts b/apps/web/src/app/api/markdown/[[...path]]/route.ts index 9a1f41ff..b7c456a3 100644 --- a/apps/web/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/web/src/app/api/markdown/[[...path]]/route.ts @@ -1,11 +1,11 @@ import { type NextRequest, NextResponse } from "next/server"; -import { convertMdxToMarkdown } from "@/content/convert"; +import { convertMdxToMarkdown } from "../../../../content/convert"; import { generateStatusDetailMarkdown, generateStatusIndexMarkdown, -} from "@/content/status-markdown"; -import { resolveContent } from "@/content/utils/resolve"; +} from "../../../../content/status-markdown"; +import { resolveContent } from "../../../../content/utils/resolve"; export const runtime = "nodejs"; // Need fs access for content loading diff --git a/apps/web/src/app/api/og/_components/background.tsx b/apps/web/src/app/api/og/_components/background.tsx index 0405b09c..1db70723 100644 --- a/apps/web/src/app/api/og/_components/background.tsx +++ b/apps/web/src/app/api/og/_components/background.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../../../../lib/utils"; export function Background({ children, diff --git a/apps/web/src/app/api/og/_components/basic-layout.tsx b/apps/web/src/app/api/og/_components/basic-layout.tsx index 9ac36793..f8f59adf 100644 --- a/apps/web/src/app/api/og/_components/basic-layout.tsx +++ b/apps/web/src/app/api/og/_components/basic-layout.tsx @@ -1,5 +1,4 @@ -import { cn } from "@/lib/utils"; - +import { cn } from "../../../../lib/utils"; import { Background } from "./background"; export function BasicLayout({ diff --git a/apps/web/src/app/api/og/_components/status-check.tsx b/apps/web/src/app/api/og/_components/status-check.tsx index db63031e..19bf209c 100644 --- a/apps/web/src/app/api/og/_components/status-check.tsx +++ b/apps/web/src/app/api/og/_components/status-check.tsx @@ -1,6 +1,6 @@ import type { Tracker } from "@openstatus/tracker"; -import { cn } from "@/lib/utils"; +import { cn } from "../../../../lib/utils"; export function StatusCheck({ tracker }: { tracker: Tracker }) { const details = tracker.currentDetails; diff --git a/apps/web/src/app/api/og/_components/tracker.tsx b/apps/web/src/app/api/og/_components/tracker.tsx index d02580eb..86011967 100644 --- a/apps/web/src/app/api/og/_components/tracker.tsx +++ b/apps/web/src/app/api/og/_components/tracker.tsx @@ -1,7 +1,7 @@ import { Tracker as OSTracker, classNames } from "@openstatus/tracker"; -import type { ResponseStatusTracker } from "@/lib/tb"; -import { cn, formatDate } from "@/lib/utils"; +import type { ResponseStatusTracker } from "../../../../lib/tb"; +import { cn, formatDate } from "../../../../lib/utils"; interface TrackerProps { data: ResponseStatusTracker[]; diff --git a/apps/web/src/app/api/og/checker/route.tsx b/apps/web/src/app/api/og/checker/route.tsx index baeaf2a3..be80038a 100644 --- a/apps/web/src/app/api/og/checker/route.tsx +++ b/apps/web/src/app/api/og/checker/route.tsx @@ -4,9 +4,8 @@ import { getCheckerDataById, regionFormatter, timestampFormatter, -} from "@/lib/checker/utils"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/checker/utils"; +import { cn } from "../../../../lib/utils"; import { BasicLayout } from "../_components/basic-layout"; import { SIZE, diff --git a/apps/web/src/app/api/og/external-service/route.tsx b/apps/web/src/app/api/og/external-service/route.tsx index a2c1333e..6552526c 100644 --- a/apps/web/src/app/api/og/external-service/route.tsx +++ b/apps/web/src/app/api/og/external-service/route.tsx @@ -1,18 +1,17 @@ import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { isStale } from "@/app/(landing)/status/utils"; +import { isStale } from "../../../(landing)/status/utils"; import { getComponentEscalation, getServiceEscalation, -} from "@/lib/external-report-escalation"; +} from "../../../../lib/external-report-escalation"; import { cachedGetExternalComponentBySlug, cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/external-service-cache"; +import { cn } from "../../../../lib/utils"; import { SIZE } from "../utils"; // nodejs (not edge): this route pulls in the service reads + Effect retry, which diff --git a/apps/web/src/app/api/og/monitor/route.tsx b/apps/web/src/app/api/og/monitor/route.tsx index 1fa453ed..788ab200 100644 --- a/apps/web/src/app/api/og/monitor/route.tsx +++ b/apps/web/src/app/api/og/monitor/route.tsx @@ -1,9 +1,8 @@ import { OSTinybird } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { env } from "@/env"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; - +import { env } from "../../../../env"; +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; import { BasicLayout } from "../_components/basic-layout"; import { Tracker } from "../_components/tracker"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/page/route.tsx b/apps/web/src/app/api/og/page/route.tsx index 1ea61b35..72e8f733 100644 --- a/apps/web/src/app/api/og/page/route.tsx +++ b/apps/web/src/app/api/og/page/route.tsx @@ -1,9 +1,8 @@ import { Tracker } from "@openstatus/tracker"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; -import { api } from "@/trpc/server"; - +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; +import { api } from "../../../../trpc/server"; import { BasicLayout } from "../_components/basic-layout"; import { StatusCheck } from "../_components/status-check"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/post/route.tsx b/apps/web/src/app/api/og/post/route.tsx index 0413f82f..1f00b7b2 100644 --- a/apps/web/src/app/api/og/post/route.tsx +++ b/apps/web/src/app/api/og/post/route.tsx @@ -1,8 +1,7 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { TITLE } from "@/lib/metadata/shared-metadata"; - +import { TITLE } from "../../../../lib/metadata/shared-metadata"; import { BasicLayout } from "../_components/basic-layout"; import { DEFAULT_URL, diff --git a/apps/web/src/app/api/og/route.tsx b/apps/web/src/app/api/og/route.tsx index 73e77332..a84516f0 100644 --- a/apps/web/src/app/api/og/route.tsx +++ b/apps/web/src/app/api/og/route.tsx @@ -1,8 +1,7 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { OG_DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; - +import { OG_DESCRIPTION, TITLE } from "../../../lib/metadata/shared-metadata"; import { SIZE } from "./utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/og/status/route.tsx b/apps/web/src/app/api/og/status/route.tsx index 988b2154..c7f2cfb3 100644 --- a/apps/web/src/app/api/og/status/route.tsx +++ b/apps/web/src/app/api/og/status/route.tsx @@ -2,10 +2,9 @@ import type { RouterOutputs } from "@openstatus/api"; import { format } from "date-fns"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; -import { cn } from "@/lib/utils"; -import { api } from "@/trpc/server"; - +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; +import { cn } from "../../../../lib/utils"; +import { api } from "../../../../trpc/server"; import { SIZE } from "../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/search/route.ts b/apps/web/src/app/api/search/route.ts index c35f79bd..e9810d5d 100644 --- a/apps/web/src/app/api/search/route.ts +++ b/apps/web/src/app/api/search/route.ts @@ -1,7 +1,7 @@ import { z } from "zod"; -import { PAGE_TYPES } from "@/content/utils"; -import { searchCorpus } from "@/content/utils/search-index"; +import { PAGE_TYPES } from "../../../content/utils"; +import { searchCorpus } from "../../../content/utils/search-index"; const SearchSchema = z.object({ p: z.enum(PAGE_TYPES).nullish(), diff --git a/apps/web/src/app/api/test/timeout/route.ts b/apps/web/src/app/api/test/timeout/route.ts index 6513b15c..3e454a7e 100644 --- a/apps/web/src/app/api/test/timeout/route.ts +++ b/apps/web/src/app/api/test/timeout/route.ts @@ -1,6 +1,6 @@ import { NextResponse } from "next/server"; -import { wait } from "@/lib/utils"; +import { wait } from "../../../../lib/utils"; export async function POST() { await wait(10_000); diff --git a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts index 8ad8edf0..5a339780 100644 --- a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,7 +3,7 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "@/trpc/shared"; +import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts index 175c51af..ddbd1dbb 100644 --- a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,7 +3,7 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "@/trpc/shared"; +import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/web/src/app/api/webhook/stripe/route.ts b/apps/web/src/app/api/webhook/stripe/route.ts index 630ba246..992eae4d 100644 --- a/apps/web/src/app/api/webhook/stripe/route.ts +++ b/apps/web/src/app/api/webhook/stripe/route.ts @@ -4,7 +4,7 @@ import { TRPCError } from "@trpc/server"; import { getHTTPStatusCodeFromError } from "@trpc/server/http"; import type { NextRequest } from "next/server"; -import { env } from "@/env"; +import { env } from "../../../../env"; export async function POST(req: NextRequest) { const payload = await req.text(); diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index bab21c8c..cdd6ea15 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,4 +1,4 @@ -import "@/styles/globals.css"; +import "../styles/globals.css"; import { OpenPanelComponent } from "@openpanel/nextjs"; import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; @@ -8,15 +8,15 @@ import LocalFont from "next/font/local"; import Script from "next/script"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { ThemeProvider } from "@/components/theme-provider"; -import { WebMcpProvider } from "@/components/webmcp-provider"; -import { env } from "@/env"; +import { ThemeProvider } from "../components/theme-provider"; +import { WebMcpProvider } from "../components/webmcp-provider"; +import { env } from "../env"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { TRPCReactQueryProvider } from "@/trpc/rq-client"; +} from "../lib/metadata/shared-metadata"; +import { TRPCReactQueryProvider } from "../trpc/rq-client"; const inter = Inter({ subsets: ["latin"], variable: "--font-sans" }); diff --git a/apps/web/src/app/not-found.tsx b/apps/web/src/app/not-found.tsx index 6902b4b5..3f52999e 100644 --- a/apps/web/src/app/not-found.tsx +++ b/apps/web/src/app/not-found.tsx @@ -1,5 +1,5 @@ -import { CustomMDX } from "@/content/mdx"; -import { getUnrelatedPage } from "@/content/utils"; +import { CustomMDX } from "../content/mdx"; +import { getUnrelatedPage } from "../content/utils"; export default function NotFound() { const page = getUnrelatedPage("not-found"); diff --git a/apps/web/src/app/sitemap.ts b/apps/web/src/app/sitemap.ts index 9d43f572..53efa8ac 100644 --- a/apps/web/src/app/sitemap.ts +++ b/apps/web/src/app/sitemap.ts @@ -13,11 +13,11 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "@/content/utils"; +} from "../content/utils"; import { cachedListExternalComponentsBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; +} from "../lib/external-service-cache"; export const revalidate = 3600; diff --git a/apps/web/src/components/dev-mode-container.tsx b/apps/web/src/components/dev-mode-container.tsx index 76eb3a55..41042767 100644 --- a/apps/web/src/components/dev-mode-container.tsx +++ b/apps/web/src/components/dev-mode-container.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export default function DevModeContainer({ children, diff --git a/apps/web/src/components/icon-cloud-provider.tsx b/apps/web/src/components/icon-cloud-provider.tsx index 14db64a1..c1e9d7a2 100644 --- a/apps/web/src/components/icon-cloud-provider.tsx +++ b/apps/web/src/components/icon-cloud-provider.tsx @@ -7,7 +7,7 @@ import { } from "@openstatus/ui/components/ui/tooltip"; import { Globe } from "lucide-react"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function IconCloudProvider({ provider, diff --git a/apps/web/src/components/loading-animation.tsx b/apps/web/src/components/loading-animation.tsx index 3142bfd3..f3fdc9e6 100644 --- a/apps/web/src/components/loading-animation.tsx +++ b/apps/web/src/components/loading-animation.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type { VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; const loadingVariants = cva( "direction-alternate animate-pulse rounded-full duration-700", diff --git a/apps/web/src/config/socials.ts b/apps/web/src/config/socials.ts index e97d2487..0287bde6 100644 --- a/apps/web/src/config/socials.ts +++ b/apps/web/src/config/socials.ts @@ -1,4 +1,4 @@ -import type { ValidIcon } from "@/components/icons"; +import type { ValidIcon } from "../components/icons"; export type Social = { title: string; diff --git a/apps/web/src/content/cmdk.tsx b/apps/web/src/content/cmdk.tsx index da40c8f8..dcd2579a 100644 --- a/apps/web/src/content/cmdk.tsx +++ b/apps/web/src/content/cmdk.tsx @@ -24,12 +24,8 @@ import { useTheme } from "next-themes"; import { useRouter } from "next/navigation"; import * as React from "react"; -import { - CORPUS_LABELS, - type Corpus, - type SearchResult, -} from "@/content/search-meta"; -import { buildHighlightRegex } from "@/content/utils/search-match"; +import { CORPUS_LABELS, type Corpus, type SearchResult } from "./search-meta"; +import { buildHighlightRegex } from "./utils/search-match"; type ConfigItem = { type: "item"; diff --git a/apps/web/src/content/docs-feedback.tsx b/apps/web/src/content/docs-feedback.tsx index c57310f8..b9cefb17 100644 --- a/apps/web/src/content/docs-feedback.tsx +++ b/apps/web/src/content/docs-feedback.tsx @@ -21,7 +21,7 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { toastAction } from "@/lib/toast"; +import { toastAction } from "../lib/toast"; type Rating = "up" | "down"; diff --git a/apps/web/src/content/docs-footer.tsx b/apps/web/src/content/docs-footer.tsx index 6c3c564e..617c8a21 100644 --- a/apps/web/src/content/docs-footer.tsx +++ b/apps/web/src/content/docs-footer.tsx @@ -1,7 +1,6 @@ -import { Link } from "@/content/link"; -import { ThemeToggle } from "@/content/theme-toggle"; - import { FooterStatus } from "./footer-status"; +import { Link } from "./link"; +import { ThemeToggle } from "./theme-toggle"; export function DocsFooter() { return ( diff --git a/apps/web/src/content/docs-sidebar.tsx b/apps/web/src/content/docs-sidebar.tsx index a1c8381a..8b7546c2 100644 --- a/apps/web/src/content/docs-sidebar.tsx +++ b/apps/web/src/content/docs-sidebar.tsx @@ -12,8 +12,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { type DocsNavGroup, type DocsNavItem, diff --git a/apps/web/src/content/docs-sub-nav.tsx b/apps/web/src/content/docs-sub-nav.tsx index 7d50c8ac..7a939409 100644 --- a/apps/web/src/content/docs-sub-nav.tsx +++ b/apps/web/src/content/docs-sub-nav.tsx @@ -4,8 +4,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { CopyDropdownButton } from "./copy-button"; export function DocsSubNav({ diff --git a/apps/web/src/content/docs-toc.tsx b/apps/web/src/content/docs-toc.tsx index d83a02ac..f9a4642f 100644 --- a/apps/web/src/content/docs-toc.tsx +++ b/apps/web/src/content/docs-toc.tsx @@ -2,8 +2,7 @@ import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import type { TocItem } from "./toc"; function useActiveHeading(items: TocItem[]) { diff --git a/apps/web/src/content/footer-status.tsx b/apps/web/src/content/footer-status.tsx index 95e024da..ea8e43fd 100644 --- a/apps/web/src/content/footer-status.tsx +++ b/apps/web/src/content/footer-status.tsx @@ -4,7 +4,7 @@ import type { StatusResponse } from "@openstatus/react"; import { useQuery } from "@tanstack/react-query"; import Link from "next/link"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function FooterStatus() { const { data } = useQuery({ diff --git a/apps/web/src/content/footer.tsx b/apps/web/src/content/footer.tsx index 1045e551..406d1694 100644 --- a/apps/web/src/content/footer.tsx +++ b/apps/web/src/content/footer.tsx @@ -1,8 +1,7 @@ -import { Link } from "@/content/link"; -import { ThemeToggle } from "@/content/theme-toggle"; -import { footerLinks } from "@/data/content"; - +import { footerLinks } from "../data/content"; import { FooterStatus } from "./footer-status"; +import { Link } from "./link"; +import { ThemeToggle } from "./theme-toggle"; export function Footer() { return ( diff --git a/apps/web/src/content/header.tsx b/apps/web/src/content/header.tsx index 38c6a890..00389e7a 100644 --- a/apps/web/src/content/header.tsx +++ b/apps/web/src/content/header.tsx @@ -6,8 +6,7 @@ import { } from "@openstatus/ui/components/ui/dropdown-menu"; import Link from "next/link"; -import { headerLinks } from "@/data/content"; - +import { headerLinks } from "../data/content"; import { CmdK } from "./cmdk"; import { LogoWithContextMenu } from "./logo-with-context-menu"; diff --git a/apps/web/src/content/highlight-text.tsx b/apps/web/src/content/highlight-text.tsx index d3a5e5a6..0a22adf1 100644 --- a/apps/web/src/content/highlight-text.tsx +++ b/apps/web/src/content/highlight-text.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "next/navigation"; import { useEffect, useRef } from "react"; -import { buildHighlightRegex } from "@/content/utils/search-match"; +import { buildHighlightRegex } from "./utils/search-match"; function escapeHtml(input: string) { return input.replace(/[&<>]/g, (c) => diff --git a/apps/web/src/content/image-zoom.tsx b/apps/web/src/content/image-zoom.tsx index fa59e93b..93dc4288 100644 --- a/apps/web/src/content/image-zoom.tsx +++ b/apps/web/src/content/image-zoom.tsx @@ -9,7 +9,7 @@ import Zoom, { type UncontrolledProps, } from "react-medium-image-zoom"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export type ImageZoomProps = UncontrolledProps & { isZoomed?: ControlledProps["isZoomed"]; diff --git a/apps/web/src/content/latency-chart-table.tsx b/apps/web/src/content/latency-chart-table.tsx index bce59b84..3a7e5cc8 100644 --- a/apps/web/src/content/latency-chart-table.tsx +++ b/apps/web/src/content/latency-chart-table.tsx @@ -2,8 +2,7 @@ import fs from "node:fs"; import { type Region, regionDict } from "@openstatus/regions"; -import type { RegionMetricsChartTable } from "@/data/content"; - +import type { RegionMetricsChartTable } from "../data/content"; import { SimpleChart } from "./simple-chart"; export interface LatencyChartTableProps { diff --git a/apps/web/src/content/link.tsx b/apps/web/src/content/link.tsx index 9043ae77..9b928a9d 100644 --- a/apps/web/src/content/link.tsx +++ b/apps/web/src/content/link.tsx @@ -1,6 +1,6 @@ import NextLink from "next/link"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; // TODO: we could add cva variants for the link diff --git a/apps/web/src/content/mdx-components/aside.tsx b/apps/web/src/content/mdx-components/aside.tsx index c23385c2..863c9829 100644 --- a/apps/web/src/content/mdx-components/aside.tsx +++ b/apps/web/src/content/mdx-components/aside.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; type AsideType = "note" | "tip" | "caution" | "danger"; diff --git a/apps/web/src/content/mdx-components/card.tsx b/apps/web/src/content/mdx-components/card.tsx index 8a692833..336c1ea6 100644 --- a/apps/web/src/content/mdx-components/card.tsx +++ b/apps/web/src/content/mdx-components/card.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function CardGrid({ children }: { children: React.ReactNode }) { return

    ; diff --git a/apps/web/src/content/mdx-components/custom-image.tsx b/apps/web/src/content/mdx-components/custom-image.tsx index e7b12e80..a7087a2c 100644 --- a/apps/web/src/content/mdx-components/custom-image.tsx +++ b/apps/web/src/content/mdx-components/custom-image.tsx @@ -3,9 +3,8 @@ import { join } from "node:path"; import Image from "next/image"; -import { getImageDimensions } from "@/lib/image-dimensions"; -import { cn } from "@/lib/utils"; - +import { getImageDimensions } from "../../lib/image-dimensions"; +import { cn } from "../../lib/utils"; import { ImageZoom, ZoomableImage } from "../image-zoom"; type CustomImageProps = React.ComponentProps & { diff --git a/apps/web/src/content/mdx-components/grid.tsx b/apps/web/src/content/mdx-components/grid.tsx index d637228c..82afd5ab 100644 --- a/apps/web/src/content/mdx-components/grid.tsx +++ b/apps/web/src/content/mdx-components/grid.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function Grid({ cols = 2, diff --git a/apps/web/src/content/mdx-components/subtle.tsx b/apps/web/src/content/mdx-components/subtle.tsx index 423f2e9e..4b1adeea 100644 --- a/apps/web/src/content/mdx-components/subtle.tsx +++ b/apps/web/src/content/mdx-components/subtle.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function Subtle({ className, ...props }: React.ComponentProps<"span">) { return ; diff --git a/apps/web/src/content/simple-chart.tsx b/apps/web/src/content/simple-chart.tsx index 87be846d..e7869a77 100644 --- a/apps/web/src/content/simple-chart.tsx +++ b/apps/web/src/content/simple-chart.tsx @@ -8,7 +8,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Line, LineChart, XAxis } from "recharts"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; const chartConfig = { latency: { diff --git a/apps/web/src/content/status-markdown.ts b/apps/web/src/content/status-markdown.ts index caf43d5d..fa79587e 100644 --- a/apps/web/src/content/status-markdown.ts +++ b/apps/web/src/content/status-markdown.ts @@ -10,11 +10,11 @@ import { } from "@openstatus/services/external-service-report"; import { OSTinybird, safePipeData } from "@openstatus/tinybird"; -import { env } from "@/env"; +import { env } from "../env"; import { cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; +} from "../lib/external-service-cache"; type LatestRow = { id: string; diff --git a/apps/web/src/content/sub-nav.tsx b/apps/web/src/content/sub-nav.tsx index 50ea6fe1..81e4e1c1 100644 --- a/apps/web/src/content/sub-nav.tsx +++ b/apps/web/src/content/sub-nav.tsx @@ -4,8 +4,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { CopyDropdownButton } from "./copy-button"; export function SubNav({ className, ...props }: React.ComponentProps<"div">) { diff --git a/apps/web/src/content/theme-toggle.tsx b/apps/web/src/content/theme-toggle.tsx index 45064ca7..a39e1028 100644 --- a/apps/web/src/content/theme-toggle.tsx +++ b/apps/web/src/content/theme-toggle.tsx @@ -5,7 +5,7 @@ import { useTheme } from "next-themes"; import type * as React from "react"; import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function ThemeToggle({ className, diff --git a/apps/web/src/content/utils/search-index.ts b/apps/web/src/content/utils/search-index.ts index 357bc83e..1f3fe251 100644 --- a/apps/web/src/content/utils/search-index.ts +++ b/apps/web/src/content/utils/search-index.ts @@ -1,7 +1,6 @@ import "server-only"; -import { slugify } from "@/content/mdx"; - import { type MDXData, PAGE_TYPES, getHomePage, getPages } from "."; +import { slugify } from "../mdx"; import type { Corpus, SearchResult } from "../search-meta"; import { closestHeadingSlug, diff --git a/apps/web/src/content/utils/search-match.test.ts b/apps/web/src/content/utils/search-match.test.ts index 15e92226..827ca8e9 100644 --- a/apps/web/src/content/utils/search-match.test.ts +++ b/apps/web/src/content/utils/search-match.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { WEIGHTS, diff --git a/apps/web/src/data/content.ts b/apps/web/src/data/content.ts index a80c48be..7cf726ad 100644 --- a/apps/web/src/data/content.ts +++ b/apps/web/src/data/content.ts @@ -7,7 +7,7 @@ import { getToolingPages, getToolsPages, getUseCasePages, -} from "@/content/utils"; +} from "../content/utils"; const products = getProductPages(); diff --git a/apps/web/src/data/trigger-dictionary.ts b/apps/web/src/data/trigger-dictionary.ts index 2b4703b2..06cbc4f5 100644 --- a/apps/web/src/data/trigger-dictionary.ts +++ b/apps/web/src/data/trigger-dictionary.ts @@ -1,5 +1,5 @@ -import type { ValidIcon } from "@/components/icons"; -import type { Trigger } from "@/lib/monitor/utils"; +import type { ValidIcon } from "../components/icons"; +import type { Trigger } from "../lib/monitor/utils"; export const triggerDict = { cron: { diff --git a/apps/web/src/lib/checker/mock.ts b/apps/web/src/lib/checker/mock.ts index ce20f05d..cdc60e49 100644 --- a/apps/web/src/lib/checker/mock.ts +++ b/apps/web/src/lib/checker/mock.ts @@ -1,7 +1,7 @@ import type { Region } from "@openstatus/db/src/schema/constants"; -import { type RegionChecker, cachedCheckerSchema } from "@/lib/checker/utils"; -import { wait } from "@/lib/utils"; +import { wait } from "../utils"; +import { type RegionChecker, cachedCheckerSchema } from "./utils"; export async function mockCheckRegion(region: Region) { const response = data.checks diff --git a/apps/web/src/lib/external-report-escalation.ts b/apps/web/src/lib/external-report-escalation.ts index be7f9de6..c9145002 100644 --- a/apps/web/src/lib/external-report-escalation.ts +++ b/apps/web/src/lib/external-report-escalation.ts @@ -10,7 +10,7 @@ import { import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { unstable_cache } from "next/cache"; -import { env } from "@/env"; +import { env } from "../env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/web/src/lib/mcp/health-check.test.ts b/apps/web/src/lib/mcp/health-check.test.ts index 1eac8d99..760265b6 100644 --- a/apps/web/src/lib/mcp/health-check.test.ts +++ b/apps/web/src/lib/mcp/health-check.test.ts @@ -1,4 +1,5 @@ -import { afterEach, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { normalizeUrlForStorage, diff --git a/apps/web/src/lib/metadata/shared-metadata.ts b/apps/web/src/lib/metadata/shared-metadata.ts index db9d7981..68e9a67b 100644 --- a/apps/web/src/lib/metadata/shared-metadata.ts +++ b/apps/web/src/lib/metadata/shared-metadata.ts @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export const TITLE = "openstatus"; export const HOMEPAGE_TITLE = "The Compliance-First Status Page"; diff --git a/apps/web/src/lib/metadata/structured-data.ts b/apps/web/src/lib/metadata/structured-data.ts index 36a29602..d7f7fb38 100644 --- a/apps/web/src/lib/metadata/structured-data.ts +++ b/apps/web/src/lib/metadata/structured-data.ts @@ -19,8 +19,7 @@ import type { WithContext, } from "schema-dts"; -import type { MDXData } from "@/content/utils"; - +import type { MDXData } from "../../content/utils"; import { BASE_URL } from "./shared-metadata"; export const getJsonLDWebPage = ( diff --git a/apps/web/src/lib/stripe/client.ts b/apps/web/src/lib/stripe/client.ts index 50e71374..8e64d21e 100644 --- a/apps/web/src/lib/stripe/client.ts +++ b/apps/web/src/lib/stripe/client.ts @@ -1,7 +1,7 @@ import type { Stripe as StripeProps } from "@stripe/stripe-js"; import { loadStripe } from "@stripe/stripe-js"; -import { env } from "@/env"; +import { env } from "../../env"; let stripePromise: Promise; diff --git a/apps/web/src/lib/tb.ts b/apps/web/src/lib/tb.ts index 371c5e02..fc16ba37 100644 --- a/apps/web/src/lib/tb.ts +++ b/apps/web/src/lib/tb.ts @@ -1,6 +1,6 @@ import { OSTinybird } from "@openstatus/tinybird"; -import { env } from "@/env"; +import { env } from "../env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/workflows/.gitignore b/apps/workflows/.gitignore index 506e4c37..e4037038 100644 --- a/apps/workflows/.gitignore +++ b/apps/workflows/.gitignore @@ -1,2 +1,6 @@ # deps node_modules/ + +# build artifacts / local dev db +app +dev.db* diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index 42ee8271..7da4a413 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -2,21 +2,10 @@ # This file is generated by Dofigen v2.8.0 # See https://github.com/lenra-io/dofigen -# docker -FROM oven/bun@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS docker -LABEL \ - org.opencontainers.image.base.digest="sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7" \ - org.opencontainers.image.base.name="docker.io/oven/bun:1.3.11" -WORKDIR /app/apps/workflows -COPY \ - --link \ - "." "/app/" -RUN bun run src/build-docker.ts - # install -FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install +FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install LABEL \ - org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ + org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ @@ -56,14 +45,14 @@ RUN \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' +cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts +cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts +cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs +mkdir -p /app/data +EOF # runtime -FROM debian@sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 AS runtime +FROM registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 AS runtime LABEL \ io.dofigen.version="2.8.0" \ org.opencontainers.image.authors="OpenStatus Team" \ - org.opencontainers.image.base.digest="sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604" \ - org.opencontainers.image.base.name="docker.io/debian:bullseye-slim" \ + org.opencontainers.image.base.digest="sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4" \ org.opencontainers.image.description="Background job processing and probe scheduling for OpenStatus" \ org.opencontainers.image.source="https://github.com/openstatusHQ/openstatus" \ org.opencontainers.image.title="OpenStatus Workflows" \ @@ -115,17 +98,16 @@ COPY \ --link \ "/app/apps/workflows/app" "/app/apps/workflows/" COPY \ - --from=libsql \ - --chown=1000:1000 \ - --link \ - "/app/node_modules" "/app/packages/db/node_modules" -COPY \ - --from=libsql \ + --from=build \ --chown=1000:1000 \ --link \ - "/app/node_modules" "/app/node_modules" -USER 0:0 -RUN apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data + "/app/data" "/app/data" USER 1000:1000 EXPOSE 3000 +HEALTHCHECK \ + --interval=1m \ + --timeout=10s \ + --start-period=30s \ + --retries=3 \ + CMD ["curl", "-f", "http://localhost:3000/ping"] ENTRYPOINT ["/app/apps/workflows/app"] diff --git a/apps/workflows/deno-migration-plan.md b/apps/workflows/deno-migration-plan.md new file mode 100644 index 00000000..2b7b2f0f --- /dev/null +++ b/apps/workflows/deno-migration-plan.md @@ -0,0 +1,437 @@ +# Plan: migrate `apps/server` + `apps/workflows` from bun to Deno 2.9 + +Goal: remove **bun** from the project. Three pillars, shipped as **one big-bang PR**: + +1. **Build** — `bun build --compile` → `deno compile` (server + workflows). +2. **Install** — the Docker `pnpm install` stage → `deno install` (server + workflows). +3. **Tests** — `bun:test` → **`node:test` runner + `@std/expect`**, run via **`deno test`**, + across **all ~270 test files** (12 packages + apps server, workflows, web, status-page). + +The other apps (`web`, `dashboard`, `status-page`, `docs`, `screenshot-service`) keep +**pnpm** for install + their existing builds; their only bun usage was `bun test`, removed by +pillar 3. `pnpm` remains the local-dev + non-migrated-app package manager. + +--- + +## Agreed decisions (the design) + +| # | Area | Decision | +|---|------|----------| +| 1 | Test scope | All ~270 `bun:test` files (12 packages + server/workflows/web/status-page) | +| 2 | Rollout | One big-bang PR, guarded by a baseline test-count parity gate (#16) | +| 3 | Entrypoint | **Split**: `index.ts` exports `app`; new `serve.ts` calls `Deno.serve`, is the compile target | +| 4 | Assertions | Keep Jest-style `expect` via **`@std/expect`** | +| 5 | Mocks | **`@std/testing/mock`** (`spy`/`stub`, `using`) + **`@std/testing/time`** (`FakeTime`) | +| 6 | `mock.module` | **Hybrid**: `stub` the reachable seams; **default-param DI** for the rest; delete dead ones | +| 7 | Test infra | New **`@openstatus/test-utils`** package: matchers (`expect.extend`), setup, shared fakes | +| 8 | DI style | **Default-parameter injection** for `dispatch*` / `getChannel` | +| 9 | Snapshots / type tests | `@std/testing/snapshot` / `expect-type` | +| 10 | Typecheck | Replace `tsc` with **`deno check`**, scoped to `apps/server` + `apps/workflows` (src + tests) | +| 11 | Permissions | `-A` for `deno test` and `deno compile` now; tighten the binary in a follow-up | +| 12 | Docker install | `deno install --prod --frozen --allow-scripts`, hoisted node_modules; `pnpm-workspace.yaml` stays authoritative; commit `deno.lock` only | +| 13 | CI install | CI test/migrate jobs **keep `pnpm install`**; `deno install` is exercised by the docker-publish build | +| 14 | CI test orchestration | Keep **turbo**; each package `"test": "deno test -A"`; swap `setup-bun` → `setup-deno` | +| 15 | Integration tests | Stay in the same `deno test -A` run, against the CI libsql service (as today) | +| 16 | Safety net | Record base-commit `bun test` pass count; assert `deno test` count ≥ it (fail CI on drop) | +| 17 | Other apps | Stay on pnpm install + existing build | +| 18 | Codemod | `ts-morph`/`jscodeshift` for the mechanical rewrite; hand-fix the ~60-file residue | + +--- + +## Resolved by codebase exploration (facts, not assumptions) + +- **Entrypoint must split** — tests do `import { app } from "@/index"`; a top-level + `Deno.serve` in `index.ts` would boot a server on every test import. +- **Server needs no libsql side-car** — `packages/db` uses `drizzle-orm/libsql/http` (pure + HTTP). Only `apps/workflows/src/lib/db.ts` uses the native `@libsql/client` embedded replica + → native-addon compile risk is **workflows-only**. +- **Tests are integration tests against a real libSQL DB** — CI runs a `libsql-server` + service + migrate + seed. The preload mocks only Tinybird/Redis/subscriptions; DB is real. +- **Step D seams are mixed**: `@/libs/clients` (`tb`/`redis` singletons) + `Redis.fromEnv` + are stub-able; `@openstatus/subscriptions` `dispatch*` + `getChannel` are destructured live + bindings called directly → need DI. +- **`node-fetch` mock is dead** — the SUT uses **global `fetch`**; tests set + `global.fetch = mockFetch` (the effective line) plus a redundant `mock.module("node-fetch")` + (not a dependency). → `stub(globalThis, "fetch", …)` and delete the `mock.module` line. +- **`start.sh` is unused by Fly** (entrypoint is the binary; compose `command` commented) — + prod migrations run via CI `migrate.yml`. We keep `start.sh` anyway and port its command. +- **migrate/seed have no `Bun.*`** — `packages/db/src/migrate.mts` + `seed.mts` use only + `@libsql/client`/drizzle/`process` → run under `deno run -A` unchanged. +- **`Bun.*` lives only in dev/build scripts** — `packages/db/env.ts`, `apps/server/env.ts`, + `apps/workflows/src/build-docker.ts` (`Bun.file`/`Bun.write`). +- **web/status-page tests are pure logic/util** — no DOM/`@testing-library`/React rendering; + run under `deno test` with no jsdom. +- **Only `apps/server` runs `tsc`** today (`tsc --noEmit`, `types: ["bun-types"]`). + +--- + +## Phase 0 — Spikes (gate the big-bang) — ✅ DONE (1,2) / deferred (3,4) + +Toolchain confirmed: **deno 2.9.0**, bun 1.3.11, pnpm 11.2.1, node 24, dofigen 2.8.0. + +1. ✅ **`Deno.serve` + Hono compile/serve.** Compiled, served, `/ping`→200, embedded asset + read via `Deno.readTextFile(new URL(...))`. **Correction: the flag is `--include`, not + `--include-as-is`** (the latter does not exist in 2.9). +2. ✅ **libSQL native addon under `deno compile` — make-or-break, PASSED with a bonus.** + `deno compile` **embeds the native addon into the binary** (10.7MB) and the binary runs from + a clean dir with **no node_modules**. **Consequence: the workflows `docker` + `libsql` + side-car stages are no longer needed** (they existed only because `bun build --compile` + could not embed native addons). One caveat for the real monorepo build: `--node-modules-dir=manual` + against the giant shared `node_modules` hangs (tries to embed everything) — use deno's + managed npm resolution / `--exclude-unused-npm` so only reachable packages embed. Final flag + combo to be settled in Phase 5 against the real Docker build. +3. ⏳ **Test stack interop** — validated at the start of Phase 2 by migrating one real route + test (faster than a synthetic spike): `@std/expect` matchers, `toHaveBeenCalled*` vs + `@std/testing/mock` spies (else `assertSpyCalls`), `expect.extend`, `stub` on `tb` getters + + `globalThis.fetch`, `FakeTime`. +4. ⏳ **`deno install` on the repo** — done carefully in Phase 3 (it may rewrite manifests and + re-layout `node_modules`, which would disrupt the in-progress pnpm-based work), in an + isolated copy first. + +--- + +## ✅ RESOLVED — deep workspace imports: exports maps + sloppy (no deno.json) + +**Solution (verified under `deno run` + `deno compile` + bun):** add an `exports` map to the +4 deep-imported packages (`@openstatus/db`, `@openstatus/api`, `@openstatus/emails`, +`@openstatus/tracker`) and pass `--unstable-sloppy-imports` on every deno command. The exports +map crosses the package boundary (sloppy can't); sloppy resolves the relative extensionless +imports inside packages. **No deno.json. 4 package.json touched, not 512 imports.** + +Exports map shape (per package), covering the 36 distinct targets (29 files, 7 dirs all in db): + +```jsonc +"exports": { + ".": "./src/index.ts", + "./env.mjs": "./env.mjs", // db only (non-src deep import) + "./src/schema": "./src/schema/index.ts", // + the 6 other directory targets + "./src/client": "./src/client.tsx", // .tsx files need explicit entries + "./src/*": "./src/*.ts" // wildcard handles the .ts files +} +``` + +Every deno invocation (`test`/`compile`/`check`/`run`) must include `--unstable-sloppy-imports`. + +### Original investigation (kept for context) + +The codebase has **512 bare deep-subpath imports across 400 files** of the form +`@openstatus/db/src/schema/constants` (also `@openstatus/api/src/*`, `@openstatus/emails/src/*`, +`@openstatus/tracker/src/*`). Targets are a **mix of `.ts` files, `.tsx` files, and directories** +(`@openstatus/db/src/schema` is a dir with `index.ts`). Verified facts (Deno 2.9.0 experiments): + +- **`--unstable-sloppy-imports` resolves *relative* extensionless imports** (incl. dir-index and + `.tsx`) for `deno run`/`compile`/`test`. ✅ +- It does **NOT** resolve **bare cross-package** deep subpaths — those go through node_modules + package resolution where sloppy does not apply. Fails for run/compile/test (works only for the + lenient `deno check` TS resolver). ❌ — true even in Deno workspace mode (`deno install`). +- **Explicit extension** (`@openstatus/db/src/schema/constants.ts`) resolves under both Deno and + bun — but directory imports still need `/index.ts`, and it risks the Next.js apps (turbopack/tsc). +- **`exports` map** with a `./src/*` wildcard handles `.ts` files but **not** the mixed + dir/`.tsx` cases reliably (Deno does not fall through exports fallback arrays on a missing file). +- **deno.json import map** prefix (`"@openstatus/db/src/": "./packages/db/src/"`) + sloppy + **resolves ALL cases** (file `.ts`/`.tsx` + dir-index) for run **and** compile. ✅ — but it is a + `deno.json`, which the user asked to avoid. + +**This is a hard fork:** the only clean, complete fix is a 4-entry `deno.json` import map, which +collides with the "no deno.json" preference ([[feedback-no-deno-json]]). Awaiting a decision (see +chat) before proceeding with Phase 2+. Everything below assumes that decision is made. + +## Implementation findings (verified during execution) + +- **`@/*` tsconfig path alias** — Deno doesn't read tsconfig `paths`. 153 `@/…` imports across + 113 files in `apps/server` rewritten to **relative paths** (codemod). workflows uses none. ✅ +- **`deno install` foundation** — works, with one workaround: it **crashes seeding `deno.lock` + from `pnpm-lock.yaml`** on a pnpm alias (`string-width-cjs@string-width@4.2.3`). Fix: move + `pnpm-lock.yaml` aside during `deno install` so Deno resolves fresh, then restore it. Deno + migrates the **catalog into root `package.json`** (not deno.json) and writes `deno.lock`. + After install, the full server graph resolves (deep imports + `zod` + `hono`). ✅ +- **`@std/expect` `toHaveBeenCalled*` does NOT accept `@std/testing/mock` spies** (verified: + "Received function must be a mock or spy function"). → the ~187 `toHaveBeenCalled*` sites must + use **`assertSpyCalls`/`assertSpyCall`** instead. Basic `expect`, `expect.extend` custom + matchers, and `FakeTime` all work. ⚠ (more test rework than planned) +- **✅ `deno compile` of `apps/server` WORKS in a clean Docker container** — the local 12-min + hang was the **polluted local node_modules** (Deno-managed mix + broken `.next` symlinks + + every app's deps). In Docker with a **scoped `pnpm install --filter @openstatus/server...`** + (20.8s) then `deno compile --node-modules-dir=manual`, the binary builds fast and **runs**: + `/ping`→200, `/openapi.yaml`→embedded asset, full app graph boots ("Listening on :3000"). + - **Winning build recipe** (`apps/server/Dockerfile.deno-test`): node:24-slim → `pnpm install + --prod --frozen-lockfile --filter @openstatus/server...` → denoland/deno:2.9.0 → `deno + compile -A --no-check --unstable-sloppy-imports --node-modules-dir=manual --include + static/openapi.yaml --include static/openapi-v1.json --output app src/serve.ts` → debian + runtime with just the binary. + - **No `deno install`** in the build — pnpm install (scoped) is what produces node_modules; + Deno reads the catalog from root `package.json` (migrated once) + consumes pnpm's layout. + This sidesteps `deno install`'s whole-monorepo install + the pnpm-alias lockfile crash. + - Catalog must be present in root `package.json` for Deno to resolve `catalog:` specifiers. + - Sandbox note: needed `docker build --network=host` here (flaky build-network); normal CI ok. + - Image 495MB (debian + binary). Could slim further later. +- **✅ `apps/workflows` also builds in Docker** (same recipe, `--filter @openstatus/workflows...`, + 465MB) and **embeds the libSQL native addon** (no side-car). Verified the binary executes (it + reaches the embedded-replica `createClient` and opens the sync connection). Full boot needs a + real Turso `DATABASE_URL` — in the sandbox it blocks in SYN_SENT to an unreachable sync URL at + module load (the `createClient` runs before logging, so no logs appear). Not a build defect. +- **⚠ `@sentry/bun` → `@sentry/deno`** — workflows used `@sentry/bun` (bun-only; hangs under + Deno) in `index.ts`, `lib/sentry.ts`, `cron/index.ts`. Swapped all three to `@sentry/deno` + (`10.61.0`, API-compatible: `init`/`captureException`/`captureMessage`/`captureCheckIn`/`flush`), + updated `package.json` + `pnpm-lock.yaml`. The server uses `@hono/sentry` (unaffected). +- **⚠ embedded-replica `createClient` blocks at module load** until the sync URL connects — so + the workflows process won't serve `/ping` until the DB is reachable. Pre-existing behavior + (bun did the same); flagged for prod startup robustness. + +## Phase 2 — Test migration — 🔶 IN PROGRESS + +- ✅ `@openstatus/test-utils` package built + validated: re-exports `node:test` runner with a + Bun-compat **`.each`** shim, `@std/expect` `expect` extended with the ~12 **bun-only matchers** + (`toBeNumber`, `toContainValue`, …), and `@std/testing/mock` (`spy`/`stub`/`assertSpyCalls`) + + `@std/testing/time` (`FakeTime`). Uses `jsr:@std/*` so only Deno needs them. +- ✅ Codemod swapped `bun:test` → `@openstatus/test-utils` in **194 files**; updated 21+ + `package.json` (`deno test` script, test-utils devDep, dropped `@types/bun`/`bun-types`); + removed `bunfig.toml`. +- ✅ **`@/*` alias → relative** rewrite: server (153), status-page (211), web (332). Deno + ignores tsconfig paths. +- ✅ **Import-only suites PASS under `deno test`**: header-analysis (7), status-page (51), web + (23). Mock pattern validated: discord + 5 more notifications PASS. +- 🔶 **Remaining mock work (~47 files)**: `@std/expect` `toHaveBeenCalled*` does NOT accept std + spies → use `assertSpyCalls`. Per-file quirks remain: 6 notifications (webhook double-stub, + bird-whatsapp `jest`, slack/grafana call-count-after-restub), importers clients, status-fetcher, + tracker (`FakeTime`), subscriptions/api/server (**`mock.module` → stub + default-param DI**, + and these are **DB-integration tests needing a running libSQL to verify**). +- ⏳ snapshots (`toMatchSnapshot` → `@std/testing/snapshot`) + type tests (`expectTypeOf` → + `expect-type`) not started. + +## Phase 1 — Source changes — ✅ DONE + +- ✅ split `index.ts`/`serve.ts` (both apps); server static asset → `Deno.readTextFile`. +- ✅ `Bun.*` → `Deno.copyFile` in `apps/server/env.ts`, `packages/db/env.ts`. +- ✅ `migrate`/`seed`/`env` scripts + `start.sh` → `deno run -A`; app `dev`/`start`/`test` → deno. + +(Detail of the changes below.) + +### Entrypoint split (both apps) + +`index.ts`: keep `export const app = new Hono(...)`, **remove** `const server = {...}` + +`export default server`. New `serve.ts`: + +```ts +import { app } from "./index"; +import { env } from "./env"; +Deno.serve({ port: env.PORT ?? 3000 }, app.fetch); +``` + +`serve.ts` is the `deno compile` target. Tests still import `app` with no server side-effect. + +### Server static asset (`apps/server/src/index.ts:22`) + +Drop `import openapiYaml … with { type: "text" }`. Embed via `--include-as-is` (Phase 4) and +read at startup: + +```ts +const openapiYaml = await Deno.readTextFile(new URL("../static/openapi.yaml", import.meta.url)); +``` + +JSON imports (`with { type: "json" }`) stay — Deno supports them. + +### `Bun.*` → Deno APIs (dev/build scripts) + +`packages/db/env.ts`, `apps/server/env.ts`: `Bun.file(p).text()/.json()` → +`Deno.readTextFile(p)` (+ `JSON.parse`); `Bun.write(p, s)` → `Deno.writeTextFile(p, s)`. +(`apps/workflows/src/build-docker.ts` is deleted in Phase 5 — no port needed.) + +### migrate / `start.sh` + +`packages/db/package.json`: `"migrate": "deno run -A src/migrate.mts"`, +`"seed": "deno run -A src/seed.mts"`, `"env": "deno run -A env.ts"`. Keep `start.sh`; change +`bun src/migrate.mts` → `deno run -A src/migrate.mts`. + +--- + +## Phase 2 — Test migration (`bun:test` → `node:test` + `@std/expect`, `deno test`) + +Surface: **~270 files**, ~2920 `expect` assertions, ~150 bun-only matchers, 47 `mock` / +21 `spyOn` / 10 `setSystemTime` / 6 `jest.*`, 4 `mock.module` seams (+ dead `node-fetch`), +12 snapshot files, 10 type-test files. + +### Step 0 — `@openstatus/test-utils` package (Decision 7) + +``` +packages/test-utils/ + src/setup.ts # registers expect.extend matchers; installs the global fetch stub helper + src/matchers.ts # the ~150 bun-only matchers (toBeNumber, toContainValue, toBeString, …) + src/fakes/ # tinybird.ts, redis.ts, subscriptions.ts — shared test doubles +``` + +Each tester adds `@openstatus/test-utils` as a devDependency; every test file imports +`@openstatus/test-utils/setup` **first** (codemod injects). + +### Step A — codemod (`ts-morph`/`jscodeshift`, ~270 files) + +Per file: replace the `bun:test` import with `node:test` + `@std/expect`, alias +`beforeAll→before`/`afterAll→after`, and inject `import "@openstatus/test-utils/setup";` as +the first import. `expect(...)` bodies untouched. + +### Step B — bun-only matchers + +Implemented once in `@openstatus/test-utils` via `expect.extend` (verified in Phase 0 spike 3). +`pass()`/`fail()` helpers → explicit `expect(...)` assertions in the few sites that use them. + +### Step C — mocks (`@std/testing/mock` + `@std/testing/time`) + +`mock(fn)`→`spy(fn)`; `spyOn(o,"m")`→`using s = spy(o,"m")` / `stub(o,"m",impl)`; sequential +returns→`returnsNext`; `setSystemTime`→`using t = new FakeTime(date)` + `t.tick`. Prefer +`using` (auto-restore) — deletes most `afterEach` teardown. Keep `toHaveBeenCalled*` if Phase-0 +interop holds, else `assertSpyCalls`/`assertSpyCall`. + +### Step D — module mocks (hybrid; Decisions 6 + 8) + +- **stub-able** → `@std/testing/mock` `stub`, fakes from `@openstatus/test-utils/fakes`: + `tb`/`redis` (`@/libs/clients` singletons), `Redis.fromEnv` (`@openstatus/upstash`). +- **global fetch** → `stub(globalThis, "fetch", …)`; **delete** every `mock.module("node-fetch")`. +- **DI (default-param)** → `dispatchMaintenanceUpdate`, `dispatchStatusReportUpdate` + (`maintenances/post.ts`, `statusReports/post.ts`), `getChannel` + (`rpc/handlers/status-page/index.ts`): add `deps = { … }` last param; tests pass fakes. +- The old global `preload.ts` is deleted; its four mocks move to the above mechanisms. + +### Step E — preload replacement + +`bunfig.toml` preload is gone; the `@openstatus/test-utils/setup` import (Step A) replaces it. +Import ordering: setup first, then the SUT. + +### Step F — snapshots + type tests + +Snapshots → `@std/testing/snapshot` `assertSnapshot(t, value)` (regenerate + diff the 12 +files). Type tests → `expect-type` (`expectTypeOf().toEqualTypeOf()`), validated by +`deno check` where in scope (the two apps). + +### Step G — invocation + +Each package/app `"test": "deno test -A"`. Pull `@std/expect`, `@std/testing`, `expect-type` +via `jsr add`/devDeps so pnpm install resolves them. Remove `bunfig.toml`, `bun-types`, +`@types/bun`. + +--- + +## Phase 3 — Install via `deno install` (Docker, server + workflows) + +Deno 2.9 reads `pnpm-workspace.yaml` catalogs (482 `catalog:` refs) + workspace globs +(244 `workspace:*`) and seeds `deno.lock` from `pnpm-lock.yaml`. dofigen `install` stage: + +```yaml + install: + fromImage: denoland/deno:2.9.0 + workdir: /app/ + env: + DENO_NODE_MODULES_DIR: auto # hoisted layout for compile + libsql side-car + bind: + - pnpm-workspace.yaml # catalog + workspace source of truth + - pnpm-lock.yaml + - deno.lock + - package.json + - …all workspace package.json (same bind list as today)… + run: deno install --prod --frozen --allow-scripts + cache: + - /deno-dir +``` + +`pnpm-workspace.yaml` stays authoritative (Decision 12); commit `deno.lock`; do **not** commit +any catalog/`deno.json` that 2.9 may emit. Verify (Phase 0 spike 4) the migration write stays +additive so pnpm keeps working for the other apps. + +--- + +## Phase 4 — `apps/server/dofigen.yml` (build) + +`build` stage → Deno + `deno compile` (target `serve.ts`). No libsql side-car (HTTP driver). + +```yaml + build: + fromImage: denoland/deno:2.9.0 + workdir: /app/apps/server + env: { NODE_ENV: production } + copy: + - . /app/ + - { fromBuilder: install, source: /app/node_modules, target: /app/node_modules } + - { fromBuilder: install, source: /app/apps/server/node_modules, target: /app/apps/server/node_modules } + - { fromBuilder: install, source: /app/packages, target: /app/packages } + run: >- + deno compile -A --no-check --node-modules-dir + --include static/openapi.yaml --include static/openapi-v1.json + --output app serve.ts +``` + +`--no-check` keeps compile fast (`deno check` is the typecheck gate, Decision 10). Optionally +benchmark experimental `--bundle` for a smaller binary. Runtime copy `/app/apps/server/app` → +`/bin/app` unchanged. + +--- + +## Phase 5 — `apps/workflows/dofigen.yml` (build) — side-car DROPPED + +Spike 2 proved `deno compile` **embeds** the libSQL native addon into the binary, so the whole +side-car apparatus goes away: + +1. **`build`** → `deno compile -A --no-check --output app serve.ts`. Settle the npm-embed flags + here (`--exclude-unused-npm` / managed npm) so it embeds reachable packages, not the whole + `node_modules` (spike 2 caveat). +2. **DELETE the `docker` stage** (`build-docker.ts` existed only to generate the side-car + `package.json`) and **DELETE the `libsql` stage**. +3. **`build-docker.ts`** itself becomes dead code → remove (its sole purpose was the side-car). +4. **runtime copy** → just the self-contained `app` binary. No `node_modules` copied at all. + +This makes the workflows runtime image dramatically simpler (binary only, like server). + +--- + +## Phase 6 — CI + +- `test.yml` + `migrate.yml`: replace `oven-sh/setup-bun` with `denoland/setup-deno@v2` + (Deno 2.9). **Keep `pnpm install`** (Decision 13), the libsql service, migrate, seed. + `pnpm test` → turbo → per-package `deno test -A` (Decision 14). +- Add a **`deno check`** step for `apps/server` + `apps/workflows` (src + tests) replacing the + server `tsc` step (Decision 10). +- **Parity gate** (Decision 16): a CI step records the base-commit `bun test` total pass count + (artifact / committed baseline number), then asserts `deno test`'s pass count ≥ baseline. +- docker-publish workflows exercise `deno install` + `deno compile` via the Dockerfiles. + +--- + +## Phase 7 — Verify & ship + +Per app: `dofigen generate`; `docker buildx build -f apps//Dockerfile .` from repo root; +run, `GET /ping` → 200; server `GET /openapi.yaml` → body; workflows embedded replica syncs + +a cron endpoint responds. Locally: `pnpm install && pnpm migrate && pnpm seed && pnpm test` +green; parity count ≥ baseline; `deno check` clean for the two apps. Watch Fly RSS/OOM on +workflows after deploy (Deno V8 heap defaults differ from bun — see `research.md`). + +--- + +## Risks + +| Risk | Mitigation | +|------|-----------| +| ~~libSQL native addon won't `deno compile`~~ | ✅ RESOLVED (spike 2): deno embeds the addon; side-car dropped | +| Big-bang PR hides a regression / silent skip | Parity gate (16); split into logical commits within the one PR for bisect | +| `@std/expect` `toHaveBeenCalled*` ✗ interop with `@std/testing/mock` spies | Phase-0 spike 3; fallback `assertSpyCalls`/`assertSpyCall` | +| `deno install` rewrites manifests / breaks pnpm for other apps | Phase-0 spike 4; keep `pnpm-workspace.yaml` authoritative, don't commit deno catalog | +| `deno check` surfaces new diagnostics vs `tsc` | Scoped to two apps (10); fix as part of the PR | +| ~270-file codemod churn | AST codemod (18) + parity gate; hand-fix the ~60-file residue | +| `stub` can't reach `tb` getter methods | Phase-0 spike 3; fallback = make `tb`/`redis` injectable like the dispatch seams | + +--- + +## TODO + +- [ ] **Phase 0** spikes: serve+compile · libsql-compile (workflows) · test-stack interop · `deno install` +- [ ] Phase 1: split `index.ts`/`serve.ts` (both) · server static asset · `Bun.*`→Deno · migrate/seed/`start.sh`→deno +- [ ] Phase 2.0: create `@openstatus/test-utils` (matchers, setup, fakes) +- [ ] Phase 2.A: codemod imports + lifecycle + setup-inject (~270 files) +- [ ] Phase 2.B–C: matchers via `expect.extend`; mocks → `@std/testing/mock`/`time` +- [ ] Phase 2.D: hybrid module mocks — stub `tb`/`redis`/`Redis.fromEnv` + `globalThis.fetch`; DI `dispatch*`/`getChannel`; delete `node-fetch` mocks + `preload.ts` +- [ ] Phase 2.F: snapshots → `@std/testing/snapshot`; type tests → `expect-type` +- [ ] Phase 2.G: `"test": "deno test -A"` everywhere; add JSR devDeps; remove `bunfig.toml`/`bun-types` +- [ ] Phase 3: `deno install` stage (both dofigen); commit `deno.lock` +- [ ] Phase 4: `apps/server` build → `deno compile` (serve.ts, `--include-as-is`) +- [ ] Phase 5: `apps/workflows` build → `deno compile`; `build-docker.ts`→deno; `libsql` stage→npm +- [ ] Phase 6: CI `setup-deno`, keep `pnpm install`, `deno check` (2 apps), parity gate +- [ ] Phase 7: `dofigen generate` + docker build + verify each app; ship; watch Fly RSS +- [ ] Update CLAUDE.md memory note "use bun test directly" → `deno test` + diff --git a/apps/workflows/docker-compose.yaml b/apps/workflows/docker-compose.yaml index 6eff4522..101f38ef 100644 --- a/apps/workflows/docker-compose.yaml +++ b/apps/workflows/docker-compose.yaml @@ -4,14 +4,9 @@ services: build: context: ../.. dockerfile: apps/workflows/Dockerfile - environment: - - DATABASE_URL=http://host.docker.internal:8081 - - DATABASE_AUTH_TOKEN=test - - RESEND_API_KEY=test - - UPSTASH_REDIS_REST_URL=test - - UPSTASH_REDIS_REST_TOKEN=test - - NODE_ENV=production - - GCP_PROJECT_ID=test + env_file: + - ../../.env.docker + extra_hosts: - "host.docker.internal:host-gateway" diff --git a/apps/workflows/dofigen.lock b/apps/workflows/dofigen.lock index cb7e8ab9..8ae0521b 100644 --- a/apps/workflows/dofigen.lock +++ b/apps/workflows/dofigen.lock @@ -12,32 +12,52 @@ effective: | - /packages/error - /packages/tracker builders: - docker: + build: fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + path: denoland/deno + digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 label: - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 + org.opencontainers.image.base.name: docker.io/denoland/deno:2.9.0 + org.opencontainers.image.base.digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + org.opencontainers.image.stage: build workdir: /app/apps/workflows + env: + NODE_ENV: production copy: - paths: - . target: /app/ + - fromBuilder: install + paths: + - /app/node_modules + target: /app/node_modules + - fromBuilder: install + paths: + - /app/apps/workflows/node_modules + target: /app/apps/workflows/node_modules + - fromBuilder: install + paths: + - /app/packages + target: /app/packages run: - - bun run src/build-docker.ts + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data install: fromImage: path: node - digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf + digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc label: + org.opencontainers.image.base.digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc org.opencontainers.image.stage: install org.opencontainers.image.base.name: docker.io/node:24-slim - org.opencontainers.image.base.digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf workdir: /app/ run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - target: /root/.local/share/pnpm/store bind: @@ -105,62 +125,22 @@ effective: | source: packages/locales/package.json - target: packages/status-fetcher/package.json source: packages/status-fetcher/package.json - libsql: - fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - label: - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - workdir: /app/ - copy: - - fromBuilder: docker - paths: - - /app/apps/build-docker/package.json - target: /app/package.json - run: - - bun install --production - build: - fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - label: - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 - org.opencontainers.image.stage: build - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - workdir: /app/apps/workflows - env: - NODE_ENV: production - copy: - - paths: - - . - target: /app/ - - fromBuilder: install - paths: - - /app/node_modules - target: /app/node_modules - - fromBuilder: install - paths: - - /app/apps/workflows/node_modules - target: /app/apps/workflows/node_modules - - fromBuilder: install - paths: - - /app/packages - target: /app/packages - run: - - bun build --compile --target bun --sourcemap src/index.ts --outfile=app fromImage: - path: debian - digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 + host: registry.access.redhat.com + port: 443 + path: hi/curl + digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 label: - org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus - org.opencontainers.image.authors: OpenStatus Team - org.opencontainers.image.base.digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 - org.opencontainers.image.title: OpenStatus Workflows - org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus - org.opencontainers.image.base.name: docker.io/debian:bullseye-slim io.dofigen.version: 2.8.0 + org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus + org.opencontainers.image.title: OpenStatus Workflows + org.opencontainers.image.authors: OpenStatus Team + org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus org.opencontainers.image.vendor: OpenStatus + org.opencontainers.image.base.digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + user: + user: '1000' + group: '1000' workdir: /app/ copy: - fromBuilder: build @@ -168,37 +148,33 @@ effective: | - /app/apps/workflows/app target: /app/apps/workflows/ chmod: '555' - - fromBuilder: libsql - paths: - - /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql + - fromBuilder: build paths: - - /app/node_modules - target: /app/node_modules - root: - run: - - apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data + - /app/data + target: /app/data entrypoint: - /app/apps/workflows/app expose: - port: 3000 + healthcheck: + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + interval: 1m + timeout: 10s + start: 30s + retries: 3 images: docker.io: + denoland: + deno: + 2.9.0: + digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 library: node: 24-slim: - digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf - debian: - bullseye-slim: - digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 - oven: - bun: - 1.3.11: - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc resources: dofigen.yml: - hash: 9ad08ee36ff20abe093e58fc36235d056b6ed3e22b8ae2f3fb30399e34cdaebe + hash: 3d98c3f4837321ccc3810b1644c53d6c17f057fb57ec5d7beafa6b3caef9f59b content: | ignore: - node_modules @@ -252,16 +228,16 @@ resources: - packages/locales/package.json - packages/status-fetcher/package.json - # Install dependencies + # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary) + # Stage 4: Build application (compile to binary with Deno) build: - fromImage: oven/bun:1.3.11 + fromImage: denoland/deno:2.9.0 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -276,35 +252,24 @@ resources: - fromBuilder: install source: /app/packages target: /app/packages - # Should set env to production here - # Compile the TypeScript application env: NODE_ENV: production - run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app - - docker: - fromImage: oven/bun:1.3.11 - workdir: /app/apps/workflows - copy: - - . /app/ - run: bun run src/build-docker.ts - - libsql: - fromImage: oven/bun:1.3.11 - workdir: /app/ - copy: - - fromBuilder: docker - source: /app/apps/build-docker/package.json - target: /app/package.json - # bun install is hoisted by default -> flat node_modules so the compiled bun binary can - # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile - # is needed (the generated package.json pins one exact version), so a single install does it. - run: bun install --production + # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: + # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads + # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, + # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. + run: + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data - fromImage: debian:bullseye-slim + # Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). + # Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. + fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 workdir: /app/ - root: - run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -314,18 +279,25 @@ resources: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team - # Copy artifacts from build stages + # Copy the self-contained compiled binary (native addon embedded by deno compile) copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: libsql - source: /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql - source: /app/node_modules - target: /app/node_modules + - fromBuilder: build + source: /app/data + target: /app/data + + user: "1000:1000" expose: "3000" + # Health check — exec form (JSON array) because the base has no shell for CMD-SHELL + healthcheck: + interval: 1m + timeout: 10s + start: 30s + retries: 3 + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/dofigen.yml b/apps/workflows/dofigen.yml index 89c086dd..b07724aa 100644 --- a/apps/workflows/dofigen.yml +++ b/apps/workflows/dofigen.yml @@ -50,16 +50,16 @@ builders: - packages/locales/package.json - packages/status-fetcher/package.json - # Install dependencies + # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary) + # Stage 4: Build application (compile to binary with Deno) build: - fromImage: oven/bun:1.3.11 + fromImage: denoland/deno:2.9.0 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -74,35 +74,24 @@ builders: - fromBuilder: install source: /app/packages target: /app/packages - # Should set env to production here - # Compile the TypeScript application env: NODE_ENV: production - run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app - - docker: - fromImage: oven/bun:1.3.11 - workdir: /app/apps/workflows - copy: - - . /app/ - run: bun run src/build-docker.ts - - libsql: - fromImage: oven/bun:1.3.11 - workdir: /app/ - copy: - - fromBuilder: docker - source: /app/apps/build-docker/package.json - target: /app/package.json - # bun install is hoisted by default -> flat node_modules so the compiled bun binary can - # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile - # is needed (the generated package.json pins one exact version), so a single install does it. - run: bun install --production + # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: + # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads + # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, + # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. + run: + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data -fromImage: debian:bullseye-slim +# Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). +# Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. +fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 workdir: /app/ -root: - run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -112,18 +101,25 @@ labels: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team -# Copy artifacts from build stages +# Copy the self-contained compiled binary (native addon embedded by deno compile) copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: libsql - source: /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql - source: /app/node_modules - target: /app/node_modules + - fromBuilder: build + source: /app/data + target: /app/data + +user: "1000:1000" expose: "3000" +# Health check — exec form (JSON array) because the base has no shell for CMD-SHELL +healthcheck: + interval: 1m + timeout: 10s + start: 30s + retries: 3 + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/package.json b/apps/workflows/package.json index e92ffa72..522f838f 100644 --- a/apps/workflows/package.json +++ b/apps/workflows/package.json @@ -1,9 +1,10 @@ { "name": "@openstatus/workflows", "scripts": { - "dev": "NODE_ENV=development bun run --hot src/index.ts", - "start": "NODE_ENV=production bun run src/index.ts", - "test": "bun test" + "check": "deno check --sloppy-imports src/serve.ts", + "dev": "NODE_ENV=development deno run -A --watch src/serve.ts", + "start": "NODE_ENV=production deno run -A src/serve.ts", + "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test -A --no-check --sloppy-imports" }, "dependencies": { "@google-cloud/tasks": "catalog:", @@ -33,9 +34,11 @@ "@openstatus/tinybird": "workspace:*", "@openstatus/upstash": "workspace:*", "@openstatus/utils": "workspace:*", + "@opentelemetry/exporter-logs-otlp-http": "catalog:", "@opentelemetry/resources": "catalog:", + "@opentelemetry/sdk-logs": "catalog:", "@opentelemetry/semantic-conventions": "catalog:", - "@sentry/bun": "catalog:", + "@sentry/deno": "catalog:", "@upstash/qstash": "catalog:", "drizzle-orm": "catalog:", "effect": "catalog:", @@ -44,8 +47,8 @@ "zod": "catalog:" }, "devDependencies": { + "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/apps/workflows/src/build-docker.ts b/apps/workflows/src/build-docker.ts deleted file mode 100644 index 1db9537c..00000000 --- a/apps/workflows/src/build-docker.ts +++ /dev/null @@ -1,81 +0,0 @@ -import path from "node:path"; - -// Create package.json that contains @libsql/client as dependency. It will be used to create node_modules and copy them alongside compiled server https://github.com/oven-sh/bun/issues/18909 -type PackageJson = Record<"name" | "description" | "version", string> & - Record<"dependencies", Record>; -const packageJson: PackageJson = await Bun.file( - path.join(__dirname, "../../../packages/db", "package.json"), -).json(); - -const extractDependenciesNames = ["@libsql/client"]; -const workspaceConfig = await Bun.file( - path.join(__dirname, "../../../pnpm-workspace.yaml"), -).text(); - -const catalog = (() => { - const lines = workspaceConfig.split(/\r?\n/); - let inCatalog = false; - const entries: Record = {}; - - for (const line of lines) { - if (!inCatalog) { - if (line.trim() === "catalog:") { - inCatalog = true; - } - continue; - } - - if (!line.startsWith(" ")) { - break; - } - - const match = line.match(/^\s{2}("[^"]+"|[^:]+):\s*(.+)$/); - if (!match) { - continue; - } - - const key = match[1].replace(/^"|"$/g, "").trim(); - const value = match[2].replace(/^"|"$/g, "").trim(); - entries[key] = value; - } - - return entries; -})(); - -const resolveVersion = (name: string, spec: string) => { - if (!spec.startsWith("catalog:")) { - return spec; - } - - const resolved = catalog[name]; - if (!resolved) { - throw new Error(`Missing catalog entry for ${name}`); - } - - return resolved; -}; - -const extractedDependencies = extractDependenciesNames.reduce( - (acc, cur) => { - const spec = packageJson.dependencies[cur]; - if (spec) { - acc[cur] = resolveVersion(cur, spec); - } - - return acc; - }, - {} as Record, -); - -const packageJsonBuild = { - name: packageJson.name, - description: packageJson.description, - version: packageJson.version, - // type: "module", - dependencies: extractedDependencies, -}; - -await Bun.write( - "../build-docker/package.json", - JSON.stringify(packageJsonBuild, null, 2), -); diff --git a/apps/workflows/src/checker/alerting.test.ts b/apps/workflows/src/checker/alerting.test.ts index 0f8bb1ee..e69ab6c9 100644 --- a/apps/workflows/src/checker/alerting.test.ts +++ b/apps/workflows/src/checker/alerting.test.ts @@ -1,95 +1,77 @@ -import { afterAll, afterEach, describe, expect, mock, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { notification, notificationTrigger, notificationsToMonitors, } from "@openstatus/db/src/schema"; - -// Mock audit log to avoid calling Tinybird -mock.module("../utils/audit-log", () => ({ - checkerAudit: { - publishAuditLog: mock(() => Promise.resolve()), - }, -})); - -// Mock notification providers to avoid real HTTP calls -const mockEmailSendAlert = mock(() => Promise.resolve()); -const mockEmailSendRecovery = mock(() => Promise.resolve()); -const mockEmailSendDegraded = mock(() => Promise.resolve()); -const mockSlackSendAlert = mock(() => Promise.resolve()); -const mockSlackSendRecovery = mock(() => Promise.resolve()); -const mockSlackSendDegraded = mock(() => Promise.resolve()); -const mockDiscordSendAlert = mock(() => Promise.resolve()); -const mockDiscordSendRecovery = mock(() => Promise.resolve()); -const mockDiscordSendDegraded = mock(() => Promise.resolve()); - -mock.module("./utils", () => ({ - providerToFunction: { - email: { - sendAlert: mockEmailSendAlert, - sendRecovery: mockEmailSendRecovery, - sendDegraded: mockEmailSendDegraded, - }, - discord: { - sendAlert: mockDiscordSendAlert, - sendRecovery: mockDiscordSendRecovery, - sendDegraded: mockDiscordSendDegraded, - }, - slack: { - sendAlert: mockSlackSendAlert, - sendRecovery: mockSlackSendRecovery, - sendDegraded: mockSlackSendDegraded, - }, - sms: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - webhook: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - telegram: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - pagerduty: { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - opsgenie: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - ntfy: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - "google-chat": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - "grafana-oncall": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - "ms-teams": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - whatsapp: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - }, -})); - -// Import after mocks are set up -const { triggerNotifications } = await import("./alerting"); +import { + afterAll, + afterEach, + assertSpyCalls, + beforeEach, + describe, + expect, + type Stub, + stub, + test, +} from "@openstatus/test-utils"; + +import { checkerAudit } from "../utils/audit-log"; +import { triggerNotifications } from "./alerting"; +import { providerToFunction } from "./utils"; + +// Deno has no module mocking, so we stub the methods on the real singletons +// that alerting.ts reads at call time. Stubbing per-test resolves them to no-op +// to avoid real HTTP / Tinybird calls and gives a fresh call count each test. +// biome-ignore lint/suspicious/noExplicitAny: heterogeneous provider stubs +type AnyStub = Stub; +let stubs: AnyStub[] = []; + +const stubSend = ( + provider: "email" | "slack" | "discord", + verb: "sendAlert" | "sendRecovery" | "sendDegraded", +): AnyStub => { + const s = stub(providerToFunction[provider], verb, () => Promise.resolve()); + stubs.push(s); + return s; +}; + +let mockEmailSendAlert: AnyStub; +let mockEmailSendRecovery: AnyStub; +let mockEmailSendDegraded: AnyStub; +let mockSlackSendAlert: AnyStub; +let mockSlackSendRecovery: AnyStub; +let mockSlackSendDegraded: AnyStub; +let mockDiscordSendAlert: AnyStub; +let mockDiscordSendRecovery: AnyStub; +let mockDiscordSendDegraded: AnyStub; // Seed data has: monitor 1 (workspace 1) linked to notification 1 (email provider) // We use unique cronTimestamp per test to avoid unique constraint conflicts -describe("triggerNotifications", () => { - afterEach(() => { - mockEmailSendAlert.mockClear(); - mockEmailSendRecovery.mockClear(); - mockEmailSendDegraded.mockClear(); - mockSlackSendAlert.mockClear(); - mockSlackSendRecovery.mockClear(); - mockSlackSendDegraded.mockClear(); - mockDiscordSendAlert.mockClear(); - mockDiscordSendRecovery.mockClear(); - mockDiscordSendDegraded.mockClear(); - }); +beforeEach(() => { + stubs = []; + // biome-ignore lint/suspicious/noExplicitAny: avoid Tinybird call + stubs.push( + stub(checkerAudit, "publishAuditLog", () => Promise.resolve()) as AnyStub, + ); + mockEmailSendAlert = stubSend("email", "sendAlert"); + mockEmailSendRecovery = stubSend("email", "sendRecovery"); + mockEmailSendDegraded = stubSend("email", "sendDegraded"); + mockSlackSendAlert = stubSend("slack", "sendAlert"); + mockSlackSendRecovery = stubSend("slack", "sendRecovery"); + mockSlackSendDegraded = stubSend("slack", "sendDegraded"); + mockDiscordSendAlert = stubSend("discord", "sendAlert"); + mockDiscordSendRecovery = stubSend("discord", "sendRecovery"); + mockDiscordSendDegraded = stubSend("discord", "sendDegraded"); +}); +afterEach(() => { + for (const s of stubs) s.restore(); + stubs = []; +}); + +describe("triggerNotifications", () => { afterAll(async () => { // Clean up notification triggers created during tests await db @@ -112,7 +94,7 @@ describe("triggerNotifications", () => { latency: 1500, }); - expect(mockEmailSendAlert).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendAlert, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -131,7 +113,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - expect(mockEmailSendRecovery).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendRecovery, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -151,7 +133,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - expect(mockEmailSendDegraded).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendDegraded, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -170,7 +152,7 @@ describe("triggerNotifications", () => { cronTimestamp, }); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + assertSpyCalls(mockEmailSendAlert, 0); expect(result).toHaveLength(0); }); @@ -185,7 +167,7 @@ describe("triggerNotifications", () => { }); expect(first).toHaveLength(1); - mockEmailSendAlert.mockClear(); + assertSpyCalls(mockEmailSendAlert, 1); // Same cronTimestamp should be skipped due to unique constraint const second = await triggerNotifications({ @@ -195,7 +177,8 @@ describe("triggerNotifications", () => { cronTimestamp, }); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + // still only the first call — the duplicate was skipped + assertSpyCalls(mockEmailSendAlert, 1); expect(second).toHaveLength(0); }); }); @@ -207,14 +190,6 @@ describe("triggerNotifications with multiple providers", () => { // We link slack and discord notifications to it for this test suite. const testMonitorId = 3; - afterEach(() => { - mockEmailSendAlert.mockClear(); - mockSlackSendAlert.mockClear(); - mockDiscordSendAlert.mockClear(); - mockSlackSendRecovery.mockClear(); - mockDiscordSendRecovery.mockClear(); - }); - afterAll(async () => { // Clean up notification triggers await db @@ -282,9 +257,9 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - expect(mockSlackSendAlert).toHaveBeenCalledTimes(1); - expect(mockDiscordSendAlert).toHaveBeenCalledTimes(1); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + assertSpyCalls(mockSlackSendAlert, 1); + assertSpyCalls(mockDiscordSendAlert, 1); + assertSpyCalls(mockEmailSendAlert, 0); expect(result).toHaveLength(2); expect(result).toContainEqual({ @@ -308,8 +283,8 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - expect(mockSlackSendRecovery).toHaveBeenCalledTimes(1); - expect(mockDiscordSendRecovery).toHaveBeenCalledTimes(1); + assertSpyCalls(mockSlackSendRecovery, 1); + assertSpyCalls(mockDiscordSendRecovery, 1); expect(result).toHaveLength(2); const providers = result.map((r) => r.provider).sort(); diff --git a/apps/workflows/src/cron/checker.ts b/apps/workflows/src/cron/checker.ts index dfdb5b32..40dbf7ab 100644 --- a/apps/workflows/src/cron/checker.ts +++ b/apps/workflows/src/cron/checker.ts @@ -51,7 +51,7 @@ export const isAuthorizedDomain = (url: string) => { const logger = getLogger("workflow"); const client = new CloudTasksClient({ - fallback: "rest", + fallback: true, projectId: env().GCP_PROJECT_ID, credentials: { client_email: env().GCP_CLIENT_EMAIL, diff --git a/apps/workflows/src/cron/index.ts b/apps/workflows/src/cron/index.ts index 9ca25c81..45bd9b6e 100644 --- a/apps/workflows/src/cron/index.ts +++ b/apps/workflows/src/cron/index.ts @@ -1,5 +1,5 @@ import { monitorPeriodicitySchema } from "@openstatus/db/src/schema/constants"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { Effect, Schedule } from "effect"; import { Hono } from "hono"; diff --git a/apps/workflows/src/index.ts b/apps/workflows/src/index.ts index fd186562..9cd13dac 100644 --- a/apps/workflows/src/index.ts +++ b/apps/workflows/src/index.ts @@ -8,9 +8,15 @@ import { withContext, } from "@logtape/logtape"; import { getOpenTelemetrySink } from "@logtape/otel"; +import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"; import { resourceFromAttributes } from "@opentelemetry/resources"; +import { + BatchLogRecordProcessor, + LoggerProvider, +} from "@opentelemetry/sdk-logs"; +import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME } from "@opentelemetry/semantic-conventions/incubating"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { Hono } from "hono"; import { showRoutes } from "hono/dev"; import { requestId } from "hono/request-id"; @@ -21,7 +27,7 @@ import { cronRouter } from "./cron"; import { env } from "./env"; import { incidentRoute } from "./incident"; -const { NODE_ENV, PORT } = env(); +const { NODE_ENV } = env(); export type Env = { Variables: { @@ -59,18 +65,30 @@ function shouldSample(event: Record): boolean { return Math.random() < 0.2; } -const defaultLogger = getOpenTelemetrySink({ - serviceName: "openstatus-workflows", - otlpExporterConfig: { - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env().AXIOM_TOKEN}`, - "X-Axiom-Dataset": env().AXIOM_DATASET, - }, - }, - additionalResource: resourceFromAttributes({ +// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` +// includes it. Letting @logtape/otel create the exporter triggers a dynamic +// import of a bare specifier, which the compiled --node-modules-dir=none binary +// can't resolve. +const loggerProvider = new LoggerProvider({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: "openstatus-workflows", [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env().NODE_ENV, }), + processors: [ + new BatchLogRecordProcessor( + new OTLPLogExporter({ + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env().AXIOM_TOKEN}`, + "X-Axiom-Dataset": env().AXIOM_DATASET, + }, + }), + ), + ], +}); + +const defaultLogger = getOpenTelemetrySink({ + loggerProvider, }); await configure({ @@ -97,7 +115,7 @@ await configure({ const logger = getLogger(["workflow"]); const otelLogger = getLogger(["workflow-otel"]); -const app = new Hono({ strict: false }); +export const app = new Hono({ strict: false }); app.use("*", requestId()); @@ -182,9 +200,3 @@ app.route("/incident", incidentRoute); if (NODE_ENV === "development") { showRoutes(app, { verbose: true, colorize: true }); } - -logger.info("Starting server", { port: PORT, environment: NODE_ENV }); - -const server = { port: PORT, fetch: app.fetch }; - -export default server; diff --git a/apps/workflows/src/lib/sentry.ts b/apps/workflows/src/lib/sentry.ts index 542d06d2..45e70c55 100644 --- a/apps/workflows/src/lib/sentry.ts +++ b/apps/workflows/src/lib/sentry.ts @@ -1,5 +1,5 @@ import { FetchError } from "@openstatus/status-fetcher"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { env } from "../env"; diff --git a/apps/workflows/src/serve.ts b/apps/workflows/src/serve.ts new file mode 100644 index 00000000..6f520562 --- /dev/null +++ b/apps/workflows/src/serve.ts @@ -0,0 +1,15 @@ +/// + +import { getLogger } from "@logtape/logtape"; + +import { env } from "./env"; +import { app } from "./index"; + +const { NODE_ENV, PORT } = env(); + +getLogger(["workflow"]).info("Starting server", { + port: PORT, + environment: NODE_ENV, +}); + +Deno.serve({ port: PORT }, app.fetch); diff --git a/apps/workflows/start.sh b/apps/workflows/start.sh index 0c6da27c..e24344a2 100644 --- a/apps/workflows/start.sh +++ b/apps/workflows/start.sh @@ -2,7 +2,7 @@ set -e echo "Running database migrations..." -cd /app/packages/db && bun src/migrate.mts +cd /app/packages/db && deno run -A src/migrate.mts echo "Starting workflows service..." cd /app/apps/workflows diff --git a/apps/workflows/tsconfig.json b/apps/workflows/tsconfig.json index 9ce54dd0..a627827e 100644 --- a/apps/workflows/tsconfig.json +++ b/apps/workflows/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "hono/jsx", - "lib": ["ES2022"], "module": "ESNext", "target": "ESNext", "moduleResolution": "bundler" diff --git a/deno.lock b/deno.lock new file mode 100644 index 00000000..59e89299 --- /dev/null +++ b/deno.lock @@ -0,0 +1,277 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/assert@^1.0.19": "1.0.19", + "jsr:@std/async@^1.4.0": "1.4.0", + "jsr:@std/data-structures@^1.1.0": "1.1.0", + "jsr:@std/expect@*": "1.0.19", + "jsr:@std/internal@^1.0.12": "1.0.14", + "jsr:@std/internal@^1.0.13": "1.0.14", + "jsr:@std/path@^1.1.4": "1.1.4", + "jsr:@std/testing@*": "1.0.19" + }, + "jsr": { + "@std/assert@1.0.19": { + "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", + "dependencies": [ + "jsr:@std/internal@^1.0.12" + ] + }, + "@std/async@1.4.0": { + "integrity": "4d70b008634f571cff9b554090d628c76141c32613aae0ff283fd5fa23d0c379" + }, + "@std/data-structures@1.1.0": { + "integrity": "c35ae4ad5d8e41a38573c2fe3e19b18ea2505f63cfea201edcb8720aca1f7f58" + }, + "@std/expect@1.0.19": { + "integrity": "25271785688c7ff902fa54875d6aa4001f552c5578f7f0fefb5b5aac1fc2ed8a", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/internal@^1.0.13", + "jsr:@std/path" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + }, + "@std/path@1.1.4": { + "integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5", + "dependencies": [ + "jsr:@std/internal@^1.0.12" + ] + }, + "@std/testing@1.0.19": { + "integrity": "f4236172365b216728dc3cc8b5e80a9f4c33083d1e4ede7613d5b25b4014898e", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/async", + "jsr:@std/data-structures" + ] + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:turbo@2.9.14" + ] + }, + "members": { + "apps/server": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/status-page": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/web": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/api": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/db": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/emails": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/header-analysis": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/importers": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/base": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/bird-whatsapp": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/discord": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/google-chat": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/grafana-oncall": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ms-teams": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ntfy": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/opsgenie": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/pagerduty": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/slack": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/telegram": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/twillio-sms": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/webhook": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/services": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/status-fetcher": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/subscriptions": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/test-utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/tracker": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + } + } + } +} diff --git a/package.json b/package.json index fcf9e3f2..995b4fb7 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "format": "oxfmt && oxlint --fix", "format:check": "oxfmt --check && oxlint", "lint:turbo": "turbo run lint", + "check": "turbo run check", "dev:web": "turbo run dev --filter='./apps/web' --filter='./packages/db'", "dev:status-page": "turbo run dev --filter='./apps/status-page' --filter='./packages/db'", "dev:dashboard": "turbo run dev --filter='./apps/dashboard' --filter='./packages/db'", diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 1594951d..4c43a19c 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@openpanel/sdk": "catalog:", "@t3-oss/env-core": "catalog:", diff --git a/packages/analytics/tsconfig.json b/packages/analytics/tsconfig.json index 7f4d9b72..3c1048af 100644 --- a/packages/analytics/tsconfig.json +++ b/packages/analytics/tsconfig.json @@ -5,7 +5,6 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", - "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/api/.env.test b/packages/api/.env.test index 84a3ecca..75fa5596 100644 --- a/packages/api/.env.test +++ b/packages/api/.env.test @@ -1,3 +1,4 @@ +NODE_ENV=test RESEND_API_KEY='test' NEXT_PUBLIC_OPENPANEL_CLIENT_ID='test' OPENPANEL_CLIENT_SECRET='test' diff --git a/packages/api/env.ts b/packages/api/env.ts index 1dd33b39..4796312c 100644 --- a/packages/api/env.ts +++ b/packages/api/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.test"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.test", "./.env"); diff --git a/packages/api/package.json b/packages/api/package.json index ae6b5c2f..b6cfb9e2 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -6,9 +6,14 @@ "license": "ISC", "author": "", "main": "index.ts", + "exports": { + ".": "./index.ts", + "./src/*": "./src/*.ts" + }, "scripts": { - "test": "bun test", - "env": "bun env.ts" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports --env-file=.env.test --import-map=test.importmap.json", + "env": "deno run -A env.ts" }, "dependencies": { "@openstatus/analytics": "workspace:*", @@ -52,6 +57,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/react": "catalog:", "@types/react-dom": "catalog:", "bun-types": "catalog:", diff --git a/packages/api/src/router/blob.test.ts b/packages/api/src/router/blob.test.ts index a357abdb..f8498a1e 100644 --- a/packages/api/src/router/blob.test.ts +++ b/packages/api/src/router/blob.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { isSvgFile, sanitizeSvg } from "./blob"; diff --git a/packages/api/src/router/effective-status.test.ts b/packages/api/src/router/effective-status.test.ts index fcd2fcec..9c7ef9e8 100644 --- a/packages/api/src/router/effective-status.test.ts +++ b/packages/api/src/router/effective-status.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { computeEffectiveStatus } from "./effective-status"; diff --git a/packages/api/src/router/import.test.ts b/packages/api/src/router/import.test.ts index 80c3c4c2..ddb77b23 100644 --- a/packages/api/src/router/import.test.ts +++ b/packages/api/src/router/import.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { maintenance, @@ -21,6 +19,8 @@ import { MOCK_SUBSCRIBERS, } from "@openstatus/importers/statuspage/fixtures"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; @@ -341,7 +341,7 @@ test("run creates page, components, and groups in DB", async () => { // Clean up for next tests await cleanup(); -}, 15_000); +}); test("run with existing pageId imports into that page", async () => { const result = await caller.import.run({ @@ -374,7 +374,7 @@ test("run with existing pageId imports into that page", async () => { expect(matchingComps.length).toBe(MOCK_COMPONENTS.length); await cleanup(); -}, 15_000); +}); test("re-run skips already-imported resources (idempotency)", async () => { // First run @@ -410,7 +410,7 @@ test("re-run skips already-imported resources (idempotency)", async () => { expect(allGroupsSkipped).toBe(true); await cleanup(); -}, 15_000); +}); test("run with includeStatusReports creates status reports", async () => { const result = await caller.import.run({ @@ -461,7 +461,7 @@ test("run with includeStatusReports creates status reports", async () => { expect(createdMaintIds.length).toBeGreaterThan(0); await cleanup(); -}, 15_000); +}); // --------------------------------------------------------------------------- // Limit warnings (go through the caller with custom workspace limits to diff --git a/packages/api/src/router/maintenance.test.ts b/packages/api/src/router/maintenance.test.ts index 65c853c0..c24e9425 100644 --- a/packages/api/src/router/maintenance.test.ts +++ b/packages/api/src/router/maintenance.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -8,6 +6,8 @@ import { pageComponent, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/monitor.test.ts b/packages/api/src/router/monitor.test.ts index d19508a7..62079b22 100644 --- a/packages/api/src/router/monitor.test.ts +++ b/packages/api/src/router/monitor.test.ts @@ -1,40 +1,88 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - -import { db, eq } from "@openstatus/db"; +import { db, eq, inArray } from "@openstatus/db"; import { monitorTag, monitorTagsToMonitors, + notification, + notificationsToMonitors, privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; +// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in +// the authed middleware, so the caller is scoped to ownWorkspaceId instead of +// resolving the seeded workspace for the session user. +function callerFor(limits?: typeof allPlans.team.limits) { + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal user for test + user: { id: 1 }, + // @ts-expect-error - minimal workspace for test + workspace: limits ? { id: ownWorkspaceId, limits } : { id: ownWorkspaceId }, + }); + return edgeRouter.createCaller(ctx); +} + +// Own workspaces/monitors per suite — these IDOR tests previously shared the +// seeded monitor 5 / workspace 3, which races sibling suites mutating that +// monitor's associations (e.g. privateLocation.test). +let ownWorkspaceId: number; +let otherWorkspaceId: number; +let ownMonitorId: number; +let otherMonitorId: number; let tagId: number; +let notifierId: number; let otherWorkspacePrivateLocationId: number; let ownWorkspacePrivateLocationId: number; beforeAll(async () => { + const own = await createWorkspace(); + const other = await createWorkspace(); + ownWorkspaceId = own.id; + otherWorkspaceId = other.id; + + const ownMonitor = await createMonitor(own.id); + const otherMonitor = await createMonitor(other.id); + ownMonitorId = ownMonitor.id; + otherMonitorId = otherMonitor.id; + const tag = await db .insert(monitorTag) + .values({ workspaceId: own.id, name: "idor-test-tag", color: "#ff0000" }) + .returning() + .get(); + tagId = tag.id; + + const notif = await db + .insert(notification) .values({ - workspaceId: 1, - name: "idor-test-tag", - color: "#ff0000", + workspaceId: own.id, + name: "idor-test-notif", + provider: "email", + data: JSON.stringify({ email: "test@example.com" }), }) .returning() .get(); - tagId = tag.id; + notifierId = notif.id; const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: 3, + workspaceId: other.id, name: "Other workspace private location", - token: "monitor-test-other-token", + token: `monitor-test-other-${otherWorkspaceId}`, }) .returning() .get(); @@ -43,47 +91,68 @@ beforeAll(async () => { const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: 1, + workspaceId: own.id, name: "Own workspace private location", - token: "monitor-test-own-token", + token: `monitor-test-own-${ownWorkspaceId}`, }) .returning() .get(); ownWorkspacePrivateLocationId = ownLoc.id; + + // Pre-existing association on the cross-workspace monitor; the IDOR test + // asserts a rejected scheduling update does not wipe it. + await db + .insert(privateLocationToMonitors) + .values({ privateLocationId: otherLoc.id, monitorId: otherMonitor.id }) + .run(); }); afterAll(async () => { - await db - .delete(monitorTagsToMonitors) - .where(eq(monitorTagsToMonitors.monitorTagId, tagId)); - await db.delete(monitorTag).where(eq(monitorTag.id, tagId)); await db .delete(privateLocationToMonitors) .where( - eq( - privateLocationToMonitors.privateLocationId, + inArray(privateLocationToMonitors.privateLocationId, [ + otherWorkspacePrivateLocationId, ownWorkspacePrivateLocationId, - ), - ); + ]), + ) + .catch(() => undefined); await db .delete(privateLocation) - .where(eq(privateLocation.id, otherWorkspacePrivateLocationId)); + .where( + inArray(privateLocation.id, [ + otherWorkspacePrivateLocationId, + ownWorkspacePrivateLocationId, + ]), + ) + .catch(() => undefined); await db - .delete(privateLocation) - .where(eq(privateLocation.id, ownWorkspacePrivateLocationId)); + .delete(monitorTagsToMonitors) + .where(eq(monitorTagsToMonitors.monitorTagId, tagId)) + .catch(() => undefined); + await db + .delete(monitorTag) + .where(eq(monitorTag.id, tagId)) + .catch(() => undefined); + await db + .delete(notificationsToMonitors) + .where(eq(notificationsToMonitors.notificationId, notifierId)) + .catch(() => undefined); + await db + .delete(notification) + .where(eq(notification.id, notifierId)) + .catch(() => undefined); + await db + .delete(workspace) + .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) + .catch(() => undefined); }); test("monitor.updateTags rejects monitor from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { - await caller.monitor.updateTags({ id: 5, tags: [] }); + await caller.monitor.updateTags({ id: otherMonitorId, tags: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -92,34 +161,22 @@ test("monitor.updateTags rejects monitor from another workspace", async () => { }); test("monitor.updateTags succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); - await caller.monitor.updateTags({ id: 1, tags: [tagId] }); + await caller.monitor.updateTags({ id: ownMonitorId, tags: [tagId] }); const result = await db.query.monitorTagsToMonitors.findFirst({ - where: eq(monitorTagsToMonitors.monitorId, 1), + where: eq(monitorTagsToMonitors.monitorId, ownMonitorId), }); expect(result).toBeDefined(); expect(result?.monitorTagId).toBe(tagId); }); test("monitor.updateNotifiers rejects monitor from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { - await caller.monitor.updateNotifiers({ id: 5, notifiers: [] }); + await caller.monitor.updateNotifiers({ id: otherMonitorId, notifiers: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -128,36 +185,26 @@ test("monitor.updateNotifiers rejects monitor from another workspace", async () }); test("monitor.updateNotifiers succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); - await caller.monitor.updateNotifiers({ id: 1, notifiers: [1] }); + await caller.monitor.updateNotifiers({ + id: ownMonitorId, + notifiers: [notifierId], + }); }); test("monitor.updateSchedulingRegions rejects monitor from another workspace", async () => { - // Monitor 5 belongs to workspace 3; try to update it from workspace 1 - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); // Verify the seed private location association exists before the attack const before = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 5), + where: eq(privateLocationToMonitors.monitorId, otherMonitorId), }); const beforeCount = before.length; try { await caller.monitor.updateSchedulingRegions({ - id: 5, + id: otherMonitorId, regions: ["ams"], periodicity: "30s", privateLocations: [], @@ -170,23 +217,16 @@ test("monitor.updateSchedulingRegions rejects monitor from another workspace", a // Verify private location associations were NOT deleted const after = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 5), + where: eq(privateLocationToMonitors.monitorId, otherMonitorId), }); expect(after.length).toBe(beforeCount); }); test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); - // Monitor 1 belongs to workspace 1 await caller.monitor.updateSchedulingRegions({ - id: 1, + id: ownMonitorId, regions: ["ams"], periodicity: "1m", privateLocations: [], @@ -194,20 +234,14 @@ test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async }); test("monitor.updateSchedulingRegions rejects privateLocations from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); try { await caller.monitor.updateSchedulingRegions({ - id: 1, // own monitor + id: ownMonitorId, regions: ["ams"], periodicity: "1m", - privateLocations: [otherWorkspacePrivateLocationId], // workspace 2 + privateLocations: [otherWorkspacePrivateLocationId], }); throw new Error("Should have thrown"); } catch (e) { @@ -217,23 +251,17 @@ test("monitor.updateSchedulingRegions rejects privateLocations from another work }); test("monitor.updateSchedulingRegions succeeds with own workspace privateLocations", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); await caller.monitor.updateSchedulingRegions({ - id: 1, + id: ownMonitorId, regions: ["ams"], periodicity: "1m", privateLocations: [ownWorkspacePrivateLocationId], }); const associations = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 1), + where: eq(privateLocationToMonitors.monitorId, ownMonitorId), }); const linked = associations.find( (a) => a.privateLocationId === ownWorkspacePrivateLocationId, diff --git a/packages/api/src/router/notification.test.ts b/packages/api/src/router/notification.test.ts index d458ca28..a0ef37bf 100644 --- a/packages/api/src/router/notification.test.ts +++ b/packages/api/src/router/notification.test.ts @@ -1,10 +1,10 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index 7137893e..e7b069f6 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -32,10 +32,6 @@ import { env } from "../env"; import { toServiceCtx, toTRPCError } from "../service-adapter"; import { createTRPCRouter, protectedProcedure } from "../trpc"; -if (process.env.NODE_ENV === "test") { - require("../test/preload"); -} - // Vercel domain helpers — transport-layer external integrations that // don't belong in the service layer. async function addDomainToVercel(domain: string) { diff --git a/packages/api/src/router/pageComponent.test.ts b/packages/api/src/router/pageComponent.test.ts index c14e9f5e..187cef84 100644 --- a/packages/api/src/router/pageComponent.test.ts +++ b/packages/api/src/router/pageComponent.test.ts @@ -1,8 +1,8 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/privateLocation.test.ts b/packages/api/src/router/privateLocation.test.ts index 19e39485..c621f351 100644 --- a/packages/api/src/router/privateLocation.test.ts +++ b/packages/api/src/router/privateLocation.test.ts @@ -1,25 +1,61 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - -import { db, eq } from "@openstatus/db"; +import { db, eq, inArray } from "@openstatus/db"; import { privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; +// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in +// the authed middleware, so the caller is scoped to ownWorkspaceId instead of +// resolving the seeded workspace for the session user. +function callerFor() { + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal user for test + user: { id: 1 }, + // @ts-expect-error - minimal workspace for test + workspace: { id: ownWorkspaceId }, + }); + return edgeRouter.createCaller(ctx); +} + +// Own workspaces/monitors per suite — sharing the seeded monitor 5 / workspace +// 3 races sibling suites that read or mutate that monitor's associations. +let ownWorkspaceId: number; +let otherWorkspaceId: number; +let ownMonitorId: number; +let otherMonitorId: number; let otherWorkspaceLocationId: number; let ownWorkspaceLocationId: number; beforeAll(async () => { + const own = await createWorkspace(); + const other = await createWorkspace(); + ownWorkspaceId = own.id; + otherWorkspaceId = other.id; + + const ownMonitor = await createMonitor(own.id); + const otherMonitor = await createMonitor(other.id); + ownMonitorId = ownMonitor.id; + otherMonitorId = otherMonitor.id; + const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: 3, + workspaceId: other.id, name: "Other workspace location", - token: "test-token-idor", + token: `test-token-idor-${otherWorkspaceId}`, }) .returning() .get(); @@ -29,16 +65,16 @@ beforeAll(async () => { .insert(privateLocationToMonitors) .values({ privateLocationId: otherWorkspaceLocationId, - monitorId: 5, + monitorId: otherMonitorId, }) .run(); const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: 1, + workspaceId: own.id, name: "Own workspace location", - token: "test-token-own", + token: `test-token-own-${ownWorkspaceId}`, }) .returning() .get(); @@ -49,29 +85,29 @@ afterAll(async () => { await db .delete(privateLocationToMonitors) .where( - eq(privateLocationToMonitors.privateLocationId, otherWorkspaceLocationId), - ); + inArray(privateLocationToMonitors.privateLocationId, [ + otherWorkspaceLocationId, + ownWorkspaceLocationId, + ]), + ) + .catch(() => undefined); await db .delete(privateLocation) - .where(eq(privateLocation.id, otherWorkspaceLocationId)); - await db - .delete(privateLocationToMonitors) .where( - eq(privateLocationToMonitors.privateLocationId, ownWorkspaceLocationId), - ); + inArray(privateLocation.id, [ + otherWorkspaceLocationId, + ownWorkspaceLocationId, + ]), + ) + .catch(() => undefined); await db - .delete(privateLocation) - .where(eq(privateLocation.id, ownWorkspaceLocationId)); + .delete(workspace) + .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) + .catch(() => undefined); }); test("privateLocation.update rejects location from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.update({ @@ -96,18 +132,12 @@ test("privateLocation.update rejects location from another workspace", async () }); test("privateLocation.update succeeds for own workspace location", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); const result = await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [1], + monitors: [ownMonitorId], }); expect(result).toBeDefined(); @@ -115,19 +145,13 @@ test("privateLocation.update succeeds for own workspace location", async () => { }); test("privateLocation.new rejects monitors from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.new({ name: "Injected Location", token: "test-token-inject", - monitors: [5], // monitor 5 belongs to workspace 3 + monitors: [otherMonitorId], }); throw new Error("Should have thrown"); } catch (e) { @@ -137,18 +161,12 @@ test("privateLocation.new rejects monitors from another workspace", async () => }); test("privateLocation.new succeeds with own workspace monitors", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); const result = await caller.privateLocation.new({ name: "Valid Location", token: "test-token-valid-new", - monitors: [1], // monitor 1 belongs to workspace 1 + monitors: [ownMonitorId], }); expect(result).toBeDefined(); @@ -159,7 +177,7 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { where: eq(privateLocationToMonitors.privateLocationId, result.id), }); expect(associations.length).toBe(1); - expect(associations[0].monitorId).toBe(1); + expect(associations[0].monitorId).toBe(ownMonitorId); // Cleanup await db @@ -169,19 +187,13 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { }); test("privateLocation.update rejects monitors from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [5], // monitor 5 belongs to workspace 3 + monitors: [otherMonitorId], }); throw new Error("Should have thrown"); } catch (e) { diff --git a/packages/api/src/router/statusPage.e2e.test.ts b/packages/api/src/router/statusPage.e2e.test.ts index 1baab894..79c611ab 100644 --- a/packages/api/src/router/statusPage.e2e.test.ts +++ b/packages/api/src/router/statusPage.e2e.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { incidentTable, @@ -9,6 +7,8 @@ import { pageSubscriber, workspace, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * End-to-end integration tests for the full unsubscribe flow. @@ -213,6 +213,7 @@ describe("Confirmation page displays correct information", () => { } const email = subscriber.email; + if (!email) throw new Error("Subscriber email not found"); expect(email).toBe("confirm-page-test@example.com"); // Apply the same masking logic as in the API diff --git a/packages/api/src/router/statusPage.unsubscribe.test.ts b/packages/api/src/router/statusPage.unsubscribe.test.ts index 9800d3fc..8cb66d5f 100644 --- a/packages/api/src/router/statusPage.unsubscribe.test.ts +++ b/packages/api/src/router/statusPage.unsubscribe.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; // Test data setup let testPageId: number; diff --git a/packages/api/src/router/statusPage.utils.test.ts b/packages/api/src/router/statusPage.utils.test.ts index 15baf720..1961e85f 100644 --- a/packages/api/src/router/statusPage.utils.test.ts +++ b/packages/api/src/router/statusPage.utils.test.ts @@ -1,5 +1,3 @@ -import { describe, expect, it } from "bun:test"; - import type { Incident, Maintenance, @@ -7,6 +5,8 @@ import type { StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { currentImpactByComponent, diff --git a/packages/api/src/router/statusReport.test.ts b/packages/api/src/router/statusReport.test.ts index 2175fbf4..1c63e8eb 100644 --- a/packages/api/src/router/statusReport.test.ts +++ b/packages/api/src/router/statusReport.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { page, @@ -9,6 +7,8 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/stripe/utils.test.ts b/packages/api/src/router/stripe/utils.test.ts index 02299b1b..048fd6b5 100644 --- a/packages/api/src/router/stripe/utils.test.ts +++ b/packages/api/src/router/stripe/utils.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { getLimits } from "@openstatus/db/src/schema/plan/utils"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type Stripe from "stripe"; import { FEATURES, PLANS, buildLimitsFromSubscription } from "./utils"; diff --git a/packages/api/src/router/tinybird/index.test.ts b/packages/api/src/router/tinybird/index.test.ts index 759d92c6..66805529 100644 --- a/packages/api/src/router/tinybird/index.test.ts +++ b/packages/api/src/router/tinybird/index.test.ts @@ -1,5 +1,5 @@ -import { expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../../edge"; diff --git a/packages/api/src/router/workspace.test.ts b/packages/api/src/router/workspace.test.ts index 02b14002..3812aff7 100644 --- a/packages/api/src/router/workspace.test.ts +++ b/packages/api/src/router/workspace.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; diff --git a/packages/api/src/test/preload.ts b/packages/api/src/test/preload.ts deleted file mode 100644 index 4d43b6ff..00000000 --- a/packages/api/src/test/preload.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { mock } from "bun:test"; - -mock.module("@openstatus/upstash", () => ({ - Redis: { - fromEnv() { - return { - get: () => Promise.resolve(undefined), - set: () => Promise.resolve([]), - }; - }, - }, -})); diff --git a/packages/api/src/test/upstash.mock.ts b/packages/api/src/test/upstash.mock.ts new file mode 100644 index 00000000..7aa2e846 --- /dev/null +++ b/packages/api/src/test/upstash.mock.ts @@ -0,0 +1,18 @@ +// Test double for @openstatus/upstash, swapped in via --import-map in the +// `deno test` command. Keeps tests off a real Upstash Redis instance. +const noopRedis = { + get: () => Promise.resolve(null), + set: () => Promise.resolve("OK"), + del: () => Promise.resolve(0), + getdel: () => Promise.resolve(null), + incr: () => Promise.resolve(1), + expire: () => Promise.resolve(1), +}; + +export const redis = noopRedis; + +export const Redis = { + fromEnv() { + return noopRedis; + }, +}; diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts index 4e380ee0..d8225921 100644 --- a/packages/api/src/trpc.ts +++ b/packages/api/src/trpc.ts @@ -7,7 +7,7 @@ import { import { db } from "@openstatus/db"; import type { User, Workspace } from "@openstatus/db/src/schema"; import { TRPCError, initTRPC } from "@trpc/server"; -import { type NextRequest, after } from "next/server"; +import { type NextRequest, after } from "next/server.js"; import superjson from "superjson"; import { ZodError, treeifyError } from "zod"; diff --git a/packages/api/test.importmap.json b/packages/api/test.importmap.json new file mode 100644 index 00000000..94b18545 --- /dev/null +++ b/packages/api/test.importmap.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@openstatus/upstash": "./src/test/upstash.mock.ts" + } +} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index 15860ea1..48baa5cf 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -1,8 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "moduleResolution": "bundler", - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/assertions/package.json b/packages/assertions/package.json index 0472bd9f..79323a62 100644 --- a/packages/assertions/package.json +++ b/packages/assertions/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "jsonpath-plus": "catalog:", "zod": "catalog:" diff --git a/packages/assertions/src/v1.ts b/packages/assertions/src/v1.ts index 0b7ea37d..9b480988 100644 --- a/packages/assertions/src/v1.ts +++ b/packages/assertions/src/v1.ts @@ -309,7 +309,7 @@ export class HeaderAssertion implements Assertion { }; } const { success, message } = evaluateString( - req.header[this.schema.key], + req.header[this.schema.key] ?? "", this.schema.compare, this.schema.target, ); diff --git a/packages/assertions/tsconfig.json b/packages/assertions/tsconfig.json index ec9f2821..aed15c74 100644 --- a/packages/assertions/tsconfig.json +++ b/packages/assertions/tsconfig.json @@ -1,7 +1,4 @@ { "extends": "@openstatus/tsconfig/base.json", - "compilerOptions": { - "lib": ["es2015", "dom"] - }, "include": ["src", "*.ts"] } diff --git a/packages/db/env.ts b/packages/db/env.ts index dbb28b16..dab63f5f 100644 --- a/packages/db/env.ts +++ b/packages/db/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/packages/db/package.json b/packages/db/package.json index a08d4abc..8e7d6d38 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -4,13 +4,27 @@ "description": "", "author": "OpenStatus", "main": "src/index.ts", + "exports": { + ".": "./src/index.ts", + "./env.mjs": "./env.mjs", + "./src/schema": "./src/schema/index.ts", + "./src/test/factories": "./src/test/factories.ts", + "./src/schema/api-keys": "./src/schema/api-keys/index.ts", + "./src/schema/check": "./src/schema/check/index.ts", + "./src/schema/incidents": "./src/schema/incidents/index.ts", + "./src/schema/maintenances": "./src/schema/maintenances/index.ts", + "./src/schema/page_components": "./src/schema/page_components/index.ts", + "./src/schema/workspaces": "./src/schema/workspaces/index.ts", + "./src/*": "./src/*.ts" + }, "scripts": { + "check": "deno check --sloppy-imports .", "generate": "drizzle-kit generate", "push": "drizzle-kit push", - "migrate": "bun src/migrate.mts", + "migrate": "deno run -A --env-file src/migrate.mts", "studio": "drizzle-kit studio", - "env": "bun env.ts", - "seed": "bun src/seed.mts", + "env": "deno run -A env.ts", + "seed": "deno run -A --env-file --sloppy-imports src/seed.mts", "dev": "turso dev --db-file ../../openstatus-dev.db" }, "dependencies": { @@ -28,6 +42,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/bcryptjs": "catalog:", "@types/node": "catalog:", "drizzle-kit": "catalog:", diff --git a/packages/db/script/region-migration.test.ts b/packages/db/script/region-migration.test.ts index b9e3bc60..f52fd0eb 100644 --- a/packages/db/script/region-migration.test.ts +++ b/packages/db/script/region-migration.test.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import type { z } from "zod"; import type { monitorRegionSchema } from "../src/schema/constants"; diff --git a/packages/db/src/schema/page_components/validation.ts b/packages/db/src/schema/page_components/validation.ts index 71188c42..fae44fbd 100644 --- a/packages/db/src/schema/page_components/validation.ts +++ b/packages/db/src/schema/page_components/validation.ts @@ -10,7 +10,7 @@ import { export const selectPageComponentSchema = createSelectSchema(pageComponent); export const insertPageComponentSchema = createInsertSchema(pageComponent, { - name: (schema) => schema.min(1), + name: z.string().min(1), }).refine( (data) => { // monitorId must be set when type='monitor' diff --git a/packages/db/src/seed.mts b/packages/db/src/seed.mts index bdc4cf4d..8e126471 100644 --- a/packages/db/src/seed.mts +++ b/packages/db/src/seed.mts @@ -24,9 +24,35 @@ import { import { externalServicesSeed } from "./seed/external-services"; async function main() { - const db = drizzle( - createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN }), + if ( + !env.DATABASE_URL.includes("localhost") && + !env.DATABASE_URL.includes("127.0.0.1") + ) { + throw new Error( + `Refusing to wipe non-local database: DATABASE_URL=${env.DATABASE_URL}`, + ); + } + + const client = createClient({ + url: env.DATABASE_URL, + authToken: env.DATABASE_AUTH_TOKEN, + }); + const db = drizzle(client); + + // Fresh slate: wipe every table so re-seeding is idempotent and tests never + // inherit residue from a previous run. `defer_foreign_keys` lets us delete in + // any order within the transaction (all tables end empty, so FKs hold at commit). + const tables = await client.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != '__drizzle_migrations'", ); + await client.batch( + [ + "PRAGMA defer_foreign_keys=ON", + ...tables.rows.map((row) => `DELETE FROM "${row.name}"`), + ], + "write", + ); + console.log("Seeding database "); await db .insert(workspace) diff --git a/packages/db/src/test/factories.ts b/packages/db/src/test/factories.ts new file mode 100644 index 00000000..72b4d2d2 --- /dev/null +++ b/packages/db/src/test/factories.ts @@ -0,0 +1,50 @@ +// Test data factories: create fresh, uniquely-identified resources so suites +// don't collide on shared seed IDs (workspace 1, monitors 1-3, …). Each call +// inserts a row with an auto-increment id and unique slug/name, then returns +// it — scope the test to the returned id and clean up in afterAll. +// +// Pass a transaction as the last arg to scope creation to it (e.g. inside a +// rolled-back `withTestTransaction`); omit it to commit to the shared db. +import { db as defaultDb } from "../db"; +import { monitor, workspace } from "../schema"; + +type Db = typeof defaultDb; +type WorkspaceInsert = typeof workspace.$inferInsert; +type MonitorInsert = typeof monitor.$inferInsert; + +const unique = () => crypto.randomUUID().slice(0, 8); + +export async function createWorkspace( + overrides: Partial = {}, + db: Db = defaultDb, +) { + const u = unique(); + const [row] = await db + .insert(workspace) + .values({ + slug: `test-ws-${u}`, + name: "Test Workspace", + stripeId: `test-stripe-${u}`, + plan: "team", + ...overrides, + }) + .returning(); + return row; +} + +export async function createMonitor( + workspaceId: number, + overrides: Partial = {}, + db: Db = defaultDb, +) { + const [row] = await db + .insert(monitor) + .values({ + workspaceId, + url: "https://example.openstatus.dev", + name: `test-monitor-${unique()}`, + ...overrides, + }) + .returning(); + return row; +} diff --git a/packages/db/src/utils/api-key.test.ts b/packages/db/src/utils/api-key.test.ts index 63971b5c..8fae1da2 100644 --- a/packages/db/src/utils/api-key.test.ts +++ b/packages/db/src/utils/api-key.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { generateApiKey, diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index c3ede090..122f1a76 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -5,7 +5,6 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", - "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/emails/package.json b/packages/emails/package.json index 849cc2a9..229b1c93 100644 --- a/packages/emails/package.json +++ b/packages/emails/package.json @@ -6,9 +6,15 @@ "license": "ISC", "author": "", "main": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./src/client": "./src/client.tsx", + "./src/*": "./src/*.ts" + }, "scripts": { + "check": "deno check --sloppy-imports .", "dev:email": "email dev", - "test": "bun test" + "test": "deno test --parallel -A --no-check --sloppy-imports" }, "dependencies": { "@t3-oss/env-core": "catalog:", @@ -21,6 +27,8 @@ "devDependencies": { "@openstatus/tsconfig": "workspace:*", "@react-email/ui": "catalog:", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "typescript": "catalog:" diff --git a/packages/emails/src/client.integration.test.tsx b/packages/emails/src/client.integration.test.tsx index 9733456f..9de77175 100644 --- a/packages/emails/src/client.integration.test.tsx +++ b/packages/emails/src/client.integration.test.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource react */ -import { describe, expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { render } from "react-email"; import StatusReportEmail from "../emails/status-report"; @@ -40,6 +40,7 @@ describe("Status Report Email - Unsubscribe Link in Body", () => { message="Test message" pageComponents={["Monitor 1"]} manageUrl={manageUrl} + unsubscribeUrl="" />, ); diff --git a/packages/emails/src/client.test.ts b/packages/emails/src/client.test.ts index cde4f7bf..59aa8292 100644 --- a/packages/emails/src/client.test.ts +++ b/packages/emails/src/client.test.ts @@ -1,4 +1,11 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { + assertSpyCalls, + returnsNext, + type Stub, + stub, +} from "@std/testing/mock"; import { EmailClient } from "./client"; @@ -35,8 +42,8 @@ const fail = { data: null, error: { name: "application_error" } } as any; describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { let client: EmailClient; - // biome-ignore lint/suspicious/noExplicitAny: bun spy handle - let batchSend: any; + // biome-ignore lint/suspicious/noExplicitAny: stub over the Resend batch method + let batchSend: Stub; beforeEach(() => { // zero backoff so the retry test doesn't wait on the real exponential sleep @@ -44,11 +51,11 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { apiKey: "re_test_123", retryBackoff: "0 millis", }); - batchSend = spyOn(client.client.batch, "send").mockResolvedValue(ok); + batchSend = stub(client.client.batch, "send", () => Promise.resolve(ok)); }); afterEach(() => { - batchSend.mockRestore(); + batchSend.restore(); }); test("passes the base idempotency key suffixed with the batch index", async () => { @@ -56,8 +63,8 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { baseReq({ idempotencyKey: "status-report-update:5" }), ); - expect(batchSend).toHaveBeenCalledTimes(1); - const [, options] = batchSend.mock.calls[0]; + assertSpyCalls(batchSend, 1); + const options = batchSend.calls[0].args[1]; expect(options).toEqual({ idempotencyKey: "status-report-update:5:0" }); }); @@ -69,32 +76,31 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { }), ); - expect(batchSend).toHaveBeenCalledTimes(3); - const keys = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([, o]: [unknown, any]) => o?.idempotencyKey, - ); + assertSpyCalls(batchSend, 3); + const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); expect(keys).toEqual([ "status-report-update:9:0", "status-report-update:9:1", "status-report-update:9:2", ]); - const sizes = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([payload]: [any[]]) => payload.length, - ); + const sizes = batchSend.calls.map((c) => c.args[0].length); expect(sizes).toEqual([100, 100, 50]); }); test("omits the option entirely when no base key is provided", async () => { await client.sendStatusReportUpdate(baseReq()); - const [, options] = batchSend.mock.calls[0]; + const options = batchSend.calls[0].args[1]; expect(options).toBeUndefined(); }); test("reuses the same key across a retry so Resend dedupes the resend", async () => { - batchSend.mockResolvedValueOnce(fail).mockResolvedValueOnce(ok); + batchSend.restore(); + batchSend = stub( + client.client.batch, + "send", + returnsNext([Promise.resolve(fail), Promise.resolve(ok)]), + ); await client.sendStatusReportUpdate( baseReq({ idempotencyKey: "status-report-update:7" }), @@ -102,11 +108,8 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { // failure → retry: the second attempt must carry the identical key, or // Resend would treat the retry as a fresh batch and double-send. - expect(batchSend).toHaveBeenCalledTimes(2); - const keys = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([, o]: [unknown, any]) => o?.idempotencyKey, - ); + assertSpyCalls(batchSend, 2); + const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); expect(keys).toEqual([ "status-report-update:7:0", "status-report-update:7:0", diff --git a/packages/emails/tsconfig.json b/packages/emails/tsconfig.json index e29f2150..39fe813f 100644 --- a/packages/emails/tsconfig.json +++ b/packages/emails/tsconfig.json @@ -1,5 +1,9 @@ { - "extends": "@openstatus/tsconfig/react-library.json", + "extends": "@openstatus/tsconfig/base.json", "include": [".", "src/env.ts"], - "exclude": ["dist", "build", "node_modules"] + "exclude": ["dist", "build", "node_modules"], + "compilerOptions": { + "jsx": "react-jsx", + "resolveJsonModule": true + } } diff --git a/packages/error/package.json b/packages/error/package.json index fd9fe953..ab7f55bc 100644 --- a/packages/error/package.json +++ b/packages/error/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "zod": "catalog:" }, diff --git a/packages/header-analysis/package.json b/packages/header-analysis/package.json index ac5d1eef..8efdb62f 100644 --- a/packages/header-analysis/package.json +++ b/packages/header-analysis/package.json @@ -7,13 +7,15 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test", - "test:watch": "bun test --watch" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch" }, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/header-analysis/src/parser/x-vercel-cache.test.ts b/packages/header-analysis/src/parser/x-vercel-cache.test.ts index eb464af7..2780dd22 100644 --- a/packages/header-analysis/src/parser/x-vercel-cache.test.ts +++ b/packages/header-analysis/src/parser/x-vercel-cache.test.ts @@ -1,19 +1,22 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { parseXVercelCache } from "./x-vercel-cache"; describe("parseXVercelCache", () => { - it.each([ + for (const [value, expectedFragment] of [ ["MISS", "The response was not found in the edge cache"], ["HIT", "The response was served from the edge cache."], ["STALE", "A background request to the origin server"], ["PRERENDER", "The response was served from static storage."], ["REVALIDATED", "the cache was refreshed"], - ])("describes the documented state %p", (value, expectedFragment) => { - const result = parseXVercelCache(value); - expect(result.value).toBe(value); - expect(result.description).toContain(expectedFragment); - }); + ]) { + it(`describes the documented state ${value}`, () => { + const result = parseXVercelCache(value); + expect(result.value).toBe(value); + expect(result.description).toContain(expectedFragment); + }); + } it("matches states case-insensitively", () => { const lower = parseXVercelCache("revalidated"); diff --git a/packages/icons/package.json b/packages/icons/package.json index f50ea616..889ca2a4 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -5,6 +5,7 @@ "main": "./src/index.tsx", "types": "./src/index.tsx", "scripts": { + "check": "deno check --sloppy-imports .", "lint": "oxlint" }, "dependencies": { diff --git a/packages/importers/package.json b/packages/importers/package.json index 894f486a..9d82d995 100644 --- a/packages/importers/package.json +++ b/packages/importers/package.json @@ -14,8 +14,9 @@ "./instatus/fixtures": "./src/providers/instatus/fixtures.ts" }, "scripts": { - "test": "bun test", - "test:watch": "bun test --watch", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -23,6 +24,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/importers/src/providers/betterstack/client.test.ts b/packages/importers/src/providers/betterstack/client.test.ts index 7b13f5dd..fbcd501e 100644 --- a/packages/importers/src/providers/betterstack/client.test.ts +++ b/packages/importers/src/providers/betterstack/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import { createBetterstackClient } from "./client"; import { @@ -16,7 +18,7 @@ const originalFetch = globalThis.fetch; function mockFetchPaginated(data: unknown[], status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const items = callCount === 1 ? data : []; const body = { @@ -39,7 +41,7 @@ function mockFetchPaginated(data: unknown[], status = 200) { } function mockFetchError(status: number, statusText: string) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify({ error: statusText }), { status, @@ -143,9 +145,9 @@ describe("BetterstackClient", () => { test("sends correct auth header", async () => { mockFetchPaginated(MOCK_MONITORS); await client.getMonitors(); - const fetchMock = globalThis.fetch as ReturnType; - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + assertSpyCalls(fetchMock, 1); + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://uptime.betterstack.com/api/v2/monitors"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -154,7 +156,7 @@ describe("BetterstackClient", () => { test("follows pagination.next for multiple pages", async () => { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 diff --git a/packages/importers/src/providers/betterstack/mapper.test.ts b/packages/importers/src/providers/betterstack/mapper.test.ts index e4e23875..70dfab13 100644 --- a/packages/importers/src/providers/betterstack/mapper.test.ts +++ b/packages/importers/src/providers/betterstack/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { MOCK_INCIDENTS, diff --git a/packages/importers/src/providers/betterstack/provider.test.ts b/packages/importers/src/providers/betterstack/provider.test.ts index 9ef88f33..28aa0545 100644 --- a/packages/importers/src/providers/betterstack/provider.test.ts +++ b/packages/importers/src/providers/betterstack/provider.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { MOCK_INCIDENTS, @@ -24,7 +26,7 @@ function makePaginated(data: unknown[]) { } function setupMockFetch() { - globalThis.fetch = mock((url: string) => { + globalThis.fetch = spy((url: string) => { const path = new URL(url as string).pathname; let body: unknown; @@ -86,7 +88,7 @@ describe("BetterstackProvider", () => { }); test("validate returns friendly 401 error", async () => { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, diff --git a/packages/importers/src/providers/instatus/client.test.ts b/packages/importers/src/providers/instatus/client.test.ts index 7bdcbf17..79edfe00 100644 --- a/packages/importers/src/providers/instatus/client.test.ts +++ b/packages/importers/src/providers/instatus/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { createInstatusClient } from "./client"; import { @@ -12,7 +14,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -25,7 +27,7 @@ function mockFetch(data: unknown, status = 200) { function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -107,8 +109,8 @@ describe("InstatusClient", () => { test("sends correct Bearer auth header", async () => { mockFetchPaginated(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.instatus.com/v2/pages?page=1&per_page=100"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -124,7 +126,7 @@ describe("InstatusClient", () => { })); let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; // First call: 100 items (= per_page), second call: empty array const body = callCount === 1 ? items : []; @@ -145,8 +147,8 @@ describe("InstatusClient", () => { test("uses v1 for incidents and v2 for other endpoints", async () => { mockFetchPaginated(MOCK_INCIDENTS); await client.getIncidents("in_page_001"); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toContain("/v1/in_page_001/incidents"); }); }); diff --git a/packages/importers/src/providers/instatus/mapper.test.ts b/packages/importers/src/providers/instatus/mapper.test.ts index 8b008a57..17a95994 100644 --- a/packages/importers/src/providers/instatus/mapper.test.ts +++ b/packages/importers/src/providers/instatus/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, @@ -112,14 +113,16 @@ describe("mapComponent", () => { }); describe("mapIncidentStatus", () => { - it.each([ + for (const [input, expected] of [ ["INVESTIGATING", "investigating"], ["IDENTIFIED", "identified"], ["MONITORING", "monitoring"], ["RESOLVED", "resolved"], - ] as const)("maps %s to %s", (input, expected) => { - expect(mapIncidentStatus(input)).toBe(expected); - }); + ] as const) { + it(`maps ${input} to ${expected}`, () => { + expect(mapIncidentStatus(input)).toBe(expected); + }); + } it("defaults to investigating for unknown status", () => { expect(mapIncidentStatus("UNKNOWN")).toBe("investigating"); diff --git a/packages/importers/src/providers/instatus/provider.test.ts b/packages/importers/src/providers/instatus/provider.test.ts index 17b961e8..0b904b36 100644 --- a/packages/importers/src/providers/instatus/provider.test.ts +++ b/packages/importers/src/providers/instatus/provider.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, diff --git a/packages/importers/src/providers/statuspage/client.test.ts b/packages/importers/src/providers/statuspage/client.test.ts index d057a5b3..79b7c7fc 100644 --- a/packages/importers/src/providers/statuspage/client.test.ts +++ b/packages/importers/src/providers/statuspage/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import { createStatuspageClient } from "./client"; import { @@ -12,7 +14,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -28,7 +30,7 @@ function mockFetch(data: unknown, status = 200) { */ function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -117,8 +119,8 @@ describe("StatuspageClient", () => { test("getPage calls correct URL path", async () => { mockFetch(MOCK_PAGES[0]); await client.getPage("sp_page_001"); - const fetchMock = globalThis.fetch as ReturnType; - const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages/sp_page_001"); }); @@ -137,9 +139,9 @@ describe("StatuspageClient", () => { test("sends correct auth header", async () => { mockFetch(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as ReturnType; - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + assertSpyCalls(fetchMock, 1); + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages"); expect((options.headers as Record).Authorization).toBe( "OAuth test-api-key", diff --git a/packages/importers/src/providers/statuspage/mapper.test.ts b/packages/importers/src/providers/statuspage/mapper.test.ts index 40f162f2..07b241b1 100644 --- a/packages/importers/src/providers/statuspage/mapper.test.ts +++ b/packages/importers/src/providers/statuspage/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, @@ -125,7 +126,7 @@ describe("mapIncidentToStatusReport", () => { }); describe("mapIncidentUpdateStatus", () => { - it.each([ + for (const [input, expected] of [ ["investigating", "investigating"], ["identified", "identified"], ["monitoring", "monitoring"], @@ -134,9 +135,11 @@ describe("mapIncidentUpdateStatus", () => { ["in_progress", "investigating"], ["verifying", "monitoring"], ["completed", "resolved"], - ] as const)("maps %s to %s", (input, expected) => { - expect(mapIncidentUpdateStatus(input)).toBe(expected); - }); + ] as const) { + it(`maps ${input} to ${expected}`, () => { + expect(mapIncidentUpdateStatus(input)).toBe(expected); + }); + } }); describe("mapIncidentToMaintenance", () => { diff --git a/packages/importers/src/providers/statuspage/provider.test.ts b/packages/importers/src/providers/statuspage/provider.test.ts index c0176167..3f314f05 100644 --- a/packages/importers/src/providers/statuspage/provider.test.ts +++ b/packages/importers/src/providers/statuspage/provider.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, diff --git a/packages/locales/package.json b/packages/locales/package.json index 9a4556ff..33a91be0 100644 --- a/packages/locales/package.json +++ b/packages/locales/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "date-fns": "catalog:" }, diff --git a/packages/notifications/base/package.json b/packages/notifications/base/package.json index cd093dd2..25472b09 100644 --- a/packages/notifications/base/package.json +++ b/packages/notifications/base/package.json @@ -7,7 +7,8 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,8 +17,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/base/src/utils/duration.test.ts b/packages/notifications/base/src/utils/duration.test.ts index a89d4378..cd99abb7 100644 --- a/packages/notifications/base/src/utils/duration.test.ts +++ b/packages/notifications/base/src/utils/duration.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { calculateDuration, formatDuration } from "./duration"; diff --git a/packages/notifications/base/src/utils/incident.test.ts b/packages/notifications/base/src/utils/incident.test.ts index bfacd6a7..78b59a7c 100644 --- a/packages/notifications/base/src/utils/incident.test.ts +++ b/packages/notifications/base/src/utils/incident.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, it } from "bun:test"; - import type { Incident } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { getIncidentDuration } from "./incident"; @@ -22,7 +22,6 @@ function createIncident(overrides: Partial): Incident { describe("getIncidentDuration", () => { it("returns null when incident.startedAt is missing", () => { const incident = createIncident({ - startedAt: null, resolvedAt: new Date("2026-01-22T12:00:00Z"), }); expect(getIncidentDuration(incident)).toBe(null); diff --git a/packages/notifications/bird-whatsapp/package.json b/packages/notifications/bird-whatsapp/package.json index 98a77afb..5ea40620 100644 --- a/packages/notifications/bird-whatsapp/package.json +++ b/packages/notifications/bird-whatsapp/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/bird-whatsapp/src/index.test.ts b/packages/notifications/bird-whatsapp/src/index.test.ts index 043e81fb..ea2039ae 100644 --- a/packages/notifications/bird-whatsapp/src/index.test.ts +++ b/packages/notifications/bird-whatsapp/src/index.test.ts @@ -1,15 +1,8 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - spyOn, - test, -} from "bun:test"; - import type { Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; @@ -34,7 +27,7 @@ function createNotification() { }); } -function parseRequestBody(call: ReturnType): { +function parseRequestBody(call: Stub): { messageRequests: Array<{ receiver: { contacts: Array<{ identifierKey: string; identifierValue: string }>; @@ -47,22 +40,21 @@ function parseRequestBody(call: ReturnType): { }; }>; } { - const body = (call as ReturnType).mock.calls[0][1]?.body; + const body = call.calls[0].args[1]?.body; return JSON.parse(body as string); } describe("WhatsApp Notifications (Bird)", () => { - let fetchMock: ReturnType; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - jest.resetAllMocks(); + fetchMock.restore(); }); test("sendAlert calls Bird API with alert template", async () => { @@ -74,11 +66,11 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const url = fetchMock.mock.calls[0][0] as string; + assertSpyCalls(fetchMock, 1); + const url = fetchMock.calls[0].args[0] as string; expect(url).toMatch(BIRD_URL_PATTERN); - const options = fetchMock.mock.calls[0][1] as RequestInit; + const options = fetchMock.calls[0].args[1] as RequestInit; expect(options.headers).toHaveProperty("Authorization"); expect((options.headers as Record).Authorization).toMatch( /^AccessKey /, @@ -115,7 +107,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "2068001e-330d-4093-8d06-7071e9d34aa1", @@ -137,7 +129,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "c9a842d9-cf9e-4a13-8cde-024d57e29143", @@ -153,7 +145,7 @@ describe("WhatsApp Notifications (Bird)", () => { test("sendTest calls Bird API with test template and openstat.us URL", async () => { await sendTest({ phoneNumber: "+33623456789" }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].receiver.contacts[0].identifierValue).toBe( "+33623456789", diff --git a/packages/notifications/bird-whatsapp/tsconfig.json b/packages/notifications/bird-whatsapp/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/bird-whatsapp/tsconfig.json +++ b/packages/notifications/bird-whatsapp/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/discord/package.json b/packages/notifications/discord/package.json index 825b2786..90ff88ec 100644 --- a/packages/notifications/discord/package.json +++ b/packages/notifications/discord/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/discord/src/index.test.ts b/packages/notifications/discord/src/index.test.ts index 14169bbe..64c6ac7c 100644 --- a/packages/notifications/discord/src/index.test.ts +++ b/packages/notifications/discord/src/index.test.ts @@ -1,7 +1,8 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLOR_DECIMALS } from "@openstatus/notification-base"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, @@ -10,20 +11,18 @@ import { sendTestDiscordMessage, } from "./index"; +const ok = (): Promise => + Promise.resolve(new Response(null, { status: 200 })); + describe("Discord Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock = stub(globalThis, "fetch", ok); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -63,8 +62,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://discord.com/api/webhooks/123456789/abcdefgh", ); @@ -95,8 +94,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is recovered"); @@ -119,8 +118,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is degraded"); @@ -132,8 +131,8 @@ describe("Discord Notifications", () => { const webhookUrl = "https://discord.com/api/webhooks/123456789/abcdefgh"; await sendTestDiscordMessage(webhookUrl); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); @@ -142,11 +141,12 @@ describe("Discord Notifications", () => { test("Send Test Discord Message with empty webhookUrl", async () => { expect(sendTestDiscordMessage("")).rejects.toThrow(); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/discord/tsconfig.json b/packages/notifications/discord/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/discord/tsconfig.json +++ b/packages/notifications/discord/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/email/package.json b/packages/notifications/email/package.json index 7aee8b5b..6078ce1a 100644 --- a/packages/notifications/email/package.json +++ b/packages/notifications/email/package.json @@ -4,7 +4,8 @@ "description": "Log drains Vercel integration.", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -20,10 +21,10 @@ "zod": "catalog:" }, "devDependencies": { + "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", "@types/node": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/email/src/index.test.ts b/packages/notifications/email/src/index.test.ts index 16b88c71..7ea2c2a0 100644 --- a/packages/notifications/email/src/index.test.ts +++ b/packages/notifications/email/src/index.test.ts @@ -1,26 +1,31 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; - +import "./test-preload.ts"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { EmailClient } from "@openstatus/emails/src/client"; +import { + afterEach, + assertSpyCalls, + beforeEach, + describe, + expect, + type Stub, + stub, + test, +} from "@openstatus/test-utils"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; -const sendMonitorAlertMock = mock(async (_callArgs) => {}); - -mock.module("@openstatus/emails/src/client", () => ({ - EmailClient: mock((_args: { apiKey: string }) => { - return { - sendMonitorAlert: sendMonitorAlertMock, - }; - }), -})); +// biome-ignore lint/suspicious/noExplicitAny: stub over the EmailClient method +let sendMonitorAlertMock: Stub; describe("Email Notifications", () => { beforeEach(() => { - sendMonitorAlertMock.mockClear(); + sendMonitorAlertMock = stub(EmailClient.prototype, "sendMonitorAlert", () => + Promise.resolve(), + ); }); afterEach(() => { - sendMonitorAlertMock.mockClear(); + sendMonitorAlertMock.restore(); }); const createMockMonitor = () => ({ @@ -62,8 +67,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.name).toBe("API Health Check"); expect(callArgs.type).toBe("alert"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -88,8 +93,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.status).toBeUndefined(); expect(callArgs.latency).toBe("N/A"); expect(callArgs.region).toBe("N/A"); @@ -111,8 +116,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("recovery"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -137,8 +142,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("degraded"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.status).toBe("503"); @@ -166,6 +171,6 @@ describe("Email Notifications", () => { }); // Should not call sendMonitorAlert when data is invalid - expect(sendMonitorAlertMock).not.toHaveBeenCalled(); + assertSpyCalls(sendMonitorAlertMock, 0); }); }); diff --git a/packages/notifications/email/src/test-preload.ts b/packages/notifications/email/src/test-preload.ts new file mode 100644 index 00000000..3e4c5cf3 --- /dev/null +++ b/packages/notifications/email/src/test-preload.ts @@ -0,0 +1,10 @@ +/** + * Test env setup. Import this FIRST so env vars are set before module-level + * env validations fire on import. + * + * Bun's test runner set NODE_ENV=test automatically; Deno does not. This + * package's env skips validation when NODE_ENV=test, and @openstatus/emails + * validates RESEND_API_KEY at module load. + */ +process.env.NODE_ENV = "test"; +process.env.RESEND_API_KEY ??= "test-key"; diff --git a/packages/notifications/email/tsconfig.json b/packages/notifications/email/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/email/tsconfig.json +++ b/packages/notifications/email/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/google-chat/package.json b/packages/notifications/google-chat/package.json index f9669749..005737cf 100644 --- a/packages/notifications/google-chat/package.json +++ b/packages/notifications/google-chat/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/google-chat/src/index.test.ts b/packages/notifications/google-chat/src/index.test.ts index 1696d2db..6a84bffd 100644 --- a/packages/notifications/google-chat/src/index.test.ts +++ b/packages/notifications/google-chat/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Google Chat Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -57,8 +55,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://google.com/api/webhooks/123456789/abcdefgh", ); @@ -87,8 +85,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("✅ Recovered"); expect(body.text).toContain("API Health Check"); @@ -109,8 +107,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("⚠️ Degraded"); expect(body.text).toContain("API Health Check"); @@ -122,8 +120,8 @@ describe("Google Chat Notifications", () => { const result = await sendTest(webhookUrl); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("🧪 Test"); @@ -134,11 +132,12 @@ describe("Google Chat Notifications", () => { const result = await sendTest(""); expect(result).toBe(false); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/google-chat/tsconfig.json b/packages/notifications/google-chat/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/google-chat/tsconfig.json +++ b/packages/notifications/google-chat/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/grafana-oncall/package.json b/packages/notifications/grafana-oncall/package.json index cc53a521..d68ea6c9 100644 --- a/packages/notifications/grafana-oncall/package.json +++ b/packages/notifications/grafana-oncall/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/grafana-oncall/src/index.test.ts b/packages/notifications/grafana-oncall/src/index.test.ts index 824a02df..5676f5c7 100644 --- a/packages/notifications/grafana-oncall/src/index.test.ts +++ b/packages/notifications/grafana-oncall/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Grafana OnCall Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -57,8 +55,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -89,8 +87,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.message).toBe("Status code: 503"); }); @@ -110,8 +108,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -138,8 +136,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -158,8 +156,8 @@ describe("Grafana OnCall Notifications", () => { const result = await sendTest({ webhookUrl }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); expect(callArgs[1].method).toBe("POST"); @@ -172,7 +170,8 @@ describe("Grafana OnCall Notifications", () => { }); test("Send Test returns false on network error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -181,11 +180,12 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on non-ok response", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 401 })), ); @@ -194,11 +194,12 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Alert throws on non-ok response", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.resolve( new Response(null, { status: 500, @@ -225,7 +226,8 @@ describe("Grafana OnCall Notifications", () => { }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -234,7 +236,7 @@ describe("Grafana OnCall Notifications", () => { createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -245,6 +247,6 @@ describe("Grafana OnCall Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/grafana-oncall/tsconfig.json b/packages/notifications/grafana-oncall/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/grafana-oncall/tsconfig.json +++ b/packages/notifications/grafana-oncall/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/ms-teams/package.json b/packages/notifications/ms-teams/package.json index 1e4244f2..02dd24a6 100644 --- a/packages/notifications/ms-teams/package.json +++ b/packages/notifications/ms-teams/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ms-teams/src/index.test.ts b/packages/notifications/ms-teams/src/index.test.ts index 18c7b6d7..6baccbba 100644 --- a/packages/notifications/ms-teams/src/index.test.ts +++ b/packages/notifications/ms-teams/src/index.test.ts @@ -1,11 +1,12 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import type { Incident, Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; -type FetchMock = ReturnType>; +type FetchMock = Stub; type AdaptiveCardElement = { type: string; @@ -41,14 +42,13 @@ describe("Microsoft Teams Notifications", () => { let fetchMock: FetchMock; beforeEach(() => { - // @ts-expect-error spyOn typing requires the full `typeof fetch` (incl. preconnect) - fetchMock = spyOn(globalThis, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.mockRestore(); + fetchMock.restore(); }); const createMockMonitor = (): Monitor => ({ @@ -114,8 +114,8 @@ describe("Microsoft Teams Notifications", () => { }); const readMessagePayload = (): MessagePayload => { - const calls = fetchMock.mock.calls; - const init = calls[0][1]; + const calls = fetchMock.calls; + const init = calls[0].args[1]; if (!init || typeof init.body !== "string") { throw new Error("expected string body"); } @@ -169,8 +169,8 @@ describe("Microsoft Teams Notifications", () => { regions: ["iad"], }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(String(url)).toContain("logic.azure.com"); expect(init?.method).toBe("POST"); @@ -302,7 +302,7 @@ describe("Microsoft Teams Notifications", () => { "https://prod-00.westeurope.logic.azure.com:443/workflows/test/triggers/manual/paths/invoke", }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const card = getCard(readMessagePayload()); const header = findContainerByStyle(card, "good"); expect(header?.items?.[0]?.text).toBe("Test notification"); @@ -311,12 +311,12 @@ describe("Microsoft Teams Notifications", () => { test("Send Test with empty webhookUrl", async () => { await expect(sendTest({ webhookUrl: "" })).rejects.toThrow(); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error", async () => { - // @ts-expect-error see beforeEach - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/ms-teams/tsconfig.json b/packages/notifications/ms-teams/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/ms-teams/tsconfig.json +++ b/packages/notifications/ms-teams/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/ntfy/package.json b/packages/notifications/ntfy/package.json index 4d6230d4..da39ed21 100644 --- a/packages/notifications/ntfy/package.json +++ b/packages/notifications/ntfy/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ntfy/src/index.test.ts b/packages/notifications/ntfy/src/index.test.ts index f7a61d85..a46f9284 100644 --- a/packages/notifications/ntfy/src/index.test.ts +++ b/packages/notifications/ntfy/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Ntfy Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -72,8 +70,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.sh/my-topic"); expect(callArgs[1].method).toBe("post"); expect(callArgs[1].body).toContain("API Health Check"); @@ -96,8 +94,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.example.com/my-topic"); }); @@ -116,8 +114,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -135,8 +133,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("error: Connection timeout"); }); @@ -155,8 +153,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("is up again"); }); @@ -173,8 +171,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -193,8 +191,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("is degraded"); }); @@ -204,8 +202,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.sh/test-topic"); expect(callArgs[1].body).toBe("This is a test message from OpenStatus"); expect(callArgs[1].headers).not.toHaveProperty("Authorization"); @@ -218,8 +216,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.example.com/test-topic"); }); @@ -230,13 +228,14 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -257,11 +256,12 @@ describe("Ntfy Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -270,6 +270,6 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/ntfy/tsconfig.json b/packages/notifications/ntfy/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/ntfy/tsconfig.json +++ b/packages/notifications/ntfy/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/opsgenie/package.json b/packages/notifications/opsgenie/package.json index 678250f3..087a5e76 100644 --- a/packages/notifications/opsgenie/package.json +++ b/packages/notifications/opsgenie/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,10 +17,11 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/opsgenie/src/index.test.ts b/packages/notifications/opsgenie/src/index.test.ts index 00ff9824..ba678823 100644 --- a/packages/notifications/opsgenie/src/index.test.ts +++ b/packages/notifications/opsgenie/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendTest } from "./index"; describe("OpsGenie Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -75,8 +73,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://api.opsgenie.com/v2/alerts"); expect(callArgs[1].method).toBe("POST"); expect(callArgs[1].headers["Content-Type"]).toBe("application/json"); @@ -107,8 +105,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://api.eu.opsgenie.com/v2/alerts"); }); @@ -129,15 +127,16 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.details.severity).toBe("degraded"); expect(body.message).toBe("API Health Check is degraded"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -159,11 +158,12 @@ describe("OpsGenie Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -173,6 +173,6 @@ describe("OpsGenie Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/opsgenie/tsconfig.json b/packages/notifications/opsgenie/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/opsgenie/tsconfig.json +++ b/packages/notifications/opsgenie/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/pagerduty/package.json b/packages/notifications/pagerduty/package.json index d242877d..7fc66f4a 100644 --- a/packages/notifications/pagerduty/package.json +++ b/packages/notifications/pagerduty/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,10 +17,11 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/pagerduty/src/index.test.ts b/packages/notifications/pagerduty/src/index.test.ts index 840cb57d..a1a94b33 100644 --- a/packages/notifications/pagerduty/src/index.test.ts +++ b/packages/notifications/pagerduty/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("PagerDuty Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -70,8 +68,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -109,9 +107,9 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(2); - expect(fetchMock.mock.calls[0][1].body).toContain("key1"); - expect(fetchMock.mock.calls[1][1].body).toContain("key2"); + assertSpyCalls(fetchMock, 2); + expect(fetchMock.calls[0].args[1].body).toContain("key1"); + expect(fetchMock.calls[1].args[1].body).toContain("key2"); }); test("Send Degraded", async () => { @@ -132,8 +130,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.payload.summary).toBe("API Health Check is degraded"); expect(body.payload.severity).toBe("warning"); @@ -158,8 +156,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); const body = JSON.parse(callArgs[1].body); expect(body.routing_key).toBe("my_key"); @@ -173,8 +171,8 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -188,7 +186,8 @@ describe("PagerDuty Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -197,11 +196,12 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -224,6 +224,6 @@ describe("PagerDuty Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/pagerduty/tsconfig.json b/packages/notifications/pagerduty/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/pagerduty/tsconfig.json +++ b/packages/notifications/pagerduty/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/slack/package.json b/packages/notifications/slack/package.json index 66b0aee6..e63632c0 100644 --- a/packages/notifications/slack/package.json +++ b/packages/notifications/slack/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/slack/src/index.test.ts b/packages/notifications/slack/src/index.test.ts index aa16993f..4fe9de09 100644 --- a/packages/notifications/slack/src/index.test.ts +++ b/packages/notifications/slack/src/index.test.ts @@ -1,7 +1,8 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLORS } from "@openstatus/notification-base"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, @@ -11,19 +12,16 @@ import { } from "./index"; describe("Slack Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -63,8 +61,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://hooks.slack.com/services/url"); expect(callArgs[1].method).toBe("POST"); @@ -90,8 +88,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments[0].color).toBe(COLORS.red); expect(body.attachments[0].blocks[3].fields[0].text).toContain("Unknown"); @@ -112,8 +110,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.green); @@ -135,8 +133,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.yellow); @@ -148,8 +146,8 @@ describe("Slack Notifications", () => { await sendTestSlackMessage(webhookUrl); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); @@ -159,16 +157,18 @@ describe("Slack Notifications", () => { }); test("Send Test Slack Message throws error on empty webhookUrl", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); expect(sendTestSlackMessage("")).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(0); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -177,8 +177,7 @@ describe("Slack Notifications", () => { createMockNotification(), ); - // Should not throw - function catches errors internally - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -189,6 +188,6 @@ describe("Slack Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/slack/tsconfig.json b/packages/notifications/slack/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/slack/tsconfig.json +++ b/packages/notifications/slack/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/telegram/package.json b/packages/notifications/telegram/package.json index 13f66b1e..0e907adc 100644 --- a/packages/notifications/telegram/package.json +++ b/packages/notifications/telegram/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -13,8 +14,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/telegram/src/index.test.ts b/packages/notifications/telegram/src/index.test.ts index 93e56e31..805cec19 100644 --- a/packages/notifications/telegram/src/index.test.ts +++ b/packages/notifications/telegram/src/index.test.ts @@ -1,29 +1,27 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Telegram Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; const originalEnv = process.env.TELEGRAM_BOT_TOKEN; beforeEach(() => { process.env.TELEGRAM_BOT_TOKEN = "test-bot-token-123"; - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); if (originalEnv) { process.env.TELEGRAM_BOT_TOKEN = originalEnv; } else { - process.env.TELEGRAM_BOT_TOKEN = undefined; + delete process.env.TELEGRAM_BOT_TOKEN; } }); @@ -68,8 +66,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -91,8 +89,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("error: Connection timeout"); }); @@ -111,8 +109,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("is up again"); }); @@ -131,8 +129,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("is degraded"); }); @@ -142,8 +140,8 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -152,7 +150,8 @@ describe("Telegram Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -161,11 +160,12 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -174,7 +174,7 @@ describe("Telegram Notifications", () => { createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -185,18 +185,18 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("fetch not called when TELEGRAM_BOT_TOKEN is not set", async () => { - process.env.TELEGRAM_BOT_TOKEN = undefined; + delete process.env.TELEGRAM_BOT_TOKEN; const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -207,6 +207,6 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); // Should not call fetch when token is missing - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); }); diff --git a/packages/notifications/telegram/tsconfig.json b/packages/notifications/telegram/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/telegram/tsconfig.json +++ b/packages/notifications/telegram/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/twillio-sms/package.json b/packages/notifications/twillio-sms/package.json index 90199e77..74f26cc0 100644 --- a/packages/notifications/twillio-sms/package.json +++ b/packages/notifications/twillio-sms/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -15,9 +16,10 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/validator": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/twillio-sms/src/index.test.ts b/packages/notifications/twillio-sms/src/index.test.ts index 12e3c25c..21b334ca 100644 --- a/packages/notifications/twillio-sms/src/index.test.ts +++ b/packages/notifications/twillio-sms/src/index.test.ts @@ -1,11 +1,12 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; describe("Twilio SMS Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; const originalEnv = { TWILLIO_ACCOUNT_ID: process.env.TWILLIO_ACCOUNT_ID, TWILLIO_AUTH_TOKEN: process.env.TWILLIO_AUTH_TOKEN, @@ -14,16 +15,13 @@ describe("Twilio SMS Notifications", () => { beforeEach(() => { process.env.TWILLIO_ACCOUNT_ID = "test-account-id"; process.env.TWILLIO_AUTH_TOKEN = "test-auth-token"; - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); if (originalEnv.TWILLIO_ACCOUNT_ID) { process.env.TWILLIO_ACCOUNT_ID = originalEnv.TWILLIO_ACCOUNT_ID; } else { @@ -73,8 +71,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://api.twilio.com/2010-04-01/Accounts/test-account-id/Messages.json", ); @@ -104,8 +102,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("error: Connection timeout"); }); @@ -125,8 +123,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is up again"); expect(formData.get("Body")).toContain("API Health Check"); @@ -147,15 +145,16 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is degraded"); expect(formData.get("Body")).toContain("API Health Check"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -175,6 +174,6 @@ describe("Twilio SMS Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/twillio-sms/tsconfig.json b/packages/notifications/twillio-sms/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/twillio-sms/tsconfig.json +++ b/packages/notifications/twillio-sms/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/webhook/package.json b/packages/notifications/webhook/package.json index dca6d651..bb543a27 100644 --- a/packages/notifications/webhook/package.json +++ b/packages/notifications/webhook/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/webhook/src/index.test.ts b/packages/notifications/webhook/src/index.test.ts index ca5d0d63..f0000ee1 100644 --- a/packages/notifications/webhook/src/index.test.ts +++ b/packages/notifications/webhook/src/index.test.ts @@ -1,31 +1,35 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendTest } from "./index"; describe("Webhook sendTest", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - fetchMock = spyOn(global, "fetch"); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockClear(); - fetchMock.mockRestore(); - } + fetchMock.restore(); }); test("should send test webhook successfully", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith( - url, + assertSpyCalls(fetchMock, 1); + expect(fetchMock.calls[0].args[0]).toBe(url); + expect(fetchMock.calls[0].args[1]).toEqual( expect.objectContaining({ method: "post", body: expect.any(String), @@ -33,7 +37,7 @@ describe("Webhook sendTest", () => { }), ); - const callArgs = fetchMock.mock.calls[0]; + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body).toMatchObject({ monitor: { @@ -45,7 +49,7 @@ describe("Webhook sendTest", () => { statusCode: 200, latency: 1337, }); - expect(body.cronTimestamp).toBeTypeOf("number"); + expect(typeof body.cronTimestamp).toBe("number"); }); test("should send test webhook with headers", async () => { @@ -54,14 +58,17 @@ describe("Webhook sendTest", () => { { key: "Authorization", value: "Bearer token123" }, { key: "Content-Type", value: "application/json" }, ]; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url, headers }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith( - url, + assertSpyCalls(fetchMock, 1); + expect(fetchMock.calls[0].args[0]).toBe(url); + expect(fetchMock.calls[0].args[1]).toEqual( expect.objectContaining({ method: "post", body: expect.any(String), @@ -75,50 +82,63 @@ describe("Webhook sendTest", () => { test("should throw error when response is not ok", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 400 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 400 })), + ); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should throw error when fetch fails", async () => { const url = "https://example.com/webhook"; const networkError = new Error("Network error"); - fetchMock.mockRejectedValue(networkError); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(networkError)); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should send test webhook with empty headers array", async () => { const url = "https://example.com/webhook"; const headers: { key: string; value: string }[] = []; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url, headers }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; // Empty headers array should still include Content-Type expect(callArgs[1].headers).toEqual({ "Content-Type": "application/json" }); }); test("should send test webhook with 500 status code", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 500 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 500 })), + ); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should send test webhook with 201 status code (success)", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 201 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 201 })), + ); const result = await sendTest({ url }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/proto/package.json b/packages/proto/package.json index 72bff34e..a9773b68 100644 --- a/packages/proto/package.json +++ b/packages/proto/package.json @@ -35,6 +35,7 @@ } }, "scripts": { + "check": "deno check --sloppy-imports .", "buf:openapi": "buf generate --path api/openstatus --template buf.gen.openapi.yaml && bun scripts/clean-openapi.ts", "buf:ts": "buf generate --path api/openstatus --template buf.gen.ts.yaml", "buf:go": "buf generate --path internal/private_location --template buf.gen.go.yaml", @@ -45,7 +46,7 @@ "dependencies": { "@bufbuild/protobuf": "catalog:", "@bufbuild/protovalidate": "catalog:", - "@connectrpc/connect": "^2.1.1" + "@connectrpc/connect": "catalog:" }, "devDependencies": { "@bufbuild/buf": "catalog:", diff --git a/packages/regions/package.json b/packages/regions/package.json index eef4b0cd..0754493e 100644 --- a/packages/regions/package.json +++ b/packages/regions/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "zod": "catalog:" }, diff --git a/packages/services/package.json b/packages/services/package.json index 74d25542..7a863399 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -127,7 +127,8 @@ } }, "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -145,7 +146,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/services/src/__tests__/retry.test.ts b/packages/services/src/__tests__/retry.test.ts index 9f26dcaa..ada57ea1 100644 --- a/packages/services/src/__tests__/retry.test.ts +++ b/packages/services/src/__tests__/retry.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { NotFoundError } from "../errors"; import { diff --git a/packages/services/src/__tests__/with-test-transaction.test.ts b/packages/services/src/__tests__/with-test-transaction.test.ts index 68fc513c..cb9a1f64 100644 --- a/packages/services/src/__tests__/with-test-transaction.test.ts +++ b/packages/services/src/__tests__/with-test-transaction.test.ts @@ -1,7 +1,7 @@ -import { afterAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { auditLog } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { withTestTransaction } from "../../test/helpers"; diff --git a/packages/services/src/__tests__/with-transaction.test.ts b/packages/services/src/__tests__/with-transaction.test.ts index 1bb9c477..aa86f019 100644 --- a/packages/services/src/__tests__/with-transaction.test.ts +++ b/packages/services/src/__tests__/with-transaction.test.ts @@ -1,4 +1,5 @@ -import { beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { loadSeededWorkspace } from "../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/docs.test.ts b/packages/services/src/agent-tools/__tests__/docs.test.ts index 039400c3..63f50d31 100644 --- a/packages/services/src/agent-tools/__tests__/docs.test.ts +++ b/packages/services/src/agent-tools/__tests__/docs.test.ts @@ -1,4 +1,6 @@ -import { afterEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import type { ServiceContext } from "../../context"; import { getDocPageTool, searchDocsTool } from "../docs"; @@ -13,7 +15,7 @@ afterEach(() => { }); function mockFetch(response: Response) { - const fn = mock(async () => response); + const fn = spy(async () => response); globalThis.fetch = fn as unknown as typeof fetch; return fn; } @@ -111,9 +113,11 @@ describe("get_doc_page", () => { }); expect(result.truncated).toBe(true); expect(result.markdown.length).toBeLessThan(24_200); - expect(result.markdown).toEndWith( - "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", - ); + expect( + result.markdown.endsWith( + "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", + ), + ).toBe(true); }); test("returns error shape on 404", async () => { @@ -149,6 +153,6 @@ describe("get_doc_page", () => { ); expect(getDocPageTool.outputSchema.safeParse(result).success).toBe(true); } - expect(fn).not.toHaveBeenCalled(); + assertSpyCalls(fn, 0); }); }); diff --git a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts index c6bfd1b3..ae1a50e6 100644 --- a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts +++ b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts @@ -1,4 +1,5 @@ -import { beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { loadSeededWorkspace, makeUserCtx } from "../../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts index dd21661c..cb0f7c38 100644 --- a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts +++ b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts @@ -1,6 +1,6 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/api-key/__tests__/api-key.test.ts b/packages/services/src/api-key/__tests__/api-key.test.ts index e401e304..7a199c8b 100644 --- a/packages/services/src/api-key/__tests__/api-key.test.ts +++ b/packages/services/src/api-key/__tests__/api-key.test.ts @@ -1,15 +1,8 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { apiKey } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; -import { - createApiKey, - listApiKeys, - revokeApiKey, - updateApiKeyLastUsed, - verifyApiKey, -} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -21,6 +14,13 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError, NotFoundError } from "../../errors"; +import { + createApiKey, + listApiKeys, + revokeApiKey, + updateApiKeyLastUsed, + verifyApiKey, +} from "../index.ts"; const TEST_PREFIX = "svc-apikey-test"; diff --git a/packages/services/src/audit/__tests__/audit.test.ts b/packages/services/src/audit/__tests__/audit.test.ts index 016e8d83..de082c72 100644 --- a/packages/services/src/audit/__tests__/audit.test.ts +++ b/packages/services/src/audit/__tests__/audit.test.ts @@ -1,8 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { auditLog, user } from "@openstatus/db/src/schema"; import type { AuditEntry } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/auth/__tests__/matches-scope.test.ts b/packages/services/src/auth/__tests__/matches-scope.test.ts index de72ef4e..0a70f475 100644 --- a/packages/services/src/auth/__tests__/matches-scope.test.ts +++ b/packages/services/src/auth/__tests__/matches-scope.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Scope } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchesScope } from "../matches-scope"; diff --git a/packages/services/src/auth/__tests__/require-scope.test.ts b/packages/services/src/auth/__tests__/require-scope.test.ts index 0278626b..cd46a176 100644 --- a/packages/services/src/auth/__tests__/require-scope.test.ts +++ b/packages/services/src/auth/__tests__/require-scope.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { Actor, ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; diff --git a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts index 08324142..e8062d01 100644 --- a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts +++ b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts @@ -1,11 +1,11 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { and, db, eq, like } from "@openstatus/db"; import type { ApiConfigType } from "@openstatus/db/src/schema"; import { externalService, externalServiceComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { getExternalComponentBySlug, diff --git a/packages/services/src/external-service-component/__tests__/internal.test.ts b/packages/services/src/external-service-component/__tests__/internal.test.ts index f219bb83..7b304e95 100644 --- a/packages/services/src/external-service-component/__tests__/internal.test.ts +++ b/packages/services/src/external-service-component/__tests__/internal.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { assignComponentSlugs, slugifyComponentName } from "../internal"; diff --git a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts index 5134ddde..66ddc5a0 100644 --- a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts +++ b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts @@ -1,10 +1,10 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { and, db, eq, like } from "@openstatus/db"; import { externalService, externalServiceIncident, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { type UpsertExternalIncidentInput, diff --git a/packages/services/src/external-service-report/__tests__/record.test.ts b/packages/services/src/external-service-report/__tests__/record.test.ts index 43a9524c..853831f7 100644 --- a/packages/services/src/external-service-report/__tests__/record.test.ts +++ b/packages/services/src/external-service-report/__tests__/record.test.ts @@ -1,11 +1,11 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { db, eq, inArray, like } from "@openstatus/db"; import { externalService, externalServiceComponent, externalServiceReport, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { NotFoundError } from "../../errors"; import { diff --git a/packages/services/src/external-service/__tests__/external-service.test.ts b/packages/services/src/external-service/__tests__/external-service.test.ts index dccf7991..6dc0c897 100644 --- a/packages/services/src/external-service/__tests__/external-service.test.ts +++ b/packages/services/src/external-service/__tests__/external-service.test.ts @@ -1,7 +1,7 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { db, like, sql } from "@openstatus/db"; import { externalService } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { ConflictError } from "../../errors"; import { assertSlugAvailable } from "../internal"; diff --git a/packages/services/src/import/__tests__/incidents-phase.test.ts b/packages/services/src/import/__tests__/incidents-phase.test.ts index 7070bc57..64d2b6d6 100644 --- a/packages/services/src/import/__tests__/incidents-phase.test.ts +++ b/packages/services/src/import/__tests__/incidents-phase.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { page, @@ -10,6 +8,8 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import type { PhaseResult } from "@openstatus/importers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/import/__tests__/unit.test.ts b/packages/services/src/import/__tests__/unit.test.ts index b7f14668..ad3b74cf 100644 --- a/packages/services/src/import/__tests__/unit.test.ts +++ b/packages/services/src/import/__tests__/unit.test.ts @@ -1,10 +1,10 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; import type { Limits } from "@openstatus/db/src/schema/plan/schema"; import type { ImportSummary } from "@openstatus/importers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { addLimitWarnings, clampPeriodicity, computePhaseStatus } from "../"; import { withTestTransaction } from "../../../test/helpers"; diff --git a/packages/services/src/incident/__tests__/incident.test.ts b/packages/services/src/incident/__tests__/incident.test.ts index 0b27432c..ae0eec54 100644 --- a/packages/services/src/incident/__tests__/incident.test.ts +++ b/packages/services/src/incident/__tests__/incident.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/integration/__tests__/install-slack-agent.test.ts b/packages/services/src/integration/__tests__/install-slack-agent.test.ts index 7092a8bf..ddbfa877 100644 --- a/packages/services/src/integration/__tests__/install-slack-agent.test.ts +++ b/packages/services/src/integration/__tests__/install-slack-agent.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, desc, eq } from "@openstatus/db"; import { integration } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -238,9 +238,9 @@ describe("installSlackAgent", () => { // shape as create/update — proves delete-path symmetry. const deleteRow = all.find((r) => r.action === "integration.delete"); expect( - (deleteRow?.before as Record | null) + typeof (deleteRow?.before as Record | null) ?.credentialFingerprint, - ).toBeTypeOf("string"); + ).toBe("string"); }); }); diff --git a/packages/services/src/invitation/__tests__/invitation.test.ts b/packages/services/src/invitation/__tests__/invitation.test.ts index 8309e1b3..58ff3132 100644 --- a/packages/services/src/invitation/__tests__/invitation.test.ts +++ b/packages/services/src/invitation/__tests__/invitation.test.ts @@ -1,15 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { invitation, user, usersToWorkspaces } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { - acceptInvitation, - createInvitation, - deleteInvitation, - getInvitationByToken, - listInvitations, -} from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -27,6 +20,13 @@ import { LimitExceededError, NotFoundError, } from "../../errors"; +import { + acceptInvitation, + createInvitation, + deleteInvitation, + getInvitationByToken, + listInvitations, +} from "../index.ts"; const TEST_PREFIX = "svc-inv-test"; diff --git a/packages/services/src/maintenance/__tests__/maintenance.test.ts b/packages/services/src/maintenance/__tests__/maintenance.test.ts index c7a8890c..32afbbba 100644 --- a/packages/services/src/maintenance/__tests__/maintenance.test.ts +++ b/packages/services/src/maintenance/__tests__/maintenance.test.ts @@ -1,18 +1,17 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { maintenancesToPageComponents, page, pageComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/member/__tests__/member.test.ts b/packages/services/src/member/__tests__/member.test.ts index a682723a..305d8885 100644 --- a/packages/services/src/member/__tests__/member.test.ts +++ b/packages/services/src/member/__tests__/member.test.ts @@ -1,9 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { user, usersToWorkspaces } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { deleteMember, listMembers } from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -23,6 +22,7 @@ import { NotFoundError, PreconditionFailedError, } from "../../errors"; +import { deleteMember, listMembers } from "../index.ts"; const OWNER_USER_ID = 1; const VICTIM_USER_ID = 4242; diff --git a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts index 26238ff7..121cbe4a 100644 --- a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts +++ b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts @@ -1,9 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitorTag } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { listMonitorTags, syncMonitorTags } from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { clearAuditLog, @@ -15,6 +14,7 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; +import { listMonitorTags, syncMonitorTags } from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/src/monitor/__tests__/monitor.test.ts b/packages/services/src/monitor/__tests__/monitor.test.ts index 9979ea2f..d8af1b46 100644 --- a/packages/services/src/monitor/__tests__/monitor.test.ts +++ b/packages/services/src/monitor/__tests__/monitor.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -7,15 +5,15 @@ import { monitorTagsToMonitors, notification, notificationsToMonitors, + selectWorkspaceSchema, + workspace, } from "@openstatus/db/src/schema"; +import { createWorkspace } from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { - SEEDED_WORKSPACE_FREE_ID, - SEEDED_WORKSPACE_TEAM_ID, -} from "../../../test/fixtures"; import { expectAuditRow, - loadSeededWorkspace, makeApiKeyCtx, makeSystemCtx, makeUserCtx, @@ -35,12 +33,18 @@ const TEST_PREFIX = "svc-monitor-test"; let teamCtx: ServiceContext; let freeCtx: ServiceContext; +let teamWorkspaceId: number; +let freeWorkspaceId: number; let testTagId: number; let testNotificationId: number; beforeAll(async () => { - const team = await loadSeededWorkspace(SEEDED_WORKSPACE_TEAM_ID); - const free = await loadSeededWorkspace(SEEDED_WORKSPACE_FREE_ID); + // Own workspaces per suite — relying on the shared seeded workspace races + // sibling suites that wipe its tags/notifications (e.g. monitor-tag). + const team = selectWorkspaceSchema.parse(await createWorkspace()); + const free = selectWorkspaceSchema.parse(await createWorkspace()); + teamWorkspaceId = team.id; + freeWorkspaceId = free.id; teamCtx = makeUserCtx(team, { userId: 1 }); freeCtx = makeUserCtx(free, { userId: 2 }); @@ -77,6 +81,10 @@ afterAll(async () => { .delete(notification) .where(eq(notification.id, testNotificationId)) .catch(() => undefined); + await db + .delete(workspace) + .where(inArray(workspace.id, [teamWorkspaceId, freeWorkspaceId])) + .catch(() => undefined); }); describe("createMonitor", () => { diff --git a/packages/services/src/monitor/__tests__/reads.test.ts b/packages/services/src/monitor/__tests__/reads.test.ts index ef90d9cb..ba2b25f0 100644 --- a/packages/services/src/monitor/__tests__/reads.test.ts +++ b/packages/services/src/monitor/__tests__/reads.test.ts @@ -1,6 +1,6 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { monitorStatusTable } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts index 431a9302..0a54da72 100644 --- a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts +++ b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -66,11 +67,13 @@ describe("streamMonitorPreview", () => { input: { monitorId: 999_999_999 }, }); - await expect(async () => { - for await (const _ of generator) { - // drain - } - }).toThrow(NotFoundError); + await expect( + (async () => { + for await (const _ of generator) { + // drain + } + })(), + ).rejects.toThrow(NotFoundError); }); }); diff --git a/packages/services/src/notification/__tests__/notification.test.ts b/packages/services/src/notification/__tests__/notification.test.ts index afd4c311..5082f971 100644 --- a/packages/services/src/notification/__tests__/notification.test.ts +++ b/packages/services/src/notification/__tests__/notification.test.ts @@ -1,11 +1,11 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts index 02db33a0..10a2f088 100644 --- a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts +++ b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { maintenance, maintenancesToPageComponents, @@ -11,6 +9,8 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/page-component/__tests__/page-component.test.ts b/packages/services/src/page-component/__tests__/page-component.test.ts index 119c6952..447099d2 100644 --- a/packages/services/src/page-component/__tests__/page-component.test.ts +++ b/packages/services/src/page-component/__tests__/page-component.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -7,6 +5,8 @@ import { pageComponent, pageComponentGroup, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts index abbfd66c..3fa02a4c 100644 --- a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts +++ b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts @@ -1,13 +1,3 @@ -import { - afterAll, - afterEach, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { auditLog, @@ -15,16 +5,16 @@ import { pageSubscriber, pageSubscriberToPageComponent, } from "@openstatus/db/src/schema"; - +import { expect } from "@std/expect"; import { - createPageSubscriber, - getSubscriberByToken, - hasPendingSubscriber, - unsubscribeSubscriber, - updateSubscriberScope, - upsertSelfSignupSubscriber, - verifySelfSignupSubscriber, -} from ".."; + afterAll, + afterEach, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; + import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -38,6 +28,15 @@ import { withTestTransaction, } from "../../../test/helpers"; import { ForbiddenError } from "../../errors"; +import { + createPageSubscriber, + getSubscriberByToken, + hasPendingSubscriber, + unsubscribeSubscriber, + updateSubscriberScope, + upsertSelfSignupSubscriber, + verifySelfSignupSubscriber, +} from "../index.ts"; // Seeded data we lean on (see packages/db/src/seed.mts): // workspace 1 = team plan, has status-subscribers=true diff --git a/packages/services/src/page/__tests__/page.test.ts b/packages/services/src/page/__tests__/page.test.ts index 429f682d..fd8673da 100644 --- a/packages/services/src/page/__tests__/page.test.ts +++ b/packages/services/src/page/__tests__/page.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/status-report/__tests__/status-report.test.ts b/packages/services/src/status-report/__tests__/status-report.test.ts index fb7bab4d..7104b8d1 100644 --- a/packages/services/src/status-report/__tests__/status-report.test.ts +++ b/packages/services/src/status-report/__tests__/status-report.test.ts @@ -1,12 +1,3 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, @@ -17,6 +8,14 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/workspace/__tests__/workspace.test.ts b/packages/services/src/workspace/__tests__/workspace.test.ts index 21dde2ae..6efc00f5 100644 --- a/packages/services/src/workspace/__tests__/workspace.test.ts +++ b/packages/services/src/workspace/__tests__/workspace.test.ts @@ -1,14 +1,8 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { workspace } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; -import { - getWorkspace, - getWorkspaceWithUsage, - listWorkspaces, - updateWorkspaceName, -} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -19,6 +13,12 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; +import { + getWorkspace, + getWorkspaceWithUsage, + listWorkspaces, + updateWorkspaceName, +} from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/test/helpers.ts b/packages/services/test/helpers.ts index 7dda2267..688bdf15 100644 --- a/packages/services/test/helpers.ts +++ b/packages/services/test/helpers.ts @@ -1,5 +1,3 @@ -import { expect } from "bun:test"; - import { and, db, desc, eq, inArray } from "@openstatus/db"; import { type Scope, @@ -10,6 +8,7 @@ import { selectWorkspaceSchema, workspace as workspaceTable, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; import type { Actor, DB, DrizzleTx, ServiceContext } from "../src/context"; import type { Workspace } from "../src/types"; diff --git a/packages/services/tsconfig.json b/packages/services/tsconfig.json index 54a1ac32..0da708f7 100644 --- a/packages/services/tsconfig.json +++ b/packages/services/tsconfig.json @@ -1,8 +1,9 @@ { - "extends": "@openstatus/tsconfig/react-library.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "test"], "exclude": ["dist", "build", "node_modules"], "compilerOptions": { + "module": "ESNext", "moduleResolution": "bundler" } } diff --git a/packages/status-fetcher/__tests__/fetch.test.ts b/packages/status-fetcher/__tests__/fetch.test.ts index 36556d49..7bafe97d 100644 --- a/packages/status-fetcher/__tests__/fetch.test.ts +++ b/packages/status-fetcher/__tests__/fetch.test.ts @@ -1,5 +1,6 @@ -import { beforeEach, describe, expect, it, mock } from "bun:test"; - +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { Cause, Effect, Exit, Option } from "effect"; import { z } from "zod"; @@ -10,7 +11,7 @@ const TEST_URL = "https://api.example.com/status"; type FetchImpl = (url: string, init?: RequestInit) => Promise; const installMockFetch = (impl: FetchImpl) => { - const fn = mock(impl); + const fn = spy(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; @@ -79,7 +80,7 @@ describe("fetchJson", () => { expect(err.httpStatus).toBe(404); expect(err.fetcherName).toBe("test"); expect(err.entryId).toBe("x"); - expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.calls.length).toBe(1); }); it("retries up to 3 times on 5xx then fails", async () => { @@ -92,7 +93,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBe(503); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); it("retries up to 3 times on network error then fails", async () => { @@ -105,7 +106,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBeUndefined(); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); it("fails with FetchError on schema mismatch without retrying", async () => { @@ -118,7 +119,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.cause).toBeInstanceOf(Error); - expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.calls.length).toBe(1); }); it("applies default User-Agent and Accept headers", async () => { @@ -200,7 +201,7 @@ describe("fetchText", () => { const exit = await Effect.runPromiseExit(fetchText({ url: TEST_URL })); const err = expectFailure(exit); expect(err.httpStatus).toBe(500); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); }); diff --git a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts index 09baa515..ae7a8d2c 100644 --- a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import type { StatusPageEntry } from "../../src/types"; @@ -113,8 +114,11 @@ describe("AtlassianFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("Etc/UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://www.githubstatus.com/api/v2/summary.json", + ); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -234,10 +238,9 @@ describe("AtlassianFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on non-200 response", async () => { @@ -332,10 +335,11 @@ describe("AtlassianFetcher", () => { const incidents = await runIncidents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://www.githubstatus.com/api/v2/incidents.json", - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(2); expect(incidents[0]).toMatchObject({ providerIncidentId: "abc", diff --git a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts index 355f070f..d1bb0869 100644 --- a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { BetterStackFetcher } from "../../src/fetchers/betterstack"; import type { StatusPageEntry } from "../../src/types"; @@ -121,8 +122,9 @@ describe("BetterStackFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("America/New_York"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com/index.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com/index.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -240,10 +242,9 @@ describe("BetterStackFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on 4xx response", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/components.test.ts b/packages/status-fetcher/__tests__/fetchers/components.test.ts index 15b1aaf4..d87f3ae3 100644 --- a/packages/status-fetcher/__tests__/fetchers/components.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/components.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; @@ -81,10 +82,11 @@ function itNormalizes( const components = await runComponents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( `${entry.status_page_url}/api/v2/components.json`, - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); // group container "grp" is excluded; only the three leaves remain expect(components).toHaveLength(3); diff --git a/packages/status-fetcher/__tests__/fetchers/custom.test.ts b/packages/status-fetcher/__tests__/fetchers/custom.test.ts index bd435051..a3091470 100644 --- a/packages/status-fetcher/__tests__/fetchers/custom.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/custom.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { CustomApiFetcher } from "../../src/fetchers/custom"; import type { StatusPageEntry } from "../../src/types"; diff --git a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts index 548186a4..d0a5194c 100644 --- a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, it } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { Exit } from "effect"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; diff --git a/packages/status-fetcher/__tests__/fetchers/html.test.ts b/packages/status-fetcher/__tests__/fetchers/html.test.ts index 209577d1..ddbac6a1 100644 --- a/packages/status-fetcher/__tests__/fetchers/html.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/html.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { HtmlScraperFetcher } from "../../src/fetchers/html"; import type { StatusPageEntry } from "../../src/types"; @@ -92,8 +93,9 @@ describe("HtmlScraperFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "Mozilla/5.0 (compatible; OpenStatus-Bot/1.0)", diff --git a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts index cbc6f75b..6a759fdd 100644 --- a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; import type { StatusPageEntry } from "../../src/types"; @@ -111,8 +112,9 @@ describe("IncidentioFetcher", () => { expect(result.status).toBe("operational"); expect(result.description).toBe("All Systems Operational"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com/api/v2/summary.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com/api/v2/summary.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -234,10 +236,9 @@ describe("IncidentioFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/summary.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/summary.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on 5xx response", async () => { @@ -323,10 +324,11 @@ describe("IncidentioFetcher", () => { const incidents = await runIncidents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://status.linear.app/api/v2/incidents.json", - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(1); expect(incidents[0]).toMatchObject({ providerIncidentId: "INC-1", diff --git a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts index 5abaf1c1..b7c528cd 100644 --- a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { InstatusFetcher } from "../../src/fetchers/instatus"; import type { StatusPageEntry } from "../../src/types"; @@ -109,8 +110,9 @@ describe("InstatusFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://test.instatus.com/summary.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://test.instatus.com/summary.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -230,10 +232,9 @@ describe("InstatusFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on non-200 response (after retries)", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts index 72c6e9b3..01dd6918 100644 --- a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { UptimeRobotFetcher } from "../../src/fetchers/uptimerobot"; import type { StatusPageEntry } from "../../src/types"; @@ -138,8 +140,9 @@ describe("UptimeRobotFetcher", () => { expect(result.description).toBe("0 monitors down (3 total)"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - ENDPOINT, + const lastCall = fetchMock.calls[fetchMock.calls.length - 1]; + expect(lastCall.args[0]).toBe(ENDPOINT); + expect(lastCall.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -272,7 +275,7 @@ describe("UptimeRobotFetcher", () => { }); it("unknown statusClass folds to operational with a warn", async () => { - const warnSpy = mock(() => {}); + const warnSpy = spy(() => {}); const originalWarn = console.warn; console.warn = warnSpy; @@ -287,7 +290,7 @@ describe("UptimeRobotFetcher", () => { expect(result.severity).toBe("none"); expect(result.status).toBe("operational"); - expect(warnSpy).toHaveBeenCalled(); + expect(warnSpy.calls.length).toBeGreaterThan(0); } finally { console.warn = originalWarn; } diff --git a/packages/status-fetcher/__tests__/helpers.ts b/packages/status-fetcher/__tests__/helpers.ts index 20f73dba..bcf6a527 100644 --- a/packages/status-fetcher/__tests__/helpers.ts +++ b/packages/status-fetcher/__tests__/helpers.ts @@ -1,5 +1,4 @@ -import { mock } from "bun:test"; - +import { spy } from "@std/testing/mock"; import { Cause, Effect, Exit, Option } from "effect"; import type { FetchError } from "../src/fetch"; @@ -14,7 +13,7 @@ import type { type FetchImpl = (url: string, init?: RequestInit) => Promise; export const installMockFetch = (impl: FetchImpl) => { - const fn = mock(impl); + const fn = spy(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; diff --git a/packages/status-fetcher/__tests__/integration.test.ts b/packages/status-fetcher/__tests__/integration.test.ts index 4c171dbd..73ab88a0 100644 --- a/packages/status-fetcher/__tests__/integration.test.ts +++ b/packages/status-fetcher/__tests__/integration.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, it } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { Effect } from "effect"; import { fetchers as allFetchers } from "../src/fetchers"; diff --git a/packages/status-fetcher/__tests__/utils.test.ts b/packages/status-fetcher/__tests__/utils.test.ts index ae1179a3..f2d78f56 100644 --- a/packages/status-fetcher/__tests__/utils.test.ts +++ b/packages/status-fetcher/__tests__/utils.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { inferStatus, urlHostnameEndsWith } from "../src/utils"; diff --git a/packages/status-fetcher/package.json b/packages/status-fetcher/package.json index 8e7c9118..8f4d305d 100644 --- a/packages/status-fetcher/package.json +++ b/packages/status-fetcher/package.json @@ -11,8 +11,9 @@ "./types": "./src/types.ts" }, "scripts": { - "test": "bun test", - "test:watch": "bun test --watch", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -21,6 +22,7 @@ "zod": "catalog:" }, "devDependencies": { - "@types/bun": "latest" + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19" } } diff --git a/packages/status-fetcher/tsconfig.json b/packages/status-fetcher/tsconfig.json index 9d6eaf3f..0d9806db 100644 --- a/packages/status-fetcher/tsconfig.json +++ b/packages/status-fetcher/tsconfig.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "ES2022", "module": "ESNext", - "lib": ["ES2022"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "noEmit": true, diff --git a/packages/subscriptions/package.json b/packages/subscriptions/package.json index c50cc3b9..ada82745 100644 --- a/packages/subscriptions/package.json +++ b/packages/subscriptions/package.json @@ -15,7 +15,8 @@ } }, "scripts": { - "test": "bun test" + "check": "deno check --sloppy-imports .", + "test": "deno test -A --no-check --sloppy-imports" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -27,7 +28,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/subscriptions/src/channels/email.test.ts b/packages/subscriptions/src/channels/email.test.ts index 6772aceb..bda44066 100644 --- a/packages/subscriptions/src/channels/email.test.ts +++ b/packages/subscriptions/src/channels/email.test.ts @@ -1,6 +1,8 @@ -import { beforeEach, describe, expect, spyOn, test } from "bun:test"; - +import "../test-preload.ts"; import { EmailClient } from "@openstatus/emails"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import type { PageUpdate, Subscription } from "../types"; import { @@ -12,15 +14,8 @@ import { // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -const sendPageSubscriptionMock = spyOn( - EmailClient.prototype, - "sendPageSubscription", -).mockResolvedValue(undefined); - -const sendStatusReportUpdateMock = spyOn( - EmailClient.prototype, - "sendStatusReportUpdate", -).mockResolvedValue(undefined); +let sendPageSubscriptionMock: Stub; +let sendStatusReportUpdateMock: Stub; function makeSub(overrides: Partial = {}): Subscription { return { @@ -51,8 +46,21 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - sendPageSubscriptionMock.mockClear(); - sendStatusReportUpdateMock.mockClear(); + sendPageSubscriptionMock = stub( + EmailClient.prototype, + "sendPageSubscription", + () => Promise.resolve(undefined), + ); + sendStatusReportUpdateMock = stub( + EmailClient.prototype, + "sendStatusReportUpdate", + () => Promise.resolve(undefined), + ); +}); + +afterEach(() => { + sendPageSubscriptionMock.restore(); + sendStatusReportUpdateMock.restore(); }); // ─── validateEmailConfig ────────────────────────────────────────────────────── @@ -94,8 +102,8 @@ describe("sendEmailVerification", () => { const sub = makeSub({ email: "user@example.com", pageName: "My Page" }); await sendEmailVerification(sub, "https://example.com/verify/abc"); - expect(sendPageSubscriptionMock).toHaveBeenCalledTimes(1); - const [args] = sendPageSubscriptionMock.mock.calls[0]; + assertSpyCalls(sendPageSubscriptionMock, 1); + const [args] = sendPageSubscriptionMock.calls[0].args; expect(args.to).toBe("user@example.com"); expect(args.link).toBe("https://example.com/verify/abc"); expect(args.page).toBe("My Page"); @@ -107,13 +115,13 @@ describe("sendEmailVerification", () => { describe("sendEmailNotifications", () => { test("does nothing for an empty subscriptions array", async () => { await sendEmailNotifications([], makeUpdate()); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("filters out subscriptions without an email address", async () => { const sub = makeSub({ email: undefined }); await sendEmailNotifications([sub], makeUpdate()); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("calls sendStatusReportUpdate once with all valid subscribers", async () => { @@ -123,8 +131,8 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub1, sub2], update); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.subscribers).toHaveLength(2); expect(args.subscribers[0].email).toBe("a@example.com"); expect(args.subscribers[1].email).toBe("b@example.com"); @@ -138,7 +146,7 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub], update); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.pageComponents).toEqual(["API", "Database"]); }); @@ -146,7 +154,7 @@ describe("sendEmailNotifications", () => { const sub = makeSub(); await sendEmailNotifications([sub], makeUpdate({ updateId: 77 })); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.idempotencyKey).toBe("status-report-update:77"); }); @@ -157,7 +165,7 @@ describe("sendEmailNotifications", () => { makeUpdate({ id: 17, updateId: undefined, status: "maintenance" }), ); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.idempotencyKey).toBe("page-update:17:maintenance"); }); }); diff --git a/packages/subscriptions/src/channels/index.test.ts b/packages/subscriptions/src/channels/index.test.ts index fc6df14f..d635918b 100644 --- a/packages/subscriptions/src/channels/index.test.ts +++ b/packages/subscriptions/src/channels/index.test.ts @@ -1,4 +1,6 @@ -import { describe, expect, test } from "bun:test"; +import "../test-preload.ts"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { getChannel } from "./index"; diff --git a/packages/subscriptions/src/channels/webhook.test.ts b/packages/subscriptions/src/channels/webhook.test.ts index a10a9b41..d17be6f4 100644 --- a/packages/subscriptions/src/channels/webhook.test.ts +++ b/packages/subscriptions/src/channels/webhook.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { webhookPayloadSchema } from "../payload"; import type { PageUpdate, Subscription } from "../types"; @@ -15,7 +17,21 @@ import { const SLACK_URL = "https://hooks.slack.com/services/T1/B1/XXX"; const DISCORD_URL = "https://discord.com/api/webhooks/1/xxx"; -let fetchMock: any; +let fetchMock: Stub; + +function setFetch( + impl: ( + input: Request | string | URL, + init?: RequestInit, + ) => Promise, +) { + fetchMock?.restore(); + fetchMock = stub(globalThis, "fetch", impl); +} + +function resolveFetch(response: Response) { + setFetch(() => Promise.resolve(response)); +} function makeSub(overrides: Partial = {}): Subscription { return { @@ -46,11 +62,13 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - fetchMock = spyOn(global, "fetch"); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); }); afterEach(() => { - fetchMock.mockRestore(); + fetchMock.restore(); }); // ─── validateWebhookConfig ──────────────────────────────────────────────────── @@ -99,7 +117,7 @@ describe("sendWebhookVerification", () => { }); test("resolves when fetch returns 200", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub(); await expect( sendWebhookVerification(sub, "https://example.com/verify/abc"), @@ -107,7 +125,7 @@ describe("sendWebhookVerification", () => { }); test("throws when fetch returns a non-ok status", async () => { - fetchMock.mockResolvedValue( + resolveFetch( new Response(null, { status: 500, statusText: "Server Error" }), ); const sub = makeSub(); @@ -117,15 +135,15 @@ describe("sendWebhookVerification", () => { }); test("posts to the correct URL with the expected payload", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "my-token", webhookUrl: "https://hooks.example.com/sub", }); await sendWebhookVerification(sub, "https://example.com/verify/my-token"); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(url).toBe("https://hooks.example.com/sub"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -141,11 +159,11 @@ describe("sendWebhookNotifications", () => { test("skips subscriptions without a webhookUrl", async () => { const sub = makeSub({ webhookUrl: undefined }); await sendWebhookNotifications([sub], makeUpdate()); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("sends a POST request to each webhook URL", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub1 = makeSub({ webhookUrl: "https://hooks.slack.com/services/T1/B1/aaa", }); @@ -155,14 +173,14 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub1, sub2], makeUpdate()); - expect(fetchMock).toHaveBeenCalledTimes(2); - const urls = fetchMock.mock.calls.map(([url]: [string]) => url); + assertSpyCalls(fetchMock, 2); + const urls = fetchMock.calls.map((c) => c.args[0]); expect(urls).toContain("https://hooks.slack.com/services/T1/B1/aaa"); expect(urls).toContain("https://hooks.slack.com/services/T2/B2/bbb"); }); test("sends a generic JSON payload to non-Slack/Discord URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const generic = makeSub({ id: 101, webhookUrl: "https://example.com/webhook", @@ -174,19 +192,19 @@ describe("sendWebhookNotifications", () => { makeUpdate({ updateId: 42 }), ); - expect(fetchMock).toHaveBeenCalledTimes(2); + assertSpyCalls(fetchMock, 2); const byUrl = new Map( - fetchMock.mock.calls.map(([url, init]: [string, RequestInit]) => [ - url, - JSON.parse(init.body as string), - ]), + fetchMock.calls.map((c) => { + const [url, init] = c.args as [string, RequestInit]; + return [url, JSON.parse(init.body as string)]; + }), ); expect(byUrl.get("https://example.com/webhook").type).toBe("status_report"); expect(byUrl.get(SLACK_URL).attachments).toBeDefined(); }); test("the status_report body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -200,14 +218,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("the maintenance body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -220,14 +238,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("applies custom headers from channelConfig", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ channelConfig: JSON.stringify({ headers: [{ key: "X-Custom-Header", value: "my-value" }], @@ -236,17 +254,17 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const headers = init?.headers as Record; expect(headers["X-Custom-Header"]).toBe("my-value"); }); test("continues sending to remaining webhooks when one keeps failing", async () => { const failUrl = "https://hooks.slack.com/services/T1/B1/fail"; - fetchMock.mockImplementation(async (url: string) => - url === failUrl + setFetch((input) => + String(input) === failUrl ? Promise.reject(new Error("Network error")) - : new Response(null, { status: 200 }), + : Promise.resolve(new Response(null, { status: 200 })), ); const sub1 = makeSub({ webhookUrl: failUrl }); @@ -258,17 +276,22 @@ describe("sendWebhookNotifications", () => { sendWebhookNotifications([sub1, sub2], makeUpdate()), ).resolves.toBeUndefined(); - const calls = fetchMock.mock.calls.map(([url]: [string]) => url); + const calls = fetchMock.calls.map((c) => String(c.args[0])); expect(calls).toContain("https://hooks.slack.com/services/T2/B2/succeed"); }); test("retries transient failures then succeeds", async () => { let attempts = 0; - fetchMock.mockImplementation(async () => { + setFetch(() => { attempts += 1; - return attempts < 3 - ? new Response(null, { status: 503, statusText: "Service Unavailable" }) - : new Response(null, { status: 200 }); + return Promise.resolve( + attempts < 3 + ? new Response(null, { + status: 503, + statusText: "Service Unavailable", + }) + : new Response(null, { status: 200 }), + ); }); await expect( @@ -279,13 +302,13 @@ describe("sendWebhookNotifications", () => { }); test("does not retry non-retryable 4xx responses", async () => { - fetchMock.mockResolvedValue( + resolveFetch( new Response(null, { status: 400, statusText: "Bad Request" }), ); await sendWebhookNotifications([makeSub()], makeUpdate()); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); @@ -313,31 +336,31 @@ describe("detectWebhookFlavor", () => { describe("sendWebhookNotifications (flavor detection)", () => { test("emits Slack blocks payload for hooks.slack.com URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: SLACK_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.attachments).toBeDefined(); expect(body.attachments[0].blocks).toBeInstanceOf(Array); }); test("emits Discord embed payload for discord.com URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.embeds).toBeInstanceOf(Array); expect(body.embeds[0].title).toBe("Test Incident"); }); test("Slack payload includes manage/unsubscribe links", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", pageSlug: "demo", @@ -345,7 +368,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const stringified = init?.body as string; expect(stringified).toContain("https://demo.openstatus.dev/manage/tok-123"); expect(stringified).toContain( @@ -354,7 +377,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Slack payload uses custom domain when present", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", customDomain: "status.partner.com", @@ -362,18 +385,18 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const stringified = init?.body as string; expect(stringified).toContain("https://status.partner.com/manage/tok-123"); }); test("Slack payload links to the event details and the page origin", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ pageSlug: "demo", pageName: "Demo" }); await sendWebhookNotifications([sub], makeUpdate({ id: 99 })); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); const stringified = init?.body as string; // title stays in a plain_text header block @@ -388,7 +411,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Discord embed url points at the event; maintenance uses the maintenance path", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL, pageSlug: "demo", @@ -400,7 +423,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { makeUpdate({ id: 7, status: "maintenance" }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.embeds[0].url).toBe( "https://demo.openstatus.dev/events/maintenance/7", @@ -584,14 +607,14 @@ describe("buildTestPayload", () => { describe("sendTestWebhookRequest", () => { test("POSTs flavor-appropriate payload", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(url).toBe("https://example.com/hook"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -599,9 +622,7 @@ describe("sendTestWebhookRequest", () => { }); test("throws on non-2xx response", async () => { - fetchMock.mockResolvedValue( - new Response(null, { status: 404, statusText: "Not Found" }), - ); + resolveFetch(new Response(null, { status: 404, statusText: "Not Found" })); await expect( sendTestWebhookRequest({ url: "https://example.com/hook", @@ -611,14 +632,14 @@ describe("sendTestWebhookRequest", () => { }); test("passes custom headers", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", headers: { "X-Custom": "abc" }, }); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const headers = init?.headers as Record; expect(headers["X-Custom"]).toBe("abc"); }); diff --git a/packages/subscriptions/src/dispatcher.test.ts b/packages/subscriptions/src/dispatcher.test.ts index 4cb54ac1..8888bc93 100644 --- a/packages/subscriptions/src/dispatcher.test.ts +++ b/packages/subscriptions/src/dispatcher.test.ts @@ -1,19 +1,20 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - spyOn, - test, -} from "bun:test"; - +import "./test-preload.ts"; import { db, eq } from "@openstatus/db"; import { pageSubscriber, pageSubscriberToPageComponent, } from "@openstatus/db/src/schema"; import { EmailClient } from "@openstatus/emails"; +import { expect } from "@std/expect"; +import { + afterAll, + afterEach, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { dispatchPageUpdate } from "./dispatcher"; import type { PageUpdate } from "./types"; @@ -21,10 +22,8 @@ import type { PageUpdate } from "./types"; // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -const sendStatusReportUpdateMock = spyOn( - EmailClient.prototype, - "sendStatusReportUpdate", -).mockResolvedValue(undefined); +let sendStatusReportUpdateMock: Stub; +let rejectNextSend: Error | null = null; // IDs present in the seeded database const PAGE_ID = 1; // slug: "status" @@ -105,7 +104,23 @@ beforeAll(async () => { afterAll(cleanAll); beforeEach(() => { - sendStatusReportUpdateMock.mockClear(); + rejectNextSend = null; + sendStatusReportUpdateMock = stub( + EmailClient.prototype, + "sendStatusReportUpdate", + () => { + if (rejectNextSend) { + const error = rejectNextSend; + rejectNextSend = null; + return Promise.reject(error); + } + return Promise.resolve(undefined); + }, + ); +}); + +afterEach(() => { + sendStatusReportUpdateMock.restore(); }); // ─── dispatchPageUpdate - component filtering ───────────────────────────────── @@ -116,8 +131,8 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -130,7 +145,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -143,7 +158,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1, COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -154,8 +169,8 @@ describe("dispatchPageUpdate - component filtering", () => { test("notifies only the entire-page subscriber when update has no affected components", async () => { await dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; expect(subscribers).toHaveLength(1); expect(subscribers[0].email).toBe(EMAILS.entirePage); @@ -167,7 +182,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).not.toContain(EMAILS.component2); @@ -182,11 +197,11 @@ describe("dispatchPageUpdate - edge cases", () => { makePageUpdate({ pageId: 99999, pageComponentIds: [COMPONENT_1] }), ); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("does not propagate channel failure — resolves even when sendStatusReportUpdate throws", async () => { - sendStatusReportUpdateMock.mockRejectedValueOnce(new Error("SMTP failure")); + rejectNextSend = new Error("SMTP failure"); await expect( dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })), diff --git a/packages/subscriptions/src/test-preload.ts b/packages/subscriptions/src/test-preload.ts index 29170704..b26048d3 100644 --- a/packages/subscriptions/src/test-preload.ts +++ b/packages/subscriptions/src/test-preload.ts @@ -1,6 +1,11 @@ /** - * Preload file for bun test. - * Runs before any test file is loaded, ensuring env vars are set - * before module-level env validations (e.g. @openstatus/emails) fire. + * Test env setup. Import this FIRST in any test file so env vars are set + * before module-level env validations (e.g. @openstatus/emails, @openstatus/db) + * fire on import. + * + * Bun's test runner set NODE_ENV=test automatically; Deno does not, so we set + * it here. The @openstatus/db env hack maps NODE_ENV=test to the local turso + * URL, and @openstatus/emails validates RESEND_API_KEY at module load. */ -process.env.RESEND_API_KEY = "test-key"; +process.env.NODE_ENV = "test"; +process.env.RESEND_API_KEY ??= "test-key"; diff --git a/packages/subscriptions/tsconfig.json b/packages/subscriptions/tsconfig.json index 868037cf..4225a2de 100644 --- a/packages/subscriptions/tsconfig.json +++ b/packages/subscriptions/tsconfig.json @@ -1,12 +1,10 @@ { "extends": "@openstatus/tsconfig/base.json", "compilerOptions": { - "lib": ["ES2022", "DOM"], "module": "ESNext", "target": "ES2022", "moduleResolution": "bundler", - "jsx": "react-jsx", - "types": ["bun"] + "jsx": "react-jsx" }, "include": [".", "src"], "exclude": ["dist", "build", "node_modules"] diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json new file mode 100644 index 00000000..ee345766 --- /dev/null +++ b/packages/test-utils/package.json @@ -0,0 +1,20 @@ +{ + "name": "@openstatus/test-utils", + "version": "1.0.0", + "private": true, + "main": "src/index.ts", + "exports": { + ".": "./src/index.ts" + }, + "scripts": { + "check": "deno check --sloppy-imports ." + }, + "dependencies": { + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19" + }, + "devDependencies": { + "@openstatus/tsconfig": "workspace:*", + "typescript": "catalog:" + } +} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts new file mode 100644 index 00000000..25c2570b --- /dev/null +++ b/packages/test-utils/src/index.ts @@ -0,0 +1,27 @@ +// Single import surface for migrated tests: `import { ... } from "@openstatus/test-utils"`. +// Importing this module registers the Bun-compat matchers (./matchers side-effect). +import "./matchers.ts"; + +export { + after, + afterAll, + afterEach, + before, + beforeAll, + beforeEach, + describe, + it, + test, +} from "./runner.ts"; +export { expect } from "jsr:@std/expect"; +export { type MockFn, mock } from "./mock-fn.ts"; +export { + assertSpyCall, + assertSpyCalls, + returnsNext, + type Spy, + spy, + type Stub, + stub, +} from "jsr:@std/testing/mock"; +export { FakeTime } from "jsr:@std/testing/time"; diff --git a/packages/test-utils/src/matchers.ts b/packages/test-utils/src/matchers.ts new file mode 100644 index 00000000..36d58bd3 --- /dev/null +++ b/packages/test-utils/src/matchers.ts @@ -0,0 +1,95 @@ +import { expect } from "jsr:@std/expect"; + +// @std/expect stopped re-exporting its matcher-context type; these matchers only +// read `value`, so a minimal local shape is enough. +type ExpectMatcherContext = { value: unknown }; + +type MatcherResult = { pass: boolean; message: () => string }; + +const isObject = (v: unknown): v is Record => + typeof v === "object" && v !== null; + +const size = (v: unknown): number => { + if (typeof v === "string" || Array.isArray(v)) return v.length; + if (v instanceof Map || v instanceof Set) return v.size; + if (isObject(v)) return Object.keys(v).length; + return -1; +}; + +// Bun's `expect` extension matchers, reimplemented on @std/expect so the ~150 +// existing call sites keep working under `deno test`. +expect.extend({ + toBeNumber(context: ExpectMatcherContext): MatcherResult { + const pass = + typeof context.value === "number" && !Number.isNaN(context.value); + return { pass, message: () => `expected ${context.value} to be a number` }; + }, + toBeString(context: ExpectMatcherContext): MatcherResult { + return { + pass: typeof context.value === "string", + message: () => `expected ${context.value} to be a string`, + }; + }, + toBeBoolean(context: ExpectMatcherContext): MatcherResult { + return { + pass: typeof context.value === "boolean", + message: () => `expected ${context.value} to be a boolean`, + }; + }, + toBeArray(context: ExpectMatcherContext): MatcherResult { + return { + pass: Array.isArray(context.value), + message: () => `expected ${context.value} to be an array`, + }; + }, + toBeTrue(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === true, + message: () => `expected ${context.value} to be true`, + }; + }, + toBeFalse(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === false, + message: () => `expected ${context.value} to be false`, + }; + }, + toBeNil(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === null || context.value === undefined, + message: () => `expected ${context.value} to be null or undefined`, + }; + }, + toBeEmpty(context: ExpectMatcherContext): MatcherResult { + return { + pass: size(context.value) === 0, + message: () => `expected ${context.value} to be empty`, + }; + }, + toBeOneOf( + context: ExpectMatcherContext, + expected: readonly unknown[], + ): MatcherResult { + return { + pass: expected.includes(context.value), + message: () => + `expected ${context.value} to be one of ${JSON.stringify(expected)}`, + }; + }, + toContainValue(context: ExpectMatcherContext, value: unknown): MatcherResult { + const pass = + isObject(context.value) && Object.values(context.value).includes(value); + return { pass, message: () => `expected object to contain value ${value}` }; + }, + toContainKey(context: ExpectMatcherContext, key: string): MatcherResult { + const pass = + isObject(context.value) && Object.keys(context.value).includes(key); + return { pass, message: () => `expected object to contain key ${key}` }; + }, + pass(_context: ExpectMatcherContext, _message?: string): MatcherResult { + return { pass: true, message: () => _message ?? "passed" }; + }, + fail(_context: ExpectMatcherContext, message?: string): MatcherResult { + return { pass: false, message: () => message ?? "failed" }; + }, +}); diff --git a/packages/test-utils/src/mock-fn.ts b/packages/test-utils/src/mock-fn.ts new file mode 100644 index 00000000..2d71214f --- /dev/null +++ b/packages/test-utils/src/mock-fn.ts @@ -0,0 +1,112 @@ +// Bun-compatible `mock()` for the Deno migration. Bun's mock function isn't +// available under `deno test`; this reimplements the subset our suites use +// (the jest-style `.mock.calls` + `.mockX()` helpers) on plain closures. +// +// NOTE: bun's `mock.module(specifier, factory)` has no Deno equivalent and is +// intentionally NOT provided here — module replacement is done via the +// `--import-map` flag and test-double modules instead. + +// oxlint-disable-next-line typescript/no-explicit-any +type AnyFn = (...args: any[]) => any; + +interface MockState { + // oxlint-disable-next-line typescript/no-explicit-any + calls: any[][]; + results: { type: "return" | "throw"; value: unknown }[]; +} + +export interface MockFn extends AnyFn { + mock: MockState; + mockClear(): MockFn; + mockReset(): MockFn; + mockImplementation(fn: AnyFn): MockFn; + mockImplementationOnce(fn: AnyFn): MockFn; + mockReturnValue(value: unknown): MockFn; + mockReturnValueOnce(value: unknown): MockFn; + mockResolvedValue(value: unknown): MockFn; + mockResolvedValueOnce(value: unknown): MockFn; + mockRejectedValue(value: unknown): MockFn; + mockRestore(): MockFn; +} + +export function mock(impl?: AnyFn): MockFn { + let defaultImpl = impl; + const onceQueue: AnyFn[] = []; + const state: MockState = { calls: [], results: [] }; + + // oxlint-disable-next-line typescript/no-explicit-any + const fn = ((...args: any[]) => { + state.calls.push(args); + const use = onceQueue.length ? onceQueue.shift() : defaultImpl; + try { + const value = use ? use(...args) : undefined; + state.results.push({ type: "return", value }); + return value; + } catch (err) { + state.results.push({ type: "throw", value: err }); + throw err; + } + }) as MockFn; + + fn.mock = state; + // Expose the @std/expect mock interface (Symbol.for("@MOCK")) so its + // `.toHaveBeenCalled*` matchers recognize this shim, not just `.mock.calls`. + Object.defineProperty(fn, Symbol.for("@MOCK"), { + get() { + return { + calls: state.calls.map((args, i) => { + const r = state.results[i]; + return { + args, + returned: r?.type === "return" ? r.value : undefined, + thrown: r?.type === "throw" ? r.value : undefined, + timestamp: 0, + returns: r?.type === "return", + throws: r?.type === "throw", + }; + }), + }; + }, + }); + fn.mockClear = () => { + state.calls = []; + state.results = []; + return fn; + }; + fn.mockReset = () => { + fn.mockClear(); + onceQueue.length = 0; + defaultImpl = undefined; + return fn; + }; + fn.mockImplementation = (f) => { + defaultImpl = f; + return fn; + }; + fn.mockImplementationOnce = (f) => { + onceQueue.push(f); + return fn; + }; + fn.mockReturnValue = (value) => { + defaultImpl = () => value; + return fn; + }; + fn.mockReturnValueOnce = (value) => { + onceQueue.push(() => value); + return fn; + }; + fn.mockResolvedValue = (value) => { + defaultImpl = () => Promise.resolve(value); + return fn; + }; + fn.mockResolvedValueOnce = (value) => { + onceQueue.push(() => Promise.resolve(value)); + return fn; + }; + fn.mockRejectedValue = (value) => { + defaultImpl = () => Promise.reject(value); + return fn; + }; + fn.mockRestore = () => fn; + return fn; +} diff --git a/packages/test-utils/src/runner.ts b/packages/test-utils/src/runner.ts new file mode 100644 index 00000000..55dd22f4 --- /dev/null +++ b/packages/test-utils/src/runner.ts @@ -0,0 +1,58 @@ +import { + describe as nodeDescribe, + it as nodeIt, + test as nodeTest, +} from "node:test"; + +type Body = () => void | Promise; +type BaseFn = (name: string, body: Body) => void; +type EachCase = readonly unknown[]; + +const formatName = (name: string, args: EachCase, index: number): string => { + let i = 0; + const interpolated = name.replace(/%[spdijfo%]/g, (token) => { + if (token === "%%") return "%"; + const arg = args[i++]; + return typeof arg === "string" ? arg : JSON.stringify(arg); + }); + return interpolated === name && args.length > 0 + ? `${name} [${index}]` + : interpolated; +}; + +const makeEach = + (base: BaseFn) => + (cases: readonly T[]) => + (name: string, body: (...args: T) => void | Promise): void => { + cases.forEach((args, index) => { + base(formatName(name, args, index), () => body(...args)); + }); + }; + +// node:test's `test`/`it`/`describe` lack Jest/Bun's `.each`; everything else +// (.skip/.todo/.only) exists natively and is preserved by reference. +type Augmented = F & { + each: ( + cases: readonly T[], + ) => (name: string, body: (...args: T) => void | Promise) => void; +}; + +const augment = (base: F): Augmented => { + const fn = base as Augmented; + fn.each = makeEach(base as unknown as BaseFn); + return fn; +}; + +export const test = augment(nodeTest); +export const it = augment(nodeIt); +export const describe = augment( + nodeDescribe as unknown as typeof nodeTest, +) as unknown as Augmented; +export { + after, + after as afterAll, + afterEach, + before, + before as beforeAll, + beforeEach, +} from "node:test"; diff --git a/packages/theme-store/package.json b/packages/theme-store/package.json index cdb62553..ffc39d71 100644 --- a/packages/theme-store/package.json +++ b/packages/theme-store/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/tinybird/package.json b/packages/tinybird/package.json index 17a465bc..c575aa6a 100644 --- a/packages/tinybird/package.json +++ b/packages/tinybird/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "license": "MIT", "main": "src/index.ts", + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@chronark/zod-bird": "catalog:", "zod": "catalog:" diff --git a/packages/tracker/package.json b/packages/tracker/package.json index 6f654a01..f73478cc 100644 --- a/packages/tracker/package.json +++ b/packages/tracker/package.json @@ -7,7 +7,8 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -16,7 +17,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "bun-types": "catalog:", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/tracker/src/mock.ts b/packages/tracker/src/mock.ts index 5f338e46..50082d4c 100644 --- a/packages/tracker/src/mock.ts +++ b/packages/tracker/src/mock.ts @@ -1,6 +1,4 @@ -import type { Monitor } from "@openstatus/tinybird"; - -import { Tracker } from "./tracker"; +import { type Monitor, Tracker } from "./tracker"; export const mockMonitor: Monitor[] = [ { day: "2024-02-21 00:00:00", count: 762, ok: 762 }, diff --git a/packages/tracker/src/tracker.test.ts b/packages/tracker/src/tracker.test.ts index 0c4fddf3..8f42f53f 100644 --- a/packages/tracker/src/tracker.test.ts +++ b/packages/tracker/src/tracker.test.ts @@ -1,11 +1,11 @@ -import { describe, expect, test } from "bun:test"; - import type { Incident, Maintenance, StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { blacklistDates } from "./blacklist"; import { classNames, statusDetails } from "./config"; @@ -149,10 +149,12 @@ describe("Tracker", () => { ["0% → Major Outage", 100, 0, Status.MajorOutage], ]; - test.each(cases)("%s", (_label, count, ok, expected) => { - const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); - expect(tracker.currentStatus).toBe(expected); - }); + for (const [label, count, ok, expected] of cases) { + test(label, () => { + const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); + expect(tracker.currentStatus).toBe(expected); + }); + } // NOTE: the lower boundary is `> 30`, while the other two are `>=`. So // exactly 30% uptime is Major (not Partial) Outage. Pinning current @@ -336,7 +338,9 @@ describe("Tracker", () => { describe("per-day precedence (maintenance > report > incident > uptime)", () => { const DAY = "2024-01-01"; - const okData = [day(`${DAY} 00:00:00`, 864, 864)]; + // date-only string so `new Date(day)` anchors to UTC midnight, matching + // the UTC fixture dates below regardless of the runner's timezone. + const okData = [day(DAY, 864, 864)]; test("maintenance overlapping the day wins", () => { const [bucket] = new Tracker({ @@ -394,7 +398,7 @@ describe("Tracker", () => { test("an incident resolved on a previous day does not affect this bucket", () => { const [bucket] = new Tracker({ - data: [day("2024-01-02 00:00:00", 864, 864)], + data: [day("2024-01-02", 864, 864)], incidents: [ createIncident({ startedAt: new Date("2024-01-01T12:00:00.000Z"), diff --git a/packages/tracker/src/tracker.ts b/packages/tracker/src/tracker.ts index e96bec6f..f5da4d4c 100644 --- a/packages/tracker/src/tracker.ts +++ b/packages/tracker/src/tracker.ts @@ -11,7 +11,7 @@ import type { StatusDetails, StatusVariant } from "./types"; import { Status } from "./types"; import { endOfDay, isSameDay, startOfDay } from "./utils"; -type Monitor = { +export type Monitor = { count: number; ok: number; day: string; diff --git a/packages/tracker/tsconfig.json b/packages/tracker/tsconfig.json index f40fdec7..bded80f3 100644 --- a/packages/tracker/tsconfig.json +++ b/packages/tracker/tsconfig.json @@ -2,7 +2,6 @@ "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "target": "ES2021", - "types": ["bun-types"] + "target": "ES2021" } } diff --git a/packages/upstash/package.json b/packages/upstash/package.json index ebda567f..68403d46 100644 --- a/packages/upstash/package.json +++ b/packages/upstash/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "license": "MIT", "main": "./src/index.ts", + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@upstash/qstash": "catalog:", "@upstash/redis": "catalog:" diff --git a/packages/utils/package.json b/packages/utils/package.json index 666520a4..23419d76 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@openstatus/assertions": "workspace:*", "@openstatus/regions": "workspace:*", @@ -14,6 +16,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/utils/src/ssrf.test.ts b/packages/utils/src/ssrf.test.ts index 387ad3a7..e687e0e9 100644 --- a/packages/utils/src/ssrf.test.ts +++ b/packages/utils/src/ssrf.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { assertSafeUrl, assertSafeUrlSync, safeUrlSchema } from "./ssrf"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4fcd3756..1c8e8803 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,9 +105,15 @@ catalogs: '@openpanel/sdk': specifier: 1.3.1 version: 1.3.1 + '@opentelemetry/exporter-logs-otlp-http': + specifier: 0.208.0 + version: 0.208.0 '@opentelemetry/resources': specifier: 2.7.1 version: 2.7.1 + '@opentelemetry/sdk-logs': + specifier: 0.208.0 + version: 0.208.0 '@opentelemetry/semantic-conventions': specifier: 1.41.1 version: 1.41.1 @@ -189,9 +195,9 @@ catalogs: '@scalar/hono-api-reference': specifier: 0.8.10 version: 0.8.10 - '@sentry/bun': - specifier: 10.53.1 - version: 10.53.1 + '@sentry/deno': + specifier: 10.61.0 + version: 10.61.0 '@sentry/nextjs': specifier: 10.53.1 version: 10.53.1 @@ -757,7 +763,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -921,7 +927,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) '@modelcontextprotocol/sdk': specifier: 'catalog:' version: 1.29.0(zod@4.1.13) @@ -1000,9 +1006,15 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils + '@opentelemetry/exporter-logs-otlp-http': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 @@ -1046,15 +1058,21 @@ importers: '@openstatus/locales': specifier: workspace:* version: link:../../packages/locales + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/validator': specifier: 'catalog:' version: 13.15.10 - bun-types: - specifier: 'catalog:' - version: 1.3.14 dotenv: specifier: 'catalog:' version: 16.6.1 @@ -1192,7 +1210,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-intl: specifier: 'catalog:' version: 4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) @@ -1251,6 +1269,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1269,9 +1293,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 shadcn: specifier: 'catalog:' version: 3.8.5(@types/node@24.12.4)(babel-plugin-macros@3.1.0)(typescript@5.9.3) @@ -1457,7 +1478,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-mdx-remote: specifier: 'catalog:' version: 6.0.0(@types/react@19.2.15)(react@19.2.6) @@ -1537,6 +1558,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1587,7 +1614,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) '@openstatus/db': specifier: workspace:* version: link:../../packages/db @@ -1654,15 +1681,21 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils + '@opentelemetry/exporter-logs-otlp-http': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 - '@sentry/bun': + '@sentry/deno': specifier: 'catalog:' - version: 10.53.1 + version: 10.61.0 '@upstash/qstash': specifier: 'catalog:' version: 2.11.0 @@ -1682,12 +1715,12 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -1834,6 +1867,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/react': specifier: 'catalog:' version: 19.2.15 @@ -1902,6 +1941,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/bcryptjs': specifier: 'catalog:' version: 3.0.0 @@ -1913,7 +1958,7 @@ importers: version: 0.31.10 next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) typescript: specifier: 'catalog:' version: 5.9.3 @@ -1945,6 +1990,12 @@ importers: '@react-email/ui': specifier: 'catalog:' version: 6.1.5(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -1973,9 +2024,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2008,6 +2062,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2037,12 +2097,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2065,12 +2128,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2093,12 +2159,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2136,6 +2205,9 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig @@ -2145,9 +2217,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2170,12 +2239,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2198,12 +2270,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2226,12 +2301,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2254,12 +2332,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2288,6 +2369,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2297,9 +2384,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2328,6 +2412,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2337,9 +2427,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2362,12 +2449,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2387,12 +2477,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2418,15 +2511,18 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 '@types/validator': specifier: 'catalog:' version: 13.15.10 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2449,12 +2545,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2468,7 +2567,7 @@ importers: specifier: 'catalog:' version: 1.2.0(@bufbuild/protobuf@2.12.0) '@connectrpc/connect': - specifier: ^2.1.1 + specifier: 'catalog:' version: 2.1.1(@bufbuild/protobuf@2.12.0) devDependencies: '@bufbuild/buf': @@ -2564,9 +2663,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2583,9 +2685,12 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' packages/subscriptions: dependencies: @@ -2611,9 +2716,28 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' + typescript: + specifier: 'catalog:' + version: 5.9.3 + + packages/test-utils: + dependencies: + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' + devDependencies: + '@openstatus/tsconfig': + specifier: workspace:* + version: link:../tsconfig typescript: specifier: 'catalog:' version: 5.9.3 @@ -2673,9 +2797,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - bun-types: - specifier: 'catalog:' - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2894,6 +3021,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2946,6 +3079,17 @@ packages: resolution: {integrity: sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==} hasBin: true + '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': + resolution: {integrity: sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==} + engines: {node: '>=18.0.0'} + + '@apm-js-collab/code-transformer@0.15.0': + resolution: {integrity: sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==} + hasBin: true + + '@apm-js-collab/tracing-hooks@0.10.0': + resolution: {integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==} + '@asamuzakjp/css-color@5.1.11': resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -4305,6 +4449,30 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsr/std__assert@1.0.19': + resolution: {integrity: sha512-pEj6RPkGbqlgRmyKwATp4cUs6+ijxtdrv3bq8v1d2I2CEcMEyPaO8cVKro61wGRDH4cNg8Zx6haztvK/9m7gkA==, tarball: https://npm.jsr.io/~/11/@jsr/std__assert/1.0.19.tgz} + + '@jsr/std__async@1.4.0': + resolution: {integrity: sha512-epQ5wsMrnAxeVtzmO9VviX14siVOSvF2o5dAm9qa6ajdWnWrrQ/oup7/Z2ctAOaxSOJbDWrfhgsenzHsODAogw==, tarball: https://npm.jsr.io/~/11/@jsr/std__async/1.4.0.tgz} + + '@jsr/std__data-structures@1.1.0': + resolution: {integrity: sha512-V/Lrzz3ZBT2ps09SbUuQKIDQ0Ac7qTTloCFNNF7r2MNoIzdz3xsW9+Vd+ZzgXFKdm46+XqBmkv0lpW/HzgRQfg==, tarball: https://npm.jsr.io/~/11/@jsr/std__data-structures/1.1.0.tgz} + + '@jsr/std__expect@1.0.19': + resolution: {integrity: sha512-t8BEISf1666L7dGDIG1nriYh0TQKoU+8mrx93zz+Kj40eov9wNKjKCX96x17p8I8bDcHby4wSv+7jy4+9W6IPg==, tarball: https://npm.jsr.io/~/11/@jsr/std__expect/1.0.19.tgz} + + '@jsr/std__fs@1.0.24': + resolution: {integrity: sha512-UunW2Rg++9sA74NJnYMGTsMVQgoFRAwPP02wRRohL0PQBNorbyxHiyCMRaxYQCtLepTLkC4nUyMtcwrGKqTR6g==, tarball: https://npm.jsr.io/~/11/@jsr/std__fs/1.0.24.tgz} + + '@jsr/std__internal@1.0.14': + resolution: {integrity: sha512-JT8b/t40WcR9q0GDwRZUooY7aXeXnFal8iidE/5TckdAFtvpVAsaJ71/Xgf1SfoChs41s6CZkuCYM8toaNgdvA==, tarball: https://npm.jsr.io/~/11/@jsr/std__internal/1.0.14.tgz} + + '@jsr/std__path@1.1.5': + resolution: {integrity: sha512-3z/0rfvMEz6qiiaZ3quFpEv8BbWQgcpd+ASX29WEdecyJsdPN9uViQf1VxIua265cmGCdICk0WghMjGFoNZ5Ig==, tarball: https://npm.jsr.io/~/11/@jsr/std__path/1.1.5.tgz} + + '@jsr/std__testing@1.0.19': + resolution: {integrity: sha512-maQIRFWIcTTWB7ITYIVbql1Q3KA9AsgR4/Ep2SfEq65V2SxQq52iLcFxuvX0azRp1leBCb8mBUXZr389SajY7Q==, tarball: https://npm.jsr.io/~/11/@jsr/std__testing/1.0.19.tgz} + '@libsql/client@0.17.4': resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==} @@ -4745,10 +4913,6 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.38.0': - resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} - engines: {node: '>=14'} - '@opentelemetry/semantic-conventions@1.41.1': resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} @@ -6276,10 +6440,6 @@ packages: resolution: {integrity: sha512-zXF373hzUOGzUOrqd8xb1U3LQi5uYC3mwv+z5OMKUUinQlu30tTWBs7ypy6YTchtix9QlYaHWlayUF8vBZ5UjA==} engines: {node: '>=18'} - '@sentry/bun@10.53.1': - resolution: {integrity: sha512-UCRUtEc3qLaanmp+9rKQi58d+weBdovytqW6d8ria1fkmxfvnVCYQqVQ0c/FLrGggqjqizO4b4WnLnuy/y/CXw==} - engines: {node: '>=18'} - '@sentry/bundler-plugin-core@5.3.0': resolution: {integrity: sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==} engines: {node: '>= 18'} @@ -6336,14 +6496,25 @@ packages: engines: {node: '>= 10'} hasBin: true + '@sentry/conventions@0.12.0': + resolution: {integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==} + engines: {node: '>=14'} + '@sentry/core@10.53.1': resolution: {integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==} engines: {node: '>=18'} + '@sentry/core@10.61.0': + resolution: {integrity: sha512-Edg8t2w45qEKiFnjeA6zRmU47R6la5FEMG+maZEOB2oTyJ+ujmh8LGaZ3G8aC0VdkKn8CXhHtDesze6oDc1oTA==} + engines: {node: '>=18'} + '@sentry/core@8.9.2': resolution: {integrity: sha512-ixm8NISFlPlEo3FjSaqmq4nnd13BRHoafwJ5MG+okCz6BKGZ1SexEggP42/QpGvDprUUHnfncG6WUMgcarr1zA==} engines: {node: '>=14.18'} + '@sentry/deno@10.61.0': + resolution: {integrity: sha512-TLs+Z+I5xWL0YdXtQ/LqJ7F1T/rRytxFlSJD1gXm5mx3T+wwNrni20N4XGnV1Bo8s8EB05HTjJXGzFb96CJDFw==} + '@sentry/nextjs@10.53.1': resolution: {integrity: sha512-pkwqrpAG//LtW5W1Odud0PLLT+rnjDjodUEbScULHVaZE6/Gt+WGBMZmtzpNM+UwhsN19/4PyO7ocLTx/IFrkQ==} engines: {node: '>=18'} @@ -6393,6 +6564,10 @@ packages: peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x + '@sentry/server-utils@10.61.0': + resolution: {integrity: sha512-IrOyMzlOyBkWtnVYb54sALf2f8WVqyyp7woRfHw8c3IMwUr5AskGOi7k2rjmUXO3Q0UkfHNVarexiEfo8ZqTsg==} + engines: {node: '>=18'} + '@sentry/types@8.9.2': resolution: {integrity: sha512-+LFOyQGl+zk5SZRGZD2MEURf7i5RHgP/mt3s85Rza+vz8M211WJ0YsjkIGUJFSY842nged5QLx4JysLaBlLymg==} engines: {node: '>=14.18'} @@ -6869,9 +7044,6 @@ packages: resolution: {integrity: sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==} deprecated: This is a stub types definition. bcryptjs provides its own type definitions, so you do not need this installed. - '@types/bun@1.3.14': - resolution: {integrity: sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw==} - '@types/caseless@0.12.5': resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} @@ -6969,9 +7141,6 @@ packages: '@types/mysql@2.15.27': resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} @@ -7858,10 +8027,6 @@ packages: resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} engines: {node: '>=20'} - dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} - engines: {node: '>=12'} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -8060,6 +8225,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -8122,6 +8290,10 @@ packages: engines: {node: '>=4'} hasBin: true + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -8180,10 +8352,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} - eventsource-parser@3.0.8: resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} engines: {node: '>=18.0.0'} @@ -8558,10 +8726,6 @@ packages: peerDependencies: hono: ^4.1.1 - hono@4.11.8: - resolution: {integrity: sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q==} - engines: {node: '>=16.9.0'} - hono@4.12.21: resolution: {integrity: sha512-uV63apnb0kyPtAUwoWgaGh9HyIFcv8lgmzPZSiTBQAFOFGIzka5EZ1dZocmGnn0XdX0+XTqJ6Tqv7selMuGLRQ==} engines: {node: '>=16.9.0'} @@ -9116,10 +9280,6 @@ packages: lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} - lru-cache@11.2.7: - resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} - engines: {node: 20 || >=22} - lru-cache@11.5.0: resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} engines: {node: 20 || >=22} @@ -9228,6 +9388,10 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meriyah@6.1.4: + resolution: {integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==} + engines: {node: '>=18.0.0'} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -9375,10 +9539,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -9423,11 +9583,6 @@ packages: nanoid-dictionary@5.0.0: resolution: {integrity: sha512-/iCyQHwt36XkaIvSE9fcC8p6DiMPCZMTSMj9UT56Cv6T7f5CuxvOMhpNncaNieQ4z4d32p7ruEtAfRsb7Ya8Gw==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -9438,11 +9593,6 @@ packages: engines: {node: ^18 || >=20} hasBin: true - nanoid@5.1.6: - resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} - engines: {node: ^18 || >=20} - hasBin: true - negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -9810,10 +9960,6 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} - path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} @@ -9918,10 +10064,6 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -10376,6 +10518,9 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semifies@1.0.0: + resolution: {integrity: sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -10686,9 +10831,6 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwind-merge@3.6.0: resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} @@ -10749,10 +10891,6 @@ packages: tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -11235,11 +11373,6 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -11343,7 +11476,31 @@ snapshots: ansis: 4.2.0 fzf: 0.5.2 package-manager-detector: 1.6.0 - tinyexec: 1.0.2 + tinyexec: 1.1.2 + + '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + es-module-lexer: 2.1.0 + magic-string: 0.30.21 + module-details-from-path: 1.0.4 + + '@apm-js-collab/code-transformer@0.15.0': + dependencies: + '@types/estree': 1.0.8 + astring: 1.9.0 + esquery: 1.7.0 + meriyah: 6.1.4 + semifies: 1.0.0 + source-map: 0.6.1 + + '@apm-js-collab/tracing-hooks@0.10.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color '@asamuzakjp/css-color@5.1.11': dependencies: @@ -12377,7 +12534,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 minimatch: 10.2.5 transitivePeerDependencies: - supports-color @@ -12460,9 +12617,9 @@ snapshots: pkce-challenge: 5.0.1 zod: 4.1.13 - '@hono/node-server@1.19.9(hono@4.11.8)': + '@hono/node-server@1.19.9(hono@4.12.21)': dependencies: - hono: 4.11.8 + hono: 4.12.21 '@hono/sentry@1.2.2(hono@4.12.21)': dependencies: @@ -12675,6 +12832,44 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@jsr/std__assert@1.0.19': + dependencies: + '@jsr/std__internal': 1.0.14 + + '@jsr/std__async@1.4.0': + dependencies: + '@jsr/std__data-structures': 1.1.0 + + '@jsr/std__data-structures@1.1.0': + dependencies: + '@jsr/std__assert': 1.0.19 + + '@jsr/std__expect@1.0.19': + dependencies: + '@jsr/std__assert': 1.0.19 + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + + '@jsr/std__fs@1.0.24': + dependencies: + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + + '@jsr/std__internal@1.0.14': {} + + '@jsr/std__path@1.1.5': + dependencies: + '@jsr/std__internal': 1.0.14 + + '@jsr/std__testing@1.0.19': + dependencies: + '@jsr/std__assert': 1.0.19 + '@jsr/std__async': 1.4.0 + '@jsr/std__data-structures': 1.1.0 + '@jsr/std__fs': 1.0.24 + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + '@libsql/client@0.17.4': dependencies: '@libsql/core': 0.17.4 @@ -12746,12 +12941,12 @@ snapshots: '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1)': + '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0)': dependencies: '@logtape/logtape': 2.1.1 - '@sentry/core': 10.53.1 + '@sentry/core': 10.61.0 '@mdx-js/mdx@3.1.1': dependencies: @@ -12791,17 +12986,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - '@hono/node-server': 1.19.9(hono@4.11.8) + '@hono/node-server': 1.19.9(hono@4.12.21) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.8 + hono: 4.12.21 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -12813,17 +13008,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@4.1.13)': dependencies: - '@hono/node-server': 1.19.9(hono@4.11.8) + '@hono/node-server': 1.19.9(hono@4.12.21) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.8 + hono: 4.12.21 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -12944,17 +13139,17 @@ snapshots: '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/exporter-logs-otlp-grpc@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -12991,7 +13186,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13000,7 +13195,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/connect': 3.4.38 transitivePeerDependencies: - supports-color @@ -13039,7 +13234,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13048,7 +13243,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color @@ -13057,7 +13252,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13065,7 +13260,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13074,7 +13269,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13089,7 +13284,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13098,7 +13293,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13106,7 +13301,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color @@ -13115,7 +13310,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/mysql': 2.15.27 transitivePeerDependencies: - supports-color @@ -13125,7 +13320,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) '@types/pg': 8.15.6 '@types/pg-pool': 2.0.7 @@ -13136,7 +13331,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color @@ -13197,13 +13392,13 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -13223,16 +13418,14 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 - - '@opentelemetry/semantic-conventions@1.38.0': {} + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/semantic-conventions@1.41.1': {} @@ -14483,7 +14676,7 @@ snapshots: '@scalar/types@0.1.16': dependencies: '@scalar/openapi-types': 0.2.3 - nanoid: 5.1.6 + nanoid: 5.1.11 zod: 3.24.1 '@schummar/icu-type-parser@1.21.5': {} @@ -14523,20 +14716,12 @@ snapshots: '@sentry-internal/replay-canvas': 10.53.1 '@sentry/core': 10.53.1 - '@sentry/bun@10.53.1': - dependencies: - '@sentry/core': 10.53.1 - '@sentry/node': 10.53.1 - transitivePeerDependencies: - - '@opentelemetry/exporter-trace-otlp-http' - - supports-color - '@sentry/bundler-plugin-core@5.3.0': dependencies: '@babel/core': 7.28.5 '@sentry/babel-plugin-component-annotate': 5.3.0 '@sentry/cli': 2.58.5 - dotenv: 16.3.1 + dotenv: 16.6.1 find-up: 5.0.0 glob: 13.0.6 magic-string: 0.30.21 @@ -14588,13 +14773,25 @@ snapshots: - encoding - supports-color + '@sentry/conventions@0.12.0': {} + '@sentry/core@10.53.1': {} + '@sentry/core@10.61.0': {} + '@sentry/core@8.9.2': dependencies: '@sentry/types': 8.9.2 '@sentry/utils': 8.9.2 + '@sentry/deno@10.61.0': + dependencies: + '@opentelemetry/api': 1.9.1 + '@sentry/core': 10.61.0 + '@sentry/server-utils': 10.61.0 + transitivePeerDependencies: + - supports-color + '@sentry/nextjs@10.53.1(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.103.0(@swc/core@1.15.18))': dependencies: '@opentelemetry/api': 1.9.1 @@ -14681,6 +14878,17 @@ snapshots: '@sentry/core': 10.53.1 react: 19.2.6 + '@sentry/server-utils@10.61.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + '@apm-js-collab/code-transformer-bundler-plugins': 0.5.0 + '@apm-js-collab/tracing-hooks': 0.10.0 + '@sentry/conventions': 0.12.0 + '@sentry/core': 10.61.0 + magic-string: 0.30.21 + transitivePeerDependencies: + - supports-color + '@sentry/types@8.9.2': {} '@sentry/utils@8.9.2': @@ -14746,7 +14954,7 @@ snapshots: dependencies: '@slack/logger': 4.0.1 '@slack/types': 2.21.1 - '@types/node': 24.10.1 + '@types/node': 24.12.4 '@types/retry': 0.12.0 axios: 1.16.1 eventemitter3: 5.0.1 @@ -15118,10 +15326,6 @@ snapshots: dependencies: bcryptjs: 3.0.3 - '@types/bun@1.3.14': - dependencies: - bun-types: 1.3.14 - '@types/caseless@0.12.5': {} '@types/connect@3.4.38': @@ -15222,10 +15426,6 @@ snapshots: dependencies: '@types/node': 24.12.4 - '@types/node@24.10.1': - dependencies: - undici-types: 7.16.0 - '@types/node@24.12.4': dependencies: undici-types: 7.16.0 @@ -16105,8 +16305,6 @@ snapshots: dependencies: type-fest: 5.2.0 - dotenv@16.3.1: {} - dotenv@16.6.1: {} dotenv@17.2.4: {} @@ -16221,6 +16419,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -16354,6 +16554,10 @@ snapshots: esprima@4.0.1: {} + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -16409,13 +16613,11 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.6: {} - eventsource-parser@3.0.8: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 execa@5.1.1: dependencies: @@ -16721,9 +16923,9 @@ snapshots: foreground-child: 3.3.1 jackspeak: 4.1.1 minimatch: 10.2.5 - minipass: 7.1.2 + minipass: 7.1.3 package-json-from-dist: 1.0.1 - path-scurry: 2.0.1 + path-scurry: 2.0.2 glob@13.0.6: dependencies: @@ -16937,8 +17139,6 @@ snapshots: dependencies: hono: 4.12.21 - hono@4.11.8: {} - hono@4.12.21: {} html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): @@ -17347,7 +17547,7 @@ snapshots: typescript: 5.9.3 unbash: 2.2.0 yaml: 2.9.0 - zod: 4.1.13 + zod: 4.4.3 launder@1.7.1: dependencies: @@ -17478,8 +17678,6 @@ snapshots: lower-case@1.1.4: {} - lru-cache@11.2.7: {} - lru-cache@11.5.0: {} lru-cache@5.1.1: @@ -17681,6 +17879,8 @@ snapshots: merge2@1.4.1: {} + meriyah@6.1.4: {} + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -17980,8 +18180,6 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} - minipass@7.1.3: {} mitt@3.0.1: {} @@ -18033,14 +18231,10 @@ snapshots: nanoid-dictionary@5.0.0: {} - nanoid@3.3.11: {} - nanoid@3.3.12: {} nanoid@5.1.11: {} - nanoid@5.1.6: {} - negotiator@0.6.3: {} negotiator@1.0.0: {} @@ -18051,7 +18245,7 @@ snapshots: neverthrow@7.2.0: {} - next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): + next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): dependencies: '@auth/core': 0.41.2 next: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -18238,7 +18432,7 @@ snapshots: openapi3-ts@4.5.0: dependencies: - yaml: 2.8.1 + yaml: 2.9.0 ora@4.1.1: dependencies: @@ -18471,11 +18665,6 @@ snapshots: path-parse@1.0.7: {} - path-scurry@2.0.1: - dependencies: - lru-cache: 11.2.7 - minipass: 7.1.2 - path-scurry@2.0.2: dependencies: lru-cache: 11.5.0 @@ -18534,7 +18723,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3)): dependencies: lilconfig: 3.1.3 - yaml: 2.8.1 + yaml: 2.9.0 optionalDependencies: postcss: 8.5.15 ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3) @@ -18551,7 +18740,7 @@ snapshots: postcss@8.4.31: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -18561,12 +18750,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -19174,7 +19357,7 @@ snapshots: is-plain-object: 5.0.0 launder: 1.7.1 parse-srcset: 1.0.2 - postcss: 8.5.6 + postcss: 8.5.15 sax@1.4.3: {} @@ -19204,6 +19387,8 @@ snapshots: dependencies: parseley: 0.12.1 + semifies@1.0.0: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -19270,12 +19455,12 @@ snapshots: node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 - postcss: 8.5.6 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 prompts: 2.4.2 recast: 0.23.11 stringify-object: 5.0.0 - tailwind-merge: 3.3.1 + tailwind-merge: 3.6.0 ts-morph: 26.0.0 tsconfig-paths: 4.2.0 validate-npm-package-name: 7.0.2 @@ -19530,7 +19715,7 @@ snapshots: stripe@13.11.0: dependencies: - '@types/node': 24.10.1 + '@types/node': 24.12.4 qs: 6.14.0 strnum@2.3.0: {} @@ -19610,8 +19795,6 @@ snapshots: tagged-tag@1.0.0: {} - tailwind-merge@3.3.1: {} - tailwind-merge@3.6.0: {} tailwindcss-animate@1.0.7(tailwindcss@4.3.0): @@ -19667,8 +19850,6 @@ snapshots: tinycolor2@1.6.0: {} - tinyexec@1.0.2: {} - tinyexec@1.1.2: {} tinyglobby@0.2.15: @@ -20001,7 +20182,7 @@ snapshots: vfile-matter@5.0.1: dependencies: vfile: 6.0.3 - yaml: 2.8.1 + yaml: 2.9.0 vfile-message@3.1.4: dependencies: @@ -20179,8 +20360,6 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} - yaml@2.9.0: {} yargs-parser@21.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c259c6f1..a61cf776 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,10 +2,8 @@ packages: - apps/* - packages/**/* - packages/config/* - trustPolicy: off -minimumReleaseAge: 1440 # 1 day (default) - +minimumReleaseAge: 1440 allowBuilds: "@bufbuild/buf": true "@parcel/watcher": true @@ -17,9 +15,7 @@ allowBuilds: msw: true protobufjs: true sharp: true - autoInstallPeers: true - catalog: "@ai-sdk/anthropic": 1.2.12 "@ai-sdk/react": 3.0.190 @@ -46,7 +42,6 @@ catalog: "@dnd-kit/sortable": 10.0.0 "@dnd-kit/utilities": 3.2.2 "@fontsource-variable/inter": 5.2.8 - # Pinned to 4.0.1 — 4.1.0+ ships an ESM build that reads config JSON via fs.readFileSync, breaking `bun build --compile` in apps/workflows "@google-cloud/tasks": 4.0.1 "@hono/mcp": 0.2.5 "@hono/sentry": 1.2.2 @@ -63,7 +58,9 @@ catalog: "@openpanel/astro": 1.4.1 "@openpanel/nextjs": 1.5.1 "@openpanel/sdk": 1.3.1 + "@opentelemetry/exporter-logs-otlp-http": 0.208.0 "@opentelemetry/resources": 2.7.1 + "@opentelemetry/sdk-logs": 0.208.0 "@opentelemetry/semantic-conventions": 1.41.1 "@radix-ui/react-accordion": 1.2.12 "@radix-ui/react-alert-dialog": 1.1.15 @@ -92,6 +89,7 @@ catalog: "@react-email/ui": 6.1.5 "@scalar/hono-api-reference": 0.8.10 "@sentry/bun": 10.53.1 + "@sentry/deno": 10.61.0 "@sentry/nextjs": 10.53.1 "@slack/web-api": 7.16.0 "@stripe/stripe-js": 2.4.0 @@ -107,7 +105,6 @@ catalog: "@tanstack/react-table": 8.21.3 "@trpc/client": 11.17.0 "@trpc/next": 11.17.0 - "@types/react": 19.2.15 "@trpc/react-query": 11.17.0 "@trpc/server": 11.17.0 "@trpc/tanstack-react-query": 11.17.0 @@ -116,6 +113,7 @@ catalog: "@types/dom-speech-recognition": 0.0.6 "@types/luxon": 3.7.1 "@types/node": 24.12.4 + "@types/react": 19.2.15 "@types/react-dom": 19.2.3 "@types/sanitize-html": 2.16.1 "@types/validator": 13.15.10 @@ -199,9 +197,9 @@ catalog: stripe: 13.11.0 sugar-high: 0.9.5 superjson: 2.2.6 + tailwind-merge: 3.6.0 tailwindcss: 4.3.0 tailwindcss-animate: 1.0.7 - tailwind-merge: 3.6.0 tsup: 7.2.0 tw-animate-css: 1.4.0 typescript: 5.9.3 diff --git a/turbo.json b/turbo.json index 7d319815..e6a28cd2 100644 --- a/turbo.json +++ b/turbo.json @@ -32,6 +32,7 @@ "outputs": [".next/**", "!.next/cache/**", "dist/**"] }, "lint": {}, + "check": {}, "dev": { "cache": false }, -- 2.51.2 From b8f95f82963a20d26d1a09e95f6b3e6ed2364ab0 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Tue, 30 Jun 2026 17:19:33 +0200 Subject: [PATCH 08/69] fix build for railway (#2324) --- apps/workflows/Dockerfile | 128 ++++++++++++++----- apps/workflows/dofigen.lock | 243 +++++++++++++++++++++--------------- apps/workflows/dofigen.yml | 69 +++++----- 3 files changed, 271 insertions(+), 169 deletions(-) diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index 7da4a413..c17729fc 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -9,39 +9,103 @@ LABEL \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ +COPY \ + --link \ + "pnpm-workspace.yaml" "/app/pnpm-workspace.yaml" +COPY \ + --link \ + "pnpm-lock.yaml" "/app/pnpm-lock.yaml" +COPY \ + --link \ + "package.json" "/app/package.json" +COPY \ + --link \ + "apps/workflows/package.json" "/app/apps/workflows/package.json" +COPY \ + --link \ + "packages/assertions/package.json" "/app/packages/assertions/package.json" +COPY \ + --link \ + "packages/db/package.json" "/app/packages/db/package.json" +COPY \ + --link \ + "packages/emails/package.json" "/app/packages/emails/package.json" +COPY \ + --link \ + "packages/notifications/base/package.json" "/app/packages/notifications/base/package.json" +COPY \ + --link \ + "packages/notifications/discord/package.json" "/app/packages/notifications/discord/package.json" +COPY \ + --link \ + "packages/notifications/email/package.json" "/app/packages/notifications/email/package.json" +COPY \ + --link \ + "packages/notifications/grafana-oncall/package.json" "/app/packages/notifications/grafana-oncall/package.json" +COPY \ + --link \ + "packages/notifications/google-chat/package.json" "/app/packages/notifications/google-chat/package.json" +COPY \ + --link \ + "packages/notifications/ms-teams/package.json" "/app/packages/notifications/ms-teams/package.json" +COPY \ + --link \ + "packages/notifications/ntfy/package.json" "/app/packages/notifications/ntfy/package.json" +COPY \ + --link \ + "packages/notifications/opsgenie/package.json" "/app/packages/notifications/opsgenie/package.json" +COPY \ + --link \ + "packages/notifications/pagerduty/package.json" "/app/packages/notifications/pagerduty/package.json" +COPY \ + --link \ + "packages/notifications/slack/package.json" "/app/packages/notifications/slack/package.json" +COPY \ + --link \ + "packages/notifications/telegram/package.json" "/app/packages/notifications/telegram/package.json" +COPY \ + --link \ + "packages/notifications/bird-whatsapp/package.json" "/app/packages/notifications/bird-whatsapp/package.json" +COPY \ + --link \ + "packages/notifications/twillio-sms/package.json" "/app/packages/notifications/twillio-sms/package.json" +COPY \ + --link \ + "packages/notifications/webhook/package.json" "/app/packages/notifications/webhook/package.json" +COPY \ + --link \ + "packages/importers/package.json" "/app/packages/importers/package.json" +COPY \ + --link \ + "packages/regions/package.json" "/app/packages/regions/package.json" +COPY \ + --link \ + "packages/services/package.json" "/app/packages/services/package.json" +COPY \ + --link \ + "packages/subscriptions/package.json" "/app/packages/subscriptions/package.json" +COPY \ + --link \ + "packages/utils/package.json" "/app/packages/utils/package.json" +COPY \ + --link \ + "packages/tsconfig/package.json" "/app/packages/tsconfig/package.json" +COPY \ + --link \ + "packages/tinybird/package.json" "/app/packages/tinybird/package.json" +COPY \ + --link \ + "packages/upstash/package.json" "/app/packages/upstash/package.json" +COPY \ + --link \ + "packages/theme-store/package.json" "/app/packages/theme-store/package.json" +COPY \ + --link \ + "packages/locales/package.json" "/app/packages/locales/package.json" +COPY \ + --link \ + "packages/status-fetcher/package.json" "/app/packages/status-fetcher/package.json" RUN \ - --mount=type=bind,target=pnpm-workspace.yaml,source=pnpm-workspace.yaml \ - --mount=type=bind,target=pnpm-lock.yaml,source=pnpm-lock.yaml \ - --mount=type=bind,target=package.json,source=package.json \ - --mount=type=bind,target=apps/workflows/package.json,source=apps/workflows/package.json \ - --mount=type=bind,target=packages/assertions/package.json,source=packages/assertions/package.json \ - --mount=type=bind,target=packages/db/package.json,source=packages/db/package.json \ - --mount=type=bind,target=packages/emails/package.json,source=packages/emails/package.json \ - --mount=type=bind,target=packages/notifications/base/package.json,source=packages/notifications/base/package.json \ - --mount=type=bind,target=packages/notifications/discord/package.json,source=packages/notifications/discord/package.json \ - --mount=type=bind,target=packages/notifications/email/package.json,source=packages/notifications/email/package.json \ - --mount=type=bind,target=packages/notifications/grafana-oncall/package.json,source=packages/notifications/grafana-oncall/package.json \ - --mount=type=bind,target=packages/notifications/google-chat/package.json,source=packages/notifications/google-chat/package.json \ - --mount=type=bind,target=packages/notifications/ms-teams/package.json,source=packages/notifications/ms-teams/package.json \ - --mount=type=bind,target=packages/notifications/ntfy/package.json,source=packages/notifications/ntfy/package.json \ - --mount=type=bind,target=packages/notifications/opsgenie/package.json,source=packages/notifications/opsgenie/package.json \ - --mount=type=bind,target=packages/notifications/pagerduty/package.json,source=packages/notifications/pagerduty/package.json \ - --mount=type=bind,target=packages/notifications/slack/package.json,source=packages/notifications/slack/package.json \ - --mount=type=bind,target=packages/notifications/telegram/package.json,source=packages/notifications/telegram/package.json \ - --mount=type=bind,target=packages/notifications/bird-whatsapp/package.json,source=packages/notifications/bird-whatsapp/package.json \ - --mount=type=bind,target=packages/notifications/twillio-sms/package.json,source=packages/notifications/twillio-sms/package.json \ - --mount=type=bind,target=packages/notifications/webhook/package.json,source=packages/notifications/webhook/package.json \ - --mount=type=bind,target=packages/importers/package.json,source=packages/importers/package.json \ - --mount=type=bind,target=packages/regions/package.json,source=packages/regions/package.json \ - --mount=type=bind,target=packages/services/package.json,source=packages/services/package.json \ - --mount=type=bind,target=packages/subscriptions/package.json,source=packages/subscriptions/package.json \ - --mount=type=bind,target=packages/utils/package.json,source=packages/utils/package.json \ - --mount=type=bind,target=packages/tsconfig/package.json,source=packages/tsconfig/package.json \ - --mount=type=bind,target=packages/tinybird/package.json,source=packages/tinybird/package.json \ - --mount=type=bind,target=packages/upstash/package.json,source=packages/upstash/package.json \ - --mount=type=bind,target=packages/theme-store/package.json,source=packages/theme-store/package.json \ - --mount=type=bind,target=packages/locales/package.json,source=packages/locales/package.json \ - --mount=type=bind,target=packages/status-fetcher/package.json,source=packages/status-fetcher/package.json \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ < Date: Tue, 30 Jun 2026 17:37:21 +0200 Subject: [PATCH 09/69] fix railway build (#2325) --- apps/workflows/Dockerfile | 2 +- apps/workflows/dofigen.lock | 90 ++++++++++++++++++++----------------- apps/workflows/dofigen.yml | 6 ++- 3 files changed, 54 insertions(+), 44 deletions(-) diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index c17729fc..1b403140 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -106,7 +106,7 @@ COPY \ --link \ "packages/status-fetcher/package.json" "/app/packages/status-fetcher/package.json" RUN \ - --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ + --mount=type=cache,target=/root/.local/share/pnpm/store,id=s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store,sharing=locked \ <{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' - - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts - - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts - - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs - - mkdir -p /app/data install: fromImage: path: node digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc label: + org.opencontainers.image.base.digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc org.opencontainers.image.stage: install org.opencontainers.image.base.name: docker.io/node:24-slim - org.opencontainers.image.base.digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc workdir: /app/ copy: - paths: @@ -156,20 +122,56 @@ effective: | - corepack enable pnpm - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - - target: /root/.local/share/pnpm/store + - id: s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store + target: /root/.local/share/pnpm/store + sharing: locked + build: + fromImage: + path: denoland/deno + digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + label: + org.opencontainers.image.base.digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + org.opencontainers.image.stage: build + org.opencontainers.image.base.name: docker.io/denoland/deno:2.9.0 + workdir: /app/apps/workflows + env: + NODE_ENV: production + copy: + - paths: + - . + target: /app/ + - fromBuilder: install + paths: + - /app/node_modules + target: /app/node_modules + - fromBuilder: install + paths: + - /app/apps/workflows/node_modules + target: /app/apps/workflows/node_modules + - fromBuilder: install + paths: + - /app/packages + target: /app/packages + run: + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data fromImage: host: registry.access.redhat.com port: 443 path: hi/curl digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 label: - org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus - io.dofigen.version: 2.8.0 - org.opencontainers.image.authors: OpenStatus Team - org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.title: OpenStatus Workflows + org.opencontainers.image.vendor: OpenStatus + org.opencontainers.image.authors: OpenStatus Team org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus org.opencontainers.image.base.digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus + io.dofigen.version: 2.8.0 user: user: '1000' group: '1000' @@ -206,7 +208,7 @@ images: digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc resources: dofigen.yml: - hash: 6e664d2b4d9649d3d56b5e2f244d826f1c4fc9f9633191d7ed38bae6ea4e12d2 + hash: 416be0bdb8fcc1bc717f637b38cfa3b095b5277c947ad7e55d51b98194fdd856 content: | ignore: - node_modules @@ -268,7 +270,11 @@ resources: - corepack enable pnpm - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - - /root/.local/share/pnpm/store + # Railway scopes cache mounts per service: the id must be literally + # s/- (env vars aren't allowed in the id). + - id: s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store + target: /root/.local/share/pnpm/store + sharing: locked # Stage 4: Build application (compile to binary with Deno) build: diff --git a/apps/workflows/dofigen.yml b/apps/workflows/dofigen.yml index 37f21bee..a49cf4a8 100644 --- a/apps/workflows/dofigen.yml +++ b/apps/workflows/dofigen.yml @@ -58,7 +58,11 @@ builders: - corepack enable pnpm - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - - /root/.local/share/pnpm/store + # Railway scopes cache mounts per service: the id must be literally + # s/- (env vars aren't allowed in the id). + - id: s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store + target: /root/.local/share/pnpm/store + sharing: locked # Stage 4: Build application (compile to binary with Deno) build: -- 2.51.2 From f0d315ef0b2d11725f0b9e3818bfb066191bd5b0 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Tue, 30 Jun 2026 17:40:17 +0200 Subject: [PATCH 10/69] fix build for railway (#2326) --- apps/workflows/Dockerfile | 2 +- apps/workflows/dofigen.lock | 16 ++++++++-------- apps/workflows/dofigen.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index 1b403140..348eacb7 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -106,7 +106,7 @@ COPY \ --link \ "packages/status-fetcher/package.json" "/app/packages/status-fetcher/package.json" RUN \ - --mount=type=cache,target=/root/.local/share/pnpm/store,id=s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store,sharing=locked \ + --mount=type=cache,target=/root/.local/share/pnpm/store,id=s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store,sharing=locked \ <- (env vars aren't allowed in the id). - - id: s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store + - id: s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store target: /root/.local/share/pnpm/store sharing: locked diff --git a/apps/workflows/dofigen.yml b/apps/workflows/dofigen.yml index a49cf4a8..bfe48b33 100644 --- a/apps/workflows/dofigen.yml +++ b/apps/workflows/dofigen.yml @@ -60,7 +60,7 @@ builders: cache: # Railway scopes cache mounts per service: the id must be literally # s/- (env vars aren't allowed in the id). - - id: s/3a5c916e-f3f2-4f35-ba0e-3c8511b6f9a3-/root/.local/share/pnpm/store + - id: s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store target: /root/.local/share/pnpm/store sharing: locked -- 2.51.2 From a07b8a666a1342e82f46d626264335ce17aefd05 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:52:16 +0200 Subject: [PATCH 11/69] revert: roll back Deno build migration (#2323-#2326) (#2328) Reverts the Deno build migration and its Railway build follow-up fixes, restoring the server and workflows apps to the prior Bun/Node toolchain. Co-authored-by: Claude Opus 4.8 --- .github/workflows/check.yml | 39 -- .github/workflows/dx.yml | 6 +- .github/workflows/test.yml | 8 +- apps/dashboard/env.ts | 3 +- apps/screenshot-service/package.json | 1 - apps/server/.gitignore | 4 - apps/server/Dockerfile | 30 +- apps/server/bunfig.toml | 2 + apps/server/deno.jsonc | 6 - apps/server/docker-compose.yaml | 2 - apps/server/dofigen.lock | 126 ++-- apps/server/dofigen.yml | 28 +- apps/server/env.ts | 3 +- apps/server/package.json | 18 +- apps/server/src/index.ts | 58 +- .../libs/middlewares/require-scope.test.ts | 4 +- .../src/libs/middlewares/validate-key.test.ts | 3 +- .../src/libs/test/doubles/analytics.mock.ts | 26 - .../src/libs/test/doubles/page-urls.mock.ts | 10 - .../src/libs/test/doubles/slack-agent.mock.ts | 8 - .../src/libs/test/doubles/slack-test-state.ts | 33 - .../libs/test/doubles/slack-web-api.mock.ts | 26 - apps/server/src/libs/test/doubles/state.ts | 49 -- .../libs/test/doubles/subscriptions.mock.ts | 11 - .../src/libs/test/doubles/tinybird.mock.ts | 59 -- .../src/libs/test/doubles/upstash.mock.ts | 36 - .../test/doubles/workspace-resolver.mock.ts | 6 - apps/server/src/libs/test/preload.ts | 3 +- apps/server/src/routes/mcp/adapter.test.ts | 4 +- apps/server/src/routes/mcp/adapter.ts | 2 +- apps/server/src/routes/mcp/handler.test.ts | 7 +- apps/server/src/routes/mcp/index.ts | 7 +- .../routes/mcp/tools/register-scoped.test.ts | 4 +- .../server/src/routes/mcp/tools/tools.test.ts | 4 +- apps/server/src/routes/public/status.test.ts | 9 +- apps/server/src/routes/public/status.ts | 2 +- apps/server/src/routes/rpc/adapter.test.ts | 4 +- .../maintenance/__tests__/maintenance.test.ts | 223 +++--- .../monitor/__tests__/monitor.test.ts | 50 +- .../monitor/converters/regions.test.ts | 20 +- .../src/routes/rpc/handlers/monitor/index.ts | 5 +- .../handlers/monitor/response-logs.test.ts | 4 +- .../__tests__/notification.test.ts | 6 +- .../status-page/__tests__/status-page.test.ts | 9 +- .../__tests__/status-report.test.ts | 86 +-- .../interceptors/__tests__/tracking.test.ts | 43 +- .../src/routes/rpc/interceptors/auth.ts | 2 +- apps/server/src/routes/slack/blocks.test.ts | 4 +- .../routes/slack/confirmation-store.test.ts | 3 +- apps/server/src/routes/slack/handler.test.ts | 150 ++-- apps/server/src/routes/slack/index.test.ts | 3 +- .../src/routes/slack/interactions.test.ts | 72 +- apps/server/src/routes/slack/oauth.test.ts | 3 +- .../slack/presenters/presenters.test.ts | 17 +- .../src/routes/slack/registry-runner.test.ts | 4 +- .../src/routes/slack/system-prompt.test.ts | 3 +- apps/server/src/routes/slack/verify.test.ts | 3 +- .../src/routes/v1/check/http/post.test.ts | 4 +- .../src/routes/v1/incidents/get.test.ts | 3 +- .../src/routes/v1/incidents/get_all.test.ts | 4 +- .../src/routes/v1/incidents/put.test.ts | 3 +- .../src/routes/v1/maintenances/get.test.ts | 3 +- .../routes/v1/maintenances/get_all.test.ts | 4 +- .../src/routes/v1/maintenances/post.test.ts | 8 +- .../src/routes/v1/maintenances/put.test.ts | 46 +- .../src/routes/v1/monitors/delete.test.ts | 3 +- .../server/src/routes/v1/monitors/get.test.ts | 3 +- .../src/routes/v1/monitors/get_all.test.ts | 3 +- .../src/routes/v1/monitors/post.test.ts | 5 +- .../src/routes/v1/monitors/post_dns.test.ts | 3 +- .../src/routes/v1/monitors/post_http.test.ts | 3 +- .../src/routes/v1/monitors/post_tcp.test.ts | 3 +- .../server/src/routes/v1/monitors/put.test.ts | 3 +- .../src/routes/v1/monitors/put_dns.test.ts | 3 +- .../src/routes/v1/monitors/put_http.test.ts | 3 +- .../src/routes/v1/monitors/put_tcp.test.ts | 3 +- .../routes/v1/monitors/results/get.test.ts | 36 +- .../src/routes/v1/monitors/run/post.test.ts | 87 ++- .../routes/v1/monitors/summary/get.test.ts | 6 +- .../src/routes/v1/monitors/summary/get.ts | 5 + .../routes/v1/monitors/trigger/post.test.ts | 4 +- .../src/routes/v1/notifications/get.test.ts | 3 +- .../routes/v1/notifications/get_all.test.ts | 4 +- .../src/routes/v1/notifications/post.test.ts | 4 +- .../routes/v1/pageSubscribers/post.test.ts | 4 +- apps/server/src/routes/v1/pages/get.test.ts | 3 +- .../src/routes/v1/pages/get_all.test.ts | 4 +- apps/server/src/routes/v1/pages/post.test.ts | 4 +- apps/server/src/routes/v1/pages/put.test.ts | 3 +- .../routes/v1/statusReportUpdates/get.test.ts | 3 +- .../v1/statusReportUpdates/post.test.ts | 7 +- .../routes/v1/statusReports/delete.test.ts | 3 +- .../src/routes/v1/statusReports/get.test.ts | 3 +- .../routes/v1/statusReports/get_all.test.ts | 4 +- .../src/routes/v1/statusReports/post.test.ts | 8 +- .../subscriber-filtering.integration.test.ts | 4 +- .../v1/statusReports/update/post.test.ts | 3 +- .../routes/v1/statusReports/update/post.ts | 3 +- apps/server/src/routes/v1/whoami/get.test.ts | 3 +- apps/server/src/serve.ts | 13 - apps/server/src/utils/audit-log.ts | 2 +- apps/server/test.importmap.json | 16 - apps/server/tsconfig.json | 10 +- apps/status-page/env.ts | 3 +- apps/status-page/package.json | 7 +- apps/status-page/src/app/(public)/client.tsx | 17 +- apps/status-page/src/app/(public)/layout.tsx | 6 +- .../[domain]/[locale]/(auth)/layout.tsx | 6 +- .../login/_components/section-magic-link.tsx | 12 +- .../login/_components/section-password.tsx | 8 +- .../[domain]/[locale]/(auth)/login/actions.ts | 4 +- .../[domain]/[locale]/(auth)/login/page.tsx | 3 +- .../[locale]/(auth)/restricted/page.tsx | 2 +- .../[domain]/[locale]/(public)/client.tsx | 22 +- .../(public)/events/(list)/layout.tsx | 2 +- .../[locale]/(public)/events/(list)/page.tsx | 9 +- .../events/(view)/maintenance/[id]/layout.tsx | 8 +- .../events/(view)/maintenance/[id]/page.tsx | 10 +- .../events/(view)/report/[id]/layout.tsx | 8 +- .../events/(view)/report/[id]/page.tsx | 12 +- .../[locale]/(public)/events/layout.tsx | 2 +- .../[locale]/(public)/feed/[type]/route.ts | 6 +- .../[locale]/(public)/feed/json/route.ts | 4 +- .../[domain]/[locale]/(public)/layout.tsx | 6 +- .../[locale]/(public)/llms.txt/route.ts | 9 +- .../(public)/manage/[token]/layout.tsx | 6 +- .../[locale]/(public)/manage/[token]/page.tsx | 10 +- .../[locale]/(public)/manage/layout.tsx | 2 +- .../(public)/monitors/[id]/layout.tsx | 2 +- .../[locale]/(public)/monitors/[id]/page.tsx | 21 +- .../[locale]/(public)/monitors/layout.tsx | 2 +- .../[locale]/(public)/monitors/page.tsx | 6 +- .../[locale]/(public)/search-params.ts | 2 +- .../(public)/unsubscribe/[token]/layout.tsx | 2 +- .../(public)/unsubscribe/[token]/page.tsx | 4 +- .../(public)/verify/[token]/layout.tsx | 2 +- .../[locale]/(public)/verify/[token]/page.tsx | 4 +- .../[domain]/[locale]/layout.tsx | 6 +- .../src/app/(status-page)/[domain]/layout.tsx | 14 +- .../src/app/api/auth/[...nextauth]/route.ts | 2 +- .../src/app/api/markdown/[[...path]]/route.ts | 12 +- .../src/app/api/status/[[...path]]/route.ts | 16 +- .../src/app/api/trpc/edge/[trpc]/route.ts | 4 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 4 +- apps/status-page/src/app/global-error.tsx | 2 +- apps/status-page/src/app/layout.tsx | 5 +- apps/status-page/src/app/not-found.tsx | 4 +- apps/status-page/src/app/robots.ts | 6 +- apps/status-page/src/app/sitemap.ts | 8 +- .../chart/chart-area-percentiles.tsx | 3 +- .../src/components/chart/chart-bar-uptime.tsx | 3 +- .../components/chart/chart-legend-badge.tsx | 2 +- .../components/chart/chart-line-regions.tsx | 5 +- .../src/components/common/link.tsx | 2 +- .../src/components/date-fns-provider.tsx | 2 +- .../src/components/date-picker.tsx | 4 +- .../forms/form-manage-subscription.tsx | 2 +- .../components/forms/form-subscribe-email.tsx | 2 +- .../i18n/status-blocks-provider.tsx | 2 +- .../src/components/layout/embed-shell.tsx | 2 +- .../src/components/locale-switcher.tsx | 2 +- .../status-page/src/components/nav/footer.tsx | 12 +- .../status-page/src/components/nav/header.tsx | 8 +- .../src/components/password-wrapper.tsx | 2 +- .../status-page/floating-button.tsx | 2 +- .../components/status-page/floating-theme.tsx | 3 +- .../src/components/status-page/status-bar.tsx | 4 +- .../components/status-page/status-blank.tsx | 2 +- .../status-page/status-calendar.tsx | 6 +- .../components/status-page/status-events.tsx | 2 +- .../components/status-page/status-feed.tsx | 7 +- .../components/status-page/status-updates.tsx | 6 +- .../src/components/themes/theme-provider.tsx | 4 +- .../src/components/themes/theme-sidebar.tsx | 4 +- .../ui/data-table/data-table-toolbar.tsx | 4 +- .../src/content/markdown/generators.test.ts | 3 +- .../src/content/markdown/match-route.test.ts | 3 +- .../src/content/status-json.test.ts | 4 +- .../src/content/status-vocab.test.ts | 3 +- apps/status-page/src/data/metrics.client.ts | 5 +- apps/status-page/src/hooks/use-embed.ts | 4 +- .../src/hooks/use-pathname-prefix.ts | 6 +- .../src/lib/alternates-metadata.ts | 4 +- apps/status-page/src/lib/alternates.test.ts | 3 +- apps/status-page/src/lib/auth/index.ts | 5 +- apps/status-page/src/lib/auth/providers.ts | 3 +- apps/status-page/src/lib/formatter.test.ts | 3 +- .../src/lib/http/client-ip.test.ts | 3 +- apps/status-page/src/lib/http/etag.test.ts | 3 +- .../src/lib/http/markdown-response.test.ts | 9 +- .../src/lib/http/markdown-response.ts | 6 +- .../proxy/apply-page-locale-override.test.ts | 3 +- .../src/lib/proxy/build-external-path.test.ts | 3 +- .../src/lib/proxy/compose-page-action.test.ts | 4 +- .../src/lib/proxy/detect-markdown.test.ts | 3 +- .../lib/proxy/evaluate-markdown-gate.test.ts | 3 +- .../src/lib/proxy/is-ip-allowed.test.ts | 3 +- .../lib/proxy/markdown-cache-control.test.ts | 3 +- .../resolve-custom-domain-rewrite.test.ts | 3 +- .../lib/proxy/resolve-default-rewrite.test.ts | 3 +- .../proxy/resolve-email-domain-action.test.ts | 3 +- .../status-page/src/lib/proxy/resolve-gate.ts | 9 +- .../resolve-ip-restriction-action.test.ts | 3 +- .../lib/proxy/resolve-locale-action.test.ts | 3 +- .../lib/proxy/resolve-password-action.test.ts | 3 +- .../lib/proxy/sanitize-redirect-param.test.ts | 3 +- .../proxy/strip-prefix-for-external.test.ts | 3 +- .../src/lib/resolve-pathname-prefix.test.ts | 3 +- .../status-page/src/lib/resolve-route.test.ts | 3 +- apps/status-page/src/lib/resolve-route.ts | 3 +- .../src/lib/status-blocks-labels.test.ts | 4 +- apps/status-page/src/lib/trpc/client.tsx | 2 +- apps/status-page/src/proxy.ts | 5 +- apps/web/env.ts | 3 +- apps/web/package.json | 6 +- apps/web/src/app/(ai)/llms-full.txt/route.ts | 6 +- apps/web/src/app/(ai)/llms.txt/route.ts | 4 +- apps/web/src/app/(ai)/mcp/route.ts | 2 +- .../src/app/(docs)/docs/[[...slug]]/page.tsx | 26 +- apps/web/src/app/(docs)/layout.tsx | 6 +- apps/web/src/app/(landing)/[slug]/page.tsx | 10 +- .../src/app/(landing)/blog/[slug]/page.tsx | 14 +- .../(landing)/blog/category/[slug]/page.tsx | 12 +- .../src/app/(landing)/blog/category/page.tsx | 7 +- .../src/app/(landing)/blog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/blog/page.tsx | 11 +- .../app/(landing)/changelog/[slug]/page.tsx | 14 +- .../changelog/category/[slug]/page.tsx | 12 +- .../app/(landing)/changelog/category/page.tsx | 7 +- .../app/(landing)/changelog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/changelog/page.tsx | 11 +- .../src/app/(landing)/compare/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/compare/page.tsx | 11 +- .../src/app/(landing)/content-box-image.tsx | 4 +- apps/web/src/app/(landing)/content-box.tsx | 2 +- .../src/app/(landing)/content-category.tsx | 2 +- apps/web/src/app/(landing)/content-list.tsx | 4 +- .../src/app/(landing)/content-metadata.tsx | 4 +- .../src/app/(landing)/content-pagination.tsx | 2 +- .../app/(landing)/customers/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/customers/page.tsx | 11 +- .../src/app/(landing)/guides/[slug]/page.tsx | 14 +- .../(landing)/guides/category/[slug]/page.tsx | 12 +- .../app/(landing)/guides/category/page.tsx | 7 +- apps/web/src/app/(landing)/guides/page.tsx | 11 +- apps/web/src/app/(landing)/layout.tsx | 6 +- .../src/app/(landing)/oss-friends/page.tsx | 5 +- apps/web/src/app/(landing)/page.tsx | 10 +- .../(landing)/play/checker/[slug]/client.tsx | 7 +- .../(landing)/play/checker/[slug]/page.tsx | 18 +- .../app/(landing)/play/checker/api/route.ts | 10 +- .../src/app/(landing)/play/checker/client.tsx | 9 +- .../src/app/(landing)/play/checker/page.tsx | 18 +- .../src/app/(landing)/play/checker/utils.ts | 4 +- apps/web/src/app/(landing)/play/curl/page.tsx | 14 +- .../(landing)/play/mcp-health/[id]/client.tsx | 3 +- .../(landing)/play/mcp-health/[id]/page.tsx | 16 +- .../(landing)/play/mcp-health/api/route.ts | 4 +- .../app/(landing)/play/mcp-health/client.tsx | 7 +- .../app/(landing)/play/mcp-health/page.tsx | 16 +- .../(landing)/play/mcp-health/utils.test.ts | 3 +- .../app/(landing)/play/mcp-health/utils.ts | 10 +- apps/web/src/app/(landing)/play/page.tsx | 5 +- .../(landing)/play/severity-matrix/client.tsx | 2 +- .../(landing)/play/severity-matrix/page.tsx | 14 +- .../app/(landing)/play/uptime-sla/page.tsx | 14 +- .../[id]/[component]/component-detail.tsx | 21 +- .../status/[id]/[component]/page.tsx | 11 +- .../app/(landing)/status/[id]/incidents.tsx | 6 +- .../src/app/(landing)/status/[id]/page.tsx | 13 +- .../(landing)/status/[id]/report-issue.tsx | 3 +- .../status/[id]/service-components.tsx | 3 +- .../(landing)/status/[id]/service-detail.tsx | 9 +- .../(landing)/status/[id]/user-reports.tsx | 2 +- .../(landing)/status/external-status-grid.tsx | 5 +- apps/web/src/app/(landing)/status/page.tsx | 9 +- .../src/app/(landing)/tooling/[slug]/page.tsx | 13 +- apps/web/src/app/(landing)/tooling/page.tsx | 11 +- .../app/(landing)/use-case/[slug]/page.tsx | 14 +- apps/web/src/app/(landing)/use-case/page.tsx | 11 +- apps/web/src/app/api/checker/cron/_cron.ts | 2 +- .../src/app/api/checker/test/http/route.ts | 3 +- apps/web/src/app/api/feedback/docs/route.ts | 4 +- .../src/app/api/markdown/[[...path]]/route.ts | 6 +- .../src/app/api/og/_components/background.tsx | 2 +- .../app/api/og/_components/basic-layout.tsx | 3 +- .../app/api/og/_components/status-check.tsx | 2 +- .../src/app/api/og/_components/tracker.tsx | 4 +- apps/web/src/app/api/og/checker/route.tsx | 5 +- .../src/app/api/og/external-service/route.tsx | 9 +- apps/web/src/app/api/og/monitor/route.tsx | 5 +- apps/web/src/app/api/og/page/route.tsx | 5 +- apps/web/src/app/api/og/post/route.tsx | 3 +- apps/web/src/app/api/og/route.tsx | 3 +- apps/web/src/app/api/og/status/route.tsx | 7 +- apps/web/src/app/api/search/route.ts | 4 +- apps/web/src/app/api/test/timeout/route.ts | 2 +- .../web/src/app/api/trpc/edge/[trpc]/route.ts | 2 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 2 +- apps/web/src/app/api/webhook/stripe/route.ts | 2 +- apps/web/src/app/layout.tsx | 12 +- apps/web/src/app/not-found.tsx | 4 +- apps/web/src/app/sitemap.ts | 4 +- .../web/src/components/dev-mode-container.tsx | 2 +- .../src/components/icon-cloud-provider.tsx | 2 +- apps/web/src/components/loading-animation.tsx | 2 +- apps/web/src/config/socials.ts | 2 +- apps/web/src/content/cmdk.tsx | 8 +- apps/web/src/content/docs-feedback.tsx | 2 +- apps/web/src/content/docs-footer.tsx | 5 +- apps/web/src/content/docs-sidebar.tsx | 3 +- apps/web/src/content/docs-sub-nav.tsx | 3 +- apps/web/src/content/docs-toc.tsx | 3 +- apps/web/src/content/footer-status.tsx | 2 +- apps/web/src/content/footer.tsx | 7 +- apps/web/src/content/header.tsx | 3 +- apps/web/src/content/highlight-text.tsx | 2 +- apps/web/src/content/image-zoom.tsx | 2 +- apps/web/src/content/latency-chart-table.tsx | 3 +- apps/web/src/content/link.tsx | 2 +- apps/web/src/content/mdx-components/aside.tsx | 2 +- apps/web/src/content/mdx-components/card.tsx | 2 +- .../content/mdx-components/custom-image.tsx | 5 +- apps/web/src/content/mdx-components/grid.tsx | 2 +- .../web/src/content/mdx-components/subtle.tsx | 2 +- apps/web/src/content/simple-chart.tsx | 2 +- apps/web/src/content/status-markdown.ts | 4 +- apps/web/src/content/sub-nav.tsx | 3 +- apps/web/src/content/theme-toggle.tsx | 2 +- apps/web/src/content/utils/search-index.ts | 3 +- .../src/content/utils/search-match.test.ts | 3 +- apps/web/src/data/content.ts | 2 +- apps/web/src/data/trigger-dictionary.ts | 4 +- apps/web/src/lib/checker/mock.ts | 4 +- .../web/src/lib/external-report-escalation.ts | 2 +- apps/web/src/lib/mcp/health-check.test.ts | 3 +- apps/web/src/lib/metadata/shared-metadata.ts | 2 +- apps/web/src/lib/metadata/structured-data.ts | 3 +- apps/web/src/lib/stripe/client.ts | 2 +- apps/web/src/lib/tb.ts | 2 +- apps/workflows/.gitignore | 4 - apps/workflows/Dockerfile | 196 ++---- apps/workflows/deno-migration-plan.md | 437 ------------ apps/workflows/docker-compose.yaml | 11 +- apps/workflows/dofigen.lock | 411 ++++++----- apps/workflows/dofigen.yml | 143 ++-- apps/workflows/package.json | 13 +- apps/workflows/src/build-docker.ts | 81 +++ apps/workflows/src/checker/alerting.test.ts | 175 +++-- apps/workflows/src/cron/checker.ts | 2 +- apps/workflows/src/cron/index.ts | 2 +- apps/workflows/src/index.ts | 50 +- apps/workflows/src/lib/sentry.ts | 2 +- apps/workflows/src/serve.ts | 15 - apps/workflows/start.sh | 2 +- apps/workflows/tsconfig.json | 1 + deno.lock | 277 -------- package.json | 1 - packages/analytics/package.json | 4 +- packages/analytics/tsconfig.json | 1 + packages/api/.env.test | 1 - packages/api/env.ts | 3 +- packages/api/package.json | 11 +- packages/api/src/router/blob.test.ts | 3 +- .../api/src/router/effective-status.test.ts | 3 +- packages/api/src/router/import.test.ts | 12 +- packages/api/src/router/maintenance.test.ts | 4 +- packages/api/src/router/monitor.test.ts | 214 +++--- packages/api/src/router/notification.test.ts | 4 +- packages/api/src/router/page.ts | 4 + packages/api/src/router/pageComponent.test.ts | 4 +- .../api/src/router/privateLocation.test.ts | 126 ++-- .../api/src/router/statusPage.e2e.test.ts | 5 +- .../src/router/statusPage.unsubscribe.test.ts | 4 +- .../api/src/router/statusPage.utils.test.ts | 4 +- packages/api/src/router/statusReport.test.ts | 4 +- packages/api/src/router/stripe/utils.test.ts | 4 +- .../api/src/router/tinybird/index.test.ts | 4 +- packages/api/src/router/workspace.test.ts | 3 +- packages/api/src/test/preload.ts | 12 + packages/api/src/test/upstash.mock.ts | 18 - packages/api/src/trpc.ts | 2 +- packages/api/test.importmap.json | 5 - packages/api/tsconfig.json | 5 +- packages/assertions/package.json | 4 +- packages/assertions/src/v1.ts | 2 +- packages/assertions/tsconfig.json | 3 + packages/db/env.ts | 3 +- packages/db/package.json | 22 +- packages/db/script/region-migration.test.ts | 4 +- .../src/schema/page_components/validation.ts | 2 +- packages/db/src/seed.mts | 30 +- packages/db/src/test/factories.ts | 50 -- packages/db/src/utils/api-key.test.ts | 3 +- packages/db/tsconfig.json | 1 + packages/emails/package.json | 10 +- .../emails/src/client.integration.test.tsx | 5 +- packages/emails/src/client.test.ts | 49 +- packages/emails/tsconfig.json | 8 +- packages/error/package.json | 4 +- packages/header-analysis/package.json | 8 +- .../src/parser/x-vercel-cache.test.ts | 17 +- packages/icons/package.json | 1 - packages/importers/package.json | 7 +- .../src/providers/betterstack/client.test.ts | 16 +- .../src/providers/betterstack/mapper.test.ts | 3 +- .../providers/betterstack/provider.test.ts | 8 +- .../src/providers/instatus/client.test.ts | 18 +- .../src/providers/instatus/mapper.test.ts | 13 +- .../src/providers/instatus/provider.test.ts | 3 +- .../src/providers/statuspage/client.test.ts | 18 +- .../src/providers/statuspage/mapper.test.ts | 13 +- .../src/providers/statuspage/provider.test.ts | 3 +- packages/locales/package.json | 4 +- packages/notifications/base/package.json | 6 +- .../base/src/utils/duration.test.ts | 3 +- .../base/src/utils/incident.test.ts | 5 +- .../notifications/bird-whatsapp/package.json | 6 +- .../bird-whatsapp/src/index.test.ts | 36 +- .../notifications/bird-whatsapp/tsconfig.json | 4 +- packages/notifications/discord/package.json | 6 +- .../notifications/discord/src/index.test.ts | 40 +- packages/notifications/discord/tsconfig.json | 4 +- packages/notifications/email/package.json | 5 +- .../notifications/email/src/index.test.ts | 49 +- .../notifications/email/src/test-preload.ts | 10 - packages/notifications/email/tsconfig.json | 4 +- .../notifications/google-chat/package.json | 6 +- .../google-chat/src/index.test.ts | 35 +- .../notifications/google-chat/tsconfig.json | 4 +- .../notifications/grafana-oncall/package.json | 6 +- .../grafana-oncall/src/index.test.ts | 54 +- .../grafana-oncall/tsconfig.json | 4 +- packages/notifications/ms-teams/package.json | 6 +- .../notifications/ms-teams/src/index.test.ts | 28 +- packages/notifications/ms-teams/tsconfig.json | 4 +- packages/notifications/ntfy/package.json | 6 +- packages/notifications/ntfy/src/index.test.ts | 64 +- packages/notifications/ntfy/tsconfig.json | 4 +- packages/notifications/opsgenie/package.json | 6 +- .../notifications/opsgenie/src/index.test.ts | 36 +- packages/notifications/opsgenie/tsconfig.json | 4 +- packages/notifications/pagerduty/package.json | 6 +- .../notifications/pagerduty/src/index.test.ts | 46 +- .../notifications/pagerduty/tsconfig.json | 4 +- packages/notifications/slack/package.json | 6 +- .../notifications/slack/src/index.test.ts | 47 +- packages/notifications/slack/tsconfig.json | 4 +- packages/notifications/telegram/package.json | 6 +- .../notifications/telegram/src/index.test.ts | 54 +- packages/notifications/telegram/tsconfig.json | 4 +- .../notifications/twillio-sms/package.json | 6 +- .../twillio-sms/src/index.test.ts | 35 +- .../notifications/twillio-sms/tsconfig.json | 4 +- packages/notifications/webhook/package.json | 6 +- .../notifications/webhook/src/index.test.ts | 76 +- packages/proto/package.json | 3 +- packages/regions/package.json | 4 +- packages/services/package.json | 6 +- packages/services/src/__tests__/retry.test.ts | 3 +- .../__tests__/with-test-transaction.test.ts | 4 +- .../src/__tests__/with-transaction.test.ts | 3 +- .../src/agent-tools/__tests__/docs.test.ts | 16 +- .../__tests__/shape-equivalence.test.ts | 3 +- .../__tests__/status-report-impacts.test.ts | 4 +- .../src/api-key/__tests__/api-key.test.ts | 18 +- .../src/audit/__tests__/audit.test.ts | 4 +- .../src/auth/__tests__/matches-scope.test.ts | 4 +- .../src/auth/__tests__/require-scope.test.ts | 3 +- .../external-service-component.test.ts | 4 +- .../__tests__/internal.test.ts | 3 +- .../external-service-incident.test.ts | 4 +- .../__tests__/record.test.ts | 4 +- .../__tests__/external-service.test.ts | 4 +- .../import/__tests__/incidents-phase.test.ts | 4 +- .../src/import/__tests__/unit.test.ts | 4 +- .../src/incident/__tests__/incident.test.ts | 4 +- .../__tests__/install-slack-agent.test.ts | 8 +- .../invitation/__tests__/invitation.test.ts | 18 +- .../maintenance/__tests__/maintenance.test.ts | 17 +- .../src/member/__tests__/member.test.ts | 6 +- .../monitor-tag/__tests__/monitor-tag.test.ts | 6 +- .../src/monitor/__tests__/monitor.test.ts | 26 +- .../src/monitor/__tests__/reads.test.ts | 4 +- .../__tests__/stream-monitor-preview.test.ts | 15 +- .../__tests__/notification.test.ts | 4 +- .../__tests__/get-daily-summary.test.ts | 4 +- .../__tests__/page-component.test.ts | 4 +- .../__tests__/page-subscriber.test.ts | 37 +- .../services/src/page/__tests__/page.test.ts | 4 +- .../__tests__/status-report.test.ts | 17 +- .../src/workspace/__tests__/workspace.test.ts | 16 +- packages/services/test/helpers.ts | 3 +- packages/services/tsconfig.json | 3 +- .../status-fetcher/__tests__/fetch.test.ts | 17 +- .../__tests__/fetchers/atlassian.test.ts | 20 +- .../__tests__/fetchers/betterstack.test.ts | 15 +- .../__tests__/fetchers/components.test.ts | 8 +- .../__tests__/fetchers/custom.test.ts | 3 +- .../__tests__/fetchers/edge-cases.test.ts | 4 +- .../__tests__/fetchers/html.test.ts | 8 +- .../__tests__/fetchers/incidentio.test.ts | 20 +- .../__tests__/fetchers/instatus.test.ts | 15 +- .../__tests__/fetchers/uptimerobot.test.ts | 13 +- packages/status-fetcher/__tests__/helpers.ts | 5 +- .../__tests__/integration.test.ts | 4 +- .../status-fetcher/__tests__/utils.test.ts | 3 +- packages/status-fetcher/package.json | 8 +- packages/status-fetcher/tsconfig.json | 1 + packages/subscriptions/package.json | 6 +- .../subscriptions/src/channels/email.test.ts | 52 +- .../subscriptions/src/channels/index.test.ts | 4 +- .../src/channels/webhook.test.ts | 131 ++-- packages/subscriptions/src/dispatcher.test.ts | 63 +- packages/subscriptions/src/test-preload.ts | 13 +- packages/subscriptions/tsconfig.json | 4 +- packages/test-utils/package.json | 20 - packages/test-utils/src/index.ts | 27 - packages/test-utils/src/matchers.ts | 95 --- packages/test-utils/src/mock-fn.ts | 112 --- packages/test-utils/src/runner.ts | 58 -- packages/theme-store/package.json | 4 +- packages/tinybird/package.json | 3 - packages/tracker/package.json | 6 +- packages/tracker/src/mock.ts | 4 +- packages/tracker/src/tracker.test.ts | 20 +- packages/tracker/src/tracker.ts | 2 +- packages/tracker/tsconfig.json | 3 +- packages/upstash/package.json | 3 - packages/utils/package.json | 6 +- packages/utils/src/ssrf.test.ts | 3 +- pnpm-lock.yaml | 659 +++++++----------- pnpm-workspace.yaml | 14 +- turbo.json | 1 - 534 files changed, 3125 insertions(+), 5066 deletions(-) delete mode 100644 .github/workflows/check.yml create mode 100644 apps/server/bunfig.toml delete mode 100644 apps/server/deno.jsonc delete mode 100644 apps/server/src/libs/test/doubles/analytics.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/page-urls.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/slack-agent.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/slack-test-state.ts delete mode 100644 apps/server/src/libs/test/doubles/slack-web-api.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/state.ts delete mode 100644 apps/server/src/libs/test/doubles/subscriptions.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/tinybird.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/upstash.mock.ts delete mode 100644 apps/server/src/libs/test/doubles/workspace-resolver.mock.ts delete mode 100644 apps/server/src/serve.ts delete mode 100644 apps/server/test.importmap.json delete mode 100644 apps/workflows/deno-migration-plan.md create mode 100644 apps/workflows/src/build-docker.ts delete mode 100644 apps/workflows/src/serve.ts delete mode 100644 deno.lock create mode 100644 packages/api/src/test/preload.ts delete mode 100644 packages/api/src/test/upstash.mock.ts delete mode 100644 packages/api/test.importmap.json delete mode 100644 packages/db/src/test/factories.ts delete mode 100644 packages/notifications/email/src/test-preload.ts delete mode 100644 packages/test-utils/package.json delete mode 100644 packages/test-utils/src/index.ts delete mode 100644 packages/test-utils/src/matchers.ts delete mode 100644 packages/test-utils/src/mock-fn.ts delete mode 100644 packages/test-utils/src/runner.ts diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index 19510a39..00000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Check -on: - push: - branches: - - "main" - pull_request: - branches: [main] - -jobs: - check: - name: 🔍 Check - runs-on: ubuntu-latest - timeout-minutes: 15 - env: - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v6 - - - name: Set up pnpm - uses: pnpm/action-setup@v6 - - - name: ⎔ Setup node - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: "pnpm" - - - name: 🦕 Setup Deno - uses: denoland/setup-deno@v2 - with: - deno-version: v2.x - - - name: 📥 Download deps - run: pnpm install - - - name: 🔍 Check - run: pnpm check diff --git a/.github/workflows/dx.yml b/.github/workflows/dx.yml index 766bae46..24e16afa 100644 --- a/.github/workflows/dx.yml +++ b/.github/workflows/dx.yml @@ -41,10 +41,10 @@ jobs: - name: 📥 Download deps run: pnpm install - - name: 🦕 Setup Deno - uses: denoland/setup-deno@v2 + - name: 🔥 Install bun + uses: oven-sh/setup-bun@v2 with: - deno-version: v2.x + bun-version: latest - name: 🔥 DX task run: pnpm dx diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 915d6aa7..60003b7a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@v6 - name: Set up pnpm - uses: pnpm/action-setup@v6 + uses: pnpm/action-setup@v4 - name: ⎔ Setup node uses: actions/setup-node@v6 @@ -38,10 +38,10 @@ jobs: node-version: 24 cache: "pnpm" - - name: 🦕 Setup Deno - uses: denoland/setup-deno@v2 + - name: 🔥 Install bun + uses: oven-sh/setup-bun@v2 with: - deno-version: v2.x + bun-version: latest - name: 📥 Download deps run: pnpm install diff --git a/apps/dashboard/env.ts b/apps/dashboard/env.ts index dab63f5f..dbb28b16 100644 --- a/apps/dashboard/env.ts +++ b/apps/dashboard/env.ts @@ -1 +1,2 @@ -await Deno.copyFile("./.env.example", "./.env"); +const file = Bun.file("./.env.example"); +await Bun.write("./.env", file); diff --git a/apps/screenshot-service/package.json b/apps/screenshot-service/package.json index 4bd7feb4..63c73984 100644 --- a/apps/screenshot-service/package.json +++ b/apps/screenshot-service/package.json @@ -2,7 +2,6 @@ "name": "@openstatus/screenshot-service", "version": "0.0.1", "scripts": { - "check": "deno check --sloppy-imports .", "dev": "bun run --hot src/index.ts", "start": "NODE_ENV=production bun run src/index.ts" }, diff --git a/apps/server/.gitignore b/apps/server/.gitignore index c1fbf070..3c3629e6 100644 --- a/apps/server/.gitignore +++ b/apps/server/.gitignore @@ -1,5 +1 @@ node_modules -app -src/_serve.bundle.mjs -.deno_compile_bundle_*.mjs -app.tmp-* diff --git a/apps/server/Dockerfile b/apps/server/Dockerfile index 178df222..f4c19c32 100644 --- a/apps/server/Dockerfile +++ b/apps/server/Dockerfile @@ -3,9 +3,9 @@ # See https://github.com/lenra-io/dofigen # install -FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install +FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install LABEL \ - org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ + org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ @@ -48,14 +48,14 @@ RUN \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <({ const logger = getLogger("api-server"); const otelLogger = getLogger("api-server-otel"); -const openapiYaml = await Deno.readTextFile( - new URL("../static/openapi.yaml", import.meta.url), -); - /** * Configure logging asynchronously without blocking module initialization. * This allows tests to import `app` immediately. */ -// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` -// includes it. Letting @logtape/otel create the exporter triggers a dynamic -// import of a bare specifier, which the compiled --node-modules-dir=none binary -// can't resolve. -const loggerProvider = new LoggerProvider({ - resource: resourceFromAttributes({ - [ATTR_SERVICE_NAME]: "openstatus-server", +const defaultLogger = getOpenTelemetrySink({ + serviceName: "openstatus-server", + otlpExporterConfig: { + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env.AXIOM_TOKEN}`, + "X-Axiom-Dataset": env.AXIOM_DATASET, + }, + }, + additionalResource: resourceFromAttributes({ [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env.NODE_ENV, }), - processors: [ - new BatchLogRecordProcessor( - new OTLPLogExporter({ - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env.AXIOM_TOKEN}`, - "X-Axiom-Dataset": env.AXIOM_DATASET, - }, - }), - ), - ], -}); - -const defaultLogger = getOpenTelemetrySink({ - loggerProvider, }); await configure({ @@ -187,7 +166,7 @@ app.use("*", async (c, next) => { // Console logging only for errors in production if (env.NODE_ENV !== "production" || c.res.status >= 500) { logger.info("request", { - request_id: reqId, + request_id: requestId, method: c.req.method, path: c.req.path, status_code: c.res.status, @@ -284,6 +263,13 @@ app.route("/mcp", mcpRoute); * create incidents, and send notifications. */ -if (process.env.NODE_ENV === "development") { - showRoutes(app, { verbose: true, colorize: true }); -} +const isDev = process.env.NODE_ENV === "development"; +const port = 3000; + +if (isDev) showRoutes(app, { verbose: true, colorize: true }); + +logger.info("Starting server", { port, environment: env.NODE_ENV }); + +const server = { port, fetch: app.fetch }; + +export default server; diff --git a/apps/server/src/libs/middlewares/require-scope.test.ts b/apps/server/src/libs/middlewares/require-scope.test.ts index f1f0962a..05818307 100644 --- a/apps/server/src/libs/middlewares/require-scope.test.ts +++ b/apps/server/src/libs/middlewares/require-scope.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import type { Scope } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import type { Variables } from "@/types"; diff --git a/apps/server/src/libs/middlewares/validate-key.test.ts b/apps/server/src/libs/middlewares/validate-key.test.ts index 58f5355a..28527fb1 100644 --- a/apps/server/src/libs/middlewares/validate-key.test.ts +++ b/apps/server/src/libs/middlewares/validate-key.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { validateKey } from "./auth"; diff --git a/apps/server/src/libs/test/doubles/analytics.mock.ts b/apps/server/src/libs/test/doubles/analytics.mock.ts deleted file mode 100644 index dfe71343..00000000 --- a/apps/server/src/libs/test/doubles/analytics.mock.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Test double for @openstatus/analytics, swapped in via --import-map. Keeps the -// real Events/parseInputToProps but replaces setupAnalytics with a spy (exposed -// on globalThis.__analyticsSpies) so tests assert tracking without OpenPanel. -export { - type EventProps, - Events, - parseInputToProps, -} from "@openstatus/analytics-real"; - -import { mock } from "@openstatus/test-utils"; - -const g = globalThis as Record; -if (!g.__analyticsSpies) { - const track = mock(() => Promise.resolve()); - g.__analyticsSpies = { - track, - setupAnalytics: mock((_props: unknown) => Promise.resolve({ track })), - }; -} - -const spies = g.__analyticsSpies as { - track: ReturnType; - setupAnalytics: ReturnType; -}; - -export const setupAnalytics = (props: unknown) => spies.setupAnalytics(props); diff --git a/apps/server/src/libs/test/doubles/page-urls.mock.ts b/apps/server/src/libs/test/doubles/page-urls.mock.ts deleted file mode 100644 index b4e18132..00000000 --- a/apps/server/src/libs/test/doubles/page-urls.mock.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Test double for src/routes/slack/page-urls.ts (which hits the db), swapped in -// via --import-map so slack presenter tests get deterministic URLs. -export const getPageUrl = (_pageId: number): Promise => - Promise.resolve("https://example.openstatus.dev"); - -export const getReportUrl = ( - _pageId: number, - reportId: number, -): Promise => - Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`); diff --git a/apps/server/src/libs/test/doubles/slack-agent.mock.ts b/apps/server/src/libs/test/doubles/slack-agent.mock.ts deleted file mode 100644 index ef4990b4..00000000 --- a/apps/server/src/libs/test/doubles/slack-agent.mock.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Test double for slack/agent.ts (pulls in the AI SDK), swapped in via -// --import-map so handler tests don't run the real agent. -import { slackTestState } from "./slack-test-state.ts"; - -export const runAgent = () => { - if (slackTestState.runAgentOverride) return slackTestState.runAgentOverride(); - return Promise.resolve({ text: "Here is my response", toolResults: [] }); -}; diff --git a/apps/server/src/libs/test/doubles/slack-test-state.ts b/apps/server/src/libs/test/doubles/slack-test-state.ts deleted file mode 100644 index 9d19743e..00000000 --- a/apps/server/src/libs/test/doubles/slack-test-state.ts +++ /dev/null @@ -1,33 +0,0 @@ -// Mutable per-test config shared by the slack module doubles below. Replaces -// the per-file bun `mock.module` closures (handler.test / interactions.test): -// each test sets the fields it needs in beforeEach and reads `calls`. -type SlackCall = { method: string; args: Record }; -type Override = ((args: Record) => Promise) | null; - -export interface SlackTestState { - resolveWorkspace: (teamId: string) => Promise; - calls: SlackCall[]; - postMessageOverride: Override; - updateOverride: Override; - postEphemeralOverride: Override; - runAgentOverride: (() => Promise) | null; - repliesImpl: () => Promise; -} - -const g = globalThis as Record; -if (!g.__slackTestState) { - g.__slackTestState = { - resolveWorkspace: () => Promise.resolve(null), - calls: [], - postMessageOverride: null, - updateOverride: null, - postEphemeralOverride: null, - runAgentOverride: null, - repliesImpl: () => - Promise.resolve({ - messages: [{ user: "U1", text: "test message", ts: "1.1" }], - }), - } satisfies SlackTestState; -} - -export const slackTestState = g.__slackTestState as SlackTestState; diff --git a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts deleted file mode 100644 index fd8d3c93..00000000 --- a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Test double for @slack/web-api (only WebClient is used), swapped in via -// --import-map. Captures chat calls into the shared slack test state. -import { slackTestState as s } from "./slack-test-state.ts"; - -export class WebClient { - chat = { - postMessage: (args: Record) => { - if (s.postMessageOverride) return s.postMessageOverride(args); - s.calls.push({ method: "postMessage", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - update: (args: Record) => { - if (s.updateOverride) return s.updateOverride(args); - s.calls.push({ method: "update", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - postEphemeral: (args: Record) => { - if (s.postEphemeralOverride) return s.postEphemeralOverride(args); - s.calls.push({ method: "postEphemeral", args }); - return Promise.resolve(); - }, - }; - conversations = { - replies: () => s.repliesImpl(), - }; -} diff --git a/apps/server/src/libs/test/doubles/state.ts b/apps/server/src/libs/test/doubles/state.ts deleted file mode 100644 index ec223907..00000000 --- a/apps/server/src/libs/test/doubles/state.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Shared test-double state, set on globalThis so tests can assert on spies and -// configure mock data — same interface the old bun `mock.module` preload -// exposed. Imported (for side effect) by every double module below. -import { mock } from "@openstatus/test-utils"; - -type Mut = Record; -const g = globalThis as Mut; - -if (!g.__subscriptionSpies) { - const sendVerification = mock(() => Promise.resolve()); - g.__subscriptionSpies = { - dispatchStatusReportUpdate: mock(() => Promise.resolve()), - dispatchMaintenanceUpdate: mock(() => Promise.resolve()), - sendVerification, - getChannel: { - id: "email", - sendVerification, - sendNotifications: mock(() => Promise.resolve()), - validateConfig: mock(() => Promise.resolve({ valid: true })), - }, - }; -} - -if (!g.__testRedisStore) { - g.__testRedisStore = new Map(); -} - -if (!g.__tinybirdMockData) { - g.__tinybirdMockData = { httpListBiweekly: [], httpGetBiweekly: [] }; -} -if (!g.__tinybirdMockCalls) { - g.__tinybirdMockCalls = { httpListBiweekly: [], httpGetBiweekly: [] }; -} - -export const subscriptionSpies = g.__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; - sendVerification: ReturnType; - getChannel: Record; -}; -export const testRedisStore = g.__testRedisStore as Map; -export const tinybirdMockData = g.__tinybirdMockData as { - httpListBiweekly: unknown[]; - httpGetBiweekly: unknown[]; -}; -export const tinybirdMockCalls = g.__tinybirdMockCalls as { - httpListBiweekly: unknown[]; - httpGetBiweekly: unknown[]; -}; diff --git a/apps/server/src/libs/test/doubles/subscriptions.mock.ts b/apps/server/src/libs/test/doubles/subscriptions.mock.ts deleted file mode 100644 index aaf5f297..00000000 --- a/apps/server/src/libs/test/doubles/subscriptions.mock.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Test double for @openstatus/subscriptions, swapped in via --import-map. -// Re-exports the real module, overriding only the dispatch fns and getChannel -// with spies (exposed on globalThis via state.ts) so route tests can assert -// notification side effects without sending anything. -export * from "@openstatus/subscriptions-real"; - -import { subscriptionSpies as spies } from "./state.ts"; - -export const dispatchStatusReportUpdate = spies.dispatchStatusReportUpdate; -export const dispatchMaintenanceUpdate = spies.dispatchMaintenanceUpdate; -export const getChannel = () => spies.getChannel; diff --git a/apps/server/src/libs/test/doubles/tinybird.mock.ts b/apps/server/src/libs/test/doubles/tinybird.mock.ts deleted file mode 100644 index 2cf71dab..00000000 --- a/apps/server/src/libs/test/doubles/tinybird.mock.ts +++ /dev/null @@ -1,59 +0,0 @@ -// Test double for @openstatus/tinybird, swapped in via --import-map. Overrides -// OSTinybird with a no-network stub backed by `__tinybirdMockData/Calls`, while -// re-exporting the real Tinybird/AuditLog/etc. for code that imports them. -export * from "@openstatus/tinybird-real"; - -import { - tinybirdMockCalls as calls, - tinybirdMockData as data, -} from "./state.ts"; - -const empty = () => Promise.resolve({ data: [] }); - -export class OSTinybird { - get legacy_httpStatus45d() { - return empty; - } - get legacy_tcpStatus45d() { - return empty; - } - get httpListBiweekly() { - return (params: unknown) => { - calls.httpListBiweekly.push(params); - return Promise.resolve({ data: data.httpListBiweekly }); - }; - } - get httpGetBiweekly() { - return (params: unknown) => { - calls.httpGetBiweekly.push(params); - return Promise.resolve({ data: data.httpGetBiweekly }); - }; - } - get httpMetricsDaily() { - return empty; - } - get httpMetricsWeekly() { - return empty; - } - get httpMetricsBiweekly() { - return empty; - } - get tcpMetricsDaily() { - return empty; - } - get tcpMetricsWeekly() { - return empty; - } - get tcpMetricsBiweekly() { - return empty; - } - get dnsMetricsDaily() { - return empty; - } - get dnsMetricsWeekly() { - return empty; - } - get dnsMetricsBiweekly() { - return empty; - } -} diff --git a/apps/server/src/libs/test/doubles/upstash.mock.ts b/apps/server/src/libs/test/doubles/upstash.mock.ts deleted file mode 100644 index b4dc5fb2..00000000 --- a/apps/server/src/libs/test/doubles/upstash.mock.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Test double for @openstatus/upstash, swapped in via --import-map. Backs the -// Redis client with the in-memory `__testRedisStore` Map so tests can assert -// on stored state without a real Upstash instance. -import { testRedisStore as store } from "./state.ts"; - -const client = { - get: (key: string) => Promise.resolve(store.get(key) ?? null), - set: (key: string, value: string) => { - store.set(key, value); - return Promise.resolve("OK"); - }, - del: (key: string) => { - const existed = store.has(key) ? 1 : 0; - store.delete(key); - return Promise.resolve(existed); - }, - getdel: (key: string) => { - const value = store.get(key) ?? null; - store.delete(key); - return Promise.resolve(value); - }, - incr: (key: string) => { - const next = Number(store.get(key) ?? 0) + 1; - store.set(key, String(next)); - return Promise.resolve(next); - }, - expire: () => Promise.resolve(1), -}; - -export const redis = client; - -export const Redis = { - fromEnv() { - return client; - }, -}; diff --git a/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts b/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts deleted file mode 100644 index 8766b79e..00000000 --- a/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Test double for slack/workspace-resolver.ts (hits the db), swapped in via -// --import-map. Delegates to the per-test resolver in the shared slack state. -import { slackTestState } from "./slack-test-state.ts"; - -export const resolveWorkspace = (teamId: string) => - slackTestState.resolveWorkspace(teamId); diff --git a/apps/server/src/libs/test/preload.ts b/apps/server/src/libs/test/preload.ts index 232bf7f9..a2efeadb 100644 --- a/apps/server/src/libs/test/preload.ts +++ b/apps/server/src/libs/test/preload.ts @@ -1,8 +1,9 @@ +import { mock } from "bun:test"; + // Import the real module BEFORE mock.module runs so we can spread real // service functions (createSubscription, updateChannel, etc.) into the // replacement while still stubbing the dispatch-side spies. import * as realSubscriptions from "@openstatus/subscriptions"; -import { mock } from "@openstatus/test-utils"; // Subscription dispatch spies — accessible in tests via globalThis.__subscriptionSpies const dispatchStatusReportUpdateSpy = mock((_id: number) => Promise.resolve()); diff --git a/apps/server/src/routes/mcp/adapter.test.ts b/apps/server/src/routes/mcp/adapter.test.ts index b1a00d1a..b5944189 100644 --- a/apps/server/src/routes/mcp/adapter.test.ts +++ b/apps/server/src/routes/mcp/adapter.test.ts @@ -1,7 +1,7 @@ +import { describe, expect, test } from "bun:test"; + import type { Workspace } from "@openstatus/db/src/schema"; import { ForbiddenError, NotFoundError } from "@openstatus/services"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { mapError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/mcp/adapter.ts b/apps/server/src/routes/mcp/adapter.ts index 2f3d2a7d..b19ede15 100644 --- a/apps/server/src/routes/mcp/adapter.ts +++ b/apps/server/src/routes/mcp/adapter.ts @@ -1,5 +1,5 @@ -import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js"; +import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { type ServiceContext, ServiceError } from "@openstatus/services"; import { ZodError } from "zod"; diff --git a/apps/server/src/routes/mcp/handler.test.ts b/apps/server/src/routes/mcp/handler.test.ts index 46ba666c..baa6efc0 100644 --- a/apps/server/src/routes/mcp/handler.test.ts +++ b/apps/server/src/routes/mcp/handler.test.ts @@ -1,13 +1,14 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { sentry } from "@hono/sentry"; import { db, desc, eq } from "@openstatus/db"; import { auditLog, page, statusReport } from "@openstatus/db/src/schema"; import { SEEDED_WORKSPACE_TEAM_ID } from "@openstatus/services/test/fixtures"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { requestId } from "hono/request-id"; -import { handleError } from "../../libs/errors"; +import { handleError } from "@/libs/errors"; + import { mcpRoute } from "./index"; /** diff --git a/apps/server/src/routes/mcp/index.ts b/apps/server/src/routes/mcp/index.ts index 822c47f4..419f324c 100644 --- a/apps/server/src/routes/mcp/index.ts +++ b/apps/server/src/routes/mcp/index.ts @@ -1,9 +1,10 @@ import { StreamableHTTPTransport } from "@hono/mcp"; import { Hono } from "hono"; -import { handleError } from "../../libs/errors"; -import { authMiddleware } from "../../libs/middlewares/auth"; -import type { Variables } from "../../types"; +import { handleError } from "@/libs/errors"; +import { authMiddleware } from "@/libs/middlewares/auth"; +import type { Variables } from "@/types"; + import { toServiceCtx } from "./adapter"; import { createMcpServer } from "./server"; diff --git a/apps/server/src/routes/mcp/tools/register-scoped.test.ts b/apps/server/src/routes/mcp/tools/register-scoped.test.ts index 3b5eae6f..f853a8f7 100644 --- a/apps/server/src/routes/mcp/tools/register-scoped.test.ts +++ b/apps/server/src/routes/mcp/tools/register-scoped.test.ts @@ -1,8 +1,8 @@ +import { describe, expect, test } from "bun:test"; + import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { Workspace } from "@openstatus/db/src/schema"; import type { ServiceContext } from "@openstatus/services"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { registerScopedTool } from "./register-scoped"; diff --git a/apps/server/src/routes/mcp/tools/tools.test.ts b/apps/server/src/routes/mcp/tools/tools.test.ts index 3e4e82b3..0d64855a 100644 --- a/apps/server/src/routes/mcp/tools/tools.test.ts +++ b/apps/server/src/routes/mcp/tools/tools.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { db, eq } from "@openstatus/db"; import { @@ -19,8 +21,6 @@ import { readAuditLog, withTestTransaction, } from "@openstatus/services/test/helpers"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { toServiceCtx } from "../adapter"; import { registerMaintenanceTools } from "./maintenance"; diff --git a/apps/server/src/routes/public/status.test.ts b/apps/server/src/routes/public/status.test.ts index 679c461e..49c71237 100644 --- a/apps/server/src/routes/public/status.test.ts +++ b/apps/server/src/routes/public/status.test.ts @@ -1,14 +1,15 @@ -import { db, eq } from "@openstatus/db"; -import { expect } from "@std/expect"; import { afterAll, beforeAll, beforeEach, describe, + expect, test, -} from "@std/testing/bdd"; +} from "bun:test"; + +import { db, eq } from "@openstatus/db"; -import { app } from "../../index"; +import { app } from "@/index"; const testRedisStore = (globalThis as Record) .__testRedisStore as Map | undefined; diff --git a/apps/server/src/routes/public/status.ts b/apps/server/src/routes/public/status.ts index dc115266..04941603 100644 --- a/apps/server/src/routes/public/status.ts +++ b/apps/server/src/routes/public/status.ts @@ -7,7 +7,7 @@ import { endTime, setMetric, startTime } from "hono/timing"; const logger = getLogger("api-server"); import { Status, Tracker } from "@openstatus/tracker"; -import { redis } from "../../libs/clients"; +import { redis } from "@/libs/clients"; // TODO: include ratelimiting diff --git a/apps/server/src/routes/rpc/adapter.test.ts b/apps/server/src/routes/rpc/adapter.test.ts index 381bfa33..d5f02493 100644 --- a/apps/server/src/routes/rpc/adapter.test.ts +++ b/apps/server/src/routes/rpc/adapter.test.ts @@ -1,3 +1,5 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { Code, ConnectError } from "@connectrpc/connect"; import type { Workspace } from "@openstatus/db/src/schema"; import { @@ -12,8 +14,6 @@ import { loadSeededWorkspace, withTestTransaction, } from "@openstatus/services/test/helpers"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { toConnectError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts index bfedbb0d..874d96f6 100644 --- a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts +++ b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { maintenance, @@ -5,19 +7,14 @@ import { page, pageComponent, pageSubscriber, - workspace, } from "@openstatus/db/src/schema"; -import { mock } from "@openstatus/test-utils"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { nanoid } from "nanoid"; -import { app } from "../../../../../index"; +import { app } from "@/index"; const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -43,14 +40,6 @@ async function connectRequest( } const TEST_PREFIX = "rpc-maintenance-test"; -// Scoped to a dedicated workspace+page so parallel suites mutating the -// shared seed workspace 1 / page 1 can't delete our fixtures mid-run. -// dev/test `validateKey` maps `x-openstatus-key` to the workspace id. -const WORKSPACE_LIMITS = - '{"monitors":50,"synthetic-checks":150000,"periodicity":["30s","1m","5m","10m","30m","1h"],"multi-region":true,"max-regions":35,"data-retention":"24 months","status-pages":20,"maintenance":true,"status-subscribers":true,"custom-domain":true,"password-protection":true,"email-domain-protection":true,"white-label":true,"notifications":true,"sms":true,"pagerduty":true,"notification-channels":50,"members":"Unlimited","audit-log":true}'; -let testWorkspaceId: number; -let authKey: string; -let testPageId: number; let testPageComponentId: number; let testMaintenanceId: number; let testMaintenanceToDeleteId: number; @@ -62,39 +51,26 @@ let testPage2Id: number; let testPage2ComponentId: number; beforeAll(async () => { - const ws = await db - .insert(workspace) - .values({ - slug: `${TEST_PREFIX}-ws-${nanoid(8)}`, - name: `${TEST_PREFIX}-workspace`, - plan: "team", - limits: WORKSPACE_LIMITS, - }) - .returning() - .get(); - testWorkspaceId = ws.id; - authKey = String(testWorkspaceId); - - // Primary page for the suite (replaces shared seed page 1). - const mainPage = await db - .insert(page) - .values({ - workspaceId: testWorkspaceId, - title: `${TEST_PREFIX}-page`, - slug: `${TEST_PREFIX}-page-slug-${nanoid(8)}`, - description: "Primary test page for maintenance tests", - customDomain: "", - }) - .returning() - .get(); - testPageId = mainPage.id; + // Clean up any existing test data + await db + .delete(maintenance) + .where(eq(maintenance.title, `${TEST_PREFIX}-main`)); + await db + .delete(maintenance) + .where(eq(maintenance.title, `${TEST_PREFIX}-to-delete`)); + await db + .delete(maintenance) + .where(eq(maintenance.title, `${TEST_PREFIX}-to-update`)); + await db + .delete(pageComponent) + .where(eq(pageComponent.name, `${TEST_PREFIX}-component`)); - // Create a test page component on the suite's page + // Create a test page component (using existing page 1 from seed) const component = await db .insert(pageComponent) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, type: "static", name: `${TEST_PREFIX}-component`, description: "Test component for maintenance tests", @@ -108,9 +84,9 @@ beforeAll(async () => { const page2 = await db .insert(page) .values({ - workspaceId: testWorkspaceId, + workspaceId: 1, title: `${TEST_PREFIX}-page-2`, - slug: `${TEST_PREFIX}-page-2-slug-${nanoid(8)}`, + slug: `${TEST_PREFIX}-page-2-slug`, description: "Second test page for mixed-page tests", customDomain: "", }) @@ -121,7 +97,7 @@ beforeAll(async () => { const component2 = await db .insert(pageComponent) .values({ - workspaceId: testWorkspaceId, + workspaceId: 1, pageId: testPage2Id, type: "static", name: `${TEST_PREFIX}-component-2`, @@ -136,8 +112,8 @@ beforeAll(async () => { const maintenanceRecord = await db .insert(maintenance) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, title: `${TEST_PREFIX}-main`, message: "Test maintenance message", from: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day from now @@ -157,8 +133,8 @@ beforeAll(async () => { const deleteRecord = await db .insert(maintenance) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, title: `${TEST_PREFIX}-to-delete`, message: "Maintenance to delete", from: new Date(Date.now() + 48 * 60 * 60 * 1000), @@ -172,8 +148,8 @@ beforeAll(async () => { const updateRecord = await db .insert(maintenance) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, title: `${TEST_PREFIX}-to-update`, message: "Maintenance to update", from: new Date(Date.now() + 72 * 60 * 60 * 1000), @@ -192,8 +168,8 @@ beforeAll(async () => { const notifyRecord = await db .insert(maintenance) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, title: `${TEST_PREFIX}-for-notify`, message: "Maintenance for notify tests", from: new Date(Date.now() + 96 * 60 * 60 * 1000), @@ -212,7 +188,7 @@ beforeAll(async () => { const subscriber = await db .insert(pageSubscriber) .values({ - pageId: testPageId, + pageId: 1, email: `${TEST_PREFIX}@example.com`, token: `${TEST_PREFIX}-token`, acceptedAt: new Date(), @@ -272,14 +248,6 @@ afterAll(async () => { .delete(pageComponent) .where(eq(pageComponent.name, `${TEST_PREFIX}-component-2`)); await db.delete(page).where(eq(page.title, `${TEST_PREFIX}-page-2`)); - - // Tear down the dedicated page + workspace last (FK order). - if (testPageId) { - await db.delete(page).where(eq(page.id, testPageId)); - } - if (testWorkspaceId) { - await db.delete(workspace).where(eq(workspace.id, testWorkspaceId)); - } }); describe("MaintenanceService.CreateMaintenance", () => { @@ -294,10 +262,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Scheduled maintenance for system upgrade.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [String(testPageComponentId)], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -335,8 +303,8 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), - pageComponentIds: [String(testPageComponentId)], + pageId: "1", + pageComponentIds: ["1"], }); expect(res.status).toBe(401); @@ -353,10 +321,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: ["99999"], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -373,13 +341,13 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [ String(testPageComponentId), String(testPage2ComponentId), ], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -400,10 +368,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test pageId mismatch with components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), // This doesn't match testPage2ComponentId's page + pageId: "1", // This doesn't match testPage2ComponentId's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -429,7 +397,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: String(testPage2Id), // Matching the component's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -473,10 +441,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Maintenance without components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -506,11 +474,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Notifying subscribers about this maintenance.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [String(testPageComponentId)], notify: true, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -551,11 +519,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "No notification for this one.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [], notify: false, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -583,10 +551,10 @@ describe("MaintenanceService.CreateMaintenance", () => { to: new Date( Date.now() + 7 * 24 * 60 * 60 * 1000 + 3600000, ).toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -605,10 +573,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test with invalid date range.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: String(testPageId), + pageId: "1", pageComponentIds: [], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -630,7 +598,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: "99999", pageComponentIds: [], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -648,7 +616,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(testMaintenanceId) }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -678,7 +646,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "99999" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -702,7 +670,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -715,7 +683,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -725,7 +693,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: " " }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -737,7 +705,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -752,7 +720,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -781,7 +749,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 1 }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -795,7 +763,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res1 = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); const data1 = await res1.json(); const totalSize = data1.totalSize; @@ -805,7 +773,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res2 = await connectRequest( "ListMaintenances", { limit: 1, offset: 0 }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); const data2 = await res2.json(); @@ -813,7 +781,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res3 = await connectRequest( "ListMaintenances", { limit: 1, offset: 1 }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); const data3 = await res3.json(); @@ -827,16 +795,16 @@ describe("MaintenanceService.ListMaintenances", () => { test("filters by page_id", async () => { const res = await connectRequest( "ListMaintenances", - { pageId: String(testPageId) }, - { "x-openstatus-key": authKey }, + { pageId: "1" }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); const data = await res.json(); - // All returned maintenances should belong to the filtered page + // All returned maintenances should have pageId 1 for (const record of data.maintenances || []) { - expect(record.pageId).toBe(String(testPageId)); + expect(record.pageId).toBe("1"); } }); @@ -858,7 +826,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -883,7 +851,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-updated-title`, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -906,7 +874,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), message: "Updated maintenance message", }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -922,22 +890,21 @@ describe("MaintenanceService.UpdateMaintenance", () => { }); test("updates page component associations", async () => { + // Use existing seeded page component 1 const res = await connectRequest( "UpdateMaintenance", { id: String(testMaintenanceToUpdateId), - pageComponentIds: [String(testPageComponentId)], + pageComponentIds: ["1"], updatePageComponentIds: true, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); const data = await res.json(); - expect(data.maintenance.pageComponentIds).toContain( - String(testPageComponentId), - ); + expect(data.maintenance.pageComponentIds).toContain("1"); }); test("returns 401 when no auth key provided", async () => { @@ -953,7 +920,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "99999", title: "Non-existent update" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -963,7 +930,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "", title: "Empty ID update" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -973,7 +940,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: " ", title: "Whitespace ID update" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -997,7 +964,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: String(otherRecord.id), title: "Should not update" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -1014,7 +981,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: ["99999"], updatePageComponentIds: true, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -1031,7 +998,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { ], updatePageComponentIds: true, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -1057,7 +1024,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), from: newFrom.toISOString(), }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -1088,7 +1055,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-title-only`, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -1137,7 +1104,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageComponentIds: ["99999"], }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -1169,7 +1136,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageId: "999", }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -1187,8 +1154,8 @@ describe("MaintenanceService.UpdateMaintenance", () => { const tempRecord = await db .insert(maintenance) .values({ - workspaceId: testWorkspaceId, - pageId: testPageId, + workspaceId: 1, + pageId: 1, title: `${TEST_PREFIX}-clear-pageid`, message: "Temp maintenance for clear test", from: new Date(Date.now() + 24 * 60 * 60 * 1000), @@ -1210,7 +1177,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: [], updatePageComponentIds: true, }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -1242,7 +1209,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(testMaintenanceToDeleteId) }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(200); @@ -1269,7 +1236,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "99999" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); @@ -1279,7 +1246,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "" }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -1289,7 +1256,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: " " }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(400); @@ -1313,7 +1280,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": authKey }, + { "x-openstatus-key": "1" }, ); expect(res.status).toBe(404); diff --git a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts index 2a6c33c7..7b9e19d9 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts @@ -1,3 +1,12 @@ +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + test, +} from "bun:test"; + import { and, db, eq } from "@openstatus/db"; import { auditLog, @@ -5,23 +14,10 @@ import { pageComponent, privateLocation, privateLocationToMonitors, - workspace, } from "@openstatus/db/src/schema"; import { monitorStatusTable } from "@openstatus/db/src/schema/monitor_status/monitor_status"; -import { - createMonitor, - createWorkspace, -} from "@openstatus/db/src/test/factories"; -import { expect } from "@std/expect"; -import { - afterAll, - beforeAll, - beforeEach, - describe, - test, -} from "@std/testing/bdd"; -import { app } from "../../../../../index"; +import { app } from "@/index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -503,17 +499,20 @@ describe("MonitorService.DeleteMonitor", () => { }); test("cannot delete monitor from another workspace", async () => { - // Isolated workspace (fresh, unique id) so this never collides with seed - // data or another suite mutating workspace 2 in parallel. - const otherWorkspace = await createWorkspace(); - const otherWorkspaceMon = await createMonitor(otherWorkspace.id, { - name: `${TEST_PREFIX}-delete-other-ws`, - url: "https://other-ws-delete.example.com", - periodicity: "1m", - active: true, - regions: "ams", - jobType: "http", - }); + // Create a monitor for workspace 2 + const otherWorkspaceMon = await db + .insert(monitor) + .values({ + workspaceId: 2, + name: `${TEST_PREFIX}-delete-other-ws`, + url: "https://other-ws-delete.example.com", + periodicity: "1m", + active: true, + regions: "ams", + jobType: "http", + }) + .returning() + .get(); try { // Try to delete with workspace 1's key @@ -537,7 +536,6 @@ describe("MonitorService.DeleteMonitor", () => { expect(stillExists?.deletedAt).toBeNull(); } finally { await db.delete(monitor).where(eq(monitor.id, otherWorkspaceMon.id)); - await db.delete(workspace).where(eq(workspace.id, otherWorkspace.id)); } }); diff --git a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts index c617b766..bce0efdc 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts @@ -1,7 +1,7 @@ +import { describe, expect, test } from "bun:test"; + import { Region } from "@openstatus/proto/monitor/v1"; import { AVAILABLE_REGIONS, RAILWAY_REGIONS } from "@openstatus/regions"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { regionToString, @@ -20,17 +20,13 @@ describe("region converter", () => { ["railway_asia-southeast1-eqsg3a", Region.RAILWAY_ASIA_SOUTHEAST1], ]; - for (const [db, proto] of cases) { - test(`stringToRegion(${db}) → enum`, () => { - expect(stringToRegion(db)).toBe(proto); - }); - } + test.each(cases)("stringToRegion(%s) → enum", (db, proto) => { + expect(stringToRegion(db)).toBe(proto); + }); - for (const [db, proto] of cases) { - test(`regionToString(enum) → ${db}`, () => { - expect(regionToString(proto)).toBe(db); - }); - } + test.each(cases)("regionToString(enum) → %s", (db, proto) => { + expect(regionToString(proto)).toBe(db); + }); test("validateRegions accepts all Railway DB codes", () => { expect(validateRegions([...RAILWAY_REGIONS])).toEqual([]); diff --git a/apps/server/src/routes/rpc/handlers/monitor/index.ts b/apps/server/src/routes/rpc/handlers/monitor/index.ts index e6a4522b..3e7fda8a 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/index.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/index.ts @@ -30,8 +30,9 @@ import { listResponseLogs, } from "@openstatus/services/monitor"; -import { env } from "../../../../env"; -import { getCheckerPayload, getCheckerUrl } from "../../../../libs/checker"; +import { env } from "@/env"; +import { getCheckerPayload, getCheckerUrl } from "@/libs/checker"; + import { toConnectError, toServiceCtx } from "../../adapter"; import { getRpcContext } from "../../interceptors"; import { diff --git a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts index 315eb4df..575dc685 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts @@ -1,6 +1,6 @@ +import { expect, test } from "bun:test"; + import { redactSensitiveHeaders } from "@openstatus/services/monitor"; -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; test("redactSensitiveHeaders returns an empty object when headers are missing", () => { expect(redactSensitiveHeaders(null)).toEqual({}); diff --git a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts index bf640a35..87c9dde4 100644 --- a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts +++ b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts @@ -1,12 +1,12 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "../../../../../index"; +import { app } from "@/index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). diff --git a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts index d153fd31..6daf779f 100644 --- a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, eq, isNull, sql } from "@openstatus/db"; import { auditLog, @@ -9,11 +11,8 @@ import { statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; -import { mock } from "@openstatus/test-utils"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "../../../../../index"; +import { app } from "@/index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -1721,7 +1720,7 @@ describe("StatusPageService.UpdateComponentGroup", () => { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - sendVerification: ReturnType; + sendVerification: ReturnType; }; describe("StatusPageService.SubscribeToPage", () => { diff --git a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts index 03f4c58a..57e03d4c 100644 --- a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { page, @@ -7,18 +9,14 @@ import { statusReportUpdate, statusReportUpdateToPageComponents, statusReportsToPageComponents, - workspace, } from "@openstatus/db/src/schema"; -import { createWorkspace } from "@openstatus/db/src/test/factories"; import { PageComponentImpact, StatusReportStatus, } from "@openstatus/proto/status_report/v1"; -import { mock } from "@openstatus/test-utils"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "../../../../../index"; +import { app } from "@/index"; + import { dbImpactToProto, protoImpactToDb, @@ -27,8 +25,8 @@ import { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -783,64 +781,36 @@ describe("StatusReportService.ListStatusReports", () => { }); test("respects offset parameter", async () => { - // Isolate in a dedicated workspace so concurrent inserts from other suites - // can't shift the pagination window mid-test. In dev/test the - // `x-openstatus-key` header is the workspace id. Distinct createdAt values - // give the `desc(createdAt)` order a deterministic sequence. - const ws = await createWorkspace(); - const key = String(ws.id); - const now = Date.now(); - const inserted = await db - .insert(statusReport) - .values([ - { - workspaceId: ws.id, - title: `${TEST_PREFIX}-offset-1`, - status: "investigating", - createdAt: new Date(now - 2000), - }, - { - workspaceId: ws.id, - title: `${TEST_PREFIX}-offset-2`, - status: "investigating", - createdAt: new Date(now - 1000), - }, - { - workspaceId: ws.id, - title: `${TEST_PREFIX}-offset-3`, - status: "investigating", - createdAt: new Date(now), - }, - ]) - .returning(); - - try { - const total = await connectRequest( - "ListStatusReports", - {}, - { "x-openstatus-key": key }, - ); - expect((await total.json()).totalSize).toBe(inserted.length); + // Get total count first + const res1 = await connectRequest( + "ListStatusReports", + {}, + { "x-openstatus-key": "1" }, + ); + const data1 = await res1.json(); + const totalSize = data1.totalSize; - const page1 = await connectRequest( + if (totalSize > 1) { + // Get first page + const res2 = await connectRequest( "ListStatusReports", { limit: 1, offset: 0 }, - { "x-openstatus-key": key }, + { "x-openstatus-key": "1" }, ); - const page2 = await connectRequest( + const data2 = await res2.json(); + + // Get second page + const res3 = await connectRequest( "ListStatusReports", { limit: 1, offset: 1 }, - { "x-openstatus-key": key }, + { "x-openstatus-key": "1" }, ); - const data1 = await page1.json(); - const data2 = await page2.json(); + const data3 = await res3.json(); - expect(data1.statusReports).toHaveLength(1); - expect(data2.statusReports).toHaveLength(1); - expect(data1.statusReports[0].id).not.toBe(data2.statusReports[0].id); - } finally { - await db.delete(statusReport).where(eq(statusReport.workspaceId, ws.id)); - await db.delete(workspace).where(eq(workspace.id, ws.id)); + // Should have different reports + if (data2.statusReports?.length > 0 && data3.statusReports?.length > 0) { + expect(data2.statusReports[0].id).not.toBe(data3.statusReports[0].id); + } } }); diff --git a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts index 234213c1..d79ebb00 100644 --- a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts +++ b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts @@ -1,26 +1,35 @@ -import type { Interceptor } from "@connectrpc/connect"; -import { Events } from "@openstatus/analytics"; // @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) // are incompatible with bun:test mocks. All runtime behavior is correct. -import { - beforeEach, - describe, - expect, - mock, - test, -} from "@openstatus/test-utils"; +import { beforeEach, describe, expect, mock, test } from "bun:test"; + +import type { Interceptor } from "@connectrpc/connect"; +import { Events } from "@openstatus/analytics"; import { RPC_CONTEXT_KEY } from "../auth"; import { RPC_EVENT_MAP, trackingInterceptor } from "../tracking"; -// @openstatus/analytics is swapped for a double (test.importmap.json) whose -// setupAnalytics/track spies are exposed here on globalThis. -const { track: mockTrack, setupAnalytics: mockSetupAnalytics } = ( - globalThis as Record -).__analyticsSpies as { - track: ReturnType; - setupAnalytics: ReturnType; -}; +// Mock analytics +const mockTrack = mock(() => Promise.resolve()); +const mockSetupAnalytics = mock((_props: unknown) => + Promise.resolve({ track: mockTrack }), +); + +mock.module("@openstatus/analytics", () => ({ + Events, + parseInputToProps: (json: unknown, props?: string[]) => { + if (typeof json !== "object" || json === null || !props) return {}; + return props.reduce( + (acc, prop) => { + if (prop in json) { + acc[prop] = (json as Record)[prop]; + } + return acc; + }, + {} as Record, + ); + }, + setupAnalytics: (props: unknown) => mockSetupAnalytics(props), +})); type NextFn = Parameters>[0]; diff --git a/apps/server/src/routes/rpc/interceptors/auth.ts b/apps/server/src/routes/rpc/interceptors/auth.ts index 72171178..ef72d8a6 100644 --- a/apps/server/src/routes/rpc/interceptors/auth.ts +++ b/apps/server/src/routes/rpc/interceptors/auth.ts @@ -7,7 +7,7 @@ import { import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { nanoid } from "nanoid"; -import { lookupWorkspace, validateKey } from "../../../libs/middlewares/auth"; +import { lookupWorkspace, validateKey } from "@/libs/middlewares/auth"; /** * RPC context containing workspace and request information. diff --git a/apps/server/src/routes/slack/blocks.test.ts b/apps/server/src/routes/slack/blocks.test.ts index ceac36c3..65cd22be 100644 --- a/apps/server/src/routes/slack/blocks.test.ts +++ b/apps/server/src/routes/slack/blocks.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import { agentTools } from "@openstatus/services/agent-tools"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { buildConfirmationBlocks, diff --git a/apps/server/src/routes/slack/confirmation-store.test.ts b/apps/server/src/routes/slack/confirmation-store.test.ts index 93e7a211..4964d393 100644 --- a/apps/server/src/routes/slack/confirmation-store.test.ts +++ b/apps/server/src/routes/slack/confirmation-store.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, test } from "@std/testing/bdd"; +import { beforeEach, describe, expect, test } from "bun:test"; import { consume, diff --git a/apps/server/src/routes/slack/handler.test.ts b/apps/server/src/routes/slack/handler.test.ts index 0bfcfbad..86e01f69 100644 --- a/apps/server/src/routes/slack/handler.test.ts +++ b/apps/server/src/routes/slack/handler.test.ts @@ -1,20 +1,84 @@ +import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; -import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; -// workspace-resolver / @slack/web-api / agent are swapped for doubles via the -// test import map; behavior is driven through this shared mutable state. -import { slackTestState } from "@/libs/test/doubles/slack-test-state"; - -import { handleSlackEvent } from "./handler"; -import { verifySlackSignature } from "./verify"; +import * as agentModule from "./agent"; const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; process.env.AI_GATEWAY_API_KEY = "test-key"; +mock.module("./workspace-resolver", () => ({ + resolveWorkspace: (teamId: string) => { + if (teamId === "T_KNOWN") { + return Promise.resolve({ + workspace: { + id: 1, + name: "Test Workspace", + slug: "test", + plan: "free", + limits: {}, + }, + botToken: "xoxb-test", + botUserId: "UBOT", + }); + } + return Promise.resolve(null); + }, +})); + +let slackMessages: Array<{ method: string; args: Record }> = + []; +let postMessageOverride: + | ((args: Record) => Promise<{ ts: string }>) + | null = null; +let updateOverride: + | ((args: Record) => Promise<{ ts: string }>) + | null = null; + +mock.module("@slack/web-api", () => ({ + WebClient: class { + chat = { + postMessage: (args: Record) => { + if (postMessageOverride) return postMessageOverride(args); + slackMessages.push({ method: "postMessage", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + update: (args: Record) => { + if (updateOverride) return updateOverride(args); + slackMessages.push({ method: "update", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + }; + conversations = { + replies: () => + Promise.resolve({ + messages: [{ user: "U1", text: "test message", ts: "1.1" }], + }), + }; + }, +})); + +let runAgentOverride: + | (() => Promise<{ text: string; toolResults: never[] }>) + | null = null; + +mock.module("./agent", () => ({ + ...agentModule, + runAgent: () => { + if (runAgentOverride) return runAgentOverride(); + return Promise.resolve({ + text: "Here is my response", + toolResults: [], + }); + }, +})); + +const { handleSlackEvent } = await import("./handler"); +const { verifySlackSignature } = await import("./verify"); + function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); app.post("/slack/events", verifySlackSignature, handleSlackEvent); @@ -48,26 +112,10 @@ describe("handleSlackEvent", () => { const app = createTestApp(); beforeEach(() => { - slackTestState.calls = []; - slackTestState.postMessageOverride = null; - slackTestState.updateOverride = null; - slackTestState.runAgentOverride = null; - slackTestState.resolveWorkspace = (teamId: string) => { - if (teamId === "T_KNOWN") { - return Promise.resolve({ - workspace: { - id: 1, - name: "Test Workspace", - slug: "test", - plan: "free", - limits: {}, - }, - botToken: "xoxb-test", - botUserId: "UBOT", - }); - } - return Promise.resolve(null); - }; + slackMessages = []; + postMessageOverride = null; + updateOverride = null; + runAgentOverride = null; }); test("responds to url_verification challenge", async () => { @@ -154,11 +202,11 @@ describe("handleSlackEvent", () => { await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - slackTestState.calls = []; + slackMessages = []; await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores events from unknown teams", async () => { @@ -177,7 +225,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores message events from bots", async () => { @@ -196,7 +244,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores channel message without bot mention", async () => { @@ -216,7 +264,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("processes DM messages without bot mention", async () => { @@ -237,7 +285,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); // DM should trigger a response (postMessage for "Thinking...") - expect(slackTestState.calls.length).toBeGreaterThan(0); + expect(slackMessages.length).toBeGreaterThan(0); }); test("ignores events without channel", async () => { @@ -255,7 +303,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores events without timestamp", async () => { @@ -273,7 +321,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores events without team_id", async () => { @@ -291,7 +339,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores unsupported event types", async () => { @@ -306,7 +354,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores channel_join system messages", async () => { @@ -326,7 +374,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores channel_leave system messages", async () => { @@ -346,7 +394,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("ignores events with no event payload", async () => { @@ -358,12 +406,12 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackTestState.calls.length).toBe(0); + expect(slackMessages.length).toBe(0); }); test("falls back to top-level message on cannot_reply_to_message", async () => { let callCount = 0; - slackTestState.postMessageOverride = (args: Record) => { + postMessageOverride = (args: Record) => { callCount++; if (callCount === 1) { const err = new Error("An API error occurred: cannot_reply_to_message"); @@ -373,7 +421,7 @@ describe("handleSlackEvent", () => { }); return Promise.reject(err); } - slackTestState.calls.push({ method: "postMessage", args }); + slackMessages.push({ method: "postMessage", args }); return Promise.resolve({ ts: "fallback.ts" }); }; @@ -393,14 +441,14 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const fallbackPost = slackTestState.calls.find( + const fallbackPost = slackMessages.find( (m) => m.method === "postMessage" && !m.args.thread_ts, ); expect(fallbackPost).toBeDefined(); }); test("returns early on non-recoverable postMessage error", async () => { - slackTestState.postMessageOverride = () => { + postMessageOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", @@ -425,15 +473,12 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const updateMessages = slackTestState.calls.filter( - (m) => m.method === "update", - ); + const updateMessages = slackMessages.filter((m) => m.method === "update"); expect(updateMessages.length).toBe(0); }); test("shows error message when runAgent throws", async () => { - slackTestState.runAgentOverride = () => - Promise.reject(new Error("agent exploded")); + runAgentOverride = () => Promise.reject(new Error("agent exploded")); const res = await signAndPost(app, { type: "event_callback", @@ -451,7 +496,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const errorUpdate = slackTestState.calls.find( + const errorUpdate = slackMessages.find( (m) => m.method === "update" && typeof m.args.text === "string" && @@ -461,9 +506,8 @@ describe("handleSlackEvent", () => { }); test("does not throw when both runAgent and error update fail", async () => { - slackTestState.runAgentOverride = () => - Promise.reject(new Error("agent exploded")); - slackTestState.updateOverride = () => { + runAgentOverride = () => Promise.reject(new Error("agent exploded")); + updateOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", diff --git a/apps/server/src/routes/slack/index.test.ts b/apps/server/src/routes/slack/index.test.ts index 89c34b80..54983660 100644 --- a/apps/server/src/routes/slack/index.test.ts +++ b/apps/server/src/routes/slack/index.test.ts @@ -1,7 +1,6 @@ +import { beforeEach, describe, expect, test } from "bun:test"; import crypto from "node:crypto"; -import { expect } from "@std/expect"; -import { beforeEach, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; const SIGNING_SECRET = "test-signing-secret"; diff --git a/apps/server/src/routes/slack/interactions.test.ts b/apps/server/src/routes/slack/interactions.test.ts index 98be8198..a056ce6d 100644 --- a/apps/server/src/routes/slack/interactions.test.ts +++ b/apps/server/src/routes/slack/interactions.test.ts @@ -1,15 +1,8 @@ +import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; -import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; -// workspace-resolver / @slack/web-api are swapped for doubles via the test -// import map; behavior is driven through this shared mutable state. -import { slackTestState } from "@/libs/test/doubles/slack-test-state"; - -import { handleSlackInteraction } from "./interactions"; -import { verifySlackSignature } from "./verify"; - const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; @@ -29,13 +22,34 @@ const basePending = { createdAt: Date.now(), }; -function configureSlackDoubles() { - slackTestState.calls = []; - slackTestState.resolveWorkspace = (teamId: string) => - teamId === "T_KNOWN" - ? Promise.resolve({ botToken: "xoxb-fallback" }) - : Promise.resolve(null); -} +mock.module("./workspace-resolver", () => ({ + resolveWorkspace: (teamId: string) => { + if (teamId === "T_KNOWN") { + return Promise.resolve({ botToken: "xoxb-fallback" }); + } + return Promise.resolve(null); + }, +})); + +let slackCalls: Array<{ method: string; args: Record }> = []; + +mock.module("@slack/web-api", () => ({ + WebClient: class { + chat = { + update: (args: Record) => { + slackCalls.push({ method: "update", args }); + return Promise.resolve(); + }, + postEphemeral: (args: Record) => { + slackCalls.push({ method: "postEphemeral", args }); + return Promise.resolve(); + }, + }; + }, +})); + +const { handleSlackInteraction } = await import("./interactions"); +const { verifySlackSignature } = await import("./verify"); function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); @@ -119,14 +133,14 @@ describe("handleSlackInteraction (dispatch)", () => { const app = createTestApp(); beforeEach(() => { - configureSlackDoubles(); + slackCalls = []; redisStore.clear(); }); test("returns ok for non-block_actions", async () => { const res = await signAndPost(app, { type: "message_action", actions: [] }); expect(res.status).toBe(200); - expect(slackTestState.calls).toHaveLength(0); + expect(slackCalls).toHaveLength(0); }); test("returns ok for unknown action_id prefix", async () => { @@ -139,7 +153,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "unknown_action" }], }); expect(res.status).toBe(200); - expect(slackTestState.calls).toHaveLength(0); + expect(slackCalls).toHaveLength(0); }); test("cancel updates message to cancelled", async () => { @@ -153,7 +167,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "cancel_pending-123" }], }); expect(res.status).toBe(200); - const cancelCall = slackTestState.calls.find( + const cancelCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -171,9 +185,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_pending-123" }], }); expect(res.status).toBe(200); - const ephemeral = slackTestState.calls.find( - (c) => c.method === "postEphemeral", - ); + const ephemeral = slackCalls.find((c) => c.method === "postEphemeral"); expect(ephemeral).toBeDefined(); expect(ephemeral?.args.text as string).toContain("Only the person"); expect(redisStore.has("slack:action:pending-123")).toBe(true); @@ -189,7 +201,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_unknown-id" }], }); expect(res.status).toBe(200); - const expiredCall = slackTestState.calls.find( + const expiredCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).includes("expired"), ); @@ -206,7 +218,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_some-id" }], }); expect(res.status).toBe(200); - expect(slackTestState.calls).toHaveLength(0); + expect(slackCalls).toHaveLength(0); }); test("approve_flag parses flag=true; approve parses flag=false", async () => { @@ -242,7 +254,7 @@ describe("registry-runner execution paths", () => { const app = createTestApp(); beforeEach(() => { - configureSlackDoubles(); + slackCalls = []; redisStore.clear(); }); @@ -257,7 +269,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackTestState.calls.find( + const successCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).includes( @@ -281,7 +293,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_flag_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackTestState.calls.find( + const successCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).includes("subscribers notified"), @@ -300,7 +312,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "cancel_maint-001" }], }); expect(res.status).toBe(200); - const cancelCall = slackTestState.calls.find( + const cancelCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -318,7 +330,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad" }], }); expect(res.status).toBe(200); - const errCall = slackTestState.calls.find( + const errCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:") && @@ -342,7 +354,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad-time" }], }); expect(res.status).toBe(200); - const errCall = slackTestState.calls.find( + const errCall = slackCalls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:"), ); expect(errCall).toBeDefined(); diff --git a/apps/server/src/routes/slack/oauth.test.ts b/apps/server/src/routes/slack/oauth.test.ts index 19624dd0..8d6bc847 100644 --- a/apps/server/src/routes/slack/oauth.test.ts +++ b/apps/server/src/routes/slack/oauth.test.ts @@ -1,7 +1,6 @@ +import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { handleSlackInstall, handleSlackOAuthCallback } from "./oauth"; diff --git a/apps/server/src/routes/slack/presenters/presenters.test.ts b/apps/server/src/routes/slack/presenters/presenters.test.ts index 1878a698..4161a12e 100644 --- a/apps/server/src/routes/slack/presenters/presenters.test.ts +++ b/apps/server/src/routes/slack/presenters/presenters.test.ts @@ -1,13 +1,20 @@ +import { describe, expect, mock, test } from "bun:test"; + import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; -import { describe, expect, test } from "@openstatus/test-utils"; import { z } from "zod"; -// page-urls.ts hits the db; it's swapped for a deterministic double via the -// test import map (see test.importmap.json). -import { defaultPresenter } from "./default"; -import { renderToolResult } from "./index"; +// page-urls.ts hits the db; stub before the presenters module loads. +mock.module("../page-urls", () => ({ + getPageUrl: (_pageId: number) => + Promise.resolve("https://example.openstatus.dev"), + getReportUrl: (_pageId: number, reportId: number) => + Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`), +})); + +const { defaultPresenter } = await import("./default"); +const { renderToolResult } = await import("./index"); const fakeCtx = { workspace: { id: 1 }, diff --git a/apps/server/src/routes/slack/registry-runner.test.ts b/apps/server/src/routes/slack/registry-runner.test.ts index a5dad44e..dd1e7494 100644 --- a/apps/server/src/routes/slack/registry-runner.test.ts +++ b/apps/server/src/routes/slack/registry-runner.test.ts @@ -1,8 +1,8 @@ +import { describe, expect, test } from "bun:test"; + import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { z } from "zod"; import { diff --git a/apps/server/src/routes/slack/system-prompt.test.ts b/apps/server/src/routes/slack/system-prompt.test.ts index 42835ee7..0b23f798 100644 --- a/apps/server/src/routes/slack/system-prompt.test.ts +++ b/apps/server/src/routes/slack/system-prompt.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { buildSystemPrompt } from "./system-prompt"; diff --git a/apps/server/src/routes/slack/verify.test.ts b/apps/server/src/routes/slack/verify.test.ts index 4640216e..83b0650c 100644 --- a/apps/server/src/routes/slack/verify.test.ts +++ b/apps/server/src/routes/slack/verify.test.ts @@ -1,7 +1,6 @@ +import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { verifySlackSignature } from "./verify"; diff --git a/apps/server/src/routes/v1/check/http/post.test.ts b/apps/server/src/routes/v1/check/http/post.test.ts index ab47edfa..586b8454 100644 --- a/apps/server/src/routes/v1/check/http/post.test.ts +++ b/apps/server/src/routes/v1/check/http/post.test.ts @@ -1,10 +1,12 @@ -import { afterEach, expect, mock, test } from "@openstatus/test-utils"; +import { expect, test } from "bun:test"; +import { afterEach, mock } from "bun:test"; import { app } from "@/index"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; +mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/incidents/get.test.ts b/apps/server/src/routes/v1/incidents/get.test.ts index 9de6b293..c7f23e00 100644 --- a/apps/server/src/routes/v1/incidents/get.test.ts +++ b/apps/server/src/routes/v1/incidents/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/get_all.test.ts b/apps/server/src/routes/v1/incidents/get_all.test.ts index 19cb2dc1..618ff95b 100644 --- a/apps/server/src/routes/v1/incidents/get_all.test.ts +++ b/apps/server/src/routes/v1/incidents/get_all.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/put.test.ts b/apps/server/src/routes/v1/incidents/put.test.ts index 8bf5f059..309e41d5 100644 --- a/apps/server/src/routes/v1/incidents/put.test.ts +++ b/apps/server/src/routes/v1/incidents/put.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get.test.ts b/apps/server/src/routes/v1/maintenances/get.test.ts index 69a4a248..c7927a23 100644 --- a/apps/server/src/routes/v1/maintenances/get.test.ts +++ b/apps/server/src/routes/v1/maintenances/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get_all.test.ts b/apps/server/src/routes/v1/maintenances/get_all.test.ts index 2eb76192..b5682afd 100644 --- a/apps/server/src/routes/v1/maintenances/get_all.test.ts +++ b/apps/server/src/routes/v1/maintenances/get_all.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { maintenance, @@ -5,8 +7,6 @@ import { monitor, pageComponent, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/post.test.ts b/apps/server/src/routes/v1/maintenances/post.test.ts index d4fd15fe..dbb51799 100644 --- a/apps/server/src/routes/v1/maintenances/post.test.ts +++ b/apps/server/src/routes/v1/maintenances/post.test.ts @@ -1,7 +1,7 @@ +import { beforeEach, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { maintenance } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -245,9 +245,7 @@ test("create a maintenance calls dispatchMaintenanceUpdate", async () => { const result = MaintenanceSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchMaintenanceUpdate.mock.calls.length).toBe(1); - expect(typeof spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBe( - "number", - ); + expect(spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBeNumber(); if (result.success) { await db.delete(maintenance).where(eq(maintenance.id, result.data.id)); diff --git a/apps/server/src/routes/v1/maintenances/put.test.ts b/apps/server/src/routes/v1/maintenances/put.test.ts index 1400f196..bf462424 100644 --- a/apps/server/src/routes/v1/maintenances/put.test.ts +++ b/apps/server/src/routes/v1/maintenances/put.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; @@ -97,7 +96,7 @@ test("update only the message", async () => { expect(result.data?.message).toBe("Only Message Updated"); }); -test.ignore("update only the dates", async () => { +test.todo("update only the dates", async () => { const from = new Date(); const to = new Date(from.getTime() + 7200000); // 2 hours later @@ -121,27 +120,24 @@ test.ignore("update only the dates", async () => { expect(result.data?.to).toEqual(to); }); -test.ignore( - "update maintenance with `from` date after `to` date should return 400", - async () => { - const to = new Date(); - const from = new Date(to.getTime() + 3600000); // from is 1 hour after to - - const res = await app.request("/v1/maintenance/1", { - method: "PUT", - headers: { - "x-openstatus-key": "1", - "Content-Type": "application/json", - }, - body: JSON.stringify({ - from: from.toISOString(), - to: to.toISOString(), - }), - }); - - expect(res.status).toBe(400); - }, -); +test.todo("update maintenance with `from` date after `to` date should return 400", async () => { + const to = new Date(); + const from = new Date(to.getTime() + 3600000); // from is 1 hour after to + + const res = await app.request("/v1/maintenance/1", { + method: "PUT", + headers: { + "x-openstatus-key": "1", + "Content-Type": "application/json", + }, + body: JSON.stringify({ + from: from.toISOString(), + to: to.toISOString(), + }), + }); + + expect(res.status).toBe(400); +}); test("remove all maintenance monitors", async () => { const res = await app.request("/v1/maintenance/1", { @@ -162,7 +158,7 @@ test("remove all maintenance monitors", async () => { expect(result.data?.monitorIds?.length).toBe(0); }); -test.ignore("empty body should return 400", async () => { +test.todo("empty body should return 400", async () => { const res = await app.request("/v1/maintenance/1", { method: "PUT", headers: { diff --git a/apps/server/src/routes/v1/monitors/delete.test.ts b/apps/server/src/routes/v1/monitors/delete.test.ts index 9e9adec8..503883c0 100644 --- a/apps/server/src/routes/v1/monitors/delete.test.ts +++ b/apps/server/src/routes/v1/monitors/delete.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get.test.ts b/apps/server/src/routes/v1/monitors/get.test.ts index 15209292..9a26b26a 100644 --- a/apps/server/src/routes/v1/monitors/get.test.ts +++ b/apps/server/src/routes/v1/monitors/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get_all.test.ts b/apps/server/src/routes/v1/monitors/get_all.test.ts index 97c7dbed..f7b286dc 100644 --- a/apps/server/src/routes/v1/monitors/get_all.test.ts +++ b/apps/server/src/routes/v1/monitors/get_all.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post.test.ts b/apps/server/src/routes/v1/monitors/post.test.ts index 84ba06e5..235329cf 100644 --- a/apps/server/src/routes/v1/monitors/post.test.ts +++ b/apps/server/src/routes/v1/monitors/post.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; import { createErrorSchema } from "@/libs/errors"; @@ -124,7 +123,7 @@ test("create a monitor with deprecated regions should return 400", async () => { expect(res.status).toBe(400); expect(errorSchema.success).toBe(true); - expect(errorSchema.data?.message).toContain( + expect(errorSchema.data?.message).toMatch( "Deprecated regions are not allowed: hkg, waw", ); }); diff --git a/apps/server/src/routes/v1/monitors/post_dns.test.ts b/apps/server/src/routes/v1/monitors/post_dns.test.ts index 5a5b3d81..70223677 100644 --- a/apps/server/src/routes/v1/monitors/post_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/post_dns.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_http.test.ts b/apps/server/src/routes/v1/monitors/post_http.test.ts index 7ac84591..9caa0bef 100644 --- a/apps/server/src/routes/v1/monitors/post_http.test.ts +++ b/apps/server/src/routes/v1/monitors/post_http.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_tcp.test.ts b/apps/server/src/routes/v1/monitors/post_tcp.test.ts index 650a79dc..7958913b 100644 --- a/apps/server/src/routes/v1/monitors/post_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/post_tcp.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put.test.ts b/apps/server/src/routes/v1/monitors/put.test.ts index 3fa45af3..5b0357de 100644 --- a/apps/server/src/routes/v1/monitors/put.test.ts +++ b/apps/server/src/routes/v1/monitors/put.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_dns.test.ts b/apps/server/src/routes/v1/monitors/put_dns.test.ts index 3561dc06..e985b8af 100644 --- a/apps/server/src/routes/v1/monitors/put_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/put_dns.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_http.test.ts b/apps/server/src/routes/v1/monitors/put_http.test.ts index 4ae822a2..f042b7d2 100644 --- a/apps/server/src/routes/v1/monitors/put_http.test.ts +++ b/apps/server/src/routes/v1/monitors/put_http.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_tcp.test.ts b/apps/server/src/routes/v1/monitors/put_tcp.test.ts index 80ff9029..fa1c2f35 100644 --- a/apps/server/src/routes/v1/monitors/put_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/put_tcp.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/results/get.test.ts b/apps/server/src/routes/v1/monitors/results/get.test.ts index 511ec1bf..67ea10dc 100644 --- a/apps/server/src/routes/v1/monitors/results/get.test.ts +++ b/apps/server/src/routes/v1/monitors/results/get.test.ts @@ -1,11 +1,10 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; import { ResultRun } from "../schema"; -test.ignore("get monitor result with valid id should return 200", async () => { +test.todo("get monitor result with valid id should return 200", async () => { const res = await app.request("/v1/monitor/1/result/1", { method: "GET", headers: { @@ -61,23 +60,20 @@ test("get monitor result from different workspace should return 404", async () = expect(res.status).toBe(404); }); -test.ignore( - "get monitor result with valid TCP monitor should return 200", - async () => { - const res = await app.request("/v1/monitor/4/result/2", { - method: "GET", - headers: { - "x-openstatus-key": "1", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - const result = ResultRun.array().safeParse(json); - expect(result.success).toBe(true); - }, -); +test.todo("get monitor result with valid TCP monitor should return 200", async () => { + const res = await app.request("/v1/monitor/4/result/2", { + method: "GET", + headers: { + "x-openstatus-key": "1", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + const result = ResultRun.array().safeParse(json); + expect(result.success).toBe(true); +}); test("get monitor result with non-matching result id should return 404", async () => { const res = await app.request("/v1/monitor/1/result/999998", { diff --git a/apps/server/src/routes/v1/monitors/run/post.test.ts b/apps/server/src/routes/v1/monitors/run/post.test.ts index b0a1f756..26547105 100644 --- a/apps/server/src/routes/v1/monitors/run/post.test.ts +++ b/apps/server/src/routes/v1/monitors/run/post.test.ts @@ -1,4 +1,5 @@ -import { afterEach, expect, mock, test } from "@openstatus/test-utils"; +import { expect, test } from "bun:test"; +import { afterEach, mock } from "bun:test"; import { app } from "@/index"; @@ -7,6 +8,7 @@ import { TriggerResult } from "../schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; +mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); @@ -142,47 +144,44 @@ test("run TCP monitor with valid id should return 200", async () => { } }); -test.ignore( - "run monitor with multiple regions should return array of results", - async () => { - mockFetch.mockReturnValue( - Promise.resolve( - new Response( - JSON.stringify({ - jobType: "http", - status: 200, - latency: 100, - region: "ams", - timestamp: 1234567890, - timing: { - dnsStart: 1, - dnsDone: 2, - connectStart: 3, - connectDone: 4, - tlsHandshakeStart: 5, - tlsHandshakeDone: 6, - firstByteStart: 7, - firstByteDone: 8, - transferStart: 9, - transferDone: 10, - }, - }), - { status: 200, headers: { "content-type": "application/json" } }, - ), +test.todo("run monitor with multiple regions should return array of results", async () => { + mockFetch.mockReturnValue( + Promise.resolve( + new Response( + JSON.stringify({ + jobType: "http", + status: 200, + latency: 100, + region: "ams", + timestamp: 1234567890, + timing: { + dnsStart: 1, + dnsDone: 2, + connectStart: 3, + connectDone: 4, + tlsHandshakeStart: 5, + tlsHandshakeDone: 6, + firstByteStart: 7, + firstByteDone: 8, + transferStart: 9, + transferDone: 10, + }, + }), + { status: 200, headers: { "content-type": "application/json" } }, ), - ); - - const res = await app.request("/v1/monitor/5/run", { - method: "POST", - headers: { - "x-openstatus-key": "1", - "content-type": "application/json", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - expect(Array.isArray(json)).toBe(true); - }, -); + ), + ); + + const res = await app.request("/v1/monitor/5/run", { + method: "POST", + headers: { + "x-openstatus-key": "1", + "content-type": "application/json", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + expect(Array.isArray(json)).toBe(true); +}); diff --git a/apps/server/src/routes/v1/monitors/summary/get.test.ts b/apps/server/src/routes/v1/monitors/summary/get.test.ts index 300271c1..4bf601d2 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.test.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.test.ts @@ -1,12 +1,12 @@ +import { expect, test } from "bun:test"; + import { z } from "@hono/zod-openapi"; -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { SummarySchema } from "./schema"; -test.ignore("return the summary of the monitor", async () => { +test.todo("return the summary of the monitor", async () => { const res = await app.request("/v1/monitor/1/summary", { headers: { "x-openstatus-key": "1", diff --git a/apps/server/src/routes/v1/monitors/summary/get.ts b/apps/server/src/routes/v1/monitors/summary/get.ts index 22320e12..6ae9cba3 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.ts @@ -8,6 +8,11 @@ import { OpenStatusApiError, openApiErrorResponses } from "@/libs/errors"; import type { monitorsApi } from "../index"; import { ParamsSchema, SummarySchema } from "./schema"; +// TODO: is there another better way to mock Redis/Tinybird? +if (process.env.NODE_ENV === "test") { + require("@/libs/test/preload"); +} + const getMonitorStats = createRoute({ method: "get", tags: ["monitor"], diff --git a/apps/server/src/routes/v1/monitors/trigger/post.test.ts b/apps/server/src/routes/v1/monitors/trigger/post.test.ts index 028a0a71..7442da5b 100644 --- a/apps/server/src/routes/v1/monitors/trigger/post.test.ts +++ b/apps/server/src/routes/v1/monitors/trigger/post.test.ts @@ -1,4 +1,5 @@ -import { afterEach, expect, mock, test } from "@openstatus/test-utils"; +import { expect, test } from "bun:test"; +import { afterEach, mock } from "bun:test"; import { app } from "@/index"; @@ -7,6 +8,7 @@ import { TriggerSchema } from "./schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; +mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/notifications/get.test.ts b/apps/server/src/routes/v1/notifications/get.test.ts index 8759de39..3e967ba5 100644 --- a/apps/server/src/routes/v1/notifications/get.test.ts +++ b/apps/server/src/routes/v1/notifications/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/get_all.test.ts b/apps/server/src/routes/v1/notifications/get_all.test.ts index 5f2f580e..0c92e23f 100644 --- a/apps/server/src/routes/v1/notifications/get_all.test.ts +++ b/apps/server/src/routes/v1/notifications/get_all.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/post.test.ts b/apps/server/src/routes/v1/notifications/post.test.ts index b90369af..5208aec5 100644 --- a/apps/server/src/routes/v1/notifications/post.test.ts +++ b/apps/server/src/routes/v1/notifications/post.test.ts @@ -1,7 +1,7 @@ +import { expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pageSubscribers/post.test.ts b/apps/server/src/routes/v1/pageSubscribers/post.test.ts index 80de79fa..7d1bc085 100644 --- a/apps/server/src/routes/v1/pageSubscribers/post.test.ts +++ b/apps/server/src/routes/v1/pageSubscribers/post.test.ts @@ -1,7 +1,7 @@ +import { expect, test } from "bun:test"; + import { and, db, eq, isNull } from "@openstatus/db"; import { pageSubscriber } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get.test.ts b/apps/server/src/routes/v1/pages/get.test.ts index 4335e569..2c197d62 100644 --- a/apps/server/src/routes/v1/pages/get.test.ts +++ b/apps/server/src/routes/v1/pages/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get_all.test.ts b/apps/server/src/routes/v1/pages/get_all.test.ts index 6c948552..155ed2cb 100644 --- a/apps/server/src/routes/v1/pages/get_all.test.ts +++ b/apps/server/src/routes/v1/pages/get_all.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/post.test.ts b/apps/server/src/routes/v1/pages/post.test.ts index e57a260c..ec8999c6 100644 --- a/apps/server/src/routes/v1/pages/post.test.ts +++ b/apps/server/src/routes/v1/pages/post.test.ts @@ -1,7 +1,7 @@ +import { expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/put.test.ts b/apps/server/src/routes/v1/pages/put.test.ts index 0c76046d..3d327ca1 100644 --- a/apps/server/src/routes/v1/pages/put.test.ts +++ b/apps/server/src/routes/v1/pages/put.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts index 510c03b8..2a90e6bf 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts index d07c2f31..575b169e 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, test } from "@std/testing/bdd"; +import { beforeEach, expect, test } from "bun:test"; import { app } from "@/index"; @@ -316,7 +315,5 @@ test("create a status report update calls dispatchStatusReportUpdate", async () const result = StatusReportUpdateSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( - "number", - ); + expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); }); diff --git a/apps/server/src/routes/v1/statusReports/delete.test.ts b/apps/server/src/routes/v1/statusReports/delete.test.ts index b0760725..2532be01 100644 --- a/apps/server/src/routes/v1/statusReports/delete.test.ts +++ b/apps/server/src/routes/v1/statusReports/delete.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get.test.ts b/apps/server/src/routes/v1/statusReports/get.test.ts index 61980dfd..a833c20a 100644 --- a/apps/server/src/routes/v1/statusReports/get.test.ts +++ b/apps/server/src/routes/v1/statusReports/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get_all.test.ts b/apps/server/src/routes/v1/statusReports/get_all.test.ts index 93e057df..22135471 100644 --- a/apps/server/src/routes/v1/statusReports/get_all.test.ts +++ b/apps/server/src/routes/v1/statusReports/get_all.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, @@ -6,8 +8,6 @@ import { statusReportUpdate, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/post.test.ts b/apps/server/src/routes/v1/statusReports/post.test.ts index 94c8d905..77154186 100644 --- a/apps/server/src/routes/v1/statusReports/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/post.test.ts @@ -1,11 +1,11 @@ +import { beforeEach, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { pageComponent, statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -202,9 +202,7 @@ test("create a status report calls dispatchStatusReportUpdate", async () => { const result = StatusReportSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( - "number", - ); + expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); if (result.success) { await db diff --git a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts index 95d14722..743cfd1c 100644 --- a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts +++ b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * Integration tests for subscriber filtering in status report email queries. diff --git a/apps/server/src/routes/v1/statusReports/update/post.test.ts b/apps/server/src/routes/v1/statusReports/update/post.test.ts index cf13fc17..2ec28aca 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/update/post.ts b/apps/server/src/routes/v1/statusReports/update/post.ts index 6f899172..5c19a0aa 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.ts @@ -114,9 +114,8 @@ export function registerStatusReportUpdateRoutes(api: typeof statusReportsApi) { .all(); const validSubscribers = subscribers.filter( - (s): s is typeof s & { token: string; email: string } => + (s): s is typeof s & { token: string } => s.token !== null && - s.email !== null && s.acceptedAt !== null && s.unsubscribedAt === null, ); diff --git a/apps/server/src/routes/v1/whoami/get.test.ts b/apps/server/src/routes/v1/whoami/get.test.ts index a0a7aa1b..91f49c78 100644 --- a/apps/server/src/routes/v1/whoami/get.test.ts +++ b/apps/server/src/routes/v1/whoami/get.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { app } from "@/index"; diff --git a/apps/server/src/serve.ts b/apps/server/src/serve.ts deleted file mode 100644 index b280c1cf..00000000 --- a/apps/server/src/serve.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getLogger } from "@logtape/logtape"; - -import { env } from "./env"; -import { app } from "./index"; - -const port = 3000; - -getLogger("api-server").info("Starting server", { - port, - environment: env.NODE_ENV, -}); - -Deno.serve({ port }, app.fetch); diff --git a/apps/server/src/utils/audit-log.ts b/apps/server/src/utils/audit-log.ts index 6c659698..1c2f3783 100644 --- a/apps/server/src/utils/audit-log.ts +++ b/apps/server/src/utils/audit-log.ts @@ -1,6 +1,6 @@ import { AuditLog, Tinybird } from "@openstatus/tinybird"; -import { env } from "@/env"; +import { env } from "../env"; const tb = new Tinybird({ token: env.TINY_BIRD_API_KEY }); diff --git a/apps/server/test.importmap.json b/apps/server/test.importmap.json deleted file mode 100644 index e2cdceab..00000000 --- a/apps/server/test.importmap.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "imports": { - "@/": "./src/", - "@openstatus/upstash": "./src/libs/test/doubles/upstash.mock.ts", - "@openstatus/tinybird": "./src/libs/test/doubles/tinybird.mock.ts", - "@openstatus/tinybird-real": "../../packages/tinybird/src/index.ts", - "@openstatus/subscriptions": "./src/libs/test/doubles/subscriptions.mock.ts", - "@openstatus/subscriptions-real": "../../packages/subscriptions/src/index.ts", - "@openstatus/analytics": "./src/libs/test/doubles/analytics.mock.ts", - "@openstatus/analytics-real": "../../packages/analytics/src/index.ts", - "./src/routes/slack/page-urls": "./src/libs/test/doubles/page-urls.mock.ts", - "./src/routes/slack/workspace-resolver": "./src/libs/test/doubles/workspace-resolver.mock.ts", - "./src/routes/slack/agent": "./src/libs/test/doubles/slack-agent.mock.ts", - "@slack/web-api": "./src/libs/test/doubles/slack-web-api.mock.ts" - } -} diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index e0efb05d..d2c9d74a 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -8,15 +8,9 @@ "moduleResolution": "bundler", "jsxImportSource": "react", "allowJs": true, - "types": [], + "types": ["bun-types"], "paths": { - "@/*": ["./src/*"], - "@modelcontextprotocol/sdk/server/mcp.js": [ - "./node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts" - ], - "@modelcontextprotocol/sdk/types.js": [ - "./node_modules/@modelcontextprotocol/sdk/dist/esm/types.d.ts" - ] + "@/*": ["./src/*"] } } } diff --git a/apps/status-page/env.ts b/apps/status-page/env.ts index dab63f5f..dbb28b16 100644 --- a/apps/status-page/env.ts +++ b/apps/status-page/env.ts @@ -1 +1,2 @@ -await Deno.copyFile("./.env.example", "./.env"); +const file = Bun.file("./.env.example"); +await Bun.write("./.env", file); diff --git a/apps/status-page/package.json b/apps/status-page/package.json index 58a35fa7..cd336827 100644 --- a/apps/status-page/package.json +++ b/apps/status-page/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "deno run -A env.ts", + "env": "bun env.ts", "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc --noEmit" }, "dependencies": { @@ -77,14 +77,13 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", "@types/dom-speech-recognition": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "bun-types": "catalog:", "shadcn": "catalog:", "tailwindcss": "catalog:", "tw-animate-css": "catalog:", diff --git a/apps/status-page/src/app/(public)/client.tsx b/apps/status-page/src/app/(public)/client.tsx index 9d8568e9..38d02ffd 100644 --- a/apps/status-page/src/app/(public)/client.tsx +++ b/apps/status-page/src/app/(public)/client.tsx @@ -26,7 +26,7 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { Link } from "../../components/common/link"; +import { Link } from "@/components/common/link"; import { Section, SectionDescription, @@ -34,13 +34,14 @@ import { SectionGroupHeader, SectionHeader, SectionTitle, -} from "../../components/content/section"; -import { recomputeStyles } from "../../components/status-page/floating-button"; -import { StatusComponentStatic } from "../../components/status-page/static/status-component-static"; -import { ThemePalettePicker } from "../../components/themes/theme-palette-picker"; -import { ThemeSelect } from "../../components/themes/theme-select"; -import { monitors } from "../../data/monitors"; -import { useTRPC } from "../../lib/trpc/client"; +} from "@/components/content/section"; +import { recomputeStyles } from "@/components/status-page/floating-button"; +import { StatusComponentStatic } from "@/components/status-page/static/status-component-static"; +import { ThemePalettePicker } from "@/components/themes/theme-palette-picker"; +import { ThemeSelect } from "@/components/themes/theme-select"; +import { monitors } from "@/data/monitors"; +import { useTRPC } from "@/lib/trpc/client"; + import { searchParamsParsers } from "./search-params"; const MAIN_COLORS = [ diff --git a/apps/status-page/src/app/(public)/layout.tsx b/apps/status-page/src/app/(public)/layout.tsx index 68c07985..9297bb8a 100644 --- a/apps/status-page/src/app/(public)/layout.tsx +++ b/apps/status-page/src/app/(public)/layout.tsx @@ -8,12 +8,12 @@ import { NextIntlClientProvider } from "next-intl"; import PlausibleProvider from "next-plausible"; import { Suspense } from "react"; -import { Link } from "../../components/common/link"; -import { ThemeProvider } from "../../components/themes/theme-provider"; +import { Link } from "@/components/common/link"; +import { ThemeProvider } from "@/components/themes/theme-provider"; import { SidebarTrigger, ThemeSidebar, -} from "../../components/themes/theme-sidebar"; +} from "@/components/themes/theme-sidebar"; const SIDEBAR_WIDTH = "20rem"; const SIDEBAR_WIDTH_MOBILE = "18rem"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx index 4dce7e67..62448552 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx @@ -1,9 +1,9 @@ import { cn } from "@openstatus/ui/lib/utils"; import { Suspense } from "react"; -import { EmbedShell } from "../../../../../components/layout/embed-shell"; -import { Footer } from "../../../../../components/nav/footer"; -import { getQueryClient, trpc } from "../../../../../lib/trpc/server"; +import { EmbedShell } from "@/components/layout/embed-shell"; +import { Footer } from "@/components/nav/footer"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx index 0030f867..6da92191 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx @@ -11,18 +11,16 @@ import { EmptyStateContainer, EmptyStateDescription, EmptyStateTitle, -} from "../../../../../../../components/content/empty-state"; +} from "@/components/content/empty-state"; import { Section, SectionDescription, SectionHeader, SectionTitle, -} from "../../../../../../../components/content/section"; -import { - FormEmail, - type FormValues, -} from "../../../../../../../components/forms/form-email"; -import { generateServerActionPromise } from "../../../../../../../lib/server-actions"; +} from "@/components/content/section"; +import { FormEmail, type FormValues } from "@/components/forms/form-email"; +import { generateServerActionPromise } from "@/lib/server-actions"; + import { signInWithResendAction } from "../actions"; export function SectionMagicLink() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx index af1bbba9..32b13e97 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx @@ -11,10 +11,10 @@ import { SectionDescription, SectionHeader, SectionTitle, -} from "../../../../../../../components/content/section"; -import { FormPassword } from "../../../../../../../components/forms/form-password"; -import { createProtectedCookieKey } from "../../../../../../../lib/protected"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/components/content/section"; +import { FormPassword } from "@/components/forms/form-password"; +import { createProtectedCookieKey } from "@/lib/protected"; +import { useTRPC } from "@/lib/trpc/client"; export function SectionPassword() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts index bef7b0a3..46056921 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts @@ -5,8 +5,8 @@ import { AuthError } from "next-auth"; import { getExtracted } from "next-intl/server"; import { isRedirectError } from "next/dist/client/components/redirect-error"; -import { signIn } from "../../../../../../lib/auth"; -import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; +import { signIn } from "@/lib/auth"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; export async function signInWithResendAction(formData: FormData) { const t = await getExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx index 0368b670..554c8146 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx @@ -3,7 +3,8 @@ import { useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; + import { SectionMagicLink } from "./_components/section-magic-link"; import { SectionPassword } from "./_components/section-password"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx index cbdecf1d..2e6e8b90 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx @@ -5,7 +5,7 @@ import { ShieldAlert } from "lucide-react"; import { useExtracted } from "next-intl"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; export default function RestrictedPage() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx index 0dc50174..f650dcf9 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx @@ -27,8 +27,8 @@ import { skipToken, useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; import { useMemo } from "react"; -import { Link } from "../../../../../components/common/link"; -import { useStatusPage } from "../../../../../components/status-page/floating-button"; +import { Link } from "@/components/common/link"; +import { useStatusPage } from "@/components/status-page/floating-button"; import { StatusBanner, StatusBannerContainer, @@ -37,23 +37,23 @@ import { StatusBannerTabsContent, StatusBannerTabsList, StatusBannerTabsTrigger, -} from "../../../../../components/status-page/status-banner"; +} from "@/components/status-page/status-banner"; import { StatusBar, StatusBarSkeleton, -} from "../../../../../components/status-page/status-bar"; -import { StatusComponentGroup } from "../../../../../components/status-page/status-component-group"; +} from "@/components/status-page/status-bar"; +import { StatusComponentGroup } from "@/components/status-page/status-component-group"; import { StatusEventAffected, StatusEventAffectedBadge, StatusEventTimelineMaintenance, StatusEventTimelineReportUpdate, -} from "../../../../../components/status-page/status-events"; -import { StatusFeed } from "../../../../../components/status-page/status-feed"; -import { useEmbed } from "../../../../../hooks/use-embed"; -import { usePathnamePrefix } from "../../../../../hooks/use-pathname-prefix"; -import { updatesWithImpactChanges } from "../../../../../lib/report-impacts"; -import { useTRPC } from "../../../../../lib/trpc/client"; +} from "@/components/status-page/status-events"; +import { StatusFeed } from "@/components/status-page/status-feed"; +import { useEmbed } from "@/hooks/use-embed"; +import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; +import { updatesWithImpactChanges } from "@/lib/report-impacts"; +import { useTRPC } from "@/lib/trpc/client"; export function Client() { const prefix = usePathnamePrefix(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx index 6a5704cb..32ea5a79 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx index 7e7134de..0d64d5c6 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx @@ -12,7 +12,7 @@ import Link from "next/link"; import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; -import { StatusBlankEvents } from "../../../../../../../components/status-page/status-blank"; +import { StatusBlankEvents } from "@/components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -25,9 +25,10 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "../../../../../../../components/status-page/status-events"; -import { updatesWithImpactChanges } from "../../../../../../../lib/report-impacts"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-events"; +import { updatesWithImpactChanges } from "@/lib/report-impacts"; +import { useTRPC } from "@/lib/trpc/client"; + import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx index 4caf455c..140e18c5 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx @@ -1,12 +1,8 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; -import { - HydrateClient, - getQueryClient, - trpc, -} from "../../../../../../../../../lib/trpc/server"; +import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx index 58a9ce95..a4eafcd5 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "../../../../../../../../../components/button/button-back"; -import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; -import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; +import { ButtonBack } from "@/components/button/button-back"; +import { ButtonCopyLink } from "@/components/button/button-copy-link"; +import { StatusBlankEvents } from "@/components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -16,8 +16,8 @@ import { StatusEventDate, StatusEventTimelineMaintenance, StatusEventTitle, -} from "../../../../../../../../../components/status-page/status-events"; -import { useTRPC } from "../../../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-events"; +import { useTRPC } from "@/lib/trpc/client"; export default function MaintenancePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx index 0977d1bf..124f989e 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx @@ -1,12 +1,8 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; -import { - HydrateClient, - getQueryClient, - trpc, -} from "../../../../../../../../../lib/trpc/server"; +import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx index 6f300055..1387487c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "../../../../../../../../../components/button/button-back"; -import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; -import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; +import { ButtonBack } from "@/components/button/button-back"; +import { ButtonCopyLink } from "@/components/button/button-copy-link"; +import { StatusBlankEvents } from "@/components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -17,9 +17,9 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "../../../../../../../../../components/status-page/status-events"; -import { updatesWithImpactChanges } from "../../../../../../../../../lib/report-impacts"; -import { useTRPC } from "../../../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-events"; +import { updatesWithImpactChanges } from "@/lib/report-impacts"; +import { useTRPC } from "@/lib/trpc/client"; export default function ReportPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx index 1d913d44..faa8e4e0 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts index f8ea2279..a3fbb463 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts @@ -1,9 +1,9 @@ import { Feed } from "feed"; import { notFound, unauthorized } from "next/navigation"; -import { auth } from "../../../../../../../lib/auth"; -import { getBaseUrl } from "../../../../../../../lib/base-url"; -import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; +import { auth } from "@/lib/auth"; +import { getBaseUrl } from "@/lib/base-url"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; const STATUS_LABELS = { investigating: "Investigating", diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts index 600d02f7..885246ea 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts @@ -1,7 +1,7 @@ import { notFound, unauthorized } from "next/navigation"; -import { auth } from "../../../../../../../lib/auth"; -import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; +import { auth } from "@/lib/auth"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; export const revalidate = 60; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx index 3e5c45e3..582ebac0 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx @@ -4,9 +4,9 @@ import { } from "@openstatus/ui/components/blocks/status-page-shell"; import { Suspense } from "react"; -import { EmbedShell } from "../../../../../components/layout/embed-shell"; -import { Footer } from "../../../../../components/nav/footer"; -import { Header } from "../../../../../components/nav/header"; +import { EmbedShell } from "@/components/layout/embed-shell"; +import { Footer } from "@/components/nav/footer"; +import { Header } from "@/components/nav/header"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts index 32ff7998..060d94fc 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts @@ -2,12 +2,9 @@ import { db, sql } from "@openstatus/db"; import { page } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { - escapeLinkLabel, - type OverviewPage, -} from "../../../../../../content/markdown"; -import { getBaseUrl } from "../../../../../../lib/base-url"; -import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; +import { escapeLinkLabel, type OverviewPage } from "@/content/markdown"; +import { getBaseUrl } from "@/lib/base-url"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx index d7759e1a..f90f987a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx @@ -1,8 +1,4 @@ -import { - HydrateClient, - getQueryClient, - trpc, -} from "../../../../../../../lib/trpc/server"; +import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx index fefbeaaf..9bc7aef7 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx @@ -18,7 +18,7 @@ import { useExtracted, useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { toast } from "sonner"; -import { ButtonBack } from "../../../../../../../components/button/button-back"; +import { ButtonBack } from "@/components/button/button-back"; import { FormCard, FormCardContent, @@ -27,16 +27,16 @@ import { FormCardFooterInfo, FormCardHeader, FormCardTitle, -} from "../../../../../../../components/forms/form-card"; -import { FormManageSubscription } from "../../../../../../../components/forms/form-manage-subscription"; +} from "@/components/forms/form-card"; +import { FormManageSubscription } from "@/components/forms/form-manage-subscription"; import { StatusBlankContainer, StatusBlankContent, StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "../../../../../../../components/status-page/status-blank"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-blank"; +import { useTRPC } from "@/lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx index 1d913d44..faa8e4e0 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx index 36dafd6d..5a45b960 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx @@ -1,7 +1,7 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx index 964d2a63..5efcc37e 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx @@ -15,27 +15,27 @@ import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; import { useMemo } from "react"; -import { ButtonBack } from "../../../../../../../components/button/button-back"; -import { ButtonCopyLink } from "../../../../../../../components/button/button-copy-link"; +import { ButtonBack } from "@/components/button/button-back"; +import { ButtonCopyLink } from "@/components/button/button-copy-link"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "../../../../../../../components/chart/chart-area-percentiles"; +} from "@/components/chart/chart-area-percentiles"; import { ChartBarUptime, ChartBarUptimeSkeleton, -} from "../../../../../../../components/chart/chart-bar-uptime"; +} from "@/components/chart/chart-bar-uptime"; import { ChartLineRegions, ChartLineRegionsSkeleton, -} from "../../../../../../../components/chart/chart-line-regions"; -import { StatusBlankMonitors } from "../../../../../../../components/status-page/status-blank"; +} from "@/components/chart/chart-line-regions"; +import { StatusBlankMonitors } from "@/components/status-page/status-blank"; import { StatusChartContent, StatusChartDescription, StatusChartHeader, StatusChartTitle, -} from "../../../../../../../components/status-page/status-charts"; +} from "@/components/status-page/status-charts"; import { StatusMonitorTabs, StatusMonitorTabsContent, @@ -44,13 +44,14 @@ import { StatusMonitorTabsTriggerLabel, StatusMonitorTabsTriggerValue, StatusMonitorTabsTriggerValueSkeleton, -} from "../../../../../../../components/status-page/status-monitor-tabs"; +} from "@/components/status-page/status-monitor-tabs"; import { formatMillisecondsRange, formatNumber, formatPercentage, -} from "../../../../../../../lib/formatter"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/lib/formatter"; +import { useTRPC } from "@/lib/trpc/client"; + import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx index b793c90a..61d96811 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "../../../../../../lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx index 6bc56d9c..48aef75d 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx @@ -18,9 +18,9 @@ import { useParams } from "next/navigation"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "../../../../../../components/chart/chart-area-percentiles"; -import { StatusBlankMonitors } from "../../../../../../components/status-page/status-blank"; -import { useTRPC } from "../../../../../../lib/trpc/client"; +} from "@/components/chart/chart-area-percentiles"; +import { StatusBlankMonitors } from "@/components/status-page/status-blank"; +import { useTRPC } from "@/lib/trpc/client"; export default function Page() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts index fb02a69a..2edef64c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts @@ -1,6 +1,6 @@ import { createSearchParamsCache } from "nuqs/server"; -import { embedParser } from "../../../../../lib/embed-params"; +import { embedParser } from "@/lib/embed-params"; export const embedSearchParamsCache = createSearchParamsCache({ embed: embedParser, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx index 41485a1e..c77dbc68 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; export default function UnsubscribeLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx index d4f0aded..53bea954 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "../../../../../../../components/status-page/status-blank"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-blank"; +import { useTRPC } from "@/lib/trpc/client"; export default function UnsubscribePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx index 3c061636..faa8e4e0 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +import { useTRPC } from "@/lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx index cf71d1f2..c27dd097 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankContent, StatusBlankLink, StatusBlankTitle, -} from "../../../../../../../components/status-page/status-blank"; -import { useTRPC } from "../../../../../../../lib/trpc/client"; +} from "@/components/status-page/status-blank"; +import { useTRPC } from "@/lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx index 1bab2f44..79d21b24 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx @@ -2,9 +2,9 @@ import { NextIntlClientProvider, hasLocale } from "next-intl"; import { setRequestLocale } from "next-intl/server"; import { notFound } from "next/navigation"; -import { DateFnsProvider } from "../../../../components/date-fns-provider"; -import { StatusBlocksProvider } from "../../../../components/i18n/status-blocks-provider"; -import { routing } from "../../../../i18n/routing"; +import { DateFnsProvider } from "@/components/date-fns-provider"; +import { StatusBlocksProvider } from "@/components/i18n/status-blocks-provider"; +import { routing } from "@/i18n/routing"; export default async function LocaleLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx index 5dbcf293..3b6b86ff 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx @@ -4,16 +4,16 @@ import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { PasswordWrapper } from "../../../components/password-wrapper"; +import { defaultMetadata, ogMetadata, twitterMetadata } from "@/app/metadata"; +import { PasswordWrapper } from "@/components/password-wrapper"; import { FloatingButton, StatusPageProvider, -} from "../../../components/status-page/floating-button"; -import { FloatingTheme } from "../../../components/status-page/floating-theme"; -import { ThemeProvider } from "../../../components/themes/theme-provider"; -import { statusPageAlternates } from "../../../lib/alternates"; -import { getQueryClient, HydrateClient, trpc } from "../../../lib/trpc/server"; -import { defaultMetadata, ogMetadata, twitterMetadata } from "../../metadata"; +} from "@/components/status-page/floating-button"; +import { FloatingTheme } from "@/components/status-page/floating-theme"; +import { ThemeProvider } from "@/components/themes/theme-provider"; +import { statusPageAlternates } from "@/lib/alternates"; +import { getQueryClient, HydrateClient, trpc } from "@/lib/trpc/server"; // Canonical schema — guarantees concrete enum output (never null/undefined). diff --git a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts index 9f1bce8e..c55a45ed 100644 --- a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts +++ b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts @@ -1,3 +1,3 @@ -import { handlers } from "../../../../lib/auth"; +import { handlers } from "@/lib/auth"; export const { GET, POST } = handlers; diff --git a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts index 5f8868af..43a151d4 100644 --- a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts @@ -10,12 +10,12 @@ import { generateReport, matchMarkdownRoute, parseMarkdownPath, -} from "../../../../content/markdown"; -import { getBaseUrl } from "../../../../lib/base-url"; -import { resolveClientIp } from "../../../../lib/http/client-ip"; -import { resolveMarkdownResponse } from "../../../../lib/http/markdown-response"; -import { type GatePage, resolveGate } from "../../../../lib/proxy/resolve-gate"; -import { getQueryClient, trpc } from "../../../../lib/trpc/server"; +} from "@/content/markdown"; +import { getBaseUrl } from "@/lib/base-url"; +import { resolveClientIp } from "@/lib/http/client-ip"; +import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; +import { type GatePage, resolveGate } from "@/lib/proxy/resolve-gate"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; // Match the feed route: getQueryClient/httpBatchLink needs Node, not Edge. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/status/[[...path]]/route.ts b/apps/status-page/src/app/api/status/[[...path]]/route.ts index 6ee8bb27..37255f80 100644 --- a/apps/status-page/src/app/api/status/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/status/[[...path]]/route.ts @@ -8,14 +8,14 @@ import { toStatus, toSummary, toUnresolvedIncidents, -} from "../../../../content/status-json"; -import { getBaseUrl } from "../../../../lib/base-url"; -import { stripHostPort } from "../../../../lib/domain"; -import { resolveClientIp } from "../../../../lib/http/client-ip"; -import { computeETag, isNotModified } from "../../../../lib/http/etag"; -import { resolveGate } from "../../../../lib/proxy/resolve-gate"; -import { resolveRoute } from "../../../../lib/resolve-route"; -import { getQueryClient, trpc } from "../../../../lib/trpc/server"; +} from "@/content/status-json"; +import { getBaseUrl } from "@/lib/base-url"; +import { stripHostPort } from "@/lib/domain"; +import { resolveClientIp } from "@/lib/http/client-ip"; +import { computeETag, isNotModified } from "@/lib/http/etag"; +import { resolveGate } from "@/lib/proxy/resolve-gate"; +import { resolveRoute } from "@/lib/resolve-route"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; // trpc httpBatchLink needs Node, matching the markdown route. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts index c05e3b01..9dd8225b 100644 --- a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,8 +3,8 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "../../../../../lib/auth"; -import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; +import { auth } from "@/lib/auth"; +import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; export const runtime = "edge"; diff --git a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts index f17aa817..944ea4af 100644 --- a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,8 +3,8 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "../../../../../lib/auth"; -import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; +import { auth } from "@/lib/auth"; +import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/status-page/src/app/global-error.tsx b/apps/status-page/src/app/global-error.tsx index 758c1809..6d4ad424 100644 --- a/apps/status-page/src/app/global-error.tsx +++ b/apps/status-page/src/app/global-error.tsx @@ -4,7 +4,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import * as Sentry from "@sentry/nextjs"; import { useEffect } from "react"; -import { Link } from "../components/common/link"; +import { Link } from "@/components/common/link"; export default function GlobalError({ error, diff --git a/apps/status-page/src/app/layout.tsx b/apps/status-page/src/app/layout.tsx index bc1a2aec..600b276d 100644 --- a/apps/status-page/src/app/layout.tsx +++ b/apps/status-page/src/app/layout.tsx @@ -6,8 +6,9 @@ import { Geist, Geist_Mono } from "next/font/google"; import LocalFont from "next/font/local"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { TailwindIndicator } from "../components/tailwind-indicator"; -import { TRPCReactProvider } from "../lib/trpc/client"; +import { TailwindIndicator } from "@/components/tailwind-indicator"; +import { TRPCReactProvider } from "@/lib/trpc/client"; + import { ogMetadata, twitterMetadata } from "./metadata"; import { defaultMetadata } from "./metadata"; diff --git a/apps/status-page/src/app/not-found.tsx b/apps/status-page/src/app/not-found.tsx index a1042a9a..47cd00e2 100644 --- a/apps/status-page/src/app/not-found.tsx +++ b/apps/status-page/src/app/not-found.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/navigation"; import { NuqsAdapter } from "nuqs/adapters/next/app"; import { Suspense } from "react"; -import { Link } from "../components/common/link"; -import { ThemeProvider } from "../components/themes/theme-provider"; +import { Link } from "@/components/common/link"; +import { ThemeProvider } from "@/components/themes/theme-provider"; export default function NotFound() { return ( diff --git a/apps/status-page/src/app/robots.ts b/apps/status-page/src/app/robots.ts index dc3db8ba..4df99d6d 100644 --- a/apps/status-page/src/app/robots.ts +++ b/apps/status-page/src/app/robots.ts @@ -3,9 +3,9 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "../lib/base-url"; -import { stripHostPort } from "../lib/domain"; -import { resolveRoute } from "../lib/resolve-route"; +import { getBaseUrl } from "@/lib/base-url"; +import { stripHostPort } from "@/lib/domain"; +import { resolveRoute } from "@/lib/resolve-route"; // trpc/db lookup needs Node, matching the sitemap and other content routes. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/sitemap.ts b/apps/status-page/src/app/sitemap.ts index 857cfbe7..b6e31bef 100644 --- a/apps/status-page/src/app/sitemap.ts +++ b/apps/status-page/src/app/sitemap.ts @@ -3,10 +3,10 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "../lib/base-url"; -import { stripHostPort } from "../lib/domain"; -import { resolveRoute } from "../lib/resolve-route"; -import { getQueryClient, trpc } from "../lib/trpc/server"; +import { getBaseUrl } from "@/lib/base-url"; +import { stripHostPort } from "@/lib/domain"; +import { resolveRoute } from "@/lib/resolve-route"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; // One sitemap per host: a custom domain must never enumerate other tenants' // pages. trpc httpBatchLink needs Node, matching the other content routes. diff --git a/apps/status-page/src/components/chart/chart-area-percentiles.tsx b/apps/status-page/src/components/chart/chart-area-percentiles.tsx index 0e4ac7b4..78f62b7c 100644 --- a/apps/status-page/src/components/chart/chart-area-percentiles.tsx +++ b/apps/status-page/src/components/chart/chart-area-percentiles.tsx @@ -13,7 +13,8 @@ import { useState } from "react"; import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; import type { AxisDomain } from "recharts/types/util/types"; -import { formatMilliseconds } from "../../lib/formatter"; +import { formatMilliseconds } from "@/lib/formatter"; + import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/chart/chart-bar-uptime.tsx b/apps/status-page/src/components/chart/chart-bar-uptime.tsx index c4565542..81df7d41 100644 --- a/apps/status-page/src/components/chart/chart-bar-uptime.tsx +++ b/apps/status-page/src/components/chart/chart-bar-uptime.tsx @@ -12,7 +12,8 @@ import { cn } from "@openstatus/ui/lib/utils"; import { useState } from "react"; import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"; -import { formatNumber } from "../../lib/formatter"; +import { formatNumber } from "@/lib/formatter"; + import { ChartLegendBadge } from "./chart-legend-badge"; const chartConfig = { diff --git a/apps/status-page/src/components/chart/chart-legend-badge.tsx b/apps/status-page/src/components/chart/chart-legend-badge.tsx index ef0d13f3..6d6d84c8 100644 --- a/apps/status-page/src/components/chart/chart-legend-badge.tsx +++ b/apps/status-page/src/components/chart/chart-legend-badge.tsx @@ -12,7 +12,7 @@ import * as React from "react"; import type * as RechartsPrimitive from "recharts"; import type { Payload } from "recharts/types/component/DefaultLegendContent"; -import { getPayloadConfigFromPayload } from "../../lib/chart"; +import { getPayloadConfigFromPayload } from "@/lib/chart"; export function ChartLegendBadge({ className, diff --git a/apps/status-page/src/components/chart/chart-line-regions.tsx b/apps/status-page/src/components/chart/chart-line-regions.tsx index f216e6b1..71c9de48 100644 --- a/apps/status-page/src/components/chart/chart-line-regions.tsx +++ b/apps/status-page/src/components/chart/chart-line-regions.tsx @@ -20,8 +20,9 @@ import { YAxis, } from "recharts"; -import { regions } from "../../data/regions"; -import { formatMilliseconds } from "../../lib/formatter"; +import { regions } from "@/data/regions"; +import { formatMilliseconds } from "@/lib/formatter"; + import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/common/link.tsx b/apps/status-page/src/components/common/link.tsx index 9a4d75c0..0d2c16cc 100644 --- a/apps/status-page/src/components/common/link.tsx +++ b/apps/status-page/src/components/common/link.tsx @@ -4,7 +4,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { type VariantProps, cva } from "class-variance-authority"; import NextLink from "next/link"; -import { useEmbed } from "../../hooks/use-embed"; +import { useEmbed } from "@/hooks/use-embed"; export const linkVariants = cva( "focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]", diff --git a/apps/status-page/src/components/date-fns-provider.tsx b/apps/status-page/src/components/date-fns-provider.tsx index f6d1f35a..046a5147 100644 --- a/apps/status-page/src/components/date-fns-provider.tsx +++ b/apps/status-page/src/components/date-fns-provider.tsx @@ -3,7 +3,7 @@ import { dateFnsLocales } from "@openstatus/locales"; import { setDefaultOptions } from "date-fns"; -import type { Locale } from "../i18n/config"; +import type { Locale } from "@/i18n/config"; export function DateFnsProvider({ locale, diff --git a/apps/status-page/src/components/date-picker.tsx b/apps/status-page/src/components/date-picker.tsx index 608fc8e8..751cc163 100644 --- a/apps/status-page/src/components/date-picker.tsx +++ b/apps/status-page/src/components/date-picker.tsx @@ -10,8 +10,8 @@ import { useExtracted } from "next-intl"; import { useState } from "react"; import type { DateRange } from "react-day-picker"; -import { formatDateForInput } from "../lib/formatter"; -import { Kbd } from "./common/kbd"; +import { Kbd } from "@/components/common/kbd"; +import { formatDateForInput } from "@/lib/formatter"; type DatePickerProps = { range: DateRange; diff --git a/apps/status-page/src/components/forms/form-manage-subscription.tsx b/apps/status-page/src/components/forms/form-manage-subscription.tsx index ac055e4c..039398d5 100644 --- a/apps/status-page/src/components/forms/form-manage-subscription.tsx +++ b/apps/status-page/src/components/forms/form-manage-subscription.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "../status-page/status-blank"; +} from "@/components/status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/forms/form-subscribe-email.tsx b/apps/status-page/src/components/forms/form-subscribe-email.tsx index 7e233c37..5bc5549e 100644 --- a/apps/status-page/src/components/forms/form-subscribe-email.tsx +++ b/apps/status-page/src/components/forms/form-subscribe-email.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "../status-page/status-blank"; +} from "@/components/status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/i18n/status-blocks-provider.tsx b/apps/status-page/src/components/i18n/status-blocks-provider.tsx index afa5e7b8..b1678e22 100644 --- a/apps/status-page/src/components/i18n/status-blocks-provider.tsx +++ b/apps/status-page/src/components/i18n/status-blocks-provider.tsx @@ -12,7 +12,7 @@ import { formatDateRange, formatDateRangeParts, formatDateTime, -} from "../../lib/formatter"; +} from "@/lib/formatter"; // Status-page timestamps render in UTC; the suffix tells viewers which zone. const withUTC = (value: string) => `${value} (UTC)`; diff --git a/apps/status-page/src/components/layout/embed-shell.tsx b/apps/status-page/src/components/layout/embed-shell.tsx index c7a960ee..2de6e875 100644 --- a/apps/status-page/src/components/layout/embed-shell.tsx +++ b/apps/status-page/src/components/layout/embed-shell.tsx @@ -2,7 +2,7 @@ import { cn } from "@openstatus/ui/lib/utils"; -import { ALL_EMBED_SECTIONS, useEmbed } from "../../hooks/use-embed"; +import { ALL_EMBED_SECTIONS, useEmbed } from "@/hooks/use-embed"; export function EmbedShell({ children, diff --git a/apps/status-page/src/components/locale-switcher.tsx b/apps/status-page/src/components/locale-switcher.tsx index ba82b8a1..234cd097 100644 --- a/apps/status-page/src/components/locale-switcher.tsx +++ b/apps/status-page/src/components/locale-switcher.tsx @@ -13,7 +13,7 @@ import { defaultLocale as globalDefaultLocale, localeTranslations, locales, -} from "../i18n/config"; +} from "@/i18n/config"; export function LocaleSwitcher({ className, diff --git a/apps/status-page/src/components/nav/footer.tsx b/apps/status-page/src/components/nav/footer.tsx index 1a2be081..a98cd31b 100644 --- a/apps/status-page/src/components/nav/footer.tsx +++ b/apps/status-page/src/components/nav/footer.tsx @@ -13,12 +13,12 @@ import { Clock } from "lucide-react"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { useEmbed } from "../../hooks/use-embed"; -import { useTRPC } from "../../lib/trpc/client"; -import { Link } from "../common/link"; -import { TimestampHoverCard } from "../content/timestamp-hover-card"; -import { LocaleSwitcher } from "../locale-switcher"; -import { ThemeSwitcher } from "../themes/theme-switcher"; +import { Link } from "@/components/common/link"; +import { TimestampHoverCard } from "@/components/content/timestamp-hover-card"; +import { LocaleSwitcher } from "@/components/locale-switcher"; +import { ThemeSwitcher } from "@/components/themes/theme-switcher"; +import { useEmbed } from "@/hooks/use-embed"; +import { useTRPC } from "@/lib/trpc/client"; export function Footer({ className, diff --git a/apps/status-page/src/components/nav/header.tsx b/apps/status-page/src/components/nav/header.tsx index 6f5b1cd0..03439456 100644 --- a/apps/status-page/src/components/nav/header.tsx +++ b/apps/status-page/src/components/nav/header.tsx @@ -30,13 +30,13 @@ import { useParams, usePathname } from "next/navigation"; import { useState } from "react"; import { toast } from "sonner"; -import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; -import { useTRPC } from "../../lib/trpc/client"; -import { Link } from "../common/link"; +import { Link } from "@/components/common/link"; import { type StatusUpdateType, StatusUpdates, -} from "../status-page/status-updates"; +} from "@/components/status-page/status-updates"; +import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; +import { useTRPC } from "@/lib/trpc/client"; type Page = RouterOutputs["statusPage"]["get"]; diff --git a/apps/status-page/src/components/password-wrapper.tsx b/apps/status-page/src/components/password-wrapper.tsx index cb364ada..41e2eee3 100644 --- a/apps/status-page/src/components/password-wrapper.tsx +++ b/apps/status-page/src/components/password-wrapper.tsx @@ -4,7 +4,7 @@ import { useParams } from "next/navigation"; import { parseAsString, useQueryState } from "nuqs"; import { useEffect } from "react"; -import { createProtectedCookieKey } from "../lib/protected"; +import { createProtectedCookieKey } from "@/lib/protected"; export function PasswordWrapper({ children }: { children?: React.ReactNode }) { const [password, setPassword] = useQueryState("pw", parseAsString); diff --git a/apps/status-page/src/components/status-page/floating-button.tsx b/apps/status-page/src/components/status-page/floating-button.tsx index c538dd26..c19e8a75 100644 --- a/apps/status-page/src/components/status-page/floating-button.tsx +++ b/apps/status-page/src/components/status-page/floating-button.tsx @@ -35,7 +35,7 @@ import { parseAsString, useQueryState } from "nuqs"; import type React from "react"; import { createContext, useContext, useEffect, useState } from "react"; -import { ThemeSelect } from "../themes/theme-select"; +import { ThemeSelect } from "@/components/themes/theme-select"; export const IS_DEV = process.env.NODE_ENV === "development"; diff --git a/apps/status-page/src/components/status-page/floating-theme.tsx b/apps/status-page/src/components/status-page/floating-theme.tsx index bbf8b90f..4e68f165 100644 --- a/apps/status-page/src/components/status-page/floating-theme.tsx +++ b/apps/status-page/src/components/status-page/floating-theme.tsx @@ -21,7 +21,8 @@ import { Check, ChevronsUpDown, Palette } from "lucide-react"; import { useEffect } from "react"; import { useState } from "react"; -import { ThemeSelect } from "../themes/theme-select"; +import { ThemeSelect } from "@/components/themes/theme-select"; + import { useStatusPage } from "./floating-button"; export const COMMUNITY_THEME = THEME_KEYS; diff --git a/apps/status-page/src/components/status-page/status-bar.tsx b/apps/status-page/src/components/status-page/status-bar.tsx index dcad7aa6..9b43257a 100644 --- a/apps/status-page/src/components/status-page/status-bar.tsx +++ b/apps/status-page/src/components/status-page/status-bar.tsx @@ -5,8 +5,8 @@ import { StatusBarEvent, } from "@openstatus/ui/components/blocks/status-bar"; -import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; -import { Link } from "../common/link"; +import { Link } from "@/components/common/link"; +import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; export { StatusBarSkeleton } from "@openstatus/ui/components/blocks/status-bar"; diff --git a/apps/status-page/src/components/status-page/status-blank.tsx b/apps/status-page/src/components/status-page/status-blank.tsx index 5d5ec21e..e4ea5977 100644 --- a/apps/status-page/src/components/status-page/status-blank.tsx +++ b/apps/status-page/src/components/status-page/status-blank.tsx @@ -3,7 +3,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import { cn } from "@openstatus/ui/lib/utils"; -import { Link } from "../common/link"; +import { Link } from "@/components/common/link"; export { StatusBlankContainer, diff --git a/apps/status-page/src/components/status-page/status-calendar.tsx b/apps/status-page/src/components/status-page/status-calendar.tsx index 19992ddd..9b38d522 100644 --- a/apps/status-page/src/components/status-page/status-calendar.tsx +++ b/apps/status-page/src/components/status-page/status-calendar.tsx @@ -20,9 +20,9 @@ import { import { useLocale } from "next-intl"; import { useCallback, useMemo } from "react"; -import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; -import type { Locale as AppLocale } from "../../i18n/config"; -import { Link } from "../common/link"; +import { Link } from "@/components/common/link"; +import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; +import type { Locale as AppLocale } from "@/i18n/config"; type Page = NonNullable; type ReportInput = Page["statusReports"][number]; diff --git a/apps/status-page/src/components/status-page/status-events.tsx b/apps/status-page/src/components/status-page/status-events.tsx index 4a01ead1..42ff846c 100644 --- a/apps/status-page/src/components/status-page/status-events.tsx +++ b/apps/status-page/src/components/status-page/status-events.tsx @@ -6,7 +6,7 @@ import { StatusEventTimelineReportUpdate as BlockStatusEventTimelineReportUpdate, } from "@openstatus/ui/components/blocks/status-events"; -import { ProcessMessage } from "../content/process-message"; +import { ProcessMessage } from "@/components/content/process-message"; // Re-export pass-through primitives that don't need glue. export { diff --git a/apps/status-page/src/components/status-page/status-feed.tsx b/apps/status-page/src/components/status-page/status-feed.tsx index bbd3f934..5f21632e 100644 --- a/apps/status-page/src/components/status-page/status-feed.tsx +++ b/apps/status-page/src/components/status-page/status-feed.tsx @@ -4,9 +4,10 @@ import { StatusBlankAction } from "@openstatus/ui/components/blocks/status-blank import { StatusFeed as BlockStatusFeed } from "@openstatus/ui/components/blocks/status-feed"; import { useExtracted } from "next-intl"; -import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; -import { Link } from "../common/link"; -import { ProcessMessage } from "../content/process-message"; +import { Link } from "@/components/common/link"; +import { ProcessMessage } from "@/components/content/process-message"; +import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; + import { StatusBlankLink } from "./status-blank"; const renderMarkdownMessage = (message: string) => ( diff --git a/apps/status-page/src/components/status-page/status-updates.tsx b/apps/status-page/src/components/status-page/status-updates.tsx index 7ba925e4..f1a38198 100644 --- a/apps/status-page/src/components/status-page/status-updates.tsx +++ b/apps/status-page/src/components/status-page/status-updates.tsx @@ -26,12 +26,12 @@ import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; import { useState } from "react"; -import { getBaseUrl } from "../../lib/base-url"; -import { createProtectedCookieKey } from "../../lib/protected"; import { FormSubscribeEmail, type FormValues, -} from "../forms/form-subscribe-email"; +} from "@/components/forms/form-subscribe-email"; +import { getBaseUrl } from "@/lib/base-url"; +import { createProtectedCookieKey } from "@/lib/protected"; export type StatusUpdateType = "email" | "rss" | "ssh" | "json" | "slack"; diff --git a/apps/status-page/src/components/themes/theme-provider.tsx b/apps/status-page/src/components/themes/theme-provider.tsx index cfd1d8a8..5c56dc14 100644 --- a/apps/status-page/src/components/themes/theme-provider.tsx +++ b/apps/status-page/src/components/themes/theme-provider.tsx @@ -4,8 +4,8 @@ import { ThemeProvider as NextThemesProvider } from "next-themes"; import { useQueryState } from "nuqs"; import type * as React from "react"; -import { useEmbed } from "../../hooks/use-embed"; -import { embedThemeParser } from "../../lib/embed-params"; +import { useEmbed } from "@/hooks/use-embed"; +import { embedThemeParser } from "@/lib/embed-params"; export function ThemeProvider({ children, diff --git a/apps/status-page/src/components/themes/theme-sidebar.tsx b/apps/status-page/src/components/themes/theme-sidebar.tsx index 3293962e..2b43361a 100644 --- a/apps/status-page/src/components/themes/theme-sidebar.tsx +++ b/apps/status-page/src/components/themes/theme-sidebar.tsx @@ -58,8 +58,8 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { searchParamsParsers } from "../../app/(public)/search-params"; -import { recomputeStyles } from "../status-page/floating-button"; +import { searchParamsParsers } from "@/app/(public)/search-params"; +import { recomputeStyles } from "@/components/status-page/floating-button"; type ThemeBuilderColor = { label: string; diff --git a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx index e945965b..bb18066f 100644 --- a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx +++ b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx @@ -5,8 +5,8 @@ import { Input } from "@openstatus/ui/components/ui/input"; import type { Table } from "@tanstack/react-table"; import { X } from "lucide-react"; -import { DataTableFacetedFilter } from "./data-table-faceted-filter"; -import { DataTableViewOptions } from "./data-table-view-options"; +import { DataTableFacetedFilter } from "@/components/ui/data-table/data-table-faceted-filter"; +import { DataTableViewOptions } from "@/components/ui/data-table/data-table-view-options"; export interface DataTableToolbarProps { table: Table; diff --git a/apps/status-page/src/content/markdown/generators.test.ts b/apps/status-page/src/content/markdown/generators.test.ts index 0bfd7274..05c074d5 100644 --- a/apps/status-page/src/content/markdown/generators.test.ts +++ b/apps/status-page/src/content/markdown/generators.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { escapeCell, diff --git a/apps/status-page/src/content/markdown/match-route.test.ts b/apps/status-page/src/content/markdown/match-route.test.ts index 4a4175fd..7000f38d 100644 --- a/apps/status-page/src/content/markdown/match-route.test.ts +++ b/apps/status-page/src/content/markdown/match-route.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { matchMarkdownRoute, parseMarkdownPath } from "./match-route"; diff --git a/apps/status-page/src/content/status-json.test.ts b/apps/status-page/src/content/status-json.test.ts index d0fe2da1..70e450c2 100644 --- a/apps/status-page/src/content/status-json.test.ts +++ b/apps/status-page/src/content/status-json.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import type { RouterOutputs } from "@openstatus/api"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { matchEndpoint, diff --git a/apps/status-page/src/content/status-vocab.test.ts b/apps/status-page/src/content/status-vocab.test.ts index da2f5bb6..5769f458 100644 --- a/apps/status-page/src/content/status-vocab.test.ts +++ b/apps/status-page/src/content/status-vocab.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { componentStatus, diff --git a/apps/status-page/src/data/metrics.client.ts b/apps/status-page/src/data/metrics.client.ts index 9db66b9e..790dc19c 100644 --- a/apps/status-page/src/data/metrics.client.ts +++ b/apps/status-page/src/data/metrics.client.ts @@ -3,8 +3,9 @@ import type { RouterOutputs } from "@openstatus/api"; import { monitorRegions } from "@openstatus/db/src/schema/constants"; -import type { MetricCard } from "../components/content/metric-card"; -import { formatDateTime, formatMilliseconds } from "../lib/formatter"; +import type { MetricCard } from "@/components/content/metric-card"; +import { formatDateTime, formatMilliseconds } from "@/lib/formatter"; + import type { RegionMetric } from "./region-metrics"; import type { Region } from "./regions"; diff --git a/apps/status-page/src/hooks/use-embed.ts b/apps/status-page/src/hooks/use-embed.ts index 1c202b4f..2369e961 100644 --- a/apps/status-page/src/hooks/use-embed.ts +++ b/apps/status-page/src/hooks/use-embed.ts @@ -2,13 +2,13 @@ import { useQueryState } from "nuqs"; -import { embedParser } from "../lib/embed-params"; +import { embedParser } from "@/lib/embed-params"; export { ALL_EMBED_SECTIONS, type EmbedSection, type EmbedState, -} from "../lib/embed-params"; +} from "@/lib/embed-params"; export function useEmbed() { const [state] = useQueryState("embed", embedParser); diff --git a/apps/status-page/src/hooks/use-pathname-prefix.ts b/apps/status-page/src/hooks/use-pathname-prefix.ts index fb0f6b0a..46a898d3 100644 --- a/apps/status-page/src/hooks/use-pathname-prefix.ts +++ b/apps/status-page/src/hooks/use-pathname-prefix.ts @@ -5,9 +5,9 @@ import { useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { defaultLocale as globalDefaultLocale } from "../i18n/config"; -import { resolvePathnamePrefix } from "../lib/resolve-pathname-prefix"; -import { useTRPC } from "../lib/trpc/client"; +import { defaultLocale as globalDefaultLocale } from "@/i18n/config"; +import { resolvePathnamePrefix } from "@/lib/resolve-pathname-prefix"; +import { useTRPC } from "@/lib/trpc/client"; export function usePathnamePrefix() { const trpc = useTRPC(); diff --git a/apps/status-page/src/lib/alternates-metadata.ts b/apps/status-page/src/lib/alternates-metadata.ts index 192b7e58..ae4d6655 100644 --- a/apps/status-page/src/lib/alternates-metadata.ts +++ b/apps/status-page/src/lib/alternates-metadata.ts @@ -1,7 +1,7 @@ import type { Metadata } from "next"; -import { statusPageAlternates } from "./alternates"; -import { getQueryClient, trpc } from "./trpc/server"; +import { statusPageAlternates } from "@/lib/alternates"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; export async function statusPageAlternatesMetadata({ domain, diff --git a/apps/status-page/src/lib/alternates.test.ts b/apps/status-page/src/lib/alternates.test.ts index 320be3b7..900502ee 100644 --- a/apps/status-page/src/lib/alternates.test.ts +++ b/apps/status-page/src/lib/alternates.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { statusPageAlternates } from "./alternates"; diff --git a/apps/status-page/src/lib/auth/index.ts b/apps/status-page/src/lib/auth/index.ts index 80fad5f0..40d655e6 100644 --- a/apps/status-page/src/lib/auth/index.ts +++ b/apps/status-page/src/lib/auth/index.ts @@ -4,8 +4,9 @@ import type { DefaultSession } from "next-auth"; import NextAuth, { AuthError } from "next-auth"; import { headers } from "next/headers"; -import { getValidCustomDomain } from "../domain"; -import { getQueryClient, trpc } from "../trpc/server"; +import { getValidCustomDomain } from "@/lib/domain"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; + import { adapter } from "./adapter"; import { ResendProvider } from "./providers"; diff --git a/apps/status-page/src/lib/auth/providers.ts b/apps/status-page/src/lib/auth/providers.ts index 45967066..8ff8d930 100644 --- a/apps/status-page/src/lib/auth/providers.ts +++ b/apps/status-page/src/lib/auth/providers.ts @@ -1,8 +1,9 @@ import { EmailClient } from "@openstatus/emails"; import Resend from "next-auth/providers/resend"; +import { getQueryClient, trpc } from "@/lib/trpc/server"; + import { getValidCustomDomain } from "../domain"; -import { getQueryClient, trpc } from "../trpc/server"; export const ResendProvider = Resend({ apiKey: undefined, diff --git a/apps/status-page/src/lib/formatter.test.ts b/apps/status-page/src/lib/formatter.test.ts index bcba4dde..d9e59b03 100644 --- a/apps/status-page/src/lib/formatter.test.ts +++ b/apps/status-page/src/lib/formatter.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { formatDate, diff --git a/apps/status-page/src/lib/http/client-ip.test.ts b/apps/status-page/src/lib/http/client-ip.test.ts index 45b2f7c4..684c07a5 100644 --- a/apps/status-page/src/lib/http/client-ip.test.ts +++ b/apps/status-page/src/lib/http/client-ip.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { resolveClientIp } from "./client-ip"; diff --git a/apps/status-page/src/lib/http/etag.test.ts b/apps/status-page/src/lib/http/etag.test.ts index 66d584e3..66e86bd8 100644 --- a/apps/status-page/src/lib/http/etag.test.ts +++ b/apps/status-page/src/lib/http/etag.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { computeETag, isNotModified } from "./etag"; diff --git a/apps/status-page/src/lib/http/markdown-response.test.ts b/apps/status-page/src/lib/http/markdown-response.test.ts index 00976f94..c519398e 100644 --- a/apps/status-page/src/lib/http/markdown-response.test.ts +++ b/apps/status-page/src/lib/http/markdown-response.test.ts @@ -1,9 +1,8 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; -import { withPoweredBy } from "../../content/markdown"; -import { computeETag } from "./etag"; -import { resolveMarkdownResponse } from "./markdown-response"; +import { withPoweredBy } from "@/content/markdown"; +import { computeETag } from "@/lib/http/etag"; +import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; const PUBLIC_CACHE = "public, max-age=60, s-maxage=60, stale-while-revalidate=300"; diff --git a/apps/status-page/src/lib/http/markdown-response.ts b/apps/status-page/src/lib/http/markdown-response.ts index 41cb8b1f..ae27ed3e 100644 --- a/apps/status-page/src/lib/http/markdown-response.ts +++ b/apps/status-page/src/lib/http/markdown-response.ts @@ -1,6 +1,6 @@ -import { withPoweredBy } from "../../content/markdown"; -import { markdownCacheControl } from "../proxy/markdown-cache-control"; -import { computeETag, isNotModified } from "./etag"; +import { withPoweredBy } from "@/content/markdown"; +import { computeETag, isNotModified } from "@/lib/http/etag"; +import { markdownCacheControl } from "@/lib/proxy/markdown-cache-control"; const MARKDOWN = "text/markdown; charset=utf-8"; diff --git a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts index c04f0fe6..f6821af1 100644 --- a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts +++ b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { applyPageLocaleOverride } from "./apply-page-locale-override"; diff --git a/apps/status-page/src/lib/proxy/build-external-path.test.ts b/apps/status-page/src/lib/proxy/build-external-path.test.ts index df5444bb..e809f6da 100644 --- a/apps/status-page/src/lib/proxy/build-external-path.test.ts +++ b/apps/status-page/src/lib/proxy/build-external-path.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { buildExternalPath } from "./build-external-path"; diff --git a/apps/status-page/src/lib/proxy/compose-page-action.test.ts b/apps/status-page/src/lib/proxy/compose-page-action.test.ts index f3778b40..92c33732 100644 --- a/apps/status-page/src/lib/proxy/compose-page-action.test.ts +++ b/apps/status-page/src/lib/proxy/compose-page-action.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import type { Page } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { type ComposeInput, composePageAction } from "./compose-page-action"; diff --git a/apps/status-page/src/lib/proxy/detect-markdown.test.ts b/apps/status-page/src/lib/proxy/detect-markdown.test.ts index 75d0c613..10dbc1f9 100644 --- a/apps/status-page/src/lib/proxy/detect-markdown.test.ts +++ b/apps/status-page/src/lib/proxy/detect-markdown.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { detectMarkdown } from "./detect-markdown"; diff --git a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts index 2386573a..02c7f46b 100644 --- a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts +++ b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { evaluateMarkdownGate } from "./evaluate-markdown-gate"; diff --git a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts index c963ca31..d96101df 100644 --- a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts +++ b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { isIpAllowed } from "./is-ip-allowed"; diff --git a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts index 0f8cd54f..9b6f9053 100644 --- a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts +++ b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { markdownCacheControl } from "./markdown-cache-control"; diff --git a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts index 67a2c1f4..06eec605 100644 --- a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { resolveCustomDomainRewrite } from "./resolve-custom-domain-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts index 5aff1bca..57f39dd2 100644 --- a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { resolveDefaultRewrite } from "./resolve-default-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts index 0a47a7ef..b6f87852 100644 --- a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { resolveEmailDomainAction } from "./resolve-email-domain-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-gate.ts b/apps/status-page/src/lib/proxy/resolve-gate.ts index fb6ca343..7e56564e 100644 --- a/apps/status-page/src/lib/proxy/resolve-gate.ts +++ b/apps/status-page/src/lib/proxy/resolve-gate.ts @@ -1,9 +1,10 @@ import type { Page } from "@openstatus/db/src/schema"; -import { auth } from "../auth"; -import { createProtectedCookieKey } from "../protected"; -import type { getQueryClient } from "../trpc/server"; -import { trpc } from "../trpc/server"; +import { auth } from "@/lib/auth"; +import { createProtectedCookieKey } from "@/lib/protected"; +import type { getQueryClient } from "@/lib/trpc/server"; +import { trpc } from "@/lib/trpc/server"; + import { evaluateMarkdownGate, type MarkdownGateResult, diff --git a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts index 58987fb9..0405f812 100644 --- a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { resolveIpRestrictionAction } from "./resolve-ip-restriction-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts index ef78a82c..946ea0b6 100644 --- a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { resolveLocaleAction } from "./resolve-locale-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts index 382f8137..5904bdf9 100644 --- a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { ResolvedRoute } from "../resolve-route"; import { resolvePasswordAction } from "./resolve-password-action"; diff --git a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts index 5a3c6989..a50c54eb 100644 --- a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts +++ b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { sanitizeRedirectParam } from "./sanitize-redirect-param"; diff --git a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts index 041ad0a4..b4447230 100644 --- a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts +++ b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { stripPrefixForExternal } from "./strip-prefix-for-external"; diff --git a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts index 85e9d9b7..867c64cc 100644 --- a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts +++ b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { resolvePathnamePrefix } from "./resolve-pathname-prefix"; diff --git a/apps/status-page/src/lib/resolve-route.test.ts b/apps/status-page/src/lib/resolve-route.test.ts index 39046b50..fa1f8e71 100644 --- a/apps/status-page/src/lib/resolve-route.test.ts +++ b/apps/status-page/src/lib/resolve-route.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { resolveRoute } from "./resolve-route"; diff --git a/apps/status-page/src/lib/resolve-route.ts b/apps/status-page/src/lib/resolve-route.ts index 2e280487..88f8760c 100644 --- a/apps/status-page/src/lib/resolve-route.ts +++ b/apps/status-page/src/lib/resolve-route.ts @@ -1,4 +1,5 @@ -import { type Locale, defaultLocale, locales } from "../i18n/config"; +import { type Locale, defaultLocale, locales } from "@/i18n/config"; + import { getValidSubdomain } from "./domain"; export type RouteType = "hostname" | "pathname"; diff --git a/apps/status-page/src/lib/status-blocks-labels.test.ts b/apps/status-page/src/lib/status-blocks-labels.test.ts index f6878d61..e3d5c223 100644 --- a/apps/status-page/src/lib/status-blocks-labels.test.ts +++ b/apps/status-page/src/lib/status-blocks-labels.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import { defaultStatusBlocksLabels as labels } from "@openstatus/ui/components/blocks/status.utils"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; // Status-page timestamps render in UTC, so the user-facing labels carry a // trailing "(UTC)" to tell viewers which zone they are reading (see #2302). diff --git a/apps/status-page/src/lib/trpc/client.tsx b/apps/status-page/src/lib/trpc/client.tsx index 51ecd68c..296c0c42 100644 --- a/apps/status-page/src/lib/trpc/client.tsx +++ b/apps/status-page/src/lib/trpc/client.tsx @@ -6,7 +6,7 @@ import { createTRPCClient, loggerLink } from "@trpc/client"; import { createTRPCContext } from "@trpc/tanstack-react-query"; import { useState } from "react"; -import { endingLink } from "./shared"; +import { endingLink } from "@/lib/trpc/shared"; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext(); diff --git a/apps/status-page/src/proxy.ts b/apps/status-page/src/proxy.ts index b93550f9..ab8511f2 100644 --- a/apps/status-page/src/proxy.ts +++ b/apps/status-page/src/proxy.ts @@ -2,8 +2,9 @@ import { db, sql } from "@openstatus/db"; import { page, selectPageSchema } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { auth } from "./lib/auth"; -import { resolveClientIp } from "./lib/http/client-ip"; +import { auth } from "@/lib/auth"; +import { resolveClientIp } from "@/lib/http/client-ip"; + import { createProtectedCookieKey } from "./lib/protected"; import { applyPageLocaleOverride } from "./lib/proxy/apply-page-locale-override"; import { composePageAction } from "./lib/proxy/compose-page-action"; diff --git a/apps/web/env.ts b/apps/web/env.ts index dab63f5f..dbb28b16 100644 --- a/apps/web/env.ts +++ b/apps/web/env.ts @@ -1 +1,2 @@ -await Deno.copyFile("./.env.example", "./.env"); +const file = Bun.file("./.env.example"); +await Bun.write("./.env", file); diff --git a/apps/web/package.json b/apps/web/package.json index ebf0045d..e7fb85bb 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -3,13 +3,13 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "deno run -A env.ts", + "env": "bun env.ts", "dev": "next dev", "build:registry": "turbo run registry:build --filter=@openstatus/ui", "build": "pnpm build:registry && next build", "start": "next start", "lint": "next lint", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc --noEmit" }, "dependencies": { @@ -98,8 +98,6 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", diff --git a/apps/web/src/app/(ai)/llms-full.txt/route.ts b/apps/web/src/app/(ai)/llms-full.txt/route.ts index f4751861..75e06708 100644 --- a/apps/web/src/app/(ai)/llms-full.txt/route.ts +++ b/apps/web/src/app/(ai)/llms-full.txt/route.ts @@ -1,15 +1,15 @@ -import { convertMdxToMarkdown } from "../../../content/convert"; +import { convertMdxToMarkdown } from "@/content/convert"; import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "../../../content/llms-context"; +} from "@/content/llms-context"; import { type MDXData, getHomePage, getProductPages, getToolingPages, getUnrelatedPages, -} from "../../../content/utils"; +} from "@/content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/llms.txt/route.ts b/apps/web/src/app/(ai)/llms.txt/route.ts index 069076c1..6bc1cf36 100644 --- a/apps/web/src/app/(ai)/llms.txt/route.ts +++ b/apps/web/src/app/(ai)/llms.txt/route.ts @@ -1,7 +1,7 @@ import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "../../../content/llms-context"; +} from "@/content/llms-context"; import { type MDXData, getBlogPosts, @@ -14,7 +14,7 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "../../../content/utils"; +} from "@/content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/mcp/route.ts b/apps/web/src/app/(ai)/mcp/route.ts index 26cd2883..dc30e23c 100644 --- a/apps/web/src/app/(ai)/mcp/route.ts +++ b/apps/web/src/app/(ai)/mcp/route.ts @@ -1,6 +1,6 @@ // Discovery endpoint for /mcp. JSON clients receive the server card inline // (no domain coupling); browsers get redirected to the human-readable page. -import { GET as serverCardGET } from "../../.well-known/mcp/server-card.json/route"; +import { GET as serverCardGET } from "@/app/.well-known/mcp/server-card.json/route"; export function GET(request: Request) { const accept = request.headers.get("accept") ?? ""; diff --git a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx index e80ed59a..fc9dc97a 100644 --- a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx +++ b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx @@ -5,34 +5,34 @@ import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "../../../(landing)/content-box"; -import { ContentPagination } from "../../../(landing)/content-pagination"; +} from "@/app/(landing)/content-box"; +import { ContentPagination } from "@/app/(landing)/content-pagination"; import { getDocs, getDocsPage, getDocsPagination, gitLastModified, validateDocsNav, -} from "../../../../content/docs"; -import { DocsFeedback } from "../../../../content/docs-feedback"; -import { DocsSubNav } from "../../../../content/docs-sub-nav"; -import { TableOfContents } from "../../../../content/docs-toc"; +} from "@/content/docs"; +import { DocsFeedback } from "@/content/docs-feedback"; +import { DocsSubNav } from "@/content/docs-sub-nav"; +import { TableOfContents } from "@/content/docs-toc"; import { type DocsNavNode, docsNavTree, findDocsNode, findDocsTrail, getDocsContainerSlugs, -} from "../../../../content/docs.config"; -import { CustomMDX } from "../../../../content/mdx"; -import { Grid } from "../../../../content/mdx-components/grid"; -import { extractHeadings } from "../../../../content/toc"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; +} from "@/content/docs.config"; +import { CustomMDX } from "@/content/mdx"; +import { Grid } from "@/content/mdx-components/grid"; +import { extractHeadings } from "@/content/toc"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, getPageMetadata, getSocialMetadata, -} from "../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -41,7 +41,7 @@ import { getJsonLDItemList, getJsonLDOrganization, getJsonLDTechArticle, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(docs)/layout.tsx b/apps/web/src/app/(docs)/layout.tsx index 1664fe19..153bdd8b 100644 --- a/apps/web/src/app/(docs)/layout.tsx +++ b/apps/web/src/app/(docs)/layout.tsx @@ -1,6 +1,6 @@ -import { DocsFooter } from "../../content/docs-footer"; -import { DocsHeader } from "../../content/docs-header"; -import { DocsMobileNav, DocsSidebar } from "../../content/docs-sidebar"; +import { DocsFooter } from "@/content/docs-footer"; +import { DocsHeader } from "@/content/docs-header"; +import { DocsMobileNav, DocsSidebar } from "@/content/docs-sidebar"; export default function DocsLayout({ children, diff --git a/apps/web/src/app/(landing)/[slug]/page.tsx b/apps/web/src/app/(landing)/[slug]/page.tsx index 41c0ecb1..1713d307 100644 --- a/apps/web/src/app/(landing)/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/[slug]/page.tsx @@ -1,10 +1,10 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../content/mdx"; -import { getMainPages } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; -import { getPageMetadata } from "../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getMainPages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -13,7 +13,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/blog/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/[slug]/page.tsx index a230288f..2d400a23 100644 --- a/apps/web/src/app/(landing)/blog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/[slug]/page.tsx @@ -2,13 +2,10 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getBlogPosts } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getBlogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -17,7 +14,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx index 64e66988..553c7cf1 100644 --- a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { getBlogPosts } from "../../../../../content/utils"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { ContentCategory } from "@/app/(landing)/content-category"; +import { ContentList } from "@/app/(landing)/content-list"; +import { getBlogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../../../lib/metadata/structured-data"; -import { ContentCategory } from "../../../content-category"; -import { ContentList } from "../../../content-list"; +} from "@/lib/metadata/structured-data"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/blog/category/page.tsx b/apps/web/src/app/(landing)/blog/category/page.tsx index 6d917999..266e2986 100644 --- a/apps/web/src/app/(landing)/blog/category/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/page.tsx @@ -1,12 +1,13 @@ import type { Metadata } from "next"; -import { components } from "../../../../content/mdx"; -import { getBlogPosts } from "../../../../content/utils"; +import { components } from "@/content/mdx"; +import { getBlogPosts } from "@/content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; + import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Blog Categories"; diff --git a/apps/web/src/app/(landing)/blog/feed.xml/route.ts b/apps/web/src/app/(landing)/blog/feed.xml/route.ts index 82a77083..e8122942 100644 --- a/apps/web/src/app/(landing)/blog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/blog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getBlogPosts } from "../../../../content/utils"; +import { getBlogPosts } from "@/content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/blog/page.tsx b/apps/web/src/app/(landing)/blog/page.tsx index 0da5f407..18bd6d31 100644 --- a/apps/web/src/app/(landing)/blog/page.tsx +++ b/apps/web/src/app/(landing)/blog/page.tsx @@ -1,20 +1,21 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getBlogPosts } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getBlogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "../../../lib/metadata/shared-metadata"; -import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; +import { twitterMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx index a0071eb2..01a9ef56 100644 --- a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx @@ -2,13 +2,10 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getChangelogPosts } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getChangelogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -17,7 +14,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx index 269532c2..d970a69d 100644 --- a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { getChangelogPosts } from "../../../../../content/utils"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { ContentCategory } from "@/app/(landing)/content-category"; +import { ContentList } from "@/app/(landing)/content-list"; +import { getChangelogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../../../lib/metadata/structured-data"; -import { ContentCategory } from "../../../content-category"; -import { ContentList } from "../../../content-list"; +} from "@/lib/metadata/structured-data"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/changelog/category/page.tsx b/apps/web/src/app/(landing)/changelog/category/page.tsx index 65b4a27c..d9472c13 100644 --- a/apps/web/src/app/(landing)/changelog/category/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/page.tsx @@ -1,12 +1,13 @@ import type { Metadata } from "next"; -import { components } from "../../../../content/mdx"; -import { getChangelogPosts } from "../../../../content/utils"; +import { components } from "@/content/mdx"; +import { getChangelogPosts } from "@/content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; + import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Changelog Categories"; diff --git a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts index 78422c9c..d48b54bc 100644 --- a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getChangelogPosts } from "../../../../content/utils"; +import { getChangelogPosts } from "@/content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/changelog/page.tsx b/apps/web/src/app/(landing)/changelog/page.tsx index c7d07e67..ad57acd8 100644 --- a/apps/web/src/app/(landing)/changelog/page.tsx +++ b/apps/web/src/app/(landing)/changelog/page.tsx @@ -1,20 +1,21 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getChangelogPosts } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getChangelogPosts } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "../../../lib/metadata/shared-metadata"; -import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; +import { twitterMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/compare/[slug]/page.tsx b/apps/web/src/app/(landing)/compare/[slug]/page.tsx index 95bcf03f..f3002f40 100644 --- a/apps/web/src/app/(landing)/compare/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/compare/[slug]/page.tsx @@ -1,13 +1,11 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getComparePages } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { ContentPagination } from "@/app/(landing)/content-pagination"; +import { CustomMDX } from "@/content/mdx"; +import { getComparePages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -16,8 +14,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; -import { ContentPagination } from "../../content-pagination"; +} from "@/lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/compare/page.tsx b/apps/web/src/app/(landing)/compare/page.tsx index f4f01e1e..7bc2f2b1 100644 --- a/apps/web/src/app/(landing)/compare/page.tsx +++ b/apps/web/src/app/(landing)/compare/page.tsx @@ -1,20 +1,21 @@ import type { Metadata } from "next"; -import { components } from "../../../content/mdx"; -import { getComparePages } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { components } from "@/content/mdx"; +import { getComparePages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/content-box-image.tsx b/apps/web/src/app/(landing)/content-box-image.tsx index 2e32b42e..4d1ff74a 100644 --- a/apps/web/src/app/(landing)/content-box-image.tsx +++ b/apps/web/src/app/(landing)/content-box-image.tsx @@ -1,7 +1,7 @@ import type React from "react"; -import { CustomImage } from "../../content/mdx-components/custom-image"; -import { cn } from "../../lib/utils"; +import { CustomImage } from "@/content/mdx-components/custom-image"; +import { cn } from "@/lib/utils"; export function ContentBoxImage({ className, diff --git a/apps/web/src/app/(landing)/content-box.tsx b/apps/web/src/app/(landing)/content-box.tsx index a66a914a..6cfbdea2 100644 --- a/apps/web/src/app/(landing)/content-box.tsx +++ b/apps/web/src/app/(landing)/content-box.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "../../lib/utils"; +import { cn } from "@/lib/utils"; export function ContentBoxLink({ href, diff --git a/apps/web/src/app/(landing)/content-category.tsx b/apps/web/src/app/(landing)/content-category.tsx index 91ca45da..826a7c5d 100644 --- a/apps/web/src/app/(landing)/content-category.tsx +++ b/apps/web/src/app/(landing)/content-category.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import { Fragment } from "react"; -import type { MDXData } from "../../content/utils"; +import type { MDXData } from "@/content/utils"; export function ContentCategory({ data, diff --git a/apps/web/src/app/(landing)/content-list.tsx b/apps/web/src/app/(landing)/content-list.tsx index 1f6c40ab..1a3e08fb 100644 --- a/apps/web/src/app/(landing)/content-list.tsx +++ b/apps/web/src/app/(landing)/content-list.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { type MDXData, formatDate } from "../../content/utils"; -import { cn } from "../../lib/utils"; +import { type MDXData, formatDate } from "@/content/utils"; +import { cn } from "@/lib/utils"; export function ContentList({ data, diff --git a/apps/web/src/app/(landing)/content-metadata.tsx b/apps/web/src/app/(landing)/content-metadata.tsx index aa9ebb23..02fd8bea 100644 --- a/apps/web/src/app/(landing)/content-metadata.tsx +++ b/apps/web/src/app/(landing)/content-metadata.tsx @@ -1,5 +1,5 @@ -import { type MDXData, formatDate } from "../../content/utils"; -import { getAuthor } from "../../data/author"; +import { type MDXData, formatDate } from "@/content/utils"; +import { getAuthor } from "@/data/author"; export function ContentMetadata({ data }: { data: MDXData }) { return ( diff --git a/apps/web/src/app/(landing)/content-pagination.tsx b/apps/web/src/app/(landing)/content-pagination.tsx index 91f98721..710feed5 100644 --- a/apps/web/src/app/(landing)/content-pagination.tsx +++ b/apps/web/src/app/(landing)/content-pagination.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; -import type { MDXData } from "../../content/utils"; +import type { MDXData } from "@/content/utils"; export function ContentPagination({ prev, diff --git a/apps/web/src/app/(landing)/customers/[slug]/page.tsx b/apps/web/src/app/(landing)/customers/[slug]/page.tsx index b4d0b714..ee02d501 100644 --- a/apps/web/src/app/(landing)/customers/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/customers/[slug]/page.tsx @@ -1,21 +1,18 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { CustomImage } from "../../../../content/mdx-components/custom-image"; -import { getCustomerPages } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { CustomImage } from "@/content/mdx-components/custom-image"; +import { getCustomerPages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/customers/page.tsx b/apps/web/src/app/(landing)/customers/page.tsx index 707baddb..b810b8aa 100644 --- a/apps/web/src/app/(landing)/customers/page.tsx +++ b/apps/web/src/app/(landing)/customers/page.tsx @@ -1,20 +1,21 @@ import type { Metadata } from "next"; -import { components } from "../../../content/mdx"; -import { getCustomerPages } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { components } from "@/content/mdx"; +import { getCustomerPages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/guides/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/[slug]/page.tsx index 2db3fd5b..22583577 100644 --- a/apps/web/src/app/(landing)/guides/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/[slug]/page.tsx @@ -2,13 +2,10 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getGuides } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getGuides } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -17,7 +14,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx index 1041fb8d..10f79591 100644 --- a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { getGuides } from "../../../../../content/utils"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { ContentCategory } from "@/app/(landing)/content-category"; +import { ContentList } from "@/app/(landing)/content-list"; +import { getGuides } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../../../lib/metadata/structured-data"; -import { ContentCategory } from "../../../content-category"; -import { ContentList } from "../../../content-list"; +} from "@/lib/metadata/structured-data"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/guides/category/page.tsx b/apps/web/src/app/(landing)/guides/category/page.tsx index cd19b69e..9660aa4c 100644 --- a/apps/web/src/app/(landing)/guides/category/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/page.tsx @@ -1,12 +1,13 @@ import type { Metadata } from "next"; -import { components } from "../../../../content/mdx"; -import { getGuides } from "../../../../content/utils"; +import { components } from "@/content/mdx"; +import { getGuides } from "@/content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; + import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Guides Categories"; diff --git a/apps/web/src/app/(landing)/guides/page.tsx b/apps/web/src/app/(landing)/guides/page.tsx index b4770986..a66d5158 100644 --- a/apps/web/src/app/(landing)/guides/page.tsx +++ b/apps/web/src/app/(landing)/guides/page.tsx @@ -1,19 +1,20 @@ import type { Metadata } from "next"; -import { getGuides } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getGuides } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "../../../lib/metadata/shared-metadata"; -import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; +import { twitterMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/layout.tsx b/apps/web/src/app/(landing)/layout.tsx index e8b074eb..2933a24a 100644 --- a/apps/web/src/app/(landing)/layout.tsx +++ b/apps/web/src/app/(landing)/layout.tsx @@ -1,6 +1,6 @@ -import { Footer } from "../../content/footer"; -import { Header } from "../../content/header"; -import { SubNav } from "../../content/sub-nav"; +import { Footer } from "@/content/footer"; +import { Header } from "@/content/header"; +import { SubNav } from "@/content/sub-nav"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/web/src/app/(landing)/oss-friends/page.tsx b/apps/web/src/app/(landing)/oss-friends/page.tsx index 9e58bc7a..ed292882 100644 --- a/apps/web/src/app/(landing)/oss-friends/page.tsx +++ b/apps/web/src/app/(landing)/oss-friends/page.tsx @@ -1,12 +1,13 @@ import type { Metadata } from "next"; import { z } from "zod"; -import { components } from "../../../content/mdx"; +import { components } from "@/content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; + import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/page.tsx b/apps/web/src/app/(landing)/page.tsx index 6576990f..b9cab94f 100644 --- a/apps/web/src/app/(landing)/page.tsx +++ b/apps/web/src/app/(landing)/page.tsx @@ -1,9 +1,9 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../content/mdx"; -import { getHomePage } from "../../content/utils"; -import { JsonLd } from "../../lib/metadata/json-ld"; -import { defaultMetadata } from "../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getHomePage } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { defaultMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -12,7 +12,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; export const metadata: Metadata = defaultMetadata; diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx index 6b979138..1f23b684 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx @@ -19,14 +19,15 @@ import { } from "@openstatus/ui/components/ui/tabs"; import { useState } from "react"; -import { IconCloudProvider } from "../../../../../components/icon-cloud-provider"; +import { IconCloudProvider } from "@/components/icon-cloud-provider"; import { type CachedRegionChecker, getTimingPhases, regionFormatter, timestampFormatter, -} from "../../../../../lib/checker/utils"; -import { cn } from "../../../../../lib/utils"; +} from "@/lib/checker/utils"; +import { cn } from "@/lib/utils"; + import { handleExportCSV } from "../utils"; const STATUS_CODES = { diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx index f07f70f0..8cc463d0 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx @@ -1,24 +1,22 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "../../../../../content/mdx"; -import { getToolsPage } from "../../../../../content/utils"; -import { mockCheckAllRegions } from "../../../../../lib/checker/mock"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { mockCheckAllRegions } from "@/lib/checker/mock"; import { getCheckerDataById, latencyFormatter, regionFormatter, -} from "../../../../../lib/checker/utils"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../../lib/metadata/shared-metadata"; +} from "@/lib/checker/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "../../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { Table } from "./client"; function formatDate(date: Date) { diff --git a/apps/web/src/app/(landing)/play/checker/api/route.ts b/apps/web/src/app/(landing)/play/checker/api/route.ts index 14230857..a9ce8c99 100644 --- a/apps/web/src/app/(landing)/play/checker/api/route.ts +++ b/apps/web/src/app/(landing)/play/checker/api/route.ts @@ -3,17 +3,17 @@ import { AVAILABLE_REGIONS } from "@openstatus/regions"; import { after } from "next/server"; import { z } from "zod"; -import { mockCheckRegion } from "../../../../../lib/checker/mock"; +import { mockCheckRegion } from "@/lib/checker/mock"; import { type Method, checkRegion, getTimingPhases, storeBaseCheckerData, storeCheckerData, -} from "../../../../../lib/checker/utils"; -import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; -import { iteratorToStream, yieldMany } from "../../../../../lib/stream"; -import { wait } from "../../../../../lib/utils"; +} from "@/lib/checker/utils"; +import { getClientIP, ratelimit } from "@/lib/ratelimit"; +import { iteratorToStream, yieldMany } from "@/lib/stream"; +import { wait } from "@/lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/(landing)/play/checker/client.tsx b/apps/web/src/app/(landing)/play/checker/client.tsx index 1db7ed7c..471ad579 100644 --- a/apps/web/src/app/(landing)/play/checker/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/client.tsx @@ -25,16 +25,17 @@ import { useTransition, } from "react"; -import { IconCloudProvider } from "../../../../components/icon-cloud-provider"; +import { IconCloudProvider } from "@/components/icon-cloud-provider"; import { type Timing, is32CharHex, latencyFormatter, regionCheckerSchema, regionFormatter, -} from "../../../../lib/checker/utils"; -import { toast } from "../../../../lib/toast"; -import { cn, notEmpty } from "../../../../lib/utils"; +} from "@/lib/checker/utils"; +import { toast } from "@/lib/toast"; +import { cn, notEmpty } from "@/lib/utils"; + import { searchParamsParsers } from "./search-params"; import { handleExportCSV } from "./utils"; diff --git a/apps/web/src/app/(landing)/play/checker/page.tsx b/apps/web/src/app/(landing)/play/checker/page.tsx index f8a6dbd1..7e53f3ee 100644 --- a/apps/web/src/app/(landing)/play/checker/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/page.tsx @@ -1,20 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolsPage } from "../../../../content/utils"; -import { mockCheckAllRegions } from "../../../../lib/checker/mock"; -import { getCheckerDataById } from "../../../../lib/checker/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { mockCheckAllRegions } from "@/lib/checker/mock"; +import { getCheckerDataById } from "@/lib/checker/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { CheckerProvider, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/checker/utils.ts b/apps/web/src/app/(landing)/play/checker/utils.ts index 410cf7a2..057b6134 100644 --- a/apps/web/src/app/(landing)/play/checker/utils.ts +++ b/apps/web/src/app/(landing)/play/checker/utils.ts @@ -1,7 +1,7 @@ import { type Region, regionDict } from "@openstatus/regions"; -import { type Timing, getTimingPhases } from "../../../../lib/checker/utils"; -import { toast } from "../../../../lib/toast"; +import { type Timing, getTimingPhases } from "@/lib/checker/utils"; +import { toast } from "@/lib/toast"; export type CheckerRow = { region: string; diff --git a/apps/web/src/app/(landing)/play/curl/page.tsx b/apps/web/src/app/(landing)/play/curl/page.tsx index c7cc3fff..ed05a6f8 100644 --- a/apps/web/src/app/(landing)/play/curl/page.tsx +++ b/apps/web/src/app/(landing)/play/curl/page.tsx @@ -1,18 +1,16 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolsPage } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { Form } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx index 1fba7fa6..5df37359 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx @@ -1,6 +1,7 @@ "use client"; -import type { HealthCheckReport } from "../../../../../lib/mcp/health-check"; +import type { HealthCheckReport } from "@/lib/mcp/health-check"; + import { ResultTableStatic, ToolsTableView, VerdictBarStatic } from "../client"; export function Table({ data }: { data: HealthCheckReport }) { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx index 33daf4af..d1d9678e 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx @@ -1,19 +1,17 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "../../../../../content/mdx"; -import { getToolsPage } from "../../../../../content/utils"; -import { getHealthReportById } from "../../../../../lib/mcp/health-check"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { getHealthReportById } from "@/lib/mcp/health-check"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "../../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { VERDICT_LABEL, formatTimestamp } from "../utils"; import { Table } from "./client"; diff --git a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts index 71ced0d5..fb81a631 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts @@ -9,8 +9,8 @@ import { runMcpHealthCheck, storeHealthReport, toPersistedReport, -} from "../../../../../lib/mcp/health-check"; -import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; +} from "@/lib/mcp/health-check"; +import { getClientIP, ratelimit } from "@/lib/ratelimit"; export const runtime = "edge"; // Worst-case 16s of step time + metadata fetch + analytics; give some slack. diff --git a/apps/web/src/app/(landing)/play/mcp-health/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/client.tsx index b42d585f..70efd99d 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/client.tsx @@ -32,9 +32,10 @@ import type { HealthCheckReport, StepResult, ToolInfo, -} from "../../../../lib/mcp/health-check"; -import { toast } from "../../../../lib/toast"; -import { cn } from "../../../../lib/utils"; +} from "@/lib/mcp/health-check"; +import { toast } from "@/lib/toast"; +import { cn } from "@/lib/utils"; + import { searchParamsParsers } from "./search-params"; import { STEP_REQUEST_BODIES, diff --git a/apps/web/src/app/(landing)/play/mcp-health/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/page.tsx index 69da93cb..c6fff2e6 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/page.tsx @@ -1,20 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolsPage } from "../../../../content/utils"; -import { getHealthReportById } from "../../../../lib/mcp/health-check"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { getHealthReportById } from "@/lib/mcp/health-check"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDHowTo, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { AuthChallengeCallout, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts index ba080c63..228c78b5 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { formatResponseBody, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.ts index 73c088b6..2080daa3 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.ts @@ -1,12 +1,6 @@ -import type { - HealthCheckReport, - StepResult, -} from "../../../../lib/mcp/health-check"; +import type { HealthCheckReport, StepResult } from "@/lib/mcp/health-check"; -export { - STEP_REQUEST_BODIES, - type StepKey, -} from "../../../../lib/mcp/protocol"; +export { STEP_REQUEST_BODIES, type StepKey } from "@/lib/mcp/protocol"; export const VERDICT_LABEL: Record = { healthy: "GOOD", diff --git a/apps/web/src/app/(landing)/play/page.tsx b/apps/web/src/app/(landing)/play/page.tsx index a7d54da9..7f27849d 100644 --- a/apps/web/src/app/(landing)/play/page.tsx +++ b/apps/web/src/app/(landing)/play/page.tsx @@ -1,11 +1,12 @@ import type { Metadata } from "next"; -import { components } from "../../../content/mdx"; +import { components } from "@/content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; + import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx index bf8e8b85..0a794ce8 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx @@ -7,7 +7,7 @@ import { Label } from "@openstatus/ui/components/ui/label"; import { Slider } from "@openstatus/ui/components/ui/slider"; import { useState } from "react"; -import { Details } from "../../../../content/mdx-components/details"; +import { Details } from "@/content/mdx-components/details"; type SeverityLevel = "SEV0" | "SEV1" | "SEV2" | "SEV3"; diff --git a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx index b4af063a..e3d57b2d 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx @@ -1,18 +1,16 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolsPage } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { SeverityMatrixBuilder } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx index 2214ce25..aa88a7c7 100644 --- a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx +++ b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx @@ -1,18 +1,16 @@ import type { Metadata } from "next"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolsPage } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { Calculation } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx index 9e47b6bd..6e6d88db 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx @@ -2,21 +2,22 @@ import { REPORT_WINDOW_MINUTES } from "@openstatus/api/src/router/effective-status"; -import { Grid } from "../../../../../content/mdx-components/grid"; -import { JsonLd } from "../../../../../lib/metadata/json-ld"; -import { BASE_URL } from "../../../../../lib/metadata/shared-metadata"; +import { + ContentBoxDescription, + ContentBoxLink, + ContentBoxTitle, +} from "@/app/(landing)/content-box"; +import { Grid } from "@/content/mdx-components/grid"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "../../../../../lib/metadata/structured-data"; -import { api } from "../../../../../trpc/rq-client"; -import { - ContentBoxDescription, - ContentBoxLink, - ContentBoxTitle, -} from "../../../content-box"; +} from "@/lib/metadata/structured-data"; +import { api } from "@/trpc/rq-client"; + import { ExternalServicePill } from "../../external-service-pill"; import { formatRelative } from "../../utils"; import { HistoryBars } from "../history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx index c5f7e78d..6906aeb7 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx @@ -2,17 +2,18 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "../../../../../content/mdx-components/button-link"; -import { CustomLink } from "../../../../../content/mdx-components/custom-link"; -import { cachedGetExternalComponentBySlug } from "../../../../../lib/external-service-cache"; +import { ButtonLink } from "@/content/mdx-components/button-link"; +import { CustomLink } from "@/content/mdx-components/custom-link"; +import { cachedGetExternalComponentBySlug } from "@/lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../../lib/metadata/shared-metadata"; -import { HydrateClient, api } from "../../../../../trpc/rq-server"; +} from "@/lib/metadata/shared-metadata"; +import { HydrateClient, api } from "@/trpc/rq-server"; + import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/incidents.tsx b/apps/web/src/app/(landing)/status/[id]/incidents.tsx index 2a4c6d60..4ee5276c 100644 --- a/apps/web/src/app/(landing)/status/[id]/incidents.tsx +++ b/apps/web/src/app/(landing)/status/[id]/incidents.tsx @@ -1,12 +1,12 @@ "use client"; -import { Grid } from "../../../../content/mdx-components/grid"; -import { api } from "../../../../trpc/rq-client"; import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "../../content-box"; +} from "@/app/(landing)/content-box"; +import { Grid } from "@/content/mdx-components/grid"; +import { api } from "@/trpc/rq-client"; function impactClass(impact: string | undefined): string { switch (impact) { diff --git a/apps/web/src/app/(landing)/status/[id]/page.tsx b/apps/web/src/app/(landing)/status/[id]/page.tsx index 20594bf5..ea21922e 100644 --- a/apps/web/src/app/(landing)/status/[id]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/page.tsx @@ -3,18 +3,19 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "../../../../content/mdx-components/button-link"; -import { CustomLink } from "../../../../content/mdx-components/custom-link"; -import { getServiceEscalation } from "../../../../lib/external-report-escalation"; -import { cachedGetExternalServiceBySlug } from "../../../../lib/external-service-cache"; +import { ButtonLink } from "@/content/mdx-components/button-link"; +import { CustomLink } from "@/content/mdx-components/custom-link"; +import { getServiceEscalation } from "@/lib/external-report-escalation"; +import { cachedGetExternalServiceBySlug } from "@/lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../../lib/metadata/shared-metadata"; -import { HydrateClient, api } from "../../../../trpc/rq-server"; +} from "@/lib/metadata/shared-metadata"; +import { HydrateClient, api } from "@/trpc/rq-server"; + import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx index 705129f0..d3ed1de2 100644 --- a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx +++ b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx @@ -12,7 +12,8 @@ import { } from "@openstatus/ui/components/ui/select"; import { useState } from "react"; -import { api } from "../../../../trpc/rq-client"; +import { api } from "@/trpc/rq-client"; + import { buildSections } from "../external-service-components"; const WHOLE_SERVICE = "all"; diff --git a/apps/web/src/app/(landing)/status/[id]/service-components.tsx b/apps/web/src/app/(landing)/status/[id]/service-components.tsx index ff0fe13d..bbaf6a57 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-components.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-components.tsx @@ -1,6 +1,7 @@ "use client"; -import { api } from "../../../../trpc/rq-client"; +import { api } from "@/trpc/rq-client"; + import { ExternalServiceComponents } from "../external-service-components"; export function ServiceComponents({ diff --git a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx index 4ca6c477..7a92deb7 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx @@ -2,16 +2,17 @@ import { Suspense } from "react"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { BASE_URL } from "../../../../lib/metadata/shared-metadata"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDService, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; -import { api } from "../../../../trpc/rq-client"; +} from "@/lib/metadata/structured-data"; +import { api } from "@/trpc/rq-client"; + import { ExternalServicePill } from "../external-service-pill"; import { formatRelative, getStatusAnswer, isStale } from "../utils"; import { HistoryBars } from "./history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx index b22c8150..96b5ea5d 100644 --- a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx +++ b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx @@ -9,7 +9,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Bar, BarChart, XAxis } from "recharts"; -import { api } from "../../../../trpc/rq-client"; +import { api } from "@/trpc/rq-client"; const chartConfig = { total: { label: "Reports", color: "var(--color-warning)" }, diff --git a/apps/web/src/app/(landing)/status/external-status-grid.tsx b/apps/web/src/app/(landing)/status/external-status-grid.tsx index 0a4a74c0..070b4dcb 100644 --- a/apps/web/src/app/(landing)/status/external-status-grid.tsx +++ b/apps/web/src/app/(landing)/status/external-status-grid.tsx @@ -3,8 +3,9 @@ import { useQueryState } from "nuqs"; import { useMemo } from "react"; -import { Grid } from "../../../content/mdx-components/grid"; -import { api } from "../../../trpc/rq-client"; +import { Grid } from "@/content/mdx-components/grid"; +import { api } from "@/trpc/rq-client"; + import { ContentBoxLink } from "../content-box"; import { ExternalServicePill } from "./external-service-pill"; import { filterServices } from "./filter-services"; diff --git a/apps/web/src/app/(landing)/status/page.tsx b/apps/web/src/app/(landing)/status/page.tsx index ef16c8e0..61656351 100644 --- a/apps/web/src/app/(landing)/status/page.tsx +++ b/apps/web/src/app/(landing)/status/page.tsx @@ -1,16 +1,17 @@ import type { Metadata } from "next"; import { Suspense } from "react"; -import { ButtonLink } from "../../../content/mdx-components/button-link"; -import { CustomLink } from "../../../content/mdx-components/custom-link"; +import { ButtonLink } from "@/content/mdx-components/button-link"; +import { CustomLink } from "@/content/mdx-components/custom-link"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; -import { HydrateClient, api } from "../../../trpc/rq-server"; +} from "@/lib/metadata/shared-metadata"; +import { HydrateClient, api } from "@/trpc/rq-server"; + import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx index 3a677a21..55e79dc4 100644 --- a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx @@ -1,13 +1,10 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getToolingPages } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getToolingPages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -15,7 +12,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/tooling/page.tsx b/apps/web/src/app/(landing)/tooling/page.tsx index bd643023..837eae5f 100644 --- a/apps/web/src/app/(landing)/tooling/page.tsx +++ b/apps/web/src/app/(landing)/tooling/page.tsx @@ -1,20 +1,21 @@ import type { Metadata } from "next"; -import { components } from "../../../content/mdx"; -import { getToolingPages } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { components } from "@/content/mdx"; +import { getToolingPages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx index 6d4cdcd6..a7855b95 100644 --- a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx @@ -2,13 +2,10 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "../../../../content/mdx"; -import { getUseCasePages } from "../../../../content/utils"; -import { JsonLd } from "../../../../lib/metadata/json-ld"; -import { - BASE_URL, - getPageMetadata, -} from "../../../../lib/metadata/shared-metadata"; +import { CustomMDX } from "@/content/mdx"; +import { getUseCasePages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -17,7 +14,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "../../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/use-case/page.tsx b/apps/web/src/app/(landing)/use-case/page.tsx index d1e5b3ba..f298ea2c 100644 --- a/apps/web/src/app/(landing)/use-case/page.tsx +++ b/apps/web/src/app/(landing)/use-case/page.tsx @@ -1,19 +1,20 @@ import type { Metadata } from "next"; -import { getUseCasePages } from "../../../content/utils"; -import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getUseCasePages } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "../../../lib/metadata/shared-metadata"; -import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; +} from "@/lib/metadata/shared-metadata"; +import { twitterMetadata } from "@/lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "../../../lib/metadata/structured-data"; +} from "@/lib/metadata/structured-data"; + import { ContentList } from "../content-list"; const TITLE = "Use Cases"; diff --git a/apps/web/src/app/api/checker/cron/_cron.ts b/apps/web/src/app/api/checker/cron/_cron.ts index 370077d6..d0385fa7 100644 --- a/apps/web/src/app/api/checker/cron/_cron.ts +++ b/apps/web/src/app/api/checker/cron/_cron.ts @@ -22,7 +22,7 @@ import { import type { NextRequest } from "next/server"; import { z } from "zod"; -import { env } from "../../../../env"; +import { env } from "@/env"; const periodicityAvailable = selectMonitorSchema.pick({ periodicity: true }); diff --git a/apps/web/src/app/api/checker/test/http/route.ts b/apps/web/src/app/api/checker/test/http/route.ts index 653c0c84..5bf9f961 100644 --- a/apps/web/src/app/api/checker/test/http/route.ts +++ b/apps/web/src/app/api/checker/test/http/route.ts @@ -3,7 +3,8 @@ import { httpPayloadSchema } from "@openstatus/utils"; import { NextResponse } from "next/server"; import { z } from "zod"; -import { checkRegion } from "../../../../../lib/checker/utils"; +import { checkRegion } from "@/lib/checker/utils"; + import { isAnInvalidTestUrl } from "../../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/feedback/docs/route.ts b/apps/web/src/app/api/feedback/docs/route.ts index d99408b9..1c0b313a 100644 --- a/apps/web/src/app/api/feedback/docs/route.ts +++ b/apps/web/src/app/api/feedback/docs/route.ts @@ -1,8 +1,8 @@ import { redis } from "@openstatus/upstash"; import { z } from "zod"; -import { getClientIP, ratelimit } from "../../../../lib/ratelimit"; -import { hashIP } from "../../../../lib/utils"; +import { getClientIP, ratelimit } from "@/lib/ratelimit"; +import { hashIP } from "@/lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/markdown/[[...path]]/route.ts b/apps/web/src/app/api/markdown/[[...path]]/route.ts index b7c456a3..9a1f41ff 100644 --- a/apps/web/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/web/src/app/api/markdown/[[...path]]/route.ts @@ -1,11 +1,11 @@ import { type NextRequest, NextResponse } from "next/server"; -import { convertMdxToMarkdown } from "../../../../content/convert"; +import { convertMdxToMarkdown } from "@/content/convert"; import { generateStatusDetailMarkdown, generateStatusIndexMarkdown, -} from "../../../../content/status-markdown"; -import { resolveContent } from "../../../../content/utils/resolve"; +} from "@/content/status-markdown"; +import { resolveContent } from "@/content/utils/resolve"; export const runtime = "nodejs"; // Need fs access for content loading diff --git a/apps/web/src/app/api/og/_components/background.tsx b/apps/web/src/app/api/og/_components/background.tsx index 1db70723..0405b09c 100644 --- a/apps/web/src/app/api/og/_components/background.tsx +++ b/apps/web/src/app/api/og/_components/background.tsx @@ -1,4 +1,4 @@ -import { cn } from "../../../../lib/utils"; +import { cn } from "@/lib/utils"; export function Background({ children, diff --git a/apps/web/src/app/api/og/_components/basic-layout.tsx b/apps/web/src/app/api/og/_components/basic-layout.tsx index f8f59adf..9ac36793 100644 --- a/apps/web/src/app/api/og/_components/basic-layout.tsx +++ b/apps/web/src/app/api/og/_components/basic-layout.tsx @@ -1,4 +1,5 @@ -import { cn } from "../../../../lib/utils"; +import { cn } from "@/lib/utils"; + import { Background } from "./background"; export function BasicLayout({ diff --git a/apps/web/src/app/api/og/_components/status-check.tsx b/apps/web/src/app/api/og/_components/status-check.tsx index 19bf209c..db63031e 100644 --- a/apps/web/src/app/api/og/_components/status-check.tsx +++ b/apps/web/src/app/api/og/_components/status-check.tsx @@ -1,6 +1,6 @@ import type { Tracker } from "@openstatus/tracker"; -import { cn } from "../../../../lib/utils"; +import { cn } from "@/lib/utils"; export function StatusCheck({ tracker }: { tracker: Tracker }) { const details = tracker.currentDetails; diff --git a/apps/web/src/app/api/og/_components/tracker.tsx b/apps/web/src/app/api/og/_components/tracker.tsx index 86011967..d02580eb 100644 --- a/apps/web/src/app/api/og/_components/tracker.tsx +++ b/apps/web/src/app/api/og/_components/tracker.tsx @@ -1,7 +1,7 @@ import { Tracker as OSTracker, classNames } from "@openstatus/tracker"; -import type { ResponseStatusTracker } from "../../../../lib/tb"; -import { cn, formatDate } from "../../../../lib/utils"; +import type { ResponseStatusTracker } from "@/lib/tb"; +import { cn, formatDate } from "@/lib/utils"; interface TrackerProps { data: ResponseStatusTracker[]; diff --git a/apps/web/src/app/api/og/checker/route.tsx b/apps/web/src/app/api/og/checker/route.tsx index be80038a..baeaf2a3 100644 --- a/apps/web/src/app/api/og/checker/route.tsx +++ b/apps/web/src/app/api/og/checker/route.tsx @@ -4,8 +4,9 @@ import { getCheckerDataById, regionFormatter, timestampFormatter, -} from "../../../../lib/checker/utils"; -import { cn } from "../../../../lib/utils"; +} from "@/lib/checker/utils"; +import { cn } from "@/lib/utils"; + import { BasicLayout } from "../_components/basic-layout"; import { SIZE, diff --git a/apps/web/src/app/api/og/external-service/route.tsx b/apps/web/src/app/api/og/external-service/route.tsx index 6552526c..a2c1333e 100644 --- a/apps/web/src/app/api/og/external-service/route.tsx +++ b/apps/web/src/app/api/og/external-service/route.tsx @@ -1,17 +1,18 @@ import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { isStale } from "../../../(landing)/status/utils"; +import { isStale } from "@/app/(landing)/status/utils"; import { getComponentEscalation, getServiceEscalation, -} from "../../../../lib/external-report-escalation"; +} from "@/lib/external-report-escalation"; import { cachedGetExternalComponentBySlug, cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "../../../../lib/external-service-cache"; -import { cn } from "../../../../lib/utils"; +} from "@/lib/external-service-cache"; +import { cn } from "@/lib/utils"; + import { SIZE } from "../utils"; // nodejs (not edge): this route pulls in the service reads + Effect retry, which diff --git a/apps/web/src/app/api/og/monitor/route.tsx b/apps/web/src/app/api/og/monitor/route.tsx index 788ab200..1fa453ed 100644 --- a/apps/web/src/app/api/og/monitor/route.tsx +++ b/apps/web/src/app/api/og/monitor/route.tsx @@ -1,8 +1,9 @@ import { OSTinybird } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { env } from "../../../../env"; -import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; +import { env } from "@/env"; +import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; + import { BasicLayout } from "../_components/basic-layout"; import { Tracker } from "../_components/tracker"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/page/route.tsx b/apps/web/src/app/api/og/page/route.tsx index 72e8f733..1ea61b35 100644 --- a/apps/web/src/app/api/og/page/route.tsx +++ b/apps/web/src/app/api/og/page/route.tsx @@ -1,8 +1,9 @@ import { Tracker } from "@openstatus/tracker"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; -import { api } from "../../../../trpc/server"; +import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; +import { api } from "@/trpc/server"; + import { BasicLayout } from "../_components/basic-layout"; import { StatusCheck } from "../_components/status-check"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/post/route.tsx b/apps/web/src/app/api/og/post/route.tsx index 1f00b7b2..0413f82f 100644 --- a/apps/web/src/app/api/og/post/route.tsx +++ b/apps/web/src/app/api/og/post/route.tsx @@ -1,7 +1,8 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { TITLE } from "../../../../lib/metadata/shared-metadata"; +import { TITLE } from "@/lib/metadata/shared-metadata"; + import { BasicLayout } from "../_components/basic-layout"; import { DEFAULT_URL, diff --git a/apps/web/src/app/api/og/route.tsx b/apps/web/src/app/api/og/route.tsx index a84516f0..73e77332 100644 --- a/apps/web/src/app/api/og/route.tsx +++ b/apps/web/src/app/api/og/route.tsx @@ -1,7 +1,8 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { OG_DESCRIPTION, TITLE } from "../../../lib/metadata/shared-metadata"; +import { OG_DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; + import { SIZE } from "./utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/og/status/route.tsx b/apps/web/src/app/api/og/status/route.tsx index c7f2cfb3..988b2154 100644 --- a/apps/web/src/app/api/og/status/route.tsx +++ b/apps/web/src/app/api/og/status/route.tsx @@ -2,9 +2,10 @@ import type { RouterOutputs } from "@openstatus/api"; import { format } from "date-fns"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; -import { cn } from "../../../../lib/utils"; -import { api } from "../../../../trpc/server"; +import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; +import { cn } from "@/lib/utils"; +import { api } from "@/trpc/server"; + import { SIZE } from "../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/search/route.ts b/apps/web/src/app/api/search/route.ts index e9810d5d..c35f79bd 100644 --- a/apps/web/src/app/api/search/route.ts +++ b/apps/web/src/app/api/search/route.ts @@ -1,7 +1,7 @@ import { z } from "zod"; -import { PAGE_TYPES } from "../../../content/utils"; -import { searchCorpus } from "../../../content/utils/search-index"; +import { PAGE_TYPES } from "@/content/utils"; +import { searchCorpus } from "@/content/utils/search-index"; const SearchSchema = z.object({ p: z.enum(PAGE_TYPES).nullish(), diff --git a/apps/web/src/app/api/test/timeout/route.ts b/apps/web/src/app/api/test/timeout/route.ts index 3e454a7e..6513b15c 100644 --- a/apps/web/src/app/api/test/timeout/route.ts +++ b/apps/web/src/app/api/test/timeout/route.ts @@ -1,6 +1,6 @@ import { NextResponse } from "next/server"; -import { wait } from "../../../../lib/utils"; +import { wait } from "@/lib/utils"; export async function POST() { await wait(10_000); diff --git a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts index 5a339780..8ad8edf0 100644 --- a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,7 +3,7 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; +import { createOnError, guardTRPCSource } from "@/trpc/shared"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts index ddbd1dbb..175c51af 100644 --- a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,7 +3,7 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; +import { createOnError, guardTRPCSource } from "@/trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/web/src/app/api/webhook/stripe/route.ts b/apps/web/src/app/api/webhook/stripe/route.ts index 992eae4d..630ba246 100644 --- a/apps/web/src/app/api/webhook/stripe/route.ts +++ b/apps/web/src/app/api/webhook/stripe/route.ts @@ -4,7 +4,7 @@ import { TRPCError } from "@trpc/server"; import { getHTTPStatusCodeFromError } from "@trpc/server/http"; import type { NextRequest } from "next/server"; -import { env } from "../../../../env"; +import { env } from "@/env"; export async function POST(req: NextRequest) { const payload = await req.text(); diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index cdd6ea15..bab21c8c 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,4 +1,4 @@ -import "../styles/globals.css"; +import "@/styles/globals.css"; import { OpenPanelComponent } from "@openpanel/nextjs"; import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; @@ -8,15 +8,15 @@ import LocalFont from "next/font/local"; import Script from "next/script"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { ThemeProvider } from "../components/theme-provider"; -import { WebMcpProvider } from "../components/webmcp-provider"; -import { env } from "../env"; +import { ThemeProvider } from "@/components/theme-provider"; +import { WebMcpProvider } from "@/components/webmcp-provider"; +import { env } from "@/env"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "../lib/metadata/shared-metadata"; -import { TRPCReactQueryProvider } from "../trpc/rq-client"; +} from "@/lib/metadata/shared-metadata"; +import { TRPCReactQueryProvider } from "@/trpc/rq-client"; const inter = Inter({ subsets: ["latin"], variable: "--font-sans" }); diff --git a/apps/web/src/app/not-found.tsx b/apps/web/src/app/not-found.tsx index 3f52999e..6902b4b5 100644 --- a/apps/web/src/app/not-found.tsx +++ b/apps/web/src/app/not-found.tsx @@ -1,5 +1,5 @@ -import { CustomMDX } from "../content/mdx"; -import { getUnrelatedPage } from "../content/utils"; +import { CustomMDX } from "@/content/mdx"; +import { getUnrelatedPage } from "@/content/utils"; export default function NotFound() { const page = getUnrelatedPage("not-found"); diff --git a/apps/web/src/app/sitemap.ts b/apps/web/src/app/sitemap.ts index 53efa8ac..9d43f572 100644 --- a/apps/web/src/app/sitemap.ts +++ b/apps/web/src/app/sitemap.ts @@ -13,11 +13,11 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "../content/utils"; +} from "@/content/utils"; import { cachedListExternalComponentsBySlug, cachedListExternalServices, -} from "../lib/external-service-cache"; +} from "@/lib/external-service-cache"; export const revalidate = 3600; diff --git a/apps/web/src/components/dev-mode-container.tsx b/apps/web/src/components/dev-mode-container.tsx index 41042767..76eb3a55 100644 --- a/apps/web/src/components/dev-mode-container.tsx +++ b/apps/web/src/components/dev-mode-container.tsx @@ -1,4 +1,4 @@ -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; export default function DevModeContainer({ children, diff --git a/apps/web/src/components/icon-cloud-provider.tsx b/apps/web/src/components/icon-cloud-provider.tsx index c1e9d7a2..14db64a1 100644 --- a/apps/web/src/components/icon-cloud-provider.tsx +++ b/apps/web/src/components/icon-cloud-provider.tsx @@ -7,7 +7,7 @@ import { } from "@openstatus/ui/components/ui/tooltip"; import { Globe } from "lucide-react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; export function IconCloudProvider({ provider, diff --git a/apps/web/src/components/loading-animation.tsx b/apps/web/src/components/loading-animation.tsx index f3fdc9e6..3142bfd3 100644 --- a/apps/web/src/components/loading-animation.tsx +++ b/apps/web/src/components/loading-animation.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type { VariantProps } from "class-variance-authority"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; const loadingVariants = cva( "direction-alternate animate-pulse rounded-full duration-700", diff --git a/apps/web/src/config/socials.ts b/apps/web/src/config/socials.ts index 0287bde6..e97d2487 100644 --- a/apps/web/src/config/socials.ts +++ b/apps/web/src/config/socials.ts @@ -1,4 +1,4 @@ -import type { ValidIcon } from "../components/icons"; +import type { ValidIcon } from "@/components/icons"; export type Social = { title: string; diff --git a/apps/web/src/content/cmdk.tsx b/apps/web/src/content/cmdk.tsx index dcd2579a..da40c8f8 100644 --- a/apps/web/src/content/cmdk.tsx +++ b/apps/web/src/content/cmdk.tsx @@ -24,8 +24,12 @@ import { useTheme } from "next-themes"; import { useRouter } from "next/navigation"; import * as React from "react"; -import { CORPUS_LABELS, type Corpus, type SearchResult } from "./search-meta"; -import { buildHighlightRegex } from "./utils/search-match"; +import { + CORPUS_LABELS, + type Corpus, + type SearchResult, +} from "@/content/search-meta"; +import { buildHighlightRegex } from "@/content/utils/search-match"; type ConfigItem = { type: "item"; diff --git a/apps/web/src/content/docs-feedback.tsx b/apps/web/src/content/docs-feedback.tsx index b9cefb17..c57310f8 100644 --- a/apps/web/src/content/docs-feedback.tsx +++ b/apps/web/src/content/docs-feedback.tsx @@ -21,7 +21,7 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { toastAction } from "../lib/toast"; +import { toastAction } from "@/lib/toast"; type Rating = "up" | "down"; diff --git a/apps/web/src/content/docs-footer.tsx b/apps/web/src/content/docs-footer.tsx index 617c8a21..6c3c564e 100644 --- a/apps/web/src/content/docs-footer.tsx +++ b/apps/web/src/content/docs-footer.tsx @@ -1,6 +1,7 @@ +import { Link } from "@/content/link"; +import { ThemeToggle } from "@/content/theme-toggle"; + import { FooterStatus } from "./footer-status"; -import { Link } from "./link"; -import { ThemeToggle } from "./theme-toggle"; export function DocsFooter() { return ( diff --git a/apps/web/src/content/docs-sidebar.tsx b/apps/web/src/content/docs-sidebar.tsx index 8b7546c2..a1c8381a 100644 --- a/apps/web/src/content/docs-sidebar.tsx +++ b/apps/web/src/content/docs-sidebar.tsx @@ -12,7 +12,8 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; + import { type DocsNavGroup, type DocsNavItem, diff --git a/apps/web/src/content/docs-sub-nav.tsx b/apps/web/src/content/docs-sub-nav.tsx index 7a939409..7d50c8ac 100644 --- a/apps/web/src/content/docs-sub-nav.tsx +++ b/apps/web/src/content/docs-sub-nav.tsx @@ -4,7 +4,8 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; + import { CopyDropdownButton } from "./copy-button"; export function DocsSubNav({ diff --git a/apps/web/src/content/docs-toc.tsx b/apps/web/src/content/docs-toc.tsx index f9a4642f..d83a02ac 100644 --- a/apps/web/src/content/docs-toc.tsx +++ b/apps/web/src/content/docs-toc.tsx @@ -2,7 +2,8 @@ import { useEffect, useState } from "react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; + import type { TocItem } from "./toc"; function useActiveHeading(items: TocItem[]) { diff --git a/apps/web/src/content/footer-status.tsx b/apps/web/src/content/footer-status.tsx index ea8e43fd..95e024da 100644 --- a/apps/web/src/content/footer-status.tsx +++ b/apps/web/src/content/footer-status.tsx @@ -4,7 +4,7 @@ import type { StatusResponse } from "@openstatus/react"; import { useQuery } from "@tanstack/react-query"; import Link from "next/link"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; export function FooterStatus() { const { data } = useQuery({ diff --git a/apps/web/src/content/footer.tsx b/apps/web/src/content/footer.tsx index 406d1694..1045e551 100644 --- a/apps/web/src/content/footer.tsx +++ b/apps/web/src/content/footer.tsx @@ -1,7 +1,8 @@ -import { footerLinks } from "../data/content"; +import { Link } from "@/content/link"; +import { ThemeToggle } from "@/content/theme-toggle"; +import { footerLinks } from "@/data/content"; + import { FooterStatus } from "./footer-status"; -import { Link } from "./link"; -import { ThemeToggle } from "./theme-toggle"; export function Footer() { return ( diff --git a/apps/web/src/content/header.tsx b/apps/web/src/content/header.tsx index 00389e7a..38c6a890 100644 --- a/apps/web/src/content/header.tsx +++ b/apps/web/src/content/header.tsx @@ -6,7 +6,8 @@ import { } from "@openstatus/ui/components/ui/dropdown-menu"; import Link from "next/link"; -import { headerLinks } from "../data/content"; +import { headerLinks } from "@/data/content"; + import { CmdK } from "./cmdk"; import { LogoWithContextMenu } from "./logo-with-context-menu"; diff --git a/apps/web/src/content/highlight-text.tsx b/apps/web/src/content/highlight-text.tsx index 0a22adf1..d3a5e5a6 100644 --- a/apps/web/src/content/highlight-text.tsx +++ b/apps/web/src/content/highlight-text.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "next/navigation"; import { useEffect, useRef } from "react"; -import { buildHighlightRegex } from "./utils/search-match"; +import { buildHighlightRegex } from "@/content/utils/search-match"; function escapeHtml(input: string) { return input.replace(/[&<>]/g, (c) => diff --git a/apps/web/src/content/image-zoom.tsx b/apps/web/src/content/image-zoom.tsx index 93dc4288..fa59e93b 100644 --- a/apps/web/src/content/image-zoom.tsx +++ b/apps/web/src/content/image-zoom.tsx @@ -9,7 +9,7 @@ import Zoom, { type UncontrolledProps, } from "react-medium-image-zoom"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; export type ImageZoomProps = UncontrolledProps & { isZoomed?: ControlledProps["isZoomed"]; diff --git a/apps/web/src/content/latency-chart-table.tsx b/apps/web/src/content/latency-chart-table.tsx index 3a7e5cc8..bce59b84 100644 --- a/apps/web/src/content/latency-chart-table.tsx +++ b/apps/web/src/content/latency-chart-table.tsx @@ -2,7 +2,8 @@ import fs from "node:fs"; import { type Region, regionDict } from "@openstatus/regions"; -import type { RegionMetricsChartTable } from "../data/content"; +import type { RegionMetricsChartTable } from "@/data/content"; + import { SimpleChart } from "./simple-chart"; export interface LatencyChartTableProps { diff --git a/apps/web/src/content/link.tsx b/apps/web/src/content/link.tsx index 9b928a9d..9043ae77 100644 --- a/apps/web/src/content/link.tsx +++ b/apps/web/src/content/link.tsx @@ -1,6 +1,6 @@ import NextLink from "next/link"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; // TODO: we could add cva variants for the link diff --git a/apps/web/src/content/mdx-components/aside.tsx b/apps/web/src/content/mdx-components/aside.tsx index 863c9829..c23385c2 100644 --- a/apps/web/src/content/mdx-components/aside.tsx +++ b/apps/web/src/content/mdx-components/aside.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type React from "react"; -import { cn } from "../../lib/utils"; +import { cn } from "@/lib/utils"; type AsideType = "note" | "tip" | "caution" | "danger"; diff --git a/apps/web/src/content/mdx-components/card.tsx b/apps/web/src/content/mdx-components/card.tsx index 336c1ea6..8a692833 100644 --- a/apps/web/src/content/mdx-components/card.tsx +++ b/apps/web/src/content/mdx-components/card.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "../../lib/utils"; +import { cn } from "@/lib/utils"; export function CardGrid({ children }: { children: React.ReactNode }) { return
    {children}
    ; diff --git a/apps/web/src/content/mdx-components/custom-image.tsx b/apps/web/src/content/mdx-components/custom-image.tsx index a7087a2c..e7b12e80 100644 --- a/apps/web/src/content/mdx-components/custom-image.tsx +++ b/apps/web/src/content/mdx-components/custom-image.tsx @@ -3,8 +3,9 @@ import { join } from "node:path"; import Image from "next/image"; -import { getImageDimensions } from "../../lib/image-dimensions"; -import { cn } from "../../lib/utils"; +import { getImageDimensions } from "@/lib/image-dimensions"; +import { cn } from "@/lib/utils"; + import { ImageZoom, ZoomableImage } from "../image-zoom"; type CustomImageProps = React.ComponentProps & { diff --git a/apps/web/src/content/mdx-components/grid.tsx b/apps/web/src/content/mdx-components/grid.tsx index 82afd5ab..d637228c 100644 --- a/apps/web/src/content/mdx-components/grid.tsx +++ b/apps/web/src/content/mdx-components/grid.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "../../lib/utils"; +import { cn } from "@/lib/utils"; export function Grid({ cols = 2, diff --git a/apps/web/src/content/mdx-components/subtle.tsx b/apps/web/src/content/mdx-components/subtle.tsx index 4b1adeea..423f2e9e 100644 --- a/apps/web/src/content/mdx-components/subtle.tsx +++ b/apps/web/src/content/mdx-components/subtle.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "../../lib/utils"; +import { cn } from "@/lib/utils"; export function Subtle({ className, ...props }: React.ComponentProps<"span">) { return ; diff --git a/apps/web/src/content/simple-chart.tsx b/apps/web/src/content/simple-chart.tsx index e7869a77..87be846d 100644 --- a/apps/web/src/content/simple-chart.tsx +++ b/apps/web/src/content/simple-chart.tsx @@ -8,7 +8,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Line, LineChart, XAxis } from "recharts"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; const chartConfig = { latency: { diff --git a/apps/web/src/content/status-markdown.ts b/apps/web/src/content/status-markdown.ts index fa79587e..caf43d5d 100644 --- a/apps/web/src/content/status-markdown.ts +++ b/apps/web/src/content/status-markdown.ts @@ -10,11 +10,11 @@ import { } from "@openstatus/services/external-service-report"; import { OSTinybird, safePipeData } from "@openstatus/tinybird"; -import { env } from "../env"; +import { env } from "@/env"; import { cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "../lib/external-service-cache"; +} from "@/lib/external-service-cache"; type LatestRow = { id: string; diff --git a/apps/web/src/content/sub-nav.tsx b/apps/web/src/content/sub-nav.tsx index 81e4e1c1..50ea6fe1 100644 --- a/apps/web/src/content/sub-nav.tsx +++ b/apps/web/src/content/sub-nav.tsx @@ -4,7 +4,8 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; + import { CopyDropdownButton } from "./copy-button"; export function SubNav({ className, ...props }: React.ComponentProps<"div">) { diff --git a/apps/web/src/content/theme-toggle.tsx b/apps/web/src/content/theme-toggle.tsx index a39e1028..45064ca7 100644 --- a/apps/web/src/content/theme-toggle.tsx +++ b/apps/web/src/content/theme-toggle.tsx @@ -5,7 +5,7 @@ import { useTheme } from "next-themes"; import type * as React from "react"; import { useEffect, useState } from "react"; -import { cn } from "../lib/utils"; +import { cn } from "@/lib/utils"; export function ThemeToggle({ className, diff --git a/apps/web/src/content/utils/search-index.ts b/apps/web/src/content/utils/search-index.ts index 1f3fe251..357bc83e 100644 --- a/apps/web/src/content/utils/search-index.ts +++ b/apps/web/src/content/utils/search-index.ts @@ -1,6 +1,7 @@ import "server-only"; +import { slugify } from "@/content/mdx"; + import { type MDXData, PAGE_TYPES, getHomePage, getPages } from "."; -import { slugify } from "../mdx"; import type { Corpus, SearchResult } from "../search-meta"; import { closestHeadingSlug, diff --git a/apps/web/src/content/utils/search-match.test.ts b/apps/web/src/content/utils/search-match.test.ts index 827ca8e9..15e92226 100644 --- a/apps/web/src/content/utils/search-match.test.ts +++ b/apps/web/src/content/utils/search-match.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { WEIGHTS, diff --git a/apps/web/src/data/content.ts b/apps/web/src/data/content.ts index 7cf726ad..a80c48be 100644 --- a/apps/web/src/data/content.ts +++ b/apps/web/src/data/content.ts @@ -7,7 +7,7 @@ import { getToolingPages, getToolsPages, getUseCasePages, -} from "../content/utils"; +} from "@/content/utils"; const products = getProductPages(); diff --git a/apps/web/src/data/trigger-dictionary.ts b/apps/web/src/data/trigger-dictionary.ts index 06cbc4f5..2b4703b2 100644 --- a/apps/web/src/data/trigger-dictionary.ts +++ b/apps/web/src/data/trigger-dictionary.ts @@ -1,5 +1,5 @@ -import type { ValidIcon } from "../components/icons"; -import type { Trigger } from "../lib/monitor/utils"; +import type { ValidIcon } from "@/components/icons"; +import type { Trigger } from "@/lib/monitor/utils"; export const triggerDict = { cron: { diff --git a/apps/web/src/lib/checker/mock.ts b/apps/web/src/lib/checker/mock.ts index cdc60e49..ce20f05d 100644 --- a/apps/web/src/lib/checker/mock.ts +++ b/apps/web/src/lib/checker/mock.ts @@ -1,7 +1,7 @@ import type { Region } from "@openstatus/db/src/schema/constants"; -import { wait } from "../utils"; -import { type RegionChecker, cachedCheckerSchema } from "./utils"; +import { type RegionChecker, cachedCheckerSchema } from "@/lib/checker/utils"; +import { wait } from "@/lib/utils"; export async function mockCheckRegion(region: Region) { const response = data.checks diff --git a/apps/web/src/lib/external-report-escalation.ts b/apps/web/src/lib/external-report-escalation.ts index c9145002..be7f9de6 100644 --- a/apps/web/src/lib/external-report-escalation.ts +++ b/apps/web/src/lib/external-report-escalation.ts @@ -10,7 +10,7 @@ import { import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { unstable_cache } from "next/cache"; -import { env } from "../env"; +import { env } from "@/env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/web/src/lib/mcp/health-check.test.ts b/apps/web/src/lib/mcp/health-check.test.ts index 760265b6..1eac8d99 100644 --- a/apps/web/src/lib/mcp/health-check.test.ts +++ b/apps/web/src/lib/mcp/health-check.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; +import { afterEach, describe, expect, test } from "bun:test"; import { normalizeUrlForStorage, diff --git a/apps/web/src/lib/metadata/shared-metadata.ts b/apps/web/src/lib/metadata/shared-metadata.ts index 68e9a67b..db9d7981 100644 --- a/apps/web/src/lib/metadata/shared-metadata.ts +++ b/apps/web/src/lib/metadata/shared-metadata.ts @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import type { MDXData } from "../../content/utils"; +import type { MDXData } from "@/content/utils"; export const TITLE = "openstatus"; export const HOMEPAGE_TITLE = "The Compliance-First Status Page"; diff --git a/apps/web/src/lib/metadata/structured-data.ts b/apps/web/src/lib/metadata/structured-data.ts index d7f7fb38..36a29602 100644 --- a/apps/web/src/lib/metadata/structured-data.ts +++ b/apps/web/src/lib/metadata/structured-data.ts @@ -19,7 +19,8 @@ import type { WithContext, } from "schema-dts"; -import type { MDXData } from "../../content/utils"; +import type { MDXData } from "@/content/utils"; + import { BASE_URL } from "./shared-metadata"; export const getJsonLDWebPage = ( diff --git a/apps/web/src/lib/stripe/client.ts b/apps/web/src/lib/stripe/client.ts index 8e64d21e..50e71374 100644 --- a/apps/web/src/lib/stripe/client.ts +++ b/apps/web/src/lib/stripe/client.ts @@ -1,7 +1,7 @@ import type { Stripe as StripeProps } from "@stripe/stripe-js"; import { loadStripe } from "@stripe/stripe-js"; -import { env } from "../../env"; +import { env } from "@/env"; let stripePromise: Promise; diff --git a/apps/web/src/lib/tb.ts b/apps/web/src/lib/tb.ts index fc16ba37..371c5e02 100644 --- a/apps/web/src/lib/tb.ts +++ b/apps/web/src/lib/tb.ts @@ -1,6 +1,6 @@ import { OSTinybird } from "@openstatus/tinybird"; -import { env } from "../env"; +import { env } from "@/env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/workflows/.gitignore b/apps/workflows/.gitignore index e4037038..506e4c37 100644 --- a/apps/workflows/.gitignore +++ b/apps/workflows/.gitignore @@ -1,6 +1,2 @@ # deps node_modules/ - -# build artifacts / local dev db -app -dev.db* diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index 348eacb7..42ee8271 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -2,121 +2,68 @@ # This file is generated by Dofigen v2.8.0 # See https://github.com/lenra-io/dofigen +# docker +FROM oven/bun@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS docker +LABEL \ + org.opencontainers.image.base.digest="sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7" \ + org.opencontainers.image.base.name="docker.io/oven/bun:1.3.11" +WORKDIR /app/apps/workflows +COPY \ + --link \ + "." "/app/" +RUN bun run src/build-docker.ts + # install -FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install +FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install LABEL \ - org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ + org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ -COPY \ - --link \ - "pnpm-workspace.yaml" "/app/pnpm-workspace.yaml" -COPY \ - --link \ - "pnpm-lock.yaml" "/app/pnpm-lock.yaml" -COPY \ - --link \ - "package.json" "/app/package.json" -COPY \ - --link \ - "apps/workflows/package.json" "/app/apps/workflows/package.json" -COPY \ - --link \ - "packages/assertions/package.json" "/app/packages/assertions/package.json" -COPY \ - --link \ - "packages/db/package.json" "/app/packages/db/package.json" -COPY \ - --link \ - "packages/emails/package.json" "/app/packages/emails/package.json" -COPY \ - --link \ - "packages/notifications/base/package.json" "/app/packages/notifications/base/package.json" -COPY \ - --link \ - "packages/notifications/discord/package.json" "/app/packages/notifications/discord/package.json" -COPY \ - --link \ - "packages/notifications/email/package.json" "/app/packages/notifications/email/package.json" -COPY \ - --link \ - "packages/notifications/grafana-oncall/package.json" "/app/packages/notifications/grafana-oncall/package.json" -COPY \ - --link \ - "packages/notifications/google-chat/package.json" "/app/packages/notifications/google-chat/package.json" -COPY \ - --link \ - "packages/notifications/ms-teams/package.json" "/app/packages/notifications/ms-teams/package.json" -COPY \ - --link \ - "packages/notifications/ntfy/package.json" "/app/packages/notifications/ntfy/package.json" -COPY \ - --link \ - "packages/notifications/opsgenie/package.json" "/app/packages/notifications/opsgenie/package.json" -COPY \ - --link \ - "packages/notifications/pagerduty/package.json" "/app/packages/notifications/pagerduty/package.json" -COPY \ - --link \ - "packages/notifications/slack/package.json" "/app/packages/notifications/slack/package.json" -COPY \ - --link \ - "packages/notifications/telegram/package.json" "/app/packages/notifications/telegram/package.json" -COPY \ - --link \ - "packages/notifications/bird-whatsapp/package.json" "/app/packages/notifications/bird-whatsapp/package.json" -COPY \ - --link \ - "packages/notifications/twillio-sms/package.json" "/app/packages/notifications/twillio-sms/package.json" -COPY \ - --link \ - "packages/notifications/webhook/package.json" "/app/packages/notifications/webhook/package.json" -COPY \ - --link \ - "packages/importers/package.json" "/app/packages/importers/package.json" -COPY \ - --link \ - "packages/regions/package.json" "/app/packages/regions/package.json" -COPY \ - --link \ - "packages/services/package.json" "/app/packages/services/package.json" -COPY \ - --link \ - "packages/subscriptions/package.json" "/app/packages/subscriptions/package.json" -COPY \ - --link \ - "packages/utils/package.json" "/app/packages/utils/package.json" -COPY \ - --link \ - "packages/tsconfig/package.json" "/app/packages/tsconfig/package.json" -COPY \ - --link \ - "packages/tinybird/package.json" "/app/packages/tinybird/package.json" -COPY \ - --link \ - "packages/upstash/package.json" "/app/packages/upstash/package.json" -COPY \ - --link \ - "packages/theme-store/package.json" "/app/packages/theme-store/package.json" -COPY \ - --link \ - "packages/locales/package.json" "/app/packages/locales/package.json" -COPY \ - --link \ - "packages/status-fetcher/package.json" "/app/packages/status-fetcher/package.json" RUN \ - --mount=type=cache,target=/root/.local/share/pnpm/store,id=s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store,sharing=locked \ + --mount=type=bind,target=pnpm-workspace.yaml,source=pnpm-workspace.yaml \ + --mount=type=bind,target=pnpm-lock.yaml,source=pnpm-lock.yaml \ + --mount=type=bind,target=package.json,source=package.json \ + --mount=type=bind,target=apps/workflows/package.json,source=apps/workflows/package.json \ + --mount=type=bind,target=packages/assertions/package.json,source=packages/assertions/package.json \ + --mount=type=bind,target=packages/db/package.json,source=packages/db/package.json \ + --mount=type=bind,target=packages/emails/package.json,source=packages/emails/package.json \ + --mount=type=bind,target=packages/notifications/base/package.json,source=packages/notifications/base/package.json \ + --mount=type=bind,target=packages/notifications/discord/package.json,source=packages/notifications/discord/package.json \ + --mount=type=bind,target=packages/notifications/email/package.json,source=packages/notifications/email/package.json \ + --mount=type=bind,target=packages/notifications/grafana-oncall/package.json,source=packages/notifications/grafana-oncall/package.json \ + --mount=type=bind,target=packages/notifications/google-chat/package.json,source=packages/notifications/google-chat/package.json \ + --mount=type=bind,target=packages/notifications/ms-teams/package.json,source=packages/notifications/ms-teams/package.json \ + --mount=type=bind,target=packages/notifications/ntfy/package.json,source=packages/notifications/ntfy/package.json \ + --mount=type=bind,target=packages/notifications/opsgenie/package.json,source=packages/notifications/opsgenie/package.json \ + --mount=type=bind,target=packages/notifications/pagerduty/package.json,source=packages/notifications/pagerduty/package.json \ + --mount=type=bind,target=packages/notifications/slack/package.json,source=packages/notifications/slack/package.json \ + --mount=type=bind,target=packages/notifications/telegram/package.json,source=packages/notifications/telegram/package.json \ + --mount=type=bind,target=packages/notifications/bird-whatsapp/package.json,source=packages/notifications/bird-whatsapp/package.json \ + --mount=type=bind,target=packages/notifications/twillio-sms/package.json,source=packages/notifications/twillio-sms/package.json \ + --mount=type=bind,target=packages/notifications/webhook/package.json,source=packages/notifications/webhook/package.json \ + --mount=type=bind,target=packages/importers/package.json,source=packages/importers/package.json \ + --mount=type=bind,target=packages/regions/package.json,source=packages/regions/package.json \ + --mount=type=bind,target=packages/services/package.json,source=packages/services/package.json \ + --mount=type=bind,target=packages/subscriptions/package.json,source=packages/subscriptions/package.json \ + --mount=type=bind,target=packages/utils/package.json,source=packages/utils/package.json \ + --mount=type=bind,target=packages/tsconfig/package.json,source=packages/tsconfig/package.json \ + --mount=type=bind,target=packages/tinybird/package.json,source=packages/tinybird/package.json \ + --mount=type=bind,target=packages/upstash/package.json,source=packages/upstash/package.json \ + --mount=type=bind,target=packages/theme-store/package.json,source=packages/theme-store/package.json \ + --mount=type=bind,target=packages/locales/package.json,source=packages/locales/package.json \ + --mount=type=bind,target=packages/status-fetcher/package.json,source=packages/status-fetcher/package.json \ + --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' -cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts -cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts -cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs -mkdir -p /app/data -EOF +RUN bun build --compile --target bun --sourcemap src/index.ts --outfile=app + +# libsql +FROM oven/bun@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS libsql +LABEL \ + org.opencontainers.image.base.digest="sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7" \ + org.opencontainers.image.base.name="docker.io/oven/bun:1.3.11" +WORKDIR /app/ +COPY \ + --from=docker \ + --link \ + "/app/apps/build-docker/package.json" "/app/package.json" +RUN bun install --production # runtime -FROM registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 AS runtime +FROM debian@sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 AS runtime LABEL \ io.dofigen.version="2.8.0" \ org.opencontainers.image.authors="OpenStatus Team" \ - org.opencontainers.image.base.digest="sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4" \ + org.opencontainers.image.base.digest="sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604" \ + org.opencontainers.image.base.name="docker.io/debian:bullseye-slim" \ org.opencontainers.image.description="Background job processing and probe scheduling for OpenStatus" \ org.opencontainers.image.source="https://github.com/openstatusHQ/openstatus" \ org.opencontainers.image.title="OpenStatus Workflows" \ @@ -162,16 +115,17 @@ COPY \ --link \ "/app/apps/workflows/app" "/app/apps/workflows/" COPY \ - --from=build \ + --from=libsql \ --chown=1000:1000 \ --link \ - "/app/data" "/app/data" + "/app/node_modules" "/app/packages/db/node_modules" +COPY \ + --from=libsql \ + --chown=1000:1000 \ + --link \ + "/app/node_modules" "/app/node_modules" +USER 0:0 +RUN apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data USER 1000:1000 EXPOSE 3000 -HEALTHCHECK \ - --interval=1m \ - --timeout=10s \ - --start-period=30s \ - --retries=3 \ - CMD ["curl", "-f", "http://localhost:3000/ping"] ENTRYPOINT ["/app/apps/workflows/app"] diff --git a/apps/workflows/deno-migration-plan.md b/apps/workflows/deno-migration-plan.md deleted file mode 100644 index 2b7b2f0f..00000000 --- a/apps/workflows/deno-migration-plan.md +++ /dev/null @@ -1,437 +0,0 @@ -# Plan: migrate `apps/server` + `apps/workflows` from bun to Deno 2.9 - -Goal: remove **bun** from the project. Three pillars, shipped as **one big-bang PR**: - -1. **Build** — `bun build --compile` → `deno compile` (server + workflows). -2. **Install** — the Docker `pnpm install` stage → `deno install` (server + workflows). -3. **Tests** — `bun:test` → **`node:test` runner + `@std/expect`**, run via **`deno test`**, - across **all ~270 test files** (12 packages + apps server, workflows, web, status-page). - -The other apps (`web`, `dashboard`, `status-page`, `docs`, `screenshot-service`) keep -**pnpm** for install + their existing builds; their only bun usage was `bun test`, removed by -pillar 3. `pnpm` remains the local-dev + non-migrated-app package manager. - ---- - -## Agreed decisions (the design) - -| # | Area | Decision | -|---|------|----------| -| 1 | Test scope | All ~270 `bun:test` files (12 packages + server/workflows/web/status-page) | -| 2 | Rollout | One big-bang PR, guarded by a baseline test-count parity gate (#16) | -| 3 | Entrypoint | **Split**: `index.ts` exports `app`; new `serve.ts` calls `Deno.serve`, is the compile target | -| 4 | Assertions | Keep Jest-style `expect` via **`@std/expect`** | -| 5 | Mocks | **`@std/testing/mock`** (`spy`/`stub`, `using`) + **`@std/testing/time`** (`FakeTime`) | -| 6 | `mock.module` | **Hybrid**: `stub` the reachable seams; **default-param DI** for the rest; delete dead ones | -| 7 | Test infra | New **`@openstatus/test-utils`** package: matchers (`expect.extend`), setup, shared fakes | -| 8 | DI style | **Default-parameter injection** for `dispatch*` / `getChannel` | -| 9 | Snapshots / type tests | `@std/testing/snapshot` / `expect-type` | -| 10 | Typecheck | Replace `tsc` with **`deno check`**, scoped to `apps/server` + `apps/workflows` (src + tests) | -| 11 | Permissions | `-A` for `deno test` and `deno compile` now; tighten the binary in a follow-up | -| 12 | Docker install | `deno install --prod --frozen --allow-scripts`, hoisted node_modules; `pnpm-workspace.yaml` stays authoritative; commit `deno.lock` only | -| 13 | CI install | CI test/migrate jobs **keep `pnpm install`**; `deno install` is exercised by the docker-publish build | -| 14 | CI test orchestration | Keep **turbo**; each package `"test": "deno test -A"`; swap `setup-bun` → `setup-deno` | -| 15 | Integration tests | Stay in the same `deno test -A` run, against the CI libsql service (as today) | -| 16 | Safety net | Record base-commit `bun test` pass count; assert `deno test` count ≥ it (fail CI on drop) | -| 17 | Other apps | Stay on pnpm install + existing build | -| 18 | Codemod | `ts-morph`/`jscodeshift` for the mechanical rewrite; hand-fix the ~60-file residue | - ---- - -## Resolved by codebase exploration (facts, not assumptions) - -- **Entrypoint must split** — tests do `import { app } from "@/index"`; a top-level - `Deno.serve` in `index.ts` would boot a server on every test import. -- **Server needs no libsql side-car** — `packages/db` uses `drizzle-orm/libsql/http` (pure - HTTP). Only `apps/workflows/src/lib/db.ts` uses the native `@libsql/client` embedded replica - → native-addon compile risk is **workflows-only**. -- **Tests are integration tests against a real libSQL DB** — CI runs a `libsql-server` - service + migrate + seed. The preload mocks only Tinybird/Redis/subscriptions; DB is real. -- **Step D seams are mixed**: `@/libs/clients` (`tb`/`redis` singletons) + `Redis.fromEnv` - are stub-able; `@openstatus/subscriptions` `dispatch*` + `getChannel` are destructured live - bindings called directly → need DI. -- **`node-fetch` mock is dead** — the SUT uses **global `fetch`**; tests set - `global.fetch = mockFetch` (the effective line) plus a redundant `mock.module("node-fetch")` - (not a dependency). → `stub(globalThis, "fetch", …)` and delete the `mock.module` line. -- **`start.sh` is unused by Fly** (entrypoint is the binary; compose `command` commented) — - prod migrations run via CI `migrate.yml`. We keep `start.sh` anyway and port its command. -- **migrate/seed have no `Bun.*`** — `packages/db/src/migrate.mts` + `seed.mts` use only - `@libsql/client`/drizzle/`process` → run under `deno run -A` unchanged. -- **`Bun.*` lives only in dev/build scripts** — `packages/db/env.ts`, `apps/server/env.ts`, - `apps/workflows/src/build-docker.ts` (`Bun.file`/`Bun.write`). -- **web/status-page tests are pure logic/util** — no DOM/`@testing-library`/React rendering; - run under `deno test` with no jsdom. -- **Only `apps/server` runs `tsc`** today (`tsc --noEmit`, `types: ["bun-types"]`). - ---- - -## Phase 0 — Spikes (gate the big-bang) — ✅ DONE (1,2) / deferred (3,4) - -Toolchain confirmed: **deno 2.9.0**, bun 1.3.11, pnpm 11.2.1, node 24, dofigen 2.8.0. - -1. ✅ **`Deno.serve` + Hono compile/serve.** Compiled, served, `/ping`→200, embedded asset - read via `Deno.readTextFile(new URL(...))`. **Correction: the flag is `--include`, not - `--include-as-is`** (the latter does not exist in 2.9). -2. ✅ **libSQL native addon under `deno compile` — make-or-break, PASSED with a bonus.** - `deno compile` **embeds the native addon into the binary** (10.7MB) and the binary runs from - a clean dir with **no node_modules**. **Consequence: the workflows `docker` + `libsql` - side-car stages are no longer needed** (they existed only because `bun build --compile` - could not embed native addons). One caveat for the real monorepo build: `--node-modules-dir=manual` - against the giant shared `node_modules` hangs (tries to embed everything) — use deno's - managed npm resolution / `--exclude-unused-npm` so only reachable packages embed. Final flag - combo to be settled in Phase 5 against the real Docker build. -3. ⏳ **Test stack interop** — validated at the start of Phase 2 by migrating one real route - test (faster than a synthetic spike): `@std/expect` matchers, `toHaveBeenCalled*` vs - `@std/testing/mock` spies (else `assertSpyCalls`), `expect.extend`, `stub` on `tb` getters + - `globalThis.fetch`, `FakeTime`. -4. ⏳ **`deno install` on the repo** — done carefully in Phase 3 (it may rewrite manifests and - re-layout `node_modules`, which would disrupt the in-progress pnpm-based work), in an - isolated copy first. - ---- - -## ✅ RESOLVED — deep workspace imports: exports maps + sloppy (no deno.json) - -**Solution (verified under `deno run` + `deno compile` + bun):** add an `exports` map to the -4 deep-imported packages (`@openstatus/db`, `@openstatus/api`, `@openstatus/emails`, -`@openstatus/tracker`) and pass `--unstable-sloppy-imports` on every deno command. The exports -map crosses the package boundary (sloppy can't); sloppy resolves the relative extensionless -imports inside packages. **No deno.json. 4 package.json touched, not 512 imports.** - -Exports map shape (per package), covering the 36 distinct targets (29 files, 7 dirs all in db): - -```jsonc -"exports": { - ".": "./src/index.ts", - "./env.mjs": "./env.mjs", // db only (non-src deep import) - "./src/schema": "./src/schema/index.ts", // + the 6 other directory targets - "./src/client": "./src/client.tsx", // .tsx files need explicit entries - "./src/*": "./src/*.ts" // wildcard handles the .ts files -} -``` - -Every deno invocation (`test`/`compile`/`check`/`run`) must include `--unstable-sloppy-imports`. - -### Original investigation (kept for context) - -The codebase has **512 bare deep-subpath imports across 400 files** of the form -`@openstatus/db/src/schema/constants` (also `@openstatus/api/src/*`, `@openstatus/emails/src/*`, -`@openstatus/tracker/src/*`). Targets are a **mix of `.ts` files, `.tsx` files, and directories** -(`@openstatus/db/src/schema` is a dir with `index.ts`). Verified facts (Deno 2.9.0 experiments): - -- **`--unstable-sloppy-imports` resolves *relative* extensionless imports** (incl. dir-index and - `.tsx`) for `deno run`/`compile`/`test`. ✅ -- It does **NOT** resolve **bare cross-package** deep subpaths — those go through node_modules - package resolution where sloppy does not apply. Fails for run/compile/test (works only for the - lenient `deno check` TS resolver). ❌ — true even in Deno workspace mode (`deno install`). -- **Explicit extension** (`@openstatus/db/src/schema/constants.ts`) resolves under both Deno and - bun — but directory imports still need `/index.ts`, and it risks the Next.js apps (turbopack/tsc). -- **`exports` map** with a `./src/*` wildcard handles `.ts` files but **not** the mixed - dir/`.tsx` cases reliably (Deno does not fall through exports fallback arrays on a missing file). -- **deno.json import map** prefix (`"@openstatus/db/src/": "./packages/db/src/"`) + sloppy - **resolves ALL cases** (file `.ts`/`.tsx` + dir-index) for run **and** compile. ✅ — but it is a - `deno.json`, which the user asked to avoid. - -**This is a hard fork:** the only clean, complete fix is a 4-entry `deno.json` import map, which -collides with the "no deno.json" preference ([[feedback-no-deno-json]]). Awaiting a decision (see -chat) before proceeding with Phase 2+. Everything below assumes that decision is made. - -## Implementation findings (verified during execution) - -- **`@/*` tsconfig path alias** — Deno doesn't read tsconfig `paths`. 153 `@/…` imports across - 113 files in `apps/server` rewritten to **relative paths** (codemod). workflows uses none. ✅ -- **`deno install` foundation** — works, with one workaround: it **crashes seeding `deno.lock` - from `pnpm-lock.yaml`** on a pnpm alias (`string-width-cjs@string-width@4.2.3`). Fix: move - `pnpm-lock.yaml` aside during `deno install` so Deno resolves fresh, then restore it. Deno - migrates the **catalog into root `package.json`** (not deno.json) and writes `deno.lock`. - After install, the full server graph resolves (deep imports + `zod` + `hono`). ✅ -- **`@std/expect` `toHaveBeenCalled*` does NOT accept `@std/testing/mock` spies** (verified: - "Received function must be a mock or spy function"). → the ~187 `toHaveBeenCalled*` sites must - use **`assertSpyCalls`/`assertSpyCall`** instead. Basic `expect`, `expect.extend` custom - matchers, and `FakeTime` all work. ⚠ (more test rework than planned) -- **✅ `deno compile` of `apps/server` WORKS in a clean Docker container** — the local 12-min - hang was the **polluted local node_modules** (Deno-managed mix + broken `.next` symlinks + - every app's deps). In Docker with a **scoped `pnpm install --filter @openstatus/server...`** - (20.8s) then `deno compile --node-modules-dir=manual`, the binary builds fast and **runs**: - `/ping`→200, `/openapi.yaml`→embedded asset, full app graph boots ("Listening on :3000"). - - **Winning build recipe** (`apps/server/Dockerfile.deno-test`): node:24-slim → `pnpm install - --prod --frozen-lockfile --filter @openstatus/server...` → denoland/deno:2.9.0 → `deno - compile -A --no-check --unstable-sloppy-imports --node-modules-dir=manual --include - static/openapi.yaml --include static/openapi-v1.json --output app src/serve.ts` → debian - runtime with just the binary. - - **No `deno install`** in the build — pnpm install (scoped) is what produces node_modules; - Deno reads the catalog from root `package.json` (migrated once) + consumes pnpm's layout. - This sidesteps `deno install`'s whole-monorepo install + the pnpm-alias lockfile crash. - - Catalog must be present in root `package.json` for Deno to resolve `catalog:` specifiers. - - Sandbox note: needed `docker build --network=host` here (flaky build-network); normal CI ok. - - Image 495MB (debian + binary). Could slim further later. -- **✅ `apps/workflows` also builds in Docker** (same recipe, `--filter @openstatus/workflows...`, - 465MB) and **embeds the libSQL native addon** (no side-car). Verified the binary executes (it - reaches the embedded-replica `createClient` and opens the sync connection). Full boot needs a - real Turso `DATABASE_URL` — in the sandbox it blocks in SYN_SENT to an unreachable sync URL at - module load (the `createClient` runs before logging, so no logs appear). Not a build defect. -- **⚠ `@sentry/bun` → `@sentry/deno`** — workflows used `@sentry/bun` (bun-only; hangs under - Deno) in `index.ts`, `lib/sentry.ts`, `cron/index.ts`. Swapped all three to `@sentry/deno` - (`10.61.0`, API-compatible: `init`/`captureException`/`captureMessage`/`captureCheckIn`/`flush`), - updated `package.json` + `pnpm-lock.yaml`. The server uses `@hono/sentry` (unaffected). -- **⚠ embedded-replica `createClient` blocks at module load** until the sync URL connects — so - the workflows process won't serve `/ping` until the DB is reachable. Pre-existing behavior - (bun did the same); flagged for prod startup robustness. - -## Phase 2 — Test migration — 🔶 IN PROGRESS - -- ✅ `@openstatus/test-utils` package built + validated: re-exports `node:test` runner with a - Bun-compat **`.each`** shim, `@std/expect` `expect` extended with the ~12 **bun-only matchers** - (`toBeNumber`, `toContainValue`, …), and `@std/testing/mock` (`spy`/`stub`/`assertSpyCalls`) + - `@std/testing/time` (`FakeTime`). Uses `jsr:@std/*` so only Deno needs them. -- ✅ Codemod swapped `bun:test` → `@openstatus/test-utils` in **194 files**; updated 21+ - `package.json` (`deno test` script, test-utils devDep, dropped `@types/bun`/`bun-types`); - removed `bunfig.toml`. -- ✅ **`@/*` alias → relative** rewrite: server (153), status-page (211), web (332). Deno - ignores tsconfig paths. -- ✅ **Import-only suites PASS under `deno test`**: header-analysis (7), status-page (51), web - (23). Mock pattern validated: discord + 5 more notifications PASS. -- 🔶 **Remaining mock work (~47 files)**: `@std/expect` `toHaveBeenCalled*` does NOT accept std - spies → use `assertSpyCalls`. Per-file quirks remain: 6 notifications (webhook double-stub, - bird-whatsapp `jest`, slack/grafana call-count-after-restub), importers clients, status-fetcher, - tracker (`FakeTime`), subscriptions/api/server (**`mock.module` → stub + default-param DI**, - and these are **DB-integration tests needing a running libSQL to verify**). -- ⏳ snapshots (`toMatchSnapshot` → `@std/testing/snapshot`) + type tests (`expectTypeOf` → - `expect-type`) not started. - -## Phase 1 — Source changes — ✅ DONE - -- ✅ split `index.ts`/`serve.ts` (both apps); server static asset → `Deno.readTextFile`. -- ✅ `Bun.*` → `Deno.copyFile` in `apps/server/env.ts`, `packages/db/env.ts`. -- ✅ `migrate`/`seed`/`env` scripts + `start.sh` → `deno run -A`; app `dev`/`start`/`test` → deno. - -(Detail of the changes below.) - -### Entrypoint split (both apps) - -`index.ts`: keep `export const app = new Hono(...)`, **remove** `const server = {...}` + -`export default server`. New `serve.ts`: - -```ts -import { app } from "./index"; -import { env } from "./env"; -Deno.serve({ port: env.PORT ?? 3000 }, app.fetch); -``` - -`serve.ts` is the `deno compile` target. Tests still import `app` with no server side-effect. - -### Server static asset (`apps/server/src/index.ts:22`) - -Drop `import openapiYaml … with { type: "text" }`. Embed via `--include-as-is` (Phase 4) and -read at startup: - -```ts -const openapiYaml = await Deno.readTextFile(new URL("../static/openapi.yaml", import.meta.url)); -``` - -JSON imports (`with { type: "json" }`) stay — Deno supports them. - -### `Bun.*` → Deno APIs (dev/build scripts) - -`packages/db/env.ts`, `apps/server/env.ts`: `Bun.file(p).text()/.json()` → -`Deno.readTextFile(p)` (+ `JSON.parse`); `Bun.write(p, s)` → `Deno.writeTextFile(p, s)`. -(`apps/workflows/src/build-docker.ts` is deleted in Phase 5 — no port needed.) - -### migrate / `start.sh` - -`packages/db/package.json`: `"migrate": "deno run -A src/migrate.mts"`, -`"seed": "deno run -A src/seed.mts"`, `"env": "deno run -A env.ts"`. Keep `start.sh`; change -`bun src/migrate.mts` → `deno run -A src/migrate.mts`. - ---- - -## Phase 2 — Test migration (`bun:test` → `node:test` + `@std/expect`, `deno test`) - -Surface: **~270 files**, ~2920 `expect` assertions, ~150 bun-only matchers, 47 `mock` / -21 `spyOn` / 10 `setSystemTime` / 6 `jest.*`, 4 `mock.module` seams (+ dead `node-fetch`), -12 snapshot files, 10 type-test files. - -### Step 0 — `@openstatus/test-utils` package (Decision 7) - -``` -packages/test-utils/ - src/setup.ts # registers expect.extend matchers; installs the global fetch stub helper - src/matchers.ts # the ~150 bun-only matchers (toBeNumber, toContainValue, toBeString, …) - src/fakes/ # tinybird.ts, redis.ts, subscriptions.ts — shared test doubles -``` - -Each tester adds `@openstatus/test-utils` as a devDependency; every test file imports -`@openstatus/test-utils/setup` **first** (codemod injects). - -### Step A — codemod (`ts-morph`/`jscodeshift`, ~270 files) - -Per file: replace the `bun:test` import with `node:test` + `@std/expect`, alias -`beforeAll→before`/`afterAll→after`, and inject `import "@openstatus/test-utils/setup";` as -the first import. `expect(...)` bodies untouched. - -### Step B — bun-only matchers - -Implemented once in `@openstatus/test-utils` via `expect.extend` (verified in Phase 0 spike 3). -`pass()`/`fail()` helpers → explicit `expect(...)` assertions in the few sites that use them. - -### Step C — mocks (`@std/testing/mock` + `@std/testing/time`) - -`mock(fn)`→`spy(fn)`; `spyOn(o,"m")`→`using s = spy(o,"m")` / `stub(o,"m",impl)`; sequential -returns→`returnsNext`; `setSystemTime`→`using t = new FakeTime(date)` + `t.tick`. Prefer -`using` (auto-restore) — deletes most `afterEach` teardown. Keep `toHaveBeenCalled*` if Phase-0 -interop holds, else `assertSpyCalls`/`assertSpyCall`. - -### Step D — module mocks (hybrid; Decisions 6 + 8) - -- **stub-able** → `@std/testing/mock` `stub`, fakes from `@openstatus/test-utils/fakes`: - `tb`/`redis` (`@/libs/clients` singletons), `Redis.fromEnv` (`@openstatus/upstash`). -- **global fetch** → `stub(globalThis, "fetch", …)`; **delete** every `mock.module("node-fetch")`. -- **DI (default-param)** → `dispatchMaintenanceUpdate`, `dispatchStatusReportUpdate` - (`maintenances/post.ts`, `statusReports/post.ts`), `getChannel` - (`rpc/handlers/status-page/index.ts`): add `deps = { … }` last param; tests pass fakes. -- The old global `preload.ts` is deleted; its four mocks move to the above mechanisms. - -### Step E — preload replacement - -`bunfig.toml` preload is gone; the `@openstatus/test-utils/setup` import (Step A) replaces it. -Import ordering: setup first, then the SUT. - -### Step F — snapshots + type tests - -Snapshots → `@std/testing/snapshot` `assertSnapshot(t, value)` (regenerate + diff the 12 -files). Type tests → `expect-type` (`expectTypeOf().toEqualTypeOf()`), validated by -`deno check` where in scope (the two apps). - -### Step G — invocation - -Each package/app `"test": "deno test -A"`. Pull `@std/expect`, `@std/testing`, `expect-type` -via `jsr add`/devDeps so pnpm install resolves them. Remove `bunfig.toml`, `bun-types`, -`@types/bun`. - ---- - -## Phase 3 — Install via `deno install` (Docker, server + workflows) - -Deno 2.9 reads `pnpm-workspace.yaml` catalogs (482 `catalog:` refs) + workspace globs -(244 `workspace:*`) and seeds `deno.lock` from `pnpm-lock.yaml`. dofigen `install` stage: - -```yaml - install: - fromImage: denoland/deno:2.9.0 - workdir: /app/ - env: - DENO_NODE_MODULES_DIR: auto # hoisted layout for compile + libsql side-car - bind: - - pnpm-workspace.yaml # catalog + workspace source of truth - - pnpm-lock.yaml - - deno.lock - - package.json - - …all workspace package.json (same bind list as today)… - run: deno install --prod --frozen --allow-scripts - cache: - - /deno-dir -``` - -`pnpm-workspace.yaml` stays authoritative (Decision 12); commit `deno.lock`; do **not** commit -any catalog/`deno.json` that 2.9 may emit. Verify (Phase 0 spike 4) the migration write stays -additive so pnpm keeps working for the other apps. - ---- - -## Phase 4 — `apps/server/dofigen.yml` (build) - -`build` stage → Deno + `deno compile` (target `serve.ts`). No libsql side-car (HTTP driver). - -```yaml - build: - fromImage: denoland/deno:2.9.0 - workdir: /app/apps/server - env: { NODE_ENV: production } - copy: - - . /app/ - - { fromBuilder: install, source: /app/node_modules, target: /app/node_modules } - - { fromBuilder: install, source: /app/apps/server/node_modules, target: /app/apps/server/node_modules } - - { fromBuilder: install, source: /app/packages, target: /app/packages } - run: >- - deno compile -A --no-check --node-modules-dir - --include static/openapi.yaml --include static/openapi-v1.json - --output app serve.ts -``` - -`--no-check` keeps compile fast (`deno check` is the typecheck gate, Decision 10). Optionally -benchmark experimental `--bundle` for a smaller binary. Runtime copy `/app/apps/server/app` → -`/bin/app` unchanged. - ---- - -## Phase 5 — `apps/workflows/dofigen.yml` (build) — side-car DROPPED - -Spike 2 proved `deno compile` **embeds** the libSQL native addon into the binary, so the whole -side-car apparatus goes away: - -1. **`build`** → `deno compile -A --no-check --output app serve.ts`. Settle the npm-embed flags - here (`--exclude-unused-npm` / managed npm) so it embeds reachable packages, not the whole - `node_modules` (spike 2 caveat). -2. **DELETE the `docker` stage** (`build-docker.ts` existed only to generate the side-car - `package.json`) and **DELETE the `libsql` stage**. -3. **`build-docker.ts`** itself becomes dead code → remove (its sole purpose was the side-car). -4. **runtime copy** → just the self-contained `app` binary. No `node_modules` copied at all. - -This makes the workflows runtime image dramatically simpler (binary only, like server). - ---- - -## Phase 6 — CI - -- `test.yml` + `migrate.yml`: replace `oven-sh/setup-bun` with `denoland/setup-deno@v2` - (Deno 2.9). **Keep `pnpm install`** (Decision 13), the libsql service, migrate, seed. - `pnpm test` → turbo → per-package `deno test -A` (Decision 14). -- Add a **`deno check`** step for `apps/server` + `apps/workflows` (src + tests) replacing the - server `tsc` step (Decision 10). -- **Parity gate** (Decision 16): a CI step records the base-commit `bun test` total pass count - (artifact / committed baseline number), then asserts `deno test`'s pass count ≥ baseline. -- docker-publish workflows exercise `deno install` + `deno compile` via the Dockerfiles. - ---- - -## Phase 7 — Verify & ship - -Per app: `dofigen generate`; `docker buildx build -f apps//Dockerfile .` from repo root; -run, `GET /ping` → 200; server `GET /openapi.yaml` → body; workflows embedded replica syncs + -a cron endpoint responds. Locally: `pnpm install && pnpm migrate && pnpm seed && pnpm test` -green; parity count ≥ baseline; `deno check` clean for the two apps. Watch Fly RSS/OOM on -workflows after deploy (Deno V8 heap defaults differ from bun — see `research.md`). - ---- - -## Risks - -| Risk | Mitigation | -|------|-----------| -| ~~libSQL native addon won't `deno compile`~~ | ✅ RESOLVED (spike 2): deno embeds the addon; side-car dropped | -| Big-bang PR hides a regression / silent skip | Parity gate (16); split into logical commits within the one PR for bisect | -| `@std/expect` `toHaveBeenCalled*` ✗ interop with `@std/testing/mock` spies | Phase-0 spike 3; fallback `assertSpyCalls`/`assertSpyCall` | -| `deno install` rewrites manifests / breaks pnpm for other apps | Phase-0 spike 4; keep `pnpm-workspace.yaml` authoritative, don't commit deno catalog | -| `deno check` surfaces new diagnostics vs `tsc` | Scoped to two apps (10); fix as part of the PR | -| ~270-file codemod churn | AST codemod (18) + parity gate; hand-fix the ~60-file residue | -| `stub` can't reach `tb` getter methods | Phase-0 spike 3; fallback = make `tb`/`redis` injectable like the dispatch seams | - ---- - -## TODO - -- [ ] **Phase 0** spikes: serve+compile · libsql-compile (workflows) · test-stack interop · `deno install` -- [ ] Phase 1: split `index.ts`/`serve.ts` (both) · server static asset · `Bun.*`→Deno · migrate/seed/`start.sh`→deno -- [ ] Phase 2.0: create `@openstatus/test-utils` (matchers, setup, fakes) -- [ ] Phase 2.A: codemod imports + lifecycle + setup-inject (~270 files) -- [ ] Phase 2.B–C: matchers via `expect.extend`; mocks → `@std/testing/mock`/`time` -- [ ] Phase 2.D: hybrid module mocks — stub `tb`/`redis`/`Redis.fromEnv` + `globalThis.fetch`; DI `dispatch*`/`getChannel`; delete `node-fetch` mocks + `preload.ts` -- [ ] Phase 2.F: snapshots → `@std/testing/snapshot`; type tests → `expect-type` -- [ ] Phase 2.G: `"test": "deno test -A"` everywhere; add JSR devDeps; remove `bunfig.toml`/`bun-types` -- [ ] Phase 3: `deno install` stage (both dofigen); commit `deno.lock` -- [ ] Phase 4: `apps/server` build → `deno compile` (serve.ts, `--include-as-is`) -- [ ] Phase 5: `apps/workflows` build → `deno compile`; `build-docker.ts`→deno; `libsql` stage→npm -- [ ] Phase 6: CI `setup-deno`, keep `pnpm install`, `deno check` (2 apps), parity gate -- [ ] Phase 7: `dofigen generate` + docker build + verify each app; ship; watch Fly RSS -- [ ] Update CLAUDE.md memory note "use bun test directly" → `deno test` - diff --git a/apps/workflows/docker-compose.yaml b/apps/workflows/docker-compose.yaml index 101f38ef..6eff4522 100644 --- a/apps/workflows/docker-compose.yaml +++ b/apps/workflows/docker-compose.yaml @@ -4,9 +4,14 @@ services: build: context: ../.. dockerfile: apps/workflows/Dockerfile - env_file: - - ../../.env.docker - + environment: + - DATABASE_URL=http://host.docker.internal:8081 + - DATABASE_AUTH_TOKEN=test + - RESEND_API_KEY=test + - UPSTASH_REDIS_REST_URL=test + - UPSTASH_REDIS_REST_TOKEN=test + - NODE_ENV=production + - GCP_PROJECT_ID=test extra_hosts: - "host.docker.internal:host-gateway" diff --git a/apps/workflows/dofigen.lock b/apps/workflows/dofigen.lock index c143f676..cb7e8ab9 100644 --- a/apps/workflows/dofigen.lock +++ b/apps/workflows/dofigen.lock @@ -12,127 +12,122 @@ effective: | - /packages/error - /packages/tracker builders: + docker: + fromImage: + path: oven/bun + digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + label: + org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 + workdir: /app/apps/workflows + copy: + - paths: + - . + target: /app/ + run: + - bun run src/build-docker.ts install: fromImage: path: node - digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc + digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf label: - org.opencontainers.image.base.digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc org.opencontainers.image.stage: install org.opencontainers.image.base.name: docker.io/node:24-slim + org.opencontainers.image.base.digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf workdir: /app/ - copy: - - paths: - - pnpm-workspace.yaml - target: /app/pnpm-workspace.yaml - - paths: - - pnpm-lock.yaml - target: /app/pnpm-lock.yaml - - paths: - - package.json - target: /app/package.json - - paths: - - apps/workflows/package.json - target: /app/apps/workflows/package.json - - paths: - - packages/assertions/package.json - target: /app/packages/assertions/package.json - - paths: - - packages/db/package.json - target: /app/packages/db/package.json - - paths: - - packages/emails/package.json - target: /app/packages/emails/package.json - - paths: - - packages/notifications/base/package.json - target: /app/packages/notifications/base/package.json - - paths: - - packages/notifications/discord/package.json - target: /app/packages/notifications/discord/package.json - - paths: - - packages/notifications/email/package.json - target: /app/packages/notifications/email/package.json - - paths: - - packages/notifications/grafana-oncall/package.json - target: /app/packages/notifications/grafana-oncall/package.json - - paths: - - packages/notifications/google-chat/package.json - target: /app/packages/notifications/google-chat/package.json - - paths: - - packages/notifications/ms-teams/package.json - target: /app/packages/notifications/ms-teams/package.json - - paths: - - packages/notifications/ntfy/package.json - target: /app/packages/notifications/ntfy/package.json - - paths: - - packages/notifications/opsgenie/package.json - target: /app/packages/notifications/opsgenie/package.json - - paths: - - packages/notifications/pagerduty/package.json - target: /app/packages/notifications/pagerduty/package.json - - paths: - - packages/notifications/slack/package.json - target: /app/packages/notifications/slack/package.json - - paths: - - packages/notifications/telegram/package.json - target: /app/packages/notifications/telegram/package.json - - paths: - - packages/notifications/bird-whatsapp/package.json - target: /app/packages/notifications/bird-whatsapp/package.json - - paths: - - packages/notifications/twillio-sms/package.json - target: /app/packages/notifications/twillio-sms/package.json - - paths: - - packages/notifications/webhook/package.json - target: /app/packages/notifications/webhook/package.json - - paths: - - packages/importers/package.json - target: /app/packages/importers/package.json - - paths: - - packages/regions/package.json - target: /app/packages/regions/package.json - - paths: - - packages/services/package.json - target: /app/packages/services/package.json - - paths: - - packages/subscriptions/package.json - target: /app/packages/subscriptions/package.json - - paths: - - packages/utils/package.json - target: /app/packages/utils/package.json - - paths: - - packages/tsconfig/package.json - target: /app/packages/tsconfig/package.json - - paths: - - packages/tinybird/package.json - target: /app/packages/tinybird/package.json - - paths: - - packages/upstash/package.json - target: /app/packages/upstash/package.json - - paths: - - packages/theme-store/package.json - target: /app/packages/theme-store/package.json - - paths: - - packages/locales/package.json - target: /app/packages/locales/package.json - - paths: - - packages/status-fetcher/package.json - target: /app/packages/status-fetcher/package.json run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose + - pnpm install --prod --frozen-lockfile --verbose cache: - - id: s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store - target: /root/.local/share/pnpm/store - sharing: locked + - target: /root/.local/share/pnpm/store + bind: + - target: pnpm-workspace.yaml + source: pnpm-workspace.yaml + - target: pnpm-lock.yaml + source: pnpm-lock.yaml + - target: package.json + source: package.json + - target: apps/workflows/package.json + source: apps/workflows/package.json + - target: packages/assertions/package.json + source: packages/assertions/package.json + - target: packages/db/package.json + source: packages/db/package.json + - target: packages/emails/package.json + source: packages/emails/package.json + - target: packages/notifications/base/package.json + source: packages/notifications/base/package.json + - target: packages/notifications/discord/package.json + source: packages/notifications/discord/package.json + - target: packages/notifications/email/package.json + source: packages/notifications/email/package.json + - target: packages/notifications/grafana-oncall/package.json + source: packages/notifications/grafana-oncall/package.json + - target: packages/notifications/google-chat/package.json + source: packages/notifications/google-chat/package.json + - target: packages/notifications/ms-teams/package.json + source: packages/notifications/ms-teams/package.json + - target: packages/notifications/ntfy/package.json + source: packages/notifications/ntfy/package.json + - target: packages/notifications/opsgenie/package.json + source: packages/notifications/opsgenie/package.json + - target: packages/notifications/pagerduty/package.json + source: packages/notifications/pagerduty/package.json + - target: packages/notifications/slack/package.json + source: packages/notifications/slack/package.json + - target: packages/notifications/telegram/package.json + source: packages/notifications/telegram/package.json + - target: packages/notifications/bird-whatsapp/package.json + source: packages/notifications/bird-whatsapp/package.json + - target: packages/notifications/twillio-sms/package.json + source: packages/notifications/twillio-sms/package.json + - target: packages/notifications/webhook/package.json + source: packages/notifications/webhook/package.json + - target: packages/importers/package.json + source: packages/importers/package.json + - target: packages/regions/package.json + source: packages/regions/package.json + - target: packages/services/package.json + source: packages/services/package.json + - target: packages/subscriptions/package.json + source: packages/subscriptions/package.json + - target: packages/utils/package.json + source: packages/utils/package.json + - target: packages/tsconfig/package.json + source: packages/tsconfig/package.json + - target: packages/tinybird/package.json + source: packages/tinybird/package.json + - target: packages/upstash/package.json + source: packages/upstash/package.json + - target: packages/theme-store/package.json + source: packages/theme-store/package.json + - target: packages/locales/package.json + source: packages/locales/package.json + - target: packages/status-fetcher/package.json + source: packages/status-fetcher/package.json + libsql: + fromImage: + path: oven/bun + digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + label: + org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 + org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + workdir: /app/ + copy: + - fromBuilder: docker + paths: + - /app/apps/build-docker/package.json + target: /app/package.json + run: + - bun install --production build: fromImage: - path: denoland/deno - digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + path: oven/bun + digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 label: - org.opencontainers.image.base.name: docker.io/denoland/deno:2.9.0 + org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 org.opencontainers.image.stage: build - org.opencontainers.image.base.digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 workdir: /app/apps/workflows env: NODE_ENV: production @@ -153,28 +148,19 @@ effective: | - /app/packages target: /app/packages run: - - mkdir -p /tmp/sc - - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' - - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts - - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts - - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs - - mkdir -p /app/data + - bun build --compile --target bun --sourcemap src/index.ts --outfile=app fromImage: - host: registry.access.redhat.com - port: 443 - path: hi/curl - digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + path: debian + digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 label: - io.dofigen.version: 2.8.0 - org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus org.opencontainers.image.authors: OpenStatus Team - org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus - org.opencontainers.image.base.digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + org.opencontainers.image.base.digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 org.opencontainers.image.title: OpenStatus Workflows - user: - user: '1000' - group: '1000' + org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus + org.opencontainers.image.base.name: docker.io/debian:bullseye-slim + io.dofigen.version: 2.8.0 + org.opencontainers.image.vendor: OpenStatus workdir: /app/ copy: - fromBuilder: build @@ -182,33 +168,37 @@ effective: | - /app/apps/workflows/app target: /app/apps/workflows/ chmod: '555' - - fromBuilder: build + - fromBuilder: libsql paths: - - /app/data - target: /app/data + - /app/node_modules + target: /app/packages/db/node_modules + - fromBuilder: libsql + paths: + - /app/node_modules + target: /app/node_modules + root: + run: + - apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data entrypoint: - /app/apps/workflows/app expose: - port: 3000 - healthcheck: - cmd: '["curl", "-f", "http://localhost:3000/ping"]' - interval: 1m - timeout: 10s - start: 30s - retries: 3 images: docker.io: - denoland: - deno: - 2.9.0: - digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 library: node: 24-slim: - digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc + digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf + debian: + bullseye-slim: + digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 + oven: + bun: + 1.3.11: + digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 resources: dofigen.yml: - hash: c478b25a43ff0cfbc6114251b800a544357c64a503b8ac64805e1077f559c3de + hash: 9ad08ee36ff20abe093e58fc36235d056b6ed3e22b8ae2f3fb30399e34cdaebe content: | ignore: - node_modules @@ -228,57 +218,50 @@ resources: workdir: /app/ labels: org.opencontainers.image.stage: install - # Railway's builder rejects --mount=type=bind (only type=cache is supported), so copy the - # manifests into the layer instead of bind-mounting them. Per-file targets preserve the - # workspace directory structure (multi-source COPY into a dir would flatten the paths). - copy: - - pnpm-workspace.yaml /app/pnpm-workspace.yaml - - pnpm-lock.yaml /app/pnpm-lock.yaml - - package.json /app/package.json - - apps/workflows/package.json /app/apps/workflows/package.json - - packages/assertions/package.json /app/packages/assertions/package.json - - packages/db/package.json /app/packages/db/package.json - - packages/emails/package.json /app/packages/emails/package.json - - packages/notifications/base/package.json /app/packages/notifications/base/package.json - - packages/notifications/discord/package.json /app/packages/notifications/discord/package.json - - packages/notifications/email/package.json /app/packages/notifications/email/package.json - - packages/notifications/grafana-oncall/package.json /app/packages/notifications/grafana-oncall/package.json - - packages/notifications/google-chat/package.json /app/packages/notifications/google-chat/package.json - - packages/notifications/ms-teams/package.json /app/packages/notifications/ms-teams/package.json - - packages/notifications/ntfy/package.json /app/packages/notifications/ntfy/package.json - - packages/notifications/opsgenie/package.json /app/packages/notifications/opsgenie/package.json - - packages/notifications/pagerduty/package.json /app/packages/notifications/pagerduty/package.json - - packages/notifications/slack/package.json /app/packages/notifications/slack/package.json - - packages/notifications/telegram/package.json /app/packages/notifications/telegram/package.json - - packages/notifications/bird-whatsapp/package.json /app/packages/notifications/bird-whatsapp/package.json - - packages/notifications/twillio-sms/package.json /app/packages/notifications/twillio-sms/package.json - - packages/notifications/webhook/package.json /app/packages/notifications/webhook/package.json - - packages/importers/package.json /app/packages/importers/package.json - - packages/regions/package.json /app/packages/regions/package.json - - packages/services/package.json /app/packages/services/package.json - - packages/subscriptions/package.json /app/packages/subscriptions/package.json - - packages/utils/package.json /app/packages/utils/package.json - - packages/tsconfig/package.json /app/packages/tsconfig/package.json - - packages/tinybird/package.json /app/packages/tinybird/package.json - - packages/upstash/package.json /app/packages/upstash/package.json - - packages/theme-store/package.json /app/packages/theme-store/package.json - - packages/locales/package.json /app/packages/locales/package.json - - packages/status-fetcher/package.json /app/packages/status-fetcher/package.json + bind: + - pnpm-workspace.yaml + - pnpm-lock.yaml + - package.json + - apps/workflows/package.json + - packages/assertions/package.json + - packages/db/package.json + - packages/emails/package.json + - packages/notifications/base/package.json + - packages/notifications/discord/package.json + - packages/notifications/email/package.json + - packages/notifications/grafana-oncall/package.json + - packages/notifications/google-chat/package.json + - packages/notifications/ms-teams/package.json + - packages/notifications/ntfy/package.json + - packages/notifications/opsgenie/package.json + - packages/notifications/pagerduty/package.json + - packages/notifications/slack/package.json + - packages/notifications/telegram/package.json + - packages/notifications/bird-whatsapp/package.json + - packages/notifications/twillio-sms/package.json + - packages/notifications/webhook/package.json + - packages/importers/package.json + - packages/regions/package.json + - packages/services/package.json + - packages/subscriptions/package.json + - packages/utils/package.json + - packages/tsconfig/package.json + - packages/tinybird/package.json + - packages/upstash/package.json + - packages/theme-store/package.json + - packages/locales/package.json + - packages/status-fetcher/package.json - # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) + # Install dependencies run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose + - pnpm install --prod --frozen-lockfile --verbose cache: - # Railway scopes cache mounts per service: the id must be literally - # s/- (env vars aren't allowed in the id). - - id: s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store - target: /root/.local/share/pnpm/store - sharing: locked + - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary with Deno) + # Stage 4: Build application (compile to binary) build: - fromImage: denoland/deno:2.9.0 + fromImage: oven/bun:1.3.11 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -293,24 +276,35 @@ resources: - fromBuilder: install source: /app/packages target: /app/packages + # Should set env to production here + # Compile the TypeScript application env: NODE_ENV: production - # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: - # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads - # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, - # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. - run: - - mkdir -p /tmp/sc - - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' - - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts - - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts - - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs - - mkdir -p /app/data + run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app - # Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). - # Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. - fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + docker: + fromImage: oven/bun:1.3.11 + workdir: /app/apps/workflows + copy: + - . /app/ + run: bun run src/build-docker.ts + + libsql: + fromImage: oven/bun:1.3.11 + workdir: /app/ + copy: + - fromBuilder: docker + source: /app/apps/build-docker/package.json + target: /app/package.json + # bun install is hoisted by default -> flat node_modules so the compiled bun binary can + # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile + # is needed (the generated package.json pins one exact version), so a single install does it. + run: bun install --production + + fromImage: debian:bullseye-slim workdir: /app/ + root: + run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -320,25 +314,18 @@ resources: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team - # Copy the self-contained compiled binary (native addon embedded by deno compile) + # Copy artifacts from build stages copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: build - source: /app/data - target: /app/data - - user: "1000:1000" + - fromBuilder: libsql + source: /app/node_modules + target: /app/packages/db/node_modules + - fromBuilder: libsql + source: /app/node_modules + target: /app/node_modules expose: "3000" - # Health check — exec form (JSON array) because the base has no shell for CMD-SHELL - healthcheck: - interval: 1m - timeout: 10s - start: 30s - retries: 3 - cmd: '["curl", "-f", "http://localhost:3000/ping"]' - entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/dofigen.yml b/apps/workflows/dofigen.yml index bfe48b33..89c086dd 100644 --- a/apps/workflows/dofigen.yml +++ b/apps/workflows/dofigen.yml @@ -16,57 +16,50 @@ builders: workdir: /app/ labels: org.opencontainers.image.stage: install - # Railway's builder rejects --mount=type=bind (only type=cache is supported), so copy the - # manifests into the layer instead of bind-mounting them. Per-file targets preserve the - # workspace directory structure (multi-source COPY into a dir would flatten the paths). - copy: - - pnpm-workspace.yaml /app/pnpm-workspace.yaml - - pnpm-lock.yaml /app/pnpm-lock.yaml - - package.json /app/package.json - - apps/workflows/package.json /app/apps/workflows/package.json - - packages/assertions/package.json /app/packages/assertions/package.json - - packages/db/package.json /app/packages/db/package.json - - packages/emails/package.json /app/packages/emails/package.json - - packages/notifications/base/package.json /app/packages/notifications/base/package.json - - packages/notifications/discord/package.json /app/packages/notifications/discord/package.json - - packages/notifications/email/package.json /app/packages/notifications/email/package.json - - packages/notifications/grafana-oncall/package.json /app/packages/notifications/grafana-oncall/package.json - - packages/notifications/google-chat/package.json /app/packages/notifications/google-chat/package.json - - packages/notifications/ms-teams/package.json /app/packages/notifications/ms-teams/package.json - - packages/notifications/ntfy/package.json /app/packages/notifications/ntfy/package.json - - packages/notifications/opsgenie/package.json /app/packages/notifications/opsgenie/package.json - - packages/notifications/pagerduty/package.json /app/packages/notifications/pagerduty/package.json - - packages/notifications/slack/package.json /app/packages/notifications/slack/package.json - - packages/notifications/telegram/package.json /app/packages/notifications/telegram/package.json - - packages/notifications/bird-whatsapp/package.json /app/packages/notifications/bird-whatsapp/package.json - - packages/notifications/twillio-sms/package.json /app/packages/notifications/twillio-sms/package.json - - packages/notifications/webhook/package.json /app/packages/notifications/webhook/package.json - - packages/importers/package.json /app/packages/importers/package.json - - packages/regions/package.json /app/packages/regions/package.json - - packages/services/package.json /app/packages/services/package.json - - packages/subscriptions/package.json /app/packages/subscriptions/package.json - - packages/utils/package.json /app/packages/utils/package.json - - packages/tsconfig/package.json /app/packages/tsconfig/package.json - - packages/tinybird/package.json /app/packages/tinybird/package.json - - packages/upstash/package.json /app/packages/upstash/package.json - - packages/theme-store/package.json /app/packages/theme-store/package.json - - packages/locales/package.json /app/packages/locales/package.json - - packages/status-fetcher/package.json /app/packages/status-fetcher/package.json + bind: + - pnpm-workspace.yaml + - pnpm-lock.yaml + - package.json + - apps/workflows/package.json + - packages/assertions/package.json + - packages/db/package.json + - packages/emails/package.json + - packages/notifications/base/package.json + - packages/notifications/discord/package.json + - packages/notifications/email/package.json + - packages/notifications/grafana-oncall/package.json + - packages/notifications/google-chat/package.json + - packages/notifications/ms-teams/package.json + - packages/notifications/ntfy/package.json + - packages/notifications/opsgenie/package.json + - packages/notifications/pagerduty/package.json + - packages/notifications/slack/package.json + - packages/notifications/telegram/package.json + - packages/notifications/bird-whatsapp/package.json + - packages/notifications/twillio-sms/package.json + - packages/notifications/webhook/package.json + - packages/importers/package.json + - packages/regions/package.json + - packages/services/package.json + - packages/subscriptions/package.json + - packages/utils/package.json + - packages/tsconfig/package.json + - packages/tinybird/package.json + - packages/upstash/package.json + - packages/theme-store/package.json + - packages/locales/package.json + - packages/status-fetcher/package.json - # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) + # Install dependencies run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose + - pnpm install --prod --frozen-lockfile --verbose cache: - # Railway scopes cache mounts per service: the id must be literally - # s/- (env vars aren't allowed in the id). - - id: s/995d9762-a732-446d-808a-498c7c33a8d5-/root/.local/share/pnpm/store - target: /root/.local/share/pnpm/store - sharing: locked + - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary with Deno) + # Stage 4: Build application (compile to binary) build: - fromImage: denoland/deno:2.9.0 + fromImage: oven/bun:1.3.11 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -81,24 +74,35 @@ builders: - fromBuilder: install source: /app/packages target: /app/packages + # Should set env to production here + # Compile the TypeScript application env: NODE_ENV: production - # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: - # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads - # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, - # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. - run: - - mkdir -p /tmp/sc - - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' - - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts - - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts - - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs - - mkdir -p /app/data + run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app + + docker: + fromImage: oven/bun:1.3.11 + workdir: /app/apps/workflows + copy: + - . /app/ + run: bun run src/build-docker.ts -# Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). -# Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. -fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + libsql: + fromImage: oven/bun:1.3.11 + workdir: /app/ + copy: + - fromBuilder: docker + source: /app/apps/build-docker/package.json + target: /app/package.json + # bun install is hoisted by default -> flat node_modules so the compiled bun binary can + # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile + # is needed (the generated package.json pins one exact version), so a single install does it. + run: bun install --production + +fromImage: debian:bullseye-slim workdir: /app/ +root: + run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -108,25 +112,18 @@ labels: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team -# Copy the self-contained compiled binary (native addon embedded by deno compile) +# Copy artifacts from build stages copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: build - source: /app/data - target: /app/data - -user: "1000:1000" + - fromBuilder: libsql + source: /app/node_modules + target: /app/packages/db/node_modules + - fromBuilder: libsql + source: /app/node_modules + target: /app/node_modules expose: "3000" -# Health check — exec form (JSON array) because the base has no shell for CMD-SHELL -healthcheck: - interval: 1m - timeout: 10s - start: 30s - retries: 3 - cmd: '["curl", "-f", "http://localhost:3000/ping"]' - entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/package.json b/apps/workflows/package.json index 522f838f..e92ffa72 100644 --- a/apps/workflows/package.json +++ b/apps/workflows/package.json @@ -1,10 +1,9 @@ { "name": "@openstatus/workflows", "scripts": { - "check": "deno check --sloppy-imports src/serve.ts", - "dev": "NODE_ENV=development deno run -A --watch src/serve.ts", - "start": "NODE_ENV=production deno run -A src/serve.ts", - "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test -A --no-check --sloppy-imports" + "dev": "NODE_ENV=development bun run --hot src/index.ts", + "start": "NODE_ENV=production bun run src/index.ts", + "test": "bun test" }, "dependencies": { "@google-cloud/tasks": "catalog:", @@ -34,11 +33,9 @@ "@openstatus/tinybird": "workspace:*", "@openstatus/upstash": "workspace:*", "@openstatus/utils": "workspace:*", - "@opentelemetry/exporter-logs-otlp-http": "catalog:", "@opentelemetry/resources": "catalog:", - "@opentelemetry/sdk-logs": "catalog:", "@opentelemetry/semantic-conventions": "catalog:", - "@sentry/deno": "catalog:", + "@sentry/bun": "catalog:", "@upstash/qstash": "catalog:", "drizzle-orm": "catalog:", "effect": "catalog:", @@ -47,8 +44,8 @@ "zod": "catalog:" }, "devDependencies": { - "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", + "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/apps/workflows/src/build-docker.ts b/apps/workflows/src/build-docker.ts new file mode 100644 index 00000000..1db9537c --- /dev/null +++ b/apps/workflows/src/build-docker.ts @@ -0,0 +1,81 @@ +import path from "node:path"; + +// Create package.json that contains @libsql/client as dependency. It will be used to create node_modules and copy them alongside compiled server https://github.com/oven-sh/bun/issues/18909 +type PackageJson = Record<"name" | "description" | "version", string> & + Record<"dependencies", Record>; +const packageJson: PackageJson = await Bun.file( + path.join(__dirname, "../../../packages/db", "package.json"), +).json(); + +const extractDependenciesNames = ["@libsql/client"]; +const workspaceConfig = await Bun.file( + path.join(__dirname, "../../../pnpm-workspace.yaml"), +).text(); + +const catalog = (() => { + const lines = workspaceConfig.split(/\r?\n/); + let inCatalog = false; + const entries: Record = {}; + + for (const line of lines) { + if (!inCatalog) { + if (line.trim() === "catalog:") { + inCatalog = true; + } + continue; + } + + if (!line.startsWith(" ")) { + break; + } + + const match = line.match(/^\s{2}("[^"]+"|[^:]+):\s*(.+)$/); + if (!match) { + continue; + } + + const key = match[1].replace(/^"|"$/g, "").trim(); + const value = match[2].replace(/^"|"$/g, "").trim(); + entries[key] = value; + } + + return entries; +})(); + +const resolveVersion = (name: string, spec: string) => { + if (!spec.startsWith("catalog:")) { + return spec; + } + + const resolved = catalog[name]; + if (!resolved) { + throw new Error(`Missing catalog entry for ${name}`); + } + + return resolved; +}; + +const extractedDependencies = extractDependenciesNames.reduce( + (acc, cur) => { + const spec = packageJson.dependencies[cur]; + if (spec) { + acc[cur] = resolveVersion(cur, spec); + } + + return acc; + }, + {} as Record, +); + +const packageJsonBuild = { + name: packageJson.name, + description: packageJson.description, + version: packageJson.version, + // type: "module", + dependencies: extractedDependencies, +}; + +await Bun.write( + "../build-docker/package.json", + JSON.stringify(packageJsonBuild, null, 2), +); diff --git a/apps/workflows/src/checker/alerting.test.ts b/apps/workflows/src/checker/alerting.test.ts index e69ab6c9..0f8bb1ee 100644 --- a/apps/workflows/src/checker/alerting.test.ts +++ b/apps/workflows/src/checker/alerting.test.ts @@ -1,77 +1,95 @@ +import { afterAll, afterEach, describe, expect, mock, test } from "bun:test"; + import { db, eq, inArray } from "@openstatus/db"; import { notification, notificationTrigger, notificationsToMonitors, } from "@openstatus/db/src/schema"; -import { - afterAll, - afterEach, - assertSpyCalls, - beforeEach, - describe, - expect, - type Stub, - stub, - test, -} from "@openstatus/test-utils"; - -import { checkerAudit } from "../utils/audit-log"; -import { triggerNotifications } from "./alerting"; -import { providerToFunction } from "./utils"; - -// Deno has no module mocking, so we stub the methods on the real singletons -// that alerting.ts reads at call time. Stubbing per-test resolves them to no-op -// to avoid real HTTP / Tinybird calls and gives a fresh call count each test. -// biome-ignore lint/suspicious/noExplicitAny: heterogeneous provider stubs -type AnyStub = Stub; -let stubs: AnyStub[] = []; - -const stubSend = ( - provider: "email" | "slack" | "discord", - verb: "sendAlert" | "sendRecovery" | "sendDegraded", -): AnyStub => { - const s = stub(providerToFunction[provider], verb, () => Promise.resolve()); - stubs.push(s); - return s; -}; - -let mockEmailSendAlert: AnyStub; -let mockEmailSendRecovery: AnyStub; -let mockEmailSendDegraded: AnyStub; -let mockSlackSendAlert: AnyStub; -let mockSlackSendRecovery: AnyStub; -let mockSlackSendDegraded: AnyStub; -let mockDiscordSendAlert: AnyStub; -let mockDiscordSendRecovery: AnyStub; -let mockDiscordSendDegraded: AnyStub; + +// Mock audit log to avoid calling Tinybird +mock.module("../utils/audit-log", () => ({ + checkerAudit: { + publishAuditLog: mock(() => Promise.resolve()), + }, +})); + +// Mock notification providers to avoid real HTTP calls +const mockEmailSendAlert = mock(() => Promise.resolve()); +const mockEmailSendRecovery = mock(() => Promise.resolve()); +const mockEmailSendDegraded = mock(() => Promise.resolve()); +const mockSlackSendAlert = mock(() => Promise.resolve()); +const mockSlackSendRecovery = mock(() => Promise.resolve()); +const mockSlackSendDegraded = mock(() => Promise.resolve()); +const mockDiscordSendAlert = mock(() => Promise.resolve()); +const mockDiscordSendRecovery = mock(() => Promise.resolve()); +const mockDiscordSendDegraded = mock(() => Promise.resolve()); + +mock.module("./utils", () => ({ + providerToFunction: { + email: { + sendAlert: mockEmailSendAlert, + sendRecovery: mockEmailSendRecovery, + sendDegraded: mockEmailSendDegraded, + }, + discord: { + sendAlert: mockDiscordSendAlert, + sendRecovery: mockDiscordSendRecovery, + sendDegraded: mockDiscordSendDegraded, + }, + slack: { + sendAlert: mockSlackSendAlert, + sendRecovery: mockSlackSendRecovery, + sendDegraded: mockSlackSendDegraded, + }, + sms: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + webhook: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + telegram: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + pagerduty: { + sendAlert: mock(), + sendRecovery: mock(), + sendDegraded: mock(), + }, + opsgenie: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + ntfy: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + "google-chat": { + sendAlert: mock(), + sendRecovery: mock(), + sendDegraded: mock(), + }, + "grafana-oncall": { + sendAlert: mock(), + sendRecovery: mock(), + sendDegraded: mock(), + }, + "ms-teams": { + sendAlert: mock(), + sendRecovery: mock(), + sendDegraded: mock(), + }, + whatsapp: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, + }, +})); + +// Import after mocks are set up +const { triggerNotifications } = await import("./alerting"); // Seed data has: monitor 1 (workspace 1) linked to notification 1 (email provider) // We use unique cronTimestamp per test to avoid unique constraint conflicts -beforeEach(() => { - stubs = []; - // biome-ignore lint/suspicious/noExplicitAny: avoid Tinybird call - stubs.push( - stub(checkerAudit, "publishAuditLog", () => Promise.resolve()) as AnyStub, - ); - mockEmailSendAlert = stubSend("email", "sendAlert"); - mockEmailSendRecovery = stubSend("email", "sendRecovery"); - mockEmailSendDegraded = stubSend("email", "sendDegraded"); - mockSlackSendAlert = stubSend("slack", "sendAlert"); - mockSlackSendRecovery = stubSend("slack", "sendRecovery"); - mockSlackSendDegraded = stubSend("slack", "sendDegraded"); - mockDiscordSendAlert = stubSend("discord", "sendAlert"); - mockDiscordSendRecovery = stubSend("discord", "sendRecovery"); - mockDiscordSendDegraded = stubSend("discord", "sendDegraded"); -}); - -afterEach(() => { - for (const s of stubs) s.restore(); - stubs = []; -}); - describe("triggerNotifications", () => { + afterEach(() => { + mockEmailSendAlert.mockClear(); + mockEmailSendRecovery.mockClear(); + mockEmailSendDegraded.mockClear(); + mockSlackSendAlert.mockClear(); + mockSlackSendRecovery.mockClear(); + mockSlackSendDegraded.mockClear(); + mockDiscordSendAlert.mockClear(); + mockDiscordSendRecovery.mockClear(); + mockDiscordSendDegraded.mockClear(); + }); + afterAll(async () => { // Clean up notification triggers created during tests await db @@ -94,7 +112,7 @@ describe("triggerNotifications", () => { latency: 1500, }); - assertSpyCalls(mockEmailSendAlert, 1); + expect(mockEmailSendAlert).toHaveBeenCalledTimes(1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -113,7 +131,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - assertSpyCalls(mockEmailSendRecovery, 1); + expect(mockEmailSendRecovery).toHaveBeenCalledTimes(1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -133,7 +151,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - assertSpyCalls(mockEmailSendDegraded, 1); + expect(mockEmailSendDegraded).toHaveBeenCalledTimes(1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -152,7 +170,7 @@ describe("triggerNotifications", () => { cronTimestamp, }); - assertSpyCalls(mockEmailSendAlert, 0); + expect(mockEmailSendAlert).not.toHaveBeenCalled(); expect(result).toHaveLength(0); }); @@ -167,7 +185,7 @@ describe("triggerNotifications", () => { }); expect(first).toHaveLength(1); - assertSpyCalls(mockEmailSendAlert, 1); + mockEmailSendAlert.mockClear(); // Same cronTimestamp should be skipped due to unique constraint const second = await triggerNotifications({ @@ -177,8 +195,7 @@ describe("triggerNotifications", () => { cronTimestamp, }); - // still only the first call — the duplicate was skipped - assertSpyCalls(mockEmailSendAlert, 1); + expect(mockEmailSendAlert).not.toHaveBeenCalled(); expect(second).toHaveLength(0); }); }); @@ -190,6 +207,14 @@ describe("triggerNotifications with multiple providers", () => { // We link slack and discord notifications to it for this test suite. const testMonitorId = 3; + afterEach(() => { + mockEmailSendAlert.mockClear(); + mockSlackSendAlert.mockClear(); + mockDiscordSendAlert.mockClear(); + mockSlackSendRecovery.mockClear(); + mockDiscordSendRecovery.mockClear(); + }); + afterAll(async () => { // Clean up notification triggers await db @@ -257,9 +282,9 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - assertSpyCalls(mockSlackSendAlert, 1); - assertSpyCalls(mockDiscordSendAlert, 1); - assertSpyCalls(mockEmailSendAlert, 0); + expect(mockSlackSendAlert).toHaveBeenCalledTimes(1); + expect(mockDiscordSendAlert).toHaveBeenCalledTimes(1); + expect(mockEmailSendAlert).not.toHaveBeenCalled(); expect(result).toHaveLength(2); expect(result).toContainEqual({ @@ -283,8 +308,8 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - assertSpyCalls(mockSlackSendRecovery, 1); - assertSpyCalls(mockDiscordSendRecovery, 1); + expect(mockSlackSendRecovery).toHaveBeenCalledTimes(1); + expect(mockDiscordSendRecovery).toHaveBeenCalledTimes(1); expect(result).toHaveLength(2); const providers = result.map((r) => r.provider).sort(); diff --git a/apps/workflows/src/cron/checker.ts b/apps/workflows/src/cron/checker.ts index 40dbf7ab..dfdb5b32 100644 --- a/apps/workflows/src/cron/checker.ts +++ b/apps/workflows/src/cron/checker.ts @@ -51,7 +51,7 @@ export const isAuthorizedDomain = (url: string) => { const logger = getLogger("workflow"); const client = new CloudTasksClient({ - fallback: true, + fallback: "rest", projectId: env().GCP_PROJECT_ID, credentials: { client_email: env().GCP_CLIENT_EMAIL, diff --git a/apps/workflows/src/cron/index.ts b/apps/workflows/src/cron/index.ts index 45bd9b6e..9ca25c81 100644 --- a/apps/workflows/src/cron/index.ts +++ b/apps/workflows/src/cron/index.ts @@ -1,5 +1,5 @@ import { monitorPeriodicitySchema } from "@openstatus/db/src/schema/constants"; -import * as Sentry from "@sentry/deno"; +import * as Sentry from "@sentry/bun"; import { Effect, Schedule } from "effect"; import { Hono } from "hono"; diff --git a/apps/workflows/src/index.ts b/apps/workflows/src/index.ts index 9cd13dac..fd186562 100644 --- a/apps/workflows/src/index.ts +++ b/apps/workflows/src/index.ts @@ -8,15 +8,9 @@ import { withContext, } from "@logtape/logtape"; import { getOpenTelemetrySink } from "@logtape/otel"; -import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"; import { resourceFromAttributes } from "@opentelemetry/resources"; -import { - BatchLogRecordProcessor, - LoggerProvider, -} from "@opentelemetry/sdk-logs"; -import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME } from "@opentelemetry/semantic-conventions/incubating"; -import * as Sentry from "@sentry/deno"; +import * as Sentry from "@sentry/bun"; import { Hono } from "hono"; import { showRoutes } from "hono/dev"; import { requestId } from "hono/request-id"; @@ -27,7 +21,7 @@ import { cronRouter } from "./cron"; import { env } from "./env"; import { incidentRoute } from "./incident"; -const { NODE_ENV } = env(); +const { NODE_ENV, PORT } = env(); export type Env = { Variables: { @@ -65,30 +59,18 @@ function shouldSample(event: Record): boolean { return Math.random() < 0.2; } -// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` -// includes it. Letting @logtape/otel create the exporter triggers a dynamic -// import of a bare specifier, which the compiled --node-modules-dir=none binary -// can't resolve. -const loggerProvider = new LoggerProvider({ - resource: resourceFromAttributes({ - [ATTR_SERVICE_NAME]: "openstatus-workflows", +const defaultLogger = getOpenTelemetrySink({ + serviceName: "openstatus-workflows", + otlpExporterConfig: { + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env().AXIOM_TOKEN}`, + "X-Axiom-Dataset": env().AXIOM_DATASET, + }, + }, + additionalResource: resourceFromAttributes({ [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env().NODE_ENV, }), - processors: [ - new BatchLogRecordProcessor( - new OTLPLogExporter({ - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env().AXIOM_TOKEN}`, - "X-Axiom-Dataset": env().AXIOM_DATASET, - }, - }), - ), - ], -}); - -const defaultLogger = getOpenTelemetrySink({ - loggerProvider, }); await configure({ @@ -115,7 +97,7 @@ await configure({ const logger = getLogger(["workflow"]); const otelLogger = getLogger(["workflow-otel"]); -export const app = new Hono({ strict: false }); +const app = new Hono({ strict: false }); app.use("*", requestId()); @@ -200,3 +182,9 @@ app.route("/incident", incidentRoute); if (NODE_ENV === "development") { showRoutes(app, { verbose: true, colorize: true }); } + +logger.info("Starting server", { port: PORT, environment: NODE_ENV }); + +const server = { port: PORT, fetch: app.fetch }; + +export default server; diff --git a/apps/workflows/src/lib/sentry.ts b/apps/workflows/src/lib/sentry.ts index 45e70c55..542d06d2 100644 --- a/apps/workflows/src/lib/sentry.ts +++ b/apps/workflows/src/lib/sentry.ts @@ -1,5 +1,5 @@ import { FetchError } from "@openstatus/status-fetcher"; -import * as Sentry from "@sentry/deno"; +import * as Sentry from "@sentry/bun"; import { env } from "../env"; diff --git a/apps/workflows/src/serve.ts b/apps/workflows/src/serve.ts deleted file mode 100644 index 6f520562..00000000 --- a/apps/workflows/src/serve.ts +++ /dev/null @@ -1,15 +0,0 @@ -/// - -import { getLogger } from "@logtape/logtape"; - -import { env } from "./env"; -import { app } from "./index"; - -const { NODE_ENV, PORT } = env(); - -getLogger(["workflow"]).info("Starting server", { - port: PORT, - environment: NODE_ENV, -}); - -Deno.serve({ port: PORT }, app.fetch); diff --git a/apps/workflows/start.sh b/apps/workflows/start.sh index e24344a2..0c6da27c 100644 --- a/apps/workflows/start.sh +++ b/apps/workflows/start.sh @@ -2,7 +2,7 @@ set -e echo "Running database migrations..." -cd /app/packages/db && deno run -A src/migrate.mts +cd /app/packages/db && bun src/migrate.mts echo "Starting workflows service..." cd /app/apps/workflows diff --git a/apps/workflows/tsconfig.json b/apps/workflows/tsconfig.json index a627827e..9ce54dd0 100644 --- a/apps/workflows/tsconfig.json +++ b/apps/workflows/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "hono/jsx", + "lib": ["ES2022"], "module": "ESNext", "target": "ESNext", "moduleResolution": "bundler" diff --git a/deno.lock b/deno.lock deleted file mode 100644 index 59e89299..00000000 --- a/deno.lock +++ /dev/null @@ -1,277 +0,0 @@ -{ - "version": "5", - "specifiers": { - "jsr:@std/assert@^1.0.19": "1.0.19", - "jsr:@std/async@^1.4.0": "1.4.0", - "jsr:@std/data-structures@^1.1.0": "1.1.0", - "jsr:@std/expect@*": "1.0.19", - "jsr:@std/internal@^1.0.12": "1.0.14", - "jsr:@std/internal@^1.0.13": "1.0.14", - "jsr:@std/path@^1.1.4": "1.1.4", - "jsr:@std/testing@*": "1.0.19" - }, - "jsr": { - "@std/assert@1.0.19": { - "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", - "dependencies": [ - "jsr:@std/internal@^1.0.12" - ] - }, - "@std/async@1.4.0": { - "integrity": "4d70b008634f571cff9b554090d628c76141c32613aae0ff283fd5fa23d0c379" - }, - "@std/data-structures@1.1.0": { - "integrity": "c35ae4ad5d8e41a38573c2fe3e19b18ea2505f63cfea201edcb8720aca1f7f58" - }, - "@std/expect@1.0.19": { - "integrity": "25271785688c7ff902fa54875d6aa4001f552c5578f7f0fefb5b5aac1fc2ed8a", - "dependencies": [ - "jsr:@std/assert", - "jsr:@std/internal@^1.0.13", - "jsr:@std/path" - ] - }, - "@std/internal@1.0.14": { - "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" - }, - "@std/path@1.1.4": { - "integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5", - "dependencies": [ - "jsr:@std/internal@^1.0.12" - ] - }, - "@std/testing@1.0.19": { - "integrity": "f4236172365b216728dc3cc8b5e80a9f4c33083d1e4ede7613d5b25b4014898e", - "dependencies": [ - "jsr:@std/assert", - "jsr:@std/async", - "jsr:@std/data-structures" - ] - } - }, - "workspace": { - "packageJson": { - "dependencies": [ - "npm:turbo@2.9.14" - ] - }, - "members": { - "apps/server": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "apps/status-page": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "apps/web": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/api": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/db": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/emails": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/header-analysis": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/importers": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/base": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/bird-whatsapp": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/discord": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/google-chat": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/grafana-oncall": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/ms-teams": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/ntfy": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/opsgenie": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/pagerduty": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/slack": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/telegram": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/twillio-sms": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/webhook": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/services": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/status-fetcher": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/subscriptions": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/test-utils": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/tracker": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/utils": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - } - } - } -} diff --git a/package.json b/package.json index 995b4fb7..fcf9e3f2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "format": "oxfmt && oxlint --fix", "format:check": "oxfmt --check && oxlint", "lint:turbo": "turbo run lint", - "check": "turbo run check", "dev:web": "turbo run dev --filter='./apps/web' --filter='./packages/db'", "dev:status-page": "turbo run dev --filter='./apps/status-page' --filter='./packages/db'", "dev:dashboard": "turbo run dev --filter='./apps/dashboard' --filter='./packages/db'", diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 4c43a19c..1594951d 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "@openpanel/sdk": "catalog:", "@t3-oss/env-core": "catalog:", diff --git a/packages/analytics/tsconfig.json b/packages/analytics/tsconfig.json index 3c1048af..7f4d9b72 100644 --- a/packages/analytics/tsconfig.json +++ b/packages/analytics/tsconfig.json @@ -5,6 +5,7 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/api/.env.test b/packages/api/.env.test index 75fa5596..84a3ecca 100644 --- a/packages/api/.env.test +++ b/packages/api/.env.test @@ -1,4 +1,3 @@ -NODE_ENV=test RESEND_API_KEY='test' NEXT_PUBLIC_OPENPANEL_CLIENT_ID='test' OPENPANEL_CLIENT_SECRET='test' diff --git a/packages/api/env.ts b/packages/api/env.ts index 4796312c..1dd33b39 100644 --- a/packages/api/env.ts +++ b/packages/api/env.ts @@ -1 +1,2 @@ -await Deno.copyFile("./.env.test", "./.env"); +const file = Bun.file("./.env.test"); +await Bun.write("./.env", file); diff --git a/packages/api/package.json b/packages/api/package.json index b6cfb9e2..ae6b5c2f 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -6,14 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "exports": { - ".": "./index.ts", - "./src/*": "./src/*.ts" - }, "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports --env-file=.env.test --import-map=test.importmap.json", - "env": "deno run -A env.ts" + "test": "bun test", + "env": "bun env.ts" }, "dependencies": { "@openstatus/analytics": "workspace:*", @@ -57,8 +52,6 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/react": "catalog:", "@types/react-dom": "catalog:", "bun-types": "catalog:", diff --git a/packages/api/src/router/blob.test.ts b/packages/api/src/router/blob.test.ts index f8498a1e..a357abdb 100644 --- a/packages/api/src/router/blob.test.ts +++ b/packages/api/src/router/blob.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { isSvgFile, sanitizeSvg } from "./blob"; diff --git a/packages/api/src/router/effective-status.test.ts b/packages/api/src/router/effective-status.test.ts index 9c7ef9e8..fcd2fcec 100644 --- a/packages/api/src/router/effective-status.test.ts +++ b/packages/api/src/router/effective-status.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { computeEffectiveStatus } from "./effective-status"; diff --git a/packages/api/src/router/import.test.ts b/packages/api/src/router/import.test.ts index ddb77b23..80c3c4c2 100644 --- a/packages/api/src/router/import.test.ts +++ b/packages/api/src/router/import.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq, inArray } from "@openstatus/db"; import { maintenance, @@ -19,8 +21,6 @@ import { MOCK_SUBSCRIBERS, } from "@openstatus/importers/statuspage/fixtures"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; @@ -341,7 +341,7 @@ test("run creates page, components, and groups in DB", async () => { // Clean up for next tests await cleanup(); -}); +}, 15_000); test("run with existing pageId imports into that page", async () => { const result = await caller.import.run({ @@ -374,7 +374,7 @@ test("run with existing pageId imports into that page", async () => { expect(matchingComps.length).toBe(MOCK_COMPONENTS.length); await cleanup(); -}); +}, 15_000); test("re-run skips already-imported resources (idempotency)", async () => { // First run @@ -410,7 +410,7 @@ test("re-run skips already-imported resources (idempotency)", async () => { expect(allGroupsSkipped).toBe(true); await cleanup(); -}); +}, 15_000); test("run with includeStatusReports creates status reports", async () => { const result = await caller.import.run({ @@ -461,7 +461,7 @@ test("run with includeStatusReports creates status reports", async () => { expect(createdMaintIds.length).toBeGreaterThan(0); await cleanup(); -}); +}, 15_000); // --------------------------------------------------------------------------- // Limit warnings (go through the caller with custom workspace limits to diff --git a/packages/api/src/router/maintenance.test.ts b/packages/api/src/router/maintenance.test.ts index c24e9425..65c853c0 100644 --- a/packages/api/src/router/maintenance.test.ts +++ b/packages/api/src/router/maintenance.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { maintenance, @@ -6,8 +8,6 @@ import { pageComponent, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/monitor.test.ts b/packages/api/src/router/monitor.test.ts index 62079b22..d19508a7 100644 --- a/packages/api/src/router/monitor.test.ts +++ b/packages/api/src/router/monitor.test.ts @@ -1,88 +1,40 @@ -import { db, eq, inArray } from "@openstatus/db"; +import { afterAll, beforeAll, expect, test } from "bun:test"; + +import { db, eq } from "@openstatus/db"; import { monitorTag, monitorTagsToMonitors, - notification, - notificationsToMonitors, privateLocation, privateLocationToMonitors, - workspace, } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; -import { - createMonitor, - createWorkspace, -} from "@openstatus/db/src/test/factories"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; -// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in -// the authed middleware, so the caller is scoped to ownWorkspaceId instead of -// resolving the seeded workspace for the session user. -function callerFor(limits?: typeof allPlans.team.limits) { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal user for test - user: { id: 1 }, - // @ts-expect-error - minimal workspace for test - workspace: limits ? { id: ownWorkspaceId, limits } : { id: ownWorkspaceId }, - }); - return edgeRouter.createCaller(ctx); -} - -// Own workspaces/monitors per suite — these IDOR tests previously shared the -// seeded monitor 5 / workspace 3, which races sibling suites mutating that -// monitor's associations (e.g. privateLocation.test). -let ownWorkspaceId: number; -let otherWorkspaceId: number; -let ownMonitorId: number; -let otherMonitorId: number; let tagId: number; -let notifierId: number; let otherWorkspacePrivateLocationId: number; let ownWorkspacePrivateLocationId: number; beforeAll(async () => { - const own = await createWorkspace(); - const other = await createWorkspace(); - ownWorkspaceId = own.id; - otherWorkspaceId = other.id; - - const ownMonitor = await createMonitor(own.id); - const otherMonitor = await createMonitor(other.id); - ownMonitorId = ownMonitor.id; - otherMonitorId = otherMonitor.id; - const tag = await db .insert(monitorTag) - .values({ workspaceId: own.id, name: "idor-test-tag", color: "#ff0000" }) - .returning() - .get(); - tagId = tag.id; - - const notif = await db - .insert(notification) .values({ - workspaceId: own.id, - name: "idor-test-notif", - provider: "email", - data: JSON.stringify({ email: "test@example.com" }), + workspaceId: 1, + name: "idor-test-tag", + color: "#ff0000", }) .returning() .get(); - notifierId = notif.id; + tagId = tag.id; const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: other.id, + workspaceId: 3, name: "Other workspace private location", - token: `monitor-test-other-${otherWorkspaceId}`, + token: "monitor-test-other-token", }) .returning() .get(); @@ -91,68 +43,47 @@ beforeAll(async () => { const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: own.id, + workspaceId: 1, name: "Own workspace private location", - token: `monitor-test-own-${ownWorkspaceId}`, + token: "monitor-test-own-token", }) .returning() .get(); ownWorkspacePrivateLocationId = ownLoc.id; - - // Pre-existing association on the cross-workspace monitor; the IDOR test - // asserts a rejected scheduling update does not wipe it. - await db - .insert(privateLocationToMonitors) - .values({ privateLocationId: otherLoc.id, monitorId: otherMonitor.id }) - .run(); }); afterAll(async () => { + await db + .delete(monitorTagsToMonitors) + .where(eq(monitorTagsToMonitors.monitorTagId, tagId)); + await db.delete(monitorTag).where(eq(monitorTag.id, tagId)); await db .delete(privateLocationToMonitors) .where( - inArray(privateLocationToMonitors.privateLocationId, [ - otherWorkspacePrivateLocationId, + eq( + privateLocationToMonitors.privateLocationId, ownWorkspacePrivateLocationId, - ]), - ) - .catch(() => undefined); + ), + ); await db .delete(privateLocation) - .where( - inArray(privateLocation.id, [ - otherWorkspacePrivateLocationId, - ownWorkspacePrivateLocationId, - ]), - ) - .catch(() => undefined); - await db - .delete(monitorTagsToMonitors) - .where(eq(monitorTagsToMonitors.monitorTagId, tagId)) - .catch(() => undefined); - await db - .delete(monitorTag) - .where(eq(monitorTag.id, tagId)) - .catch(() => undefined); - await db - .delete(notificationsToMonitors) - .where(eq(notificationsToMonitors.notificationId, notifierId)) - .catch(() => undefined); - await db - .delete(notification) - .where(eq(notification.id, notifierId)) - .catch(() => undefined); + .where(eq(privateLocation.id, otherWorkspacePrivateLocationId)); await db - .delete(workspace) - .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) - .catch(() => undefined); + .delete(privateLocation) + .where(eq(privateLocation.id, ownWorkspacePrivateLocationId)); }); test("monitor.updateTags rejects monitor from another workspace", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); try { - await caller.monitor.updateTags({ id: otherMonitorId, tags: [] }); + await caller.monitor.updateTags({ id: 5, tags: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -161,22 +92,34 @@ test("monitor.updateTags rejects monitor from another workspace", async () => { }); test("monitor.updateTags succeeds for own workspace monitor", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); - await caller.monitor.updateTags({ id: ownMonitorId, tags: [tagId] }); + await caller.monitor.updateTags({ id: 1, tags: [tagId] }); const result = await db.query.monitorTagsToMonitors.findFirst({ - where: eq(monitorTagsToMonitors.monitorId, ownMonitorId), + where: eq(monitorTagsToMonitors.monitorId, 1), }); expect(result).toBeDefined(); expect(result?.monitorTagId).toBe(tagId); }); test("monitor.updateNotifiers rejects monitor from another workspace", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); try { - await caller.monitor.updateNotifiers({ id: otherMonitorId, notifiers: [] }); + await caller.monitor.updateNotifiers({ id: 5, notifiers: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -185,26 +128,36 @@ test("monitor.updateNotifiers rejects monitor from another workspace", async () }); test("monitor.updateNotifiers succeeds for own workspace monitor", async () => { - const caller = callerFor(); - - await caller.monitor.updateNotifiers({ - id: ownMonitorId, - notifiers: [notifierId], + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, }); + const caller = edgeRouter.createCaller(ctx); + + await caller.monitor.updateNotifiers({ id: 1, notifiers: [1] }); }); test("monitor.updateSchedulingRegions rejects monitor from another workspace", async () => { - const caller = callerFor(allPlans.team.limits); + // Monitor 5 belongs to workspace 3; try to update it from workspace 1 + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1, limits: allPlans.team.limits }, + }); + const caller = edgeRouter.createCaller(ctx); // Verify the seed private location association exists before the attack const before = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, otherMonitorId), + where: eq(privateLocationToMonitors.monitorId, 5), }); const beforeCount = before.length; try { await caller.monitor.updateSchedulingRegions({ - id: otherMonitorId, + id: 5, regions: ["ams"], periodicity: "30s", privateLocations: [], @@ -217,16 +170,23 @@ test("monitor.updateSchedulingRegions rejects monitor from another workspace", a // Verify private location associations were NOT deleted const after = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, otherMonitorId), + where: eq(privateLocationToMonitors.monitorId, 5), }); expect(after.length).toBe(beforeCount); }); test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async () => { - const caller = callerFor(allPlans.team.limits); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1, limits: allPlans.team.limits }, + }); + const caller = edgeRouter.createCaller(ctx); + // Monitor 1 belongs to workspace 1 await caller.monitor.updateSchedulingRegions({ - id: ownMonitorId, + id: 1, regions: ["ams"], periodicity: "1m", privateLocations: [], @@ -234,14 +194,20 @@ test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async }); test("monitor.updateSchedulingRegions rejects privateLocations from another workspace", async () => { - const caller = callerFor(allPlans.team.limits); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1, limits: allPlans.team.limits }, + }); + const caller = edgeRouter.createCaller(ctx); try { await caller.monitor.updateSchedulingRegions({ - id: ownMonitorId, + id: 1, // own monitor regions: ["ams"], periodicity: "1m", - privateLocations: [otherWorkspacePrivateLocationId], + privateLocations: [otherWorkspacePrivateLocationId], // workspace 2 }); throw new Error("Should have thrown"); } catch (e) { @@ -251,17 +217,23 @@ test("monitor.updateSchedulingRegions rejects privateLocations from another work }); test("monitor.updateSchedulingRegions succeeds with own workspace privateLocations", async () => { - const caller = callerFor(allPlans.team.limits); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1, limits: allPlans.team.limits }, + }); + const caller = edgeRouter.createCaller(ctx); await caller.monitor.updateSchedulingRegions({ - id: ownMonitorId, + id: 1, regions: ["ams"], periodicity: "1m", privateLocations: [ownWorkspacePrivateLocationId], }); const associations = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, ownMonitorId), + where: eq(privateLocationToMonitors.monitorId, 1), }); const linked = associations.find( (a) => a.privateLocationId === ownWorkspacePrivateLocationId, diff --git a/packages/api/src/router/notification.test.ts b/packages/api/src/router/notification.test.ts index a0ef37bf..d458ca28 100644 --- a/packages/api/src/router/notification.test.ts +++ b/packages/api/src/router/notification.test.ts @@ -1,10 +1,10 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index e7b069f6..7137893e 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -32,6 +32,10 @@ import { env } from "../env"; import { toServiceCtx, toTRPCError } from "../service-adapter"; import { createTRPCRouter, protectedProcedure } from "../trpc"; +if (process.env.NODE_ENV === "test") { + require("../test/preload"); +} + // Vercel domain helpers — transport-layer external integrations that // don't belong in the service layer. async function addDomainToVercel(domain: string) { diff --git a/packages/api/src/router/pageComponent.test.ts b/packages/api/src/router/pageComponent.test.ts index 187cef84..c14e9f5e 100644 --- a/packages/api/src/router/pageComponent.test.ts +++ b/packages/api/src/router/pageComponent.test.ts @@ -1,8 +1,8 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/privateLocation.test.ts b/packages/api/src/router/privateLocation.test.ts index c621f351..19e39485 100644 --- a/packages/api/src/router/privateLocation.test.ts +++ b/packages/api/src/router/privateLocation.test.ts @@ -1,61 +1,25 @@ -import { db, eq, inArray } from "@openstatus/db"; +import { afterAll, beforeAll, expect, test } from "bun:test"; + +import { db, eq } from "@openstatus/db"; import { privateLocation, privateLocationToMonitors, - workspace, } from "@openstatus/db/src/schema"; -import { - createMonitor, - createWorkspace, -} from "@openstatus/db/src/test/factories"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; -// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in -// the authed middleware, so the caller is scoped to ownWorkspaceId instead of -// resolving the seeded workspace for the session user. -function callerFor() { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal user for test - user: { id: 1 }, - // @ts-expect-error - minimal workspace for test - workspace: { id: ownWorkspaceId }, - }); - return edgeRouter.createCaller(ctx); -} - -// Own workspaces/monitors per suite — sharing the seeded monitor 5 / workspace -// 3 races sibling suites that read or mutate that monitor's associations. -let ownWorkspaceId: number; -let otherWorkspaceId: number; -let ownMonitorId: number; -let otherMonitorId: number; let otherWorkspaceLocationId: number; let ownWorkspaceLocationId: number; beforeAll(async () => { - const own = await createWorkspace(); - const other = await createWorkspace(); - ownWorkspaceId = own.id; - otherWorkspaceId = other.id; - - const ownMonitor = await createMonitor(own.id); - const otherMonitor = await createMonitor(other.id); - ownMonitorId = ownMonitor.id; - otherMonitorId = otherMonitor.id; - const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: other.id, + workspaceId: 3, name: "Other workspace location", - token: `test-token-idor-${otherWorkspaceId}`, + token: "test-token-idor", }) .returning() .get(); @@ -65,16 +29,16 @@ beforeAll(async () => { .insert(privateLocationToMonitors) .values({ privateLocationId: otherWorkspaceLocationId, - monitorId: otherMonitorId, + monitorId: 5, }) .run(); const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: own.id, + workspaceId: 1, name: "Own workspace location", - token: `test-token-own-${ownWorkspaceId}`, + token: "test-token-own", }) .returning() .get(); @@ -85,29 +49,29 @@ afterAll(async () => { await db .delete(privateLocationToMonitors) .where( - inArray(privateLocationToMonitors.privateLocationId, [ - otherWorkspaceLocationId, - ownWorkspaceLocationId, - ]), - ) - .catch(() => undefined); + eq(privateLocationToMonitors.privateLocationId, otherWorkspaceLocationId), + ); await db .delete(privateLocation) + .where(eq(privateLocation.id, otherWorkspaceLocationId)); + await db + .delete(privateLocationToMonitors) .where( - inArray(privateLocation.id, [ - otherWorkspaceLocationId, - ownWorkspaceLocationId, - ]), - ) - .catch(() => undefined); + eq(privateLocationToMonitors.privateLocationId, ownWorkspaceLocationId), + ); await db - .delete(workspace) - .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) - .catch(() => undefined); + .delete(privateLocation) + .where(eq(privateLocation.id, ownWorkspaceLocationId)); }); test("privateLocation.update rejects location from another workspace", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); try { await caller.privateLocation.update({ @@ -132,12 +96,18 @@ test("privateLocation.update rejects location from another workspace", async () }); test("privateLocation.update succeeds for own workspace location", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); const result = await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [ownMonitorId], + monitors: [1], }); expect(result).toBeDefined(); @@ -145,13 +115,19 @@ test("privateLocation.update succeeds for own workspace location", async () => { }); test("privateLocation.new rejects monitors from another workspace", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); try { await caller.privateLocation.new({ name: "Injected Location", token: "test-token-inject", - monitors: [otherMonitorId], + monitors: [5], // monitor 5 belongs to workspace 3 }); throw new Error("Should have thrown"); } catch (e) { @@ -161,12 +137,18 @@ test("privateLocation.new rejects monitors from another workspace", async () => }); test("privateLocation.new succeeds with own workspace monitors", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); const result = await caller.privateLocation.new({ name: "Valid Location", token: "test-token-valid-new", - monitors: [ownMonitorId], + monitors: [1], // monitor 1 belongs to workspace 1 }); expect(result).toBeDefined(); @@ -177,7 +159,7 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { where: eq(privateLocationToMonitors.privateLocationId, result.id), }); expect(associations.length).toBe(1); - expect(associations[0].monitorId).toBe(ownMonitorId); + expect(associations[0].monitorId).toBe(1); // Cleanup await db @@ -187,13 +169,19 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { }); test("privateLocation.update rejects monitors from another workspace", async () => { - const caller = callerFor(); + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal workspace for test + workspace: { id: 1 }, + }); + const caller = edgeRouter.createCaller(ctx); try { await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [otherMonitorId], + monitors: [5], // monitor 5 belongs to workspace 3 }); throw new Error("Should have thrown"); } catch (e) { diff --git a/packages/api/src/router/statusPage.e2e.test.ts b/packages/api/src/router/statusPage.e2e.test.ts index 79c611ab..1baab894 100644 --- a/packages/api/src/router/statusPage.e2e.test.ts +++ b/packages/api/src/router/statusPage.e2e.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { incidentTable, @@ -7,8 +9,6 @@ import { pageSubscriber, workspace, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * End-to-end integration tests for the full unsubscribe flow. @@ -213,7 +213,6 @@ describe("Confirmation page displays correct information", () => { } const email = subscriber.email; - if (!email) throw new Error("Subscriber email not found"); expect(email).toBe("confirm-page-test@example.com"); // Apply the same masking logic as in the API diff --git a/packages/api/src/router/statusPage.unsubscribe.test.ts b/packages/api/src/router/statusPage.unsubscribe.test.ts index 8cb66d5f..9800d3fc 100644 --- a/packages/api/src/router/statusPage.unsubscribe.test.ts +++ b/packages/api/src/router/statusPage.unsubscribe.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; // Test data setup let testPageId: number; diff --git a/packages/api/src/router/statusPage.utils.test.ts b/packages/api/src/router/statusPage.utils.test.ts index 1961e85f..15baf720 100644 --- a/packages/api/src/router/statusPage.utils.test.ts +++ b/packages/api/src/router/statusPage.utils.test.ts @@ -1,3 +1,5 @@ +import { describe, expect, it } from "bun:test"; + import type { Incident, Maintenance, @@ -5,8 +7,6 @@ import type { StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; import { currentImpactByComponent, diff --git a/packages/api/src/router/statusReport.test.ts b/packages/api/src/router/statusReport.test.ts index 1c63e8eb..2175fbf4 100644 --- a/packages/api/src/router/statusReport.test.ts +++ b/packages/api/src/router/statusReport.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, expect, test } from "bun:test"; + import { db, eq, inArray } from "@openstatus/db"; import { page, @@ -7,8 +9,6 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/stripe/utils.test.ts b/packages/api/src/router/stripe/utils.test.ts index 048fd6b5..02299b1b 100644 --- a/packages/api/src/router/stripe/utils.test.ts +++ b/packages/api/src/router/stripe/utils.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import { getLimits } from "@openstatus/db/src/schema/plan/utils"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import type Stripe from "stripe"; import { FEATURES, PLANS, buildLimitsFromSubscription } from "./utils"; diff --git a/packages/api/src/router/tinybird/index.test.ts b/packages/api/src/router/tinybird/index.test.ts index 66805529..759d92c6 100644 --- a/packages/api/src/router/tinybird/index.test.ts +++ b/packages/api/src/router/tinybird/index.test.ts @@ -1,5 +1,5 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; + import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../../edge"; diff --git a/packages/api/src/router/workspace.test.ts b/packages/api/src/router/workspace.test.ts index 3812aff7..02b14002 100644 --- a/packages/api/src/router/workspace.test.ts +++ b/packages/api/src/router/workspace.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { test } from "@std/testing/bdd"; +import { expect, test } from "bun:test"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; diff --git a/packages/api/src/test/preload.ts b/packages/api/src/test/preload.ts new file mode 100644 index 00000000..4d43b6ff --- /dev/null +++ b/packages/api/src/test/preload.ts @@ -0,0 +1,12 @@ +import { mock } from "bun:test"; + +mock.module("@openstatus/upstash", () => ({ + Redis: { + fromEnv() { + return { + get: () => Promise.resolve(undefined), + set: () => Promise.resolve([]), + }; + }, + }, +})); diff --git a/packages/api/src/test/upstash.mock.ts b/packages/api/src/test/upstash.mock.ts deleted file mode 100644 index 7aa2e846..00000000 --- a/packages/api/src/test/upstash.mock.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Test double for @openstatus/upstash, swapped in via --import-map in the -// `deno test` command. Keeps tests off a real Upstash Redis instance. -const noopRedis = { - get: () => Promise.resolve(null), - set: () => Promise.resolve("OK"), - del: () => Promise.resolve(0), - getdel: () => Promise.resolve(null), - incr: () => Promise.resolve(1), - expire: () => Promise.resolve(1), -}; - -export const redis = noopRedis; - -export const Redis = { - fromEnv() { - return noopRedis; - }, -}; diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts index d8225921..4e380ee0 100644 --- a/packages/api/src/trpc.ts +++ b/packages/api/src/trpc.ts @@ -7,7 +7,7 @@ import { import { db } from "@openstatus/db"; import type { User, Workspace } from "@openstatus/db/src/schema"; import { TRPCError, initTRPC } from "@trpc/server"; -import { type NextRequest, after } from "next/server.js"; +import { type NextRequest, after } from "next/server"; import superjson from "superjson"; import { ZodError, treeifyError } from "zod"; diff --git a/packages/api/test.importmap.json b/packages/api/test.importmap.json deleted file mode 100644 index 94b18545..00000000 --- a/packages/api/test.importmap.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "imports": { - "@openstatus/upstash": "./src/test/upstash.mock.ts" - } -} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index 48baa5cf..15860ea1 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -1,7 +1,8 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "moduleResolution": "bundler", + "types": ["bun-types"] } } diff --git a/packages/assertions/package.json b/packages/assertions/package.json index 79323a62..0472bd9f 100644 --- a/packages/assertions/package.json +++ b/packages/assertions/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "jsonpath-plus": "catalog:", "zod": "catalog:" diff --git a/packages/assertions/src/v1.ts b/packages/assertions/src/v1.ts index 9b480988..0b7ea37d 100644 --- a/packages/assertions/src/v1.ts +++ b/packages/assertions/src/v1.ts @@ -309,7 +309,7 @@ export class HeaderAssertion implements Assertion { }; } const { success, message } = evaluateString( - req.header[this.schema.key] ?? "", + req.header[this.schema.key], this.schema.compare, this.schema.target, ); diff --git a/packages/assertions/tsconfig.json b/packages/assertions/tsconfig.json index aed15c74..ec9f2821 100644 --- a/packages/assertions/tsconfig.json +++ b/packages/assertions/tsconfig.json @@ -1,4 +1,7 @@ { "extends": "@openstatus/tsconfig/base.json", + "compilerOptions": { + "lib": ["es2015", "dom"] + }, "include": ["src", "*.ts"] } diff --git a/packages/db/env.ts b/packages/db/env.ts index dab63f5f..dbb28b16 100644 --- a/packages/db/env.ts +++ b/packages/db/env.ts @@ -1 +1,2 @@ -await Deno.copyFile("./.env.example", "./.env"); +const file = Bun.file("./.env.example"); +await Bun.write("./.env", file); diff --git a/packages/db/package.json b/packages/db/package.json index 8e7d6d38..a08d4abc 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -4,27 +4,13 @@ "description": "", "author": "OpenStatus", "main": "src/index.ts", - "exports": { - ".": "./src/index.ts", - "./env.mjs": "./env.mjs", - "./src/schema": "./src/schema/index.ts", - "./src/test/factories": "./src/test/factories.ts", - "./src/schema/api-keys": "./src/schema/api-keys/index.ts", - "./src/schema/check": "./src/schema/check/index.ts", - "./src/schema/incidents": "./src/schema/incidents/index.ts", - "./src/schema/maintenances": "./src/schema/maintenances/index.ts", - "./src/schema/page_components": "./src/schema/page_components/index.ts", - "./src/schema/workspaces": "./src/schema/workspaces/index.ts", - "./src/*": "./src/*.ts" - }, "scripts": { - "check": "deno check --sloppy-imports .", "generate": "drizzle-kit generate", "push": "drizzle-kit push", - "migrate": "deno run -A --env-file src/migrate.mts", + "migrate": "bun src/migrate.mts", "studio": "drizzle-kit studio", - "env": "deno run -A env.ts", - "seed": "deno run -A --env-file --sloppy-imports src/seed.mts", + "env": "bun env.ts", + "seed": "bun src/seed.mts", "dev": "turso dev --db-file ../../openstatus-dev.db" }, "dependencies": { @@ -42,8 +28,6 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/bcryptjs": "catalog:", "@types/node": "catalog:", "drizzle-kit": "catalog:", diff --git a/packages/db/script/region-migration.test.ts b/packages/db/script/region-migration.test.ts index f52fd0eb..b9e3bc60 100644 --- a/packages/db/script/region-migration.test.ts +++ b/packages/db/script/region-migration.test.ts @@ -1,5 +1,5 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, test } from "@std/testing/bdd"; +import { beforeEach, describe, expect, test } from "bun:test"; + import type { z } from "zod"; import type { monitorRegionSchema } from "../src/schema/constants"; diff --git a/packages/db/src/schema/page_components/validation.ts b/packages/db/src/schema/page_components/validation.ts index fae44fbd..71188c42 100644 --- a/packages/db/src/schema/page_components/validation.ts +++ b/packages/db/src/schema/page_components/validation.ts @@ -10,7 +10,7 @@ import { export const selectPageComponentSchema = createSelectSchema(pageComponent); export const insertPageComponentSchema = createInsertSchema(pageComponent, { - name: z.string().min(1), + name: (schema) => schema.min(1), }).refine( (data) => { // monitorId must be set when type='monitor' diff --git a/packages/db/src/seed.mts b/packages/db/src/seed.mts index 8e126471..bdc4cf4d 100644 --- a/packages/db/src/seed.mts +++ b/packages/db/src/seed.mts @@ -24,35 +24,9 @@ import { import { externalServicesSeed } from "./seed/external-services"; async function main() { - if ( - !env.DATABASE_URL.includes("localhost") && - !env.DATABASE_URL.includes("127.0.0.1") - ) { - throw new Error( - `Refusing to wipe non-local database: DATABASE_URL=${env.DATABASE_URL}`, - ); - } - - const client = createClient({ - url: env.DATABASE_URL, - authToken: env.DATABASE_AUTH_TOKEN, - }); - const db = drizzle(client); - - // Fresh slate: wipe every table so re-seeding is idempotent and tests never - // inherit residue from a previous run. `defer_foreign_keys` lets us delete in - // any order within the transaction (all tables end empty, so FKs hold at commit). - const tables = await client.execute( - "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != '__drizzle_migrations'", + const db = drizzle( + createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN }), ); - await client.batch( - [ - "PRAGMA defer_foreign_keys=ON", - ...tables.rows.map((row) => `DELETE FROM "${row.name}"`), - ], - "write", - ); - console.log("Seeding database "); await db .insert(workspace) diff --git a/packages/db/src/test/factories.ts b/packages/db/src/test/factories.ts deleted file mode 100644 index 72b4d2d2..00000000 --- a/packages/db/src/test/factories.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Test data factories: create fresh, uniquely-identified resources so suites -// don't collide on shared seed IDs (workspace 1, monitors 1-3, …). Each call -// inserts a row with an auto-increment id and unique slug/name, then returns -// it — scope the test to the returned id and clean up in afterAll. -// -// Pass a transaction as the last arg to scope creation to it (e.g. inside a -// rolled-back `withTestTransaction`); omit it to commit to the shared db. -import { db as defaultDb } from "../db"; -import { monitor, workspace } from "../schema"; - -type Db = typeof defaultDb; -type WorkspaceInsert = typeof workspace.$inferInsert; -type MonitorInsert = typeof monitor.$inferInsert; - -const unique = () => crypto.randomUUID().slice(0, 8); - -export async function createWorkspace( - overrides: Partial = {}, - db: Db = defaultDb, -) { - const u = unique(); - const [row] = await db - .insert(workspace) - .values({ - slug: `test-ws-${u}`, - name: "Test Workspace", - stripeId: `test-stripe-${u}`, - plan: "team", - ...overrides, - }) - .returning(); - return row; -} - -export async function createMonitor( - workspaceId: number, - overrides: Partial = {}, - db: Db = defaultDb, -) { - const [row] = await db - .insert(monitor) - .values({ - workspaceId, - url: "https://example.openstatus.dev", - name: `test-monitor-${unique()}`, - ...overrides, - }) - .returning(); - return row; -} diff --git a/packages/db/src/utils/api-key.test.ts b/packages/db/src/utils/api-key.test.ts index 8fae1da2..63971b5c 100644 --- a/packages/db/src/utils/api-key.test.ts +++ b/packages/db/src/utils/api-key.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { generateApiKey, diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index 122f1a76..c3ede090 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -5,6 +5,7 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/emails/package.json b/packages/emails/package.json index 229b1c93..849cc2a9 100644 --- a/packages/emails/package.json +++ b/packages/emails/package.json @@ -6,15 +6,9 @@ "license": "ISC", "author": "", "main": "./src/index.ts", - "exports": { - ".": "./src/index.ts", - "./src/client": "./src/client.tsx", - "./src/*": "./src/*.ts" - }, "scripts": { - "check": "deno check --sloppy-imports .", "dev:email": "email dev", - "test": "deno test --parallel -A --no-check --sloppy-imports" + "test": "bun test" }, "dependencies": { "@t3-oss/env-core": "catalog:", @@ -27,8 +21,6 @@ "devDependencies": { "@openstatus/tsconfig": "workspace:*", "@react-email/ui": "catalog:", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "typescript": "catalog:" diff --git a/packages/emails/src/client.integration.test.tsx b/packages/emails/src/client.integration.test.tsx index 9de77175..9733456f 100644 --- a/packages/emails/src/client.integration.test.tsx +++ b/packages/emails/src/client.integration.test.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource react */ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; + import { render } from "react-email"; import StatusReportEmail from "../emails/status-report"; @@ -40,7 +40,6 @@ describe("Status Report Email - Unsubscribe Link in Body", () => { message="Test message" pageComponents={["Monitor 1"]} manageUrl={manageUrl} - unsubscribeUrl="" />, ); diff --git a/packages/emails/src/client.test.ts b/packages/emails/src/client.test.ts index 59aa8292..cde4f7bf 100644 --- a/packages/emails/src/client.test.ts +++ b/packages/emails/src/client.test.ts @@ -1,11 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { - assertSpyCalls, - returnsNext, - type Stub, - stub, -} from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; import { EmailClient } from "./client"; @@ -42,8 +35,8 @@ const fail = { data: null, error: { name: "application_error" } } as any; describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { let client: EmailClient; - // biome-ignore lint/suspicious/noExplicitAny: stub over the Resend batch method - let batchSend: Stub; + // biome-ignore lint/suspicious/noExplicitAny: bun spy handle + let batchSend: any; beforeEach(() => { // zero backoff so the retry test doesn't wait on the real exponential sleep @@ -51,11 +44,11 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { apiKey: "re_test_123", retryBackoff: "0 millis", }); - batchSend = stub(client.client.batch, "send", () => Promise.resolve(ok)); + batchSend = spyOn(client.client.batch, "send").mockResolvedValue(ok); }); afterEach(() => { - batchSend.restore(); + batchSend.mockRestore(); }); test("passes the base idempotency key suffixed with the batch index", async () => { @@ -63,8 +56,8 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { baseReq({ idempotencyKey: "status-report-update:5" }), ); - assertSpyCalls(batchSend, 1); - const options = batchSend.calls[0].args[1]; + expect(batchSend).toHaveBeenCalledTimes(1); + const [, options] = batchSend.mock.calls[0]; expect(options).toEqual({ idempotencyKey: "status-report-update:5:0" }); }); @@ -76,31 +69,32 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { }), ); - assertSpyCalls(batchSend, 3); - const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); + expect(batchSend).toHaveBeenCalledTimes(3); + const keys = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([, o]: [unknown, any]) => o?.idempotencyKey, + ); expect(keys).toEqual([ "status-report-update:9:0", "status-report-update:9:1", "status-report-update:9:2", ]); - const sizes = batchSend.calls.map((c) => c.args[0].length); + const sizes = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([payload]: [any[]]) => payload.length, + ); expect(sizes).toEqual([100, 100, 50]); }); test("omits the option entirely when no base key is provided", async () => { await client.sendStatusReportUpdate(baseReq()); - const options = batchSend.calls[0].args[1]; + const [, options] = batchSend.mock.calls[0]; expect(options).toBeUndefined(); }); test("reuses the same key across a retry so Resend dedupes the resend", async () => { - batchSend.restore(); - batchSend = stub( - client.client.batch, - "send", - returnsNext([Promise.resolve(fail), Promise.resolve(ok)]), - ); + batchSend.mockResolvedValueOnce(fail).mockResolvedValueOnce(ok); await client.sendStatusReportUpdate( baseReq({ idempotencyKey: "status-report-update:7" }), @@ -108,8 +102,11 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { // failure → retry: the second attempt must carry the identical key, or // Resend would treat the retry as a fresh batch and double-send. - assertSpyCalls(batchSend, 2); - const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); + expect(batchSend).toHaveBeenCalledTimes(2); + const keys = batchSend.mock.calls.map( + // biome-ignore lint/suspicious/noExplicitAny: positional spy args + ([, o]: [unknown, any]) => o?.idempotencyKey, + ); expect(keys).toEqual([ "status-report-update:7:0", "status-report-update:7:0", diff --git a/packages/emails/tsconfig.json b/packages/emails/tsconfig.json index 39fe813f..e29f2150 100644 --- a/packages/emails/tsconfig.json +++ b/packages/emails/tsconfig.json @@ -1,9 +1,5 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/react-library.json", "include": [".", "src/env.ts"], - "exclude": ["dist", "build", "node_modules"], - "compilerOptions": { - "jsx": "react-jsx", - "resolveJsonModule": true - } + "exclude": ["dist", "build", "node_modules"] } diff --git a/packages/error/package.json b/packages/error/package.json index ab7f55bc..fd9fe953 100644 --- a/packages/error/package.json +++ b/packages/error/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "zod": "catalog:" }, diff --git a/packages/header-analysis/package.json b/packages/header-analysis/package.json index 8efdb62f..ac5d1eef 100644 --- a/packages/header-analysis/package.json +++ b/packages/header-analysis/package.json @@ -7,15 +7,13 @@ "author": "", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", - "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch" + "test": "bun test", + "test:watch": "bun test --watch" }, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", + "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/packages/header-analysis/src/parser/x-vercel-cache.test.ts b/packages/header-analysis/src/parser/x-vercel-cache.test.ts index 2780dd22..eb464af7 100644 --- a/packages/header-analysis/src/parser/x-vercel-cache.test.ts +++ b/packages/header-analysis/src/parser/x-vercel-cache.test.ts @@ -1,22 +1,19 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { parseXVercelCache } from "./x-vercel-cache"; describe("parseXVercelCache", () => { - for (const [value, expectedFragment] of [ + it.each([ ["MISS", "The response was not found in the edge cache"], ["HIT", "The response was served from the edge cache."], ["STALE", "A background request to the origin server"], ["PRERENDER", "The response was served from static storage."], ["REVALIDATED", "the cache was refreshed"], - ]) { - it(`describes the documented state ${value}`, () => { - const result = parseXVercelCache(value); - expect(result.value).toBe(value); - expect(result.description).toContain(expectedFragment); - }); - } + ])("describes the documented state %p", (value, expectedFragment) => { + const result = parseXVercelCache(value); + expect(result.value).toBe(value); + expect(result.description).toContain(expectedFragment); + }); it("matches states case-insensitively", () => { const lower = parseXVercelCache("revalidated"); diff --git a/packages/icons/package.json b/packages/icons/package.json index 889ca2a4..f50ea616 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -5,7 +5,6 @@ "main": "./src/index.tsx", "types": "./src/index.tsx", "scripts": { - "check": "deno check --sloppy-imports .", "lint": "oxlint" }, "dependencies": { diff --git a/packages/importers/package.json b/packages/importers/package.json index 9d82d995..894f486a 100644 --- a/packages/importers/package.json +++ b/packages/importers/package.json @@ -14,9 +14,8 @@ "./instatus/fixtures": "./src/providers/instatus/fixtures.ts" }, "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", - "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", + "test": "bun test", + "test:watch": "bun test --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -24,8 +23,6 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/importers/src/providers/betterstack/client.test.ts b/packages/importers/src/providers/betterstack/client.test.ts index fbcd501e..7b13f5dd 100644 --- a/packages/importers/src/providers/betterstack/client.test.ts +++ b/packages/importers/src/providers/betterstack/client.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, spy } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { createBetterstackClient } from "./client"; import { @@ -18,7 +16,7 @@ const originalFetch = globalThis.fetch; function mockFetchPaginated(data: unknown[], status = 200) { let callCount = 0; - globalThis.fetch = spy(() => { + globalThis.fetch = mock(() => { callCount++; const items = callCount === 1 ? data : []; const body = { @@ -41,7 +39,7 @@ function mockFetchPaginated(data: unknown[], status = 200) { } function mockFetchError(status: number, statusText: string) { - globalThis.fetch = spy(() => + globalThis.fetch = mock(() => Promise.resolve( new Response(JSON.stringify({ error: statusText }), { status, @@ -145,9 +143,9 @@ describe("BetterstackClient", () => { test("sends correct auth header", async () => { mockFetchPaginated(MOCK_MONITORS); await client.getMonitors(); - const fetchMock = globalThis.fetch as unknown as ReturnType; - assertSpyCalls(fetchMock, 1); - const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; + const fetchMock = globalThis.fetch as ReturnType; + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; expect(url).toBe("https://uptime.betterstack.com/api/v2/monitors"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -156,7 +154,7 @@ describe("BetterstackClient", () => { test("follows pagination.next for multiple pages", async () => { let callCount = 0; - globalThis.fetch = spy(() => { + globalThis.fetch = mock(() => { callCount++; const body = callCount === 1 diff --git a/packages/importers/src/providers/betterstack/mapper.test.ts b/packages/importers/src/providers/betterstack/mapper.test.ts index 70dfab13..e4e23875 100644 --- a/packages/importers/src/providers/betterstack/mapper.test.ts +++ b/packages/importers/src/providers/betterstack/mapper.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { MOCK_INCIDENTS, diff --git a/packages/importers/src/providers/betterstack/provider.test.ts b/packages/importers/src/providers/betterstack/provider.test.ts index 28aa0545..9ef88f33 100644 --- a/packages/importers/src/providers/betterstack/provider.test.ts +++ b/packages/importers/src/providers/betterstack/provider.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { spy } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { MOCK_INCIDENTS, @@ -26,7 +24,7 @@ function makePaginated(data: unknown[]) { } function setupMockFetch() { - globalThis.fetch = spy((url: string) => { + globalThis.fetch = mock((url: string) => { const path = new URL(url as string).pathname; let body: unknown; @@ -88,7 +86,7 @@ describe("BetterstackProvider", () => { }); test("validate returns friendly 401 error", async () => { - globalThis.fetch = spy(() => + globalThis.fetch = mock(() => Promise.resolve( new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, diff --git a/packages/importers/src/providers/instatus/client.test.ts b/packages/importers/src/providers/instatus/client.test.ts index 79edfe00..7bdcbf17 100644 --- a/packages/importers/src/providers/instatus/client.test.ts +++ b/packages/importers/src/providers/instatus/client.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { spy } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { createInstatusClient } from "./client"; import { @@ -14,7 +12,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = spy(() => + globalThis.fetch = mock(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -27,7 +25,7 @@ function mockFetch(data: unknown, status = 200) { function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = spy(() => { + globalThis.fetch = mock(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -109,8 +107,8 @@ describe("InstatusClient", () => { test("sends correct Bearer auth header", async () => { mockFetchPaginated(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; expect(url).toBe("https://api.instatus.com/v2/pages?page=1&per_page=100"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -126,7 +124,7 @@ describe("InstatusClient", () => { })); let callCount = 0; - globalThis.fetch = spy(() => { + globalThis.fetch = mock(() => { callCount++; // First call: 100 items (= per_page), second call: empty array const body = callCount === 1 ? items : []; @@ -147,8 +145,8 @@ describe("InstatusClient", () => { test("uses v1 for incidents and v2 for other endpoints", async () => { mockFetchPaginated(MOCK_INCIDENTS); await client.getIncidents("in_page_001"); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url] = fetchMock.calls[0].args as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; expect(url).toContain("/v1/in_page_001/incidents"); }); }); diff --git a/packages/importers/src/providers/instatus/mapper.test.ts b/packages/importers/src/providers/instatus/mapper.test.ts index 17a95994..8b008a57 100644 --- a/packages/importers/src/providers/instatus/mapper.test.ts +++ b/packages/importers/src/providers/instatus/mapper.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { MOCK_COMPONENTS, @@ -113,16 +112,14 @@ describe("mapComponent", () => { }); describe("mapIncidentStatus", () => { - for (const [input, expected] of [ + it.each([ ["INVESTIGATING", "investigating"], ["IDENTIFIED", "identified"], ["MONITORING", "monitoring"], ["RESOLVED", "resolved"], - ] as const) { - it(`maps ${input} to ${expected}`, () => { - expect(mapIncidentStatus(input)).toBe(expected); - }); - } + ] as const)("maps %s to %s", (input, expected) => { + expect(mapIncidentStatus(input)).toBe(expected); + }); it("defaults to investigating for unknown status", () => { expect(mapIncidentStatus("UNKNOWN")).toBe("investigating"); diff --git a/packages/importers/src/providers/instatus/provider.test.ts b/packages/importers/src/providers/instatus/provider.test.ts index 0b904b36..17b961e8 100644 --- a/packages/importers/src/providers/instatus/provider.test.ts +++ b/packages/importers/src/providers/instatus/provider.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; +import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { MOCK_COMPONENTS, diff --git a/packages/importers/src/providers/statuspage/client.test.ts b/packages/importers/src/providers/statuspage/client.test.ts index 79b7c7fc..d057a5b3 100644 --- a/packages/importers/src/providers/statuspage/client.test.ts +++ b/packages/importers/src/providers/statuspage/client.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, spy } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { createStatuspageClient } from "./client"; import { @@ -14,7 +12,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = spy(() => + globalThis.fetch = mock(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -30,7 +28,7 @@ function mockFetch(data: unknown, status = 200) { */ function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = spy(() => { + globalThis.fetch = mock(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -119,8 +117,8 @@ describe("StatuspageClient", () => { test("getPage calls correct URL path", async () => { mockFetch(MOCK_PAGES[0]); await client.getPage("sp_page_001"); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url] = fetchMock.calls[0].args as [string, RequestInit]; + const fetchMock = globalThis.fetch as ReturnType; + const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages/sp_page_001"); }); @@ -139,9 +137,9 @@ describe("StatuspageClient", () => { test("sends correct auth header", async () => { mockFetch(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as unknown as ReturnType; - assertSpyCalls(fetchMock, 1); - const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; + const fetchMock = globalThis.fetch as ReturnType; + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages"); expect((options.headers as Record).Authorization).toBe( "OAuth test-api-key", diff --git a/packages/importers/src/providers/statuspage/mapper.test.ts b/packages/importers/src/providers/statuspage/mapper.test.ts index 07b241b1..40f162f2 100644 --- a/packages/importers/src/providers/statuspage/mapper.test.ts +++ b/packages/importers/src/providers/statuspage/mapper.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { MOCK_COMPONENTS, @@ -126,7 +125,7 @@ describe("mapIncidentToStatusReport", () => { }); describe("mapIncidentUpdateStatus", () => { - for (const [input, expected] of [ + it.each([ ["investigating", "investigating"], ["identified", "identified"], ["monitoring", "monitoring"], @@ -135,11 +134,9 @@ describe("mapIncidentUpdateStatus", () => { ["in_progress", "investigating"], ["verifying", "monitoring"], ["completed", "resolved"], - ] as const) { - it(`maps ${input} to ${expected}`, () => { - expect(mapIncidentUpdateStatus(input)).toBe(expected); - }); - } + ] as const)("maps %s to %s", (input, expected) => { + expect(mapIncidentUpdateStatus(input)).toBe(expected); + }); }); describe("mapIncidentToMaintenance", () => { diff --git a/packages/importers/src/providers/statuspage/provider.test.ts b/packages/importers/src/providers/statuspage/provider.test.ts index 3f314f05..c0176167 100644 --- a/packages/importers/src/providers/statuspage/provider.test.ts +++ b/packages/importers/src/providers/statuspage/provider.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; +import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { MOCK_COMPONENTS, diff --git a/packages/locales/package.json b/packages/locales/package.json index 33a91be0..9a4556ff 100644 --- a/packages/locales/package.json +++ b/packages/locales/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "date-fns": "catalog:" }, diff --git a/packages/notifications/base/package.json b/packages/notifications/base/package.json index 25472b09..cd093dd2 100644 --- a/packages/notifications/base/package.json +++ b/packages/notifications/base/package.json @@ -7,8 +7,7 @@ "author": "", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -17,9 +16,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/base/src/utils/duration.test.ts b/packages/notifications/base/src/utils/duration.test.ts index cd99abb7..a89d4378 100644 --- a/packages/notifications/base/src/utils/duration.test.ts +++ b/packages/notifications/base/src/utils/duration.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { calculateDuration, formatDuration } from "./duration"; diff --git a/packages/notifications/base/src/utils/incident.test.ts b/packages/notifications/base/src/utils/incident.test.ts index 78b59a7c..bfacd6a7 100644 --- a/packages/notifications/base/src/utils/incident.test.ts +++ b/packages/notifications/base/src/utils/incident.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, it } from "bun:test"; + import type { Incident } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; import { getIncidentDuration } from "./incident"; @@ -22,6 +22,7 @@ function createIncident(overrides: Partial): Incident { describe("getIncidentDuration", () => { it("returns null when incident.startedAt is missing", () => { const incident = createIncident({ + startedAt: null, resolvedAt: new Date("2026-01-22T12:00:00Z"), }); expect(getIncidentDuration(incident)).toBe(null); diff --git a/packages/notifications/bird-whatsapp/package.json b/packages/notifications/bird-whatsapp/package.json index 5ea40620..98a77afb 100644 --- a/packages/notifications/bird-whatsapp/package.json +++ b/packages/notifications/bird-whatsapp/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/bird-whatsapp/src/index.test.ts b/packages/notifications/bird-whatsapp/src/index.test.ts index ea2039ae..043e81fb 100644 --- a/packages/notifications/bird-whatsapp/src/index.test.ts +++ b/packages/notifications/bird-whatsapp/src/index.test.ts @@ -1,8 +1,15 @@ +import { + afterEach, + beforeEach, + describe, + expect, + jest, + spyOn, + test, +} from "bun:test"; + import type { Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; @@ -27,7 +34,7 @@ function createNotification() { }); } -function parseRequestBody(call: Stub): { +function parseRequestBody(call: ReturnType): { messageRequests: Array<{ receiver: { contacts: Array<{ identifierKey: string; identifierValue: string }>; @@ -40,21 +47,22 @@ function parseRequestBody(call: Stub): { }; }>; } { - const body = call.calls[0].args[1]?.body; + const body = (call as ReturnType).mock.calls[0][1]?.body; return JSON.parse(body as string); } describe("WhatsApp Notifications (Bird)", () => { - let fetchMock: Stub; + let fetchMock: ReturnType; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + jest.resetAllMocks(); }); test("sendAlert calls Bird API with alert template", async () => { @@ -66,11 +74,11 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const url = fetchMock.calls[0].args[0] as string; + expect(fetchMock).toHaveBeenCalledTimes(1); + const url = fetchMock.mock.calls[0][0] as string; expect(url).toMatch(BIRD_URL_PATTERN); - const options = fetchMock.calls[0].args[1] as RequestInit; + const options = fetchMock.mock.calls[0][1] as RequestInit; expect(options.headers).toHaveProperty("Authorization"); expect((options.headers as Record).Authorization).toMatch( /^AccessKey /, @@ -107,7 +115,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "2068001e-330d-4093-8d06-7071e9d34aa1", @@ -129,7 +137,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "c9a842d9-cf9e-4a13-8cde-024d57e29143", @@ -145,7 +153,7 @@ describe("WhatsApp Notifications (Bird)", () => { test("sendTest calls Bird API with test template and openstat.us URL", async () => { await sendTest({ phoneNumber: "+33623456789" }); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].receiver.contacts[0].identifierValue).toBe( "+33623456789", diff --git a/packages/notifications/bird-whatsapp/tsconfig.json b/packages/notifications/bird-whatsapp/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/bird-whatsapp/tsconfig.json +++ b/packages/notifications/bird-whatsapp/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/discord/package.json b/packages/notifications/discord/package.json index 90ff88ec..825b2786 100644 --- a/packages/notifications/discord/package.json +++ b/packages/notifications/discord/package.json @@ -3,8 +3,7 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/discord/src/index.test.ts b/packages/notifications/discord/src/index.test.ts index 64c6ac7c..14169bbe 100644 --- a/packages/notifications/discord/src/index.test.ts +++ b/packages/notifications/discord/src/index.test.ts @@ -1,8 +1,7 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLOR_DECIMALS } from "@openstatus/notification-base"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, @@ -11,18 +10,20 @@ import { sendTestDiscordMessage, } from "./index"; -const ok = (): Promise => - Promise.resolve(new Response(null, { status: 200 })); - describe("Discord Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", ok); + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => + Promise.resolve(new Response(null, { status: 200 })), + ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -62,8 +63,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://discord.com/api/webhooks/123456789/abcdefgh", ); @@ -94,8 +95,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is recovered"); @@ -118,8 +119,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is degraded"); @@ -131,8 +132,8 @@ describe("Discord Notifications", () => { const webhookUrl = "https://discord.com/api/webhooks/123456789/abcdefgh"; await sendTestDiscordMessage(webhookUrl); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); @@ -141,12 +142,11 @@ describe("Discord Notifications", () => { test("Send Test Discord Message with empty webhookUrl", async () => { expect(sendTestDiscordMessage("")).rejects.toThrow(); - assertSpyCalls(fetchMock, 0); + expect(fetchMock).not.toHaveBeenCalled(); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/discord/tsconfig.json b/packages/notifications/discord/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/discord/tsconfig.json +++ b/packages/notifications/discord/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/email/package.json b/packages/notifications/email/package.json index 6078ce1a..7aee8b5b 100644 --- a/packages/notifications/email/package.json +++ b/packages/notifications/email/package.json @@ -4,8 +4,7 @@ "description": "Log drains Vercel integration.", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -21,10 +20,10 @@ "zod": "catalog:" }, "devDependencies": { - "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", "@types/node": "catalog:", "@types/react-dom": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/email/src/index.test.ts b/packages/notifications/email/src/index.test.ts index 7ea2c2a0..16b88c71 100644 --- a/packages/notifications/email/src/index.test.ts +++ b/packages/notifications/email/src/index.test.ts @@ -1,31 +1,26 @@ -import "./test-preload.ts"; +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { EmailClient } from "@openstatus/emails/src/client"; -import { - afterEach, - assertSpyCalls, - beforeEach, - describe, - expect, - type Stub, - stub, - test, -} from "@openstatus/test-utils"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; -// biome-ignore lint/suspicious/noExplicitAny: stub over the EmailClient method -let sendMonitorAlertMock: Stub; +const sendMonitorAlertMock = mock(async (_callArgs) => {}); + +mock.module("@openstatus/emails/src/client", () => ({ + EmailClient: mock((_args: { apiKey: string }) => { + return { + sendMonitorAlert: sendMonitorAlertMock, + }; + }), +})); describe("Email Notifications", () => { beforeEach(() => { - sendMonitorAlertMock = stub(EmailClient.prototype, "sendMonitorAlert", () => - Promise.resolve(), - ); + sendMonitorAlertMock.mockClear(); }); afterEach(() => { - sendMonitorAlertMock.restore(); + sendMonitorAlertMock.mockClear(); }); const createMockMonitor = () => ({ @@ -67,8 +62,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(sendMonitorAlertMock, 1); - const callArgs = sendMonitorAlertMock.calls[0].args[0]; + expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); + const callArgs = sendMonitorAlertMock.mock.calls[0][0]; expect(callArgs.name).toBe("API Health Check"); expect(callArgs.type).toBe("alert"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -93,8 +88,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(sendMonitorAlertMock, 1); - const callArgs = sendMonitorAlertMock.calls[0].args[0]; + expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); + const callArgs = sendMonitorAlertMock.mock.calls[0][0]; expect(callArgs.status).toBeUndefined(); expect(callArgs.latency).toBe("N/A"); expect(callArgs.region).toBe("N/A"); @@ -116,8 +111,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(sendMonitorAlertMock, 1); - const callArgs = sendMonitorAlertMock.calls[0].args[0]; + expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); + const callArgs = sendMonitorAlertMock.mock.calls[0][0]; expect(callArgs.type).toBe("recovery"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -142,8 +137,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(sendMonitorAlertMock, 1); - const callArgs = sendMonitorAlertMock.calls[0].args[0]; + expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); + const callArgs = sendMonitorAlertMock.mock.calls[0][0]; expect(callArgs.type).toBe("degraded"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.status).toBe("503"); @@ -171,6 +166,6 @@ describe("Email Notifications", () => { }); // Should not call sendMonitorAlert when data is invalid - assertSpyCalls(sendMonitorAlertMock, 0); + expect(sendMonitorAlertMock).not.toHaveBeenCalled(); }); }); diff --git a/packages/notifications/email/src/test-preload.ts b/packages/notifications/email/src/test-preload.ts deleted file mode 100644 index 3e4c5cf3..00000000 --- a/packages/notifications/email/src/test-preload.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Test env setup. Import this FIRST so env vars are set before module-level - * env validations fire on import. - * - * Bun's test runner set NODE_ENV=test automatically; Deno does not. This - * package's env skips validation when NODE_ENV=test, and @openstatus/emails - * validates RESEND_API_KEY at module load. - */ -process.env.NODE_ENV = "test"; -process.env.RESEND_API_KEY ??= "test-key"; diff --git a/packages/notifications/email/tsconfig.json b/packages/notifications/email/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/email/tsconfig.json +++ b/packages/notifications/email/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/google-chat/package.json b/packages/notifications/google-chat/package.json index 005737cf..f9669749 100644 --- a/packages/notifications/google-chat/package.json +++ b/packages/notifications/google-chat/package.json @@ -3,8 +3,7 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/google-chat/src/index.test.ts b/packages/notifications/google-chat/src/index.test.ts index 6a84bffd..1696d2db 100644 --- a/packages/notifications/google-chat/src/index.test.ts +++ b/packages/notifications/google-chat/src/index.test.ts @@ -1,21 +1,23 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Google Chat Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -55,8 +57,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://google.com/api/webhooks/123456789/abcdefgh", ); @@ -85,8 +87,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("✅ Recovered"); expect(body.text).toContain("API Health Check"); @@ -107,8 +109,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("⚠️ Degraded"); expect(body.text).toContain("API Health Check"); @@ -120,8 +122,8 @@ describe("Google Chat Notifications", () => { const result = await sendTest(webhookUrl); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("🧪 Test"); @@ -132,12 +134,11 @@ describe("Google Chat Notifications", () => { const result = await sendTest(""); expect(result).toBe(false); - assertSpyCalls(fetchMock, 0); + expect(fetchMock).not.toHaveBeenCalled(); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/google-chat/tsconfig.json b/packages/notifications/google-chat/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/google-chat/tsconfig.json +++ b/packages/notifications/google-chat/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/grafana-oncall/package.json b/packages/notifications/grafana-oncall/package.json index d68ea6c9..cc53a521 100644 --- a/packages/notifications/grafana-oncall/package.json +++ b/packages/notifications/grafana-oncall/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/grafana-oncall/src/index.test.ts b/packages/notifications/grafana-oncall/src/index.test.ts index 5676f5c7..824a02df 100644 --- a/packages/notifications/grafana-oncall/src/index.test.ts +++ b/packages/notifications/grafana-oncall/src/index.test.ts @@ -1,21 +1,23 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Grafana OnCall Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -55,8 +57,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -87,8 +89,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.message).toBe("Status code: 503"); }); @@ -108,8 +110,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -136,8 +138,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -156,8 +158,8 @@ describe("Grafana OnCall Notifications", () => { const result = await sendTest({ webhookUrl }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe(webhookUrl); expect(callArgs[1].method).toBe("POST"); @@ -170,8 +172,7 @@ describe("Grafana OnCall Notifications", () => { }); test("Send Test returns false on network error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -180,12 +181,11 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Send Test returns false on non-ok response", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.resolve(new Response(null, { status: 401 })), ); @@ -194,12 +194,11 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Send Alert throws on non-ok response", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.resolve( new Response(null, { status: 500, @@ -226,8 +225,7 @@ describe("Grafana OnCall Notifications", () => { }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -236,7 +234,7 @@ describe("Grafana OnCall Notifications", () => { createMockNotification(), ); - await expect( + expect( sendAlert({ // @ts-expect-error monitor, @@ -247,6 +245,6 @@ describe("Grafana OnCall Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/grafana-oncall/tsconfig.json b/packages/notifications/grafana-oncall/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/grafana-oncall/tsconfig.json +++ b/packages/notifications/grafana-oncall/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/ms-teams/package.json b/packages/notifications/ms-teams/package.json index 02dd24a6..1e4244f2 100644 --- a/packages/notifications/ms-teams/package.json +++ b/packages/notifications/ms-teams/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ms-teams/src/index.test.ts b/packages/notifications/ms-teams/src/index.test.ts index 6baccbba..18c7b6d7 100644 --- a/packages/notifications/ms-teams/src/index.test.ts +++ b/packages/notifications/ms-teams/src/index.test.ts @@ -1,12 +1,11 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import type { Incident, Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; -type FetchMock = Stub; +type FetchMock = ReturnType>; type AdaptiveCardElement = { type: string; @@ -42,13 +41,14 @@ describe("Microsoft Teams Notifications", () => { let fetchMock: FetchMock; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error spyOn typing requires the full `typeof fetch` (incl. preconnect) + fetchMock = spyOn(globalThis, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + fetchMock.mockRestore(); }); const createMockMonitor = (): Monitor => ({ @@ -114,8 +114,8 @@ describe("Microsoft Teams Notifications", () => { }); const readMessagePayload = (): MessagePayload => { - const calls = fetchMock.calls; - const init = calls[0].args[1]; + const calls = fetchMock.mock.calls; + const init = calls[0][1]; if (!init || typeof init.body !== "string") { throw new Error("expected string body"); } @@ -169,8 +169,8 @@ describe("Microsoft Teams Notifications", () => { regions: ["iad"], }); - assertSpyCalls(fetchMock, 1); - const [url, init] = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, init] = fetchMock.mock.calls[0]; expect(String(url)).toContain("logic.azure.com"); expect(init?.method).toBe("POST"); @@ -302,7 +302,7 @@ describe("Microsoft Teams Notifications", () => { "https://prod-00.westeurope.logic.azure.com:443/workflows/test/triggers/manual/paths/invoke", }); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); const card = getCard(readMessagePayload()); const header = findContainerByStyle(card, "good"); expect(header?.items?.[0]?.text).toBe("Test notification"); @@ -311,12 +311,12 @@ describe("Microsoft Teams Notifications", () => { test("Send Test with empty webhookUrl", async () => { await expect(sendTest({ webhookUrl: "" })).rejects.toThrow(); - assertSpyCalls(fetchMock, 0); + expect(fetchMock).not.toHaveBeenCalled(); }); test("Handle fetch error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error see beforeEach + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/ms-teams/tsconfig.json b/packages/notifications/ms-teams/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/ms-teams/tsconfig.json +++ b/packages/notifications/ms-teams/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/ntfy/package.json b/packages/notifications/ntfy/package.json index da39ed21..4d6230d4 100644 --- a/packages/notifications/ntfy/package.json +++ b/packages/notifications/ntfy/package.json @@ -3,8 +3,7 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ntfy/src/index.test.ts b/packages/notifications/ntfy/src/index.test.ts index a46f9284..f7a61d85 100644 --- a/packages/notifications/ntfy/src/index.test.ts +++ b/packages/notifications/ntfy/src/index.test.ts @@ -1,21 +1,23 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Ntfy Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -70,8 +72,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://ntfy.sh/my-topic"); expect(callArgs[1].method).toBe("post"); expect(callArgs[1].body).toContain("API Health Check"); @@ -94,8 +96,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://ntfy.example.com/my-topic"); }); @@ -114,8 +116,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -133,8 +135,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].body).toContain("error: Connection timeout"); }); @@ -153,8 +155,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].body).toContain("is up again"); }); @@ -171,8 +173,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -191,8 +193,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].body).toContain("is degraded"); }); @@ -202,8 +204,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://ntfy.sh/test-topic"); expect(callArgs[1].body).toBe("This is a test message from OpenStatus"); expect(callArgs[1].headers).not.toHaveProperty("Authorization"); @@ -216,8 +218,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://ntfy.example.com/test-topic"); }); @@ -228,14 +230,13 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token"); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -256,12 +257,11 @@ describe("Ntfy Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Send Test returns false on error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -270,6 +270,6 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/ntfy/tsconfig.json b/packages/notifications/ntfy/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/ntfy/tsconfig.json +++ b/packages/notifications/ntfy/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/opsgenie/package.json b/packages/notifications/opsgenie/package.json index 087a5e76..678250f3 100644 --- a/packages/notifications/opsgenie/package.json +++ b/packages/notifications/opsgenie/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -17,11 +16,10 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/opsgenie/src/index.test.ts b/packages/notifications/opsgenie/src/index.test.ts index ba678823..00ff9824 100644 --- a/packages/notifications/opsgenie/src/index.test.ts +++ b/packages/notifications/opsgenie/src/index.test.ts @@ -1,21 +1,23 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendTest } from "./index"; describe("OpsGenie Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -73,8 +75,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://api.opsgenie.com/v2/alerts"); expect(callArgs[1].method).toBe("POST"); expect(callArgs[1].headers["Content-Type"]).toBe("application/json"); @@ -105,8 +107,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://api.eu.opsgenie.com/v2/alerts"); }); @@ -127,16 +129,15 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.details.severity).toBe("degraded"); expect(body.message).toBe("API Health Check is degraded"); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -158,12 +159,11 @@ describe("OpsGenie Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Send Test returns false on error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -173,6 +173,6 @@ describe("OpsGenie Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/opsgenie/tsconfig.json b/packages/notifications/opsgenie/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/opsgenie/tsconfig.json +++ b/packages/notifications/opsgenie/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/pagerduty/package.json b/packages/notifications/pagerduty/package.json index 7fc66f4a..d242877d 100644 --- a/packages/notifications/pagerduty/package.json +++ b/packages/notifications/pagerduty/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -17,11 +16,10 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/pagerduty/src/index.test.ts b/packages/notifications/pagerduty/src/index.test.ts index a1a94b33..840cb57d 100644 --- a/packages/notifications/pagerduty/src/index.test.ts +++ b/packages/notifications/pagerduty/src/index.test.ts @@ -1,21 +1,23 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("PagerDuty Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -68,8 +70,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -107,9 +109,9 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 2); - expect(fetchMock.calls[0].args[1].body).toContain("key1"); - expect(fetchMock.calls[1].args[1].body).toContain("key2"); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(fetchMock.mock.calls[0][1].body).toContain("key1"); + expect(fetchMock.mock.calls[1][1].body).toContain("key2"); }); test("Send Degraded", async () => { @@ -130,8 +132,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.payload.summary).toBe("API Health Check is degraded"); expect(body.payload.severity).toBe("warning"); @@ -156,8 +158,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); const body = JSON.parse(callArgs[1].body); expect(body.routing_key).toBe("my_key"); @@ -171,8 +173,8 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -186,8 +188,7 @@ describe("PagerDuty Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -196,12 +197,11 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -224,6 +224,6 @@ describe("PagerDuty Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/pagerduty/tsconfig.json b/packages/notifications/pagerduty/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/pagerduty/tsconfig.json +++ b/packages/notifications/pagerduty/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/slack/package.json b/packages/notifications/slack/package.json index e63632c0..66b0aee6 100644 --- a/packages/notifications/slack/package.json +++ b/packages/notifications/slack/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/slack/src/index.test.ts b/packages/notifications/slack/src/index.test.ts index 4fe9de09..aa16993f 100644 --- a/packages/notifications/slack/src/index.test.ts +++ b/packages/notifications/slack/src/index.test.ts @@ -1,8 +1,7 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLORS } from "@openstatus/notification-base"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, @@ -12,16 +11,19 @@ import { } from "./index"; describe("Slack Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } }); const createMockMonitor = () => ({ @@ -61,8 +63,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe("https://hooks.slack.com/services/url"); expect(callArgs[1].method).toBe("POST"); @@ -88,8 +90,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.attachments[0].color).toBe(COLORS.red); expect(body.attachments[0].blocks[3].fields[0].text).toContain("Unknown"); @@ -110,8 +112,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.green); @@ -133,8 +135,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.yellow); @@ -146,8 +148,8 @@ describe("Slack Notifications", () => { await sendTestSlackMessage(webhookUrl); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); @@ -157,18 +159,16 @@ describe("Slack Notifications", () => { }); test("Send Test Slack Message throws error on empty webhookUrl", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); expect(sendTestSlackMessage("")).rejects.toThrow(); - assertSpyCalls(fetchMock, 0); + expect(fetchMock).toHaveBeenCalledTimes(0); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -177,7 +177,8 @@ describe("Slack Notifications", () => { createMockNotification(), ); - await expect( + // Should not throw - function catches errors internally + expect( sendAlert({ // @ts-expect-error monitor, @@ -188,6 +189,6 @@ describe("Slack Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/slack/tsconfig.json b/packages/notifications/slack/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/slack/tsconfig.json +++ b/packages/notifications/slack/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/telegram/package.json b/packages/notifications/telegram/package.json index 0e907adc..13f66b1e 100644 --- a/packages/notifications/telegram/package.json +++ b/packages/notifications/telegram/package.json @@ -3,8 +3,7 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -14,9 +13,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/telegram/src/index.test.ts b/packages/notifications/telegram/src/index.test.ts index 805cec19..93e56e31 100644 --- a/packages/notifications/telegram/src/index.test.ts +++ b/packages/notifications/telegram/src/index.test.ts @@ -1,27 +1,29 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Telegram Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; const originalEnv = process.env.TELEGRAM_BOT_TOKEN; beforeEach(() => { process.env.TELEGRAM_BOT_TOKEN = "test-bot-token-123"; - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } if (originalEnv) { process.env.TELEGRAM_BOT_TOKEN = originalEnv; } else { - delete process.env.TELEGRAM_BOT_TOKEN; + process.env.TELEGRAM_BOT_TOKEN = undefined; } }); @@ -66,8 +68,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -89,8 +91,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toContain("error: Connection timeout"); }); @@ -109,8 +111,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toContain("is up again"); }); @@ -129,8 +131,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toContain("is degraded"); }); @@ -140,8 +142,8 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -150,8 +152,7 @@ describe("Telegram Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -160,12 +161,11 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(false); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -174,7 +174,7 @@ describe("Telegram Notifications", () => { createMockNotification(), ); - await expect( + expect( sendAlert({ // @ts-expect-error monitor, @@ -185,18 +185,18 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("fetch not called when TELEGRAM_BOT_TOKEN is not set", async () => { - delete process.env.TELEGRAM_BOT_TOKEN; + process.env.TELEGRAM_BOT_TOKEN = undefined; const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), ); - await expect( + expect( sendAlert({ // @ts-expect-error monitor, @@ -207,6 +207,6 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); // Should not call fetch when token is missing - assertSpyCalls(fetchMock, 0); + expect(fetchMock).not.toHaveBeenCalled(); }); }); diff --git a/packages/notifications/telegram/tsconfig.json b/packages/notifications/telegram/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/telegram/tsconfig.json +++ b/packages/notifications/telegram/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/twillio-sms/package.json b/packages/notifications/twillio-sms/package.json index 74f26cc0..90199e77 100644 --- a/packages/notifications/twillio-sms/package.json +++ b/packages/notifications/twillio-sms/package.json @@ -3,8 +3,7 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -16,10 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/validator": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/twillio-sms/src/index.test.ts b/packages/notifications/twillio-sms/src/index.test.ts index 21b334ca..12e3c25c 100644 --- a/packages/notifications/twillio-sms/src/index.test.ts +++ b/packages/notifications/twillio-sms/src/index.test.ts @@ -1,12 +1,11 @@ +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { selectNotificationSchema } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; describe("Twilio SMS Notifications", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; const originalEnv = { TWILLIO_ACCOUNT_ID: process.env.TWILLIO_ACCOUNT_ID, TWILLIO_AUTH_TOKEN: process.env.TWILLIO_AUTH_TOKEN, @@ -15,13 +14,16 @@ describe("Twilio SMS Notifications", () => { beforeEach(() => { process.env.TWILLIO_ACCOUNT_ID = "test-account-id"; process.env.TWILLIO_AUTH_TOKEN = "test-auth-token"; - fetchMock = stub(globalThis, "fetch", () => + // @ts-expect-error + fetchMock = spyOn(global, "fetch").mockImplementation(() => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockRestore(); + } if (originalEnv.TWILLIO_ACCOUNT_ID) { process.env.TWILLIO_ACCOUNT_ID = originalEnv.TWILLIO_ACCOUNT_ID; } else { @@ -71,8 +73,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; expect(callArgs[0]).toBe( "https://api.twilio.com/2010-04-01/Accounts/test-account-id/Messages.json", ); @@ -102,8 +104,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("error: Connection timeout"); }); @@ -123,8 +125,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is up again"); expect(formData.get("Body")).toContain("API Health Check"); @@ -145,16 +147,15 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is degraded"); expect(formData.get("Body")).toContain("API Health Check"); }); test("Handle fetch error gracefully", async () => { - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => + fetchMock.mockImplementation(() => Promise.reject(new Error("Network error")), ); @@ -174,6 +175,6 @@ describe("Twilio SMS Notifications", () => { }), ).rejects.toThrow(); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/notifications/twillio-sms/tsconfig.json b/packages/notifications/twillio-sms/tsconfig.json index 48baa5cf..b4382e67 100644 --- a/packages/notifications/twillio-sms/tsconfig.json +++ b/packages/notifications/twillio-sms/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/nextjs.json", "include": ["src", "*.ts"], "compilerOptions": { - "resolveJsonModule": true + "types": ["bun-types"] } } diff --git a/packages/notifications/webhook/package.json b/packages/notifications/webhook/package.json index bb543a27..dca6d651 100644 --- a/packages/notifications/webhook/package.json +++ b/packages/notifications/webhook/package.json @@ -3,8 +3,7 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc" }, "dependencies": { @@ -15,9 +14,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/webhook/src/index.test.ts b/packages/notifications/webhook/src/index.test.ts index f0000ee1..ca5d0d63 100644 --- a/packages/notifications/webhook/src/index.test.ts +++ b/packages/notifications/webhook/src/index.test.ts @@ -1,35 +1,31 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; import { sendTest } from "./index"; describe("Webhook sendTest", () => { - let fetchMock: Stub; + let fetchMock: any = undefined; beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock = spyOn(global, "fetch"); }); afterEach(() => { - fetchMock.restore(); + if (fetchMock) { + fetchMock.mockClear(); + fetchMock.mockRestore(); + } }); test("should send test webhook successfully", async () => { const url = "https://example.com/webhook"; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const result = await sendTest({ url }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - expect(fetchMock.calls[0].args[0]).toBe(url); - expect(fetchMock.calls[0].args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledTimes(1); + expect(fetchMock).toHaveBeenCalledWith( + url, expect.objectContaining({ method: "post", body: expect.any(String), @@ -37,7 +33,7 @@ describe("Webhook sendTest", () => { }), ); - const callArgs = fetchMock.calls[0].args; + const callArgs = fetchMock.mock.calls[0]; const body = JSON.parse(callArgs[1].body); expect(body).toMatchObject({ monitor: { @@ -49,7 +45,7 @@ describe("Webhook sendTest", () => { statusCode: 200, latency: 1337, }); - expect(typeof body.cronTimestamp).toBe("number"); + expect(body.cronTimestamp).toBeTypeOf("number"); }); test("should send test webhook with headers", async () => { @@ -58,17 +54,14 @@ describe("Webhook sendTest", () => { { key: "Authorization", value: "Bearer token123" }, { key: "Content-Type", value: "application/json" }, ]; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const result = await sendTest({ url, headers }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - expect(fetchMock.calls[0].args[0]).toBe(url); - expect(fetchMock.calls[0].args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledTimes(1); + expect(fetchMock).toHaveBeenCalledWith( + url, expect.objectContaining({ method: "post", body: expect.any(String), @@ -82,63 +75,50 @@ describe("Webhook sendTest", () => { test("should throw error when response is not ok", async () => { const url = "https://example.com/webhook"; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 400 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 400 })); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("should throw error when fetch fails", async () => { const url = "https://example.com/webhook"; const networkError = new Error("Network error"); - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => Promise.reject(networkError)); + fetchMock.mockRejectedValue(networkError); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("should send test webhook with empty headers array", async () => { const url = "https://example.com/webhook"; const headers: { key: string; value: string }[] = []; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const result = await sendTest({ url, headers }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); - const callArgs = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const callArgs = fetchMock.mock.calls[0]; // Empty headers array should still include Content-Type expect(callArgs[1].headers).toEqual({ "Content-Type": "application/json" }); }); test("should send test webhook with 500 status code", async () => { const url = "https://example.com/webhook"; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 500 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 500 })); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); test("should send test webhook with 201 status code (success)", async () => { const url = "https://example.com/webhook"; - fetchMock.restore(); - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 201 })), - ); + fetchMock.mockResolvedValue(new Response(null, { status: 201 })); const result = await sendTest({ url }); expect(result).toBe(true); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/proto/package.json b/packages/proto/package.json index a9773b68..72bff34e 100644 --- a/packages/proto/package.json +++ b/packages/proto/package.json @@ -35,7 +35,6 @@ } }, "scripts": { - "check": "deno check --sloppy-imports .", "buf:openapi": "buf generate --path api/openstatus --template buf.gen.openapi.yaml && bun scripts/clean-openapi.ts", "buf:ts": "buf generate --path api/openstatus --template buf.gen.ts.yaml", "buf:go": "buf generate --path internal/private_location --template buf.gen.go.yaml", @@ -46,7 +45,7 @@ "dependencies": { "@bufbuild/protobuf": "catalog:", "@bufbuild/protovalidate": "catalog:", - "@connectrpc/connect": "catalog:" + "@connectrpc/connect": "^2.1.1" }, "devDependencies": { "@bufbuild/buf": "catalog:", diff --git a/packages/regions/package.json b/packages/regions/package.json index 0754493e..eef4b0cd 100644 --- a/packages/regions/package.json +++ b/packages/regions/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "zod": "catalog:" }, diff --git a/packages/services/package.json b/packages/services/package.json index 7a863399..74d25542 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -127,8 +127,7 @@ } }, "scripts": { - "check": "deno check --sloppy-imports .", - "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test --parallel -A --no-check --sloppy-imports", + "test": "bun test", "tsc": "tsc --noEmit" }, "dependencies": { @@ -146,8 +145,7 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", + "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/packages/services/src/__tests__/retry.test.ts b/packages/services/src/__tests__/retry.test.ts index ada57ea1..9f26dcaa 100644 --- a/packages/services/src/__tests__/retry.test.ts +++ b/packages/services/src/__tests__/retry.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { NotFoundError } from "../errors"; import { diff --git a/packages/services/src/__tests__/with-test-transaction.test.ts b/packages/services/src/__tests__/with-test-transaction.test.ts index cb9a1f64..68fc513c 100644 --- a/packages/services/src/__tests__/with-test-transaction.test.ts +++ b/packages/services/src/__tests__/with-test-transaction.test.ts @@ -1,7 +1,7 @@ +import { afterAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { auditLog } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { withTestTransaction } from "../../test/helpers"; diff --git a/packages/services/src/__tests__/with-transaction.test.ts b/packages/services/src/__tests__/with-transaction.test.ts index aa86f019..1bb9c477 100644 --- a/packages/services/src/__tests__/with-transaction.test.ts +++ b/packages/services/src/__tests__/with-transaction.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; +import { beforeAll, describe, expect, test } from "bun:test"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { loadSeededWorkspace } from "../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/docs.test.ts b/packages/services/src/agent-tools/__tests__/docs.test.ts index 63f50d31..039400c3 100644 --- a/packages/services/src/agent-tools/__tests__/docs.test.ts +++ b/packages/services/src/agent-tools/__tests__/docs.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, spy } from "@std/testing/mock"; +import { afterEach, describe, expect, mock, test } from "bun:test"; import type { ServiceContext } from "../../context"; import { getDocPageTool, searchDocsTool } from "../docs"; @@ -15,7 +13,7 @@ afterEach(() => { }); function mockFetch(response: Response) { - const fn = spy(async () => response); + const fn = mock(async () => response); globalThis.fetch = fn as unknown as typeof fetch; return fn; } @@ -113,11 +111,9 @@ describe("get_doc_page", () => { }); expect(result.truncated).toBe(true); expect(result.markdown.length).toBeLessThan(24_200); - expect( - result.markdown.endsWith( - "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", - ), - ).toBe(true); + expect(result.markdown).toEndWith( + "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", + ); }); test("returns error shape on 404", async () => { @@ -153,6 +149,6 @@ describe("get_doc_page", () => { ); expect(getDocPageTool.outputSchema.safeParse(result).success).toBe(true); } - assertSpyCalls(fn, 0); + expect(fn).not.toHaveBeenCalled(); }); }); diff --git a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts index ae1a50e6..c6bfd1b3 100644 --- a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts +++ b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; +import { beforeAll, describe, expect, test } from "bun:test"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { loadSeededWorkspace, makeUserCtx } from "../../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts index cb0f7c38..dd21661c 100644 --- a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts +++ b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts @@ -1,6 +1,6 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { page, pageComponent } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/api-key/__tests__/api-key.test.ts b/packages/services/src/api-key/__tests__/api-key.test.ts index 7a199c8b..e401e304 100644 --- a/packages/services/src/api-key/__tests__/api-key.test.ts +++ b/packages/services/src/api-key/__tests__/api-key.test.ts @@ -1,8 +1,15 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { eq } from "@openstatus/db"; import { apiKey } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; +import { + createApiKey, + listApiKeys, + revokeApiKey, + updateApiKeyLastUsed, + verifyApiKey, +} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -14,13 +21,6 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError, NotFoundError } from "../../errors"; -import { - createApiKey, - listApiKeys, - revokeApiKey, - updateApiKeyLastUsed, - verifyApiKey, -} from "../index.ts"; const TEST_PREFIX = "svc-apikey-test"; diff --git a/packages/services/src/audit/__tests__/audit.test.ts b/packages/services/src/audit/__tests__/audit.test.ts index de082c72..016e8d83 100644 --- a/packages/services/src/audit/__tests__/audit.test.ts +++ b/packages/services/src/audit/__tests__/audit.test.ts @@ -1,8 +1,8 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { auditLog, user } from "@openstatus/db/src/schema"; import type { AuditEntry } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/auth/__tests__/matches-scope.test.ts b/packages/services/src/auth/__tests__/matches-scope.test.ts index 0a70f475..de72ef4e 100644 --- a/packages/services/src/auth/__tests__/matches-scope.test.ts +++ b/packages/services/src/auth/__tests__/matches-scope.test.ts @@ -1,6 +1,6 @@ +import { describe, expect, test } from "bun:test"; + import type { Scope } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { matchesScope } from "../matches-scope"; diff --git a/packages/services/src/auth/__tests__/require-scope.test.ts b/packages/services/src/auth/__tests__/require-scope.test.ts index cd46a176..0278626b 100644 --- a/packages/services/src/auth/__tests__/require-scope.test.ts +++ b/packages/services/src/auth/__tests__/require-scope.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import type { Actor, ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; diff --git a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts index e8062d01..08324142 100644 --- a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts +++ b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts @@ -1,11 +1,11 @@ +import { afterEach, describe, expect, test } from "bun:test"; + import { and, db, eq, like } from "@openstatus/db"; import type { ApiConfigType } from "@openstatus/db/src/schema"; import { externalService, externalServiceComponent, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; import { getExternalComponentBySlug, diff --git a/packages/services/src/external-service-component/__tests__/internal.test.ts b/packages/services/src/external-service-component/__tests__/internal.test.ts index 7b304e95..f219bb83 100644 --- a/packages/services/src/external-service-component/__tests__/internal.test.ts +++ b/packages/services/src/external-service-component/__tests__/internal.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { assignComponentSlugs, slugifyComponentName } from "../internal"; diff --git a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts index 66ddc5a0..5134ddde 100644 --- a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts +++ b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts @@ -1,10 +1,10 @@ +import { afterEach, describe, expect, test } from "bun:test"; + import { and, db, eq, like } from "@openstatus/db"; import { externalService, externalServiceIncident, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; import { type UpsertExternalIncidentInput, diff --git a/packages/services/src/external-service-report/__tests__/record.test.ts b/packages/services/src/external-service-report/__tests__/record.test.ts index 853831f7..43a9524c 100644 --- a/packages/services/src/external-service-report/__tests__/record.test.ts +++ b/packages/services/src/external-service-report/__tests__/record.test.ts @@ -1,11 +1,11 @@ +import { afterEach, describe, expect, test } from "bun:test"; + import { db, eq, inArray, like } from "@openstatus/db"; import { externalService, externalServiceComponent, externalServiceReport, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; import { NotFoundError } from "../../errors"; import { diff --git a/packages/services/src/external-service/__tests__/external-service.test.ts b/packages/services/src/external-service/__tests__/external-service.test.ts index 6dc0c897..dccf7991 100644 --- a/packages/services/src/external-service/__tests__/external-service.test.ts +++ b/packages/services/src/external-service/__tests__/external-service.test.ts @@ -1,7 +1,7 @@ +import { afterEach, describe, expect, test } from "bun:test"; + import { db, like, sql } from "@openstatus/db"; import { externalService } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterEach, describe, test } from "@std/testing/bdd"; import { ConflictError } from "../../errors"; import { assertSlugAvailable } from "../internal"; diff --git a/packages/services/src/import/__tests__/incidents-phase.test.ts b/packages/services/src/import/__tests__/incidents-phase.test.ts index 64d2b6d6..7070bc57 100644 --- a/packages/services/src/import/__tests__/incidents-phase.test.ts +++ b/packages/services/src/import/__tests__/incidents-phase.test.ts @@ -1,3 +1,5 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { eq } from "@openstatus/db"; import { page, @@ -8,8 +10,6 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import type { PhaseResult } from "@openstatus/importers"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/import/__tests__/unit.test.ts b/packages/services/src/import/__tests__/unit.test.ts index ad3b74cf..b7f14668 100644 --- a/packages/services/src/import/__tests__/unit.test.ts +++ b/packages/services/src/import/__tests__/unit.test.ts @@ -1,10 +1,10 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; import type { Limits } from "@openstatus/db/src/schema/plan/schema"; import type { ImportSummary } from "@openstatus/importers"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { addLimitWarnings, clampPeriodicity, computePhaseStatus } from "../"; import { withTestTransaction } from "../../../test/helpers"; diff --git a/packages/services/src/incident/__tests__/incident.test.ts b/packages/services/src/incident/__tests__/incident.test.ts index ae0eec54..0b27432c 100644 --- a/packages/services/src/incident/__tests__/incident.test.ts +++ b/packages/services/src/incident/__tests__/incident.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/integration/__tests__/install-slack-agent.test.ts b/packages/services/src/integration/__tests__/install-slack-agent.test.ts index ddbfa877..7092a8bf 100644 --- a/packages/services/src/integration/__tests__/install-slack-agent.test.ts +++ b/packages/services/src/integration/__tests__/install-slack-agent.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, desc, eq } from "@openstatus/db"; import { integration } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -238,9 +238,9 @@ describe("installSlackAgent", () => { // shape as create/update — proves delete-path symmetry. const deleteRow = all.find((r) => r.action === "integration.delete"); expect( - typeof (deleteRow?.before as Record | null) + (deleteRow?.before as Record | null) ?.credentialFingerprint, - ).toBe("string"); + ).toBeTypeOf("string"); }); }); diff --git a/packages/services/src/invitation/__tests__/invitation.test.ts b/packages/services/src/invitation/__tests__/invitation.test.ts index 58ff3132..8309e1b3 100644 --- a/packages/services/src/invitation/__tests__/invitation.test.ts +++ b/packages/services/src/invitation/__tests__/invitation.test.ts @@ -1,8 +1,15 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { invitation, user, usersToWorkspaces } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { + acceptInvitation, + createInvitation, + deleteInvitation, + getInvitationByToken, + listInvitations, +} from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -20,13 +27,6 @@ import { LimitExceededError, NotFoundError, } from "../../errors"; -import { - acceptInvitation, - createInvitation, - deleteInvitation, - getInvitationByToken, - listInvitations, -} from "../index.ts"; const TEST_PREFIX = "svc-inv-test"; diff --git a/packages/services/src/maintenance/__tests__/maintenance.test.ts b/packages/services/src/maintenance/__tests__/maintenance.test.ts index 32afbbba..c7a8890c 100644 --- a/packages/services/src/maintenance/__tests__/maintenance.test.ts +++ b/packages/services/src/maintenance/__tests__/maintenance.test.ts @@ -1,17 +1,18 @@ -import { db, eq, inArray } from "@openstatus/db"; -import { - maintenancesToPageComponents, - page, - pageComponent, -} from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; import { afterAll, beforeAll, beforeEach, describe, + expect, test, -} from "@std/testing/bdd"; +} from "bun:test"; + +import { db, eq, inArray } from "@openstatus/db"; +import { + maintenancesToPageComponents, + page, + pageComponent, +} from "@openstatus/db/src/schema"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/member/__tests__/member.test.ts b/packages/services/src/member/__tests__/member.test.ts index 305d8885..a682723a 100644 --- a/packages/services/src/member/__tests__/member.test.ts +++ b/packages/services/src/member/__tests__/member.test.ts @@ -1,8 +1,9 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, eq } from "@openstatus/db"; import { user, usersToWorkspaces } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { deleteMember, listMembers } from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -22,7 +23,6 @@ import { NotFoundError, PreconditionFailedError, } from "../../errors"; -import { deleteMember, listMembers } from "../index.ts"; const OWNER_USER_ID = 1; const VICTIM_USER_ID = 4242; diff --git a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts index 121cbe4a..26238ff7 100644 --- a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts +++ b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts @@ -1,8 +1,9 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitorTag } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { listMonitorTags, syncMonitorTags } from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { clearAuditLog, @@ -14,7 +15,6 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; -import { listMonitorTags, syncMonitorTags } from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/src/monitor/__tests__/monitor.test.ts b/packages/services/src/monitor/__tests__/monitor.test.ts index d8af1b46..9979ea2f 100644 --- a/packages/services/src/monitor/__tests__/monitor.test.ts +++ b/packages/services/src/monitor/__tests__/monitor.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -5,15 +7,15 @@ import { monitorTagsToMonitors, notification, notificationsToMonitors, - selectWorkspaceSchema, - workspace, } from "@openstatus/db/src/schema"; -import { createWorkspace } from "@openstatus/db/src/test/factories"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { + SEEDED_WORKSPACE_FREE_ID, + SEEDED_WORKSPACE_TEAM_ID, +} from "../../../test/fixtures"; import { expectAuditRow, + loadSeededWorkspace, makeApiKeyCtx, makeSystemCtx, makeUserCtx, @@ -33,18 +35,12 @@ const TEST_PREFIX = "svc-monitor-test"; let teamCtx: ServiceContext; let freeCtx: ServiceContext; -let teamWorkspaceId: number; -let freeWorkspaceId: number; let testTagId: number; let testNotificationId: number; beforeAll(async () => { - // Own workspaces per suite — relying on the shared seeded workspace races - // sibling suites that wipe its tags/notifications (e.g. monitor-tag). - const team = selectWorkspaceSchema.parse(await createWorkspace()); - const free = selectWorkspaceSchema.parse(await createWorkspace()); - teamWorkspaceId = team.id; - freeWorkspaceId = free.id; + const team = await loadSeededWorkspace(SEEDED_WORKSPACE_TEAM_ID); + const free = await loadSeededWorkspace(SEEDED_WORKSPACE_FREE_ID); teamCtx = makeUserCtx(team, { userId: 1 }); freeCtx = makeUserCtx(free, { userId: 2 }); @@ -81,10 +77,6 @@ afterAll(async () => { .delete(notification) .where(eq(notification.id, testNotificationId)) .catch(() => undefined); - await db - .delete(workspace) - .where(inArray(workspace.id, [teamWorkspaceId, freeWorkspaceId])) - .catch(() => undefined); }); describe("createMonitor", () => { diff --git a/packages/services/src/monitor/__tests__/reads.test.ts b/packages/services/src/monitor/__tests__/reads.test.ts index ba2b25f0..ef90d9cb 100644 --- a/packages/services/src/monitor/__tests__/reads.test.ts +++ b/packages/services/src/monitor/__tests__/reads.test.ts @@ -1,6 +1,6 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { monitorStatusTable } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts index 0a54da72..431a9302 100644 --- a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts +++ b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -67,13 +66,11 @@ describe("streamMonitorPreview", () => { input: { monitorId: 999_999_999 }, }); - await expect( - (async () => { - for await (const _ of generator) { - // drain - } - })(), - ).rejects.toThrow(NotFoundError); + await expect(async () => { + for await (const _ of generator) { + // drain + } + }).toThrow(NotFoundError); }); }); diff --git a/packages/services/src/notification/__tests__/notification.test.ts b/packages/services/src/notification/__tests__/notification.test.ts index 5082f971..afd4c311 100644 --- a/packages/services/src/notification/__tests__/notification.test.ts +++ b/packages/services/src/notification/__tests__/notification.test.ts @@ -1,11 +1,11 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts index 10a2f088..02db33a0 100644 --- a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts +++ b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts @@ -1,3 +1,5 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { maintenance, maintenancesToPageComponents, @@ -9,8 +11,6 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/page-component/__tests__/page-component.test.ts b/packages/services/src/page-component/__tests__/page-component.test.ts index 447099d2..119c6952 100644 --- a/packages/services/src/page-component/__tests__/page-component.test.ts +++ b/packages/services/src/page-component/__tests__/page-component.test.ts @@ -1,3 +1,5 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { and, db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -5,8 +7,6 @@ import { pageComponent, pageComponentGroup, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts index 3fa02a4c..abbfd66c 100644 --- a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts +++ b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts @@ -1,20 +1,30 @@ -import { and, db, eq } from "@openstatus/db"; -import { - auditLog, - page, - pageSubscriber, - pageSubscriberToPageComponent, -} from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; import { afterAll, afterEach, beforeAll, beforeEach, describe, + expect, test, -} from "@std/testing/bdd"; +} from "bun:test"; + +import { and, db, eq } from "@openstatus/db"; +import { + auditLog, + page, + pageSubscriber, + pageSubscriberToPageComponent, +} from "@openstatus/db/src/schema"; +import { + createPageSubscriber, + getSubscriberByToken, + hasPendingSubscriber, + unsubscribeSubscriber, + updateSubscriberScope, + upsertSelfSignupSubscriber, + verifySelfSignupSubscriber, +} from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -28,15 +38,6 @@ import { withTestTransaction, } from "../../../test/helpers"; import { ForbiddenError } from "../../errors"; -import { - createPageSubscriber, - getSubscriberByToken, - hasPendingSubscriber, - unsubscribeSubscriber, - updateSubscriberScope, - upsertSelfSignupSubscriber, - verifySelfSignupSubscriber, -} from "../index.ts"; // Seeded data we lean on (see packages/db/src/seed.mts): // workspace 1 = team plan, has status-subscribers=true diff --git a/packages/services/src/page/__tests__/page.test.ts b/packages/services/src/page/__tests__/page.test.ts index fd8673da..429f682d 100644 --- a/packages/services/src/page/__tests__/page.test.ts +++ b/packages/services/src/page/__tests__/page.test.ts @@ -1,7 +1,7 @@ +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; + import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/status-report/__tests__/status-report.test.ts b/packages/services/src/status-report/__tests__/status-report.test.ts index 7104b8d1..fb7bab4d 100644 --- a/packages/services/src/status-report/__tests__/status-report.test.ts +++ b/packages/services/src/status-report/__tests__/status-report.test.ts @@ -1,3 +1,12 @@ +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + test, +} from "bun:test"; + import { db, eq } from "@openstatus/db"; import { page, @@ -8,14 +17,6 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { - afterAll, - beforeAll, - beforeEach, - describe, - test, -} from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/workspace/__tests__/workspace.test.ts b/packages/services/src/workspace/__tests__/workspace.test.ts index 6efc00f5..21dde2ae 100644 --- a/packages/services/src/workspace/__tests__/workspace.test.ts +++ b/packages/services/src/workspace/__tests__/workspace.test.ts @@ -1,8 +1,14 @@ +import { beforeAll, describe, expect, test } from "bun:test"; + import { eq } from "@openstatus/db"; import { workspace } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { beforeAll, describe, test } from "@std/testing/bdd"; +import { + getWorkspace, + getWorkspaceWithUsage, + listWorkspaces, + updateWorkspaceName, +} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -13,12 +19,6 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; -import { - getWorkspace, - getWorkspaceWithUsage, - listWorkspaces, - updateWorkspaceName, -} from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/test/helpers.ts b/packages/services/test/helpers.ts index 688bdf15..7dda2267 100644 --- a/packages/services/test/helpers.ts +++ b/packages/services/test/helpers.ts @@ -1,3 +1,5 @@ +import { expect } from "bun:test"; + import { and, db, desc, eq, inArray } from "@openstatus/db"; import { type Scope, @@ -8,7 +10,6 @@ import { selectWorkspaceSchema, workspace as workspaceTable, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; import type { Actor, DB, DrizzleTx, ServiceContext } from "../src/context"; import type { Workspace } from "../src/types"; diff --git a/packages/services/tsconfig.json b/packages/services/tsconfig.json index 0da708f7..54a1ac32 100644 --- a/packages/services/tsconfig.json +++ b/packages/services/tsconfig.json @@ -1,9 +1,8 @@ { - "extends": "@openstatus/tsconfig/base.json", + "extends": "@openstatus/tsconfig/react-library.json", "include": ["src", "test"], "exclude": ["dist", "build", "node_modules"], "compilerOptions": { - "module": "ESNext", "moduleResolution": "bundler" } } diff --git a/packages/status-fetcher/__tests__/fetch.test.ts b/packages/status-fetcher/__tests__/fetch.test.ts index 7bafe97d..36556d49 100644 --- a/packages/status-fetcher/__tests__/fetch.test.ts +++ b/packages/status-fetcher/__tests__/fetch.test.ts @@ -1,6 +1,5 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; -import { spy } from "@std/testing/mock"; +import { beforeEach, describe, expect, it, mock } from "bun:test"; + import { Cause, Effect, Exit, Option } from "effect"; import { z } from "zod"; @@ -11,7 +10,7 @@ const TEST_URL = "https://api.example.com/status"; type FetchImpl = (url: string, init?: RequestInit) => Promise; const installMockFetch = (impl: FetchImpl) => { - const fn = spy(impl); + const fn = mock(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; @@ -80,7 +79,7 @@ describe("fetchJson", () => { expect(err.httpStatus).toBe(404); expect(err.fetcherName).toBe("test"); expect(err.entryId).toBe("x"); - expect(fetchMock.calls.length).toBe(1); + expect(fetchMock.mock.calls.length).toBe(1); }); it("retries up to 3 times on 5xx then fails", async () => { @@ -93,7 +92,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBe(503); - expect(fetchMock.calls.length).toBe(4); + expect(fetchMock.mock.calls.length).toBe(4); }); it("retries up to 3 times on network error then fails", async () => { @@ -106,7 +105,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBeUndefined(); - expect(fetchMock.calls.length).toBe(4); + expect(fetchMock.mock.calls.length).toBe(4); }); it("fails with FetchError on schema mismatch without retrying", async () => { @@ -119,7 +118,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.cause).toBeInstanceOf(Error); - expect(fetchMock.calls.length).toBe(1); + expect(fetchMock.mock.calls.length).toBe(1); }); it("applies default User-Agent and Accept headers", async () => { @@ -201,7 +200,7 @@ describe("fetchText", () => { const exit = await Effect.runPromiseExit(fetchText({ url: TEST_URL })); const err = expectFailure(exit); expect(err.httpStatus).toBe(500); - expect(fetchMock.calls.length).toBe(4); + expect(fetchMock.mock.calls.length).toBe(4); }); }); diff --git a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts index ae7a8d2c..09baa515 100644 --- a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import type { StatusPageEntry } from "../../src/types"; @@ -114,11 +113,8 @@ describe("AtlassianFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("Etc/UTC"); expect(typeof result.updated_at).toBe("number"); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe( + expect(fetchMock).toHaveBeenCalledWith( "https://www.githubstatus.com/api/v2/summary.json", - ); - expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -238,9 +234,10 @@ describe("AtlassianFetcher", () => { await runFetcher(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); - expect(call.args[1]).toEqual(expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith( + "https://custom.endpoint.com/status.json", + expect.any(Object), + ); }); it("should fail with FetchError on non-200 response", async () => { @@ -335,11 +332,10 @@ describe("AtlassianFetcher", () => { const incidents = await runIncidents(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe( + expect(fetchMock).toHaveBeenCalledWith( "https://www.githubstatus.com/api/v2/incidents.json", + expect.any(Object), ); - expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(2); expect(incidents[0]).toMatchObject({ providerIncidentId: "abc", diff --git a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts index d1bb0869..355f070f 100644 --- a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { BetterStackFetcher } from "../../src/fetchers/betterstack"; import type { StatusPageEntry } from "../../src/types"; @@ -122,9 +121,8 @@ describe("BetterStackFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("America/New_York"); expect(typeof result.updated_at).toBe("number"); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://status.test.com/index.json"); - expect(call.args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledWith( + "https://status.test.com/index.json", expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -242,9 +240,10 @@ describe("BetterStackFetcher", () => { await runFetcher(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); - expect(call.args[1]).toEqual(expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith( + "https://custom.endpoint.com/status.json", + expect.any(Object), + ); }); it("should fail with FetchError on 4xx response", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/components.test.ts b/packages/status-fetcher/__tests__/fetchers/components.test.ts index d87f3ae3..15b1aaf4 100644 --- a/packages/status-fetcher/__tests__/fetchers/components.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/components.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; @@ -82,11 +81,10 @@ function itNormalizes( const components = await runComponents(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe( + expect(fetchMock).toHaveBeenCalledWith( `${entry.status_page_url}/api/v2/components.json`, + expect.any(Object), ); - expect(call.args[1]).toEqual(expect.any(Object)); // group container "grp" is excluded; only the three leaves remain expect(components).toHaveLength(3); diff --git a/packages/status-fetcher/__tests__/fetchers/custom.test.ts b/packages/status-fetcher/__tests__/fetchers/custom.test.ts index a3091470..bd435051 100644 --- a/packages/status-fetcher/__tests__/fetchers/custom.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/custom.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { CustomApiFetcher } from "../../src/fetchers/custom"; import type { StatusPageEntry } from "../../src/types"; diff --git a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts index d0a5194c..548186a4 100644 --- a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts @@ -1,5 +1,5 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; + import { Exit } from "effect"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; diff --git a/packages/status-fetcher/__tests__/fetchers/html.test.ts b/packages/status-fetcher/__tests__/fetchers/html.test.ts index ddbac6a1..209577d1 100644 --- a/packages/status-fetcher/__tests__/fetchers/html.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/html.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { HtmlScraperFetcher } from "../../src/fetchers/html"; import type { StatusPageEntry } from "../../src/types"; @@ -93,9 +92,8 @@ describe("HtmlScraperFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://status.test.com"); - expect(call.args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledWith( + "https://status.test.com", expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "Mozilla/5.0 (compatible; OpenStatus-Bot/1.0)", diff --git a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts index 6a759fdd..cbc6f75b 100644 --- a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; import type { StatusPageEntry } from "../../src/types"; @@ -112,9 +111,8 @@ describe("IncidentioFetcher", () => { expect(result.status).toBe("operational"); expect(result.description).toBe("All Systems Operational"); expect(typeof result.updated_at).toBe("number"); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://status.test.com/api/v2/summary.json"); - expect(call.args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledWith( + "https://status.test.com/api/v2/summary.json", expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -236,9 +234,10 @@ describe("IncidentioFetcher", () => { await runFetcher(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://custom.endpoint.com/summary.json"); - expect(call.args[1]).toEqual(expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith( + "https://custom.endpoint.com/summary.json", + expect.any(Object), + ); }); it("should fail with FetchError on 5xx response", async () => { @@ -324,11 +323,10 @@ describe("IncidentioFetcher", () => { const incidents = await runIncidents(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe( + expect(fetchMock).toHaveBeenCalledWith( "https://status.linear.app/api/v2/incidents.json", + expect.any(Object), ); - expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(1); expect(incidents[0]).toMatchObject({ providerIncidentId: "INC-1", diff --git a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts index b7c528cd..5abaf1c1 100644 --- a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { beforeEach, describe, it } from "@std/testing/bdd"; +import { beforeEach, describe, expect, it } from "bun:test"; import { InstatusFetcher } from "../../src/fetchers/instatus"; import type { StatusPageEntry } from "../../src/types"; @@ -110,9 +109,8 @@ describe("InstatusFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://test.instatus.com/summary.json"); - expect(call.args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledWith( + "https://test.instatus.com/summary.json", expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -232,9 +230,10 @@ describe("InstatusFetcher", () => { await runFetcher(fetcher, entry); - const call = fetchMock.calls[fetchMock.calls.length - 1]; - expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); - expect(call.args[1]).toEqual(expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith( + "https://custom.endpoint.com/status.json", + expect.any(Object), + ); }); it("should fail with FetchError on non-200 response (after retries)", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts index 01dd6918..72c6e9b3 100644 --- a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; -import { spy } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test"; import { UptimeRobotFetcher } from "../../src/fetchers/uptimerobot"; import type { StatusPageEntry } from "../../src/types"; @@ -140,9 +138,8 @@ describe("UptimeRobotFetcher", () => { expect(result.description).toBe("0 monitors down (3 total)"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - const lastCall = fetchMock.calls[fetchMock.calls.length - 1]; - expect(lastCall.args[0]).toBe(ENDPOINT); - expect(lastCall.args[1]).toEqual( + expect(fetchMock).toHaveBeenCalledWith( + ENDPOINT, expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -275,7 +272,7 @@ describe("UptimeRobotFetcher", () => { }); it("unknown statusClass folds to operational with a warn", async () => { - const warnSpy = spy(() => {}); + const warnSpy = mock(() => {}); const originalWarn = console.warn; console.warn = warnSpy; @@ -290,7 +287,7 @@ describe("UptimeRobotFetcher", () => { expect(result.severity).toBe("none"); expect(result.status).toBe("operational"); - expect(warnSpy.calls.length).toBeGreaterThan(0); + expect(warnSpy).toHaveBeenCalled(); } finally { console.warn = originalWarn; } diff --git a/packages/status-fetcher/__tests__/helpers.ts b/packages/status-fetcher/__tests__/helpers.ts index bcf6a527..20f73dba 100644 --- a/packages/status-fetcher/__tests__/helpers.ts +++ b/packages/status-fetcher/__tests__/helpers.ts @@ -1,4 +1,5 @@ -import { spy } from "@std/testing/mock"; +import { mock } from "bun:test"; + import { Cause, Effect, Exit, Option } from "effect"; import type { FetchError } from "../src/fetch"; @@ -13,7 +14,7 @@ import type { type FetchImpl = (url: string, init?: RequestInit) => Promise; export const installMockFetch = (impl: FetchImpl) => { - const fn = spy(impl); + const fn = mock(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; diff --git a/packages/status-fetcher/__tests__/integration.test.ts b/packages/status-fetcher/__tests__/integration.test.ts index 73ab88a0..4c171dbd 100644 --- a/packages/status-fetcher/__tests__/integration.test.ts +++ b/packages/status-fetcher/__tests__/integration.test.ts @@ -1,5 +1,5 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; + import { Effect } from "effect"; import { fetchers as allFetchers } from "../src/fetchers"; diff --git a/packages/status-fetcher/__tests__/utils.test.ts b/packages/status-fetcher/__tests__/utils.test.ts index f2d78f56..ae1179a3 100644 --- a/packages/status-fetcher/__tests__/utils.test.ts +++ b/packages/status-fetcher/__tests__/utils.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { inferStatus, urlHostnameEndsWith } from "../src/utils"; diff --git a/packages/status-fetcher/package.json b/packages/status-fetcher/package.json index 8f4d305d..8e7c9118 100644 --- a/packages/status-fetcher/package.json +++ b/packages/status-fetcher/package.json @@ -11,9 +11,8 @@ "./types": "./src/types.ts" }, "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports", - "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", + "test": "bun test", + "test:watch": "bun test --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -22,7 +21,6 @@ "zod": "catalog:" }, "devDependencies": { - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19" + "@types/bun": "latest" } } diff --git a/packages/status-fetcher/tsconfig.json b/packages/status-fetcher/tsconfig.json index 0d9806db..9d6eaf3f 100644 --- a/packages/status-fetcher/tsconfig.json +++ b/packages/status-fetcher/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "target": "ES2022", "module": "ESNext", + "lib": ["ES2022"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "noEmit": true, diff --git a/packages/subscriptions/package.json b/packages/subscriptions/package.json index ada82745..c50cc3b9 100644 --- a/packages/subscriptions/package.json +++ b/packages/subscriptions/package.json @@ -15,8 +15,7 @@ } }, "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test -A --no-check --sloppy-imports" + "test": "bun test" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -28,8 +27,7 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", + "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/packages/subscriptions/src/channels/email.test.ts b/packages/subscriptions/src/channels/email.test.ts index bda44066..6772aceb 100644 --- a/packages/subscriptions/src/channels/email.test.ts +++ b/packages/subscriptions/src/channels/email.test.ts @@ -1,8 +1,6 @@ -import "../test-preload.ts"; +import { beforeEach, describe, expect, spyOn, test } from "bun:test"; + import { EmailClient } from "@openstatus/emails"; -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import type { PageUpdate, Subscription } from "../types"; import { @@ -14,8 +12,15 @@ import { // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -let sendPageSubscriptionMock: Stub; -let sendStatusReportUpdateMock: Stub; +const sendPageSubscriptionMock = spyOn( + EmailClient.prototype, + "sendPageSubscription", +).mockResolvedValue(undefined); + +const sendStatusReportUpdateMock = spyOn( + EmailClient.prototype, + "sendStatusReportUpdate", +).mockResolvedValue(undefined); function makeSub(overrides: Partial = {}): Subscription { return { @@ -46,21 +51,8 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - sendPageSubscriptionMock = stub( - EmailClient.prototype, - "sendPageSubscription", - () => Promise.resolve(undefined), - ); - sendStatusReportUpdateMock = stub( - EmailClient.prototype, - "sendStatusReportUpdate", - () => Promise.resolve(undefined), - ); -}); - -afterEach(() => { - sendPageSubscriptionMock.restore(); - sendStatusReportUpdateMock.restore(); + sendPageSubscriptionMock.mockClear(); + sendStatusReportUpdateMock.mockClear(); }); // ─── validateEmailConfig ────────────────────────────────────────────────────── @@ -102,8 +94,8 @@ describe("sendEmailVerification", () => { const sub = makeSub({ email: "user@example.com", pageName: "My Page" }); await sendEmailVerification(sub, "https://example.com/verify/abc"); - assertSpyCalls(sendPageSubscriptionMock, 1); - const [args] = sendPageSubscriptionMock.calls[0].args; + expect(sendPageSubscriptionMock).toHaveBeenCalledTimes(1); + const [args] = sendPageSubscriptionMock.mock.calls[0]; expect(args.to).toBe("user@example.com"); expect(args.link).toBe("https://example.com/verify/abc"); expect(args.page).toBe("My Page"); @@ -115,13 +107,13 @@ describe("sendEmailVerification", () => { describe("sendEmailNotifications", () => { test("does nothing for an empty subscriptions array", async () => { await sendEmailNotifications([], makeUpdate()); - assertSpyCalls(sendStatusReportUpdateMock, 0); + expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); }); test("filters out subscriptions without an email address", async () => { const sub = makeSub({ email: undefined }); await sendEmailNotifications([sub], makeUpdate()); - assertSpyCalls(sendStatusReportUpdateMock, 0); + expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); }); test("calls sendStatusReportUpdate once with all valid subscribers", async () => { @@ -131,8 +123,8 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub1, sub2], update); - assertSpyCalls(sendStatusReportUpdateMock, 1); - const [args] = sendStatusReportUpdateMock.calls[0].args; + expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); + const [args] = sendStatusReportUpdateMock.mock.calls[0]; expect(args.subscribers).toHaveLength(2); expect(args.subscribers[0].email).toBe("a@example.com"); expect(args.subscribers[1].email).toBe("b@example.com"); @@ -146,7 +138,7 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub], update); - const [args] = sendStatusReportUpdateMock.calls[0].args; + const [args] = sendStatusReportUpdateMock.mock.calls[0]; expect(args.pageComponents).toEqual(["API", "Database"]); }); @@ -154,7 +146,7 @@ describe("sendEmailNotifications", () => { const sub = makeSub(); await sendEmailNotifications([sub], makeUpdate({ updateId: 77 })); - const [args] = sendStatusReportUpdateMock.calls[0].args; + const [args] = sendStatusReportUpdateMock.mock.calls[0]; expect(args.idempotencyKey).toBe("status-report-update:77"); }); @@ -165,7 +157,7 @@ describe("sendEmailNotifications", () => { makeUpdate({ id: 17, updateId: undefined, status: "maintenance" }), ); - const [args] = sendStatusReportUpdateMock.calls[0].args; + const [args] = sendStatusReportUpdateMock.mock.calls[0]; expect(args.idempotencyKey).toBe("page-update:17:maintenance"); }); }); diff --git a/packages/subscriptions/src/channels/index.test.ts b/packages/subscriptions/src/channels/index.test.ts index d635918b..fc6df14f 100644 --- a/packages/subscriptions/src/channels/index.test.ts +++ b/packages/subscriptions/src/channels/index.test.ts @@ -1,6 +1,4 @@ -import "../test-preload.ts"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; +import { describe, expect, test } from "bun:test"; import { getChannel } from "./index"; diff --git a/packages/subscriptions/src/channels/webhook.test.ts b/packages/subscriptions/src/channels/webhook.test.ts index d17be6f4..a10a9b41 100644 --- a/packages/subscriptions/src/channels/webhook.test.ts +++ b/packages/subscriptions/src/channels/webhook.test.ts @@ -1,6 +1,4 @@ -import { expect } from "@std/expect"; -import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; -import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; +import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; import { webhookPayloadSchema } from "../payload"; import type { PageUpdate, Subscription } from "../types"; @@ -17,21 +15,7 @@ import { const SLACK_URL = "https://hooks.slack.com/services/T1/B1/XXX"; const DISCORD_URL = "https://discord.com/api/webhooks/1/xxx"; -let fetchMock: Stub; - -function setFetch( - impl: ( - input: Request | string | URL, - init?: RequestInit, - ) => Promise, -) { - fetchMock?.restore(); - fetchMock = stub(globalThis, "fetch", impl); -} - -function resolveFetch(response: Response) { - setFetch(() => Promise.resolve(response)); -} +let fetchMock: any; function makeSub(overrides: Partial = {}): Subscription { return { @@ -62,13 +46,11 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - fetchMock = stub(globalThis, "fetch", () => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock = spyOn(global, "fetch"); }); afterEach(() => { - fetchMock.restore(); + fetchMock.mockRestore(); }); // ─── validateWebhookConfig ──────────────────────────────────────────────────── @@ -117,7 +99,7 @@ describe("sendWebhookVerification", () => { }); test("resolves when fetch returns 200", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub(); await expect( sendWebhookVerification(sub, "https://example.com/verify/abc"), @@ -125,7 +107,7 @@ describe("sendWebhookVerification", () => { }); test("throws when fetch returns a non-ok status", async () => { - resolveFetch( + fetchMock.mockResolvedValue( new Response(null, { status: 500, statusText: "Server Error" }), ); const sub = makeSub(); @@ -135,15 +117,15 @@ describe("sendWebhookVerification", () => { }); test("posts to the correct URL with the expected payload", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ token: "my-token", webhookUrl: "https://hooks.example.com/sub", }); await sendWebhookVerification(sub, "https://example.com/verify/my-token"); - assertSpyCalls(fetchMock, 1); - const [url, init] = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, init] = fetchMock.mock.calls[0]; expect(url).toBe("https://hooks.example.com/sub"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -159,11 +141,11 @@ describe("sendWebhookNotifications", () => { test("skips subscriptions without a webhookUrl", async () => { const sub = makeSub({ webhookUrl: undefined }); await sendWebhookNotifications([sub], makeUpdate()); - assertSpyCalls(fetchMock, 0); + expect(fetchMock).not.toHaveBeenCalled(); }); test("sends a POST request to each webhook URL", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub1 = makeSub({ webhookUrl: "https://hooks.slack.com/services/T1/B1/aaa", }); @@ -173,14 +155,14 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub1, sub2], makeUpdate()); - assertSpyCalls(fetchMock, 2); - const urls = fetchMock.calls.map((c) => c.args[0]); + expect(fetchMock).toHaveBeenCalledTimes(2); + const urls = fetchMock.mock.calls.map(([url]: [string]) => url); expect(urls).toContain("https://hooks.slack.com/services/T1/B1/aaa"); expect(urls).toContain("https://hooks.slack.com/services/T2/B2/bbb"); }); test("sends a generic JSON payload to non-Slack/Discord URLs", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const generic = makeSub({ id: 101, webhookUrl: "https://example.com/webhook", @@ -192,19 +174,19 @@ describe("sendWebhookNotifications", () => { makeUpdate({ updateId: 42 }), ); - assertSpyCalls(fetchMock, 2); + expect(fetchMock).toHaveBeenCalledTimes(2); const byUrl = new Map( - fetchMock.calls.map((c) => { - const [url, init] = c.args as [string, RequestInit]; - return [url, JSON.parse(init.body as string)]; - }), + fetchMock.mock.calls.map(([url, init]: [string, RequestInit]) => [ + url, + JSON.parse(init.body as string), + ]), ); expect(byUrl.get("https://example.com/webhook").type).toBe("status_report"); expect(byUrl.get(SLACK_URL).attachments).toBeDefined(); }); test("the status_report body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -218,14 +200,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("the maintenance body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -238,14 +220,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("applies custom headers from channelConfig", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ channelConfig: JSON.stringify({ headers: [{ key: "X-Custom-Header", value: "my-value" }], @@ -254,17 +236,17 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const headers = init?.headers as Record; expect(headers["X-Custom-Header"]).toBe("my-value"); }); test("continues sending to remaining webhooks when one keeps failing", async () => { const failUrl = "https://hooks.slack.com/services/T1/B1/fail"; - setFetch((input) => - String(input) === failUrl + fetchMock.mockImplementation(async (url: string) => + url === failUrl ? Promise.reject(new Error("Network error")) - : Promise.resolve(new Response(null, { status: 200 })), + : new Response(null, { status: 200 }), ); const sub1 = makeSub({ webhookUrl: failUrl }); @@ -276,22 +258,17 @@ describe("sendWebhookNotifications", () => { sendWebhookNotifications([sub1, sub2], makeUpdate()), ).resolves.toBeUndefined(); - const calls = fetchMock.calls.map((c) => String(c.args[0])); + const calls = fetchMock.mock.calls.map(([url]: [string]) => url); expect(calls).toContain("https://hooks.slack.com/services/T2/B2/succeed"); }); test("retries transient failures then succeeds", async () => { let attempts = 0; - setFetch(() => { + fetchMock.mockImplementation(async () => { attempts += 1; - return Promise.resolve( - attempts < 3 - ? new Response(null, { - status: 503, - statusText: "Service Unavailable", - }) - : new Response(null, { status: 200 }), - ); + return attempts < 3 + ? new Response(null, { status: 503, statusText: "Service Unavailable" }) + : new Response(null, { status: 200 }); }); await expect( @@ -302,13 +279,13 @@ describe("sendWebhookNotifications", () => { }); test("does not retry non-retryable 4xx responses", async () => { - resolveFetch( + fetchMock.mockResolvedValue( new Response(null, { status: 400, statusText: "Bad Request" }), ); await sendWebhookNotifications([makeSub()], makeUpdate()); - assertSpyCalls(fetchMock, 1); + expect(fetchMock).toHaveBeenCalledTimes(1); }); }); @@ -336,31 +313,31 @@ describe("detectWebhookFlavor", () => { describe("sendWebhookNotifications (flavor detection)", () => { test("emits Slack blocks payload for hooks.slack.com URLs", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: SLACK_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const body = JSON.parse(init?.body as string); expect(body.attachments).toBeDefined(); expect(body.attachments[0].blocks).toBeInstanceOf(Array); }); test("emits Discord embed payload for discord.com URLs", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const body = JSON.parse(init?.body as string); expect(body.embeds).toBeInstanceOf(Array); expect(body.embeds[0].title).toBe("Test Incident"); }); test("Slack payload includes manage/unsubscribe links", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", pageSlug: "demo", @@ -368,7 +345,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const stringified = init?.body as string; expect(stringified).toContain("https://demo.openstatus.dev/manage/tok-123"); expect(stringified).toContain( @@ -377,7 +354,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Slack payload uses custom domain when present", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", customDomain: "status.partner.com", @@ -385,18 +362,18 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const stringified = init?.body as string; expect(stringified).toContain("https://status.partner.com/manage/tok-123"); }); test("Slack payload links to the event details and the page origin", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ pageSlug: "demo", pageName: "Demo" }); await sendWebhookNotifications([sub], makeUpdate({ id: 99 })); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const body = JSON.parse(init?.body as string); const stringified = init?.body as string; // title stays in a plain_text header block @@ -411,7 +388,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Discord embed url points at the event; maintenance uses the maintenance path", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL, pageSlug: "demo", @@ -423,7 +400,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { makeUpdate({ id: 7, status: "maintenance" }), ); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const body = JSON.parse(init?.body as string); expect(body.embeds[0].url).toBe( "https://demo.openstatus.dev/events/maintenance/7", @@ -607,14 +584,14 @@ describe("buildTestPayload", () => { describe("sendTestWebhookRequest", () => { test("POSTs flavor-appropriate payload", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", }); - assertSpyCalls(fetchMock, 1); - const [url, init] = fetchMock.calls[0].args; + expect(fetchMock).toHaveBeenCalledTimes(1); + const [url, init] = fetchMock.mock.calls[0]; expect(url).toBe("https://example.com/hook"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -622,7 +599,9 @@ describe("sendTestWebhookRequest", () => { }); test("throws on non-2xx response", async () => { - resolveFetch(new Response(null, { status: 404, statusText: "Not Found" })); + fetchMock.mockResolvedValue( + new Response(null, { status: 404, statusText: "Not Found" }), + ); await expect( sendTestWebhookRequest({ url: "https://example.com/hook", @@ -632,14 +611,14 @@ describe("sendTestWebhookRequest", () => { }); test("passes custom headers", async () => { - resolveFetch(new Response(null, { status: 200 })); + fetchMock.mockResolvedValue(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", headers: { "X-Custom": "abc" }, }); - const [, init] = fetchMock.calls[0].args; + const [, init] = fetchMock.mock.calls[0]; const headers = init?.headers as Record; expect(headers["X-Custom"]).toBe("abc"); }); diff --git a/packages/subscriptions/src/dispatcher.test.ts b/packages/subscriptions/src/dispatcher.test.ts index 8888bc93..4cb54ac1 100644 --- a/packages/subscriptions/src/dispatcher.test.ts +++ b/packages/subscriptions/src/dispatcher.test.ts @@ -1,20 +1,19 @@ -import "./test-preload.ts"; -import { db, eq } from "@openstatus/db"; -import { - pageSubscriber, - pageSubscriberToPageComponent, -} from "@openstatus/db/src/schema"; -import { EmailClient } from "@openstatus/emails"; -import { expect } from "@std/expect"; import { afterAll, - afterEach, beforeAll, beforeEach, describe, + expect, + spyOn, test, -} from "@std/testing/bdd"; -import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; +} from "bun:test"; + +import { db, eq } from "@openstatus/db"; +import { + pageSubscriber, + pageSubscriberToPageComponent, +} from "@openstatus/db/src/schema"; +import { EmailClient } from "@openstatus/emails"; import { dispatchPageUpdate } from "./dispatcher"; import type { PageUpdate } from "./types"; @@ -22,8 +21,10 @@ import type { PageUpdate } from "./types"; // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -let sendStatusReportUpdateMock: Stub; -let rejectNextSend: Error | null = null; +const sendStatusReportUpdateMock = spyOn( + EmailClient.prototype, + "sendStatusReportUpdate", +).mockResolvedValue(undefined); // IDs present in the seeded database const PAGE_ID = 1; // slug: "status" @@ -104,23 +105,7 @@ beforeAll(async () => { afterAll(cleanAll); beforeEach(() => { - rejectNextSend = null; - sendStatusReportUpdateMock = stub( - EmailClient.prototype, - "sendStatusReportUpdate", - () => { - if (rejectNextSend) { - const error = rejectNextSend; - rejectNextSend = null; - return Promise.reject(error); - } - return Promise.resolve(undefined); - }, - ); -}); - -afterEach(() => { - sendStatusReportUpdateMock.restore(); + sendStatusReportUpdateMock.mockClear(); }); // ─── dispatchPageUpdate - component filtering ───────────────────────────────── @@ -131,8 +116,8 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - assertSpyCalls(sendStatusReportUpdateMock, 1); - const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; + expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); + const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -145,7 +130,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; + const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -158,7 +143,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1, COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; + const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -169,8 +154,8 @@ describe("dispatchPageUpdate - component filtering", () => { test("notifies only the entire-page subscriber when update has no affected components", async () => { await dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })); - assertSpyCalls(sendStatusReportUpdateMock, 1); - const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; + expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); + const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; expect(subscribers).toHaveLength(1); expect(subscribers[0].email).toBe(EMAILS.entirePage); @@ -182,7 +167,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; + const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).not.toContain(EMAILS.component2); @@ -197,11 +182,11 @@ describe("dispatchPageUpdate - edge cases", () => { makePageUpdate({ pageId: 99999, pageComponentIds: [COMPONENT_1] }), ); - assertSpyCalls(sendStatusReportUpdateMock, 0); + expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); }); test("does not propagate channel failure — resolves even when sendStatusReportUpdate throws", async () => { - rejectNextSend = new Error("SMTP failure"); + sendStatusReportUpdateMock.mockRejectedValueOnce(new Error("SMTP failure")); await expect( dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })), diff --git a/packages/subscriptions/src/test-preload.ts b/packages/subscriptions/src/test-preload.ts index b26048d3..29170704 100644 --- a/packages/subscriptions/src/test-preload.ts +++ b/packages/subscriptions/src/test-preload.ts @@ -1,11 +1,6 @@ /** - * Test env setup. Import this FIRST in any test file so env vars are set - * before module-level env validations (e.g. @openstatus/emails, @openstatus/db) - * fire on import. - * - * Bun's test runner set NODE_ENV=test automatically; Deno does not, so we set - * it here. The @openstatus/db env hack maps NODE_ENV=test to the local turso - * URL, and @openstatus/emails validates RESEND_API_KEY at module load. + * Preload file for bun test. + * Runs before any test file is loaded, ensuring env vars are set + * before module-level env validations (e.g. @openstatus/emails) fire. */ -process.env.NODE_ENV = "test"; -process.env.RESEND_API_KEY ??= "test-key"; +process.env.RESEND_API_KEY = "test-key"; diff --git a/packages/subscriptions/tsconfig.json b/packages/subscriptions/tsconfig.json index 4225a2de..868037cf 100644 --- a/packages/subscriptions/tsconfig.json +++ b/packages/subscriptions/tsconfig.json @@ -1,10 +1,12 @@ { "extends": "@openstatus/tsconfig/base.json", "compilerOptions": { + "lib": ["ES2022", "DOM"], "module": "ESNext", "target": "ES2022", "moduleResolution": "bundler", - "jsx": "react-jsx" + "jsx": "react-jsx", + "types": ["bun"] }, "include": [".", "src"], "exclude": ["dist", "build", "node_modules"] diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json deleted file mode 100644 index ee345766..00000000 --- a/packages/test-utils/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@openstatus/test-utils", - "version": "1.0.0", - "private": true, - "main": "src/index.ts", - "exports": { - ".": "./src/index.ts" - }, - "scripts": { - "check": "deno check --sloppy-imports ." - }, - "dependencies": { - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19" - }, - "devDependencies": { - "@openstatus/tsconfig": "workspace:*", - "typescript": "catalog:" - } -} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts deleted file mode 100644 index 25c2570b..00000000 --- a/packages/test-utils/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Single import surface for migrated tests: `import { ... } from "@openstatus/test-utils"`. -// Importing this module registers the Bun-compat matchers (./matchers side-effect). -import "./matchers.ts"; - -export { - after, - afterAll, - afterEach, - before, - beforeAll, - beforeEach, - describe, - it, - test, -} from "./runner.ts"; -export { expect } from "jsr:@std/expect"; -export { type MockFn, mock } from "./mock-fn.ts"; -export { - assertSpyCall, - assertSpyCalls, - returnsNext, - type Spy, - spy, - type Stub, - stub, -} from "jsr:@std/testing/mock"; -export { FakeTime } from "jsr:@std/testing/time"; diff --git a/packages/test-utils/src/matchers.ts b/packages/test-utils/src/matchers.ts deleted file mode 100644 index 36d58bd3..00000000 --- a/packages/test-utils/src/matchers.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { expect } from "jsr:@std/expect"; - -// @std/expect stopped re-exporting its matcher-context type; these matchers only -// read `value`, so a minimal local shape is enough. -type ExpectMatcherContext = { value: unknown }; - -type MatcherResult = { pass: boolean; message: () => string }; - -const isObject = (v: unknown): v is Record => - typeof v === "object" && v !== null; - -const size = (v: unknown): number => { - if (typeof v === "string" || Array.isArray(v)) return v.length; - if (v instanceof Map || v instanceof Set) return v.size; - if (isObject(v)) return Object.keys(v).length; - return -1; -}; - -// Bun's `expect` extension matchers, reimplemented on @std/expect so the ~150 -// existing call sites keep working under `deno test`. -expect.extend({ - toBeNumber(context: ExpectMatcherContext): MatcherResult { - const pass = - typeof context.value === "number" && !Number.isNaN(context.value); - return { pass, message: () => `expected ${context.value} to be a number` }; - }, - toBeString(context: ExpectMatcherContext): MatcherResult { - return { - pass: typeof context.value === "string", - message: () => `expected ${context.value} to be a string`, - }; - }, - toBeBoolean(context: ExpectMatcherContext): MatcherResult { - return { - pass: typeof context.value === "boolean", - message: () => `expected ${context.value} to be a boolean`, - }; - }, - toBeArray(context: ExpectMatcherContext): MatcherResult { - return { - pass: Array.isArray(context.value), - message: () => `expected ${context.value} to be an array`, - }; - }, - toBeTrue(context: ExpectMatcherContext): MatcherResult { - return { - pass: context.value === true, - message: () => `expected ${context.value} to be true`, - }; - }, - toBeFalse(context: ExpectMatcherContext): MatcherResult { - return { - pass: context.value === false, - message: () => `expected ${context.value} to be false`, - }; - }, - toBeNil(context: ExpectMatcherContext): MatcherResult { - return { - pass: context.value === null || context.value === undefined, - message: () => `expected ${context.value} to be null or undefined`, - }; - }, - toBeEmpty(context: ExpectMatcherContext): MatcherResult { - return { - pass: size(context.value) === 0, - message: () => `expected ${context.value} to be empty`, - }; - }, - toBeOneOf( - context: ExpectMatcherContext, - expected: readonly unknown[], - ): MatcherResult { - return { - pass: expected.includes(context.value), - message: () => - `expected ${context.value} to be one of ${JSON.stringify(expected)}`, - }; - }, - toContainValue(context: ExpectMatcherContext, value: unknown): MatcherResult { - const pass = - isObject(context.value) && Object.values(context.value).includes(value); - return { pass, message: () => `expected object to contain value ${value}` }; - }, - toContainKey(context: ExpectMatcherContext, key: string): MatcherResult { - const pass = - isObject(context.value) && Object.keys(context.value).includes(key); - return { pass, message: () => `expected object to contain key ${key}` }; - }, - pass(_context: ExpectMatcherContext, _message?: string): MatcherResult { - return { pass: true, message: () => _message ?? "passed" }; - }, - fail(_context: ExpectMatcherContext, message?: string): MatcherResult { - return { pass: false, message: () => message ?? "failed" }; - }, -}); diff --git a/packages/test-utils/src/mock-fn.ts b/packages/test-utils/src/mock-fn.ts deleted file mode 100644 index 2d71214f..00000000 --- a/packages/test-utils/src/mock-fn.ts +++ /dev/null @@ -1,112 +0,0 @@ -// Bun-compatible `mock()` for the Deno migration. Bun's mock function isn't -// available under `deno test`; this reimplements the subset our suites use -// (the jest-style `.mock.calls` + `.mockX()` helpers) on plain closures. -// -// NOTE: bun's `mock.module(specifier, factory)` has no Deno equivalent and is -// intentionally NOT provided here — module replacement is done via the -// `--import-map` flag and test-double modules instead. - -// oxlint-disable-next-line typescript/no-explicit-any -type AnyFn = (...args: any[]) => any; - -interface MockState { - // oxlint-disable-next-line typescript/no-explicit-any - calls: any[][]; - results: { type: "return" | "throw"; value: unknown }[]; -} - -export interface MockFn extends AnyFn { - mock: MockState; - mockClear(): MockFn; - mockReset(): MockFn; - mockImplementation(fn: AnyFn): MockFn; - mockImplementationOnce(fn: AnyFn): MockFn; - mockReturnValue(value: unknown): MockFn; - mockReturnValueOnce(value: unknown): MockFn; - mockResolvedValue(value: unknown): MockFn; - mockResolvedValueOnce(value: unknown): MockFn; - mockRejectedValue(value: unknown): MockFn; - mockRestore(): MockFn; -} - -export function mock(impl?: AnyFn): MockFn { - let defaultImpl = impl; - const onceQueue: AnyFn[] = []; - const state: MockState = { calls: [], results: [] }; - - // oxlint-disable-next-line typescript/no-explicit-any - const fn = ((...args: any[]) => { - state.calls.push(args); - const use = onceQueue.length ? onceQueue.shift() : defaultImpl; - try { - const value = use ? use(...args) : undefined; - state.results.push({ type: "return", value }); - return value; - } catch (err) { - state.results.push({ type: "throw", value: err }); - throw err; - } - }) as MockFn; - - fn.mock = state; - // Expose the @std/expect mock interface (Symbol.for("@MOCK")) so its - // `.toHaveBeenCalled*` matchers recognize this shim, not just `.mock.calls`. - Object.defineProperty(fn, Symbol.for("@MOCK"), { - get() { - return { - calls: state.calls.map((args, i) => { - const r = state.results[i]; - return { - args, - returned: r?.type === "return" ? r.value : undefined, - thrown: r?.type === "throw" ? r.value : undefined, - timestamp: 0, - returns: r?.type === "return", - throws: r?.type === "throw", - }; - }), - }; - }, - }); - fn.mockClear = () => { - state.calls = []; - state.results = []; - return fn; - }; - fn.mockReset = () => { - fn.mockClear(); - onceQueue.length = 0; - defaultImpl = undefined; - return fn; - }; - fn.mockImplementation = (f) => { - defaultImpl = f; - return fn; - }; - fn.mockImplementationOnce = (f) => { - onceQueue.push(f); - return fn; - }; - fn.mockReturnValue = (value) => { - defaultImpl = () => value; - return fn; - }; - fn.mockReturnValueOnce = (value) => { - onceQueue.push(() => value); - return fn; - }; - fn.mockResolvedValue = (value) => { - defaultImpl = () => Promise.resolve(value); - return fn; - }; - fn.mockResolvedValueOnce = (value) => { - onceQueue.push(() => Promise.resolve(value)); - return fn; - }; - fn.mockRejectedValue = (value) => { - defaultImpl = () => Promise.reject(value); - return fn; - }; - fn.mockRestore = () => fn; - return fn; -} diff --git a/packages/test-utils/src/runner.ts b/packages/test-utils/src/runner.ts deleted file mode 100644 index 55dd22f4..00000000 --- a/packages/test-utils/src/runner.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - describe as nodeDescribe, - it as nodeIt, - test as nodeTest, -} from "node:test"; - -type Body = () => void | Promise; -type BaseFn = (name: string, body: Body) => void; -type EachCase = readonly unknown[]; - -const formatName = (name: string, args: EachCase, index: number): string => { - let i = 0; - const interpolated = name.replace(/%[spdijfo%]/g, (token) => { - if (token === "%%") return "%"; - const arg = args[i++]; - return typeof arg === "string" ? arg : JSON.stringify(arg); - }); - return interpolated === name && args.length > 0 - ? `${name} [${index}]` - : interpolated; -}; - -const makeEach = - (base: BaseFn) => - (cases: readonly T[]) => - (name: string, body: (...args: T) => void | Promise): void => { - cases.forEach((args, index) => { - base(formatName(name, args, index), () => body(...args)); - }); - }; - -// node:test's `test`/`it`/`describe` lack Jest/Bun's `.each`; everything else -// (.skip/.todo/.only) exists natively and is preserved by reference. -type Augmented = F & { - each: ( - cases: readonly T[], - ) => (name: string, body: (...args: T) => void | Promise) => void; -}; - -const augment = (base: F): Augmented => { - const fn = base as Augmented; - fn.each = makeEach(base as unknown as BaseFn); - return fn; -}; - -export const test = augment(nodeTest); -export const it = augment(nodeIt); -export const describe = augment( - nodeDescribe as unknown as typeof nodeTest, -) as unknown as Augmented; -export { - after, - after as afterAll, - afterEach, - before, - before as beforeAll, - beforeEach, -} from "node:test"; diff --git a/packages/theme-store/package.json b/packages/theme-store/package.json index ffc39d71..cdb62553 100644 --- a/packages/theme-store/package.json +++ b/packages/theme-store/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/tinybird/package.json b/packages/tinybird/package.json index c575aa6a..17a465bc 100644 --- a/packages/tinybird/package.json +++ b/packages/tinybird/package.json @@ -3,9 +3,6 @@ "version": "0.0.0", "license": "MIT", "main": "src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, "dependencies": { "@chronark/zod-bird": "catalog:", "zod": "catalog:" diff --git a/packages/tracker/package.json b/packages/tracker/package.json index f73478cc..6f654a01 100644 --- a/packages/tracker/package.json +++ b/packages/tracker/package.json @@ -7,8 +7,7 @@ "author": "", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports .", - "test": "deno test --parallel -A --no-check --sloppy-imports" + "test": "bun test" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -17,8 +16,7 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", + "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/tracker/src/mock.ts b/packages/tracker/src/mock.ts index 50082d4c..5f338e46 100644 --- a/packages/tracker/src/mock.ts +++ b/packages/tracker/src/mock.ts @@ -1,4 +1,6 @@ -import { type Monitor, Tracker } from "./tracker"; +import type { Monitor } from "@openstatus/tinybird"; + +import { Tracker } from "./tracker"; export const mockMonitor: Monitor[] = [ { day: "2024-02-21 00:00:00", count: 762, ok: 762 }, diff --git a/packages/tracker/src/tracker.test.ts b/packages/tracker/src/tracker.test.ts index 8f42f53f..0c4fddf3 100644 --- a/packages/tracker/src/tracker.test.ts +++ b/packages/tracker/src/tracker.test.ts @@ -1,11 +1,11 @@ +import { describe, expect, test } from "bun:test"; + import type { Incident, Maintenance, StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; -import { expect } from "@std/expect"; -import { describe, test } from "@std/testing/bdd"; import { blacklistDates } from "./blacklist"; import { classNames, statusDetails } from "./config"; @@ -149,12 +149,10 @@ describe("Tracker", () => { ["0% → Major Outage", 100, 0, Status.MajorOutage], ]; - for (const [label, count, ok, expected] of cases) { - test(label, () => { - const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); - expect(tracker.currentStatus).toBe(expected); - }); - } + test.each(cases)("%s", (_label, count, ok, expected) => { + const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); + expect(tracker.currentStatus).toBe(expected); + }); // NOTE: the lower boundary is `> 30`, while the other two are `>=`. So // exactly 30% uptime is Major (not Partial) Outage. Pinning current @@ -338,9 +336,7 @@ describe("Tracker", () => { describe("per-day precedence (maintenance > report > incident > uptime)", () => { const DAY = "2024-01-01"; - // date-only string so `new Date(day)` anchors to UTC midnight, matching - // the UTC fixture dates below regardless of the runner's timezone. - const okData = [day(DAY, 864, 864)]; + const okData = [day(`${DAY} 00:00:00`, 864, 864)]; test("maintenance overlapping the day wins", () => { const [bucket] = new Tracker({ @@ -398,7 +394,7 @@ describe("Tracker", () => { test("an incident resolved on a previous day does not affect this bucket", () => { const [bucket] = new Tracker({ - data: [day("2024-01-02", 864, 864)], + data: [day("2024-01-02 00:00:00", 864, 864)], incidents: [ createIncident({ startedAt: new Date("2024-01-01T12:00:00.000Z"), diff --git a/packages/tracker/src/tracker.ts b/packages/tracker/src/tracker.ts index f5da4d4c..e96bec6f 100644 --- a/packages/tracker/src/tracker.ts +++ b/packages/tracker/src/tracker.ts @@ -11,7 +11,7 @@ import type { StatusDetails, StatusVariant } from "./types"; import { Status } from "./types"; import { endOfDay, isSameDay, startOfDay } from "./utils"; -export type Monitor = { +type Monitor = { count: number; ok: number; day: string; diff --git a/packages/tracker/tsconfig.json b/packages/tracker/tsconfig.json index bded80f3..f40fdec7 100644 --- a/packages/tracker/tsconfig.json +++ b/packages/tracker/tsconfig.json @@ -2,6 +2,7 @@ "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "target": "ES2021" + "target": "ES2021", + "types": ["bun-types"] } } diff --git a/packages/upstash/package.json b/packages/upstash/package.json index 68403d46..ebda567f 100644 --- a/packages/upstash/package.json +++ b/packages/upstash/package.json @@ -3,9 +3,6 @@ "version": "0.0.0", "license": "MIT", "main": "./src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, "dependencies": { "@upstash/qstash": "catalog:", "@upstash/redis": "catalog:" diff --git a/packages/utils/package.json b/packages/utils/package.json index 23419d76..666520a4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -6,9 +6,7 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": { - "check": "deno check --sloppy-imports ." - }, + "scripts": {}, "dependencies": { "@openstatus/assertions": "workspace:*", "@openstatus/regions": "workspace:*", @@ -16,8 +14,6 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@std/expect": "jsr:^1.0.19", - "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/utils/src/ssrf.test.ts b/packages/utils/src/ssrf.test.ts index e687e0e9..387ad3a7 100644 --- a/packages/utils/src/ssrf.test.ts +++ b/packages/utils/src/ssrf.test.ts @@ -1,5 +1,4 @@ -import { expect } from "@std/expect"; -import { describe, it } from "@std/testing/bdd"; +import { describe, expect, it } from "bun:test"; import { assertSafeUrl, assertSafeUrlSync, safeUrlSchema } from "./ssrf"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c8e8803..4fcd3756 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,15 +105,9 @@ catalogs: '@openpanel/sdk': specifier: 1.3.1 version: 1.3.1 - '@opentelemetry/exporter-logs-otlp-http': - specifier: 0.208.0 - version: 0.208.0 '@opentelemetry/resources': specifier: 2.7.1 version: 2.7.1 - '@opentelemetry/sdk-logs': - specifier: 0.208.0 - version: 0.208.0 '@opentelemetry/semantic-conventions': specifier: 1.41.1 version: 1.41.1 @@ -195,9 +189,9 @@ catalogs: '@scalar/hono-api-reference': specifier: 0.8.10 version: 0.8.10 - '@sentry/deno': - specifier: 10.61.0 - version: 10.61.0 + '@sentry/bun': + specifier: 10.53.1 + version: 10.53.1 '@sentry/nextjs': specifier: 10.53.1 version: 10.53.1 @@ -763,7 +757,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -927,7 +921,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) '@modelcontextprotocol/sdk': specifier: 'catalog:' version: 1.29.0(zod@4.1.13) @@ -1006,15 +1000,9 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils - '@opentelemetry/exporter-logs-otlp-http': - specifier: 'catalog:' - version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': - specifier: 'catalog:' - version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 @@ -1058,21 +1046,15 @@ importers: '@openstatus/locales': specifier: workspace:* version: link:../../packages/locales - '@openstatus/test-utils': - specifier: workspace:* - version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/validator': specifier: 'catalog:' version: 13.15.10 + bun-types: + specifier: 'catalog:' + version: 1.3.14 dotenv: specifier: 'catalog:' version: 16.6.1 @@ -1210,7 +1192,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-intl: specifier: 'catalog:' version: 4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) @@ -1269,12 +1251,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1293,6 +1269,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) + bun-types: + specifier: 'catalog:' + version: 1.3.14 shadcn: specifier: 'catalog:' version: 3.8.5(@types/node@24.12.4)(babel-plugin-macros@3.1.0)(typescript@5.9.3) @@ -1478,7 +1457,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-mdx-remote: specifier: 'catalog:' version: 6.0.0(@types/react@19.2.15)(react@19.2.6) @@ -1558,12 +1537,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1614,7 +1587,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) '@openstatus/db': specifier: workspace:* version: link:../../packages/db @@ -1681,21 +1654,15 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils - '@opentelemetry/exporter-logs-otlp-http': - specifier: 'catalog:' - version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': - specifier: 'catalog:' - version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 - '@sentry/deno': + '@sentry/bun': specifier: 'catalog:' - version: 10.61.0 + version: 10.53.1 '@upstash/qstash': specifier: 'catalog:' version: 2.11.0 @@ -1715,12 +1682,12 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: - '@openstatus/test-utils': - specifier: workspace:* - version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@types/bun': + specifier: latest + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -1867,12 +1834,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/react': specifier: 'catalog:' version: 19.2.15 @@ -1941,12 +1902,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/bcryptjs': specifier: 'catalog:' version: 3.0.0 @@ -1958,7 +1913,7 @@ importers: version: 0.31.10 next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) typescript: specifier: 'catalog:' version: 5.9.3 @@ -1990,12 +1945,6 @@ importers: '@react-email/ui': specifier: 'catalog:' version: 6.1.5(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2024,12 +1973,9 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' + '@types/bun': + specifier: latest + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2062,12 +2008,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2097,15 +2037,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2128,15 +2065,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2159,15 +2093,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2205,9 +2136,6 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: - '@openstatus/test-utils': - specifier: workspace:* - version: link:../../test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig @@ -2217,6 +2145,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2239,15 +2170,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2270,15 +2198,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2301,15 +2226,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2332,15 +2254,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2369,12 +2288,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2384,6 +2297,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2412,12 +2328,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2427,6 +2337,9 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2449,15 +2362,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2477,15 +2387,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2511,18 +2418,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 '@types/validator': specifier: 'catalog:' version: 13.15.10 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2545,15 +2449,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2567,7 +2468,7 @@ importers: specifier: 'catalog:' version: 1.2.0(@bufbuild/protobuf@2.12.0) '@connectrpc/connect': - specifier: 'catalog:' + specifier: ^2.1.1 version: 2.1.1(@bufbuild/protobuf@2.12.0) devDependencies: '@bufbuild/buf': @@ -2663,12 +2564,9 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' + '@types/bun': + specifier: latest + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2685,12 +2583,9 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' + '@types/bun': + specifier: latest + version: 1.3.14 packages/subscriptions: dependencies: @@ -2716,28 +2611,9 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' - typescript: - specifier: 'catalog:' - version: 5.9.3 - - packages/test-utils: - dependencies: - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' - devDependencies: - '@openstatus/tsconfig': - specifier: workspace:* - version: link:../tsconfig + '@types/bun': + specifier: latest + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2797,12 +2673,9 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' + bun-types: + specifier: 'catalog:' + version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -3021,12 +2894,6 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@std/expect': - specifier: jsr:^1.0.19 - version: '@jsr/std__expect@1.0.19' - '@std/testing': - specifier: jsr:^1.0.19 - version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -3079,17 +2946,6 @@ packages: resolution: {integrity: sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==} hasBin: true - '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': - resolution: {integrity: sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==} - engines: {node: '>=18.0.0'} - - '@apm-js-collab/code-transformer@0.15.0': - resolution: {integrity: sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==} - hasBin: true - - '@apm-js-collab/tracing-hooks@0.10.0': - resolution: {integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==} - '@asamuzakjp/css-color@5.1.11': resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -4449,30 +4305,6 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - '@jsr/std__assert@1.0.19': - resolution: {integrity: sha512-pEj6RPkGbqlgRmyKwATp4cUs6+ijxtdrv3bq8v1d2I2CEcMEyPaO8cVKro61wGRDH4cNg8Zx6haztvK/9m7gkA==, tarball: https://npm.jsr.io/~/11/@jsr/std__assert/1.0.19.tgz} - - '@jsr/std__async@1.4.0': - resolution: {integrity: sha512-epQ5wsMrnAxeVtzmO9VviX14siVOSvF2o5dAm9qa6ajdWnWrrQ/oup7/Z2ctAOaxSOJbDWrfhgsenzHsODAogw==, tarball: https://npm.jsr.io/~/11/@jsr/std__async/1.4.0.tgz} - - '@jsr/std__data-structures@1.1.0': - resolution: {integrity: sha512-V/Lrzz3ZBT2ps09SbUuQKIDQ0Ac7qTTloCFNNF7r2MNoIzdz3xsW9+Vd+ZzgXFKdm46+XqBmkv0lpW/HzgRQfg==, tarball: https://npm.jsr.io/~/11/@jsr/std__data-structures/1.1.0.tgz} - - '@jsr/std__expect@1.0.19': - resolution: {integrity: sha512-t8BEISf1666L7dGDIG1nriYh0TQKoU+8mrx93zz+Kj40eov9wNKjKCX96x17p8I8bDcHby4wSv+7jy4+9W6IPg==, tarball: https://npm.jsr.io/~/11/@jsr/std__expect/1.0.19.tgz} - - '@jsr/std__fs@1.0.24': - resolution: {integrity: sha512-UunW2Rg++9sA74NJnYMGTsMVQgoFRAwPP02wRRohL0PQBNorbyxHiyCMRaxYQCtLepTLkC4nUyMtcwrGKqTR6g==, tarball: https://npm.jsr.io/~/11/@jsr/std__fs/1.0.24.tgz} - - '@jsr/std__internal@1.0.14': - resolution: {integrity: sha512-JT8b/t40WcR9q0GDwRZUooY7aXeXnFal8iidE/5TckdAFtvpVAsaJ71/Xgf1SfoChs41s6CZkuCYM8toaNgdvA==, tarball: https://npm.jsr.io/~/11/@jsr/std__internal/1.0.14.tgz} - - '@jsr/std__path@1.1.5': - resolution: {integrity: sha512-3z/0rfvMEz6qiiaZ3quFpEv8BbWQgcpd+ASX29WEdecyJsdPN9uViQf1VxIua265cmGCdICk0WghMjGFoNZ5Ig==, tarball: https://npm.jsr.io/~/11/@jsr/std__path/1.1.5.tgz} - - '@jsr/std__testing@1.0.19': - resolution: {integrity: sha512-maQIRFWIcTTWB7ITYIVbql1Q3KA9AsgR4/Ep2SfEq65V2SxQq52iLcFxuvX0azRp1leBCb8mBUXZr389SajY7Q==, tarball: https://npm.jsr.io/~/11/@jsr/std__testing/1.0.19.tgz} - '@libsql/client@0.17.4': resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==} @@ -4913,6 +4745,10 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/semantic-conventions@1.38.0': + resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} + engines: {node: '>=14'} + '@opentelemetry/semantic-conventions@1.41.1': resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} @@ -6440,6 +6276,10 @@ packages: resolution: {integrity: sha512-zXF373hzUOGzUOrqd8xb1U3LQi5uYC3mwv+z5OMKUUinQlu30tTWBs7ypy6YTchtix9QlYaHWlayUF8vBZ5UjA==} engines: {node: '>=18'} + '@sentry/bun@10.53.1': + resolution: {integrity: sha512-UCRUtEc3qLaanmp+9rKQi58d+weBdovytqW6d8ria1fkmxfvnVCYQqVQ0c/FLrGggqjqizO4b4WnLnuy/y/CXw==} + engines: {node: '>=18'} + '@sentry/bundler-plugin-core@5.3.0': resolution: {integrity: sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==} engines: {node: '>= 18'} @@ -6496,25 +6336,14 @@ packages: engines: {node: '>= 10'} hasBin: true - '@sentry/conventions@0.12.0': - resolution: {integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==} - engines: {node: '>=14'} - '@sentry/core@10.53.1': resolution: {integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==} engines: {node: '>=18'} - '@sentry/core@10.61.0': - resolution: {integrity: sha512-Edg8t2w45qEKiFnjeA6zRmU47R6la5FEMG+maZEOB2oTyJ+ujmh8LGaZ3G8aC0VdkKn8CXhHtDesze6oDc1oTA==} - engines: {node: '>=18'} - '@sentry/core@8.9.2': resolution: {integrity: sha512-ixm8NISFlPlEo3FjSaqmq4nnd13BRHoafwJ5MG+okCz6BKGZ1SexEggP42/QpGvDprUUHnfncG6WUMgcarr1zA==} engines: {node: '>=14.18'} - '@sentry/deno@10.61.0': - resolution: {integrity: sha512-TLs+Z+I5xWL0YdXtQ/LqJ7F1T/rRytxFlSJD1gXm5mx3T+wwNrni20N4XGnV1Bo8s8EB05HTjJXGzFb96CJDFw==} - '@sentry/nextjs@10.53.1': resolution: {integrity: sha512-pkwqrpAG//LtW5W1Odud0PLLT+rnjDjodUEbScULHVaZE6/Gt+WGBMZmtzpNM+UwhsN19/4PyO7ocLTx/IFrkQ==} engines: {node: '>=18'} @@ -6564,10 +6393,6 @@ packages: peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x - '@sentry/server-utils@10.61.0': - resolution: {integrity: sha512-IrOyMzlOyBkWtnVYb54sALf2f8WVqyyp7woRfHw8c3IMwUr5AskGOi7k2rjmUXO3Q0UkfHNVarexiEfo8ZqTsg==} - engines: {node: '>=18'} - '@sentry/types@8.9.2': resolution: {integrity: sha512-+LFOyQGl+zk5SZRGZD2MEURf7i5RHgP/mt3s85Rza+vz8M211WJ0YsjkIGUJFSY842nged5QLx4JysLaBlLymg==} engines: {node: '>=14.18'} @@ -7044,6 +6869,9 @@ packages: resolution: {integrity: sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==} deprecated: This is a stub types definition. bcryptjs provides its own type definitions, so you do not need this installed. + '@types/bun@1.3.14': + resolution: {integrity: sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw==} + '@types/caseless@0.12.5': resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} @@ -7141,6 +6969,9 @@ packages: '@types/mysql@2.15.27': resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} @@ -8027,6 +7858,10 @@ packages: resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} engines: {node: '>=20'} + dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -8225,9 +8060,6 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -8290,10 +8122,6 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -8352,6 +8180,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + eventsource-parser@3.0.8: resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} engines: {node: '>=18.0.0'} @@ -8726,6 +8558,10 @@ packages: peerDependencies: hono: ^4.1.1 + hono@4.11.8: + resolution: {integrity: sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q==} + engines: {node: '>=16.9.0'} + hono@4.12.21: resolution: {integrity: sha512-uV63apnb0kyPtAUwoWgaGh9HyIFcv8lgmzPZSiTBQAFOFGIzka5EZ1dZocmGnn0XdX0+XTqJ6Tqv7selMuGLRQ==} engines: {node: '>=16.9.0'} @@ -9280,6 +9116,10 @@ packages: lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + lru-cache@11.2.7: + resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} + engines: {node: 20 || >=22} + lru-cache@11.5.0: resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} engines: {node: 20 || >=22} @@ -9388,10 +9228,6 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - meriyah@6.1.4: - resolution: {integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==} - engines: {node: '>=18.0.0'} - micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -9539,6 +9375,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -9583,6 +9423,11 @@ packages: nanoid-dictionary@5.0.0: resolution: {integrity: sha512-/iCyQHwt36XkaIvSE9fcC8p6DiMPCZMTSMj9UT56Cv6T7f5CuxvOMhpNncaNieQ4z4d32p7ruEtAfRsb7Ya8Gw==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -9593,6 +9438,11 @@ packages: engines: {node: ^18 || >=20} hasBin: true + nanoid@5.1.6: + resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} + engines: {node: ^18 || >=20} + hasBin: true + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -9960,6 +9810,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} @@ -10064,6 +9918,10 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -10518,9 +10376,6 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} - semifies@1.0.0: - resolution: {integrity: sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==} - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -10831,6 +10686,9 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwind-merge@3.6.0: resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} @@ -10891,6 +10749,10 @@ packages: tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -11373,6 +11235,11 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -11476,31 +11343,7 @@ snapshots: ansis: 4.2.0 fzf: 0.5.2 package-manager-detector: 1.6.0 - tinyexec: 1.1.2 - - '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': - dependencies: - '@apm-js-collab/code-transformer': 0.15.0 - es-module-lexer: 2.1.0 - magic-string: 0.30.21 - module-details-from-path: 1.0.4 - - '@apm-js-collab/code-transformer@0.15.0': - dependencies: - '@types/estree': 1.0.8 - astring: 1.9.0 - esquery: 1.7.0 - meriyah: 6.1.4 - semifies: 1.0.0 - source-map: 0.6.1 - - '@apm-js-collab/tracing-hooks@0.10.0': - dependencies: - '@apm-js-collab/code-transformer': 0.15.0 - debug: 4.4.3 - module-details-from-path: 1.0.4 - transitivePeerDependencies: - - supports-color + tinyexec: 1.0.2 '@asamuzakjp/css-color@5.1.11': dependencies: @@ -12534,7 +12377,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 minimatch: 10.2.5 transitivePeerDependencies: - supports-color @@ -12617,9 +12460,9 @@ snapshots: pkce-challenge: 5.0.1 zod: 4.1.13 - '@hono/node-server@1.19.9(hono@4.12.21)': + '@hono/node-server@1.19.9(hono@4.11.8)': dependencies: - hono: 4.12.21 + hono: 4.11.8 '@hono/sentry@1.2.2(hono@4.12.21)': dependencies: @@ -12832,44 +12675,6 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} - '@jsr/std__assert@1.0.19': - dependencies: - '@jsr/std__internal': 1.0.14 - - '@jsr/std__async@1.4.0': - dependencies: - '@jsr/std__data-structures': 1.1.0 - - '@jsr/std__data-structures@1.1.0': - dependencies: - '@jsr/std__assert': 1.0.19 - - '@jsr/std__expect@1.0.19': - dependencies: - '@jsr/std__assert': 1.0.19 - '@jsr/std__internal': 1.0.14 - '@jsr/std__path': 1.1.5 - - '@jsr/std__fs@1.0.24': - dependencies: - '@jsr/std__internal': 1.0.14 - '@jsr/std__path': 1.1.5 - - '@jsr/std__internal@1.0.14': {} - - '@jsr/std__path@1.1.5': - dependencies: - '@jsr/std__internal': 1.0.14 - - '@jsr/std__testing@1.0.19': - dependencies: - '@jsr/std__assert': 1.0.19 - '@jsr/std__async': 1.4.0 - '@jsr/std__data-structures': 1.1.0 - '@jsr/std__fs': 1.0.24 - '@jsr/std__internal': 1.0.14 - '@jsr/std__path': 1.1.5 - '@libsql/client@0.17.4': dependencies: '@libsql/core': 0.17.4 @@ -12941,12 +12746,12 @@ snapshots: '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 - '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0)': + '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1)': dependencies: '@logtape/logtape': 2.1.1 - '@sentry/core': 10.61.0 + '@sentry/core': 10.53.1 '@mdx-js/mdx@3.1.1': dependencies: @@ -12986,17 +12791,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - '@hono/node-server': 1.19.9(hono@4.12.21) + '@hono/node-server': 1.19.9(hono@4.11.8) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.8 + eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.12.21 + hono: 4.11.8 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -13008,17 +12813,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@4.1.13)': dependencies: - '@hono/node-server': 1.19.9(hono@4.12.21) + '@hono/node-server': 1.19.9(hono@4.11.8) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.8 + eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.12.21 + hono: 4.11.8 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -13139,17 +12944,17 @@ snapshots: '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/exporter-logs-otlp-grpc@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -13186,7 +12991,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13195,7 +13000,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@types/connect': 3.4.38 transitivePeerDependencies: - supports-color @@ -13234,7 +13039,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13243,7 +13048,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color @@ -13252,7 +13057,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13260,7 +13065,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13269,7 +13074,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13284,7 +13089,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13293,7 +13098,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 transitivePeerDependencies: - supports-color @@ -13301,7 +13106,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color @@ -13310,7 +13115,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@types/mysql': 2.15.27 transitivePeerDependencies: - supports-color @@ -13320,7 +13125,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) '@types/pg': 8.15.6 '@types/pg-pool': 2.0.7 @@ -13331,7 +13136,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color @@ -13392,13 +13197,13 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -13418,14 +13223,16 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 '@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/semantic-conventions': 1.38.0 + + '@opentelemetry/semantic-conventions@1.38.0': {} '@opentelemetry/semantic-conventions@1.41.1': {} @@ -14676,7 +14483,7 @@ snapshots: '@scalar/types@0.1.16': dependencies: '@scalar/openapi-types': 0.2.3 - nanoid: 5.1.11 + nanoid: 5.1.6 zod: 3.24.1 '@schummar/icu-type-parser@1.21.5': {} @@ -14716,12 +14523,20 @@ snapshots: '@sentry-internal/replay-canvas': 10.53.1 '@sentry/core': 10.53.1 + '@sentry/bun@10.53.1': + dependencies: + '@sentry/core': 10.53.1 + '@sentry/node': 10.53.1 + transitivePeerDependencies: + - '@opentelemetry/exporter-trace-otlp-http' + - supports-color + '@sentry/bundler-plugin-core@5.3.0': dependencies: '@babel/core': 7.28.5 '@sentry/babel-plugin-component-annotate': 5.3.0 '@sentry/cli': 2.58.5 - dotenv: 16.6.1 + dotenv: 16.3.1 find-up: 5.0.0 glob: 13.0.6 magic-string: 0.30.21 @@ -14773,25 +14588,13 @@ snapshots: - encoding - supports-color - '@sentry/conventions@0.12.0': {} - '@sentry/core@10.53.1': {} - '@sentry/core@10.61.0': {} - '@sentry/core@8.9.2': dependencies: '@sentry/types': 8.9.2 '@sentry/utils': 8.9.2 - '@sentry/deno@10.61.0': - dependencies: - '@opentelemetry/api': 1.9.1 - '@sentry/core': 10.61.0 - '@sentry/server-utils': 10.61.0 - transitivePeerDependencies: - - supports-color - '@sentry/nextjs@10.53.1(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.103.0(@swc/core@1.15.18))': dependencies: '@opentelemetry/api': 1.9.1 @@ -14878,17 +14681,6 @@ snapshots: '@sentry/core': 10.53.1 react: 19.2.6 - '@sentry/server-utils@10.61.0': - dependencies: - '@apm-js-collab/code-transformer': 0.15.0 - '@apm-js-collab/code-transformer-bundler-plugins': 0.5.0 - '@apm-js-collab/tracing-hooks': 0.10.0 - '@sentry/conventions': 0.12.0 - '@sentry/core': 10.61.0 - magic-string: 0.30.21 - transitivePeerDependencies: - - supports-color - '@sentry/types@8.9.2': {} '@sentry/utils@8.9.2': @@ -14954,7 +14746,7 @@ snapshots: dependencies: '@slack/logger': 4.0.1 '@slack/types': 2.21.1 - '@types/node': 24.12.4 + '@types/node': 24.10.1 '@types/retry': 0.12.0 axios: 1.16.1 eventemitter3: 5.0.1 @@ -15326,6 +15118,10 @@ snapshots: dependencies: bcryptjs: 3.0.3 + '@types/bun@1.3.14': + dependencies: + bun-types: 1.3.14 + '@types/caseless@0.12.5': {} '@types/connect@3.4.38': @@ -15426,6 +15222,10 @@ snapshots: dependencies: '@types/node': 24.12.4 + '@types/node@24.10.1': + dependencies: + undici-types: 7.16.0 + '@types/node@24.12.4': dependencies: undici-types: 7.16.0 @@ -16305,6 +16105,8 @@ snapshots: dependencies: type-fest: 5.2.0 + dotenv@16.3.1: {} + dotenv@16.6.1: {} dotenv@17.2.4: {} @@ -16419,8 +16221,6 @@ snapshots: es-module-lexer@1.7.0: {} - es-module-lexer@2.1.0: {} - es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -16554,10 +16354,6 @@ snapshots: esprima@4.0.1: {} - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -16613,11 +16409,13 @@ snapshots: events@3.3.0: {} + eventsource-parser@3.0.6: {} + eventsource-parser@3.0.8: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.8 + eventsource-parser: 3.0.6 execa@5.1.1: dependencies: @@ -16923,9 +16721,9 @@ snapshots: foreground-child: 3.3.1 jackspeak: 4.1.1 minimatch: 10.2.5 - minipass: 7.1.3 + minipass: 7.1.2 package-json-from-dist: 1.0.1 - path-scurry: 2.0.2 + path-scurry: 2.0.1 glob@13.0.6: dependencies: @@ -17139,6 +16937,8 @@ snapshots: dependencies: hono: 4.12.21 + hono@4.11.8: {} + hono@4.12.21: {} html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): @@ -17547,7 +17347,7 @@ snapshots: typescript: 5.9.3 unbash: 2.2.0 yaml: 2.9.0 - zod: 4.4.3 + zod: 4.1.13 launder@1.7.1: dependencies: @@ -17678,6 +17478,8 @@ snapshots: lower-case@1.1.4: {} + lru-cache@11.2.7: {} + lru-cache@11.5.0: {} lru-cache@5.1.1: @@ -17879,8 +17681,6 @@ snapshots: merge2@1.4.1: {} - meriyah@6.1.4: {} - micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -18180,6 +17980,8 @@ snapshots: minimist@1.2.8: {} + minipass@7.1.2: {} + minipass@7.1.3: {} mitt@3.0.1: {} @@ -18231,10 +18033,14 @@ snapshots: nanoid-dictionary@5.0.0: {} + nanoid@3.3.11: {} + nanoid@3.3.12: {} nanoid@5.1.11: {} + nanoid@5.1.6: {} + negotiator@0.6.3: {} negotiator@1.0.0: {} @@ -18245,7 +18051,7 @@ snapshots: neverthrow@7.2.0: {} - next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): + next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): dependencies: '@auth/core': 0.41.2 next: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -18432,7 +18238,7 @@ snapshots: openapi3-ts@4.5.0: dependencies: - yaml: 2.9.0 + yaml: 2.8.1 ora@4.1.1: dependencies: @@ -18665,6 +18471,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.7 + minipass: 7.1.2 + path-scurry@2.0.2: dependencies: lru-cache: 11.5.0 @@ -18723,7 +18534,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3)): dependencies: lilconfig: 3.1.3 - yaml: 2.9.0 + yaml: 2.8.1 optionalDependencies: postcss: 8.5.15 ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3) @@ -18740,7 +18551,7 @@ snapshots: postcss@8.4.31: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -18750,6 +18561,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -19357,7 +19174,7 @@ snapshots: is-plain-object: 5.0.0 launder: 1.7.1 parse-srcset: 1.0.2 - postcss: 8.5.15 + postcss: 8.5.6 sax@1.4.3: {} @@ -19387,8 +19204,6 @@ snapshots: dependencies: parseley: 0.12.1 - semifies@1.0.0: {} - semver@6.3.1: {} semver@7.7.3: {} @@ -19455,12 +19270,12 @@ snapshots: node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 - postcss: 8.5.15 + postcss: 8.5.6 postcss-selector-parser: 7.1.1 prompts: 2.4.2 recast: 0.23.11 stringify-object: 5.0.0 - tailwind-merge: 3.6.0 + tailwind-merge: 3.3.1 ts-morph: 26.0.0 tsconfig-paths: 4.2.0 validate-npm-package-name: 7.0.2 @@ -19715,7 +19530,7 @@ snapshots: stripe@13.11.0: dependencies: - '@types/node': 24.12.4 + '@types/node': 24.10.1 qs: 6.14.0 strnum@2.3.0: {} @@ -19795,6 +19610,8 @@ snapshots: tagged-tag@1.0.0: {} + tailwind-merge@3.3.1: {} + tailwind-merge@3.6.0: {} tailwindcss-animate@1.0.7(tailwindcss@4.3.0): @@ -19850,6 +19667,8 @@ snapshots: tinycolor2@1.6.0: {} + tinyexec@1.0.2: {} + tinyexec@1.1.2: {} tinyglobby@0.2.15: @@ -20182,7 +20001,7 @@ snapshots: vfile-matter@5.0.1: dependencies: vfile: 6.0.3 - yaml: 2.9.0 + yaml: 2.8.1 vfile-message@3.1.4: dependencies: @@ -20360,6 +20179,8 @@ snapshots: yaml@1.10.2: {} + yaml@2.8.1: {} + yaml@2.9.0: {} yargs-parser@21.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a61cf776..c259c6f1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,8 +2,10 @@ packages: - apps/* - packages/**/* - packages/config/* + trustPolicy: off -minimumReleaseAge: 1440 +minimumReleaseAge: 1440 # 1 day (default) + allowBuilds: "@bufbuild/buf": true "@parcel/watcher": true @@ -15,7 +17,9 @@ allowBuilds: msw: true protobufjs: true sharp: true + autoInstallPeers: true + catalog: "@ai-sdk/anthropic": 1.2.12 "@ai-sdk/react": 3.0.190 @@ -42,6 +46,7 @@ catalog: "@dnd-kit/sortable": 10.0.0 "@dnd-kit/utilities": 3.2.2 "@fontsource-variable/inter": 5.2.8 + # Pinned to 4.0.1 — 4.1.0+ ships an ESM build that reads config JSON via fs.readFileSync, breaking `bun build --compile` in apps/workflows "@google-cloud/tasks": 4.0.1 "@hono/mcp": 0.2.5 "@hono/sentry": 1.2.2 @@ -58,9 +63,7 @@ catalog: "@openpanel/astro": 1.4.1 "@openpanel/nextjs": 1.5.1 "@openpanel/sdk": 1.3.1 - "@opentelemetry/exporter-logs-otlp-http": 0.208.0 "@opentelemetry/resources": 2.7.1 - "@opentelemetry/sdk-logs": 0.208.0 "@opentelemetry/semantic-conventions": 1.41.1 "@radix-ui/react-accordion": 1.2.12 "@radix-ui/react-alert-dialog": 1.1.15 @@ -89,7 +92,6 @@ catalog: "@react-email/ui": 6.1.5 "@scalar/hono-api-reference": 0.8.10 "@sentry/bun": 10.53.1 - "@sentry/deno": 10.61.0 "@sentry/nextjs": 10.53.1 "@slack/web-api": 7.16.0 "@stripe/stripe-js": 2.4.0 @@ -105,6 +107,7 @@ catalog: "@tanstack/react-table": 8.21.3 "@trpc/client": 11.17.0 "@trpc/next": 11.17.0 + "@types/react": 19.2.15 "@trpc/react-query": 11.17.0 "@trpc/server": 11.17.0 "@trpc/tanstack-react-query": 11.17.0 @@ -113,7 +116,6 @@ catalog: "@types/dom-speech-recognition": 0.0.6 "@types/luxon": 3.7.1 "@types/node": 24.12.4 - "@types/react": 19.2.15 "@types/react-dom": 19.2.3 "@types/sanitize-html": 2.16.1 "@types/validator": 13.15.10 @@ -197,9 +199,9 @@ catalog: stripe: 13.11.0 sugar-high: 0.9.5 superjson: 2.2.6 - tailwind-merge: 3.6.0 tailwindcss: 4.3.0 tailwindcss-animate: 1.0.7 + tailwind-merge: 3.6.0 tsup: 7.2.0 tw-animate-css: 1.4.0 typescript: 5.9.3 diff --git a/turbo.json b/turbo.json index e6a28cd2..7d319815 100644 --- a/turbo.json +++ b/turbo.json @@ -32,7 +32,6 @@ "outputs": [".next/**", "!.next/cache/**", "dist/**"] }, "lint": {}, - "check": {}, "dev": { "cache": false }, -- 2.51.2 From 4b5a70f423a0fb44cf40f036f28d297700d467cc Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 1 Jul 2026 08:28:15 +0200 Subject: [PATCH 12/69] revert: restore Deno build state (#2323) (#2329) --- .github/workflows/check.yml | 39 ++ .github/workflows/dx.yml | 6 +- .github/workflows/test.yml | 8 +- apps/dashboard/env.ts | 3 +- apps/screenshot-service/package.json | 1 + apps/server/.gitignore | 4 + apps/server/Dockerfile | 30 +- apps/server/bunfig.toml | 2 - apps/server/deno.jsonc | 6 + apps/server/docker-compose.yaml | 2 + apps/server/dofigen.lock | 126 ++-- apps/server/dofigen.yml | 28 +- apps/server/env.ts | 3 +- apps/server/package.json | 18 +- apps/server/src/index.ts | 58 +- .../libs/middlewares/require-scope.test.ts | 4 +- .../src/libs/middlewares/validate-key.test.ts | 3 +- .../src/libs/test/doubles/analytics.mock.ts | 26 + .../src/libs/test/doubles/page-urls.mock.ts | 10 + .../src/libs/test/doubles/slack-agent.mock.ts | 8 + .../src/libs/test/doubles/slack-test-state.ts | 33 + .../libs/test/doubles/slack-web-api.mock.ts | 26 + apps/server/src/libs/test/doubles/state.ts | 49 ++ .../libs/test/doubles/subscriptions.mock.ts | 11 + .../src/libs/test/doubles/tinybird.mock.ts | 59 ++ .../src/libs/test/doubles/upstash.mock.ts | 36 + .../test/doubles/workspace-resolver.mock.ts | 6 + apps/server/src/libs/test/preload.ts | 3 +- apps/server/src/routes/mcp/adapter.test.ts | 4 +- apps/server/src/routes/mcp/adapter.ts | 2 +- apps/server/src/routes/mcp/handler.test.ts | 7 +- apps/server/src/routes/mcp/index.ts | 7 +- .../routes/mcp/tools/register-scoped.test.ts | 4 +- .../server/src/routes/mcp/tools/tools.test.ts | 4 +- apps/server/src/routes/public/status.test.ts | 9 +- apps/server/src/routes/public/status.ts | 2 +- apps/server/src/routes/rpc/adapter.test.ts | 4 +- .../maintenance/__tests__/maintenance.test.ts | 223 +++--- .../monitor/__tests__/monitor.test.ts | 50 +- .../monitor/converters/regions.test.ts | 20 +- .../src/routes/rpc/handlers/monitor/index.ts | 5 +- .../handlers/monitor/response-logs.test.ts | 4 +- .../__tests__/notification.test.ts | 6 +- .../status-page/__tests__/status-page.test.ts | 9 +- .../__tests__/status-report.test.ts | 86 ++- .../interceptors/__tests__/tracking.test.ts | 43 +- .../src/routes/rpc/interceptors/auth.ts | 2 +- apps/server/src/routes/slack/blocks.test.ts | 4 +- .../routes/slack/confirmation-store.test.ts | 3 +- apps/server/src/routes/slack/handler.test.ts | 150 ++-- apps/server/src/routes/slack/index.test.ts | 3 +- .../src/routes/slack/interactions.test.ts | 72 +- apps/server/src/routes/slack/oauth.test.ts | 3 +- .../slack/presenters/presenters.test.ts | 17 +- .../src/routes/slack/registry-runner.test.ts | 4 +- .../src/routes/slack/system-prompt.test.ts | 3 +- apps/server/src/routes/slack/verify.test.ts | 3 +- .../src/routes/v1/check/http/post.test.ts | 4 +- .../src/routes/v1/incidents/get.test.ts | 3 +- .../src/routes/v1/incidents/get_all.test.ts | 4 +- .../src/routes/v1/incidents/put.test.ts | 3 +- .../src/routes/v1/maintenances/get.test.ts | 3 +- .../routes/v1/maintenances/get_all.test.ts | 4 +- .../src/routes/v1/maintenances/post.test.ts | 8 +- .../src/routes/v1/maintenances/put.test.ts | 46 +- .../src/routes/v1/monitors/delete.test.ts | 3 +- .../server/src/routes/v1/monitors/get.test.ts | 3 +- .../src/routes/v1/monitors/get_all.test.ts | 3 +- .../src/routes/v1/monitors/post.test.ts | 5 +- .../src/routes/v1/monitors/post_dns.test.ts | 3 +- .../src/routes/v1/monitors/post_http.test.ts | 3 +- .../src/routes/v1/monitors/post_tcp.test.ts | 3 +- .../server/src/routes/v1/monitors/put.test.ts | 3 +- .../src/routes/v1/monitors/put_dns.test.ts | 3 +- .../src/routes/v1/monitors/put_http.test.ts | 3 +- .../src/routes/v1/monitors/put_tcp.test.ts | 3 +- .../routes/v1/monitors/results/get.test.ts | 36 +- .../src/routes/v1/monitors/run/post.test.ts | 87 +-- .../routes/v1/monitors/summary/get.test.ts | 6 +- .../src/routes/v1/monitors/summary/get.ts | 5 - .../routes/v1/monitors/trigger/post.test.ts | 4 +- .../src/routes/v1/notifications/get.test.ts | 3 +- .../routes/v1/notifications/get_all.test.ts | 4 +- .../src/routes/v1/notifications/post.test.ts | 4 +- .../routes/v1/pageSubscribers/post.test.ts | 4 +- apps/server/src/routes/v1/pages/get.test.ts | 3 +- .../src/routes/v1/pages/get_all.test.ts | 4 +- apps/server/src/routes/v1/pages/post.test.ts | 4 +- apps/server/src/routes/v1/pages/put.test.ts | 3 +- .../routes/v1/statusReportUpdates/get.test.ts | 3 +- .../v1/statusReportUpdates/post.test.ts | 7 +- .../routes/v1/statusReports/delete.test.ts | 3 +- .../src/routes/v1/statusReports/get.test.ts | 3 +- .../routes/v1/statusReports/get_all.test.ts | 4 +- .../src/routes/v1/statusReports/post.test.ts | 8 +- .../subscriber-filtering.integration.test.ts | 4 +- .../v1/statusReports/update/post.test.ts | 3 +- .../routes/v1/statusReports/update/post.ts | 3 +- apps/server/src/routes/v1/whoami/get.test.ts | 3 +- apps/server/src/serve.ts | 13 + apps/server/src/utils/audit-log.ts | 2 +- apps/server/test.importmap.json | 16 + apps/server/tsconfig.json | 10 +- apps/status-page/env.ts | 3 +- apps/status-page/package.json | 7 +- apps/status-page/src/app/(public)/client.tsx | 17 +- apps/status-page/src/app/(public)/layout.tsx | 6 +- .../[domain]/[locale]/(auth)/layout.tsx | 6 +- .../login/_components/section-magic-link.tsx | 12 +- .../login/_components/section-password.tsx | 8 +- .../[domain]/[locale]/(auth)/login/actions.ts | 4 +- .../[domain]/[locale]/(auth)/login/page.tsx | 3 +- .../[locale]/(auth)/restricted/page.tsx | 2 +- .../[domain]/[locale]/(public)/client.tsx | 22 +- .../(public)/events/(list)/layout.tsx | 2 +- .../[locale]/(public)/events/(list)/page.tsx | 9 +- .../events/(view)/maintenance/[id]/layout.tsx | 8 +- .../events/(view)/maintenance/[id]/page.tsx | 10 +- .../events/(view)/report/[id]/layout.tsx | 8 +- .../events/(view)/report/[id]/page.tsx | 12 +- .../[locale]/(public)/events/layout.tsx | 2 +- .../[locale]/(public)/feed/[type]/route.ts | 6 +- .../[locale]/(public)/feed/json/route.ts | 4 +- .../[domain]/[locale]/(public)/layout.tsx | 6 +- .../[locale]/(public)/llms.txt/route.ts | 9 +- .../(public)/manage/[token]/layout.tsx | 6 +- .../[locale]/(public)/manage/[token]/page.tsx | 10 +- .../[locale]/(public)/manage/layout.tsx | 2 +- .../(public)/monitors/[id]/layout.tsx | 2 +- .../[locale]/(public)/monitors/[id]/page.tsx | 21 +- .../[locale]/(public)/monitors/layout.tsx | 2 +- .../[locale]/(public)/monitors/page.tsx | 6 +- .../[locale]/(public)/search-params.ts | 2 +- .../(public)/unsubscribe/[token]/layout.tsx | 2 +- .../(public)/unsubscribe/[token]/page.tsx | 4 +- .../(public)/verify/[token]/layout.tsx | 2 +- .../[locale]/(public)/verify/[token]/page.tsx | 4 +- .../[domain]/[locale]/layout.tsx | 6 +- .../src/app/(status-page)/[domain]/layout.tsx | 14 +- .../src/app/api/auth/[...nextauth]/route.ts | 2 +- .../src/app/api/markdown/[[...path]]/route.ts | 12 +- .../src/app/api/status/[[...path]]/route.ts | 16 +- .../src/app/api/trpc/edge/[trpc]/route.ts | 4 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 4 +- apps/status-page/src/app/global-error.tsx | 2 +- apps/status-page/src/app/layout.tsx | 5 +- apps/status-page/src/app/not-found.tsx | 4 +- apps/status-page/src/app/robots.ts | 6 +- apps/status-page/src/app/sitemap.ts | 8 +- .../chart/chart-area-percentiles.tsx | 3 +- .../src/components/chart/chart-bar-uptime.tsx | 3 +- .../components/chart/chart-legend-badge.tsx | 2 +- .../components/chart/chart-line-regions.tsx | 5 +- .../src/components/common/link.tsx | 2 +- .../src/components/date-fns-provider.tsx | 2 +- .../src/components/date-picker.tsx | 4 +- .../forms/form-manage-subscription.tsx | 2 +- .../components/forms/form-subscribe-email.tsx | 2 +- .../i18n/status-blocks-provider.tsx | 2 +- .../src/components/layout/embed-shell.tsx | 2 +- .../src/components/locale-switcher.tsx | 2 +- .../status-page/src/components/nav/footer.tsx | 12 +- .../status-page/src/components/nav/header.tsx | 8 +- .../src/components/password-wrapper.tsx | 2 +- .../status-page/floating-button.tsx | 2 +- .../components/status-page/floating-theme.tsx | 3 +- .../src/components/status-page/status-bar.tsx | 4 +- .../components/status-page/status-blank.tsx | 2 +- .../status-page/status-calendar.tsx | 6 +- .../components/status-page/status-events.tsx | 2 +- .../components/status-page/status-feed.tsx | 7 +- .../components/status-page/status-updates.tsx | 6 +- .../src/components/themes/theme-provider.tsx | 4 +- .../src/components/themes/theme-sidebar.tsx | 4 +- .../ui/data-table/data-table-toolbar.tsx | 4 +- .../src/content/markdown/generators.test.ts | 3 +- .../src/content/markdown/match-route.test.ts | 3 +- .../src/content/status-json.test.ts | 4 +- .../src/content/status-vocab.test.ts | 3 +- apps/status-page/src/data/metrics.client.ts | 5 +- apps/status-page/src/hooks/use-embed.ts | 4 +- .../src/hooks/use-pathname-prefix.ts | 6 +- .../src/lib/alternates-metadata.ts | 4 +- apps/status-page/src/lib/alternates.test.ts | 3 +- apps/status-page/src/lib/auth/index.ts | 5 +- apps/status-page/src/lib/auth/providers.ts | 3 +- apps/status-page/src/lib/formatter.test.ts | 3 +- .../src/lib/http/client-ip.test.ts | 3 +- apps/status-page/src/lib/http/etag.test.ts | 3 +- .../src/lib/http/markdown-response.test.ts | 9 +- .../src/lib/http/markdown-response.ts | 6 +- .../proxy/apply-page-locale-override.test.ts | 3 +- .../src/lib/proxy/build-external-path.test.ts | 3 +- .../src/lib/proxy/compose-page-action.test.ts | 4 +- .../src/lib/proxy/detect-markdown.test.ts | 3 +- .../lib/proxy/evaluate-markdown-gate.test.ts | 3 +- .../src/lib/proxy/is-ip-allowed.test.ts | 3 +- .../lib/proxy/markdown-cache-control.test.ts | 3 +- .../resolve-custom-domain-rewrite.test.ts | 3 +- .../lib/proxy/resolve-default-rewrite.test.ts | 3 +- .../proxy/resolve-email-domain-action.test.ts | 3 +- .../status-page/src/lib/proxy/resolve-gate.ts | 9 +- .../resolve-ip-restriction-action.test.ts | 3 +- .../lib/proxy/resolve-locale-action.test.ts | 3 +- .../lib/proxy/resolve-password-action.test.ts | 3 +- .../lib/proxy/sanitize-redirect-param.test.ts | 3 +- .../proxy/strip-prefix-for-external.test.ts | 3 +- .../src/lib/resolve-pathname-prefix.test.ts | 3 +- .../status-page/src/lib/resolve-route.test.ts | 3 +- apps/status-page/src/lib/resolve-route.ts | 3 +- .../src/lib/status-blocks-labels.test.ts | 4 +- apps/status-page/src/lib/trpc/client.tsx | 2 +- apps/status-page/src/proxy.ts | 5 +- apps/web/env.ts | 3 +- apps/web/package.json | 6 +- apps/web/src/app/(ai)/llms-full.txt/route.ts | 6 +- apps/web/src/app/(ai)/llms.txt/route.ts | 4 +- apps/web/src/app/(ai)/mcp/route.ts | 2 +- .../src/app/(docs)/docs/[[...slug]]/page.tsx | 26 +- apps/web/src/app/(docs)/layout.tsx | 6 +- apps/web/src/app/(landing)/[slug]/page.tsx | 10 +- .../src/app/(landing)/blog/[slug]/page.tsx | 14 +- .../(landing)/blog/category/[slug]/page.tsx | 12 +- .../src/app/(landing)/blog/category/page.tsx | 7 +- .../src/app/(landing)/blog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/blog/page.tsx | 11 +- .../app/(landing)/changelog/[slug]/page.tsx | 14 +- .../changelog/category/[slug]/page.tsx | 12 +- .../app/(landing)/changelog/category/page.tsx | 7 +- .../app/(landing)/changelog/feed.xml/route.ts | 2 +- apps/web/src/app/(landing)/changelog/page.tsx | 11 +- .../src/app/(landing)/compare/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/compare/page.tsx | 11 +- .../src/app/(landing)/content-box-image.tsx | 4 +- apps/web/src/app/(landing)/content-box.tsx | 2 +- .../src/app/(landing)/content-category.tsx | 2 +- apps/web/src/app/(landing)/content-list.tsx | 4 +- .../src/app/(landing)/content-metadata.tsx | 4 +- .../src/app/(landing)/content-pagination.tsx | 2 +- .../app/(landing)/customers/[slug]/page.tsx | 15 +- apps/web/src/app/(landing)/customers/page.tsx | 11 +- .../src/app/(landing)/guides/[slug]/page.tsx | 14 +- .../(landing)/guides/category/[slug]/page.tsx | 12 +- .../app/(landing)/guides/category/page.tsx | 7 +- apps/web/src/app/(landing)/guides/page.tsx | 11 +- apps/web/src/app/(landing)/layout.tsx | 6 +- .../src/app/(landing)/oss-friends/page.tsx | 5 +- apps/web/src/app/(landing)/page.tsx | 10 +- .../(landing)/play/checker/[slug]/client.tsx | 7 +- .../(landing)/play/checker/[slug]/page.tsx | 18 +- .../app/(landing)/play/checker/api/route.ts | 10 +- .../src/app/(landing)/play/checker/client.tsx | 9 +- .../src/app/(landing)/play/checker/page.tsx | 18 +- .../src/app/(landing)/play/checker/utils.ts | 4 +- apps/web/src/app/(landing)/play/curl/page.tsx | 14 +- .../(landing)/play/mcp-health/[id]/client.tsx | 3 +- .../(landing)/play/mcp-health/[id]/page.tsx | 16 +- .../(landing)/play/mcp-health/api/route.ts | 4 +- .../app/(landing)/play/mcp-health/client.tsx | 7 +- .../app/(landing)/play/mcp-health/page.tsx | 16 +- .../(landing)/play/mcp-health/utils.test.ts | 3 +- .../app/(landing)/play/mcp-health/utils.ts | 10 +- apps/web/src/app/(landing)/play/page.tsx | 5 +- .../(landing)/play/severity-matrix/client.tsx | 2 +- .../(landing)/play/severity-matrix/page.tsx | 14 +- .../app/(landing)/play/uptime-sla/page.tsx | 14 +- .../[id]/[component]/component-detail.tsx | 21 +- .../status/[id]/[component]/page.tsx | 11 +- .../app/(landing)/status/[id]/incidents.tsx | 6 +- .../src/app/(landing)/status/[id]/page.tsx | 13 +- .../(landing)/status/[id]/report-issue.tsx | 3 +- .../status/[id]/service-components.tsx | 3 +- .../(landing)/status/[id]/service-detail.tsx | 9 +- .../(landing)/status/[id]/user-reports.tsx | 2 +- .../(landing)/status/external-status-grid.tsx | 5 +- apps/web/src/app/(landing)/status/page.tsx | 9 +- .../src/app/(landing)/tooling/[slug]/page.tsx | 13 +- apps/web/src/app/(landing)/tooling/page.tsx | 11 +- .../app/(landing)/use-case/[slug]/page.tsx | 14 +- apps/web/src/app/(landing)/use-case/page.tsx | 11 +- apps/web/src/app/api/checker/cron/_cron.ts | 2 +- .../src/app/api/checker/test/http/route.ts | 3 +- apps/web/src/app/api/feedback/docs/route.ts | 4 +- .../src/app/api/markdown/[[...path]]/route.ts | 6 +- .../src/app/api/og/_components/background.tsx | 2 +- .../app/api/og/_components/basic-layout.tsx | 3 +- .../app/api/og/_components/status-check.tsx | 2 +- .../src/app/api/og/_components/tracker.tsx | 4 +- apps/web/src/app/api/og/checker/route.tsx | 5 +- .../src/app/api/og/external-service/route.tsx | 9 +- apps/web/src/app/api/og/monitor/route.tsx | 5 +- apps/web/src/app/api/og/page/route.tsx | 5 +- apps/web/src/app/api/og/post/route.tsx | 3 +- apps/web/src/app/api/og/route.tsx | 3 +- apps/web/src/app/api/og/status/route.tsx | 7 +- apps/web/src/app/api/search/route.ts | 4 +- apps/web/src/app/api/test/timeout/route.ts | 2 +- .../web/src/app/api/trpc/edge/[trpc]/route.ts | 2 +- .../src/app/api/trpc/lambda/[trpc]/route.ts | 2 +- apps/web/src/app/api/webhook/stripe/route.ts | 2 +- apps/web/src/app/layout.tsx | 12 +- apps/web/src/app/not-found.tsx | 4 +- apps/web/src/app/sitemap.ts | 4 +- .../web/src/components/dev-mode-container.tsx | 2 +- .../src/components/icon-cloud-provider.tsx | 2 +- apps/web/src/components/loading-animation.tsx | 2 +- apps/web/src/config/socials.ts | 2 +- apps/web/src/content/cmdk.tsx | 8 +- apps/web/src/content/docs-feedback.tsx | 2 +- apps/web/src/content/docs-footer.tsx | 5 +- apps/web/src/content/docs-sidebar.tsx | 3 +- apps/web/src/content/docs-sub-nav.tsx | 3 +- apps/web/src/content/docs-toc.tsx | 3 +- apps/web/src/content/footer-status.tsx | 2 +- apps/web/src/content/footer.tsx | 7 +- apps/web/src/content/header.tsx | 3 +- apps/web/src/content/highlight-text.tsx | 2 +- apps/web/src/content/image-zoom.tsx | 2 +- apps/web/src/content/latency-chart-table.tsx | 3 +- apps/web/src/content/link.tsx | 2 +- apps/web/src/content/mdx-components/aside.tsx | 2 +- apps/web/src/content/mdx-components/card.tsx | 2 +- .../content/mdx-components/custom-image.tsx | 5 +- apps/web/src/content/mdx-components/grid.tsx | 2 +- .../web/src/content/mdx-components/subtle.tsx | 2 +- apps/web/src/content/simple-chart.tsx | 2 +- apps/web/src/content/status-markdown.ts | 4 +- apps/web/src/content/sub-nav.tsx | 3 +- apps/web/src/content/theme-toggle.tsx | 2 +- apps/web/src/content/utils/search-index.ts | 3 +- .../src/content/utils/search-match.test.ts | 3 +- apps/web/src/data/content.ts | 2 +- apps/web/src/data/trigger-dictionary.ts | 4 +- apps/web/src/lib/checker/mock.ts | 4 +- .../web/src/lib/external-report-escalation.ts | 2 +- apps/web/src/lib/mcp/health-check.test.ts | 3 +- apps/web/src/lib/metadata/shared-metadata.ts | 2 +- apps/web/src/lib/metadata/structured-data.ts | 3 +- apps/web/src/lib/stripe/client.ts | 2 +- apps/web/src/lib/tb.ts | 2 +- apps/workflows/.gitignore | 4 + apps/workflows/Dockerfile | 66 +- apps/workflows/deno-migration-plan.md | 437 ++++++++++++ apps/workflows/docker-compose.yaml | 11 +- apps/workflows/dofigen.lock | 204 +++--- apps/workflows/dofigen.yml | 68 +- apps/workflows/package.json | 13 +- apps/workflows/src/build-docker.ts | 81 --- apps/workflows/src/checker/alerting.test.ts | 175 ++--- apps/workflows/src/cron/checker.ts | 2 +- apps/workflows/src/cron/index.ts | 2 +- apps/workflows/src/index.ts | 50 +- apps/workflows/src/lib/sentry.ts | 2 +- apps/workflows/src/serve.ts | 15 + apps/workflows/start.sh | 2 +- apps/workflows/tsconfig.json | 1 - deno.lock | 277 ++++++++ package.json | 1 + packages/analytics/package.json | 4 +- packages/analytics/tsconfig.json | 1 - packages/api/.env.test | 1 + packages/api/env.ts | 3 +- packages/api/package.json | 11 +- packages/api/src/router/blob.test.ts | 3 +- .../api/src/router/effective-status.test.ts | 3 +- packages/api/src/router/import.test.ts | 12 +- packages/api/src/router/maintenance.test.ts | 4 +- packages/api/src/router/monitor.test.ts | 214 +++--- packages/api/src/router/notification.test.ts | 4 +- packages/api/src/router/page.ts | 4 - packages/api/src/router/pageComponent.test.ts | 4 +- .../api/src/router/privateLocation.test.ts | 126 ++-- .../api/src/router/statusPage.e2e.test.ts | 5 +- .../src/router/statusPage.unsubscribe.test.ts | 4 +- .../api/src/router/statusPage.utils.test.ts | 4 +- packages/api/src/router/statusReport.test.ts | 4 +- packages/api/src/router/stripe/utils.test.ts | 4 +- .../api/src/router/tinybird/index.test.ts | 4 +- packages/api/src/router/workspace.test.ts | 3 +- packages/api/src/test/preload.ts | 12 - packages/api/src/test/upstash.mock.ts | 18 + packages/api/src/trpc.ts | 2 +- packages/api/test.importmap.json | 5 + packages/api/tsconfig.json | 5 +- packages/assertions/package.json | 4 +- packages/assertions/src/v1.ts | 2 +- packages/assertions/tsconfig.json | 3 - packages/db/env.ts | 3 +- packages/db/package.json | 22 +- packages/db/script/region-migration.test.ts | 4 +- .../src/schema/page_components/validation.ts | 2 +- packages/db/src/seed.mts | 30 +- packages/db/src/test/factories.ts | 50 ++ packages/db/src/utils/api-key.test.ts | 3 +- packages/db/tsconfig.json | 1 - packages/emails/package.json | 10 +- .../emails/src/client.integration.test.tsx | 5 +- packages/emails/src/client.test.ts | 49 +- packages/emails/tsconfig.json | 8 +- packages/error/package.json | 4 +- packages/header-analysis/package.json | 8 +- .../src/parser/x-vercel-cache.test.ts | 17 +- packages/icons/package.json | 1 + packages/importers/package.json | 7 +- .../src/providers/betterstack/client.test.ts | 16 +- .../src/providers/betterstack/mapper.test.ts | 3 +- .../providers/betterstack/provider.test.ts | 8 +- .../src/providers/instatus/client.test.ts | 18 +- .../src/providers/instatus/mapper.test.ts | 13 +- .../src/providers/instatus/provider.test.ts | 3 +- .../src/providers/statuspage/client.test.ts | 18 +- .../src/providers/statuspage/mapper.test.ts | 13 +- .../src/providers/statuspage/provider.test.ts | 3 +- packages/locales/package.json | 4 +- packages/notifications/base/package.json | 6 +- .../base/src/utils/duration.test.ts | 3 +- .../base/src/utils/incident.test.ts | 5 +- .../notifications/bird-whatsapp/package.json | 6 +- .../bird-whatsapp/src/index.test.ts | 36 +- .../notifications/bird-whatsapp/tsconfig.json | 4 +- packages/notifications/discord/package.json | 6 +- .../notifications/discord/src/index.test.ts | 40 +- packages/notifications/discord/tsconfig.json | 4 +- packages/notifications/email/package.json | 5 +- .../notifications/email/src/index.test.ts | 49 +- .../notifications/email/src/test-preload.ts | 10 + packages/notifications/email/tsconfig.json | 4 +- .../notifications/google-chat/package.json | 6 +- .../google-chat/src/index.test.ts | 35 +- .../notifications/google-chat/tsconfig.json | 4 +- .../notifications/grafana-oncall/package.json | 6 +- .../grafana-oncall/src/index.test.ts | 54 +- .../grafana-oncall/tsconfig.json | 4 +- packages/notifications/ms-teams/package.json | 6 +- .../notifications/ms-teams/src/index.test.ts | 28 +- packages/notifications/ms-teams/tsconfig.json | 4 +- packages/notifications/ntfy/package.json | 6 +- packages/notifications/ntfy/src/index.test.ts | 64 +- packages/notifications/ntfy/tsconfig.json | 4 +- packages/notifications/opsgenie/package.json | 6 +- .../notifications/opsgenie/src/index.test.ts | 36 +- packages/notifications/opsgenie/tsconfig.json | 4 +- packages/notifications/pagerduty/package.json | 6 +- .../notifications/pagerduty/src/index.test.ts | 46 +- .../notifications/pagerduty/tsconfig.json | 4 +- packages/notifications/slack/package.json | 6 +- .../notifications/slack/src/index.test.ts | 47 +- packages/notifications/slack/tsconfig.json | 4 +- packages/notifications/telegram/package.json | 6 +- .../notifications/telegram/src/index.test.ts | 54 +- packages/notifications/telegram/tsconfig.json | 4 +- .../notifications/twillio-sms/package.json | 6 +- .../twillio-sms/src/index.test.ts | 35 +- .../notifications/twillio-sms/tsconfig.json | 4 +- packages/notifications/webhook/package.json | 6 +- .../notifications/webhook/src/index.test.ts | 76 +- packages/proto/package.json | 3 +- packages/regions/package.json | 4 +- packages/services/package.json | 6 +- packages/services/src/__tests__/retry.test.ts | 3 +- .../__tests__/with-test-transaction.test.ts | 4 +- .../src/__tests__/with-transaction.test.ts | 3 +- .../src/agent-tools/__tests__/docs.test.ts | 16 +- .../__tests__/shape-equivalence.test.ts | 3 +- .../__tests__/status-report-impacts.test.ts | 4 +- .../src/api-key/__tests__/api-key.test.ts | 18 +- .../src/audit/__tests__/audit.test.ts | 4 +- .../src/auth/__tests__/matches-scope.test.ts | 4 +- .../src/auth/__tests__/require-scope.test.ts | 3 +- .../external-service-component.test.ts | 4 +- .../__tests__/internal.test.ts | 3 +- .../external-service-incident.test.ts | 4 +- .../__tests__/record.test.ts | 4 +- .../__tests__/external-service.test.ts | 4 +- .../import/__tests__/incidents-phase.test.ts | 4 +- .../src/import/__tests__/unit.test.ts | 4 +- .../src/incident/__tests__/incident.test.ts | 4 +- .../__tests__/install-slack-agent.test.ts | 8 +- .../invitation/__tests__/invitation.test.ts | 18 +- .../maintenance/__tests__/maintenance.test.ts | 17 +- .../src/member/__tests__/member.test.ts | 6 +- .../monitor-tag/__tests__/monitor-tag.test.ts | 6 +- .../src/monitor/__tests__/monitor.test.ts | 26 +- .../src/monitor/__tests__/reads.test.ts | 4 +- .../__tests__/stream-monitor-preview.test.ts | 15 +- .../__tests__/notification.test.ts | 4 +- .../__tests__/get-daily-summary.test.ts | 4 +- .../__tests__/page-component.test.ts | 4 +- .../__tests__/page-subscriber.test.ts | 37 +- .../services/src/page/__tests__/page.test.ts | 4 +- .../__tests__/status-report.test.ts | 17 +- .../src/workspace/__tests__/workspace.test.ts | 16 +- packages/services/test/helpers.ts | 3 +- packages/services/tsconfig.json | 3 +- .../status-fetcher/__tests__/fetch.test.ts | 17 +- .../__tests__/fetchers/atlassian.test.ts | 20 +- .../__tests__/fetchers/betterstack.test.ts | 15 +- .../__tests__/fetchers/components.test.ts | 8 +- .../__tests__/fetchers/custom.test.ts | 3 +- .../__tests__/fetchers/edge-cases.test.ts | 4 +- .../__tests__/fetchers/html.test.ts | 8 +- .../__tests__/fetchers/incidentio.test.ts | 20 +- .../__tests__/fetchers/instatus.test.ts | 15 +- .../__tests__/fetchers/uptimerobot.test.ts | 13 +- packages/status-fetcher/__tests__/helpers.ts | 5 +- .../__tests__/integration.test.ts | 4 +- .../status-fetcher/__tests__/utils.test.ts | 3 +- packages/status-fetcher/package.json | 8 +- packages/status-fetcher/tsconfig.json | 1 - packages/subscriptions/package.json | 6 +- .../subscriptions/src/channels/email.test.ts | 52 +- .../subscriptions/src/channels/index.test.ts | 4 +- .../src/channels/webhook.test.ts | 131 ++-- packages/subscriptions/src/dispatcher.test.ts | 63 +- packages/subscriptions/src/test-preload.ts | 13 +- packages/subscriptions/tsconfig.json | 4 +- packages/test-utils/package.json | 20 + packages/test-utils/src/index.ts | 27 + packages/test-utils/src/matchers.ts | 95 +++ packages/test-utils/src/mock-fn.ts | 112 +++ packages/test-utils/src/runner.ts | 58 ++ packages/theme-store/package.json | 4 +- packages/tinybird/package.json | 3 + packages/tracker/package.json | 6 +- packages/tracker/src/mock.ts | 4 +- packages/tracker/src/tracker.test.ts | 20 +- packages/tracker/src/tracker.ts | 2 +- packages/tracker/tsconfig.json | 3 +- packages/upstash/package.json | 3 + packages/utils/package.json | 6 +- packages/utils/src/ssrf.test.ts | 3 +- pnpm-lock.yaml | 659 +++++++++++------- pnpm-workspace.yaml | 14 +- turbo.json | 1 + 534 files changed, 4804 insertions(+), 2975 deletions(-) create mode 100644 .github/workflows/check.yml delete mode 100644 apps/server/bunfig.toml create mode 100644 apps/server/deno.jsonc create mode 100644 apps/server/src/libs/test/doubles/analytics.mock.ts create mode 100644 apps/server/src/libs/test/doubles/page-urls.mock.ts create mode 100644 apps/server/src/libs/test/doubles/slack-agent.mock.ts create mode 100644 apps/server/src/libs/test/doubles/slack-test-state.ts create mode 100644 apps/server/src/libs/test/doubles/slack-web-api.mock.ts create mode 100644 apps/server/src/libs/test/doubles/state.ts create mode 100644 apps/server/src/libs/test/doubles/subscriptions.mock.ts create mode 100644 apps/server/src/libs/test/doubles/tinybird.mock.ts create mode 100644 apps/server/src/libs/test/doubles/upstash.mock.ts create mode 100644 apps/server/src/libs/test/doubles/workspace-resolver.mock.ts create mode 100644 apps/server/src/serve.ts create mode 100644 apps/server/test.importmap.json create mode 100644 apps/workflows/deno-migration-plan.md delete mode 100644 apps/workflows/src/build-docker.ts create mode 100644 apps/workflows/src/serve.ts create mode 100644 deno.lock delete mode 100644 packages/api/src/test/preload.ts create mode 100644 packages/api/src/test/upstash.mock.ts create mode 100644 packages/api/test.importmap.json create mode 100644 packages/db/src/test/factories.ts create mode 100644 packages/notifications/email/src/test-preload.ts create mode 100644 packages/test-utils/package.json create mode 100644 packages/test-utils/src/index.ts create mode 100644 packages/test-utils/src/matchers.ts create mode 100644 packages/test-utils/src/mock-fn.ts create mode 100644 packages/test-utils/src/runner.ts diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..19510a39 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,39 @@ +name: Check +on: + push: + branches: + - "main" + pull_request: + branches: [main] + +jobs: + check: + name: 🔍 Check + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ secrets.TURBO_TEAM }} + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v6 + + - name: Set up pnpm + uses: pnpm/action-setup@v6 + + - name: ⎔ Setup node + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: "pnpm" + + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + + - name: 📥 Download deps + run: pnpm install + + - name: 🔍 Check + run: pnpm check diff --git a/.github/workflows/dx.yml b/.github/workflows/dx.yml index 24e16afa..766bae46 100644 --- a/.github/workflows/dx.yml +++ b/.github/workflows/dx.yml @@ -41,10 +41,10 @@ jobs: - name: 📥 Download deps run: pnpm install - - name: 🔥 Install bun - uses: oven-sh/setup-bun@v2 + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 with: - bun-version: latest + deno-version: v2.x - name: 🔥 DX task run: pnpm dx diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 60003b7a..915d6aa7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@v6 - name: Set up pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v6 - name: ⎔ Setup node uses: actions/setup-node@v6 @@ -38,10 +38,10 @@ jobs: node-version: 24 cache: "pnpm" - - name: 🔥 Install bun - uses: oven-sh/setup-bun@v2 + - name: 🦕 Setup Deno + uses: denoland/setup-deno@v2 with: - bun-version: latest + deno-version: v2.x - name: 📥 Download deps run: pnpm install diff --git a/apps/dashboard/env.ts b/apps/dashboard/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/dashboard/env.ts +++ b/apps/dashboard/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/screenshot-service/package.json b/apps/screenshot-service/package.json index 63c73984..4bd7feb4 100644 --- a/apps/screenshot-service/package.json +++ b/apps/screenshot-service/package.json @@ -2,6 +2,7 @@ "name": "@openstatus/screenshot-service", "version": "0.0.1", "scripts": { + "check": "deno check --sloppy-imports .", "dev": "bun run --hot src/index.ts", "start": "NODE_ENV=production bun run src/index.ts" }, diff --git a/apps/server/.gitignore b/apps/server/.gitignore index 3c3629e6..c1fbf070 100644 --- a/apps/server/.gitignore +++ b/apps/server/.gitignore @@ -1 +1,5 @@ node_modules +app +src/_serve.bundle.mjs +.deno_compile_bundle_*.mjs +app.tmp-* diff --git a/apps/server/Dockerfile b/apps/server/Dockerfile index f4c19c32..178df222 100644 --- a/apps/server/Dockerfile +++ b/apps/server/Dockerfile @@ -3,9 +3,9 @@ # See https://github.com/lenra-io/dofigen # install -FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install +FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install LABEL \ - org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ + org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ @@ -48,14 +48,14 @@ RUN \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <({ const logger = getLogger("api-server"); const otelLogger = getLogger("api-server-otel"); +const openapiYaml = await Deno.readTextFile( + new URL("../static/openapi.yaml", import.meta.url), +); + /** * Configure logging asynchronously without blocking module initialization. * This allows tests to import `app` immediately. */ -const defaultLogger = getOpenTelemetrySink({ - serviceName: "openstatus-server", - otlpExporterConfig: { - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env.AXIOM_TOKEN}`, - "X-Axiom-Dataset": env.AXIOM_DATASET, - }, - }, - additionalResource: resourceFromAttributes({ +// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` +// includes it. Letting @logtape/otel create the exporter triggers a dynamic +// import of a bare specifier, which the compiled --node-modules-dir=none binary +// can't resolve. +const loggerProvider = new LoggerProvider({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: "openstatus-server", [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env.NODE_ENV, }), + processors: [ + new BatchLogRecordProcessor( + new OTLPLogExporter({ + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env.AXIOM_TOKEN}`, + "X-Axiom-Dataset": env.AXIOM_DATASET, + }, + }), + ), + ], +}); + +const defaultLogger = getOpenTelemetrySink({ + loggerProvider, }); await configure({ @@ -166,7 +187,7 @@ app.use("*", async (c, next) => { // Console logging only for errors in production if (env.NODE_ENV !== "production" || c.res.status >= 500) { logger.info("request", { - request_id: requestId, + request_id: reqId, method: c.req.method, path: c.req.path, status_code: c.res.status, @@ -263,13 +284,6 @@ app.route("/mcp", mcpRoute); * create incidents, and send notifications. */ -const isDev = process.env.NODE_ENV === "development"; -const port = 3000; - -if (isDev) showRoutes(app, { verbose: true, colorize: true }); - -logger.info("Starting server", { port, environment: env.NODE_ENV }); - -const server = { port, fetch: app.fetch }; - -export default server; +if (process.env.NODE_ENV === "development") { + showRoutes(app, { verbose: true, colorize: true }); +} diff --git a/apps/server/src/libs/middlewares/require-scope.test.ts b/apps/server/src/libs/middlewares/require-scope.test.ts index 05818307..f1f0962a 100644 --- a/apps/server/src/libs/middlewares/require-scope.test.ts +++ b/apps/server/src/libs/middlewares/require-scope.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Scope } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import type { Variables } from "@/types"; diff --git a/apps/server/src/libs/middlewares/validate-key.test.ts b/apps/server/src/libs/middlewares/validate-key.test.ts index 28527fb1..58f5355a 100644 --- a/apps/server/src/libs/middlewares/validate-key.test.ts +++ b/apps/server/src/libs/middlewares/validate-key.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { validateKey } from "./auth"; diff --git a/apps/server/src/libs/test/doubles/analytics.mock.ts b/apps/server/src/libs/test/doubles/analytics.mock.ts new file mode 100644 index 00000000..dfe71343 --- /dev/null +++ b/apps/server/src/libs/test/doubles/analytics.mock.ts @@ -0,0 +1,26 @@ +// Test double for @openstatus/analytics, swapped in via --import-map. Keeps the +// real Events/parseInputToProps but replaces setupAnalytics with a spy (exposed +// on globalThis.__analyticsSpies) so tests assert tracking without OpenPanel. +export { + type EventProps, + Events, + parseInputToProps, +} from "@openstatus/analytics-real"; + +import { mock } from "@openstatus/test-utils"; + +const g = globalThis as Record; +if (!g.__analyticsSpies) { + const track = mock(() => Promise.resolve()); + g.__analyticsSpies = { + track, + setupAnalytics: mock((_props: unknown) => Promise.resolve({ track })), + }; +} + +const spies = g.__analyticsSpies as { + track: ReturnType; + setupAnalytics: ReturnType; +}; + +export const setupAnalytics = (props: unknown) => spies.setupAnalytics(props); diff --git a/apps/server/src/libs/test/doubles/page-urls.mock.ts b/apps/server/src/libs/test/doubles/page-urls.mock.ts new file mode 100644 index 00000000..b4e18132 --- /dev/null +++ b/apps/server/src/libs/test/doubles/page-urls.mock.ts @@ -0,0 +1,10 @@ +// Test double for src/routes/slack/page-urls.ts (which hits the db), swapped in +// via --import-map so slack presenter tests get deterministic URLs. +export const getPageUrl = (_pageId: number): Promise => + Promise.resolve("https://example.openstatus.dev"); + +export const getReportUrl = ( + _pageId: number, + reportId: number, +): Promise => + Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`); diff --git a/apps/server/src/libs/test/doubles/slack-agent.mock.ts b/apps/server/src/libs/test/doubles/slack-agent.mock.ts new file mode 100644 index 00000000..ef4990b4 --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-agent.mock.ts @@ -0,0 +1,8 @@ +// Test double for slack/agent.ts (pulls in the AI SDK), swapped in via +// --import-map so handler tests don't run the real agent. +import { slackTestState } from "./slack-test-state.ts"; + +export const runAgent = () => { + if (slackTestState.runAgentOverride) return slackTestState.runAgentOverride(); + return Promise.resolve({ text: "Here is my response", toolResults: [] }); +}; diff --git a/apps/server/src/libs/test/doubles/slack-test-state.ts b/apps/server/src/libs/test/doubles/slack-test-state.ts new file mode 100644 index 00000000..9d19743e --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-test-state.ts @@ -0,0 +1,33 @@ +// Mutable per-test config shared by the slack module doubles below. Replaces +// the per-file bun `mock.module` closures (handler.test / interactions.test): +// each test sets the fields it needs in beforeEach and reads `calls`. +type SlackCall = { method: string; args: Record }; +type Override = ((args: Record) => Promise) | null; + +export interface SlackTestState { + resolveWorkspace: (teamId: string) => Promise; + calls: SlackCall[]; + postMessageOverride: Override; + updateOverride: Override; + postEphemeralOverride: Override; + runAgentOverride: (() => Promise) | null; + repliesImpl: () => Promise; +} + +const g = globalThis as Record; +if (!g.__slackTestState) { + g.__slackTestState = { + resolveWorkspace: () => Promise.resolve(null), + calls: [], + postMessageOverride: null, + updateOverride: null, + postEphemeralOverride: null, + runAgentOverride: null, + repliesImpl: () => + Promise.resolve({ + messages: [{ user: "U1", text: "test message", ts: "1.1" }], + }), + } satisfies SlackTestState; +} + +export const slackTestState = g.__slackTestState as SlackTestState; diff --git a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts new file mode 100644 index 00000000..fd8d3c93 --- /dev/null +++ b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts @@ -0,0 +1,26 @@ +// Test double for @slack/web-api (only WebClient is used), swapped in via +// --import-map. Captures chat calls into the shared slack test state. +import { slackTestState as s } from "./slack-test-state.ts"; + +export class WebClient { + chat = { + postMessage: (args: Record) => { + if (s.postMessageOverride) return s.postMessageOverride(args); + s.calls.push({ method: "postMessage", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + update: (args: Record) => { + if (s.updateOverride) return s.updateOverride(args); + s.calls.push({ method: "update", args }); + return Promise.resolve({ ts: "msg.ts" }); + }, + postEphemeral: (args: Record) => { + if (s.postEphemeralOverride) return s.postEphemeralOverride(args); + s.calls.push({ method: "postEphemeral", args }); + return Promise.resolve(); + }, + }; + conversations = { + replies: () => s.repliesImpl(), + }; +} diff --git a/apps/server/src/libs/test/doubles/state.ts b/apps/server/src/libs/test/doubles/state.ts new file mode 100644 index 00000000..ec223907 --- /dev/null +++ b/apps/server/src/libs/test/doubles/state.ts @@ -0,0 +1,49 @@ +// Shared test-double state, set on globalThis so tests can assert on spies and +// configure mock data — same interface the old bun `mock.module` preload +// exposed. Imported (for side effect) by every double module below. +import { mock } from "@openstatus/test-utils"; + +type Mut = Record; +const g = globalThis as Mut; + +if (!g.__subscriptionSpies) { + const sendVerification = mock(() => Promise.resolve()); + g.__subscriptionSpies = { + dispatchStatusReportUpdate: mock(() => Promise.resolve()), + dispatchMaintenanceUpdate: mock(() => Promise.resolve()), + sendVerification, + getChannel: { + id: "email", + sendVerification, + sendNotifications: mock(() => Promise.resolve()), + validateConfig: mock(() => Promise.resolve({ valid: true })), + }, + }; +} + +if (!g.__testRedisStore) { + g.__testRedisStore = new Map(); +} + +if (!g.__tinybirdMockData) { + g.__tinybirdMockData = { httpListBiweekly: [], httpGetBiweekly: [] }; +} +if (!g.__tinybirdMockCalls) { + g.__tinybirdMockCalls = { httpListBiweekly: [], httpGetBiweekly: [] }; +} + +export const subscriptionSpies = g.__subscriptionSpies as { + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; + sendVerification: ReturnType; + getChannel: Record; +}; +export const testRedisStore = g.__testRedisStore as Map; +export const tinybirdMockData = g.__tinybirdMockData as { + httpListBiweekly: unknown[]; + httpGetBiweekly: unknown[]; +}; +export const tinybirdMockCalls = g.__tinybirdMockCalls as { + httpListBiweekly: unknown[]; + httpGetBiweekly: unknown[]; +}; diff --git a/apps/server/src/libs/test/doubles/subscriptions.mock.ts b/apps/server/src/libs/test/doubles/subscriptions.mock.ts new file mode 100644 index 00000000..aaf5f297 --- /dev/null +++ b/apps/server/src/libs/test/doubles/subscriptions.mock.ts @@ -0,0 +1,11 @@ +// Test double for @openstatus/subscriptions, swapped in via --import-map. +// Re-exports the real module, overriding only the dispatch fns and getChannel +// with spies (exposed on globalThis via state.ts) so route tests can assert +// notification side effects without sending anything. +export * from "@openstatus/subscriptions-real"; + +import { subscriptionSpies as spies } from "./state.ts"; + +export const dispatchStatusReportUpdate = spies.dispatchStatusReportUpdate; +export const dispatchMaintenanceUpdate = spies.dispatchMaintenanceUpdate; +export const getChannel = () => spies.getChannel; diff --git a/apps/server/src/libs/test/doubles/tinybird.mock.ts b/apps/server/src/libs/test/doubles/tinybird.mock.ts new file mode 100644 index 00000000..2cf71dab --- /dev/null +++ b/apps/server/src/libs/test/doubles/tinybird.mock.ts @@ -0,0 +1,59 @@ +// Test double for @openstatus/tinybird, swapped in via --import-map. Overrides +// OSTinybird with a no-network stub backed by `__tinybirdMockData/Calls`, while +// re-exporting the real Tinybird/AuditLog/etc. for code that imports them. +export * from "@openstatus/tinybird-real"; + +import { + tinybirdMockCalls as calls, + tinybirdMockData as data, +} from "./state.ts"; + +const empty = () => Promise.resolve({ data: [] }); + +export class OSTinybird { + get legacy_httpStatus45d() { + return empty; + } + get legacy_tcpStatus45d() { + return empty; + } + get httpListBiweekly() { + return (params: unknown) => { + calls.httpListBiweekly.push(params); + return Promise.resolve({ data: data.httpListBiweekly }); + }; + } + get httpGetBiweekly() { + return (params: unknown) => { + calls.httpGetBiweekly.push(params); + return Promise.resolve({ data: data.httpGetBiweekly }); + }; + } + get httpMetricsDaily() { + return empty; + } + get httpMetricsWeekly() { + return empty; + } + get httpMetricsBiweekly() { + return empty; + } + get tcpMetricsDaily() { + return empty; + } + get tcpMetricsWeekly() { + return empty; + } + get tcpMetricsBiweekly() { + return empty; + } + get dnsMetricsDaily() { + return empty; + } + get dnsMetricsWeekly() { + return empty; + } + get dnsMetricsBiweekly() { + return empty; + } +} diff --git a/apps/server/src/libs/test/doubles/upstash.mock.ts b/apps/server/src/libs/test/doubles/upstash.mock.ts new file mode 100644 index 00000000..b4dc5fb2 --- /dev/null +++ b/apps/server/src/libs/test/doubles/upstash.mock.ts @@ -0,0 +1,36 @@ +// Test double for @openstatus/upstash, swapped in via --import-map. Backs the +// Redis client with the in-memory `__testRedisStore` Map so tests can assert +// on stored state without a real Upstash instance. +import { testRedisStore as store } from "./state.ts"; + +const client = { + get: (key: string) => Promise.resolve(store.get(key) ?? null), + set: (key: string, value: string) => { + store.set(key, value); + return Promise.resolve("OK"); + }, + del: (key: string) => { + const existed = store.has(key) ? 1 : 0; + store.delete(key); + return Promise.resolve(existed); + }, + getdel: (key: string) => { + const value = store.get(key) ?? null; + store.delete(key); + return Promise.resolve(value); + }, + incr: (key: string) => { + const next = Number(store.get(key) ?? 0) + 1; + store.set(key, String(next)); + return Promise.resolve(next); + }, + expire: () => Promise.resolve(1), +}; + +export const redis = client; + +export const Redis = { + fromEnv() { + return client; + }, +}; diff --git a/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts b/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts new file mode 100644 index 00000000..8766b79e --- /dev/null +++ b/apps/server/src/libs/test/doubles/workspace-resolver.mock.ts @@ -0,0 +1,6 @@ +// Test double for slack/workspace-resolver.ts (hits the db), swapped in via +// --import-map. Delegates to the per-test resolver in the shared slack state. +import { slackTestState } from "./slack-test-state.ts"; + +export const resolveWorkspace = (teamId: string) => + slackTestState.resolveWorkspace(teamId); diff --git a/apps/server/src/libs/test/preload.ts b/apps/server/src/libs/test/preload.ts index a2efeadb..232bf7f9 100644 --- a/apps/server/src/libs/test/preload.ts +++ b/apps/server/src/libs/test/preload.ts @@ -1,9 +1,8 @@ -import { mock } from "bun:test"; - // Import the real module BEFORE mock.module runs so we can spread real // service functions (createSubscription, updateChannel, etc.) into the // replacement while still stubbing the dispatch-side spies. import * as realSubscriptions from "@openstatus/subscriptions"; +import { mock } from "@openstatus/test-utils"; // Subscription dispatch spies — accessible in tests via globalThis.__subscriptionSpies const dispatchStatusReportUpdateSpy = mock((_id: number) => Promise.resolve()); diff --git a/apps/server/src/routes/mcp/adapter.test.ts b/apps/server/src/routes/mcp/adapter.test.ts index b5944189..b1a00d1a 100644 --- a/apps/server/src/routes/mcp/adapter.test.ts +++ b/apps/server/src/routes/mcp/adapter.test.ts @@ -1,7 +1,7 @@ -import { describe, expect, test } from "bun:test"; - import type { Workspace } from "@openstatus/db/src/schema"; import { ForbiddenError, NotFoundError } from "@openstatus/services"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { mapError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/mcp/adapter.ts b/apps/server/src/routes/mcp/adapter.ts index b19ede15..2f3d2a7d 100644 --- a/apps/server/src/routes/mcp/adapter.ts +++ b/apps/server/src/routes/mcp/adapter.ts @@ -1,5 +1,5 @@ -import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js"; import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { type ServiceContext, ServiceError } from "@openstatus/services"; import { ZodError } from "zod"; diff --git a/apps/server/src/routes/mcp/handler.test.ts b/apps/server/src/routes/mcp/handler.test.ts index baa6efc0..46ba666c 100644 --- a/apps/server/src/routes/mcp/handler.test.ts +++ b/apps/server/src/routes/mcp/handler.test.ts @@ -1,14 +1,13 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { sentry } from "@hono/sentry"; import { db, desc, eq } from "@openstatus/db"; import { auditLog, page, statusReport } from "@openstatus/db/src/schema"; import { SEEDED_WORKSPACE_TEAM_ID } from "@openstatus/services/test/fixtures"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { requestId } from "hono/request-id"; -import { handleError } from "@/libs/errors"; - +import { handleError } from "../../libs/errors"; import { mcpRoute } from "./index"; /** diff --git a/apps/server/src/routes/mcp/index.ts b/apps/server/src/routes/mcp/index.ts index 419f324c..822c47f4 100644 --- a/apps/server/src/routes/mcp/index.ts +++ b/apps/server/src/routes/mcp/index.ts @@ -1,10 +1,9 @@ import { StreamableHTTPTransport } from "@hono/mcp"; import { Hono } from "hono"; -import { handleError } from "@/libs/errors"; -import { authMiddleware } from "@/libs/middlewares/auth"; -import type { Variables } from "@/types"; - +import { handleError } from "../../libs/errors"; +import { authMiddleware } from "../../libs/middlewares/auth"; +import type { Variables } from "../../types"; import { toServiceCtx } from "./adapter"; import { createMcpServer } from "./server"; diff --git a/apps/server/src/routes/mcp/tools/register-scoped.test.ts b/apps/server/src/routes/mcp/tools/register-scoped.test.ts index f853a8f7..3b5eae6f 100644 --- a/apps/server/src/routes/mcp/tools/register-scoped.test.ts +++ b/apps/server/src/routes/mcp/tools/register-scoped.test.ts @@ -1,8 +1,8 @@ -import { describe, expect, test } from "bun:test"; - import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { Workspace } from "@openstatus/db/src/schema"; import type { ServiceContext } from "@openstatus/services"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { registerScopedTool } from "./register-scoped"; diff --git a/apps/server/src/routes/mcp/tools/tools.test.ts b/apps/server/src/routes/mcp/tools/tools.test.ts index 0d64855a..3e4e82b3 100644 --- a/apps/server/src/routes/mcp/tools/tools.test.ts +++ b/apps/server/src/routes/mcp/tools/tools.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { db, eq } from "@openstatus/db"; import { @@ -21,6 +19,8 @@ import { readAuditLog, withTestTransaction, } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { toServiceCtx } from "../adapter"; import { registerMaintenanceTools } from "./maintenance"; diff --git a/apps/server/src/routes/public/status.test.ts b/apps/server/src/routes/public/status.test.ts index 49c71237..679c461e 100644 --- a/apps/server/src/routes/public/status.test.ts +++ b/apps/server/src/routes/public/status.test.ts @@ -1,15 +1,14 @@ +import { db, eq } from "@openstatus/db"; +import { expect } from "@std/expect"; import { afterAll, beforeAll, beforeEach, describe, - expect, test, -} from "bun:test"; - -import { db, eq } from "@openstatus/db"; +} from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../index"; const testRedisStore = (globalThis as Record) .__testRedisStore as Map | undefined; diff --git a/apps/server/src/routes/public/status.ts b/apps/server/src/routes/public/status.ts index 04941603..dc115266 100644 --- a/apps/server/src/routes/public/status.ts +++ b/apps/server/src/routes/public/status.ts @@ -7,7 +7,7 @@ import { endTime, setMetric, startTime } from "hono/timing"; const logger = getLogger("api-server"); import { Status, Tracker } from "@openstatus/tracker"; -import { redis } from "@/libs/clients"; +import { redis } from "../../libs/clients"; // TODO: include ratelimiting diff --git a/apps/server/src/routes/rpc/adapter.test.ts b/apps/server/src/routes/rpc/adapter.test.ts index d5f02493..381bfa33 100644 --- a/apps/server/src/routes/rpc/adapter.test.ts +++ b/apps/server/src/routes/rpc/adapter.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { Code, ConnectError } from "@connectrpc/connect"; import type { Workspace } from "@openstatus/db/src/schema"; import { @@ -14,6 +12,8 @@ import { loadSeededWorkspace, withTestTransaction, } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { toConnectError, toServiceCtx } from "./adapter"; diff --git a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts index 874d96f6..bfedbb0d 100644 --- a/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts +++ b/apps/server/src/routes/rpc/handlers/maintenance/__tests__/maintenance.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -7,14 +5,19 @@ import { page, pageComponent, pageSubscriber, + workspace, } from "@openstatus/db/src/schema"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; +import { nanoid } from "nanoid"; -import { app } from "@/index"; +import { app } from "../../../../../index"; const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -40,6 +43,14 @@ async function connectRequest( } const TEST_PREFIX = "rpc-maintenance-test"; +// Scoped to a dedicated workspace+page so parallel suites mutating the +// shared seed workspace 1 / page 1 can't delete our fixtures mid-run. +// dev/test `validateKey` maps `x-openstatus-key` to the workspace id. +const WORKSPACE_LIMITS = + '{"monitors":50,"synthetic-checks":150000,"periodicity":["30s","1m","5m","10m","30m","1h"],"multi-region":true,"max-regions":35,"data-retention":"24 months","status-pages":20,"maintenance":true,"status-subscribers":true,"custom-domain":true,"password-protection":true,"email-domain-protection":true,"white-label":true,"notifications":true,"sms":true,"pagerduty":true,"notification-channels":50,"members":"Unlimited","audit-log":true}'; +let testWorkspaceId: number; +let authKey: string; +let testPageId: number; let testPageComponentId: number; let testMaintenanceId: number; let testMaintenanceToDeleteId: number; @@ -51,26 +62,39 @@ let testPage2Id: number; let testPage2ComponentId: number; beforeAll(async () => { - // Clean up any existing test data - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-main`)); - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-to-delete`)); - await db - .delete(maintenance) - .where(eq(maintenance.title, `${TEST_PREFIX}-to-update`)); - await db - .delete(pageComponent) - .where(eq(pageComponent.name, `${TEST_PREFIX}-component`)); + const ws = await db + .insert(workspace) + .values({ + slug: `${TEST_PREFIX}-ws-${nanoid(8)}`, + name: `${TEST_PREFIX}-workspace`, + plan: "team", + limits: WORKSPACE_LIMITS, + }) + .returning() + .get(); + testWorkspaceId = ws.id; + authKey = String(testWorkspaceId); + + // Primary page for the suite (replaces shared seed page 1). + const mainPage = await db + .insert(page) + .values({ + workspaceId: testWorkspaceId, + title: `${TEST_PREFIX}-page`, + slug: `${TEST_PREFIX}-page-slug-${nanoid(8)}`, + description: "Primary test page for maintenance tests", + customDomain: "", + }) + .returning() + .get(); + testPageId = mainPage.id; - // Create a test page component (using existing page 1 from seed) + // Create a test page component on the suite's page const component = await db .insert(pageComponent) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, type: "static", name: `${TEST_PREFIX}-component`, description: "Test component for maintenance tests", @@ -84,9 +108,9 @@ beforeAll(async () => { const page2 = await db .insert(page) .values({ - workspaceId: 1, + workspaceId: testWorkspaceId, title: `${TEST_PREFIX}-page-2`, - slug: `${TEST_PREFIX}-page-2-slug`, + slug: `${TEST_PREFIX}-page-2-slug-${nanoid(8)}`, description: "Second test page for mixed-page tests", customDomain: "", }) @@ -97,7 +121,7 @@ beforeAll(async () => { const component2 = await db .insert(pageComponent) .values({ - workspaceId: 1, + workspaceId: testWorkspaceId, pageId: testPage2Id, type: "static", name: `${TEST_PREFIX}-component-2`, @@ -112,8 +136,8 @@ beforeAll(async () => { const maintenanceRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-main`, message: "Test maintenance message", from: new Date(Date.now() + 24 * 60 * 60 * 1000), // 1 day from now @@ -133,8 +157,8 @@ beforeAll(async () => { const deleteRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-to-delete`, message: "Maintenance to delete", from: new Date(Date.now() + 48 * 60 * 60 * 1000), @@ -148,8 +172,8 @@ beforeAll(async () => { const updateRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-to-update`, message: "Maintenance to update", from: new Date(Date.now() + 72 * 60 * 60 * 1000), @@ -168,8 +192,8 @@ beforeAll(async () => { const notifyRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-for-notify`, message: "Maintenance for notify tests", from: new Date(Date.now() + 96 * 60 * 60 * 1000), @@ -188,7 +212,7 @@ beforeAll(async () => { const subscriber = await db .insert(pageSubscriber) .values({ - pageId: 1, + pageId: testPageId, email: `${TEST_PREFIX}@example.com`, token: `${TEST_PREFIX}-token`, acceptedAt: new Date(), @@ -248,6 +272,14 @@ afterAll(async () => { .delete(pageComponent) .where(eq(pageComponent.name, `${TEST_PREFIX}-component-2`)); await db.delete(page).where(eq(page.title, `${TEST_PREFIX}-page-2`)); + + // Tear down the dedicated page + workspace last (FK order). + if (testPageId) { + await db.delete(page).where(eq(page.id, testPageId)); + } + if (testWorkspaceId) { + await db.delete(workspace).where(eq(workspace.id, testWorkspaceId)); + } }); describe("MaintenanceService.CreateMaintenance", () => { @@ -262,10 +294,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Scheduled maintenance for system upgrade.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [String(testPageComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -303,8 +335,8 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", - pageComponentIds: ["1"], + pageId: String(testPageId), + pageComponentIds: [String(testPageComponentId)], }); expect(res.status).toBe(401); @@ -321,10 +353,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: ["99999"], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -341,13 +373,13 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test message", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [ String(testPageComponentId), String(testPage2ComponentId), ], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -368,10 +400,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test pageId mismatch with components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", // This doesn't match testPage2ComponentId's page + pageId: String(testPageId), // This doesn't match testPage2ComponentId's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -397,7 +429,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: String(testPage2Id), // Matching the component's page pageComponentIds: [String(testPage2ComponentId)], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -441,10 +473,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Maintenance without components.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -474,11 +506,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Notifying subscribers about this maintenance.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [String(testPageComponentId)], notify: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -519,11 +551,11 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "No notification for this one.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], notify: false, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -551,10 +583,10 @@ describe("MaintenanceService.CreateMaintenance", () => { to: new Date( Date.now() + 7 * 24 * 60 * 60 * 1000 + 3600000, ).toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -573,10 +605,10 @@ describe("MaintenanceService.CreateMaintenance", () => { message: "Test with invalid date range.", from: fromDate.toISOString(), to: toDate.toISOString(), - pageId: "1", + pageId: String(testPageId), pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -598,7 +630,7 @@ describe("MaintenanceService.CreateMaintenance", () => { pageId: "99999", pageComponentIds: [], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -616,7 +648,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(testMaintenanceId) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -646,7 +678,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "99999" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -670,7 +702,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -683,7 +715,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: "" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -693,7 +725,7 @@ describe("MaintenanceService.GetMaintenance", () => { const res = await connectRequest( "GetMaintenance", { id: " " }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -705,7 +737,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -720,7 +752,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -749,7 +781,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -763,7 +795,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res1 = await connectRequest( "ListMaintenances", {}, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data1 = await res1.json(); const totalSize = data1.totalSize; @@ -773,7 +805,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res2 = await connectRequest( "ListMaintenances", { limit: 1, offset: 0 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data2 = await res2.json(); @@ -781,7 +813,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res3 = await connectRequest( "ListMaintenances", { limit: 1, offset: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); const data3 = await res3.json(); @@ -795,16 +827,16 @@ describe("MaintenanceService.ListMaintenances", () => { test("filters by page_id", async () => { const res = await connectRequest( "ListMaintenances", - { pageId: "1" }, - { "x-openstatus-key": "1" }, + { pageId: String(testPageId) }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); const data = await res.json(); - // All returned maintenances should have pageId 1 + // All returned maintenances should belong to the filtered page for (const record of data.maintenances || []) { - expect(record.pageId).toBe("1"); + expect(record.pageId).toBe(String(testPageId)); } }); @@ -826,7 +858,7 @@ describe("MaintenanceService.ListMaintenances", () => { const res = await connectRequest( "ListMaintenances", { limit: 100 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -851,7 +883,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-updated-title`, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -874,7 +906,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), message: "Updated maintenance message", }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -890,21 +922,22 @@ describe("MaintenanceService.UpdateMaintenance", () => { }); test("updates page component associations", async () => { - // Use existing seeded page component 1 const res = await connectRequest( "UpdateMaintenance", { id: String(testMaintenanceToUpdateId), - pageComponentIds: ["1"], + pageComponentIds: [String(testPageComponentId)], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); const data = await res.json(); - expect(data.maintenance.pageComponentIds).toContain("1"); + expect(data.maintenance.pageComponentIds).toContain( + String(testPageComponentId), + ); }); test("returns 401 when no auth key provided", async () => { @@ -920,7 +953,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "99999", title: "Non-existent update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -930,7 +963,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: "", title: "Empty ID update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -940,7 +973,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: " ", title: "Whitespace ID update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -964,7 +997,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { const res = await connectRequest( "UpdateMaintenance", { id: String(otherRecord.id), title: "Should not update" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -981,7 +1014,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: ["99999"], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -998,7 +1031,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { ], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1024,7 +1057,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), from: newFrom.toISOString(), }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1055,7 +1088,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), title: `${TEST_PREFIX}-title-only`, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1104,7 +1137,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageComponentIds: ["99999"], }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1136,7 +1169,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { id: String(testMaintenanceToUpdateId), pageId: "999", }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1154,8 +1187,8 @@ describe("MaintenanceService.UpdateMaintenance", () => { const tempRecord = await db .insert(maintenance) .values({ - workspaceId: 1, - pageId: 1, + workspaceId: testWorkspaceId, + pageId: testPageId, title: `${TEST_PREFIX}-clear-pageid`, message: "Temp maintenance for clear test", from: new Date(Date.now() + 24 * 60 * 60 * 1000), @@ -1177,7 +1210,7 @@ describe("MaintenanceService.UpdateMaintenance", () => { pageComponentIds: [], updatePageComponentIds: true, }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1209,7 +1242,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(testMaintenanceToDeleteId) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(200); @@ -1236,7 +1269,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "99999" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); @@ -1246,7 +1279,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: "" }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1256,7 +1289,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: " " }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(400); @@ -1280,7 +1313,7 @@ describe("MaintenanceService.DeleteMaintenance", () => { const res = await connectRequest( "DeleteMaintenance", { id: String(otherRecord.id) }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": authKey }, ); expect(res.status).toBe(404); diff --git a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts index 7b9e19d9..2a6c33c7 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/__tests__/monitor.test.ts @@ -1,12 +1,3 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { auditLog, @@ -14,10 +5,23 @@ import { pageComponent, privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; import { monitorStatusTable } from "@openstatus/db/src/schema/monitor_status/monitor_status"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -499,20 +503,17 @@ describe("MonitorService.DeleteMonitor", () => { }); test("cannot delete monitor from another workspace", async () => { - // Create a monitor for workspace 2 - const otherWorkspaceMon = await db - .insert(monitor) - .values({ - workspaceId: 2, - name: `${TEST_PREFIX}-delete-other-ws`, - url: "https://other-ws-delete.example.com", - periodicity: "1m", - active: true, - regions: "ams", - jobType: "http", - }) - .returning() - .get(); + // Isolated workspace (fresh, unique id) so this never collides with seed + // data or another suite mutating workspace 2 in parallel. + const otherWorkspace = await createWorkspace(); + const otherWorkspaceMon = await createMonitor(otherWorkspace.id, { + name: `${TEST_PREFIX}-delete-other-ws`, + url: "https://other-ws-delete.example.com", + periodicity: "1m", + active: true, + regions: "ams", + jobType: "http", + }); try { // Try to delete with workspace 1's key @@ -536,6 +537,7 @@ describe("MonitorService.DeleteMonitor", () => { expect(stillExists?.deletedAt).toBeNull(); } finally { await db.delete(monitor).where(eq(monitor.id, otherWorkspaceMon.id)); + await db.delete(workspace).where(eq(workspace.id, otherWorkspace.id)); } }); diff --git a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts index bce0efdc..c617b766 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/converters/regions.test.ts @@ -1,7 +1,7 @@ -import { describe, expect, test } from "bun:test"; - import { Region } from "@openstatus/proto/monitor/v1"; import { AVAILABLE_REGIONS, RAILWAY_REGIONS } from "@openstatus/regions"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { regionToString, @@ -20,13 +20,17 @@ describe("region converter", () => { ["railway_asia-southeast1-eqsg3a", Region.RAILWAY_ASIA_SOUTHEAST1], ]; - test.each(cases)("stringToRegion(%s) → enum", (db, proto) => { - expect(stringToRegion(db)).toBe(proto); - }); + for (const [db, proto] of cases) { + test(`stringToRegion(${db}) → enum`, () => { + expect(stringToRegion(db)).toBe(proto); + }); + } - test.each(cases)("regionToString(enum) → %s", (db, proto) => { - expect(regionToString(proto)).toBe(db); - }); + for (const [db, proto] of cases) { + test(`regionToString(enum) → ${db}`, () => { + expect(regionToString(proto)).toBe(db); + }); + } test("validateRegions accepts all Railway DB codes", () => { expect(validateRegions([...RAILWAY_REGIONS])).toEqual([]); diff --git a/apps/server/src/routes/rpc/handlers/monitor/index.ts b/apps/server/src/routes/rpc/handlers/monitor/index.ts index 3e7fda8a..e6a4522b 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/index.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/index.ts @@ -30,9 +30,8 @@ import { listResponseLogs, } from "@openstatus/services/monitor"; -import { env } from "@/env"; -import { getCheckerPayload, getCheckerUrl } from "@/libs/checker"; - +import { env } from "../../../../env"; +import { getCheckerPayload, getCheckerUrl } from "../../../../libs/checker"; import { toConnectError, toServiceCtx } from "../../adapter"; import { getRpcContext } from "../../interceptors"; import { diff --git a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts index 575dc685..315eb4df 100644 --- a/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts +++ b/apps/server/src/routes/rpc/handlers/monitor/response-logs.test.ts @@ -1,6 +1,6 @@ -import { expect, test } from "bun:test"; - import { redactSensitiveHeaders } from "@openstatus/services/monitor"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; test("redactSensitiveHeaders returns an empty object when headers are missing", () => { expect(redactSensitiveHeaders(null)).toEqual({}); diff --git a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts index 87c9dde4..bf640a35 100644 --- a/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts +++ b/apps/server/src/routes/rpc/handlers/notification/__tests__/notification.test.ts @@ -1,12 +1,12 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). diff --git a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts index 6daf779f..d153fd31 100644 --- a/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-page/__tests__/status-page.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNull, sql } from "@openstatus/db"; import { auditLog, @@ -11,8 +9,11 @@ import { statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; +import { app } from "../../../../../index"; /** * Helper to make ConnectRPC requests using the Connect protocol (JSON). @@ -1720,7 +1721,7 @@ describe("StatusPageService.UpdateComponentGroup", () => { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - sendVerification: ReturnType; + sendVerification: ReturnType; }; describe("StatusPageService.SubscribeToPage", () => { diff --git a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts index 57e03d4c..03f4c58a 100644 --- a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts +++ b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, @@ -9,14 +7,18 @@ import { statusReportUpdate, statusReportUpdateToPageComponents, statusReportsToPageComponents, + workspace, } from "@openstatus/db/src/schema"; +import { createWorkspace } from "@openstatus/db/src/test/factories"; import { PageComponentImpact, StatusReportStatus, } from "@openstatus/proto/status_report/v1"; +import { mock } from "@openstatus/test-utils"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { app } from "@/index"; - +import { app } from "../../../../../index"; import { dbImpactToProto, protoImpactToDb, @@ -25,8 +27,8 @@ import { const subscriptionSpies = (globalThis as Record) .__subscriptionSpies as { - dispatchStatusReportUpdate: ReturnType; - dispatchMaintenanceUpdate: ReturnType; + dispatchStatusReportUpdate: ReturnType; + dispatchMaintenanceUpdate: ReturnType; }; /** @@ -781,36 +783,64 @@ describe("StatusReportService.ListStatusReports", () => { }); test("respects offset parameter", async () => { - // Get total count first - const res1 = await connectRequest( - "ListStatusReports", - {}, - { "x-openstatus-key": "1" }, - ); - const data1 = await res1.json(); - const totalSize = data1.totalSize; + // Isolate in a dedicated workspace so concurrent inserts from other suites + // can't shift the pagination window mid-test. In dev/test the + // `x-openstatus-key` header is the workspace id. Distinct createdAt values + // give the `desc(createdAt)` order a deterministic sequence. + const ws = await createWorkspace(); + const key = String(ws.id); + const now = Date.now(); + const inserted = await db + .insert(statusReport) + .values([ + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-1`, + status: "investigating", + createdAt: new Date(now - 2000), + }, + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-2`, + status: "investigating", + createdAt: new Date(now - 1000), + }, + { + workspaceId: ws.id, + title: `${TEST_PREFIX}-offset-3`, + status: "investigating", + createdAt: new Date(now), + }, + ]) + .returning(); - if (totalSize > 1) { - // Get first page - const res2 = await connectRequest( + try { + const total = await connectRequest( "ListStatusReports", - { limit: 1, offset: 0 }, - { "x-openstatus-key": "1" }, + {}, + { "x-openstatus-key": key }, ); - const data2 = await res2.json(); + expect((await total.json()).totalSize).toBe(inserted.length); - // Get second page - const res3 = await connectRequest( + const page1 = await connectRequest( + "ListStatusReports", + { limit: 1, offset: 0 }, + { "x-openstatus-key": key }, + ); + const page2 = await connectRequest( "ListStatusReports", { limit: 1, offset: 1 }, - { "x-openstatus-key": "1" }, + { "x-openstatus-key": key }, ); - const data3 = await res3.json(); + const data1 = await page1.json(); + const data2 = await page2.json(); - // Should have different reports - if (data2.statusReports?.length > 0 && data3.statusReports?.length > 0) { - expect(data2.statusReports[0].id).not.toBe(data3.statusReports[0].id); - } + expect(data1.statusReports).toHaveLength(1); + expect(data2.statusReports).toHaveLength(1); + expect(data1.statusReports[0].id).not.toBe(data2.statusReports[0].id); + } finally { + await db.delete(statusReport).where(eq(statusReport.workspaceId, ws.id)); + await db.delete(workspace).where(eq(workspace.id, ws.id)); } }); diff --git a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts index d79ebb00..234213c1 100644 --- a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts +++ b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts @@ -1,35 +1,26 @@ -// @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) -// are incompatible with bun:test mocks. All runtime behavior is correct. -import { beforeEach, describe, expect, mock, test } from "bun:test"; - import type { Interceptor } from "@connectrpc/connect"; import { Events } from "@openstatus/analytics"; +// @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) +// are incompatible with bun:test mocks. All runtime behavior is correct. +import { + beforeEach, + describe, + expect, + mock, + test, +} from "@openstatus/test-utils"; import { RPC_CONTEXT_KEY } from "../auth"; import { RPC_EVENT_MAP, trackingInterceptor } from "../tracking"; -// Mock analytics -const mockTrack = mock(() => Promise.resolve()); -const mockSetupAnalytics = mock((_props: unknown) => - Promise.resolve({ track: mockTrack }), -); - -mock.module("@openstatus/analytics", () => ({ - Events, - parseInputToProps: (json: unknown, props?: string[]) => { - if (typeof json !== "object" || json === null || !props) return {}; - return props.reduce( - (acc, prop) => { - if (prop in json) { - acc[prop] = (json as Record)[prop]; - } - return acc; - }, - {} as Record, - ); - }, - setupAnalytics: (props: unknown) => mockSetupAnalytics(props), -})); +// @openstatus/analytics is swapped for a double (test.importmap.json) whose +// setupAnalytics/track spies are exposed here on globalThis. +const { track: mockTrack, setupAnalytics: mockSetupAnalytics } = ( + globalThis as Record +).__analyticsSpies as { + track: ReturnType; + setupAnalytics: ReturnType; +}; type NextFn = Parameters>[0]; diff --git a/apps/server/src/routes/rpc/interceptors/auth.ts b/apps/server/src/routes/rpc/interceptors/auth.ts index ef72d8a6..72171178 100644 --- a/apps/server/src/routes/rpc/interceptors/auth.ts +++ b/apps/server/src/routes/rpc/interceptors/auth.ts @@ -7,7 +7,7 @@ import { import type { Scope, Workspace } from "@openstatus/db/src/schema"; import { nanoid } from "nanoid"; -import { lookupWorkspace, validateKey } from "@/libs/middlewares/auth"; +import { lookupWorkspace, validateKey } from "../../../libs/middlewares/auth"; /** * RPC context containing workspace and request information. diff --git a/apps/server/src/routes/slack/blocks.test.ts b/apps/server/src/routes/slack/blocks.test.ts index 65cd22be..ceac36c3 100644 --- a/apps/server/src/routes/slack/blocks.test.ts +++ b/apps/server/src/routes/slack/blocks.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { agentTools } from "@openstatus/services/agent-tools"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildConfirmationBlocks, diff --git a/apps/server/src/routes/slack/confirmation-store.test.ts b/apps/server/src/routes/slack/confirmation-store.test.ts index 4964d393..93e7a211 100644 --- a/apps/server/src/routes/slack/confirmation-store.test.ts +++ b/apps/server/src/routes/slack/confirmation-store.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import { consume, diff --git a/apps/server/src/routes/slack/handler.test.ts b/apps/server/src/routes/slack/handler.test.ts index 86e01f69..0bfcfbad 100644 --- a/apps/server/src/routes/slack/handler.test.ts +++ b/apps/server/src/routes/slack/handler.test.ts @@ -1,84 +1,20 @@ -import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; +import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; -import * as agentModule from "./agent"; +// workspace-resolver / @slack/web-api / agent are swapped for doubles via the +// test import map; behavior is driven through this shared mutable state. +import { slackTestState } from "@/libs/test/doubles/slack-test-state"; + +import { handleSlackEvent } from "./handler"; +import { verifySlackSignature } from "./verify"; const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; process.env.AI_GATEWAY_API_KEY = "test-key"; -mock.module("./workspace-resolver", () => ({ - resolveWorkspace: (teamId: string) => { - if (teamId === "T_KNOWN") { - return Promise.resolve({ - workspace: { - id: 1, - name: "Test Workspace", - slug: "test", - plan: "free", - limits: {}, - }, - botToken: "xoxb-test", - botUserId: "UBOT", - }); - } - return Promise.resolve(null); - }, -})); - -let slackMessages: Array<{ method: string; args: Record }> = - []; -let postMessageOverride: - | ((args: Record) => Promise<{ ts: string }>) - | null = null; -let updateOverride: - | ((args: Record) => Promise<{ ts: string }>) - | null = null; - -mock.module("@slack/web-api", () => ({ - WebClient: class { - chat = { - postMessage: (args: Record) => { - if (postMessageOverride) return postMessageOverride(args); - slackMessages.push({ method: "postMessage", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - update: (args: Record) => { - if (updateOverride) return updateOverride(args); - slackMessages.push({ method: "update", args }); - return Promise.resolve({ ts: "msg.ts" }); - }, - }; - conversations = { - replies: () => - Promise.resolve({ - messages: [{ user: "U1", text: "test message", ts: "1.1" }], - }), - }; - }, -})); - -let runAgentOverride: - | (() => Promise<{ text: string; toolResults: never[] }>) - | null = null; - -mock.module("./agent", () => ({ - ...agentModule, - runAgent: () => { - if (runAgentOverride) return runAgentOverride(); - return Promise.resolve({ - text: "Here is my response", - toolResults: [], - }); - }, -})); - -const { handleSlackEvent } = await import("./handler"); -const { verifySlackSignature } = await import("./verify"); - function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); app.post("/slack/events", verifySlackSignature, handleSlackEvent); @@ -112,10 +48,26 @@ describe("handleSlackEvent", () => { const app = createTestApp(); beforeEach(() => { - slackMessages = []; - postMessageOverride = null; - updateOverride = null; - runAgentOverride = null; + slackTestState.calls = []; + slackTestState.postMessageOverride = null; + slackTestState.updateOverride = null; + slackTestState.runAgentOverride = null; + slackTestState.resolveWorkspace = (teamId: string) => { + if (teamId === "T_KNOWN") { + return Promise.resolve({ + workspace: { + id: 1, + name: "Test Workspace", + slug: "test", + plan: "free", + limits: {}, + }, + botToken: "xoxb-test", + botUserId: "UBOT", + }); + } + return Promise.resolve(null); + }; }); test("responds to url_verification challenge", async () => { @@ -202,11 +154,11 @@ describe("handleSlackEvent", () => { await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - slackMessages = []; + slackTestState.calls = []; await signAndPost(app, body); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events from unknown teams", async () => { @@ -225,7 +177,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores message events from bots", async () => { @@ -244,7 +196,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel message without bot mention", async () => { @@ -264,7 +216,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("processes DM messages without bot mention", async () => { @@ -285,7 +237,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); // DM should trigger a response (postMessage for "Thinking...") - expect(slackMessages.length).toBeGreaterThan(0); + expect(slackTestState.calls.length).toBeGreaterThan(0); }); test("ignores events without channel", async () => { @@ -303,7 +255,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events without timestamp", async () => { @@ -321,7 +273,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events without team_id", async () => { @@ -339,7 +291,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores unsupported event types", async () => { @@ -354,7 +306,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel_join system messages", async () => { @@ -374,7 +326,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores channel_leave system messages", async () => { @@ -394,7 +346,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events with no event payload", async () => { @@ -406,12 +358,12 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - expect(slackMessages.length).toBe(0); + expect(slackTestState.calls.length).toBe(0); }); test("falls back to top-level message on cannot_reply_to_message", async () => { let callCount = 0; - postMessageOverride = (args: Record) => { + slackTestState.postMessageOverride = (args: Record) => { callCount++; if (callCount === 1) { const err = new Error("An API error occurred: cannot_reply_to_message"); @@ -421,7 +373,7 @@ describe("handleSlackEvent", () => { }); return Promise.reject(err); } - slackMessages.push({ method: "postMessage", args }); + slackTestState.calls.push({ method: "postMessage", args }); return Promise.resolve({ ts: "fallback.ts" }); }; @@ -441,14 +393,14 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const fallbackPost = slackMessages.find( + const fallbackPost = slackTestState.calls.find( (m) => m.method === "postMessage" && !m.args.thread_ts, ); expect(fallbackPost).toBeDefined(); }); test("returns early on non-recoverable postMessage error", async () => { - postMessageOverride = () => { + slackTestState.postMessageOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", @@ -473,12 +425,15 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const updateMessages = slackMessages.filter((m) => m.method === "update"); + const updateMessages = slackTestState.calls.filter( + (m) => m.method === "update", + ); expect(updateMessages.length).toBe(0); }); test("shows error message when runAgent throws", async () => { - runAgentOverride = () => Promise.reject(new Error("agent exploded")); + slackTestState.runAgentOverride = () => + Promise.reject(new Error("agent exploded")); const res = await signAndPost(app, { type: "event_callback", @@ -496,7 +451,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 100)); - const errorUpdate = slackMessages.find( + const errorUpdate = slackTestState.calls.find( (m) => m.method === "update" && typeof m.args.text === "string" && @@ -506,8 +461,9 @@ describe("handleSlackEvent", () => { }); test("does not throw when both runAgent and error update fail", async () => { - runAgentOverride = () => Promise.reject(new Error("agent exploded")); - updateOverride = () => { + slackTestState.runAgentOverride = () => + Promise.reject(new Error("agent exploded")); + slackTestState.updateOverride = () => { const err = new Error("An API error occurred: channel_not_found"); Object.assign(err, { code: "slack_webapi_platform_error", diff --git a/apps/server/src/routes/slack/index.test.ts b/apps/server/src/routes/slack/index.test.ts index 54983660..89c34b80 100644 --- a/apps/server/src/routes/slack/index.test.ts +++ b/apps/server/src/routes/slack/index.test.ts @@ -1,6 +1,7 @@ -import { beforeEach, describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; const SIGNING_SECRET = "test-signing-secret"; diff --git a/apps/server/src/routes/slack/interactions.test.ts b/apps/server/src/routes/slack/interactions.test.ts index a056ce6d..98be8198 100644 --- a/apps/server/src/routes/slack/interactions.test.ts +++ b/apps/server/src/routes/slack/interactions.test.ts @@ -1,8 +1,15 @@ -import { beforeEach, describe, expect, mock, test } from "bun:test"; import crypto from "node:crypto"; +import { beforeEach, describe, expect, test } from "@openstatus/test-utils"; import { Hono } from "hono"; +// workspace-resolver / @slack/web-api are swapped for doubles via the test +// import map; behavior is driven through this shared mutable state. +import { slackTestState } from "@/libs/test/doubles/slack-test-state"; + +import { handleSlackInteraction } from "./interactions"; +import { verifySlackSignature } from "./verify"; + const SIGNING_SECRET = "test-signing-secret"; process.env.SLACK_SIGNING_SECRET = SIGNING_SECRET; @@ -22,34 +29,13 @@ const basePending = { createdAt: Date.now(), }; -mock.module("./workspace-resolver", () => ({ - resolveWorkspace: (teamId: string) => { - if (teamId === "T_KNOWN") { - return Promise.resolve({ botToken: "xoxb-fallback" }); - } - return Promise.resolve(null); - }, -})); - -let slackCalls: Array<{ method: string; args: Record }> = []; - -mock.module("@slack/web-api", () => ({ - WebClient: class { - chat = { - update: (args: Record) => { - slackCalls.push({ method: "update", args }); - return Promise.resolve(); - }, - postEphemeral: (args: Record) => { - slackCalls.push({ method: "postEphemeral", args }); - return Promise.resolve(); - }, - }; - }, -})); - -const { handleSlackInteraction } = await import("./interactions"); -const { verifySlackSignature } = await import("./verify"); +function configureSlackDoubles() { + slackTestState.calls = []; + slackTestState.resolveWorkspace = (teamId: string) => + teamId === "T_KNOWN" + ? Promise.resolve({ botToken: "xoxb-fallback" }) + : Promise.resolve(null); +} function createTestApp() { const app = new Hono<{ Variables: { slackBody: unknown } }>(); @@ -133,14 +119,14 @@ describe("handleSlackInteraction (dispatch)", () => { const app = createTestApp(); beforeEach(() => { - slackCalls = []; + configureSlackDoubles(); redisStore.clear(); }); test("returns ok for non-block_actions", async () => { const res = await signAndPost(app, { type: "message_action", actions: [] }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("returns ok for unknown action_id prefix", async () => { @@ -153,7 +139,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "unknown_action" }], }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("cancel updates message to cancelled", async () => { @@ -167,7 +153,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "cancel_pending-123" }], }); expect(res.status).toBe(200); - const cancelCall = slackCalls.find( + const cancelCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -185,7 +171,9 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_pending-123" }], }); expect(res.status).toBe(200); - const ephemeral = slackCalls.find((c) => c.method === "postEphemeral"); + const ephemeral = slackTestState.calls.find( + (c) => c.method === "postEphemeral", + ); expect(ephemeral).toBeDefined(); expect(ephemeral?.args.text as string).toContain("Only the person"); expect(redisStore.has("slack:action:pending-123")).toBe(true); @@ -201,7 +189,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_unknown-id" }], }); expect(res.status).toBe(200); - const expiredCall = slackCalls.find( + const expiredCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("expired"), ); @@ -218,7 +206,7 @@ describe("handleSlackInteraction (dispatch)", () => { actions: [{ action_id: "approve_some-id" }], }); expect(res.status).toBe(200); - expect(slackCalls).toHaveLength(0); + expect(slackTestState.calls).toHaveLength(0); }); test("approve_flag parses flag=true; approve parses flag=false", async () => { @@ -254,7 +242,7 @@ describe("registry-runner execution paths", () => { const app = createTestApp(); beforeEach(() => { - slackCalls = []; + configureSlackDoubles(); redisStore.clear(); }); @@ -269,7 +257,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackCalls.find( + const successCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes( @@ -293,7 +281,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_flag_maint-001" }], }); expect(res.status).toBe(200); - const successCall = slackCalls.find( + const successCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("subscribers notified"), @@ -312,7 +300,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "cancel_maint-001" }], }); expect(res.status).toBe(200); - const cancelCall = slackCalls.find( + const cancelCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).includes("Cancelled"), ); @@ -330,7 +318,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad" }], }); expect(res.status).toBe(200); - const errCall = slackCalls.find( + const errCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:") && @@ -354,7 +342,7 @@ describe("registry-runner execution paths", () => { actions: [{ action_id: "approve_maint-bad-time" }], }); expect(res.status).toBe(200); - const errCall = slackCalls.find( + const errCall = slackTestState.calls.find( (c) => c.method === "update" && (c.args.text as string).startsWith(":x:"), ); expect(errCall).toBeDefined(); diff --git a/apps/server/src/routes/slack/oauth.test.ts b/apps/server/src/routes/slack/oauth.test.ts index 8d6bc847..19624dd0 100644 --- a/apps/server/src/routes/slack/oauth.test.ts +++ b/apps/server/src/routes/slack/oauth.test.ts @@ -1,6 +1,7 @@ -import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { handleSlackInstall, handleSlackOAuthCallback } from "./oauth"; diff --git a/apps/server/src/routes/slack/presenters/presenters.test.ts b/apps/server/src/routes/slack/presenters/presenters.test.ts index 4161a12e..1878a698 100644 --- a/apps/server/src/routes/slack/presenters/presenters.test.ts +++ b/apps/server/src/routes/slack/presenters/presenters.test.ts @@ -1,20 +1,13 @@ -import { describe, expect, mock, test } from "bun:test"; - import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; +import { describe, expect, test } from "@openstatus/test-utils"; import { z } from "zod"; -// page-urls.ts hits the db; stub before the presenters module loads. -mock.module("../page-urls", () => ({ - getPageUrl: (_pageId: number) => - Promise.resolve("https://example.openstatus.dev"), - getReportUrl: (_pageId: number, reportId: number) => - Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`), -})); - -const { defaultPresenter } = await import("./default"); -const { renderToolResult } = await import("./index"); +// page-urls.ts hits the db; it's swapped for a deterministic double via the +// test import map (see test.importmap.json). +import { defaultPresenter } from "./default"; +import { renderToolResult } from "./index"; const fakeCtx = { workspace: { id: 1 }, diff --git a/apps/server/src/routes/slack/registry-runner.test.ts b/apps/server/src/routes/slack/registry-runner.test.ts index dd1e7494..a5dad44e 100644 --- a/apps/server/src/routes/slack/registry-runner.test.ts +++ b/apps/server/src/routes/slack/registry-runner.test.ts @@ -1,8 +1,8 @@ -import { describe, expect, test } from "bun:test"; - import type { ServiceContext } from "@openstatus/services"; import { agentTools } from "@openstatus/services/agent-tools"; import type { AnyAgentTool } from "@openstatus/services/agent-tools"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { z } from "zod"; import { diff --git a/apps/server/src/routes/slack/system-prompt.test.ts b/apps/server/src/routes/slack/system-prompt.test.ts index 0b23f798..42835ee7 100644 --- a/apps/server/src/routes/slack/system-prompt.test.ts +++ b/apps/server/src/routes/slack/system-prompt.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildSystemPrompt } from "./system-prompt"; diff --git a/apps/server/src/routes/slack/verify.test.ts b/apps/server/src/routes/slack/verify.test.ts index 83b0650c..4640216e 100644 --- a/apps/server/src/routes/slack/verify.test.ts +++ b/apps/server/src/routes/slack/verify.test.ts @@ -1,6 +1,7 @@ -import { describe, expect, test } from "bun:test"; import crypto from "node:crypto"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { Hono } from "hono"; import { verifySlackSignature } from "./verify"; diff --git a/apps/server/src/routes/v1/check/http/post.test.ts b/apps/server/src/routes/v1/check/http/post.test.ts index 586b8454..ab47edfa 100644 --- a/apps/server/src/routes/v1/check/http/post.test.ts +++ b/apps/server/src/routes/v1/check/http/post.test.ts @@ -1,12 +1,10 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/incidents/get.test.ts b/apps/server/src/routes/v1/incidents/get.test.ts index c7f23e00..9de6b293 100644 --- a/apps/server/src/routes/v1/incidents/get.test.ts +++ b/apps/server/src/routes/v1/incidents/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/get_all.test.ts b/apps/server/src/routes/v1/incidents/get_all.test.ts index 618ff95b..19cb2dc1 100644 --- a/apps/server/src/routes/v1/incidents/get_all.test.ts +++ b/apps/server/src/routes/v1/incidents/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/incidents/put.test.ts b/apps/server/src/routes/v1/incidents/put.test.ts index 309e41d5..8bf5f059 100644 --- a/apps/server/src/routes/v1/incidents/put.test.ts +++ b/apps/server/src/routes/v1/incidents/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get.test.ts b/apps/server/src/routes/v1/maintenances/get.test.ts index c7927a23..69a4a248 100644 --- a/apps/server/src/routes/v1/maintenances/get.test.ts +++ b/apps/server/src/routes/v1/maintenances/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/get_all.test.ts b/apps/server/src/routes/v1/maintenances/get_all.test.ts index b5682afd..2eb76192 100644 --- a/apps/server/src/routes/v1/maintenances/get_all.test.ts +++ b/apps/server/src/routes/v1/maintenances/get_all.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -7,6 +5,8 @@ import { monitor, pageComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/maintenances/post.test.ts b/apps/server/src/routes/v1/maintenances/post.test.ts index dbb51799..d4fd15fe 100644 --- a/apps/server/src/routes/v1/maintenances/post.test.ts +++ b/apps/server/src/routes/v1/maintenances/post.test.ts @@ -1,7 +1,7 @@ -import { beforeEach, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -245,7 +245,9 @@ test("create a maintenance calls dispatchMaintenanceUpdate", async () => { const result = MaintenanceSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchMaintenanceUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchMaintenanceUpdate.mock.calls[0][0]).toBe( + "number", + ); if (result.success) { await db.delete(maintenance).where(eq(maintenance.id, result.data.id)); diff --git a/apps/server/src/routes/v1/maintenances/put.test.ts b/apps/server/src/routes/v1/maintenances/put.test.ts index bf462424..1400f196 100644 --- a/apps/server/src/routes/v1/maintenances/put.test.ts +++ b/apps/server/src/routes/v1/maintenances/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -96,7 +97,7 @@ test("update only the message", async () => { expect(result.data?.message).toBe("Only Message Updated"); }); -test.todo("update only the dates", async () => { +test.ignore("update only the dates", async () => { const from = new Date(); const to = new Date(from.getTime() + 7200000); // 2 hours later @@ -120,24 +121,27 @@ test.todo("update only the dates", async () => { expect(result.data?.to).toEqual(to); }); -test.todo("update maintenance with `from` date after `to` date should return 400", async () => { - const to = new Date(); - const from = new Date(to.getTime() + 3600000); // from is 1 hour after to - - const res = await app.request("/v1/maintenance/1", { - method: "PUT", - headers: { - "x-openstatus-key": "1", - "Content-Type": "application/json", - }, - body: JSON.stringify({ - from: from.toISOString(), - to: to.toISOString(), - }), - }); - - expect(res.status).toBe(400); -}); +test.ignore( + "update maintenance with `from` date after `to` date should return 400", + async () => { + const to = new Date(); + const from = new Date(to.getTime() + 3600000); // from is 1 hour after to + + const res = await app.request("/v1/maintenance/1", { + method: "PUT", + headers: { + "x-openstatus-key": "1", + "Content-Type": "application/json", + }, + body: JSON.stringify({ + from: from.toISOString(), + to: to.toISOString(), + }), + }); + + expect(res.status).toBe(400); + }, +); test("remove all maintenance monitors", async () => { const res = await app.request("/v1/maintenance/1", { @@ -158,7 +162,7 @@ test("remove all maintenance monitors", async () => { expect(result.data?.monitorIds?.length).toBe(0); }); -test.todo("empty body should return 400", async () => { +test.ignore("empty body should return 400", async () => { const res = await app.request("/v1/maintenance/1", { method: "PUT", headers: { diff --git a/apps/server/src/routes/v1/monitors/delete.test.ts b/apps/server/src/routes/v1/monitors/delete.test.ts index 503883c0..9e9adec8 100644 --- a/apps/server/src/routes/v1/monitors/delete.test.ts +++ b/apps/server/src/routes/v1/monitors/delete.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get.test.ts b/apps/server/src/routes/v1/monitors/get.test.ts index 9a26b26a..15209292 100644 --- a/apps/server/src/routes/v1/monitors/get.test.ts +++ b/apps/server/src/routes/v1/monitors/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/get_all.test.ts b/apps/server/src/routes/v1/monitors/get_all.test.ts index f7b286dc..97c7dbed 100644 --- a/apps/server/src/routes/v1/monitors/get_all.test.ts +++ b/apps/server/src/routes/v1/monitors/get_all.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post.test.ts b/apps/server/src/routes/v1/monitors/post.test.ts index 235329cf..84ba06e5 100644 --- a/apps/server/src/routes/v1/monitors/post.test.ts +++ b/apps/server/src/routes/v1/monitors/post.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { createErrorSchema } from "@/libs/errors"; @@ -123,7 +124,7 @@ test("create a monitor with deprecated regions should return 400", async () => { expect(res.status).toBe(400); expect(errorSchema.success).toBe(true); - expect(errorSchema.data?.message).toMatch( + expect(errorSchema.data?.message).toContain( "Deprecated regions are not allowed: hkg, waw", ); }); diff --git a/apps/server/src/routes/v1/monitors/post_dns.test.ts b/apps/server/src/routes/v1/monitors/post_dns.test.ts index 70223677..5a5b3d81 100644 --- a/apps/server/src/routes/v1/monitors/post_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/post_dns.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_http.test.ts b/apps/server/src/routes/v1/monitors/post_http.test.ts index 9caa0bef..7ac84591 100644 --- a/apps/server/src/routes/v1/monitors/post_http.test.ts +++ b/apps/server/src/routes/v1/monitors/post_http.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/post_tcp.test.ts b/apps/server/src/routes/v1/monitors/post_tcp.test.ts index 7958913b..650a79dc 100644 --- a/apps/server/src/routes/v1/monitors/post_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/post_tcp.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put.test.ts b/apps/server/src/routes/v1/monitors/put.test.ts index 5b0357de..3fa45af3 100644 --- a/apps/server/src/routes/v1/monitors/put.test.ts +++ b/apps/server/src/routes/v1/monitors/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_dns.test.ts b/apps/server/src/routes/v1/monitors/put_dns.test.ts index e985b8af..3561dc06 100644 --- a/apps/server/src/routes/v1/monitors/put_dns.test.ts +++ b/apps/server/src/routes/v1/monitors/put_dns.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_http.test.ts b/apps/server/src/routes/v1/monitors/put_http.test.ts index f042b7d2..4ae822a2 100644 --- a/apps/server/src/routes/v1/monitors/put_http.test.ts +++ b/apps/server/src/routes/v1/monitors/put_http.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/put_tcp.test.ts b/apps/server/src/routes/v1/monitors/put_tcp.test.ts index fa1c2f35..80ff9029 100644 --- a/apps/server/src/routes/v1/monitors/put_tcp.test.ts +++ b/apps/server/src/routes/v1/monitors/put_tcp.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/monitors/results/get.test.ts b/apps/server/src/routes/v1/monitors/results/get.test.ts index 67ea10dc..511ec1bf 100644 --- a/apps/server/src/routes/v1/monitors/results/get.test.ts +++ b/apps/server/src/routes/v1/monitors/results/get.test.ts @@ -1,10 +1,11 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { ResultRun } from "../schema"; -test.todo("get monitor result with valid id should return 200", async () => { +test.ignore("get monitor result with valid id should return 200", async () => { const res = await app.request("/v1/monitor/1/result/1", { method: "GET", headers: { @@ -60,20 +61,23 @@ test("get monitor result from different workspace should return 404", async () = expect(res.status).toBe(404); }); -test.todo("get monitor result with valid TCP monitor should return 200", async () => { - const res = await app.request("/v1/monitor/4/result/2", { - method: "GET", - headers: { - "x-openstatus-key": "1", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - const result = ResultRun.array().safeParse(json); - expect(result.success).toBe(true); -}); +test.ignore( + "get monitor result with valid TCP monitor should return 200", + async () => { + const res = await app.request("/v1/monitor/4/result/2", { + method: "GET", + headers: { + "x-openstatus-key": "1", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + const result = ResultRun.array().safeParse(json); + expect(result.success).toBe(true); + }, +); test("get monitor result with non-matching result id should return 404", async () => { const res = await app.request("/v1/monitor/1/result/999998", { diff --git a/apps/server/src/routes/v1/monitors/run/post.test.ts b/apps/server/src/routes/v1/monitors/run/post.test.ts index 26547105..b0a1f756 100644 --- a/apps/server/src/routes/v1/monitors/run/post.test.ts +++ b/apps/server/src/routes/v1/monitors/run/post.test.ts @@ -1,5 +1,4 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; @@ -8,7 +7,6 @@ import { TriggerResult } from "../schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); @@ -144,44 +142,47 @@ test("run TCP monitor with valid id should return 200", async () => { } }); -test.todo("run monitor with multiple regions should return array of results", async () => { - mockFetch.mockReturnValue( - Promise.resolve( - new Response( - JSON.stringify({ - jobType: "http", - status: 200, - latency: 100, - region: "ams", - timestamp: 1234567890, - timing: { - dnsStart: 1, - dnsDone: 2, - connectStart: 3, - connectDone: 4, - tlsHandshakeStart: 5, - tlsHandshakeDone: 6, - firstByteStart: 7, - firstByteDone: 8, - transferStart: 9, - transferDone: 10, - }, - }), - { status: 200, headers: { "content-type": "application/json" } }, +test.ignore( + "run monitor with multiple regions should return array of results", + async () => { + mockFetch.mockReturnValue( + Promise.resolve( + new Response( + JSON.stringify({ + jobType: "http", + status: 200, + latency: 100, + region: "ams", + timestamp: 1234567890, + timing: { + dnsStart: 1, + dnsDone: 2, + connectStart: 3, + connectDone: 4, + tlsHandshakeStart: 5, + tlsHandshakeDone: 6, + firstByteStart: 7, + firstByteDone: 8, + transferStart: 9, + transferDone: 10, + }, + }), + { status: 200, headers: { "content-type": "application/json" } }, + ), ), - ), - ); - - const res = await app.request("/v1/monitor/5/run", { - method: "POST", - headers: { - "x-openstatus-key": "1", - "content-type": "application/json", - }, - }); - - expect(res.status).toBe(200); - - const json = await res.json(); - expect(Array.isArray(json)).toBe(true); -}); + ); + + const res = await app.request("/v1/monitor/5/run", { + method: "POST", + headers: { + "x-openstatus-key": "1", + "content-type": "application/json", + }, + }); + + expect(res.status).toBe(200); + + const json = await res.json(); + expect(Array.isArray(json)).toBe(true); + }, +); diff --git a/apps/server/src/routes/v1/monitors/summary/get.test.ts b/apps/server/src/routes/v1/monitors/summary/get.test.ts index 4bf601d2..300271c1 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.test.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.test.ts @@ -1,12 +1,12 @@ -import { expect, test } from "bun:test"; - import { z } from "@hono/zod-openapi"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; import { SummarySchema } from "./schema"; -test.todo("return the summary of the monitor", async () => { +test.ignore("return the summary of the monitor", async () => { const res = await app.request("/v1/monitor/1/summary", { headers: { "x-openstatus-key": "1", diff --git a/apps/server/src/routes/v1/monitors/summary/get.ts b/apps/server/src/routes/v1/monitors/summary/get.ts index 6ae9cba3..22320e12 100644 --- a/apps/server/src/routes/v1/monitors/summary/get.ts +++ b/apps/server/src/routes/v1/monitors/summary/get.ts @@ -8,11 +8,6 @@ import { OpenStatusApiError, openApiErrorResponses } from "@/libs/errors"; import type { monitorsApi } from "../index"; import { ParamsSchema, SummarySchema } from "./schema"; -// TODO: is there another better way to mock Redis/Tinybird? -if (process.env.NODE_ENV === "test") { - require("@/libs/test/preload"); -} - const getMonitorStats = createRoute({ method: "get", tags: ["monitor"], diff --git a/apps/server/src/routes/v1/monitors/trigger/post.test.ts b/apps/server/src/routes/v1/monitors/trigger/post.test.ts index 7442da5b..028a0a71 100644 --- a/apps/server/src/routes/v1/monitors/trigger/post.test.ts +++ b/apps/server/src/routes/v1/monitors/trigger/post.test.ts @@ -1,5 +1,4 @@ -import { expect, test } from "bun:test"; -import { afterEach, mock } from "bun:test"; +import { afterEach, expect, mock, test } from "@openstatus/test-utils"; import { app } from "@/index"; @@ -8,7 +7,6 @@ import { TriggerSchema } from "./schema"; const mockFetch = mock(); global.fetch = mockFetch as unknown as typeof fetch; -mock.module("node-fetch", () => mockFetch); afterEach(() => { mockFetch.mockReset(); diff --git a/apps/server/src/routes/v1/notifications/get.test.ts b/apps/server/src/routes/v1/notifications/get.test.ts index 3e967ba5..8759de39 100644 --- a/apps/server/src/routes/v1/notifications/get.test.ts +++ b/apps/server/src/routes/v1/notifications/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/get_all.test.ts b/apps/server/src/routes/v1/notifications/get_all.test.ts index 0c92e23f..5f2f580e 100644 --- a/apps/server/src/routes/v1/notifications/get_all.test.ts +++ b/apps/server/src/routes/v1/notifications/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/notifications/post.test.ts b/apps/server/src/routes/v1/notifications/post.test.ts index 5208aec5..b90369af 100644 --- a/apps/server/src/routes/v1/notifications/post.test.ts +++ b/apps/server/src/routes/v1/notifications/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pageSubscribers/post.test.ts b/apps/server/src/routes/v1/pageSubscribers/post.test.ts index 7d1bc085..80de79fa 100644 --- a/apps/server/src/routes/v1/pageSubscribers/post.test.ts +++ b/apps/server/src/routes/v1/pageSubscribers/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { and, db, eq, isNull } from "@openstatus/db"; import { pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get.test.ts b/apps/server/src/routes/v1/pages/get.test.ts index 2c197d62..4335e569 100644 --- a/apps/server/src/routes/v1/pages/get.test.ts +++ b/apps/server/src/routes/v1/pages/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/get_all.test.ts b/apps/server/src/routes/v1/pages/get_all.test.ts index 155ed2cb..6c948552 100644 --- a/apps/server/src/routes/v1/pages/get_all.test.ts +++ b/apps/server/src/routes/v1/pages/get_all.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/post.test.ts b/apps/server/src/routes/v1/pages/post.test.ts index ec8999c6..e57a260c 100644 --- a/apps/server/src/routes/v1/pages/post.test.ts +++ b/apps/server/src/routes/v1/pages/post.test.ts @@ -1,7 +1,7 @@ -import { expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/pages/put.test.ts b/apps/server/src/routes/v1/pages/put.test.ts index 3d327ca1..0c76046d 100644 --- a/apps/server/src/routes/v1/pages/put.test.ts +++ b/apps/server/src/routes/v1/pages/put.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts index 2a90e6bf..510c03b8 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/get.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts index 575b169e..d07c2f31 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/post.test.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/post.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -315,5 +316,7 @@ test("create a status report update calls dispatchStatusReportUpdate", async () const result = StatusReportUpdateSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( + "number", + ); }); diff --git a/apps/server/src/routes/v1/statusReports/delete.test.ts b/apps/server/src/routes/v1/statusReports/delete.test.ts index 2532be01..b0760725 100644 --- a/apps/server/src/routes/v1/statusReports/delete.test.ts +++ b/apps/server/src/routes/v1/statusReports/delete.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get.test.ts b/apps/server/src/routes/v1/statusReports/get.test.ts index a833c20a..61980dfd 100644 --- a/apps/server/src/routes/v1/statusReports/get.test.ts +++ b/apps/server/src/routes/v1/statusReports/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/get_all.test.ts b/apps/server/src/routes/v1/statusReports/get_all.test.ts index 22135471..93e057df 100644 --- a/apps/server/src/routes/v1/statusReports/get_all.test.ts +++ b/apps/server/src/routes/v1/statusReports/get_all.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, @@ -8,6 +6,8 @@ import { statusReportUpdate, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/post.test.ts b/apps/server/src/routes/v1/statusReports/post.test.ts index 77154186..94c8d905 100644 --- a/apps/server/src/routes/v1/statusReports/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/post.test.ts @@ -1,11 +1,11 @@ -import { beforeEach, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { pageComponent, statusReport, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeEach, test } from "@std/testing/bdd"; import { app } from "@/index"; @@ -202,7 +202,9 @@ test("create a status report calls dispatchStatusReportUpdate", async () => { const result = StatusReportSchema.safeParse(await res.json()); expect(result.success).toBe(true); expect(spies.dispatchStatusReportUpdate.mock.calls.length).toBe(1); - expect(spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBeNumber(); + expect(typeof spies.dispatchStatusReportUpdate.mock.calls[0][0]).toBe( + "number", + ); if (result.success) { await db diff --git a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts index 743cfd1c..95d14722 100644 --- a/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts +++ b/apps/server/src/routes/v1/statusReports/subscriber-filtering.integration.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * Integration tests for subscriber filtering in status report email queries. diff --git a/apps/server/src/routes/v1/statusReports/update/post.test.ts b/apps/server/src/routes/v1/statusReports/update/post.test.ts index 2ec28aca..cf13fc17 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.test.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/routes/v1/statusReports/update/post.ts b/apps/server/src/routes/v1/statusReports/update/post.ts index 5c19a0aa..6f899172 100644 --- a/apps/server/src/routes/v1/statusReports/update/post.ts +++ b/apps/server/src/routes/v1/statusReports/update/post.ts @@ -114,8 +114,9 @@ export function registerStatusReportUpdateRoutes(api: typeof statusReportsApi) { .all(); const validSubscribers = subscribers.filter( - (s): s is typeof s & { token: string } => + (s): s is typeof s & { token: string; email: string } => s.token !== null && + s.email !== null && s.acceptedAt !== null && s.unsubscribedAt === null, ); diff --git a/apps/server/src/routes/v1/whoami/get.test.ts b/apps/server/src/routes/v1/whoami/get.test.ts index 91f49c78..a0a7aa1b 100644 --- a/apps/server/src/routes/v1/whoami/get.test.ts +++ b/apps/server/src/routes/v1/whoami/get.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { app } from "@/index"; diff --git a/apps/server/src/serve.ts b/apps/server/src/serve.ts new file mode 100644 index 00000000..b280c1cf --- /dev/null +++ b/apps/server/src/serve.ts @@ -0,0 +1,13 @@ +import { getLogger } from "@logtape/logtape"; + +import { env } from "./env"; +import { app } from "./index"; + +const port = 3000; + +getLogger("api-server").info("Starting server", { + port, + environment: env.NODE_ENV, +}); + +Deno.serve({ port }, app.fetch); diff --git a/apps/server/src/utils/audit-log.ts b/apps/server/src/utils/audit-log.ts index 1c2f3783..6c659698 100644 --- a/apps/server/src/utils/audit-log.ts +++ b/apps/server/src/utils/audit-log.ts @@ -1,6 +1,6 @@ import { AuditLog, Tinybird } from "@openstatus/tinybird"; -import { env } from "../env"; +import { env } from "@/env"; const tb = new Tinybird({ token: env.TINY_BIRD_API_KEY }); diff --git a/apps/server/test.importmap.json b/apps/server/test.importmap.json new file mode 100644 index 00000000..e2cdceab --- /dev/null +++ b/apps/server/test.importmap.json @@ -0,0 +1,16 @@ +{ + "imports": { + "@/": "./src/", + "@openstatus/upstash": "./src/libs/test/doubles/upstash.mock.ts", + "@openstatus/tinybird": "./src/libs/test/doubles/tinybird.mock.ts", + "@openstatus/tinybird-real": "../../packages/tinybird/src/index.ts", + "@openstatus/subscriptions": "./src/libs/test/doubles/subscriptions.mock.ts", + "@openstatus/subscriptions-real": "../../packages/subscriptions/src/index.ts", + "@openstatus/analytics": "./src/libs/test/doubles/analytics.mock.ts", + "@openstatus/analytics-real": "../../packages/analytics/src/index.ts", + "./src/routes/slack/page-urls": "./src/libs/test/doubles/page-urls.mock.ts", + "./src/routes/slack/workspace-resolver": "./src/libs/test/doubles/workspace-resolver.mock.ts", + "./src/routes/slack/agent": "./src/libs/test/doubles/slack-agent.mock.ts", + "@slack/web-api": "./src/libs/test/doubles/slack-web-api.mock.ts" + } +} diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index d2c9d74a..e0efb05d 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -8,9 +8,15 @@ "moduleResolution": "bundler", "jsxImportSource": "react", "allowJs": true, - "types": ["bun-types"], + "types": [], "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@modelcontextprotocol/sdk/server/mcp.js": [ + "./node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts" + ], + "@modelcontextprotocol/sdk/types.js": [ + "./node_modules/@modelcontextprotocol/sdk/dist/esm/types.d.ts" + ] } } } diff --git a/apps/status-page/env.ts b/apps/status-page/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/status-page/env.ts +++ b/apps/status-page/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/status-page/package.json b/apps/status-page/package.json index cd336827..58a35fa7 100644 --- a/apps/status-page/package.json +++ b/apps/status-page/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "bun env.ts", + "env": "deno run -A env.ts", "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint", - "test": "bun test", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -77,13 +77,14 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@tailwindcss/typography": "catalog:", "@types/dom-speech-recognition": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "shadcn": "catalog:", "tailwindcss": "catalog:", "tw-animate-css": "catalog:", diff --git a/apps/status-page/src/app/(public)/client.tsx b/apps/status-page/src/app/(public)/client.tsx index 38d02ffd..9d8568e9 100644 --- a/apps/status-page/src/app/(public)/client.tsx +++ b/apps/status-page/src/app/(public)/client.tsx @@ -26,7 +26,7 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { Link } from "@/components/common/link"; +import { Link } from "../../components/common/link"; import { Section, SectionDescription, @@ -34,14 +34,13 @@ import { SectionGroupHeader, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { recomputeStyles } from "@/components/status-page/floating-button"; -import { StatusComponentStatic } from "@/components/status-page/static/status-component-static"; -import { ThemePalettePicker } from "@/components/themes/theme-palette-picker"; -import { ThemeSelect } from "@/components/themes/theme-select"; -import { monitors } from "@/data/monitors"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../components/content/section"; +import { recomputeStyles } from "../../components/status-page/floating-button"; +import { StatusComponentStatic } from "../../components/status-page/static/status-component-static"; +import { ThemePalettePicker } from "../../components/themes/theme-palette-picker"; +import { ThemeSelect } from "../../components/themes/theme-select"; +import { monitors } from "../../data/monitors"; +import { useTRPC } from "../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; const MAIN_COLORS = [ diff --git a/apps/status-page/src/app/(public)/layout.tsx b/apps/status-page/src/app/(public)/layout.tsx index 9297bb8a..68c07985 100644 --- a/apps/status-page/src/app/(public)/layout.tsx +++ b/apps/status-page/src/app/(public)/layout.tsx @@ -8,12 +8,12 @@ import { NextIntlClientProvider } from "next-intl"; import PlausibleProvider from "next-plausible"; import { Suspense } from "react"; -import { Link } from "@/components/common/link"; -import { ThemeProvider } from "@/components/themes/theme-provider"; +import { Link } from "../../components/common/link"; +import { ThemeProvider } from "../../components/themes/theme-provider"; import { SidebarTrigger, ThemeSidebar, -} from "@/components/themes/theme-sidebar"; +} from "../../components/themes/theme-sidebar"; const SIDEBAR_WIDTH = "20rem"; const SIDEBAR_WIDTH_MOBILE = "18rem"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx index 62448552..4dce7e67 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/layout.tsx @@ -1,9 +1,9 @@ import { cn } from "@openstatus/ui/lib/utils"; import { Suspense } from "react"; -import { EmbedShell } from "@/components/layout/embed-shell"; -import { Footer } from "@/components/nav/footer"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { EmbedShell } from "../../../../../components/layout/embed-shell"; +import { Footer } from "../../../../../components/nav/footer"; +import { getQueryClient, trpc } from "../../../../../lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx index 6da92191..0030f867 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-magic-link.tsx @@ -11,16 +11,18 @@ import { EmptyStateContainer, EmptyStateDescription, EmptyStateTitle, -} from "@/components/content/empty-state"; +} from "../../../../../../../components/content/empty-state"; import { Section, SectionDescription, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { FormEmail, type FormValues } from "@/components/forms/form-email"; -import { generateServerActionPromise } from "@/lib/server-actions"; - +} from "../../../../../../../components/content/section"; +import { + FormEmail, + type FormValues, +} from "../../../../../../../components/forms/form-email"; +import { generateServerActionPromise } from "../../../../../../../lib/server-actions"; import { signInWithResendAction } from "../actions"; export function SectionMagicLink() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx index 32b13e97..af1bbba9 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/_components/section-password.tsx @@ -11,10 +11,10 @@ import { SectionDescription, SectionHeader, SectionTitle, -} from "@/components/content/section"; -import { FormPassword } from "@/components/forms/form-password"; -import { createProtectedCookieKey } from "@/lib/protected"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/content/section"; +import { FormPassword } from "../../../../../../../components/forms/form-password"; +import { createProtectedCookieKey } from "../../../../../../../lib/protected"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export function SectionPassword() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts index 46056921..bef7b0a3 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/actions.ts @@ -5,8 +5,8 @@ import { AuthError } from "next-auth"; import { getExtracted } from "next-intl/server"; import { isRedirectError } from "next/dist/client/components/redirect-error"; -import { signIn } from "@/lib/auth"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { signIn } from "../../../../../../lib/auth"; +import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; export async function signInWithResendAction(formData: FormData) { const t = await getExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx index 554c8146..0368b670 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/login/page.tsx @@ -3,8 +3,7 @@ import { useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; - +import { useTRPC } from "../../../../../../lib/trpc/client"; import { SectionMagicLink } from "./_components/section-magic-link"; import { SectionPassword } from "./_components/section-password"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx index 2e6e8b90..cbdecf1d 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(auth)/restricted/page.tsx @@ -5,7 +5,7 @@ import { ShieldAlert } from "lucide-react"; import { useExtracted } from "next-intl"; import { notFound, useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function RestrictedPage() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx index f650dcf9..0dc50174 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/client.tsx @@ -27,8 +27,8 @@ import { skipToken, useQuery } from "@tanstack/react-query"; import { notFound, useParams } from "next/navigation"; import { useMemo } from "react"; -import { Link } from "@/components/common/link"; -import { useStatusPage } from "@/components/status-page/floating-button"; +import { Link } from "../../../../../components/common/link"; +import { useStatusPage } from "../../../../../components/status-page/floating-button"; import { StatusBanner, StatusBannerContainer, @@ -37,23 +37,23 @@ import { StatusBannerTabsContent, StatusBannerTabsList, StatusBannerTabsTrigger, -} from "@/components/status-page/status-banner"; +} from "../../../../../components/status-page/status-banner"; import { StatusBar, StatusBarSkeleton, -} from "@/components/status-page/status-bar"; -import { StatusComponentGroup } from "@/components/status-page/status-component-group"; +} from "../../../../../components/status-page/status-bar"; +import { StatusComponentGroup } from "../../../../../components/status-page/status-component-group"; import { StatusEventAffected, StatusEventAffectedBadge, StatusEventTimelineMaintenance, StatusEventTimelineReportUpdate, -} from "@/components/status-page/status-events"; -import { StatusFeed } from "@/components/status-page/status-feed"; -import { useEmbed } from "@/hooks/use-embed"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../components/status-page/status-events"; +import { StatusFeed } from "../../../../../components/status-page/status-feed"; +import { useEmbed } from "../../../../../hooks/use-embed"; +import { usePathnamePrefix } from "../../../../../hooks/use-pathname-prefix"; +import { updatesWithImpactChanges } from "../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../lib/trpc/client"; export function Client() { const prefix = usePathnamePrefix(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx index 32ea5a79..6a5704cb 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx index 0d64d5c6..7e7134de 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(list)/page.tsx @@ -12,7 +12,7 @@ import Link from "next/link"; import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { StatusBlankEvents } from "../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -25,10 +25,9 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "@/components/status-page/status-events"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../../../../../../components/status-page/status-events"; +import { updatesWithImpactChanges } from "../../../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx index 140e18c5..4caf455c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/layout.tsx @@ -1,8 +1,12 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../../../lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx index a4eafcd5..58a9ce95 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/maintenance/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { ButtonBack } from "../../../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; +import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -16,8 +16,8 @@ import { StatusEventDate, StatusEventTimelineMaintenance, StatusEventTitle, -} from "@/components/status-page/status-events"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../../../components/status-page/status-events"; +import { useTRPC } from "../../../../../../../../../lib/trpc/client"; export default function MaintenancePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx index 124f989e..0977d1bf 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/layout.tsx @@ -1,8 +1,12 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternatesMetadata } from "../../../../../../../../../lib/alternates-metadata"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../../../lib/trpc/server"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx index 1387487c..6f300055 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/(view)/report/[id]/page.tsx @@ -4,9 +4,9 @@ import { useQuery } from "@tanstack/react-query"; import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; -import { StatusBlankEvents } from "@/components/status-page/status-blank"; +import { ButtonBack } from "../../../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../../../components/button/button-copy-link"; +import { StatusBlankEvents } from "../../../../../../../../../components/status-page/status-blank"; import { StatusEvent, StatusEventAffected, @@ -17,9 +17,9 @@ import { StatusEventTimelineReport, StatusEventTitle, StatusEventTitleCheck, -} from "@/components/status-page/status-events"; -import { updatesWithImpactChanges } from "@/lib/report-impacts"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../../../components/status-page/status-events"; +import { updatesWithImpactChanges } from "../../../../../../../../../lib/report-impacts"; +import { useTRPC } from "../../../../../../../../../lib/trpc/client"; export default function ReportPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx index faa8e4e0..1d913d44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/events/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts index a3fbb463..f8ea2279 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/[type]/route.ts @@ -1,9 +1,9 @@ import { Feed } from "feed"; import { notFound, unauthorized } from "next/navigation"; -import { auth } from "@/lib/auth"; -import { getBaseUrl } from "@/lib/base-url"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { auth } from "../../../../../../../lib/auth"; +import { getBaseUrl } from "../../../../../../../lib/base-url"; +import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; const STATUS_LABELS = { investigating: "Investigating", diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts index 885246ea..600d02f7 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/feed/json/route.ts @@ -1,7 +1,7 @@ import { notFound, unauthorized } from "next/navigation"; -import { auth } from "@/lib/auth"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { auth } from "../../../../../../../lib/auth"; +import { getQueryClient, trpc } from "../../../../../../../lib/trpc/server"; export const revalidate = 60; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx index 582ebac0..3e5c45e3 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/layout.tsx @@ -4,9 +4,9 @@ import { } from "@openstatus/ui/components/blocks/status-page-shell"; import { Suspense } from "react"; -import { EmbedShell } from "@/components/layout/embed-shell"; -import { Footer } from "@/components/nav/footer"; -import { Header } from "@/components/nav/header"; +import { EmbedShell } from "../../../../../components/layout/embed-shell"; +import { Footer } from "../../../../../components/nav/footer"; +import { Header } from "../../../../../components/nav/header"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts index 060d94fc..32ff7998 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/llms.txt/route.ts @@ -2,9 +2,12 @@ import { db, sql } from "@openstatus/db"; import { page } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { escapeLinkLabel, type OverviewPage } from "@/content/markdown"; -import { getBaseUrl } from "@/lib/base-url"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { + escapeLinkLabel, + type OverviewPage, +} from "../../../../../../content/markdown"; +import { getBaseUrl } from "../../../../../../lib/base-url"; +import { getQueryClient, trpc } from "../../../../../../lib/trpc/server"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx index f90f987a..d7759e1a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/layout.tsx @@ -1,4 +1,8 @@ -import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; +import { + HydrateClient, + getQueryClient, + trpc, +} from "../../../../../../../lib/trpc/server"; export default async function Layout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx index 9bc7aef7..fefbeaaf 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/[token]/page.tsx @@ -18,7 +18,7 @@ import { useExtracted, useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { toast } from "sonner"; -import { ButtonBack } from "@/components/button/button-back"; +import { ButtonBack } from "../../../../../../../components/button/button-back"; import { FormCard, FormCardContent, @@ -27,16 +27,16 @@ import { FormCardFooterInfo, FormCardHeader, FormCardTitle, -} from "@/components/forms/form-card"; -import { FormManageSubscription } from "@/components/forms/form-manage-subscription"; +} from "../../../../../../../components/forms/form-card"; +import { FormManageSubscription } from "../../../../../../../components/forms/form-manage-subscription"; import { StatusBlankContainer, StatusBlankContent, StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx index faa8e4e0..1d913d44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/manage/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx index 5a45b960..36dafd6d 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/layout.tsx @@ -1,7 +1,7 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx index 5efcc37e..964d2a63 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/[id]/page.tsx @@ -15,27 +15,27 @@ import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; import { useMemo } from "react"; -import { ButtonBack } from "@/components/button/button-back"; -import { ButtonCopyLink } from "@/components/button/button-copy-link"; +import { ButtonBack } from "../../../../../../../components/button/button-back"; +import { ButtonCopyLink } from "../../../../../../../components/button/button-copy-link"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "@/components/chart/chart-area-percentiles"; +} from "../../../../../../../components/chart/chart-area-percentiles"; import { ChartBarUptime, ChartBarUptimeSkeleton, -} from "@/components/chart/chart-bar-uptime"; +} from "../../../../../../../components/chart/chart-bar-uptime"; import { ChartLineRegions, ChartLineRegionsSkeleton, -} from "@/components/chart/chart-line-regions"; -import { StatusBlankMonitors } from "@/components/status-page/status-blank"; +} from "../../../../../../../components/chart/chart-line-regions"; +import { StatusBlankMonitors } from "../../../../../../../components/status-page/status-blank"; import { StatusChartContent, StatusChartDescription, StatusChartHeader, StatusChartTitle, -} from "@/components/status-page/status-charts"; +} from "../../../../../../../components/status-page/status-charts"; import { StatusMonitorTabs, StatusMonitorTabsContent, @@ -44,14 +44,13 @@ import { StatusMonitorTabsTriggerLabel, StatusMonitorTabsTriggerValue, StatusMonitorTabsTriggerValueSkeleton, -} from "@/components/status-page/status-monitor-tabs"; +} from "../../../../../../../components/status-page/status-monitor-tabs"; import { formatMillisecondsRange, formatNumber, formatPercentage, -} from "@/lib/formatter"; -import { useTRPC } from "@/lib/trpc/client"; - +} from "../../../../../../../lib/formatter"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; import { searchParamsParsers } from "./search-params"; export default function Page() { diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx index 61d96811..b793c90a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import { statusPageAlternatesMetadata } from "@/lib/alternates-metadata"; +import { statusPageAlternatesMetadata } from "../../../../../../lib/alternates-metadata"; export async function generateMetadata({ params, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx index 48aef75d..6bc56d9c 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/monitors/page.tsx @@ -18,9 +18,9 @@ import { useParams } from "next/navigation"; import { ChartAreaPercentiles, ChartAreaPercentilesSkeleton, -} from "@/components/chart/chart-area-percentiles"; -import { StatusBlankMonitors } from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../components/chart/chart-area-percentiles"; +import { StatusBlankMonitors } from "../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../lib/trpc/client"; export default function Page() { const { domain } = useParams<{ domain: string }>(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts index 2edef64c..fb02a69a 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/search-params.ts @@ -1,6 +1,6 @@ import { createSearchParamsCache } from "nuqs/server"; -import { embedParser } from "@/lib/embed-params"; +import { embedParser } from "../../../../../lib/embed-params"; export const embedSearchParamsCache = createSearchParamsCache({ embed: embedParser, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx index c77dbc68..41485a1e 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function UnsubscribeLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx index 53bea954..d4f0aded 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/unsubscribe/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankDescription, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function UnsubscribePage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx index faa8e4e0..3c061636 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/layout.tsx @@ -10,7 +10,7 @@ import { import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; -import { useTRPC } from "@/lib/trpc/client"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function EventLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx index c27dd097..cf71d1f2 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/(public)/verify/[token]/page.tsx @@ -11,8 +11,8 @@ import { StatusBlankContent, StatusBlankLink, StatusBlankTitle, -} from "@/components/status-page/status-blank"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../../../../../../../components/status-page/status-blank"; +import { useTRPC } from "../../../../../../../lib/trpc/client"; export default function VerifyPage() { const t = useExtracted(); diff --git a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx index 79d21b24..1bab2f44 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/[locale]/layout.tsx @@ -2,9 +2,9 @@ import { NextIntlClientProvider, hasLocale } from "next-intl"; import { setRequestLocale } from "next-intl/server"; import { notFound } from "next/navigation"; -import { DateFnsProvider } from "@/components/date-fns-provider"; -import { StatusBlocksProvider } from "@/components/i18n/status-blocks-provider"; -import { routing } from "@/i18n/routing"; +import { DateFnsProvider } from "../../../../components/date-fns-provider"; +import { StatusBlocksProvider } from "../../../../components/i18n/status-blocks-provider"; +import { routing } from "../../../../i18n/routing"; export default async function LocaleLayout({ children, diff --git a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx index 3b6b86ff..5dbcf293 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx @@ -4,16 +4,16 @@ import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { defaultMetadata, ogMetadata, twitterMetadata } from "@/app/metadata"; -import { PasswordWrapper } from "@/components/password-wrapper"; +import { PasswordWrapper } from "../../../components/password-wrapper"; import { FloatingButton, StatusPageProvider, -} from "@/components/status-page/floating-button"; -import { FloatingTheme } from "@/components/status-page/floating-theme"; -import { ThemeProvider } from "@/components/themes/theme-provider"; -import { statusPageAlternates } from "@/lib/alternates"; -import { getQueryClient, HydrateClient, trpc } from "@/lib/trpc/server"; +} from "../../../components/status-page/floating-button"; +import { FloatingTheme } from "../../../components/status-page/floating-theme"; +import { ThemeProvider } from "../../../components/themes/theme-provider"; +import { statusPageAlternates } from "../../../lib/alternates"; +import { getQueryClient, HydrateClient, trpc } from "../../../lib/trpc/server"; +import { defaultMetadata, ogMetadata, twitterMetadata } from "../../metadata"; // Canonical schema — guarantees concrete enum output (never null/undefined). diff --git a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts index c55a45ed..9f1bce8e 100644 --- a/apps/status-page/src/app/api/auth/[...nextauth]/route.ts +++ b/apps/status-page/src/app/api/auth/[...nextauth]/route.ts @@ -1,3 +1,3 @@ -import { handlers } from "@/lib/auth"; +import { handlers } from "../../../../lib/auth"; export const { GET, POST } = handlers; diff --git a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts index 43a151d4..5f8868af 100644 --- a/apps/status-page/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/markdown/[[...path]]/route.ts @@ -10,12 +10,12 @@ import { generateReport, matchMarkdownRoute, parseMarkdownPath, -} from "@/content/markdown"; -import { getBaseUrl } from "@/lib/base-url"; -import { resolveClientIp } from "@/lib/http/client-ip"; -import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; -import { type GatePage, resolveGate } from "@/lib/proxy/resolve-gate"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +} from "../../../../content/markdown"; +import { getBaseUrl } from "../../../../lib/base-url"; +import { resolveClientIp } from "../../../../lib/http/client-ip"; +import { resolveMarkdownResponse } from "../../../../lib/http/markdown-response"; +import { type GatePage, resolveGate } from "../../../../lib/proxy/resolve-gate"; +import { getQueryClient, trpc } from "../../../../lib/trpc/server"; // Match the feed route: getQueryClient/httpBatchLink needs Node, not Edge. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/status/[[...path]]/route.ts b/apps/status-page/src/app/api/status/[[...path]]/route.ts index 37255f80..6ee8bb27 100644 --- a/apps/status-page/src/app/api/status/[[...path]]/route.ts +++ b/apps/status-page/src/app/api/status/[[...path]]/route.ts @@ -8,14 +8,14 @@ import { toStatus, toSummary, toUnresolvedIncidents, -} from "@/content/status-json"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveClientIp } from "@/lib/http/client-ip"; -import { computeETag, isNotModified } from "@/lib/http/etag"; -import { resolveGate } from "@/lib/proxy/resolve-gate"; -import { resolveRoute } from "@/lib/resolve-route"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +} from "../../../../content/status-json"; +import { getBaseUrl } from "../../../../lib/base-url"; +import { stripHostPort } from "../../../../lib/domain"; +import { resolveClientIp } from "../../../../lib/http/client-ip"; +import { computeETag, isNotModified } from "../../../../lib/http/etag"; +import { resolveGate } from "../../../../lib/proxy/resolve-gate"; +import { resolveRoute } from "../../../../lib/resolve-route"; +import { getQueryClient, trpc } from "../../../../lib/trpc/server"; // trpc httpBatchLink needs Node, matching the markdown route. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts index 9dd8225b..c05e3b01 100644 --- a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,8 +3,8 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "@/lib/auth"; -import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; +import { auth } from "../../../../../lib/auth"; +import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; export const runtime = "edge"; diff --git a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts index 944ea4af..f17aa817 100644 --- a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,8 +3,8 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { auth } from "@/lib/auth"; -import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; +import { auth } from "../../../../../lib/auth"; +import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/status-page/src/app/global-error.tsx b/apps/status-page/src/app/global-error.tsx index 6d4ad424..758c1809 100644 --- a/apps/status-page/src/app/global-error.tsx +++ b/apps/status-page/src/app/global-error.tsx @@ -4,7 +4,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import * as Sentry from "@sentry/nextjs"; import { useEffect } from "react"; -import { Link } from "@/components/common/link"; +import { Link } from "../components/common/link"; export default function GlobalError({ error, diff --git a/apps/status-page/src/app/layout.tsx b/apps/status-page/src/app/layout.tsx index 600b276d..bc1a2aec 100644 --- a/apps/status-page/src/app/layout.tsx +++ b/apps/status-page/src/app/layout.tsx @@ -6,9 +6,8 @@ import { Geist, Geist_Mono } from "next/font/google"; import LocalFont from "next/font/local"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { TailwindIndicator } from "@/components/tailwind-indicator"; -import { TRPCReactProvider } from "@/lib/trpc/client"; - +import { TailwindIndicator } from "../components/tailwind-indicator"; +import { TRPCReactProvider } from "../lib/trpc/client"; import { ogMetadata, twitterMetadata } from "./metadata"; import { defaultMetadata } from "./metadata"; diff --git a/apps/status-page/src/app/not-found.tsx b/apps/status-page/src/app/not-found.tsx index 47cd00e2..a1042a9a 100644 --- a/apps/status-page/src/app/not-found.tsx +++ b/apps/status-page/src/app/not-found.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/navigation"; import { NuqsAdapter } from "nuqs/adapters/next/app"; import { Suspense } from "react"; -import { Link } from "@/components/common/link"; -import { ThemeProvider } from "@/components/themes/theme-provider"; +import { Link } from "../components/common/link"; +import { ThemeProvider } from "../components/themes/theme-provider"; export default function NotFound() { return ( diff --git a/apps/status-page/src/app/robots.ts b/apps/status-page/src/app/robots.ts index 4df99d6d..dc3db8ba 100644 --- a/apps/status-page/src/app/robots.ts +++ b/apps/status-page/src/app/robots.ts @@ -3,9 +3,9 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveRoute } from "@/lib/resolve-route"; +import { getBaseUrl } from "../lib/base-url"; +import { stripHostPort } from "../lib/domain"; +import { resolveRoute } from "../lib/resolve-route"; // trpc/db lookup needs Node, matching the sitemap and other content routes. export const runtime = "nodejs"; diff --git a/apps/status-page/src/app/sitemap.ts b/apps/status-page/src/app/sitemap.ts index b6e31bef..857cfbe7 100644 --- a/apps/status-page/src/app/sitemap.ts +++ b/apps/status-page/src/app/sitemap.ts @@ -3,10 +3,10 @@ import { page } from "@openstatus/db/src/schema"; import type { MetadataRoute } from "next"; import { headers } from "next/headers"; -import { getBaseUrl } from "@/lib/base-url"; -import { stripHostPort } from "@/lib/domain"; -import { resolveRoute } from "@/lib/resolve-route"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { getBaseUrl } from "../lib/base-url"; +import { stripHostPort } from "../lib/domain"; +import { resolveRoute } from "../lib/resolve-route"; +import { getQueryClient, trpc } from "../lib/trpc/server"; // One sitemap per host: a custom domain must never enumerate other tenants' // pages. trpc httpBatchLink needs Node, matching the other content routes. diff --git a/apps/status-page/src/components/chart/chart-area-percentiles.tsx b/apps/status-page/src/components/chart/chart-area-percentiles.tsx index 78f62b7c..0e4ac7b4 100644 --- a/apps/status-page/src/components/chart/chart-area-percentiles.tsx +++ b/apps/status-page/src/components/chart/chart-area-percentiles.tsx @@ -13,8 +13,7 @@ import { useState } from "react"; import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; import type { AxisDomain } from "recharts/types/util/types"; -import { formatMilliseconds } from "@/lib/formatter"; - +import { formatMilliseconds } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/chart/chart-bar-uptime.tsx b/apps/status-page/src/components/chart/chart-bar-uptime.tsx index 81df7d41..c4565542 100644 --- a/apps/status-page/src/components/chart/chart-bar-uptime.tsx +++ b/apps/status-page/src/components/chart/chart-bar-uptime.tsx @@ -12,8 +12,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { useState } from "react"; import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"; -import { formatNumber } from "@/lib/formatter"; - +import { formatNumber } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; const chartConfig = { diff --git a/apps/status-page/src/components/chart/chart-legend-badge.tsx b/apps/status-page/src/components/chart/chart-legend-badge.tsx index 6d6d84c8..ef0d13f3 100644 --- a/apps/status-page/src/components/chart/chart-legend-badge.tsx +++ b/apps/status-page/src/components/chart/chart-legend-badge.tsx @@ -12,7 +12,7 @@ import * as React from "react"; import type * as RechartsPrimitive from "recharts"; import type { Payload } from "recharts/types/component/DefaultLegendContent"; -import { getPayloadConfigFromPayload } from "@/lib/chart"; +import { getPayloadConfigFromPayload } from "../../lib/chart"; export function ChartLegendBadge({ className, diff --git a/apps/status-page/src/components/chart/chart-line-regions.tsx b/apps/status-page/src/components/chart/chart-line-regions.tsx index 71c9de48..f216e6b1 100644 --- a/apps/status-page/src/components/chart/chart-line-regions.tsx +++ b/apps/status-page/src/components/chart/chart-line-regions.tsx @@ -20,9 +20,8 @@ import { YAxis, } from "recharts"; -import { regions } from "@/data/regions"; -import { formatMilliseconds } from "@/lib/formatter"; - +import { regions } from "../../data/regions"; +import { formatMilliseconds } from "../../lib/formatter"; import { ChartLegendBadge } from "./chart-legend-badge"; import { ChartTooltipNumber } from "./chart-tooltip-number"; diff --git a/apps/status-page/src/components/common/link.tsx b/apps/status-page/src/components/common/link.tsx index 0d2c16cc..9a4d75c0 100644 --- a/apps/status-page/src/components/common/link.tsx +++ b/apps/status-page/src/components/common/link.tsx @@ -4,7 +4,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { type VariantProps, cva } from "class-variance-authority"; import NextLink from "next/link"; -import { useEmbed } from "@/hooks/use-embed"; +import { useEmbed } from "../../hooks/use-embed"; export const linkVariants = cva( "focus-visible:ring-ring/50 rounded-sm outline-none focus-visible:ring-[3px]", diff --git a/apps/status-page/src/components/date-fns-provider.tsx b/apps/status-page/src/components/date-fns-provider.tsx index 046a5147..f6d1f35a 100644 --- a/apps/status-page/src/components/date-fns-provider.tsx +++ b/apps/status-page/src/components/date-fns-provider.tsx @@ -3,7 +3,7 @@ import { dateFnsLocales } from "@openstatus/locales"; import { setDefaultOptions } from "date-fns"; -import type { Locale } from "@/i18n/config"; +import type { Locale } from "../i18n/config"; export function DateFnsProvider({ locale, diff --git a/apps/status-page/src/components/date-picker.tsx b/apps/status-page/src/components/date-picker.tsx index 751cc163..608fc8e8 100644 --- a/apps/status-page/src/components/date-picker.tsx +++ b/apps/status-page/src/components/date-picker.tsx @@ -10,8 +10,8 @@ import { useExtracted } from "next-intl"; import { useState } from "react"; import type { DateRange } from "react-day-picker"; -import { Kbd } from "@/components/common/kbd"; -import { formatDateForInput } from "@/lib/formatter"; +import { formatDateForInput } from "../lib/formatter"; +import { Kbd } from "./common/kbd"; type DatePickerProps = { range: DateRange; diff --git a/apps/status-page/src/components/forms/form-manage-subscription.tsx b/apps/status-page/src/components/forms/form-manage-subscription.tsx index 039398d5..ac055e4c 100644 --- a/apps/status-page/src/components/forms/form-manage-subscription.tsx +++ b/apps/status-page/src/components/forms/form-manage-subscription.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "@/components/status-page/status-blank"; +} from "../status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/forms/form-subscribe-email.tsx b/apps/status-page/src/components/forms/form-subscribe-email.tsx index 5bc5549e..7e233c37 100644 --- a/apps/status-page/src/components/forms/form-subscribe-email.tsx +++ b/apps/status-page/src/components/forms/form-subscribe-email.tsx @@ -23,7 +23,7 @@ import { StatusBlankContainer, StatusBlankDescription, StatusBlankTitle, -} from "@/components/status-page/status-blank"; +} from "../status-page/status-blank"; type Page = NonNullable; diff --git a/apps/status-page/src/components/i18n/status-blocks-provider.tsx b/apps/status-page/src/components/i18n/status-blocks-provider.tsx index b1678e22..afa5e7b8 100644 --- a/apps/status-page/src/components/i18n/status-blocks-provider.tsx +++ b/apps/status-page/src/components/i18n/status-blocks-provider.tsx @@ -12,7 +12,7 @@ import { formatDateRange, formatDateRangeParts, formatDateTime, -} from "@/lib/formatter"; +} from "../../lib/formatter"; // Status-page timestamps render in UTC; the suffix tells viewers which zone. const withUTC = (value: string) => `${value} (UTC)`; diff --git a/apps/status-page/src/components/layout/embed-shell.tsx b/apps/status-page/src/components/layout/embed-shell.tsx index 2de6e875..c7a960ee 100644 --- a/apps/status-page/src/components/layout/embed-shell.tsx +++ b/apps/status-page/src/components/layout/embed-shell.tsx @@ -2,7 +2,7 @@ import { cn } from "@openstatus/ui/lib/utils"; -import { ALL_EMBED_SECTIONS, useEmbed } from "@/hooks/use-embed"; +import { ALL_EMBED_SECTIONS, useEmbed } from "../../hooks/use-embed"; export function EmbedShell({ children, diff --git a/apps/status-page/src/components/locale-switcher.tsx b/apps/status-page/src/components/locale-switcher.tsx index 234cd097..ba82b8a1 100644 --- a/apps/status-page/src/components/locale-switcher.tsx +++ b/apps/status-page/src/components/locale-switcher.tsx @@ -13,7 +13,7 @@ import { defaultLocale as globalDefaultLocale, localeTranslations, locales, -} from "@/i18n/config"; +} from "../i18n/config"; export function LocaleSwitcher({ className, diff --git a/apps/status-page/src/components/nav/footer.tsx b/apps/status-page/src/components/nav/footer.tsx index a98cd31b..1a2be081 100644 --- a/apps/status-page/src/components/nav/footer.tsx +++ b/apps/status-page/src/components/nav/footer.tsx @@ -13,12 +13,12 @@ import { Clock } from "lucide-react"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { Link } from "@/components/common/link"; -import { TimestampHoverCard } from "@/components/content/timestamp-hover-card"; -import { LocaleSwitcher } from "@/components/locale-switcher"; -import { ThemeSwitcher } from "@/components/themes/theme-switcher"; -import { useEmbed } from "@/hooks/use-embed"; -import { useTRPC } from "@/lib/trpc/client"; +import { useEmbed } from "../../hooks/use-embed"; +import { useTRPC } from "../../lib/trpc/client"; +import { Link } from "../common/link"; +import { TimestampHoverCard } from "../content/timestamp-hover-card"; +import { LocaleSwitcher } from "../locale-switcher"; +import { ThemeSwitcher } from "../themes/theme-switcher"; export function Footer({ className, diff --git a/apps/status-page/src/components/nav/header.tsx b/apps/status-page/src/components/nav/header.tsx index 03439456..6f5b1cd0 100644 --- a/apps/status-page/src/components/nav/header.tsx +++ b/apps/status-page/src/components/nav/header.tsx @@ -30,13 +30,13 @@ import { useParams, usePathname } from "next/navigation"; import { useState } from "react"; import { toast } from "sonner"; -import { Link } from "@/components/common/link"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { useTRPC } from "../../lib/trpc/client"; +import { Link } from "../common/link"; import { type StatusUpdateType, StatusUpdates, -} from "@/components/status-page/status-updates"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import { useTRPC } from "@/lib/trpc/client"; +} from "../status-page/status-updates"; type Page = RouterOutputs["statusPage"]["get"]; diff --git a/apps/status-page/src/components/password-wrapper.tsx b/apps/status-page/src/components/password-wrapper.tsx index 41e2eee3..cb364ada 100644 --- a/apps/status-page/src/components/password-wrapper.tsx +++ b/apps/status-page/src/components/password-wrapper.tsx @@ -4,7 +4,7 @@ import { useParams } from "next/navigation"; import { parseAsString, useQueryState } from "nuqs"; import { useEffect } from "react"; -import { createProtectedCookieKey } from "@/lib/protected"; +import { createProtectedCookieKey } from "../lib/protected"; export function PasswordWrapper({ children }: { children?: React.ReactNode }) { const [password, setPassword] = useQueryState("pw", parseAsString); diff --git a/apps/status-page/src/components/status-page/floating-button.tsx b/apps/status-page/src/components/status-page/floating-button.tsx index c19e8a75..c538dd26 100644 --- a/apps/status-page/src/components/status-page/floating-button.tsx +++ b/apps/status-page/src/components/status-page/floating-button.tsx @@ -35,7 +35,7 @@ import { parseAsString, useQueryState } from "nuqs"; import type React from "react"; import { createContext, useContext, useEffect, useState } from "react"; -import { ThemeSelect } from "@/components/themes/theme-select"; +import { ThemeSelect } from "../themes/theme-select"; export const IS_DEV = process.env.NODE_ENV === "development"; diff --git a/apps/status-page/src/components/status-page/floating-theme.tsx b/apps/status-page/src/components/status-page/floating-theme.tsx index 4e68f165..bbf8b90f 100644 --- a/apps/status-page/src/components/status-page/floating-theme.tsx +++ b/apps/status-page/src/components/status-page/floating-theme.tsx @@ -21,8 +21,7 @@ import { Check, ChevronsUpDown, Palette } from "lucide-react"; import { useEffect } from "react"; import { useState } from "react"; -import { ThemeSelect } from "@/components/themes/theme-select"; - +import { ThemeSelect } from "../themes/theme-select"; import { useStatusPage } from "./floating-button"; export const COMMUNITY_THEME = THEME_KEYS; diff --git a/apps/status-page/src/components/status-page/status-bar.tsx b/apps/status-page/src/components/status-page/status-bar.tsx index 9b43257a..dcad7aa6 100644 --- a/apps/status-page/src/components/status-page/status-bar.tsx +++ b/apps/status-page/src/components/status-page/status-bar.tsx @@ -5,8 +5,8 @@ import { StatusBarEvent, } from "@openstatus/ui/components/blocks/status-bar"; -import { Link } from "@/components/common/link"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { Link } from "../common/link"; export { StatusBarSkeleton } from "@openstatus/ui/components/blocks/status-bar"; diff --git a/apps/status-page/src/components/status-page/status-blank.tsx b/apps/status-page/src/components/status-page/status-blank.tsx index e4ea5977..5d5ec21e 100644 --- a/apps/status-page/src/components/status-page/status-blank.tsx +++ b/apps/status-page/src/components/status-page/status-blank.tsx @@ -3,7 +3,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import { cn } from "@openstatus/ui/lib/utils"; -import { Link } from "@/components/common/link"; +import { Link } from "../common/link"; export { StatusBlankContainer, diff --git a/apps/status-page/src/components/status-page/status-calendar.tsx b/apps/status-page/src/components/status-page/status-calendar.tsx index 9b38d522..19992ddd 100644 --- a/apps/status-page/src/components/status-page/status-calendar.tsx +++ b/apps/status-page/src/components/status-page/status-calendar.tsx @@ -20,9 +20,9 @@ import { import { useLocale } from "next-intl"; import { useCallback, useMemo } from "react"; -import { Link } from "@/components/common/link"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; -import type { Locale as AppLocale } from "@/i18n/config"; +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import type { Locale as AppLocale } from "../../i18n/config"; +import { Link } from "../common/link"; type Page = NonNullable; type ReportInput = Page["statusReports"][number]; diff --git a/apps/status-page/src/components/status-page/status-events.tsx b/apps/status-page/src/components/status-page/status-events.tsx index 42ff846c..4a01ead1 100644 --- a/apps/status-page/src/components/status-page/status-events.tsx +++ b/apps/status-page/src/components/status-page/status-events.tsx @@ -6,7 +6,7 @@ import { StatusEventTimelineReportUpdate as BlockStatusEventTimelineReportUpdate, } from "@openstatus/ui/components/blocks/status-events"; -import { ProcessMessage } from "@/components/content/process-message"; +import { ProcessMessage } from "../content/process-message"; // Re-export pass-through primitives that don't need glue. export { diff --git a/apps/status-page/src/components/status-page/status-feed.tsx b/apps/status-page/src/components/status-page/status-feed.tsx index 5f21632e..bbd3f934 100644 --- a/apps/status-page/src/components/status-page/status-feed.tsx +++ b/apps/status-page/src/components/status-page/status-feed.tsx @@ -4,10 +4,9 @@ import { StatusBlankAction } from "@openstatus/ui/components/blocks/status-blank import { StatusFeed as BlockStatusFeed } from "@openstatus/ui/components/blocks/status-feed"; import { useExtracted } from "next-intl"; -import { Link } from "@/components/common/link"; -import { ProcessMessage } from "@/components/content/process-message"; -import { usePathnamePrefix } from "@/hooks/use-pathname-prefix"; - +import { usePathnamePrefix } from "../../hooks/use-pathname-prefix"; +import { Link } from "../common/link"; +import { ProcessMessage } from "../content/process-message"; import { StatusBlankLink } from "./status-blank"; const renderMarkdownMessage = (message: string) => ( diff --git a/apps/status-page/src/components/status-page/status-updates.tsx b/apps/status-page/src/components/status-page/status-updates.tsx index f1a38198..7ba925e4 100644 --- a/apps/status-page/src/components/status-page/status-updates.tsx +++ b/apps/status-page/src/components/status-page/status-updates.tsx @@ -26,12 +26,12 @@ import { useExtracted } from "next-intl"; import { useParams } from "next/navigation"; import { useState } from "react"; +import { getBaseUrl } from "../../lib/base-url"; +import { createProtectedCookieKey } from "../../lib/protected"; import { FormSubscribeEmail, type FormValues, -} from "@/components/forms/form-subscribe-email"; -import { getBaseUrl } from "@/lib/base-url"; -import { createProtectedCookieKey } from "@/lib/protected"; +} from "../forms/form-subscribe-email"; export type StatusUpdateType = "email" | "rss" | "ssh" | "json" | "slack"; diff --git a/apps/status-page/src/components/themes/theme-provider.tsx b/apps/status-page/src/components/themes/theme-provider.tsx index 5c56dc14..cfd1d8a8 100644 --- a/apps/status-page/src/components/themes/theme-provider.tsx +++ b/apps/status-page/src/components/themes/theme-provider.tsx @@ -4,8 +4,8 @@ import { ThemeProvider as NextThemesProvider } from "next-themes"; import { useQueryState } from "nuqs"; import type * as React from "react"; -import { useEmbed } from "@/hooks/use-embed"; -import { embedThemeParser } from "@/lib/embed-params"; +import { useEmbed } from "../../hooks/use-embed"; +import { embedThemeParser } from "../../lib/embed-params"; export function ThemeProvider({ children, diff --git a/apps/status-page/src/components/themes/theme-sidebar.tsx b/apps/status-page/src/components/themes/theme-sidebar.tsx index 2b43361a..3293962e 100644 --- a/apps/status-page/src/components/themes/theme-sidebar.tsx +++ b/apps/status-page/src/components/themes/theme-sidebar.tsx @@ -58,8 +58,8 @@ import { useTheme } from "next-themes"; import { useQueryStates } from "nuqs"; import { useEffect, useState } from "react"; -import { searchParamsParsers } from "@/app/(public)/search-params"; -import { recomputeStyles } from "@/components/status-page/floating-button"; +import { searchParamsParsers } from "../../app/(public)/search-params"; +import { recomputeStyles } from "../status-page/floating-button"; type ThemeBuilderColor = { label: string; diff --git a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx index bb18066f..e945965b 100644 --- a/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx +++ b/apps/status-page/src/components/ui/data-table/data-table-toolbar.tsx @@ -5,8 +5,8 @@ import { Input } from "@openstatus/ui/components/ui/input"; import type { Table } from "@tanstack/react-table"; import { X } from "lucide-react"; -import { DataTableFacetedFilter } from "@/components/ui/data-table/data-table-faceted-filter"; -import { DataTableViewOptions } from "@/components/ui/data-table/data-table-view-options"; +import { DataTableFacetedFilter } from "./data-table-faceted-filter"; +import { DataTableViewOptions } from "./data-table-view-options"; export interface DataTableToolbarProps { table: Table; diff --git a/apps/status-page/src/content/markdown/generators.test.ts b/apps/status-page/src/content/markdown/generators.test.ts index 05c074d5..0bfd7274 100644 --- a/apps/status-page/src/content/markdown/generators.test.ts +++ b/apps/status-page/src/content/markdown/generators.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { escapeCell, diff --git a/apps/status-page/src/content/markdown/match-route.test.ts b/apps/status-page/src/content/markdown/match-route.test.ts index 7000f38d..4a4175fd 100644 --- a/apps/status-page/src/content/markdown/match-route.test.ts +++ b/apps/status-page/src/content/markdown/match-route.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchMarkdownRoute, parseMarkdownPath } from "./match-route"; diff --git a/apps/status-page/src/content/status-json.test.ts b/apps/status-page/src/content/status-json.test.ts index 70e450c2..d0fe2da1 100644 --- a/apps/status-page/src/content/status-json.test.ts +++ b/apps/status-page/src/content/status-json.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { RouterOutputs } from "@openstatus/api"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchEndpoint, diff --git a/apps/status-page/src/content/status-vocab.test.ts b/apps/status-page/src/content/status-vocab.test.ts index 5769f458..da2f5bb6 100644 --- a/apps/status-page/src/content/status-vocab.test.ts +++ b/apps/status-page/src/content/status-vocab.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { componentStatus, diff --git a/apps/status-page/src/data/metrics.client.ts b/apps/status-page/src/data/metrics.client.ts index 790dc19c..9db66b9e 100644 --- a/apps/status-page/src/data/metrics.client.ts +++ b/apps/status-page/src/data/metrics.client.ts @@ -3,9 +3,8 @@ import type { RouterOutputs } from "@openstatus/api"; import { monitorRegions } from "@openstatus/db/src/schema/constants"; -import type { MetricCard } from "@/components/content/metric-card"; -import { formatDateTime, formatMilliseconds } from "@/lib/formatter"; - +import type { MetricCard } from "../components/content/metric-card"; +import { formatDateTime, formatMilliseconds } from "../lib/formatter"; import type { RegionMetric } from "./region-metrics"; import type { Region } from "./regions"; diff --git a/apps/status-page/src/hooks/use-embed.ts b/apps/status-page/src/hooks/use-embed.ts index 2369e961..1c202b4f 100644 --- a/apps/status-page/src/hooks/use-embed.ts +++ b/apps/status-page/src/hooks/use-embed.ts @@ -2,13 +2,13 @@ import { useQueryState } from "nuqs"; -import { embedParser } from "@/lib/embed-params"; +import { embedParser } from "../lib/embed-params"; export { ALL_EMBED_SECTIONS, type EmbedSection, type EmbedState, -} from "@/lib/embed-params"; +} from "../lib/embed-params"; export function useEmbed() { const [state] = useQueryState("embed", embedParser); diff --git a/apps/status-page/src/hooks/use-pathname-prefix.ts b/apps/status-page/src/hooks/use-pathname-prefix.ts index 46a898d3..fb0f6b0a 100644 --- a/apps/status-page/src/hooks/use-pathname-prefix.ts +++ b/apps/status-page/src/hooks/use-pathname-prefix.ts @@ -5,9 +5,9 @@ import { useLocale } from "next-intl"; import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { defaultLocale as globalDefaultLocale } from "@/i18n/config"; -import { resolvePathnamePrefix } from "@/lib/resolve-pathname-prefix"; -import { useTRPC } from "@/lib/trpc/client"; +import { defaultLocale as globalDefaultLocale } from "../i18n/config"; +import { resolvePathnamePrefix } from "../lib/resolve-pathname-prefix"; +import { useTRPC } from "../lib/trpc/client"; export function usePathnamePrefix() { const trpc = useTRPC(); diff --git a/apps/status-page/src/lib/alternates-metadata.ts b/apps/status-page/src/lib/alternates-metadata.ts index ae4d6655..192b7e58 100644 --- a/apps/status-page/src/lib/alternates-metadata.ts +++ b/apps/status-page/src/lib/alternates-metadata.ts @@ -1,7 +1,7 @@ import type { Metadata } from "next"; -import { statusPageAlternates } from "@/lib/alternates"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; +import { statusPageAlternates } from "./alternates"; +import { getQueryClient, trpc } from "./trpc/server"; export async function statusPageAlternatesMetadata({ domain, diff --git a/apps/status-page/src/lib/alternates.test.ts b/apps/status-page/src/lib/alternates.test.ts index 900502ee..320be3b7 100644 --- a/apps/status-page/src/lib/alternates.test.ts +++ b/apps/status-page/src/lib/alternates.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { statusPageAlternates } from "./alternates"; diff --git a/apps/status-page/src/lib/auth/index.ts b/apps/status-page/src/lib/auth/index.ts index 40d655e6..80fad5f0 100644 --- a/apps/status-page/src/lib/auth/index.ts +++ b/apps/status-page/src/lib/auth/index.ts @@ -4,9 +4,8 @@ import type { DefaultSession } from "next-auth"; import NextAuth, { AuthError } from "next-auth"; import { headers } from "next/headers"; -import { getValidCustomDomain } from "@/lib/domain"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; - +import { getValidCustomDomain } from "../domain"; +import { getQueryClient, trpc } from "../trpc/server"; import { adapter } from "./adapter"; import { ResendProvider } from "./providers"; diff --git a/apps/status-page/src/lib/auth/providers.ts b/apps/status-page/src/lib/auth/providers.ts index 8ff8d930..45967066 100644 --- a/apps/status-page/src/lib/auth/providers.ts +++ b/apps/status-page/src/lib/auth/providers.ts @@ -1,9 +1,8 @@ import { EmailClient } from "@openstatus/emails"; import Resend from "next-auth/providers/resend"; -import { getQueryClient, trpc } from "@/lib/trpc/server"; - import { getValidCustomDomain } from "../domain"; +import { getQueryClient, trpc } from "../trpc/server"; export const ResendProvider = Resend({ apiKey: undefined, diff --git a/apps/status-page/src/lib/formatter.test.ts b/apps/status-page/src/lib/formatter.test.ts index d9e59b03..bcba4dde 100644 --- a/apps/status-page/src/lib/formatter.test.ts +++ b/apps/status-page/src/lib/formatter.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { formatDate, diff --git a/apps/status-page/src/lib/http/client-ip.test.ts b/apps/status-page/src/lib/http/client-ip.test.ts index 684c07a5..45b2f7c4 100644 --- a/apps/status-page/src/lib/http/client-ip.test.ts +++ b/apps/status-page/src/lib/http/client-ip.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveClientIp } from "./client-ip"; diff --git a/apps/status-page/src/lib/http/etag.test.ts b/apps/status-page/src/lib/http/etag.test.ts index 66e86bd8..66d584e3 100644 --- a/apps/status-page/src/lib/http/etag.test.ts +++ b/apps/status-page/src/lib/http/etag.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { computeETag, isNotModified } from "./etag"; diff --git a/apps/status-page/src/lib/http/markdown-response.test.ts b/apps/status-page/src/lib/http/markdown-response.test.ts index c519398e..00976f94 100644 --- a/apps/status-page/src/lib/http/markdown-response.test.ts +++ b/apps/status-page/src/lib/http/markdown-response.test.ts @@ -1,8 +1,9 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; -import { withPoweredBy } from "@/content/markdown"; -import { computeETag } from "@/lib/http/etag"; -import { resolveMarkdownResponse } from "@/lib/http/markdown-response"; +import { withPoweredBy } from "../../content/markdown"; +import { computeETag } from "./etag"; +import { resolveMarkdownResponse } from "./markdown-response"; const PUBLIC_CACHE = "public, max-age=60, s-maxage=60, stale-while-revalidate=300"; diff --git a/apps/status-page/src/lib/http/markdown-response.ts b/apps/status-page/src/lib/http/markdown-response.ts index ae27ed3e..41cb8b1f 100644 --- a/apps/status-page/src/lib/http/markdown-response.ts +++ b/apps/status-page/src/lib/http/markdown-response.ts @@ -1,6 +1,6 @@ -import { withPoweredBy } from "@/content/markdown"; -import { computeETag, isNotModified } from "@/lib/http/etag"; -import { markdownCacheControl } from "@/lib/proxy/markdown-cache-control"; +import { withPoweredBy } from "../../content/markdown"; +import { markdownCacheControl } from "../proxy/markdown-cache-control"; +import { computeETag, isNotModified } from "./etag"; const MARKDOWN = "text/markdown; charset=utf-8"; diff --git a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts index f6821af1..c04f0fe6 100644 --- a/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts +++ b/apps/status-page/src/lib/proxy/apply-page-locale-override.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { applyPageLocaleOverride } from "./apply-page-locale-override"; diff --git a/apps/status-page/src/lib/proxy/build-external-path.test.ts b/apps/status-page/src/lib/proxy/build-external-path.test.ts index e809f6da..df5444bb 100644 --- a/apps/status-page/src/lib/proxy/build-external-path.test.ts +++ b/apps/status-page/src/lib/proxy/build-external-path.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { buildExternalPath } from "./build-external-path"; diff --git a/apps/status-page/src/lib/proxy/compose-page-action.test.ts b/apps/status-page/src/lib/proxy/compose-page-action.test.ts index 92c33732..f3778b40 100644 --- a/apps/status-page/src/lib/proxy/compose-page-action.test.ts +++ b/apps/status-page/src/lib/proxy/compose-page-action.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Page } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { type ComposeInput, composePageAction } from "./compose-page-action"; diff --git a/apps/status-page/src/lib/proxy/detect-markdown.test.ts b/apps/status-page/src/lib/proxy/detect-markdown.test.ts index 10dbc1f9..75d0c613 100644 --- a/apps/status-page/src/lib/proxy/detect-markdown.test.ts +++ b/apps/status-page/src/lib/proxy/detect-markdown.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { detectMarkdown } from "./detect-markdown"; diff --git a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts index 02c7f46b..2386573a 100644 --- a/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts +++ b/apps/status-page/src/lib/proxy/evaluate-markdown-gate.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { evaluateMarkdownGate } from "./evaluate-markdown-gate"; diff --git a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts index d96101df..c963ca31 100644 --- a/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts +++ b/apps/status-page/src/lib/proxy/is-ip-allowed.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { isIpAllowed } from "./is-ip-allowed"; diff --git a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts index 9b6f9053..0f8cd54f 100644 --- a/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts +++ b/apps/status-page/src/lib/proxy/markdown-cache-control.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { markdownCacheControl } from "./markdown-cache-control"; diff --git a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts index 06eec605..67a2c1f4 100644 --- a/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-custom-domain-rewrite.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveCustomDomainRewrite } from "./resolve-custom-domain-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts index 57f39dd2..5aff1bca 100644 --- a/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-default-rewrite.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveDefaultRewrite } from "./resolve-default-rewrite"; diff --git a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts index b6f87852..0a47a7ef 100644 --- a/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-email-domain-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveEmailDomainAction } from "./resolve-email-domain-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-gate.ts b/apps/status-page/src/lib/proxy/resolve-gate.ts index 7e56564e..fb6ca343 100644 --- a/apps/status-page/src/lib/proxy/resolve-gate.ts +++ b/apps/status-page/src/lib/proxy/resolve-gate.ts @@ -1,10 +1,9 @@ import type { Page } from "@openstatus/db/src/schema"; -import { auth } from "@/lib/auth"; -import { createProtectedCookieKey } from "@/lib/protected"; -import type { getQueryClient } from "@/lib/trpc/server"; -import { trpc } from "@/lib/trpc/server"; - +import { auth } from "../auth"; +import { createProtectedCookieKey } from "../protected"; +import type { getQueryClient } from "../trpc/server"; +import { trpc } from "../trpc/server"; import { evaluateMarkdownGate, type MarkdownGateResult, diff --git a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts index 0405f812..58987fb9 100644 --- a/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-ip-restriction-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveIpRestrictionAction } from "./resolve-ip-restriction-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts index 946ea0b6..ef78a82c 100644 --- a/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-locale-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolveLocaleAction } from "./resolve-locale-action"; diff --git a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts index 5904bdf9..382f8137 100644 --- a/apps/status-page/src/lib/proxy/resolve-password-action.test.ts +++ b/apps/status-page/src/lib/proxy/resolve-password-action.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { ResolvedRoute } from "../resolve-route"; import { resolvePasswordAction } from "./resolve-password-action"; diff --git a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts index a50c54eb..5a3c6989 100644 --- a/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts +++ b/apps/status-page/src/lib/proxy/sanitize-redirect-param.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { sanitizeRedirectParam } from "./sanitize-redirect-param"; diff --git a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts index b4447230..041ad0a4 100644 --- a/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts +++ b/apps/status-page/src/lib/proxy/strip-prefix-for-external.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { stripPrefixForExternal } from "./strip-prefix-for-external"; diff --git a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts index 867c64cc..85e9d9b7 100644 --- a/apps/status-page/src/lib/resolve-pathname-prefix.test.ts +++ b/apps/status-page/src/lib/resolve-pathname-prefix.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolvePathnamePrefix } from "./resolve-pathname-prefix"; diff --git a/apps/status-page/src/lib/resolve-route.test.ts b/apps/status-page/src/lib/resolve-route.test.ts index fa1f8e71..39046b50 100644 --- a/apps/status-page/src/lib/resolve-route.test.ts +++ b/apps/status-page/src/lib/resolve-route.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { resolveRoute } from "./resolve-route"; diff --git a/apps/status-page/src/lib/resolve-route.ts b/apps/status-page/src/lib/resolve-route.ts index 88f8760c..2e280487 100644 --- a/apps/status-page/src/lib/resolve-route.ts +++ b/apps/status-page/src/lib/resolve-route.ts @@ -1,5 +1,4 @@ -import { type Locale, defaultLocale, locales } from "@/i18n/config"; - +import { type Locale, defaultLocale, locales } from "../i18n/config"; import { getValidSubdomain } from "./domain"; export type RouteType = "hostname" | "pathname"; diff --git a/apps/status-page/src/lib/status-blocks-labels.test.ts b/apps/status-page/src/lib/status-blocks-labels.test.ts index e3d5c223..f6878d61 100644 --- a/apps/status-page/src/lib/status-blocks-labels.test.ts +++ b/apps/status-page/src/lib/status-blocks-labels.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { defaultStatusBlocksLabels as labels } from "@openstatus/ui/components/blocks/status.utils"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; // Status-page timestamps render in UTC, so the user-facing labels carry a // trailing "(UTC)" to tell viewers which zone they are reading (see #2302). diff --git a/apps/status-page/src/lib/trpc/client.tsx b/apps/status-page/src/lib/trpc/client.tsx index 296c0c42..51ecd68c 100644 --- a/apps/status-page/src/lib/trpc/client.tsx +++ b/apps/status-page/src/lib/trpc/client.tsx @@ -6,7 +6,7 @@ import { createTRPCClient, loggerLink } from "@trpc/client"; import { createTRPCContext } from "@trpc/tanstack-react-query"; import { useState } from "react"; -import { endingLink } from "@/lib/trpc/shared"; +import { endingLink } from "./shared"; export const { TRPCProvider, useTRPC, useTRPCClient } = createTRPCContext(); diff --git a/apps/status-page/src/proxy.ts b/apps/status-page/src/proxy.ts index ab8511f2..b93550f9 100644 --- a/apps/status-page/src/proxy.ts +++ b/apps/status-page/src/proxy.ts @@ -2,9 +2,8 @@ import { db, sql } from "@openstatus/db"; import { page, selectPageSchema } from "@openstatus/db/src/schema"; import { NextResponse } from "next/server"; -import { auth } from "@/lib/auth"; -import { resolveClientIp } from "@/lib/http/client-ip"; - +import { auth } from "./lib/auth"; +import { resolveClientIp } from "./lib/http/client-ip"; import { createProtectedCookieKey } from "./lib/protected"; import { applyPageLocaleOverride } from "./lib/proxy/apply-page-locale-override"; import { composePageAction } from "./lib/proxy/compose-page-action"; diff --git a/apps/web/env.ts b/apps/web/env.ts index dbb28b16..dab63f5f 100644 --- a/apps/web/env.ts +++ b/apps/web/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/apps/web/package.json b/apps/web/package.json index e7fb85bb..ebf0045d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -3,13 +3,13 @@ "version": "1.0.0", "private": true, "scripts": { - "env": "bun env.ts", + "env": "deno run -A env.ts", "dev": "next dev", "build:registry": "turbo run registry:build --filter=@openstatus/ui", "build": "pnpm build:registry && next build", "start": "next start", "lint": "next lint", - "test": "bun test", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -98,6 +98,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@tailwindcss/postcss": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", diff --git a/apps/web/src/app/(ai)/llms-full.txt/route.ts b/apps/web/src/app/(ai)/llms-full.txt/route.ts index 75e06708..f4751861 100644 --- a/apps/web/src/app/(ai)/llms-full.txt/route.ts +++ b/apps/web/src/app/(ai)/llms-full.txt/route.ts @@ -1,15 +1,15 @@ -import { convertMdxToMarkdown } from "@/content/convert"; +import { convertMdxToMarkdown } from "../../../content/convert"; import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "@/content/llms-context"; +} from "../../../content/llms-context"; import { type MDXData, getHomePage, getProductPages, getToolingPages, getUnrelatedPages, -} from "@/content/utils"; +} from "../../../content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/llms.txt/route.ts b/apps/web/src/app/(ai)/llms.txt/route.ts index 6bc1cf36..069076c1 100644 --- a/apps/web/src/app/(ai)/llms.txt/route.ts +++ b/apps/web/src/app/(ai)/llms.txt/route.ts @@ -1,7 +1,7 @@ import { PRODUCT_CONTEXT_MARKDOWN, PRODUCT_SUMMARY, -} from "@/content/llms-context"; +} from "../../../content/llms-context"; import { type MDXData, getBlogPosts, @@ -14,7 +14,7 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "@/content/utils"; +} from "../../../content/utils"; export const runtime = "nodejs"; export const revalidate = 3600; diff --git a/apps/web/src/app/(ai)/mcp/route.ts b/apps/web/src/app/(ai)/mcp/route.ts index dc30e23c..26cd2883 100644 --- a/apps/web/src/app/(ai)/mcp/route.ts +++ b/apps/web/src/app/(ai)/mcp/route.ts @@ -1,6 +1,6 @@ // Discovery endpoint for /mcp. JSON clients receive the server card inline // (no domain coupling); browsers get redirected to the human-readable page. -import { GET as serverCardGET } from "@/app/.well-known/mcp/server-card.json/route"; +import { GET as serverCardGET } from "../../.well-known/mcp/server-card.json/route"; export function GET(request: Request) { const accept = request.headers.get("accept") ?? ""; diff --git a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx index fc9dc97a..e80ed59a 100644 --- a/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx +++ b/apps/web/src/app/(docs)/docs/[[...slug]]/page.tsx @@ -5,34 +5,34 @@ import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { ContentPagination } from "@/app/(landing)/content-pagination"; +} from "../../../(landing)/content-box"; +import { ContentPagination } from "../../../(landing)/content-pagination"; import { getDocs, getDocsPage, getDocsPagination, gitLastModified, validateDocsNav, -} from "@/content/docs"; -import { DocsFeedback } from "@/content/docs-feedback"; -import { DocsSubNav } from "@/content/docs-sub-nav"; -import { TableOfContents } from "@/content/docs-toc"; +} from "../../../../content/docs"; +import { DocsFeedback } from "../../../../content/docs-feedback"; +import { DocsSubNav } from "../../../../content/docs-sub-nav"; +import { TableOfContents } from "../../../../content/docs-toc"; import { type DocsNavNode, docsNavTree, findDocsNode, findDocsTrail, getDocsContainerSlugs, -} from "@/content/docs.config"; -import { CustomMDX } from "@/content/mdx"; -import { Grid } from "@/content/mdx-components/grid"; -import { extractHeadings } from "@/content/toc"; -import { JsonLd } from "@/lib/metadata/json-ld"; +} from "../../../../content/docs.config"; +import { CustomMDX } from "../../../../content/mdx"; +import { Grid } from "../../../../content/mdx-components/grid"; +import { extractHeadings } from "../../../../content/toc"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; import { BASE_URL, getPageMetadata, getSocialMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -41,7 +41,7 @@ import { getJsonLDItemList, getJsonLDOrganization, getJsonLDTechArticle, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(docs)/layout.tsx b/apps/web/src/app/(docs)/layout.tsx index 153bdd8b..1664fe19 100644 --- a/apps/web/src/app/(docs)/layout.tsx +++ b/apps/web/src/app/(docs)/layout.tsx @@ -1,6 +1,6 @@ -import { DocsFooter } from "@/content/docs-footer"; -import { DocsHeader } from "@/content/docs-header"; -import { DocsMobileNav, DocsSidebar } from "@/content/docs-sidebar"; +import { DocsFooter } from "../../content/docs-footer"; +import { DocsHeader } from "../../content/docs-header"; +import { DocsMobileNav, DocsSidebar } from "../../content/docs-sidebar"; export default function DocsLayout({ children, diff --git a/apps/web/src/app/(landing)/[slug]/page.tsx b/apps/web/src/app/(landing)/[slug]/page.tsx index 1713d307..41c0ecb1 100644 --- a/apps/web/src/app/(landing)/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/[slug]/page.tsx @@ -1,10 +1,10 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getMainPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../content/mdx"; +import { getMainPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; +import { getPageMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -13,7 +13,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/blog/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/[slug]/page.tsx index 2d400a23..a230288f 100644 --- a/apps/web/src/app/(landing)/blog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getBlogPosts } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx index 553c7cf1..64e66988 100644 --- a/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getBlogPosts } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/blog/category/page.tsx b/apps/web/src/app/(landing)/blog/category/page.tsx index 266e2986..6d917999 100644 --- a/apps/web/src/app/(landing)/blog/category/page.tsx +++ b/apps/web/src/app/(landing)/blog/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getBlogPosts } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getBlogPosts } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Blog Categories"; diff --git a/apps/web/src/app/(landing)/blog/feed.xml/route.ts b/apps/web/src/app/(landing)/blog/feed.xml/route.ts index e8122942..82a77083 100644 --- a/apps/web/src/app/(landing)/blog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/blog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getBlogPosts } from "@/content/utils"; +import { getBlogPosts } from "../../../../content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/blog/page.tsx b/apps/web/src/app/(landing)/blog/page.tsx index 18bd6d31..0da5f407 100644 --- a/apps/web/src/app/(landing)/blog/page.tsx +++ b/apps/web/src/app/(landing)/blog/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getBlogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getBlogPosts } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx index 01a9ef56..a0071eb2 100644 --- a/apps/web/src/app/(landing)/changelog/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getChangelogPosts } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx index d970a69d..269532c2 100644 --- a/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getChangelogPosts } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/changelog/category/page.tsx b/apps/web/src/app/(landing)/changelog/category/page.tsx index d9472c13..65b4a27c 100644 --- a/apps/web/src/app/(landing)/changelog/category/page.tsx +++ b/apps/web/src/app/(landing)/changelog/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getChangelogPosts } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getChangelogPosts } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Changelog Categories"; diff --git a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts index d48b54bc..78422c9c 100644 --- a/apps/web/src/app/(landing)/changelog/feed.xml/route.ts +++ b/apps/web/src/app/(landing)/changelog/feed.xml/route.ts @@ -1,7 +1,7 @@ import { Feed } from "feed"; import { getAuthor } from "src/data/author"; -import { getChangelogPosts } from "@/content/utils"; +import { getChangelogPosts } from "../../../../content/utils"; export async function GET() { const feed = new Feed({ diff --git a/apps/web/src/app/(landing)/changelog/page.tsx b/apps/web/src/app/(landing)/changelog/page.tsx index ad57acd8..c7d07e67 100644 --- a/apps/web/src/app/(landing)/changelog/page.tsx +++ b/apps/web/src/app/(landing)/changelog/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; import Link from "next/link"; -import { getChangelogPosts } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getChangelogPosts } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/compare/[slug]/page.tsx b/apps/web/src/app/(landing)/compare/[slug]/page.tsx index f3002f40..95bcf03f 100644 --- a/apps/web/src/app/(landing)/compare/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/compare/[slug]/page.tsx @@ -1,11 +1,13 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { ContentPagination } from "@/app/(landing)/content-pagination"; -import { CustomMDX } from "@/content/mdx"; -import { getComparePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getComparePages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,7 +16,8 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; +import { ContentPagination } from "../../content-pagination"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/compare/page.tsx b/apps/web/src/app/(landing)/compare/page.tsx index 7bc2f2b1..f4f01e1e 100644 --- a/apps/web/src/app/(landing)/compare/page.tsx +++ b/apps/web/src/app/(landing)/compare/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getComparePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getComparePages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/content-box-image.tsx b/apps/web/src/app/(landing)/content-box-image.tsx index 4d1ff74a..2e32b42e 100644 --- a/apps/web/src/app/(landing)/content-box-image.tsx +++ b/apps/web/src/app/(landing)/content-box-image.tsx @@ -1,7 +1,7 @@ import type React from "react"; -import { CustomImage } from "@/content/mdx-components/custom-image"; -import { cn } from "@/lib/utils"; +import { CustomImage } from "../../content/mdx-components/custom-image"; +import { cn } from "../../lib/utils"; export function ContentBoxImage({ className, diff --git a/apps/web/src/app/(landing)/content-box.tsx b/apps/web/src/app/(landing)/content-box.tsx index 6cfbdea2..a66a914a 100644 --- a/apps/web/src/app/(landing)/content-box.tsx +++ b/apps/web/src/app/(landing)/content-box.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function ContentBoxLink({ href, diff --git a/apps/web/src/app/(landing)/content-category.tsx b/apps/web/src/app/(landing)/content-category.tsx index 826a7c5d..91ca45da 100644 --- a/apps/web/src/app/(landing)/content-category.tsx +++ b/apps/web/src/app/(landing)/content-category.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import { Fragment } from "react"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export function ContentCategory({ data, diff --git a/apps/web/src/app/(landing)/content-list.tsx b/apps/web/src/app/(landing)/content-list.tsx index 1a3e08fb..1f6c40ab 100644 --- a/apps/web/src/app/(landing)/content-list.tsx +++ b/apps/web/src/app/(landing)/content-list.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { type MDXData, formatDate } from "@/content/utils"; -import { cn } from "@/lib/utils"; +import { type MDXData, formatDate } from "../../content/utils"; +import { cn } from "../../lib/utils"; export function ContentList({ data, diff --git a/apps/web/src/app/(landing)/content-metadata.tsx b/apps/web/src/app/(landing)/content-metadata.tsx index 02fd8bea..aa9ebb23 100644 --- a/apps/web/src/app/(landing)/content-metadata.tsx +++ b/apps/web/src/app/(landing)/content-metadata.tsx @@ -1,5 +1,5 @@ -import { type MDXData, formatDate } from "@/content/utils"; -import { getAuthor } from "@/data/author"; +import { type MDXData, formatDate } from "../../content/utils"; +import { getAuthor } from "../../data/author"; export function ContentMetadata({ data }: { data: MDXData }) { return ( diff --git a/apps/web/src/app/(landing)/content-pagination.tsx b/apps/web/src/app/(landing)/content-pagination.tsx index 710feed5..91f98721 100644 --- a/apps/web/src/app/(landing)/content-pagination.tsx +++ b/apps/web/src/app/(landing)/content-pagination.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export function ContentPagination({ prev, diff --git a/apps/web/src/app/(landing)/customers/[slug]/page.tsx b/apps/web/src/app/(landing)/customers/[slug]/page.tsx index ee02d501..b4d0b714 100644 --- a/apps/web/src/app/(landing)/customers/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/customers/[slug]/page.tsx @@ -1,18 +1,21 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { CustomImage } from "@/content/mdx-components/custom-image"; -import { getCustomerPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { CustomImage } from "../../../../content/mdx-components/custom-image"; +import { getCustomerPages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/customers/page.tsx b/apps/web/src/app/(landing)/customers/page.tsx index b810b8aa..707baddb 100644 --- a/apps/web/src/app/(landing)/customers/page.tsx +++ b/apps/web/src/app/(landing)/customers/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getCustomerPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getCustomerPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/guides/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/[slug]/page.tsx index 22583577..2db3fd5b 100644 --- a/apps/web/src/app/(landing)/guides/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getGuides } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx index 10f79591..1041fb8d 100644 --- a/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/[slug]/page.tsx @@ -1,21 +1,21 @@ import type { Metadata } from "next"; -import { ContentCategory } from "@/app/(landing)/content-category"; -import { ContentList } from "@/app/(landing)/content-list"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getGuides } from "../../../../../content/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; +} from "../../../../../lib/metadata/structured-data"; +import { ContentCategory } from "../../../content-category"; +import { ContentList } from "../../../content-list"; export async function generateMetadata({ params, diff --git a/apps/web/src/app/(landing)/guides/category/page.tsx b/apps/web/src/app/(landing)/guides/category/page.tsx index 9660aa4c..cd19b69e 100644 --- a/apps/web/src/app/(landing)/guides/category/page.tsx +++ b/apps/web/src/app/(landing)/guides/category/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getGuides } from "@/content/utils"; +import { components } from "../../../../content/mdx"; +import { getGuides } from "../../../../content/utils"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../../lib/metadata/shared-metadata"; import { ContentBoxLink, ContentBoxTitle } from "../../content-box"; const TITLE = "Guides Categories"; diff --git a/apps/web/src/app/(landing)/guides/page.tsx b/apps/web/src/app/(landing)/guides/page.tsx index a66d5158..b4770986 100644 --- a/apps/web/src/app/(landing)/guides/page.tsx +++ b/apps/web/src/app/(landing)/guides/page.tsx @@ -1,20 +1,19 @@ import type { Metadata } from "next"; -import { getGuides } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getGuides } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentCategory } from "../content-category"; import { ContentList } from "../content-list"; diff --git a/apps/web/src/app/(landing)/layout.tsx b/apps/web/src/app/(landing)/layout.tsx index 2933a24a..e8b074eb 100644 --- a/apps/web/src/app/(landing)/layout.tsx +++ b/apps/web/src/app/(landing)/layout.tsx @@ -1,6 +1,6 @@ -import { Footer } from "@/content/footer"; -import { Header } from "@/content/header"; -import { SubNav } from "@/content/sub-nav"; +import { Footer } from "../../content/footer"; +import { Header } from "../../content/header"; +import { SubNav } from "../../content/sub-nav"; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/apps/web/src/app/(landing)/oss-friends/page.tsx b/apps/web/src/app/(landing)/oss-friends/page.tsx index ed292882..9e58bc7a 100644 --- a/apps/web/src/app/(landing)/oss-friends/page.tsx +++ b/apps/web/src/app/(landing)/oss-friends/page.tsx @@ -1,13 +1,12 @@ import type { Metadata } from "next"; import { z } from "zod"; -import { components } from "@/content/mdx"; +import { components } from "../../../content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../lib/metadata/shared-metadata"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/page.tsx b/apps/web/src/app/(landing)/page.tsx index b9cab94f..6576990f 100644 --- a/apps/web/src/app/(landing)/page.tsx +++ b/apps/web/src/app/(landing)/page.tsx @@ -1,9 +1,9 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getHomePage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { defaultMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../content/mdx"; +import { getHomePage } from "../../content/utils"; +import { JsonLd } from "../../lib/metadata/json-ld"; +import { defaultMetadata } from "../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDFAQPage, @@ -12,7 +12,7 @@ import { getJsonLDProduct, getJsonLDSoftwareApplication, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../lib/metadata/structured-data"; export const metadata: Metadata = defaultMetadata; diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx index 1f23b684..6b979138 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/client.tsx @@ -19,15 +19,14 @@ import { } from "@openstatus/ui/components/ui/tabs"; import { useState } from "react"; -import { IconCloudProvider } from "@/components/icon-cloud-provider"; +import { IconCloudProvider } from "../../../../../components/icon-cloud-provider"; import { type CachedRegionChecker, getTimingPhases, regionFormatter, timestampFormatter, -} from "@/lib/checker/utils"; -import { cn } from "@/lib/utils"; - +} from "../../../../../lib/checker/utils"; +import { cn } from "../../../../../lib/utils"; import { handleExportCSV } from "../utils"; const STATUS_CODES = { diff --git a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx index 8cc463d0..f07f70f0 100644 --- a/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/[slug]/page.tsx @@ -1,22 +1,24 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { mockCheckAllRegions } from "@/lib/checker/mock"; +import { CustomMDX } from "../../../../../content/mdx"; +import { getToolsPage } from "../../../../../content/utils"; +import { mockCheckAllRegions } from "../../../../../lib/checker/mock"; import { getCheckerDataById, latencyFormatter, regionFormatter, -} from "@/lib/checker/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../../../lib/checker/utils"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../../lib/metadata/structured-data"; import { Table } from "./client"; function formatDate(date: Date) { diff --git a/apps/web/src/app/(landing)/play/checker/api/route.ts b/apps/web/src/app/(landing)/play/checker/api/route.ts index a9ce8c99..14230857 100644 --- a/apps/web/src/app/(landing)/play/checker/api/route.ts +++ b/apps/web/src/app/(landing)/play/checker/api/route.ts @@ -3,17 +3,17 @@ import { AVAILABLE_REGIONS } from "@openstatus/regions"; import { after } from "next/server"; import { z } from "zod"; -import { mockCheckRegion } from "@/lib/checker/mock"; +import { mockCheckRegion } from "../../../../../lib/checker/mock"; import { type Method, checkRegion, getTimingPhases, storeBaseCheckerData, storeCheckerData, -} from "@/lib/checker/utils"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; -import { iteratorToStream, yieldMany } from "@/lib/stream"; -import { wait } from "@/lib/utils"; +} from "../../../../../lib/checker/utils"; +import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; +import { iteratorToStream, yieldMany } from "../../../../../lib/stream"; +import { wait } from "../../../../../lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/(landing)/play/checker/client.tsx b/apps/web/src/app/(landing)/play/checker/client.tsx index 471ad579..1db7ed7c 100644 --- a/apps/web/src/app/(landing)/play/checker/client.tsx +++ b/apps/web/src/app/(landing)/play/checker/client.tsx @@ -25,17 +25,16 @@ import { useTransition, } from "react"; -import { IconCloudProvider } from "@/components/icon-cloud-provider"; +import { IconCloudProvider } from "../../../../components/icon-cloud-provider"; import { type Timing, is32CharHex, latencyFormatter, regionCheckerSchema, regionFormatter, -} from "@/lib/checker/utils"; -import { toast } from "@/lib/toast"; -import { cn, notEmpty } from "@/lib/utils"; - +} from "../../../../lib/checker/utils"; +import { toast } from "../../../../lib/toast"; +import { cn, notEmpty } from "../../../../lib/utils"; import { searchParamsParsers } from "./search-params"; import { handleExportCSV } from "./utils"; diff --git a/apps/web/src/app/(landing)/play/checker/page.tsx b/apps/web/src/app/(landing)/play/checker/page.tsx index 7e53f3ee..f8a6dbd1 100644 --- a/apps/web/src/app/(landing)/play/checker/page.tsx +++ b/apps/web/src/app/(landing)/play/checker/page.tsx @@ -1,18 +1,20 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { mockCheckAllRegions } from "@/lib/checker/mock"; -import { getCheckerDataById } from "@/lib/checker/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { mockCheckAllRegions } from "../../../../lib/checker/mock"; +import { getCheckerDataById } from "../../../../lib/checker/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { CheckerProvider, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/checker/utils.ts b/apps/web/src/app/(landing)/play/checker/utils.ts index 057b6134..410cf7a2 100644 --- a/apps/web/src/app/(landing)/play/checker/utils.ts +++ b/apps/web/src/app/(landing)/play/checker/utils.ts @@ -1,7 +1,7 @@ import { type Region, regionDict } from "@openstatus/regions"; -import { type Timing, getTimingPhases } from "@/lib/checker/utils"; -import { toast } from "@/lib/toast"; +import { type Timing, getTimingPhases } from "../../../../lib/checker/utils"; +import { toast } from "../../../../lib/toast"; export type CheckerRow = { region: string; diff --git a/apps/web/src/app/(landing)/play/curl/page.tsx b/apps/web/src/app/(landing)/play/curl/page.tsx index ed05a6f8..c7cc3fff 100644 --- a/apps/web/src/app/(landing)/play/curl/page.tsx +++ b/apps/web/src/app/(landing)/play/curl/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { Form } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx index 5df37359..1fba7fa6 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/client.tsx @@ -1,7 +1,6 @@ "use client"; -import type { HealthCheckReport } from "@/lib/mcp/health-check"; - +import type { HealthCheckReport } from "../../../../../lib/mcp/health-check"; import { ResultTableStatic, ToolsTableView, VerdictBarStatic } from "../client"; export function Table({ data }: { data: HealthCheckReport }) { diff --git a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx index d1d9678e..33daf4af 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/[id]/page.tsx @@ -1,17 +1,19 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { getHealthReportById } from "@/lib/mcp/health-check"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../../content/mdx"; +import { getToolsPage } from "../../../../../content/utils"; +import { getHealthReportById } from "../../../../../lib/mcp/health-check"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../../lib/metadata/structured-data"; import { VERDICT_LABEL, formatTimestamp } from "../utils"; import { Table } from "./client"; diff --git a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts index fb81a631..71ced0d5 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/api/route.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/api/route.ts @@ -9,8 +9,8 @@ import { runMcpHealthCheck, storeHealthReport, toPersistedReport, -} from "@/lib/mcp/health-check"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; +} from "../../../../../lib/mcp/health-check"; +import { getClientIP, ratelimit } from "../../../../../lib/ratelimit"; export const runtime = "edge"; // Worst-case 16s of step time + metadata fetch + analytics; give some slack. diff --git a/apps/web/src/app/(landing)/play/mcp-health/client.tsx b/apps/web/src/app/(landing)/play/mcp-health/client.tsx index 70efd99d..b42d585f 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/client.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/client.tsx @@ -32,10 +32,9 @@ import type { HealthCheckReport, StepResult, ToolInfo, -} from "@/lib/mcp/health-check"; -import { toast } from "@/lib/toast"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/mcp/health-check"; +import { toast } from "../../../../lib/toast"; +import { cn } from "../../../../lib/utils"; import { searchParamsParsers } from "./search-params"; import { STEP_REQUEST_BODIES, diff --git a/apps/web/src/app/(landing)/play/mcp-health/page.tsx b/apps/web/src/app/(landing)/play/mcp-health/page.tsx index c6fff2e6..69da93cb 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/page.tsx +++ b/apps/web/src/app/(landing)/play/mcp-health/page.tsx @@ -1,18 +1,20 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { getHealthReportById } from "@/lib/mcp/health-check"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { getHealthReportById } from "../../../../lib/mcp/health-check"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDHowTo, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { AuthChallengeCallout, DetailsButtonLink, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts index 228c78b5..ba080c63 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { formatResponseBody, diff --git a/apps/web/src/app/(landing)/play/mcp-health/utils.ts b/apps/web/src/app/(landing)/play/mcp-health/utils.ts index 2080daa3..73c088b6 100644 --- a/apps/web/src/app/(landing)/play/mcp-health/utils.ts +++ b/apps/web/src/app/(landing)/play/mcp-health/utils.ts @@ -1,6 +1,12 @@ -import type { HealthCheckReport, StepResult } from "@/lib/mcp/health-check"; +import type { + HealthCheckReport, + StepResult, +} from "../../../../lib/mcp/health-check"; -export { STEP_REQUEST_BODIES, type StepKey } from "@/lib/mcp/protocol"; +export { + STEP_REQUEST_BODIES, + type StepKey, +} from "../../../../lib/mcp/protocol"; export const VERDICT_LABEL: Record = { healthy: "GOOD", diff --git a/apps/web/src/app/(landing)/play/page.tsx b/apps/web/src/app/(landing)/play/page.tsx index 7f27849d..a7d54da9 100644 --- a/apps/web/src/app/(landing)/play/page.tsx +++ b/apps/web/src/app/(landing)/play/page.tsx @@ -1,12 +1,11 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; +import { components } from "../../../content/mdx"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; - +} from "../../../lib/metadata/shared-metadata"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx index 0a794ce8..bf8e8b85 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/client.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/client.tsx @@ -7,7 +7,7 @@ import { Label } from "@openstatus/ui/components/ui/label"; import { Slider } from "@openstatus/ui/components/ui/slider"; import { useState } from "react"; -import { Details } from "@/content/mdx-components/details"; +import { Details } from "../../../../content/mdx-components/details"; type SeverityLevel = "SEV0" | "SEV1" | "SEV2" | "SEV3"; diff --git a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx index e3d57b2d..b4af063a 100644 --- a/apps/web/src/app/(landing)/play/severity-matrix/page.tsx +++ b/apps/web/src/app/(landing)/play/severity-matrix/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { SeverityMatrixBuilder } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx index aa88a7c7..2214ce25 100644 --- a/apps/web/src/app/(landing)/play/uptime-sla/page.tsx +++ b/apps/web/src/app/(landing)/play/uptime-sla/page.tsx @@ -1,16 +1,18 @@ import type { Metadata } from "next"; -import { CustomMDX } from "@/content/mdx"; -import { getToolsPage } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolsPage } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { Calculation } from "./client"; export function generateMetadata(): Metadata { diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx index 6e6d88db..9e47b6bd 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx @@ -2,22 +2,21 @@ import { REPORT_WINDOW_MINUTES } from "@openstatus/api/src/router/effective-status"; -import { - ContentBoxDescription, - ContentBoxLink, - ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { Grid } from "@/content/mdx-components/grid"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL } from "@/lib/metadata/shared-metadata"; +import { Grid } from "../../../../../content/mdx-components/grid"; +import { JsonLd } from "../../../../../lib/metadata/json-ld"; +import { BASE_URL } from "../../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; -import { api } from "@/trpc/rq-client"; - +} from "../../../../../lib/metadata/structured-data"; +import { api } from "../../../../../trpc/rq-client"; +import { + ContentBoxDescription, + ContentBoxLink, + ContentBoxTitle, +} from "../../../content-box"; import { ExternalServicePill } from "../../external-service-pill"; import { formatRelative } from "../../utils"; import { HistoryBars } from "../history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx index 6906aeb7..c5f7e78d 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/page.tsx @@ -2,18 +2,17 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; -import { cachedGetExternalComponentBySlug } from "@/lib/external-service-cache"; +import { ButtonLink } from "../../../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../../../content/mdx-components/custom-link"; +import { cachedGetExternalComponentBySlug } from "../../../../../lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/incidents.tsx b/apps/web/src/app/(landing)/status/[id]/incidents.tsx index 4ee5276c..2a4c6d60 100644 --- a/apps/web/src/app/(landing)/status/[id]/incidents.tsx +++ b/apps/web/src/app/(landing)/status/[id]/incidents.tsx @@ -1,12 +1,12 @@ "use client"; +import { Grid } from "../../../../content/mdx-components/grid"; +import { api } from "../../../../trpc/rq-client"; import { ContentBoxDescription, ContentBoxLink, ContentBoxTitle, -} from "@/app/(landing)/content-box"; -import { Grid } from "@/content/mdx-components/grid"; -import { api } from "@/trpc/rq-client"; +} from "../../content-box"; function impactClass(impact: string | undefined): string { switch (impact) { diff --git a/apps/web/src/app/(landing)/status/[id]/page.tsx b/apps/web/src/app/(landing)/status/[id]/page.tsx index ea21922e..20594bf5 100644 --- a/apps/web/src/app/(landing)/status/[id]/page.tsx +++ b/apps/web/src/app/(landing)/status/[id]/page.tsx @@ -3,19 +3,18 @@ import type { Metadata } from "next"; import { notFound, permanentRedirect } from "next/navigation"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; -import { getServiceEscalation } from "@/lib/external-report-escalation"; -import { cachedGetExternalServiceBySlug } from "@/lib/external-service-cache"; +import { ButtonLink } from "../../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../../content/mdx-components/custom-link"; +import { getServiceEscalation } from "../../../../lib/external-report-escalation"; +import { cachedGetExternalServiceBySlug } from "../../../../lib/external-service-cache"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx index d3ed1de2..705129f0 100644 --- a/apps/web/src/app/(landing)/status/[id]/report-issue.tsx +++ b/apps/web/src/app/(landing)/status/[id]/report-issue.tsx @@ -12,8 +12,7 @@ import { } from "@openstatus/ui/components/ui/select"; import { useState } from "react"; -import { api } from "@/trpc/rq-client"; - +import { api } from "../../../../trpc/rq-client"; import { buildSections } from "../external-service-components"; const WHOLE_SERVICE = "all"; diff --git a/apps/web/src/app/(landing)/status/[id]/service-components.tsx b/apps/web/src/app/(landing)/status/[id]/service-components.tsx index bbaf6a57..ff0fe13d 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-components.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-components.tsx @@ -1,7 +1,6 @@ "use client"; -import { api } from "@/trpc/rq-client"; - +import { api } from "../../../../trpc/rq-client"; import { ExternalServiceComponents } from "../external-service-components"; export function ServiceComponents({ diff --git a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx index 7a92deb7..4ca6c477 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx @@ -2,17 +2,16 @@ import { Suspense } from "react"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL } from "@/lib/metadata/shared-metadata"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { BASE_URL } from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDFAQPage, getJsonLDService, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; -import { api } from "@/trpc/rq-client"; - +} from "../../../../lib/metadata/structured-data"; +import { api } from "../../../../trpc/rq-client"; import { ExternalServicePill } from "../external-service-pill"; import { formatRelative, getStatusAnswer, isStale } from "../utils"; import { HistoryBars } from "./history-bars"; diff --git a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx index 96b5ea5d..b22c8150 100644 --- a/apps/web/src/app/(landing)/status/[id]/user-reports.tsx +++ b/apps/web/src/app/(landing)/status/[id]/user-reports.tsx @@ -9,7 +9,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Bar, BarChart, XAxis } from "recharts"; -import { api } from "@/trpc/rq-client"; +import { api } from "../../../../trpc/rq-client"; const chartConfig = { total: { label: "Reports", color: "var(--color-warning)" }, diff --git a/apps/web/src/app/(landing)/status/external-status-grid.tsx b/apps/web/src/app/(landing)/status/external-status-grid.tsx index 070b4dcb..0a4a74c0 100644 --- a/apps/web/src/app/(landing)/status/external-status-grid.tsx +++ b/apps/web/src/app/(landing)/status/external-status-grid.tsx @@ -3,9 +3,8 @@ import { useQueryState } from "nuqs"; import { useMemo } from "react"; -import { Grid } from "@/content/mdx-components/grid"; -import { api } from "@/trpc/rq-client"; - +import { Grid } from "../../../content/mdx-components/grid"; +import { api } from "../../../trpc/rq-client"; import { ContentBoxLink } from "../content-box"; import { ExternalServicePill } from "./external-service-pill"; import { filterServices } from "./filter-services"; diff --git a/apps/web/src/app/(landing)/status/page.tsx b/apps/web/src/app/(landing)/status/page.tsx index 61656351..ef16c8e0 100644 --- a/apps/web/src/app/(landing)/status/page.tsx +++ b/apps/web/src/app/(landing)/status/page.tsx @@ -1,17 +1,16 @@ import type { Metadata } from "next"; import { Suspense } from "react"; -import { ButtonLink } from "@/content/mdx-components/button-link"; -import { CustomLink } from "@/content/mdx-components/custom-link"; +import { ButtonLink } from "../../../content/mdx-components/button-link"; +import { CustomLink } from "../../../content/mdx-components/custom-link"; import { APP_URL, BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { HydrateClient, api } from "@/trpc/rq-server"; - +} from "../../../lib/metadata/shared-metadata"; +import { HydrateClient, api } from "../../../trpc/rq-server"; import { ContentBoxContainer, ContentBoxDescription, diff --git a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx index 55e79dc4..3a677a21 100644 --- a/apps/web/src/app/(landing)/tooling/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/tooling/[slug]/page.tsx @@ -1,10 +1,13 @@ import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getToolingPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getToolingPages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, @@ -12,7 +15,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; +} from "../../../../lib/metadata/structured-data"; export const dynamicParams = false; diff --git a/apps/web/src/app/(landing)/tooling/page.tsx b/apps/web/src/app/(landing)/tooling/page.tsx index 837eae5f..bd643023 100644 --- a/apps/web/src/app/(landing)/tooling/page.tsx +++ b/apps/web/src/app/(landing)/tooling/page.tsx @@ -1,21 +1,20 @@ import type { Metadata } from "next"; -import { components } from "@/content/mdx"; -import { getToolingPages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { components } from "../../../content/mdx"; +import { getToolingPages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentBoxDescription, ContentBoxLink, diff --git a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx index a7855b95..6d4cdcd6 100644 --- a/apps/web/src/app/(landing)/use-case/[slug]/page.tsx +++ b/apps/web/src/app/(landing)/use-case/[slug]/page.tsx @@ -2,10 +2,13 @@ import type { Metadata } from "next"; import Image from "next/image"; import { notFound } from "next/navigation"; -import { CustomMDX } from "@/content/mdx"; -import { getUseCasePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; -import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { CustomMDX } from "../../../../content/mdx"; +import { getUseCasePages } from "../../../../content/utils"; +import { JsonLd } from "../../../../lib/metadata/json-ld"; +import { + BASE_URL, + getPageMetadata, +} from "../../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBlogPosting, @@ -14,8 +17,7 @@ import { getJsonLDHowTo, getJsonLDOrganization, getJsonLDWebPage, -} from "@/lib/metadata/structured-data"; - +} from "../../../../lib/metadata/structured-data"; import { ContentMetadata } from "../../content-metadata"; import { ContentPagination } from "../../content-pagination"; diff --git a/apps/web/src/app/(landing)/use-case/page.tsx b/apps/web/src/app/(landing)/use-case/page.tsx index f298ea2c..d1e5b3ba 100644 --- a/apps/web/src/app/(landing)/use-case/page.tsx +++ b/apps/web/src/app/(landing)/use-case/page.tsx @@ -1,20 +1,19 @@ import type { Metadata } from "next"; -import { getUseCasePages } from "@/content/utils"; -import { JsonLd } from "@/lib/metadata/json-ld"; +import { getUseCasePages } from "../../../content/utils"; +import { JsonLd } from "../../../lib/metadata/json-ld"; import { BASE_URL, defaultMetadata, ogMetadata, -} from "@/lib/metadata/shared-metadata"; -import { twitterMetadata } from "@/lib/metadata/shared-metadata"; +} from "../../../lib/metadata/shared-metadata"; +import { twitterMetadata } from "../../../lib/metadata/shared-metadata"; import { createJsonLDGraph, getJsonLDBreadcrumbList, getJsonLDItemList, getJsonLDOrganization, -} from "@/lib/metadata/structured-data"; - +} from "../../../lib/metadata/structured-data"; import { ContentList } from "../content-list"; const TITLE = "Use Cases"; diff --git a/apps/web/src/app/api/checker/cron/_cron.ts b/apps/web/src/app/api/checker/cron/_cron.ts index d0385fa7..370077d6 100644 --- a/apps/web/src/app/api/checker/cron/_cron.ts +++ b/apps/web/src/app/api/checker/cron/_cron.ts @@ -22,7 +22,7 @@ import { import type { NextRequest } from "next/server"; import { z } from "zod"; -import { env } from "@/env"; +import { env } from "../../../../env"; const periodicityAvailable = selectMonitorSchema.pick({ periodicity: true }); diff --git a/apps/web/src/app/api/checker/test/http/route.ts b/apps/web/src/app/api/checker/test/http/route.ts index 5bf9f961..653c0c84 100644 --- a/apps/web/src/app/api/checker/test/http/route.ts +++ b/apps/web/src/app/api/checker/test/http/route.ts @@ -3,8 +3,7 @@ import { httpPayloadSchema } from "@openstatus/utils"; import { NextResponse } from "next/server"; import { z } from "zod"; -import { checkRegion } from "@/lib/checker/utils"; - +import { checkRegion } from "../../../../../lib/checker/utils"; import { isAnInvalidTestUrl } from "../../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/feedback/docs/route.ts b/apps/web/src/app/api/feedback/docs/route.ts index 1c0b313a..d99408b9 100644 --- a/apps/web/src/app/api/feedback/docs/route.ts +++ b/apps/web/src/app/api/feedback/docs/route.ts @@ -1,8 +1,8 @@ import { redis } from "@openstatus/upstash"; import { z } from "zod"; -import { getClientIP, ratelimit } from "@/lib/ratelimit"; -import { hashIP } from "@/lib/utils"; +import { getClientIP, ratelimit } from "../../../../lib/ratelimit"; +import { hashIP } from "../../../../lib/utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/markdown/[[...path]]/route.ts b/apps/web/src/app/api/markdown/[[...path]]/route.ts index 9a1f41ff..b7c456a3 100644 --- a/apps/web/src/app/api/markdown/[[...path]]/route.ts +++ b/apps/web/src/app/api/markdown/[[...path]]/route.ts @@ -1,11 +1,11 @@ import { type NextRequest, NextResponse } from "next/server"; -import { convertMdxToMarkdown } from "@/content/convert"; +import { convertMdxToMarkdown } from "../../../../content/convert"; import { generateStatusDetailMarkdown, generateStatusIndexMarkdown, -} from "@/content/status-markdown"; -import { resolveContent } from "@/content/utils/resolve"; +} from "../../../../content/status-markdown"; +import { resolveContent } from "../../../../content/utils/resolve"; export const runtime = "nodejs"; // Need fs access for content loading diff --git a/apps/web/src/app/api/og/_components/background.tsx b/apps/web/src/app/api/og/_components/background.tsx index 0405b09c..1db70723 100644 --- a/apps/web/src/app/api/og/_components/background.tsx +++ b/apps/web/src/app/api/og/_components/background.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../../../../lib/utils"; export function Background({ children, diff --git a/apps/web/src/app/api/og/_components/basic-layout.tsx b/apps/web/src/app/api/og/_components/basic-layout.tsx index 9ac36793..f8f59adf 100644 --- a/apps/web/src/app/api/og/_components/basic-layout.tsx +++ b/apps/web/src/app/api/og/_components/basic-layout.tsx @@ -1,5 +1,4 @@ -import { cn } from "@/lib/utils"; - +import { cn } from "../../../../lib/utils"; import { Background } from "./background"; export function BasicLayout({ diff --git a/apps/web/src/app/api/og/_components/status-check.tsx b/apps/web/src/app/api/og/_components/status-check.tsx index db63031e..19bf209c 100644 --- a/apps/web/src/app/api/og/_components/status-check.tsx +++ b/apps/web/src/app/api/og/_components/status-check.tsx @@ -1,6 +1,6 @@ import type { Tracker } from "@openstatus/tracker"; -import { cn } from "@/lib/utils"; +import { cn } from "../../../../lib/utils"; export function StatusCheck({ tracker }: { tracker: Tracker }) { const details = tracker.currentDetails; diff --git a/apps/web/src/app/api/og/_components/tracker.tsx b/apps/web/src/app/api/og/_components/tracker.tsx index d02580eb..86011967 100644 --- a/apps/web/src/app/api/og/_components/tracker.tsx +++ b/apps/web/src/app/api/og/_components/tracker.tsx @@ -1,7 +1,7 @@ import { Tracker as OSTracker, classNames } from "@openstatus/tracker"; -import type { ResponseStatusTracker } from "@/lib/tb"; -import { cn, formatDate } from "@/lib/utils"; +import type { ResponseStatusTracker } from "../../../../lib/tb"; +import { cn, formatDate } from "../../../../lib/utils"; interface TrackerProps { data: ResponseStatusTracker[]; diff --git a/apps/web/src/app/api/og/checker/route.tsx b/apps/web/src/app/api/og/checker/route.tsx index baeaf2a3..be80038a 100644 --- a/apps/web/src/app/api/og/checker/route.tsx +++ b/apps/web/src/app/api/og/checker/route.tsx @@ -4,9 +4,8 @@ import { getCheckerDataById, regionFormatter, timestampFormatter, -} from "@/lib/checker/utils"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/checker/utils"; +import { cn } from "../../../../lib/utils"; import { BasicLayout } from "../_components/basic-layout"; import { SIZE, diff --git a/apps/web/src/app/api/og/external-service/route.tsx b/apps/web/src/app/api/og/external-service/route.tsx index a2c1333e..6552526c 100644 --- a/apps/web/src/app/api/og/external-service/route.tsx +++ b/apps/web/src/app/api/og/external-service/route.tsx @@ -1,18 +1,17 @@ import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { isStale } from "@/app/(landing)/status/utils"; +import { isStale } from "../../../(landing)/status/utils"; import { getComponentEscalation, getServiceEscalation, -} from "@/lib/external-report-escalation"; +} from "../../../../lib/external-report-escalation"; import { cachedGetExternalComponentBySlug, cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; -import { cn } from "@/lib/utils"; - +} from "../../../../lib/external-service-cache"; +import { cn } from "../../../../lib/utils"; import { SIZE } from "../utils"; // nodejs (not edge): this route pulls in the service reads + Effect retry, which diff --git a/apps/web/src/app/api/og/monitor/route.tsx b/apps/web/src/app/api/og/monitor/route.tsx index 1fa453ed..788ab200 100644 --- a/apps/web/src/app/api/og/monitor/route.tsx +++ b/apps/web/src/app/api/og/monitor/route.tsx @@ -1,9 +1,8 @@ import { OSTinybird } from "@openstatus/tinybird"; import { ImageResponse } from "next/og"; -import { env } from "@/env"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; - +import { env } from "../../../../env"; +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; import { BasicLayout } from "../_components/basic-layout"; import { Tracker } from "../_components/tracker"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/page/route.tsx b/apps/web/src/app/api/og/page/route.tsx index 1ea61b35..72e8f733 100644 --- a/apps/web/src/app/api/og/page/route.tsx +++ b/apps/web/src/app/api/og/page/route.tsx @@ -1,9 +1,8 @@ import { Tracker } from "@openstatus/tracker"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; -import { api } from "@/trpc/server"; - +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; +import { api } from "../../../../trpc/server"; import { BasicLayout } from "../_components/basic-layout"; import { StatusCheck } from "../_components/status-check"; import { SIZE, calSemiBold, interLight, interRegular } from "../utils"; diff --git a/apps/web/src/app/api/og/post/route.tsx b/apps/web/src/app/api/og/post/route.tsx index 0413f82f..1f00b7b2 100644 --- a/apps/web/src/app/api/og/post/route.tsx +++ b/apps/web/src/app/api/og/post/route.tsx @@ -1,8 +1,7 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { TITLE } from "@/lib/metadata/shared-metadata"; - +import { TITLE } from "../../../../lib/metadata/shared-metadata"; import { BasicLayout } from "../_components/basic-layout"; import { DEFAULT_URL, diff --git a/apps/web/src/app/api/og/route.tsx b/apps/web/src/app/api/og/route.tsx index 73e77332..a84516f0 100644 --- a/apps/web/src/app/api/og/route.tsx +++ b/apps/web/src/app/api/og/route.tsx @@ -1,8 +1,7 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; -import { OG_DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; - +import { OG_DESCRIPTION, TITLE } from "../../../lib/metadata/shared-metadata"; import { SIZE } from "./utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/og/status/route.tsx b/apps/web/src/app/api/og/status/route.tsx index 988b2154..c7f2cfb3 100644 --- a/apps/web/src/app/api/og/status/route.tsx +++ b/apps/web/src/app/api/og/status/route.tsx @@ -2,10 +2,9 @@ import type { RouterOutputs } from "@openstatus/api"; import { format } from "date-fns"; import { ImageResponse } from "next/og"; -import { DESCRIPTION, TITLE } from "@/lib/metadata/shared-metadata"; -import { cn } from "@/lib/utils"; -import { api } from "@/trpc/server"; - +import { DESCRIPTION, TITLE } from "../../../../lib/metadata/shared-metadata"; +import { cn } from "../../../../lib/utils"; +import { api } from "../../../../trpc/server"; import { SIZE } from "../utils"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/search/route.ts b/apps/web/src/app/api/search/route.ts index c35f79bd..e9810d5d 100644 --- a/apps/web/src/app/api/search/route.ts +++ b/apps/web/src/app/api/search/route.ts @@ -1,7 +1,7 @@ import { z } from "zod"; -import { PAGE_TYPES } from "@/content/utils"; -import { searchCorpus } from "@/content/utils/search-index"; +import { PAGE_TYPES } from "../../../content/utils"; +import { searchCorpus } from "../../../content/utils/search-index"; const SearchSchema = z.object({ p: z.enum(PAGE_TYPES).nullish(), diff --git a/apps/web/src/app/api/test/timeout/route.ts b/apps/web/src/app/api/test/timeout/route.ts index 6513b15c..3e454a7e 100644 --- a/apps/web/src/app/api/test/timeout/route.ts +++ b/apps/web/src/app/api/test/timeout/route.ts @@ -1,6 +1,6 @@ import { NextResponse } from "next/server"; -import { wait } from "@/lib/utils"; +import { wait } from "../../../../lib/utils"; export async function POST() { await wait(10_000); diff --git a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts index 8ad8edf0..5a339780 100644 --- a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts @@ -3,7 +3,7 @@ import { edgeRouter } from "@openstatus/api/src/edge"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "@/trpc/shared"; +import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; export const runtime = "edge"; diff --git a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts index 175c51af..ddbd1dbb 100644 --- a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts @@ -3,7 +3,7 @@ import { lambdaRouter } from "@openstatus/api/src/lambda"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; -import { createOnError, guardTRPCSource } from "@/trpc/shared"; +import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; // Stripe is incompatible with Edge runtimes due to using Node.js events // export const runtime = "edge"; diff --git a/apps/web/src/app/api/webhook/stripe/route.ts b/apps/web/src/app/api/webhook/stripe/route.ts index 630ba246..992eae4d 100644 --- a/apps/web/src/app/api/webhook/stripe/route.ts +++ b/apps/web/src/app/api/webhook/stripe/route.ts @@ -4,7 +4,7 @@ import { TRPCError } from "@trpc/server"; import { getHTTPStatusCodeFromError } from "@trpc/server/http"; import type { NextRequest } from "next/server"; -import { env } from "@/env"; +import { env } from "../../../../env"; export async function POST(req: NextRequest) { const payload = await req.text(); diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index bab21c8c..cdd6ea15 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,4 +1,4 @@ -import "@/styles/globals.css"; +import "../styles/globals.css"; import { OpenPanelComponent } from "@openpanel/nextjs"; import { Toaster } from "@openstatus/ui/components/ui/sonner"; import type { Metadata } from "next"; @@ -8,15 +8,15 @@ import LocalFont from "next/font/local"; import Script from "next/script"; import { NuqsAdapter } from "nuqs/adapters/next/app"; -import { ThemeProvider } from "@/components/theme-provider"; -import { WebMcpProvider } from "@/components/webmcp-provider"; -import { env } from "@/env"; +import { ThemeProvider } from "../components/theme-provider"; +import { WebMcpProvider } from "../components/webmcp-provider"; +import { env } from "../env"; import { defaultMetadata, ogMetadata, twitterMetadata, -} from "@/lib/metadata/shared-metadata"; -import { TRPCReactQueryProvider } from "@/trpc/rq-client"; +} from "../lib/metadata/shared-metadata"; +import { TRPCReactQueryProvider } from "../trpc/rq-client"; const inter = Inter({ subsets: ["latin"], variable: "--font-sans" }); diff --git a/apps/web/src/app/not-found.tsx b/apps/web/src/app/not-found.tsx index 6902b4b5..3f52999e 100644 --- a/apps/web/src/app/not-found.tsx +++ b/apps/web/src/app/not-found.tsx @@ -1,5 +1,5 @@ -import { CustomMDX } from "@/content/mdx"; -import { getUnrelatedPage } from "@/content/utils"; +import { CustomMDX } from "../content/mdx"; +import { getUnrelatedPage } from "../content/utils"; export default function NotFound() { const page = getUnrelatedPage("not-found"); diff --git a/apps/web/src/app/sitemap.ts b/apps/web/src/app/sitemap.ts index 9d43f572..53efa8ac 100644 --- a/apps/web/src/app/sitemap.ts +++ b/apps/web/src/app/sitemap.ts @@ -13,11 +13,11 @@ import { getToolsPages, getUnrelatedPages, getUseCasePages, -} from "@/content/utils"; +} from "../content/utils"; import { cachedListExternalComponentsBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; +} from "../lib/external-service-cache"; export const revalidate = 3600; diff --git a/apps/web/src/components/dev-mode-container.tsx b/apps/web/src/components/dev-mode-container.tsx index 76eb3a55..41042767 100644 --- a/apps/web/src/components/dev-mode-container.tsx +++ b/apps/web/src/components/dev-mode-container.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export default function DevModeContainer({ children, diff --git a/apps/web/src/components/icon-cloud-provider.tsx b/apps/web/src/components/icon-cloud-provider.tsx index 14db64a1..c1e9d7a2 100644 --- a/apps/web/src/components/icon-cloud-provider.tsx +++ b/apps/web/src/components/icon-cloud-provider.tsx @@ -7,7 +7,7 @@ import { } from "@openstatus/ui/components/ui/tooltip"; import { Globe } from "lucide-react"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function IconCloudProvider({ provider, diff --git a/apps/web/src/components/loading-animation.tsx b/apps/web/src/components/loading-animation.tsx index 3142bfd3..f3fdc9e6 100644 --- a/apps/web/src/components/loading-animation.tsx +++ b/apps/web/src/components/loading-animation.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type { VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; const loadingVariants = cva( "direction-alternate animate-pulse rounded-full duration-700", diff --git a/apps/web/src/config/socials.ts b/apps/web/src/config/socials.ts index e97d2487..0287bde6 100644 --- a/apps/web/src/config/socials.ts +++ b/apps/web/src/config/socials.ts @@ -1,4 +1,4 @@ -import type { ValidIcon } from "@/components/icons"; +import type { ValidIcon } from "../components/icons"; export type Social = { title: string; diff --git a/apps/web/src/content/cmdk.tsx b/apps/web/src/content/cmdk.tsx index da40c8f8..dcd2579a 100644 --- a/apps/web/src/content/cmdk.tsx +++ b/apps/web/src/content/cmdk.tsx @@ -24,12 +24,8 @@ import { useTheme } from "next-themes"; import { useRouter } from "next/navigation"; import * as React from "react"; -import { - CORPUS_LABELS, - type Corpus, - type SearchResult, -} from "@/content/search-meta"; -import { buildHighlightRegex } from "@/content/utils/search-match"; +import { CORPUS_LABELS, type Corpus, type SearchResult } from "./search-meta"; +import { buildHighlightRegex } from "./utils/search-match"; type ConfigItem = { type: "item"; diff --git a/apps/web/src/content/docs-feedback.tsx b/apps/web/src/content/docs-feedback.tsx index c57310f8..b9cefb17 100644 --- a/apps/web/src/content/docs-feedback.tsx +++ b/apps/web/src/content/docs-feedback.tsx @@ -21,7 +21,7 @@ import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; -import { toastAction } from "@/lib/toast"; +import { toastAction } from "../lib/toast"; type Rating = "up" | "down"; diff --git a/apps/web/src/content/docs-footer.tsx b/apps/web/src/content/docs-footer.tsx index 6c3c564e..617c8a21 100644 --- a/apps/web/src/content/docs-footer.tsx +++ b/apps/web/src/content/docs-footer.tsx @@ -1,7 +1,6 @@ -import { Link } from "@/content/link"; -import { ThemeToggle } from "@/content/theme-toggle"; - import { FooterStatus } from "./footer-status"; +import { Link } from "./link"; +import { ThemeToggle } from "./theme-toggle"; export function DocsFooter() { return ( diff --git a/apps/web/src/content/docs-sidebar.tsx b/apps/web/src/content/docs-sidebar.tsx index a1c8381a..8b7546c2 100644 --- a/apps/web/src/content/docs-sidebar.tsx +++ b/apps/web/src/content/docs-sidebar.tsx @@ -12,8 +12,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { type DocsNavGroup, type DocsNavItem, diff --git a/apps/web/src/content/docs-sub-nav.tsx b/apps/web/src/content/docs-sub-nav.tsx index 7d50c8ac..7a939409 100644 --- a/apps/web/src/content/docs-sub-nav.tsx +++ b/apps/web/src/content/docs-sub-nav.tsx @@ -4,8 +4,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { CopyDropdownButton } from "./copy-button"; export function DocsSubNav({ diff --git a/apps/web/src/content/docs-toc.tsx b/apps/web/src/content/docs-toc.tsx index d83a02ac..f9a4642f 100644 --- a/apps/web/src/content/docs-toc.tsx +++ b/apps/web/src/content/docs-toc.tsx @@ -2,8 +2,7 @@ import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import type { TocItem } from "./toc"; function useActiveHeading(items: TocItem[]) { diff --git a/apps/web/src/content/footer-status.tsx b/apps/web/src/content/footer-status.tsx index 95e024da..ea8e43fd 100644 --- a/apps/web/src/content/footer-status.tsx +++ b/apps/web/src/content/footer-status.tsx @@ -4,7 +4,7 @@ import type { StatusResponse } from "@openstatus/react"; import { useQuery } from "@tanstack/react-query"; import Link from "next/link"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function FooterStatus() { const { data } = useQuery({ diff --git a/apps/web/src/content/footer.tsx b/apps/web/src/content/footer.tsx index 1045e551..406d1694 100644 --- a/apps/web/src/content/footer.tsx +++ b/apps/web/src/content/footer.tsx @@ -1,8 +1,7 @@ -import { Link } from "@/content/link"; -import { ThemeToggle } from "@/content/theme-toggle"; -import { footerLinks } from "@/data/content"; - +import { footerLinks } from "../data/content"; import { FooterStatus } from "./footer-status"; +import { Link } from "./link"; +import { ThemeToggle } from "./theme-toggle"; export function Footer() { return ( diff --git a/apps/web/src/content/header.tsx b/apps/web/src/content/header.tsx index 38c6a890..00389e7a 100644 --- a/apps/web/src/content/header.tsx +++ b/apps/web/src/content/header.tsx @@ -6,8 +6,7 @@ import { } from "@openstatus/ui/components/ui/dropdown-menu"; import Link from "next/link"; -import { headerLinks } from "@/data/content"; - +import { headerLinks } from "../data/content"; import { CmdK } from "./cmdk"; import { LogoWithContextMenu } from "./logo-with-context-menu"; diff --git a/apps/web/src/content/highlight-text.tsx b/apps/web/src/content/highlight-text.tsx index d3a5e5a6..0a22adf1 100644 --- a/apps/web/src/content/highlight-text.tsx +++ b/apps/web/src/content/highlight-text.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "next/navigation"; import { useEffect, useRef } from "react"; -import { buildHighlightRegex } from "@/content/utils/search-match"; +import { buildHighlightRegex } from "./utils/search-match"; function escapeHtml(input: string) { return input.replace(/[&<>]/g, (c) => diff --git a/apps/web/src/content/image-zoom.tsx b/apps/web/src/content/image-zoom.tsx index fa59e93b..93dc4288 100644 --- a/apps/web/src/content/image-zoom.tsx +++ b/apps/web/src/content/image-zoom.tsx @@ -9,7 +9,7 @@ import Zoom, { type UncontrolledProps, } from "react-medium-image-zoom"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export type ImageZoomProps = UncontrolledProps & { isZoomed?: ControlledProps["isZoomed"]; diff --git a/apps/web/src/content/latency-chart-table.tsx b/apps/web/src/content/latency-chart-table.tsx index bce59b84..3a7e5cc8 100644 --- a/apps/web/src/content/latency-chart-table.tsx +++ b/apps/web/src/content/latency-chart-table.tsx @@ -2,8 +2,7 @@ import fs from "node:fs"; import { type Region, regionDict } from "@openstatus/regions"; -import type { RegionMetricsChartTable } from "@/data/content"; - +import type { RegionMetricsChartTable } from "../data/content"; import { SimpleChart } from "./simple-chart"; export interface LatencyChartTableProps { diff --git a/apps/web/src/content/link.tsx b/apps/web/src/content/link.tsx index 9043ae77..9b928a9d 100644 --- a/apps/web/src/content/link.tsx +++ b/apps/web/src/content/link.tsx @@ -1,6 +1,6 @@ import NextLink from "next/link"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; // TODO: we could add cva variants for the link diff --git a/apps/web/src/content/mdx-components/aside.tsx b/apps/web/src/content/mdx-components/aside.tsx index c23385c2..863c9829 100644 --- a/apps/web/src/content/mdx-components/aside.tsx +++ b/apps/web/src/content/mdx-components/aside.tsx @@ -1,7 +1,7 @@ import { cva } from "class-variance-authority"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; type AsideType = "note" | "tip" | "caution" | "danger"; diff --git a/apps/web/src/content/mdx-components/card.tsx b/apps/web/src/content/mdx-components/card.tsx index 8a692833..336c1ea6 100644 --- a/apps/web/src/content/mdx-components/card.tsx +++ b/apps/web/src/content/mdx-components/card.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function CardGrid({ children }: { children: React.ReactNode }) { return
    {children}
    ; diff --git a/apps/web/src/content/mdx-components/custom-image.tsx b/apps/web/src/content/mdx-components/custom-image.tsx index e7b12e80..a7087a2c 100644 --- a/apps/web/src/content/mdx-components/custom-image.tsx +++ b/apps/web/src/content/mdx-components/custom-image.tsx @@ -3,9 +3,8 @@ import { join } from "node:path"; import Image from "next/image"; -import { getImageDimensions } from "@/lib/image-dimensions"; -import { cn } from "@/lib/utils"; - +import { getImageDimensions } from "../../lib/image-dimensions"; +import { cn } from "../../lib/utils"; import { ImageZoom, ZoomableImage } from "../image-zoom"; type CustomImageProps = React.ComponentProps & { diff --git a/apps/web/src/content/mdx-components/grid.tsx b/apps/web/src/content/mdx-components/grid.tsx index d637228c..82afd5ab 100644 --- a/apps/web/src/content/mdx-components/grid.tsx +++ b/apps/web/src/content/mdx-components/grid.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function Grid({ cols = 2, diff --git a/apps/web/src/content/mdx-components/subtle.tsx b/apps/web/src/content/mdx-components/subtle.tsx index 423f2e9e..4b1adeea 100644 --- a/apps/web/src/content/mdx-components/subtle.tsx +++ b/apps/web/src/content/mdx-components/subtle.tsx @@ -1,6 +1,6 @@ import type React from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../../lib/utils"; export function Subtle({ className, ...props }: React.ComponentProps<"span">) { return ; diff --git a/apps/web/src/content/simple-chart.tsx b/apps/web/src/content/simple-chart.tsx index 87be846d..e7869a77 100644 --- a/apps/web/src/content/simple-chart.tsx +++ b/apps/web/src/content/simple-chart.tsx @@ -8,7 +8,7 @@ import { } from "@openstatus/ui/components/ui/chart"; import { Line, LineChart, XAxis } from "recharts"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; const chartConfig = { latency: { diff --git a/apps/web/src/content/status-markdown.ts b/apps/web/src/content/status-markdown.ts index caf43d5d..fa79587e 100644 --- a/apps/web/src/content/status-markdown.ts +++ b/apps/web/src/content/status-markdown.ts @@ -10,11 +10,11 @@ import { } from "@openstatus/services/external-service-report"; import { OSTinybird, safePipeData } from "@openstatus/tinybird"; -import { env } from "@/env"; +import { env } from "../env"; import { cachedGetExternalServiceBySlug, cachedListExternalServices, -} from "@/lib/external-service-cache"; +} from "../lib/external-service-cache"; type LatestRow = { id: string; diff --git a/apps/web/src/content/sub-nav.tsx b/apps/web/src/content/sub-nav.tsx index 50ea6fe1..81e4e1c1 100644 --- a/apps/web/src/content/sub-nav.tsx +++ b/apps/web/src/content/sub-nav.tsx @@ -4,8 +4,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { Fragment } from "react"; -import { cn } from "@/lib/utils"; - +import { cn } from "../lib/utils"; import { CopyDropdownButton } from "./copy-button"; export function SubNav({ className, ...props }: React.ComponentProps<"div">) { diff --git a/apps/web/src/content/theme-toggle.tsx b/apps/web/src/content/theme-toggle.tsx index 45064ca7..a39e1028 100644 --- a/apps/web/src/content/theme-toggle.tsx +++ b/apps/web/src/content/theme-toggle.tsx @@ -5,7 +5,7 @@ import { useTheme } from "next-themes"; import type * as React from "react"; import { useEffect, useState } from "react"; -import { cn } from "@/lib/utils"; +import { cn } from "../lib/utils"; export function ThemeToggle({ className, diff --git a/apps/web/src/content/utils/search-index.ts b/apps/web/src/content/utils/search-index.ts index 357bc83e..1f3fe251 100644 --- a/apps/web/src/content/utils/search-index.ts +++ b/apps/web/src/content/utils/search-index.ts @@ -1,7 +1,6 @@ import "server-only"; -import { slugify } from "@/content/mdx"; - import { type MDXData, PAGE_TYPES, getHomePage, getPages } from "."; +import { slugify } from "../mdx"; import type { Corpus, SearchResult } from "../search-meta"; import { closestHeadingSlug, diff --git a/apps/web/src/content/utils/search-match.test.ts b/apps/web/src/content/utils/search-match.test.ts index 15e92226..827ca8e9 100644 --- a/apps/web/src/content/utils/search-match.test.ts +++ b/apps/web/src/content/utils/search-match.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { WEIGHTS, diff --git a/apps/web/src/data/content.ts b/apps/web/src/data/content.ts index a80c48be..7cf726ad 100644 --- a/apps/web/src/data/content.ts +++ b/apps/web/src/data/content.ts @@ -7,7 +7,7 @@ import { getToolingPages, getToolsPages, getUseCasePages, -} from "@/content/utils"; +} from "../content/utils"; const products = getProductPages(); diff --git a/apps/web/src/data/trigger-dictionary.ts b/apps/web/src/data/trigger-dictionary.ts index 2b4703b2..06cbc4f5 100644 --- a/apps/web/src/data/trigger-dictionary.ts +++ b/apps/web/src/data/trigger-dictionary.ts @@ -1,5 +1,5 @@ -import type { ValidIcon } from "@/components/icons"; -import type { Trigger } from "@/lib/monitor/utils"; +import type { ValidIcon } from "../components/icons"; +import type { Trigger } from "../lib/monitor/utils"; export const triggerDict = { cron: { diff --git a/apps/web/src/lib/checker/mock.ts b/apps/web/src/lib/checker/mock.ts index ce20f05d..cdc60e49 100644 --- a/apps/web/src/lib/checker/mock.ts +++ b/apps/web/src/lib/checker/mock.ts @@ -1,7 +1,7 @@ import type { Region } from "@openstatus/db/src/schema/constants"; -import { type RegionChecker, cachedCheckerSchema } from "@/lib/checker/utils"; -import { wait } from "@/lib/utils"; +import { wait } from "../utils"; +import { type RegionChecker, cachedCheckerSchema } from "./utils"; export async function mockCheckRegion(region: Region) { const response = data.checks diff --git a/apps/web/src/lib/external-report-escalation.ts b/apps/web/src/lib/external-report-escalation.ts index be7f9de6..c9145002 100644 --- a/apps/web/src/lib/external-report-escalation.ts +++ b/apps/web/src/lib/external-report-escalation.ts @@ -10,7 +10,7 @@ import { import { OSTinybird, safePipeData } from "@openstatus/tinybird"; import { unstable_cache } from "next/cache"; -import { env } from "@/env"; +import { env } from "../env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/web/src/lib/mcp/health-check.test.ts b/apps/web/src/lib/mcp/health-check.test.ts index 1eac8d99..760265b6 100644 --- a/apps/web/src/lib/mcp/health-check.test.ts +++ b/apps/web/src/lib/mcp/health-check.test.ts @@ -1,4 +1,5 @@ -import { afterEach, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { normalizeUrlForStorage, diff --git a/apps/web/src/lib/metadata/shared-metadata.ts b/apps/web/src/lib/metadata/shared-metadata.ts index db9d7981..68e9a67b 100644 --- a/apps/web/src/lib/metadata/shared-metadata.ts +++ b/apps/web/src/lib/metadata/shared-metadata.ts @@ -1,6 +1,6 @@ import type { Metadata } from "next"; -import type { MDXData } from "@/content/utils"; +import type { MDXData } from "../../content/utils"; export const TITLE = "openstatus"; export const HOMEPAGE_TITLE = "The Compliance-First Status Page"; diff --git a/apps/web/src/lib/metadata/structured-data.ts b/apps/web/src/lib/metadata/structured-data.ts index 36a29602..d7f7fb38 100644 --- a/apps/web/src/lib/metadata/structured-data.ts +++ b/apps/web/src/lib/metadata/structured-data.ts @@ -19,8 +19,7 @@ import type { WithContext, } from "schema-dts"; -import type { MDXData } from "@/content/utils"; - +import type { MDXData } from "../../content/utils"; import { BASE_URL } from "./shared-metadata"; export const getJsonLDWebPage = ( diff --git a/apps/web/src/lib/stripe/client.ts b/apps/web/src/lib/stripe/client.ts index 50e71374..8e64d21e 100644 --- a/apps/web/src/lib/stripe/client.ts +++ b/apps/web/src/lib/stripe/client.ts @@ -1,7 +1,7 @@ import type { Stripe as StripeProps } from "@stripe/stripe-js"; import { loadStripe } from "@stripe/stripe-js"; -import { env } from "@/env"; +import { env } from "../../env"; let stripePromise: Promise; diff --git a/apps/web/src/lib/tb.ts b/apps/web/src/lib/tb.ts index 371c5e02..fc16ba37 100644 --- a/apps/web/src/lib/tb.ts +++ b/apps/web/src/lib/tb.ts @@ -1,6 +1,6 @@ import { OSTinybird } from "@openstatus/tinybird"; -import { env } from "@/env"; +import { env } from "../env"; const tb = new OSTinybird(env.TINY_BIRD_API_KEY); diff --git a/apps/workflows/.gitignore b/apps/workflows/.gitignore index 506e4c37..e4037038 100644 --- a/apps/workflows/.gitignore +++ b/apps/workflows/.gitignore @@ -1,2 +1,6 @@ # deps node_modules/ + +# build artifacts / local dev db +app +dev.db* diff --git a/apps/workflows/Dockerfile b/apps/workflows/Dockerfile index 42ee8271..7da4a413 100644 --- a/apps/workflows/Dockerfile +++ b/apps/workflows/Dockerfile @@ -2,21 +2,10 @@ # This file is generated by Dofigen v2.8.0 # See https://github.com/lenra-io/dofigen -# docker -FROM oven/bun@sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 AS docker -LABEL \ - org.opencontainers.image.base.digest="sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7" \ - org.opencontainers.image.base.name="docker.io/oven/bun:1.3.11" -WORKDIR /app/apps/workflows -COPY \ - --link \ - "." "/app/" -RUN bun run src/build-docker.ts - # install -FROM node@sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf AS install +FROM node@sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc AS install LABEL \ - org.opencontainers.image.base.digest="sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf" \ + org.opencontainers.image.base.digest="sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc" \ org.opencontainers.image.base.name="docker.io/node:24-slim" \ org.opencontainers.image.stage="install" WORKDIR /app/ @@ -56,14 +45,14 @@ RUN \ --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ <{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' +cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts +cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts +cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs +mkdir -p /app/data +EOF # runtime -FROM debian@sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 AS runtime +FROM registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 AS runtime LABEL \ io.dofigen.version="2.8.0" \ org.opencontainers.image.authors="OpenStatus Team" \ - org.opencontainers.image.base.digest="sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604" \ - org.opencontainers.image.base.name="docker.io/debian:bullseye-slim" \ + org.opencontainers.image.base.digest="sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4" \ org.opencontainers.image.description="Background job processing and probe scheduling for OpenStatus" \ org.opencontainers.image.source="https://github.com/openstatusHQ/openstatus" \ org.opencontainers.image.title="OpenStatus Workflows" \ @@ -115,17 +98,16 @@ COPY \ --link \ "/app/apps/workflows/app" "/app/apps/workflows/" COPY \ - --from=libsql \ - --chown=1000:1000 \ - --link \ - "/app/node_modules" "/app/packages/db/node_modules" -COPY \ - --from=libsql \ + --from=build \ --chown=1000:1000 \ --link \ - "/app/node_modules" "/app/node_modules" -USER 0:0 -RUN apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data + "/app/data" "/app/data" USER 1000:1000 EXPOSE 3000 +HEALTHCHECK \ + --interval=1m \ + --timeout=10s \ + --start-period=30s \ + --retries=3 \ + CMD ["curl", "-f", "http://localhost:3000/ping"] ENTRYPOINT ["/app/apps/workflows/app"] diff --git a/apps/workflows/deno-migration-plan.md b/apps/workflows/deno-migration-plan.md new file mode 100644 index 00000000..2b7b2f0f --- /dev/null +++ b/apps/workflows/deno-migration-plan.md @@ -0,0 +1,437 @@ +# Plan: migrate `apps/server` + `apps/workflows` from bun to Deno 2.9 + +Goal: remove **bun** from the project. Three pillars, shipped as **one big-bang PR**: + +1. **Build** — `bun build --compile` → `deno compile` (server + workflows). +2. **Install** — the Docker `pnpm install` stage → `deno install` (server + workflows). +3. **Tests** — `bun:test` → **`node:test` runner + `@std/expect`**, run via **`deno test`**, + across **all ~270 test files** (12 packages + apps server, workflows, web, status-page). + +The other apps (`web`, `dashboard`, `status-page`, `docs`, `screenshot-service`) keep +**pnpm** for install + their existing builds; their only bun usage was `bun test`, removed by +pillar 3. `pnpm` remains the local-dev + non-migrated-app package manager. + +--- + +## Agreed decisions (the design) + +| # | Area | Decision | +|---|------|----------| +| 1 | Test scope | All ~270 `bun:test` files (12 packages + server/workflows/web/status-page) | +| 2 | Rollout | One big-bang PR, guarded by a baseline test-count parity gate (#16) | +| 3 | Entrypoint | **Split**: `index.ts` exports `app`; new `serve.ts` calls `Deno.serve`, is the compile target | +| 4 | Assertions | Keep Jest-style `expect` via **`@std/expect`** | +| 5 | Mocks | **`@std/testing/mock`** (`spy`/`stub`, `using`) + **`@std/testing/time`** (`FakeTime`) | +| 6 | `mock.module` | **Hybrid**: `stub` the reachable seams; **default-param DI** for the rest; delete dead ones | +| 7 | Test infra | New **`@openstatus/test-utils`** package: matchers (`expect.extend`), setup, shared fakes | +| 8 | DI style | **Default-parameter injection** for `dispatch*` / `getChannel` | +| 9 | Snapshots / type tests | `@std/testing/snapshot` / `expect-type` | +| 10 | Typecheck | Replace `tsc` with **`deno check`**, scoped to `apps/server` + `apps/workflows` (src + tests) | +| 11 | Permissions | `-A` for `deno test` and `deno compile` now; tighten the binary in a follow-up | +| 12 | Docker install | `deno install --prod --frozen --allow-scripts`, hoisted node_modules; `pnpm-workspace.yaml` stays authoritative; commit `deno.lock` only | +| 13 | CI install | CI test/migrate jobs **keep `pnpm install`**; `deno install` is exercised by the docker-publish build | +| 14 | CI test orchestration | Keep **turbo**; each package `"test": "deno test -A"`; swap `setup-bun` → `setup-deno` | +| 15 | Integration tests | Stay in the same `deno test -A` run, against the CI libsql service (as today) | +| 16 | Safety net | Record base-commit `bun test` pass count; assert `deno test` count ≥ it (fail CI on drop) | +| 17 | Other apps | Stay on pnpm install + existing build | +| 18 | Codemod | `ts-morph`/`jscodeshift` for the mechanical rewrite; hand-fix the ~60-file residue | + +--- + +## Resolved by codebase exploration (facts, not assumptions) + +- **Entrypoint must split** — tests do `import { app } from "@/index"`; a top-level + `Deno.serve` in `index.ts` would boot a server on every test import. +- **Server needs no libsql side-car** — `packages/db` uses `drizzle-orm/libsql/http` (pure + HTTP). Only `apps/workflows/src/lib/db.ts` uses the native `@libsql/client` embedded replica + → native-addon compile risk is **workflows-only**. +- **Tests are integration tests against a real libSQL DB** — CI runs a `libsql-server` + service + migrate + seed. The preload mocks only Tinybird/Redis/subscriptions; DB is real. +- **Step D seams are mixed**: `@/libs/clients` (`tb`/`redis` singletons) + `Redis.fromEnv` + are stub-able; `@openstatus/subscriptions` `dispatch*` + `getChannel` are destructured live + bindings called directly → need DI. +- **`node-fetch` mock is dead** — the SUT uses **global `fetch`**; tests set + `global.fetch = mockFetch` (the effective line) plus a redundant `mock.module("node-fetch")` + (not a dependency). → `stub(globalThis, "fetch", …)` and delete the `mock.module` line. +- **`start.sh` is unused by Fly** (entrypoint is the binary; compose `command` commented) — + prod migrations run via CI `migrate.yml`. We keep `start.sh` anyway and port its command. +- **migrate/seed have no `Bun.*`** — `packages/db/src/migrate.mts` + `seed.mts` use only + `@libsql/client`/drizzle/`process` → run under `deno run -A` unchanged. +- **`Bun.*` lives only in dev/build scripts** — `packages/db/env.ts`, `apps/server/env.ts`, + `apps/workflows/src/build-docker.ts` (`Bun.file`/`Bun.write`). +- **web/status-page tests are pure logic/util** — no DOM/`@testing-library`/React rendering; + run under `deno test` with no jsdom. +- **Only `apps/server` runs `tsc`** today (`tsc --noEmit`, `types: ["bun-types"]`). + +--- + +## Phase 0 — Spikes (gate the big-bang) — ✅ DONE (1,2) / deferred (3,4) + +Toolchain confirmed: **deno 2.9.0**, bun 1.3.11, pnpm 11.2.1, node 24, dofigen 2.8.0. + +1. ✅ **`Deno.serve` + Hono compile/serve.** Compiled, served, `/ping`→200, embedded asset + read via `Deno.readTextFile(new URL(...))`. **Correction: the flag is `--include`, not + `--include-as-is`** (the latter does not exist in 2.9). +2. ✅ **libSQL native addon under `deno compile` — make-or-break, PASSED with a bonus.** + `deno compile` **embeds the native addon into the binary** (10.7MB) and the binary runs from + a clean dir with **no node_modules**. **Consequence: the workflows `docker` + `libsql` + side-car stages are no longer needed** (they existed only because `bun build --compile` + could not embed native addons). One caveat for the real monorepo build: `--node-modules-dir=manual` + against the giant shared `node_modules` hangs (tries to embed everything) — use deno's + managed npm resolution / `--exclude-unused-npm` so only reachable packages embed. Final flag + combo to be settled in Phase 5 against the real Docker build. +3. ⏳ **Test stack interop** — validated at the start of Phase 2 by migrating one real route + test (faster than a synthetic spike): `@std/expect` matchers, `toHaveBeenCalled*` vs + `@std/testing/mock` spies (else `assertSpyCalls`), `expect.extend`, `stub` on `tb` getters + + `globalThis.fetch`, `FakeTime`. +4. ⏳ **`deno install` on the repo** — done carefully in Phase 3 (it may rewrite manifests and + re-layout `node_modules`, which would disrupt the in-progress pnpm-based work), in an + isolated copy first. + +--- + +## ✅ RESOLVED — deep workspace imports: exports maps + sloppy (no deno.json) + +**Solution (verified under `deno run` + `deno compile` + bun):** add an `exports` map to the +4 deep-imported packages (`@openstatus/db`, `@openstatus/api`, `@openstatus/emails`, +`@openstatus/tracker`) and pass `--unstable-sloppy-imports` on every deno command. The exports +map crosses the package boundary (sloppy can't); sloppy resolves the relative extensionless +imports inside packages. **No deno.json. 4 package.json touched, not 512 imports.** + +Exports map shape (per package), covering the 36 distinct targets (29 files, 7 dirs all in db): + +```jsonc +"exports": { + ".": "./src/index.ts", + "./env.mjs": "./env.mjs", // db only (non-src deep import) + "./src/schema": "./src/schema/index.ts", // + the 6 other directory targets + "./src/client": "./src/client.tsx", // .tsx files need explicit entries + "./src/*": "./src/*.ts" // wildcard handles the .ts files +} +``` + +Every deno invocation (`test`/`compile`/`check`/`run`) must include `--unstable-sloppy-imports`. + +### Original investigation (kept for context) + +The codebase has **512 bare deep-subpath imports across 400 files** of the form +`@openstatus/db/src/schema/constants` (also `@openstatus/api/src/*`, `@openstatus/emails/src/*`, +`@openstatus/tracker/src/*`). Targets are a **mix of `.ts` files, `.tsx` files, and directories** +(`@openstatus/db/src/schema` is a dir with `index.ts`). Verified facts (Deno 2.9.0 experiments): + +- **`--unstable-sloppy-imports` resolves *relative* extensionless imports** (incl. dir-index and + `.tsx`) for `deno run`/`compile`/`test`. ✅ +- It does **NOT** resolve **bare cross-package** deep subpaths — those go through node_modules + package resolution where sloppy does not apply. Fails for run/compile/test (works only for the + lenient `deno check` TS resolver). ❌ — true even in Deno workspace mode (`deno install`). +- **Explicit extension** (`@openstatus/db/src/schema/constants.ts`) resolves under both Deno and + bun — but directory imports still need `/index.ts`, and it risks the Next.js apps (turbopack/tsc). +- **`exports` map** with a `./src/*` wildcard handles `.ts` files but **not** the mixed + dir/`.tsx` cases reliably (Deno does not fall through exports fallback arrays on a missing file). +- **deno.json import map** prefix (`"@openstatus/db/src/": "./packages/db/src/"`) + sloppy + **resolves ALL cases** (file `.ts`/`.tsx` + dir-index) for run **and** compile. ✅ — but it is a + `deno.json`, which the user asked to avoid. + +**This is a hard fork:** the only clean, complete fix is a 4-entry `deno.json` import map, which +collides with the "no deno.json" preference ([[feedback-no-deno-json]]). Awaiting a decision (see +chat) before proceeding with Phase 2+. Everything below assumes that decision is made. + +## Implementation findings (verified during execution) + +- **`@/*` tsconfig path alias** — Deno doesn't read tsconfig `paths`. 153 `@/…` imports across + 113 files in `apps/server` rewritten to **relative paths** (codemod). workflows uses none. ✅ +- **`deno install` foundation** — works, with one workaround: it **crashes seeding `deno.lock` + from `pnpm-lock.yaml`** on a pnpm alias (`string-width-cjs@string-width@4.2.3`). Fix: move + `pnpm-lock.yaml` aside during `deno install` so Deno resolves fresh, then restore it. Deno + migrates the **catalog into root `package.json`** (not deno.json) and writes `deno.lock`. + After install, the full server graph resolves (deep imports + `zod` + `hono`). ✅ +- **`@std/expect` `toHaveBeenCalled*` does NOT accept `@std/testing/mock` spies** (verified: + "Received function must be a mock or spy function"). → the ~187 `toHaveBeenCalled*` sites must + use **`assertSpyCalls`/`assertSpyCall`** instead. Basic `expect`, `expect.extend` custom + matchers, and `FakeTime` all work. ⚠ (more test rework than planned) +- **✅ `deno compile` of `apps/server` WORKS in a clean Docker container** — the local 12-min + hang was the **polluted local node_modules** (Deno-managed mix + broken `.next` symlinks + + every app's deps). In Docker with a **scoped `pnpm install --filter @openstatus/server...`** + (20.8s) then `deno compile --node-modules-dir=manual`, the binary builds fast and **runs**: + `/ping`→200, `/openapi.yaml`→embedded asset, full app graph boots ("Listening on :3000"). + - **Winning build recipe** (`apps/server/Dockerfile.deno-test`): node:24-slim → `pnpm install + --prod --frozen-lockfile --filter @openstatus/server...` → denoland/deno:2.9.0 → `deno + compile -A --no-check --unstable-sloppy-imports --node-modules-dir=manual --include + static/openapi.yaml --include static/openapi-v1.json --output app src/serve.ts` → debian + runtime with just the binary. + - **No `deno install`** in the build — pnpm install (scoped) is what produces node_modules; + Deno reads the catalog from root `package.json` (migrated once) + consumes pnpm's layout. + This sidesteps `deno install`'s whole-monorepo install + the pnpm-alias lockfile crash. + - Catalog must be present in root `package.json` for Deno to resolve `catalog:` specifiers. + - Sandbox note: needed `docker build --network=host` here (flaky build-network); normal CI ok. + - Image 495MB (debian + binary). Could slim further later. +- **✅ `apps/workflows` also builds in Docker** (same recipe, `--filter @openstatus/workflows...`, + 465MB) and **embeds the libSQL native addon** (no side-car). Verified the binary executes (it + reaches the embedded-replica `createClient` and opens the sync connection). Full boot needs a + real Turso `DATABASE_URL` — in the sandbox it blocks in SYN_SENT to an unreachable sync URL at + module load (the `createClient` runs before logging, so no logs appear). Not a build defect. +- **⚠ `@sentry/bun` → `@sentry/deno`** — workflows used `@sentry/bun` (bun-only; hangs under + Deno) in `index.ts`, `lib/sentry.ts`, `cron/index.ts`. Swapped all three to `@sentry/deno` + (`10.61.0`, API-compatible: `init`/`captureException`/`captureMessage`/`captureCheckIn`/`flush`), + updated `package.json` + `pnpm-lock.yaml`. The server uses `@hono/sentry` (unaffected). +- **⚠ embedded-replica `createClient` blocks at module load** until the sync URL connects — so + the workflows process won't serve `/ping` until the DB is reachable. Pre-existing behavior + (bun did the same); flagged for prod startup robustness. + +## Phase 2 — Test migration — 🔶 IN PROGRESS + +- ✅ `@openstatus/test-utils` package built + validated: re-exports `node:test` runner with a + Bun-compat **`.each`** shim, `@std/expect` `expect` extended with the ~12 **bun-only matchers** + (`toBeNumber`, `toContainValue`, …), and `@std/testing/mock` (`spy`/`stub`/`assertSpyCalls`) + + `@std/testing/time` (`FakeTime`). Uses `jsr:@std/*` so only Deno needs them. +- ✅ Codemod swapped `bun:test` → `@openstatus/test-utils` in **194 files**; updated 21+ + `package.json` (`deno test` script, test-utils devDep, dropped `@types/bun`/`bun-types`); + removed `bunfig.toml`. +- ✅ **`@/*` alias → relative** rewrite: server (153), status-page (211), web (332). Deno + ignores tsconfig paths. +- ✅ **Import-only suites PASS under `deno test`**: header-analysis (7), status-page (51), web + (23). Mock pattern validated: discord + 5 more notifications PASS. +- 🔶 **Remaining mock work (~47 files)**: `@std/expect` `toHaveBeenCalled*` does NOT accept std + spies → use `assertSpyCalls`. Per-file quirks remain: 6 notifications (webhook double-stub, + bird-whatsapp `jest`, slack/grafana call-count-after-restub), importers clients, status-fetcher, + tracker (`FakeTime`), subscriptions/api/server (**`mock.module` → stub + default-param DI**, + and these are **DB-integration tests needing a running libSQL to verify**). +- ⏳ snapshots (`toMatchSnapshot` → `@std/testing/snapshot`) + type tests (`expectTypeOf` → + `expect-type`) not started. + +## Phase 1 — Source changes — ✅ DONE + +- ✅ split `index.ts`/`serve.ts` (both apps); server static asset → `Deno.readTextFile`. +- ✅ `Bun.*` → `Deno.copyFile` in `apps/server/env.ts`, `packages/db/env.ts`. +- ✅ `migrate`/`seed`/`env` scripts + `start.sh` → `deno run -A`; app `dev`/`start`/`test` → deno. + +(Detail of the changes below.) + +### Entrypoint split (both apps) + +`index.ts`: keep `export const app = new Hono(...)`, **remove** `const server = {...}` + +`export default server`. New `serve.ts`: + +```ts +import { app } from "./index"; +import { env } from "./env"; +Deno.serve({ port: env.PORT ?? 3000 }, app.fetch); +``` + +`serve.ts` is the `deno compile` target. Tests still import `app` with no server side-effect. + +### Server static asset (`apps/server/src/index.ts:22`) + +Drop `import openapiYaml … with { type: "text" }`. Embed via `--include-as-is` (Phase 4) and +read at startup: + +```ts +const openapiYaml = await Deno.readTextFile(new URL("../static/openapi.yaml", import.meta.url)); +``` + +JSON imports (`with { type: "json" }`) stay — Deno supports them. + +### `Bun.*` → Deno APIs (dev/build scripts) + +`packages/db/env.ts`, `apps/server/env.ts`: `Bun.file(p).text()/.json()` → +`Deno.readTextFile(p)` (+ `JSON.parse`); `Bun.write(p, s)` → `Deno.writeTextFile(p, s)`. +(`apps/workflows/src/build-docker.ts` is deleted in Phase 5 — no port needed.) + +### migrate / `start.sh` + +`packages/db/package.json`: `"migrate": "deno run -A src/migrate.mts"`, +`"seed": "deno run -A src/seed.mts"`, `"env": "deno run -A env.ts"`. Keep `start.sh`; change +`bun src/migrate.mts` → `deno run -A src/migrate.mts`. + +--- + +## Phase 2 — Test migration (`bun:test` → `node:test` + `@std/expect`, `deno test`) + +Surface: **~270 files**, ~2920 `expect` assertions, ~150 bun-only matchers, 47 `mock` / +21 `spyOn` / 10 `setSystemTime` / 6 `jest.*`, 4 `mock.module` seams (+ dead `node-fetch`), +12 snapshot files, 10 type-test files. + +### Step 0 — `@openstatus/test-utils` package (Decision 7) + +``` +packages/test-utils/ + src/setup.ts # registers expect.extend matchers; installs the global fetch stub helper + src/matchers.ts # the ~150 bun-only matchers (toBeNumber, toContainValue, toBeString, …) + src/fakes/ # tinybird.ts, redis.ts, subscriptions.ts — shared test doubles +``` + +Each tester adds `@openstatus/test-utils` as a devDependency; every test file imports +`@openstatus/test-utils/setup` **first** (codemod injects). + +### Step A — codemod (`ts-morph`/`jscodeshift`, ~270 files) + +Per file: replace the `bun:test` import with `node:test` + `@std/expect`, alias +`beforeAll→before`/`afterAll→after`, and inject `import "@openstatus/test-utils/setup";` as +the first import. `expect(...)` bodies untouched. + +### Step B — bun-only matchers + +Implemented once in `@openstatus/test-utils` via `expect.extend` (verified in Phase 0 spike 3). +`pass()`/`fail()` helpers → explicit `expect(...)` assertions in the few sites that use them. + +### Step C — mocks (`@std/testing/mock` + `@std/testing/time`) + +`mock(fn)`→`spy(fn)`; `spyOn(o,"m")`→`using s = spy(o,"m")` / `stub(o,"m",impl)`; sequential +returns→`returnsNext`; `setSystemTime`→`using t = new FakeTime(date)` + `t.tick`. Prefer +`using` (auto-restore) — deletes most `afterEach` teardown. Keep `toHaveBeenCalled*` if Phase-0 +interop holds, else `assertSpyCalls`/`assertSpyCall`. + +### Step D — module mocks (hybrid; Decisions 6 + 8) + +- **stub-able** → `@std/testing/mock` `stub`, fakes from `@openstatus/test-utils/fakes`: + `tb`/`redis` (`@/libs/clients` singletons), `Redis.fromEnv` (`@openstatus/upstash`). +- **global fetch** → `stub(globalThis, "fetch", …)`; **delete** every `mock.module("node-fetch")`. +- **DI (default-param)** → `dispatchMaintenanceUpdate`, `dispatchStatusReportUpdate` + (`maintenances/post.ts`, `statusReports/post.ts`), `getChannel` + (`rpc/handlers/status-page/index.ts`): add `deps = { … }` last param; tests pass fakes. +- The old global `preload.ts` is deleted; its four mocks move to the above mechanisms. + +### Step E — preload replacement + +`bunfig.toml` preload is gone; the `@openstatus/test-utils/setup` import (Step A) replaces it. +Import ordering: setup first, then the SUT. + +### Step F — snapshots + type tests + +Snapshots → `@std/testing/snapshot` `assertSnapshot(t, value)` (regenerate + diff the 12 +files). Type tests → `expect-type` (`expectTypeOf().toEqualTypeOf()`), validated by +`deno check` where in scope (the two apps). + +### Step G — invocation + +Each package/app `"test": "deno test -A"`. Pull `@std/expect`, `@std/testing`, `expect-type` +via `jsr add`/devDeps so pnpm install resolves them. Remove `bunfig.toml`, `bun-types`, +`@types/bun`. + +--- + +## Phase 3 — Install via `deno install` (Docker, server + workflows) + +Deno 2.9 reads `pnpm-workspace.yaml` catalogs (482 `catalog:` refs) + workspace globs +(244 `workspace:*`) and seeds `deno.lock` from `pnpm-lock.yaml`. dofigen `install` stage: + +```yaml + install: + fromImage: denoland/deno:2.9.0 + workdir: /app/ + env: + DENO_NODE_MODULES_DIR: auto # hoisted layout for compile + libsql side-car + bind: + - pnpm-workspace.yaml # catalog + workspace source of truth + - pnpm-lock.yaml + - deno.lock + - package.json + - …all workspace package.json (same bind list as today)… + run: deno install --prod --frozen --allow-scripts + cache: + - /deno-dir +``` + +`pnpm-workspace.yaml` stays authoritative (Decision 12); commit `deno.lock`; do **not** commit +any catalog/`deno.json` that 2.9 may emit. Verify (Phase 0 spike 4) the migration write stays +additive so pnpm keeps working for the other apps. + +--- + +## Phase 4 — `apps/server/dofigen.yml` (build) + +`build` stage → Deno + `deno compile` (target `serve.ts`). No libsql side-car (HTTP driver). + +```yaml + build: + fromImage: denoland/deno:2.9.0 + workdir: /app/apps/server + env: { NODE_ENV: production } + copy: + - . /app/ + - { fromBuilder: install, source: /app/node_modules, target: /app/node_modules } + - { fromBuilder: install, source: /app/apps/server/node_modules, target: /app/apps/server/node_modules } + - { fromBuilder: install, source: /app/packages, target: /app/packages } + run: >- + deno compile -A --no-check --node-modules-dir + --include static/openapi.yaml --include static/openapi-v1.json + --output app serve.ts +``` + +`--no-check` keeps compile fast (`deno check` is the typecheck gate, Decision 10). Optionally +benchmark experimental `--bundle` for a smaller binary. Runtime copy `/app/apps/server/app` → +`/bin/app` unchanged. + +--- + +## Phase 5 — `apps/workflows/dofigen.yml` (build) — side-car DROPPED + +Spike 2 proved `deno compile` **embeds** the libSQL native addon into the binary, so the whole +side-car apparatus goes away: + +1. **`build`** → `deno compile -A --no-check --output app serve.ts`. Settle the npm-embed flags + here (`--exclude-unused-npm` / managed npm) so it embeds reachable packages, not the whole + `node_modules` (spike 2 caveat). +2. **DELETE the `docker` stage** (`build-docker.ts` existed only to generate the side-car + `package.json`) and **DELETE the `libsql` stage**. +3. **`build-docker.ts`** itself becomes dead code → remove (its sole purpose was the side-car). +4. **runtime copy** → just the self-contained `app` binary. No `node_modules` copied at all. + +This makes the workflows runtime image dramatically simpler (binary only, like server). + +--- + +## Phase 6 — CI + +- `test.yml` + `migrate.yml`: replace `oven-sh/setup-bun` with `denoland/setup-deno@v2` + (Deno 2.9). **Keep `pnpm install`** (Decision 13), the libsql service, migrate, seed. + `pnpm test` → turbo → per-package `deno test -A` (Decision 14). +- Add a **`deno check`** step for `apps/server` + `apps/workflows` (src + tests) replacing the + server `tsc` step (Decision 10). +- **Parity gate** (Decision 16): a CI step records the base-commit `bun test` total pass count + (artifact / committed baseline number), then asserts `deno test`'s pass count ≥ baseline. +- docker-publish workflows exercise `deno install` + `deno compile` via the Dockerfiles. + +--- + +## Phase 7 — Verify & ship + +Per app: `dofigen generate`; `docker buildx build -f apps//Dockerfile .` from repo root; +run, `GET /ping` → 200; server `GET /openapi.yaml` → body; workflows embedded replica syncs + +a cron endpoint responds. Locally: `pnpm install && pnpm migrate && pnpm seed && pnpm test` +green; parity count ≥ baseline; `deno check` clean for the two apps. Watch Fly RSS/OOM on +workflows after deploy (Deno V8 heap defaults differ from bun — see `research.md`). + +--- + +## Risks + +| Risk | Mitigation | +|------|-----------| +| ~~libSQL native addon won't `deno compile`~~ | ✅ RESOLVED (spike 2): deno embeds the addon; side-car dropped | +| Big-bang PR hides a regression / silent skip | Parity gate (16); split into logical commits within the one PR for bisect | +| `@std/expect` `toHaveBeenCalled*` ✗ interop with `@std/testing/mock` spies | Phase-0 spike 3; fallback `assertSpyCalls`/`assertSpyCall` | +| `deno install` rewrites manifests / breaks pnpm for other apps | Phase-0 spike 4; keep `pnpm-workspace.yaml` authoritative, don't commit deno catalog | +| `deno check` surfaces new diagnostics vs `tsc` | Scoped to two apps (10); fix as part of the PR | +| ~270-file codemod churn | AST codemod (18) + parity gate; hand-fix the ~60-file residue | +| `stub` can't reach `tb` getter methods | Phase-0 spike 3; fallback = make `tb`/`redis` injectable like the dispatch seams | + +--- + +## TODO + +- [ ] **Phase 0** spikes: serve+compile · libsql-compile (workflows) · test-stack interop · `deno install` +- [ ] Phase 1: split `index.ts`/`serve.ts` (both) · server static asset · `Bun.*`→Deno · migrate/seed/`start.sh`→deno +- [ ] Phase 2.0: create `@openstatus/test-utils` (matchers, setup, fakes) +- [ ] Phase 2.A: codemod imports + lifecycle + setup-inject (~270 files) +- [ ] Phase 2.B–C: matchers via `expect.extend`; mocks → `@std/testing/mock`/`time` +- [ ] Phase 2.D: hybrid module mocks — stub `tb`/`redis`/`Redis.fromEnv` + `globalThis.fetch`; DI `dispatch*`/`getChannel`; delete `node-fetch` mocks + `preload.ts` +- [ ] Phase 2.F: snapshots → `@std/testing/snapshot`; type tests → `expect-type` +- [ ] Phase 2.G: `"test": "deno test -A"` everywhere; add JSR devDeps; remove `bunfig.toml`/`bun-types` +- [ ] Phase 3: `deno install` stage (both dofigen); commit `deno.lock` +- [ ] Phase 4: `apps/server` build → `deno compile` (serve.ts, `--include-as-is`) +- [ ] Phase 5: `apps/workflows` build → `deno compile`; `build-docker.ts`→deno; `libsql` stage→npm +- [ ] Phase 6: CI `setup-deno`, keep `pnpm install`, `deno check` (2 apps), parity gate +- [ ] Phase 7: `dofigen generate` + docker build + verify each app; ship; watch Fly RSS +- [ ] Update CLAUDE.md memory note "use bun test directly" → `deno test` + diff --git a/apps/workflows/docker-compose.yaml b/apps/workflows/docker-compose.yaml index 6eff4522..101f38ef 100644 --- a/apps/workflows/docker-compose.yaml +++ b/apps/workflows/docker-compose.yaml @@ -4,14 +4,9 @@ services: build: context: ../.. dockerfile: apps/workflows/Dockerfile - environment: - - DATABASE_URL=http://host.docker.internal:8081 - - DATABASE_AUTH_TOKEN=test - - RESEND_API_KEY=test - - UPSTASH_REDIS_REST_URL=test - - UPSTASH_REDIS_REST_TOKEN=test - - NODE_ENV=production - - GCP_PROJECT_ID=test + env_file: + - ../../.env.docker + extra_hosts: - "host.docker.internal:host-gateway" diff --git a/apps/workflows/dofigen.lock b/apps/workflows/dofigen.lock index cb7e8ab9..8ae0521b 100644 --- a/apps/workflows/dofigen.lock +++ b/apps/workflows/dofigen.lock @@ -12,32 +12,52 @@ effective: | - /packages/error - /packages/tracker builders: - docker: + build: fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + path: denoland/deno + digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 label: - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 + org.opencontainers.image.base.name: docker.io/denoland/deno:2.9.0 + org.opencontainers.image.base.digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 + org.opencontainers.image.stage: build workdir: /app/apps/workflows + env: + NODE_ENV: production copy: - paths: - . target: /app/ + - fromBuilder: install + paths: + - /app/node_modules + target: /app/node_modules + - fromBuilder: install + paths: + - /app/apps/workflows/node_modules + target: /app/apps/workflows/node_modules + - fromBuilder: install + paths: + - /app/packages + target: /app/packages run: - - bun run src/build-docker.ts + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data install: fromImage: path: node - digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf + digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc label: + org.opencontainers.image.base.digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc org.opencontainers.image.stage: install org.opencontainers.image.base.name: docker.io/node:24-slim - org.opencontainers.image.base.digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf workdir: /app/ run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - target: /root/.local/share/pnpm/store bind: @@ -105,62 +125,22 @@ effective: | source: packages/locales/package.json - target: packages/status-fetcher/package.json source: packages/status-fetcher/package.json - libsql: - fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - label: - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - workdir: /app/ - copy: - - fromBuilder: docker - paths: - - /app/apps/build-docker/package.json - target: /app/package.json - run: - - bun install --production - build: - fromImage: - path: oven/bun - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - label: - org.opencontainers.image.base.name: docker.io/oven/bun:1.3.11 - org.opencontainers.image.stage: build - org.opencontainers.image.base.digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 - workdir: /app/apps/workflows - env: - NODE_ENV: production - copy: - - paths: - - . - target: /app/ - - fromBuilder: install - paths: - - /app/node_modules - target: /app/node_modules - - fromBuilder: install - paths: - - /app/apps/workflows/node_modules - target: /app/apps/workflows/node_modules - - fromBuilder: install - paths: - - /app/packages - target: /app/packages - run: - - bun build --compile --target bun --sourcemap src/index.ts --outfile=app fromImage: - path: debian - digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 + host: registry.access.redhat.com + port: 443 + path: hi/curl + digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 label: - org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus - org.opencontainers.image.authors: OpenStatus Team - org.opencontainers.image.base.digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 - org.opencontainers.image.title: OpenStatus Workflows - org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus - org.opencontainers.image.base.name: docker.io/debian:bullseye-slim io.dofigen.version: 2.8.0 + org.opencontainers.image.source: https://github.com/openstatusHQ/openstatus + org.opencontainers.image.title: OpenStatus Workflows + org.opencontainers.image.authors: OpenStatus Team + org.opencontainers.image.description: Background job processing and probe scheduling for OpenStatus org.opencontainers.image.vendor: OpenStatus + org.opencontainers.image.base.digest: sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 + user: + user: '1000' + group: '1000' workdir: /app/ copy: - fromBuilder: build @@ -168,37 +148,33 @@ effective: | - /app/apps/workflows/app target: /app/apps/workflows/ chmod: '555' - - fromBuilder: libsql - paths: - - /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql + - fromBuilder: build paths: - - /app/node_modules - target: /app/node_modules - root: - run: - - apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data + - /app/data + target: /app/data entrypoint: - /app/apps/workflows/app expose: - port: 3000 + healthcheck: + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + interval: 1m + timeout: 10s + start: 30s + retries: 3 images: docker.io: + denoland: + deno: + 2.9.0: + digest: sha256:8d24854de78a79c56e74b49aa4c5996c60e1fe3730efba8fbdd2692c582e6e29 library: node: 24-slim: - digest: sha256:242549cd46785b480c832479a730f4f2a20865d61ea2e404fdb2a5c3d3b73ecf - debian: - bullseye-slim: - digest: sha256:cd1bc32f233a49f1b82149c9edb8ef34fb1e6c45f37211445c51a97603468604 - oven: - bun: - 1.3.11: - digest: sha256:0733e50325078969732ebe3b15ce4c4be5082f18c4ac1a0f0ca4839c2e4e42a7 + digest: sha256:b31e7a42fdf8b8aa5f5ed477c72d694301273f1069c5a2f71d53c6482e99a2fc resources: dofigen.yml: - hash: 9ad08ee36ff20abe093e58fc36235d056b6ed3e22b8ae2f3fb30399e34cdaebe + hash: 3d98c3f4837321ccc3810b1644c53d6c17f057fb57ec5d7beafa6b3caef9f59b content: | ignore: - node_modules @@ -252,16 +228,16 @@ resources: - packages/locales/package.json - packages/status-fetcher/package.json - # Install dependencies + # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary) + # Stage 4: Build application (compile to binary with Deno) build: - fromImage: oven/bun:1.3.11 + fromImage: denoland/deno:2.9.0 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -276,35 +252,24 @@ resources: - fromBuilder: install source: /app/packages target: /app/packages - # Should set env to production here - # Compile the TypeScript application env: NODE_ENV: production - run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app - - docker: - fromImage: oven/bun:1.3.11 - workdir: /app/apps/workflows - copy: - - . /app/ - run: bun run src/build-docker.ts - - libsql: - fromImage: oven/bun:1.3.11 - workdir: /app/ - copy: - - fromBuilder: docker - source: /app/apps/build-docker/package.json - target: /app/package.json - # bun install is hoisted by default -> flat node_modules so the compiled bun binary can - # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile - # is needed (the generated package.json pins one exact version), so a single install does it. - run: bun install --production + # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: + # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads + # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, + # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. + run: + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data - fromImage: debian:bullseye-slim + # Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). + # Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. + fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 workdir: /app/ - root: - run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -314,18 +279,25 @@ resources: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team - # Copy artifacts from build stages + # Copy the self-contained compiled binary (native addon embedded by deno compile) copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: libsql - source: /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql - source: /app/node_modules - target: /app/node_modules + - fromBuilder: build + source: /app/data + target: /app/data + + user: "1000:1000" expose: "3000" + # Health check — exec form (JSON array) because the base has no shell for CMD-SHELL + healthcheck: + interval: 1m + timeout: 10s + start: 30s + retries: 3 + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/dofigen.yml b/apps/workflows/dofigen.yml index 89c086dd..b07724aa 100644 --- a/apps/workflows/dofigen.yml +++ b/apps/workflows/dofigen.yml @@ -50,16 +50,16 @@ builders: - packages/locales/package.json - packages/status-fetcher/package.json - # Install dependencies + # Install dependencies (scoped to the workflows subgraph so node_modules — and the binary that embeds it — stays small) run: - corepack enable pnpm - - pnpm install --prod --frozen-lockfile --verbose + - pnpm install --prod --frozen-lockfile --filter=@openstatus/workflows... --verbose cache: - /root/.local/share/pnpm/store - # Stage 4: Build application (compile to binary) + # Stage 4: Build application (compile to binary with Deno) build: - fromImage: oven/bun:1.3.11 + fromImage: denoland/deno:2.9.0 workdir: /app/apps/workflows labels: org.opencontainers.image.stage: build @@ -74,35 +74,24 @@ builders: - fromBuilder: install source: /app/packages target: /app/packages - # Should set env to production here - # Compile the TypeScript application env: NODE_ENV: production - run: bun build --compile --target bun --sourcemap src/index.ts --outfile=app - - docker: - fromImage: oven/bun:1.3.11 - workdir: /app/apps/workflows - copy: - - . /app/ - run: bun run src/build-docker.ts - - libsql: - fromImage: oven/bun:1.3.11 - workdir: /app/ - copy: - - fromBuilder: docker - source: /app/apps/build-docker/package.json - target: /app/package.json - # bun install is hoisted by default -> flat node_modules so the compiled bun binary can - # resolve the libsql native addon (@libsql/) from disk at runtime. No lockfile - # is needed (the generated package.json pins one exact version), so a single install does it. - run: bun install --production + # Bundle the app to self-contained JS, EXTERNALISING the 3 packages that can't be inlined: + # @libsql/client + libsql (native .node loader) and @google-cloud/tasks (google-proto-files reads + # files via CJS __dirname). They ship as a minimal side-car node_modules (deno install, ~46MB, + # platform-aware so Fly amd64 works) instead of embedding all node_modules. Binary ~146MB vs ~360MB. + run: + - mkdir -p /tmp/sc + - deno eval 'const p="/app/node_modules/.pnpm";const v=(x)=>{for(const e of Deno.readDirSync(p))if(e.name.startsWith(x+"@"))return e.name.slice(x.length+1).split("_")[0]};Deno.writeTextFileSync("/tmp/sc/package.json",JSON.stringify({dependencies:{"@libsql/client":v("@libsql+client"),libsql:v("libsql"),"@google-cloud/tasks":v("@google-cloud+tasks")}}))' + - cd /tmp/sc && deno install --node-modules-dir=auto --allow-scripts + - cd /app/apps/workflows && deno bundle --platform=deno --minify --sloppy-imports --node-modules-dir=manual --external '@libsql/client' --external 'libsql' --external '@google-cloud/tasks' --output /tmp/sc/_serve.bundle.mjs src/serve.ts + - cd /tmp/sc && deno compile --no-check -A --node-modules-dir=manual --output /app/apps/workflows/app /tmp/sc/_serve.bundle.mjs + - mkdir -p /app/data -fromImage: debian:bullseye-slim +# Runtime: distroless glibc base that already ships curl + CA certs (Deno's HTTPS works on it; no apt needed). +# Pinned to the multi-arch index digest of hi/curl:latest — dofigen mis-resolves this registry's tag to an unpullable digest. +fromImage: registry.access.redhat.com/hi/curl@sha256:848b81ab5d5e55371d7193fd4f1ea7b605d14dbb039344ffad34a4c1f0d880f4 workdir: /app/ -root: - run: apt-get update -q && apt-get install -y -q --no-install-recommends ca-certificates curl && update-ca-certificates && rm -rf /var/lib/apt/lists/* && mkdir -p /app/data && chown -R 1000:1000 /app/data # Metadata labels labels: @@ -112,18 +101,25 @@ labels: org.opencontainers.image.vendor: OpenStatus org.opencontainers.image.authors: OpenStatus Team -# Copy artifacts from build stages +# Copy the self-contained compiled binary (native addon embedded by deno compile) copy: - fromBuilder: build source: /app/apps/workflows/app target: /app/apps/workflows/ chmod: "555" - - fromBuilder: libsql - source: /app/node_modules - target: /app/packages/db/node_modules - - fromBuilder: libsql - source: /app/node_modules - target: /app/node_modules + - fromBuilder: build + source: /app/data + target: /app/data + +user: "1000:1000" expose: "3000" +# Health check — exec form (JSON array) because the base has no shell for CMD-SHELL +healthcheck: + interval: 1m + timeout: 10s + start: 30s + retries: 3 + cmd: '["curl", "-f", "http://localhost:3000/ping"]' + entrypoint: /app/apps/workflows/app diff --git a/apps/workflows/package.json b/apps/workflows/package.json index e92ffa72..522f838f 100644 --- a/apps/workflows/package.json +++ b/apps/workflows/package.json @@ -1,9 +1,10 @@ { "name": "@openstatus/workflows", "scripts": { - "dev": "NODE_ENV=development bun run --hot src/index.ts", - "start": "NODE_ENV=production bun run src/index.ts", - "test": "bun test" + "check": "deno check --sloppy-imports src/serve.ts", + "dev": "NODE_ENV=development deno run -A --watch src/serve.ts", + "start": "NODE_ENV=production deno run -A src/serve.ts", + "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test -A --no-check --sloppy-imports" }, "dependencies": { "@google-cloud/tasks": "catalog:", @@ -33,9 +34,11 @@ "@openstatus/tinybird": "workspace:*", "@openstatus/upstash": "workspace:*", "@openstatus/utils": "workspace:*", + "@opentelemetry/exporter-logs-otlp-http": "catalog:", "@opentelemetry/resources": "catalog:", + "@opentelemetry/sdk-logs": "catalog:", "@opentelemetry/semantic-conventions": "catalog:", - "@sentry/bun": "catalog:", + "@sentry/deno": "catalog:", "@upstash/qstash": "catalog:", "drizzle-orm": "catalog:", "effect": "catalog:", @@ -44,8 +47,8 @@ "zod": "catalog:" }, "devDependencies": { + "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", "typescript": "catalog:" } } diff --git a/apps/workflows/src/build-docker.ts b/apps/workflows/src/build-docker.ts deleted file mode 100644 index 1db9537c..00000000 --- a/apps/workflows/src/build-docker.ts +++ /dev/null @@ -1,81 +0,0 @@ -import path from "node:path"; - -// Create package.json that contains @libsql/client as dependency. It will be used to create node_modules and copy them alongside compiled server https://github.com/oven-sh/bun/issues/18909 -type PackageJson = Record<"name" | "description" | "version", string> & - Record<"dependencies", Record>; -const packageJson: PackageJson = await Bun.file( - path.join(__dirname, "../../../packages/db", "package.json"), -).json(); - -const extractDependenciesNames = ["@libsql/client"]; -const workspaceConfig = await Bun.file( - path.join(__dirname, "../../../pnpm-workspace.yaml"), -).text(); - -const catalog = (() => { - const lines = workspaceConfig.split(/\r?\n/); - let inCatalog = false; - const entries: Record = {}; - - for (const line of lines) { - if (!inCatalog) { - if (line.trim() === "catalog:") { - inCatalog = true; - } - continue; - } - - if (!line.startsWith(" ")) { - break; - } - - const match = line.match(/^\s{2}("[^"]+"|[^:]+):\s*(.+)$/); - if (!match) { - continue; - } - - const key = match[1].replace(/^"|"$/g, "").trim(); - const value = match[2].replace(/^"|"$/g, "").trim(); - entries[key] = value; - } - - return entries; -})(); - -const resolveVersion = (name: string, spec: string) => { - if (!spec.startsWith("catalog:")) { - return spec; - } - - const resolved = catalog[name]; - if (!resolved) { - throw new Error(`Missing catalog entry for ${name}`); - } - - return resolved; -}; - -const extractedDependencies = extractDependenciesNames.reduce( - (acc, cur) => { - const spec = packageJson.dependencies[cur]; - if (spec) { - acc[cur] = resolveVersion(cur, spec); - } - - return acc; - }, - {} as Record, -); - -const packageJsonBuild = { - name: packageJson.name, - description: packageJson.description, - version: packageJson.version, - // type: "module", - dependencies: extractedDependencies, -}; - -await Bun.write( - "../build-docker/package.json", - JSON.stringify(packageJsonBuild, null, 2), -); diff --git a/apps/workflows/src/checker/alerting.test.ts b/apps/workflows/src/checker/alerting.test.ts index 0f8bb1ee..e69ab6c9 100644 --- a/apps/workflows/src/checker/alerting.test.ts +++ b/apps/workflows/src/checker/alerting.test.ts @@ -1,95 +1,77 @@ -import { afterAll, afterEach, describe, expect, mock, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { notification, notificationTrigger, notificationsToMonitors, } from "@openstatus/db/src/schema"; - -// Mock audit log to avoid calling Tinybird -mock.module("../utils/audit-log", () => ({ - checkerAudit: { - publishAuditLog: mock(() => Promise.resolve()), - }, -})); - -// Mock notification providers to avoid real HTTP calls -const mockEmailSendAlert = mock(() => Promise.resolve()); -const mockEmailSendRecovery = mock(() => Promise.resolve()); -const mockEmailSendDegraded = mock(() => Promise.resolve()); -const mockSlackSendAlert = mock(() => Promise.resolve()); -const mockSlackSendRecovery = mock(() => Promise.resolve()); -const mockSlackSendDegraded = mock(() => Promise.resolve()); -const mockDiscordSendAlert = mock(() => Promise.resolve()); -const mockDiscordSendRecovery = mock(() => Promise.resolve()); -const mockDiscordSendDegraded = mock(() => Promise.resolve()); - -mock.module("./utils", () => ({ - providerToFunction: { - email: { - sendAlert: mockEmailSendAlert, - sendRecovery: mockEmailSendRecovery, - sendDegraded: mockEmailSendDegraded, - }, - discord: { - sendAlert: mockDiscordSendAlert, - sendRecovery: mockDiscordSendRecovery, - sendDegraded: mockDiscordSendDegraded, - }, - slack: { - sendAlert: mockSlackSendAlert, - sendRecovery: mockSlackSendRecovery, - sendDegraded: mockSlackSendDegraded, - }, - sms: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - webhook: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - telegram: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - pagerduty: { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - opsgenie: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - ntfy: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - "google-chat": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - "grafana-oncall": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - "ms-teams": { - sendAlert: mock(), - sendRecovery: mock(), - sendDegraded: mock(), - }, - whatsapp: { sendAlert: mock(), sendRecovery: mock(), sendDegraded: mock() }, - }, -})); - -// Import after mocks are set up -const { triggerNotifications } = await import("./alerting"); +import { + afterAll, + afterEach, + assertSpyCalls, + beforeEach, + describe, + expect, + type Stub, + stub, + test, +} from "@openstatus/test-utils"; + +import { checkerAudit } from "../utils/audit-log"; +import { triggerNotifications } from "./alerting"; +import { providerToFunction } from "./utils"; + +// Deno has no module mocking, so we stub the methods on the real singletons +// that alerting.ts reads at call time. Stubbing per-test resolves them to no-op +// to avoid real HTTP / Tinybird calls and gives a fresh call count each test. +// biome-ignore lint/suspicious/noExplicitAny: heterogeneous provider stubs +type AnyStub = Stub; +let stubs: AnyStub[] = []; + +const stubSend = ( + provider: "email" | "slack" | "discord", + verb: "sendAlert" | "sendRecovery" | "sendDegraded", +): AnyStub => { + const s = stub(providerToFunction[provider], verb, () => Promise.resolve()); + stubs.push(s); + return s; +}; + +let mockEmailSendAlert: AnyStub; +let mockEmailSendRecovery: AnyStub; +let mockEmailSendDegraded: AnyStub; +let mockSlackSendAlert: AnyStub; +let mockSlackSendRecovery: AnyStub; +let mockSlackSendDegraded: AnyStub; +let mockDiscordSendAlert: AnyStub; +let mockDiscordSendRecovery: AnyStub; +let mockDiscordSendDegraded: AnyStub; // Seed data has: monitor 1 (workspace 1) linked to notification 1 (email provider) // We use unique cronTimestamp per test to avoid unique constraint conflicts -describe("triggerNotifications", () => { - afterEach(() => { - mockEmailSendAlert.mockClear(); - mockEmailSendRecovery.mockClear(); - mockEmailSendDegraded.mockClear(); - mockSlackSendAlert.mockClear(); - mockSlackSendRecovery.mockClear(); - mockSlackSendDegraded.mockClear(); - mockDiscordSendAlert.mockClear(); - mockDiscordSendRecovery.mockClear(); - mockDiscordSendDegraded.mockClear(); - }); +beforeEach(() => { + stubs = []; + // biome-ignore lint/suspicious/noExplicitAny: avoid Tinybird call + stubs.push( + stub(checkerAudit, "publishAuditLog", () => Promise.resolve()) as AnyStub, + ); + mockEmailSendAlert = stubSend("email", "sendAlert"); + mockEmailSendRecovery = stubSend("email", "sendRecovery"); + mockEmailSendDegraded = stubSend("email", "sendDegraded"); + mockSlackSendAlert = stubSend("slack", "sendAlert"); + mockSlackSendRecovery = stubSend("slack", "sendRecovery"); + mockSlackSendDegraded = stubSend("slack", "sendDegraded"); + mockDiscordSendAlert = stubSend("discord", "sendAlert"); + mockDiscordSendRecovery = stubSend("discord", "sendRecovery"); + mockDiscordSendDegraded = stubSend("discord", "sendDegraded"); +}); +afterEach(() => { + for (const s of stubs) s.restore(); + stubs = []; +}); + +describe("triggerNotifications", () => { afterAll(async () => { // Clean up notification triggers created during tests await db @@ -112,7 +94,7 @@ describe("triggerNotifications", () => { latency: 1500, }); - expect(mockEmailSendAlert).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendAlert, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -131,7 +113,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - expect(mockEmailSendRecovery).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendRecovery, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -151,7 +133,7 @@ describe("triggerNotifications", () => { regions: ["ams"], }); - expect(mockEmailSendDegraded).toHaveBeenCalledTimes(1); + assertSpyCalls(mockEmailSendDegraded, 1); expect(result).toHaveLength(1); expect(result[0]).toEqual({ notificationId: 1, @@ -170,7 +152,7 @@ describe("triggerNotifications", () => { cronTimestamp, }); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + assertSpyCalls(mockEmailSendAlert, 0); expect(result).toHaveLength(0); }); @@ -185,7 +167,7 @@ describe("triggerNotifications", () => { }); expect(first).toHaveLength(1); - mockEmailSendAlert.mockClear(); + assertSpyCalls(mockEmailSendAlert, 1); // Same cronTimestamp should be skipped due to unique constraint const second = await triggerNotifications({ @@ -195,7 +177,8 @@ describe("triggerNotifications", () => { cronTimestamp, }); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + // still only the first call — the duplicate was skipped + assertSpyCalls(mockEmailSendAlert, 1); expect(second).toHaveLength(0); }); }); @@ -207,14 +190,6 @@ describe("triggerNotifications with multiple providers", () => { // We link slack and discord notifications to it for this test suite. const testMonitorId = 3; - afterEach(() => { - mockEmailSendAlert.mockClear(); - mockSlackSendAlert.mockClear(); - mockDiscordSendAlert.mockClear(); - mockSlackSendRecovery.mockClear(); - mockDiscordSendRecovery.mockClear(); - }); - afterAll(async () => { // Clean up notification triggers await db @@ -282,9 +257,9 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - expect(mockSlackSendAlert).toHaveBeenCalledTimes(1); - expect(mockDiscordSendAlert).toHaveBeenCalledTimes(1); - expect(mockEmailSendAlert).not.toHaveBeenCalled(); + assertSpyCalls(mockSlackSendAlert, 1); + assertSpyCalls(mockDiscordSendAlert, 1); + assertSpyCalls(mockEmailSendAlert, 0); expect(result).toHaveLength(2); expect(result).toContainEqual({ @@ -308,8 +283,8 @@ describe("triggerNotifications with multiple providers", () => { regions: ["ams"], }); - expect(mockSlackSendRecovery).toHaveBeenCalledTimes(1); - expect(mockDiscordSendRecovery).toHaveBeenCalledTimes(1); + assertSpyCalls(mockSlackSendRecovery, 1); + assertSpyCalls(mockDiscordSendRecovery, 1); expect(result).toHaveLength(2); const providers = result.map((r) => r.provider).sort(); diff --git a/apps/workflows/src/cron/checker.ts b/apps/workflows/src/cron/checker.ts index dfdb5b32..40dbf7ab 100644 --- a/apps/workflows/src/cron/checker.ts +++ b/apps/workflows/src/cron/checker.ts @@ -51,7 +51,7 @@ export const isAuthorizedDomain = (url: string) => { const logger = getLogger("workflow"); const client = new CloudTasksClient({ - fallback: "rest", + fallback: true, projectId: env().GCP_PROJECT_ID, credentials: { client_email: env().GCP_CLIENT_EMAIL, diff --git a/apps/workflows/src/cron/index.ts b/apps/workflows/src/cron/index.ts index 9ca25c81..45bd9b6e 100644 --- a/apps/workflows/src/cron/index.ts +++ b/apps/workflows/src/cron/index.ts @@ -1,5 +1,5 @@ import { monitorPeriodicitySchema } from "@openstatus/db/src/schema/constants"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { Effect, Schedule } from "effect"; import { Hono } from "hono"; diff --git a/apps/workflows/src/index.ts b/apps/workflows/src/index.ts index fd186562..9cd13dac 100644 --- a/apps/workflows/src/index.ts +++ b/apps/workflows/src/index.ts @@ -8,9 +8,15 @@ import { withContext, } from "@logtape/logtape"; import { getOpenTelemetrySink } from "@logtape/otel"; +import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"; import { resourceFromAttributes } from "@opentelemetry/resources"; +import { + BatchLogRecordProcessor, + LoggerProvider, +} from "@opentelemetry/sdk-logs"; +import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions"; import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME } from "@opentelemetry/semantic-conventions/incubating"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { Hono } from "hono"; import { showRoutes } from "hono/dev"; import { requestId } from "hono/request-id"; @@ -21,7 +27,7 @@ import { cronRouter } from "./cron"; import { env } from "./env"; import { incidentRoute } from "./incident"; -const { NODE_ENV, PORT } = env(); +const { NODE_ENV } = env(); export type Env = { Variables: { @@ -59,18 +65,30 @@ function shouldSample(event: Record): boolean { return Math.random() < 0.2; } -const defaultLogger = getOpenTelemetrySink({ - serviceName: "openstatus-workflows", - otlpExporterConfig: { - url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", - headers: { - Authorization: `Bearer ${env().AXIOM_TOKEN}`, - "X-Axiom-Dataset": env().AXIOM_DATASET, - }, - }, - additionalResource: resourceFromAttributes({ +// Build the LoggerProvider with a static OTLP exporter import so `deno bundle` +// includes it. Letting @logtape/otel create the exporter triggers a dynamic +// import of a bare specifier, which the compiled --node-modules-dir=none binary +// can't resolve. +const loggerProvider = new LoggerProvider({ + resource: resourceFromAttributes({ + [ATTR_SERVICE_NAME]: "openstatus-workflows", [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: env().NODE_ENV, }), + processors: [ + new BatchLogRecordProcessor( + new OTLPLogExporter({ + url: "https://eu-central-1.aws.edge.axiom.co/v1/logs", + headers: { + Authorization: `Bearer ${env().AXIOM_TOKEN}`, + "X-Axiom-Dataset": env().AXIOM_DATASET, + }, + }), + ), + ], +}); + +const defaultLogger = getOpenTelemetrySink({ + loggerProvider, }); await configure({ @@ -97,7 +115,7 @@ await configure({ const logger = getLogger(["workflow"]); const otelLogger = getLogger(["workflow-otel"]); -const app = new Hono({ strict: false }); +export const app = new Hono({ strict: false }); app.use("*", requestId()); @@ -182,9 +200,3 @@ app.route("/incident", incidentRoute); if (NODE_ENV === "development") { showRoutes(app, { verbose: true, colorize: true }); } - -logger.info("Starting server", { port: PORT, environment: NODE_ENV }); - -const server = { port: PORT, fetch: app.fetch }; - -export default server; diff --git a/apps/workflows/src/lib/sentry.ts b/apps/workflows/src/lib/sentry.ts index 542d06d2..45e70c55 100644 --- a/apps/workflows/src/lib/sentry.ts +++ b/apps/workflows/src/lib/sentry.ts @@ -1,5 +1,5 @@ import { FetchError } from "@openstatus/status-fetcher"; -import * as Sentry from "@sentry/bun"; +import * as Sentry from "@sentry/deno"; import { env } from "../env"; diff --git a/apps/workflows/src/serve.ts b/apps/workflows/src/serve.ts new file mode 100644 index 00000000..6f520562 --- /dev/null +++ b/apps/workflows/src/serve.ts @@ -0,0 +1,15 @@ +/// + +import { getLogger } from "@logtape/logtape"; + +import { env } from "./env"; +import { app } from "./index"; + +const { NODE_ENV, PORT } = env(); + +getLogger(["workflow"]).info("Starting server", { + port: PORT, + environment: NODE_ENV, +}); + +Deno.serve({ port: PORT }, app.fetch); diff --git a/apps/workflows/start.sh b/apps/workflows/start.sh index 0c6da27c..e24344a2 100644 --- a/apps/workflows/start.sh +++ b/apps/workflows/start.sh @@ -2,7 +2,7 @@ set -e echo "Running database migrations..." -cd /app/packages/db && bun src/migrate.mts +cd /app/packages/db && deno run -A src/migrate.mts echo "Starting workflows service..." cd /app/apps/workflows diff --git a/apps/workflows/tsconfig.json b/apps/workflows/tsconfig.json index 9ce54dd0..a627827e 100644 --- a/apps/workflows/tsconfig.json +++ b/apps/workflows/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "hono/jsx", - "lib": ["ES2022"], "module": "ESNext", "target": "ESNext", "moduleResolution": "bundler" diff --git a/deno.lock b/deno.lock new file mode 100644 index 00000000..59e89299 --- /dev/null +++ b/deno.lock @@ -0,0 +1,277 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/assert@^1.0.19": "1.0.19", + "jsr:@std/async@^1.4.0": "1.4.0", + "jsr:@std/data-structures@^1.1.0": "1.1.0", + "jsr:@std/expect@*": "1.0.19", + "jsr:@std/internal@^1.0.12": "1.0.14", + "jsr:@std/internal@^1.0.13": "1.0.14", + "jsr:@std/path@^1.1.4": "1.1.4", + "jsr:@std/testing@*": "1.0.19" + }, + "jsr": { + "@std/assert@1.0.19": { + "integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e", + "dependencies": [ + "jsr:@std/internal@^1.0.12" + ] + }, + "@std/async@1.4.0": { + "integrity": "4d70b008634f571cff9b554090d628c76141c32613aae0ff283fd5fa23d0c379" + }, + "@std/data-structures@1.1.0": { + "integrity": "c35ae4ad5d8e41a38573c2fe3e19b18ea2505f63cfea201edcb8720aca1f7f58" + }, + "@std/expect@1.0.19": { + "integrity": "25271785688c7ff902fa54875d6aa4001f552c5578f7f0fefb5b5aac1fc2ed8a", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/internal@^1.0.13", + "jsr:@std/path" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + }, + "@std/path@1.1.4": { + "integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5", + "dependencies": [ + "jsr:@std/internal@^1.0.12" + ] + }, + "@std/testing@1.0.19": { + "integrity": "f4236172365b216728dc3cc8b5e80a9f4c33083d1e4ede7613d5b25b4014898e", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/async", + "jsr:@std/data-structures" + ] + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:turbo@2.9.14" + ] + }, + "members": { + "apps/server": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/status-page": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/web": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/api": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/db": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/emails": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/header-analysis": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/importers": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/base": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/bird-whatsapp": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/discord": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/google-chat": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/grafana-oncall": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ms-teams": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ntfy": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/opsgenie": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/pagerduty": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/slack": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/telegram": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/twillio-sms": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/webhook": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/services": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/status-fetcher": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/subscriptions": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/test-utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/tracker": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + } + } + } +} diff --git a/package.json b/package.json index fcf9e3f2..995b4fb7 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "format": "oxfmt && oxlint --fix", "format:check": "oxfmt --check && oxlint", "lint:turbo": "turbo run lint", + "check": "turbo run check", "dev:web": "turbo run dev --filter='./apps/web' --filter='./packages/db'", "dev:status-page": "turbo run dev --filter='./apps/status-page' --filter='./packages/db'", "dev:dashboard": "turbo run dev --filter='./apps/dashboard' --filter='./packages/db'", diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 1594951d..4c43a19c 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@openpanel/sdk": "catalog:", "@t3-oss/env-core": "catalog:", diff --git a/packages/analytics/tsconfig.json b/packages/analytics/tsconfig.json index 7f4d9b72..3c1048af 100644 --- a/packages/analytics/tsconfig.json +++ b/packages/analytics/tsconfig.json @@ -5,7 +5,6 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", - "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/api/.env.test b/packages/api/.env.test index 84a3ecca..75fa5596 100644 --- a/packages/api/.env.test +++ b/packages/api/.env.test @@ -1,3 +1,4 @@ +NODE_ENV=test RESEND_API_KEY='test' NEXT_PUBLIC_OPENPANEL_CLIENT_ID='test' OPENPANEL_CLIENT_SECRET='test' diff --git a/packages/api/env.ts b/packages/api/env.ts index 1dd33b39..4796312c 100644 --- a/packages/api/env.ts +++ b/packages/api/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.test"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.test", "./.env"); diff --git a/packages/api/package.json b/packages/api/package.json index ae6b5c2f..b6cfb9e2 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -6,9 +6,14 @@ "license": "ISC", "author": "", "main": "index.ts", + "exports": { + ".": "./index.ts", + "./src/*": "./src/*.ts" + }, "scripts": { - "test": "bun test", - "env": "bun env.ts" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports --env-file=.env.test --import-map=test.importmap.json", + "env": "deno run -A env.ts" }, "dependencies": { "@openstatus/analytics": "workspace:*", @@ -52,6 +57,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/react": "catalog:", "@types/react-dom": "catalog:", "bun-types": "catalog:", diff --git a/packages/api/src/router/blob.test.ts b/packages/api/src/router/blob.test.ts index a357abdb..f8498a1e 100644 --- a/packages/api/src/router/blob.test.ts +++ b/packages/api/src/router/blob.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { isSvgFile, sanitizeSvg } from "./blob"; diff --git a/packages/api/src/router/effective-status.test.ts b/packages/api/src/router/effective-status.test.ts index fcd2fcec..9c7ef9e8 100644 --- a/packages/api/src/router/effective-status.test.ts +++ b/packages/api/src/router/effective-status.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { computeEffectiveStatus } from "./effective-status"; diff --git a/packages/api/src/router/import.test.ts b/packages/api/src/router/import.test.ts index 80c3c4c2..ddb77b23 100644 --- a/packages/api/src/router/import.test.ts +++ b/packages/api/src/router/import.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { maintenance, @@ -21,6 +19,8 @@ import { MOCK_SUBSCRIBERS, } from "@openstatus/importers/statuspage/fixtures"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; @@ -341,7 +341,7 @@ test("run creates page, components, and groups in DB", async () => { // Clean up for next tests await cleanup(); -}, 15_000); +}); test("run with existing pageId imports into that page", async () => { const result = await caller.import.run({ @@ -374,7 +374,7 @@ test("run with existing pageId imports into that page", async () => { expect(matchingComps.length).toBe(MOCK_COMPONENTS.length); await cleanup(); -}, 15_000); +}); test("re-run skips already-imported resources (idempotency)", async () => { // First run @@ -410,7 +410,7 @@ test("re-run skips already-imported resources (idempotency)", async () => { expect(allGroupsSkipped).toBe(true); await cleanup(); -}, 15_000); +}); test("run with includeStatusReports creates status reports", async () => { const result = await caller.import.run({ @@ -461,7 +461,7 @@ test("run with includeStatusReports creates status reports", async () => { expect(createdMaintIds.length).toBeGreaterThan(0); await cleanup(); -}, 15_000); +}); // --------------------------------------------------------------------------- // Limit warnings (go through the caller with custom workspace limits to diff --git a/packages/api/src/router/maintenance.test.ts b/packages/api/src/router/maintenance.test.ts index 65c853c0..c24e9425 100644 --- a/packages/api/src/router/maintenance.test.ts +++ b/packages/api/src/router/maintenance.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { maintenance, @@ -8,6 +6,8 @@ import { pageComponent, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/monitor.test.ts b/packages/api/src/router/monitor.test.ts index d19508a7..62079b22 100644 --- a/packages/api/src/router/monitor.test.ts +++ b/packages/api/src/router/monitor.test.ts @@ -1,40 +1,88 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - -import { db, eq } from "@openstatus/db"; +import { db, eq, inArray } from "@openstatus/db"; import { monitorTag, monitorTagsToMonitors, + notification, + notificationsToMonitors, privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; +// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in +// the authed middleware, so the caller is scoped to ownWorkspaceId instead of +// resolving the seeded workspace for the session user. +function callerFor(limits?: typeof allPlans.team.limits) { + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal user for test + user: { id: 1 }, + // @ts-expect-error - minimal workspace for test + workspace: limits ? { id: ownWorkspaceId, limits } : { id: ownWorkspaceId }, + }); + return edgeRouter.createCaller(ctx); +} + +// Own workspaces/monitors per suite — these IDOR tests previously shared the +// seeded monitor 5 / workspace 3, which races sibling suites mutating that +// monitor's associations (e.g. privateLocation.test). +let ownWorkspaceId: number; +let otherWorkspaceId: number; +let ownMonitorId: number; +let otherMonitorId: number; let tagId: number; +let notifierId: number; let otherWorkspacePrivateLocationId: number; let ownWorkspacePrivateLocationId: number; beforeAll(async () => { + const own = await createWorkspace(); + const other = await createWorkspace(); + ownWorkspaceId = own.id; + otherWorkspaceId = other.id; + + const ownMonitor = await createMonitor(own.id); + const otherMonitor = await createMonitor(other.id); + ownMonitorId = ownMonitor.id; + otherMonitorId = otherMonitor.id; + const tag = await db .insert(monitorTag) + .values({ workspaceId: own.id, name: "idor-test-tag", color: "#ff0000" }) + .returning() + .get(); + tagId = tag.id; + + const notif = await db + .insert(notification) .values({ - workspaceId: 1, - name: "idor-test-tag", - color: "#ff0000", + workspaceId: own.id, + name: "idor-test-notif", + provider: "email", + data: JSON.stringify({ email: "test@example.com" }), }) .returning() .get(); - tagId = tag.id; + notifierId = notif.id; const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: 3, + workspaceId: other.id, name: "Other workspace private location", - token: "monitor-test-other-token", + token: `monitor-test-other-${otherWorkspaceId}`, }) .returning() .get(); @@ -43,47 +91,68 @@ beforeAll(async () => { const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: 1, + workspaceId: own.id, name: "Own workspace private location", - token: "monitor-test-own-token", + token: `monitor-test-own-${ownWorkspaceId}`, }) .returning() .get(); ownWorkspacePrivateLocationId = ownLoc.id; + + // Pre-existing association on the cross-workspace monitor; the IDOR test + // asserts a rejected scheduling update does not wipe it. + await db + .insert(privateLocationToMonitors) + .values({ privateLocationId: otherLoc.id, monitorId: otherMonitor.id }) + .run(); }); afterAll(async () => { - await db - .delete(monitorTagsToMonitors) - .where(eq(monitorTagsToMonitors.monitorTagId, tagId)); - await db.delete(monitorTag).where(eq(monitorTag.id, tagId)); await db .delete(privateLocationToMonitors) .where( - eq( - privateLocationToMonitors.privateLocationId, + inArray(privateLocationToMonitors.privateLocationId, [ + otherWorkspacePrivateLocationId, ownWorkspacePrivateLocationId, - ), - ); + ]), + ) + .catch(() => undefined); await db .delete(privateLocation) - .where(eq(privateLocation.id, otherWorkspacePrivateLocationId)); + .where( + inArray(privateLocation.id, [ + otherWorkspacePrivateLocationId, + ownWorkspacePrivateLocationId, + ]), + ) + .catch(() => undefined); await db - .delete(privateLocation) - .where(eq(privateLocation.id, ownWorkspacePrivateLocationId)); + .delete(monitorTagsToMonitors) + .where(eq(monitorTagsToMonitors.monitorTagId, tagId)) + .catch(() => undefined); + await db + .delete(monitorTag) + .where(eq(monitorTag.id, tagId)) + .catch(() => undefined); + await db + .delete(notificationsToMonitors) + .where(eq(notificationsToMonitors.notificationId, notifierId)) + .catch(() => undefined); + await db + .delete(notification) + .where(eq(notification.id, notifierId)) + .catch(() => undefined); + await db + .delete(workspace) + .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) + .catch(() => undefined); }); test("monitor.updateTags rejects monitor from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { - await caller.monitor.updateTags({ id: 5, tags: [] }); + await caller.monitor.updateTags({ id: otherMonitorId, tags: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -92,34 +161,22 @@ test("monitor.updateTags rejects monitor from another workspace", async () => { }); test("monitor.updateTags succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); - await caller.monitor.updateTags({ id: 1, tags: [tagId] }); + await caller.monitor.updateTags({ id: ownMonitorId, tags: [tagId] }); const result = await db.query.monitorTagsToMonitors.findFirst({ - where: eq(monitorTagsToMonitors.monitorId, 1), + where: eq(monitorTagsToMonitors.monitorId, ownMonitorId), }); expect(result).toBeDefined(); expect(result?.monitorTagId).toBe(tagId); }); test("monitor.updateNotifiers rejects monitor from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { - await caller.monitor.updateNotifiers({ id: 5, notifiers: [] }); + await caller.monitor.updateNotifiers({ id: otherMonitorId, notifiers: [] }); throw new Error("Should have thrown"); } catch (e) { expect(e).toBeInstanceOf(TRPCError); @@ -128,36 +185,26 @@ test("monitor.updateNotifiers rejects monitor from another workspace", async () }); test("monitor.updateNotifiers succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); - await caller.monitor.updateNotifiers({ id: 1, notifiers: [1] }); + await caller.monitor.updateNotifiers({ + id: ownMonitorId, + notifiers: [notifierId], + }); }); test("monitor.updateSchedulingRegions rejects monitor from another workspace", async () => { - // Monitor 5 belongs to workspace 3; try to update it from workspace 1 - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); // Verify the seed private location association exists before the attack const before = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 5), + where: eq(privateLocationToMonitors.monitorId, otherMonitorId), }); const beforeCount = before.length; try { await caller.monitor.updateSchedulingRegions({ - id: 5, + id: otherMonitorId, regions: ["ams"], periodicity: "30s", privateLocations: [], @@ -170,23 +217,16 @@ test("monitor.updateSchedulingRegions rejects monitor from another workspace", a // Verify private location associations were NOT deleted const after = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 5), + where: eq(privateLocationToMonitors.monitorId, otherMonitorId), }); expect(after.length).toBe(beforeCount); }); test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); - // Monitor 1 belongs to workspace 1 await caller.monitor.updateSchedulingRegions({ - id: 1, + id: ownMonitorId, regions: ["ams"], periodicity: "1m", privateLocations: [], @@ -194,20 +234,14 @@ test("monitor.updateSchedulingRegions succeeds for own workspace monitor", async }); test("monitor.updateSchedulingRegions rejects privateLocations from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); try { await caller.monitor.updateSchedulingRegions({ - id: 1, // own monitor + id: ownMonitorId, regions: ["ams"], periodicity: "1m", - privateLocations: [otherWorkspacePrivateLocationId], // workspace 2 + privateLocations: [otherWorkspacePrivateLocationId], }); throw new Error("Should have thrown"); } catch (e) { @@ -217,23 +251,17 @@ test("monitor.updateSchedulingRegions rejects privateLocations from another work }); test("monitor.updateSchedulingRegions succeeds with own workspace privateLocations", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1, limits: allPlans.team.limits }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(allPlans.team.limits); await caller.monitor.updateSchedulingRegions({ - id: 1, + id: ownMonitorId, regions: ["ams"], periodicity: "1m", privateLocations: [ownWorkspacePrivateLocationId], }); const associations = await db.query.privateLocationToMonitors.findMany({ - where: eq(privateLocationToMonitors.monitorId, 1), + where: eq(privateLocationToMonitors.monitorId, ownMonitorId), }); const linked = associations.find( (a) => a.privateLocationId === ownWorkspacePrivateLocationId, diff --git a/packages/api/src/router/notification.test.ts b/packages/api/src/router/notification.test.ts index d458ca28..a0ef37bf 100644 --- a/packages/api/src/router/notification.test.ts +++ b/packages/api/src/router/notification.test.ts @@ -1,10 +1,10 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index 7137893e..e7b069f6 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -32,10 +32,6 @@ import { env } from "../env"; import { toServiceCtx, toTRPCError } from "../service-adapter"; import { createTRPCRouter, protectedProcedure } from "../trpc"; -if (process.env.NODE_ENV === "test") { - require("../test/preload"); -} - // Vercel domain helpers — transport-layer external integrations that // don't belong in the service layer. async function addDomainToVercel(domain: string) { diff --git a/packages/api/src/router/pageComponent.test.ts b/packages/api/src/router/pageComponent.test.ts index c14e9f5e..187cef84 100644 --- a/packages/api/src/router/pageComponent.test.ts +++ b/packages/api/src/router/pageComponent.test.ts @@ -1,8 +1,8 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/privateLocation.test.ts b/packages/api/src/router/privateLocation.test.ts index 19e39485..c621f351 100644 --- a/packages/api/src/router/privateLocation.test.ts +++ b/packages/api/src/router/privateLocation.test.ts @@ -1,25 +1,61 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - -import { db, eq } from "@openstatus/db"; +import { db, eq, inArray } from "@openstatus/db"; import { privateLocation, privateLocationToMonitors, + workspace, } from "@openstatus/db/src/schema"; +import { + createMonitor, + createWorkspace, +} from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; +// Passing both `user` and `workspace` trips the NODE_ENV=test escape hatch in +// the authed middleware, so the caller is scoped to ownWorkspaceId instead of +// resolving the seeded workspace for the session user. +function callerFor() { + const ctx = createInnerTRPCContext({ + req: undefined, + session: { user: { id: "1" } }, + // @ts-expect-error - minimal user for test + user: { id: 1 }, + // @ts-expect-error - minimal workspace for test + workspace: { id: ownWorkspaceId }, + }); + return edgeRouter.createCaller(ctx); +} + +// Own workspaces/monitors per suite — sharing the seeded monitor 5 / workspace +// 3 races sibling suites that read or mutate that monitor's associations. +let ownWorkspaceId: number; +let otherWorkspaceId: number; +let ownMonitorId: number; +let otherMonitorId: number; let otherWorkspaceLocationId: number; let ownWorkspaceLocationId: number; beforeAll(async () => { + const own = await createWorkspace(); + const other = await createWorkspace(); + ownWorkspaceId = own.id; + otherWorkspaceId = other.id; + + const ownMonitor = await createMonitor(own.id); + const otherMonitor = await createMonitor(other.id); + ownMonitorId = ownMonitor.id; + otherMonitorId = otherMonitor.id; + const otherLoc = await db .insert(privateLocation) .values({ - workspaceId: 3, + workspaceId: other.id, name: "Other workspace location", - token: "test-token-idor", + token: `test-token-idor-${otherWorkspaceId}`, }) .returning() .get(); @@ -29,16 +65,16 @@ beforeAll(async () => { .insert(privateLocationToMonitors) .values({ privateLocationId: otherWorkspaceLocationId, - monitorId: 5, + monitorId: otherMonitorId, }) .run(); const ownLoc = await db .insert(privateLocation) .values({ - workspaceId: 1, + workspaceId: own.id, name: "Own workspace location", - token: "test-token-own", + token: `test-token-own-${ownWorkspaceId}`, }) .returning() .get(); @@ -49,29 +85,29 @@ afterAll(async () => { await db .delete(privateLocationToMonitors) .where( - eq(privateLocationToMonitors.privateLocationId, otherWorkspaceLocationId), - ); + inArray(privateLocationToMonitors.privateLocationId, [ + otherWorkspaceLocationId, + ownWorkspaceLocationId, + ]), + ) + .catch(() => undefined); await db .delete(privateLocation) - .where(eq(privateLocation.id, otherWorkspaceLocationId)); - await db - .delete(privateLocationToMonitors) .where( - eq(privateLocationToMonitors.privateLocationId, ownWorkspaceLocationId), - ); + inArray(privateLocation.id, [ + otherWorkspaceLocationId, + ownWorkspaceLocationId, + ]), + ) + .catch(() => undefined); await db - .delete(privateLocation) - .where(eq(privateLocation.id, ownWorkspaceLocationId)); + .delete(workspace) + .where(inArray(workspace.id, [ownWorkspaceId, otherWorkspaceId])) + .catch(() => undefined); }); test("privateLocation.update rejects location from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.update({ @@ -96,18 +132,12 @@ test("privateLocation.update rejects location from another workspace", async () }); test("privateLocation.update succeeds for own workspace location", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); const result = await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [1], + monitors: [ownMonitorId], }); expect(result).toBeDefined(); @@ -115,19 +145,13 @@ test("privateLocation.update succeeds for own workspace location", async () => { }); test("privateLocation.new rejects monitors from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.new({ name: "Injected Location", token: "test-token-inject", - monitors: [5], // monitor 5 belongs to workspace 3 + monitors: [otherMonitorId], }); throw new Error("Should have thrown"); } catch (e) { @@ -137,18 +161,12 @@ test("privateLocation.new rejects monitors from another workspace", async () => }); test("privateLocation.new succeeds with own workspace monitors", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); const result = await caller.privateLocation.new({ name: "Valid Location", token: "test-token-valid-new", - monitors: [1], // monitor 1 belongs to workspace 1 + monitors: [ownMonitorId], }); expect(result).toBeDefined(); @@ -159,7 +177,7 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { where: eq(privateLocationToMonitors.privateLocationId, result.id), }); expect(associations.length).toBe(1); - expect(associations[0].monitorId).toBe(1); + expect(associations[0].monitorId).toBe(ownMonitorId); // Cleanup await db @@ -169,19 +187,13 @@ test("privateLocation.new succeeds with own workspace monitors", async () => { }); test("privateLocation.update rejects monitors from another workspace", async () => { - const ctx = createInnerTRPCContext({ - req: undefined, - session: { user: { id: "1" } }, - // @ts-expect-error - minimal workspace for test - workspace: { id: 1 }, - }); - const caller = edgeRouter.createCaller(ctx); + const caller = callerFor(); try { await caller.privateLocation.update({ id: ownWorkspaceLocationId, name: "Updated Location Name", - monitors: [5], // monitor 5 belongs to workspace 3 + monitors: [otherMonitorId], }); throw new Error("Should have thrown"); } catch (e) { diff --git a/packages/api/src/router/statusPage.e2e.test.ts b/packages/api/src/router/statusPage.e2e.test.ts index 1baab894..79c611ab 100644 --- a/packages/api/src/router/statusPage.e2e.test.ts +++ b/packages/api/src/router/statusPage.e2e.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, isNotNull, isNull } from "@openstatus/db"; import { incidentTable, @@ -9,6 +7,8 @@ import { pageSubscriber, workspace, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; /** * End-to-end integration tests for the full unsubscribe flow. @@ -213,6 +213,7 @@ describe("Confirmation page displays correct information", () => { } const email = subscriber.email; + if (!email) throw new Error("Subscriber email not found"); expect(email).toBe("confirm-page-test@example.com"); // Apply the same masking logic as in the API diff --git a/packages/api/src/router/statusPage.unsubscribe.test.ts b/packages/api/src/router/statusPage.unsubscribe.test.ts index 9800d3fc..8cb66d5f 100644 --- a/packages/api/src/router/statusPage.unsubscribe.test.ts +++ b/packages/api/src/router/statusPage.unsubscribe.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; // Test data setup let testPageId: number; diff --git a/packages/api/src/router/statusPage.utils.test.ts b/packages/api/src/router/statusPage.utils.test.ts index 15baf720..1961e85f 100644 --- a/packages/api/src/router/statusPage.utils.test.ts +++ b/packages/api/src/router/statusPage.utils.test.ts @@ -1,5 +1,3 @@ -import { describe, expect, it } from "bun:test"; - import type { Incident, Maintenance, @@ -7,6 +5,8 @@ import type { StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { currentImpactByComponent, diff --git a/packages/api/src/router/statusReport.test.ts b/packages/api/src/router/statusReport.test.ts index 2175fbf4..1c63e8eb 100644 --- a/packages/api/src/router/statusReport.test.ts +++ b/packages/api/src/router/statusReport.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { page, @@ -9,6 +7,8 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import { clearAuditLogFor } from "@openstatus/services/test/helpers"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../edge"; diff --git a/packages/api/src/router/stripe/utils.test.ts b/packages/api/src/router/stripe/utils.test.ts index 02299b1b..048fd6b5 100644 --- a/packages/api/src/router/stripe/utils.test.ts +++ b/packages/api/src/router/stripe/utils.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import { getLimits } from "@openstatus/db/src/schema/plan/utils"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type Stripe from "stripe"; import { FEATURES, PLANS, buildLimitsFromSubscription } from "./utils"; diff --git a/packages/api/src/router/tinybird/index.test.ts b/packages/api/src/router/tinybird/index.test.ts index 759d92c6..66805529 100644 --- a/packages/api/src/router/tinybird/index.test.ts +++ b/packages/api/src/router/tinybird/index.test.ts @@ -1,5 +1,5 @@ -import { expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { TRPCError } from "@trpc/server"; import { edgeRouter } from "../../edge"; diff --git a/packages/api/src/router/workspace.test.ts b/packages/api/src/router/workspace.test.ts index 02b14002..3812aff7 100644 --- a/packages/api/src/router/workspace.test.ts +++ b/packages/api/src/router/workspace.test.ts @@ -1,4 +1,5 @@ -import { expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { test } from "@std/testing/bdd"; import { edgeRouter } from "../edge"; import { createInnerTRPCContext } from "../trpc"; diff --git a/packages/api/src/test/preload.ts b/packages/api/src/test/preload.ts deleted file mode 100644 index 4d43b6ff..00000000 --- a/packages/api/src/test/preload.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { mock } from "bun:test"; - -mock.module("@openstatus/upstash", () => ({ - Redis: { - fromEnv() { - return { - get: () => Promise.resolve(undefined), - set: () => Promise.resolve([]), - }; - }, - }, -})); diff --git a/packages/api/src/test/upstash.mock.ts b/packages/api/src/test/upstash.mock.ts new file mode 100644 index 00000000..7aa2e846 --- /dev/null +++ b/packages/api/src/test/upstash.mock.ts @@ -0,0 +1,18 @@ +// Test double for @openstatus/upstash, swapped in via --import-map in the +// `deno test` command. Keeps tests off a real Upstash Redis instance. +const noopRedis = { + get: () => Promise.resolve(null), + set: () => Promise.resolve("OK"), + del: () => Promise.resolve(0), + getdel: () => Promise.resolve(null), + incr: () => Promise.resolve(1), + expire: () => Promise.resolve(1), +}; + +export const redis = noopRedis; + +export const Redis = { + fromEnv() { + return noopRedis; + }, +}; diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts index 4e380ee0..d8225921 100644 --- a/packages/api/src/trpc.ts +++ b/packages/api/src/trpc.ts @@ -7,7 +7,7 @@ import { import { db } from "@openstatus/db"; import type { User, Workspace } from "@openstatus/db/src/schema"; import { TRPCError, initTRPC } from "@trpc/server"; -import { type NextRequest, after } from "next/server"; +import { type NextRequest, after } from "next/server.js"; import superjson from "superjson"; import { ZodError, treeifyError } from "zod"; diff --git a/packages/api/test.importmap.json b/packages/api/test.importmap.json new file mode 100644 index 00000000..94b18545 --- /dev/null +++ b/packages/api/test.importmap.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@openstatus/upstash": "./src/test/upstash.mock.ts" + } +} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index 15860ea1..48baa5cf 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -1,8 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "moduleResolution": "bundler", - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/assertions/package.json b/packages/assertions/package.json index 0472bd9f..79323a62 100644 --- a/packages/assertions/package.json +++ b/packages/assertions/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "jsonpath-plus": "catalog:", "zod": "catalog:" diff --git a/packages/assertions/src/v1.ts b/packages/assertions/src/v1.ts index 0b7ea37d..9b480988 100644 --- a/packages/assertions/src/v1.ts +++ b/packages/assertions/src/v1.ts @@ -309,7 +309,7 @@ export class HeaderAssertion implements Assertion { }; } const { success, message } = evaluateString( - req.header[this.schema.key], + req.header[this.schema.key] ?? "", this.schema.compare, this.schema.target, ); diff --git a/packages/assertions/tsconfig.json b/packages/assertions/tsconfig.json index ec9f2821..aed15c74 100644 --- a/packages/assertions/tsconfig.json +++ b/packages/assertions/tsconfig.json @@ -1,7 +1,4 @@ { "extends": "@openstatus/tsconfig/base.json", - "compilerOptions": { - "lib": ["es2015", "dom"] - }, "include": ["src", "*.ts"] } diff --git a/packages/db/env.ts b/packages/db/env.ts index dbb28b16..dab63f5f 100644 --- a/packages/db/env.ts +++ b/packages/db/env.ts @@ -1,2 +1 @@ -const file = Bun.file("./.env.example"); -await Bun.write("./.env", file); +await Deno.copyFile("./.env.example", "./.env"); diff --git a/packages/db/package.json b/packages/db/package.json index a08d4abc..8e7d6d38 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -4,13 +4,27 @@ "description": "", "author": "OpenStatus", "main": "src/index.ts", + "exports": { + ".": "./src/index.ts", + "./env.mjs": "./env.mjs", + "./src/schema": "./src/schema/index.ts", + "./src/test/factories": "./src/test/factories.ts", + "./src/schema/api-keys": "./src/schema/api-keys/index.ts", + "./src/schema/check": "./src/schema/check/index.ts", + "./src/schema/incidents": "./src/schema/incidents/index.ts", + "./src/schema/maintenances": "./src/schema/maintenances/index.ts", + "./src/schema/page_components": "./src/schema/page_components/index.ts", + "./src/schema/workspaces": "./src/schema/workspaces/index.ts", + "./src/*": "./src/*.ts" + }, "scripts": { + "check": "deno check --sloppy-imports .", "generate": "drizzle-kit generate", "push": "drizzle-kit push", - "migrate": "bun src/migrate.mts", + "migrate": "deno run -A --env-file src/migrate.mts", "studio": "drizzle-kit studio", - "env": "bun env.ts", - "seed": "bun src/seed.mts", + "env": "deno run -A env.ts", + "seed": "deno run -A --env-file --sloppy-imports src/seed.mts", "dev": "turso dev --db-file ../../openstatus-dev.db" }, "dependencies": { @@ -28,6 +42,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/bcryptjs": "catalog:", "@types/node": "catalog:", "drizzle-kit": "catalog:", diff --git a/packages/db/script/region-migration.test.ts b/packages/db/script/region-migration.test.ts index b9e3bc60..f52fd0eb 100644 --- a/packages/db/script/region-migration.test.ts +++ b/packages/db/script/region-migration.test.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { beforeEach, describe, test } from "@std/testing/bdd"; import type { z } from "zod"; import type { monitorRegionSchema } from "../src/schema/constants"; diff --git a/packages/db/src/schema/page_components/validation.ts b/packages/db/src/schema/page_components/validation.ts index 71188c42..fae44fbd 100644 --- a/packages/db/src/schema/page_components/validation.ts +++ b/packages/db/src/schema/page_components/validation.ts @@ -10,7 +10,7 @@ import { export const selectPageComponentSchema = createSelectSchema(pageComponent); export const insertPageComponentSchema = createInsertSchema(pageComponent, { - name: (schema) => schema.min(1), + name: z.string().min(1), }).refine( (data) => { // monitorId must be set when type='monitor' diff --git a/packages/db/src/seed.mts b/packages/db/src/seed.mts index bdc4cf4d..8e126471 100644 --- a/packages/db/src/seed.mts +++ b/packages/db/src/seed.mts @@ -24,9 +24,35 @@ import { import { externalServicesSeed } from "./seed/external-services"; async function main() { - const db = drizzle( - createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN }), + if ( + !env.DATABASE_URL.includes("localhost") && + !env.DATABASE_URL.includes("127.0.0.1") + ) { + throw new Error( + `Refusing to wipe non-local database: DATABASE_URL=${env.DATABASE_URL}`, + ); + } + + const client = createClient({ + url: env.DATABASE_URL, + authToken: env.DATABASE_AUTH_TOKEN, + }); + const db = drizzle(client); + + // Fresh slate: wipe every table so re-seeding is idempotent and tests never + // inherit residue from a previous run. `defer_foreign_keys` lets us delete in + // any order within the transaction (all tables end empty, so FKs hold at commit). + const tables = await client.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name != '__drizzle_migrations'", ); + await client.batch( + [ + "PRAGMA defer_foreign_keys=ON", + ...tables.rows.map((row) => `DELETE FROM "${row.name}"`), + ], + "write", + ); + console.log("Seeding database "); await db .insert(workspace) diff --git a/packages/db/src/test/factories.ts b/packages/db/src/test/factories.ts new file mode 100644 index 00000000..72b4d2d2 --- /dev/null +++ b/packages/db/src/test/factories.ts @@ -0,0 +1,50 @@ +// Test data factories: create fresh, uniquely-identified resources so suites +// don't collide on shared seed IDs (workspace 1, monitors 1-3, …). Each call +// inserts a row with an auto-increment id and unique slug/name, then returns +// it — scope the test to the returned id and clean up in afterAll. +// +// Pass a transaction as the last arg to scope creation to it (e.g. inside a +// rolled-back `withTestTransaction`); omit it to commit to the shared db. +import { db as defaultDb } from "../db"; +import { monitor, workspace } from "../schema"; + +type Db = typeof defaultDb; +type WorkspaceInsert = typeof workspace.$inferInsert; +type MonitorInsert = typeof monitor.$inferInsert; + +const unique = () => crypto.randomUUID().slice(0, 8); + +export async function createWorkspace( + overrides: Partial = {}, + db: Db = defaultDb, +) { + const u = unique(); + const [row] = await db + .insert(workspace) + .values({ + slug: `test-ws-${u}`, + name: "Test Workspace", + stripeId: `test-stripe-${u}`, + plan: "team", + ...overrides, + }) + .returning(); + return row; +} + +export async function createMonitor( + workspaceId: number, + overrides: Partial = {}, + db: Db = defaultDb, +) { + const [row] = await db + .insert(monitor) + .values({ + workspaceId, + url: "https://example.openstatus.dev", + name: `test-monitor-${unique()}`, + ...overrides, + }) + .returning(); + return row; +} diff --git a/packages/db/src/utils/api-key.test.ts b/packages/db/src/utils/api-key.test.ts index 63971b5c..8fae1da2 100644 --- a/packages/db/src/utils/api-key.test.ts +++ b/packages/db/src/utils/api-key.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { generateApiKey, diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index c3ede090..122f1a76 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -5,7 +5,6 @@ "compilerOptions": { "outDir": "dist", "target": "es2021", - "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "checkJs": true, "skipLibCheck": true, diff --git a/packages/emails/package.json b/packages/emails/package.json index 849cc2a9..229b1c93 100644 --- a/packages/emails/package.json +++ b/packages/emails/package.json @@ -6,9 +6,15 @@ "license": "ISC", "author": "", "main": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./src/client": "./src/client.tsx", + "./src/*": "./src/*.ts" + }, "scripts": { + "check": "deno check --sloppy-imports .", "dev:email": "email dev", - "test": "bun test" + "test": "deno test --parallel -A --no-check --sloppy-imports" }, "dependencies": { "@t3-oss/env-core": "catalog:", @@ -21,6 +27,8 @@ "devDependencies": { "@openstatus/tsconfig": "workspace:*", "@react-email/ui": "catalog:", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "typescript": "catalog:" diff --git a/packages/emails/src/client.integration.test.tsx b/packages/emails/src/client.integration.test.tsx index 9733456f..9de77175 100644 --- a/packages/emails/src/client.integration.test.tsx +++ b/packages/emails/src/client.integration.test.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource react */ -import { describe, expect, test } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { render } from "react-email"; import StatusReportEmail from "../emails/status-report"; @@ -40,6 +40,7 @@ describe("Status Report Email - Unsubscribe Link in Body", () => { message="Test message" pageComponents={["Monitor 1"]} manageUrl={manageUrl} + unsubscribeUrl="" />, ); diff --git a/packages/emails/src/client.test.ts b/packages/emails/src/client.test.ts index cde4f7bf..59aa8292 100644 --- a/packages/emails/src/client.test.ts +++ b/packages/emails/src/client.test.ts @@ -1,4 +1,11 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { + assertSpyCalls, + returnsNext, + type Stub, + stub, +} from "@std/testing/mock"; import { EmailClient } from "./client"; @@ -35,8 +42,8 @@ const fail = { data: null, error: { name: "application_error" } } as any; describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { let client: EmailClient; - // biome-ignore lint/suspicious/noExplicitAny: bun spy handle - let batchSend: any; + // biome-ignore lint/suspicious/noExplicitAny: stub over the Resend batch method + let batchSend: Stub; beforeEach(() => { // zero backoff so the retry test doesn't wait on the real exponential sleep @@ -44,11 +51,11 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { apiKey: "re_test_123", retryBackoff: "0 millis", }); - batchSend = spyOn(client.client.batch, "send").mockResolvedValue(ok); + batchSend = stub(client.client.batch, "send", () => Promise.resolve(ok)); }); afterEach(() => { - batchSend.mockRestore(); + batchSend.restore(); }); test("passes the base idempotency key suffixed with the batch index", async () => { @@ -56,8 +63,8 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { baseReq({ idempotencyKey: "status-report-update:5" }), ); - expect(batchSend).toHaveBeenCalledTimes(1); - const [, options] = batchSend.mock.calls[0]; + assertSpyCalls(batchSend, 1); + const options = batchSend.calls[0].args[1]; expect(options).toEqual({ idempotencyKey: "status-report-update:5:0" }); }); @@ -69,32 +76,31 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { }), ); - expect(batchSend).toHaveBeenCalledTimes(3); - const keys = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([, o]: [unknown, any]) => o?.idempotencyKey, - ); + assertSpyCalls(batchSend, 3); + const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); expect(keys).toEqual([ "status-report-update:9:0", "status-report-update:9:1", "status-report-update:9:2", ]); - const sizes = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([payload]: [any[]]) => payload.length, - ); + const sizes = batchSend.calls.map((c) => c.args[0].length); expect(sizes).toEqual([100, 100, 50]); }); test("omits the option entirely when no base key is provided", async () => { await client.sendStatusReportUpdate(baseReq()); - const [, options] = batchSend.mock.calls[0]; + const options = batchSend.calls[0].args[1]; expect(options).toBeUndefined(); }); test("reuses the same key across a retry so Resend dedupes the resend", async () => { - batchSend.mockResolvedValueOnce(fail).mockResolvedValueOnce(ok); + batchSend.restore(); + batchSend = stub( + client.client.batch, + "send", + returnsNext([Promise.resolve(fail), Promise.resolve(ok)]), + ); await client.sendStatusReportUpdate( baseReq({ idempotencyKey: "status-report-update:7" }), @@ -102,11 +108,8 @@ describe("EmailClient.sendStatusReportUpdate - idempotency & chunking", () => { // failure → retry: the second attempt must carry the identical key, or // Resend would treat the retry as a fresh batch and double-send. - expect(batchSend).toHaveBeenCalledTimes(2); - const keys = batchSend.mock.calls.map( - // biome-ignore lint/suspicious/noExplicitAny: positional spy args - ([, o]: [unknown, any]) => o?.idempotencyKey, - ); + assertSpyCalls(batchSend, 2); + const keys = batchSend.calls.map((c) => c.args[1]?.idempotencyKey); expect(keys).toEqual([ "status-report-update:7:0", "status-report-update:7:0", diff --git a/packages/emails/tsconfig.json b/packages/emails/tsconfig.json index e29f2150..39fe813f 100644 --- a/packages/emails/tsconfig.json +++ b/packages/emails/tsconfig.json @@ -1,5 +1,9 @@ { - "extends": "@openstatus/tsconfig/react-library.json", + "extends": "@openstatus/tsconfig/base.json", "include": [".", "src/env.ts"], - "exclude": ["dist", "build", "node_modules"] + "exclude": ["dist", "build", "node_modules"], + "compilerOptions": { + "jsx": "react-jsx", + "resolveJsonModule": true + } } diff --git a/packages/error/package.json b/packages/error/package.json index fd9fe953..ab7f55bc 100644 --- a/packages/error/package.json +++ b/packages/error/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "zod": "catalog:" }, diff --git a/packages/header-analysis/package.json b/packages/header-analysis/package.json index ac5d1eef..8efdb62f 100644 --- a/packages/header-analysis/package.json +++ b/packages/header-analysis/package.json @@ -7,13 +7,15 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test", - "test:watch": "bun test --watch" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch" }, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/header-analysis/src/parser/x-vercel-cache.test.ts b/packages/header-analysis/src/parser/x-vercel-cache.test.ts index eb464af7..2780dd22 100644 --- a/packages/header-analysis/src/parser/x-vercel-cache.test.ts +++ b/packages/header-analysis/src/parser/x-vercel-cache.test.ts @@ -1,19 +1,22 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { parseXVercelCache } from "./x-vercel-cache"; describe("parseXVercelCache", () => { - it.each([ + for (const [value, expectedFragment] of [ ["MISS", "The response was not found in the edge cache"], ["HIT", "The response was served from the edge cache."], ["STALE", "A background request to the origin server"], ["PRERENDER", "The response was served from static storage."], ["REVALIDATED", "the cache was refreshed"], - ])("describes the documented state %p", (value, expectedFragment) => { - const result = parseXVercelCache(value); - expect(result.value).toBe(value); - expect(result.description).toContain(expectedFragment); - }); + ]) { + it(`describes the documented state ${value}`, () => { + const result = parseXVercelCache(value); + expect(result.value).toBe(value); + expect(result.description).toContain(expectedFragment); + }); + } it("matches states case-insensitively", () => { const lower = parseXVercelCache("revalidated"); diff --git a/packages/icons/package.json b/packages/icons/package.json index f50ea616..889ca2a4 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -5,6 +5,7 @@ "main": "./src/index.tsx", "types": "./src/index.tsx", "scripts": { + "check": "deno check --sloppy-imports .", "lint": "oxlint" }, "dependencies": { diff --git a/packages/importers/package.json b/packages/importers/package.json index 894f486a..9d82d995 100644 --- a/packages/importers/package.json +++ b/packages/importers/package.json @@ -14,8 +14,9 @@ "./instatus/fixtures": "./src/providers/instatus/fixtures.ts" }, "scripts": { - "test": "bun test", - "test:watch": "bun test --watch", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -23,6 +24,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/importers/src/providers/betterstack/client.test.ts b/packages/importers/src/providers/betterstack/client.test.ts index 7b13f5dd..fbcd501e 100644 --- a/packages/importers/src/providers/betterstack/client.test.ts +++ b/packages/importers/src/providers/betterstack/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import { createBetterstackClient } from "./client"; import { @@ -16,7 +18,7 @@ const originalFetch = globalThis.fetch; function mockFetchPaginated(data: unknown[], status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const items = callCount === 1 ? data : []; const body = { @@ -39,7 +41,7 @@ function mockFetchPaginated(data: unknown[], status = 200) { } function mockFetchError(status: number, statusText: string) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify({ error: statusText }), { status, @@ -143,9 +145,9 @@ describe("BetterstackClient", () => { test("sends correct auth header", async () => { mockFetchPaginated(MOCK_MONITORS); await client.getMonitors(); - const fetchMock = globalThis.fetch as ReturnType; - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + assertSpyCalls(fetchMock, 1); + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://uptime.betterstack.com/api/v2/monitors"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -154,7 +156,7 @@ describe("BetterstackClient", () => { test("follows pagination.next for multiple pages", async () => { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 diff --git a/packages/importers/src/providers/betterstack/mapper.test.ts b/packages/importers/src/providers/betterstack/mapper.test.ts index e4e23875..70dfab13 100644 --- a/packages/importers/src/providers/betterstack/mapper.test.ts +++ b/packages/importers/src/providers/betterstack/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { MOCK_INCIDENTS, diff --git a/packages/importers/src/providers/betterstack/provider.test.ts b/packages/importers/src/providers/betterstack/provider.test.ts index 9ef88f33..28aa0545 100644 --- a/packages/importers/src/providers/betterstack/provider.test.ts +++ b/packages/importers/src/providers/betterstack/provider.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { MOCK_INCIDENTS, @@ -24,7 +26,7 @@ function makePaginated(data: unknown[]) { } function setupMockFetch() { - globalThis.fetch = mock((url: string) => { + globalThis.fetch = spy((url: string) => { const path = new URL(url as string).pathname; let body: unknown; @@ -86,7 +88,7 @@ describe("BetterstackProvider", () => { }); test("validate returns friendly 401 error", async () => { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, diff --git a/packages/importers/src/providers/instatus/client.test.ts b/packages/importers/src/providers/instatus/client.test.ts index 7bdcbf17..79edfe00 100644 --- a/packages/importers/src/providers/instatus/client.test.ts +++ b/packages/importers/src/providers/instatus/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { createInstatusClient } from "./client"; import { @@ -12,7 +14,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -25,7 +27,7 @@ function mockFetch(data: unknown, status = 200) { function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -107,8 +109,8 @@ describe("InstatusClient", () => { test("sends correct Bearer auth header", async () => { mockFetchPaginated(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.instatus.com/v2/pages?page=1&per_page=100"); expect((options.headers as Record).Authorization).toBe( "Bearer test-api-key", @@ -124,7 +126,7 @@ describe("InstatusClient", () => { })); let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; // First call: 100 items (= per_page), second call: empty array const body = callCount === 1 ? items : []; @@ -145,8 +147,8 @@ describe("InstatusClient", () => { test("uses v1 for incidents and v2 for other endpoints", async () => { mockFetchPaginated(MOCK_INCIDENTS); await client.getIncidents("in_page_001"); - const fetchMock = globalThis.fetch as unknown as ReturnType; - const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toContain("/v1/in_page_001/incidents"); }); }); diff --git a/packages/importers/src/providers/instatus/mapper.test.ts b/packages/importers/src/providers/instatus/mapper.test.ts index 8b008a57..17a95994 100644 --- a/packages/importers/src/providers/instatus/mapper.test.ts +++ b/packages/importers/src/providers/instatus/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, @@ -112,14 +113,16 @@ describe("mapComponent", () => { }); describe("mapIncidentStatus", () => { - it.each([ + for (const [input, expected] of [ ["INVESTIGATING", "investigating"], ["IDENTIFIED", "identified"], ["MONITORING", "monitoring"], ["RESOLVED", "resolved"], - ] as const)("maps %s to %s", (input, expected) => { - expect(mapIncidentStatus(input)).toBe(expected); - }); + ] as const) { + it(`maps ${input} to ${expected}`, () => { + expect(mapIncidentStatus(input)).toBe(expected); + }); + } it("defaults to investigating for unknown status", () => { expect(mapIncidentStatus("UNKNOWN")).toBe("investigating"); diff --git a/packages/importers/src/providers/instatus/provider.test.ts b/packages/importers/src/providers/instatus/provider.test.ts index 17b961e8..0b904b36 100644 --- a/packages/importers/src/providers/instatus/provider.test.ts +++ b/packages/importers/src/providers/instatus/provider.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, diff --git a/packages/importers/src/providers/statuspage/client.test.ts b/packages/importers/src/providers/statuspage/client.test.ts index d057a5b3..79b7c7fc 100644 --- a/packages/importers/src/providers/statuspage/client.test.ts +++ b/packages/importers/src/providers/statuspage/client.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import { createStatuspageClient } from "./client"; import { @@ -12,7 +14,7 @@ import { const originalFetch = globalThis.fetch; function mockFetch(data: unknown, status = 200) { - globalThis.fetch = mock(() => + globalThis.fetch = spy(() => Promise.resolve( new Response(JSON.stringify(data), { status, @@ -28,7 +30,7 @@ function mockFetch(data: unknown, status = 200) { */ function mockFetchPaginated(data: unknown, status = 200) { let callCount = 0; - globalThis.fetch = mock(() => { + globalThis.fetch = spy(() => { callCount++; const body = callCount === 1 ? data : []; return Promise.resolve( @@ -117,8 +119,8 @@ describe("StatuspageClient", () => { test("getPage calls correct URL path", async () => { mockFetch(MOCK_PAGES[0]); await client.getPage("sp_page_001"); - const fetchMock = globalThis.fetch as ReturnType; - const [url] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + const [url] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages/sp_page_001"); }); @@ -137,9 +139,9 @@ describe("StatuspageClient", () => { test("sends correct auth header", async () => { mockFetch(MOCK_PAGES); await client.getPages(); - const fetchMock = globalThis.fetch as ReturnType; - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; + const fetchMock = globalThis.fetch as unknown as ReturnType; + assertSpyCalls(fetchMock, 1); + const [url, options] = fetchMock.calls[0].args as [string, RequestInit]; expect(url).toBe("https://api.statuspage.io/v1/pages"); expect((options.headers as Record).Authorization).toBe( "OAuth test-api-key", diff --git a/packages/importers/src/providers/statuspage/mapper.test.ts b/packages/importers/src/providers/statuspage/mapper.test.ts index 40f162f2..07b241b1 100644 --- a/packages/importers/src/providers/statuspage/mapper.test.ts +++ b/packages/importers/src/providers/statuspage/mapper.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, @@ -125,7 +126,7 @@ describe("mapIncidentToStatusReport", () => { }); describe("mapIncidentUpdateStatus", () => { - it.each([ + for (const [input, expected] of [ ["investigating", "investigating"], ["identified", "identified"], ["monitoring", "monitoring"], @@ -134,9 +135,11 @@ describe("mapIncidentUpdateStatus", () => { ["in_progress", "investigating"], ["verifying", "monitoring"], ["completed", "resolved"], - ] as const)("maps %s to %s", (input, expected) => { - expect(mapIncidentUpdateStatus(input)).toBe(expected); - }); + ] as const) { + it(`maps ${input} to ${expected}`, () => { + expect(mapIncidentUpdateStatus(input)).toBe(expected); + }); + } }); describe("mapIncidentToMaintenance", () => { diff --git a/packages/importers/src/providers/statuspage/provider.test.ts b/packages/importers/src/providers/statuspage/provider.test.ts index c0176167..3f314f05 100644 --- a/packages/importers/src/providers/statuspage/provider.test.ts +++ b/packages/importers/src/providers/statuspage/provider.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; import { MOCK_COMPONENTS, diff --git a/packages/locales/package.json b/packages/locales/package.json index 9a4556ff..33a91be0 100644 --- a/packages/locales/package.json +++ b/packages/locales/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "date-fns": "catalog:" }, diff --git a/packages/notifications/base/package.json b/packages/notifications/base/package.json index cd093dd2..25472b09 100644 --- a/packages/notifications/base/package.json +++ b/packages/notifications/base/package.json @@ -7,7 +7,8 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,8 +17,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/base/src/utils/duration.test.ts b/packages/notifications/base/src/utils/duration.test.ts index a89d4378..cd99abb7 100644 --- a/packages/notifications/base/src/utils/duration.test.ts +++ b/packages/notifications/base/src/utils/duration.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { calculateDuration, formatDuration } from "./duration"; diff --git a/packages/notifications/base/src/utils/incident.test.ts b/packages/notifications/base/src/utils/incident.test.ts index bfacd6a7..78b59a7c 100644 --- a/packages/notifications/base/src/utils/incident.test.ts +++ b/packages/notifications/base/src/utils/incident.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, it } from "bun:test"; - import type { Incident } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { getIncidentDuration } from "./incident"; @@ -22,7 +22,6 @@ function createIncident(overrides: Partial): Incident { describe("getIncidentDuration", () => { it("returns null when incident.startedAt is missing", () => { const incident = createIncident({ - startedAt: null, resolvedAt: new Date("2026-01-22T12:00:00Z"), }); expect(getIncidentDuration(incident)).toBe(null); diff --git a/packages/notifications/bird-whatsapp/package.json b/packages/notifications/bird-whatsapp/package.json index 98a77afb..5ea40620 100644 --- a/packages/notifications/bird-whatsapp/package.json +++ b/packages/notifications/bird-whatsapp/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/bird-whatsapp/src/index.test.ts b/packages/notifications/bird-whatsapp/src/index.test.ts index 043e81fb..ea2039ae 100644 --- a/packages/notifications/bird-whatsapp/src/index.test.ts +++ b/packages/notifications/bird-whatsapp/src/index.test.ts @@ -1,15 +1,8 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - spyOn, - test, -} from "bun:test"; - import type { Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; @@ -34,7 +27,7 @@ function createNotification() { }); } -function parseRequestBody(call: ReturnType): { +function parseRequestBody(call: Stub): { messageRequests: Array<{ receiver: { contacts: Array<{ identifierKey: string; identifierValue: string }>; @@ -47,22 +40,21 @@ function parseRequestBody(call: ReturnType): { }; }>; } { - const body = (call as ReturnType).mock.calls[0][1]?.body; + const body = call.calls[0].args[1]?.body; return JSON.parse(body as string); } describe("WhatsApp Notifications (Bird)", () => { - let fetchMock: ReturnType; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - jest.resetAllMocks(); + fetchMock.restore(); }); test("sendAlert calls Bird API with alert template", async () => { @@ -74,11 +66,11 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const url = fetchMock.mock.calls[0][0] as string; + assertSpyCalls(fetchMock, 1); + const url = fetchMock.calls[0].args[0] as string; expect(url).toMatch(BIRD_URL_PATTERN); - const options = fetchMock.mock.calls[0][1] as RequestInit; + const options = fetchMock.calls[0].args[1] as RequestInit; expect(options.headers).toHaveProperty("Authorization"); expect((options.headers as Record).Authorization).toMatch( /^AccessKey /, @@ -115,7 +107,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "2068001e-330d-4093-8d06-7071e9d34aa1", @@ -137,7 +129,7 @@ describe("WhatsApp Notifications (Bird)", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].template.projectId).toBe( "c9a842d9-cf9e-4a13-8cde-024d57e29143", @@ -153,7 +145,7 @@ describe("WhatsApp Notifications (Bird)", () => { test("sendTest calls Bird API with test template and openstat.us URL", async () => { await sendTest({ phoneNumber: "+33623456789" }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const body = parseRequestBody(fetchMock); expect(body.messageRequests[0].receiver.contacts[0].identifierValue).toBe( "+33623456789", diff --git a/packages/notifications/bird-whatsapp/tsconfig.json b/packages/notifications/bird-whatsapp/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/bird-whatsapp/tsconfig.json +++ b/packages/notifications/bird-whatsapp/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/discord/package.json b/packages/notifications/discord/package.json index 825b2786..90ff88ec 100644 --- a/packages/notifications/discord/package.json +++ b/packages/notifications/discord/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/discord/src/index.test.ts b/packages/notifications/discord/src/index.test.ts index 14169bbe..64c6ac7c 100644 --- a/packages/notifications/discord/src/index.test.ts +++ b/packages/notifications/discord/src/index.test.ts @@ -1,7 +1,8 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLOR_DECIMALS } from "@openstatus/notification-base"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { sendAlert, @@ -10,20 +11,18 @@ import { sendTestDiscordMessage, } from "./index"; +const ok = (): Promise => + Promise.resolve(new Response(null, { status: 200 })); + describe("Discord Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => - Promise.resolve(new Response(null, { status: 200 })), - ); + fetchMock = stub(globalThis, "fetch", ok); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -63,8 +62,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://discord.com/api/webhooks/123456789/abcdefgh", ); @@ -95,8 +94,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is recovered"); @@ -119,8 +118,8 @@ describe("Discord Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); expect(body.embeds[0].title).toContain("is degraded"); @@ -132,8 +131,8 @@ describe("Discord Notifications", () => { const webhookUrl = "https://discord.com/api/webhooks/123456789/abcdefgh"; await sendTestDiscordMessage(webhookUrl); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.embeds).toBeDefined(); @@ -142,11 +141,12 @@ describe("Discord Notifications", () => { test("Send Test Discord Message with empty webhookUrl", async () => { expect(sendTestDiscordMessage("")).rejects.toThrow(); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/discord/tsconfig.json b/packages/notifications/discord/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/discord/tsconfig.json +++ b/packages/notifications/discord/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/email/package.json b/packages/notifications/email/package.json index 7aee8b5b..6078ce1a 100644 --- a/packages/notifications/email/package.json +++ b/packages/notifications/email/package.json @@ -4,7 +4,8 @@ "description": "Log drains Vercel integration.", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -20,10 +21,10 @@ "zod": "catalog:" }, "devDependencies": { + "@openstatus/test-utils": "workspace:*", "@openstatus/tsconfig": "workspace:*", "@types/node": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/email/src/index.test.ts b/packages/notifications/email/src/index.test.ts index 16b88c71..7ea2c2a0 100644 --- a/packages/notifications/email/src/index.test.ts +++ b/packages/notifications/email/src/index.test.ts @@ -1,26 +1,31 @@ -import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; - +import "./test-preload.ts"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { EmailClient } from "@openstatus/emails/src/client"; +import { + afterEach, + assertSpyCalls, + beforeEach, + describe, + expect, + type Stub, + stub, + test, +} from "@openstatus/test-utils"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; -const sendMonitorAlertMock = mock(async (_callArgs) => {}); - -mock.module("@openstatus/emails/src/client", () => ({ - EmailClient: mock((_args: { apiKey: string }) => { - return { - sendMonitorAlert: sendMonitorAlertMock, - }; - }), -})); +// biome-ignore lint/suspicious/noExplicitAny: stub over the EmailClient method +let sendMonitorAlertMock: Stub; describe("Email Notifications", () => { beforeEach(() => { - sendMonitorAlertMock.mockClear(); + sendMonitorAlertMock = stub(EmailClient.prototype, "sendMonitorAlert", () => + Promise.resolve(), + ); }); afterEach(() => { - sendMonitorAlertMock.mockClear(); + sendMonitorAlertMock.restore(); }); const createMockMonitor = () => ({ @@ -62,8 +67,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.name).toBe("API Health Check"); expect(callArgs.type).toBe("alert"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -88,8 +93,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.status).toBeUndefined(); expect(callArgs.latency).toBe("N/A"); expect(callArgs.region).toBe("N/A"); @@ -111,8 +116,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("recovery"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.to).toBe("ping@openstatus.dev"); @@ -137,8 +142,8 @@ describe("Email Notifications", () => { cronTimestamp: Date.now(), }); - expect(sendMonitorAlertMock).toHaveBeenCalledTimes(1); - const callArgs = sendMonitorAlertMock.mock.calls[0][0]; + assertSpyCalls(sendMonitorAlertMock, 1); + const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("degraded"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.status).toBe("503"); @@ -166,6 +171,6 @@ describe("Email Notifications", () => { }); // Should not call sendMonitorAlert when data is invalid - expect(sendMonitorAlertMock).not.toHaveBeenCalled(); + assertSpyCalls(sendMonitorAlertMock, 0); }); }); diff --git a/packages/notifications/email/src/test-preload.ts b/packages/notifications/email/src/test-preload.ts new file mode 100644 index 00000000..3e4c5cf3 --- /dev/null +++ b/packages/notifications/email/src/test-preload.ts @@ -0,0 +1,10 @@ +/** + * Test env setup. Import this FIRST so env vars are set before module-level + * env validations fire on import. + * + * Bun's test runner set NODE_ENV=test automatically; Deno does not. This + * package's env skips validation when NODE_ENV=test, and @openstatus/emails + * validates RESEND_API_KEY at module load. + */ +process.env.NODE_ENV = "test"; +process.env.RESEND_API_KEY ??= "test-key"; diff --git a/packages/notifications/email/tsconfig.json b/packages/notifications/email/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/email/tsconfig.json +++ b/packages/notifications/email/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/google-chat/package.json b/packages/notifications/google-chat/package.json index f9669749..005737cf 100644 --- a/packages/notifications/google-chat/package.json +++ b/packages/notifications/google-chat/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/google-chat/src/index.test.ts b/packages/notifications/google-chat/src/index.test.ts index 1696d2db..6a84bffd 100644 --- a/packages/notifications/google-chat/src/index.test.ts +++ b/packages/notifications/google-chat/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Google Chat Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -57,8 +55,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://google.com/api/webhooks/123456789/abcdefgh", ); @@ -87,8 +85,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("✅ Recovered"); expect(body.text).toContain("API Health Check"); @@ -109,8 +107,8 @@ describe("Google Chat Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("⚠️ Degraded"); expect(body.text).toContain("API Health Check"); @@ -122,8 +120,8 @@ describe("Google Chat Notifications", () => { const result = await sendTest(webhookUrl); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); expect(body.text).toContain("🧪 Test"); @@ -134,11 +132,12 @@ describe("Google Chat Notifications", () => { const result = await sendTest(""); expect(result).toBe(false); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/google-chat/tsconfig.json b/packages/notifications/google-chat/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/google-chat/tsconfig.json +++ b/packages/notifications/google-chat/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/grafana-oncall/package.json b/packages/notifications/grafana-oncall/package.json index cc53a521..d68ea6c9 100644 --- a/packages/notifications/grafana-oncall/package.json +++ b/packages/notifications/grafana-oncall/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/grafana-oncall/src/index.test.ts b/packages/notifications/grafana-oncall/src/index.test.ts index 824a02df..5676f5c7 100644 --- a/packages/notifications/grafana-oncall/src/index.test.ts +++ b/packages/notifications/grafana-oncall/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Grafana OnCall Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -57,8 +55,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -89,8 +87,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.message).toBe("Status code: 503"); }); @@ -110,8 +108,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -138,8 +136,8 @@ describe("Grafana OnCall Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://oncall.example.com/integrations/v1/webhook/abc123", ); @@ -158,8 +156,8 @@ describe("Grafana OnCall Notifications", () => { const result = await sendTest({ webhookUrl }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); expect(callArgs[1].method).toBe("POST"); @@ -172,7 +170,8 @@ describe("Grafana OnCall Notifications", () => { }); test("Send Test returns false on network error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -181,11 +180,12 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on non-ok response", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 401 })), ); @@ -194,11 +194,12 @@ describe("Grafana OnCall Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Alert throws on non-ok response", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.resolve( new Response(null, { status: 500, @@ -225,7 +226,8 @@ describe("Grafana OnCall Notifications", () => { }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -234,7 +236,7 @@ describe("Grafana OnCall Notifications", () => { createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -245,6 +247,6 @@ describe("Grafana OnCall Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/grafana-oncall/tsconfig.json b/packages/notifications/grafana-oncall/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/grafana-oncall/tsconfig.json +++ b/packages/notifications/grafana-oncall/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/ms-teams/package.json b/packages/notifications/ms-teams/package.json index 1e4244f2..02dd24a6 100644 --- a/packages/notifications/ms-teams/package.json +++ b/packages/notifications/ms-teams/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ms-teams/src/index.test.ts b/packages/notifications/ms-teams/src/index.test.ts index 18c7b6d7..6baccbba 100644 --- a/packages/notifications/ms-teams/src/index.test.ts +++ b/packages/notifications/ms-teams/src/index.test.ts @@ -1,11 +1,12 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import type { Incident, Monitor } from "@openstatus/db/src/schema"; import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; -type FetchMock = ReturnType>; +type FetchMock = Stub; type AdaptiveCardElement = { type: string; @@ -41,14 +42,13 @@ describe("Microsoft Teams Notifications", () => { let fetchMock: FetchMock; beforeEach(() => { - // @ts-expect-error spyOn typing requires the full `typeof fetch` (incl. preconnect) - fetchMock = spyOn(globalThis, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - fetchMock.mockRestore(); + fetchMock.restore(); }); const createMockMonitor = (): Monitor => ({ @@ -114,8 +114,8 @@ describe("Microsoft Teams Notifications", () => { }); const readMessagePayload = (): MessagePayload => { - const calls = fetchMock.mock.calls; - const init = calls[0][1]; + const calls = fetchMock.calls; + const init = calls[0].args[1]; if (!init || typeof init.body !== "string") { throw new Error("expected string body"); } @@ -169,8 +169,8 @@ describe("Microsoft Teams Notifications", () => { regions: ["iad"], }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(String(url)).toContain("logic.azure.com"); expect(init?.method).toBe("POST"); @@ -302,7 +302,7 @@ describe("Microsoft Teams Notifications", () => { "https://prod-00.westeurope.logic.azure.com:443/workflows/test/triggers/manual/paths/invoke", }); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); const card = getCard(readMessagePayload()); const header = findContainerByStyle(card, "good"); expect(header?.items?.[0]?.text).toBe("Test notification"); @@ -311,12 +311,12 @@ describe("Microsoft Teams Notifications", () => { test("Send Test with empty webhookUrl", async () => { await expect(sendTest({ webhookUrl: "" })).rejects.toThrow(); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error", async () => { - // @ts-expect-error see beforeEach - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); diff --git a/packages/notifications/ms-teams/tsconfig.json b/packages/notifications/ms-teams/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/ms-teams/tsconfig.json +++ b/packages/notifications/ms-teams/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/ntfy/package.json b/packages/notifications/ntfy/package.json index 4d6230d4..da39ed21 100644 --- a/packages/notifications/ntfy/package.json +++ b/packages/notifications/ntfy/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/ntfy/src/index.test.ts b/packages/notifications/ntfy/src/index.test.ts index f7a61d85..a46f9284 100644 --- a/packages/notifications/ntfy/src/index.test.ts +++ b/packages/notifications/ntfy/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Ntfy Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -72,8 +70,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.sh/my-topic"); expect(callArgs[1].method).toBe("post"); expect(callArgs[1].body).toContain("API Health Check"); @@ -96,8 +94,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.example.com/my-topic"); }); @@ -116,8 +114,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -135,8 +133,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("error: Connection timeout"); }); @@ -155,8 +153,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("is up again"); }); @@ -173,8 +171,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token-123"); }); @@ -193,8 +191,8 @@ describe("Ntfy Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].body).toContain("is degraded"); }); @@ -204,8 +202,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.sh/test-topic"); expect(callArgs[1].body).toBe("This is a test message from OpenStatus"); expect(callArgs[1].headers).not.toHaveProperty("Authorization"); @@ -218,8 +216,8 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://ntfy.example.com/test-topic"); }); @@ -230,13 +228,14 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[1].headers.Authorization).toBe("Bearer test-token"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -257,11 +256,12 @@ describe("Ntfy Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -270,6 +270,6 @@ describe("Ntfy Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/ntfy/tsconfig.json b/packages/notifications/ntfy/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/ntfy/tsconfig.json +++ b/packages/notifications/ntfy/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/opsgenie/package.json b/packages/notifications/opsgenie/package.json index 678250f3..087a5e76 100644 --- a/packages/notifications/opsgenie/package.json +++ b/packages/notifications/opsgenie/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,10 +17,11 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/opsgenie/src/index.test.ts b/packages/notifications/opsgenie/src/index.test.ts index 00ff9824..ba678823 100644 --- a/packages/notifications/opsgenie/src/index.test.ts +++ b/packages/notifications/opsgenie/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendTest } from "./index"; describe("OpsGenie Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -75,8 +73,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://api.opsgenie.com/v2/alerts"); expect(callArgs[1].method).toBe("POST"); expect(callArgs[1].headers["Content-Type"]).toBe("application/json"); @@ -107,8 +105,8 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://api.eu.opsgenie.com/v2/alerts"); }); @@ -129,15 +127,16 @@ describe("OpsGenie Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.details.severity).toBe("degraded"); expect(body.message).toBe("API Health Check is degraded"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -159,11 +158,12 @@ describe("OpsGenie Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -173,6 +173,6 @@ describe("OpsGenie Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/opsgenie/tsconfig.json b/packages/notifications/opsgenie/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/opsgenie/tsconfig.json +++ b/packages/notifications/opsgenie/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/pagerduty/package.json b/packages/notifications/pagerduty/package.json index d242877d..7fc66f4a 100644 --- a/packages/notifications/pagerduty/package.json +++ b/packages/notifications/pagerduty/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -16,10 +17,11 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/react": "catalog:", "@types/react-dom": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/pagerduty/src/index.test.ts b/packages/notifications/pagerduty/src/index.test.ts index 840cb57d..a1a94b33 100644 --- a/packages/notifications/pagerduty/src/index.test.ts +++ b/packages/notifications/pagerduty/src/index.test.ts @@ -1,23 +1,21 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("PagerDuty Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -70,8 +68,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -109,9 +107,9 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(2); - expect(fetchMock.mock.calls[0][1].body).toContain("key1"); - expect(fetchMock.mock.calls[1][1].body).toContain("key2"); + assertSpyCalls(fetchMock, 2); + expect(fetchMock.calls[0].args[1].body).toContain("key1"); + expect(fetchMock.calls[1].args[1].body).toContain("key2"); }); test("Send Degraded", async () => { @@ -132,8 +130,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.payload.summary).toBe("API Health Check is degraded"); expect(body.payload.severity).toBe("warning"); @@ -158,8 +156,8 @@ describe("PagerDuty Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); const body = JSON.parse(callArgs[1].body); expect(body.routing_key).toBe("my_key"); @@ -173,8 +171,8 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://events.pagerduty.com/v2/enqueue"); expect(callArgs[1].method).toBe("POST"); @@ -188,7 +186,8 @@ describe("PagerDuty Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -197,11 +196,12 @@ describe("PagerDuty Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -224,6 +224,6 @@ describe("PagerDuty Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/pagerduty/tsconfig.json b/packages/notifications/pagerduty/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/pagerduty/tsconfig.json +++ b/packages/notifications/pagerduty/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/slack/package.json b/packages/notifications/slack/package.json index 66b0aee6..e63632c0 100644 --- a/packages/notifications/slack/package.json +++ b/packages/notifications/slack/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/slack/src/index.test.ts b/packages/notifications/slack/src/index.test.ts index aa16993f..4fe9de09 100644 --- a/packages/notifications/slack/src/index.test.ts +++ b/packages/notifications/slack/src/index.test.ts @@ -1,7 +1,8 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; import { COLORS } from "@openstatus/notification-base"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, @@ -11,19 +12,16 @@ import { } from "./index"; describe("Slack Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); }); const createMockMonitor = () => ({ @@ -63,8 +61,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe("https://hooks.slack.com/services/url"); expect(callArgs[1].method).toBe("POST"); @@ -90,8 +88,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments[0].color).toBe(COLORS.red); expect(body.attachments[0].blocks[3].fields[0].text).toContain("Unknown"); @@ -112,8 +110,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.green); @@ -135,8 +133,8 @@ describe("Slack Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body.attachments).toBeDefined(); expect(body.attachments[0].color).toBe(COLORS.yellow); @@ -148,8 +146,8 @@ describe("Slack Notifications", () => { await sendTestSlackMessage(webhookUrl); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe(webhookUrl); const body = JSON.parse(callArgs[1].body); @@ -159,16 +157,18 @@ describe("Slack Notifications", () => { }); test("Send Test Slack Message throws error on empty webhookUrl", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); expect(sendTestSlackMessage("")).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(0); + assertSpyCalls(fetchMock, 0); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -177,8 +177,7 @@ describe("Slack Notifications", () => { createMockNotification(), ); - // Should not throw - function catches errors internally - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -189,6 +188,6 @@ describe("Slack Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/slack/tsconfig.json b/packages/notifications/slack/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/slack/tsconfig.json +++ b/packages/notifications/slack/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/telegram/package.json b/packages/notifications/telegram/package.json index 13f66b1e..0e907adc 100644 --- a/packages/notifications/telegram/package.json +++ b/packages/notifications/telegram/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -13,8 +14,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/telegram/src/index.test.ts b/packages/notifications/telegram/src/index.test.ts index 93e56e31..805cec19 100644 --- a/packages/notifications/telegram/src/index.test.ts +++ b/packages/notifications/telegram/src/index.test.ts @@ -1,29 +1,27 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery, sendTest } from "./index"; describe("Telegram Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; const originalEnv = process.env.TELEGRAM_BOT_TOKEN; beforeEach(() => { process.env.TELEGRAM_BOT_TOKEN = "test-bot-token-123"; - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); if (originalEnv) { process.env.TELEGRAM_BOT_TOKEN = originalEnv; } else { - process.env.TELEGRAM_BOT_TOKEN = undefined; + delete process.env.TELEGRAM_BOT_TOKEN; } }); @@ -68,8 +66,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -91,8 +89,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("error: Connection timeout"); }); @@ -111,8 +109,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("is up again"); }); @@ -131,8 +129,8 @@ describe("Telegram Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain("is degraded"); }); @@ -142,8 +140,8 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toContain( "https://api.telegram.org/bottest-bot-token-123/sendMessage", ); @@ -152,7 +150,8 @@ describe("Telegram Notifications", () => { }); test("Send Test returns false on error", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -161,11 +160,12 @@ describe("Telegram Notifications", () => { }); expect(result).toBe(false); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -174,7 +174,7 @@ describe("Telegram Notifications", () => { createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -185,18 +185,18 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("fetch not called when TELEGRAM_BOT_TOKEN is not set", async () => { - process.env.TELEGRAM_BOT_TOKEN = undefined; + delete process.env.TELEGRAM_BOT_TOKEN; const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), ); - expect( + await expect( sendAlert({ // @ts-expect-error monitor, @@ -207,6 +207,6 @@ describe("Telegram Notifications", () => { }), ).rejects.toThrow(); // Should not call fetch when token is missing - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); }); diff --git a/packages/notifications/telegram/tsconfig.json b/packages/notifications/telegram/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/telegram/tsconfig.json +++ b/packages/notifications/telegram/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/twillio-sms/package.json b/packages/notifications/twillio-sms/package.json index 90199e77..74f26cc0 100644 --- a/packages/notifications/twillio-sms/package.json +++ b/packages/notifications/twillio-sms/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -15,9 +16,10 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "@types/validator": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/twillio-sms/src/index.test.ts b/packages/notifications/twillio-sms/src/index.test.ts index 12e3c25c..21b334ca 100644 --- a/packages/notifications/twillio-sms/src/index.test.ts +++ b/packages/notifications/twillio-sms/src/index.test.ts @@ -1,11 +1,12 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; - import { selectNotificationSchema } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendAlert, sendDegraded, sendRecovery } from "./index"; describe("Twilio SMS Notifications", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; const originalEnv = { TWILLIO_ACCOUNT_ID: process.env.TWILLIO_ACCOUNT_ID, TWILLIO_AUTH_TOKEN: process.env.TWILLIO_AUTH_TOKEN, @@ -14,16 +15,13 @@ describe("Twilio SMS Notifications", () => { beforeEach(() => { process.env.TWILLIO_ACCOUNT_ID = "test-account-id"; process.env.TWILLIO_AUTH_TOKEN = "test-auth-token"; - // @ts-expect-error - fetchMock = spyOn(global, "fetch").mockImplementation(() => + fetchMock = stub(globalThis, "fetch", () => Promise.resolve(new Response(null, { status: 200 })), ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockRestore(); - } + fetchMock.restore(); if (originalEnv.TWILLIO_ACCOUNT_ID) { process.env.TWILLIO_ACCOUNT_ID = originalEnv.TWILLIO_ACCOUNT_ID; } else { @@ -73,8 +71,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; expect(callArgs[0]).toBe( "https://api.twilio.com/2010-04-01/Accounts/test-account-id/Messages.json", ); @@ -104,8 +102,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("error: Connection timeout"); }); @@ -125,8 +123,8 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is up again"); expect(formData.get("Body")).toContain("API Health Check"); @@ -147,15 +145,16 @@ describe("Twilio SMS Notifications", () => { cronTimestamp: Date.now(), }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; const formData = callArgs[1].body as FormData; expect(formData.get("Body")).toContain("is degraded"); expect(formData.get("Body")).toContain("API Health Check"); }); test("Handle fetch error gracefully", async () => { - fetchMock.mockImplementation(() => + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(new Error("Network error")), ); @@ -175,6 +174,6 @@ describe("Twilio SMS Notifications", () => { }), ).rejects.toThrow(); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/notifications/twillio-sms/tsconfig.json b/packages/notifications/twillio-sms/tsconfig.json index b4382e67..48baa5cf 100644 --- a/packages/notifications/twillio-sms/tsconfig.json +++ b/packages/notifications/twillio-sms/tsconfig.json @@ -1,7 +1,7 @@ { - "extends": "@openstatus/tsconfig/nextjs.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "types": ["bun-types"] + "resolveJsonModule": true } } diff --git a/packages/notifications/webhook/package.json b/packages/notifications/webhook/package.json index dca6d651..bb543a27 100644 --- a/packages/notifications/webhook/package.json +++ b/packages/notifications/webhook/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "main": "src/index.ts", "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc" }, "dependencies": { @@ -14,8 +15,9 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", - "bun-types": "catalog:", "typescript": "catalog:" } } diff --git a/packages/notifications/webhook/src/index.test.ts b/packages/notifications/webhook/src/index.test.ts index ca5d0d63..f0000ee1 100644 --- a/packages/notifications/webhook/src/index.test.ts +++ b/packages/notifications/webhook/src/index.test.ts @@ -1,31 +1,35 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, stub, type Stub } from "@std/testing/mock"; import { sendTest } from "./index"; describe("Webhook sendTest", () => { - let fetchMock: any = undefined; + let fetchMock: Stub; beforeEach(() => { - fetchMock = spyOn(global, "fetch"); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); }); afterEach(() => { - if (fetchMock) { - fetchMock.mockClear(); - fetchMock.mockRestore(); - } + fetchMock.restore(); }); test("should send test webhook successfully", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith( - url, + assertSpyCalls(fetchMock, 1); + expect(fetchMock.calls[0].args[0]).toBe(url); + expect(fetchMock.calls[0].args[1]).toEqual( expect.objectContaining({ method: "post", body: expect.any(String), @@ -33,7 +37,7 @@ describe("Webhook sendTest", () => { }), ); - const callArgs = fetchMock.mock.calls[0]; + const callArgs = fetchMock.calls[0].args; const body = JSON.parse(callArgs[1].body); expect(body).toMatchObject({ monitor: { @@ -45,7 +49,7 @@ describe("Webhook sendTest", () => { statusCode: 200, latency: 1337, }); - expect(body.cronTimestamp).toBeTypeOf("number"); + expect(typeof body.cronTimestamp).toBe("number"); }); test("should send test webhook with headers", async () => { @@ -54,14 +58,17 @@ describe("Webhook sendTest", () => { { key: "Authorization", value: "Bearer token123" }, { key: "Content-Type", value: "application/json" }, ]; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url, headers }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - expect(fetchMock).toHaveBeenCalledWith( - url, + assertSpyCalls(fetchMock, 1); + expect(fetchMock.calls[0].args[0]).toBe(url); + expect(fetchMock.calls[0].args[1]).toEqual( expect.objectContaining({ method: "post", body: expect.any(String), @@ -75,50 +82,63 @@ describe("Webhook sendTest", () => { test("should throw error when response is not ok", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 400 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 400 })), + ); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should throw error when fetch fails", async () => { const url = "https://example.com/webhook"; const networkError = new Error("Network error"); - fetchMock.mockRejectedValue(networkError); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => Promise.reject(networkError)); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should send test webhook with empty headers array", async () => { const url = "https://example.com/webhook"; const headers: { key: string; value: string }[] = []; - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); const result = await sendTest({ url, headers }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); - const callArgs = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const callArgs = fetchMock.calls[0].args; // Empty headers array should still include Content-Type expect(callArgs[1].headers).toEqual({ "Content-Type": "application/json" }); }); test("should send test webhook with 500 status code", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 500 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 500 })), + ); await expect(sendTest({ url })).rejects.toThrow("Failed to send test"); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); test("should send test webhook with 201 status code (success)", async () => { const url = "https://example.com/webhook"; - fetchMock.mockResolvedValue(new Response(null, { status: 201 })); + fetchMock.restore(); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 201 })), + ); const result = await sendTest({ url }); expect(result).toBe(true); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); diff --git a/packages/proto/package.json b/packages/proto/package.json index 72bff34e..a9773b68 100644 --- a/packages/proto/package.json +++ b/packages/proto/package.json @@ -35,6 +35,7 @@ } }, "scripts": { + "check": "deno check --sloppy-imports .", "buf:openapi": "buf generate --path api/openstatus --template buf.gen.openapi.yaml && bun scripts/clean-openapi.ts", "buf:ts": "buf generate --path api/openstatus --template buf.gen.ts.yaml", "buf:go": "buf generate --path internal/private_location --template buf.gen.go.yaml", @@ -45,7 +46,7 @@ "dependencies": { "@bufbuild/protobuf": "catalog:", "@bufbuild/protovalidate": "catalog:", - "@connectrpc/connect": "^2.1.1" + "@connectrpc/connect": "catalog:" }, "devDependencies": { "@bufbuild/buf": "catalog:", diff --git a/packages/regions/package.json b/packages/regions/package.json index eef4b0cd..0754493e 100644 --- a/packages/regions/package.json +++ b/packages/regions/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "zod": "catalog:" }, diff --git a/packages/services/package.json b/packages/services/package.json index 74d25542..7a863399 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -127,7 +127,8 @@ } }, "scripts": { - "test": "bun test", + "check": "deno check --sloppy-imports .", + "test": "NODE_ENV=test RESEND_API_KEY=test-key deno test --parallel -A --no-check --sloppy-imports", "tsc": "tsc --noEmit" }, "dependencies": { @@ -145,7 +146,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/services/src/__tests__/retry.test.ts b/packages/services/src/__tests__/retry.test.ts index 9f26dcaa..ada57ea1 100644 --- a/packages/services/src/__tests__/retry.test.ts +++ b/packages/services/src/__tests__/retry.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { NotFoundError } from "../errors"; import { diff --git a/packages/services/src/__tests__/with-test-transaction.test.ts b/packages/services/src/__tests__/with-test-transaction.test.ts index 68fc513c..cb9a1f64 100644 --- a/packages/services/src/__tests__/with-test-transaction.test.ts +++ b/packages/services/src/__tests__/with-test-transaction.test.ts @@ -1,7 +1,7 @@ -import { afterAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { auditLog } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { withTestTransaction } from "../../test/helpers"; diff --git a/packages/services/src/__tests__/with-transaction.test.ts b/packages/services/src/__tests__/with-transaction.test.ts index 1bb9c477..aa86f019 100644 --- a/packages/services/src/__tests__/with-transaction.test.ts +++ b/packages/services/src/__tests__/with-transaction.test.ts @@ -1,4 +1,5 @@ -import { beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../test/fixtures"; import { loadSeededWorkspace } from "../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/docs.test.ts b/packages/services/src/agent-tools/__tests__/docs.test.ts index 039400c3..63f50d31 100644 --- a/packages/services/src/agent-tools/__tests__/docs.test.ts +++ b/packages/services/src/agent-tools/__tests__/docs.test.ts @@ -1,4 +1,6 @@ -import { afterEach, describe, expect, mock, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import type { ServiceContext } from "../../context"; import { getDocPageTool, searchDocsTool } from "../docs"; @@ -13,7 +15,7 @@ afterEach(() => { }); function mockFetch(response: Response) { - const fn = mock(async () => response); + const fn = spy(async () => response); globalThis.fetch = fn as unknown as typeof fetch; return fn; } @@ -111,9 +113,11 @@ describe("get_doc_page", () => { }); expect(result.truncated).toBe(true); expect(result.markdown.length).toBeLessThan(24_200); - expect(result.markdown).toEndWith( - "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", - ); + expect( + result.markdown.endsWith( + "[truncated — content continues at https://www.openstatus.dev/docs/concept/page-1]", + ), + ).toBe(true); }); test("returns error shape on 404", async () => { @@ -149,6 +153,6 @@ describe("get_doc_page", () => { ); expect(getDocPageTool.outputSchema.safeParse(result).success).toBe(true); } - expect(fn).not.toHaveBeenCalled(); + assertSpyCalls(fn, 0); }); }); diff --git a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts index c6bfd1b3..ae1a50e6 100644 --- a/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts +++ b/packages/services/src/agent-tools/__tests__/shape-equivalence.test.ts @@ -1,4 +1,5 @@ -import { beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { loadSeededWorkspace, makeUserCtx } from "../../../test/helpers"; diff --git a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts index dd21661c..cb0f7c38 100644 --- a/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts +++ b/packages/services/src/agent-tools/__tests__/status-report-impacts.test.ts @@ -1,6 +1,6 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { page, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/api-key/__tests__/api-key.test.ts b/packages/services/src/api-key/__tests__/api-key.test.ts index e401e304..7a199c8b 100644 --- a/packages/services/src/api-key/__tests__/api-key.test.ts +++ b/packages/services/src/api-key/__tests__/api-key.test.ts @@ -1,15 +1,8 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { apiKey } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; -import { - createApiKey, - listApiKeys, - revokeApiKey, - updateApiKeyLastUsed, - verifyApiKey, -} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -21,6 +14,13 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError, NotFoundError } from "../../errors"; +import { + createApiKey, + listApiKeys, + revokeApiKey, + updateApiKeyLastUsed, + verifyApiKey, +} from "../index.ts"; const TEST_PREFIX = "svc-apikey-test"; diff --git a/packages/services/src/audit/__tests__/audit.test.ts b/packages/services/src/audit/__tests__/audit.test.ts index 016e8d83..de082c72 100644 --- a/packages/services/src/audit/__tests__/audit.test.ts +++ b/packages/services/src/audit/__tests__/audit.test.ts @@ -1,8 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { auditLog, user } from "@openstatus/db/src/schema"; import type { AuditEntry } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/auth/__tests__/matches-scope.test.ts b/packages/services/src/auth/__tests__/matches-scope.test.ts index de72ef4e..0a70f475 100644 --- a/packages/services/src/auth/__tests__/matches-scope.test.ts +++ b/packages/services/src/auth/__tests__/matches-scope.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, test } from "bun:test"; - import type { Scope } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { matchesScope } from "../matches-scope"; diff --git a/packages/services/src/auth/__tests__/require-scope.test.ts b/packages/services/src/auth/__tests__/require-scope.test.ts index 0278626b..cd46a176 100644 --- a/packages/services/src/auth/__tests__/require-scope.test.ts +++ b/packages/services/src/auth/__tests__/require-scope.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import type { Actor, ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; diff --git a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts index 08324142..e8062d01 100644 --- a/packages/services/src/external-service-component/__tests__/external-service-component.test.ts +++ b/packages/services/src/external-service-component/__tests__/external-service-component.test.ts @@ -1,11 +1,11 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { and, db, eq, like } from "@openstatus/db"; import type { ApiConfigType } from "@openstatus/db/src/schema"; import { externalService, externalServiceComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { getExternalComponentBySlug, diff --git a/packages/services/src/external-service-component/__tests__/internal.test.ts b/packages/services/src/external-service-component/__tests__/internal.test.ts index f219bb83..7b304e95 100644 --- a/packages/services/src/external-service-component/__tests__/internal.test.ts +++ b/packages/services/src/external-service-component/__tests__/internal.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { assignComponentSlugs, slugifyComponentName } from "../internal"; diff --git a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts index 5134ddde..66ddc5a0 100644 --- a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts +++ b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts @@ -1,10 +1,10 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { and, db, eq, like } from "@openstatus/db"; import { externalService, externalServiceIncident, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { type UpsertExternalIncidentInput, diff --git a/packages/services/src/external-service-report/__tests__/record.test.ts b/packages/services/src/external-service-report/__tests__/record.test.ts index 43a9524c..853831f7 100644 --- a/packages/services/src/external-service-report/__tests__/record.test.ts +++ b/packages/services/src/external-service-report/__tests__/record.test.ts @@ -1,11 +1,11 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { db, eq, inArray, like } from "@openstatus/db"; import { externalService, externalServiceComponent, externalServiceReport, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { NotFoundError } from "../../errors"; import { diff --git a/packages/services/src/external-service/__tests__/external-service.test.ts b/packages/services/src/external-service/__tests__/external-service.test.ts index dccf7991..6dc0c897 100644 --- a/packages/services/src/external-service/__tests__/external-service.test.ts +++ b/packages/services/src/external-service/__tests__/external-service.test.ts @@ -1,7 +1,7 @@ -import { afterEach, describe, expect, test } from "bun:test"; - import { db, like, sql } from "@openstatus/db"; import { externalService } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; import { ConflictError } from "../../errors"; import { assertSlugAvailable } from "../internal"; diff --git a/packages/services/src/import/__tests__/incidents-phase.test.ts b/packages/services/src/import/__tests__/incidents-phase.test.ts index 7070bc57..64d2b6d6 100644 --- a/packages/services/src/import/__tests__/incidents-phase.test.ts +++ b/packages/services/src/import/__tests__/incidents-phase.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { page, @@ -10,6 +8,8 @@ import { statusReportsToPageComponents, } from "@openstatus/db/src/schema"; import type { PhaseResult } from "@openstatus/importers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/import/__tests__/unit.test.ts b/packages/services/src/import/__tests__/unit.test.ts index b7f14668..ad3b74cf 100644 --- a/packages/services/src/import/__tests__/unit.test.ts +++ b/packages/services/src/import/__tests__/unit.test.ts @@ -1,10 +1,10 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; import { allPlans } from "@openstatus/db/src/schema/plan/config"; import type { Limits } from "@openstatus/db/src/schema/plan/schema"; import type { ImportSummary } from "@openstatus/importers"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { addLimitWarnings, clampPeriodicity, computePhaseStatus } from "../"; import { withTestTransaction } from "../../../test/helpers"; diff --git a/packages/services/src/incident/__tests__/incident.test.ts b/packages/services/src/incident/__tests__/incident.test.ts index 0b27432c..ae0eec54 100644 --- a/packages/services/src/incident/__tests__/incident.test.ts +++ b/packages/services/src/incident/__tests__/incident.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { incidentTable, monitor } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/integration/__tests__/install-slack-agent.test.ts b/packages/services/src/integration/__tests__/install-slack-agent.test.ts index 7092a8bf..ddbfa877 100644 --- a/packages/services/src/integration/__tests__/install-slack-agent.test.ts +++ b/packages/services/src/integration/__tests__/install-slack-agent.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, desc, eq } from "@openstatus/db"; import { integration } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -238,9 +238,9 @@ describe("installSlackAgent", () => { // shape as create/update — proves delete-path symmetry. const deleteRow = all.find((r) => r.action === "integration.delete"); expect( - (deleteRow?.before as Record | null) + typeof (deleteRow?.before as Record | null) ?.credentialFingerprint, - ).toBeTypeOf("string"); + ).toBe("string"); }); }); diff --git a/packages/services/src/invitation/__tests__/invitation.test.ts b/packages/services/src/invitation/__tests__/invitation.test.ts index 8309e1b3..58ff3132 100644 --- a/packages/services/src/invitation/__tests__/invitation.test.ts +++ b/packages/services/src/invitation/__tests__/invitation.test.ts @@ -1,15 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { invitation, user, usersToWorkspaces } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { - acceptInvitation, - createInvitation, - deleteInvitation, - getInvitationByToken, - listInvitations, -} from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -27,6 +20,13 @@ import { LimitExceededError, NotFoundError, } from "../../errors"; +import { + acceptInvitation, + createInvitation, + deleteInvitation, + getInvitationByToken, + listInvitations, +} from "../index.ts"; const TEST_PREFIX = "svc-inv-test"; diff --git a/packages/services/src/maintenance/__tests__/maintenance.test.ts b/packages/services/src/maintenance/__tests__/maintenance.test.ts index c7a8890c..32afbbba 100644 --- a/packages/services/src/maintenance/__tests__/maintenance.test.ts +++ b/packages/services/src/maintenance/__tests__/maintenance.test.ts @@ -1,18 +1,17 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { maintenancesToPageComponents, page, pageComponent, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/member/__tests__/member.test.ts b/packages/services/src/member/__tests__/member.test.ts index a682723a..305d8885 100644 --- a/packages/services/src/member/__tests__/member.test.ts +++ b/packages/services/src/member/__tests__/member.test.ts @@ -1,9 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { user, usersToWorkspaces } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { deleteMember, listMembers } from ".."; import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -23,6 +22,7 @@ import { NotFoundError, PreconditionFailedError, } from "../../errors"; +import { deleteMember, listMembers } from "../index.ts"; const OWNER_USER_ID = 1; const VICTIM_USER_ID = 4242; diff --git a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts index 26238ff7..121cbe4a 100644 --- a/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts +++ b/packages/services/src/monitor-tag/__tests__/monitor-tag.test.ts @@ -1,9 +1,8 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitorTag } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { listMonitorTags, syncMonitorTags } from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { clearAuditLog, @@ -15,6 +14,7 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; +import { listMonitorTags, syncMonitorTags } from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/src/monitor/__tests__/monitor.test.ts b/packages/services/src/monitor/__tests__/monitor.test.ts index 9979ea2f..d8af1b46 100644 --- a/packages/services/src/monitor/__tests__/monitor.test.ts +++ b/packages/services/src/monitor/__tests__/monitor.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -7,15 +5,15 @@ import { monitorTagsToMonitors, notification, notificationsToMonitors, + selectWorkspaceSchema, + workspace, } from "@openstatus/db/src/schema"; +import { createWorkspace } from "@openstatus/db/src/test/factories"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; -import { - SEEDED_WORKSPACE_FREE_ID, - SEEDED_WORKSPACE_TEAM_ID, -} from "../../../test/fixtures"; import { expectAuditRow, - loadSeededWorkspace, makeApiKeyCtx, makeSystemCtx, makeUserCtx, @@ -35,12 +33,18 @@ const TEST_PREFIX = "svc-monitor-test"; let teamCtx: ServiceContext; let freeCtx: ServiceContext; +let teamWorkspaceId: number; +let freeWorkspaceId: number; let testTagId: number; let testNotificationId: number; beforeAll(async () => { - const team = await loadSeededWorkspace(SEEDED_WORKSPACE_TEAM_ID); - const free = await loadSeededWorkspace(SEEDED_WORKSPACE_FREE_ID); + // Own workspaces per suite — relying on the shared seeded workspace races + // sibling suites that wipe its tags/notifications (e.g. monitor-tag). + const team = selectWorkspaceSchema.parse(await createWorkspace()); + const free = selectWorkspaceSchema.parse(await createWorkspace()); + teamWorkspaceId = team.id; + freeWorkspaceId = free.id; teamCtx = makeUserCtx(team, { userId: 1 }); freeCtx = makeUserCtx(free, { userId: 2 }); @@ -77,6 +81,10 @@ afterAll(async () => { .delete(notification) .where(eq(notification.id, testNotificationId)) .catch(() => undefined); + await db + .delete(workspace) + .where(inArray(workspace.id, [teamWorkspaceId, freeWorkspaceId])) + .catch(() => undefined); }); describe("createMonitor", () => { diff --git a/packages/services/src/monitor/__tests__/reads.test.ts b/packages/services/src/monitor/__tests__/reads.test.ts index ef90d9cb..ba2b25f0 100644 --- a/packages/services/src/monitor/__tests__/reads.test.ts +++ b/packages/services/src/monitor/__tests__/reads.test.ts @@ -1,6 +1,6 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { monitorStatusTable } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts index 431a9302..0a54da72 100644 --- a/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts +++ b/packages/services/src/monitor/__tests__/stream-monitor-preview.test.ts @@ -1,4 +1,5 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { @@ -66,11 +67,13 @@ describe("streamMonitorPreview", () => { input: { monitorId: 999_999_999 }, }); - await expect(async () => { - for await (const _ of generator) { - // drain - } - }).toThrow(NotFoundError); + await expect( + (async () => { + for await (const _ of generator) { + // drain + } + })(), + ).rejects.toThrow(NotFoundError); }); }); diff --git a/packages/services/src/notification/__tests__/notification.test.ts b/packages/services/src/notification/__tests__/notification.test.ts index afd4c311..5082f971 100644 --- a/packages/services/src/notification/__tests__/notification.test.ts +++ b/packages/services/src/notification/__tests__/notification.test.ts @@ -1,11 +1,11 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, notification, notificationsToMonitors, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts index 02db33a0..10a2f088 100644 --- a/packages/services/src/page-component/__tests__/get-daily-summary.test.ts +++ b/packages/services/src/page-component/__tests__/get-daily-summary.test.ts @@ -1,5 +1,3 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { maintenance, maintenancesToPageComponents, @@ -11,6 +9,8 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { diff --git a/packages/services/src/page-component/__tests__/page-component.test.ts b/packages/services/src/page-component/__tests__/page-component.test.ts index 119c6952..447099d2 100644 --- a/packages/services/src/page-component/__tests__/page-component.test.ts +++ b/packages/services/src/page-component/__tests__/page-component.test.ts @@ -1,5 +1,3 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { and, db, eq, inArray } from "@openstatus/db"; import { monitor, @@ -7,6 +5,8 @@ import { pageComponent, pageComponentGroup, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts index abbfd66c..3fa02a4c 100644 --- a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts +++ b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts @@ -1,13 +1,3 @@ -import { - afterAll, - afterEach, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { and, db, eq } from "@openstatus/db"; import { auditLog, @@ -15,16 +5,16 @@ import { pageSubscriber, pageSubscriberToPageComponent, } from "@openstatus/db/src/schema"; - +import { expect } from "@std/expect"; import { - createPageSubscriber, - getSubscriberByToken, - hasPendingSubscriber, - unsubscribeSubscriber, - updateSubscriberScope, - upsertSelfSignupSubscriber, - verifySelfSignupSubscriber, -} from ".."; + afterAll, + afterEach, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; + import { SEEDED_WORKSPACE_FREE_ID, SEEDED_WORKSPACE_TEAM_ID, @@ -38,6 +28,15 @@ import { withTestTransaction, } from "../../../test/helpers"; import { ForbiddenError } from "../../errors"; +import { + createPageSubscriber, + getSubscriberByToken, + hasPendingSubscriber, + unsubscribeSubscriber, + updateSubscriberScope, + upsertSelfSignupSubscriber, + verifySelfSignupSubscriber, +} from "../index.ts"; // Seeded data we lean on (see packages/db/src/seed.mts): // workspace 1 = team plan, has status-subscribers=true diff --git a/packages/services/src/page/__tests__/page.test.ts b/packages/services/src/page/__tests__/page.test.ts index 429f682d..fd8673da 100644 --- a/packages/services/src/page/__tests__/page.test.ts +++ b/packages/services/src/page/__tests__/page.test.ts @@ -1,7 +1,7 @@ -import { afterAll, beforeAll, describe, expect, test } from "bun:test"; - import { db, eq } from "@openstatus/db"; import { monitor, pageComponent } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/status-report/__tests__/status-report.test.ts b/packages/services/src/status-report/__tests__/status-report.test.ts index fb7bab4d..7104b8d1 100644 --- a/packages/services/src/status-report/__tests__/status-report.test.ts +++ b/packages/services/src/status-report/__tests__/status-report.test.ts @@ -1,12 +1,3 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - test, -} from "bun:test"; - import { db, eq } from "@openstatus/db"; import { page, @@ -17,6 +8,14 @@ import { statusReportUpdateToPageComponents, statusReportsToPageComponents, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { + afterAll, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; import { SEEDED_WORKSPACE_FREE_ID, diff --git a/packages/services/src/workspace/__tests__/workspace.test.ts b/packages/services/src/workspace/__tests__/workspace.test.ts index 21dde2ae..6efc00f5 100644 --- a/packages/services/src/workspace/__tests__/workspace.test.ts +++ b/packages/services/src/workspace/__tests__/workspace.test.ts @@ -1,14 +1,8 @@ -import { beforeAll, describe, expect, test } from "bun:test"; - import { eq } from "@openstatus/db"; import { workspace } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; -import { - getWorkspace, - getWorkspaceWithUsage, - listWorkspaces, - updateWorkspaceName, -} from ".."; import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; import { expectAuditRow, @@ -19,6 +13,12 @@ import { } from "../../../test/helpers"; import type { ServiceContext } from "../../context"; import { ForbiddenError } from "../../errors"; +import { + getWorkspace, + getWorkspaceWithUsage, + listWorkspaces, + updateWorkspaceName, +} from "../index.ts"; let teamCtx: ServiceContext; diff --git a/packages/services/test/helpers.ts b/packages/services/test/helpers.ts index 7dda2267..688bdf15 100644 --- a/packages/services/test/helpers.ts +++ b/packages/services/test/helpers.ts @@ -1,5 +1,3 @@ -import { expect } from "bun:test"; - import { and, db, desc, eq, inArray } from "@openstatus/db"; import { type Scope, @@ -10,6 +8,7 @@ import { selectWorkspaceSchema, workspace as workspaceTable, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; import type { Actor, DB, DrizzleTx, ServiceContext } from "../src/context"; import type { Workspace } from "../src/types"; diff --git a/packages/services/tsconfig.json b/packages/services/tsconfig.json index 54a1ac32..0da708f7 100644 --- a/packages/services/tsconfig.json +++ b/packages/services/tsconfig.json @@ -1,8 +1,9 @@ { - "extends": "@openstatus/tsconfig/react-library.json", + "extends": "@openstatus/tsconfig/base.json", "include": ["src", "test"], "exclude": ["dist", "build", "node_modules"], "compilerOptions": { + "module": "ESNext", "moduleResolution": "bundler" } } diff --git a/packages/status-fetcher/__tests__/fetch.test.ts b/packages/status-fetcher/__tests__/fetch.test.ts index 36556d49..7bafe97d 100644 --- a/packages/status-fetcher/__tests__/fetch.test.ts +++ b/packages/status-fetcher/__tests__/fetch.test.ts @@ -1,5 +1,6 @@ -import { beforeEach, describe, expect, it, mock } from "bun:test"; - +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { Cause, Effect, Exit, Option } from "effect"; import { z } from "zod"; @@ -10,7 +11,7 @@ const TEST_URL = "https://api.example.com/status"; type FetchImpl = (url: string, init?: RequestInit) => Promise; const installMockFetch = (impl: FetchImpl) => { - const fn = mock(impl); + const fn = spy(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; @@ -79,7 +80,7 @@ describe("fetchJson", () => { expect(err.httpStatus).toBe(404); expect(err.fetcherName).toBe("test"); expect(err.entryId).toBe("x"); - expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.calls.length).toBe(1); }); it("retries up to 3 times on 5xx then fails", async () => { @@ -92,7 +93,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBe(503); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); it("retries up to 3 times on network error then fails", async () => { @@ -105,7 +106,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.httpStatus).toBeUndefined(); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); it("fails with FetchError on schema mismatch without retrying", async () => { @@ -118,7 +119,7 @@ describe("fetchJson", () => { ); const err = expectFailure(exit); expect(err.cause).toBeInstanceOf(Error); - expect(fetchMock.mock.calls.length).toBe(1); + expect(fetchMock.calls.length).toBe(1); }); it("applies default User-Agent and Accept headers", async () => { @@ -200,7 +201,7 @@ describe("fetchText", () => { const exit = await Effect.runPromiseExit(fetchText({ url: TEST_URL })); const err = expectFailure(exit); expect(err.httpStatus).toBe(500); - expect(fetchMock.mock.calls.length).toBe(4); + expect(fetchMock.calls.length).toBe(4); }); }); diff --git a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts index 09baa515..ae7a8d2c 100644 --- a/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/atlassian.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import type { StatusPageEntry } from "../../src/types"; @@ -113,8 +114,11 @@ describe("AtlassianFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("Etc/UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://www.githubstatus.com/api/v2/summary.json", + ); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -234,10 +238,9 @@ describe("AtlassianFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on non-200 response", async () => { @@ -332,10 +335,11 @@ describe("AtlassianFetcher", () => { const incidents = await runIncidents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://www.githubstatus.com/api/v2/incidents.json", - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(2); expect(incidents[0]).toMatchObject({ providerIncidentId: "abc", diff --git a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts index 355f070f..d1bb0869 100644 --- a/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/betterstack.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { BetterStackFetcher } from "../../src/fetchers/betterstack"; import type { StatusPageEntry } from "../../src/types"; @@ -121,8 +122,9 @@ describe("BetterStackFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("America/New_York"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com/index.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com/index.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -240,10 +242,9 @@ describe("BetterStackFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on 4xx response", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/components.test.ts b/packages/status-fetcher/__tests__/fetchers/components.test.ts index 15b1aaf4..d87f3ae3 100644 --- a/packages/status-fetcher/__tests__/fetchers/components.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/components.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; @@ -81,10 +82,11 @@ function itNormalizes( const components = await runComponents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( `${entry.status_page_url}/api/v2/components.json`, - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); // group container "grp" is excluded; only the three leaves remain expect(components).toHaveLength(3); diff --git a/packages/status-fetcher/__tests__/fetchers/custom.test.ts b/packages/status-fetcher/__tests__/fetchers/custom.test.ts index bd435051..a3091470 100644 --- a/packages/status-fetcher/__tests__/fetchers/custom.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/custom.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { CustomApiFetcher } from "../../src/fetchers/custom"; import type { StatusPageEntry } from "../../src/types"; diff --git a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts index 548186a4..d0a5194c 100644 --- a/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/edge-cases.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, it } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { Exit } from "effect"; import { AtlassianFetcher } from "../../src/fetchers/atlassian"; diff --git a/packages/status-fetcher/__tests__/fetchers/html.test.ts b/packages/status-fetcher/__tests__/fetchers/html.test.ts index 209577d1..ddbac6a1 100644 --- a/packages/status-fetcher/__tests__/fetchers/html.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/html.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { HtmlScraperFetcher } from "../../src/fetchers/html"; import type { StatusPageEntry } from "../../src/types"; @@ -92,8 +93,9 @@ describe("HtmlScraperFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "Mozilla/5.0 (compatible; OpenStatus-Bot/1.0)", diff --git a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts index cbc6f75b..6a759fdd 100644 --- a/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/incidentio.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { IncidentioFetcher } from "../../src/fetchers/incidentio"; import type { StatusPageEntry } from "../../src/types"; @@ -111,8 +112,9 @@ describe("IncidentioFetcher", () => { expect(result.status).toBe("operational"); expect(result.description).toBe("All Systems Operational"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://status.test.com/api/v2/summary.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://status.test.com/api/v2/summary.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -234,10 +236,9 @@ describe("IncidentioFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/summary.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/summary.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on 5xx response", async () => { @@ -323,10 +324,11 @@ describe("IncidentioFetcher", () => { const incidents = await runIncidents(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe( "https://status.linear.app/api/v2/incidents.json", - expect.any(Object), ); + expect(call.args[1]).toEqual(expect.any(Object)); expect(incidents).toHaveLength(1); expect(incidents[0]).toMatchObject({ providerIncidentId: "INC-1", diff --git a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts index 5abaf1c1..b7c528cd 100644 --- a/packages/status-fetcher/__tests__/fetchers/instatus.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/instatus.test.ts @@ -1,4 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { beforeEach, describe, it } from "@std/testing/bdd"; import { InstatusFetcher } from "../../src/fetchers/instatus"; import type { StatusPageEntry } from "../../src/types"; @@ -109,8 +110,9 @@ describe("InstatusFetcher", () => { expect(result.description).toBe("All Systems Operational"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - "https://test.instatus.com/summary.json", + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://test.instatus.com/summary.json"); + expect(call.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -230,10 +232,9 @@ describe("InstatusFetcher", () => { await runFetcher(fetcher, entry); - expect(fetchMock).toHaveBeenCalledWith( - "https://custom.endpoint.com/status.json", - expect.any(Object), - ); + const call = fetchMock.calls[fetchMock.calls.length - 1]; + expect(call.args[0]).toBe("https://custom.endpoint.com/status.json"); + expect(call.args[1]).toEqual(expect.any(Object)); }); it("should fail with FetchError on non-200 response (after retries)", async () => { diff --git a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts index 72c6e9b3..01dd6918 100644 --- a/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts +++ b/packages/status-fetcher/__tests__/fetchers/uptimerobot.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; +import { spy } from "@std/testing/mock"; import { UptimeRobotFetcher } from "../../src/fetchers/uptimerobot"; import type { StatusPageEntry } from "../../src/types"; @@ -138,8 +140,9 @@ describe("UptimeRobotFetcher", () => { expect(result.description).toBe("0 monitors down (3 total)"); expect(result.timezone).toBe("UTC"); expect(typeof result.updated_at).toBe("number"); - expect(fetchMock).toHaveBeenCalledWith( - ENDPOINT, + const lastCall = fetchMock.calls[fetchMock.calls.length - 1]; + expect(lastCall.args[0]).toBe(ENDPOINT); + expect(lastCall.args[1]).toEqual( expect.objectContaining({ headers: expect.objectContaining({ "User-Agent": "OpenStatus-Directory/1.0", @@ -272,7 +275,7 @@ describe("UptimeRobotFetcher", () => { }); it("unknown statusClass folds to operational with a warn", async () => { - const warnSpy = mock(() => {}); + const warnSpy = spy(() => {}); const originalWarn = console.warn; console.warn = warnSpy; @@ -287,7 +290,7 @@ describe("UptimeRobotFetcher", () => { expect(result.severity).toBe("none"); expect(result.status).toBe("operational"); - expect(warnSpy).toHaveBeenCalled(); + expect(warnSpy.calls.length).toBeGreaterThan(0); } finally { console.warn = originalWarn; } diff --git a/packages/status-fetcher/__tests__/helpers.ts b/packages/status-fetcher/__tests__/helpers.ts index 20f73dba..bcf6a527 100644 --- a/packages/status-fetcher/__tests__/helpers.ts +++ b/packages/status-fetcher/__tests__/helpers.ts @@ -1,5 +1,4 @@ -import { mock } from "bun:test"; - +import { spy } from "@std/testing/mock"; import { Cause, Effect, Exit, Option } from "effect"; import type { FetchError } from "../src/fetch"; @@ -14,7 +13,7 @@ import type { type FetchImpl = (url: string, init?: RequestInit) => Promise; export const installMockFetch = (impl: FetchImpl) => { - const fn = mock(impl); + const fn = spy(impl); global.fetch = fn as unknown as typeof fetch; return fn; }; diff --git a/packages/status-fetcher/__tests__/integration.test.ts b/packages/status-fetcher/__tests__/integration.test.ts index 4c171dbd..73ab88a0 100644 --- a/packages/status-fetcher/__tests__/integration.test.ts +++ b/packages/status-fetcher/__tests__/integration.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, it } from "bun:test"; - +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { Effect } from "effect"; import { fetchers as allFetchers } from "../src/fetchers"; diff --git a/packages/status-fetcher/__tests__/utils.test.ts b/packages/status-fetcher/__tests__/utils.test.ts index ae1179a3..f2d78f56 100644 --- a/packages/status-fetcher/__tests__/utils.test.ts +++ b/packages/status-fetcher/__tests__/utils.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { inferStatus, urlHostnameEndsWith } from "../src/utils"; diff --git a/packages/status-fetcher/package.json b/packages/status-fetcher/package.json index 8e7c9118..8f4d305d 100644 --- a/packages/status-fetcher/package.json +++ b/packages/status-fetcher/package.json @@ -11,8 +11,9 @@ "./types": "./src/types.ts" }, "scripts": { - "test": "bun test", - "test:watch": "bun test --watch", + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "test:watch": "deno test --parallel -A --no-check --sloppy-imports --watch", "tsc": "tsc --noEmit" }, "dependencies": { @@ -21,6 +22,7 @@ "zod": "catalog:" }, "devDependencies": { - "@types/bun": "latest" + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19" } } diff --git a/packages/status-fetcher/tsconfig.json b/packages/status-fetcher/tsconfig.json index 9d6eaf3f..0d9806db 100644 --- a/packages/status-fetcher/tsconfig.json +++ b/packages/status-fetcher/tsconfig.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "ES2022", "module": "ESNext", - "lib": ["ES2022"], "moduleResolution": "bundler", "allowImportingTsExtensions": true, "noEmit": true, diff --git a/packages/subscriptions/package.json b/packages/subscriptions/package.json index c50cc3b9..ada82745 100644 --- a/packages/subscriptions/package.json +++ b/packages/subscriptions/package.json @@ -15,7 +15,8 @@ } }, "scripts": { - "test": "bun test" + "check": "deno check --sloppy-imports .", + "test": "deno test -A --no-check --sloppy-imports" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -27,7 +28,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "@types/bun": "latest", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/subscriptions/src/channels/email.test.ts b/packages/subscriptions/src/channels/email.test.ts index 6772aceb..bda44066 100644 --- a/packages/subscriptions/src/channels/email.test.ts +++ b/packages/subscriptions/src/channels/email.test.ts @@ -1,6 +1,8 @@ -import { beforeEach, describe, expect, spyOn, test } from "bun:test"; - +import "../test-preload.ts"; import { EmailClient } from "@openstatus/emails"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import type { PageUpdate, Subscription } from "../types"; import { @@ -12,15 +14,8 @@ import { // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -const sendPageSubscriptionMock = spyOn( - EmailClient.prototype, - "sendPageSubscription", -).mockResolvedValue(undefined); - -const sendStatusReportUpdateMock = spyOn( - EmailClient.prototype, - "sendStatusReportUpdate", -).mockResolvedValue(undefined); +let sendPageSubscriptionMock: Stub; +let sendStatusReportUpdateMock: Stub; function makeSub(overrides: Partial = {}): Subscription { return { @@ -51,8 +46,21 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - sendPageSubscriptionMock.mockClear(); - sendStatusReportUpdateMock.mockClear(); + sendPageSubscriptionMock = stub( + EmailClient.prototype, + "sendPageSubscription", + () => Promise.resolve(undefined), + ); + sendStatusReportUpdateMock = stub( + EmailClient.prototype, + "sendStatusReportUpdate", + () => Promise.resolve(undefined), + ); +}); + +afterEach(() => { + sendPageSubscriptionMock.restore(); + sendStatusReportUpdateMock.restore(); }); // ─── validateEmailConfig ────────────────────────────────────────────────────── @@ -94,8 +102,8 @@ describe("sendEmailVerification", () => { const sub = makeSub({ email: "user@example.com", pageName: "My Page" }); await sendEmailVerification(sub, "https://example.com/verify/abc"); - expect(sendPageSubscriptionMock).toHaveBeenCalledTimes(1); - const [args] = sendPageSubscriptionMock.mock.calls[0]; + assertSpyCalls(sendPageSubscriptionMock, 1); + const [args] = sendPageSubscriptionMock.calls[0].args; expect(args.to).toBe("user@example.com"); expect(args.link).toBe("https://example.com/verify/abc"); expect(args.page).toBe("My Page"); @@ -107,13 +115,13 @@ describe("sendEmailVerification", () => { describe("sendEmailNotifications", () => { test("does nothing for an empty subscriptions array", async () => { await sendEmailNotifications([], makeUpdate()); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("filters out subscriptions without an email address", async () => { const sub = makeSub({ email: undefined }); await sendEmailNotifications([sub], makeUpdate()); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("calls sendStatusReportUpdate once with all valid subscribers", async () => { @@ -123,8 +131,8 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub1, sub2], update); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.subscribers).toHaveLength(2); expect(args.subscribers[0].email).toBe("a@example.com"); expect(args.subscribers[1].email).toBe("b@example.com"); @@ -138,7 +146,7 @@ describe("sendEmailNotifications", () => { await sendEmailNotifications([sub], update); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.pageComponents).toEqual(["API", "Database"]); }); @@ -146,7 +154,7 @@ describe("sendEmailNotifications", () => { const sub = makeSub(); await sendEmailNotifications([sub], makeUpdate({ updateId: 77 })); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.idempotencyKey).toBe("status-report-update:77"); }); @@ -157,7 +165,7 @@ describe("sendEmailNotifications", () => { makeUpdate({ id: 17, updateId: undefined, status: "maintenance" }), ); - const [args] = sendStatusReportUpdateMock.mock.calls[0]; + const [args] = sendStatusReportUpdateMock.calls[0].args; expect(args.idempotencyKey).toBe("page-update:17:maintenance"); }); }); diff --git a/packages/subscriptions/src/channels/index.test.ts b/packages/subscriptions/src/channels/index.test.ts index fc6df14f..d635918b 100644 --- a/packages/subscriptions/src/channels/index.test.ts +++ b/packages/subscriptions/src/channels/index.test.ts @@ -1,4 +1,6 @@ -import { describe, expect, test } from "bun:test"; +import "../test-preload.ts"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { getChannel } from "./index"; diff --git a/packages/subscriptions/src/channels/webhook.test.ts b/packages/subscriptions/src/channels/webhook.test.ts index a10a9b41..d17be6f4 100644 --- a/packages/subscriptions/src/channels/webhook.test.ts +++ b/packages/subscriptions/src/channels/webhook.test.ts @@ -1,4 +1,6 @@ -import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"; +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { webhookPayloadSchema } from "../payload"; import type { PageUpdate, Subscription } from "../types"; @@ -15,7 +17,21 @@ import { const SLACK_URL = "https://hooks.slack.com/services/T1/B1/XXX"; const DISCORD_URL = "https://discord.com/api/webhooks/1/xxx"; -let fetchMock: any; +let fetchMock: Stub; + +function setFetch( + impl: ( + input: Request | string | URL, + init?: RequestInit, + ) => Promise, +) { + fetchMock?.restore(); + fetchMock = stub(globalThis, "fetch", impl); +} + +function resolveFetch(response: Response) { + setFetch(() => Promise.resolve(response)); +} function makeSub(overrides: Partial = {}): Subscription { return { @@ -46,11 +62,13 @@ function makeUpdate(overrides: Partial = {}): PageUpdate { } beforeEach(() => { - fetchMock = spyOn(global, "fetch"); + fetchMock = stub(globalThis, "fetch", () => + Promise.resolve(new Response(null, { status: 200 })), + ); }); afterEach(() => { - fetchMock.mockRestore(); + fetchMock.restore(); }); // ─── validateWebhookConfig ──────────────────────────────────────────────────── @@ -99,7 +117,7 @@ describe("sendWebhookVerification", () => { }); test("resolves when fetch returns 200", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub(); await expect( sendWebhookVerification(sub, "https://example.com/verify/abc"), @@ -107,7 +125,7 @@ describe("sendWebhookVerification", () => { }); test("throws when fetch returns a non-ok status", async () => { - fetchMock.mockResolvedValue( + resolveFetch( new Response(null, { status: 500, statusText: "Server Error" }), ); const sub = makeSub(); @@ -117,15 +135,15 @@ describe("sendWebhookVerification", () => { }); test("posts to the correct URL with the expected payload", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "my-token", webhookUrl: "https://hooks.example.com/sub", }); await sendWebhookVerification(sub, "https://example.com/verify/my-token"); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(url).toBe("https://hooks.example.com/sub"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -141,11 +159,11 @@ describe("sendWebhookNotifications", () => { test("skips subscriptions without a webhookUrl", async () => { const sub = makeSub({ webhookUrl: undefined }); await sendWebhookNotifications([sub], makeUpdate()); - expect(fetchMock).not.toHaveBeenCalled(); + assertSpyCalls(fetchMock, 0); }); test("sends a POST request to each webhook URL", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub1 = makeSub({ webhookUrl: "https://hooks.slack.com/services/T1/B1/aaa", }); @@ -155,14 +173,14 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub1, sub2], makeUpdate()); - expect(fetchMock).toHaveBeenCalledTimes(2); - const urls = fetchMock.mock.calls.map(([url]: [string]) => url); + assertSpyCalls(fetchMock, 2); + const urls = fetchMock.calls.map((c) => c.args[0]); expect(urls).toContain("https://hooks.slack.com/services/T1/B1/aaa"); expect(urls).toContain("https://hooks.slack.com/services/T2/B2/bbb"); }); test("sends a generic JSON payload to non-Slack/Discord URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const generic = makeSub({ id: 101, webhookUrl: "https://example.com/webhook", @@ -174,19 +192,19 @@ describe("sendWebhookNotifications", () => { makeUpdate({ updateId: 42 }), ); - expect(fetchMock).toHaveBeenCalledTimes(2); + assertSpyCalls(fetchMock, 2); const byUrl = new Map( - fetchMock.mock.calls.map(([url, init]: [string, RequestInit]) => [ - url, - JSON.parse(init.body as string), - ]), + fetchMock.calls.map((c) => { + const [url, init] = c.args as [string, RequestInit]; + return [url, JSON.parse(init.body as string)]; + }), ); expect(byUrl.get("https://example.com/webhook").type).toBe("status_report"); expect(byUrl.get(SLACK_URL).attachments).toBeDefined(); }); test("the status_report body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -200,14 +218,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("the maintenance body sent over the wire satisfies webhookPayloadSchema (v1)", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: "https://example.com/webhook" }); await sendWebhookNotifications( @@ -220,14 +238,14 @@ describe("sendWebhookNotifications", () => { }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const sentBody = JSON.parse(init?.body as string); const result = webhookPayloadSchema.safeParse(sentBody); expect(result.success).toBe(true); }); test("applies custom headers from channelConfig", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ channelConfig: JSON.stringify({ headers: [{ key: "X-Custom-Header", value: "my-value" }], @@ -236,17 +254,17 @@ describe("sendWebhookNotifications", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const headers = init?.headers as Record; expect(headers["X-Custom-Header"]).toBe("my-value"); }); test("continues sending to remaining webhooks when one keeps failing", async () => { const failUrl = "https://hooks.slack.com/services/T1/B1/fail"; - fetchMock.mockImplementation(async (url: string) => - url === failUrl + setFetch((input) => + String(input) === failUrl ? Promise.reject(new Error("Network error")) - : new Response(null, { status: 200 }), + : Promise.resolve(new Response(null, { status: 200 })), ); const sub1 = makeSub({ webhookUrl: failUrl }); @@ -258,17 +276,22 @@ describe("sendWebhookNotifications", () => { sendWebhookNotifications([sub1, sub2], makeUpdate()), ).resolves.toBeUndefined(); - const calls = fetchMock.mock.calls.map(([url]: [string]) => url); + const calls = fetchMock.calls.map((c) => String(c.args[0])); expect(calls).toContain("https://hooks.slack.com/services/T2/B2/succeed"); }); test("retries transient failures then succeeds", async () => { let attempts = 0; - fetchMock.mockImplementation(async () => { + setFetch(() => { attempts += 1; - return attempts < 3 - ? new Response(null, { status: 503, statusText: "Service Unavailable" }) - : new Response(null, { status: 200 }); + return Promise.resolve( + attempts < 3 + ? new Response(null, { + status: 503, + statusText: "Service Unavailable", + }) + : new Response(null, { status: 200 }), + ); }); await expect( @@ -279,13 +302,13 @@ describe("sendWebhookNotifications", () => { }); test("does not retry non-retryable 4xx responses", async () => { - fetchMock.mockResolvedValue( + resolveFetch( new Response(null, { status: 400, statusText: "Bad Request" }), ); await sendWebhookNotifications([makeSub()], makeUpdate()); - expect(fetchMock).toHaveBeenCalledTimes(1); + assertSpyCalls(fetchMock, 1); }); }); @@ -313,31 +336,31 @@ describe("detectWebhookFlavor", () => { describe("sendWebhookNotifications (flavor detection)", () => { test("emits Slack blocks payload for hooks.slack.com URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: SLACK_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.attachments).toBeDefined(); expect(body.attachments[0].blocks).toBeInstanceOf(Array); }); test("emits Discord embed payload for discord.com URLs", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL }); await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.embeds).toBeInstanceOf(Array); expect(body.embeds[0].title).toBe("Test Incident"); }); test("Slack payload includes manage/unsubscribe links", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", pageSlug: "demo", @@ -345,7 +368,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const stringified = init?.body as string; expect(stringified).toContain("https://demo.openstatus.dev/manage/tok-123"); expect(stringified).toContain( @@ -354,7 +377,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Slack payload uses custom domain when present", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ token: "tok-123", customDomain: "status.partner.com", @@ -362,18 +385,18 @@ describe("sendWebhookNotifications (flavor detection)", () => { await sendWebhookNotifications([sub], makeUpdate()); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const stringified = init?.body as string; expect(stringified).toContain("https://status.partner.com/manage/tok-123"); }); test("Slack payload links to the event details and the page origin", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ pageSlug: "demo", pageName: "Demo" }); await sendWebhookNotifications([sub], makeUpdate({ id: 99 })); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); const stringified = init?.body as string; // title stays in a plain_text header block @@ -388,7 +411,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { }); test("Discord embed url points at the event; maintenance uses the maintenance path", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); const sub = makeSub({ webhookUrl: DISCORD_URL, pageSlug: "demo", @@ -400,7 +423,7 @@ describe("sendWebhookNotifications (flavor detection)", () => { makeUpdate({ id: 7, status: "maintenance" }), ); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const body = JSON.parse(init?.body as string); expect(body.embeds[0].url).toBe( "https://demo.openstatus.dev/events/maintenance/7", @@ -584,14 +607,14 @@ describe("buildTestPayload", () => { describe("sendTestWebhookRequest", () => { test("POSTs flavor-appropriate payload", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", }); - expect(fetchMock).toHaveBeenCalledTimes(1); - const [url, init] = fetchMock.mock.calls[0]; + assertSpyCalls(fetchMock, 1); + const [url, init] = fetchMock.calls[0].args; expect(url).toBe("https://example.com/hook"); expect(init?.method).toBe("POST"); const body = JSON.parse(init?.body as string); @@ -599,9 +622,7 @@ describe("sendTestWebhookRequest", () => { }); test("throws on non-2xx response", async () => { - fetchMock.mockResolvedValue( - new Response(null, { status: 404, statusText: "Not Found" }), - ); + resolveFetch(new Response(null, { status: 404, statusText: "Not Found" })); await expect( sendTestWebhookRequest({ url: "https://example.com/hook", @@ -611,14 +632,14 @@ describe("sendTestWebhookRequest", () => { }); test("passes custom headers", async () => { - fetchMock.mockResolvedValue(new Response(null, { status: 200 })); + resolveFetch(new Response(null, { status: 200 })); await sendTestWebhookRequest({ url: "https://example.com/hook", flavor: "generic", headers: { "X-Custom": "abc" }, }); - const [, init] = fetchMock.mock.calls[0]; + const [, init] = fetchMock.calls[0].args; const headers = init?.headers as Record; expect(headers["X-Custom"]).toBe("abc"); }); diff --git a/packages/subscriptions/src/dispatcher.test.ts b/packages/subscriptions/src/dispatcher.test.ts index 4cb54ac1..8888bc93 100644 --- a/packages/subscriptions/src/dispatcher.test.ts +++ b/packages/subscriptions/src/dispatcher.test.ts @@ -1,19 +1,20 @@ -import { - afterAll, - beforeAll, - beforeEach, - describe, - expect, - spyOn, - test, -} from "bun:test"; - +import "./test-preload.ts"; import { db, eq } from "@openstatus/db"; import { pageSubscriber, pageSubscriberToPageComponent, } from "@openstatus/db/src/schema"; import { EmailClient } from "@openstatus/emails"; +import { expect } from "@std/expect"; +import { + afterAll, + afterEach, + beforeAll, + beforeEach, + describe, + test, +} from "@std/testing/bdd"; +import { assertSpyCalls, type Stub, stub } from "@std/testing/mock"; import { dispatchPageUpdate } from "./dispatcher"; import type { PageUpdate } from "./types"; @@ -21,10 +22,8 @@ import type { PageUpdate } from "./types"; // RESEND_API_KEY is set in test-preload.ts (see bunfig.toml) so @openstatus/emails // loads successfully and EmailClient prototype methods can be spied on. -const sendStatusReportUpdateMock = spyOn( - EmailClient.prototype, - "sendStatusReportUpdate", -).mockResolvedValue(undefined); +let sendStatusReportUpdateMock: Stub; +let rejectNextSend: Error | null = null; // IDs present in the seeded database const PAGE_ID = 1; // slug: "status" @@ -105,7 +104,23 @@ beforeAll(async () => { afterAll(cleanAll); beforeEach(() => { - sendStatusReportUpdateMock.mockClear(); + rejectNextSend = null; + sendStatusReportUpdateMock = stub( + EmailClient.prototype, + "sendStatusReportUpdate", + () => { + if (rejectNextSend) { + const error = rejectNextSend; + rejectNextSend = null; + return Promise.reject(error); + } + return Promise.resolve(undefined); + }, + ); +}); + +afterEach(() => { + sendStatusReportUpdateMock.restore(); }); // ─── dispatchPageUpdate - component filtering ───────────────────────────────── @@ -116,8 +131,8 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -130,7 +145,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -143,7 +158,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1, COMPONENT_2] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).toContain(EMAILS.entirePage); @@ -154,8 +169,8 @@ describe("dispatchPageUpdate - component filtering", () => { test("notifies only the entire-page subscriber when update has no affected components", async () => { await dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })); - expect(sendStatusReportUpdateMock).toHaveBeenCalledTimes(1); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + assertSpyCalls(sendStatusReportUpdateMock, 1); + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; expect(subscribers).toHaveLength(1); expect(subscribers[0].email).toBe(EMAILS.entirePage); @@ -167,7 +182,7 @@ describe("dispatchPageUpdate - component filtering", () => { makePageUpdate({ pageComponentIds: [COMPONENT_1] }), ); - const { subscribers } = sendStatusReportUpdateMock.mock.calls[0][0]; + const { subscribers } = sendStatusReportUpdateMock.calls[0].args[0]; const emails = subscribers.map((s: { email: string }) => s.email); expect(emails).not.toContain(EMAILS.component2); @@ -182,11 +197,11 @@ describe("dispatchPageUpdate - edge cases", () => { makePageUpdate({ pageId: 99999, pageComponentIds: [COMPONENT_1] }), ); - expect(sendStatusReportUpdateMock).not.toHaveBeenCalled(); + assertSpyCalls(sendStatusReportUpdateMock, 0); }); test("does not propagate channel failure — resolves even when sendStatusReportUpdate throws", async () => { - sendStatusReportUpdateMock.mockRejectedValueOnce(new Error("SMTP failure")); + rejectNextSend = new Error("SMTP failure"); await expect( dispatchPageUpdate(makePageUpdate({ pageComponentIds: [] })), diff --git a/packages/subscriptions/src/test-preload.ts b/packages/subscriptions/src/test-preload.ts index 29170704..b26048d3 100644 --- a/packages/subscriptions/src/test-preload.ts +++ b/packages/subscriptions/src/test-preload.ts @@ -1,6 +1,11 @@ /** - * Preload file for bun test. - * Runs before any test file is loaded, ensuring env vars are set - * before module-level env validations (e.g. @openstatus/emails) fire. + * Test env setup. Import this FIRST in any test file so env vars are set + * before module-level env validations (e.g. @openstatus/emails, @openstatus/db) + * fire on import. + * + * Bun's test runner set NODE_ENV=test automatically; Deno does not, so we set + * it here. The @openstatus/db env hack maps NODE_ENV=test to the local turso + * URL, and @openstatus/emails validates RESEND_API_KEY at module load. */ -process.env.RESEND_API_KEY = "test-key"; +process.env.NODE_ENV = "test"; +process.env.RESEND_API_KEY ??= "test-key"; diff --git a/packages/subscriptions/tsconfig.json b/packages/subscriptions/tsconfig.json index 868037cf..4225a2de 100644 --- a/packages/subscriptions/tsconfig.json +++ b/packages/subscriptions/tsconfig.json @@ -1,12 +1,10 @@ { "extends": "@openstatus/tsconfig/base.json", "compilerOptions": { - "lib": ["ES2022", "DOM"], "module": "ESNext", "target": "ES2022", "moduleResolution": "bundler", - "jsx": "react-jsx", - "types": ["bun"] + "jsx": "react-jsx" }, "include": [".", "src"], "exclude": ["dist", "build", "node_modules"] diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json new file mode 100644 index 00000000..ee345766 --- /dev/null +++ b/packages/test-utils/package.json @@ -0,0 +1,20 @@ +{ + "name": "@openstatus/test-utils", + "version": "1.0.0", + "private": true, + "main": "src/index.ts", + "exports": { + ".": "./src/index.ts" + }, + "scripts": { + "check": "deno check --sloppy-imports ." + }, + "dependencies": { + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19" + }, + "devDependencies": { + "@openstatus/tsconfig": "workspace:*", + "typescript": "catalog:" + } +} diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts new file mode 100644 index 00000000..25c2570b --- /dev/null +++ b/packages/test-utils/src/index.ts @@ -0,0 +1,27 @@ +// Single import surface for migrated tests: `import { ... } from "@openstatus/test-utils"`. +// Importing this module registers the Bun-compat matchers (./matchers side-effect). +import "./matchers.ts"; + +export { + after, + afterAll, + afterEach, + before, + beforeAll, + beforeEach, + describe, + it, + test, +} from "./runner.ts"; +export { expect } from "jsr:@std/expect"; +export { type MockFn, mock } from "./mock-fn.ts"; +export { + assertSpyCall, + assertSpyCalls, + returnsNext, + type Spy, + spy, + type Stub, + stub, +} from "jsr:@std/testing/mock"; +export { FakeTime } from "jsr:@std/testing/time"; diff --git a/packages/test-utils/src/matchers.ts b/packages/test-utils/src/matchers.ts new file mode 100644 index 00000000..36d58bd3 --- /dev/null +++ b/packages/test-utils/src/matchers.ts @@ -0,0 +1,95 @@ +import { expect } from "jsr:@std/expect"; + +// @std/expect stopped re-exporting its matcher-context type; these matchers only +// read `value`, so a minimal local shape is enough. +type ExpectMatcherContext = { value: unknown }; + +type MatcherResult = { pass: boolean; message: () => string }; + +const isObject = (v: unknown): v is Record => + typeof v === "object" && v !== null; + +const size = (v: unknown): number => { + if (typeof v === "string" || Array.isArray(v)) return v.length; + if (v instanceof Map || v instanceof Set) return v.size; + if (isObject(v)) return Object.keys(v).length; + return -1; +}; + +// Bun's `expect` extension matchers, reimplemented on @std/expect so the ~150 +// existing call sites keep working under `deno test`. +expect.extend({ + toBeNumber(context: ExpectMatcherContext): MatcherResult { + const pass = + typeof context.value === "number" && !Number.isNaN(context.value); + return { pass, message: () => `expected ${context.value} to be a number` }; + }, + toBeString(context: ExpectMatcherContext): MatcherResult { + return { + pass: typeof context.value === "string", + message: () => `expected ${context.value} to be a string`, + }; + }, + toBeBoolean(context: ExpectMatcherContext): MatcherResult { + return { + pass: typeof context.value === "boolean", + message: () => `expected ${context.value} to be a boolean`, + }; + }, + toBeArray(context: ExpectMatcherContext): MatcherResult { + return { + pass: Array.isArray(context.value), + message: () => `expected ${context.value} to be an array`, + }; + }, + toBeTrue(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === true, + message: () => `expected ${context.value} to be true`, + }; + }, + toBeFalse(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === false, + message: () => `expected ${context.value} to be false`, + }; + }, + toBeNil(context: ExpectMatcherContext): MatcherResult { + return { + pass: context.value === null || context.value === undefined, + message: () => `expected ${context.value} to be null or undefined`, + }; + }, + toBeEmpty(context: ExpectMatcherContext): MatcherResult { + return { + pass: size(context.value) === 0, + message: () => `expected ${context.value} to be empty`, + }; + }, + toBeOneOf( + context: ExpectMatcherContext, + expected: readonly unknown[], + ): MatcherResult { + return { + pass: expected.includes(context.value), + message: () => + `expected ${context.value} to be one of ${JSON.stringify(expected)}`, + }; + }, + toContainValue(context: ExpectMatcherContext, value: unknown): MatcherResult { + const pass = + isObject(context.value) && Object.values(context.value).includes(value); + return { pass, message: () => `expected object to contain value ${value}` }; + }, + toContainKey(context: ExpectMatcherContext, key: string): MatcherResult { + const pass = + isObject(context.value) && Object.keys(context.value).includes(key); + return { pass, message: () => `expected object to contain key ${key}` }; + }, + pass(_context: ExpectMatcherContext, _message?: string): MatcherResult { + return { pass: true, message: () => _message ?? "passed" }; + }, + fail(_context: ExpectMatcherContext, message?: string): MatcherResult { + return { pass: false, message: () => message ?? "failed" }; + }, +}); diff --git a/packages/test-utils/src/mock-fn.ts b/packages/test-utils/src/mock-fn.ts new file mode 100644 index 00000000..2d71214f --- /dev/null +++ b/packages/test-utils/src/mock-fn.ts @@ -0,0 +1,112 @@ +// Bun-compatible `mock()` for the Deno migration. Bun's mock function isn't +// available under `deno test`; this reimplements the subset our suites use +// (the jest-style `.mock.calls` + `.mockX()` helpers) on plain closures. +// +// NOTE: bun's `mock.module(specifier, factory)` has no Deno equivalent and is +// intentionally NOT provided here — module replacement is done via the +// `--import-map` flag and test-double modules instead. + +// oxlint-disable-next-line typescript/no-explicit-any +type AnyFn = (...args: any[]) => any; + +interface MockState { + // oxlint-disable-next-line typescript/no-explicit-any + calls: any[][]; + results: { type: "return" | "throw"; value: unknown }[]; +} + +export interface MockFn extends AnyFn { + mock: MockState; + mockClear(): MockFn; + mockReset(): MockFn; + mockImplementation(fn: AnyFn): MockFn; + mockImplementationOnce(fn: AnyFn): MockFn; + mockReturnValue(value: unknown): MockFn; + mockReturnValueOnce(value: unknown): MockFn; + mockResolvedValue(value: unknown): MockFn; + mockResolvedValueOnce(value: unknown): MockFn; + mockRejectedValue(value: unknown): MockFn; + mockRestore(): MockFn; +} + +export function mock(impl?: AnyFn): MockFn { + let defaultImpl = impl; + const onceQueue: AnyFn[] = []; + const state: MockState = { calls: [], results: [] }; + + // oxlint-disable-next-line typescript/no-explicit-any + const fn = ((...args: any[]) => { + state.calls.push(args); + const use = onceQueue.length ? onceQueue.shift() : defaultImpl; + try { + const value = use ? use(...args) : undefined; + state.results.push({ type: "return", value }); + return value; + } catch (err) { + state.results.push({ type: "throw", value: err }); + throw err; + } + }) as MockFn; + + fn.mock = state; + // Expose the @std/expect mock interface (Symbol.for("@MOCK")) so its + // `.toHaveBeenCalled*` matchers recognize this shim, not just `.mock.calls`. + Object.defineProperty(fn, Symbol.for("@MOCK"), { + get() { + return { + calls: state.calls.map((args, i) => { + const r = state.results[i]; + return { + args, + returned: r?.type === "return" ? r.value : undefined, + thrown: r?.type === "throw" ? r.value : undefined, + timestamp: 0, + returns: r?.type === "return", + throws: r?.type === "throw", + }; + }), + }; + }, + }); + fn.mockClear = () => { + state.calls = []; + state.results = []; + return fn; + }; + fn.mockReset = () => { + fn.mockClear(); + onceQueue.length = 0; + defaultImpl = undefined; + return fn; + }; + fn.mockImplementation = (f) => { + defaultImpl = f; + return fn; + }; + fn.mockImplementationOnce = (f) => { + onceQueue.push(f); + return fn; + }; + fn.mockReturnValue = (value) => { + defaultImpl = () => value; + return fn; + }; + fn.mockReturnValueOnce = (value) => { + onceQueue.push(() => value); + return fn; + }; + fn.mockResolvedValue = (value) => { + defaultImpl = () => Promise.resolve(value); + return fn; + }; + fn.mockResolvedValueOnce = (value) => { + onceQueue.push(() => Promise.resolve(value)); + return fn; + }; + fn.mockRejectedValue = (value) => { + defaultImpl = () => Promise.reject(value); + return fn; + }; + fn.mockRestore = () => fn; + return fn; +} diff --git a/packages/test-utils/src/runner.ts b/packages/test-utils/src/runner.ts new file mode 100644 index 00000000..55dd22f4 --- /dev/null +++ b/packages/test-utils/src/runner.ts @@ -0,0 +1,58 @@ +import { + describe as nodeDescribe, + it as nodeIt, + test as nodeTest, +} from "node:test"; + +type Body = () => void | Promise; +type BaseFn = (name: string, body: Body) => void; +type EachCase = readonly unknown[]; + +const formatName = (name: string, args: EachCase, index: number): string => { + let i = 0; + const interpolated = name.replace(/%[spdijfo%]/g, (token) => { + if (token === "%%") return "%"; + const arg = args[i++]; + return typeof arg === "string" ? arg : JSON.stringify(arg); + }); + return interpolated === name && args.length > 0 + ? `${name} [${index}]` + : interpolated; +}; + +const makeEach = + (base: BaseFn) => + (cases: readonly T[]) => + (name: string, body: (...args: T) => void | Promise): void => { + cases.forEach((args, index) => { + base(formatName(name, args, index), () => body(...args)); + }); + }; + +// node:test's `test`/`it`/`describe` lack Jest/Bun's `.each`; everything else +// (.skip/.todo/.only) exists natively and is preserved by reference. +type Augmented = F & { + each: ( + cases: readonly T[], + ) => (name: string, body: (...args: T) => void | Promise) => void; +}; + +const augment = (base: F): Augmented => { + const fn = base as Augmented; + fn.each = makeEach(base as unknown as BaseFn); + return fn; +}; + +export const test = augment(nodeTest); +export const it = augment(nodeIt); +export const describe = augment( + nodeDescribe as unknown as typeof nodeTest, +) as unknown as Augmented; +export { + after, + after as afterAll, + afterEach, + before, + before as beforeAll, + beforeEach, +} from "node:test"; diff --git a/packages/theme-store/package.json b/packages/theme-store/package.json index cdb62553..ffc39d71 100644 --- a/packages/theme-store/package.json +++ b/packages/theme-store/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": {}, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/tinybird/package.json b/packages/tinybird/package.json index 17a465bc..c575aa6a 100644 --- a/packages/tinybird/package.json +++ b/packages/tinybird/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "license": "MIT", "main": "src/index.ts", + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@chronark/zod-bird": "catalog:", "zod": "catalog:" diff --git a/packages/tracker/package.json b/packages/tracker/package.json index 6f654a01..f73478cc 100644 --- a/packages/tracker/package.json +++ b/packages/tracker/package.json @@ -7,7 +7,8 @@ "author": "", "main": "src/index.ts", "scripts": { - "test": "bun test" + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports" }, "dependencies": { "@openstatus/db": "workspace:*", @@ -16,7 +17,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", - "bun-types": "catalog:", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/tracker/src/mock.ts b/packages/tracker/src/mock.ts index 5f338e46..50082d4c 100644 --- a/packages/tracker/src/mock.ts +++ b/packages/tracker/src/mock.ts @@ -1,6 +1,4 @@ -import type { Monitor } from "@openstatus/tinybird"; - -import { Tracker } from "./tracker"; +import { type Monitor, Tracker } from "./tracker"; export const mockMonitor: Monitor[] = [ { day: "2024-02-21 00:00:00", count: 762, ok: 762 }, diff --git a/packages/tracker/src/tracker.test.ts b/packages/tracker/src/tracker.test.ts index 0c4fddf3..8f42f53f 100644 --- a/packages/tracker/src/tracker.test.ts +++ b/packages/tracker/src/tracker.test.ts @@ -1,11 +1,11 @@ -import { describe, expect, test } from "bun:test"; - import type { Incident, Maintenance, StatusReport, StatusReportUpdate, } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { blacklistDates } from "./blacklist"; import { classNames, statusDetails } from "./config"; @@ -149,10 +149,12 @@ describe("Tracker", () => { ["0% → Major Outage", 100, 0, Status.MajorOutage], ]; - test.each(cases)("%s", (_label, count, ok, expected) => { - const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); - expect(tracker.currentStatus).toBe(expected); - }); + for (const [label, count, ok, expected] of cases) { + test(label, () => { + const tracker = new Tracker({ data: [day("2024-01-01", count, ok)] }); + expect(tracker.currentStatus).toBe(expected); + }); + } // NOTE: the lower boundary is `> 30`, while the other two are `>=`. So // exactly 30% uptime is Major (not Partial) Outage. Pinning current @@ -336,7 +338,9 @@ describe("Tracker", () => { describe("per-day precedence (maintenance > report > incident > uptime)", () => { const DAY = "2024-01-01"; - const okData = [day(`${DAY} 00:00:00`, 864, 864)]; + // date-only string so `new Date(day)` anchors to UTC midnight, matching + // the UTC fixture dates below regardless of the runner's timezone. + const okData = [day(DAY, 864, 864)]; test("maintenance overlapping the day wins", () => { const [bucket] = new Tracker({ @@ -394,7 +398,7 @@ describe("Tracker", () => { test("an incident resolved on a previous day does not affect this bucket", () => { const [bucket] = new Tracker({ - data: [day("2024-01-02 00:00:00", 864, 864)], + data: [day("2024-01-02", 864, 864)], incidents: [ createIncident({ startedAt: new Date("2024-01-01T12:00:00.000Z"), diff --git a/packages/tracker/src/tracker.ts b/packages/tracker/src/tracker.ts index e96bec6f..f5da4d4c 100644 --- a/packages/tracker/src/tracker.ts +++ b/packages/tracker/src/tracker.ts @@ -11,7 +11,7 @@ import type { StatusDetails, StatusVariant } from "./types"; import { Status } from "./types"; import { endOfDay, isSameDay, startOfDay } from "./utils"; -type Monitor = { +export type Monitor = { count: number; ok: number; day: string; diff --git a/packages/tracker/tsconfig.json b/packages/tracker/tsconfig.json index f40fdec7..bded80f3 100644 --- a/packages/tracker/tsconfig.json +++ b/packages/tracker/tsconfig.json @@ -2,7 +2,6 @@ "extends": "@openstatus/tsconfig/base.json", "include": ["src", "*.ts"], "compilerOptions": { - "target": "ES2021", - "types": ["bun-types"] + "target": "ES2021" } } diff --git a/packages/upstash/package.json b/packages/upstash/package.json index ebda567f..68403d46 100644 --- a/packages/upstash/package.json +++ b/packages/upstash/package.json @@ -3,6 +3,9 @@ "version": "0.0.0", "license": "MIT", "main": "./src/index.ts", + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@upstash/qstash": "catalog:", "@upstash/redis": "catalog:" diff --git a/packages/utils/package.json b/packages/utils/package.json index 666520a4..23419d76 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -6,7 +6,9 @@ "license": "ISC", "author": "", "main": "src/index.ts", - "scripts": {}, + "scripts": { + "check": "deno check --sloppy-imports ." + }, "dependencies": { "@openstatus/assertions": "workspace:*", "@openstatus/regions": "workspace:*", @@ -14,6 +16,8 @@ }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "typescript": "catalog:" } } diff --git a/packages/utils/src/ssrf.test.ts b/packages/utils/src/ssrf.test.ts index 387ad3a7..e687e0e9 100644 --- a/packages/utils/src/ssrf.test.ts +++ b/packages/utils/src/ssrf.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, it } from "@std/testing/bdd"; import { assertSafeUrl, assertSafeUrlSync, safeUrlSchema } from "./ssrf"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4fcd3756..1c8e8803 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,9 +105,15 @@ catalogs: '@openpanel/sdk': specifier: 1.3.1 version: 1.3.1 + '@opentelemetry/exporter-logs-otlp-http': + specifier: 0.208.0 + version: 0.208.0 '@opentelemetry/resources': specifier: 2.7.1 version: 2.7.1 + '@opentelemetry/sdk-logs': + specifier: 0.208.0 + version: 0.208.0 '@opentelemetry/semantic-conventions': specifier: 1.41.1 version: 1.41.1 @@ -189,9 +195,9 @@ catalogs: '@scalar/hono-api-reference': specifier: 0.8.10 version: 0.8.10 - '@sentry/bun': - specifier: 10.53.1 - version: 10.53.1 + '@sentry/deno': + specifier: 10.61.0 + version: 10.61.0 '@sentry/nextjs': specifier: 10.53.1 version: 10.53.1 @@ -757,7 +763,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -921,7 +927,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) '@modelcontextprotocol/sdk': specifier: 'catalog:' version: 1.29.0(zod@4.1.13) @@ -1000,9 +1006,15 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils + '@opentelemetry/exporter-logs-otlp-http': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 @@ -1046,15 +1058,21 @@ importers: '@openstatus/locales': specifier: workspace:* version: link:../../packages/locales + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/validator': specifier: 'catalog:' version: 13.15.10 - bun-types: - specifier: 'catalog:' - version: 1.3.14 dotenv: specifier: 'catalog:' version: 16.6.1 @@ -1192,7 +1210,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-intl: specifier: 'catalog:' version: 4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) @@ -1251,6 +1269,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1269,9 +1293,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 shadcn: specifier: 'catalog:' version: 3.8.5(@types/node@24.12.4)(babel-plugin-macros@3.1.0)(typescript@5.9.3) @@ -1457,7 +1478,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-mdx-remote: specifier: 'catalog:' version: 6.0.0(@types/react@19.2.15)(react@19.2.6) @@ -1537,6 +1558,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@tailwindcss/postcss': specifier: 'catalog:' version: 4.3.0 @@ -1587,7 +1614,7 @@ importers: version: 2.1.1(@logtape/logtape@2.1.1) '@logtape/sentry': specifier: 'catalog:' - version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1) + version: 2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0) '@openstatus/db': specifier: workspace:* version: link:../../packages/db @@ -1654,15 +1681,21 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../../packages/utils + '@opentelemetry/exporter-logs-otlp-http': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: 'catalog:' version: 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': + specifier: 'catalog:' + version: 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: 'catalog:' version: 1.41.1 - '@sentry/bun': + '@sentry/deno': specifier: 'catalog:' - version: 10.53.1 + version: 10.61.0 '@upstash/qstash': specifier: 'catalog:' version: 2.11.0 @@ -1682,12 +1715,12 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../packages/test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../packages/tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -1834,6 +1867,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/react': specifier: 'catalog:' version: 19.2.15 @@ -1902,6 +1941,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/bcryptjs': specifier: 'catalog:' version: 3.0.0 @@ -1913,7 +1958,7 @@ importers: version: 0.31.10 next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) typescript: specifier: 'catalog:' version: 5.9.3 @@ -1945,6 +1990,12 @@ importers: '@react-email/ui': specifier: 'catalog:' version: 6.1.5(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -1973,9 +2024,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2008,6 +2062,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2037,12 +2097,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2065,12 +2128,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2093,12 +2159,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2136,6 +2205,9 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: + '@openstatus/test-utils': + specifier: workspace:* + version: link:../../test-utils '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig @@ -2145,9 +2217,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2170,12 +2239,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2198,12 +2270,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2226,12 +2301,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2254,12 +2332,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2288,6 +2369,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2297,9 +2384,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2328,6 +2412,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -2337,9 +2427,6 @@ importers: '@types/react-dom': specifier: 'catalog:' version: 19.2.3(@types/react@19.2.15) - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2362,12 +2449,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2387,12 +2477,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2418,15 +2511,18 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 '@types/validator': specifier: 'catalog:' version: 13.15.10 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2449,12 +2545,15 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 - bun-types: - specifier: 'catalog:' - version: 1.3.14 typescript: specifier: 'catalog:' version: 5.9.3 @@ -2468,7 +2567,7 @@ importers: specifier: 'catalog:' version: 1.2.0(@bufbuild/protobuf@2.12.0) '@connectrpc/connect': - specifier: ^2.1.1 + specifier: 'catalog:' version: 2.1.1(@bufbuild/protobuf@2.12.0) devDependencies: '@bufbuild/buf': @@ -2564,9 +2663,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2583,9 +2685,12 @@ importers: specifier: 'catalog:' version: 4.1.13 devDependencies: - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' packages/subscriptions: dependencies: @@ -2611,9 +2716,28 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - '@types/bun': - specifier: latest - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' + typescript: + specifier: 'catalog:' + version: 5.9.3 + + packages/test-utils: + dependencies: + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' + devDependencies: + '@openstatus/tsconfig': + specifier: workspace:* + version: link:../tsconfig typescript: specifier: 'catalog:' version: 5.9.3 @@ -2673,9 +2797,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig - bun-types: - specifier: 'catalog:' - version: 1.3.14 + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2894,6 +3021,12 @@ importers: '@openstatus/tsconfig': specifier: workspace:* version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' typescript: specifier: 'catalog:' version: 5.9.3 @@ -2946,6 +3079,17 @@ packages: resolution: {integrity: sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==} hasBin: true + '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': + resolution: {integrity: sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==} + engines: {node: '>=18.0.0'} + + '@apm-js-collab/code-transformer@0.15.0': + resolution: {integrity: sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==} + hasBin: true + + '@apm-js-collab/tracing-hooks@0.10.0': + resolution: {integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==} + '@asamuzakjp/css-color@5.1.11': resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -4305,6 +4449,30 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsr/std__assert@1.0.19': + resolution: {integrity: sha512-pEj6RPkGbqlgRmyKwATp4cUs6+ijxtdrv3bq8v1d2I2CEcMEyPaO8cVKro61wGRDH4cNg8Zx6haztvK/9m7gkA==, tarball: https://npm.jsr.io/~/11/@jsr/std__assert/1.0.19.tgz} + + '@jsr/std__async@1.4.0': + resolution: {integrity: sha512-epQ5wsMrnAxeVtzmO9VviX14siVOSvF2o5dAm9qa6ajdWnWrrQ/oup7/Z2ctAOaxSOJbDWrfhgsenzHsODAogw==, tarball: https://npm.jsr.io/~/11/@jsr/std__async/1.4.0.tgz} + + '@jsr/std__data-structures@1.1.0': + resolution: {integrity: sha512-V/Lrzz3ZBT2ps09SbUuQKIDQ0Ac7qTTloCFNNF7r2MNoIzdz3xsW9+Vd+ZzgXFKdm46+XqBmkv0lpW/HzgRQfg==, tarball: https://npm.jsr.io/~/11/@jsr/std__data-structures/1.1.0.tgz} + + '@jsr/std__expect@1.0.19': + resolution: {integrity: sha512-t8BEISf1666L7dGDIG1nriYh0TQKoU+8mrx93zz+Kj40eov9wNKjKCX96x17p8I8bDcHby4wSv+7jy4+9W6IPg==, tarball: https://npm.jsr.io/~/11/@jsr/std__expect/1.0.19.tgz} + + '@jsr/std__fs@1.0.24': + resolution: {integrity: sha512-UunW2Rg++9sA74NJnYMGTsMVQgoFRAwPP02wRRohL0PQBNorbyxHiyCMRaxYQCtLepTLkC4nUyMtcwrGKqTR6g==, tarball: https://npm.jsr.io/~/11/@jsr/std__fs/1.0.24.tgz} + + '@jsr/std__internal@1.0.14': + resolution: {integrity: sha512-JT8b/t40WcR9q0GDwRZUooY7aXeXnFal8iidE/5TckdAFtvpVAsaJ71/Xgf1SfoChs41s6CZkuCYM8toaNgdvA==, tarball: https://npm.jsr.io/~/11/@jsr/std__internal/1.0.14.tgz} + + '@jsr/std__path@1.1.5': + resolution: {integrity: sha512-3z/0rfvMEz6qiiaZ3quFpEv8BbWQgcpd+ASX29WEdecyJsdPN9uViQf1VxIua265cmGCdICk0WghMjGFoNZ5Ig==, tarball: https://npm.jsr.io/~/11/@jsr/std__path/1.1.5.tgz} + + '@jsr/std__testing@1.0.19': + resolution: {integrity: sha512-maQIRFWIcTTWB7ITYIVbql1Q3KA9AsgR4/Ep2SfEq65V2SxQq52iLcFxuvX0azRp1leBCb8mBUXZr389SajY7Q==, tarball: https://npm.jsr.io/~/11/@jsr/std__testing/1.0.19.tgz} + '@libsql/client@0.17.4': resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==} @@ -4745,10 +4913,6 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.38.0': - resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} - engines: {node: '>=14'} - '@opentelemetry/semantic-conventions@1.41.1': resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} @@ -6276,10 +6440,6 @@ packages: resolution: {integrity: sha512-zXF373hzUOGzUOrqd8xb1U3LQi5uYC3mwv+z5OMKUUinQlu30tTWBs7ypy6YTchtix9QlYaHWlayUF8vBZ5UjA==} engines: {node: '>=18'} - '@sentry/bun@10.53.1': - resolution: {integrity: sha512-UCRUtEc3qLaanmp+9rKQi58d+weBdovytqW6d8ria1fkmxfvnVCYQqVQ0c/FLrGggqjqizO4b4WnLnuy/y/CXw==} - engines: {node: '>=18'} - '@sentry/bundler-plugin-core@5.3.0': resolution: {integrity: sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==} engines: {node: '>= 18'} @@ -6336,14 +6496,25 @@ packages: engines: {node: '>= 10'} hasBin: true + '@sentry/conventions@0.12.0': + resolution: {integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==} + engines: {node: '>=14'} + '@sentry/core@10.53.1': resolution: {integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==} engines: {node: '>=18'} + '@sentry/core@10.61.0': + resolution: {integrity: sha512-Edg8t2w45qEKiFnjeA6zRmU47R6la5FEMG+maZEOB2oTyJ+ujmh8LGaZ3G8aC0VdkKn8CXhHtDesze6oDc1oTA==} + engines: {node: '>=18'} + '@sentry/core@8.9.2': resolution: {integrity: sha512-ixm8NISFlPlEo3FjSaqmq4nnd13BRHoafwJ5MG+okCz6BKGZ1SexEggP42/QpGvDprUUHnfncG6WUMgcarr1zA==} engines: {node: '>=14.18'} + '@sentry/deno@10.61.0': + resolution: {integrity: sha512-TLs+Z+I5xWL0YdXtQ/LqJ7F1T/rRytxFlSJD1gXm5mx3T+wwNrni20N4XGnV1Bo8s8EB05HTjJXGzFb96CJDFw==} + '@sentry/nextjs@10.53.1': resolution: {integrity: sha512-pkwqrpAG//LtW5W1Odud0PLLT+rnjDjodUEbScULHVaZE6/Gt+WGBMZmtzpNM+UwhsN19/4PyO7ocLTx/IFrkQ==} engines: {node: '>=18'} @@ -6393,6 +6564,10 @@ packages: peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x + '@sentry/server-utils@10.61.0': + resolution: {integrity: sha512-IrOyMzlOyBkWtnVYb54sALf2f8WVqyyp7woRfHw8c3IMwUr5AskGOi7k2rjmUXO3Q0UkfHNVarexiEfo8ZqTsg==} + engines: {node: '>=18'} + '@sentry/types@8.9.2': resolution: {integrity: sha512-+LFOyQGl+zk5SZRGZD2MEURf7i5RHgP/mt3s85Rza+vz8M211WJ0YsjkIGUJFSY842nged5QLx4JysLaBlLymg==} engines: {node: '>=14.18'} @@ -6869,9 +7044,6 @@ packages: resolution: {integrity: sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==} deprecated: This is a stub types definition. bcryptjs provides its own type definitions, so you do not need this installed. - '@types/bun@1.3.14': - resolution: {integrity: sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw==} - '@types/caseless@0.12.5': resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} @@ -6969,9 +7141,6 @@ packages: '@types/mysql@2.15.27': resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} @@ -7858,10 +8027,6 @@ packages: resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} engines: {node: '>=20'} - dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} - engines: {node: '>=12'} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -8060,6 +8225,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -8122,6 +8290,10 @@ packages: engines: {node: '>=4'} hasBin: true + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -8180,10 +8352,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} - eventsource-parser@3.0.8: resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} engines: {node: '>=18.0.0'} @@ -8558,10 +8726,6 @@ packages: peerDependencies: hono: ^4.1.1 - hono@4.11.8: - resolution: {integrity: sha512-eVkB/CYCCei7K2WElZW9yYQFWssG0DhaDhVvr7wy5jJ22K+ck8fWW0EsLpB0sITUTvPnc97+rrbQqIr5iqiy9Q==} - engines: {node: '>=16.9.0'} - hono@4.12.21: resolution: {integrity: sha512-uV63apnb0kyPtAUwoWgaGh9HyIFcv8lgmzPZSiTBQAFOFGIzka5EZ1dZocmGnn0XdX0+XTqJ6Tqv7selMuGLRQ==} engines: {node: '>=16.9.0'} @@ -9116,10 +9280,6 @@ packages: lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} - lru-cache@11.2.7: - resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} - engines: {node: 20 || >=22} - lru-cache@11.5.0: resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} engines: {node: 20 || >=22} @@ -9228,6 +9388,10 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meriyah@6.1.4: + resolution: {integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==} + engines: {node: '>=18.0.0'} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -9375,10 +9539,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -9423,11 +9583,6 @@ packages: nanoid-dictionary@5.0.0: resolution: {integrity: sha512-/iCyQHwt36XkaIvSE9fcC8p6DiMPCZMTSMj9UT56Cv6T7f5CuxvOMhpNncaNieQ4z4d32p7ruEtAfRsb7Ya8Gw==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -9438,11 +9593,6 @@ packages: engines: {node: ^18 || >=20} hasBin: true - nanoid@5.1.6: - resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} - engines: {node: ^18 || >=20} - hasBin: true - negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -9810,10 +9960,6 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} - path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} @@ -9918,10 +10064,6 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -10376,6 +10518,9 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semifies@1.0.0: + resolution: {integrity: sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -10686,9 +10831,6 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} - tailwind-merge@3.3.1: - resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} - tailwind-merge@3.6.0: resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} @@ -10749,10 +10891,6 @@ packages: tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -11235,11 +11373,6 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -11343,7 +11476,31 @@ snapshots: ansis: 4.2.0 fzf: 0.5.2 package-manager-detector: 1.6.0 - tinyexec: 1.0.2 + tinyexec: 1.1.2 + + '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + es-module-lexer: 2.1.0 + magic-string: 0.30.21 + module-details-from-path: 1.0.4 + + '@apm-js-collab/code-transformer@0.15.0': + dependencies: + '@types/estree': 1.0.8 + astring: 1.9.0 + esquery: 1.7.0 + meriyah: 6.1.4 + semifies: 1.0.0 + source-map: 0.6.1 + + '@apm-js-collab/tracing-hooks@0.10.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color '@asamuzakjp/css-color@5.1.11': dependencies: @@ -12377,7 +12534,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 minimatch: 10.2.5 transitivePeerDependencies: - supports-color @@ -12460,9 +12617,9 @@ snapshots: pkce-challenge: 5.0.1 zod: 4.1.13 - '@hono/node-server@1.19.9(hono@4.11.8)': + '@hono/node-server@1.19.9(hono@4.12.21)': dependencies: - hono: 4.11.8 + hono: 4.12.21 '@hono/sentry@1.2.2(hono@4.12.21)': dependencies: @@ -12675,6 +12832,44 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@jsr/std__assert@1.0.19': + dependencies: + '@jsr/std__internal': 1.0.14 + + '@jsr/std__async@1.4.0': + dependencies: + '@jsr/std__data-structures': 1.1.0 + + '@jsr/std__data-structures@1.1.0': + dependencies: + '@jsr/std__assert': 1.0.19 + + '@jsr/std__expect@1.0.19': + dependencies: + '@jsr/std__assert': 1.0.19 + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + + '@jsr/std__fs@1.0.24': + dependencies: + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + + '@jsr/std__internal@1.0.14': {} + + '@jsr/std__path@1.1.5': + dependencies: + '@jsr/std__internal': 1.0.14 + + '@jsr/std__testing@1.0.19': + dependencies: + '@jsr/std__assert': 1.0.19 + '@jsr/std__async': 1.4.0 + '@jsr/std__data-structures': 1.1.0 + '@jsr/std__fs': 1.0.24 + '@jsr/std__internal': 1.0.14 + '@jsr/std__path': 1.1.5 + '@libsql/client@0.17.4': dependencies: '@libsql/core': 0.17.4 @@ -12746,12 +12941,12 @@ snapshots: '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.53.1)': + '@logtape/sentry@2.1.1(@logtape/logtape@2.1.1)(@sentry/core@10.61.0)': dependencies: '@logtape/logtape': 2.1.1 - '@sentry/core': 10.53.1 + '@sentry/core': 10.61.0 '@mdx-js/mdx@3.1.1': dependencies: @@ -12791,17 +12986,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - '@hono/node-server': 1.19.9(hono@4.11.8) + '@hono/node-server': 1.19.9(hono@4.12.21) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.8 + hono: 4.12.21 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -12813,17 +13008,17 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@4.1.13)': dependencies: - '@hono/node-server': 1.19.9(hono@4.11.8) + '@hono/node-server': 1.19.9(hono@4.12.21) ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 express: 5.2.1 express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.8 + hono: 4.12.21 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -12944,17 +13139,17 @@ snapshots: '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/exporter-logs-otlp-grpc@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -12991,7 +13186,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13000,7 +13195,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/connect': 3.4.38 transitivePeerDependencies: - supports-color @@ -13039,7 +13234,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13048,7 +13243,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color @@ -13057,7 +13252,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13065,7 +13260,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13074,7 +13269,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13089,7 +13284,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13098,7 +13293,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -13106,7 +13301,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color @@ -13115,7 +13310,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/mysql': 2.15.27 transitivePeerDependencies: - supports-color @@ -13125,7 +13320,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) '@types/pg': 8.15.6 '@types/pg-pool': 2.0.7 @@ -13136,7 +13331,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color @@ -13197,13 +13392,13 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.1)': dependencies: @@ -13223,16 +13418,14 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.38.0 - - '@opentelemetry/semantic-conventions@1.38.0': {} + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/semantic-conventions@1.41.1': {} @@ -14483,7 +14676,7 @@ snapshots: '@scalar/types@0.1.16': dependencies: '@scalar/openapi-types': 0.2.3 - nanoid: 5.1.6 + nanoid: 5.1.11 zod: 3.24.1 '@schummar/icu-type-parser@1.21.5': {} @@ -14523,20 +14716,12 @@ snapshots: '@sentry-internal/replay-canvas': 10.53.1 '@sentry/core': 10.53.1 - '@sentry/bun@10.53.1': - dependencies: - '@sentry/core': 10.53.1 - '@sentry/node': 10.53.1 - transitivePeerDependencies: - - '@opentelemetry/exporter-trace-otlp-http' - - supports-color - '@sentry/bundler-plugin-core@5.3.0': dependencies: '@babel/core': 7.28.5 '@sentry/babel-plugin-component-annotate': 5.3.0 '@sentry/cli': 2.58.5 - dotenv: 16.3.1 + dotenv: 16.6.1 find-up: 5.0.0 glob: 13.0.6 magic-string: 0.30.21 @@ -14588,13 +14773,25 @@ snapshots: - encoding - supports-color + '@sentry/conventions@0.12.0': {} + '@sentry/core@10.53.1': {} + '@sentry/core@10.61.0': {} + '@sentry/core@8.9.2': dependencies: '@sentry/types': 8.9.2 '@sentry/utils': 8.9.2 + '@sentry/deno@10.61.0': + dependencies: + '@opentelemetry/api': 1.9.1 + '@sentry/core': 10.61.0 + '@sentry/server-utils': 10.61.0 + transitivePeerDependencies: + - supports-color + '@sentry/nextjs@10.53.1(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(webpack@5.103.0(@swc/core@1.15.18))': dependencies: '@opentelemetry/api': 1.9.1 @@ -14681,6 +14878,17 @@ snapshots: '@sentry/core': 10.53.1 react: 19.2.6 + '@sentry/server-utils@10.61.0': + dependencies: + '@apm-js-collab/code-transformer': 0.15.0 + '@apm-js-collab/code-transformer-bundler-plugins': 0.5.0 + '@apm-js-collab/tracing-hooks': 0.10.0 + '@sentry/conventions': 0.12.0 + '@sentry/core': 10.61.0 + magic-string: 0.30.21 + transitivePeerDependencies: + - supports-color + '@sentry/types@8.9.2': {} '@sentry/utils@8.9.2': @@ -14746,7 +14954,7 @@ snapshots: dependencies: '@slack/logger': 4.0.1 '@slack/types': 2.21.1 - '@types/node': 24.10.1 + '@types/node': 24.12.4 '@types/retry': 0.12.0 axios: 1.16.1 eventemitter3: 5.0.1 @@ -15118,10 +15326,6 @@ snapshots: dependencies: bcryptjs: 3.0.3 - '@types/bun@1.3.14': - dependencies: - bun-types: 1.3.14 - '@types/caseless@0.12.5': {} '@types/connect@3.4.38': @@ -15222,10 +15426,6 @@ snapshots: dependencies: '@types/node': 24.12.4 - '@types/node@24.10.1': - dependencies: - undici-types: 7.16.0 - '@types/node@24.12.4': dependencies: undici-types: 7.16.0 @@ -16105,8 +16305,6 @@ snapshots: dependencies: type-fest: 5.2.0 - dotenv@16.3.1: {} - dotenv@16.6.1: {} dotenv@17.2.4: {} @@ -16221,6 +16419,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.1.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -16354,6 +16554,10 @@ snapshots: esprima@4.0.1: {} + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -16409,13 +16613,11 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.6: {} - eventsource-parser@3.0.8: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.6 + eventsource-parser: 3.0.8 execa@5.1.1: dependencies: @@ -16721,9 +16923,9 @@ snapshots: foreground-child: 3.3.1 jackspeak: 4.1.1 minimatch: 10.2.5 - minipass: 7.1.2 + minipass: 7.1.3 package-json-from-dist: 1.0.1 - path-scurry: 2.0.1 + path-scurry: 2.0.2 glob@13.0.6: dependencies: @@ -16937,8 +17139,6 @@ snapshots: dependencies: hono: 4.12.21 - hono@4.11.8: {} - hono@4.12.21: {} html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): @@ -17347,7 +17547,7 @@ snapshots: typescript: 5.9.3 unbash: 2.2.0 yaml: 2.9.0 - zod: 4.1.13 + zod: 4.4.3 launder@1.7.1: dependencies: @@ -17478,8 +17678,6 @@ snapshots: lower-case@1.1.4: {} - lru-cache@11.2.7: {} - lru-cache@11.5.0: {} lru-cache@5.1.1: @@ -17681,6 +17879,8 @@ snapshots: merge2@1.4.1: {} + meriyah@6.1.4: {} + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -17980,8 +18180,6 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} - minipass@7.1.3: {} mitt@3.0.1: {} @@ -18033,14 +18231,10 @@ snapshots: nanoid-dictionary@5.0.0: {} - nanoid@3.3.11: {} - nanoid@3.3.12: {} nanoid@5.1.11: {} - nanoid@5.1.6: {} - negotiator@0.6.3: {} negotiator@1.0.0: {} @@ -18051,7 +18245,7 @@ snapshots: neverthrow@7.2.0: {} - next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): + next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): dependencies: '@auth/core': 0.41.2 next: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -18238,7 +18432,7 @@ snapshots: openapi3-ts@4.5.0: dependencies: - yaml: 2.8.1 + yaml: 2.9.0 ora@4.1.1: dependencies: @@ -18471,11 +18665,6 @@ snapshots: path-parse@1.0.7: {} - path-scurry@2.0.1: - dependencies: - lru-cache: 11.2.7 - minipass: 7.1.2 - path-scurry@2.0.2: dependencies: lru-cache: 11.5.0 @@ -18534,7 +18723,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3)): dependencies: lilconfig: 3.1.3 - yaml: 2.8.1 + yaml: 2.9.0 optionalDependencies: postcss: 8.5.15 ts-node: 10.9.2(@swc/core@1.15.18)(@types/node@24.12.4)(typescript@5.9.3) @@ -18551,7 +18740,7 @@ snapshots: postcss@8.4.31: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -18561,12 +18750,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -19174,7 +19357,7 @@ snapshots: is-plain-object: 5.0.0 launder: 1.7.1 parse-srcset: 1.0.2 - postcss: 8.5.6 + postcss: 8.5.15 sax@1.4.3: {} @@ -19204,6 +19387,8 @@ snapshots: dependencies: parseley: 0.12.1 + semifies@1.0.0: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -19270,12 +19455,12 @@ snapshots: node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 - postcss: 8.5.6 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 prompts: 2.4.2 recast: 0.23.11 stringify-object: 5.0.0 - tailwind-merge: 3.3.1 + tailwind-merge: 3.6.0 ts-morph: 26.0.0 tsconfig-paths: 4.2.0 validate-npm-package-name: 7.0.2 @@ -19530,7 +19715,7 @@ snapshots: stripe@13.11.0: dependencies: - '@types/node': 24.10.1 + '@types/node': 24.12.4 qs: 6.14.0 strnum@2.3.0: {} @@ -19610,8 +19795,6 @@ snapshots: tagged-tag@1.0.0: {} - tailwind-merge@3.3.1: {} - tailwind-merge@3.6.0: {} tailwindcss-animate@1.0.7(tailwindcss@4.3.0): @@ -19667,8 +19850,6 @@ snapshots: tinycolor2@1.6.0: {} - tinyexec@1.0.2: {} - tinyexec@1.1.2: {} tinyglobby@0.2.15: @@ -20001,7 +20182,7 @@ snapshots: vfile-matter@5.0.1: dependencies: vfile: 6.0.3 - yaml: 2.8.1 + yaml: 2.9.0 vfile-message@3.1.4: dependencies: @@ -20179,8 +20360,6 @@ snapshots: yaml@1.10.2: {} - yaml@2.8.1: {} - yaml@2.9.0: {} yargs-parser@21.1.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c259c6f1..a61cf776 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,10 +2,8 @@ packages: - apps/* - packages/**/* - packages/config/* - trustPolicy: off -minimumReleaseAge: 1440 # 1 day (default) - +minimumReleaseAge: 1440 allowBuilds: "@bufbuild/buf": true "@parcel/watcher": true @@ -17,9 +15,7 @@ allowBuilds: msw: true protobufjs: true sharp: true - autoInstallPeers: true - catalog: "@ai-sdk/anthropic": 1.2.12 "@ai-sdk/react": 3.0.190 @@ -46,7 +42,6 @@ catalog: "@dnd-kit/sortable": 10.0.0 "@dnd-kit/utilities": 3.2.2 "@fontsource-variable/inter": 5.2.8 - # Pinned to 4.0.1 — 4.1.0+ ships an ESM build that reads config JSON via fs.readFileSync, breaking `bun build --compile` in apps/workflows "@google-cloud/tasks": 4.0.1 "@hono/mcp": 0.2.5 "@hono/sentry": 1.2.2 @@ -63,7 +58,9 @@ catalog: "@openpanel/astro": 1.4.1 "@openpanel/nextjs": 1.5.1 "@openpanel/sdk": 1.3.1 + "@opentelemetry/exporter-logs-otlp-http": 0.208.0 "@opentelemetry/resources": 2.7.1 + "@opentelemetry/sdk-logs": 0.208.0 "@opentelemetry/semantic-conventions": 1.41.1 "@radix-ui/react-accordion": 1.2.12 "@radix-ui/react-alert-dialog": 1.1.15 @@ -92,6 +89,7 @@ catalog: "@react-email/ui": 6.1.5 "@scalar/hono-api-reference": 0.8.10 "@sentry/bun": 10.53.1 + "@sentry/deno": 10.61.0 "@sentry/nextjs": 10.53.1 "@slack/web-api": 7.16.0 "@stripe/stripe-js": 2.4.0 @@ -107,7 +105,6 @@ catalog: "@tanstack/react-table": 8.21.3 "@trpc/client": 11.17.0 "@trpc/next": 11.17.0 - "@types/react": 19.2.15 "@trpc/react-query": 11.17.0 "@trpc/server": 11.17.0 "@trpc/tanstack-react-query": 11.17.0 @@ -116,6 +113,7 @@ catalog: "@types/dom-speech-recognition": 0.0.6 "@types/luxon": 3.7.1 "@types/node": 24.12.4 + "@types/react": 19.2.15 "@types/react-dom": 19.2.3 "@types/sanitize-html": 2.16.1 "@types/validator": 13.15.10 @@ -199,9 +197,9 @@ catalog: stripe: 13.11.0 sugar-high: 0.9.5 superjson: 2.2.6 + tailwind-merge: 3.6.0 tailwindcss: 4.3.0 tailwindcss-animate: 1.0.7 - tailwind-merge: 3.6.0 tsup: 7.2.0 tw-animate-css: 1.4.0 typescript: 5.9.3 diff --git a/turbo.json b/turbo.json index 7d319815..e6a28cd2 100644 --- a/turbo.json +++ b/turbo.json @@ -32,6 +32,7 @@ "outputs": [".next/**", "!.next/cache/**", "dist/**"] }, "lint": {}, + "check": {}, "dev": { "cache": false }, -- 2.51.2 From 414e5f2c3c1c1281cef5d0095cc452a309c31e6c Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 1 Jul 2026 09:07:15 +0200 Subject: [PATCH 13/69] workflow: move to http (#2331) --- apps/workflows/src/cron/checker.ts | 2 +- apps/workflows/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/workflows/src/cron/checker.ts b/apps/workflows/src/cron/checker.ts index 40dbf7ab..dfdb5b32 100644 --- a/apps/workflows/src/cron/checker.ts +++ b/apps/workflows/src/cron/checker.ts @@ -51,7 +51,7 @@ export const isAuthorizedDomain = (url: string) => { const logger = getLogger("workflow"); const client = new CloudTasksClient({ - fallback: true, + fallback: "rest", projectId: env().GCP_PROJECT_ID, credentials: { client_email: env().GCP_CLIENT_EMAIL, diff --git a/apps/workflows/src/index.ts b/apps/workflows/src/index.ts index 9cd13dac..5bded409 100644 --- a/apps/workflows/src/index.ts +++ b/apps/workflows/src/index.ts @@ -100,7 +100,7 @@ await configure({ loggers: [ { category: "workflow", - lowestLevel: "debug", + lowestLevel: "warning", sinks: ["console"], }, { -- 2.51.2 From 241eae7abd03caf23b38e62989c609c81977dd2e Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 1 Jul 2026 12:39:27 +0200 Subject: [PATCH 14/69] task grpc default (#2333) --- apps/workflows/src/cron/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/workflows/src/cron/checker.ts b/apps/workflows/src/cron/checker.ts index dfdb5b32..b7b1854a 100644 --- a/apps/workflows/src/cron/checker.ts +++ b/apps/workflows/src/cron/checker.ts @@ -51,7 +51,7 @@ export const isAuthorizedDomain = (url: string) => { const logger = getLogger("workflow"); const client = new CloudTasksClient({ - fallback: "rest", + // fallback: true, projectId: env().GCP_PROJECT_ID, credentials: { client_email: env().GCP_CLIENT_EMAIL, -- 2.51.2 From af6b77f3f0c234cfa7eb566485fb9096b316c17c Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 1 Jul 2026 13:26:57 +0200 Subject: [PATCH 15/69] infra: scale up machine (#2334) --- apps/workflows/fly.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/workflows/fly.toml b/apps/workflows/fly.toml index 68f7d049..458e9c2c 100644 --- a/apps/workflows/fly.toml +++ b/apps/workflows/fly.toml @@ -11,8 +11,8 @@ primary_region = 'ams' [[vm]] cpu_kind = "shared" - cpus = 2 - memory_mb = 1024 + cpus = 6 + memory_mb = 1536 [http_service] internal_port = 3000 -- 2.51.2 From 45cd071b63d836e092a31c5505d493607a85c6fd Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 1 Jul 2026 16:40:56 +0200 Subject: [PATCH 16/69] status page: robots no index (#2335) --- apps/status-page/src/app/robots.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/status-page/src/app/robots.ts b/apps/status-page/src/app/robots.ts index dc3db8ba..9b1d57a8 100644 --- a/apps/status-page/src/app/robots.ts +++ b/apps/status-page/src/app/robots.ts @@ -26,13 +26,31 @@ export default async function robots(): Promise { : null; const row = route ? await db - .select({ slug: page.slug, customDomain: page.customDomain }) + .select({ + slug: page.slug, + customDomain: page.customDomain, + allowIndex: page.allowIndex, + }) .from(page) .where( sql`lower(${page.slug}) = ${route.prefix} OR lower(${page.customDomain}) = ${route.prefix}`, ) .get() : undefined; + + // The page owner opted out of indexing: disallow everything and omit the + // sitemap so crawlers have nothing to follow. + if (row && !row.allowIndex) { + return { + rules: [ + { + userAgent: "*", + disallow: "/", + }, + ], + }; + } + const sitemap = row ? `${getBaseUrl({ slug: row.slug, customDomain: row.customDomain ?? undefined })}/sitemap.xml` : undefined; -- 2.51.2 From f1124d791dd3f68c0a3dc35fe0346c76b01290f6 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:52:53 +0200 Subject: [PATCH 17/69] feat(status-page): fall back to manual mode when Tinybird is slow or errors (#2330) * feat(status-page): fall back to manual mode when Tinybird is slow or errors Status pages read uptime bars and latency charts from Tinybird. When Tinybird is slow or unavailable the page would hang or 500 instead of showing anything. Race every Tinybird read on the public status-page router against a 5s budget via `withTinybirdFallback`. On timeout or error: - `getUptime` degrades the whole page to "manual" mode, so bars/cards still render from DB-authored events (reports, maintenances) exactly like a manually configured manual page. - `getMonitors` / `getMonitor` return empty chart data so the page renders instead of throwing. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ByfrAY2esPbXucdyPo2jcY * refactor(status-page): extract TinybirdResult type, drop as-const casts Name the fallback helper's discriminated return as `TinybirdResult`. Fold manual mode into the fetch thunk so `withTinybirdFallback` infers a single `Promise` for both branches, removing the `as const` casts the manual-mode object literal previously needed. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01ByfrAY2esPbXucdyPo2jcY --------- Co-authored-by: Claude --- packages/api/src/router/statusPage.ts | 110 +++++++++++------- .../api/src/router/statusPage.utils.test.ts | 23 ++++ packages/api/src/router/statusPage.utils.ts | 37 ++++++ 3 files changed, 130 insertions(+), 40 deletions(-) diff --git a/packages/api/src/router/statusPage.ts b/packages/api/src/router/statusPage.ts index 3d415a8b..45bbf0b1 100644 --- a/packages/api/src/router/statusPage.ts +++ b/packages/api/src/router/statusPage.ts @@ -38,6 +38,7 @@ import { getWorstVariant, isMonitorComponent, setDataByType, + withTinybirdFallback, } from "./statusPage.utils"; import { getMetricsLatencyMultiProcedure, @@ -660,17 +661,30 @@ export const statusPageRouter = createTRPCRouter({ dns: getStatusProcedure("45d", "dns"), }; - const [statusHttp, statusTcp, statusDns] = await Promise.all( - Object.entries(proceduresByType).map(([type, procedure]) => { - const monitorIds = monitorsByType[ - type as keyof typeof proceduresByType - ].map((c) => c.monitor.id.toString()); - if (monitorIds.length === 0) return null; - // NOTE: if manual mode, don't fetch data from tinybird - return input.barType === "manual" ? null : procedure({ monitorIds }); - }), + // Manual mode never touches Tinybird. Otherwise race the reads against + // the fallback budget: a slow (>5s) or erroring Tinybird degrades the + // whole page to manual mode so bars still render from DB events. + const tinybird = await withTinybirdFallback(() => + input.barType === "manual" + ? Promise.resolve([null, null, null]) + : Promise.all( + Object.entries(proceduresByType).map(([type, procedure]) => { + const monitorIds = monitorsByType[ + type as keyof typeof proceduresByType + ].map((c) => c.monitor.id.toString()); + if (monitorIds.length === 0) return null; + return procedure({ monitorIds }); + }), + ), ); + const tinybirdUnhealthy = !tinybird.ok; + const [statusHttp, statusTcp, statusDns] = tinybird.data ?? [ + null, + null, + null, + ]; + const statusDataByMonitorId = new Map< string, | Awaited>["data"] @@ -713,6 +727,7 @@ export const statusPageRouter = createTRPCRouter({ c.type === "monitor" && c.monitor && input.barType !== "manual" && + !tinybirdUnhealthy && process.env.NOOP_UPTIME !== "true"; let filledData: StatusData[]; @@ -734,10 +749,11 @@ export const statusPageRouter = createTRPCRouter({ }); } - // Static components always use manual mode since they don't have real monitoring data - const effectiveBarType = c.type === "static" ? "manual" : input.barType; - const effectiveCardType = - c.type === "static" ? "manual" : input.cardType; + // Static components have no monitoring data; a degraded Tinybird forces + // every component into manual mode so bars/cards still render. + const forceManual = c.type === "static" || tinybirdUnhealthy; + const effectiveBarType = forceManual ? "manual" : input.barType; + const effectiveCardType = forceManual ? "manual" : input.cardType; const processedData = setDataByType({ events, @@ -951,19 +967,24 @@ export const statusPageRouter = createTRPCRouter({ dns: getMetricsLatencyMultiProcedure("1d", "dns"), }; + // Slow/erroring Tinybird → empty latency data so the page still renders. + const metrics = await withTinybirdFallback(() => + Promise.all( + Object.entries(proceduresByType).map(([type, procedure]) => { + const monitorIds = monitorsByType[ + type as keyof typeof proceduresByType + ].map((c) => c.monitor.id.toString()); + if (monitorIds.length === 0) return null; + return procedure({ monitorIds }); + }), + ), + ); + const [ metricsLatencyMultiHttp, metricsLatencyMultiTcp, metricsLatencyMultiDns, - ] = await Promise.all( - Object.entries(proceduresByType).map(([type, procedure]) => { - const monitorIds = monitorsByType[ - type as keyof typeof proceduresByType - ].map((c) => c.monitor.id.toString()); - if (monitorIds.length === 0) return null; - return procedure({ monitorIds }); - }), - ); + ] = metrics.data ?? [null, null, null]; const metricsDataByMonitorId = new Map< string, @@ -1069,24 +1090,33 @@ export const statusPageRouter = createTRPCRouter({ const fromDate = startOfDay(subDays(new Date(), 7)).toISOString(); const toDate = endOfDay(new Date()).toISOString(); - const [latency, regions, uptime] = await Promise.all([ - await proceduresByType[type].latency({ - monitorId: _monitor.id.toString(), - fromDate, - toDate, - }), - await proceduresByType[type].regions({ - monitorId: _monitor.id.toString(), - fromDate, - toDate, - }), - await proceduresByType[type].uptime({ - monitorId: _monitor.id.toString(), - interval: 240, - fromDate, - toDate, - }), - ]); + // Slow/erroring Tinybird → empty chart data so the page still renders. + const metrics = await withTinybirdFallback(() => + Promise.all([ + proceduresByType[type].latency({ + monitorId: _monitor.id.toString(), + fromDate, + toDate, + }), + proceduresByType[type].regions({ + monitorId: _monitor.id.toString(), + fromDate, + toDate, + }), + proceduresByType[type].uptime({ + monitorId: _monitor.id.toString(), + interval: 240, + fromDate, + toDate, + }), + ]), + ); + + const [latency, regions, uptime] = metrics.data ?? [ + { data: [] }, + { data: [] }, + { data: [] }, + ]; return { ...selectPublicMonitorSchema.parse(_monitor), diff --git a/packages/api/src/router/statusPage.utils.test.ts b/packages/api/src/router/statusPage.utils.test.ts index 1961e85f..f7fe16d9 100644 --- a/packages/api/src/router/statusPage.utils.test.ts +++ b/packages/api/src/router/statusPage.utils.test.ts @@ -14,6 +14,7 @@ import { getEvents, getUptime, setDataByType, + withTinybirdFallback, } from "./statusPage.utils"; type StatusData = { @@ -2079,3 +2080,25 @@ describe("componentImpacts", () => { }); }); }); + +describe("withTinybirdFallback", () => { + it("returns ok with data when the read resolves in time", async () => { + const result = await withTinybirdFallback(async () => ({ data: [1, 2] })); + expect(result).toEqual({ ok: true, data: { data: [1, 2] } }); + }); + + it("falls back when the read throws", async () => { + const result = await withTinybirdFallback(async () => { + throw new Error("tinybird down"); + }); + expect(result).toEqual({ ok: false, data: null }); + }); + + it("falls back when the read exceeds the timeout", async () => { + const result = await withTinybirdFallback( + () => new Promise((resolve) => setTimeout(resolve, 50)), + 10, + ); + expect(result).toEqual({ ok: false, data: null }); + }); +}); diff --git a/packages/api/src/router/statusPage.utils.ts b/packages/api/src/router/statusPage.utils.ts index 6e7534f0..5f6d5dfa 100644 --- a/packages/api/src/router/statusPage.utils.ts +++ b/packages/api/src/router/statusPage.utils.ts @@ -17,6 +17,43 @@ import { export * from "@openstatus/services/status-timeline"; +// Status pages must render even when Tinybird is degraded. Read latency above +// this budget is treated as an outage and the page falls back to manual mode. +export const TINYBIRD_FALLBACK_TIMEOUT_MS = 5_000; + +// Discriminated result of a guarded Tinybird read: `ok: true` carries the data, +// `ok: false` (timeout or error) carries `null` and signals manual-mode fallback. +export type TinybirdResult = + | { ok: true; data: T } + | { ok: false; data: null }; + +// Races a Tinybird read against the fallback budget. `ok: false` (timeout or +// thrown error) signals the caller to serve manual mode — DB-authored events +// only — instead of hanging or 500ing on Tinybird. +export async function withTinybirdFallback( + fetch: () => Promise, + timeoutMs = TINYBIRD_FALLBACK_TIMEOUT_MS, +): Promise> { + let timer: ReturnType | undefined; + try { + const data = await Promise.race([ + fetch(), + new Promise((_, reject) => { + timer = setTimeout( + () => reject(new Error("tinybird timeout")), + timeoutMs, + ); + }), + ]); + return { ok: true, data }; + } catch (err) { + console.error("[status-page] tinybird unhealthy, using manual mode:", err); + return { ok: false, data: null }; + } finally { + clearTimeout(timer); + } +} + type UptimeData = { day: string; events: Event[]; -- 2.51.2 From fbc1332675a5486272eaa570d913158ef871fecc Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Thu, 2 Jul 2026 15:03:35 +0200 Subject: [PATCH 18/69] github action: once daily (#2339) --- .github/workflows/restart-workflows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/restart-workflows.yml b/.github/workflows/restart-workflows.yml index 02f64b44..6e943738 100644 --- a/.github/workflows/restart-workflows.yml +++ b/.github/workflows/restart-workflows.yml @@ -4,7 +4,7 @@ name: Restart Workflows Machines # (see apps/workflows/research.md). Restarts machines one at a time so the app stays up. on: schedule: - - cron: "0 */12 * * *" + - cron: "0 12 * * *" workflow_dispatch: {} concurrency: -- 2.51.2 From 9ea1d163f0ed9524a28cbc5b3588c918c43ee5a4 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Thu, 2 Jul 2026 15:20:06 +0200 Subject: [PATCH 19/69] github action: once daily (#2340) -- 2.51.2 From 46cf48620c4a6549095b1f9826ff7da56823e617 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:26:31 +0200 Subject: [PATCH 20/69] feat: frozen monitor uptime (#2341) * wip: ui * chore: frozen monitor uptime * wip: * fix: updatedAt * wip: * chore: connect ui to db * testL downtime utility * fix: legacy behavior * wip: minor stuff * chore: minor stuff * wip: * wip: --- .../status-pages/[id]/constants.ts | 11 +- .../status-pages/[id]/history/client.tsx | 279 + .../status-pages/[id]/history/examples.ts | 95 + .../status-pages/[id]/history/layout.tsx | 46 + .../status-pages/[id]/history/page.tsx | 29 + .../[id]/history/search-params.ts | 9 + .../status-pages/[id]/subscribers/page.tsx | 78 +- apps/dashboard/src/components/common/note.tsx | 2 +- .../components/content/hint-collapsible.tsx | 93 + .../status-page-history/columns.tsx | 89 + .../status-page-history/table-cell-uptime.tsx | 165 + .../components/ui/data-table/data-table.tsx | 13 +- apps/dashboard/src/data/plans.ts | 4 + .../dashboard/src/data/status-page-history.ts | 104 + apps/workflows/src/cron/index.ts | 5 + apps/workflows/src/cron/uptime-freeze.ts | 70 + deno.lock | 218 - packages/api/src/router/page.ts | 14 + .../api/src/router/statusPage.utils.test.ts | 9 +- packages/api/src/router/statusPage.utils.ts | 144 +- packages/api/src/router/stripe/webhook.ts | 3 +- packages/db/drizzle/0077_military_jackpot.sql | 13 + packages/db/drizzle/meta/0077_snapshot.json | 4696 +++++++++++++++++ packages/db/drizzle/meta/_journal.json | 7 + .../frozen_uptime/frozen_monitor_uptime.ts | 56 + packages/db/src/schema/frozen_uptime/index.ts | 2 + .../db/src/schema/frozen_uptime/validation.ts | 41 + packages/db/src/schema/index.ts | 1 + packages/db/src/schema/plan/config.ts | 4 + packages/db/src/schema/plan/schema.ts | 1 + packages/services/package.json | 4 + .../frozen-uptime/__tests__/compute.test.ts | 134 + .../frozen-uptime/__tests__/freeze.test.ts | 200 + .../__tests__/get-history.test.ts | 809 +++ .../src/frozen-uptime/__tests__/run.test.ts | 483 ++ .../frozen-uptime/__tests__/schemas.test.ts | 46 + .../services/src/frozen-uptime/compute.ts | 79 + packages/services/src/frozen-uptime/freeze.ts | 48 + .../services/src/frozen-uptime/get-history.ts | 403 ++ packages/services/src/frozen-uptime/index.ts | 18 + packages/services/src/frozen-uptime/run.ts | 277 + .../services/src/frozen-uptime/schemas.ts | 15 + .../__tests__/downtime.test.ts | 41 + .../status-timeline/__tests__/uptime.test.ts | 197 + .../services/src/status-timeline/downtime.ts | 24 + .../services/src/status-timeline/index.ts | 2 + .../services/src/status-timeline/uptime.ts | 150 + packages/ui/src/components/ui/sidebar.tsx | 2 +- 48 files changed, 8856 insertions(+), 377 deletions(-) create mode 100644 apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx create mode 100644 apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/examples.ts create mode 100644 apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/layout.tsx create mode 100644 apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/page.tsx create mode 100644 apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/search-params.ts create mode 100644 apps/dashboard/src/components/content/hint-collapsible.tsx create mode 100644 apps/dashboard/src/components/data-table/status-page-history/columns.tsx create mode 100644 apps/dashboard/src/components/data-table/status-page-history/table-cell-uptime.tsx create mode 100644 apps/dashboard/src/data/status-page-history.ts create mode 100644 apps/workflows/src/cron/uptime-freeze.ts create mode 100644 packages/db/drizzle/0077_military_jackpot.sql create mode 100644 packages/db/drizzle/meta/0077_snapshot.json create mode 100644 packages/db/src/schema/frozen_uptime/frozen_monitor_uptime.ts create mode 100644 packages/db/src/schema/frozen_uptime/index.ts create mode 100644 packages/db/src/schema/frozen_uptime/validation.ts create mode 100644 packages/services/src/frozen-uptime/__tests__/compute.test.ts create mode 100644 packages/services/src/frozen-uptime/__tests__/freeze.test.ts create mode 100644 packages/services/src/frozen-uptime/__tests__/get-history.test.ts create mode 100644 packages/services/src/frozen-uptime/__tests__/run.test.ts create mode 100644 packages/services/src/frozen-uptime/__tests__/schemas.test.ts create mode 100644 packages/services/src/frozen-uptime/compute.ts create mode 100644 packages/services/src/frozen-uptime/freeze.ts create mode 100644 packages/services/src/frozen-uptime/get-history.ts create mode 100644 packages/services/src/frozen-uptime/index.ts create mode 100644 packages/services/src/frozen-uptime/run.ts create mode 100644 packages/services/src/frozen-uptime/schemas.ts create mode 100644 packages/services/src/status-timeline/__tests__/downtime.test.ts create mode 100644 packages/services/src/status-timeline/__tests__/uptime.test.ts create mode 100644 packages/services/src/status-timeline/downtime.ts create mode 100644 packages/services/src/status-timeline/uptime.ts diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts index e4961473..a1a57bfe 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/constants.ts @@ -1,5 +1,12 @@ import type { LucideIcon } from "lucide-react"; -import { Cog, Hammer, LayoutTemplate, Megaphone, Users } from "lucide-react"; +import { + CalendarDays, + Cog, + Hammer, + LayoutTemplate, + Megaphone, + Users, +} from "lucide-react"; export const STATUS_PAGE_TABS: { value: string; @@ -10,5 +17,7 @@ export const STATUS_PAGE_TABS: { { value: "maintenances", label: "Maintenances", icon: Hammer }, { value: "subscribers", label: "Subscribers", icon: Users }, { value: "components", label: "Components", icon: LayoutTemplate }, + // TODO: hidden in the tabs but still accessible via direct link - can be enabled in the future + // { value: "history", label: "History", icon: CalendarDays }, { value: "edit", label: "Settings", icon: Cog }, ]; diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx new file mode 100644 index 00000000..120a0315 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx @@ -0,0 +1,279 @@ +"use client"; + +import { Tabs, TabsList, TabsTrigger } from "@openstatus/ui/components/ui/tabs"; +import { useQuery } from "@tanstack/react-query"; +import { format } from "date-fns"; +import { Info, Lock } from "lucide-react"; +import { useParams } from "next/navigation"; +import { useQueryStates } from "nuqs"; +import { useMemo, useState } from "react"; + +import { Note, NoteButton } from "@/components/common/note"; +import { + BillingOverlay, + BillingOverlayButton, + BillingOverlayContainer, + BillingOverlayDescription, +} from "@/components/content/billing-overlay"; +import { + EmptyStateContainer, + EmptyStateDescription, + EmptyStateTitle, +} from "@/components/content/empty-state"; +import { + HintCollapsible, + HintCollapsibleContent, + HintCollapsibleDescription, + HintCollapsibleTitle, + HintCollapsibleTrigger, +} from "@/components/content/hint-collapsible"; +import { + Section, + SectionDescription, + SectionGroup, + SectionHeader, + SectionHeaderRow, + SectionTitle, +} from "@/components/content/section"; +import { getColumns } from "@/components/data-table/status-page-history/columns"; +import { UpgradeDialog } from "@/components/dialogs/upgrade"; +import { FormDialogSupportContact } from "@/components/forms/support-contact/dialog"; +import { + MetricCard, + MetricCardGroup, + MetricCardHeader, + MetricCardTitle, + MetricCardValue, +} from "@/components/metric/metric-card"; +import { DataTable } from "@/components/ui/data-table/data-table"; +import { + HISTORY_WINDOWS, + getColumnVisibility, + parseWindow, + windowKey, +} from "@/data/status-page-history"; +import { useTRPC } from "@/lib/trpc/client"; + +import { buildExampleHistory } from "./examples"; +import { searchParamsParsers } from "./search-params"; + +export function Client() { + const { id } = useParams<{ id: string }>(); + const trpc = useTRPC(); + const [{ window }, setSearchParams] = useQueryStates(searchParamsParsers); + const [openDialog, setOpenDialog] = useState(false); + + const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); + const isLimited = workspace?.limits["uptime-history"] === false; + + // one 24-month fetch; the window tabs only toggle column visibility + const { data: liveHistory } = useQuery({ + ...trpc.page.getUptimeHistory.queryOptions({ id: Number.parseInt(id) }), + enabled: !!workspace && !isLimited, + }); + + const exampleHistory = useMemo( + () => (isLimited ? buildExampleHistory() : null), + [isLimited], + ); + const history = isLimited ? exampleHistory : liveHistory; + + const columns = useMemo( + () => getColumns(history?.months ?? [], window), + [history?.months, window], + ); + const columnVisibility = useMemo( + () => getColumnVisibility(window, history?.months.length ?? 0), + [window, history?.months.length], + ); + + if (!history) return null; + + const summary = history.summary[windowKey(window)]; + const hasAnyData = history.rows.some((row) => + Object.values(row.months).some((value) => value !== null), + ); + + return ( + +
    + + +
    + History + + Long-term uptime, build from your page's components. + +
    + setSearchParams({ window: parseWindow(v) })} + > + + {HISTORY_WINDOWS.map((w) => ( + + {w} months + + ))} + + +
    +
    +
    +
    + + + + + Page Uptime + + + + {summary.uptime === null ? "—" : `${summary.uptime.toFixed(2)}%`} + + + + + Reports + + {summary.reports} + + + + + Components + + + {history.rows.length} + + + + + Created At + + + + {history.createdAt ? format(history.createdAt, "MMM yy") : "—"} + + + + {isLimited ? ( + +
    + +
    + + setOpenDialog(true)}> + + Upgrade + + + Keep an overview of your uptime history for the last 24 months. + + + +
    + ) : hasAnyData ? ( +
    + +
    + ) : ( + + No history yet + + The first{" "} + snapshot{" "} + freezes on the{" "} + + 10th of next month + {" "} + — until then, the current month is served live. + + + )} + + + + How uptime is calculated + + + Each percentage depends on the page's calculation mode and the + component type. + + + +

    + The calculation mode is set page-wide in the status page settings + and applies to every month shown here. What is frozen monthly are + the raw daily check counts — changing the mode re-renders all + months from those immutable counts. +

    +
      +
    • + + requests + {" "} + + — Monitor components. Uptime is{" "} + + (ok + degraded) / total checks + + . Degraded responses still count as up. + +
    • +
    • + + duration + {" "} + + — Monitor components. Downtime is measured from incident and + status-report intervals, weighted by impact (major outage + counts fully, partial outage at half) and merged so + overlapping events are never double-counted. + +
    • +
    • + + manual + {" "} + + — No probe data is considered; uptime is derived entirely from + reported incidents. Static components always work this way, + with their full history kept — reports never expire. + +
    • +
    +

    + Months without recorded checks are shown as{" "} + no data and + excluded from totals — they are never counted as downtime. +

    +
    +
    + {!isLimited ? ( + + + If there are any missing months, please contact us. + + Request Backfill + + + ) : null} +
    +
    + ); +} diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/examples.ts b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/examples.ts new file mode 100644 index 00000000..4ea78aea --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/examples.ts @@ -0,0 +1,95 @@ +import type { RouterOutputs } from "@openstatus/api"; + +type UptimeHistory = RouterOutputs["page"]["getUptimeHistory"]; +type HistoryRow = UptimeHistory["rows"][number]; + +// TODO: rework later - currently not happy how we keep the metrics data available + +const HISTORY_MONTHS = 24; +const WINDOWS = ["6", "12", "24"] as const; + +// deterministic PRNG so the placeholder rows don't reshuffle between renders +function mulberry32(seed: number) { + let a = seed; + return () => { + a |= 0; + a = (a + 0x6d2b79f5) | 0; + let t = Math.imul(a ^ (a >>> 15), 1 | a); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +// UTC buckets, matching the server's monthKeys +function monthKeys(now: Date): string[] { + return Array.from({ length: HISTORY_MONTHS }, (_, i) => { + const d = new Date( + Date.UTC( + now.getUTCFullYear(), + now.getUTCMonth() - (HISTORY_MONTHS - 1 - i), + 1, + ), + ); + const mm = String(d.getUTCMonth() + 1).padStart(2, "0"); + return `${d.getUTCFullYear()}-${mm}`; + }); +} + +const COMPONENTS: { id: number; name: string; type: "monitor" | "static" }[] = [ + { id: 1, name: "API", type: "monitor" }, + { id: 2, name: "Dashboard", type: "monitor" }, + { id: 3, name: "Documentation", type: "static" }, +]; + +const round = (value: number) => Math.round(value * 100) / 100; + +function average(values: (number | null)[]): number | null { + const present = values.filter((v): v is number => v !== null); + if (present.length === 0) return null; + return round(present.reduce((a, b) => a + b, 0) / present.length); +} + +export function buildExampleHistory(now = new Date()): UptimeHistory { + const months = monthKeys(now); + + const rows: HistoryRow[] = COMPONENTS.map((component, index) => { + const rng = mulberry32(component.id * 7919); + const values = months.map((_, i) => { + // stagger creation dates so older cells show the no-data state + if (i < index * 3) return null; + const roll = rng(); + if (roll > 0.96) return round(97 + rng() * 1.9); + if (roll > 0.85) return round(99 + rng() * 0.85); + return round(99.9 + rng() * 0.1); + }); + + return { + component: { ...component, monitorId: null }, + months: Object.fromEntries(months.map((key, i) => [key, values[i]])), + rolling: Object.fromEntries( + WINDOWS.map((w) => [w, average(values.slice(-Number(w)))]), + ) as HistoryRow["rolling"], + events: [], + }; + }); + + const summary = Object.fromEntries( + WINDOWS.map((w) => [ + w, + { + uptime: average(rows.map((row) => row.rolling[w])), + reports: Number(w) / 3, + }, + ]), + ) as UptimeHistory["summary"]; + + return { + mode: "requests", + months, + createdAt: new Date( + Date.UTC(now.getUTCFullYear() - 2, now.getUTCMonth(), 1), + ), + summary, + rows, + }; +} diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/layout.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/layout.tsx new file mode 100644 index 00000000..9b18b101 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/layout.tsx @@ -0,0 +1,46 @@ +import { SidebarProvider } from "@openstatus/ui/components/ui/sidebar"; + +import { + RIGHT_SIDEBAR_COOKIE, + getSidebarDefaultOpen, +} from "@/lib/sidebar-cookie"; +import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; + +import { Sidebar } from "../sidebar"; + +export default async function Layout({ + children, + params, +}: { + children: React.ReactNode; + params: Promise<{ id: string }>; +}) { + const { id } = await params; + const queryClient = getQueryClient(); + + await Promise.all([ + queryClient.prefetchQuery( + trpc.page.get.queryOptions({ id: Number.parseInt(id) }), + ), + queryClient.prefetchQuery(trpc.monitor.list.queryOptions()), + queryClient.prefetchQuery( + trpc.pageComponent.list.queryOptions({ pageId: Number.parseInt(id) }), + ), + ]); + const defaultOpen = await getSidebarDefaultOpen(RIGHT_SIDEBAR_COOKIE, false); + + return ( + + +
    {children}
    +
    + +
    +
    +
    + ); +} diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/page.tsx new file mode 100644 index 00000000..706e19c5 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/page.tsx @@ -0,0 +1,29 @@ +import type { SearchParams } from "nuqs"; + +import { HydrateClient, getQueryClient, trpc } from "@/lib/trpc/server"; + +import { Client } from "./client"; +import { searchParamsCache } from "./search-params"; + +export default async function Page({ + params, + searchParams, +}: { + params: Promise<{ id: string }>; + searchParams: Promise; +}) { + const { id } = await params; + const queryClient = getQueryClient(); + + // NOTE: store in cache to avoid flicker on clients first render + await searchParamsCache.parse(searchParams); + await queryClient.prefetchQuery( + trpc.page.getUptimeHistory.queryOptions({ id: Number.parseInt(id) }), + ); + + return ( + + + + ); +} diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/search-params.ts b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/search-params.ts new file mode 100644 index 00000000..d07cc78b --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/search-params.ts @@ -0,0 +1,9 @@ +import { createSearchParamsCache, parseAsNumberLiteral } from "nuqs/server"; + +import { HISTORY_WINDOWS } from "@/data/status-page-history"; + +export const searchParamsParsers = { + window: parseAsNumberLiteral(HISTORY_WINDOWS).withDefault(6), +}; + +export const searchParamsCache = createSearchParamsCache(searchParamsParsers); diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx index 1b335b32..7a57fdd3 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/subscribers/page.tsx @@ -109,45 +109,47 @@ export default function Page() { {page?.title} List of all subscribers. - {isLimited ? ( - - ) : ( - { - if (values.channelType === "email") { - await createAction.mutateAsync({ - pageId, - channelType: "email", - email: values.email, - name: values.name || null, - componentIds: values.componentIds, - }); - } else { - await createAction.mutateAsync({ - pageId, - channelType: "webhook", - webhookUrl: values.webhookUrl, - name: values.name || null, - headers: values.headers, - componentIds: values.componentIds, - }); - } - }} - > - - - )} + ) : ( + { + if (values.channelType === "email") { + await createAction.mutateAsync({ + pageId, + channelType: "email", + email: values.email, + name: values.name || null, + componentIds: values.componentIds, + }); + } else { + await createAction.mutateAsync({ + pageId, + channelType: "webhook", + webhookUrl: values.webhookUrl, + name: values.name || null, + headers: values.headers, + componentIds: values.componentIds, + }); + } + }} + > + + + )} +
    diff --git a/apps/dashboard/src/components/common/note.tsx b/apps/dashboard/src/components/common/note.tsx index a00947e1..85f81ca5 100644 --- a/apps/dashboard/src/components/common/note.tsx +++ b/apps/dashboard/src/components/common/note.tsx @@ -3,7 +3,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import { type VariantProps, cva } from "class-variance-authority"; const noteVariants = cva( - "flex items-center gap-2 rounded-xl border [&>svg]:shrink-0 [&>svg]:text-current", + "flex items-center gap-2 rounded-lg border [&>svg]:shrink-0 [&>svg]:text-current", { variants: { variant: { diff --git a/apps/dashboard/src/components/content/hint-collapsible.tsx b/apps/dashboard/src/components/content/hint-collapsible.tsx new file mode 100644 index 00000000..f9cbd787 --- /dev/null +++ b/apps/dashboard/src/components/content/hint-collapsible.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@openstatus/ui/components/ui/collapsible"; +import { ChevronDown } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +export function HintCollapsible({ + children, + className, + ...props +}: React.ComponentProps) { + return ( + + {children} + + ); +} + +export function HintCollapsibleTrigger({ + children, + className, + ...props +}: React.ComponentProps) { + return ( + + {/* spans with display:block — a + + +
    + {monthLabel} +
    + {cell.percentage === null ? ( +
    + No data recorded for {monthLabel}. +
    + ) : ( +
    + + Uptime + + {cell.percentage.toFixed(2)} + % + +
    + )} + {events.length > 0 && ( + <> +
    +
    + {events.map((event) => { + const key = `${event.type}-${event.id}`; + const href = eventHref(event, pageId, monitorId); + const node = ; + if (!href) return {node}; + return ( + + {node} + + ); + })} +
    + + )} + + + ); +} diff --git a/apps/dashboard/src/components/ui/data-table/data-table.tsx b/apps/dashboard/src/components/ui/data-table/data-table.tsx index 084bb62a..332056dd 100644 --- a/apps/dashboard/src/components/ui/data-table/data-table.tsx +++ b/apps/dashboard/src/components/ui/data-table/data-table.tsx @@ -53,6 +53,8 @@ export interface DataTableProps { setSorting?: React.Dispatch>; pagination?: PaginationState; setPagination?: React.Dispatch>; + columnVisibility?: VisibilityState; + setColumnVisibility?: React.Dispatch>; } export function DataTable({ @@ -74,11 +76,13 @@ export function DataTable({ setSorting, pagination, setPagination, + columnVisibility, + setColumnVisibility, }: DataTableProps) { // oxlint-disable-next-line typescript/no-explicit-any const [globalFilter, setGlobalFilter] = React.useState(); const [rowSelection, setRowSelection] = React.useState({}); - const [columnVisibility, setColumnVisibility] = + const [internalColumnVisibility, setInternalColumnVisibility] = React.useState(defaultColumnVisibility); const [internalPagination, setInternalPagination] = React.useState(defaultPagination); @@ -94,13 +98,16 @@ export function DataTable({ const setSortingState = setSorting ?? setInternalSorting; const paginationState = pagination ?? internalPagination; const setPaginationState = setPagination ?? setInternalPagination; + const columnVisibilityState = columnVisibility ?? internalColumnVisibility; + const setColumnVisibilityState = + setColumnVisibility ?? setInternalColumnVisibility; const table = useReactTable({ data, columns, state: { sorting: sortingState, - columnVisibility, + columnVisibility: columnVisibilityState, rowSelection, pagination: paginationState, columnFilters: columnFiltersState, @@ -110,7 +117,7 @@ export function DataTable({ onRowSelectionChange: setRowSelection, onSortingChange: setSortingState, onColumnFiltersChange: setColumnFiltersState, - onColumnVisibilityChange: setColumnVisibility, + onColumnVisibilityChange: setColumnVisibilityState, onPaginationChange: setPaginationState, onGlobalFilterChange: setGlobalFilter, getCoreRowModel: getCoreRowModel(), diff --git a/apps/dashboard/src/data/plans.ts b/apps/dashboard/src/data/plans.ts index 1a6f99a4..0e1bcc6f 100644 --- a/apps/dashboard/src/data/plans.ts +++ b/apps/dashboard/src/data/plans.ts @@ -40,6 +40,10 @@ export const config: Record< value: "monitor-values-visibility", label: "Toggle numbers visibility", }, + // { + // value: "uptime-history", + // label: "Uptime history (24 months)", + // }, { value: "status-subscribers", label: "Subscribers", diff --git a/apps/dashboard/src/data/status-page-history.ts b/apps/dashboard/src/data/status-page-history.ts new file mode 100644 index 00000000..33edea62 --- /dev/null +++ b/apps/dashboard/src/data/status-page-history.ts @@ -0,0 +1,104 @@ +import type { RouterOutputs } from "@openstatus/api"; +import { format } from "date-fns"; + +// single client-side source for the window set; the server keeps its own +// WINDOWS tuple (services can't be imported into client bundles) +export const HISTORY_WINDOWS = [6, 12, 24] as const; +export type HistoryWindow = (typeof HISTORY_WINDOWS)[number]; + +// safe because callers only pass values rendered from HISTORY_WINDOWS tabs; +// anything else falls back to the default window +export function parseWindow(value: string): HistoryWindow { + const window = Number(value); + return (HISTORY_WINDOWS as readonly number[]).includes(window) + ? (window as HistoryWindow) + : HISTORY_WINDOWS[0]; +} + +export type UptimeStatus = + | "operational" + | "degraded" + | "down" + | "in-progress" + | "no-data"; + +export type MonthCell = { + percentage: number | null; + status: UptimeStatus; +}; + +// wire types inferred from the endpoint so server shape changes surface here +export type HistoryRow = + RouterOutputs["page"]["getUptimeHistory"]["rows"][number]; +export type HistoryEvent = HistoryRow["events"][number]; + +// safe because HistoryRow.rolling keys are exactly the string forms of HistoryWindow +export function windowKey(window: HistoryWindow): keyof HistoryRow["rolling"] { + return String(window) as keyof HistoryRow["rolling"]; +} + +/** + * Events overlapping the month; open-ended events count up to now. + * UTC boundaries — the server buckets months in UTC, so local boundaries + * would list an event under a neighboring month for non-UTC users. + */ +export function eventsForMonth( + events: HistoryEvent[], + key: string, +): HistoryEvent[] { + const [year, month] = key.split("-").map(Number); + const start = Date.UTC(year, month - 1, 1); + const end = Date.UTC(year, month, 1); + const now = Date.now(); + return events.filter((e) => { + const from = e.from.getTime(); + const to = e.to?.getTime() ?? now; + return from < end && to >= start; + }); +} + +// presentational thresholds only — the verb owns the uptime math +export function cellFromPercentage( + percentage: number | null, + isCurrent = false, +): MonthCell { + if (percentage === null) return { percentage, status: "no-data" }; + if (isCurrent) return { percentage, status: "in-progress" }; + return { + percentage, + status: + percentage >= 99.9 + ? "operational" + : percentage >= 99 + ? "degraded" + : "down", + }; +} + +function monthKeyToDate(key: string): Date { + const [year, month] = key.split("-").map(Number); + return new Date(year, month - 1, 1); +} + +export function monthKeyToLabel(key: string): string { + return format(monthKeyToDate(key), "MMM yy"); +} + +/** Full month + year, e.g. "October 2025". */ +export function monthKeyToFullLabel(key: string): string { + return format(monthKeyToDate(key), "MMMM yyyy"); +} + +/** Show slots 1…window; hide the rest of the served months. */ +export function getColumnVisibility( + window: HistoryWindow, + monthCount: number, +): Record { + if (window >= monthCount) return {}; + return Object.fromEntries( + Array.from({ length: monthCount - window }, (_, i) => [ + String(i + window + 1), + false, + ]), + ); +} diff --git a/apps/workflows/src/cron/index.ts b/apps/workflows/src/cron/index.ts index 45bd9b6e..f6444ddc 100644 --- a/apps/workflows/src/cron/index.ts +++ b/apps/workflows/src/cron/index.ts @@ -16,6 +16,7 @@ import { StepPaused, workflowStepSchema, } from "./monitor"; +import { handleUptimeFreezeCron } from "./uptime-freeze"; const app = new Hono({ strict: false }); @@ -93,6 +94,10 @@ app.get("/external-incidents-prune", async (c) => { return handleExternalIncidentsPruneCron(c); }); +app.get("/uptime-freeze", async (c) => { + return handleUptimeFreezeCron(c); +}); + app.get("/emails/follow-up", async (c) => { try { await sendFollowUpEmails(); diff --git a/apps/workflows/src/cron/uptime-freeze.ts b/apps/workflows/src/cron/uptime-freeze.ts new file mode 100644 index 00000000..2ee0e231 --- /dev/null +++ b/apps/workflows/src/cron/uptime-freeze.ts @@ -0,0 +1,70 @@ +import { getLogger } from "@logtape/logtape"; +import { + type UptimeFreezePipes, + runUptimeFreeze, +} from "@openstatus/services/frozen-uptime"; +import { OSTinybird } from "@openstatus/tinybird"; +import type { Context } from "hono"; + +import { env } from "../env"; +import { reportBackgroundError, runSentryCron } from "../lib/sentry"; + +const logger = getLogger(["workflow", "uptime-freeze"]); + +const tb = new OSTinybird(env().TINY_BIRD_API_KEY); + +const pipes: UptimeFreezePipes = { + http: tb.httpStatus45d, + tcp: tb.tcpStatus45d, + dns: tb.dnsStatus45d, +}; + +export async function handleUptimeFreezeCron(c: Context) { + const { cronCompleted, cronFailed } = runSentryCron("uptime-freeze"); + + // Background chain: must not capture `c` or anything derived from it — + // the handler returns 200 before this resolves (see external-status.ts) + void runUptimeFreeze({ + pipes, + onChunkFailure: ({ jobType, error }) => { + logger.warn("uptime-freeze: tinybird {jobType} chunk failed: {reason}", { + jobType, + reason: error instanceof Error ? error.message : String(error), + }); + }, + }) + .then(async (res) => { + if (res.failures.length > 0) { + // isolate: a Sentry transport failure must not flip a completed + // freeze run into cronFailed via the outer catch + try { + await reportBackgroundError( + `uptime-freeze ${res.month}: ${res.failures.length} failures (frozen=${res.frozen}, alreadyFrozen=${res.alreadyFrozen}, skipped=${res.skipped}). First: ${res.failures.slice(0, 5).join("; ")}`, + ); + } catch (reportError) { + logger.warn("uptime-freeze: reportBackgroundError failed: {reason}", { + reason: + reportError instanceof Error + ? reportError.message + : String(reportError), + }); + } + } + logger.info( + "uptime-freeze complete: month={month} frozen={frozen} alreadyFrozen={alreadyFrozen} skipped={skipped} failed={failed}", + { ...res, failed: res.failures.length }, + ); + void cronCompleted(); + }) + .catch((e) => { + logger.error("uptime-freeze errored: {message}", { + message: e instanceof Error ? e.message : String(e), + }); + void reportBackgroundError( + `uptime-freeze failed: ${e instanceof Error ? e.message : String(e)}`, + ); + void cronFailed(); + }); + + return c.json({ success: true }, 200); +} diff --git a/deno.lock b/deno.lock index 59e89299..0fb0ec68 100644 --- a/deno.lock +++ b/deno.lock @@ -54,224 +54,6 @@ "dependencies": [ "npm:turbo@2.9.14" ] - }, - "members": { - "apps/server": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "apps/status-page": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "apps/web": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/api": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/db": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/emails": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/header-analysis": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/importers": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/base": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/bird-whatsapp": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/discord": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/google-chat": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/grafana-oncall": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/ms-teams": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/ntfy": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/opsgenie": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/pagerduty": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/slack": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/telegram": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/twillio-sms": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/notifications/webhook": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/services": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/status-fetcher": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/subscriptions": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/test-utils": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/tracker": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - }, - "packages/utils": { - "packageJson": { - "dependencies": [ - "npm:@jsr/std__expect@^1.0.19", - "npm:@jsr/std__testing@^1.0.19" - ] - } - } } } } diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index e7b069f6..1c4c262a 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -1,6 +1,7 @@ import { Events } from "@openstatus/analytics"; import { locales } from "@openstatus/locales"; import { NotFoundError } from "@openstatus/services"; +import { getUptimeHistory } from "@openstatus/services/frozen-uptime"; import { type CreatePageInput, // `CreatePageInput` re-exports the drizzle insert schema so routers @@ -153,6 +154,19 @@ export const pageRouter = createTRPCRouter({ } }), + getUptimeHistory: protectedProcedure + .input(z.object({ id: z.number() })) + .query(async ({ ctx, input }) => { + try { + return await getUptimeHistory({ + ctx: toServiceCtx(ctx), + input: { pageId: input.id }, + }); + } catch (err) { + toTRPCError(err); + } + }), + // TODO: rename to create new: protectedProcedure .meta({ track: Events.CreatePage, trackProps: ["slug"] }) diff --git a/packages/api/src/router/statusPage.utils.test.ts b/packages/api/src/router/statusPage.utils.test.ts index f7fe16d9..a9ae1c57 100644 --- a/packages/api/src/router/statusPage.utils.test.ts +++ b/packages/api/src/router/statusPage.utils.test.ts @@ -2095,10 +2095,17 @@ describe("withTinybirdFallback", () => { }); it("falls back when the read exceeds the timeout", async () => { + // keep a handle on the slow read's timer — deno's leak sanitizer fails + // the test if it outlives the assertion + let slowRead!: ReturnType; const result = await withTinybirdFallback( - () => new Promise((resolve) => setTimeout(resolve, 50)), + () => + new Promise((resolve) => { + slowRead = setTimeout(resolve, 50); + }), 10, ); + clearTimeout(slowRead); expect(result).toEqual({ ok: false, data: null }); }); }); diff --git a/packages/api/src/router/statusPage.utils.ts b/packages/api/src/router/statusPage.utils.ts index 5f6d5dfa..32f97855 100644 --- a/packages/api/src/router/statusPage.utils.ts +++ b/packages/api/src/router/statusPage.utils.ts @@ -1,18 +1,20 @@ import type { PageComponentImpact } from "@openstatus/db/src/schema"; -import { - LEGACY_IMPACT_WEIGHT, - impactToStatusType, - impactUptimeWeight, - worstImpact, -} from "@openstatus/db/src/schema"; +import { impactToStatusType, worstImpact } from "@openstatus/db/src/schema"; import { type Event, + MS_PER_DAY, type StatusData, + type UptimeWindow, + dayCoverage, + durationDowntimeMs, + floorPct, getHighestPriorityStatus, getWorstVariant, isDateWithinEvent, reportEventDayImpact, reportEventDayStatus, + reportsOnlyDowntimeMs, + requestsTally, } from "@openstatus/services/status-timeline"; export * from "@openstatus/services/status-timeline"; @@ -69,8 +71,6 @@ type UptimeData = { }[]; }; -// Constants for time calculations -const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; const MILLISECONDS_PER_MINUTE = 1000 * 60; // Helper to format numbers @@ -170,7 +170,7 @@ function getTotalEventsDurationMs(events: Event[], date: Date): number { }, 0); // Cap at 24 hours per day - return Math.min(total, MILLISECONDS_PER_DAY); + return Math.min(total, MS_PER_DAY); } export function setDataByType({ @@ -233,13 +233,11 @@ export function setDataByType({ return [ { status: "success" as const, - height: - ((MILLISECONDS_PER_DAY - errorSegmentCount) / MILLISECONDS_PER_DAY) * - 100, + height: ((MS_PER_DAY - errorSegmentCount) / MS_PER_DAY) * 100, }, { status: "error" as const, - height: (errorSegmentCount / MILLISECONDS_PER_DAY) * 100, + height: (errorSegmentCount / MS_PER_DAY) * 100, }, ]; } @@ -252,8 +250,7 @@ export function setDataByType({ const errorMs = segments .filter((segment) => segment.status === "error") .reduce((sum, segment) => sum + segment.count, 0); - const errorHeight = - (Math.min(errorMs, MILLISECONDS_PER_DAY) / MILLISECONDS_PER_DAY) * 100; + const errorHeight = (Math.min(errorMs, MS_PER_DAY) / MS_PER_DAY) * 100; const remainingHeight = Math.max(0, 100 - errorHeight); const highlightSegments = segments.filter( @@ -641,31 +638,6 @@ export function setDataByType({ }); } -type WeightedInterval = { from: number; to: number; weight: number }; - -// concurrent events describing the same outage must not double-count -// downtime: per time slice the worst (max) weight wins, mirroring -// mergeWorstImpactIntervals — summing could push uptime negative -function mergedDowntimeMs(intervals: WeightedInterval[]): number { - const boundaries = [ - ...new Set(intervals.flatMap((iv) => [iv.from, iv.to])), - ].sort((a, b) => a - b); - - let total = 0; - for (let i = 0; i + 1 < boundaries.length; i++) { - const sliceStart = boundaries[i]; - const sliceEnd = boundaries[i + 1]; - let weight = 0; - for (const iv of intervals) { - if (iv.from <= sliceStart && iv.to >= sliceEnd) { - weight = Math.max(weight, iv.weight); - } - } - total += weight * (sliceEnd - sliceStart); - } - return total; -} - export function getUptime({ data, events, @@ -677,81 +649,27 @@ export function getUptime({ barType: "absolute" | "dominant" | "manual"; cardType: "requests" | "duration" | "dominant" | "manual"; }): string { - // Clamp event durations to the data lookback window to avoid - // events outside the window producing negative uptime values. - const timestamps = data.map((d) => new Date(d.day).getTime()); - const windowStart = timestamps.length > 0 ? Math.min(...timestamps) : 0; - const windowEndDate = new Date( - timestamps.length > 0 ? Math.max(...timestamps) : Date.now(), - ); - windowEndDate.setUTCHours(23, 59, 59, 999); - const windowEnd = windowEndDate.getTime(); - - function clampedInterval( - from: Date, - to: Date | null, - weight: number, - ): WeightedInterval | null { - const start = Math.max(from.getTime(), windowStart); - const end = Math.min((to ?? new Date()).getTime(), windowEnd); - if (end <= start || weight === 0) return null; - return { from: start, to: end, weight }; - } - - function reportImpactIntervals(event: Event): WeightedInterval[] { - return (event.impactIntervals ?? []) - .map((iv) => - clampedInterval(iv.from, iv.to, impactUptimeWeight(iv.impact)), - ) - .filter((iv): iv is WeightedInterval => iv !== null); - } - - if (barType === "manual") { - // NOTE: we want only user events; legacy reports (no impact rows) keep - // their full duration as downtime - const intervals = events - .filter((e) => e.type === "report") - .flatMap((e) => - e.impactIntervals - ? reportImpactIntervals(e) - : (clampedInterval(e.from, e.to, LEGACY_IMPACT_WEIGHT) ?? []), - ); - - const total = data.length * MILLISECONDS_PER_DAY; - if (total === 0) return "100%"; - const duration = mergedDowntimeMs(intervals); - - return `${Math.floor(((total - duration) / total) * 10000) / 100}%`; - } - - if (cardType === "duration") { - // incidents and impact-report downtime share one timeline so an incident - // plus a report describing the same outage counts once; legacy reports - // stay ignored to preserve pre-impact uptime values - const intervals = events.flatMap((e) => { - if (e.type === "incident") return clampedInterval(e.from, e.to, 1) ?? []; - if (e.type === "report") return reportImpactIntervals(e); - return []; - }); - - const total = data.length * MILLISECONDS_PER_DAY; + if (barType === "manual" || cardType === "duration") { + // Clamp event durations to the data lookback window to avoid + // events outside the window producing negative uptime values. + const timestamps = data.map((d) => new Date(d.day).getTime()); + const { segments: coverage, totalMs: total } = dayCoverage(timestamps); if (total === 0) return "100%"; - const duration = mergedDowntimeMs(intervals); - - return `${Math.floor(((total - duration) / total) * 10000) / 100}%`; + const windowEndDate = new Date(Math.max(...timestamps)); + windowEndDate.setUTCHours(23, 59, 59, 999); + const window: UptimeWindow = { + start: Math.min(...timestamps), + end: windowEndDate.getTime(), + now: Date.now(), + }; + const duration = + barType === "manual" + ? reportsOnlyDowntimeMs(events, window, coverage) + : durationDowntimeMs(events, window, coverage); + return `${floorPct((total - duration) / total)}%`; } - const { ok, total } = data.reduce( - (acc, item) => ({ - ok: acc.ok + item.ok + item.degraded, - total: acc.total + item.ok + item.degraded + item.error, - }), - { - ok: 0, - total: 0, - }, - ); - + const { up, total } = requestsTally(data); if (total === 0) return "100%"; - return `${Math.floor((ok / total) * 10000) / 100}%`; + return `${floorPct(up / total)}%`; } diff --git a/packages/api/src/router/stripe/webhook.ts b/packages/api/src/router/stripe/webhook.ts index abb22729..192f5e5c 100644 --- a/packages/api/src/router/stripe/webhook.ts +++ b/packages/api/src/router/stripe/webhook.ts @@ -260,7 +260,7 @@ export const webhookRouter = createTRPCRouter({ for (const m of activeMonitors.slice(1)) { await tx .update(monitor) - .set({ active: false }) + .set({ active: false, updatedAt: new Date() }) .where(eq(monitor.id, m.id)) .run(); } @@ -283,6 +283,7 @@ export const webhookRouter = createTRPCRouter({ password: null, accessType: "public", authEmailDomains: null, + updatedAt: new Date(), }) .where(eq(page.id, statusPages[0].id)) .run(); diff --git a/packages/db/drizzle/0077_military_jackpot.sql b/packages/db/drizzle/0077_military_jackpot.sql new file mode 100644 index 00000000..5e36e4a1 --- /dev/null +++ b/packages/db/drizzle/0077_military_jackpot.sql @@ -0,0 +1,13 @@ +CREATE TABLE `frozen_monitor_uptime` ( + `id` integer PRIMARY KEY NOT NULL, + `workspace_id` integer NOT NULL, + `monitor_id` integer NOT NULL, + `month` text NOT NULL, + `days` text NOT NULL, + `created_at` integer DEFAULT (strftime('%s', 'now')), + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`monitor_id`) REFERENCES `monitor`(`id`) ON UPDATE no action ON DELETE cascade +); +--> statement-breakpoint +CREATE INDEX `frozen_monitor_uptime_workspace_id_idx` ON `frozen_monitor_uptime` (`workspace_id`);--> statement-breakpoint +CREATE UNIQUE INDEX `frozen_monitor_uptime_monitor_id_month_unique` ON `frozen_monitor_uptime` (`monitor_id`,`month`); \ No newline at end of file diff --git a/packages/db/drizzle/meta/0077_snapshot.json b/packages/db/drizzle/meta/0077_snapshot.json new file mode 100644 index 00000000..2efba0c9 --- /dev/null +++ b/packages/db/drizzle/meta/0077_snapshot.json @@ -0,0 +1,4696 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "e88d56a5-ae87-4b25-9d59-1153f97a63bb", + "prevId": "bcbfadc8-aa40-4d0c-ad3b-eb3f3caa61ea", + "tables": { + "workspace": { + "name": "workspace", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ends_at": { + "name": "ends_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "paid_until": { + "name": "paid_until", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "limits": { + "name": "limits", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "dsn": { + "name": "dsn", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "workspace_slug_unique": { + "name": "workspace_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "workspace_stripe_id_unique": { + "name": "workspace_stripe_id_unique", + "columns": [ + "stripe_id" + ], + "isUnique": true + }, + "workspace_id_dsn_unique": { + "name": "workspace_id_dsn_unique", + "columns": [ + "id", + "dsn" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "account": { + "name": "account", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_provider_account_id_pk": { + "columns": [ + "provider", + "provider_account_id" + ], + "name": "account_provider_provider_account_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "tenant_id": { + "name": "tenant_id", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "photo_url": { + "name": "photo_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "emailVerified": { + "name": "emailVerified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_tenant_id_unique": { + "name": "user_tenant_id_unique", + "columns": [ + "tenant_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users_to_workspaces": { + "name": "users_to_workspaces", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "users_to_workspaces_workspace_id_idx": { + "name": "users_to_workspaces_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "users_to_workspaces_user_id_user_id_fk": { + "name": "users_to_workspaces_user_id_user_id_fk", + "tableFrom": "users_to_workspaces", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "users_to_workspaces_workspace_id_workspace_id_fk": { + "name": "users_to_workspaces_workspace_id_workspace_id_fk", + "tableFrom": "users_to_workspaces", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "users_to_workspaces_user_id_workspace_id_pk": { + "columns": [ + "user_id", + "workspace_id" + ], + "name": "users_to_workspaces_user_id_workspace_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "verification_token": { + "name": "verification_token", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verification_token_identifier_token_pk": { + "columns": [ + "identifier", + "token" + ], + "name": "verification_token_identifier_token_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report": { + "name": "status_report", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_workspace_created_idx": { + "name": "status_report_workspace_created_idx", + "columns": [ + "workspace_id", + "created_at" + ], + "isUnique": false + }, + "status_report_page_id_idx": { + "name": "status_report_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_workspace_id_workspace_id_fk": { + "name": "status_report_workspace_id_workspace_id_fk", + "tableFrom": "status_report", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "status_report_page_id_page_id_fk": { + "name": "status_report_page_id_page_id_fk", + "tableFrom": "status_report", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report_update": { + "name": "status_report_update", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status_report_id": { + "name": "status_report_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_update_status_report_id_idx": { + "name": "status_report_update_status_report_id_idx", + "columns": [ + "status_report_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_update_status_report_id_status_report_id_fk": { + "name": "status_report_update_status_report_id_status_report_id_fk", + "tableFrom": "status_report_update", + "tableTo": "status_report", + "columnsFrom": [ + "status_report_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integration": { + "name": "integration", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential": { + "name": "credential", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "integration_workspace_id_idx": { + "name": "integration_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integration_workspace_id_workspace_id_fk": { + "name": "integration_workspace_id_workspace_id_fk", + "tableFrom": "integration", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page": { + "name": "page", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "slug": { + "name": "slug", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "custom_domain": { + "name": "custom_domain", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "published": { + "name": "published", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "force_theme": { + "name": "force_theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'system'" + }, + "password": { + "name": "password", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password_protected": { + "name": "password_protected", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "access_type": { + "name": "access_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'public'" + }, + "auth_email_domains": { + "name": "auth_email_domains", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allowed_ip_ranges": { + "name": "allowed_ip_ranges", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "homepage_url": { + "name": "homepage_url", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "contact_url": { + "name": "contact_url", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_locale": { + "name": "default_locale", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'en'" + }, + "locales": { + "name": "locales", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "legacy_page": { + "name": "legacy_page", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "configuration": { + "name": "configuration", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allow_index": { + "name": "allow_index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "show_monitor_values": { + "name": "show_monitor_values", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_slug_unique": { + "name": "page_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "page_lower_slug_idx": { + "name": "page_lower_slug_idx", + "columns": [ + "LOWER(\"slug\")" + ], + "isUnique": false + }, + "page_lower_custom_domain_idx": { + "name": "page_lower_custom_domain_idx", + "columns": [ + "LOWER(\"custom_domain\")" + ], + "isUnique": false + }, + "page_workspace_id_idx": { + "name": "page_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "page_workspace_id_workspace_id_fk": { + "name": "page_workspace_id_workspace_id_fk", + "tableFrom": "page", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor": { + "name": "monitor", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "job_type": { + "name": "job_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'http'" + }, + "periodicity": { + "name": "periodicity", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'other'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "active": { + "name": "active", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "regions": { + "name": "regions", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "url": { + "name": "url", + "type": "text(2048)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "external_name": { + "name": "external_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "headers": { + "name": "headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'GET'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timeout": { + "name": "timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 45000 + }, + "degraded_after": { + "name": "degraded_after", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "assertions": { + "name": "assertions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "otel_endpoint": { + "name": "otel_endpoint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "otel_headers": { + "name": "otel_headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public": { + "name": "public", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "retry": { + "name": "retry", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 3 + }, + "follow_redirects": { + "name": "follow_redirects", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "monitor_workspace_id_active_idx": { + "name": "monitor_workspace_id_active_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false, + "where": "\"monitor\".\"deleted_at\" IS NULL" + } + }, + "foreignKeys": { + "monitor_workspace_id_workspace_id_fk": { + "name": "monitor_workspace_id_workspace_id_fk", + "tableFrom": "monitor", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_subscriber": { + "name": "page_subscriber", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_type": { + "name": "channel_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'email'" + }, + "webhook_url": { + "name": "webhook_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "channel_config": { + "name": "channel_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'self_signup'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accepted_at": { + "name": "accepted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "unsubscribed_at": { + "name": "unsubscribed_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "idx_page_subscriber_email_page_active": { + "name": "idx_page_subscriber_email_page_active", + "columns": [ + "LOWER(\"email\")", + "page_id" + ], + "isUnique": true, + "where": "\"page_subscriber\".\"unsubscribed_at\" IS NULL AND \"page_subscriber\".\"channel_type\" = 'email'" + }, + "idx_page_subscriber_webhook_page_active": { + "name": "idx_page_subscriber_webhook_page_active", + "columns": [ + "LOWER(\"webhook_url\")", + "page_id" + ], + "isUnique": true, + "where": "\"page_subscriber\".\"unsubscribed_at\" IS NULL AND \"page_subscriber\".\"channel_type\" = 'webhook'" + } + }, + "foreignKeys": { + "page_subscriber_page_id_page_id_fk": { + "name": "page_subscriber_page_id_page_id_fk", + "tableFrom": "page_subscriber", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "page_subscriber_channel_check": { + "name": "page_subscriber_channel_check", + "value": "(\"page_subscriber\".\"channel_type\" = 'email' AND \"page_subscriber\".\"email\" IS NOT NULL AND \"page_subscriber\".\"webhook_url\" IS NULL) OR (\"page_subscriber\".\"channel_type\" = 'webhook' AND \"page_subscriber\".\"webhook_url\" IS NOT NULL AND \"page_subscriber\".\"email\" IS NULL)" + } + } + }, + "page_subscriber_to_page_component": { + "name": "page_subscriber_to_page_component", + "columns": { + "page_subscriber_id": { + "name": "page_subscriber_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": {}, + "foreignKeys": { + "page_subscriber_to_page_component_page_subscriber_id_page_subscriber_id_fk": { + "name": "page_subscriber_to_page_component_page_subscriber_id_page_subscriber_id_fk", + "tableFrom": "page_subscriber_to_page_component", + "tableTo": "page_subscriber", + "columnsFrom": [ + "page_subscriber_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_subscriber_to_page_component_page_component_id_page_component_id_fk": { + "name": "page_subscriber_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "page_subscriber_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "page_subscriber_to_page_component_page_subscriber_id_page_component_id_pk": { + "columns": [ + "page_subscriber_id", + "page_component_id" + ], + "name": "page_subscriber_to_page_component_page_subscriber_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notification": { + "name": "notification", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'{}'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "notification_workspace_id_idx": { + "name": "notification_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "notification_workspace_id_workspace_id_fk": { + "name": "notification_workspace_id_workspace_id_fk", + "tableFrom": "notification", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notification_trigger": { + "name": "notification_trigger", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notification_id": { + "name": "notification_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cron_timestamp": { + "name": "cron_timestamp", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "notification_id_monitor_id_crontimestampe": { + "name": "notification_id_monitor_id_crontimestampe", + "columns": [ + "notification_id", + "monitor_id", + "cron_timestamp" + ], + "isUnique": true + } + }, + "foreignKeys": { + "notification_trigger_monitor_id_monitor_id_fk": { + "name": "notification_trigger_monitor_id_monitor_id_fk", + "tableFrom": "notification_trigger", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_trigger_notification_id_notification_id_fk": { + "name": "notification_trigger_notification_id_notification_id_fk", + "tableFrom": "notification_trigger", + "tableTo": "notification", + "columnsFrom": [ + "notification_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notifications_to_monitors": { + "name": "notifications_to_monitors", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notification_id": { + "name": "notification_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "notifications_to_monitors_notification_id_idx": { + "name": "notifications_to_monitors_notification_id_idx", + "columns": [ + "notification_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "notifications_to_monitors_monitor_id_monitor_id_fk": { + "name": "notifications_to_monitors_monitor_id_monitor_id_fk", + "tableFrom": "notifications_to_monitors", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_to_monitors_notification_id_notification_id_fk": { + "name": "notifications_to_monitors_notification_id_notification_id_fk", + "tableFrom": "notifications_to_monitors", + "tableTo": "notification", + "columnsFrom": [ + "notification_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "notifications_to_monitors_monitor_id_notification_id_pk": { + "columns": [ + "monitor_id", + "notification_id" + ], + "name": "notifications_to_monitors_monitor_id_notification_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_status": { + "name": "monitor_status", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_status_idx": { + "name": "monitor_status_idx", + "columns": [ + "monitor_id", + "region" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_status_monitor_id_monitor_id_fk": { + "name": "monitor_status_monitor_id_monitor_id_fk", + "tableFrom": "monitor_status", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "monitor_status_monitor_id_region_pk": { + "columns": [ + "monitor_id", + "region" + ], + "name": "monitor_status_monitor_id_region_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "invitation": { + "name": "invitation", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'member'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "accepted_at": { + "name": "accepted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "invitation_workspace_id_idx": { + "name": "invitation_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "incident": { + "name": "incident", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'triage'" + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "acknowledged_at": { + "name": "acknowledged_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "acknowledged_by": { + "name": "acknowledged_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolved_by": { + "name": "resolved_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "incident_screenshot_url": { + "name": "incident_screenshot_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "recovery_screenshot_url": { + "name": "recovery_screenshot_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auto_resolved": { + "name": "auto_resolved", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "incident_workspace_id_idx": { + "name": "incident_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "incident_monitor_id_started_at_unique": { + "name": "incident_monitor_id_started_at_unique", + "columns": [ + "monitor_id", + "started_at" + ], + "isUnique": true + } + }, + "foreignKeys": { + "incident_monitor_id_monitor_id_fk": { + "name": "incident_monitor_id_monitor_id_fk", + "tableFrom": "incident", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set default", + "onUpdate": "no action" + }, + "incident_workspace_id_workspace_id_fk": { + "name": "incident_workspace_id_workspace_id_fk", + "tableFrom": "incident", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "incident_acknowledged_by_user_id_fk": { + "name": "incident_acknowledged_by_user_id_fk", + "tableFrom": "incident", + "tableTo": "user", + "columnsFrom": [ + "acknowledged_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "incident_resolved_by_user_id_fk": { + "name": "incident_resolved_by_user_id_fk", + "tableFrom": "incident", + "tableTo": "user", + "columnsFrom": [ + "resolved_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_tag": { + "name": "monitor_tag", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_tag_workspace_id_idx": { + "name": "monitor_tag_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_tag_workspace_id_workspace_id_fk": { + "name": "monitor_tag_workspace_id_workspace_id_fk", + "tableFrom": "monitor_tag", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_tag_to_monitor": { + "name": "monitor_tag_to_monitor", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monitor_tag_id": { + "name": "monitor_tag_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_tag_to_monitor_monitor_tag_id_idx": { + "name": "monitor_tag_to_monitor_monitor_tag_id_idx", + "columns": [ + "monitor_tag_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_tag_to_monitor_monitor_id_monitor_id_fk": { + "name": "monitor_tag_to_monitor_monitor_id_monitor_id_fk", + "tableFrom": "monitor_tag_to_monitor", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk": { + "name": "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk", + "tableFrom": "monitor_tag_to_monitor", + "tableTo": "monitor_tag", + "columnsFrom": [ + "monitor_tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk": { + "columns": [ + "monitor_id", + "monitor_tag_id" + ], + "name": "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "application": { + "name": "application", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dsn": { + "name": "dsn", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "application_dsn_unique": { + "name": "application_dsn_unique", + "columns": [ + "dsn" + ], + "isUnique": true + }, + "application_workspace_id_idx": { + "name": "application_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "application_workspace_id_workspace_id_fk": { + "name": "application_workspace_id_workspace_id_fk", + "tableFrom": "application", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance": { + "name": "maintenance", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "from": { + "name": "from", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "to": { + "name": "to", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "maintenance_page_id_idx": { + "name": "maintenance_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + }, + "maintenance_workspace_id_idx": { + "name": "maintenance_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "maintenance_workspace_id_workspace_id_fk": { + "name": "maintenance_workspace_id_workspace_id_fk", + "tableFrom": "maintenance", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "maintenance_page_id_page_id_fk": { + "name": "maintenance_page_id_page_id_fk", + "tableFrom": "maintenance", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "check": { + "name": "check", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "regions": { + "name": "regions", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "url": { + "name": "url", + "type": "text(4096)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "headers": { + "name": "headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'GET'" + }, + "count_requests": { + "name": "count_requests", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 1 + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "check_workspace_id_idx": { + "name": "check_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "check_workspace_id_workspace_id_fk": { + "name": "check_workspace_id_workspace_id_fk", + "tableFrom": "check", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_run": { + "name": "monitor_run", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "runned_at": { + "name": "runned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_run_workspace_id_idx": { + "name": "monitor_run_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "monitor_run_monitor_id_idx": { + "name": "monitor_run_monitor_id_idx", + "columns": [ + "monitor_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_run_workspace_id_workspace_id_fk": { + "name": "monitor_run_workspace_id_workspace_id_fk", + "tableFrom": "monitor_run", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "monitor_run_monitor_id_monitor_id_fk": { + "name": "monitor_run_monitor_id_monitor_id_fk", + "tableFrom": "monitor_run", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "private_location": { + "name": "private_location", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "private_location_workspace_id_idx": { + "name": "private_location_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "private_location_workspace_id_workspace_id_fk": { + "name": "private_location_workspace_id_workspace_id_fk", + "tableFrom": "private_location", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "private_location_to_monitor": { + "name": "private_location_to_monitor", + "columns": { + "private_location_id": { + "name": "private_location_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "private_location_to_monitor_private_location_id_idx": { + "name": "private_location_to_monitor_private_location_id_idx", + "columns": [ + "private_location_id" + ], + "isUnique": false + }, + "private_location_to_monitor_monitor_id_idx": { + "name": "private_location_to_monitor_monitor_id_idx", + "columns": [ + "monitor_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "private_location_to_monitor_private_location_id_private_location_id_fk": { + "name": "private_location_to_monitor_private_location_id_private_location_id_fk", + "tableFrom": "private_location_to_monitor", + "tableTo": "private_location", + "columnsFrom": [ + "private_location_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "private_location_to_monitor_monitor_id_monitor_id_fk": { + "name": "private_location_to_monitor_monitor_id_monitor_id_fk", + "tableFrom": "private_location_to_monitor", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_group": { + "name": "monitor_group", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_group_workspace_id_idx": { + "name": "monitor_group_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "monitor_group_page_id_idx": { + "name": "monitor_group_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_group_workspace_id_workspace_id_fk": { + "name": "monitor_group_workspace_id_workspace_id_fk", + "tableFrom": "monitor_group", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "monitor_group_page_id_page_id_fk": { + "name": "monitor_group_page_id_page_id_fk", + "tableFrom": "monitor_group", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer": { + "name": "viewer", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "emailVerified": { + "name": "emailVerified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "viewer_email_unique": { + "name": "viewer_email_unique", + "columns": [ + "email" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer_accounts": { + "name": "viewer_accounts", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "viewer_accounts_user_id_viewer_id_fk": { + "name": "viewer_accounts_user_id_viewer_id_fk", + "tableFrom": "viewer_accounts", + "tableTo": "viewer", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "viewer_accounts_provider_providerAccountId_pk": { + "columns": [ + "provider", + "providerAccountId" + ], + "name": "viewer_accounts_provider_providerAccountId_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer_session": { + "name": "viewer_session", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "viewer_session_user_id_viewer_id_fk": { + "name": "viewer_session_user_id_viewer_id_fk", + "tableFrom": "viewer_session", + "tableTo": "viewer", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "api_key": { + "name": "api_key", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "hashed_token": { + "name": "hashed_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[\"write\"]'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "api_key_prefix_unique": { + "name": "api_key_prefix_unique", + "columns": [ + "prefix" + ], + "isUnique": true + }, + "api_key_hashed_token_unique": { + "name": "api_key_hashed_token_unique", + "columns": [ + "hashed_token" + ], + "isUnique": true + }, + "api_key_prefix_idx": { + "name": "api_key_prefix_idx", + "columns": [ + "prefix" + ], + "isUnique": false + }, + "api_key_workspace_id_idx": { + "name": "api_key_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "api_key_workspace_id_workspace_id_fk": { + "name": "api_key_workspace_id_workspace_id_fk", + "tableFrom": "api_key", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "api_key_created_by_id_user_id_fk": { + "name": "api_key_created_by_id_user_id_fk", + "tableFrom": "api_key", + "tableTo": "user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance_to_page_component": { + "name": "maintenance_to_page_component", + "columns": { + "maintenance_id": { + "name": "maintenance_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "maintenance_to_page_component_page_component_id_idx": { + "name": "maintenance_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "maintenance_to_page_component_maintenance_id_maintenance_id_fk": { + "name": "maintenance_to_page_component_maintenance_id_maintenance_id_fk", + "tableFrom": "maintenance_to_page_component", + "tableTo": "maintenance", + "columnsFrom": [ + "maintenance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "maintenance_to_page_component_page_component_id_page_component_id_fk": { + "name": "maintenance_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "maintenance_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "maintenance_to_page_component_maintenance_id_page_component_id_pk": { + "columns": [ + "maintenance_id", + "page_component_id" + ], + "name": "maintenance_to_page_component_maintenance_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_component": { + "name": "page_component", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'monitor'" + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_order": { + "name": "group_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_component_workspace_id_idx": { + "name": "page_component_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "page_component_page_id_monitor_id_unique": { + "name": "page_component_page_id_monitor_id_unique", + "columns": [ + "page_id", + "monitor_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "page_component_workspace_id_workspace_id_fk": { + "name": "page_component_workspace_id_workspace_id_fk", + "tableFrom": "page_component", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_page_id_page_id_fk": { + "name": "page_component_page_id_page_id_fk", + "tableFrom": "page_component", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_monitor_id_monitor_id_fk": { + "name": "page_component_monitor_id_monitor_id_fk", + "tableFrom": "page_component", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_group_id_page_component_groups_id_fk": { + "name": "page_component_group_id_page_component_groups_id_fk", + "tableFrom": "page_component", + "tableTo": "page_component_groups", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "page_component_type_check": { + "name": "page_component_type_check", + "value": "\"page_component\".\"type\" = 'monitor' AND \"page_component\".\"monitor_id\" IS NOT NULL OR \"page_component\".\"type\" = 'static' AND \"page_component\".\"monitor_id\" IS NULL" + } + } + }, + "status_report_update_to_page_component": { + "name": "status_report_update_to_page_component", + "columns": { + "status_report_update_id": { + "name": "status_report_update_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "impact": { + "name": "impact", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_update_to_page_component_page_component_id_idx": { + "name": "status_report_update_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_update_to_page_component_status_report_update_id_status_report_update_id_fk": { + "name": "status_report_update_to_page_component_status_report_update_id_status_report_update_id_fk", + "tableFrom": "status_report_update_to_page_component", + "tableTo": "status_report_update", + "columnsFrom": [ + "status_report_update_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "status_report_update_to_page_component_page_component_id_page_component_id_fk": { + "name": "status_report_update_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "status_report_update_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "status_report_update_to_page_component_status_report_update_id_page_component_id_pk": { + "columns": [ + "status_report_update_id", + "page_component_id" + ], + "name": "status_report_update_to_page_component_status_report_update_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report_to_page_component": { + "name": "status_report_to_page_component", + "columns": { + "status_report_id": { + "name": "status_report_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_to_page_component_page_component_id_idx": { + "name": "status_report_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_to_page_component_status_report_id_status_report_id_fk": { + "name": "status_report_to_page_component_status_report_id_status_report_id_fk", + "tableFrom": "status_report_to_page_component", + "tableTo": "status_report", + "columnsFrom": [ + "status_report_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "status_report_to_page_component_page_component_id_page_component_id_fk": { + "name": "status_report_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "status_report_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "status_report_to_page_component_status_report_id_page_component_id_pk": { + "columns": [ + "status_report_id", + "page_component_id" + ], + "name": "status_report_to_page_component_status_report_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_component_groups": { + "name": "page_component_groups", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_open": { + "name": "default_open", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_component_groups_page_id_idx": { + "name": "page_component_groups_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + }, + "page_component_groups_workspace_id_idx": { + "name": "page_component_groups_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "page_component_groups_workspace_id_workspace_id_fk": { + "name": "page_component_groups_workspace_id_workspace_id_fk", + "tableFrom": "page_component_groups", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_groups_page_id_page_id_fk": { + "name": "page_component_groups_page_id_page_id_fk", + "tableFrom": "page_component_groups", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "feedback": { + "name": "feedback", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "blocker": { + "name": "blocker", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "feedback_workspace_id_idx": { + "name": "feedback_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "feedback_workspace_id_workspace_id_fk": { + "name": "feedback_workspace_id_workspace_id_fk", + "tableFrom": "feedback", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "feedback_user_id_user_id_fk": { + "name": "feedback_user_id_user_id_fk", + "tableFrom": "feedback", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "audit_log": { + "name": "audit_log", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_type": { + "name": "actor_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "before": { + "name": "before", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "after": { + "name": "after", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "changed_fields": { + "name": "changed_fields", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "audit_log_workspace_created_idx": { + "name": "audit_log_workspace_created_idx", + "columns": [ + "workspace_id", + "created_at" + ], + "isUnique": false + }, + "audit_log_entity_idx": { + "name": "audit_log_entity_idx", + "columns": [ + "workspace_id", + "entity_type", + "entity_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service": { + "name": "external_service", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "aliases": { + "name": "aliases", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(json_array())" + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status_page_url": { + "name": "status_page_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "industry": { + "name": "industry", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_config": { + "name": "api_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_slug_unique": { + "name": "external_service_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "external_service_deleted_at_idx": { + "name": "external_service_deleted_at_idx", + "columns": [ + "deleted_at" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_component": { + "name": "external_service_component", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "upstream_component_id": { + "name": "upstream_component_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "aliases": { + "name": "aliases", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(json_array())" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "indicator": { + "name": "indicator", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_component_unique_idx": { + "name": "external_service_component_unique_idx", + "columns": [ + "external_service_id", + "upstream_component_id" + ], + "isUnique": true + }, + "external_service_component_slug_unique_idx": { + "name": "external_service_component_slug_unique_idx", + "columns": [ + "external_service_id", + "slug" + ], + "isUnique": true + } + }, + "foreignKeys": { + "external_service_component_external_service_id_external_service_id_fk": { + "name": "external_service_component_external_service_id_external_service_id_fk", + "tableFrom": "external_service_component", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_incident": { + "name": "external_service_incident", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_incident_id": { + "name": "provider_incident_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "impact": { + "name": "impact", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "shortlink": { + "name": "shortlink", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "affected_component_ids": { + "name": "affected_component_ids", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[]'" + }, + "raw_payload": { + "name": "raw_payload", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "raw_payload_purged_at": { + "name": "raw_payload_purged_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_incident_unique_idx": { + "name": "external_service_incident_unique_idx", + "columns": [ + "external_service_id", + "provider_incident_id" + ], + "isUnique": true + }, + "external_service_incident_started_at_idx": { + "name": "external_service_incident_started_at_idx", + "columns": [ + "external_service_id", + "started_at" + ], + "isUnique": false + }, + "external_service_incident_resolved_at_idx": { + "name": "external_service_incident_resolved_at_idx", + "columns": [ + "resolved_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_service_incident_external_service_id_external_service_id_fk": { + "name": "external_service_incident_external_service_id_external_service_id_fk", + "tableFrom": "external_service_incident", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_report": { + "name": "external_service_report", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_service_component_id": { + "name": "external_service_component_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "reporter_hash": { + "name": "reporter_hash", + "type": "text(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "country": { + "name": "country", + "type": "text(2)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_report_service_idx": { + "name": "external_service_report_service_idx", + "columns": [ + "external_service_id", + "created_at" + ], + "isUnique": false + }, + "external_service_report_component_idx": { + "name": "external_service_report_component_idx", + "columns": [ + "external_service_component_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_service_report_external_service_id_external_service_id_fk": { + "name": "external_service_report_external_service_id_external_service_id_fk", + "tableFrom": "external_service_report", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "external_service_report_external_service_component_id_external_service_component_id_fk": { + "name": "external_service_report_external_service_component_id_external_service_component_id_fk", + "tableFrom": "external_service_report", + "tableTo": "external_service_component", + "columnsFrom": [ + "external_service_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "chat_session": { + "name": "chat_session", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "messages": { + "name": "messages", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "chat_session_workspace_user_updated_idx": { + "name": "chat_session_workspace_user_updated_idx", + "columns": [ + "workspace_id", + "user_id", + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "chat_session_workspace_id_workspace_id_fk": { + "name": "chat_session_workspace_id_workspace_id_fk", + "tableFrom": "chat_session", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "chat_session_user_id_user_id_fk": { + "name": "chat_session_user_id_user_id_fk", + "tableFrom": "chat_session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "frozen_monitor_uptime": { + "name": "frozen_monitor_uptime", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "month": { + "name": "month", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "days": { + "name": "days", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "frozen_monitor_uptime_workspace_id_idx": { + "name": "frozen_monitor_uptime_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "frozen_monitor_uptime_monitor_id_month_unique": { + "name": "frozen_monitor_uptime_monitor_id_month_unique", + "columns": [ + "monitor_id", + "month" + ], + "isUnique": true + } + }, + "foreignKeys": { + "frozen_monitor_uptime_workspace_id_workspace_id_fk": { + "name": "frozen_monitor_uptime_workspace_id_workspace_id_fk", + "tableFrom": "frozen_monitor_uptime", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "frozen_monitor_uptime_monitor_id_monitor_id_fk": { + "name": "frozen_monitor_uptime_monitor_id_monitor_id_fk", + "tableFrom": "frozen_monitor_uptime", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": { + "page_lower_slug_idx": { + "columns": { + "LOWER(\"slug\")": { + "isExpression": true + } + } + }, + "page_lower_custom_domain_idx": { + "columns": { + "LOWER(\"custom_domain\")": { + "isExpression": true + } + } + }, + "idx_page_subscriber_email_page_active": { + "columns": { + "LOWER(\"email\")": { + "isExpression": true + } + } + }, + "idx_page_subscriber_webhook_page_active": { + "columns": { + "LOWER(\"webhook_url\")": { + "isExpression": true + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index 28d7004f..13a807b7 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -540,6 +540,13 @@ "when": 1781258845086, "tag": "0076_tense_night_thrasher", "breakpoints": true + }, + { + "idx": 77, + "version": "6", + "when": 1782994900937, + "tag": "0077_military_jackpot", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/frozen_uptime/frozen_monitor_uptime.ts b/packages/db/src/schema/frozen_uptime/frozen_monitor_uptime.ts new file mode 100644 index 00000000..206738c8 --- /dev/null +++ b/packages/db/src/schema/frozen_uptime/frozen_monitor_uptime.ts @@ -0,0 +1,56 @@ +import { relations, sql } from "drizzle-orm"; +import { + index, + integer, + sqliteTable, + text, + unique, +} from "drizzle-orm/sqlite-core"; + +import { monitor } from "../monitors/monitor"; +import { workspace } from "../workspaces/workspace"; +import type { FrozenMonitorUptimeDay } from "./validation"; + +export const frozenMonitorUptime = sqliteTable( + "frozen_monitor_uptime", + { + id: integer("id").primaryKey(), + workspaceId: integer("workspace_id") + .notNull() + .references(() => workspace.id, { onDelete: "cascade" }), + monitorId: integer("monitor_id") + .notNull() + .references(() => monitor.id, { onDelete: "cascade" }), + // UTC first-of-month, YYYY-MM-01 + month: text("month").notNull(), + days: text("days", { mode: "json" }) + .$type() + .notNull(), + + createdAt: integer("created_at", { mode: "timestamp" }).default( + sql`(strftime('%s', 'now'))`, + ), + }, + (t) => [ + // idempotency key: re-freezing a month is a silent no-op + unique("frozen_monitor_uptime_monitor_id_month_unique").on( + t.monitorId, + t.month, + ), + index("frozen_monitor_uptime_workspace_id_idx").on(t.workspaceId), + ], +); + +export const frozenMonitorUptimeRelations = relations( + frozenMonitorUptime, + ({ one }) => ({ + monitor: one(monitor, { + fields: [frozenMonitorUptime.monitorId], + references: [monitor.id], + }), + workspace: one(workspace, { + fields: [frozenMonitorUptime.workspaceId], + references: [workspace.id], + }), + }), +); diff --git a/packages/db/src/schema/frozen_uptime/index.ts b/packages/db/src/schema/frozen_uptime/index.ts new file mode 100644 index 00000000..10997af8 --- /dev/null +++ b/packages/db/src/schema/frozen_uptime/index.ts @@ -0,0 +1,2 @@ +export * from "./frozen_monitor_uptime"; +export * from "./validation"; diff --git a/packages/db/src/schema/frozen_uptime/validation.ts b/packages/db/src/schema/frozen_uptime/validation.ts new file mode 100644 index 00000000..d5ef9c6d --- /dev/null +++ b/packages/db/src/schema/frozen_uptime/validation.ts @@ -0,0 +1,41 @@ +import { createInsertSchema, createSelectSchema } from "drizzle-zod"; +import { z } from "zod"; + +import { frozenMonitorUptime } from "./frozen_monitor_uptime"; + +export const frozenMonitorUptimeDaySchema = z.object({ + day: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "day must be YYYY-MM-DD"), // UTC + ok: z.number().int().nonnegative(), + degraded: z.number().int().nonnegative(), + error: z.number().int().nonnegative(), +}); +export type FrozenMonitorUptimeDay = z.infer< + typeof frozenMonitorUptimeDaySchema +>; + +// YYYY-MM-01, UTC first-of-month +export const frozenMonitorUptimeMonthSchema = z + .string() + .regex(/^\d{4}-\d{2}-01$/, "month must be YYYY-MM-01"); + +export const selectFrozenMonitorUptimeSchema = createSelectSchema( + frozenMonitorUptime, + { + days: frozenMonitorUptimeDaySchema.array(), + month: frozenMonitorUptimeMonthSchema, + }, +); +export type FrozenMonitorUptime = z.infer< + typeof selectFrozenMonitorUptimeSchema +>; + +export const insertFrozenMonitorUptimeSchema = createInsertSchema( + frozenMonitorUptime, + { + days: frozenMonitorUptimeDaySchema.array(), + month: frozenMonitorUptimeMonthSchema, + }, +); +export type InsertFrozenMonitorUptime = z.infer< + typeof insertFrozenMonitorUptimeSchema +>; diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts index 82dfb559..ddc5bece 100644 --- a/packages/db/src/schema/index.ts +++ b/packages/db/src/schema/index.ts @@ -25,3 +25,4 @@ export * from "./feedbacks"; export * from "./audit_logs"; export * from "./external_services"; export * from "./chat_sessions"; +export * from "./frozen_uptime"; diff --git a/packages/db/src/schema/plan/config.ts b/packages/db/src/schema/plan/config.ts index 28597339..f7a3f33f 100644 --- a/packages/db/src/schema/plan/config.ts +++ b/packages/db/src/schema/plan/config.ts @@ -41,6 +41,7 @@ export const allPlans: Record = { "page-components": 3, maintenance: true, "monitor-values-visibility": true, + "uptime-history": false, "response-logs": false, screenshots: false, otel: false, @@ -124,6 +125,7 @@ export const allPlans: Record = { "page-components": 20, maintenance: true, "monitor-values-visibility": true, + "uptime-history": false, "response-logs": true, screenshots: true, otel: false, @@ -207,6 +209,7 @@ export const allPlans: Record = { "page-components": 50, maintenance: true, "monitor-values-visibility": true, + "uptime-history": true, "response-logs": true, screenshots: true, otel: true, @@ -263,6 +266,7 @@ export const allPlans: Record = { "page-components": 500, maintenance: true, "monitor-values-visibility": true, + "uptime-history": true, "response-logs": true, screenshots: true, otel: true, diff --git a/packages/db/src/schema/plan/schema.ts b/packages/db/src/schema/plan/schema.ts index bc2f8a12..3a3b1570 100644 --- a/packages/db/src/schema/plan/schema.ts +++ b/packages/db/src/schema/plan/schema.ts @@ -31,6 +31,7 @@ export const limitsSchema = z.object({ "page-components": z.number().prefault(3), maintenance: z.boolean().prefault(true), "monitor-values-visibility": z.boolean().prefault(true), + "uptime-history": z.boolean().prefault(false), "status-subscribers": z.boolean().prefault(false), "custom-domain": z.boolean().prefault(false), i18n: z.boolean().prefault(false), diff --git a/packages/services/package.json b/packages/services/package.json index 7a863399..c353cc42 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -45,6 +45,10 @@ "import": "./src/status-timeline/index.ts", "types": "./src/status-timeline/index.ts" }, + "./frozen-uptime": { + "import": "./src/frozen-uptime/index.ts", + "types": "./src/frozen-uptime/index.ts" + }, "./workspace": { "import": "./src/workspace/index.ts", "types": "./src/workspace/index.ts" diff --git a/packages/services/src/frozen-uptime/__tests__/compute.test.ts b/packages/services/src/frozen-uptime/__tests__/compute.test.ts new file mode 100644 index 00000000..c7464b51 --- /dev/null +++ b/packages/services/src/frozen-uptime/__tests__/compute.test.ts @@ -0,0 +1,134 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { + type ComputeCountRow, + computeMonitorMonth, + monthDays, + monthRange, + previousMonth, +} from "../compute"; + +const MONTH = "2026-06-01"; + +const row = ( + day: string, + counts: Partial> = {}, + monitorId = "77", +): ComputeCountRow => ({ + monitorId, + day, + ok: counts.ok ?? 0, + degraded: counts.degraded ?? 0, + error: counts.error ?? 0, +}); + +describe("previousMonth", () => { + test("returns the UTC first-of-month before now", () => { + expect(previousMonth(new Date(Date.UTC(2026, 6, 10)))).toBe("2026-06-01"); + expect(previousMonth(new Date(Date.UTC(2026, 0, 10)))).toBe("2025-12-01"); + }); +}); + +describe("monthRange", () => { + test("spans [first-of-month, first-of-next-month) in UTC ms", () => { + const { start, end } = monthRange(MONTH); + expect(start).toBe(Date.UTC(2026, 5, 1)); + expect(end).toBe(Date.UTC(2026, 6, 1)); + }); +}); + +describe("monthDays", () => { + test("handles 31/30/28-day months and leap February", () => { + expect(monthDays("2026-07-01").length).toBe(31); + expect(monthDays("2026-06-01").length).toBe(30); + expect(monthDays("2026-02-01").length).toBe(28); + expect(monthDays("2028-02-01").length).toBe(29); + expect(monthDays(MONTH)[0]).toBe("2026-06-01"); + expect(monthDays(MONTH)[29]).toBe("2026-06-30"); + }); +}); + +describe("computeMonitorMonth", () => { + test("slices ISO day strings and zero-fills missing days", () => { + const computed = computeMonitorMonth({ + month: MONTH, + monitorId: 77, + counts: [ + row("2026-06-05T00:00:00.000Z", { ok: 42, degraded: 1 }), + row("2026-06-30", { ok: 7, error: 2 }), + ], + }); + + expect(computed).not.toBeNull(); + expect(computed?.days.length).toBe(30); + expect(computed?.days[4]).toEqual({ + day: "2026-06-05", + ok: 42, + degraded: 1, + error: 0, + }); + expect(computed?.days[29]).toEqual({ + day: "2026-06-30", + ok: 7, + degraded: 0, + error: 2, + }); + expect(computed?.days[0]).toEqual({ + day: "2026-06-01", + ok: 0, + degraded: 0, + error: 0, + }); + }); + + test("drops rows outside the month and rows of other monitors", () => { + const computed = computeMonitorMonth({ + month: MONTH, + monitorId: 77, + counts: [ + row("2026-05-31", { ok: 99 }), + row("2026-07-01", { ok: 99 }), + row("2026-06-10", { ok: 99 }, "88"), + row("2026-06-10", { ok: 5 }), + ], + }); + + expect(computed?.days[9].ok).toBe(5); + expect(computed?.days.every((d) => d.ok <= 5)).toBe(true); + }); + + test("sums multiple rows for the same day instead of overwriting", () => { + const computed = computeMonitorMonth({ + month: MONTH, + monitorId: 77, + counts: [ + row("2026-06-10", { ok: 10, degraded: 1 }), + row("2026-06-10T12:00:00.000Z", { ok: 5, error: 2 }), + ], + }); + + expect(computed?.days[9]).toEqual({ + day: "2026-06-10", + ok: 15, + degraded: 1, + error: 2, + }); + }); + + test("returns null when the monitor has no counts in the month", () => { + expect( + computeMonitorMonth({ month: MONTH, monitorId: 77, counts: [] }), + ).toBeNull(); + expect( + computeMonitorMonth({ + month: MONTH, + monitorId: 77, + counts: [ + row("2026-05-31", { ok: 1 }), + row("2026-06-10", { ok: 1 }, "88"), + ], + }), + ).toBeNull(); + }); +}); diff --git a/packages/services/src/frozen-uptime/__tests__/freeze.test.ts b/packages/services/src/frozen-uptime/__tests__/freeze.test.ts new file mode 100644 index 00000000..7f2416a8 --- /dev/null +++ b/packages/services/src/frozen-uptime/__tests__/freeze.test.ts @@ -0,0 +1,200 @@ +import { eq } from "@openstatus/db"; +import { + frozenMonitorUptime, + monitor, + workspace, +} from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; + +import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; +import { + loadSeededWorkspace, + makeApiKeyCtx, + makeSystemCtx, + readAuditLog, + withTestTransaction, +} from "../../../test/helpers"; +import type { ServiceContext } from "../../context"; +import { ForbiddenError, NotFoundError } from "../../errors"; +import { freezeMonitorMonth } from "../freeze"; +import type { FreezeMonitorMonthInput } from "../schemas"; + +let systemCtx: ServiceContext; +let readOnlyCtx: ServiceContext; + +beforeAll(async () => { + const team = await loadSeededWorkspace(SEEDED_WORKSPACE_TEAM_ID); + systemCtx = makeSystemCtx(team, { job: "uptime-freeze" }); + readOnlyCtx = makeApiKeyCtx(team, { + keyId: "k", + userId: 1, + scopes: ["read"], + }); +}); + +async function insertTestMonitor(tx: NonNullable) { + return tx + .insert(monitor) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + active: true, + url: "https://example.com", + name: "svc-frozen-uptime-monitor", + method: "GET", + periodicity: "10m", + regions: "ams", + jobType: "http", + }) + .returning() + .get(); +} + +function makeInput( + monitorId: number, + overrides: Partial = {}, +): FreezeMonitorMonthInput { + return { + monitorId, + month: "2026-06-01", + days: [{ day: "2026-06-01", ok: 42, degraded: 0, error: 1 }], + ...overrides, + }; +} + +describe("freezeMonitorMonth", () => { + test("inserts a frozen month — and emits NO audit row (deliberate exception)", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...systemCtx, db: tx }; + const testMonitor = await insertTestMonitor(tx); + const input = makeInput(testMonitor.id); + + const row = await freezeMonitorMonth({ ctx, input }); + + expect(row).not.toBeNull(); + expect(row?.workspaceId).toBe(SEEDED_WORKSPACE_TEAM_ID); + expect(row?.month).toBe("2026-06-01"); + expect(row?.days).toEqual(input.days); + + const persisted = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, input.monitorId)) + .all(); + expect(persisted.length).toBe(1); + + const auditRows = await readAuditLog({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + entityType: "frozen_monitor_uptime", + db: tx, + }); + expect(auditRows.length).toBe(0); + }); + }); + + test("re-run on same (monitorId, month) returns null and writes nothing", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...systemCtx, db: tx }; + const testMonitor = await insertTestMonitor(tx); + const input = makeInput(testMonitor.id); + + const first = await freezeMonitorMonth({ ctx, input }); + expect(first).not.toBeNull(); + + // same key, different payload: the frozen month must stay untouched + const second = await freezeMonitorMonth({ + ctx, + input: { + ...input, + days: [{ day: "2026-06-01", ok: 0, degraded: 0, error: 0 }], + }, + }); + expect(second).toBeNull(); + + const persisted = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, input.monitorId)) + .all(); + expect(persisted.length).toBe(1); + expect(persisted[0].days[0].ok).toBe(42); + + const auditRows = await readAuditLog({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + entityType: "frozen_monitor_uptime", + db: tx, + }); + expect(auditRows.length).toBe(0); + }); + }); + + test("same monitor, different month inserts a second row", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...systemCtx, db: tx }; + const testMonitor = await insertTestMonitor(tx); + const input = makeInput(testMonitor.id); + + const june = await freezeMonitorMonth({ ctx, input }); + const july = await freezeMonitorMonth({ + ctx, + input: { + ...input, + month: "2026-07-01", + days: [{ ...input.days[0], day: "2026-07-01" }], + }, + }); + expect(june).not.toBeNull(); + expect(july).not.toBeNull(); + + const persisted = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, input.monitorId)) + .all(); + expect(persisted.length).toBe(2); + }); + }); + + test("rejects a monitor from another workspace", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...systemCtx, db: tx }; + const foreignWorkspace = await tx + .insert(workspace) + .values({ slug: "svc-frozen-uptime-foreign-ws" }) + .returning() + .get(); + const foreignMonitor = await tx + .insert(monitor) + .values({ + workspaceId: foreignWorkspace.id, + active: true, + url: "https://example.com", + name: "svc-frozen-uptime-foreign-monitor", + method: "GET", + periodicity: "10m", + regions: "ams", + jobType: "http", + }) + .returning() + .get(); + + await expect( + freezeMonitorMonth({ ctx, input: makeInput(foreignMonitor.id) }), + ).rejects.toThrow(NotFoundError); + + const persisted = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, foreignMonitor.id)) + .all(); + expect(persisted.length).toBe(0); + }); + }); + + test("rejects read-only actor", async () => { + // requireScope fires before any DB lookup, so fake ids are fine + await expect( + freezeMonitorMonth({ ctx: readOnlyCtx, input: makeInput(1) }), + ).rejects.toThrow(ForbiddenError); + }); +}); diff --git a/packages/services/src/frozen-uptime/__tests__/get-history.test.ts b/packages/services/src/frozen-uptime/__tests__/get-history.test.ts new file mode 100644 index 00000000..d4ec0b7b --- /dev/null +++ b/packages/services/src/frozen-uptime/__tests__/get-history.test.ts @@ -0,0 +1,809 @@ +import { + frozenMonitorUptime, + incidentTable, + monitor, + page, + pageComponent, + statusReport, + statusReportUpdate, + statusReportUpdateToPageComponents, + statusReportsToPageComponents, +} from "@openstatus/db/src/schema"; +import type { FrozenMonitorUptimeDay } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { beforeAll, describe, test } from "@std/testing/bdd"; + +import { + SEEDED_WORKSPACE_FREE_ID, + SEEDED_WORKSPACE_TEAM_ID, +} from "../../../test/fixtures"; +import { + loadSeededWorkspace, + makeUserCtx, + withTestTransaction, +} from "../../../test/helpers"; +import type { ServiceContext } from "../../context"; +import { ForbiddenError, NotFoundError } from "../../errors"; +import type { ComputeCountRow } from "../compute"; +import { monthDays } from "../compute"; +import { getUptimeHistory } from "../get-history"; +import type { UptimeFreezePipes } from "../run"; + +const MS_PER_DAY = 86_400_000; +const noSleep = () => Promise.resolve(); + +let userCtx: ServiceContext; +let freeCtx: ServiceContext; + +beforeAll(async () => { + userCtx = makeUserCtx(await loadSeededWorkspace(SEEDED_WORKSPACE_TEAM_ID)); + freeCtx = makeUserCtx(await loadSeededWorkspace(SEEDED_WORKSPACE_FREE_ID), { + userId: 2, + }); +}); + +// tests anchor months to the real clock: getEvents filters against `new +// Date()` internally, so an artificial `now` would skew the event window +const now = new Date(); + +/** "YYYY-MM" for `offset` months before the current month (0 = current). */ +function key(offset: number): string { + const d = new Date( + Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - offset, 1), + ); + return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}`; +} + +function monthStart(k: string): Date { + const [y, m] = k.split("-").map(Number); + return new Date(Date.UTC(y, m - 1, 1)); +} + +function monthEnd(k: string): Date { + const [y, m] = k.split("-").map(Number); + return new Date(Date.UTC(y, m, 1)); +} + +/** Full zero-filled month with `counts` applied to every day. */ +function fullMonth( + k: string, + counts: { ok?: number; degraded?: number; error?: number }, +): FrozenMonitorUptimeDay[] { + return monthDays(`${k}-01`).map((day) => ({ + day, + ok: counts.ok ?? 0, + degraded: counts.degraded ?? 0, + error: counts.error ?? 0, + })); +} + +function makePipes(rows: ComputeCountRow[]): UptimeFreezePipes { + const pipe = () => Promise.resolve({ data: rows }); + return { http: pipe, tcp: pipe, dns: pipe }; +} + +function failingPipes(): UptimeFreezePipes { + const pipe = () => Promise.reject(new Error("tinybird down")); + return { http: pipe, tcp: pipe, dns: pipe }; +} + +type Tx = Parameters[0]>[0]; + +let slugCounter = 0; + +async function insertPage( + tx: Tx, + overrides: Partial = {}, +) { + return tx + .insert(page) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + title: "svc-history-page", + description: "", + slug: `svc-history-${Date.now()}-${slugCounter++}`, + customDomain: "", + ...overrides, + }) + .returning() + .get(); +} + +async function insertMonitor(tx: Tx) { + return tx + .insert(monitor) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + active: true, + url: "https://example.com", + name: "svc-history-monitor", + method: "GET", + periodicity: "10m", + regions: "ams", + jobType: "http", + }) + .returning() + .get(); +} + +async function insertComponent( + tx: Tx, + args: { + pageId: number; + monitorId?: number; + createdAt?: Date; + name?: string; + }, +) { + return tx + .insert(pageComponent) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + pageId: args.pageId, + type: args.monitorId ? "monitor" : "static", + monitorId: args.monitorId ?? null, + name: args.name ?? "svc-history-component", + createdAt: args.createdAt ?? now, + }) + .returning() + .get(); +} + +async function insertFrozen( + tx: Tx, + args: { monitorId: number; month: string; days: FrozenMonitorUptimeDay[] }, +) { + return tx + .insert(frozenMonitorUptime) + .values({ workspaceId: SEEDED_WORKSPACE_TEAM_ID, ...args }) + .returning() + .get(); +} + +/** Resolved impact report against one component: `impact` from → to. */ +async function insertImpactReport( + tx: Tx, + args: { + pageId: number; + pageComponentId: number; + impact: "major_outage" | "partial_outage"; + from: Date; + to: Date; + }, +) { + const report = await tx + .insert(statusReport) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + pageId: args.pageId, + status: "resolved", + title: "svc-history-report", + }) + .returning() + .get(); + await tx.insert(statusReportsToPageComponents).values({ + statusReportId: report.id, + pageComponentId: args.pageComponentId, + }); + const open = await tx + .insert(statusReportUpdate) + .values({ + statusReportId: report.id, + status: "identified", + date: args.from, + message: "down", + }) + .returning() + .get(); + await tx.insert(statusReportUpdateToPageComponents).values({ + statusReportUpdateId: open.id, + pageComponentId: args.pageComponentId, + impact: args.impact, + }); + const close = await tx + .insert(statusReportUpdate) + .values({ + statusReportId: report.id, + status: "resolved", + date: args.to, + message: "up", + }) + .returning() + .get(); + await tx.insert(statusReportUpdateToPageComponents).values({ + statusReportUpdateId: close.id, + pageComponentId: args.pageComponentId, + impact: "operational", + }); + return report; +} + +/** Legacy report: membership + updates but NO per-update impact rows. */ +async function insertLegacyReport( + tx: Tx, + args: { + pageId: number; + pageComponentIds: number[]; + from: Date; + to: Date; + }, +) { + const report = await tx + .insert(statusReport) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + pageId: args.pageId, + status: "resolved", + title: "svc-history-legacy-report", + }) + .returning() + .get(); + for (const pageComponentId of args.pageComponentIds) { + await tx.insert(statusReportsToPageComponents).values({ + statusReportId: report.id, + pageComponentId, + }); + } + await tx.insert(statusReportUpdate).values({ + statusReportId: report.id, + status: "identified", + date: args.from, + message: "down", + }); + await tx.insert(statusReportUpdate).values({ + statusReportId: report.id, + status: "resolved", + date: args.to, + message: "up", + }); + return report; +} + +describe("getUptimeHistory", () => { + test("legacy report (no impact rows) counts full duration for static components", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testPage = await insertPage(tx); + const createdAt = monthStart(key(1)); + const component = await insertComponent(tx, { + pageId: testPage.id, + createdAt, + }); + + const from = new Date(createdAt.getTime() + 2 * MS_PER_DAY); + const twelveHours = 12 * 3_600_000; + await insertLegacyReport(tx, { + pageId: testPage.id, + pageComponentIds: [component.id], + from, + to: new Date(from.getTime() + twelveHours), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + const totalMs = monthEnd(key(1)).getTime() - monthStart(key(1)).getTime(); + const expected = + Math.floor(((totalMs - twelveHours) / totalMs) * 10_000) / 100; + expect(res.rows[0].months[key(1)]).toBe(expected); + }); + }); + + test("report member never named by impact rows still counts full duration (empty projection)", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testPage = await insertPage(tx); + const createdAt = monthStart(key(1)); + const memberOnly = await insertComponent(tx, { + pageId: testPage.id, + createdAt, + name: "member-only", + }); + const impacted = await insertComponent(tx, { + pageId: testPage.id, + createdAt, + name: "impacted", + }); + + // impact rows name only `impacted`; `memberOnly` joins as plain member, + // so its projection is an EMPTY impactIntervals array, not undefined + const from = new Date(createdAt.getTime() + 2 * MS_PER_DAY); + const twelveHours = 12 * 3_600_000; + const report = await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: impacted.id, + impact: "partial_outage", + from, + to: new Date(from.getTime() + twelveHours), + }); + await tx.insert(statusReportsToPageComponents).values({ + statusReportId: report.id, + pageComponentId: memberOnly.id, + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + const totalMs = monthEnd(key(1)).getTime() - monthStart(key(1)).getTime(); + const legacyExpected = + Math.floor(((totalMs - twelveHours) / totalMs) * 10_000) / 100; + const partialExpected = + Math.floor(((totalMs - twelveHours / 2) / totalMs) * 10_000) / 100; + + const byName = new Map(res.rows.map((r) => [r.component.name, r])); + // empty projection falls through to legacy full-duration downtime + expect(byName.get("member-only")?.months[key(1)]).toBe(legacyExpected); + // the impacted component keeps its weighted (0.5) interval + expect(byName.get("impacted")?.months[key(1)]).toBe(partialExpected); + }); + }); + + test("requests mode: frozen months + live current/previous, older unfrozen months null", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx); + await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(2)}-01`, + days: fullMonth(key(2), { ok: 100 }), + }); + // previous month NOT frozen (freeze runs on the 10th) → served live + const pipes = makePipes([ + { + monitorId: String(testMonitor.id), + day: `${key(1)}-02`, + ok: 99, + degraded: 0, + error: 1, + }, + { + monitorId: String(testMonitor.id), + day: `${key(0)}-01`, + ok: 50, + degraded: 0, + error: 0, + }, + ]); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes, + now, + sleep: noSleep, + }); + + expect(res.mode).toBe("requests"); + expect(res.months.length).toBe(24); + expect(res.months[res.months.length - 1]).toBe(key(0)); + const row = res.rows[0]; + expect(row.component.type).toBe("monitor"); + expect(row.months[key(2)]).toBe(100); + expect(row.months[key(1)]).toBe(99); + expect(row.months[key(0)]).toBe(100); + // aged past the TB window without a freeze → no data, never down + expect(row.months[key(3)]).toBe(null); + expect(res.createdAt?.getTime()).toBe(testPage.createdAt?.getTime()); + }); + }); + + test("tinybird failure: live months degrade to null, frozen months still served", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx); + await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days: fullMonth(key(1), { ok: 10 }), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: failingPipes(), + now, + sleep: noSleep, + }); + + const row = res.rows[0]; + expect(row.months[key(1)]).toBe(100); + expect(row.months[key(0)]).toBe(null); + }); + }); + + test("a 0/0/0 month is null, not 0% — and floor rounding never shows 100.00 with a failed check", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx); + await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(2)}-01`, + days: fullMonth(key(2), {}), + }); + const days = fullMonth(key(1), {}); + days[0] = { day: days[0].day, ok: 99_999, degraded: 0, error: 1 }; + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days, + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + const row = res.rows[0]; + expect(row.months[key(2)]).toBe(null); + expect(row.months[key(1)]).toBe(99.99); + // live month with zero pipe rows is also no-data + expect(row.months[key(0)]).toBe(null); + }); + }); + + test("rolling totals are additive across months, not averaged percentages", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx); + await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + const up = fullMonth(key(2), {}); + up[0] = { day: up[0].day, ok: 3000, degraded: 0, error: 0 }; + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(2)}-01`, + days: up, + }); + const down = fullMonth(key(1), {}); + down[0] = { day: down[0].day, ok: 0, degraded: 0, error: 1000 }; + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days: down, + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + const row = res.rows[0]; + expect(row.months[key(2)]).toBe(100); + expect(row.months[key(1)]).toBe(0); + // additive: 3000/4000 = 75.00; a naive percentage average would say 50 + expect(row.rolling["6"]).toBe(75); + expect(row.rolling["24"]).toBe(75); + }); + }); + + test("duration mode: overlapping incident + report count once, partial weighs 0.5, no-counts month stays null", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx, { + configuration: { value: "duration" }, + }); + const component = await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days: fullMonth(key(1), { ok: 10 }), + }); + + const base = monthStart(key(1)).getTime() + 5 * MS_PER_DAY; + const twoHours = 2 * 3_600_000; + // incident and major report describe the same 2h outage → merged once + await tx.insert(incidentTable).values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + monitorId: testMonitor.id, + startedAt: new Date(base), + createdAt: new Date(base), + resolvedAt: new Date(base + twoHours), + }); + await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: component.id, + impact: "major_outage", + from: new Date(base), + to: new Date(base + twoHours), + }); + // disjoint partial outage of 2h → weighs 1h + await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: component.id, + impact: "partial_outage", + from: new Date(base + 10 * MS_PER_DAY), + to: new Date(base + 10 * MS_PER_DAY + twoHours), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + expect(res.mode).toBe("duration"); + const row = res.rows[0]; + const totalMs = monthDays(`${key(1)}-01`).length * MS_PER_DAY; + const expected = + Math.floor(((totalMs - 3 * 3_600_000) / totalMs) * 10_000) / 100; + expect(row.months[key(1)]).toBe(expected); + // events overlap key(2) not at all and it has no counts → null anyway + expect(row.months[key(2)]).toBe(null); + // reports metric counts status reports only, not checker incidents + expect(res.summary["6"].reports).toBe(2); + }); + }); + + test("duration mode: downtime during a paused stretch doesn't zero the month", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx, { + configuration: { value: "duration" }, + }); + const component = await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + // checks on days 1-5 and 25-28 only; the monitor was paused in between + const days = fullMonth(key(1), {}); + for (const i of [0, 1, 2, 3, 4, 24, 25, 26, 27]) { + days[i] = { day: days[i].day, ok: 10, degraded: 0, error: 0 }; + } + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days, + }); + + // 12-day outage report entirely inside the paused gap + const start = monthStart(key(1)).getTime(); + await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: component.id, + impact: "major_outage", + from: new Date(start + 7 * MS_PER_DAY), + to: new Date(start + 19 * MS_PER_DAY), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + // downtime is clipped to checked days: the gap outage contributes 0, + // so the month is 100%, not max(0, 9d - 12d) = 0% + expect(res.rows[0].months[key(1)]).toBe(100); + }); + }); + + test("duration mode: in-progress month clamps today to elapsed time", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx, { + configuration: { value: "duration" }, + }); + await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + // pretend it's noon on the 2nd of the current month, checks on both days + const start = monthStart(key(0)).getTime(); + const injectedNow = new Date(start + MS_PER_DAY + 12 * 3_600_000); + const pipes = makePipes([ + { + monitorId: String(testMonitor.id), + day: `${key(0)}-01`, + ok: 10, + degraded: 0, + error: 0, + }, + { + monitorId: String(testMonitor.id), + day: `${key(0)}-02`, + ok: 10, + degraded: 0, + error: 0, + }, + ]); + const twoHours = 2 * 3_600_000; + await tx.insert(incidentTable).values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + monitorId: testMonitor.id, + startedAt: new Date(start + twoHours), + createdAt: new Date(start + twoHours), + resolvedAt: new Date(start + 2 * twoHours), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes, + now: injectedNow, + sleep: noSleep, + }); + + // denominator = elapsed 36h (not 48h): 2h down → ~94.44, not 95.83 + const lastDayEnd = Date.parse(`${key(0)}-02T23:59:59.999Z`); + const total = 2 * MS_PER_DAY - (lastDayEnd - injectedNow.getTime()); + const expected = Math.floor(((total - twoHours) / total) * 10_000) / 100; + expect(res.rows[0].months[key(0)]).toBe(expected); + expect(expected).toBeLessThan(95); + }); + }); + + test("duration mode: sparse month uses days-with-checks as denominator", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testMonitor = await insertMonitor(tx); + const testPage = await insertPage(tx, { + configuration: { value: "duration" }, + }); + const component = await insertComponent(tx, { + pageId: testPage.id, + monitorId: testMonitor.id, + }); + + // checks on only the first 10 days of the month + const days = fullMonth(key(1), {}); + for (let i = 0; i < 10; i++) { + days[i] = { day: days[i].day, ok: 10, degraded: 0, error: 0 }; + } + await insertFrozen(tx, { + monitorId: testMonitor.id, + month: `${key(1)}-01`, + days, + }); + + const from = new Date(monthStart(key(1)).getTime() + 2 * MS_PER_DAY); + await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: component.id, + impact: "major_outage", + from, + to: new Date(from.getTime() + MS_PER_DAY), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + // 1 day down of 10 days with checks = 90.00 — a full-month denominator + // would dilute it to ~96.7 + expect(res.rows[0].months[key(1)]).toBe(90); + }); + }); + + test("static component: event-derived, months before creation are null", async () => { + await withTestTransaction(async (tx) => { + const ctx = { ...userCtx, db: tx }; + const testPage = await insertPage(tx); + const createdAt = monthStart(key(1)); + const component = await insertComponent(tx, { + pageId: testPage.id, + createdAt, + }); + + const from = new Date(createdAt.getTime() + 2 * MS_PER_DAY); + const sixHours = 6 * 3_600_000; + await insertImpactReport(tx, { + pageId: testPage.id, + pageComponentId: component.id, + impact: "major_outage", + from, + to: new Date(from.getTime() + sixHours), + }); + + const res = await getUptimeHistory({ + ctx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }); + + const row = res.rows[0]; + expect(row.component.type).toBe("static"); + expect(row.months[key(2)]).toBe(null); + const totalMs = monthEnd(key(1)).getTime() - monthStart(key(1)).getTime(); + const expected = + Math.floor(((totalMs - sixHours) / totalMs) * 10_000) / 100; + expect(row.months[key(1)]).toBe(expected); + // current month: no events → clean so far + expect(row.months[key(0)]).toBe(100); + }); + }); + + test("throws ForbiddenError when plan disables uptime-history", async () => { + await withTestTransaction(async (tx) => { + // Free plan: limits["uptime-history"] === false. Guard fires before + // any page lookup, so a fake id is fine. + await expect( + getUptimeHistory({ + ctx: { ...freeCtx, db: tx }, + input: { pageId: 999_999 }, + pipes: makePipes([]), + now, + sleep: noSleep, + }), + ).rejects.toBeInstanceOf(ForbiddenError); + }); + }); + + test("workspace scoping: another workspace's page is NotFound", async () => { + await withTestTransaction(async (tx) => { + const testPage = await insertPage(tx); + // enable the limit so the scoping check (not the plan gate) is what fires + const otherCtx = { + ...freeCtx, + workspace: { + ...freeCtx.workspace, + limits: { ...freeCtx.workspace.limits, "uptime-history": true }, + }, + db: tx, + }; + await expect( + getUptimeHistory({ + ctx: otherCtx, + input: { pageId: testPage.id }, + pipes: makePipes([]), + now, + sleep: noSleep, + }), + ).rejects.toThrow(NotFoundError); + }); + }); +}); diff --git a/packages/services/src/frozen-uptime/__tests__/run.test.ts b/packages/services/src/frozen-uptime/__tests__/run.test.ts new file mode 100644 index 00000000..a973fb1d --- /dev/null +++ b/packages/services/src/frozen-uptime/__tests__/run.test.ts @@ -0,0 +1,483 @@ +import { eq } from "@openstatus/db"; +import { frozenMonitorUptime, monitor } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; +import { withTestTransaction } from "../../../test/helpers"; +import type { ComputeCountRow } from "../compute"; +import { + type ChunkFailure, + type UptimeFreezePipes, + fetchFreezeCounts, + runUptimeFreeze, +} from "../run"; + +const noSleep = () => Promise.resolve(); + +function okPipe(rows: ComputeCountRow[] = []) { + const calls: string[][] = []; + const pipe = (params: { monitorIds: string[] }) => { + calls.push(params.monitorIds); + return Promise.resolve({ data: rows }); + }; + return { pipe, calls }; +} + +function makePipes( + overrides: Partial = {}, +): UptimeFreezePipes { + const fallback = okPipe().pipe; + return { + http: overrides.http ?? fallback, + tcp: overrides.tcp ?? fallback, + dns: overrides.dns ?? fallback, + }; +} + +type Tx = Parameters[0]>[0]; + +function insertTestMonitor( + tx: Tx, + overrides: Partial = {}, +) { + return tx + .insert(monitor) + .values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + active: true, + url: "https://example.com", + name: "svc-uptime-freeze-monitor", + method: "GET", + periodicity: "10m", + regions: "ams", + jobType: "http", + ...overrides, + }) + .returning() + .get(); +} + +describe("fetchFreezeCounts", () => { + test("chunks ids and concatenates rows", async () => { + const row = (id: string): ComputeCountRow => ({ + monitorId: id, + day: "2026-06-01", + ok: 1, + degraded: 0, + error: 0, + }); + const calls: string[][] = []; + const http = (params: { monitorIds: string[] }) => { + calls.push(params.monitorIds); + return Promise.resolve({ data: params.monitorIds.map(row) }); + }; + const ids = Array.from({ length: 250 }, (_, i) => String(i + 1)); + + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType: new Map([["http", new Set(ids)]]), + pipes: makePipes({ http }), + chunkSize: 100, + sleep: noSleep, + }); + + expect(calls.map((c) => c.length)).toEqual([100, 100, 50]); + expect(counts.length).toBe(250); + expect(failedMonitorIds.size).toBe(0); + }); + + test("throttles between chunks, not before the first", async () => { + const delays: number[] = []; + const http = okPipe(); + const ids = Array.from({ length: 30 }, (_, i) => String(i + 1)); + + await fetchFreezeCounts({ + monitorIdsByJobType: new Map([["http", new Set(ids)]]), + pipes: makePipes({ http: http.pipe }), + chunkSize: 10, + throttleMs: 100, + sleep: (ms) => { + delays.push(ms); + return Promise.resolve(); + }, + }); + + expect(http.calls.length).toBe(3); + expect(delays).toEqual([100, 100]); + }); + + test("retries with backoff, then succeeds without marking failures", async () => { + let attempts = 0; + const delays: number[] = []; + const flaky = () => { + attempts++; + if (attempts < 3) return Promise.reject(new Error("tb 500")); + return Promise.resolve({ + data: [ + { monitorId: "1", day: "2026-06-01", ok: 5, degraded: 0, error: 0 }, + ], + }); + }; + + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType: new Map([["tcp", new Set(["1"])]]), + pipes: makePipes({ tcp: flaky }), + sleep: (ms) => { + delays.push(ms); + return Promise.resolve(); + }, + }); + + expect(attempts).toBe(3); + expect(delays).toEqual([1_000, 2_000]); + expect(counts.length).toBe(1); + expect(failedMonitorIds.size).toBe(0); + }); + + test("exhausted retries mark every id in the chunk failed, never zero-count rows", async () => { + const failures: ChunkFailure[] = []; + const dead = () => Promise.reject(new Error("tb down")); + + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType: new Map([["http", new Set(["1", "2"])]]), + pipes: makePipes({ http: dead }), + attempts: 3, + sleep: noSleep, + onChunkFailure: (f) => failures.push(f), + }); + + expect(counts).toEqual([]); + expect([...failedMonitorIds].sort()).toEqual(["1", "2"]); + expect(failures.length).toBe(1); + expect(failures[0].jobType).toBe("http"); + expect((failures[0].error as Error).message).toBe("tb down"); + }); + + test("job types without a status pipe are skipped, not failed", async () => { + const http = okPipe(); + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType: new Map([ + ["icmp", new Set(["9"])], + ["ssl", new Set(["10"])], + ]), + pipes: makePipes({ http: http.pipe }), + sleep: noSleep, + }); + + expect(http.calls.length).toBe(0); + expect(counts).toEqual([]); + expect(failedMonitorIds.size).toBe(0); + }); + + test("one job type failing does not block the others", async () => { + const dead = () => Promise.reject(new Error("tb down")); + const dns = okPipe([ + { monitorId: "2", day: "2026-06-01", ok: 3, degraded: 0, error: 0 }, + ]); + + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType: new Map([ + ["http", new Set(["1"])], + ["dns", new Set(["2"])], + ]), + pipes: makePipes({ http: dead, dns: dns.pipe }), + sleep: noSleep, + onChunkFailure: () => undefined, + }); + + expect(failedMonitorIds.has("1")).toBe(true); + expect(counts.map((c) => c.monitorId)).toEqual(["2"]); + }); +}); + +// requires the frozen_monitor_uptime migration (like freeze.test.ts) +describe("runUptimeFreeze", () => { + test("freezes previous month; re-run skips frozen monitors without refetching TB", async () => { + await withTestTransaction(async (tx) => { + const testMonitor = await insertTestMonitor(tx); + + const http = okPipe([ + { + monitorId: String(testMonitor.id), + day: "2026-06-05T00:00:00.000Z", + ok: 42, + degraded: 0, + error: 0, + }, + ]); + const runArgs = { + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [testMonitor.id], + sleep: noSleep, + }; + + const first = await runUptimeFreeze(runArgs); + expect(first.month).toBe("2026-06-01"); + expect(first.frozen).toBe(1); + expect(first.alreadyFrozen).toBe(0); + expect(first.failures).toEqual([]); + expect(http.calls).toEqual([[String(testMonitor.id)]]); + + const rows = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, testMonitor.id)) + .all(); + expect(rows.length).toBe(1); + expect(rows[0].workspaceId).toBe(SEEDED_WORKSPACE_TEAM_ID); + expect(rows[0].days.length).toBe(30); + expect(rows[0].days[4].ok).toBe(42); + expect(rows[0].days[0].ok).toBe(0); + + // re-run: frozen monitors are pre-skipped — no TB refetch, no insert + const second = await runUptimeFreeze(runArgs); + expect(second.frozen).toBe(0); + expect(second.alreadyFrozen).toBe(1); + expect(http.calls.length).toBe(1); + }); + }); + + test("monitor without counts in the month gets no row — silent, not a failure", async () => { + await withTestTransaction(async (tx) => { + const paused = await insertTestMonitor(tx, { active: false }); + + const res = await runUptimeFreeze({ + pipes: makePipes(), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [paused.id], + sleep: noSleep, + }); + + expect(res.frozen).toBe(0); + expect(res.skipped).toBe(0); + expect(res.failures).toEqual([]); + + const rows = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, paused.id)) + .all(); + expect(rows).toEqual([]); + }); + }); + + test("deleted monitors are excluded before any TB fetch", async () => { + await withTestTransaction(async (tx) => { + const deleted = await insertTestMonitor(tx, { deletedAt: new Date() }); + const http = okPipe(); + + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [deleted.id], + sleep: noSleep, + }); + + expect(res.frozen).toBe(0); + expect(res.alreadyFrozen).toBe(0); + expect(http.calls.length).toBe(0); + }); + }); + + test("refuses to freeze once the month is past the 45d Tinybird window", async () => { + await withTestTransaction(async (tx) => { + const testMonitor = await insertTestMonitor(tx); + const http = okPipe(); + + // freezing July on Aug 20: July 1 is 50 days back, beyond the pipes' + // 45d lookback — writing would freeze permanent zero-count days + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 7, 20)), + db: tx, + monitorIds: [testMonitor.id], + sleep: noSleep, + }); + + expect(http.calls.length).toBe(0); + expect(res.month).toBe("2026-07-01"); + expect(res.frozen).toBe(0); + expect(res.failures.length).toBe(1); + expect(res.failures[0]).toContain("45d"); + + const rows = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, testMonitor.id)) + .all(); + expect(rows).toEqual([]); + }); + }); + + test("still freezes at the end of the retry runway (day 15)", async () => { + await withTestTransaction(async (tx) => { + const testMonitor = await insertTestMonitor(tx); + const http = okPipe([ + { + monitorId: String(testMonitor.id), + day: "2026-06-05T00:00:00.000Z", + ok: 42, + degraded: 0, + error: 0, + }, + ]); + + // July 15 is 44 days after June 1 — inside the window + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 15)), + db: tx, + monitorIds: [testMonitor.id], + sleep: noSleep, + }); + + expect(res.month).toBe("2026-06-01"); + expect(res.frozen).toBe(1); + expect(res.failures).toEqual([]); + }); + }); + + test("inactive monitor untouched since before the month is skipped without a TB fetch", async () => { + await withTestTransaction(async (tx) => { + // paused in May, freezing June: provably inactive the whole month + const paused = await insertTestMonitor(tx, { + active: false, + updatedAt: new Date(Date.UTC(2026, 4, 15)), + }); + const http = okPipe(); + + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [paused.id], + sleep: noSleep, + }); + + expect(http.calls.length).toBe(0); + expect(res.frozen).toBe(0); + expect(res.failures).toEqual([]); + + const rows = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, paused.id)) + .all(); + expect(rows).toEqual([]); + }); + }); + + test("inactive monitor paused mid-month is checked and its partial counts frozen", async () => { + await withTestTransaction(async (tx) => { + // active until June 20, then paused: June 1-19 has real counts + const paused = await insertTestMonitor(tx, { + active: false, + updatedAt: new Date(Date.UTC(2026, 5, 20)), + }); + const http = okPipe([ + { + monitorId: String(paused.id), + day: "2026-06-05T00:00:00.000Z", + ok: 42, + degraded: 0, + error: 0, + }, + ]); + + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [paused.id], + sleep: noSleep, + }); + + expect(http.calls).toEqual([[String(paused.id)]]); + expect(res.frozen).toBe(1); + + const rows = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, paused.id)) + .all(); + expect(rows.length).toBe(1); + expect(rows[0].days[4].ok).toBe(42); + }); + }); + + test("inactive monitor paused after the month is still checked", async () => { + await withTestTransaction(async (tx) => { + // paused July 3 while freezing June: could have been active all June + const paused = await insertTestMonitor(tx, { + active: false, + updatedAt: new Date(Date.UTC(2026, 6, 3)), + }); + const http = okPipe(); + + const res = await runUptimeFreeze({ + pipes: makePipes({ http: http.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [paused.id], + sleep: noSleep, + }); + + // checked against TB; no counts came back, so nothing is frozen + expect(http.calls).toEqual([[String(paused.id)]]); + expect(res.frozen).toBe(0); + expect(res.failures).toEqual([]); + }); + }); + + test("failed TB chunk skips its monitors but freezes the rest", async () => { + await withTestTransaction(async (tx) => { + const httpMonitor = await insertTestMonitor(tx); + const dnsMonitor = await insertTestMonitor(tx, { jobType: "dns" }); + + const dead = () => Promise.reject(new Error("tb down")); + const dns = okPipe([ + { + monitorId: String(dnsMonitor.id), + day: "2026-06-05T00:00:00.000Z", + ok: 7, + degraded: 0, + error: 0, + }, + ]); + + const res = await runUptimeFreeze({ + pipes: makePipes({ http: dead, dns: dns.pipe }), + now: new Date(Date.UTC(2026, 6, 10)), + db: tx, + monitorIds: [httpMonitor.id, dnsMonitor.id], + sleep: noSleep, + onChunkFailure: () => undefined, + }); + + expect(res.frozen).toBe(1); + expect(res.skipped).toBe(1); + expect(res.failures).toEqual([ + `monitor ${httpMonitor.id}: tinybird counts unavailable`, + ]); + + const frozenHttp = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, httpMonitor.id)) + .all(); + expect(frozenHttp).toEqual([]); + + const frozenDns = await tx + .select() + .from(frozenMonitorUptime) + .where(eq(frozenMonitorUptime.monitorId, dnsMonitor.id)) + .all(); + expect(frozenDns.length).toBe(1); + expect(frozenDns[0].days[4].ok).toBe(7); + }); + }); +}); diff --git a/packages/services/src/frozen-uptime/__tests__/schemas.test.ts b/packages/services/src/frozen-uptime/__tests__/schemas.test.ts new file mode 100644 index 00000000..1250673d --- /dev/null +++ b/packages/services/src/frozen-uptime/__tests__/schemas.test.ts @@ -0,0 +1,46 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { FreezeMonitorMonthInput } from "../schemas"; + +const valid: FreezeMonitorMonthInput = { + monitorId: 1, + month: "2026-06-01", + days: [{ day: "2026-06-01", ok: 10, degraded: 1, error: 0 }], +}; + +describe("FreezeMonitorMonthInput", () => { + test("accepts a valid row", () => { + expect(FreezeMonitorMonthInput.parse(valid)).toEqual(valid); + }); + + test("rejects a month that is not first-of-month", () => { + expect(() => + FreezeMonitorMonthInput.parse({ ...valid, month: "2026-06-15" }), + ).toThrow(); + expect(() => + FreezeMonitorMonthInput.parse({ ...valid, month: "2026-06" }), + ).toThrow(); + }); + + test("rejects malformed days", () => { + expect(() => + FreezeMonitorMonthInput.parse({ + ...valid, + days: [{ day: "2026-06-01", ok: 0 }], + }), + ).toThrow(); + expect(() => + FreezeMonitorMonthInput.parse({ + ...valid, + days: [{ day: "2026-06-01T00:00:00Z", ok: 0, degraded: 0, error: 0 }], + }), + ).toThrow(); + expect(() => + FreezeMonitorMonthInput.parse({ + ...valid, + days: [{ day: "2026-06-01", ok: -1, degraded: 0, error: 0 }], + }), + ).toThrow(); + }); +}); diff --git a/packages/services/src/frozen-uptime/compute.ts b/packages/services/src/frozen-uptime/compute.ts new file mode 100644 index 00000000..4d74a35b --- /dev/null +++ b/packages/services/src/frozen-uptime/compute.ts @@ -0,0 +1,79 @@ +import type { FrozenMonitorUptimeDay } from "@openstatus/db/src/schema"; + +export type ComputeCountRow = { + monitorId: string; + day: string; // ISO or YYYY-MM-DD; sliced to YYYY-MM-DD here + ok: number; + degraded: number; + error: number; +}; + +// UTC first-of-month of the month before `now`, YYYY-MM-01 +export function previousMonth(now: Date): string { + const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1)); + const mm = String(d.getUTCMonth() + 1).padStart(2, "0"); + return `${d.getUTCFullYear()}-${mm}-01`; +} + +// [start of month, start of next month) in UTC ms +export function monthRange(month: string): { start: number; end: number } { + const [year, mo] = month.split("-").map(Number); + return { + start: Date.UTC(year, mo - 1, 1), + end: Date.UTC(year, mo, 1), + }; +} + +export function monthDays(month: string): string[] { + const [year, mo] = month.split("-").map(Number); + const count = new Date(Date.UTC(year, mo, 0)).getUTCDate(); + const prefix = month.slice(0, 8); // YYYY-MM- + return Array.from( + { length: count }, + (_, i) => `${prefix}${String(i + 1).padStart(2, "0")}`, + ); +} + +/** + * Pure assembly of one monitor's frozen month from already-fetched count + * rows — no I/O. Returns null when the monitor has no counts in the month + * (paused, or created later): no row is frozen rather than an all-zero month. + */ +export function computeMonitorMonth(args: { + month: string; // YYYY-MM-01 + monitorId: number; + counts: ComputeCountRow[]; +}): { days: FrozenMonitorUptimeDay[] } | null { + const { month, monitorId, counts } = args; + const prefix = month.slice(0, 8); // YYYY-MM- + + // sum rather than overwrite: the pipe aggregates per day today, but a + // silent overwrite here would freeze truncated counts permanently + const byDay = new Map< + string, + { ok: number; degraded: number; error: number } + >(); + for (const row of counts) { + if (row.monitorId !== String(monitorId)) continue; + const day = row.day.slice(0, 10); + if (!day.startsWith(prefix)) continue; + const acc = byDay.get(day) ?? { ok: 0, degraded: 0, error: 0 }; + acc.ok += row.ok; + acc.degraded += row.degraded; + acc.error += row.error; + byDay.set(day, acc); + } + if (byDay.size === 0) return null; + + const days = monthDays(month).map((day) => { + const row = byDay.get(day); + return { + day, + ok: row?.ok ?? 0, + degraded: row?.degraded ?? 0, + error: row?.error ?? 0, + }; + }); + + return { days }; +} diff --git a/packages/services/src/frozen-uptime/freeze.ts b/packages/services/src/frozen-uptime/freeze.ts new file mode 100644 index 00000000..56a55391 --- /dev/null +++ b/packages/services/src/frozen-uptime/freeze.ts @@ -0,0 +1,48 @@ +import { db as defaultDb } from "@openstatus/db"; +import { + type FrozenMonitorUptime, + frozenMonitorUptime, + selectFrozenMonitorUptimeSchema, +} from "@openstatus/db/src/schema"; + +import { requireScope } from "../auth"; +import type { ServiceContext } from "../context"; +import { getMonitorInWorkspace } from "../monitor/internal"; +import { withBusyRetry } from "../retry"; +import { FreezeMonitorMonthInput } from "./schemas"; + +/** + * Write-once freeze of one (monitor, month). Returns the inserted row, or + * null when the month was already frozen (silent re-run). Deliberately no + * audit row — system cron on a write-once table would be pure volume. + */ +export async function freezeMonitorMonth(args: { + ctx: ServiceContext; + input: FreezeMonitorMonthInput; +}): Promise { + const { ctx } = args; + requireScope(ctx, "write"); + const input = FreezeMonitorMonthInput.parse(args.input); + + const db = ctx.db ?? defaultDb; + const owner = await withBusyRetry(() => + getMonitorInWorkspace({ + tx: db, + id: input.monitorId, + workspaceId: ctx.workspace.id, + }), + ); + // attribute the row to the monitor's own workspace, not the caller's claim; + // the scoped fetch above pins them equal (and non-null) + const rows = await withBusyRetry(() => + db + .insert(frozenMonitorUptime) + .values({ ...input, workspaceId: owner.workspaceId ?? ctx.workspace.id }) + .onConflictDoNothing({ + target: [frozenMonitorUptime.monitorId, frozenMonitorUptime.month], + }) + .returning(), + ); + const row = rows[0]; + return row ? selectFrozenMonitorUptimeSchema.parse(row) : null; +} diff --git a/packages/services/src/frozen-uptime/get-history.ts b/packages/services/src/frozen-uptime/get-history.ts new file mode 100644 index 00000000..7411edf2 --- /dev/null +++ b/packages/services/src/frozen-uptime/get-history.ts @@ -0,0 +1,403 @@ +import { and, eq, gte, inArray } from "@openstatus/db"; +import { + frozenMonitorUptime, + pageConfigurationSchema, +} from "@openstatus/db/src/schema"; + +import { type ServiceContext, defaultTb, getReadDb } from "../context"; +import { ForbiddenError, NotFoundError } from "../errors"; +import { + type Event, + dayCoverage, + durationDowntimeMs, + floorPct, + getEvents, + reportsOnlyDowntimeMs, + requestsTally, +} from "../status-timeline"; +import { type ComputeCountRow, monthRange } from "./compute"; +import { type UptimeFreezePipes, fetchFreezeCounts } from "./run"; +import { GetUptimeHistoryInput } from "./schemas"; + +const HISTORY_MONTHS = 24; + +const WINDOWS = [6, 12, 24] as const; +type HistoryWindowKey = "6" | "12" | "24"; + +// safe because HistoryWindowKey is exactly the string form of each WINDOWS entry +function windowKey(w: (typeof WINDOWS)[number]): HistoryWindowKey { + return String(w) as HistoryWindowKey; +} + +type DayCount = { day: string; ok: number; degraded: number; error: number }; + +// native-unit numerators kept alongside the percentage so rolling windows +// stay additive (checks for requests mode, milliseconds for event math); +// averaging monthly percentages would weigh a 2-day month like a full one +type MonthValue = { percentage: number; up: number; total: number } | null; + +type UptimeHistoryEvent = Pick< + Event, + "id" | "name" | "type" | "status" | "from" | "to" +>; + +type UptimeHistoryRow = { + component: { + id: number; + name: string; + type: "monitor" | "static"; + /** for event links, null for static components */ + monitorId: number | null; + }; + /** "YYYY-MM" → percentage; null = no data recorded, NEVER "down" */ + months: Record; + rolling: Record; + /** component events in the window; clients bucket per month by overlap */ + events: UptimeHistoryEvent[]; +}; + +type UptimeHistoryResult = { + mode: "requests" | "duration" | "manual"; + /** oldest → newest, length HISTORY_MONTHS, last entry = current month */ + months: string[]; + createdAt: Date | null; + summary: Record; + rows: UptimeHistoryRow[]; +}; + +function monthKeys(now: Date): string[] { + return Array.from({ length: HISTORY_MONTHS }, (_, i) => { + const d = new Date( + Date.UTC( + now.getUTCFullYear(), + now.getUTCMonth() - (HISTORY_MONTHS - 1 - i), + 1, + ), + ); + const mm = String(d.getUTCMonth() + 1).padStart(2, "0"); + return `${d.getUTCFullYear()}-${mm}`; + }); +} + +function requestsMonth(days: DayCount[] | null): MonthValue { + if (!days) return null; + const { up, total } = requestsTally(days); + if (total === 0) return null; + return { percentage: floorPct(up / total), up, total }; +} + +function durationMonth( + days: DayCount[] | null, + events: Event[], + nowMs: number, +): MonthValue { + // denominator = days with checks, matching getUptime's data.length; frozen + // months are zero-filled so counting all days would inflate sparse months + const withChecks = (days ?? []).filter( + (d) => d.ok + d.degraded + d.error > 0, + ); + if (withChecks.length === 0) return null; + // downtime is clipped to the checked days (a paused stretch can't exceed + // the denominator) and the in-progress day is clamped to elapsed time so + // 2h down on the 2nd isn't diluted by the rest of today + const dayStarts = withChecks.map((d) => Date.parse(`${d.day}T00:00:00.000Z`)); + const { segments, totalMs } = dayCoverage(dayStarts, nowMs); + if (segments.length === 0 || totalMs <= 0) return null; + const window = { + start: segments[0].start, + end: segments[segments.length - 1].end, + now: nowMs, + }; + const downtime = durationDowntimeMs(events, window, segments); + const up = Math.max(0, totalMs - downtime); + return { percentage: floorPct(up / totalMs), up, total: totalMs }; +} + +function eventOnlyMonth( + events: Event[], + key: string, + nowMs: number, + notBeforeMs?: number, +): MonthValue { + const { start, end } = monthRange(`${key}-01`); + // months fully before the component existed are "no data", not fake 100% + if (notBeforeMs !== undefined && end <= notBeforeMs) return null; + const clampedEnd = Math.min(end, nowMs); + if (clampedEnd <= start) return null; + const total = clampedEnd - start; + const downtime = reportsOnlyDowntimeMs(events, { + start, + end: clampedEnd, + now: nowMs, + }); + const up = Math.max(0, total - downtime); + return { percentage: floorPct(up / total), up, total }; +} + +/** + * Read-time uptime history for a page: frozen monthly counts + live Tinybird + * for months the freeze hasn't covered, percentages recomputed under the + * page's current calculation mode. + */ +export async function getUptimeHistory(args: { + ctx: ServiceContext; + input: GetUptimeHistoryInput; + pipes?: UptimeFreezePipes; + now?: Date; + sleep?: (ms: number) => Promise; +}): Promise { + const { ctx } = args; + const input = GetUptimeHistoryInput.parse(args.input); + if (!ctx.workspace.limits["uptime-history"]) { + throw new ForbiddenError("Uptime history is not enabled on this plan."); + } + const db = getReadDb(ctx); + const now = args.now ?? new Date(); + const nowMs = now.getTime(); + + const _page = await db.query.page.findFirst({ + where: (page, { and: andWhere, eq: eqWhere }) => + andWhere( + eqWhere(page.id, input.pageId), + eqWhere(page.workspaceId, ctx.workspace.id), + ), + with: { + statusReports: { + with: { + statusReportUpdates: { + orderBy: (updates, { desc }) => desc(updates.date), + with: { statusReportUpdateToPageComponents: true }, + }, + statusReportsToPageComponents: { with: { pageComponent: true } }, + }, + }, + maintenances: { + with: { + maintenancesToPageComponents: { with: { pageComponent: true } }, + }, + }, + pageComponents: { + with: { monitor: { with: { incidents: true } } }, + orderBy: (components, { asc }) => asc(components.order), + }, + }, + }); + if (!_page) throw new NotFoundError("page", input.pageId); + + const configuration = pageConfigurationSchema.safeParse( + _page.configuration ?? {}, + ); + const mode = configuration.success ? configuration.data.value : "requests"; + + const months = monthKeys(now); + const currentKey = months[months.length - 1]; + const previousKey = months[months.length - 2]; + + const components = _page.pageComponents; + const monitorIds = [ + ...new Set( + components.flatMap((c) => (c.monitorId !== null ? [c.monitorId] : [])), + ), + ]; + + // the frozen-rows read and the independent Tinybird round-trip overlap + const dbReads = (async () => { + if (monitorIds.length === 0) return { frozenRows: [] }; + const frozenRows = await db + .select({ + monitorId: frozenMonitorUptime.monitorId, + month: frozenMonitorUptime.month, + days: frozenMonitorUptime.days, + }) + .from(frozenMonitorUptime) + .where( + and( + eq(frozenMonitorUptime.workspaceId, ctx.workspace.id), + inArray(frozenMonitorUptime.monitorId, monitorIds), + gte(frozenMonitorUptime.month, `${months[0]}-01`), + ), + ); + return { frozenRows }; + })(); + + // current month is never frozen, the previous may not be yet (freeze runs + // on the 10th) — both come live from the 45d pipes; fetchFreezeCounts never + // throws, failed monitors land in failedMonitorIds and render as no-data + const liveReads = (async () => { + if (monitorIds.length === 0) { + return { + counts: [] as ComputeCountRow[], + failedMonitorIds: new Set(), + }; + } + const monitorIdsByJobType = new Map>(); + for (const c of components) { + if (c.monitorId === null || !c.monitor) continue; + const ids = monitorIdsByJobType.get(c.monitor.jobType) ?? new Set(); + ids.add(String(c.monitorId)); + monitorIdsByJobType.set(c.monitor.jobType, ids); + } + const pipes = args.pipes ?? { + http: defaultTb.httpStatus45d, + tcp: defaultTb.tcpStatus45d, + dns: defaultTb.dnsStatus45d, + }; + return fetchFreezeCounts({ + monitorIdsByJobType, + pipes, + throttleMs: 0, + sleep: args.sleep, + }); + })(); + + const [{ frozenRows }, { counts: liveCounts, failedMonitorIds: liveFailed }] = + await Promise.all([dbReads, liveReads]); + const frozenByKey = new Map( + frozenRows.map((r) => [`${r.monitorId}:${r.month.slice(0, 7)}`, r.days]), + ); + + const liveByMonitorMonth = new Map>(); + for (const row of liveCounts) { + const day = row.day.slice(0, 10); + const key = day.slice(0, 7); + if (key !== currentKey && key !== previousKey) continue; + const mapKey = `${row.monitorId}:${key}`; + const byDay = liveByMonitorMonth.get(mapKey) ?? new Map(); + const acc = byDay.get(day) ?? { day, ok: 0, degraded: 0, error: 0 }; + acc.ok += row.ok; + acc.degraded += row.degraded; + acc.error += row.error; + byDay.set(day, acc); + liveByMonitorMonth.set(mapKey, byDay); + } + + function countsFor(monitorId: number, key: string): DayCount[] | null { + const frozen = frozenByKey.get(`${monitorId}:${key}`); + if (frozen && key !== currentKey) return frozen; + // older unfrozen months are never reconstructed from the partial 45d + // overlap — backfill is the fix, not partial months + const isLive = key === currentKey || key === previousKey; + if (!isLive || liveFailed.has(String(monitorId))) return null; + const byDay = liveByMonitorMonth.get(`${monitorId}:${key}`); + if (!byDay || byDay.size === 0) return null; + return [...byDay.values()].sort((a, b) => (a.day < b.day ? -1 : 1)); + } + + const pastDays = HISTORY_MONTHS * 31 + 7; + const rows: UptimeHistoryRow[] = components.map((c) => { + const events = getEvents({ + maintenances: _page.maintenances, + incidents: c.monitor?.incidents ?? [], + reports: _page.statusReports, + pageComponentId: c.id, + monitorId: c.monitorId ?? undefined, + componentType: c.type, + pastDays, + }); + + const values = new Map(); + for (const key of months) { + let value: MonthValue = null; + if (c.type === "monitor" && c.monitorId !== null) { + const days = countsFor(c.monitorId, key); + if (mode === "requests") { + value = requestsMonth(days); + } else if (mode === "duration") { + value = durationMonth(days, events, nowMs); + } else { + // manual mode still keys "did the monitor run" off counts: a + // zero-check month has no meaningful uptime in any mode + value = days?.some((d) => d.ok + d.degraded + d.error > 0) + ? eventOnlyMonth(events, key, nowMs) + : null; + } + } else { + value = eventOnlyMonth( + events, + key, + nowMs, + c.createdAt?.getTime() ?? undefined, + ); + } + values.set(key, value); + } + + const rolling = {} as Record; + for (const w of WINDOWS) { + let up = 0; + let total = 0; + for (const key of months.slice(-w)) { + const v = values.get(key); + if (!v) continue; + up += v.up; + total += v.total; + } + rolling[windowKey(w)] = total > 0 ? floorPct(up / total) : null; + } + + return { + component: { + id: c.id, + name: c.name, + type: c.type === "static" ? ("static" as const) : ("monitor" as const), + monitorId: c.monitorId, + }, + months: Object.fromEntries( + months.map((k) => [k, values.get(k)?.percentage ?? null]), + ), + rolling, + events: events.map((e) => ({ + id: e.id, + name: e.name, + type: e.type, + status: e.status, + from: e.from, + to: e.to, + })), + }; + }); + + // page-level events (no component filter) for the report metric + const pageEvents = getEvents({ + maintenances: _page.maintenances, + incidents: [], + reports: _page.statusReports, + pastDays, + }); + + const summary = {} as UptimeHistoryResult["summary"]; + for (const w of WINDOWS) { + const windowStart = monthRange(`${months[months.length - w]}-01`).start; + const seen = new Set(); + for (const e of pageEvents) { + if (e.type !== "report") continue; + const endMs = e.to?.getTime() ?? nowMs; + if (e.from.getTime() <= nowMs && endMs >= windowStart) { + seen.add(e.id); + } + } + // components weigh equally — native units (checks vs ms) differ per + // component, so a cross-component sum would weight by unit volume + const wk = windowKey(w); + const uptimes = rows.flatMap((r) => + r.rolling[wk] !== null ? [r.rolling[wk] as number] : [], + ); + summary[wk] = { + uptime: + uptimes.length > 0 + ? Math.floor( + (uptimes.reduce((a, b) => a + b, 0) / uptimes.length) * 100, + ) / 100 + : null, + reports: seen.size, + }; + } + + return { + mode, + months, + createdAt: _page.createdAt, + summary, + rows, + }; +} diff --git a/packages/services/src/frozen-uptime/index.ts b/packages/services/src/frozen-uptime/index.ts new file mode 100644 index 00000000..23f17adf --- /dev/null +++ b/packages/services/src/frozen-uptime/index.ts @@ -0,0 +1,18 @@ +export { + type ComputeCountRow, + computeMonitorMonth, + monthDays, + monthRange, + previousMonth, +} from "./compute"; +export { freezeMonitorMonth } from "./freeze"; +export { getUptimeHistory } from "./get-history"; +export { + type ChunkFailure, + type RunUptimeFreezeResult, + type StatusPipeFn, + type UptimeFreezePipes, + fetchFreezeCounts, + runUptimeFreeze, +} from "./run"; +export { FreezeMonitorMonthInput } from "./schemas"; diff --git a/packages/services/src/frozen-uptime/run.ts b/packages/services/src/frozen-uptime/run.ts new file mode 100644 index 00000000..767ba790 --- /dev/null +++ b/packages/services/src/frozen-uptime/run.ts @@ -0,0 +1,277 @@ +import { and, db as defaultDb, eq, inArray, isNull } from "@openstatus/db"; +import { + frozenMonitorUptime, + monitor, + selectWorkspaceSchema, + workspace, +} from "@openstatus/db/src/schema"; + +import type { DB } from "../context"; +import { + type ComputeCountRow, + computeMonitorMonth, + monthRange, + previousMonth, +} from "./compute"; +import { freezeMonitorMonth } from "./freeze"; + +export type StatusPipeFn = (params: { + monitorIds: string[]; +}) => Promise<{ data: ComputeCountRow[] }>; + +// only these job types have a 45d status pipe; others (icmp/udp/ssl) have no +// counts on the live status page either and are skipped +export type UptimeFreezePipes = Record<"http" | "tcp" | "dns", StatusPipeFn>; + +export type ChunkFailure = { + jobType: string; + monitorIds: string[]; + error: unknown; +}; + +// zod-bird sends monitorIds as one comma-joined GET query param — unbounded +// batches risk URL-length 400s +const TB_CHUNK_SIZE = 200; +const TB_ATTEMPTS = 3; +// spacing between chunk requests: keeps the monthly sweep from bursting TB +// (zod-bird already absorbs 429/5xx with its own internal retries) +const TB_THROTTLE_MS = 250; + +// the status pipes look back a fixed 45 days; past monthStart + 45d the +// earliest month days return no rows and would freeze as permanent zeros +const FREEZE_CUTOFF_MS = 45 * 86_400_000; + +function chunk(items: T[], size: number): T[][] { + if (size <= 0) throw new Error(`chunk size must be positive, got ${size}`); + const out: T[][] = []; + for (let i = 0; i < items.length; i += size) { + out.push(items.slice(i, i + size)); + } + return out; +} + +function hasStatusPipe( + jobType: string | null | undefined, +): jobType is keyof UptimeFreezePipes { + return jobType === "http" || jobType === "tcp" || jobType === "dns"; +} + +/** + * Fetch daily counts for all monitors, chunked and retried. Monitors whose + * chunk still fails after retries land in `failedMonitorIds` — they are + * skipped (never frozen with silent zeros) and picked up by a re-run. + */ +export async function fetchFreezeCounts(args: { + monitorIdsByJobType: Map>; + pipes: UptimeFreezePipes; + chunkSize?: number; + attempts?: number; + throttleMs?: number; + sleep?: (ms: number) => Promise; + onChunkFailure?: (failure: ChunkFailure) => void; +}): Promise<{ counts: ComputeCountRow[]; failedMonitorIds: Set }> { + const chunkSize = args.chunkSize ?? TB_CHUNK_SIZE; + const attempts = args.attempts ?? TB_ATTEMPTS; + const throttleMs = args.throttleMs ?? TB_THROTTLE_MS; + const sleep = + args.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms))); + + const counts: ComputeCountRow[] = []; + const failedMonitorIds = new Set(); + let firstChunk = true; + + for (const [jobType, ids] of args.monitorIdsByJobType) { + if (!hasStatusPipe(jobType)) continue; + const pipe = args.pipes[jobType]; + for (const monitorIds of chunk([...ids], chunkSize)) { + if (!firstChunk && throttleMs > 0) await sleep(throttleMs); + firstChunk = false; + let lastError: unknown; + let done = false; + for (let attempt = 0; attempt < attempts && !done; attempt++) { + try { + if (attempt > 0) await sleep(1000 * 2 ** (attempt - 1)); + const res = await pipe({ monitorIds }); + counts.push(...res.data); + done = true; + } catch (e) { + lastError = e; + } + } + if (!done) { + for (const id of monitorIds) failedMonitorIds.add(id); + args.onChunkFailure?.({ jobType, monitorIds, error: lastError }); + } + } + } + + return { counts, failedMonitorIds }; +} + +export type RunUptimeFreezeResult = { + month: string; + frozen: number; + alreadyFrozen: number; + skipped: number; + failures: string[]; +}; + +/** + * Freeze the previous calendar month for every non-deleted monitor. + * Pipes (and optionally db/now) are injected so the cron stays a thin + * env/Sentry wrapper and this orchestration is unit-testable. + */ +export async function runUptimeFreeze(args: { + pipes: UptimeFreezePipes; + now?: Date; + db?: DB; + monitorIds?: number[]; // scope a run (tests, manual retries); default all + sleep?: (ms: number) => Promise; + onChunkFailure?: (failure: ChunkFailure) => void; +}): Promise { + const db = args.db ?? defaultDb; + const now = args.now ?? new Date(); + const month = previousMonth(now); + const monthStart = new Date(monthRange(month).start); + + // refuse instead of writing wrong zeros into the write-once table; the + // failure surfaces via the cron's reportBackgroundError + if (now.getTime() - monthStart.getTime() >= FREEZE_CUTOFF_MS) { + return { + month, + frozen: 0, + alreadyFrozen: 0, + skipped: 0, + failures: [ + `month ${month}: past the 45d Tinybird window — freezing now would write permanent zero-count days`, + ], + }; + } + + // all non-deleted monitors, regardless of page attachment — months without + // counts are dropped by computeMonitorMonth anyway + const monitorRows = await db + .select({ + id: monitor.id, + workspaceId: monitor.workspaceId, + jobType: monitor.jobType, + active: monitor.active, + updatedAt: monitor.updatedAt, + }) + .from(monitor) + .where( + and( + isNull(monitor.deletedAt), + args.monitorIds ? inArray(monitor.id, args.monitorIds) : undefined, + ), + ); + // inactive + untouched since before the month ⇒ it was inactive the whole + // month (pausing bumps updatedAt), so skip the TB fetch entirely; inactive + // but updated during/after the month may have run part of it — check TB + const monitors = monitorRows.flatMap((m) => + m.workspaceId === null || + (!m.active && m.updatedAt !== null && m.updatedAt < monthStart) + ? [] + : [{ ...m, workspaceId: m.workspaceId }], + ); + + // re-runs only work the monitors that failed last time: those with a frozen + // row for this month are excluded before any TB fetch (the insert's + // onConflictDoNothing stays as the race backstop) + const frozenRows = await db + .select({ monitorId: frozenMonitorUptime.monitorId }) + .from(frozenMonitorUptime) + .where( + args.monitorIds + ? and( + eq(frozenMonitorUptime.month, month), + inArray(frozenMonitorUptime.monitorId, args.monitorIds), + ) + : eq(frozenMonitorUptime.month, month), + ); + const frozenMonitorIds = new Set(frozenRows.map((r) => r.monitorId)); + + const pending = monitors.filter((m) => !frozenMonitorIds.has(m.id)); + let alreadyFrozen = monitors.length - pending.length; + + const monitorIdsByJobType = new Map>(); + for (const m of pending) { + const ids = monitorIdsByJobType.get(m.jobType) ?? new Set(); + ids.add(String(m.id)); + monitorIdsByJobType.set(m.jobType, ids); + } + + const { counts, failedMonitorIds } = await fetchFreezeCounts({ + monitorIdsByJobType, + pipes: args.pipes, + sleep: args.sleep, + onChunkFailure: args.onChunkFailure, + }); + + // avoid an O(pending²) sweep: computeMonitorMonth scans linearly per call + const countsByMonitorId = new Map(); + for (const row of counts) { + const rows = countsByMonitorId.get(row.monitorId); + if (rows) rows.push(row); + else countsByMonitorId.set(row.monitorId, [row]); + } + + const workspaceIds = [...new Set(pending.map((m) => m.workspaceId))]; + const workspaceRows = + workspaceIds.length > 0 + ? await db + .select() + .from(workspace) + .where(inArray(workspace.id, workspaceIds)) + : []; + const workspacesById = new Map( + workspaceRows.map((w) => [w.id, selectWorkspaceSchema.parse(w)]), + ); + + let frozen = 0; + let skipped = 0; + const failures: string[] = []; + + for (const m of pending) { + if (failedMonitorIds.has(String(m.id))) { + skipped++; + failures.push(`monitor ${m.id}: tinybird counts unavailable`); + continue; + } + + // no counts in the month (paused, created later, or no status pipe for + // the job type): nothing to freeze — silent, not a failure + const computed = computeMonitorMonth({ + month, + monitorId: m.id, + counts: countsByMonitorId.get(String(m.id)) ?? [], + }); + if (!computed) continue; + + const ws = workspacesById.get(m.workspaceId); + if (!ws) { + failures.push(`monitor ${m.id}: workspace ${m.workspaceId} not found`); + continue; + } + const ctx = { + workspace: ws, + actor: { type: "system" as const, job: "uptime-freeze" }, + db, + }; + + try { + const inserted = await freezeMonitorMonth({ + ctx, + input: { monitorId: m.id, month, days: computed.days }, + }); + if (inserted) frozen++; + else alreadyFrozen++; + } catch (e) { + failures.push( + `monitor ${m.id}: ${e instanceof Error ? e.message : String(e)}`, + ); + } + } + + return { month, frozen, alreadyFrozen, skipped, failures }; +} diff --git a/packages/services/src/frozen-uptime/schemas.ts b/packages/services/src/frozen-uptime/schemas.ts new file mode 100644 index 00000000..2700d93d --- /dev/null +++ b/packages/services/src/frozen-uptime/schemas.ts @@ -0,0 +1,15 @@ +import { insertFrozenMonitorUptimeSchema } from "@openstatus/db/src/schema"; +import { z } from "zod"; + +// workspaceId comes from ctx; id/createdAt from the db +export const FreezeMonitorMonthInput = insertFrozenMonitorUptimeSchema.omit({ + id: true, + workspaceId: true, + createdAt: true, +}); +export type FreezeMonitorMonthInput = z.infer; + +export const GetUptimeHistoryInput = z.object({ + pageId: z.number().int().positive(), +}); +export type GetUptimeHistoryInput = z.infer; diff --git a/packages/services/src/status-timeline/__tests__/downtime.test.ts b/packages/services/src/status-timeline/__tests__/downtime.test.ts new file mode 100644 index 00000000..61300a8f --- /dev/null +++ b/packages/services/src/status-timeline/__tests__/downtime.test.ts @@ -0,0 +1,41 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { type WeightedInterval, mergedDowntimeMs } from "../downtime"; + +const HOUR = 3_600_000; + +function iv(from: number, to: number, weight = 1): WeightedInterval { + return { from, to, weight }; +} + +describe("mergedDowntimeMs", () => { + test("empty input and single interval", () => { + expect(mergedDowntimeMs([])).toBe(0); + expect(mergedDowntimeMs([iv(0, 2 * HOUR)])).toBe(2 * HOUR); + expect(mergedDowntimeMs([iv(0, 2 * HOUR, 0.5)])).toBe(1 * HOUR); + }); + + test("disjoint intervals sum, identical overlaps count once", () => { + expect(mergedDowntimeMs([iv(0, HOUR), iv(2 * HOUR, 3 * HOUR)])).toBe( + 2 * HOUR, + ); + expect(mergedDowntimeMs([iv(0, 2 * HOUR), iv(0, 2 * HOUR)])).toBe(2 * HOUR); + }); + + test("partial overlap takes the max weight per slice, never the sum", () => { + // [0,2h] w=0.5 and [1h,3h] w=1 → 1h*0.5 + 2h*1 = 2.5h + expect( + mergedDowntimeMs([iv(0, 2 * HOUR, 0.5), iv(HOUR, 3 * HOUR, 1)]), + ).toBe(2.5 * HOUR); + // full containment: heavier inner interval wins only for its span + // [0,4h] w=0.5 containing [1h,2h] w=1 → 3h*0.5 + 1h*1 = 2.5h + expect( + mergedDowntimeMs([iv(0, 4 * HOUR, 0.5), iv(HOUR, 2 * HOUR, 1)]), + ).toBe(2.5 * HOUR); + }); + + test("adjacent intervals sharing a boundary don't double-count the edge", () => { + expect(mergedDowntimeMs([iv(0, HOUR), iv(HOUR, 2 * HOUR)])).toBe(2 * HOUR); + }); +}); diff --git a/packages/services/src/status-timeline/__tests__/uptime.test.ts b/packages/services/src/status-timeline/__tests__/uptime.test.ts new file mode 100644 index 00000000..3f4c9d94 --- /dev/null +++ b/packages/services/src/status-timeline/__tests__/uptime.test.ts @@ -0,0 +1,197 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import type { Event } from "../events"; +import { + type UptimeWindow, + durationDowntimeMs, + floorPct, + reportsOnlyDowntimeMs, + requestsTally, +} from "../uptime"; + +const HOUR = 3_600_000; +const DAY = 24 * HOUR; + +const base = Date.UTC(2026, 5, 10); +const window: UptimeWindow = { + start: base, + end: base + 10 * DAY, + now: base + 10 * DAY, +}; + +function incident(fromMs: number, toMs: number | null): Event { + return { + id: 1, + name: "incident", + from: new Date(fromMs), + to: toMs === null ? null : new Date(toMs), + type: "incident", + status: "error", + }; +} + +function impactReport( + fromMs: number, + toMs: number, + impact: "major_outage" | "partial_outage" | "degraded_performance", +): Event { + return { + id: 2, + name: "report", + from: new Date(fromMs), + to: new Date(toMs), + type: "report", + status: "error", + impactIntervals: [{ from: new Date(fromMs), to: new Date(toMs), impact }], + }; +} + +function legacyReport(fromMs: number, toMs: number): Event { + return { + id: 3, + name: "legacy", + from: new Date(fromMs), + to: new Date(toMs), + type: "report", + status: "degraded", + }; +} + +describe("floorPct", () => { + test("floors instead of rounding — one failed check never shows 100.00", () => { + expect(floorPct(99_999 / 100_000)).toBe(99.99); + expect(floorPct(1)).toBe(100); + expect(floorPct(0)).toBe(0); + }); +}); + +describe("requestsTally", () => { + test("degraded counts as up, error does not", () => { + expect( + requestsTally([ + { ok: 90, degraded: 5, error: 5 }, + { ok: 100, degraded: 0, error: 0 }, + ]), + ).toEqual({ up: 195, total: 200 }); + }); + + test("empty input is a zero tally", () => { + expect(requestsTally([])).toEqual({ up: 0, total: 0 }); + }); +}); + +describe("durationDowntimeMs", () => { + test("incident counts at full weight", () => { + expect(durationDowntimeMs([incident(base, base + 2 * HOUR)], window)).toBe( + 2 * HOUR, + ); + }); + + test("incident + major report describing the same outage count once", () => { + const events = [ + incident(base, base + 2 * HOUR), + impactReport(base, base + 2 * HOUR, "major_outage"), + ]; + expect(durationDowntimeMs(events, window)).toBe(2 * HOUR); + }); + + test("partial outage weighs 0.5; overlapping major wins per slice", () => { + expect( + durationDowntimeMs( + [impactReport(base, base + 2 * HOUR, "partial_outage")], + window, + ), + ).toBe(1 * HOUR); + // overlapping partial must not add on top of major (max, not sum) + expect( + durationDowntimeMs( + [ + impactReport(base, base + 2 * HOUR, "major_outage"), + impactReport(base, base + 2 * HOUR, "partial_outage"), + ], + window, + ), + ).toBe(2 * HOUR); + }); + + test("degraded_performance weighs 0 and legacy reports are ignored", () => { + expect( + durationDowntimeMs( + [ + impactReport(base, base + 2 * HOUR, "degraded_performance"), + legacyReport(base, base + 2 * HOUR), + ], + window, + ), + ).toBe(0); + }); + + test("coverage clips downtime inside check gaps", () => { + const coverage = [ + { start: base, end: base + 2 * DAY }, + { start: base + 8 * DAY, end: base + 10 * DAY }, + ]; + // outage entirely inside the uncovered gap (paused monitor) → no downtime + expect( + durationDowntimeMs( + [incident(base + 3 * DAY, base + 7 * DAY)], + window, + coverage, + ), + ).toBe(0); + // outage spanning covered and uncovered time counts only the covered part + expect( + durationDowntimeMs( + [incident(base + DAY, base + 9 * DAY)], + window, + coverage, + ), + ).toBe(2 * DAY); + }); + + test("events are clamped to the window; open events close at now", () => { + // straddles the window start: only the inside part counts + expect( + durationDowntimeMs([incident(base - DAY, base + HOUR)], window), + ).toBe(1 * HOUR); + // still-open incident: closed at `now` + expect(durationDowntimeMs([incident(base + 9 * DAY, null)], window)).toBe( + 1 * DAY, + ); + // fully outside the window: nothing + expect( + durationDowntimeMs([incident(base - 2 * DAY, base - DAY)], window), + ).toBe(0); + }); +}); + +describe("reportsOnlyDowntimeMs", () => { + test("empty impactIntervals falls through to the legacy path, not zero downtime", () => { + // getEvents emits [] for a report member the updates never impacted + const report: Event = { + ...legacyReport(base, base + 2 * HOUR), + impactIntervals: [], + }; + expect(reportsOnlyDowntimeMs([report], window)).toBe(2 * HOUR); + // duration math keeps ignoring legacy-shaped reports + expect(durationDowntimeMs([report], window)).toBe(0); + }); + + test("incidents are ignored, legacy reports count full duration", () => { + const events = [ + incident(base, base + 5 * HOUR), + legacyReport(base + 6 * HOUR, base + 8 * HOUR), + ]; + expect(reportsOnlyDowntimeMs(events, window)).toBe(2 * HOUR); + }); + + test("impact reports stay weighted", () => { + expect( + reportsOnlyDowntimeMs( + [impactReport(base, base + 4 * HOUR, "partial_outage")], + window, + ), + ).toBe(2 * HOUR); + }); +}); diff --git a/packages/services/src/status-timeline/downtime.ts b/packages/services/src/status-timeline/downtime.ts new file mode 100644 index 00000000..e9f13764 --- /dev/null +++ b/packages/services/src/status-timeline/downtime.ts @@ -0,0 +1,24 @@ +export type WeightedInterval = { from: number; to: number; weight: number }; + +// concurrent events describing the same outage must not double-count +// downtime: per time slice the worst (max) weight wins, mirroring +// mergeWorstImpactIntervals — summing could push uptime negative +export function mergedDowntimeMs(intervals: WeightedInterval[]): number { + const boundaries = [ + ...new Set(intervals.flatMap((iv) => [iv.from, iv.to])), + ].sort((a, b) => a - b); + + let total = 0; + for (let i = 0; i + 1 < boundaries.length; i++) { + const sliceStart = boundaries[i]; + const sliceEnd = boundaries[i + 1]; + let weight = 0; + for (const iv of intervals) { + if (iv.from <= sliceStart && iv.to >= sliceEnd) { + weight = Math.max(weight, iv.weight); + } + } + total += weight * (sliceEnd - sliceStart); + } + return total; +} diff --git a/packages/services/src/status-timeline/index.ts b/packages/services/src/status-timeline/index.ts index 1784004f..46a245c6 100644 --- a/packages/services/src/status-timeline/index.ts +++ b/packages/services/src/status-timeline/index.ts @@ -1 +1,3 @@ +export * from "./downtime"; export * from "./events"; +export * from "./uptime"; diff --git a/packages/services/src/status-timeline/uptime.ts b/packages/services/src/status-timeline/uptime.ts new file mode 100644 index 00000000..c6a205f3 --- /dev/null +++ b/packages/services/src/status-timeline/uptime.ts @@ -0,0 +1,150 @@ +import { + LEGACY_IMPACT_WEIGHT, + impactUptimeWeight, +} from "@openstatus/db/src/schema"; + +import { type WeightedInterval, mergedDowntimeMs } from "./downtime"; +import type { Event } from "./events"; + +export const MS_PER_DAY = 86_400_000; + +export type CheckCounts = { ok: number; degraded: number; error: number }; + +/** Downtime is clamped to [start, end]; `now` closes still-open events. */ +export type UptimeWindow = { start: number; end: number; now: number }; + +/** Time actually covered by checks; downtime outside it must not count. */ +export type CoverageSegment = { start: number; end: number }; + +/** + * Day-granular coverage plus its total in one place — the denominator MUST + * equal the covered time or clipped downtime is measured against the wrong + * base. `clampEndMs` cuts the in-progress day to elapsed time. + */ +export function dayCoverage( + dayStartsMs: number[], + clampEndMs?: number, +): { segments: CoverageSegment[]; totalMs: number } { + let totalMs = 0; + const segments: CoverageSegment[] = []; + for (const start of dayStartsMs) { + const end = + clampEndMs === undefined + ? start + MS_PER_DAY + : Math.min(start + MS_PER_DAY, clampEndMs); + if (end <= start) continue; + totalMs += end - start; + segments.push({ start, end }); + } + return { segments, totalMs }; +} + +// downtime during a coverage gap (paused monitor, missing data days) would +// exceed a days-with-checks denominator and fake 0% for a healthy monitor — +// clip every interval to the covered segments before merging +function clipToCoverage( + intervals: WeightedInterval[], + coverage: CoverageSegment[], +): WeightedInterval[] { + return intervals.flatMap((iv) => + coverage.flatMap((segment) => { + const from = Math.max(iv.from, segment.start); + const to = Math.min(iv.to, segment.end); + return to > from ? [{ from, to, weight: iv.weight }] : []; + }), + ); +} + +// floor so a single failed check never rounds up to 100.00 +export function floorPct(ratio: number): number { + return Math.floor(ratio * 10_000) / 100; +} + +export function requestsTally(counts: CheckCounts[]): { + up: number; + total: number; +} { + let up = 0; + let total = 0; + for (const c of counts) { + up += c.ok + c.degraded; + total += c.ok + c.degraded + c.error; + } + return { up, total }; +} + +function clampInterval( + from: Date, + to: Date | null, + weight: number, + window: UptimeWindow, +): WeightedInterval | null { + const start = Math.max(from.getTime(), window.start); + const end = Math.min(to ? to.getTime() : window.now, window.end); + if (end <= start || weight === 0) return null; + return { from: start, to: end, weight }; +} + +function downtimeIntervals( + events: Event[], + window: UptimeWindow, + reportsOnly: boolean, +): WeightedInterval[] { + return events.flatMap((e) => { + if (e.type === "incident") { + if (reportsOnly) return []; + return clampInterval(e.from, e.to, 1, window) ?? []; + } + if (e.type !== "report") return []; + // empty array falls through: getEvents emits [] for a member component + // no update ever impacted — treat like legacy, not like "no downtime" + // (mirrors eventWorstImpact's length check in events.ts) + if (e.impactIntervals?.length) { + return e.impactIntervals.flatMap( + (iv) => + clampInterval( + iv.from, + iv.to, + impactUptimeWeight(iv.impact), + window, + ) ?? [], + ); + } + // legacy report (no impact rows): counts full-duration in reports-only + // math, ignored in duration math to preserve pre-impact uptime values + return reportsOnly + ? (clampInterval(e.from, e.to, LEGACY_IMPACT_WEIGHT, window) ?? []) + : []; + }); +} + +/** + * Duration-mode downtime: incidents (weight 1) + impact-weighted reports + * share one merged timeline so an incident plus a report describing the same + * outage counts once; legacy reports are ignored. + */ +export function durationDowntimeMs( + events: Event[], + window: UptimeWindow, + coverage?: CoverageSegment[], +): number { + const intervals = downtimeIntervals(events, window, false); + return mergedDowntimeMs( + coverage ? clipToCoverage(intervals, coverage) : intervals, + ); +} + +/** + * Reports-only downtime (manual mode, static components): impact-weighted + * reports plus legacy reports at full weight; incidents are ignored. + */ +export function reportsOnlyDowntimeMs( + events: Event[], + window: UptimeWindow, + coverage?: CoverageSegment[], +): number { + const intervals = downtimeIntervals(events, window, true); + return mergedDowntimeMs( + coverage ? clipToCoverage(intervals, coverage) : intervals, + ); +} diff --git a/packages/ui/src/components/ui/sidebar.tsx b/packages/ui/src/components/ui/sidebar.tsx index 4972fbd7..385f5617 100644 --- a/packages/ui/src/components/ui/sidebar.tsx +++ b/packages/ui/src/components/ui/sidebar.tsx @@ -311,7 +311,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
    Date: Fri, 3 Jul 2026 14:41:30 +0200 Subject: [PATCH 21/69] fix: link incidents to status bars (#2309) * fix: link incidents to status bars * fix: address feedback * fix: redundant floorUtcDay usage --- .../[id]/[component]/component-detail.tsx | 4 +- .../(landing)/status/[id]/history-bars.tsx | 14 +- .../(landing)/status/[id]/service-detail.tsx | 4 +- .../status/external-service-components.tsx | 14 +- .../app/(landing)/status/incident-event.tsx | 38 +++++ .../(landing)/status/incident-events.test.ts | 153 ++++++++++++++++++ .../app/(landing)/status/incident-events.ts | 82 ++++++++++ packages/api/src/router/externalService.ts | 142 +++++++++++----- .../external-service-incident.test.ts | 71 ++++++++ .../src/external-service-incident/list.ts | 79 +++++---- .../ui/src/components/blocks/status.types.ts | 2 + 11 files changed, 524 insertions(+), 79 deletions(-) create mode 100644 apps/web/src/app/(landing)/status/incident-event.tsx create mode 100644 apps/web/src/app/(landing)/status/incident-events.test.ts create mode 100644 apps/web/src/app/(landing)/status/incident-events.ts diff --git a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx index 9e47b6bd..ccb63411 100644 --- a/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/[component]/component-detail.tsx @@ -152,7 +152,7 @@ export function ComponentDetail({ }); if (!data.found || !data.service || !data.component) return null; - const { service, component, history, incidents } = data; + const { service, component, history, incidents, overlayIncidents } = data; const fullName = `${service.name} ${component.name}`; const answer = answerFor({ @@ -232,7 +232,7 @@ export function ComponentDetail({ {component.name} uptime over the last {days} days
  2. _hYw%gm_6UK;LBdawDKCDa|B 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 M)78&qol`;+0HO@KSO5S3 literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a9a3e3c2ce2886cfbf6d1625990ba0a2fbb96b GIT binary patch literal 338084 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Ð#;O@3* zOTF(+-nDDjwm7*>ulZzc6uQNAbE@m#8f5%l;Jg0LwzUrb?hE^$7GM9rt!JKrGpNh( zq@u8Ja@+mi=X57s{{KX{a2EH1{Gz}HQRlPw-@gla_3GBY_v`nbJ9CDo`ugWxsoAF+ zf8Hwi-`E@!6!mK7vHR!V*;YTDz5Pz&Jgbs5H`RVUnSZeP^OH^9dXw1Yf3&Xo`Np~O zSLc4O@@oBAu`*N9rl~kub~YGWg)KVM`wlS;(728BMY`r+A6G|)#(BCICN%E*yZ`RD z9M`aZaL_tPaQe(L@hoEFn^^qJZ}N;62jtBbOQvqkaF`-%^MCsOKS$LI;?Cd9HTk?E z_Dz-Tw{_dkmtR?Jo0pil@Xwoc`^liPH@5t)DyV~Cvuf2U6~%`s&#p{+wlM7Z9J^3H z866SRn2kxU-e)b_LH1o}W%{-K*^&867Nl>?y)72`<5{-R`#C=sNp5|+$nk5`{?yNI zyS3KDTYr9^yFlRRvuC^OZGNuVv-t;e<-3#nPfj@4Y%_h;*C(FBppIEstj6>Ab5-ve zC$zi|2@f@oOpJ=k0wqO5L&He|@;A~KZ@(9(vV3l7W6l4*=(RatUcSui-Thg{dM=-3 z?Kz*y?`P{zm+z~eZu9?8z0LC*n5Cou*9`rmF&7OL-%MBsNt_N0jq@}Y%wM@m%a^Ao z{EhedDG66OzQi=Pt=J{}@TRS)qt!ncsZXBizhwvZ?zh`)RDDt=IXo`R zi(#+5$}2$!hDHN{3kl`R58r$?^M>Q6dyZeE9;`hc_2zS~+yY^}H!pO4MXDYC`65uc zCM;+}@^nyJefheb&9%S3owon?bIqSO$L&8@+9v*qsC@bK`kGzM?Oe6zULI`TUmFou z`**F{*R`Q| zs#QMo&0N*|B+_#;S8Dq1y2$W1{%-a5nolpiZtl!3pZqyQ0bZj(Sq{HhV%B98S}eYO zoiiLfI|P=9n7{JN=Bc}vWnNOM5O7$K&cQNo+P3tH4PKC9Vb|6JN5$iFHtpq`c2d}F z+b%xq&#Pra)~%Paseilm`YCt$T9u0zFNT@@3bW>FX4@skt8(Rf{r}(hLDf#>lZoyr zCnhM)yLt2VmyjPfEsx&Fy}2#=O3-h}oMp>=huXPzrb}z>MQ%BMx@+38@8E*R_huhd ztNs)Gzv4=IgR9!+KUc5ceG&ZpeZt>1UthncU*11oX`87RvR`E24W$T6+OPpCQe16Z!WE-jQVN0@YWam~$*j?adF)}t% zG0$IdX0GYYl&8FJ{P(cg-#qx7oljV3hc*SO>7q{*8 zc^Ae1c$RHful&a6%g@6#o7Zoz-*VxbfEIK8=3Coxt0xC$8l#_jeybz0lz_%7qTHxl!c`TlUPiP;);>eQ)PsU9gqr)7RK-vmFeUEnYE z>rv?R>hP_**3V!6>+9R(+IgSy*392q!neKdx!=#P&h;PcQs4GVS?=+a6@`Th1Ej>~ zP`FUX*gjdN^KJMNc1VH|a9H5ja6atM>;{MPVjMcV)}>2ttb$1GYCSOX`5a~8(~Adwz6&eSy{Bqs78Y0eR5aW7=+UE#4o)~I zVmc>9=js&jjDbKMQ|Z=OjdmtWce7n=zqG*e&F-(zmLTK}qiyLP+y&z^TBR!`2?*8~_< zegC#{JAd7m=JzMQWCp)+-oJixn$P6p|G#b6^Z(rHpbeQz*ZlcmyYpMt|Hkk7d;e5T z-X~RSl3g^93lbo(5{;2XAY*pJ;fr6YCv5wABoqh$`34=?|d_qTgoyoT{tzuh0{nKqew{P)%t z9Q;%KPrq0iKh=)^x9H5Ax>Y}|?|*6Q+WY(4?dg?qph3d(b&uyJ+&160 zPrFaP`p-$V`T4)Tot#u}`}zNx?}<-35+}`?r6e9(Fz?T|gTJ3Vo4rr!f{FL(Q%~M( zes*fZA4MT?@$}f@>-F{5ZDub2dEn1!y`3vO_s=%Z&kk~Dg(XXP;kPBeL1Fzj=}XKo znFQ_+H&0D_Alf)j^T6l5RnLB(gDkvL@_Df3^7$zz)sm~KqPzmMSFc+)ZF*dl=f6MC z?Y&)HT?4L{r9Dn)zW-KdQ`OzY{dQW9kM~dK*54B#BrLqNa9dUV>i}<4U7LzFn^dNc zn&2pWs2mU-tz7y}s&L05XEROSMb|+U?L77AFNA%*M0D5QvwHEU{>81U3l^Wge15M+ z{O?nxVG3KnM>wKiL=iR`E>;}TJz`e z$@Hh**JB>8?CFRi{Pl6#tFNz{UYP7wIcv$X zB`2)&_o;N>k5_tMzafN+yF2C970qkG%zmbSE5*0(?EKideBRe}NoXspK%E-Z1IhQD zR6Xs%VF&7+&R`G{5pY<*&Mn|@zxjU6H1KL80ZFElY6~>AwWHN~WyQWUmA$#4xc}$b z{3T14sJzHN{FBN0L0tT4AF-?V|Gq0X%DrWx-C#GPa`nru(AO@#-d)|zJEv>|+aRm6 zfbq#fo(0!m-g5l(P|oGP!BH{>0Xm7sbYNW@_$jt~GxXZbyr^9<;BkyZ_%SE^gf%%kNvl(ifXs)x2GH z`^n|h_gf?!*3X~+?#I3UCr6*ppP*9wd134(BjYDs-um0jcCXucy}j=Dh8+DHH}7b^ z0_SIBV!>V}mddT+6JEo+I+K}dwpnE!lw-2>TyRh4+8z7HFFdo;)`A0p!)4KdJD2^Z z|5@0qVytYt;OWhSPjCJ3um3f<=GV*RkL)Janl9km6{*boFM4BAtIfY3j~&m)_+Aa` zg{E-Tfb2~h%3Urh`~uA+e!J{b!ecG`_krS1S;LeIwPjas&7R%CwlKcprRk?z(%iGH z?95#Qty}n|JXIuUIm1|?RMv2AL%@vWg zdlUP%y#DMiUZe7RuA6dxs)I~jc$OZ zB-Jp7CAk78X1Pm8n=S)4vRbA$>|Pf2%17*1pT@tY7wKo_ToydcdUg4_$m{oJrrzK8 z_tVt%_mx0d5Y!TW^5SB$F5mvb%VOFKs;|9#e)4erzuD){a-5A_;rQVGo~L{}pZ!{Y zS~`EP^46`TzO!E5e>Zn`+3Cst_WH%=b~(h=?)}>E&-K0TM9cJf`s??6TQ+6Nv|nFV z{xv=4C!bS2pKtdE2m9A|s{j8#*%JKxg#WvLOKpCyuRr~%-)>^L_+I_`KbPa5F3Z2K zD6X?3YFplIxhp#5?{8{PkExvd=STYYu6@f*P0#-Se|ux{@wJ9me=WTKS96772CSC| z4K8^33-&&kC~0-La%Z#trIat5>JBekCo$g;nnD-IG9@4Ho7gQDqiA0HQ>e3SC(|p> z=J|bcwp!t_rBgEm_KNZD;Zj?%=cB_zxrY4n-|rNkpQ=8;Cg{?oOK(<%#b^7NUA4FU z*7WE3(e%`_v$n3?wj4APCeX=LTP$s~UjD{j)iu+^rRS>{7Iw;-E&r3KoN~|d^ID!S zRwo1}@BMvJ{olRB$E=qMOH*ftg#KV_W-p4>xNR}lPtq=DMM`R#hnrizXGi~ZWwjOi zUVIR|xwX1K<3Me-S5(xhC%iHWe}8|Ue58d%_(!b5Y_t4{n>Ky=R-(PPYN_{qyU3u> zP*rw5xvZ`G6K-$ME}C0XSW`16=l+gM&!3(Azvt7gn!nF(N6&3M{nX_BX@}4E_&3^l z%bLCazV9!4%H3bR&z7~{3R@5M3rcX#RTNlvKe;vQ?a7z5PFF>d_9{p;PFl=f=)lk@ zrv@HQJ=*Ac>#KpxH0XM*azP3E#7RA8&U0H-+>5(@JAc2fcKEuS@C$qHhL=~xZp)du zXYYsHolhotA9=|0#?huKxk>81$u*V><;%-w?^J4V@E0h!9^zTzv&Y4f>G%CF3BD%6 zwY`;HC#S5uyq4kNQ}5|4w_QDMU!N^~ujFiOtVu*v{-O6Pq(7Q2{<$hSJLT&0Y^PmU zl->Kf@*1Zl+-AR(@4mIWw|8qEU&hM+e-=8|G(F$?cAo9;s9i^j&%Ir@b<+*@*(dK^ zX0*ngroahHp}}DWhk%2;T0YBVNKRg$%QSOlZR(2!cNXaBYHLq^KCjx(%iG(Q@ypwj zcI%t7*{bg9?f+9W(u3n+wTj^zomBXt8k)?9-&)rD4+UZ2tM$*Z%^_UHbu3+FxT zlfCV_y+C7ESgbKCqv#2foBz|#&(bqq?mu;=@iH$TpPm`Zc}{(Ne6+4{-?ypyrk2|; zrhLa(IgJwQ;6SkTY+(2`?@Qk1Fi;uR*dZigrV~GD(qz@`^KT_ujqjzc3_L9|SLwmJbwc4K zYj#?mx~ciN^s2(w(yfcKmntN1Kq^7C>2|Lb;J;^x=?GW>b2yj~^yTJDFH{$5^F zqW6F0-TCNJckL_F)Boz@Di1I3V+Q#HUhYE2{ZYgeF0nH8%XF7;UIUL_G&qp}B*+6{Y_shLFPm@33}vt7LH__`{GeRnm}1K$gK)En--v05Z! zmuvI(%cC%_1-WY-ep?Bj$^Uo$VGhTK{$?_WypY926OObH^+q>YPQa91HqiY@dDGb$*n>Ose`>tVq?%IX28vl<;=SLj;Syui2LCNmkd7tmCU$J7t z?BBIt^A=yP%9q-*e)hGS>u*hbm%Z`$rJXl!J~vhP*Ju51!j&r_tIt)>yXJcKkMr8A zb6`CxshD>~M>`IS%GOQhKG^f>j_EaDCdC(BdP+VI_SgTh|MchbfB#LtzkXeFCNob$ z#?a>eEt{!l-`ITnG5OO6<@)?*JV@OZa9YJA98$Oi9OQ4l*Ix}@jn$FRxZ{Y*$#=5_ zFL1qW_}t1ZerjX#aUZtm?dk_?7Vt%7E@6Cm>p5svq2K=Bj^$g+6L!g-cxPFebbNR3 zcgx-P>aG^=y1zsI_nunk2D#g%QU>|#mtOBHXZYK~Dg5NqY5n|5^S{gN`M&vgTGy;# za1-f}|AKYbbgy0&6?%T@|B+s<{hZsf-M(JCRnjZMBE_Afe?xQg`5F56_x=^z`Em92 zPVEMDVOhHxmv_|<6e}OCd@faf+z{4{z|5Oa|6WiAt<@6DH|_>cz;~E5HZm8f8Y%`> zEnm*IWy`N!Rjcnt=kFE$^q}(X4ZgVYnFm~}?H6>;bn9h)^!D|eDr<>*>%P}*JzvRw z_I2sEtz{qf#4Y}P%kTWlf2-H;)8ZD>F_7$L{%vu^+V-eX`0u&9%c}jGYgs@GYYYTd ztXw6q{IcrBjhu-FvoH8MUSBHB%2>~on)dmO{QbZ*i2r@iL)Cq9}aRDU-RGByeC=VS4&%N~aW!DPYn2bdrg`HMIv z=eB3w_s`s$=kt2)*|_Fo5S{bdc+3dvip zT>Cxe?*6}7-{0OncJKQ2)YH>W&aFn*DeyXcTQ(u4brb|hd8|wQ-iuz{qk- z%YmUb`sohHLWD*=krSt0Y45FG%3{;3;XXw~M8qRAGc(}eYes$nHr}@nemE=-N-|pi z%9nNL&Yg{MNi$d5f~Ol5Y*@drTku+xyI3B1*u{6=lg(naReA4LvAPf*fu6LpTmm-t zb+|Exl@$b-8fVOikTlAf!XsyO$mXs2GSB`_&u1t1rJX+WO1-kV-8(dNY0m9Ee%o>* z^KCVEoMc5C0i3Jx;Kh-R5?s*2)=6c;tZ8bQD^D_hUv~4dX~do#J1ib#EA3qvwW9N| z;E&^qrs36)VfY_hS9Yylx@wcptE{^ZtxtxfEi1lm`XUN4jR#Hi@YK;Vx#8clDdrV3 z=9J!Jk~B+-*?jQx*|X+mW`1tHb9F!i!6(D!-;0^NVa4U1U%m6oWWBWLc}%&IWPj7oNr! zFETuRI`}I#UVV0Y^`S#f+A}t&vm9sVTC5ft8p_CiVfD^i&_XVL!LnUJU-IMDuw9%j z|81A^%Hr!0GoN$Ld(Zb?tQcG#NBRa(_%EUO`d^q>m= z#Wp6E3+1=B_jQ6tx4xt>PXGBxPtndSfr(e>dP3pfqG027!AH1O>1b(fVtOGg%zXOU z`e#|-#fSng?X!0}TvJx?DWx zc%2#;Vp72insMfvf@WU;;>|#nToU(||F?zAv$7t!3DJCaR%BD;*aP?kyGGP7j z)AlvTRSvA+_!{y8whRm$;JX|eI5y}xq4#yBzkMG_y;(Qo--Mwer_v_U^dpn=T3Y$7Wm4 zdXaSb*ZH*!CA=}$-@lxrR#AKB$jVO-tMj*(ReGF1eq6nx>G|DfD<`bBi&m>HH$U65 zzwT>#(Wxz#lddk`zhvq6X%iQ#N8~zNNurdSje3FwB_~%v_u()wy%oBUBXKar>H3<_ zQV#Lq;n&v{D!)wnyJ*{UAt26vb4}(hd z=2Z&X$m`{Ee@0EeV4n$Os4O`6+3&n?)$7!w$Gw}l=6!#ccl_JgP1(oI{6pQ+>`%VB zeZTmQq%||!)9SkSH#d~IZa(6$aWsoL3Xo7RVLt-gJ$`nG2G z>gVTwfJ65ncgBILP}h}LX1xj2``p~8ZRNMfN;7-PzZ*~2trRIQox0<04TanD;?#F-4H5Fa@M8vN@RI!fGMCSoOHaP7@-<-l+h{X0=>vJ+Z(A?!?~$<% ztor^gIlMA1+c&6h?{4mtuU${is-5vNI`}Pk+5Eh%|5I)zX=-avd%5{}WnRz);n`?CQb69YiwPIVy^!=whiIarhB;FG+en($9U$0Y^$80Tig2< zCcm7)a=u)`R2Ez~qg9+O5e}QD-(LFRLY=0*_E!GeUw2hMH}f~x$(CQ;e|cRW^Nt-q zZUp+Tc64^H_;!2OXUPf&rPqp$-L%4rL2GRU2VUVb>%NADt{VfzpGr-_)T}}!Jo>hUv>nqc~H4G za=|GZ&MSJeI_r{10>dviPSYrr09fP0rO#pQPe=Fdue{n%y2&g1eNLWs zSyH#pZRVt=*uuHrvg;Hs@4KsZdvAHz>V)5munQ-haPm@0>Zx>~>d6Vki@MS#GhSyRS|G%^E zPL;2Z*EXYruN~L^)Xn-kOLWubgzl~DOE(sNR4b_KOG){%wdo5x->K=cx6NO!OgsJJ zYVa#(8aXC(KY0R`cI} zZSB6t>b~2JE}GxwL~a$AENi$IpY^Uf_vf}N=jI3`gFDR%4Gs^OzJ3jgm91D7b9URj zDN|CK_P=J5S3VTI>u#QQgWa{1ha6iXo*jeiJQAp6l6nvq9GjWip|5SJ^z^9vl1nzv zB8-pk_T9^N==y8lkY#iK38dww#lK#oPwci%re74oU>ACXz`{H3OnEj(K zB8s-F4LMjU8*X+sJIAy9>bnYi# zhT0;pSzGh}JLd;!XxioND_t|af4bhJx6$Sm&z9wu>^p5=aeMN`ec|tYeqTz9H?8>h zcxiX)X3l5!WnVUY{kvrMvnTJn4!if7@1JOTrtdVjew8PgI{Cw(t&(<*P@cWEkOPc!aYOdRCTyP|7J!GyL+G;)I zwBX^wKqt0e8!F6aus~W~2RSp;zI^J^^7Jy1yuz$8tJY3i`}CbFW?!I#O{kllCc}BriU(ao7^D}LHw5!)Z^6KhUTB-l{#co=iuv*48=*F8XUrwIi z$=n|CoQwbM^s~~}O>X-&UpGyt|90o|nl)c)Hy77zy8HhAZts%r&Q4R#Evsg|b>4hj z-a1G{a^_!^wc*a!{-sIJI;Gss{q(@UyJzQJvwS{d&F?5J?bA;`i=LjHyL@VuvBO?Z zou%fCGI~}ow%@&W_H_-@zqf5x>AZ*JP182H%wArfwe0VvOKlBRyLpjIo|35!&J4Dl zA-hk_FNAcdGbTIq{#>+n&7MOs)t@%b)Gb}&_-N)#-Sov7FMoO1ERPpROG%lb|7H<$ z+`L)P4kn}ufW`uIy=`q>M9#u+7C z2sru9KH$+KsY&5Sj~(;8w;=J_vc@m3?f!?H@=FQce!u+eD!Fnc=lyImw}!1CW2S0i&ymncqr{*`+v-`3P_V0gWo6dVHKhx)I&Hi1j z4As>>su-O^K3 zJbCKQylMAtf02*q@ZWlJ-uv|x=XdV-F=Kxk;XJZ|{w|D`qRhHC2Srw=qT z`)=#s6}JDvme?yXZy|GYklG9GcNo{fU%(>GX!&i%FSWm(p4fGDerw82O*IL7#fK>j zza}1Tce<2cZLMin7gBP2Q{mbrOO~Ddaq{xg@bx;A|Jph(J8$KEulBX-d4WQ;$jPxr zM!!4r8mBBtGdhv2_FM6=o9DTPgY$HL^#0yte8YSl|Fav_=Twj1{y%&APtHl;fktpo zyTM_*h(g1@=zY09;1iD)Ea#T7DskYG=d=-SPg^Zvk}=_Dld)@8S67wFe5s6!vpKiC zILpG!#*8a&aw;r@vx>Gl~kQY+? zfkXYFjsruj#eVBEypTj~&vbiR-bCis_O%HG)&_U{gZ;O%b@$8JMsaa*t=V-f{#>Qh zwhhVssr#$yPhLBedTnLGt!>xBqt92LuYPi3Vi?;mhu@ce!u$J3c^uSZfpHt>DHL2_ zxsY8@k(1-R?d!$IeiOgns|p6VouqY?+asD zqt`N2%?*FwV>gfC*QrxQ=R>Zqk5t@Umh)AHeY0`hr4s)Sf9}~@r!>D@y+-GQdLX-T zSgLF5@||fn^lh&Eo2_UgyQvvbCpwr56_hOAX%q@A$t@H&6kpHN)YhMT*xf&6M~180 z{yW81bBi9fidPwJ$PVM=)%bpI%ei}7_MU$F>E@el-wM8MtnJ+&o_qbOEAN+OjI~#P z#uOZ6oz^MG9&{xNR%t-e6v9>*>kA9x-`v#K&%VxEx@_6ENfQ^VSM)XCEwqX?dU+-C zQAZX>_)62p&(Y@Vxwp+W+wSlEUbpz1#r<1uy>mqZ>`UYJtGXUPQn5}`)AFbF+;6w1 zE!w~K>#Mn$u~lC@Cf4lwW4r(0=Z~D7xsr#T&k9;^slI&K?>Uc=3g5?)~?WzkY&k^*5F)W;5KZ&cAq(5xF6uackM$K!pj5u4VaQteu3U zHAu);O>#JRjn}B+1xIIpKF5P|@^)@s-d)Y-cC6d4?K{sZIw;7GEid2r;Ac^_#=!Kc zpFRb7zMq=NyIk_d_M8}PQ`4)ueE03m&lm4o^CTth$7A>Yh=cDsJ5Nr!sUAH?%`kNB z?YEh)_b$$sPuTQMUe7AU=!X2~IbFTo=A84ToXWen_$yvXzuysaaZ;Vqg?%4)CiL~o zTPrPHdUVp1DN28fKc$>*Gp%F(COmmk>a~~8JI`ew-{zb4j=fp33$juJoQXJEwlXk& zN&NfG0K7Awk>wBfo7>yn%ih~+Ja*&#djG`ho|C5fnVFfNe&7Fp@6@5V=;-V$pR|hg zPd?mZ{Cw|s++CKf(ivstZ$pk>{`PH${+pEaE{ zZ(d&S^IGSI{jayg!RAMBCNUMpzrLAIm&>2}a`UrPU9{2vIR&S9F0Og~`g)C8p1tGa zdu}H+GmSD&`4sy)f7mr|weij8+}rZL*1s@&c_r-rMs-1-}&1p+QoUX(F? zO*^I**T?WH@B2B!L`b5NV!5_9Ryp~YpUB@!MiX>i1@^Tul;*B?-T&qC@w{u-UoLNI zOJbdITkxw?bp9=tpe^#NZ^X{saqZRlFNv(LwqKgac0T&=47*on{~tYetjg%g_M*%K z%dcu$T1Kwh|F7!v(u4={%~x`cud7}33_Qzfc$S*WMR> z+qf_9_MU^Mo~-+uI#cIM)#QWs?y`nm`*y0U$kWSj>!$C|`EooumLB}Xdb=iHO2cM{ zKO3Kv+TNeW!8`4ciyL;L&kq&}?OuXyw371Iwj$L3Vdm2!!%`7>kB_iv|-Qjf)aKJtjC zv)|t!@`?KITJP6qYp$=4)wJfG_0Mm~bGxWr9?NF!E76slS-W=a&U0E?r&5j{mp9=& zbbn7`ujra}k-s(M`|vYY$Mmp@(A`0cIkuibZ!d*3%T*PoNgdOAHVwL9Zr|=08uZ_Sdrt4U?Ud*e<_*wmu`^$2MK*Gu!S77p%+Ot<0{miR8z<-MhEB@y+~t>*me9=PTc5FZ-$5eSd=DVYld;-%OkLmakm7a@(d$ z>y2l=ziVoGZ~2E?^?c!B_u1;4JmxolJg(h!$@1k4Ywm5co`m!IZ~vBg0JQK1R#@JRQOJ6CQ#?|z z=(Tyyt7qPczaZZHV$--W`S=M}?sXGp@2lx_nSJ1gLl@g|aZ%Berq^SX-|zdKw|RO? zG(+u*XU6I0WGa8HT)wpY{k>-!r~4YuGieWeTy}cCT(#rB&yO~5N;`Y&*{lH2$^e%= z4)^cWWcRX{nV;Pt^07O;5n>x^1Ng3+!lnJkz5Lz_hrM^*|0V`B)Gx|#|I(2=@1!oi z`FeYM-h@q;gjTOiTQ)z>=zKO?#cmnvs4FXHzIa>sHI(_q5d`hwgLAs;0g|LX&k?Uz+sz+U42Id-v(S zmEmijS=?p1%uaLHnk^Apr%ta?_uszMejTLpUSQ2RMaK5V+-0X@1RWGum=?S7ZLi|g zxunO!dl|MgK8s*}YWib$qITw_qcNK|=~ve;^cScNPg%6R(8RjV^P^$*=GV7At=hkH>NJt) z=-cboPkwy7FCsd6UH)lPDHHjwt=m&`pne3mkQS_Fk%=`mfOc>i95PtSX1J@byBi@; zkRHhQS-^Mm-1>t*i|&?Q?>wEdEV50c-vtMf`=31*cN7?PE#;%EWRemaev+JavAJ#%%L7(`u{BX7Ri^K8xl2 zZQC1;U)+74RqoCZ_6@Mk>G%MuY6S5H3PH}!VjZrvA>D^}iGWr#Al04`FH356|8 zXW1`)=X&n|VdCC+O^SdRJdF1VEUQAu_a-nne*<|hR=6%z+k!=J=2MQ4-zM=WW_cyon zQd5s^N_>0jn*JhK+Jl7X1wO`b>vd0qprODa-1uE=zw*r5U#C|JyL(mLI+^g}+Op*b zpH7dfTDc}_tCw8W3&q0ScNZ~!xfl5=`nB?%bFc4|@(JNOTI*G ztoin{sxtrM?uXl4o+0%iFr(9DN(0-)`fnfE1-Gh+p{RVQ?Z8m`W1smM9#F%8p|OGW z+uOVP?R@Vhrp{kG^=JAyjvrRMX8oO=6XpLrU=IojQThMlxcwT3V%{b1*B$-M*3hlD z%j4a?-+7&VecxEFvhP~=^jMJZRmfSv7Zfg-o6BRa+y}Ri(1``n+!njOzL^Q#_s3De za} zFg3o|E3u)Mn{E4pcSp)*U4A?JUY%!N-A?nJnSMFPb>E4G^K46wIbbFs?(^Q&$zu_h zN@KuvulvPrZ=#x}uHn*ppUiJz>5rC#qLGdj5R5 zW%08Y>+65677`Yo+s%|?`fHh4_KtHAQNdF9>L*z74oQm&4Gz}@7ckXcuhg{^1|^Bc zJiQ6&S|^^TyuH{JnqB($YVp(SEeCe&X4<>7yTAW>{J&4)q9P(0UteAId$DKblCn8{ z7jiuAJuT9-wT%UB9J;zaKK}WJS;F(mL&L4xu3egS37lT-#4V<5{{30~40NCuHCbFZ z$g-n3iM`sA7CZ5XJrx^`jEuLI9sYJ++^q0i z*lc;Dln%MtFM+XzM@2V<-pT#2XK~Bp{Vz=J9Jj9imSg+vMzWW;clO1N^=WU`EZn*T zs}sUI48T}(_&Da~K!F4c|L;LvaLsiTcg_EpHDe7~oa)qU=tK7DQ6xVg;)#hWM@7-9`_ zf^1x;?$EIB_1pSv-f(zHzeO8a zpq5vVk^)zdC|vl;!f~N|@AWChkQS^%x0r5Fn%lBz>;J5Al`^Y%_x}C*`G0<>@A`hP zdg{D+?^-U-7WT-$*f)FQ#Qy&N;-1Cs{nzaOedPc9HordD$*F1c8p*>IyP~wS)81yl zk|iws@j4|oxPhVedQGgQHY7Z^ys`J*nt0i4?d>g_U8U;w)p7A~U75b_-=w&Thpcyt zPV3I=dao7*K5&VZzT7>-1U0ha(3!j5?v7vaz$;f zr7_4ApbWIr+&kMoHh0y9`c->xvd>!jkmcgvnz;^D4haoxd@?J3|0|t;uj;k#-12*s zT^$_(0RafKQU2xZt_Oa&(W9G z^qOu8yVip@zDhh8KbH$3N&yFH&JQebOU z+qU!OcHB3U?peQTRnYl)wx*@0LUi|}Ej(xczeZI}t!k~w`+MhZ&seT+J!ks*rTKLW zY;T*Nj=G4Mx}o_Rv;vM#JHa__`M-kD_y(AEU!NJ z{OQw`X^K_Rx%b+hKYsLROTj~@*z&ujQZ^MEHrMZ#-@VT=@#kg#T?;mxn6c){y0VkkuWwhDS2_-lkP<1z-#5G37?|#YlEwGhx0b~q*EZ&}y=C(Enfd;UxAXVE^^vdrGBJ4SzayQ( zTH4yhPVdUBt#3Zqy;d#%@cVDvZj4yxBRp@r8QxN7!D4O;#wym5FNdG}fW=aypQ1y@D*zg)!aK` zroP?FeGI-RU{^20{I$EzdY|o73Wz_@@;q1BA^!D&{SZ@1q#31U=G*TNIl4^h&vdbv z6^$qN-hOf?_rcw^yRXga^OjPd7;w{)IOfW!)C6S`~Cv&E@@T@e7H4oy?G44g({L)#8S~KB@N67X=&^{N}o{ z>`snl6|A%YIZk1IT)=`&n~KiPwDb%<)^Bq4LGA7*KX=DmjoO>GIc&`zm)Y0WUtATc zz57XJQ4qvWSY2}ADC?QK4Xd@ZMLZhzb??70M-Ei~F)(p#+1~KiNA)u_n=LSNs9z;h z`#tr+8Ay}=MIDowM_t1Iy3nvGn$`akV-1R%9wjI55;-z)57XYwMZIM?_ZODms|uc3 zZM^%+&q5=7ZrIBbGxg~zPM(SV`PX%NuI!ETJtqcDSLa$Cd`q{!N!OBM;wZ^)yv0!a z-R!{|s2jF1nFY-Id0>CZ*{#>J{vSL%%O-D$TCZ<#Lc;TXU(;Pvm)b?{4wYYjcg>tN zwpDc(7v=qyDn>sw8`)hKN?BH|(()DkWyH$TS~hp`BOiD!-K>#d?|t)phzX0pi+fBg zFLr-_ef}n7!N&uR8x22q7$%1VhAp})X*tU#v88S4m+Aff&v*Iy_U_z!?c3eRUm0i9 zWUWd9R@+zjXJ23cJQQ+hBaT+dt{w;1%9(%uFg*+3V;H5r<-yRk3P6LIam2Fnu|jxL6;WEEFEpv~8Nd6kKXER^4NU zni1fCfbD#8^|~vn(_>dPxAU!xpReL8VH|U^R_N8&*Bbucp2}UC_4W3Yxx3@p`BPro zuiv|H@$tUWDTg0hz=9YW;V9fjGw~HV`cv1>pU>3nbh{>p%?0M$U5gxCD?8t$Yk)FE z0xQRb&vwxET%$2d4#VG*$LEJ6B{k{oc;NK*?5VK-Pxg8FdtZF;ul7u?W9|7H&vNt% zcCOm0t{pym+q1#VMQkAC|2G0-95gryZ* z8D#qq0~1FHU*oB+py!(>hg`Pgo3Yr1p|MO{!QuY9BX1xsZ#<`+!2HtR?&lIEB_)&U zZ#i#oOLGcdJYHEC~3$>08FpE>SHl ztygR_hvgB0Ut4rH7e=aEY8j59m z`9)t;szZwf2Vs^RhuV{qRQ=9>nW((A{ENibF8_dxiWcET{;y=0+jV~I>h7Jmer3re zv9-&Vxw-d=W&A&A^Hk1e(VIKYT6U33l->C;>}xAPm2XJ)?eRgmHQ1IfzaRpg(N(5OFS5*IkfdH zHKmvF^YBbtU+>UvZ%nQ!KsxiZ>FBTc}w@VBSWK~ibKOb;k^+u zT9D|H^*z9L>vh|$-(TM@o-#$`>$|y2cI=37b#>LYP;p^obX;XN)j#H{sg|~Oxu3Fy zg-6}KN&WrnS81IN4U1a!_&E2}>E$8pd~dG5ySsbp+{w2u`ptX{Efm0kfI(6fVRt zGJQEKy4W7#Yz`BR1m^cG_oSaBqK~2Z zYIiR(hTZxxr|c>Kl6-k)7#u8>x+_wD>xu7YG@E#v9fU4tE}mBPKK&Z=RJS> z!k$=nke#zM92)j@29$uotwAVxZD2PHP$xHLZ@JdujWLk$eJ@5$52 z(3l76;Y9B_Ge-qlq7dU*h`S-)MQUgu3ln47U8e?y+U*rHEj=L}5jeK z&zkX9-XFOKSIEjMjd_X>f~%*oyx4to^;vS0{1vtr{!$C!-7ubjP?OQ!h zLj21Vj}Za#D<5hI&`Q;)~X=Dy8Qi> zduPs=*}EfJxfpI8vtG}6~THxu)UeIObxKMt2`rOGlyEPd;37?*v^pZ7;v8_I)tzzO+JE>}= zf6|;uLXUk5?A-S4+t-_WPw#b2P0bvw@7pfbo;tAaoZYI`t4l4`JN)LC3tTtzl3SnY z)YsjmZ(az#y|K?%zWz_)ZW-=o+;zx>NRX?ph4($i?W*8LPGR+oA0H-my%b!1YO>?(KAH&@qTkx6l$_(dk6FDxF@0;GIjN3)Zjr(eUXIz?+`Rb~+=ibRe zCOWAN!FO%frI$#*efWkix%uD8TH!e__h=?hDPI#%ZB%SxVj3!}e)ht{!@s|tbeGps zSO5M-PNEuj)8;`8_lysFa#>zv%l;5Y$p}c5-~wq*pBV;mi{1KzQ%d-kF6X`4ai#Iq zW$S&XId5G3O|{=y|Kyj{kn*Y7t(a#Lpzw+#+y@M!TTV6b#;`ASkc`?Kfb0t~ctT{E58vo3G5eRXkhd)w09 zE3ZP|XTQFdd(SLU5-G-@UWHX7bHf@KYM0l(v?#z;<2GJqRZ>zez4?dL>&@NkEYIDu z54}j_;^MN|D}8=1#|>_t9M@l47BX*1J6z`K;x_x$-{h~qE~#1-K5Ch+8-Zm%0o2Vh4x8z=CTU(KTR6O@o6)ul3vRLh5VEo1RU#PGFEff&kUd|&&kIq{4dAhdY z%Jt9A&02G1%D>*y^jKlmH>@1fih*~|;QcbSGNn5stBPJXnt=4m=t zf6ujJTj#%Oo~k{2m*rnP76yPUymI>BL1;*0rgjt81ILfMU%y|_{OgPC0&btHKfgR| zp1n!3HcCT4Olr|j@v{L%_gz|9+E@7RudDhtGd(0Y`0^pan~+&(EHTBO@bAu! z&EdF0zfp|qi@)Esqo1E?tE#$+pPjenhFqYoOy}8I+6nq0FXjp?Pt~>yO9|<@S5v!k z)3>+T?+m`+%7p?B59V+REU-`i@&;$(S+JAo@-n}xJ350+>&|$booDCA$oS{X-I&AI zzHJxRiP`+1X6+Ays7A(vQM=Q&+QsbMwe|2O>>HQBi6h;$VZY8C(X=w03o|Z6HU0zz zi*r^=O`Ue>*25e7M47%FYTdb6ZDn{2|4(+d74A9yy0M$Kh$?T=#GNVA-5VJG z-YiVh2V0GeSSzsOVVksR!Ucg?!~AW(zV+oF^~l|w>Fe8@?jSEOfBw%)<9BtuUwk{-e>F3GUf%myBRkv(QmpBEq5<=k5M|XyaYRZ?9fu-8}jC4%^MQPhP)%ZF8&fjg|Gy zx_4>UufI*6zB@)QG%U>OualFL&F$UW3y-Zddwk`}yUTjz@2{W#@#FXW+w*_DW#u)G zEnX?MUvOD;bMx09kNa2Nnj;J!6G5s0A^EMbPop5OKJ9{%U@2 z$(M;QXW5tUa&l@q_p@-P_P*WDAFi$oepnG)b5C#c!Eck*{a+pF6h3wSe7K`yV^>#K zNMPW?PoIj;r_8^-F^9oULE!-B!P^RZY@eSv;c@iHkrnR!a_4GFO19M0_*(40)$;l5 zV&Qq;r>bwr4}4?vedAnimFmR9Tf<{kT))RPalU1L`usYtqeqWEe-v;-9hYkvn0mPc z7UWN9N8T%jnz5fd9cVkYe&;*4UP;rS&ps7)1`qE1oAY+vk9XTPoX>sw<4^L>Q~D>u zeap+oj~-E8%D?{w?0l=Xk&o)hiHbuvm#ovDJTjrL3!_ zJd3qB%W~%Lxt9-j9{xOa>Qukd%IMI23io|lSx=ofaiNi!eahUqZ++PLZue4hA z#Kzr0wG|aRgpaMaeztSQc5$mS`!m{#b(S62CuaM53g<<6d-3)|cDOs0AG91A?rC## z<5Y33)gdBc#=6}P)0XzjTvR;t*^D7y``B%*PumXtd3SgB*0Q%zYvcFF?Jj#8l$N$^ z^F7&~?fvgI?5W){nfK6bhdsGvdu1>0J*T(%{N2-U7gx`W&2#=;W?#1HY+m~6EBvxn zAHp#rCq8^a%{N>=mgMKgez57wxe^PSE-2WTJZEkSO$DFIYw?ye=xb^gZrl8@>h^iF@88}%f9EdU@_*5@cekh1 zmCe7sJ-__WpVQOz!~5lIr%al(C~|XJ=Cd<1{WjbSTfW_~`u3_-tL7wczWOG&`2FeH zJ?9RY{X5?FLf=^Nm)GX}-?Qv~Twq>Rw)0knJ`bLj)@N3Z3+DHGbaB?8w;Ug=-hOx4 zK}~0$in=x?W~N(-{JcDwpWd%~b*o@I@6_Es7piY>%k@k6ciG>*bk+XnPoKX0@bIwT z*2;2)dtp<{+b`T*Sdw3zku!Juzh2$Vzc){o-MnW{OloSXRpqB8!e8$1E?+PFMcyoD z#<70+^_s!UG%PJ|a$dUq@7tan)0*$!?)9Cnwd<924!+LH#+K1osjIEMDkc7QyIj?Z zm9sA)dgKdaS^qdc7M-)l!Ex^y*VT%(PlT^*mi=D#?1Jgj;~}AwR)0Dyze=aNbEbV! zn))t`CT)SOkTpPdbIsdypz z`gXSC-2)YMb^EsE+A-?jdsBZK&ANl$}8;y*O=T6wQ_Rl-M^VjdL+uOHxVd3j{ zx7!}PHN0uC*Y+PXJD-NRdHBtnH#ap_MLXVK$Ir!8r1pJVnf3RYyMK2~o4+4+7C=RG zSb1&nb7rPLQ}38N?riVZ*3`VX^4a}6hA-e}{+NU|+~2q_Ld&9VlG3GjAs(Nme&Y6< z(EtDD?>BGltakhFpTNR;%rC$pr7P=H|Eg6L`_aoUhuxrtp;fZ*f_(ENHb{NA;4#OI zS4I2({p|m8fB(;&Z`vDn+?Y4Z{=HIbTU*xESN*oz^WIyypP2{_^%51ve;;m4jN|Qt zESYRvr&;i`iPg(f_F>EOzgPe{J>peXE|&ufI3*{K=Dn zo}Qi8A8%wV`Tpcx!uj~!a*R%9v3y;0@m#}wBKHhW5`ts-iLG$H8xMWE?>jh8E;p~Z#Qf{~m299z zapN{2k9YIeaO>>}dG0%V!Iv!ub4_#h7UneEJ95_6@#CpeUg`JRPH)esis#~AmU4G><%Zu9DzoDUTmp8K)m+twnqgoVRbvw-F_+TCOxJOWVU;3)O z+yA<*?tQ;CGrRT=Q|PYuSC^G869;(|-od!w)cA|B%9um+MYP7rG)PRB1T^jxKXc94 z-)2Qi+{dqd9}XOJ*0QP$5)^zm@2R2T#b1}Ma-Y$?Qm(CRe0uX7Nl0b0hM~UVNiD38 z`c^UF@GbLuKT?-2=fD2u<>OoWdvdu>?C?2SJpJ@jmgBh*H76 zfRFRktuHAS>OlMn&g2RgSV1EQ2gRobLly!a;JRU-cmLzw+h3pC|J&Zw-1KT;&99qQ zvBihiR=t|}+%)e_hU!%>&Uuw>2F#Y7Q6Re`H<)=nsV;> zg@?+zR!df|+i^zna9?m_#@4x#o^!Xe}(<7t4Q96H@=gPxv z*$0mrKYjoHdY*Mj`+>KMc{}RATy(E`xpexMSF6`&y}h+n%iunL?v8ys&)Vh{Z_hse z&(~6|-1HYSJKqVvn_S^qm#RC~R#@%kPTn<{$_D;c}VW0J$Q**$#_c&}9 z=HTVMxcC1L``WM9X4}?(C{woi`-c11vF-0oratpqwPT5k{=PjfdmlZXVrO*r?$MiR zzqXu|vP#)-FZSa;VUzD`Y}}3g?S3`n?W$Y&EY>JIRPDltbDzFPm#Appi+a?Pc>Lz{ zxr?{HHrtXRV+L~SuEh-X6>s|1TRn#y@9OZI>&zTO=fm!O7el9?4GVFJnEn1tnE&>( zY>#sj?%3U0@Ml-)>n}Hw`!hd2I(lnw_4c3lqF;tYzxQLTdY$C_M)leD#y4+rZhCzw zv$L{_nmBPH7YE0N*g1CZ4EAnb!2AE>_s_ve>myR1%1xc`-}`gkyt{3SjYXhYrX-!Q z?s(RptNi|d(;myt+H=jFbE506l2!dh{L@!0Iu*alaC_Y+Q|1}%)3)`=EZ9E3x1HDj z@&ZRqtD+wpe$Ko2r@J8f)uA$!#8<}jj$!XlF=uGfZCs~tVY~k%x!M?D?`=_n*siKRdrWf|>oxb=~;ieMLpz zuix%dN45f#CAYX8_-A38b;srGOvAvB8x7Y=t~!{TyW?ovi_@o1&prOxPJ3wo%y!4I~_kh`()l zi+Z5p@E|nd)s)Vv7xCpQ)6dI&z4rXM_>1iOzZ%2pzhv%xS~~wm!rybTyU*XS%dJ>- zFXmU%zJG76rS9%~7jXt&Hy{tO__1(w2wr8%GUtQ~7yQW(1n~k@( z_t%5$@-qag=YjSc>c;E{IC=79-{QRn_iN{UYihZ0A)r4$`~3NR?3;@DPwrEft9|nD z8sG76P{%YdFum1G&^|p|+V(4t{w4W+QmYv^{woT-n(^&J!OPQizb+#vU>j&#wBk?k`D^=gu@jkx&)zh<9 z>eaC#lt5Ks`o=7JS8mH%CtHCY*Rg?a)?cn>h(c53$ ztA2kK)N1JI;qiB^%76I7nC*=l_nP*vx3*?aPcFS*`#tmYG+ixi?awoQ{rst^p>aZZ z-uBx&mR}2)YhS$Q^Sll3dBM$Ia4qNHE^1J&Wc0E!KJ*29d{;=;ob^V1Q(hjOsy-z? zWbIDnLtjqlFDkitC5!d<^b^Og$K1&JHQPIS?*DUNBWpMPa^AVzRK9-6+}qnV-(N^P zpU5j=5^#V2YSsr@;*~ ztqa$!K0udv&GkEQ&+Tu0{r~K{C5KJZWqx0}e*X%8-H+m_Q>M(@xNae<<<8$*AH0(O z(!c-T`e)~N-?)7C{{8zm&vOLJen{W{EC2l4x3;n~&}Tvxa57DtI8kbvT~u+pZ(u}( zhw!$HIC1G&<^Jma^R9e*d;9AVVgDCr&F^1nWM-eUVLNZ*?wEDYc<=aD-8R_6d*=O( zjfelt3sB0gxa@1LsjKVzZR_UOcc;F%JxN8!zIm{mu0A*Uwj{TCdN#QQv#7^7UEcU-H&v zA?5eKJ~y7W8L47oWU-ogVC8#_kOl8k)=RfT))zI1cJy~&_3oClSGLJt{r2z2^W`t4 z@9*0j`LJ^PD&9M{bKgpot=aYV*lTgC-&=k!gEt(ZIqE`8qxW(uU9UgSF~zndTMH=(`Pe>_wTMRaop{xF5Ooi9}y54xze`!n?+f- zm~N5Q#oGbZ(IK<*J1*~2cbobB*wW9>&9AgRh1$`;z?2?&;QIEM!ilQOUezqUxw-#O zjdsc5GaRfTzccU7^P2nRu-AOQltK#+FPgZ|5uf*A8WYzSWa-x zHrvp9A9dvGgUiZ)d{ErGY|dM!AU0Y9oW_3+s>F z#}|SNwG#ivz?aHjUNo1lE`NWdiosP);lo||KQ5>5#l_`U7SF$7-*Lb6``=sJYL~zJ z`+UBrpxisjq(?tCR(;+oUi$j_{?)y+w^d9le>&47xU&Aj0mfIi%}?$;n^ESs&ggqu z=ILv1eXVj|o2Q&mSe~DnI@K)q-m9DI^5?7c${KqqyYpP$nEdnBuH5Bebw4HwdwnRe zG8GmPQK{B>seF0L6>G=W<~i5Yv#(j*o_lZm%JXj{n%TaE@84Hj^2cT3%5yt{ZAzTFMM0x&1|I^&7O*9TJ)zm!rYyD5#v(G;+uKH>lyy0Za zTkE3R+fp}+*?yn0ujcjjC;9vAV{)}F-v4}l|5fWJ7d99yUB*{F?P<#U;JAAet6smh zdnqZsyzb;lKLLCD|1-WlfA-?RLFQFP_rqsh`r~8zXQ6Yu_PLM~{T&?vj*k2IYp=N)It6`+=ikM~9e-h8Fd-=^Y0kp3y!+4YOg(jb$Ggm zub=}%% zQ}LT`yWRIc`6o5cEa>3DgHfA)xE2d;sLV&+Hj%NAf$^8vp^ea4uIEk<4t-94x$yV9 zqB@CHyZ@ir`@7`y^?i$DcYnVUduP?p?e`)VdW*-bJ}&=nIvd}QJyr?tkFf0h^(gq) zukG(H+(;UY-8>Hoq=(rE~C}Z$A^RX8nEge1GV*eL3r2 zM}j-mpf(q{cVQBqaA}IN*{(S4;oMe^mL_IZa^t-rFDmeCDOkF1T73$ zi2M<;G$DjN{+VbL-B%cv5FZ<-MHPnwK@M z-(M6Sdv&;-?^W;8^;u_^%g^7q?p@QdV<)UjBG&KwHR)RIx6He~DgA$cN$-E7Q=NHn zbJh2`sb8%i@P#5O7J+_;;u$HI-@G8dl>(j@Nx&=m}EOm?5Fi8GY^40Uz>Wwc~#^2bkDSO8;U;5QH#k}a!eM^?O z%$zy1>dnUETXJq1&9x{z6q(ojV7b5VP51KGkIiiV?pZr`Yt84g=3hS?=FdJq&$e%8 z?7Qq$9lH*HS)PCW((}h>s#Q+z34c@F2Hz*7P%w@4jcl7wg581bKIL)ZD+TsTr9KOp zq4oLdueXOXYLn}>)MWiRJGaZ{?N2HBnd{U9;;R!^8&|(7sP&y@2U!BXH{zUQx59<3(>bbM`yi2c$*pc`D+jo2Z z^W`7D2gI^JgY@XZZNF^}kLSBsf7@7G0;&5;tQ-HG{QGL|=lyaOF7-bi$NQGDh3|cu z`}4_;l^unbb?;x%um9#8y!DUS`3uYCyVG6O=WVp_u>1Rid6r>r*K?h|*$WQ5&fl}N zXK&=WO^tsio4&u)Es|UJV#`}2WBK$$ufyYirwS`&{3+dFUsv~db$sEfTk@u&kL~}w z5MCR*{bJ7j;OFP<{13PDmLA)(ZU2v(^_ho{osFuv`t;l;TgjQfUQ9l}CHcAD*SC|G z{G1+_)R{(gOc_x+0C- zWkgmeYBrbt{NwE#dQjlGQ}6vhpVa-f9&4AcJ++zF7~+3$k*Lt%P|O;1*)98A52sqr z+v|6HrQhbSo_{;d`Aa*${I$*J?N)EUUl(m@Y3Y|*^8J?^dtz!c(>Loidr#bHd%Ah^ z=C9YH^H;X7Y^uDSyIoUJ@!-w}w`vQWoEiVHvF9hW*7o1{e(GRz`<9~6zuiBjZ?qgm zSe>hypf_QQ=+ouBt3sk`7VyawXC6H#r7EXocKXm15#beClk4@hOdWp*TUJQ#SijP6 z{^_&Z%zWaL?VPP%pZWEceYL5=!SI)y2WJ^Aa*)q4E7vPJbVb(OWq;-8s@UbTWdoxp z?p=AdPHtb;!>^yr%MWgv`fPs9pTxJfHr|c7lC9@p!1!^YbMV=_E&COv7wvy^sx|8O zP4!KoH(qa>x%v4Ft{=}WyZdH!y*_XAb;t6ky|VRJUToa;Y?t)hg1>*X*IoN}CnopS zj(zV0el0R|>z7=eo&Te&SZ4aU{V~74KhOAk>--!;FR!kxb$6p~ax?y#S?urQV>JKt z_v_O4|E8ST@$uZwThCY9|2eStM&*`=Kl1Bdhdj7jGri*R*QIIl*=IgJvk-rfO4Z5h2WBqUPXv@mNVjJEZHyF8<@a{h#>VZO`v6&u9Ks79YE}_U*OVuUntT|380w zmc?79zt{cimR7(2z1{flhvoaP9a;JO_0;hA?*%tjeZ2qg*>#)q(z81I`Yye_zavzB z-9H!Mz?ob^5Ag)>~4jB%eeLTdX?X;-JgCrdwzbuZqvWceg1a0zS`Lx2P9u# zJU;(gEx+9=>-s<5y>o56XK&B@ob&JV{5vaMf_qyKg&wG;*y56K?x%RhhX;&ORy+Q& zKGc;wecR0Jz})%s*H6_B&$_tC_15n4^~*o)+5S%_dtSp{<5|3~Z`^17_V)I3iS-d1 zo!osE9FJS@fbW8N{*`0Zx4(DQp1<*(4>G(A>MB3b;hGV%+rPB)nP1;DO{?{1E!9IG zzh3;em9eTgcV?OVG(M5*D|TFBd%E<-1+BA^kJqnUW)?92gwfAasoTsSRz06^c7NKQ zv%kGlPyai!IeFEQHxG2?`E!?r&WK--75=t$S76|`8MCjk%}}Ta37K;F=Th-`7q6X_ zp8H`>?1Q4v%-h>^t6qI{4+)CNc{gY4agnf9|I4Qr6o)_3Ucc+w&3j_mRWBN=Z68+d zzEJn>-iErh?|$8$Zxedw`AmkIyVs@|<~aP@SU-Ee>&%ZiyWh3xS2un5_S0Q{-4=eo z*%mt=YJCw_zq)R-;y2UzHE-@6soYa??`hY|n}=t{Z~CFS_uH$}eiirhHi+Bj-`^I> z|Mzv?Q(41&jmvtwO7;m~E1y^K^LX2H`5oWq|2qHLd&=JY^&i)SWk#+{ezerO8#4X_ zDtZMnHZ{~wuD%3c`EPNYDcODb>va2li(~tg?uAU;o>*9Zd-~kP@_#<0TUBnlvG>I1 zibX3ce0sF>)ZO|6m*0PpjApenHug53)%7nmb?f#wCEqtD zvPe&vZ&cZoqhPP1a$}}k^&`o@f9HSSxw}$M`^;Ob`hTzQXP;WaDP^%?|K^%^ted~i zPkmqUYe)K+1ro3F=@9y;`R*VpX(S8wO_=^`W&N9uOrlhR&bXD2O>tQmviw&mmzPbIq z=kLEgf9@LZe{A;h!AryGN8X&=-G21Vfh2Om4cOe58h>=hO8MOB8Z%$1n9S3!l+YykK*Fbg$j^1wpD)uS#9D z_egYP)zah6{#Q8nsP3EZJilcRhjsP$tl2AE7+g00hV{wIx*8WkZhgPBE$7|>`MV!w z^|P03e5|H*;g04FGii(SC+|JqdS9^k`P%Tfs(T>`{1?8xjeh+#^Ob~kSe7Cx%L!Y5pRwJ& zweoUX)$PwLpsdOOCK|VaHUNlq^}x2Pq`NBArp$VCMK1T?AMZH_cFFEO)pB$H*S+$U zyytg+kBy32c6SN1>JIZ~%y@8b&AsHi#kV&WZ{KO~Ks^1=gUE8`YQY2L z@BgfvSNDc7{o@{Qy^>WIjL6 z!cN64*;Dto%J%o0&F2>X?Mt~{`uy6p=lO@w;Y)JCy+r40e+qxp* zvhT*?UbBKe`T3T8{&_pbDpPO6nhQ5X>RsD@y}a7by;XB@(ES}cZZB(@&OCRWZg)4i z`Zl-D*$~NPhZaexy8K=h?$cq!Z&t-3o0RJ7o6A}y&6b~KU6HVV`RhB~`k~u658Tdr z>6^RwSkKpz*uM|i=T+t#zhD2MZenKfu^$Cb+5H;s_07-wmb?1)?KJz}^;@czKGWTC zi1Q-9m*gVb-DOs<@BH_fVRCcNmaXCE*TrqUwD(4(j6uPI;*X8BN!n-4uWj07H0OKw z{{8c-zWU{Cc-<#^TRP@A^06#Y$_@?tOsjGrqf!h^v2G7O{hVHP?x}tLzO|*V&8y~_ zn`|z<%@Y92;Vt_8`*-&Bb+J*~a%SGE|6hAE>*c!z<*&aV;K*al&Qi~Qmv`;f zEOk{?%gYZAHosn5{yqEb;=6Ne->0O^()z;kBHH;R{76KH%dBUf?>oU^&pPWuP3F?I zcJH<2r*nqRKA+~u7%DaM$?7{c)!!8}6V@llo>+e=K7K_|W$1)!Z!K5-e&2EV#lC~L zsup-0RsE*trWTOj^d)o|Q*Fad4V^RLrdOYBPQ6_G(%1f**{e+Z?``fb7K`Uv6z(~> zI4$kX#cyk)O?7mAH-7y1>*o5p#d{@Z-rDfcIQ7lFrL~cf%Z%znn;#!Ndd%{5m*1QV zp2gx%rfqrFQ~2bBW3i3i^St1~!jE6ezJGibI?McjQM6y&WHnz)We5ArOCiha6YCC2 zD*oJ+%|2v8aA|wRB43U#ZvE7L}SEs6A8@U-kWNIcS36#f62=ejgUQ zHg61^%Dh1ow=~pM zYwe2OId9H$U;nJ#{iXTzAybQc@v}G8K6x#&$h>)0n%?O(dksFHu}`*mZGFmq;>5st z@5PSyo7+0%_y2#${{AYj`Ta#3AFEp}H%_?VaP#E0O_zd%m&Gri`d;_?y)!)Nk$3AC zEm|~ZIXl11irqURKcAI6{B+f|#Lu>?w(rz1J2j{HZrPg~fp1Mh@3-?wuQPnCmUVHn zzh(KNO|_GLeF=SUx3yei^VC;&ul~Aw+kKuD|L+=)tX0N4ubY08nE&7}-|61m!^p?& zMQJ-U?AzLu16!Ap?wjy-SMRUG^8c?b`fDn-VEfeDuiMU-zqxbwN$s3_+rw+-d`o?9 zvSaVw+RSRx{KVGF=ii>M|1%fVn3!F{@vVuW+}rZ2^7`MFXw`Z$)62!jvhJ)%RI9o4 zjdSLyQ(n0@HyvGRw?FwfpL$2KKGU+fvW(KJHeEh9*Lv=&50lmX!&Y$~XJKR8_LA|( z%-D%14;&#ZigYbsXdnUVmrdnDn!THx&I| zD%*C*@KXIfTd#g8-n7|Y{?_Zyud?=? zuWU_JMAS69K`SrA-IiOh`-DpV zG`-kWzO&6v#)@vr3s^jR)BLHIx1IaO#P&Pmt$E&^71!gceLa^IrTX~z?CrjM`%yz1 zzvP1N)yGclTfV8d_;!-VF>ostOk@NsaBJ@meN{12ME2eCg#SiU!)7z=U8$14=*udz zr!W5hd*mn@&Zcc}!+&PG)7hZvgKPfoc^6a>u=P)t&xw01Z*yntJ{BV&`7C(lj1LS? zr_bE@`K@d@^O=z7srSy5?0B|LF5mg7^tIY+iyogodve-bvHf3~oSYAvWE6Crn_b)3 z)-Um}<)!}aKVGS6Z!Y$|jkbL(Zy&ef#{?GDZ|l~+dlz}JXXdk>hw=go<`r(Om)17< zZMQc!V!PkcWm$C{od5dgTO1W$Aa7r|>2m4zoio0@xTw55KW(3Kjor0J)8h>ke@{*S zl8AgFqpa(Kx2OM?OfiNZOyKbR?2J|B)AucKzG*ErH%I>V^f2v&cW$?yJmV|eVg4dx zVejSs^K$8hg`S($zyJJ*I>1^p@xYRmms6V03qCXpxcn<^fBMe-*>i0wFL9pR|Km}& zRmFz|D+}H~Z`roD_Iu{vdDizit}WcF{yXYM?Tv0pBO{|P9}e?dJN`O!$Z6+$mIrlv zqqH;bJ0A{aJF#y$XcIrQgng@%AoM9UG%;%PVyAH4E6M7ynd#^#t9lxa4VHJB_Yh|68*qv3%vJvsTeN z_blEv@#W&FWviHKkIjqSG(SK3HmLhvd716*=l=aKex}d=#ABX#N#y*Vxt1j_7JRlb zF>$$QX!~ky_N&RydM3`8pm9IAoZGtO#R19PE7q*JkUqcejgG(c#B~h~4qv_H7QB!% zJh!PoteXFrywUxOcXTax?ysKajx<|hwFI=W;^(G<01oi5%$D8*^Zz~HE@k`b^KD-< zlT~k%f0tb^`%&;$OY(3~yU9$Y(hRS?``Y`TT&=EKH($o`ZH3b6aaQ}n?adp@jb7y53x>@#J1{hU6I)?6|M{P-DW#n;rdOrz z>N_}^iY{BVXUqE)r$wHvym)kR^{YuMO+S6tp4PvArRw|F%Jso3|81ISw@bs;r&U!? z)*`9ti&{y((l;+}K9l6D86QstT{b`B^DOC1aB%f}-{NEMZ*QNU_owLXeaBU?S2ta~ zJp1yZ#mOdRcUXL97sfTuuH92L^*K}147sn)pI+PjzOwo5(dlPCpQ)a`^XIhnFV*e; zZ+#YDH+AQN8`m!{wM>q&$#^CF<2`r#WZSdr>*Lp#->(f%O-;=; zvt!=scVM4b{{Fw)w&mPh^!Rwcb@Nr;o7?kBEZ;AcduE$@KN=~j%0xbVEaf_~{=Vpf z{!LmU@(-6MdYT0VWv)8gp7HdYQs~Yl^J8Tf@7^c5&aZscfrZY$@KT1oxd*n*RMRW z!sB_zy{K<(M#kSvUcboO@l&k!?YH+c1pck{yK(3CF=qCeO+L%>8sG5E-2FTE#)fmB zBdeah`8?IEXi9bH-s6fZ51SNz68S1`;j!&d_1*osrlmcam(wypqh&kV`QpH}>DJw95Jtv9x~`?}hcTpF6d*wC>zJR}u5`Ur~Bw&HA`s&$jP-f5-Gq zk6+rsR`J+HuX}H=um8>-Yw=wuKQ;ns@W^2|*Nl91c#tiq=DwkDY}WZ}S)Z2NvOl(* z*FV?DBkI=kTJxMccOE*)=uP*|zMg-jrEsf#PM?%#!@iUHda@|B)J-PkOP8n4y0rhS z*2L>GvZj8sp3R%`{^n-))nRLc{QUYp@43l-ob9br!s-j}Z*BF~4qta=fn&2t*_()T z`&?1b+RD;#H;#$eMpQ@fys_5VKBYz*2jzravaQERnM z@U?$ZvRWKhKIy8?N|@H`-+AH5!e#qwo~&9I_^)vKwKwZ7{d?S4*2$*&Yj&=3$(ln; z>-VH+-I~30(_`!37P}u-N?+mQ=KZ{9);~tZuCA`2{&^dvvY1{nHa5;HeZTkjwz&9D zo1Rw&r%&7aahBVX>uvY)|D6ionsf8@t*y1~J2@=;n}dUSppz6-1Q7B;;ubB@mZ|M9roy6~2j_Zps^bYI5x_v-by^_rK{E5g?PD_EL- z@AjEb<peZTI&E=PPkJ{ebmxowID8JNeGCI(yURzDQG5 z{?Xm{+LEAioZwRSt(HT>zSv4h$P$spKGg{q-hbY(-FB1n&3mi8O4cm4vv%KHaZ-97 z!{4LD=dW*BIr+=OSN>9Wf8H=$T=Mkk^vYj146Tx?OJ9Oitogibb$HF3eJg_M8usu1 z_uJe){MtU5+&f!brOopLGc`r!tRKBTZHQcsOk}D0(h+>>z`oov53`nB<|}3jn-UMR z?fw7n_q+ohv)?Y6$-J}q;WtAKjT4r3-!~m=%kq-nT^szn@^*Of_T0SxZGGqWxy?4q zy|ixbZj-7j8P8>E{`h#T>Ww)qDrmSu1L)HgTTk z?+DBc?fv)s=iyT)3?Kh$naQ!Y(q=3F`rrA>TlWeHl|DU`EiJp(z&?Kco-ccZzvOL6 zX4W<~DtrC+>H8OZEX6f$v0Poh_g~ub^xmC24jd18QoeoDr6Aj%H}+56tABd$iO)MK zFSFVH{vy2V+pgInQc{ani^V+eNO`-dEDQylclzx!o>cIS&CQ4x_U zTl3rR|NTFHul7KC=-qmm|Ecdig`92(DC8VGIB8*1_4Uv#TI-_zUk%HSj^4d?YpC^= ztgY8VMb<{WzQ?smB=B1tqmzOnqtFRC|9{`h5AC(9JW*4$`9blUr#m0tDLz+w|96#X z<9pll_y6l0baZ@H;pw^Z&->o(uh-tbXnnutwe8QJ{_hOxAI_RIC*^F?rzKy-=Y^kK zxM&eud)Z^&>nGM^uQNHmdd-4US6)6pb#3iT-fPdHO(t*(;7~BA`@`bt?R}$__P)5+I|?7Kkrdf|o%3S0 zZ1u%`Z%cV^zphGl?XSMR`StDjW!1e~6R%$k*u8h%^V{9;?Sfa%tj~}Zd?;AD&iQv| zZ|~F#8v;&lXfiatR-g4G?d8NtDSN(3{(jVb{%+2!ZP4&$U}ULbT{Hh@7SrL>cbl?a zKfhP|sat#P&GYQ+p8KzOL{1G=y8XFn?add>D%%hITBfma+AM|F&+Yq{sE41v@o(a! z4A$4*r&c|=C;t89pQ(x0{M)6xFV1iNnqKjKe*4?neasoRbN@#EOK@EH^}YS?)cm-0 zIGj7^i%i z5`4y+^_$_}EA_#@t6mCK{=NF&BQtX4cg1T+RZE6BBh#0+Zocl&xV$iv_1k-Uh5i5T z%0Jcr{{J4&=Jv1CXZzdy694&dZu#kVcdK9V*lw-vviY(6zUTaVd*}S!|Nn8b@3~j+ zLh_zZ-COyy=zJ~zsoL*}T}<_i8);ZhLRJ zJKg@j(8EgiW>IK+2hvgUP)L3eAbDZ?^73Pg7p~I1wf^A`*KV=M#3@&=ooSh>w&!kK zW99wEto>yId&}S7D>}?;?s0!#t*i6Dd#T&^PBDW zp8pv4-S*z4-1pn0qOO0OdDHnV*EI=eC#N&pSzKIQXHMrdnUcc(<89X3pCNv=+rCID zJKUG@Jm(4-^JQd_5-X@Xwk@sm`h4YVrlyp8T?RMj&DFlY-^NdEY5VDw&X1Sen&q=+ z!IB`aRcq$wuia&+*eE0`nDJL8T3K`+!_3_qWB&b{FLZOFd?xFGuS@;r%jeBiyzzUk z?7Fo&aTf6`P+!z;jcYpo-CvWd&*9I4KmS1JN{yKZ{f(-|i3y?)wy%&T~fwDtUCXaWFD ze3`f}cz6Gm`E#CEp!OqJ!hPj|In(2&1~2!WR(#&>aLmIglhsd&f3}}c`C0trwli<9 zy-~hqf8+am?aRx2jEtFX@yOR2`OmA&>)U%%(|-Qn?=qIDuTB>I`VxHRhu=JtxM}r2 zXP)_+voPoGG|i_^MJL%6G{~4|wS0MV^YG3#rfjik?Ek;5*nAfC0)q<^9Fn$+yu7cz zcH!Z=x9hj<6V$f1kDsO!sdRgdr1ac?{`j?9|EXAOtbg3m(J{fU_ScCA2b+Bx?&RH- zTl{zB@3#uO>t=oU`7mKmZC_ef$+NQGGIL`uRTufa|2(%?Dq`d7SBblA->>>+_xtki zh~(F0yYJ1f(!KY1oAc+Y`)|G;yOnd&5R^I=!^4DQ%hm?A+x-6zNJ%K%{+#@D`G1Yc z6JMqlo%?vO=+6NU&ko*cH#B%}UiYY6>b{A4)sxd_T|XWCq!qa{vVL3dq=tn4D|W^^4UQQOg$qwv^L9Ng`}ubLyGhdPci)Qf&d69HY_+7D+@%4YVu8H3t2ioBjQ09I3ejblk^W$9^_jhFo zEZMW?PR*^y8~ZcszuCP%u=8em>co;|e(#goFT5=-iT?jQ`pb^H^WJa#wQcUVHJ{%E z-M9N4kvzX_|F6uZ&tVZ>_FG?6oIUgN+OAz&TrZ}3&o`{SW|qG#C=zi&OQV_SioZYg zPyC5^wUTr4)M%#EqsO#3d9^0|xZ%~=^&vv|47+EbXM>0g&y-cK0zR^|MBA@_b$-*e z^JnGe)bH{Yi{0uY@JcYFfU$zI&J}aJTTJi}zhiH1+hR z@!S1y`1bCu_Aj9g=d#xAzr7{YWB0!7&EH>EfQ~QxBe(SNidCzMzFqzPdvUGqt-f{U zp?lV!%{%`u=S|G++~1dXuX}HI|65Ie_5AGhw@bfVUQ-?G_2A*}y!*2^Y%oY(^!@a@ z`?n-te!Y1q-Dkcj)0c0t4~0R)zn~&7qnh#cU(eU+R-fBNjW{Q9`7e1Qx1mnLCct|4 zp3j???u*W>yLVMI*8WfA?xXXeDG(Br4$lQF{;cL={B^F-S^{>=or!`$;VVgAnarE- zuGmTHS|$EFbaat-)_0MY_xG>=^78KKIrFz_M;jTJpO`o2PTJP(86Sl*J@2pI|FiGK zr8}RVT>dW>8x`~>+xyiuUpBrM>bBM21m^ z@2aJx<*ZK3*QJ!M-@IE~RP^Mu{{AV44mk;**w(-E(!}|_FK(EqEHQpm|MhBk(TfX; zoSd91FV7NI`gAMX>3Q7kU9WcgZ$EwNRNsyF#Zh}_SFM{>xjl3J?fGRE@!R)`SMRU8 zRl3*yb@X=jh1XYYK3_dwT2@xqIPJ`YA3uIn#d~c(pZjvTUGlFrfdb$v4MhAAUZHtk zoiXulRL!P;XVU-stWdxH{c~RO@7b3Z_VqS_+zkms(4n!@9daA)WiOlY?bVDrm=TTZ z6edjG9bWSDPxsQ;#2va)$^Z7%F6x%4oqkP;T?=JU<~6I*+5;u$jqcsPp%>+1H-`dT-nMliSyw(^=pBeaG%d{haSFE;=9U zkyPHeapN*c+w*ycci)}1=C$#%^HPv4m7s)mz`k+Sq*$R#Jq&x_pReitdTr9K-mQz1 zk;+m~PJF8xAid!E?9I1M&xU%uAXFj!d7Ized8?Zj8^Q`BP%3p`X!O%GSWsUttmN<2 zQ(RhOb@=zEr>B>$SaG7|n(2bI-tMBjY?b;}>wIUMSvFQx$Mm)ynJulCwT5@M{NFF@ zp6`8EyJn-^-t!m5ncqCxdq3{Fe{2r(ZvMN=8LRHD|L(qBSV$=4<)x+9%y)gAzGKI& z=ZiKL-uP?wb>;aP`!*~%e`nj7Gs{*LL%Mii|G6))DWBM)((~=+ZA-J#97I6{l3lQu zh3WQc%yzK72!1<=N&omHOSXW%*_RnP@ z&vY|?cIMW!^?4q5Lv`^j?*(OSzrMZdg~pD5U0iUeqUYVl`V3UCe3+psx|9Jl=G#lSFbKIzL0-sN8qW`r>#q#Ro3gBvF^#6zuxiF zv?$>Bb_pMpb zE!(#J_jkGF-*?sS*?4}{Dy@@e&P+Kw+uVBdh3Zwdy>lSaE1tcOTR2@zeHY6??V)05B4{l z`xdw5VSL)h{i5ekE4*Fn9A5w5w(E7AwK8-D2b4wNSpn>%j8+FPudbH%Ht!st5bda+ z&qAt~ecrRj=H|xa_L+)*XD?n;D$2xkCTlIC?k|iv{6Uv$o^F`fetg`NS>vns~#eGb2{m1vPB(lF? zX1@FLIY+JAmzkH-`w{+ym)%g)9J*Puva)x7HovC(YUU|OEI_4@i+cBFhwtz1s@h$f zd-J(0|7-pA{BP_PEG;e1IJ{p_vR9P%0%(Nq+xz?Pf7M<|_nU8v+8jo)R9A>&#ah`r zizcstY@tN924??(#Ks>-TsnKp%pKx`qLeImTKYA_rOSNZ{(|S*ls@4L41eF<-Mw_l z5|>4b7spC>5Dres7k>jE%b*s^u+Vn+FC~8$b`}5wqi|PWUtdY+qYDe2LHFT=hK636 z^!)p{a?`Hh<_xJbN7fOA7ds)~%h2Mz%X?U4o?>W2m-$ULnk5*N( zIb&0ux7FPm*>IG2J3fu!|F43ayZP%7`zTTKLV>S>hDF4o!_KkU{?eBuPkVcLsVFEk zFzj8u>Fxa)_nh}mZ*6T|$M)hY{v_F8&-90PGv4Ii80KK5V{#<4^U|fDm21|RJgnqR z$o@EY@11+^vyPiQTh&lk-JmBbDyru4KJD?ZGcPwI6;j~XK_U*wGo~&0?%rFB9BL>Y zQ#rup(Z0h*cn90M)vH#W;rSv^Udvc3xoFRxJ6C_NJU_>-8nqHd(fmg+femj29cWq9 z+|(R1RYP0bc=NPs8@bE--oN?0uFNetS8Ks{zr&yN*k62|`8b;6)|YD+VMi;YXVHQX zZh-~%tMc{5A!}XH(i*6(HrK(yVF622_iR_@FH$?UF@MS1<{SN1eZj-Z*e}woU*_$K zY+7^k`B#b(+W{`a?#Me!E*vNg4V}svzx$?M?$-4Uf6p>bojP?<_ib0a1;alM0sQfB z%SGWqfl-uw>Bi<8_vT*Re%|iOgfBpKpOx``Z`ryHXi?|WhD@rVYR+ybrI#52R zY?}2!TxZZX>Zt_;D~BDpd)KkOtxaf0+4L>W(U(8$xfg66Zie4X>e7c%ft1I_#e zv8)^ywriWuMH=Bo$v^J>4!*taHrF1dadLATH)iJ=YiOJ}yDW3HEbA9(#xMU~{=IVa zEW=*HWf}geA;Ib5)zGW!JTp#M+1SK5IXSs7-}v?@irwT&9#dmu6^alc`*PNLc7jvjSe%><3ZIU!piX zce~ww$9q%X-h#2JP~Txa!5pIC@V;N_IeMCgJE!9~*PiL&A-mKTHdfAE8zat}P`ze? ziDK3DirZTi_m)qcI`vs=$Bi2i#?pJEnJ*Bieh8+rCAVgA?pd?ukSQnc+3XuuT3V-A z)|s~WzMRGM>rwMxrr80 zA8%%borZ?TqQ#3<)zpq%WvI=J+*$eU*8f#6;OmExiZ5_7e2^ia;81UJ$8{ZS0T_B= z_JX1D(k3BIJy3j1pD<&_3ziqw4<^01kNBmFWs@^N>$ zSibp%@$&O>xN|CFJqyQ$-;0k~g3};2B4|VXei?GcX7c z5*GIDxc9F8{5tgo`nDMjaqpMj3-<4=W~?HRGA<}JHr%?!@*;YPTPlwB2m@nu!u54J zC(qj}n3}dP&)LZT<7ejf$#drD)c*QnXng+nO_AlL8yec4Reybzy3f<${p!72$|7#{ z5iB|um^r*Zw?FsCWqaJ2tt7BU{yQ2dorKareDv0x!f-M*BPV+ zb(FrqM619FbV}EbK**q-};T92-o3N*rJtblPymhfl&pFJWH&0JfQ*+Yf$;wx+UiIs^ z$Ct7D+Dw1veU9(9y*t1Bx8BZ`o6oMEoV)b4r>Cb;#s!69{5t{Yfxd-}WCj zi~H9pFC2|k(+;R6Eq(Ske?@D0mP7pX2|Er7**-|J-10V5^OlYKs;-8?<|{MWcy#eU(dljG;x=IyQj#ne(a*}?&7PoEd`UmEesnnawHB-;}1wuV3!fUH+2inbq$6a97q^3F??ZMt1ELgcTQAlf3^DZ zge_vc7yM_N`P%*c60E7AVeorTy8ia-Z~cQGevseyyJq{=S>Nq=&zgtqdHr);b-sDY zzIWHNFMX&her$yu`e0?b-D5xl`?k6I=VEeYayXtC>fifUc zU-m*#W5<#*=rp>=`Ed9ldQ^jJQndcsvz3W6k~TgeI*TPvio(dq2X z>Q7O!3$A}CEiK*3nRxuzu~VGta}+kGot^aPQIfHpbwghJ#kaZd4{lGHf9-2*&FxQi z>;7hay!SkI|H9I>@={V+=dxG$d4H3)D)E?C@rW~Wd){2mDX({a>t@%@T(0}-l{wpy zqeng6+}e&DIWnX0m%TkV^|2dI*2kUu)FURAZT3F=>f^_cMNg-O&l1?icBJ&; z%}314eCMCVMPJ?CS=IbX>QUYrlhQli?;Lw|JNc{K@{Palecf~YwYB^Ax3{vcSf4`je z%~qdp+s|*22ByttdtPdI^cQ!Yw%`2(ao^UhTjlG$ouB{uw(|C~)P`fl zzkB(d&tHH2!F6We{26&X4&{f#D2f|w_^VFd9SV5syn;8C-?O5SbjVrJhxzfbTV`b2Wj~2 zA16!Ov7hBh)^nadyK$_?Htw9||3_lIR`&VpZT`J**0ox`@>FKX?0+)l1{ASl$ygQ}dan6CPVUSMt>c!NpHz*4y3_Z96N0 zRDv5YvAn1hz)`?3vP9`_sJ|a~^3KlPUm2^iRmu$R@TFxJ{DX{Cq%eIs=kw)j&#rwJ zcHI=uIQuNGb??@-Y2uS3*ZZD)y)){K;my}+%fGhU-rf`I|2rplqE`@xV^9Tuw1B)qo@ZNKdel4N z3{pDSz`*z``Ny;3mk2QwRzozC^tJWV6(tX+oN6%)tJw8*ZI(i`^9!rrHL0mf-`v?5 zd~I!Xy3=DvM@QbWghQWrc^q!*Y)doD&$|%wx>Env%DuVktNC5}Zzg{F)mMEz_uQ`X z>azX6R$kvw`Z`QgQ`7M53)Af{jy60ixp&6u*7ke+e`V})cJ#>G-~0MuPwB}`x$fIu z7$XfVXV^E&abDy9cJ2SSH|uL>ZuwhPwtjhT^mdQ9yu8W0Vj?0Yk?mZitk3E`P5k2V zTGepl#!tUi|6f@>K^LiHvf9bO_{*=ZSps(R9(uRuf+)+rACHP>npCcObMox;Emu_b zx2;jkxxeVQle2T`%}uGFPAK=E=##Z}Nsr0TyLe!ySnhGYh34O5?pKvX@B4i_Yxlx` zCHvc+mtL#Xm72GG{ra`XE(Pqi5|eeWs@ml3=!XE8F(gpTAdQ z{CFR7%r<@#?BL>`@ccc`6@#nO=HU;P0c>&#vNKznOl2dwN>AzWTu5woIfh zNn;sk&l%r|64;(Il*nXY;*jBH`u+X+$!EEdb?h&sjV=}JVB6x}C!?tywkG2n&vRbZ z3(~KauYULb#p^4-7aO1NmoRj4a&lU-YL}N2lk=?F`Ll}d?=kiMauaC`dCPnUub74- zZddj_xMgeSu7C?jPftlXv2yu5t!^=0P&J(X?d!2~Pa|$~v#_#yMn%o?nP(Hp#xE6PExhme z-h!#eA5Y|+y}jEm8j(R7&nXHBseF3e?fhgBr?0!;wl^P7%=HiV_-6OL&MhauRpIsR zsck%xYA5dotE!oW@rlVyu&pjTJ?-r5Guvafey#ZPvi{4A$7}DOWLmOjOUSkL(b4Y( zl$95!oVc*?Swx~^W6teeOYc?P-KFX|zwYmujdQP=H@!W*zILank(QT{QQOSFk=ErN zarfe$|2c8OWA)ox$uq-tvxfbSV&juh+579;#19)dZqD23YqULgVpkW}^F7PL*m!)V z$L+0}{d8XSid}oS4eTz5h>bTEEZc z(Tr&8KX3nUdAZ#C*8|0%*icpbUk7!+wq0?THFsM#ue4e6)xJM9KcAj|x2F8Y^0OAf z%jTNhmD&BieE+1{_UxrgN~TNa{j=Zvb-v~K)9JtDb5e)qzIzfY&dsqX##<*TjA=jXLr>-T(V znq!i;Xinib%V$4w@9#eNYwkpbzk(5O5Pkgu7LE(nB5TkK4EQ+7mN13t@M&vq&v;qY z5ZC-=Wf;ffImPED_S^r9ICbjOl3lyZT9Vt}L|d1g%b(eB&hGx&X!D(4E_pA_zrXKU zH2ar07WUoW{rP|CyxlfW6ET4A@LW(sYwbjBd7bGGYnf)tgxotQ6*=?f*QPVSgx+so zzbnjdp3&8v$39&$vW$q(_{jNDC~2?9tT|b%C-zr&@5w$}^Y7d2|HZF%ZoG8sU-;UX zJf<&>*Ump{ZsVD{b#=I$;hMz5ZdSi{sj7Mw6?x5#eDb#WaQpRZ+Bf#!|7Ese?zeYo z^=|IRPw>D0u~H?vv09h)H@}BZ%$gVPg&P|ijUJ!b?0ew<-0gAex1YUuym#vB{9p4} z+FLA+ck{_j>Nvr1@%3z@w;`Pyf8E&qeYWI>xn0PCccG!7y1x6a1N$4~6DAQ2deCfV z8Ot=CIF-G>m!7`TnY>oOIc2qeOtbQ`2>H&tLaCRQcorR#Oh2*v{l07_p{hNnW`%CF z?P@!$`RI(^{8_WKp3g0x=QGD5P)JCKr}rNJ^Lbl^UIzqruDLx&^Op}&Z`Er0fqBfP zo1QydpA)*za#FCL|DE`4pi>GD_ScOUPS)SiBRk6Y4Og&#Mc$12>s z8M*1t>-DoPmu!BuW!wL&+TkaTPLE6cC1qE0M3Av+Z`;DdZPz8e+d}ov&pLZ|cgf~` zoIdd)7dB;G<$CXYHg105ugFOgW~dbZ`@3dM%tjwRS*wggpC7CFO!C&>A9U!@;U{xG z>rdI59d`2DncUJ_z5V_Zve)gt$a((!-zUmHt6mD7ytB>M$;mn8#f67Ouf7-Tq%k>OQ942ZPzPvurJNGQwlsIxI?_nu>cT2VP_vf=ZU*dNEjoZq6^Vdpa zkz>b?pB4>|QB-#Co6^z2Va&Z(Zt<4+4fonttk5`l;>3j0db`iu5uR&#X!XCLK!$$fiy0C-UpzYPTOJyE_0tpKeyfL-cUS6P(~JMM)#ms5`r=i z)$hdZHyKCe^S;cVJzKfDxaf>V8^3(%k&LSEFSP>=FFyKM@ub_8`)nca;@@Jt_iwwV zZ~eYJgW4Jw%m1;KYb6;%l)Qz)Trc)= zfJU4be)&=|)2?<`kDM*2?Hu!d$E{uSrvB9{{xQKPM&84c&tJg|ClmGGf{T!?0etS=+!%kaePm> zSx$ud{JK92=U6@F>Fn&CDyZysvg>Jlb@<2ZyKDc2uZ_^VeBS2t8HM|6qbI%D9Ot+7 z^oGL+f5^_foqG1wRHM2}Cyi2GY*4P-E|nHLdD^EbQ%hv#QcucZD3AV-RPSe^*no`PbGbSJYl-Mc5siC0KN< zM{?5Kxw_Tg-WWPo-4`wm^XU4`BsJ~&&FAXAvsBXORW3Vn^yti)&+oqToIiKYotVg9 zPlLA4US^B1O`LUKvDbz>WpRh~L#Bmw#QeTqbaUEmL;XE%t?iw9y;EO2dSun^-Y@w& zM?cQwe&qW6)QO@D*BSOs3%pjD$MWLttN8Su>kNCvc+cq1us^@%wY+nCugUA#X6vT= z&NiD-`nOGgE^AzR#q~w^ZA?>61Z>_{cUNlVs#Qj>b^j`VE~x%Gce(M&*W5g|)!(Pt z?frdi<)nFbH+GgweOkX}i`+7{uD+d1mV_uNXQ!{uUm&#`sb@l{?%AQbq4IH5AdIv+8xO$o;=wtu9SlaQ(v`*#+O{9=x}AqRedF zm9JL>E`GA*vY+wh^V?h3@B6(WYir|FcW>G(mAmLiK;YcRCp}N5 z{l0LpIjH1Cz})10($(MJO?>q#OW4fc&+nt{o9o-6|K{J`=GxWWrJ`jORiajD?XX^7 zglEIPK(Eto*jO;^e3 zF4&$ee(9uiko9j>mg*G;4<5X~Q-g|7u5md(^f!+L3!Ue2jcj+xj(n+Lkvr?^b+>ejO5C ztzxczyyg7kr0nyT|E|@{`}+Q4Maovw;@>|wC#Mt~3%Hp7`BLr6W+R^m`!D_an|XSg zZ`z92*Vma{H&98QvFGzO>9qJ`7al$fuKymDytm^){zkQ#-&Y@TId1j*>6^@7aZjS| z`?)pTQ%pvT`Y+&YJfPNBjPw2-2FCp?X8BS2+|$?CD0RFIPmWX1{Ge>05s*l~$M5`>eV3u(I@us)mNgq)C%fuC0kIy5ycb?4=z9OF2@j*WHh3z3>{7h*tH?@nEWt1H;x(9L4^_epZL z+hL!ZJ5tlT&t?0i3cumwFlp|>M=3ReLM4gMMcH4nQc~QMLfK{CwuGdbUA1F zT*lMaH+S>R=U*c)rn}9TMQYIf<~riacH*ZxtGCmaiJMQpwzFMU+V?FeA|gR=qkGil z`%6S~{@%N&YkBjEzC}%3cI}-v^?z@f28D+HzO>qQam}#{iD@0Luhkf@{k}# z3`par@Y)9?mSNqvx8+@k*&YeE9I(cCH(xcRpN9I3M#m@?v@$qDZ;$ zkI8sB+iCsv923*)1k_e?-e-AQ8vFgF;o8dql6UO`mi6syqj_NnOw={|C=@$-Q2S9+wHk*yeB7|IHB?S=;M278rgf9 zzE}zGjn%LHARuXwvEhdO>-BLr4ejT@KXvQjgqxe6TU*zJDJdx}jozMTSA7#{-O+-? z#&zFkdmX-hND!?6fpZ)E)HWnMbh+9i(9qCDioa&flG?mv`SR1H*JIVw z=ax=8a_pGbQc;GB$@h+y-~KJ}+MO#SK}}7~E$z$(eA z($|Qoc-UI>cI)+1o$B*4T34=`J6$M;d3Rp6{nwi_cE8a6d8jH3sZfzs{_wLcYiD&? zE9b@IE;Yt&8QHOiKkwhrmpS*>skT_To131WDA@b%a&qj-H4z(qxVX8`PFOytXcmvW z<*s`V{b!g&9+RnWvYeLPdd58eRzUvVY41vQ|G&CAD}4fgH^=nO$;)OuToW5BJ?*>P z?ORt@pGmv_k2xjbSHk9fSx1ZBYrWm~@1J$Pb!}Yj+pm)*8m>9_zHH&O_f6^Z%NNSj zKeAXZhm;pNOxzbde19$L+|4Vf6COwb?682daclOqlP4}FKiz!v^wU4a>gIvFE89&E zK1opNaE{zrU`pfjKo9*Glho9Ew*LtU& zo0FL~FFcy}O7-sR_nYdgzuvsDxqA7F%}xl*UsyEyhh;hJbE?Zf>mXlK;pJv+^M9jd z*#8@wzF$4DU0!4T{{->d(SdP##sB{H)V#kYKWpOoT@TYL|Ial~IcmgvP23|XY0(^u zyrwf2k9CUgBs1E6e-r%dd8)bI)wlon-`rQx)q z+TX1bv^a4lWd7W}-pBlBT$y)xu|6W3>ghN%?Bl*~(}t@pUn1IAe!nVMXt(O=2aUBV z$pP`#+t+Shp1s3bPwyPdK4)j=vunP*-~WH#n>#x%uh|~@g*Ka<^biR;|{-`ApZZ}ImcrT|U+5Aa>QpWXUm>z_wIxiWQZ z?(YfP9j43MxBthX{ZBt>ubXt@1jo)Fm$c73surDkt$WXT+rLY4?r*#LJz({=yYJ%D zCxKd=vY(gnemy^Jf7MwpOVh6E$?@XGx=li+YX=UHH z?a0piwm<7Bm*ww0+-D5T^Y183ohtg3uk!Az(4tpgZZZ75bya(<_(a>U*Rs#gH8qv1 zd|bc&MEYmDiJZdz)3$6e>Fns4Hplj6+OwbQ_x}o7wQAL^VvjGa@V?)LsjPheBjgKC zy?j3Ve#y19_is$qZ{LWBT5w}x%S4B)_m0b+&RKId_X_h_CCGr#fsHB#uXnvpJ@n&a z(Z89KWB2FqUZ}Q_6Q0DsVcCS0-$G8Wi{1TX|Np=1_xyO&y{YbR)yfTN(Oa6ot>a(7 zZN9?z!ty0cPN+_gQMw*iy>@2hzD=7hoq4r>`clT~wU5gxKmTR@^iw?kgt5Q<)3VE3 zV2jRCPJIylKM6d#6kJ_ueTx{dKO=pZjX!UW*YaVy%#bSxJZG{%`ra z`_E2qjb=S@5+RAk(iN}xz1CdC$}H~J7q6+0-LC9gas5-6l%2AH!G)H+zBBI4TDbwV zC-3Xk@Y4;9%uhDD%TGQ!Uw>PZ$kkBJuZh?kd2P*YgFHXz0QH;$W|wY0Dcu{rJXP5n@*oe&&pcGdG5AcS?zZH)ck*pKT8fy z-*l)-?90pr;PeP4w(Me|My*0-j%=(t=YFscgXSSiK+hTv-9Pz z)vB5+qxarD78$RbSuc9_>*jTnCQS;e{CV~N$;bY7+PBN!tobfe1`SSlSU*^H;14VJ zlJfieJ{`QH|6~)l-{cJ!0?cQZ-@5c+yY1~gY)94oW@s!_TsUdkG`0D4zgFhl*x;z8 zrR9>o_Il)tw-0{-KOY=yPW|-cWZJb#-iybNAD8AXy|8rcq0djJ?Y#H< z%^IJJ>5WM3O*^KmOLxvSb6B6eSmA-TLD7>8Nu!b(H*3GIe?KuiZkF=vYip-XdX%(T zU&+SFZ=R9wIjiqA8|xYkf7|_gQF}k_2GS7a0}e)}FYXgIKyHU`T&FIObXKbT?A80z ztm}W&zLwt|ZC31&lG4I?_xzqmLO)+0{y$;A{kJ6{VWFi`Eti+iS28rbxK`@??)UX7 zOP8ju&04(J&u?2?%M7E+MK9wHbFbg~ugsmdwGOHC@4&zq&iZW6ho&RPRZqEp-Z!N< z%_nQ}hHbJe*Zp}7@Dd^O?S^i%U??)zQ%K zsQU6k@#V{xMzz06EMKqLobuzt!=&>b`R&i%`ft~Fe&2fU^V{1-uJaj@%H!XhQ=aQi zp0MNK+v|zkRhPg?=z>8_|CV`151*VAO7;~hyX$K{TdTFTRVd-FxU~4|IYCiTTL0^Q zdEVTVxp;Fw@_t<@&`qQhcz#2?^+Jis*_iG0{r_eAdE}>ETqXGWOtJmm&+LmDze?}_ z?tF9V-rb>Zcb0z2udAHS^Wy&Y(6ha=^{54lAFu%t z%?%7pu`v$KSMv9NZfj|4^)A}ZB3b_DgV|0c-nQ!%Yb39({eQ;i^Hn)Xqm+&>Thk86 z+t=-}`F^MP)4Sd8PwlJyy=2dxm{olHL)I}C$tI`kS=q^^7av=7u=4NS`1D8i|Nne` z+Qh9l!7%w4sDU$cX?*&t>sDn2_x6=l-_~tcJ$>!ut;l)P9WVE%zO&*x2AzyDv5-p(&vo?8!niF)*C-^>7?{k}TI zx5I?zoj-j$I$rn<(xoZriBGxUSWocNkNf|-Dk&Z6mnfLF+vBHdum8JlO~lSyzXe{SmEasZv^FIF z=KJ}nyH!X;NU4)^qfv%Ke)#R}hwn2sTA3#{WLg_&T&QVlZ$DjlTvi>lFs|{_^tdX| zXXoZ>M@B|I+tGH`G-O?4)%yk8?=D--{B^P6d&8Hz^sLNc-{kI&ygPl?EG=O*p9%T3 zucJXzPr?=#v#%uon$##3`~9DZwBEmsmC@65Vm6(*Q@r;(a(75n<7}i(`?kGWhA)k8 zZ-1;-bs4-}$3$gA-r205bGIHjuI|zGb+_;LDer;;12uP-zn^5gd-GiJh0<2@k;jXE za0x8`-+!V$?&tiU?RC}r|IVDeJKXM1 z#k!kUWT^pban6`ub}Mt!4XN|#^J~+ZzD%7uwY2G_mDu|SRnfg`SC+jsywO-*efxKCe`|!k z+6!(btIPkMoSY0AiB5a=x21)}SbBf$zHiU>#@#OqPR@E&aqeF2r+ez%sh@XUUG#kp zBIjH%WOAMT+@qjklgpP`7Y&&|yxdxH-F;E=B83YwjZIC=i%u`&eLXvPt`$-`G0|{n z*ykw42d-}vE>yC9k^k}k*Mq(8Ezjet|K|QYdA?rP)%ECEsXgbGm_J_{{`Bnj`;&kF z{}8?N$D!i6pOcc4p1f3-n|S%$t^hA@Yj=jflXrf8x^8#<>z;|oB?o9x;9}DtczS?&|3n7+iRz@8{MhqiI|HZAv3E`>73yhf|JriEhfes&#W$ z>1xpn8UnSPvCOaJ`j;Pe{<1Hzd@oyU$+jBZySqv!*Zuu<@dQ=fm+UG#kxQdku-g&w^bwBeWHO0CnAXE09hU}-Bm zlVBs7W>&*{{`Cx`ekf@3*lvz15ql%zk9jrhi{0{)1=0*JXRWJvefHA+`1@A9cHfR% z{PE$xy@S51&E4P=iU1DZpRxvcZc;=E_$%_Ev?BCDl*Xwyt z*PD8Fw)yFOwZB#D?c=??ynF)o+A_b`*L>~cEyW7nBkfU}zq`A+dDYbHQBha-c5`c+ zQ}Bng=+DRFr&nBDe8%VZGb#T0&u_;?=S`nB&H7>G-s4EwvrpVW@s}vSN98#sPXD<& zi6@g)H5Tojy0kz0^1(_iuBE$7!cTpk<{5d8N%QQ(*`2pU<{X1m2#{IU2Of;tHtSm% zYS%K?LmCbjQdz3Ly$Mu*vX1%xkIR*xe*c!s`D&UW-OSEA;pK9_;#<3Z9?O2Z^LhNF zySu+z{Ek4Bx)2i==(5bK`jxr!<+1mtqUG66yQce3y)a?IwinC%W~Z5bcgQ{@sU5R! z^O@|61;1WgT%3AkMPSiM)#)c@nPxwk>~AN?dnG+J_2j{3_N8mqoMCxcdhPqNLtmEl zAKq&g`n_PQntfAq^I7xDt}ZSfPEJirmM%RxMKd@BG&X!kQ&V%%eVgT9xA@PsjNfir z@ZNTwnst_IYgd<7<>$k!n^HfkU99#-xc5a2lT?EGk$XGeaV|!Pg3db=RB*U&ckT-$ z0XAeaZLfRpW?VeyZo)j%-*(o~Ff>yuEsyGu37u{-DHmdfs&J6n#fyey`DxIOj6 z0mi>e%iqttww;gl#JM%Gn{{A4z{u=SD8=a|>s=`=D)-k=hBeRHz= zv^{_BU!R-&b#0H7I8SZ%@% zRDXN({E7ATGm`|gf7JeyoV=EyB6r1J-N-%6Pk&i2_@|d6KKJ6^CzJinHt!S{5jnBU zcXrCnO{tq|eim)sSNb|^<(f4n`=`Htf3?gZ?)H^!HO#N0j;~u@y7zVF{CmgW8opS5 zZL|2?!ny|s8ZYgyua`7V>zPwwm@J{gF?TEYp$>&I(uxe&t{B^ECT!NViT!@|(>FDd5bXsrc3ct72 z|9^U^*ZSVPS^eY(=kgO97CJw9xc^U}8;|^}Ih$&ZuBu}GBK2y=muT^b z`_l^crtnBUx$-@3=Kg|>f1af8pZM0gtm=K5EOJQn6*fM4lvJ5{E@$P>Z=pgdtQXGD zG+Y_$^u=tqY|!_6*A#Z0`ywYUp1xP+u5TNktXBH`+HGH*${KTSZaVtw+P1r(eVngV zAIpMPdRKpcH}%t}BH=aHC0~_3`!0}eR{Q?JF4-;D{jCGm*WP|DRdK!8L}z}=-Y4^B z&C;s<^<^SxMcvJ3rUvr`<|}kwJAJmZvr{N{@13=ezsT;dm3{kj<-?!lYd-ur6}tMV zy}n)k-&&`_>N0=m=2%EIhgy-FfR6AAl;eXIRy$eF%_v;u;^t=2d@1s1{LlB&=e9*_ z-+Cr%zvJi`iFLVduC86*{@!|>zx%3d`_{#YAL9SKimUvwzTPC+BK6hDYu=pVr%tcG zX5U@)zpnP_bNjuACEvfX)Hj!`y1wC1GQYiscx*vm@x1q^Jk@)qTAu$K{Ov4WUkni4Tz~4MaOyqx{8RIFn$_pkTx)TWvTbYzr&1_UaE9ZBdF$Wj zN5$71sC?V==J}kuO)YIDXX4Xezpp5}*icndvnTS`*VpMyAC=qsC;VmqHv2+NUEIFN z^JmXab-uPePu8a5f{v8Jb%$D4*Vdm~4u6%JblvQ0xmB!*!TQ@)&3o7$C9l1IFlmkW zfyuQnh0mA0+iE=J>Y__}G+%JxOq2z z##;T`ajH|Vz1Mvnsraj-V}l=a@_DuS6J{uUn;tjg?3vGVpJk>hU`8IawS13><;7mp2*?)j z1(UgZHXXWtFZJG^)_b$pt;@cBkMY;W&|Mum*Id1=Z>YS2C5}w=A-dqm&S-b!L z)|mfy^W!8ge2le!ttDB1i8F15l;4iG-*&I5|D&H-@O|N?udajJA_!i>X(fu+&kauZ{jk<6XY9w_UqgR(yE-+kLfF zv+EzM7v?M2d^l~3X~qMFosTwk&kp=NTkHMa{~KTQyxf=i{~vSF@&0Wx4;)jW?ydyne1MSUZ3J@5VoGC*Imt`+8m6?zp_Y zkM(B${bKKv;FK=?=d6C6lJWYTC%0!!zAbg*`iGsdCDZ=M|9PROsin28+;TqqT1kG> z2>YapHXbkejBocVfB%oXuk&Hrn^X7RURj;*nm+OWHPP!QzR6m@w$AzXGGfo!xcbks zJD>CO&nRer@5##AYV^A8{b~32`_kf6I<}>S|M{C=UwFiuXW#RUz0gDoPQAzHHLz`* zU-?UOrsZd^&%4jHKA)qs_i~UG&mq2j?5wPvdSwgl-Ft6qaCdpBi9!DKU$1T+m->CB zVb9&^*Dja6c{^>}%}c*}d%gQp-`>++zu!3AXnWoy%i_3el|X z5j%I?W7sSA|Hb6WPlvkKpO|`o-<6R6hu_y}a*NgKEnS-W>2>^{5R)rwLA}~f$JynL zUZ4Hx?EGx|{mSyiq4wK;)jf(of9kCHIis)3d}gLJJz?h)F{zsO{@~~H*4|1=ht9s! z(hm8wH~M|f7rB>P@BaBKf3iA%pU%RC3)6PKXewSi^V9#Aw@c=}O;6u{BcmctySm@? z?1P`vBpDbS7(87ZL+U;(o^PGlXVoiv@4|(D-}C>k-18ylEzgf%Le1w&&g*>nnz@l5 zxou%GqxRm<=bo97Gv^e(a*?#H30Urs=_j$*vUFCl;l8&&^30d>ZhyTdW_P6BkCKf! z_jb75tNN_FefDys^+8DOHEwo&K?(6Q~De2er zoEI4Xx&N^_I_1z0;ir$d&zt^UwQALqYx4hGw6wHlo&9p@^!m>C+#Fx${`r3V-_tjI z+tO5Ql8>!CS5_RZXYoE~`K#*p^(v>QtuNUo9TmAdui5nVpWEjia<37n3r_tg?mcUj z((}2+%Yxn0Kk4i1mv57fn)&_aA*-)%W`2}jb-oVjE^u0~*v4wIU~kIB^iSv5=bvmZ zp6-#FdUYf3rN;2}-{j9lE4|syKmLTrkBNUt;+5GWm~c0W8|-| zv+{QT)vJ8_wB9=*VZopKXU#1(AIf&G|95-wrmDBU#J;ZFyxx5IllQmPe}9*saO4O} zaP5_jhl?Kmel|@(yQKcljEjC>OJAE?z4l#Oab4E1W<^VTyZ21f?quiGr>jhPWsQE9 z>Zr@vA6t2Oj>7)1b=%U;-rteg4eCqGnLY1b{4@QSH(L%PhA}}I^nvzgm%5#+F=7Ay0J|B#TXXL1iM&_;T=%u~>9Q?}`6eiN8zr0? zb~CZOxcha9DJ1Z3g(zriM?Y$-7hWK5Q?a0C@0ypA$Nx%B+4eTpX#4vqee)RW@BMKt zx_)>6SGj50uj6ZePPO@WKK;qG+3U>}t9UPEUljOpxc}egqqP|ddv>}W{wAzGCuP<0 zB`T)hO@j4TMlX_FUmH~1{5$IY_Pp;?Qf_WEKArcfK4S!KS+%#P>2?+;SgA0ANJ1VI{3=Lf)I{1 zahv`296ok=*_=CRj8(a}ck9G&JXQU9MfCs2&HOVN_I_`@TXy{X8J?H-e$R@!9(hNa zd(rQC?`0SGd%b#Az2o9r5$!MUVr!f~-aB4%-8|<`NP2kI_bFn%yU(4x*7iPP(&R}l z)2B^qWd6PVi^wZwB-b1;)LNildA{-?>rA7{O;e^#J=M3yw&>LpVO1@oKN6yuw@>To zX-@SQuTfonEpNiq_gVk;uOu9i{ZE%R@sM(gVvF7)u zd`sW>x|gn>w!6#a7oNDCxu9|Cf&~f}x9vTxUi`c|U#|4^^EsxEJF;gL-U_+7sr0ts zZ|U2DGD1qPo`0;6TK!Cho144zn(fuI*2gUmrmHF(NOxDB&1g3@`uAI=eQz_bA3dtt z+tc8Tn$)bBq@Kj>Puwdqx4bds-I-~Z*WP?#%=Wc-d0~_xleF3U381;u>P?%Uyxo3p z!k#@fDKK9k7mX0H7n_(^UhICeHu(YAisOq89G`z~vQYN1?I%uf6#uNP`aa2fe`({M zFQ2m46=lr6wJny5Uryxh?+o3{Oxq{@-~avUIQ{#kf1Y@4X5!snz3wvE8SWcI=lO3> z3yj~t@Ey;4-mB*&jBZ#?nSOs0gHztSxaTpklCumWwxzyXv3dQ%-X6u~S2CyW&JIuC zy;Qoo_MH9qMcPkRuMgj{MG_@S8JOxgGZy@wxqSYl;AL}_T3cIPk^H>8Q{CmO9KLK;O+E2o*TXMu=dSK+=kYA(d!PG|r|#$PZ_)SdKAc_i z^i_pRJ}5HsC6BG8rl;J$)3rhpH-7z(z7F=Rp4H>O_VX%E-LrXRm%rDU$-pl ze{A4M-@9_^!^8Vm?oN7|rKz2Lms{xS)vKWPuHW{>?m`R74NwN>8p}j2Qfj+zb?e*c z%kTN!R`cPbjW)}_T{_WQ16QqDb-Pq1cB8RrkhW>CwQ0!d=4qO!y%yxaYh3KQ;H&5E z#jZ`SA;Jr~Io_PPrF#Bc-Nthn%jaA9)_vS;{rb)4bm!X_w(aRYckJG!nHTq-e}Cq+ zq%+%9&g1w0KRCR|c;oAw-}b+s+Mc^$nqpshi6wpa%Bk7wb~#dup4PEE~E_f^+v-rxH$3e*u15){1m#4-fpVpuAerM#i+tySfx&iWI3{OzY~ zzdv95{GK1vKy8*)Ys4EgOIfeDn;a|q?#WCO$%MKVS zemF2+e&U-qwx#R7PJ17x-f#P7fs1>+@#4z4T)jCjEUVUSdlUJ^c&fUB1w-b8oeIz#UZewgVOgS-uvH2k%v)jaNJFec1 zo#bV+^Hcr2$@gxn?Dfo(^55Tn_m1-W-}AoLyvx0=vj20;$rB#yH&;)eGG*1y%2m(O z<{NzYHT(UQoBIse?^XS--S{!*!kaqbH9b3o_v14Y}K0ZkeuHo+i%sDP0Kaj z(DgYj$t*1;EbSQXIB`f9RdBc;86UY0e7eViVD21EohjUU`;3I<@WsFJRF_enthP@* zeQse_#WuDjhmS9^jh4>Nu3eM=7BswC^kriE)q8i-ZilV4(bU{{k)M0o^|-u$PtT|R z*r0gs-KkSvJHP#!trD=B>*3k`fA@-rn^kVzFUMZLN*G$9zeSBbh zX?OT}kKgwHe#$L>RhQx}9QI~1*S`W-j zJL~`b{C`q9e{Xbc`RcXxA8)c>+8;k(ZSMOYlh03EzyGhD(XqJdcY5nHw|*|z@bBFI zJL>iIFD{<=_)7b@Z1EDCZy#zW#)kj><5v0g>vrYa+l=bw+djSe|Bv>j_nTJNJ#4v= zdwiMi?9@wB^iywc67@^1*v!xV{jhA_udlhE^m+T;qqF+&t}PFJvA^tgy;_^{-MqcH!~4^?YvMZhNhHzV@Q0`5W7B z>(%ANc6%!9`SG{z=abDRHx*n=($rr+p^^F5>+1ZLFE1vF=RLCMwg2F8^1OZrcs}V? zzr*&p<~b+VMB45D>(ez8-WBi_xl#MQ&?xIm-lSRcG?m-=rwKa$@;?7=r?1S`+Vc2~ zS#!_K*zB?F>>TxIv!|!8%-=UXfB)Zgwf?hi!jE9;6?pJGqW8ceO-Q7GTOAw<8-%%d zq^)l3%zE!v@ixW?A~)CVK-0%|+2StYYxiom8=9^=?ew)>rljHXioykry{V_eEv}y4 z8?Alg_UGpB;i2yNs|9MAgY&LD)YH`b^q{uBv*mgHpUhb{UryM+mU+Ck{GK@XMfu{8 zP}P6-e?OLgx@vy^lUmt1KMmZ$&gYFGdH z-8y}-T>hDJ-s|_o<^8{Vw&!&3Gw}w84aw*-(K{# zUz&aM-s7jY-&cElm%E$tVnLnJihBK%C%y7F7H@xc;Pq$olTEItQ@{N=`fKkSsmR@B zOKbi<6^UGT|Nmxq3_(mp;%*4$jF=lZorCe$+*hH`lfZ)pR*Mg;3SIs5NbvcIr}cIQ z}#ZW8vv7S`Yi}{%!g5^OViK4>kF)`+!^z` zJKob_^_%P4@BEp4J9Ylvvgv2e@OZwxIr;|^Hk`}*e((Q=2#f#c%kOB_ zR()S}@!YSy{|_GbyIQ@QbCIQ(^yg`}-%aWN_kCqd-AUG>2aLjVvOa7*zHQZ){=c6y zXa0D(5v)JmZON%~r9`{U2%5nVl=#fz6zoX$MA%FEF_a&u1 zdDUityr|HIPa*OLt`YQb?drRiK-n`i2rSbdilHPMhzu6kQr()%rxXs&k`d@ueaWgW~ z&-I_2?WZGJkI&CD_J4L}u6`LaGdB}Q2@j*)uU*M|{LTnL%g$Nh3G4TMo22O6{_=at z&Pg+-=-5`5Or0mS#eWSsZU>(ZaO5VecdxNbK{fz z2=(H$^OM%^`=#~mUHKM?PieZ!i(3mRt^-Y_+@@lFv`E}Qz! zw%W6(NZixIXVSa7n@m0CtKOWMc~04Ot@jmwrtEVkZ!9m*y%nP&&1GiYzx6eD%GFt4 zgTkVejvj5@ly$UdreW=_Gw~Z1So)uifSTRl&@TAkd4%k`r?4 zPragda?&dEZMTb)lJ*?=x#!%*Rq4^+U)jz7obxy|?AOvon=VzZi~9b$YU#Vr*{VN_ zZU#l@M1T2RQ+;noruWs2n}Tj`S?O?XP1IWRljo-%?G|fYe#{tBAftE>>_^akQiTA~ z1^EjE+rdSPfJ4G_(G}V*|8LLES8&+>d7ti%A`~wqEEn5wpz7^~syx5GFK@1T?|ND~ z^-GVAr{_zhlb$ChEqM6r#}A8-FL+<()n*7**0wCUBwxT&8`mGa^WLjFEX|CZEKEV` z<|~9RQ~dd8Qj(^Y))Zgql$ZQYdgvnXeqkf9<^eR`BnoP2wUvUIr2q8ukbM`B(HYJZ#IGpAx7e94nj~7;0q= z5WB6DL{FU8pHP19x52e%Taeb6!8#)_pEI)D@;PwmQz574qi%1J!ktn1a#9z{Z#y&p z-WRYaBy5V8YhNI$Qhgg{r z$;f^FxcagVbG?PB{#P!%kh=5zsCs7Iech)^U0YsAe|m&+4yQ@KgGc+t-yP9EK5w6u zzODx|cA;U567C!d7fcve+uVQl@MqTagyM~s8zEr}Q?yoT!&m1W92d5CnW;m|d7Nnj zDsjv2!0T?|_?V>Iz6<({Z_mle(?PM>Asci&m~Q4doCgcTEQe^@GO^*hwEm-8QF$AC zp9y^3Vx^v*7s$T}ZCtMow23YMR0l*4swXhT9CizRsHlCLWp`Em^1SC^we!{>=O2gX z0w2oyPCw9sLA63{Qji(`~O;P+H1V#%UgQ~z5Sn_PntC? z>T%I>pI=*!mAT)xc-JyH^~sBk=eGQ>xSelx>&r~U9I}Hkhroh-HkURm{>2(D8P$zP zmZZGAx7a;JDRy`14x z2~BBOoq^=s1$((81ZvjrJ$~9QCde3LC->+gLe=z|ujI#g~%fhfc6zt zUYl9;Y-YNf)|BmsGRt3x1lRvL`11PJ=y^OcJG_08zr4HbU-jkH(=BuDzAm5ftK^tl z+fA?I0X$*8h4#8yT(9OvsXA|MpFZZ^`zWQ6v&zH-; zNgK`ob(w$D_OQw2J7bON4*lDdaBvS>?6;fSSN+b_~=j$=;C`P*-vGM)KwVm5|C(i+Gm-3rtntkoWt5EHftEZ;k-rAdbyn(S< z#nkp}rd8RUcN6uJkM&LNmHs^U?WaveGfj)DoY3rQK^{b~;Vdi`1EICU)hv`Yp$5-|Fu#l`AW4mn=|- z4_g3?3#T26UWH?d2?fm@9Ho0&dOTy z_ICbWy&!Fe{r?@=PYb%ss%K_~Hh%X=j-6?r-nZw&ALC8SCQg0aZ}Tfca@*?@ubeGk zFP~GFmU91BY4+1=_wR_@U!vciu@@Lvj-+!&$X8>`wNX90^%jL_`h|*xhjY?Zo%{{+@dIpu7Ki!JoLV zWpc)4=AJ%2CAVsRf1UoQ%v5Ie#syz}_wVv`>y>=n^4$601d*H*)6YtqceOY@`dXE8 ze($%7X8R}4xwG!;JbP73SH1n8Zsk6#d>da~_;SuUyZ27Ko%5wR&)@FlDLePU$Rl6k z$Jw>@6AY8Lhfd^|U;TdPmMup(f4X!3x@}iIMdbP#ru#9UH+KCt|MzP9rq>#OOPbd{ z{CRe^xwmU&tMStxEftn8w-`TZ`~SN)V(IUU(=QBnpDf+KW20Nez6|e$H+*@v$&{Q( zEIL;y?)o|^dH!Diygfg+3-O(g-uly(Til~EbLM3|Q{B*Yd;d+}bbjCOt1phT!CPJq z#|1n7>7VK|u21X2R+nHCJ5a_Xx81w$$2;leN;{9gzIx#EzfV8Y=jUA4+jF?@HfU$V z<>kIp6P3$&<-306EPQu*-3~XMfZXm-i~9F(&6g}$qLngl+BCi6^J`YU+4{ZWsX@p6#r; z8T9l0?);N;A~(-D^(!*+rcu!s3CoXDjORS~7x{e7deI-xJpuz0m(a8t|D8QMZ$dBYZKhun-F97)`Mk2|PSxXvdnO<5?an{lf4_e9_5CsH4{JA< zN$RxA6>i~?wDS4&O@6`D@BI_YukQRcY2G}==dl$VZ@kXw-Ya&${`XeUuFFS{9;e*c zAXxMv(fw51DxlW!YmH{J=olS zqEbBe)t+bSb1GJSe#sOjJ0GdUPv$hKS)Fryms}cTW(`|3poukz8I@Znep_k(_d&*& zcele=PyXJgHF@q_?cF?bZ)AS|yPZGhz!vSS)4A6DcE4Coo;g=m_UFgl?VnC{pLaj> zd0X-4XTG1_1pA-(v$J@vS=ict4b1$d*A~}q{P1Tn|KHeq*8~1+TG~B#L2YK_O0iAr zSGn9@>b**4{leU6GtrzW?eF%7*Zp}|t!|V58&q7Y%hx|Sb9me2-AhhrE}xsZT6dGl z^_o7bUlk`$oGN+txb!&{VXDdw$)V~cyivpm`6-M>cx%719#`hReq?uxhHe-W1)B9zjw}O`*Qixr8#%k z@B6do%pAL`mHIdO91iGjPCGl{`M5Z~oEa`foQ4-XHgJUKDZRBmr|KKFv#Rc{|(JN|3i@}o>wAEy4<_q#Pb+vfe+ zsV7Yf-@ln{^zyRQ@kO~27WMpVb@IDgH~s&6=kmF#xB3eM0_N4d3S7Qwuk7t?d0T(k z(~DR?Z~gSwzf?w4a_?=6jahHE*?c_jo^pEH*}&U%|6U&VdvS-a@1mXA^=T2alI_g4 z+kRhXG}F3z+Mn-x%NO}w%~Pp(cCy~;_@21_9vM@$OXnVcJoRGZZp+(Zo9dq)t#|JW zjo;|?=e%90soU4TSFeBGmCya`_;J+`dy&ZbhJV$6J}nJDsmy;@UwfK<_nUO2wD_1K zq&6?`_)L9c`2Br|(ibZ$BeAjgoTWP(|H@S-;;ye$dtON+zxPo6qA@el9o?b&we=ia>i7JA>XswC9o zj@ByuIE($i7QVeEer~?Hb33p2{Cj66%$zFvwdQtd)|0+xGyF^4SDVD&-;{FFX|0F6 z0QZIRxAVj^tqLyaO?>s)c$xp?uCA^V8*gcEHeHgxe(&|?t7}i(jN6-)n({xaY_MH}Breu3gOf zqMM65`|GNmGZ&jP+(-(2(Qor>$1L{j++L|*(QVuB-u<-8-8O!$Uhln}zMmoGGG;a5 zAFm4L@cW-T^m*Hp(${kLR3)S1t#1d~GRS8JZQ%sxA_OHD2ou&jZxT~ zeomy?KjrzeQ)l<@4b2aWP_h5}W$q1MPVebD6CDo3@8w3?7bP3ez);Ixb8!ZA#F|iZ z@xmmg^S0mT@JN{i*vy-CanilL)!sWk{aJEeJ+t*)s_C-ChmU@K7Qb@ix}4d*IYyp+ zwhvVbci%OtyZ<+v!E|GgO7H;m>M|e=y zf5EeIOWFK?XC&}8=@1RR1v6Q-w6s#5or(O~m-X;x=H+EqZ!g;`b7xcPW}n|L-6d_y z%q2}KHl(Dcde{A9^YrqX7VF+yxa{ZS@Ao}DJw1Jb`B=DVksdPH~?gT-*u-}#vJT7Id%(t&S z78X+a{W_|%yMOiT37hZVWByB-+Qxmm zQ!HQk{jK?vz2*1Tl2RPU90t`n?QFZTJSS?(<{uk8h2=iD@Y{dV^9+(W1P*lw+j&vOdDIU`$yE1}tyUO1yZcg*#&v&ccX0}mBdz!v*^`4KfPM_-) zV`k%<^q1eprL9-uVav;Y%YQDBTM8VT*VpPiU&IT~yAH3pc0_+KnZrwDR5CPP69-jg zA~`3@{cOta>{#`DW9a$U*Vj({`T5x~o0VI$!`*Kk6FSkiC9TwKaS0v)#S7oi}YRe*Naw>hS!vQFfOs_az*x zSs7Ql_ncoK-=80Uw@=)=*sZ^JjeE4@j?)P@OP^?X`grt|?TGwldc5XL;o)Cj&(*Z? zNGle8{8)PK?BkCoTK@7)xTW|r)qDDhXKUwk7^H14oHTW6>~jg>Z}t~f%EgB_fBC{A zx%>7zP>-?HbmIDbGjx8X751g4q+Pq&$Bal?Zvzg5nyNE>dHZ2&q8CCKAIqUyq+s`U zSKn3Zw;$i>Hv97QV7uuF3NK`=9>4i~^z~N{1Bog6`)7!(t=#)tt=8(IrQG}(3gU4! zGhIG+bazkg*4ul?vfq^N`^xeMR($`yJpLZEBelEu%a+aOrY=0Z>d^nKv(;7APpeLk zRSl0R-g~F)c>F8grPtrxp7HkCtn*9GuaYU=T{iXfx*cIU8uGc8Up^>5JyWbdAv$lr zGoS676CT35KR#Tozs%w`XJ=>8!Si~(zoNcek(Ttc`FX`-e};DY%OB$LbyMfm-fJ!W z^-bQu<4EY#JzVYo7xx}TYzS)nrv2chdBTU>Mdq&S?*9@DeOtcj3=e8@UZBeobZOI^ z%VN2j8QqtQ{g9hN8P1H|td(E7!<&ojwtGMNBKW?r+pe=bJ7Wd!^5ZKZqb@5H51ika zRgkk?aQ=)PfXDaKJxzi`x6GYzpm8KzL$5u@6C&=yZd`& zY>&PC^>uo%O1*Pv>E{m-si~=#cKgS_yrt`Jw0TwCH_Nxn<)3z+oZmj%W!~>9gOYh(ORp=lOa5h&enyISRql+hzrMasnRD*sp7~=-bu(YS^gDk&zS2`ncTRlnlpA5}{E}MDTe|k@g1V@2!7s~X zXJ^}aPuH0wsO)B0eD37gsgBI-uX)+yH1+j`>lXx7eR-j(KBr`rOwA3!b23~ekH4&6 zE_Yp8o@t_`Zrq-LZ+D9KsHmx0t{t0Sv@WJc=V|C`s6CN z(5FAj@7F0CwXGF-^8B>j?|0ANNZVAb_|aUqQe*Xnol{OfP;}nH^slk#(8=YU=bsm^ zx?unR&SmRAolK^FXOOyit2v%L38{^mc-?aL-!GF9tvf_TgkU8s7vB&sU1=io{^FFH zO>EPvRE~LmU&3;-vww2P+6%L$38;H_omLU}aQe(y)k*PjinFz}mKsS+Y6$zE0v-Qt zJf|D5%JG%>y!wUC@lT$dx9@Iw^VVsZ&n-I}`O~aXPk*_~{n{Nv0`IEZ%C|PHT;L!pKlRk9E~$2HlL!AkG=D#N_4?nS zOP4OC{5TPKZn2y4-HMm3&sB_-y?=d^5BNP{^WK1bvmZH+{-^wJ=9^fuSM$*q7=Oz+qmFTYn4a(FN>%lP z>anIhQ)S;zjyu_Dq@wFu^`dxJUi8<>`KNVVr4&|uVNdxtEh#cAMCr4+=qazYTXrql z;$${us`tjW1x_t5Xa9Fia)D;h46(+U#>-AFYwDGnaPGo$rkSS2xA^*ZSAJIe`8u}z zlw!O5($I7Klk`@uG(DzuV}qmJRflit!uD6B1)5F!-o7}t#9#f?si&u(Y*6ki(>fQ< zUlx6#`s=ExpKhK0KQVH1+M5@eQdieoKHHpmIqdjhzVcOjqAT|P3JMC+0`+?Ld_2`1 z6t%6^v?hCZ(b1xvul={5E<8S0=kd2Y-ZpanDIK8U8t?y=exOkT%a>0sEB{`+cFzjM z-!Ff4GB2NB*Y~94^(zxj>D#<2-eS6!6#i}ARQ7gO#@(B+16nu~E-FaARt3Iue_WB)g*SYT4DBi@#>C ztUYTezy05CV{`LxBje3Smzo!>i`nR8maCI-Wy<79la@rsm3#X6O%v6ge)`y-V_*5_ z>nJK7lw9sTU2l_D?q~Bg{PK?^K|uk|y9=1Xt3_s-ioURZ(0zOg*u4UvAu>#&aT!<2 zk;+t;=_-=5X6gJcJv*f_Ds^9XxbsJ;j_XsVv)%v76P0_<>08pn%G(PaE4feaF4>=< z;bT6hVUKtJ(ih3+^*$Qy@-CklAEG6EUF^h?uhOZBg)^s^2XDQ)EYA2Z%<9HzA{;Mz z+rs|dm0P=2L|nAf_SWf3GM_g}^IcmL`PioH%Puc3uat|2Sgmi_URu9qjn6clIFXxa zh~jBMF^9l{_cH61!|~4Z9Z{LENc6e;lBFkF-k4Zg*hcPB|8ZokqH6d8C#SHOdv9+_ z&A46~eqg2Pd!99nmDjIzeHL58A36Vnq;5pM?%%qPnY$ly#=X369e(UpWnAQ5$7O47 ztEl=t{Z+s|59*Z#S6RRO-#vHsqo}_}4Ch>UhPHlf%OnQIUtvwpOz^fhqPcdMKH2B( zwMgccsq?q15B^+m;XSu|>#RL&_nN~J?=3!9$$jGXVX^ePk%hNfzFR9+-OhEa<~`f) z{Nr;4LbLzeM-E|Qa;KTRX@p3KQlKcB?%UJ?)cwN{-Q+GgF-=n(MV{#Ne)`S)W>sVO1DicJXPcFzM9?9D_WeNQ>w^HZmHsi2mEA=eK1j+?QL} z(DtDH;zAh{d2)~zyyWF`TJ1yfm={&^Kv*RCzuc5Lo3j9}f- z@HZoF=z1^XHDU5s+j-Z@_6ayS2F}#=PcN}l{@Qc<@T@**F%@j4L)cWv-94! z+ZIus_ijCXX}SLWRNd*K(>xt3TX~Pb=5y9+JXpVG!l|yHk4ImtU)Zwv=(CjKWN57o zElHxh4|H{Iz#7Q#G*hC)xSj1R;ulK#%|W9%#4MV zIwtEIt8Q;o*>k(DcFFlL$GGby8tK+g)=!ww_R3kRXZz8m2P>Z6ytZ1(@_5Xx{aLr2 ze(ZYp@x|ohi+&j0cs?nc{o4(zWtZo|de;}am_$=mAFbEOK5BfeUTb#u*-k_`0SeL# zUq-D9+n1R=$9>gl0aIn=-6wO5{nwV?`#<}~%s)RaZ>hSy<$CknzrSv+uJ%5^I)9P> zx$`fT9zS+^bTJ|7!sD$`A7+*Cdu>=0sFQDlm5hQmDjLua(w(={TOvy z3kA!#b?;_s{#L0vvbfQNd;jgE&G=FD7EPNt1nTdc1y0l zUi)cJah$q~e95`=hrd(SyVqSa_I?+!A!_%{nXpN*1*WVz8{)!(Uff}M{`J`F|9gM0 z`ZxDM4VN$XIhX&n3D5an?AQJCugJFEm3v;#LTHf;igO2s#$Bu&7p~_X#(4-SC{-_T z=1j>h{eF24{Fsz?g_3=g7 zh8XRW(bd^9S6+SImc-AyGy2TkwF}KZ9?e`3r+q$K^!J3YY30_p!z%BIJ=gKmuuFM- zQ;zr1&NcJ-7JPm2)kabC`hq3sBTy2Mj zeYt-vt)b-$*4%eNhpAJl&0a^@vG2TxP=8qG_srIc=$NR=dr6*E&v?W4lQn1V7&zI~?Bh#Mb z-?K7Kuc|>UHV}=BsF((Z+HT=u_=*-tOo1W-!CH{YYGd_hUF@T$r{>KR($b#Hb+^p= zf9A(>-p$scPfR`XUo)&a{$iWE^pBGH z*TtWI`S@ecqpQguIXV3j?EJKEboWi2Fk^*(-p8Xqk1T#WH$8j#-!;GXT#h^Zl{4z+ zy~iIdr@nt&vSy;)^e1Yep(nRjqSZQx7RXvf2i9NL0-nhrgfLkS+?)|N{=PVqBDps8 z#oCIRrLFhB3i7laS)cf;A+-Ct&==8PG8eKwE#z9OwElc*)JnS)(MMk+!|BLAg3-2c(_jm@g6Q5){P581Q5>l@=;`AdJrmTfQm`zt=+ z{L8{{+0WU(C!9N;U;Cvdc8gJMSj?O=>#cZk)sT&0f(w{xR~r-yL9-Cn2JM1WmQOW# zmYUjuUM39hTb`Q!$~#!9ZIOTV*Vv5|FwRKIz&Zw}pak|0#eneec7ajjT;;ZbIkF{~}bA7wIyHo$R z{gFDZ%dqSAj6kD;gnG#v`{(mWTsUvJFXg3C$xA9MI%(}EcKK|s%lhd|lUq9(pd-mDcc!l@%A2tTRtlHh@d*h<1xjWyD z`uOKH-}arn1yEW;lf6iHCZ2j?EOBa_`IEOpVgy)k3V1WZEIhD=FklJI+MV8)&Ep~ ze)+8F_rbVEXWH}i>h&t1W#yY+zRusL9UfEc{NzWY)RlctubZFRu&`PA_oB5rahpQq z>Yi{`ew=E)#EE&SZ>&v}?5_>Zd{gGf7WBQbu3JB&ZF9p{@2Y?9a`j$aU0unqg!8UU zIKBB*?c=lixy`Rj%Y1qg{=aU5_iB`RCWN*RSQ)Omw%K|EG0M z*)><*Z=162JfBm$OQ!yepi$nPh>x$bo7#N5QhaV}?wuVg59+NgtmWO?zwhrq zcgt@_jHTyf?>Jcbs_6RsJkT(|-M=TBpT5rD-(R)n*STvI{Gs;o*=y2&*nD#N?{kvx z=iJLXzw8yh^kEn4>$iyqOII7b&v|`+dmZno+rM=e)b~fV{_v{Z_I>u(i_0e3`CYAi zEze^a`m(v|PM!)EiwVp6w`(u$y?pE3)0StZ73&xNSe5m?%T8*wt}fw!`af^Sw!nv#(gzNGGynHU>iOQHZ!?!$DL!!X zU&LxHQ~5*j)6L`WPtE^V(EVoX^LK{r&vU)P=KkH4tvCJsz8M<(cm5RjTl!0EPFB0@ zF5~^}-@JUMY)M%9`PPm3f!o`z)k^t&e>Gpa-){F^InGy&4ez$MAHApjH;Vb*we4XG zzW?4TwMQ@X>dUQ8ds`oW-C?^%YH#Rr{`}W*%NOmrz35xj88PYex$4)yiOu4FvBU3Z z)!X#jQ_JLH*Wb!leo?cf|GKpLyq1de*|6RQJmW%RjL?cyQ(W-xz%T+t5_1xcmuk0dU+1axbr_ZYo;E)|GVVNo11$NZYwoCaq83*>-zd`n}7ZLJ)NAKV$YUk{8ts9`@ChVwDr23 zd;VS8T=c>5_wkxIZoB_)*OyzFt363cKYm9)%K7#G>-+yW%2ofc<9&B5?4j)~i?ci5 z_ua04eMjXYXrmTy_SCCym$hlm-=nYG#-DpBV(!}F^m_iClZBRe7{Bz}TCS`3emleO zYXZANXY*&ZR<2gc?`D0xR%)+VnOtK-?(0=k=Up%5J{8SyKZ<>8|5xt+o-0?Wtv^0j z>TBrp&1Pa(uFu(LJkPe$bVGb->%LX9_O6X?t;$YWzV+*>XHqNty{38XRqR6TyCLe( z3|~g3FKbtx-3iGz2nh)5z{-Drw^zTLQvL4}=uXURF~QXy|9?lPk*jSVi=IWAMWqwU&!!PQLnuN-Y! zAEx{F+x@$H4m;n>uG=4%oR;R+oP6Wwna5iu`)6#(O_rK*@^Jlr_cOb7#djY(m^Urs z+)+Ezhf~Gp<$dbaJZrgpo6PFX``gcyb!sb|Z0DW8^tac4Wjyo8D6V_S6DxdI-_~!` zS@Z7FgI%GE&H1~JM}Mu1*7~|LX!VKqZDH-(59|%Dy~la}^{%$}hp#@*wb`Gyd(Epo z!bjGx(s_R?D)-*G#K*TH^lG;$>}h1xl{7^{A`=+=W*um7UqsF`GU9ay?LYa^Rj$i=7x`f?lMZt=U&?L z@aG55e(Pr*f3GxsJ~Vsnzntr(7g^J{pQyZi`SKj;5FMSpoAu}Zv=yn#z+vnG1r%Em1f3f-MB>n3jSKnfpqZ#_ja#hohs=T|w z3zMyjFP51lq+ZY${pY25>FlK|CN~2@-h6qCqt;fqfPc)a;my9=5jmi)VFt*)kaBL3Zut-sc-cr8}+|7dBrt8G|ydSv8Gov1A?%g)bH zWo4DlmhanD`(q({=S`DT%Y^+OCry}eVTz(st?q$)d#mG8c7N+?-JieX-K$%>7w7%| z@Hph>@nrv#y4&w+mf!!~u;({iQ?o#NZs{e?*nKhCXudFK7XSL+`j}m;IVQ+={sT zW!w6!yK7(HTbp~QEav*-+?2PEFE#9Om$$pSjq68P?mfF?702_k>q9^0dR~~_Wm9$J z-xX2S2F$XSjHUd~Uw!!tR71AEi|#UG}XvAZ(9e%jv^nwp<+ zb4%uCo8N!BjdFkKMD9)NEqOaj`*1to#LwsKV%Jnv)^@Wx%kTNGXZc~nV-@@T3-&ED zl-JhOoH{+OGIp8Ye9+~dlh&;9xtV%_!SZ!a@RHf*)-HUyfcd*HchCN>=Y9vyR#R68 zl>^axoa{BeG z9e;F9W2N8Sdh)!hi|c3REuOV;ZzslK<<6 z>#Ne)vw6b`54~Maq-L5tJ^f+biOqZ6w%;w94621E)@}_qGB&>QmZ$Q^M0KV1wDU7p zum37NF*o{V?i&rs3;W}HYcHB*ecxEbOp;SXpZ{q!XW$mBm zZT$K{NL*aK%=pOO^8XthUkmr!yWOk(zqla$`A*Yy>yL5XE?B(wp7Yw;lTZIGc#^L( zIZiY0q|_9(c`W^F>hfobtkt{tU{BheujgmEe|~K@JvZd<-bBYA6@QJR*PXY!yF9Ss z?{4Sqe;Jnx?cKV0nd9`ZW!L|SP2hheQOA2__m;UwAD(`*W8KsncDcz@U##`_(7yY6 zneeIYx!YfC+s1#(;@gF@V4wqoH%f7B)DBQ7ymbyz+PUlxwq@(c9CI z>VlzhuET+*Q?}J*`5(M=TmHPh|JSjrD=SQ({`+43r;Y9MlcVcD*B2eEOuuUFm*=-F z2GqKlUj1(U_E;VE`!&C9e_qwC?}&Q&H=o~Tk?7a;)3Vp^+H!E=x*cB*SuuY}ySzSs ze%0|GPd1+{y4O10d+GiCvAdsYhn7 z>}f~#H|lw7|H)oSD6Yutea$_8_1gKjU)f%{b$zX5Y2@5^mE>O~7e7=77*(ls{eBU* zDaiTD)YV?9w&xZ*R!#q5diI_0`X9P4)+PRO;@!2|)MbC<{a`b zI-~W2cIh0I_5NL_yp}q-fBo`G)p(ijm4JWSzAraR#69%1;9-!zt{tl%dP;$gwplkH zc)5Jug$Jp2|L2E4d2aqEYxjqm9m$!QGw=Mlec$@v+YkG8&0G6vN2qn)sZWQx*Pjx- z{>Lb*;@+{X2A}8F?+kyp^Zh|Kf8(kv>n`oB{<7-v^0_hl&+^;*O`RWG=6mHs%~#?5 zzkb~=`Yr!{)xPZAUyIM#gs%Bi6+Er{-fxF>d%n5-e70L&rukKJ?boyAMHe0(KkXm9 zJp8_FY3+{ zzI%3SF;BW@8uv@)zWW{K-6x)H;<~w}zI<9(h?i$-YsA;e?QPE=e|dl0h4-xb>*Y-< z**EU4Uid3z??WX&=8txNRk*pY|JIRN-`~*sGB)nHu->V+%Xrp0?RRZ{ANSX#Md)vF z*rJ6$op|p}&w6lg)h+R?&|kV$`wn^8E`N7F=;d^y-2FTE#5@nyTW!4iWv)-W?WQGy>Q@{cGvpY?QwP0w`HS#+{jYAzW+|$ z@z|mlitHZm<7{8&WL$lB{QchLKK~xAwz_?#{J^SR(GmNrzP{Ua>;Cue^(QX6%c(iH zzX=K#RzFk!MX>$UV}HBg#b?(YZohW>e4doW@21mBmMq!gwtttIT;(6ljSb%lkIP7I z^>lJ-l36qLWPIJ*vn!5E-?FSc6@Jc_m67+vwXHYi za~~GdnA;aFZTHWgX_f1?_v|v?`I_tZe4EB%dL=t_^V+8U@rUx@cX4w zv;41okJ|Vzvf$Ss-_A5(znY;imI(=dpmdkw5_{p9h^UC z7RG5_{kYa?uRHTkx!e_o)taTPDxSyJ^X&TickR?SU(XlJk-My@8pr&7=`C|jkqJSz z>31G1{B+CTc%|KXwB3EstjM8op^NF;YWBZ7RT+PUnLH1{9Gqle;&`)$Y5Dx1`qt9o zo$vp(C-ZeiKmES@|E~s{58L-&@vfQ`w)g%;hQIRvzl3XE&pNqLM@;SiY1{9oFaNJu zaqpSC{Lb2je^=OY?0)?azPTgt@W$SVxSFTER?J__&a`k=zb|O`_t1U*1TWsX=38oh z|Lyl{{bhTsckTAfJioFl41d?$EPnkqo&Ejp-+Y$8|9Gc-^WL*Xx0?CpTzFtnHu=!GT_xAP2W+{1IbXAscSX4EDy9!r-}{#=sb2E^ z;oa2IIniC|xmWyqE|^IbZJ+J=M%b!mq1VTk`rVUsS=QeUtKH{x`P0X+!Z`nsm4|Qn z`r2_{e0}&SXC_1Z;m=YX`WHVR&6e2b^WVTeH`uZ zdGG(ako?)V*zJF0EDF=->j-C_U#h#?wBX*ZUy&zn9?L)T>16ukqrW0sKkk~g@YmnS zx2fmvmapEs`q;PUllQIJD0}+Yl9TaP3&XijxJ9e=+_%2vXLzSFc!PvmmgP_jvTl^0TXUzmXH)Z?{~<>(+ss&eOirr>;Lg z@zF|YRma0`Ps;IL$-ZH`;=TIc*WstWc&{w`l3iMLSNEyZiSkU>%IH<|bVA;j{fpap z>x*LV_2WD5__e>ZjOPxyS!);Va> zo-mkc6K4NJoDC!qjvg|5-9rfP8IQ?wq zm+wl^T-;B8%hyf%#q{Ftu50!8cB!R?zSiZrKjY}3r}4F)_sVRz|HEqc(xuD1Vq)fm zHLmN}a`N^yMd#z|^vz@HL$^48eYaZMCV%dyFJCt-s83#habNtJFWFk=$5LNz zYSZ?qzH>3ZA!0|y#v92F|LeZaJFB%OzTn-=bBCpFSuQ_6L-q2q^Ov5_H1fUv`7`$` z*~NQhOR{h5@P8j?l=4C09xzm(0e}pdtZ~J-w&e6A@Y!5HNK30+NTwn#)1#5f8 zyOw%0R=a@5{}&i@|ERIs`RG#jlV92ECmgGD+0FWP{hmMRMGt?bpRTR{-~Q+EM)jpZ z_D!=nkIe_MDau-(1NXTGJk-Jci2KVLldPkpsT(ogj5iGyXE zlHNbQ>~9M`-@Im4Ozr%X3x3P)yj#A}cyD`Cl$l+~v+M2$I4|uM+Vkk;EX{RWOw<|P zdwESbvheRx_dVfZ>Sw0;-d`hL-dX3f@!w6ZtP^*&F6`c#RkN}$dA|`?mT6`0+1G|= zkH6l0d*0WDrmst*4}ZILVrlJ>ycHJ(_OZTqzIA-<@jL4tT=Qq!=yon4XwBPGMny;G z-VVJtYxVr58y(VxxBg1^a$;Zo?9eXU@pn6)?7K@d3?K~<>*)@8e%tnZ{8aqu_3U-| zB^CR2O<{eX+hZPI>6ha(txq{2ROfh~q-yp1t-E<7F8FKjyP3ZddFC*qx^Z1>vGkws zFWY3-2*d?!*m#ip%<1f!A2rT(kDDGn^gI&u(#Bj}{Z35L?q?<$!kKr@Xh%vd$ba+b zdO&ry-u?duq4^)`7M)yvr}T%x&WF2JKiQwZU&p@Y?@CaI&sT1+wCU?mbnM<)wC-XEfuKF-F`hU!B6W#oS6}^Y77glqh z{XJ*CZiGf%wnW@~?IuRfjEH-}^A(n^d@1zmrnmO#?~^Cko!V5qL`TzAYs;HGtsk^a zH1-GDpH1GX@7ZKqb@GaD>!-V)O#KY(ZOUPbr@$#6iDc3E zKYO9+hS@XD<#V*HrDSgA8Ch?544TK#i``ah@^^~-{Z+djz?qDq~tyeaCV{hl~-+QvscW=~9<2^PX zJ|q_%pZ}gW-z)ieZ^@en+Sad2%Rfx-eF@#3@1QPx;)F;3hb}JZNJTrF1f8i*jg6$_ zMfA0FxaKbkJnwq+DDO6Z@3%sklXo%~cbDWn^2*v;X;QdC>}}rt>uVx5dgcB6+M6_A z`{j}#@=jV>y*{gPJE;coNFFHNGe%^zRFBy3cL?5k){r>fh=1%tCUnjHw-Sn>e z>myALk5#R2wubI(yH~qw+1BTCFYIZ3p<69~X`dqRjdrJ~JiDFUEbKfJb~HAtI_6K{ zdg<%9?nugVsoH|eYMgly`Ujt$RxwGRCbB+8PkJw>)V%k)uT5tCKetCUXwmajTphAo zK?%`^R_Uf6+zDN^k1lz5OZU4_P-V$}s|I;Pye3!i;tNkjj z&)x3%^+C;!g`qcB?=wle^XjkFuV3e??#lixP5uWgKW*AJXYskSX5C8I zAF=Atbvc!37wX^IZJRsq+J_o0v%Id7-lJ-lcFYWq@r&6ulRdZbq0WxqUpDKXIO4B< z5;W=Z#y)X=n&s)1kJZ+p_xUZpMBI#cYnnOjptOXF?|pUsf4@(vwLUk`y{B|J{fx+N zzG=T$tsYme_$JE#V%`$Pvh_QPgG_Ahhc+FJQms2G!+DGMXXeXCUS5*|cE+FDKIO!; zUe!%irTbF8fAHv6-gRr{SDz2>&3~SNGp?N)7;2+ez_t*~3Vg86{;u9)_qS2WF5JiB3(xWzvNPx; z{67+W{$zIk9_9ZP57rkQsC%sZ_~wnWzU+0oH8-u-4d=U4A8+~dNb=LG*YD?@&NO*- zC$_kFN%eP|<^F|*oo8n6UvTeV<=rh_FFVwkKm|c>!T)Nlrt{!J(^^vh*Y|Aw{r2DHPb=T<`s(}g z-mBW_y77w3=hser@^X3iP2NlHa&;X&*Zo7f%bW|>Oy2xn_uaMkmHPYsJl|NBS!BIi z@ZZmRTRqSSU!~4&&Xjk1SkHZ*Y@Bv(;>yd*UaOxyd-cPgI9Vfy`!{Br*A#|1?tST< zUdexT+J;jfoqsLqRFBSo;CXh!gtq6}&(BZZbanO85bk5)$DU_zxU2e<_2{q7i-aO~ zZ;bFViI{Jzuhx-^Os6C9d_$@{y|x# z@QH?}pa1k7KUfN@ADLLMuiu{CaPL;DjiYYU`>8v2SQKW@c9_2}=-*xbPxtxlC(DPe zonBObz%2!5A_!?O;!u=dft zo#HWS{&xQs$W(n`oLKl)=Kt>>#+9GnepmW^tLW+X{lBLMS8mv<&GPPr>HNA^o}k*f zd{=bnkH!8Ld+#lj`*U2_sO*cz$unmrxOPuJRjj{9W^3(NY1uVecOsw1D$V!(b%;~V z^|iq39T$IX+g=Mv3HRdIpTSR+IimI8`hh1^f2ZhhYhT~`#wf!fw*A#z`;3JDRsG_k z;@*LQg?n=s$;ue!cx<`L`%e1GfzliM@4gj2e8^kJto+Z2=C&C)XYRy79Gvq-D~M&z!k({&&r@udvxXTX8t`e(kqOC*x~Ee+P8u z%&+)kxaszdK;Ayv++#X_O*UPB`q?wytU|f0xq0hmHcQLfc7OGzt$do2e*BWoGc(!0 zwjsZrij9R*rYFvP%%=Tk z>ZRS;n^M$X^>QwqI%(>2!S8jFn~d)1wib7ris%bnaM+Xfe(SG2VGFKHFVJG=6?;F? z-TO|5;G`+D)IM@{KKgbnlRH=Dp9%Nb3%j?ppME{jVt1m~|9#xAc=c72-MtHDg&m&1 zd&RdaHz6mWBUSOB&ISV`%PkjBYS>U51R24fr8i;D9F_h1zlNK#&9cnyiz&PM)mmg8 zKYz->YU#&sug6Vzc$G=HY~6p~KOt+Hs-pEHqY^)Ti_V*tU0+xn?Z4FZ-2bcB@1I(6 z_xohU-8@qyf6a=uQ?e*=6-`}pees^NL@iW-9 z#&d%YFs*qMTepRQZC zU1WN8#Xc2{Mx*^dm>pLZupW8J=@I7D^u@zpWWD?0_i^)Ew6s)pPwUS6dnu)|Df*i4 zZKce-=_=JGF6-aB*Jth8@qMnszSy#fElX6^+Q_e0to|L+koEBAtI3xn_MUz#I$z)K z(c?#|y2{RdmahULH{~onGi&#TbJG8_c@DBML2E^{k<|-AOk#&GB`Iv2{xGxC(*Sn2 z`I`*~Sf9@gRZa*D3tM*Zd%TCI=S#kR$#)saHzJ-seflu=+|D<1a(C8zxOn8mOMmO9 zEqp%>zfR=NNLadQQ_!;Wb7Ipg?(HgnJxf~hsMh)8n~oUe={zpkVg_n{ZMok06WX?S zcrNzi*X{Sxdk#GAv)pvh?5ecP>ZymNxdiI}`W}A1)-J8$uGS25krKY`y!P_NUmjix zc=~z%muJ^+ot~nC7U#xF_Kh}(|(cQoQbKcG3KZ@t7{@S{<@!nm! zQ0;74&5@3UU;Dn^=eL`-|KHn%GY&nCU0oX=@qWSDnu6MY+x#Ot%CdeJ8&ynqyvUck z{rvOKCl%S>@4x$R+MSE{?mIusK7ZD0V)S|m#rAjh4o*jg@mS>F2dbMZIEcQ%&g9is@`GW5s6pi@n?%F77FP)0OLM z+P|}+b(+`W)k1mX_1491VcL6d&ZCP5_MTpK`nCQHrK!&k3$OZ^qgd5{PvhZLf!aA= zUfvDnvnz=Ayz1YJyY}`u@bl)fYhsz3ISZ0lAU)a}iHy_hdcLtfpBK6KzjD95F1MK3 zefPxM5&tXRXzqMB>$LLojm36xVxH?T#v5P2z#@){AiPc)_x5!7gmu8_m+GYh|+qw_xXI|#OZg> z=2b;LnEm|b8{OjP=k}Ce+4&Q<*NC=e}2JlUGr(xld6~d9^HOle?`c(@=C4i&ENgCx7*&d z{NLUxdTnF4Z_OpcPw)Bu z@+!07+gnNh8=F(V-MoF_)tqS+A9t!NPWI&H3i*m>r2@7{`zyJHjy@$N} z_Qu{e+wp&%bqHIwxT)sB1@~f071pihIyUvpQ$4MY?;DrTJN!*{_o=tpQB_vU?*8Za z7rlSaovN)9pT_?R3!Heq(|@ts)3E3trxz7{pZ)<07~lp<2dv$?<-3JWTX%)z<%L z++FxsxBTYa{5ys(cddT-`f+m1+AqIf{*YYthhBRe^=G7 zH_BY(e|}xWpX)_SR;#;_wXuRNS9i@$jkn+SS)?RXz8Uy|AoQ+a&*9h@3;;;^Tdf1Fj^#3Ay?3wD#KQ ztu77?``2As{(WUb+r7QJoa2rKt&q#!e^!fmDNFE{+}pPzSpVnVT{r#g?J2y|-hSJV z5&kXz-X`CBK1btrFXJi`JHz{g|4v|_yFld&13sCaEyXTJXaB9Ky($sy$Ry>|)GR12 z-k*HY@W!5>_9811!i(cH{J-FD*Ez#y8OQ0ljipubxQkF*L&2*)&I0?G3DGE?wYS3$hf@z z&(<|QvKw!1tzN(Hzs~01+zAV=ZjY~LTzt&mB`|Q}TCLP=d%ye%may4SKlAM|-ud;G z*LS>_@V-;4`R5KpWnaeK+pH|huB1-=RX1zOlr?GsBCi-~qTim_mQiXS7dJ6GJTUW` z&YneD9|9!zXltpi_z`o-Eh0iV#xk$O^=xQXeQxjhicKvoUCb}sdE~n`E_PqEhm*PX zYWXttbeo)yDzDceMdak`f=Ed_)_q_LQiPN_8jX zb6T(W7h-?v2z~GS#4LH zb@A?H&a>5KPMyJmlP3Lr@a8dp`BdMyf080AceTFS@9g*LyChp_PgaDfg8plz`N>~1 z!`MB`sw<;Bl;ywv?z^U2_~V7)RLS{_U#=y^EJsQC@REvw^_71Ei4m>CBB)}KaM*0%nq4Q*6+otF@tZ#QC5G^424G3;%Bw_ zrw-H~e`~(le%t?b&AwS5LnQ3K75VHf<=R#HHfM7r=Yszw*K+>&r*>@-&G>M_`Fm0i z*Ru_wV!D6sZHer$F0((sMUUHdSNYNZ`~F_qvevVkuWIKWvvyutp30fxj|-3Ge!FG* zZhPJO6A8Py*y?}Z?cea@{8BUCHMb{!<$HVk;m(=;4-fr&e*0GMj~3w{Rqx7wBz-ea zwY&VZcfZZ$RejM`VHa;`@A`M_VCm~?lHB`duMJO5dVFE^{REF?SK8n0mo|^7=iRf% zrZ@EKZWbk-ztxs8j>uJV3j(b>7Y`pL)iQ$BT5w;eis_`{xE$M@#A9Q`}db6wH-?A3qr51ub$ezCM} z{k*#$S8_eu|NGy|r+$;B_`EHukBIxQXUq4~`Q1;?CU)0^ciD)vZp-!a)!X*&&63yZ z3ICc}Z|r{G@Kvw-Yq!2sNZyA%A=8SdhWE+$>*a61SAO+};f&8`{}ic9pWabaRHQib z#oMV9mD`dpzOTP|d+qkqDNo)%JEOIIZjtncTanR^jm>tazBaql^15er*?s%E|GYes zCJgWEerWQ^+pSXX@Yq)QbMNt1X1xPz&3#vWxOFr8&P6-tZ@(h1zHQt$Z^pW&=g0dx z8f^|T*bu!Gp4PZbVmH}`TN5Av`6`SPJl_lP z=ubYgRDwq<;9lgvD=I7B^t$G1YX;S7T)Mu+BgCW`BmB)c!7e7V++kD0(Zuau2+s-n-P>n8g7Ul21;X|2t_Xro5&W8Rz#^wxV^IKMl8Z_mTSZ3(lu{LY;{ ztGoVJ=GOI_*zR7r%(3ss7u!EuzsTRI`E9GAp|Qc*kMmLGx0UXOKYwL^z0CY3lqXka zQFEF-m?#1pUXQoZO9R=T=G}-u%1)CsEp~mS0|sc z-RoHC~7;Z(iZCd;q&_L(rZ;Sdv2&~F|;bpS-*Lb^!!Poanhf@thjY*lip;b|9{@H zuZi5vc)R@Fp~A0UmMl2nVB05nSbtSX!~5Is>vOiBjz9ZT?0Rf<>P|DG%mvB6=YM!9 z9{>3G{JO0>;-|g&e(Ah=n$3#&i&DS4WF7B|-JLyU=Kej~vWxFeO4UBayI{Jy-PzfH zHRWm_MgHA;ym+t}9U!Q2EXixjMius`b z3Z7p^H>2kHZOHr_X7l-v_Oio$?(Wm8=RWZxj`z3R9JRa=z@t9_Kvi#94 zt*w@JFE7up|GW0L-u;bQTEgq3*eg#)Jnf7zvW!?4n=9h}i|1;I%_o(v3kv!+HO1jQ zveFCZr95l=W4n7o*&B%EZT8IQuWp5$VF&XW6-Om)7FF zyX@BGty_BC?dWmw)#tZodv5%-w`cXQ{Dh5MXUtb9dIjt~WfdQ@i1|5pDBGW=CMVg7 z_%%$gyhCdB^~m-Vl3kG~$e zG4J-TJEf&@(Ql=iQ&c8ASQ>u+khcE0D_2!Ko;;IYe>`2QV~LvUKZpNk-}vinTD*Me z^4DkTCkD2cUS4}XvvcC~Sf+aW_`P*Iqxb?P4c5;vi2Uz(qvBuc|1~a$Ixo3jyI*xV z<#F2IynFs9Z6aGSuF zn@-L%WPLWffB&A1;YY9RSufff`zq|)ui4wPW2PmvPoH1!#eUvf;p{)=i4ofqh5c5X z@9ZhRaNyqrpYEWh=H?F<>QZ^zh0f>6X%g?JnY^lHT!`zJj7R&GwuxE{dXPvh9A>^8r-{o`*n+t#Gax* z8Gkp0AHVm_Y3kRCS6kR8PMn#!-fQc&_=0~sCxn-tT6ENVL&?pe-R-BA+_8RN$FW~q zT5|W^OHp_GPuDKpGilN!#m4i#v)de-PHG3IJbG>W-9GB&a*xnuXLqgo{HW^mEcW%D}6p18Je!~6#inpefwE;)5z^xbAO*JTHm|z-#%vc zuPmXDcdae|8K-#NBktIwnTbCw|CC?dRmA+_>5kcXd-xXX?RW82xY=F%n}5ZEWc@F% zF7nD+xxDCna%@}n=e^sGsn<@bul~O#VyQYu__ltbocy^43pO3UwfcF+e8uX&Ych6s z|MJ~LV%LsChp#e} zPp!ST;FeZdP~#7dw%syI{z<167_L~i>g}r^N?)DlEqeAUsO6ASxNW4%zVELXs;t3BIpm6lqTzBWp~R})kGwc<+%BTJB6?GL*@|DFrExF5e|wI%3w-b|yD zN)>TTF>*8hSzNmE_}tmk#^?91YW{w_S8}DfciVgG{Qa!&>ppa@y!A(3%qcF&Z;r>I z>BY*SC)w_^J0Ux)YjT5e1Kp7(3xw@o^cKkwI_uQT&r89Xy6vU&NuN>1bX zH7=y`?vY{&JE(8DqEepZhz(OW2q-Os;*8=E}d{WRCsy9_j$F)Vt?7{ ztl_k)d2TwVJ}!Q*UgW#fMThkF>uy`2u3cO8eFMk5`nPAle>iqqKH|#nQo#>D!;3@N z&fLEc;rnTV!#wM}{ha+aW|tSqg~J=34z=7TYA^Vd`v1LD?0@a%%J|B+vRA%%#9&6_?PxqLqS#+km@>JO84ZLfc|v0ZzOwrEom)7RBOQ~krLo_;Og znEw9XDw#_OrB8R?&|bg4d3t=su0wV%Te6ueLznOQ@M-o`tDLK^N=4Z&+|D|2^y`)K z$ea3;SLM&C$<0*Dk7l29M@&ejN3ogh#q_;dpGw+p{pj)fz17q%IsU2jtE1w)dfzou zj_nfNd%FDW$?Lu=Rz%JG+xJaU>+(S^GmF&?CHnf}U*6r32v#q1_ z?Ozr_o4rHADyLT7ySdb)B5q#9f~MzpuY9*}?$^H*b9dw446!nK>$Vj)e3qm>UA>@8 z^v622(%IrCIrI;{*VB^T+a2{SF!E7zt*xNco3&~ecQ2Y7&c?HD-Y?_TlTIu?u{VPC z?CP?R=+yi&PSJ(fsu`E}d6nsg-CBN@{Dy)MG zj{s=0U*O0RQYR<|llC)joTfWFy5y#n_nxEYq}D}j&#iqYWfs5mFmD>;m!n#jZyq+D z7goO^H1a~o$8X;bX;0-?wV~XJ(_q?z+~kRc_kTZFoZ9p}wZ6)&jc<*8fx)E+S^m5A z;3mt@g?c&uV3xeN?w2RtA9A71876p%ml^Du z?U{f7eaN-opKGGn&r54BU$P|1=f;i=|9^f6xcM>??rR5U?i$PA(x!}GFI$~#vU`2n z^2dY6k*0D{u0cF&-zk<$H+KB+GX3~*dHkct=l87%xw|TCQs?&f z^VNd8s?`cx{rwz~J6k)v&mB5^(p zw*NpwgHdwbyQSAJ?(>e1DgJxb$|2@oLtI?s?z+X9<^AtseNUI}47j>6{QIx^_4B+o zl;3CE?d<8}b!g7c<(qz#zq@iU?e2mF!RHJO3(a0jnE(6p`n^Q)(b5+;{@TPCybzMz zlW^yFIV`hiT$sS5zweV;-kzs=OO{64eO$S#cG3aAo$mFIUW$hptniu`!<~9~neK$T zu!PzCLW) z&A6MqlTQA=X8kVI-^P2*8%5D;tIvLv^jEvSc9XD3&+!@iPcM0!9$#^`CV1*}*_Xy4 zH_z?fDRp6ew#K~O>-FXK>}8K~ZCPxwoP)KUPsv)5Ez?!iqqs<)cV2k?Q%%hi?UPUa zc(>5#;_fOlr<5*Zu{HijX2ota{r5i6D@rQqk>85@6H`_n_!%SWFn?|Hi_IklwS8Q3 z&IkTqYqZag?do%>>sRYSibq_H7 zx+Ruc4Q{MDG+K#e+&rZ9`_IJW(i*o19ak;a{0?|7tMQy={ob!~XEr~v|9>X=!{^Vs z&pB@IKEwQ8{QpLl=zq7*Osz49nq%fQ~U6I(*CP^pNK~6O{?wQ zwJq~=SdT=hsMxm&cb&hiiY$GmyBjJH0&k?%nEdGpA`s8LYp(wAj6(VoKV^ z^)D>kZ^sKaGfn-uVcF4}Hzm)`Ha&VZyzl6imD^{`Dh{9d_w}wTDQ`me{+q2W_@L-Z z#g@zypF&u|uW!1k6}~#>zfgyg>#IM14x8_I_$zyrY2}d;BRyDq(xH(}Xu^Bx@R(v| zHlCe4^0mKIC!JLbnRZ?EWX%7g;rAab@;>(9Q{nZ5|Bb=If~T$5t@^EUA^4Z61M5QX zfNIy&yKTNROj5Pj_@!BAmPAfg`aXMl@63k8>3xUiRDLcMdwyz*xUh8l&Eoxsmo8p^ zE%Il-oORsH!!rB&eB1>3HMjd6mao@!ZsU5iHpkP~`?&so-D5|j^A1nFey>CJm1fjc zU3NaVS3Y0F`D8o!ud;Nzc27@uy-n6);*1PygBvGLK3n8;3bReqiSAQ8?Dkrn z#pBwiTRMH8Bv)nlMDApb*sd#Ay-iK={Q<=%@9*~RNj^Sd=A_P^JwhqZnOU{CYYn{; z0(w0^?3q2CzwEg6!`)Y3?Kpf=Ys0>0llgl7+LYOdRezJc68S>)c8y!xtM*^t(|MNZ z*Xr}GvES-{HSnv^Rqc4z^YV5@GOMrW2HkvJ+;jF5G_7EiGa?HdnmMQV)?QACeb@;b z8(PuRQ2On=vioa0fkVG!uGOya+5dXexvu)_59;mz^{hVDe{uQFvO}Uj9xjj9n)}kw zLPJ34K(0>pcUc3yupfD`=35FoT;2X~Nf%7uGBsTBNR@e7&cQ0;qX1V3QrP=31 zhLl{IaloEcx#7#}e2>LleJw9OKOj+@o7-s#&Z$9+@bW4a7<`&=?#sVN+WCu?SDo^^ zyeyF;{ClVG;X?vKLM=;{q_`YEqNrvjcJbmyE#*&sPo6!y79IXH?p@z*`6E5*^Ih3X z<)tsK<5g0+_3F(HBTk2X<|ijNsaRL!PM6*N?ZHF$`Iqcscb7PA{!sAt@|H{sraynL zOkOZ);*1$B!sV(~9-7)Xe<14N%@|?+_E&05=JG7vR7bfugj`o4OKlEY*%S)E@2 z(b}L^e0|v3NcPH;-=EplR?V_I{;1@|g+!NCg{LfYdy5Y*)7@(2=l+vNGI!1W&)i)b zGxKfieqZDa|NhNoN4go$QPvaZbluj?Ivf|1)3A9~!MjyXFJd3?_^)@nA@#bYQoH}r zgO9=frJM7%?|S_+i|P9^-P?+j@9Zvp%MmWRL4WeD&v!n3DX$b47vHhs3Cr?*`^6UT zSRv3_b*Q%UmyCMS%THH3Iz3lhJ@D^UU;A2J(*@+^1(q?N3niG?cb&8hAyd#*7$7Ob?jCD_h(0~G;Y<*|N7}( z?QdN(Q_kF)D7FjNj~rk+aIS0hujF4-q}N@Re5M*)U+KC@@Ra<$*Q>9jyy30&$ly}rJ_+H=>eP}8|qK2hg<_VwH~?=M@u`N_rIy`k=L+TWrney5&a z|FLDos&Af5C%6CE?z?|gRZi{I^(TMy)b{vWG`jBppBj^Uq1^oskEEkfG1rEa>^-OM z$u)Fa?^eEZnn8SO$i5RNS>M_H(pXSg{i|nvv7CN0cJIk+dfxlj)64JZ{%kX+ zeVfbQNih0m!QD2Q9QRNjtyjC+ ze=YvCrvLsiP~S6n>xvZ;g<6Y~QbI(&$#)!Cb~gH|{N1@94_dFEx-vRmdX>?)wtfHN zYi;@K|83=Yd@QaHG(R=_lv`HZox67pKV3@v_4V_J<+NtRv0hxQ{zp_?T+vopcw&2B!uNa4tLo;=dT{nZWw!r1 z=m-jC>gH8H!0@YW^YfX|V)v@h2EMrM=lJ5+x@lXS04MPWAF6KuJ>0+l!KshQ1{DeQ zwdXRmn7=p8uM4c-V7umDh4#(!In#gqVCj~XwRU+Ba7C~?_gk3Nmi+XM-bOFy_AOOo z6Yc%JcYEA6j(Po|jGyP%el#^(;WP2}w)a|-=YHHIcvvfIQ`qw^x-x>$Jb%HzG06;C+wYK{l4B;V23GccNTS&}}%5V1YKY!rd-QR-J(;4dR?O9lVDywJ+ z%$qk)LrW`U^0v(rrc7x{5zWz$d~IxOeERQPpS`7X)E7bfSdbYB^H9MrH21|8;tLMr^6zoLBcPl}DmTbJ-m$UQlIN z=p|6Qe%@W**D>gW(TvB%CX_Hp-eir~Yt5<6C!%P^d?L*8rQWM@x&1j_N9rf42drUw z`+D<<_Z@yJYL6FqMSQq_EjD6fmhH4ZfAy#R+bp#@wCz`}_4fxKCO)2!@cWaH)Rpx4 zm3p}Q6VI4<7MNduU<4VhJ#dh9mO1zJ{zGPE#%5-6KYy0~=g6^apL06mN#UJK;_f=` z{j$eb=kLpYb?bs+vq8!QhOa9Melvdg)PBErw%P2ymv>e+XYO3odTy@&)w{cL*^7$3 zo4;#YoxAw$`jG|E*UxEPp3{C-vGjG?&i7}_?Luz8xRU(rwC3LGtN9J(zQ^93xE_B@ zRai`}<_RbF+c?|Zk!y+(r75({C=;(>Yb~$6{rKbUxs@F!^IGO|>P74_<+H4G<-JyU za>D%Ob?H;)P3#nzT4?9XdL}*f`GO4_I5zcT7z9r=4U4(1LYy6Dpn@`z|ETs=KT6Qc2pfmFjz6YyUucDs^@|u zPVf?5#?wLQxTv`3%J79<-V?$Fxwwla&Y!(@Ud{D_PF9(d9kmM?SXZeZ$hW^*{5TL& z7&Nj8W+aL_=sRxw8hWOA(bGBCYFDnW3wdVqsrBW-m;NsnJ!!VgKFa8Y$C5$KUT~6#vSds(DlE@GXD)|7n}+s;YKnR=c=F@7QJW zOy<}ssU15cK70}Gf3Z=L=iD#x*VpDxe(@sW@(o)Xn+was`7iHU+nQN^hl}&n`W08U zWriM)oBBHbV#KOl`!{R|*y(@#3;X+nD<&!zoW1(^bgq(t0mH+G%hmQr#4j%5f98jt zZ3;9R&%BBGv-v59*}G1+yt;+XUwh}m`eO$QS?7dY*pseY&tjI>ckJQXhw@igdTahZ zeED{9(@WdLg3{CvdmhKxed}QY2Tws5x5uBh?p@&%tHpMfPpp>MIelWa)Xwc6gT7l7 ztv?J3`30+(`Xu*;UJcw}2g#ogbOa5~Kht%#t9g>KxA%_Ki)*{|zh0Z@H811%xw}8U ze7?Ek@ixt09cF8zr&gyF6>-h0`D&BPVVmje z^W(>6{nI?Dzt6>b_%wim ztF6ARim8wOyZ)rv%tZUwr!6b$o;}_*^Z2s+{mSlr55L<_o01u3w>rM=+rG?2?v9R( z({$q_m&uu83s&qf znY=osRQF-6TWUmPJ0!pz8mmMKf*8M?`_*ar>ZIj4y@Im9gJ0gwD<}@uFX#XJ=_9vW zSsIs-anRMjJex0FfBf{}N{xajZi9w@TlUqwu>r@xoLq39T4Gaa!0w~xqT)8%O)rhl z`dPB|(w)`$dzwM(8aPVy*FUVh|F@x=ExzM)Xv6L)jm&xnc1^8M`g!WAg-B_Ht(a`a z-Bqe={BQU6@Q>R;S+E{{F_&=GV^B?JsI4?fiFAl0WhNzrU|GzFxPZ z>XC11U*-y4QAv;eDMp75Fg}l#I5X2+{&Rgq#IoC#mOCr{A3p!#NDuqheR^}PlU_b* zjo4nNtio~chCVw*Uf!cWMusR4=Z=!SJC9tTT=He)br7nsxDo>zjA+e_Rrlv z?O*YH*=J|>%lOODa72_Z{qaHy>s4_e4V%S-@SvJmFefMKJ$PUQ0dzm zd_HJvopTR7xUw*9rK`Gn`i|h*8;_j?&DOhi}ULXOC-Wcv z{cXFV^JlHuzH{f!#2-hUeSWVMPdopYuiyUboL{M%|E`aZjJ#R#Vxqd?@6Y_c{SLXe zOn5#`5|R;VIkH6M^)l(4y{p)YLqGiaBI$qIwBrBb^Al!I?@pgLhq3vf}K*{i5vWe!EW2v)$zw zx2>zfc7v9%`(x`+n*5F=wrs_1u?F_3d4CegC0@A&U>y zO+EO3Q(*YxyZm-XJCC@`);;lUY5nxNZxS~7lRKoLZDUYcfF>gtbB-a?q()PXEv z^tE&xPIXFr?MnObN3yupQUDf6Ih-QTp1-V~H|2_|d zDSc;y%_eWr<%);hUze=h{r!#h-9z(X=3A^eu&e(6Axqt83zz?V@|Inn^<>@&)UG`3 zXTq7=6Sg*Lk?ZHQUna-<+?BOnaU?x{w7NDbJw3gpwe`^D!@=x!%a<+<-@W#i#f3Wy zmh51e7#P@LQzEf)W#(0@y}Nf?Ta~|R=qSq-kd^JO{mrlNu;neohg0(wtn)d0T(5Rz z@9X%RhM`;I92)Fzxo>fveeJn|nVFw|*ou|ep}!CON?+$N`Pthq4<7Z&S`@RNoCvPn z4@9af_`jc69bBzyY#e+)_~z~NZ()7`m$D6yIp>_+fBe(8kL~^S9s4vaXTJ3C_g!J| zv-feVrf2_&7 zAYAdw?(aqo|9W;El7TFQoHLP0d``Vyn$Ldu+UoB)7e40R`6C}!^;LIGBuHyNtH0^`Rdyoq3x6d zFSQ?BT~SiBP-T{%cc;7Gv}AQNo7$x}i@E01F&$&562JR(^2-!z}%}dg-F3nkUbnBLcQ9Ece#=DS~r7e5@9;9XklM;GA3IoH;QntNt(V zm$18HQlqc$A5(c$!X#UYFFZUvB_-|P@#TVS{BQbKZudKA?0?=tIX^$RHnQT&$Mg+_ zm&LksW55lU#?9diCdN;Yt4XW+bhG=wL~vA~I3MIci#-Q!eyi3=PiJP5GH>0y*?5yt z(ADn!`-^|@Yg&6i!`@*pr-;atgPwQwckZk{aQ3qF&PYj(K*z5-A`1@O)D;jCTEpmN zd}01wF&SHMT^jJ9N9f15->ez8cZt5+^;qokju;*`pFPjK{u5tc|{$H?Q!v2`GvsWJo!(H@(W60qxXT|Ry&P^{q7Z*>M zJTEHN%wA|uAC5fI79b|E~h>nqf0%U3qA z9Mg~5t-;Kf$Jf=Nt8??s;6lZm^> zc*4iu)w3{AwLis_3zYr>?k|17Vlh9k`B4JYUV;{hEI1&k_2B8-0?D{2{cmQSkI*g1VtwU!uHzylr8fP_4ouK90dAgQH+NuRPl&N#sdt_-avJr=S6Q|Lzh+5Isu(~>P+Lb?h=48p7b%qHqU|@AQP@$i?XZs>9R*ix( zE`x@DZ}z;CF(umM1%pLZ2s zA==zIZcKjX{4_KfyS%&n7sqX04cB>KBg>OGuXih--0Ny(60xXem2jy47FXRj2kt8Z zNwM*=mxF8dMkG~N0vf)Dn6f;1C}Q!J)ocFy(p&t^%($bg;2W2Pwe{hNs#$k^eX&$<-u$0GZuTC$2&;Swj&WI78V0|TtS+>K2hl6vhVLO? z-OdUJ9!O-BaCpCAdYkNGlr#qpU}y{kgdMngm3OXHxnq0Z+zZ=ctADVw95{VC+P-MV zjujG-kuxm{l^A!IwYRq%U9s`;#$WeEe)0K+dUht$dNbN~$(M83@mRxsJZxy*03_(I=9C7XqK>J$FQ9XTT7 zo>Q`=s^87a%V<_ho8q3xVw2GIV!BZaQdeJlQU6dubjMxE_}Y(>O8jqDpUvB-iyj7O z>7d{iC#VCxJLQc5D{}lG+@Vom#j#G8-AHVMYaz*6Gv11P&H2&4l)ZAFTXZm#UTjg(-e0O(s zQwo)R{^Uu^g$n^&GH!Ay_DZkL`Kh^ze_}`A&ClA=JZ$16FP8igz9ez)-o1|QZs#?p z4#Wpa8!;ZdexKj+re)Tf-Cthrx$<%D?h@C64PR6xC$jTDaB-?h-OXfPUTzW``EU02 z98Pod@~iESJM7AQ`mgR0Ebiu0_x*Fl^zF^v{VQ)Z*8ZL_b7o?cd3?sTJ*{=G9FkMR zLPB~(Of!?NpL=`a+&Q!L%cifc(p&7E=*U=>b3bgE?PE51`S>lp9T!%+FItr2cgNrw zFBf0n^&P5*4$XR1b@6!r%kw>R7H{*qy-koK`x=j3Z;im(JN+_!POEmch3ba>w5hD9 zSdjc&@0ZBSm6;tO|CecL#qR#v(7l?wi>rG>?d^Ke(C2k%F@>C1SGY5>UAV4n=I@HN z;RQ-R3$&Pm^X9E;zW#KEzg>-Z_4jw{PCeX}S5;+YSM@*F#^A5vmdx9H*W>D$<0>CY ziinHf&dq+XKvAObrp6C;wrMMimGtE7SNnX6Hp|u6>~Cfg#`t}^-`r*2YrkD&zp?z6 z&C_cutrG73YOvj1mU!>Z`Uz7i4pmJ*`fEXV+p2#(ZS&{PKUx-PxuINt-`ww}k3tIe zuPu6cBJjnPt+V+G>L1=zFZ}pHP{J}x=8o+h-Bs%9YLD)2k9T(3^VgwjW{APNE=~!f z5{o%==IZoKpZYaB?Df7U&!4`meJ1v7YOmdvu!&|Q}uBrTN?b>Df5n3k*0YUT0FK@11-*Wa^Q;#px{p0bay?pbg*QKmD z$$CskLZ+wseLV}KW2!o@hpfJS{+-_kly_v@P+j)m=aCkcBQo}RIZS``Ui3@$+w+Ep zo9|t_VnYCXjQ54Dl@m)JdmBxeJ)N74=Lj?Zc>~t-(?zCd{J-)= zGxk-~{9mH=rRP%X?!D6c{{u0D_2o_P zZ@G#ap!L-Mx&3d&mV7LTvH!V@Yxeqg&pqvmUteE$?QOMrR*T=<-P5Yq6`$XIU`zek zRa2Lx!e(kQi$jqG4apn^%zKk#*uOR5jO2#a1FFh;*I%=0{r=kY^M2GDV+o!ef6rB4 zSQ?$#u;=Hw6(>B796$O>;dQb*U-I?7+^X*%lifEK{k$(>^ChWA##ZdVPIS{Gq0>5F znA>Ao7@65${t}Y0%YT;>{H%b};r+$U;%Yv77==V?Z>})x=(A(ve78OPSgfUE`rCVZ z5@o~w?iOO_e-j)!_rktpcb**u2322Pt-U>~=yb@QFMlqlZmQxB`unmzF|)o;*0#xB z>~GWF-Q~*a=IoA+2VY!UtbQ!Ek~b!XXU2-AfBbLmcb_@KGyCqu1J5sNt^Qp%b>qL| z^81c|Om;63`?uhMfNACfw~{wkBH7RThdloMVDI)*TP`ktzthTi&l`c`sr7#wh1G>h z_8vH(z$0HM$;Kzybzwt6?w%+8_X~Yy+Sk-)n*FPmo6*N7YptkjDrzjJch)bjcG84n z3wLB4Dy`b=6A|&_GJnM1_go%qC7S#8)$RDX&HCcH+UnZ3zxgFvrfUDY_u2$o@CtL$EvQ)8y*USFy6@z{f(Ek7#O{HWGc@ra!ky)|=j zbLY}|rI8=c2kkw1`LgiBg}u6E=AS+u-0@NPi`mIHe{ZVG&uDs{x;SOy|NPTwHKwnV zBQJhkH`5}L-T$?ywEdqye+vu#+tvL1x%|fV^6h*R^tH5(yqjzN;pcMs2OV5Z(}eD= znaMRpe$Dh=`LpRn~?}=|-%kTNT%x*u+d2dfIuPbKuHTM4NtACpuni?LzdV22P z3HxM%9Y4$O`>xg}*LmsS=OBH}k1U`H=j*%`{MO4$rK8&ySD&}5+AUH4{p|H+4=QhJ zTu=X3e*eXp*T?&1n{S`w`C=xmmA*LTQGa)DTgu%3PZodw`lILI=c0(JDye(*&v~Cb zpUQS+{^e!4mTRy6T^Dxh)cN!N^D_?qfA;dE6f5h}+RN7~zx$n;`5^iPk!-@hm<{KPn6{gp4DMdan%Pc*Za ze7?Kud&?i`t)aKJbUP#zOt`nT?rhfAncL?qNqQ}jhr3zr(D+LmkKYRW$e|aT7zpiJdzfIHo{d2p|+y9n0Z}U^* z+Pb*ZHBrxEjh2aviM)9G(06w9oA+0L$IQJLZT9cm=l%&j@3)x~7Tdij8xwq;2q;0FdH|}oVeec^&u3OU|6h@~$ z{girRbM^FlSA%6AKS}w2{hs&#n4DA3^6pKWu_kI`O#URFualLGk1UE8pY?v#mrvLJn?0T?KL6-pexJkdVy$!J)EQq*s*Uwp zT^x0DO>n&Q;X|`$`8|F2EHTO~{>IK^ZMj|V^=kecwAOn4Kk##`sGhf2b){G16k*Pf zS{47KXCFTi%>Jy#^7J#i$H#8{u<;bD(wtPdKYjkbW6N~!{r+lwf6Kl!-^|*}Y_tC#e+$^3tgM`Bqt|-$-102jq%If>TgD2hi6^Y_C38#EbM=ER=xS=$7^1D9s7P| zO3LfA%St)B?8=N*?DCym_TkGHqqnawE;cEM+SKFj8s(>C5NfqkpfX{9Tv2JUb3#Do zxBS;uoAe?tyq)^vNANk_s4W`7x@ya==qhLkD7*I>vwokxGJ;!LC3*K=rGvK_8yTz0 z3m&gZFWG)QuXNk-V=lA#q}QpHZOMq-&GYO{ulfIvo^7B@9ysATBARgLrApJ!`64f7vto(_S3i%uf~NBOnSWc zS-)X)n2^Hr3~NnjTDhjHtE-2XP2#PmFCTIyUwdC#wkg_s!k>?ij|<${vGJwF=hhuJ zB24lxUb@m(7=PmAn%9yqU!FK~!XR(kPd&%Km&}_FHcSw>{d^*GvOnA0+c{639J}%2 zamL+cx^w2teehnsVa}YKz3M7UOt|-?EZkr6w_Y2T`XPERvgJ<81q?|h&fIzGNU9D&yqGgfXociM$f({GhNZzP|q+>v>)yDw}kPXAk3 z{iSpH)s%MU8@oy;n^_k9*zjwPNZ9Uf#>U2F$!D9t`bwV_^YZEv6c_JKJA2x%ZbH`9 zkCl^7%FH&;J@E4tr@&jKTZioxE+jR1T+h4v@afZ))mzKXuJlw(yZb~5PZeRZ#G%t_ z=dY_)%rB%rDSfzuJHm1}D$GA!j28A+S;6omDY$pq+NjqKpPT;FOuhRntybw zGuQjGPM!T;KdkZnwyyc}=iiH&xuE=Ia81k{u6KD{_V+J6&e<9{ljqLHw8tMleh!uV zxK8%=sW;l1)9!bL?{`_H^J9L^54m;oYlQdIO1(Vu zLYz;Er_$51>9jbeT9>zc z`ng;_;n5Q5i>uG?+-1G?)|R$COHM3lSsT6m!TqQ8%C7>J+zXp3zb|e6+8Zx|Z@zoG zRZu+HzTw`TP2hSu>=i@R%nuj0->;1Lbo~9YcVBF0PTi;A&w6Y1Nl`qLc44cRkocVT1Sm`VM@1g2v=k6*6L6ubN3qbBbfeGQG4lv&%uxk4MZ?tSzq>B8<$ zMa8-6g;ZuUoq%kLlJH2t}7 zmFkj0jdy$Nt(cmdecG2TU7`?W8>kRy+v%VtEn~GqUYvh_2>XrMTBZ-2%F4{rYCkE? z`uk7%*PPq@bFIrSM}Ag4aOd!4;pcPj%l{2Y_^CAY;Q#OU>(&MNpH;8kQC$&Iv1WF4 zW?EgeX!h&RB>_Lxj~riIn6W}`x?#h;)2F#(cYVFE{NA2a;i4jc+lvRn>UZ?wYzH&2 zO8Gr_5^o{3j@iZ-Pm+${dXkd*n%D85qL_8kqW;&VoVUK^UEzqFIaBO+ulB)SX=(A( zd#Zo`c$I6ZWxbIluI^^;h-P)zzPh_Q~1)PWUjP`{Ie~>JSXJNH)kpBsTE zvL816KY04IbndNfhZRyUt@IZEd!^;{@t(sAPc+}yoj(2Lj4rWDm;Gzy4jrDI^nIP| zQ#qy5H&bu@u~{4YSN~YgexZkFXT4l*aAd`sAGTFr8w-oNQdZ(wN$S9OT(sa?toHx! zkNa*{!&b|H`uk|f^nj$sgt@U&67muv9O2i4Bey<&loVKD4jvxn`?|7LHM6#lOBGL+!S zxVx*@?uo}0#kp7S#(k)9NVs}y+tvOpTP{5)(a+Bp{SiAW`*_&iY0tN8+q&~k?#-K# zH#XL;p7+Dx|LvX2cGdo#n;*6Aj8jd`oRv`#mIprudH$Ol;csCmyGAVQ^XDyfZ?#0k zr`j<(srh@nytsLLoxhLAfrHGyzZ%sejmV-i8PeQ(h?~%1Cb6Xv@wDCr-)YP=u=1OMS_m~vb zn_u(4yPth$&3)C!J2&?1C|Oc?@!9W=iHm)2Z_l}v5w$HYdT~j|52J9#+bFJamp&T zfAY3P5}7Mk{<<-5?{5VSjR^hQzX~5NP_(+dcWv#awPyDID_8kf`=uRze{Zw+ohzlU zFKnD__ch8iZf3+m(DWTF9X1+!9*DMOef!Qj|M2$Ww8TqCR$sj?b^Ctyxh00h$fa=l zwuZl3jMBgDu(U#t1VodKPrKm50lVP)QtfSuR=;*+);?_dpLlC8|AN%jVKWNemi|b; zDde#%Pdq$)OYUX9;Jlr8MLcvOFPzW3D%Bq9R?N9=f58RUU9u;q$cdM0?cSbqXICk= ziuTU=^W{N3Qd#S5pg#Dr&r;&&-q$Ot%!u@=$>HIPV0|S0`s8kw^!p{BLu~$^c?=p0 zyx;29TVs%UN_SOI=7Uxix!Kd#{?9$O;|u49k6({o6;@Z&e97|d&Arq(SAB1`uhIGY zy|174@IOAe-?rz^o;^livorZ@hn+0*~c znttXB&t9#4b#?zv?J_aA6QQoEDS5KflY@t^Y43v4lR@?`+h!}ie>%16oa%8oTbb0X zq&GiSe|#6c-bpQE#`HvGJ!hA8zGt&_rm6ew5{$iagjMsTXQ$bE|Lm_bP2wIO5uT=2 z6jN-vGWo)UZb4z;-um!A%}q@;H`jEtELtDES!#NWnULJPc{@HnyZzzXYyHJLc9{I$ zy>Xrok7W7LP|&8et$!<{Hb09m2}_=SlKn3`&!zwWyt+c`udmxyS(mp2G2p%;zA;jM z|LT46TUTB56#w%@``+&lm!-BA?vjxayT)?A?(fW%yHAI&J9OrGoZ(vknKiO<^LXv5bBUaBQzTwV6p=j9j9uicem7^$UUtAq0XOK(=re0lQP?j5ib zcN}Cnm#lX9ka*brg~Q83i=1+T4?a0o^vI=&%g21d+*7;m1+gCI-}fTvi}il{V}1LD zp7ZYzIH#rXclOQr6+LfkOBt&7e`Z&(v5`r>@~?01?iV=^HrxH>xYSoU@xe;X-y64I&CLyd> zpC_M;@7Db`b3F@t`-1zdf4{1I?6a#ovn9Ie?(Hqz4jYU(c(|MX}{#pCnC@?6Uo>~#{JhN6l`0CiK zf9!|0`hlxwWBs{4gkN_)wJ2WvRr%xoTfb~1Z(C2C(BPQm)HQpzwAJc;-ZwXAi-+mO zr>!{zU)m?-@WAK4?X{V9`)>U?0otrl^6G}%!K|jN()i!}GDq&8{=fEYo@Gw7VSDjNuiU@=ZV|K6t*xeO-DT~XOtbxM8&7X(hVBw*yzJ8OJ#_iW)+BSy z0Cpxt#ijmMr7N4a-BiKTe7fSWz=QQ{{=Ged&sQF(;4F&Un`Fr+cPBrq@S;BV!^KVO zf5%&Ruuu0+*e-JNz`wtHEN?98`x-d&oO`d_a^|(w^P{Ci;+HgC694}XR2?N|ovukd z{%!4#Z?o4MKAiRX;Zmk)ph4ccnb#*iZTeGl=HDY@8M_q8H#xESUsu&%)Ut|VU)CSo zc;(Y3J$HWju-u#HUTHMG*=2t{Zave7yQOMHC*AT^uL*q~we^#H^zN+G+y3@7{nqbx z@&D7>;IgiJkILg6DL2jat+(f2HhXqEC34ehemSEMS^186S`Xslg7(e%YG}4De))89 z{a>PMZ@W1#z3eSbS=0oY8=NjLbYb4oruV=3WpZw%?G2b&?CJ3HcK)6&cKJ#le}{~P zO&6EnF}k{FCG+oZ5Ba}VzPz}4`_Zz;UQ1@J+3@K7Qi&yMg(r5X#aMg3-&8g+;k#x0 z*+YS*3lHt7s5ZYeKlt%B1Jld{yG~qYv8(y7>$Cg4;@=XMlfU%zUmN|uy_187=-i-}m{#u6f63)JwddzhnY|0kYK6}t3G~?^j7#_(I#XWoXPFNvS za_;Z9`t&P5EF=&GS>tB^2F5Sx_f4O7;F`f~yzG#0^3namd0g|_PifSjEuH-F(r5pL z9<0IMnwpx&wil;6Gp##sxqK?$vi>fsC7YK`U*U5VX?8X^$jfw3HZ8S``@+Pr%!LapZrBVD%DngozWuiW0jv9N;$9e^>!ZX z|NonBclmpht+C?VkG|iz-2d|tHBIUs{VgH zuH-Yr;^v;0MyID*PM1-+{&cQ+{LvGE$rr*{-~C>>oZaK%b+?`R|Ne@LPKle<>;8Vj z$HJN6|XH}jcMVCyui<(1U2Y?Ze%b|oC2_s?zq@neUP`{~In|Kfg$>+Pzr2$~$c z;nDo1sjp73RZ1OLt#8|Waq)Tw`L8W3%?A@!sr!4(_6 zwN$gg&RU!M_SOBo$aU0lff-+)%CN9cwTryG$9>*Bxrzt(tbJ!snl$O-$MpD_*UpM> z%Uyr_y~MNUMPHtlzBXSJJ)iN#y|vtCd3TzaOckfMBKNVDZ*I6e;o;)1`Jc+)-z>N4 zZ?0XAsCdE6rba8Fj7xjw=2^bG(P(AGJbNir{=mEgOQiFT{bbg=vb#QZhXZ@S?bXrZ zw`*%_1%-sTVB;;yY_Vb%cuSP&T-^kV(FD` zS5j4#{8+g0MEJ}%tAqAPn+E;OTw}D1UBQ)g_VHs!7A#nhl^gQ3=G!Z)m7c7Pjt4V@ z#QNsE(UA#fyeI1GV~~G3p}?`Az@V$UJ5->0(L8~~eeu(HwO-d$Tz%5#evEqH^-DoM4aC zVu)313klh?XU`YQJ$v^S+We9T3ONv5+P%1D-m2U6a_-P(zC&cA@!#(e>5qOqx%aEh z^ZKKg$Co=d-Oimlzb>xDUA~?z^HpcGscv1}z8l+WVO zFwe%E)la?APxjX8BaRHl7v}qg_twH<1=ebYI*@_&oL1xeXJ;KhPt(1)rjolys+u)w zYhHK$^Rw#$FBF6_Tn=sM+LN`|qo5=vr>8D-yDjIv^%@QPcjbmZwK!>@fAHZ{UV-g- z(M%6>Q&Y^>tNTk&So8hUD$kW?cJ{pWX8SX1%AGqgGGYEsE3!_WIkV!6;?0{kEkr6e zT>5%?^$U&p%Rl`(Q41ebdf+2Ip>y$ho1Ywat_sh4Gqo_;?a}(B_0CK$r5E+=$=UI8 zOJU*18+%e`$K_u$k(ti3-y?n3{NHbDT-=Y(dL=0ywLPmd&UUx+t7og!^WWax9>14Q zLC@}B#L_d>ySL>E2wpt4rS|51?W-GizIvG8w`0TqpBeHO!)(`{VwE<_YfCw)ucKph zRX5*JO(Vu6MImbC`x!$=~D z`RCHDX58J8{B_n>F~%=KKmJZRwaUICpSV-I`T|14FJ%8`Nrq+!g zQ$Fwe&1gKYhA+HFx^?&aJ!f}FPLHWuIxisM)&W*TO~=SJ1++4+s9;AoY8XI^DNu%R zaOPgJV$Fl~d%wu2#nm(aioGD8_byMO{;R1(`BN4ZRaK?9O}maCRkG9bE5GW`>eABE zqO_>i{RcbSgBK4ESNv?9$!p6qZ$7g5|I^>=Jy>mV&93kNW3Lv0Ne&7-te3h*MR~RE z3M^k(l>hr$-rfAWu`739z9&_x6~NW%RCs+ti^`F^_h$NTwpC|h6w=vWY2R*aY;A1) z+g9_v>hqiFf({Gf7-wJHtG0UgS&e@ecdx%{ofrOc&n=eiw|zeFPHjFWx8V8wDwo8> zg}l5MJ=JAaH}l&#JdgR1|2J>b&ir*M+p^R1*3?D36?*iVhntu8V(j+&OZM!k+57*Y zdTHP7zTfZm`97ahnYH)$n^}|Z)jNyF)Ku<0zI|(P^|zeOck6$=Tiul#Jon>{Z*qRt zse7Vk*T2?_-nZzR;w|vu=e|0igCDd1Z)~?*{qM`)@Y1mR_a2vuEn#M45xCLF#B$-i zLyli70~1&=I+4@eaMtDjEp6eicehVAeYZi`q~L_X&)>gS`sS?p{3_e%^7ZIdt3o0p z6Oa8`y=Tv!dx|AWC`YaDZgTMbP*W2Voo>A{Q#v&GzUa5~?*b;z zrDez4C4I7A4qfg)#kTGGl+e}JGfw&MKXv?ic=EUV;blF#7cT}@y?Iz|@@ztKNK8zO z@t$+Pzg~}d$a4O6{pGWNvl};;^}oCO=Vev3a7 ztPXyjI(6!=}zW-tr9&wb?)4|Ea_>S(4)*Dh9y%k=n?zN>!< zU;AEv6)!&bxrueT*QKlBf4s}@fA={1(CWQ%8~-L}J-6C(YVSilx&&aL4 zYtLQEYkv7%%Ibu6!@YMe`)05I9(A7WX8f1;+FK2655Mfsxa!4!r+Rmv?Jth?g|~0t zxMn*)!|3z(_rLuUYNqbg{PW0r{k8OXpRzk|_qFlLuK9kiD)QUr1qz6CvSBR~%Z2>a zGM_=A*z5A<73?eklwg2d)X+FrB_Jwl)zNM-i}iE2w6gi{&U+hmx90BEa~}^KYGONH z2vG(OeMXjVF^vrk41b@W@-F?iGu=Y`=Oyj@R}0A6*3d&~E1OJLr6d%ORIf4_T6euK^>u{!wq+k?B`ZPz@k=D#}O;8lMi>)&UB z&7~def1lsE>(MLe(7?cl>ul5C+1yQS`aHkliQV?|Y*+n%ec|42TXBIwRc%}GZOffI ze|;CdzU$!UZw`5J^Zph8UArkc+vxFb;cbgIt*y3uw&L*KbHCnv)<11kHErhRe^-3B z-%Z{0?*7}GzOqoy2skh_t`%BQH}7(oZzA*>F!cNi3e~UNAt6(;FE8_X9vTx9^IxF~ zdW#V_WD@#CHyr$|Z})wN-u^F2t+SV>-kiSnwq5m^%_br?@$n1xKHoDpRNvh3jhS>! z?b8p={9(RoRn>ns>+f5aKSP+~|KEQ5-N$ppe(cz`F>iNS>Z$X=dz+qT_x(32t@6EE zDSu)8`taWk7Z>lj^?u*~jb=F>A75?m{qu)u?~hN?rN6c>Pmccf=KcHSweGy-{@M9n z6;C?T?`%tdI`_L>(6ReB|J(jv3CdPbUtNe`G`e6O)>R1QBT@_w7BANomhhNbsU)~o(oH+_v=s1v=-iIuhWYu?i0n(5Yy?W?|{5GT%BrhkT74d(z(YRo#zC`?GE9rW4=aUiSWWb;hN&(c*ut&RQ?7IlJf5 zrA@O|UEh87!oHnC(b_v|etw$D%NM_EW-_netuu|eH;Z#}q}Pj1Uz<^}ziff6UDgx3 zxZ(^@>VmrXLIfkz3u*167FhBqBE2G5jaE#&tmoH9Y&<2I&HU1~`31k#2Zo~biREj-ulM=vbL)8t%seQ zZD(6AjSGo+Q+n^k3Xk<=Z{1$MSaBT3Aq7Z>+> z`<5=>yFCBQ2dnLO*Z24LOP$(sf3th}`i~}{f(#lkH>4V0-LBl8#+HoaKuEz3P70Vr z)EYVOYXm-yZ!#+^ZRD3F+RUH;96oMy+%(JAX=_VM?YjN7-tcGi)bNlUzwLe=c`PC)_iUT3_VYQFtL9Za zv5PIZH`8xIMZ^C6&mXF-tp9wsKkl_m`58ee(<1rxcDG;LTf17%=KmV2zt)Q%f7ajs z&FXD%zwLq*D?HZQWt)DSdHl(Jp0qgiMU8NmZgA%oaMyk@9l1s0@HGlb# z{oNOa*8Om=(Snl2YwP_V%|FFh=- z_HXXgDN}Ytd-&umKRLg4L3IAEYd<4*|LUrLefs>p>v7KPJCj!+CC?4IOuqHpueZHv zvV`V4ywL*Exx4qks?h8&zt2Q+nKa&*9#=WnYRRXWd5c3=U$6MvQ1bp-D0{!{0qu%=X;J$hulxP=@RayH$IMcb4<0(Y>(8p!p>f&{ z_8J-|c<04$w~L$}U+Ww^uWa|Vs*g|2OTLzFuSi|=J*MDi*VJ7P9-W>#eg1p&dY3fU zGBo~Tou(7JuF!qn3T}Oi=;iZjnr^8cspdU%_Vi_*$vf|-&5O_6^uxUTXU3)UsNH3I z*X{ge)O)XdN%gKxn~Z9|ANJq%>elSgxNA0&AMQ@hO?|qy-0s5k$@{Nrs>>~B{QFyT zn{Q9p+Q`+c++r{H@~f|0v7$mdJjDVj!QW%DOXjoOb*fA^X3LS^9JvMj!E42cYY%r47hSOYcUhY4B>+<^i>3g)aa^XE$Er0T8N;_DAIFz7~ZbJEmY zd3)odZ@#(0!pWN+l!vV3oVUHu$*iNUT-V>GXuh9R{hHl>C;pb-<(%hH;P1f-ir<9o zVh`%W-(HiKpY5Koo8{M+cQ4PVGyg3!G?D~KBg!P)tj1kTqN1Wvxkk%xUtbqsWMrHg zzq=|^`nFp&zx1l}`~U1ZxR&q5{p+@2p`lB^p47~n&4m;!(Lx{YUSjAYwx9zA%~{P2 z-{YK3Uj8*VNq=^}>f_GirDsE@pG^DsUB}MOZr7tt-B(wqf1Mosc4Pc<-|)=LmCp@c zAq8hnSOd?O*-sx5TNyDhahPmBut`+=>e}e^pTEMMGw%hJ4=a?9W&Y~1-;(y$>gcx4 zi*<|LR^-o*dlz=<^y#lB9-rTltA%8ziCY81uVWg9Y{Z5sBg-sb1#Ru<>G7q_^QwOd zx^BsOI%m22_jQ}r|MK$6nxz&~wDaE#)8+dPe^EpfK>^_lPL=%hxVk;(nyn8%QYa%i z1r&l9+zp3W>SlcEcI&YV$=~yLpO%)^Yuo&|x_xT(pZD_Fy{Tw={#taAFx>GA92tde z^0_5ntd{)&5pA^fJ8=HI|KDHVuDz&rUsb+duB$)$^`2YDj#^!xHEmm9X68#T)A!wC z`d82I_q)93CwFLM=?4@rndA_}M zH2dzZl;_oFzn+vX+iAO55uT$O?|Lt=YPh#-@p7nV56CG_5RhN~`Mj<3<9_>NoHO!Y zEIPEi#B6`gt2c7{Ji{#yevz;Hvofygsqam9xgez00z7-7h&9et1a*2+PlsEqpIcaW zt`kw&J?HviHT_$;)i2xcMmvolPWo2Uc;W=d-Kxi?v;Lhn-}Pk@=WO12`5uSUR&FnT zD^;euTMe8Qad;oaW^h8mhhGQ}t z=C9lPuuN23yju4D&EB%NLR;>yc=$|e)p}Jcty4SqJv|+sb+c>gEc^P2MV~)OZ9RL# z%us6YeUJ2<(9o%N|DJqyJDV&(LXvJc@J`u*;qSZ8ksE^{(XfZb$*JkbiEY;b<^{`vI>WuHEM{`zIJ{;Qwj@pm8XtN!w0*>d^% z3$fh{Rnwc03p#e!_KQD#D$)ZbZ?*8KF}S0 z>~eKZ_C7x&^=&@SxTShz_vE*hZ+FU9ebL;W?;ffYwe=GBdAnuIZvCIEQp3WwrJehA z`Q)zr*Rn#lR~Ikuld?*gz{JEfXQSDJKPQjB3r`JQYB%f4%sG(ZyqunKE8qCezGv%x{P^)=YNvnZl@qmh zf^$7QuL}Fyt}nNrp)$L2f0?I23fnnm z5Sxh${{!=M0#fzPxqrGldHuv}XK>k(;4jR<%X=}I|E_ZU{rZ3LKUQ7ME_sys+${4$ zP4DevUwGygoVppcCneH%dhxsC^83Qe^sQITDZZ8&ckuIPF`X-k?sHd!->+DH??L76 z^&-Lv^@nxKU-cC0g=J>0+#D+H@&8q~zxFoYGkv$Lo;!kVB$Bux%Hs23kM4h$`=Q%^ zLMjYKma@b~ZN1$tveqiQthY2i1a+lmo2Blo^^HAw^5j)Z@jua(KYzZvBrA0L^t)7d zk?OtM?|hK|9^yTH?S+kx&j;K(Rdo8cppcLyeirXuob`Pu zK~iAKX+7BA9w$B>GVFRlPF+C$dYJgU`f1loZU0^Q9C!2KUOuzLzUnG=zy;7KcwC-?Q$X~n1{7aWCGp*u1-#AfF@YS`on|GDJ z&f4^Fd*G_b^w>{qXJ>s~e(Ka|+xA^w_2y0%k(GVA1vLEkR^BRQ!JE~~rc4jdco+XU zd)6LOT2UMo90CsS8y!U^{mX9rWeOX8m1npRL>T>DTQ|2j6(g zT3amNRK2nK*ZaHtCbw7C*3^`Inb^Mbb^V8r%V%Xao!P#0&%bBYc?^FW>T2ga_?mh; zJg02sh7AF+#aC0UUVjO`qwsGQCur37UHkl!yS>}ZttRXXKmTsm=Wo(?Yp<*c{hYV? z)&76ac31t}x_!#jsj-*e?uq|C|8(h@!1n5|S55Z)c(QlaD&zIv4?IL|J`&6<2ke>l z{SR3QZ6qC7r*@ckhjmqoZTh-=*oLA6trFvz))(xo_V-t0xN# zf4y7n`ReB4+iBOiI5;lsEx)(uy?Xtvgb#aS71rgh5#I3sBzwNrqR`c6*PV1Ep9ap`XBOOxJXd{I zUO2vP@3K{k7M;B>@qlj$DJ_#N4vb7Mq93%MQw1mTH+4+xJ@>9>UyiT;+?*rutxwPF z@!#q3wTmzNNxq+V>)qO&OfQ5VJ-++-%sg9nGmbjP5$4zH3YT_kWN|m!4~_`tp;ve$nsrbH9S8#}>{FTOaxQ z+trY~9pAjl*YMtxw@%vvY8w~-_{(o^Xzp9{=*s2G#-)!-!>ztXZhro1+U@r%Bb&-e zisrK%Kk}YQv_mVZ1aUzLn-%-7`_=ubToqpJZdUi_W%&BbSMSZfe(-J1k)ua*x2_<*u#|UcUQsw$Y{CvLR4wi7U{zc{ecpdiyBZ2vW#eyB$a~{H{}f zHvYlQl2;Q21+CuAP@Xe=?e*|kNoVHl{Jdw{y1nM>n{VIj$i96oHZi$sSM+_sso#CJ zeLw0w&9q`w&l#V+AD>mf`&d_7wY&8Eskz_nmdyLx_Hv5xx$>rW-QC@`{MT3h|MuHw zd;SH7_tNTjm`QZ5=K?F)S7yGcLJ;?Iyy0MskB@hCb*-A4Rr`r;{Wjj7{~vGvUm5GP z=kor8DIW60A1D3uecr~^3^{4;8A9*$V{aM>Y;gCaz58ny>^qKq4uf7$3 z41b^3otJj<($jY{ZrqUA9=AIvAYg@NZ%vlNvt>HvRrBxJ-n9}XDIL58W%qB=o0uSu zJ*)NL@nhxRpLEO=Zf}+;Jz`;Aaqru0hpOApBWGp#q^2${D*k+DDadITSf=)z@qMRd zXt?(7uf7#$W|^jUFOS@9cT-kaLSn^)2?^Wxnu=CWc43}NnRS5`qF}Kjp#^y}+Q_w&yujb0U`D<_6oxc>4 z%=G84sNls@vAb5SIU*|5r=XU1% z{r5deyS)Nb$>JJ6q z&&Uej&W`h2cl+GQvsY&{_g`yF{#N{}?#D;*n_zcZm3n{{GIo*W{XaJ1nQ+52&Pkwfb&G zmti%p?31l;R$a~BbIbSUk3XmLOKzXNZs~pNz^B6Yo~yUt*X{6K-jOT3xcc3mqjP`% z>0WQe_&U$sICNgk7rXTjeu@Yi*nfO_-8A``4rucD)TvW@&ei-qP*<-O|cQ+wA$&tDU{`S~vI zdBxW<)tq&e*8|;qisQ@#>TiCk-*h|wtW~tJ*@64_wJZLuUcdkH3+Da{ z#^?7wVR?U@Z{GIo-?J@6pjHuf8)&NVnV>?$zRH+LXoE{l^vBQZnQ^aWO};UJddgql zcDTL1c2P~CX3O=J%l`aX9lm>|w0!-qnY*7f)YY0i+_U*kS+cg-i+??r{Yu*FfBzME z`sB&3x6fAbNL&b4R6O|ZQ@_o>o==}X-z}@1y3m>J+I3%f5|V0zgD{7H!+n+x9mvSN zLoxRao%f*0ip)cY50(5ebl>?_Hq`QWPq2uH$dh?`+S<|fe;>)-c`ui<=+x`{ealt7 zr|(`J`+fdt)0+2t?|hr4WoKts^=0Ais~epcS$|pV|Bv%jx%KRYldf!R-knugxKT_e z=FK+gRd39*UeD7@(CcpkWf-)~jgx!912o&kdDH+B17*t`Qd5`O{rM5RUUyFUxtDQo zpXIr@xxHA#eeR>xS?l-pYc5?1TEA~u-ju0RU;baWEAFYN=($T~i+}&l-@hig-!7?p zITs(_wZGr*fJQm4$y&eNF8S-(Z23E7#bJ{s2j6-6Htw60(TUva;XA)f;(T>^cY1C6 zo?k`9|4+`lzu4WJ^~djO+2xRMBhnWE`xzL&eBFJa8?63-p1Q%y%ldo1J(+p;&T9u_ z({<)E?=N1YboXkm+gI_pnyb0y>8bDHKbQV*?%%zfgNNrzvA^w_|FwU%^;x`0Xl-xb zc|7OX&u?#qOFp&~n-f zQj~%TWLoV;DC@25-XCt=nzZ!vo?B;cN*LD6IA`}cWPR|S50_qh`QCnU_4=G%_4$>K zvo~!j`G0r&$^Y+rURS?2b@`ThdYNzJsZ-~|l75$MVtl#P+s$p6pY>~}rxh$)uFGA% z@^;apB-^iNT+9vj#oxd8>)mR9lfU0*ZgTu!cBB5rg@aNT_OGw@eP92jGyK?}U*Eo5 z-^1#4d&asQ+cus{tTsNVYyQW*d%9kzgF}O#)!RM4mR)QI#{qG~mI_ca^iMwn1Goa% z-F@Hy6Up_Ul@P>`uF+4tkTz$zuuU9{$0oA>bZ|WvjwkAv%j8T zE?-&3R=3;#_o~=azT1A9->dTHxBu2-WMrHzpZD!s@Oi(GLeGuwc06VK`SYiiib_N> z-;MK?SM7dYKEH28{IY-BjxzjeYI6Gfd{^|BTi)k)%R^?$hU-AR*XE$g@c8S`7Vq9t#~ z({ppB0{%TZo&Vy@XT58GSi3{w0t3@GXJ1=qeDkCFi*wcTtBThw?91OjAKcN1U+xDQ zu)n_H-QC?4TQecUU?^?|2Rk-GH|_w-`P+|-pG{aicg5z`?r9<4Kd3_sz&DeaKBxPK z&NefAcki413lH7MU3YTLOP7Y9e+QaAxVml(VDi?TMTUvXP>!d_U1C9kkBI$ zA(=&AdU&2bd6M^5s0TEoYo;x5f8p+8o6@_R&h|aVHs|2*nfuRNo%5Cx)B7aV*&e)i zU^s7hcK_no=RDQF-f#T&<@N2-x=A-UVP1L3^ymF5+rPrkehFkmEbxCn@0?@(^Yg!i zx0~6_R)z-524~h=+xE+yx@5_QcPhr)$NEUTDby#Duk=TXOkgAhl)ImOh>_T}@fdwW>9 zLF;wCxVpJnNS^)u_2t_=-(Ox1{#nWTE8|l7uYybeLtbmH)t>(6A@eO48AT51u77cX-0afW2H%s+HUSwu`|<(@r7 zQ>RYVR8qQAqdsBrnm0OAMW(Ms>oZ3pKMa!HLiIAD$zVnwGX| zL&5L)6W%<3zWTs{g!Jfd)%#Yh-LU2Qo9EBhcb(#zS{3toTbwd@tres;6Sxt~x{CS5 z_baO(?}9YlZaA~B@xFOqsv7uAym0-#A6s%R>^bZAKG?r&rr_cBm*1k-U!F35*{kXC z%QN5Z`s#IWLROsg8U4FVS2w$te|>ZBYUTUH`_*N^IkU~;p0CW@^Z%myu5WF(w`)o4 zPt$u3i4LqmxZx|48GoEhNXw%~$yc?EToe`mbs0H+77bO^3SY;$;Ct|d`Tf)M|9j7! zbm+Y_EW4CYZ6KMgR{|_|2zP%qkQ*vh1=Ax-amyEX6DW7pj;AZNaTfH*< ze&VOEUrXK2&HlSN==%Cwht@o^uld*dKj?pB^DEnldrzuZS5FSpiC(sH|Gy=n+TmBM z*X=tOxA)hJ1I_%Q`~NYg>|63#YE#8Ur`rE-uSXf=uM7Ww&7|tvtJU7?cifs;bo}gf zZC%~17cXb8yZP>Mr@LIn7aKODM0w#73&(=|%=s4A!S(NkXfB>LQyW18Qk&N6PW`aK zK(_LS;<;?^cswN~CO2%XaYa(!j+mBr=!Pt(=}W<+$>)Oz_&`<3A8{w=^QtgEIu zT-#{f;**DD7k&6}PfN$3@r(Ag%;czfS?8{{+)iI9rY0aDu;N~`o2K5v$9d&X9S=G_ zdp3pTxoOecZ|X%Yy^~>unVo-XyQl8T+~#!XmzK$% z-CkbTHB>gZgf`yn;xIn=)zEh8)OjmgKVMtDV1bY6^SsPwG4H=|x@_$W{lD zKRlsXM;}?fx>kMSo9->2&E{+3*B`gtwDI@P*~=|mTvx{acIlPaxqesK`-S`d{(9Xu z`~8K(-|wdyT~5Egd-CRUyB&V>$iI|{-d(kI-@jMfx{;eMaPH#g zv(0;@Y8xuOT(tLocr*FyI#*a-0}g{XF^o(v%GcSagQ@@lhXsL5-^5D;CklS;)796% zekoPkr2e6jZp4NgSEgsbPjoK*)OmbmtW(Y2VyRa?zPDHK+yA@5InUqIH#1L^GLJ}Ohoc=V2h)r0%=Z`5D7iVZl zNz*UBR||Pxn`QjHwdR%fN~75yHdemW>Cw zpEu{n%~Q3`o*cG5YGvmBe`^-^S;n=?R&GhUwdJB@`rPHq=T#gjUJ)#BlQKiv=Kt;W z`(L~@kNYytqg;YD31xXZjl$KX-3A!g7B4v}sjqKR@>0 z|LUOoypaEOwOjtzExxigJN@YK?WIhw9zT9OXJe*Xgq^PL-9MLV7mMk}tpZIgRDKp; zwP}*OXI0`QWZR)#PDttOu)vbVXHC`A8lPuBwYK_ug=~+j)-+r>+blO?<)l+4Kf_p8 zt*|)2a$HXF^`j5ctW?qG`Q4BJ`>DSy5LlyN!#Pnwqv|MRwghegETU zwZ3^x4#_N+%+_2xWO+FxE>10e|6TJxPd5A8oB5}86gJ)c{Y8GkLA4Km&)?h}!xSGM zKeyzTq+j*dQ=(O$zlP6Q^ZOk`f7jV#|NrgIUm3gGrS$z(Z}mAPtJ2Q>xXW^Twsln5 z#H97=dU}qslP8Ht$gB~WywKjVa&K1`m-+6)YiC|J(>rJBURXGBnr>{+`(58O8Dy=> zism&L*58{`b^OM;g2^ZM&#v@xcs;}HnOkqn(j_yb>#wcN{$TteM#DtMN7hW`}x6_iY1vby~A{eADbzxqPM&as7xtqb>iD6@2Z%o4xY>QxKQ z`0tbs*EF+oyUFURrEPfgMfA<(*V9(-II_jJCeNc_fl^b{%2lD-N4LIK3k}J9`^tg! z*Y8z34utO$U8<#hL&JW*lIphC3m<&QSlZ&MeZbzqTYRl)_RSZSOy0BK8sBdgi`$nm zZIjWrIm;#Yf4z13RYIOd=KY1uZEuY)X*cY1KYy>Qr>DfuR$3;%`H6XWPQkb8_xl#k z&fg!M`0(MY%iHHa`+K#Z;m5OUS+A1!R(-v=Q&=x-HOG7P_~|pHi|s1@%l`fKc}kW4 z&aI!@cx0C??w5YgvgUs2@v~po-CSF(Keznh(NzZixA(o7#Qm!0qhY4*v+UvfbC<*9vA^|WnYXq{DRU2>7Sq3`t#A9D<;rzS4|aG3 zabTW)!vB-m|6ab{{XAYX95z%3$+`*+2ke;+s;$2Cc6-e7_xolo$zHe1r(MRx?PFo? zT<~J(H+|9Tr^|X{nRA@wzQD`#?l0{NDet~%n@2uVzBTheS^Ur6BAR*|C;#zL_;bvZ z+xJ2BvQM9lLxV&Tj4mIak@IDt)(PLRxO-KTm&R$GSs4_Ux2{rDQ+ch!%bBccbCZO7 z=Bw>*;1Zq1^W|u&s+Z^O1y6Wihom*VU_Q(g8Z=M+{;49@wx=3;3wx`+zRl2^{NU%a zpKHGF3H`q0LFMn4At50dFE1TE$A0yE%EIl8H%wDEaI$SzRkq!Gu;J~jji&FVCrzHZ zDY5yo%%1SCe`Y0Hzpnk!5xDEksq8rqe*U>*^Y`QL_rIPl*F1G^%SoF~C6DEEEBpAY zQex)5&3(PciaR&;c;IoF_04>;&solkKY5yc?ackHSx31-L&H`&2dT#v|J8kUd3pTY z(7((~C2x7RTOIsd_GVV7_Se7WleeZ^RC?}t=i5n!>vwCc_y1n2><*8i3r;Nm>Rw4n zzKA~Y{A?;xQwh`zIAL?l#^L=QyFlf({D0oszbzhh>sh!n|N45>bNT$`n>KA?` zj#Hj;BXh#1V&f^hGuI{EQuF-hcg1C6 z+QVn8pRGAQ+vh!dueHzPJ`1}lu47`$aUw* zE}otDcl~FV#*OU#m&NDTK9XAu>#%buT-XF^&_>QT4+l4B!GR1Swq!I)uiu^3eem-< z2eS+J&h31>?zipkyT5igAA7a2{e5W2lJCm>xo*|7&;Fa#eeUwp@Vg66-miIoZXv>G zkTIY(jc&w&W2kFR%_%E%gJ@!WWF>An!V zpP8rlbwaD+cJ2D^6A<<)=BQhX#&)Bqz{0m8g7=Q5OpRaq=nYS6tNY9azqCZ3glHHX zxt}s?eSn|aG|9_x3k3sLZR%ga|0OV|CY!Z=ThQ!nAG1V75{>Sb2b6u&YGr$_t+;V+ z(dVG8d8K8gM!)tOf8P4QzsEb@k?HmI^~LMWl#DL%F6i&*D*07hTzuzo@5(DZ{U+IO z-v~)cF6C2uaA(@f%XNj#&$GXMeW@<5Wvc6{Jzf7R*S!1JDotPKo!;HwzuwR8DNp*V zCH?m$jVA%)Mpeu_NNI$$61&n`DKMq z#r3F<8<|CXr}_li)LIh_0Y%^O!Fa^+54z0S63M$Q*UzXkU5C75(Q z6^w1~?!B|&LO_4jj$nNqor2#|!I~N?&OMS76T3F!;aRI?JC>ZdBN9Bfuu5w!StgyR%Vk_HFz4n!Ba%4_Cc8`TWb@C;n5eY;0yue|}@< z^_cqA+>*kVqx$VC%IE6Oy2B_Z`a5-sto7smo2Sm)c~Y2iJX|?yYfxk5pG|+Aa>6yP zrG43_EFyi|ZGQdF-mdQM^48pq?65WttT8exbb^l5 ziJhOTS^uAFYxaFNL&56Io69n}@1%b*X0CgzdQ^3mZT7OZH(R%Vlij<&YR3NR zx}PuIb>sE~NKcyVn^T**clo_*m0$I)ojA9|Z|v4g=#C-FM2*n;>J* z&=z~+G);rFFZ<%e>z>>4SF)bJF0+O4>$e--=WXLIFTGWq8}@6(e)+pO>{F*seYx0k z{>!W8_X?lQslJwJ_3wtVsDQwOEpKmtD!lJ^{&!ry7g)c=wDF~Sue~2L`xn#ob+2wH zUgQj#zdvE)zggQIf|vhar|{BI-gt8a-g42fTQ|G% z=&Cha&it9ZKVbHzO(K$FE2e6$Jaxj$RPozCEiJFGhWG_qpNm67!cxx#>csCCdiwOK zMy2yqr^D773lBTAx*uCzoZ63-8Z{D=*^3GU(;)KTb^@dYVobX7G=sO^1Zspp+A59%DgaP;U;tLIR&3q zo?FS~yX?=-;QnBI<@WF#MYK`)2V| zlv2{6Tgb!X!#|~`%jYjQtN6RM|LVNzClA{z&elG7sQ&edvHp(Q>G8GA)7D2UoxN`V zskhdTHZ+%KF#Nrs$o%!vXa8CH7jN&X-Z1sSgM_!HB@;edy`OXW>p%DTGv55#zA{DK zX48)F^Y7l>tNQ-x;k9h7ZTdz^PD`J$wce}`v!Ar{Sw!%@a-SUi-P7m(ZE0AxNA21z zvqssk#@lmuCyT)w$qY;!Z_Y7=su|s5J6`_o;_a0A{DBklCvN)8Eh=}*%}(v~ruu}b zRo`S+Uzku(e7JsF-LH47r7vb=%)50hR@&_8%F>cGpNy|(Ty0wUD!Zx1{fqR1mKz1E z?JTp_d`jfv;Ry*%UHa3!WF=epl#HLhczomcd1+7b{Z{#3=qEeN%2VpM_h^ZTJW0OR zZFKXM@sv&P_)Fhi4%?T;pE|XUiz73?=_m7*b;%2V@tiDWdXfEYpY`v}*H$g>^l}x_5Iy*9&caY!ghC8*Ub5XS3B*N`TxH9 zr+mg+x$Jjd3oDJDa-X-${Fmo>DPVHvzU4dT@p*cxov;Z}c6+<}p|ab{%bxPDW}l3& z$W4uYUa7lDw0FS*h4L?7?o0iX%{!|gUp?7>tf++reb&!7me*b4 zJiaQt|DDy}H{4U_ZA{*80NTuQCYL{ts1YPOVq%{fkSTt@4Wu(`71hJNPK;&H6Z9?e!lw;gISTBKJa{*%z5Un5?p*TBsKPy=UzCH3 zFKGR}+PSZPXTO`TrLSMUzVzFgnNqfCYZfI(t&ZL<7qzcuW%ZhcUdNaCb@lca^PQh( zdRSIWP;zZ@pZxnR({*EG@)`D?6^akm(mJE8IBUn6=-qDLQoR>&hRGYH=*w39nE32{ z8;fl5oeJF;1OM08*RCzTwsvOvq`lTh&!69Z&dO9)QSl&XOX#fGTshDFU5}slqBJL4 z>gds_5$mo<8`8g$SAR9AeHX>9vH{nfnU z-Wb?)3#jD_P8eQ>{d(VZKuhCpepz+hF06Xp^#`$Q5;s4+&T?LS#&P}lnwM9t%Kk|1 zdb|Jo%emj}E*+U3Z!Y;f|LTOj{1^Iz>k7;47u3hc)}Ix%{^NCRt^YO6^f~J{KJL3Z z<*bchLVJFXFj}We;Q|lS-0CkTlJ`!FhzKvep~oB&5w)y0Q|vW+u?!@~5W zH%LhcBphQud7kCUcVqvU*LSzAzO_YmQNxOJU77p)4=MRB*jK;AiP`G(arJ#x3HMoU zuC7_@)s?Qj#K^z#Q>a72gh#hZL%#2Gp5@r2DtKcnOU{Jvtm3h&wiRAwe7}F@nGf?) zZ(dq@>eQVlC7=^=H)yNP~n^4C(g z?d$$az2&qje;M|^GHiX+%P;P3Zl}`T&_mVxyBEJ)OYWGYn}OL z#O(VEMBGcHzdvI#P6AFKDes7M(r(H$n&s+6^VRM3`!_#%e|dT4$3^u__j1!iLzmvG{cZZZBB{O4>V1>< zll;7}mFsW(pLgEodrj%PTSqPb{M(&Bb9S=UorSHft!l4p`Yy|Dx_&Qje|qYR`+r|% zu1w3joU-73^1An*R8WHBkP+cvwnWQa>IfHl67}}1fSvM{3a<^db)Lb%rZ{#_*Yx^ z?cMqCi}Cr3Z_DqluXUFXD4+Dw)7!J~*Js;xo9{Iuotp9HBGbR>FINjOHogDR{jlid zp1kH;*+wp^rEeC@-}g6W^1tspL3N*@*2P+ZTbjSl*}gWBt$#D|U19XkN2~Mq-a32r#kcR%i_8A%Z!hrs{q)yo z;rNR)n7;B&UGV|6J&C|KnVOC`xS2pZrJ3Vjn8Jn!?udhtc?Ym^QteWq3 z(%pA&9Udpu`pZjcvjOp=a9sv$D4h_USDWXVEys?TzZ1q(Csa~gzMP%+qE?k(XwqW0>l#6`k2Y=lB^gVLnhcKh+j-Z|K;i6BbXx{u& zt+oG)x~eLxhF#r?MYmiu7v|2{^;K%Y)9(MPY9qG@W^8dtNa%3u+j>%(X=~Y4CEc0k zi!T<>PD+TmU2*j2(cRuR8H%clJ=i~2&wr@=-E{x#73XaBmwnCJ`~TbQcNXVQ?b-kA z)%5vwSL%NEUwp8)ZDnlIqJ6*9HciusTJq+NZ&yc0NdLUOB^MOiEswvsBe~!A@|v0Z ztMwjVSzhyhZJ%Y`9yUI?MUVY0BI9d6+KY;cYntfz9G5YVyIcLOpdTjd$h0*o#-@FSq#njsJJ`$_Eb;((elUeE8e;s=mKm-pp@%N76q1n@+hLV!>_WG<64t+S9+!>`X%GW-oB%(uv#^qrd0N zEWMo{V!r>%UGQh=bf1E_y!5qQbCaJ}iQO*$Cb@iuJBPc~T}HLXS2WdS-|w+Ge)Y=c z&Bb5-bg#c=GW+XYC%gK%{J!fmvzi}$mn#i;n>y#)QQ>n}L7PUd@Y}tyDDUBwoB!iYvfuBv=yzAN z*Y91bH`n^*(&zIEj$a9}`Q2y#Q^)uB+27q^za#IJ{`R%{@__kib`y(@cVy&DyFWkb zcfCJ&e4E6D+~+svPy8QKIrGpVC)??TO^5s~AJ?pn*m-MpeYVuvLx)Q@M*d&K`FzHK zcN?sNr|ZTi8l~7ScwhfxJ={`#VezHi;r!p9Kl-#f|3bCAPf>r>zcX{nAEwT-&flkI_jyJe&$n}V zVR`!)>hAqnbHDPv^ShYnk8|EvCV1Ny&r3!=P^5u@DO#wbgJ)WN=rpcP+)v-nUirzZ zp7p2LY5$pOA8g$pDy|Kcx_OI5tX_HMna`<~JGs1i3>?2^pXt4;9XerK#J-KSOD@%f z{$yWugynep^XHmZSSJ0N629Wn9Tol0@9!^|ARyc#oyGJr_gJ?4^MqQ)9#4YilDG_08R_rED9$(eUG|JE<$Ue5bwbI#hb?|OZNID zez6=2?q6a*^YJX#mcHKdrsr=L>}c_`wrQ}lTDCQB_v?LZ-y=dJm#*CZZ_W4nm4|Ik zF5Gjl@cq88yM#sRegq!Z(6e(~KL6|a_mbKEn+|@RY*(|tZ2RSZ?`G>?t$(0U`tp`9 zXv~;h*2<4n?QzwNpL+v+BQ5Ip)tNH>_6-dRHhUp1oROE$AhGrSKPk(sEt4i+pLySZ zYf#ARjOQkxJvA@>mY;dg$bI*6-fNrP2S5Xrso^niSuVyG-JE)C+o3A~=)LQlTX{S~GAy>7@fBv02eNIzHt01q9dab?zO|G!_i+gmVxF;l*NLh$z$=?k?7Uew+# z%@zCX=P5f^=TqME`%?{nhxc!udFQ!qM9A+A;k)nD+>95_k(HHwD!2OOX4$8y_u^B& zy}$0BzxP|ytyw|Yn$tzzv(~yoF|u2gyR!-&qIuA6xXTy65Mi@6MkkZ_YN(+2|jVaog-#jpeI+Bi&yw?@y0OFxn;h zdZGLLqUCv~&(E=*i5O@G^&U64GRhk-@(R4DcDFiopVp~AK4m|YM8&49UbQIVr)Ke% z57&LW`b=jo6kT!WOvukE&sHul@UCoKcArt?G0B`D=!TT>Tv34h!}(IW4)$T_2e6TZFac_{=k3UwYl$ z5IEIrf}M?H;e{VHt z)?55|r*UDy3{P$ebKIiiLFH$xuEkB%_y*~5lr&O!5KPR7QPMGNR=E6nE zJm%ZMJ_dh(zu&u9^z^hVkx9|dBb(FbSH-l;)lJ#yxqS8HhxhKS`S5&={g;pJ?=_eC zetrMx)tnFS`|Q*F!k6yc_`G1U?ESPq`MGuO*Q2i1%jf!d8=GtFS-!J4?fT4llP0bC zf3Iq>pY7wEuhIq=KKj18b5wGAcAnoXw6K>QAF z@vDF359)@sazoaaFu>L$6tF(BE-8Pt^7XWxwY!Ut+8z4-D_ie+>+|`s>cN#~OKtd}kUrjlAZlid7rL+0{vhCL`y4rHvSmDSCJym`*INmP`?CF-mHh4R-|g|B^8&Q4 z+Bnr+*l=-P`<-29h3uc+K0oI{+3n2vd>=j}`)ePskxc96eX{S{tN)iXm-m$4sy`dQ z!kN$h-pcELK5paOw>|R0+v(H4eV%7rKJQ=k`Q};qO@DLU>Z^JA?|qMdyFb3P?Te

    - +

    {component.name} recent incidents

    diff --git a/apps/web/src/app/(landing)/status/[id]/history-bars.tsx b/apps/web/src/app/(landing)/status/[id]/history-bars.tsx index a41469c3..a85da73b 100644 --- a/apps/web/src/app/(landing)/status/[id]/history-bars.tsx +++ b/apps/web/src/app/(landing)/status/[id]/history-bars.tsx @@ -6,6 +6,12 @@ import type { StatusType, } from "@openstatus/ui/components/blocks/status.types"; +import { renderIncidentEvent } from "../incident-event"; +import { + type OverlayIncident, + bucketIncidentsByUtcDay, +} from "../incident-events"; + type DailyRow = { day: string; worstIndicator: string; @@ -49,6 +55,7 @@ function labelFor(status: StatusType): string { export type HistoryBarsProps = { daily: DailyRow[]; days: number; + incidents?: OverlayIncident[]; }; const INDICATOR_SEVERITY: Record = { @@ -87,6 +94,9 @@ function buildSeries(props: HistoryBarsProps): StatusBarData[] { snapshotCount: prev.snapshotCount + r.snapshotCount, }); } + const eventsByDay = bucketIncidentsByUtcDay(props.incidents ?? [], { + days: props.days, + }); const out: StatusBarData[] = []; const today = new Date(); today.setUTCHours(0, 0, 0, 0); @@ -105,7 +115,7 @@ function buildSeries(props: HistoryBarsProps): StatusBarData[] { day: iso, bar: [{ status, height: 100 }], card: [{ status, value: labelFor(status) }], - events: [], + events: eventsByDay.get(iso) ?? [], }); } return out; @@ -119,7 +129,7 @@ export function HistoryBars(props: HistoryBarsProps) { // single-class utilities) without forking the shared component. return (
    - +
    ); } diff --git a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx index 4ca6c477..a06f7363 100644 --- a/apps/web/src/app/(landing)/status/[id]/service-detail.tsx +++ b/apps/web/src/app/(landing)/status/[id]/service-detail.tsx @@ -44,7 +44,7 @@ function jsonLd(args: { export function ServiceDetail({ slug, days }: { slug: string; days: number }) { const [data] = api.externalService.detail.useSuspenseQuery({ slug, days }); - const { service, latest, history, effective } = data; + const { service, latest, history, effective, overlayIncidents } = data; const indicator = effective.indicator; const status = effective.status; @@ -128,7 +128,7 @@ export function ServiceDetail({ slug, days }: { slug: string; days: number }) { {service.name} uptime over the last {days} days

AM&}6dmg6_uE*{`?$%o6M6 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�x30mxR-Clbv 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app.png b/apps/web/public/docs/guides/how-to-deploy-statuspage-socials-notifier/bsky-settings-create-app.png new file mode 100644 index 0000000000000000000000000000000000000000..83864e9c97f672904254708a5432123dd7a7201d GIT binary patch literal 256991 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

- +
diff --git a/apps/web/src/app/(landing)/status/external-service-components.tsx b/apps/web/src/app/(landing)/status/external-service-components.tsx index 6bdd0be1..aa0cced9 100644 --- a/apps/web/src/app/(landing)/status/external-service-components.tsx +++ b/apps/web/src/app/(landing)/status/external-service-components.tsx @@ -16,6 +16,11 @@ import { ChevronDownIcon, ChevronRightIcon } from "lucide-react"; import { useState } from "react"; import { ExternalServicePill } from "./external-service-pill"; +import { renderIncidentEvent } from "./incident-event"; +import { + type OverlayIncident, + bucketIncidentsByUtcDay, +} from "./incident-events"; export type ComponentHistoryDay = { day: string; @@ -34,6 +39,7 @@ export type ExternalServiceComponentItem = { indicator: string; status: string; history: ComponentHistoryDay[]; + incidents?: OverlayIncident[]; }; export type ExternalServiceComponentsProps = { @@ -89,10 +95,12 @@ function indicatorToStatusType(args: { function buildSeries( history: ComponentHistoryDay[], days: number, + incidents?: OverlayIncident[], ): StatusBarData[] { const byDay = new Map(); for (const r of history) byDay.set(r.day.slice(0, 10), r); + const eventsByDay = bucketIncidentsByUtcDay(incidents ?? [], { days }); const out: StatusBarData[] = []; const today = new Date(); today.setUTCHours(0, 0, 0, 0); @@ -111,7 +119,7 @@ function buildSeries( day: iso, bar: [{ status, height: 100 }], card: [{ status, value: systemStatusLabels[status].short }], - events: [], + events: eventsByDay.get(iso) ?? [], }); } return out; @@ -178,7 +186,7 @@ function ComponentRow({ days: number; hrefBase?: string; }) { - const series = buildSeries(component.history, days); + const series = buildSeries(component.history, days, component.incidents); return (
@@ -199,7 +207,7 @@ function ComponentRow({ />
- +
); diff --git a/apps/web/src/app/(landing)/status/incident-event.tsx b/apps/web/src/app/(landing)/status/incident-event.tsx new file mode 100644 index 00000000..710d4691 --- /dev/null +++ b/apps/web/src/app/(landing)/status/incident-event.tsx @@ -0,0 +1,38 @@ +import { StatusBarEvent } from "@openstatus/ui/components/blocks/status-bar"; +import type { StatusBarData } from "@openstatus/ui/components/blocks/status.types"; +import { cn } from "@openstatus/ui/lib/utils"; + +export function renderIncidentEvent( + event: StatusBarData["events"][number], + index: number, +) { + const key = `${event.id}-${event.type}-${index}`; + const spacing = index > 0 ? "mt-2" : undefined; + const node = ( + + ); + if (!event.shortlink) + return ( +
+ {node} +
+ ); + return ( +
+ {node} + + ); +} diff --git a/apps/web/src/app/(landing)/status/incident-events.test.ts b/apps/web/src/app/(landing)/status/incident-events.test.ts new file mode 100644 index 00000000..21ddd2cf --- /dev/null +++ b/apps/web/src/app/(landing)/status/incident-events.test.ts @@ -0,0 +1,153 @@ +import { describe, expect, test } from "bun:test"; + +import { + type OverlayIncident, + bucketIncidentsByUtcDay, +} from "./incident-events"; + +const NOW = new Date("2026-06-24T12:00:00.000Z"); +const DAYS = 45; // window start = 2026-05-11 + +function bucket(incidents: OverlayIncident[]) { + return bucketIncidentsByUtcDay(incidents, { days: DAYS, now: NOW }); +} + +function keys(incidents: OverlayIncident[]): string[] { + return [...bucket(incidents).keys()].sort(); +} + +describe("bucketIncidentsByUtcDay", () => { + test("single-day incident maps to one UTC day", () => { + const inc: OverlayIncident = { + id: "a", + name: "Elevated error rate", + impact: "critical", + startedAt: "2026-06-23T16:19:00.000Z", + createdAt: "2026-06-23T16:19:00.000Z", + resolvedAt: "2026-06-23T18:44:00.000Z", + }; + const map = bucket([inc]); + expect([...map.keys()]).toEqual(["2026-06-23"]); + const [event] = map.get("2026-06-23") ?? []; + expect(event?.type).toBe("incident"); + expect(event?.to).not.toBeNull(); + }); + + test("multi-day incident spans every overlapped UTC day", () => { + const inc: OverlayIncident = { + id: "b", + name: "Long outage", + startedAt: "2026-06-20T22:00:00.000Z", + createdAt: "2026-06-20T22:00:00.000Z", + resolvedAt: "2026-06-22T02:00:00.000Z", + }; + expect(keys([inc])).toEqual(["2026-06-20", "2026-06-21", "2026-06-22"]); + }); + + test("ongoing incident spans through today with to=null", () => { + const inc: OverlayIncident = { + id: "c", + name: "Still down", + startedAt: "2026-06-23T10:00:00.000Z", + createdAt: "2026-06-23T10:00:00.000Z", + resolvedAt: null, + }; + const map = bucket([inc]); + expect([...map.keys()].sort()).toEqual(["2026-06-23", "2026-06-24"]); + expect(map.get("2026-06-24")?.[0]?.to).toBeNull(); + }); + + test("null startedAt falls back to createdAt for the start", () => { + const inc: OverlayIncident = { + id: "d", + name: "No start time", + createdAt: "2026-06-22T09:00:00.000Z", + resolvedAt: "2026-06-22T10:00:00.000Z", + }; + const map = bucket([inc]); + expect([...map.keys()]).toEqual(["2026-06-22"]); + expect(map.get("2026-06-22")?.[0]?.from?.toISOString()).toBe( + "2026-06-22T09:00:00.000Z", + ); + }); + + test("clamps to the window but keeps the full span on from/to", () => { + const inc: OverlayIncident = { + id: "e", + name: "Started before the window", + startedAt: "2026-05-09T00:00:00.000Z", + createdAt: "2026-05-09T00:00:00.000Z", + resolvedAt: "2026-05-13T00:00:00.000Z", + }; + const map = bucket([inc]); + expect([...map.keys()].sort()).toEqual([ + "2026-05-11", + "2026-05-12", + "2026-05-13", + ]); + expect(map.get("2026-05-11")?.[0]?.from?.toISOString()).toBe( + "2026-05-09T00:00:00.000Z", + ); + }); + + test("incident fully before the window produces no days", () => { + const inc: OverlayIncident = { + id: "f", + name: "Ancient", + startedAt: "2026-04-01T00:00:00.000Z", + createdAt: "2026-04-01T00:00:00.000Z", + resolvedAt: "2026-04-02T00:00:00.000Z", + }; + expect(keys([inc])).toEqual([]); + }); + + test("resolvedAt before startedAt paints a single day", () => { + const inc: OverlayIncident = { + id: "g", + name: "Bad timestamps", + startedAt: "2026-06-23T10:00:00.000Z", + createdAt: "2026-06-23T10:00:00.000Z", + resolvedAt: "2026-06-23T09:00:00.000Z", + }; + expect(keys([inc])).toEqual(["2026-06-23"]); + }); + + test("present-but-invalid resolvedAt is resolved, not ongoing", () => { + const inc: OverlayIncident = { + id: "j", + name: "Bad resolvedAt", + startedAt: "2026-06-23T10:00:00.000Z", + createdAt: "2026-06-23T10:00:00.000Z", + resolvedAt: "not-a-date", + }; + const map = bucket([inc]); + expect([...map.keys()]).toEqual(["2026-06-23"]); + expect(map.get("2026-06-23")?.[0]?.to).not.toBeNull(); + }); + + test("maintenance impact yields a maintenance event", () => { + const inc: OverlayIncident = { + id: "h", + name: "Scheduled maintenance", + impact: "maintenance", + startedAt: "2026-06-23T10:00:00.000Z", + createdAt: "2026-06-23T10:00:00.000Z", + resolvedAt: "2026-06-23T11:00:00.000Z", + }; + expect(bucket([inc]).get("2026-06-23")?.[0]?.type).toBe("maintenance"); + }); + + test("carries shortlink onto each day event", () => { + const inc: OverlayIncident = { + id: "i", + name: "Linked", + shortlink: "https://stspg.io/abc", + startedAt: "2026-06-23T10:00:00.000Z", + createdAt: "2026-06-23T10:00:00.000Z", + resolvedAt: "2026-06-23T11:00:00.000Z", + }; + expect(bucket([inc]).get("2026-06-23")?.[0]?.shortlink).toBe( + "https://stspg.io/abc", + ); + }); +}); diff --git a/apps/web/src/app/(landing)/status/incident-events.ts b/apps/web/src/app/(landing)/status/incident-events.ts new file mode 100644 index 00000000..2b13a7d9 --- /dev/null +++ b/apps/web/src/app/(landing)/status/incident-events.ts @@ -0,0 +1,82 @@ +import type { StatusBarData } from "@openstatus/ui/components/blocks/status.types"; + +export type OverlayIncident = { + id: string; + name: string; + impact?: string; + shortlink?: string; + startedAt?: string; + createdAt: string; + resolvedAt?: string | null; +}; + +type DayEvent = StatusBarData["events"][number]; + +function floorUtcDay(d: Date): Date { + const x = new Date(d); + x.setUTCHours(0, 0, 0, 0); + return x; +} + +// Maps incidents onto the UTC days they overlap, keyed by `YYYY-MM-DD` so the +// keys line up with the day buckets built in the history bars. Each spanned day +// gets the incident's full range (`from`/`to`); `to: null` marks an ongoing one. +export function bucketIncidentsByUtcDay( + incidents: OverlayIncident[], + opts: { days: number; now?: Date }, +): Map { + const map = new Map(); + const now = opts.now ?? new Date(); + const todayUtc = floorUtcDay(now); + const windowStart = new Date(todayUtc); + windowStart.setUTCDate(todayUtc.getUTCDate() - (opts.days - 1)); + + for (const inc of incidents) { + const startMs = Date.parse(inc.startedAt ?? inc.createdAt); + if (Number.isNaN(startMs)) continue; + + // Only a null/absent resolvedAt is ongoing; a present-but-unparseable value + // is bad data, so resolve it to a zero-length span (not extended to today). + const from = new Date(startMs); + let to: Date | null; + let endMs: number; + if (inc.resolvedAt == null) { + to = null; + endMs = now.getTime(); + } else { + const resolvedMs = Date.parse(inc.resolvedAt); + endMs = Number.isNaN(resolvedMs) + ? startMs + : Math.max(resolvedMs, startMs); + to = new Date(endMs); + } + const type: DayEvent["type"] = + inc.impact === "maintenance" ? "maintenance" : "incident"; + + let cursor = floorUtcDay(new Date(startMs)); + if (cursor.getTime() < windowStart.getTime()) + cursor = floorUtcDay(windowStart); + const lastDay = floorUtcDay(new Date(endMs)); + const lastClamped = + lastDay.getTime() > todayUtc.getTime() ? todayUtc : lastDay; + + while (cursor.getTime() <= lastClamped.getTime()) { + const iso = cursor.toISOString().slice(0, 10); + const event: DayEvent = { + id: inc.id, + name: inc.name, + type, + from, + to, + shortlink: inc.shortlink, + }; + const list = map.get(iso); + if (list) list.push(event); + else map.set(iso, [event]); + cursor = new Date(cursor); + cursor.setUTCDate(cursor.getUTCDate() + 1); + } + } + + return map; +} diff --git a/packages/api/src/router/externalService.ts b/packages/api/src/router/externalService.ts index be5c8080..70c39e99 100644 --- a/packages/api/src/router/externalService.ts +++ b/packages/api/src/router/externalService.ts @@ -9,6 +9,7 @@ import { import { type ExternalIncidentListItem, listExternalIncidentsByComponent, + listExternalIncidentsByServiceId, listExternalIncidentsBySlug, } from "@openstatus/services/external-service-incident"; import { @@ -192,6 +193,7 @@ const componentItemSchema = z.object({ indicator: z.string(), status: z.string(), history: z.array(historyRowSchema), + incidents: z.array(incidentSchema), }); const componentDetailSchema = z.object({ @@ -216,6 +218,7 @@ const componentDetailSchema = z.object({ .nullable(), history: z.array(historyRowSchema), incidents: z.array(incidentSchema), + overlayIncidents: z.array(incidentSchema), }); type HistoryTbRow = { @@ -247,6 +250,24 @@ function toIncidentDTO(i: ExternalIncidentListItem) { }; } +// Window for overlaying incidents onto the bars: the visible `days` plus a +// one-day pad so an incident starting just before the first bar still buckets. +function overlaySince(days: number): Date { + return new Date(Date.now() - (days + 1) * 24 * 60 * 60 * 1000); +} + +// An untagged incident (empty affected_component_ids) is service-wide, so it +// applies to every component; otherwise it must name this upstream component. +function incidentAffectsComponent( + i: ExternalIncidentListItem, + upstreamComponentId: string, +): boolean { + return ( + i.affectedComponentIds.length === 0 || + i.affectedComponentIds.includes(upstreamComponentId) + ); +} + export const externalServiceRouter = createTRPCRouter({ grid: publicProcedure.output(z.array(gridItemSchema)).query(async () => { const [services, latestRows] = await Promise.all([ @@ -306,6 +327,7 @@ export const externalServiceRouter = createTRPCRouter({ history: z.array(historyRowSchema), effective: effectiveSchema, reports: z.object({ reporters: z.number(), threshold: z.number() }), + overlayIncidents: z.array(incidentSchema), }), ) .query(async ({ input }) => { @@ -322,20 +344,28 @@ export const externalServiceRouter = createTRPCRouter({ const days = input.days ?? DEFAULT_HISTORY_DAYS; const since = new Date(Date.now() - REPORT_WINDOW_MS); - const [latestRows, historyRows, reportRows] = await Promise.all([ - safeData( - tb.externalStatusLatest({ ids: slugChain }), - "externalStatusLatest", - ), - safeData( - tb.externalStatusHistory({ ids: slugChain, days }), - "externalStatusHistory", - ), - safeRows( - getServiceReportWindows({ serviceIds: [service.id], since }), - "getServiceReportWindows (detail)", - ), - ]); + const [latestRows, historyRows, reportRows, overlayIncidentRows] = + await Promise.all([ + safeData( + tb.externalStatusLatest({ ids: slugChain }), + "externalStatusLatest", + ), + safeData( + tb.externalStatusHistory({ ids: slugChain, days }), + "externalStatusHistory", + ), + safeRows( + getServiceReportWindows({ serviceIds: [service.id], since }), + "getServiceReportWindows (detail)", + ), + safeRows( + listExternalIncidentsByServiceId({ + externalServiceId: service.id, + since: overlaySince(days), + }), + "listExternalIncidentsByServiceId (detail)", + ), + ]); const newest = [...latestRows].sort( (a, b) => b.last_fetched_at - a.last_fetched_at, @@ -373,6 +403,7 @@ export const externalServiceRouter = createTRPCRouter({ history: historyRows.map(toHistoryRow), effective, reports: { reporters, threshold }, + overlayIncidents: overlayIncidentRows.map(toIncidentDTO), }; }), @@ -424,22 +455,30 @@ export const externalServiceRouter = createTRPCRouter({ ) .query(async ({ input }) => { try { - const { supported, components } = await listExternalComponentsBySlug({ - slug: input.slug, - }); - if (!supported || components.length === 0) { + const { supported, components, service } = + await listExternalComponentsBySlug({ slug: input.slug }); + if (!supported || !service || components.length === 0) { return { supported, components: [] }; } const days = input.days ?? DEFAULT_HISTORY_DAYS; const componentIds = components.map((c) => String(c.id)); - const historyRows = await safeData( - tb.externalStatusComponentHistory({ - component_ids: componentIds, - days, - }), - "externalStatusComponentHistory", - ); + const [historyRows, serviceIncidents] = await Promise.all([ + safeData( + tb.externalStatusComponentHistory({ + component_ids: componentIds, + days, + }), + "externalStatusComponentHistory", + ), + safeRows( + listExternalIncidentsByServiceId({ + externalServiceId: service.id, + since: overlaySince(days), + }), + "listExternalIncidentsByServiceId (components)", + ), + ]); const historyByComponent = new Map(); for (const row of historyRows) { @@ -462,6 +501,11 @@ export const externalServiceRouter = createTRPCRouter({ history: (historyByComponent.get(String(c.id)) ?? []).map( toHistoryRow, ), + incidents: serviceIncidents + .filter((inc) => + incidentAffectsComponent(inc, c.upstreamComponentId), + ) + .map(toIncidentDTO), })), }; } catch (err) { @@ -489,6 +533,7 @@ export const externalServiceRouter = createTRPCRouter({ component: null, history: [], incidents: [], + overlayIncidents: [], }; try { const { service, component } = await getExternalComponentBySlug({ @@ -499,24 +544,32 @@ export const externalServiceRouter = createTRPCRouter({ const days = input.days ?? DEFAULT_HISTORY_DAYS; const since = new Date(Date.now() - REPORT_WINDOW_MS); - const [historyRows, incidents, reportRows] = await Promise.all([ - safeData( - tb.externalStatusComponentHistory({ - component_ids: [String(component.id)], - days, + const [historyRows, incidents, reportRows, overlayServiceIncidents] = + await Promise.all([ + safeData( + tb.externalStatusComponentHistory({ + component_ids: [String(component.id)], + days, + }), + "externalStatusComponentHistory (component)", + ), + listExternalIncidentsByComponent({ + externalServiceId: service.id, + upstreamComponentId: component.upstreamComponentId, + limit: INCIDENTS_LIMIT, }), - "externalStatusComponentHistory (component)", - ), - listExternalIncidentsByComponent({ - externalServiceId: service.id, - upstreamComponentId: component.upstreamComponentId, - limit: INCIDENTS_LIMIT, - }), - safeRows( - getComponentReportWindows({ serviceId: service.id, since }), - "getComponentReportWindows (component)", - ), - ]); + safeRows( + getComponentReportWindows({ serviceId: service.id, since }), + "getComponentReportWindows (component)", + ), + safeRows( + listExternalIncidentsByServiceId({ + externalServiceId: service.id, + since: overlaySince(days), + }), + "listExternalIncidentsByServiceId (component)", + ), + ]); const reporters = reportRows.find((r) => r.componentId === component.id)?.reporters ?? @@ -550,6 +603,11 @@ export const externalServiceRouter = createTRPCRouter({ }, history: historyRows.map(toHistoryRow), incidents: incidents.map(toIncidentDTO), + overlayIncidents: overlayServiceIncidents + .filter((inc) => + incidentAffectsComponent(inc, component.upstreamComponentId), + ) + .map(toIncidentDTO), }; } catch (err) { console.warn( diff --git a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts index 66ddc5a0..9f1ba013 100644 --- a/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts +++ b/packages/services/src/external-service-incident/__tests__/external-service-incident.test.ts @@ -9,6 +9,7 @@ import { afterEach, describe, test } from "@std/testing/bdd"; import { type UpsertExternalIncidentInput, listExternalIncidentsByComponent, + listExternalIncidentsByServiceId, listExternalIncidentsBySlug, pruneStaleRawPayloads, upsertExternalIncidentsForService, @@ -594,3 +595,73 @@ describe("pruneStaleRawPayloads", () => { expect(byId.get("ongoing-old")?.rawPayloadPurgedAt).toBeNull(); }); }); + +describe("listExternalIncidentsByServiceId since-window", () => { + test("keeps ongoing and resolved-in-window, drops resolved-before", async () => { + const serviceId = await seedService({ slug: `${TEST_PREFIX}-since` }); + const now = new Date("2026-06-15T00:00:00.000Z"); + const since = new Date("2026-06-01T00:00:00.000Z"); + + await upsertExternalIncidentsForService({ + externalServiceId: serviceId, + now, + incidents: [ + { + providerIncidentId: "ongoing-old", + name: "Ongoing since May", + status: "investigating", + impact: "major", + shortlink: "https://stspg.io/ongoing", + startedAt: new Date("2026-05-01T00:00:00.000Z"), + createdAt: new Date("2026-05-01T00:00:00.000Z"), + resolvedAt: null, + affectedComponentIds: ["cmp-a"], + raw: { id: "ongoing-old" }, + }, + { + providerIncidentId: "resolved-before", + name: "Resolved before window", + status: "resolved", + impact: "minor", + startedAt: new Date("2026-05-01T00:00:00.000Z"), + createdAt: new Date("2026-05-01T00:00:00.000Z"), + resolvedAt: new Date("2026-05-20T00:00:00.000Z"), + affectedComponentIds: [], + raw: { id: "resolved-before" }, + }, + { + providerIncidentId: "resolved-after", + name: "Resolved inside window", + status: "resolved", + impact: "critical", + startedAt: new Date("2026-05-25T00:00:00.000Z"), + createdAt: new Date("2026-05-25T00:00:00.000Z"), + resolvedAt: new Date("2026-06-10T00:00:00.000Z"), + affectedComponentIds: ["cmp-b"], + raw: { id: "resolved-after" }, + }, + ], + }); + + const windowed = await listExternalIncidentsByServiceId({ + externalServiceId: serviceId, + since, + }); + const ids = new Set(windowed.map((r) => r.providerIncidentId)); + expect(ids.has("ongoing-old")).toBe(true); + expect(ids.has("resolved-after")).toBe(true); + expect(ids.has("resolved-before")).toBe(false); + + // affectedComponentIds is returned for server-side per-component bucketing + const ongoing = windowed.find( + (r) => r.providerIncidentId === "ongoing-old", + ); + expect(ongoing?.affectedComponentIds).toEqual(["cmp-a"]); + + // no `since` returns everything (within the default limit) + const all = await listExternalIncidentsByServiceId({ + externalServiceId: serviceId, + }); + expect(all.length).toBe(3); + }); +}); diff --git a/packages/services/src/external-service-incident/list.ts b/packages/services/src/external-service-incident/list.ts index 2d2c4baf..b54b159d 100644 --- a/packages/services/src/external-service-incident/list.ts +++ b/packages/services/src/external-service-incident/list.ts @@ -1,4 +1,13 @@ -import { and, db as defaultDb, desc, eq, sql } from "@openstatus/db"; +import { + and, + db as defaultDb, + desc, + eq, + gte, + isNull, + or, + sql, +} from "@openstatus/db"; import type { ApiConfigType } from "@openstatus/db/src/schema"; import { externalServiceIncident } from "@openstatus/db/src/schema"; @@ -17,9 +26,37 @@ export type ExternalIncidentListItem = { startedAt: Date | null; createdAt: Date; resolvedAt: Date | null; + affectedComponentIds: string[]; }; const DEFAULT_LIMIT = 5; +const OVERLAY_LIMIT = 200; + +// An incident is "within the window" if it's ongoing or resolved on/after `since`. +// Keyed off the indexed `resolved_at`, so a long incident still in progress (or +// resolved inside the window) is kept even when it started before `since`. +function withinWindow(since: Date | undefined) { + return since + ? or( + isNull(externalServiceIncident.resolvedAt), + gte(externalServiceIncident.resolvedAt, since), + ) + : undefined; +} + +const INCIDENT_COLUMNS = { + id: externalServiceIncident.id, + externalServiceId: externalServiceIncident.externalServiceId, + providerIncidentId: externalServiceIncident.providerIncidentId, + name: externalServiceIncident.name, + status: externalServiceIncident.status, + impact: externalServiceIncident.impact, + shortlink: externalServiceIncident.shortlink, + startedAt: externalServiceIncident.startedAt, + createdAt: externalServiceIncident.createdAt, + resolvedAt: externalServiceIncident.resolvedAt, + affectedComponentIds: externalServiceIncident.affectedComponentIds, +}; // must stay in sync with fetchers that implement `fetchIncidents` in @openstatus/status-fetcher export const INCIDENT_SUPPORTED_API_CONFIG_TYPES = new Set([ @@ -35,27 +72,22 @@ export async function listExternalIncidentsByServiceId(args: { ctx?: GlobalReadContext; externalServiceId: number; limit?: number; + since?: Date; }): Promise { const { ctx, externalServiceId } = args; const db = ctx?.db ?? defaultDb; - const limit = args.limit ?? DEFAULT_LIMIT; + const limit = args.limit ?? (args.since ? OVERLAY_LIMIT : DEFAULT_LIMIT); const rows = await retryRead(() => db - .select({ - id: externalServiceIncident.id, - externalServiceId: externalServiceIncident.externalServiceId, - providerIncidentId: externalServiceIncident.providerIncidentId, - name: externalServiceIncident.name, - status: externalServiceIncident.status, - impact: externalServiceIncident.impact, - shortlink: externalServiceIncident.shortlink, - startedAt: externalServiceIncident.startedAt, - createdAt: externalServiceIncident.createdAt, - resolvedAt: externalServiceIncident.resolvedAt, - }) + .select(INCIDENT_COLUMNS) .from(externalServiceIncident) - .where(eq(externalServiceIncident.externalServiceId, externalServiceId)) + .where( + and( + eq(externalServiceIncident.externalServiceId, externalServiceId), + withinWindow(args.since), + ), + ) .orderBy( desc( sql`COALESCE(${externalServiceIncident.startedAt}, ${externalServiceIncident.createdAt})`, @@ -76,30 +108,21 @@ export async function listExternalIncidentsByComponent(args: { externalServiceId: number; upstreamComponentId: string; limit?: number; + since?: Date; }): Promise { const { ctx, externalServiceId, upstreamComponentId } = args; const db = ctx?.db ?? defaultDb; - const limit = args.limit ?? DEFAULT_LIMIT; + const limit = args.limit ?? (args.since ? OVERLAY_LIMIT : DEFAULT_LIMIT); const rows = await retryRead(() => db - .select({ - id: externalServiceIncident.id, - externalServiceId: externalServiceIncident.externalServiceId, - providerIncidentId: externalServiceIncident.providerIncidentId, - name: externalServiceIncident.name, - status: externalServiceIncident.status, - impact: externalServiceIncident.impact, - shortlink: externalServiceIncident.shortlink, - startedAt: externalServiceIncident.startedAt, - createdAt: externalServiceIncident.createdAt, - resolvedAt: externalServiceIncident.resolvedAt, - }) + .select(INCIDENT_COLUMNS) .from(externalServiceIncident) .where( and( eq(externalServiceIncident.externalServiceId, externalServiceId), sql`EXISTS (SELECT 1 FROM json_each(${externalServiceIncident.affectedComponentIds}) WHERE value = ${upstreamComponentId})`, + withinWindow(args.since), ), ) .orderBy( diff --git a/packages/ui/src/components/blocks/status.types.ts b/packages/ui/src/components/blocks/status.types.ts index ce3d8e9d..869831bb 100644 --- a/packages/ui/src/components/blocks/status.types.ts +++ b/packages/ui/src/components/blocks/status.types.ts @@ -67,5 +67,7 @@ export type StatusBarData = { isAggregated?: boolean; /** Overrides the type-derived dot color (e.g. the day's worst report impact). */ status?: Exclude; + /** External link for the event (e.g. an upstream incident page). */ + shortlink?: string; }[]; }; -- 2.51.2 From fe176c837ecdb4d1ab8f1516d48aada94733b750 Mon Sep 17 00:00:00 2001 From: psdojo <71039532+psdojo@users.noreply.github.com> Date: Fri, 3 Jul 2026 18:26:24 +0530 Subject: [PATCH 22/69] fix: use exec-form CMD for workflows/server healthchecks (#2342) * fix: use exec-form CMD for workflows/server healthchecks (missing /bin/sh) * fixed docker-compose.yaml * Update docker-compose.github-packages.yaml Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --------- Co-authored-by: psdojo Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- docker-compose.github-packages.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker-compose.github-packages.yaml b/docker-compose.github-packages.yaml index a1c86549..833ac298 100644 --- a/docker-compose.github-packages.yaml +++ b/docker-compose.github-packages.yaml @@ -72,7 +72,7 @@ services: libsql: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:3000/ping || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:3000/ping"] interval: 15s timeout: 10s retries: 3 @@ -97,7 +97,7 @@ services: libsql: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:3000/ping || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:3000/ping"] interval: 15s timeout: 10s retries: 3 @@ -152,7 +152,7 @@ services: server: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 15s timeout: 10s retries: 3 @@ -181,7 +181,7 @@ services: server: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:3000/ || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:3000/"] interval: 15s timeout: 10s retries: 3 @@ -210,7 +210,7 @@ services: server: condition: service_healthy healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:3000/ || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:3000/"] interval: 15s timeout: 10s retries: 3 -- 2.51.2 From 1007278f65332e4f6173b7d3da266ba710de1705 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:59:33 +0200 Subject: [PATCH 23/69] fix: gh actions migrate ci (#2344) --- .github/workflows/migrate.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/migrate.yml b/.github/workflows/migrate.yml index bda12736..1770625c 100644 --- a/.github/workflows/migrate.yml +++ b/.github/workflows/migrate.yml @@ -1,5 +1,6 @@ name: Migrate DB on: + workflow_dispatch: push: branches: - main @@ -25,10 +26,10 @@ jobs: node-version: 24 cache: "pnpm" - - name: 🔥 Install bun - uses: oven-sh/setup-bun@v2 + - name: 🦕 Install deno + uses: denoland/setup-deno@v2 with: - bun-version: latest + deno-version: v2.x - name: 📥 Download deps run: pnpm install -- 2.51.2 From 3299a1758dd247a16c326d37a88c078610f62f66 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 3 Jul 2026 15:26:10 +0200 Subject: [PATCH 24/69] fix: incident events tests (#2345) --- apps/web/src/app/(landing)/status/incident-events.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/(landing)/status/incident-events.test.ts b/apps/web/src/app/(landing)/status/incident-events.test.ts index 21ddd2cf..b2fcfc7e 100644 --- a/apps/web/src/app/(landing)/status/incident-events.test.ts +++ b/apps/web/src/app/(landing)/status/incident-events.test.ts @@ -1,4 +1,5 @@ -import { describe, expect, test } from "bun:test"; +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; import { type OverlayIncident, -- 2.51.2 From fcc857b06af3b97b09fccb4f41d0b4ae98e211f0 Mon Sep 17 00:00:00 2001 From: Moulik Aggarwal Date: Fri, 3 Jul 2026 18:57:37 +0530 Subject: [PATCH 25/69] =?UTF-8?q?feat:=20bring-your-own-gateway=20(BYOG)?= =?UTF-8?q?=20=E2=80=94=20OpenAI-compatible=20AI=20provider=20for=20self-h?= =?UTF-8?q?osting=20(#2322)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added feature for Bring your own Gateway ( BYOG ) for self hosting openstatus Signed-off-by: Moulik Aggarwal * ci: apply automated fixes * Update the package according to review Signed-off-by: Moulik Aggarwal * Updated to deno tests Signed-off-by: Moulik Aggarwal * fix: changelog --------- Signed-off-by: Moulik Aggarwal Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Maximilian Kaske --- .env.docker.example | 10 ++ apps/dashboard/.env.example | 19 +++- apps/dashboard/package.json | 1 + apps/dashboard/src/app/api/chat/route.ts | 24 ++--- .../changelog/bring-your-own-ai-provider.png | Bin 0 -> 201011 bytes .../changelog/bring-your-own-ai-provider.mdx | 22 +++++ .../docs/guides/self-hosting-openstatus.mdx | 35 +++++++ packages/ai/.gitignore | 5 + packages/ai/package.json | 32 +++++++ packages/ai/src/index.ts | 1 + packages/ai/src/resolve-model.test.ts | 76 +++++++++++++++ packages/ai/src/resolve-model.ts | 51 ++++++++++ packages/ai/tsconfig.json | 7 ++ pnpm-lock.yaml | 89 ++++++++++++++++++ pnpm-workspace.yaml | 1 + 15 files changed, 360 insertions(+), 13 deletions(-) create mode 100644 apps/web/public/assets/changelog/bring-your-own-ai-provider.png create mode 100644 apps/web/src/content/pages/changelog/bring-your-own-ai-provider.mdx create mode 100644 packages/ai/.gitignore create mode 100644 packages/ai/package.json create mode 100644 packages/ai/src/index.ts create mode 100644 packages/ai/src/resolve-model.test.ts create mode 100644 packages/ai/src/resolve-model.ts create mode 100644 packages/ai/tsconfig.json diff --git a/.env.docker.example b/.env.docker.example index c7340aa4..18f9c555 100644 --- a/.env.docker.example +++ b/.env.docker.example @@ -144,6 +144,16 @@ OPENSTATUS_INGEST_URL=https://openstatus-private-location.fly.dev # /api/markdown endpoints. Defaults to the public openstatus.dev docs. # OPENSTATUS_WEB_BASE_URL=https://www.openstatus.dev +# AI chat provider (optional). Configure ONE option to enable the assistant. +# Option 1 — OpenAI-compatible endpoint (NVIDIA NIM, vLLM, Ollama, OpenRouter…). +# Recommended for self-hosting; takes priority when AI_BASE_URL is set. The model +# MUST support tool calling. AI_API_KEY is optional for keyless local gateways. +# AI_BASE_URL=https://integrate.api.nvidia.com/v1 +# AI_API_KEY=nvapi-xxxxx +# AI_MODEL=meta/llama-3.1-70b-instruct +# Option 2 — Vercel AI Gateway (model chosen by workspace plan). +# AI_GATEWAY_API_KEY= + # DEVELOPMENT & TESTING # ============================================================================ # Turbo build mode diff --git a/apps/dashboard/.env.example b/apps/dashboard/.env.example index 30af12a1..acb817ac 100644 --- a/apps/dashboard/.env.example +++ b/apps/dashboard/.env.example @@ -82,5 +82,20 @@ OPENPANEL_CLIENT_SECRET=something # https://github.com/ExodusOSS/bytes/issues/13#issuecomment-3965264022 NODE_OPTIONS=--experimental-require-module -# chat model via AI Gateway -AI_GATEWAY_API_KEY= \ No newline at end of file +# AI chat provider. Configure ONE of the two options below. +# +# Option 1 — Vercel AI Gateway (hosted default). Free workspaces use a cheaper +# model, paid workspaces a stronger one. +AI_GATEWAY_API_KEY= +# +# Option 2 — Self-hosted / OpenAI-compatible endpoint (NVIDIA NIM, vLLM, Ollama, +# OpenRouter, …). Takes priority over the gateway when AI_BASE_URL is set. +# The model MUST support tool/function calling — the agent depends on it. +# AI_API_KEY is optional for keyless local gateways. +# Example (NVIDIA NIM): +# AI_BASE_URL=https://integrate.api.nvidia.com/v1 +# AI_API_KEY=nvapi-xxxxx +# AI_MODEL=meta/llama-3.1-70b-instruct +AI_BASE_URL= +AI_API_KEY= +AI_MODEL= \ No newline at end of file diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 5e3bf0b3..89749cb0 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -23,6 +23,7 @@ "@hookform/resolvers": "catalog:", "@libsql/client": "catalog:", "@openpanel/nextjs": "catalog:", + "@openstatus/ai": "workspace:*", "@openstatus/analytics": "workspace:*", "@openstatus/api": "workspace:*", "@openstatus/assertions": "workspace:*", diff --git a/apps/dashboard/src/app/api/chat/route.ts b/apps/dashboard/src/app/api/chat/route.ts index 8b9730f2..ecf80b68 100644 --- a/apps/dashboard/src/app/api/chat/route.ts +++ b/apps/dashboard/src/app/api/chat/route.ts @@ -1,3 +1,4 @@ +import { resolveChatModel } from "@openstatus/ai"; import { type ChatStoredMessage, storedMessageSchema, @@ -27,9 +28,6 @@ import { chatRateLimit } from "@/lib/rate-limit/chat"; export const runtime = "edge"; -const CHAT_MODEL_FREE = "anthropic/claude-haiku-4.5"; -const CHAT_MODEL_PAID = "anthropic/claude-sonnet-4.5"; - // Drop tool parts that have no result the SDK can turn into a tool_result // block. `ignoreIncompleteToolCalls` doesn't cover `approval-requested`, so // a mid-confirmation reload would otherwise replay an orphan `tool_use` to @@ -55,13 +53,6 @@ const requestSchema = z.object({ }); export async function POST(req: NextRequest) { - if (!process.env.AI_GATEWAY_API_KEY) { - return NextResponse.json( - { error: "Chat is not configured on this deployment." }, - { status: 503 }, - ); - } - const workspaceSlug = (await cookies()).get("workspace-slug")?.value; const ctx = await getChatServiceContext({ workspaceSlug }); if (!ctx || ctx.actor.type !== "user") { @@ -77,6 +68,17 @@ export async function POST(req: NextRequest) { const plan = ctx.workspace.plan ?? "free"; + // Provider is resolved from env: a self-hosted OpenAI-compatible endpoint + // (`AI_BASE_URL`) or the Vercel AI Gateway (`AI_GATEWAY_API_KEY`). `null` + // means neither is configured. + const model = resolveChatModel({ plan }); + if (!model) { + return NextResponse.json( + { error: "Chat is not configured on this deployment." }, + { status: 503 }, + ); + } + // Skip the LLM-cost cap entirely in non-prod so testing doesn't // burn through the daily allowance. The Redis counter still // increments in prod where it matters. @@ -148,7 +150,7 @@ export async function POST(req: NextRequest) { ); const result = streamText({ - model: plan === "free" ? CHAT_MODEL_FREE : CHAT_MODEL_PAID, + model, system: buildAgentSystemPrompt({ workspaceName: ctx.workspace.name ?? "Unknown", surface: "dashboard", diff --git a/apps/web/public/assets/changelog/bring-your-own-ai-provider.png b/apps/web/public/assets/changelog/bring-your-own-ai-provider.png new file mode 100644 index 0000000000000000000000000000000000000000..9ca97a78a411d949218ee6dcc70a3f05d4602285 GIT binary patch literal 201011 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

OUrZ&~eN^@TQ4VY01)x-O|=_0(;7~8DB~XZqfS9 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 literal 0 HcmV?d00001 diff --git a/apps/web/src/content/pages/changelog/bring-your-own-ai-provider.mdx b/apps/web/src/content/pages/changelog/bring-your-own-ai-provider.mdx new file mode 100644 index 00000000..f91b8451 --- /dev/null +++ b/apps/web/src/content/pages/changelog/bring-your-own-ai-provider.mdx @@ -0,0 +1,22 @@ +--- +title: "Self-host the AI assistant with your own model" +description: "Self-hosted openstatus can now run the AI assistant on any OpenAI-compatible model — NVIDIA NIM, vLLM, Ollama, and more." +image: "/assets/changelog/bring-your-own-ai-provider.png" +publishedAt: "2026-07-03" +author: "Moulik Aggarwal" +category: "integrations" +--- + +Running openstatus on your own infrastructure? The in-dashboard AI assistant no longer depends on a hosted gateway — you can now power it with **your own model provider**. + +Point it at any **OpenAI-compatible** endpoint ([NVIDIA NIM](https://build.nvidia.com/), vLLM, Ollama, OpenRouter, or a private gateway) by setting three environment variables in your `.env.docker`: + +```env +AI_BASE_URL=https://integrate.api.nvidia.com/v1 +AI_API_KEY=nvapi-xxxxx +AI_MODEL=meta/llama-3.1-70b-instruct +``` + +The model and API key stay entirely on your own infrastructure, and `AI_API_KEY` is optional for keyless local gateways like Ollama. The only requirement is that the model supports tool calling, which the assistant uses to manage your monitors and status pages. + +See the [self-hosting guide](/docs/guides/self-hosting-openstatus) for the full configuration. diff --git a/apps/web/src/content/pages/docs/guides/self-hosting-openstatus.mdx b/apps/web/src/content/pages/docs/guides/self-hosting-openstatus.mdx index 2d11ec96..79ed3bb4 100644 --- a/apps/web/src/content/pages/docs/guides/self-hosting-openstatus.mdx +++ b/apps/web/src/content/pages/docs/guides/self-hosting-openstatus.mdx @@ -177,6 +177,41 @@ Now that the services are running, you can access the dashboard and perform the /> +## Configuring the AI assistant (optional) + +openstatus ships an in-dashboard AI assistant. It is **off by default** when self-hosting — the chat endpoint returns `503 "Chat is not configured"` until you point it at a model provider. Configure **one** of the two options below in your `.env.docker` (root) — or `apps/dashboard/.env` for a manual setup — then restart the dashboard. + +### Option 1: OpenAI-compatible endpoint (bring your own model) + +Use any OpenAI-compatible API — [NVIDIA NIM](https://build.nvidia.com/), vLLM, Ollama, OpenRouter, LM Studio, or a private gateway. This is the recommended path for self-hosting: the model and key stay on your own infrastructure. + +```env +AI_BASE_URL=https://integrate.api.nvidia.com/v1 +AI_API_KEY=nvapi-xxxxx +AI_MODEL=meta/llama-3.1-70b-instruct +``` + +- `AI_BASE_URL` — the provider's OpenAI-compatible base URL (usually ends in `/v1`). Setting it enables this option. +- `AI_API_KEY` — optional. Leave empty for keyless local gateways such as Ollama. +- `AI_MODEL` — the model id to use. It **must support tool / function calling** — the assistant manages your monitors and status pages through tools, so a model without tool support cannot act. + +A fully local, keyless setup with Ollama: + +```env +AI_BASE_URL=http://localhost:11434/v1 +AI_MODEL=llama3.1 +``` + +### Option 2: Vercel AI Gateway + +If you use the [Vercel AI Gateway](https://vercel.com/docs/ai-gateway), set a single key. The model is chosen automatically (a smaller model for free workspaces, a stronger one for paid). + +```env +AI_GATEWAY_API_KEY=your-gateway-key +``` + +When both are configured, `AI_BASE_URL` takes priority over the gateway. + ## Service architecture openstatus consists of multiple services running together: diff --git a/packages/ai/.gitignore b/packages/ai/.gitignore new file mode 100644 index 00000000..e365bcee --- /dev/null +++ b/packages/ai/.gitignore @@ -0,0 +1,5 @@ +# Type-check only package — never commit emitted output +*.js +*.d.ts +*.d.ts.map +*.tsbuildinfo diff --git a/packages/ai/package.json b/packages/ai/package.json new file mode 100644 index 00000000..ae9f8d21 --- /dev/null +++ b/packages/ai/package.json @@ -0,0 +1,32 @@ +{ + "name": "@openstatus/ai", + "version": "0.0.0", + "license": "MIT", + "type": "module", + "main": "./src/index.ts", + "types": "./src/index.ts", + "exports": { + ".": { + "import": "./src/index.ts", + "types": "./src/index.ts" + } + }, + "scripts": { + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports", + "lint": "oxlint", + "tsc": "tsc --noEmit" + }, + "dependencies": { + "@ai-sdk/openai-compatible": "catalog:", + "ai": "catalog:" + }, + "devDependencies": { + "@openstatus/db": "workspace:*", + "@openstatus/tsconfig": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", + "@types/node": "catalog:", + "typescript": "catalog:" + } +} diff --git a/packages/ai/src/index.ts b/packages/ai/src/index.ts new file mode 100644 index 00000000..357c5960 --- /dev/null +++ b/packages/ai/src/index.ts @@ -0,0 +1 @@ +export { resolveChatModel } from "./resolve-model"; diff --git a/packages/ai/src/resolve-model.test.ts b/packages/ai/src/resolve-model.test.ts new file mode 100644 index 00000000..a1bfb388 --- /dev/null +++ b/packages/ai/src/resolve-model.test.ts @@ -0,0 +1,76 @@ +import { expect } from "@std/expect"; +import { afterEach, beforeEach, describe, test } from "@std/testing/bdd"; + +import { resolveChatModel } from "./resolve-model"; + +const ENV_KEYS = [ + "AI_BASE_URL", + "AI_MODEL", + "AI_API_KEY", + "AI_GATEWAY_API_KEY", +]; + +function clearEnv() { + for (const key of ENV_KEYS) delete process.env[key]; +} + +describe("resolveChatModel", () => { + beforeEach(clearEnv); + afterEach(clearEnv); + + test("returns null when no provider is configured", () => { + expect(resolveChatModel({ plan: "free" })).toBeNull(); + }); + + test("gateway path: free plan resolves the cheaper model string", () => { + process.env.AI_GATEWAY_API_KEY = "gw-key"; + expect(resolveChatModel({ plan: "free" })).toBe( + "anthropic/claude-haiku-4.5", + ); + }); + + test("gateway path: paid plan resolves the stronger model string", () => { + process.env.AI_GATEWAY_API_KEY = "gw-key"; + expect(resolveChatModel({ plan: "team" })).toBe( + "anthropic/claude-sonnet-4.5", + ); + }); + + test("self-host path: AI_BASE_URL + AI_MODEL builds a model, plan ignored", () => { + process.env.AI_BASE_URL = "https://integrate.api.nvidia.com/v1"; + process.env.AI_API_KEY = "nvapi-test"; + process.env.AI_MODEL = "meta/llama-3.1-70b-instruct"; + const model = resolveChatModel({ plan: "free" }); + expect(model).not.toBeNull(); + expect(typeof model).toBe("object"); + expect((model as { modelId: string }).modelId).toBe( + "meta/llama-3.1-70b-instruct", + ); + }); + + test("self-host path works without an API key (keyless local gateway)", () => { + process.env.AI_BASE_URL = "http://localhost:11434/v1"; + process.env.AI_MODEL = "llama3.1"; + const model = resolveChatModel({ plan: "free" }); + expect(typeof model).toBe("object"); + expect((model as { modelId: string }).modelId).toBe("llama3.1"); + }); + + test("self-host path takes priority over the gateway", () => { + process.env.AI_GATEWAY_API_KEY = "gw-key"; + process.env.AI_BASE_URL = "https://integrate.api.nvidia.com/v1"; + process.env.AI_MODEL = "meta/llama-3.1-70b-instruct"; + expect(typeof resolveChatModel({ plan: "free" })).toBe("object"); + }); + + test("AI_BASE_URL set but AI_MODEL missing returns null", () => { + process.env.AI_BASE_URL = "https://integrate.api.nvidia.com/v1"; + expect(resolveChatModel({ plan: "free" })).toBeNull(); + }); + + test("whitespace-only env values are treated as unset", () => { + process.env.AI_BASE_URL = " "; + process.env.AI_GATEWAY_API_KEY = " "; + expect(resolveChatModel({ plan: "free" })).toBeNull(); + }); +}); diff --git a/packages/ai/src/resolve-model.ts b/packages/ai/src/resolve-model.ts new file mode 100644 index 00000000..b53fa1d7 --- /dev/null +++ b/packages/ai/src/resolve-model.ts @@ -0,0 +1,51 @@ +import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; +import type { WorkspacePlan } from "@openstatus/db/src/schema"; +import type { LanguageModel } from "ai"; + +// Hosted openstatus.dev defaults, resolved through the Vercel AI Gateway as +// bare model strings. Free workspaces get the cheaper model because we pay for +// their inference; this tiering applies ONLY to the gateway path. +const GATEWAY_MODEL_FREE = "anthropic/claude-haiku-4.5"; +const GATEWAY_MODEL_PAID = "anthropic/claude-sonnet-4.5"; + +// `||` (not `??`) so empty / whitespace-only env values fall back instead of +// being passed through as a real value. +function readEnv(name: string): string | undefined { + return process.env[name]?.trim() || undefined; +} + +/** + * Resolve the chat model from environment, provider-agnostic. + * + * 1. Self-host (`AI_BASE_URL`): any OpenAI-compatible endpoint (NVIDIA NIM, + * vLLM, Ollama, OpenRouter, …). Single `AI_MODEL`; `plan` is ignored + * because the operator runs and pays for inference. `AI_API_KEY` is + * optional so keyless local gateways work. The model MUST support tool + * calling — the agent relies on it. + * 2. Vercel AI Gateway (`AI_GATEWAY_API_KEY`): hosted default; `plan` selects + * the model. Unchanged behavior. + * 3. Neither configured → `null` (caller returns 503). + */ +export function resolveChatModel({ + plan, +}: { + plan: WorkspacePlan; +}): LanguageModel | null { + const baseURL = readEnv("AI_BASE_URL"); + if (baseURL) { + const model = readEnv("AI_MODEL"); + if (!model) return null; + const provider = createOpenAICompatible({ + name: "self-hosted", + baseURL, + apiKey: readEnv("AI_API_KEY"), + }); + return provider.chatModel(model); + } + + if (readEnv("AI_GATEWAY_API_KEY")) { + return plan === "free" ? GATEWAY_MODEL_FREE : GATEWAY_MODEL_PAID; + } + + return null; +} diff --git a/packages/ai/tsconfig.json b/packages/ai/tsconfig.json new file mode 100644 index 00000000..230005c3 --- /dev/null +++ b/packages/ai/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@openstatus/tsconfig/base.json", + "include": ["src", "*.ts"], + "compilerOptions": { + "noEmit": true + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c8e8803..43da4219 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,9 @@ catalogs: '@ai-sdk/anthropic': specifier: 1.2.12 version: 1.2.12 + '@ai-sdk/openai-compatible': + specifier: 2.0.54 + version: 2.0.54 '@ai-sdk/react': specifier: 3.0.190 version: 3.0.190 @@ -596,6 +599,9 @@ importers: '@openpanel/nextjs': specifier: 'catalog:' version: 1.5.1(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@openstatus/ai': + specifier: workspace:* + version: link:../../packages/ai '@openstatus/analytics': specifier: workspace:* version: link:../../packages/analytics @@ -1725,6 +1731,34 @@ importers: specifier: 'catalog:' version: 5.9.3 + packages/ai: + dependencies: + '@ai-sdk/openai-compatible': + specifier: 'catalog:' + version: 2.0.54(zod@4.4.3) + ai: + specifier: 'catalog:' + version: 6.0.188(zod@4.4.3) + devDependencies: + '@openstatus/db': + specifier: workspace:* + version: link:../db + '@openstatus/tsconfig': + specifier: workspace:* + version: link:../tsconfig + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' + '@types/node': + specifier: 'catalog:' + version: 24.12.4 + typescript: + specifier: 'catalog:' + version: 5.9.3 + packages/analytics: dependencies: '@openpanel/sdk': @@ -3045,6 +3079,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/openai-compatible@2.0.54': + resolution: {integrity: sha512-OyXt0zK8y2/ZIyWlbxTv2r1M7AK227S+Gl4BYOEF42q0wz1n5m4fwR8L4Fy/MQ4Ho6xje47MPsFcRdIqIyP6Rw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@2.2.8': resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==} engines: {node: '>=18'} @@ -3057,6 +3097,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@4.0.33': + resolution: {integrity: sha512-nJ0bAfegMAIJtrzMJtbzer1cS3nb7c7DsyU1S4nrPm7ZU0Mn6SBBZv5IGZZGTbpWTJwqKTSPeZJTXalbAxt1BA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider@1.1.3': resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} engines: {node: '>=18'} @@ -3065,6 +3111,10 @@ packages: resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} engines: {node: '>=18'} + '@ai-sdk/provider@3.0.12': + resolution: {integrity: sha512-sj9DWTJ2Ze0WR9qsiOPqoqzNx3OxL6iMxHImbhvoe9qOspekbzxNDMiJ4TIGfYHYh9w4OmBjz3prvqhzTi96+Q==} + engines: {node: '>=18'} + '@ai-sdk/react@3.0.190': resolution: {integrity: sha512-ee8bZ3ZCC/PZDfCIX0LNvoPezo1v+jHp85pW6ct6B3qddsSp4SoFvapGuhK1gHRMLR6rKq0D5Gjii/+rgLzb9g==} engines: {node: '>=18'} @@ -11437,6 +11487,19 @@ snapshots: '@vercel/oidc': 3.2.0 zod: 4.1.13 + '@ai-sdk/gateway@3.0.118(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) + '@vercel/oidc': 3.2.0 + zod: 4.4.3 + + '@ai-sdk/openai-compatible@2.0.54(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 3.0.12 + '@ai-sdk/provider-utils': 4.0.33(zod@4.4.3) + zod: 4.4.3 + '@ai-sdk/provider-utils@2.2.8(zod@4.1.13)': dependencies: '@ai-sdk/provider': 1.1.3 @@ -11451,6 +11514,20 @@ snapshots: eventsource-parser: 3.0.8 zod: 4.1.13 + '@ai-sdk/provider-utils@4.0.27(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 3.0.10 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.8 + zod: 4.4.3 + + '@ai-sdk/provider-utils@4.0.33(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 3.0.12 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.8 + zod: 4.4.3 + '@ai-sdk/provider@1.1.3': dependencies: json-schema: 0.4.0 @@ -11459,6 +11536,10 @@ snapshots: dependencies: json-schema: 0.4.0 + '@ai-sdk/provider@3.0.12': + dependencies: + json-schema: 0.4.0 + '@ai-sdk/react@3.0.190(react@19.2.6)(zod@4.1.13)': dependencies: '@ai-sdk/provider-utils': 4.0.27(zod@4.1.13) @@ -15660,6 +15741,14 @@ snapshots: '@opentelemetry/api': 1.9.1 zod: 4.1.13 + ai@6.0.188(zod@4.4.3): + dependencies: + '@ai-sdk/gateway': 3.0.118(zod@4.4.3) + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) + '@opentelemetry/api': 1.9.1 + zod: 4.4.3 + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a61cf776..3f5864cf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,6 +18,7 @@ allowBuilds: autoInstallPeers: true catalog: "@ai-sdk/anthropic": 1.2.12 + "@ai-sdk/openai-compatible": 2.0.54 "@ai-sdk/react": 3.0.190 "@astrojs/check": 0.9.9 "@astrojs/react": 4.4.2 -- 2.51.2 From 52867b582151e7682c7cf5cb0ff9fd5315dd3056 Mon Sep 17 00:00:00 2001 From: Moulik Aggarwal Date: Sun, 5 Jul 2026 23:24:57 +0530 Subject: [PATCH 26/69] Created CDN Cache Tool for SEO Marketing (#2244) * Created CDN Cache Tool for SEO Marketing Signed-off-by: Moulik Aggarwal * Updated after code review Signed-off-by: Moulik Aggarwal * Cubic Review P1 Signed-off-by: Moulik Aggarwal * ci: apply automated fixes * ci: apply automated fixes (attempt 2/3) * Update the Review from Max * Updated code review and knip exports * Updated Review by Max Signed-off-by: Moulik Aggarwal * Updated google broad matches Signed-off-by: Moulik Aggarwal * Updated tests to deno CDN Checker Signed-off-by: Moulik Aggarwal * Address review: tie-safe CDN majority, live context guard, corroborated Fastly detection, abortable checks - summary: a tied provider count now yields cdn: null instead of an arbitrary sort winner (mixedCdn already flags the disagreement) - client: context default is null so useCdnChecker throws outside the provider instead of silently no-oping - detect-cdn: `x-served-by: cache-` no longer claims Fastly alone; broad signals must be corroborated by a strong signal or a second broad one - client: in-flight checks are aborted on re-submit and unmount so stale stream rows can't interleave and readers don't leak Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TLfsNjBxP4VuZiudBimEfK * Align cdn-checker with checker: hand-rolled results table, hero fallback Replace DataTable with the plain table pattern from the speed checker, drop the probing placeholder from SummaryCard, and use metadata.hero for the page H1. Co-Authored-By: Claude Fable 5 --------- Signed-off-by: Moulik Aggarwal Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5 Co-authored-by: Maximilian Kaske --- .../app/(dashboard)/monitors/create/page.tsx | 47 ++++ .../monitors/create/search-params.ts | 12 + apps/web/deno.jsonc | 6 + apps/web/next-env.d.ts | 2 +- .../(landing)/play/cdn-checker/api/route.ts | 140 ++++++++++ .../app/(landing)/play/cdn-checker/client.tsx | 239 ++++++++++++++++++ .../cdn-checker/components/monitor-cta.tsx | 76 ++++++ .../cdn-checker/components/results-table.tsx | 207 +++++++++++++++ .../cdn-checker/components/summary-card.tsx | 96 +++++++ .../app/(landing)/play/cdn-checker/page.tsx | 58 +++++ .../play/cdn-checker/search-params.ts | 5 + .../app/(landing)/play/cdn-checker/utils.ts | 28 ++ apps/web/src/app/(landing)/play/page.tsx | 6 + .../data-table/data-table-column-header.tsx | 60 +++++ .../components/ui/data-table/data-table.tsx | 158 ++++++++++++ .../src/content/pages/tools/cdn-checker.mdx | 99 ++++++++ apps/web/src/lib/cdn-checker/dev-probe.ts | 73 ++++++ apps/web/src/lib/cdn-checker/guards.ts | 47 ++++ apps/web/src/lib/cdn-checker/probe.test.ts | 142 +++++++++++ apps/web/src/lib/cdn-checker/probe.ts | 92 +++++++ apps/web/src/lib/cdn-checker/ratelimit.ts | 47 ++++ apps/web/src/lib/cdn-checker/schema.ts | 54 ++++ apps/web/src/lib/cdn-checker/summary.test.ts | 100 ++++++++ apps/web/src/lib/cdn-checker/summary.ts | 44 ++++ apps/web/src/lib/checker/utils.ts | 4 +- packages/analytics/src/events.ts | 4 + .../src/cdn/detect-cdn.test.ts | 108 ++++++++ .../header-analysis/src/cdn/detect-cdn.ts | 166 ++++++++++++ .../header-analysis/src/cdn/edge-pop.test.ts | 56 ++++ packages/header-analysis/src/cdn/edge-pop.ts | 68 +++++ .../header-analysis/src/cdn/get-header.ts | 11 + .../src/cdn/infer-topology.test.ts | 68 +++++ .../header-analysis/src/cdn/infer-topology.ts | 41 +++ .../src/cdn/normalize-cache-status.test.ts | 140 ++++++++++ .../src/cdn/normalize-cache-status.ts | 91 +++++++ packages/header-analysis/src/index.ts | 5 + 36 files changed, 2598 insertions(+), 2 deletions(-) create mode 100644 apps/dashboard/src/app/(dashboard)/monitors/create/search-params.ts create mode 100644 apps/web/deno.jsonc create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/api/route.ts create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/client.tsx create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/page.tsx create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/search-params.ts create mode 100644 apps/web/src/app/(landing)/play/cdn-checker/utils.ts create mode 100644 apps/web/src/components/ui/data-table/data-table-column-header.tsx create mode 100644 apps/web/src/components/ui/data-table/data-table.tsx create mode 100644 apps/web/src/content/pages/tools/cdn-checker.mdx create mode 100644 apps/web/src/lib/cdn-checker/dev-probe.ts create mode 100644 apps/web/src/lib/cdn-checker/guards.ts create mode 100644 apps/web/src/lib/cdn-checker/probe.test.ts create mode 100644 apps/web/src/lib/cdn-checker/probe.ts create mode 100644 apps/web/src/lib/cdn-checker/ratelimit.ts create mode 100644 apps/web/src/lib/cdn-checker/schema.ts create mode 100644 apps/web/src/lib/cdn-checker/summary.test.ts create mode 100644 apps/web/src/lib/cdn-checker/summary.ts create mode 100644 packages/header-analysis/src/cdn/detect-cdn.test.ts create mode 100644 packages/header-analysis/src/cdn/detect-cdn.ts create mode 100644 packages/header-analysis/src/cdn/edge-pop.test.ts create mode 100644 packages/header-analysis/src/cdn/edge-pop.ts create mode 100644 packages/header-analysis/src/cdn/get-header.ts create mode 100644 packages/header-analysis/src/cdn/infer-topology.test.ts create mode 100644 packages/header-analysis/src/cdn/infer-topology.ts create mode 100644 packages/header-analysis/src/cdn/normalize-cache-status.test.ts create mode 100644 packages/header-analysis/src/cdn/normalize-cache-status.ts diff --git a/apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx b/apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx index 6d9ae8ea..88240aa0 100644 --- a/apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/monitors/create/page.tsx @@ -1,7 +1,9 @@ "use client"; +import { headerAssertion } from "@openstatus/assertions"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; +import { useQueryStates } from "nuqs"; import { EmptyStateContainer, @@ -17,10 +19,54 @@ import { import { FormGeneral } from "@/components/forms/monitor/form-general"; import { useTRPC } from "@/lib/trpc/client"; +import { searchParamsParsers } from "./search-params"; + +function safeHostname(url: string) { + try { + return new URL(url).hostname; + } catch { + return url; + } +} + +// prefill from play tools (e.g. /play/cdn-checker): malformed params fall +// back to an empty form rather than erroring +function buildPrefill(params: { + url: string | null; + name: string | null; + assertionHeaderKey: string | null; + assertionHeaderCompare: string | null; + assertionHeaderValue: string | null; +}): React.ComponentProps["defaultValues"] { + if (!params.url) return undefined; + + const assertion = headerAssertion.safeParse({ + type: "header", + version: "v1", + compare: params.assertionHeaderCompare ?? "eq", + key: params.assertionHeaderKey, + target: params.assertionHeaderValue, + }); + + return { + active: true, + name: params.name ?? safeHostname(params.url), + type: "http", + method: "GET", + url: params.url, + headers: [], + body: "", + assertions: assertion.success ? [assertion.data] : [], + skipCheck: false, + saveCheck: false, + }; +} + export default function Page() { const trpc = useTRPC(); const queryClient = useQueryClient(); const router = useRouter(); + const [params] = useQueryStates(searchParamsParsers); const triggerCheckMutation = useMutation( trpc.checker.triggerChecker.mutationOptions({}), @@ -47,6 +93,7 @@ export default function Page() { Create Monitor { await createMonitorMutation.mutateAsync({ name: data.name, diff --git a/apps/dashboard/src/app/(dashboard)/monitors/create/search-params.ts b/apps/dashboard/src/app/(dashboard)/monitors/create/search-params.ts new file mode 100644 index 00000000..66d3fd07 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/monitors/create/search-params.ts @@ -0,0 +1,12 @@ +import { createSearchParamsCache, parseAsString } from "nuqs/server"; + +// prefill contract used by the play tools (e.g. /play/cdn-checker) +export const searchParamsParsers = { + url: parseAsString, + name: parseAsString, + assertionHeaderKey: parseAsString, + assertionHeaderCompare: parseAsString, + assertionHeaderValue: parseAsString, +}; + +export const searchParamsCache = createSearchParamsCache(searchParamsParsers); diff --git a/apps/web/deno.jsonc b/apps/web/deno.jsonc new file mode 100644 index 00000000..d3de83dd --- /dev/null +++ b/apps/web/deno.jsonc @@ -0,0 +1,6 @@ +/* Needed to fix the import aliases */ +{ + "imports": { + "@/": "./src/", + }, +} diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index 9edff1c7..c4b7818f 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/src/app/(landing)/play/cdn-checker/api/route.ts b/apps/web/src/app/(landing)/play/cdn-checker/api/route.ts new file mode 100644 index 00000000..8381fdd5 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/api/route.ts @@ -0,0 +1,140 @@ +import { Events, setupAnalytics } from "@openstatus/analytics"; +import { AVAILABLE_REGIONS } from "@openstatus/regions"; +import { after } from "next/server"; +import { z } from "zod"; + +import { devProbeCdnRegion } from "@/lib/cdn-checker/dev-probe"; +import { validateCdnUrl } from "@/lib/cdn-checker/guards"; +import { probeCdnRegion } from "@/lib/cdn-checker/probe"; +import { + MAX_REQUESTS_PER_WINDOW, + RATE_LIMIT_WINDOW, + rateLimitCdnRequest, + rateLimitHeaders, +} from "@/lib/cdn-checker/ratelimit"; +import type { CdnRegionResponse } from "@/lib/cdn-checker/schema"; +import { computeCdnSummary } from "@/lib/cdn-checker/summary"; +import { iteratorToStream, yieldMany } from "@/lib/stream"; + +export const runtime = "edge"; +// 28 concurrent probes, slowest capped at 12s + summary; give some slack +export const maxDuration = 30; + +const requestSchema = z.object({ + url: z.url("Invalid URL format"), +}); + +type ErrorCode = + | "RATE_LIMIT_EXCEEDED" + | "INVALID_REQUEST" + | "NO_CLIENT_IP" + | "INTERNAL_ERROR"; + +function errorResponse( + code: ErrorCode, + error: string, + status: number, + details?: Record, + headers?: Record, +) { + return new Response(JSON.stringify({ error, code, ...details }), { + status, + headers: { "Content-Type": "application/json", ...headers }, + }); +} + +const encoder = new TextEncoder(); + +// strip query, hash and userinfo: tracked URLs must not leak tokens +function urlForAnalytics(url: string): string { + const parsed = new URL(url); + return `${parsed.origin}${parsed.pathname}`; +} + +async function* makeIterator({ url }: { url: string }) { + const rows: CdnRegionResponse[] = []; + const promises = AVAILABLE_REGIONS.map(async (region) => { + const result = + process.env.NODE_ENV === "production" + ? await probeCdnRegion({ url, region }) + : await devProbeCdnRegion({ url, region }); + rows.push(result); + return encoder.encode(`${JSON.stringify(result)}\n`); + }); + + yield* yieldMany(promises); + yield encoder.encode(`${JSON.stringify(computeCdnSummary(rows))}\n`); +} + +export async function POST(request: Request) { + let parsed: z.infer; + try { + const json = await request.json(); + const result = requestSchema.safeParse(json); + if (!result.success) { + return errorResponse("INVALID_REQUEST", "Invalid request format", 400, { + details: { + issues: result.error.issues.map((issue) => ({ + field: issue.path.join("."), + message: issue.message, + })), + }, + }); + } + parsed = result.data; + } catch { + return errorResponse( + "INVALID_REQUEST", + "Invalid JSON in request body", + 400, + ); + } + + const guard = validateCdnUrl(parsed.url); + if (!guard.ok) { + return errorResponse("INVALID_REQUEST", guard.error, guard.status); + } + + const rl = await rateLimitCdnRequest("play-cdn", request.headers); + if (rl.status === "no-client-ip") { + return errorResponse( + "NO_CLIENT_IP", + "Unable to determine client IP address", + 400, + ); + } + if (rl.status === "limited") { + return errorResponse( + "RATE_LIMIT_EXCEEDED", + `You have exceeded the rate limit of ${MAX_REQUESTS_PER_WINDOW} requests per ${RATE_LIMIT_WINDOW} seconds`, + 429, + { limit: rl.limit, remaining: rl.remaining, reset: rl.reset }, + { + ...rateLimitHeaders(rl), + "Retry-After": Math.ceil((rl.reset - Date.now()) / 1000).toString(), + }, + ); + } + + after(async () => { + try { + const analytics = await setupAnalytics({}); + await analytics.track({ + ...Events.CdnChecker, + url: urlForAnalytics(parsed.url), + }); + } catch (error) { + console.error("cdn-checker analytics failed", error); + } + }); + + // results are not persisted on purpose: cache state must be near-real-time + const stream = iteratorToStream(makeIterator({ url: parsed.url })); + return new Response(stream, { + headers: { + "Content-Type": "application/x-ndjson", + "Cache-Control": "no-store", + ...rateLimitHeaders(rl), + }, + }); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/client.tsx b/apps/web/src/app/(landing)/play/cdn-checker/client.tsx new file mode 100644 index 00000000..df0a8a01 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/client.tsx @@ -0,0 +1,239 @@ +"use client"; + +import { Button } from "@openstatus/ui/components/ui/button"; +import { Input } from "@openstatus/ui/components/ui/input"; +import { useQueryStates } from "nuqs"; +import { + createContext, + useContext, + useEffect, + useRef, + useState, + useTransition, +} from "react"; + +import type { CdnRegionResponse, CdnSummary } from "@/lib/cdn-checker/schema"; +import { + cdnRegionResponseSchema, + cdnSummarySchema, +} from "@/lib/cdn-checker/schema"; +import { regionFormatter } from "@/lib/checker/utils"; +import { toast } from "@/lib/toast"; + +import { searchParamsParsers } from "./search-params"; + +type CdnCheckerContextType = { + rows: CdnRegionResponse[]; + summary: CdnSummary | null; + checkedUrl: string | null; + isPending: boolean; + runCheck: (url: string) => void; +}; + +// null default so out-of-provider usage throws instead of silently no-oping +const CdnCheckerContext = createContext(null); + +export function useCdnChecker() { + const context = useContext(CdnCheckerContext); + if (!context) { + throw new Error("useCdnChecker must be used within a CdnCheckerProvider"); + } + return context; +} + +export function CdnCheckerProvider({ + children, +}: { + children: React.ReactNode; +}) { + const [rows, setRows] = useState([]); + const [summary, setSummary] = useState(null); + const [checkedUrl, setCheckedUrl] = useState(null); + const [isPending, startTransition] = useTransition(); + const [{ url: urlParam }, setSearchParams] = + useQueryStates(searchParamsParsers); + const autoRan = useRef(false); + const abortRef = useRef(null); + + // cancel the in-flight stream when the provider unmounts + useEffect(() => { + return () => abortRef.current?.abort(); + }, []); + + function runCheck(url: string) { + try { + new URL(url); + } catch { + toast.error("Invalid URL"); + return; + } + + // abort the previous check so its stale rows can't interleave with ours + abortRef.current?.abort(); + const controller = new AbortController(); + abortRef.current = controller; + + setRows([]); + setSummary(null); + setCheckedUrl(url); + setSearchParams({ url }); + + startTransition(async () => { + let toastId: string | number | undefined; + try { + toastId = toast.loading("Checking cache status from all regions...", { + duration: Number.POSITIVE_INFINITY, + closeButton: false, + }); + + const response = await fetch("/play/cdn-checker/api", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ url }), + signal: controller.signal, + }); + + if (!response.ok) { + try { + const json = await response.json(); + toast.error(json.error, { + id: toastId, + className: "text-destructive!", + }); + } catch { + toast.error("Failed to fetch data", { + id: toastId, + description: "Please try again.", + className: "text-destructive!", + }); + } + return; + } + + const reader = response.body?.getReader(); + if (!reader) { + toast.error("Failed to read response", { + id: toastId, + description: "Please try again.", + className: "text-destructive!", + }); + return; + } + + const decoder = new TextDecoder(); + // lines can split across chunks: buffer until a newline arrives + let buffer = ""; + let done = false; + + while (!done) { + const { value, done: streamDone } = await reader.read(); + done = streamDone; + buffer += decoder.decode(value, { stream: !done }); + + const lines = buffer.split("\n"); + buffer = lines.pop() ?? ""; + + for (const line of lines) { + if (!line.trim()) continue; + let parsed: unknown; + try { + parsed = JSON.parse(line); + } catch { + continue; + } + + const summaryResult = cdnSummarySchema.safeParse(parsed); + if ( + summaryResult.success && + (parsed as { type?: string }).type === "summary" + ) { + setSummary(summaryResult.data); + toast.success( + `Cached in ${summaryResult.data.cachedRegions} of ${summaryResult.data.respondedRegions} regions`, + { id: toastId, duration: 4000 }, + ); + continue; + } + + const rowResult = cdnRegionResponseSchema.safeParse(parsed); + if (rowResult.success) { + const row = rowResult.data; + setRows((prev) => [...prev, row]); + if (row.state === "success") { + toast.loading( + `${regionFormatter(row.region, "long")}: ${row.cacheStatus}`, + { id: toastId }, + ); + } + } + } + } + } catch (error) { + // deliberate abort (new submission or unmount) is not an error + if (controller.signal.aborted) { + if (toastId !== undefined) toast.dismiss(toastId); + return; + } + console.error("Error fetching data:", error); + toast.error("Something went wrong", { + id: toastId, + description: "Please try again.", + className: "text-destructive!", + }); + } + }); + } + + // ?url= present on mount: re-run the probe live (shareable result links) + // biome-ignore lint/correctness/useExhaustiveDependencies: run once on mount + useEffect(() => { + if (autoRan.current) return; + autoRan.current = true; + if (urlParam) runCheck(urlParam); + }, []); + + return ( + + {children} + + ); +} + +export function CdnForm() { + const { runCheck, isPending } = useCdnChecker(); + const [{ url: urlParam }] = useQueryStates(searchParamsParsers); + + function handleSubmit(event: React.FormEvent) { + event.preventDefault(); + const formData = new FormData(event.target as HTMLFormElement); + runCheck(formData.get("url") as string); + } + + return ( +

+
+
+ +
+
+ +
+
+
+ ); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx b/apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx new file mode 100644 index 00000000..5cdc3aa0 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/components/monitor-cta.tsx @@ -0,0 +1,76 @@ +"use client"; + +import type { CdnProvider } from "@openstatus/header-analysis"; +import { Button } from "@openstatus/ui/components/ui/button"; + +import { APP_URL } from "@/lib/metadata/shared-metadata"; + +import { useCdnChecker } from "../client"; + +// keys in Go-canonical casing: the checker matches header assertions by +// exact key (apps/checker/pkg/assertions), not case-insensitively +const CACHE_ASSERTION: Partial< + Record< + CdnProvider, + { key: string; compare: "eq" | "contains"; target: string } + > +> = { + cloudflare: { key: "Cf-Cache-Status", compare: "eq", target: "HIT" }, + vercel: { key: "X-Vercel-Cache", compare: "eq", target: "HIT" }, + cloudfront: { key: "X-Cache", compare: "contains", target: "Hit" }, + fastly: { key: "X-Cache", compare: "contains", target: "HIT" }, + akamai: { key: "X-Cache", compare: "contains", target: "HIT" }, +}; + +export function MonitorCta() { + const { summary, checkedUrl } = useCdnChecker(); + + if (!summary || !checkedUrl) return null; + + const uncached = summary.uncachedRegions.length; + const unreachable = summary.unreachableRegions.length; + const assertion = summary.cdn ? CACHE_ASSERTION[summary.cdn] : undefined; + + const params = new URLSearchParams({ url: checkedUrl, ref: "cdn-checker" }); + if (assertion) { + params.set("assertionHeaderKey", assertion.key); + params.set("assertionHeaderCompare", assertion.compare); + params.set("assertionHeaderValue", assertion.target); + } + + return ( +
+
+

+ {uncached > 0 + ? `Your CDN is not serving from cache in ${uncached} ${ + uncached === 1 ? "region" : "regions" + }.` + : unreachable > 0 + ? `Caching looks healthy in the regions that responded (${unreachable} unreachable).` + : "Caching looks healthy — keep it that way."} +

+

+ {uncached > 0 + ? "Monitor cache status and edge latency continuously and get alerted when caching breaks. Free." + : "Monitor this URL and get alerted the moment a region stops caching. Free."} + {assertion + ? ` The monitor comes pre-filled with a ${assertion.key} assertion.` + : null} +

+
+ +
+ ); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx b/apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx new file mode 100644 index 00000000..1cc40831 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/components/results-table.tsx @@ -0,0 +1,207 @@ +"use client"; + +import { CDN_LABELS } from "@openstatus/header-analysis"; +import { AVAILABLE_REGIONS, regionDict } from "@openstatus/regions"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@openstatus/ui/components/ui/dialog"; + +import { IconCloudProvider } from "@/components/icon-cloud-provider"; +import type { CdnRegionResult } from "@/lib/cdn-checker/schema"; +import { regionFormatter } from "@/lib/checker/utils"; +import { cn } from "@/lib/utils"; + +import { useCdnChecker } from "../client"; +import { + CACHE_STATUS_COLOR, + CACHE_STATUS_DESCRIPTION, + formatAge, +} from "../utils"; + +function CacheStatusIndicator({ + status, +}: { + status: CdnRegionResult["cacheStatus"]; +}) { + return ( +
+ ); +} + +export function CacheStatusLegend() { + return ( +
+ {Object.entries(CACHE_STATUS_COLOR).map(([status, className]) => ( +
+ {status} +
+ ))} +
+ ); +} + +function DetailsDialog({ result }: { result: CdnRegionResult }) { + const config = regionDict[result.region]; + const entries = [ + { label: "Edge", value: result.edgePop ?? "-" }, + { label: "Status", value: String(result.statusCode) }, + { label: "Age", value: formatAge(result.age) }, + { label: "CDN", value: result.cdn ? CDN_LABELS[result.cdn] : "-" }, + { label: "Cache Header", value: result.cacheStatusRaw }, + { label: "Cache-Control", value: result.cacheControl }, + { label: "ETag", value: result.etag }, + { label: "Edge Location", value: result.edgePopLocation }, + ].filter((entry) => entry.value); + + return ( + + + + + + + Cache Details + + Cache status and response headers for this region. + + +
+ + + + + + + {entries.map((entry) => ( + + + + + ))} + +
Region + {config.location} {config.flag}, {config.provider}{" "} + +
{entry.label}{entry.value}
+
+
+
+ ); +} + +export function ResultsTable() { + const { rows } = useCdnChecker(); + + const successRows = rows + .filter((row) => row.state === "success") + .sort((a, b) => a.ttfbMs - b.ttfbMs); + const errorRows = rows.filter((row) => row.state === "error"); + + return ( +
+ {errorRows.length > 0 ? ( +

+ Unreachable:{" "} + {errorRows + .map((row) => regionFormatter(row.region, "short")) + .join(", ")} +

+ ) : null} +
+ + + + + + + + + {successRows.length === 0 ? ( + + + + + + + + ) : ( + successRows.map((row) => { + const config = regionDict[row.region]; + return ( + + + + + + + + ); + }) + )} + + +
+ + RegionLatency +
+ + +
+
+
+
+
+
+
+
+ + + + + {config.flag} {config.code}{" "} + + {config.location} + + + {Intl.NumberFormat("en-US", { + maximumFractionDigits: 0, + }).format(row.ttfbMs)} + ms + + +
+ Results of your check ({rows.length} / {AVAILABLE_REGIONS.length}{" "} + regions) +
+
+
+ ); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx b/apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx new file mode 100644 index 00000000..a4997104 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/components/summary-card.tsx @@ -0,0 +1,96 @@ +"use client"; + +import { CDN_LABELS } from "@openstatus/header-analysis"; + +import { regionFormatter } from "@/lib/checker/utils"; +import { cn } from "@/lib/utils"; + +import { useCdnChecker } from "../client"; + +const UNCACHED_PREVIEW_COUNT = 6; + +function ratioColor(cached: number, responded: number) { + if (responded === 0) return "text-muted-foreground"; + const ratio = cached / responded; + if (ratio >= 0.9) return "text-success"; + if (ratio >= 0.5) return "text-warning"; + return "text-destructive"; +} + +export function SummaryCard() { + const { summary } = useCdnChecker(); + + if (!summary) return null; + + const { + cachedRegions, + respondedRegions, + uncachedRegions, + unreachableRegions, + cdn, + mixedCdn, + topology, + topologyBasis, + } = summary; + + return ( +
+
+

Cache hit ratio

+

+ {cachedRegions} / {respondedRegions} +

+

+ regions served from cache + {unreachableRegions.length > 0 + ? ` (${unreachableRegions.length} unreachable)` + : null} +

+
+
+

CDN

+

+ {cdn ? CDN_LABELS[cdn] : "Not detected"} +

+

+ {mixedCdn + ? "multiple providers detected" + : topology !== "unknown" + ? `${topology}${topologyBasis === "provider" ? " (inferred)" : ""}` + : "topology unknown"} +

+
+
+

Uncached regions

+ {uncachedRegions.length === 0 ? ( +

None

+ ) : ( + <> +

+ {uncachedRegions.length} +

+

+ {uncachedRegions + .slice(0, UNCACHED_PREVIEW_COUNT) + .map((region) => regionFormatter(region, "short")) + .join(", ")} + {uncachedRegions.length > UNCACHED_PREVIEW_COUNT + ? ` +${uncachedRegions.length - UNCACHED_PREVIEW_COUNT} more` + : ""} +

+ + )} +

+ {uncachedRegions.length > 0 + ? "MISS can mean first request — run again to confirm" + : "caching looks healthy"} +

+
+
+ ); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/page.tsx b/apps/web/src/app/(landing)/play/cdn-checker/page.tsx new file mode 100644 index 00000000..fdfaa673 --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/page.tsx @@ -0,0 +1,58 @@ +import type { Metadata } from "next"; +import { Suspense } from "react"; + +import { CustomMDX } from "@/content/mdx"; +import { getToolsPage } from "@/content/utils"; +import { JsonLd } from "@/lib/metadata/json-ld"; +import { BASE_URL, getPageMetadata } from "@/lib/metadata/shared-metadata"; +import { + createJsonLDGraph, + getJsonLDBreadcrumbList, + getJsonLDFAQPage, + getJsonLDWebPage, +} from "@/lib/metadata/structured-data"; + +import { CdnCheckerProvider, CdnForm } from "./client"; +import { MonitorCta } from "./components/monitor-cta"; +import { CacheStatusLegend, ResultsTable } from "./components/results-table"; +import { SummaryCard } from "./components/summary-card"; + +export function generateMetadata(): Metadata { + const page = getToolsPage("cdn-checker"); + return getPageMetadata(page, "play"); +} + +export default function Page() { + const page = getToolsPage("cdn-checker"); + + const jsonLDGraph = createJsonLDGraph([ + getJsonLDWebPage(page), + getJsonLDBreadcrumbList([ + { name: "Home", url: BASE_URL }, + { name: "Playground", url: `${BASE_URL}/play` }, + { name: page.metadata.title, url: `${BASE_URL}/play/cdn-checker` }, + ]), + getJsonLDFAQPage(page), + ]); + + return ( +
+ +

{page.metadata.hero ?? page.metadata.title}

+

{page.metadata.description}

+ + + + + + + + + +

+ Checks run live — results are not stored. +

+ +
+ ); +} diff --git a/apps/web/src/app/(landing)/play/cdn-checker/search-params.ts b/apps/web/src/app/(landing)/play/cdn-checker/search-params.ts new file mode 100644 index 00000000..62e5dd7f --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/search-params.ts @@ -0,0 +1,5 @@ +import { parseAsString } from "nuqs/server"; + +export const searchParamsParsers = { + url: parseAsString, +}; diff --git a/apps/web/src/app/(landing)/play/cdn-checker/utils.ts b/apps/web/src/app/(landing)/play/cdn-checker/utils.ts new file mode 100644 index 00000000..b5fcb5ba --- /dev/null +++ b/apps/web/src/app/(landing)/play/cdn-checker/utils.ts @@ -0,0 +1,28 @@ +import type { CacheStatus } from "@openstatus/header-analysis"; + +export const CACHE_STATUS_COLOR: Record = { + HIT: "bg-success", + STALE: "bg-success/80", + EXPIRED: "bg-warning", + MISS: "bg-destructive", + BYPASS: "bg-muted-foreground", + DYNAMIC: "bg-info", + UNKNOWN: "bg-muted-foreground", +}; + +export const CACHE_STATUS_DESCRIPTION: Record = { + HIT: "Served from the edge cache", + STALE: "Served from cache while revalidating with origin", + EXPIRED: "Found in cache but expired — fetched from origin", + MISS: "Not in cache — fetched from origin", + BYPASS: "Caching explicitly bypassed for this asset", + DYNAMIC: "Not eligible for caching", + UNKNOWN: "No cache headers detected", +}; + +export function formatAge(seconds: number | null): string { + if (seconds === null) return "-"; + if (seconds < 60) return `${seconds}s`; + if (seconds < 3600) return `${Math.floor(seconds / 60)}m`; + return `${Math.floor(seconds / 3600)}h`; +} diff --git a/apps/web/src/app/(landing)/play/page.tsx b/apps/web/src/app/(landing)/play/page.tsx index a7d54da9..0b9d1767 100644 --- a/apps/web/src/app/(landing)/play/page.tsx +++ b/apps/web/src/app/(landing)/play/page.tsx @@ -59,6 +59,12 @@ const PLAY = [ description: "Test the latency of your website worldwide", href: "/play/checker", }, + { + label: "CDN Cache Checker", + description: + "Check if your CDN is caching, and which edge served each region", + href: "/play/cdn-checker", + }, { label: "MCP Server Health Check", description: "JSON-RPC ping check for Model Context Protocol servers", diff --git a/apps/web/src/components/ui/data-table/data-table-column-header.tsx b/apps/web/src/components/ui/data-table/data-table-column-header.tsx new file mode 100644 index 00000000..0d63e103 --- /dev/null +++ b/apps/web/src/components/ui/data-table/data-table-column-header.tsx @@ -0,0 +1,60 @@ +import { Button } from "@openstatus/ui/components/ui/button"; +import { cn } from "@openstatus/ui/lib/utils"; +import type { Column } from "@tanstack/react-table"; +import { ChevronDown, ChevronUp } from "lucide-react"; + +interface DataTableColumnHeaderProps< + TData, + TValue, +> extends React.ComponentProps<"button"> { + column: Column; + title: string; +} + +export function DataTableColumnHeader({ + column, + title, + className, + onClick, + ...props +}: DataTableColumnHeaderProps) { + if (!column.getCanSort()) { + return
{title}
; + } + + return ( + + ); +} diff --git a/apps/web/src/components/ui/data-table/data-table.tsx b/apps/web/src/components/ui/data-table/data-table.tsx new file mode 100644 index 00000000..926eee6a --- /dev/null +++ b/apps/web/src/components/ui/data-table/data-table.tsx @@ -0,0 +1,158 @@ +"use client"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@openstatus/ui/components/ui/table"; +import { + type ColumnDef, + type ColumnFiltersState, + type Row, + type SortingState, + type VisibilityState, + flexRender, + getCoreRowModel, + getExpandedRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import * as React from "react"; +import { Fragment } from "react"; + +interface DataTableToolbarProps { + table: import("@tanstack/react-table").Table; +} + +// trimmed port of apps/dashboard data-table: no pagination/action bar — +// play tools render a fixed, small set of rows +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; + rowComponent?: React.ComponentType<{ row: Row }>; + toolbarComponent?: React.ComponentType>; + onRowClick?: (row: Row) => void; + defaultSorting?: SortingState; + defaultColumnVisibility?: VisibilityState; + defaultColumnFilters?: ColumnFiltersState; + emptyState?: React.ReactNode; +} + +export function DataTable({ + columns, + data, + rowComponent, + toolbarComponent, + onRowClick, + defaultSorting = [], + defaultColumnVisibility = {}, + defaultColumnFilters = [], + emptyState = "No results.", +}: DataTableProps) { + const [columnVisibility, setColumnVisibility] = + React.useState(defaultColumnVisibility); + const [columnFilters, setColumnFilters] = + React.useState(defaultColumnFilters); + const [sorting, setSorting] = React.useState(defaultSorting); + + const table = useReactTable({ + data, + columns, + state: { + sorting, + columnVisibility, + columnFilters, + }, + onSortingChange: setSorting, + onColumnFiltersChange: setColumnFilters, + onColumnVisibilityChange: setColumnVisibility, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getSortedRowModel: getSortedRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + getExpandedRowModel: getExpandedRowModel(), + getRowCanExpand: () => Boolean(rowComponent), + }); + + return ( +
+ {toolbarComponent + ? React.createElement(toolbarComponent, { table }) + : null} + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + onRowClick?.(row)} + className="data-[state=selected]:bg-muted/50" + > + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + {row.getIsExpanded() && ( + + + {rowComponent + ? React.createElement(rowComponent, { row }) + : null} + + + )} + + )) + ) : ( + + + {emptyState} + + + )} + +
+
+ ); +} diff --git a/apps/web/src/content/pages/tools/cdn-checker.mdx b/apps/web/src/content/pages/tools/cdn-checker.mdx new file mode 100644 index 00000000..daf70124 --- /dev/null +++ b/apps/web/src/content/pages/tools/cdn-checker.mdx @@ -0,0 +1,99 @@ +--- +title: "CDN Cache Checker" +publishedAt: "2026-06-07" +author: "Thibault Le Ouay Ducasse" +description: "Check if your CDN is actually caching from 28 regions worldwide. See cache HIT/MISS per region, which edge served you, and which CDN a website uses." +category: "Product" +faq: + - question: "What is a CDN cache checker?" + answer: "A CDN cache checker tests whether your CDN is serving content from its edge cache instead of your origin server. OpenStatus requests your URL from 28 regions worldwide and reads the cache headers (cf-cache-status, x-cache, x-vercel-cache, age) to report HIT, MISS, EXPIRED, STALE, BYPASS or DYNAMIC per region." + - question: "Why does my CDN return MISS in some regions?" + answer: "CDN caches are regional: each edge location keeps its own copy. A MISS in a region usually means no user has requested the asset from that edge recently, the TTL expired, or your cache rules exclude it. The first request from a region is always a MISS — run the check again to confirm whether the edge cached the response." + - question: "How do I know what CDN a website is using?" + answer: "CDNs add identifying response headers. Cloudflare adds cf-ray and cf-cache-status, Amazon CloudFront adds x-amz-cf-id and x-amz-cf-pop, Fastly adds x-served-by, Vercel adds x-vercel-id. The CDN Cache Checker fingerprints these headers automatically and shows the detected provider." + - question: "What is the difference between anycast and unicast CDNs?" + answer: "With anycast, every edge location announces the same IP address and the network routes users to the nearest one. With unicast or GeoDNS, DNS hands out different IP addresses per region. Anycast typically fails over faster; GeoDNS gives the provider more routing control. The checker infers the topology from the responses." +--- + +## Start monitoring your cache + + +
+ +**Cache status per region** + +See HIT, MISS, EXPIRED, STALE or DYNAMIC for every region — read straight from your CDN's response headers, not guessed from latency. + +
+
+ +**CDN detection & edge PoP** + +Identify which CDN serves a website and which edge location (PoP) answered each region, with anycast vs unicast topology inference. + +
+
+ +**Monitor it continuously** + +Turn a one-off check into a monitor with an assertion on the cache header — get alerted the moment a region stops caching. + +
+
+ +### How CDN caching works + +A CDN keeps copies of your content on edge servers close to your users. When a request arrives, the edge either serves its cached copy (a **HIT**) or forwards the request to your origin (a **MISS**) and usually stores the response for next time. + +Caches are regional: a HIT in Frankfurt says nothing about Tokyo. That is why checking from a single location — or only from your own machine — routinely hides cold or misconfigured regions. This tool runs the same request from 28 regions at once and reads the cache headers from every response. + +### Reading cache headers: HIT vs MISS vs EXPIRED vs STALE + +Each provider reports cache state in its own header. The checker normalizes them into one status: + +| Status | Meaning | +| --- | --- | +| `HIT` | Served from the edge cache. | +| `MISS` | Not in cache — fetched from origin. The next request should be a HIT. | +| `EXPIRED` | Found in cache but past its TTL — revalidated against origin. | +| `STALE` | Served from cache while revalidating in the background (`stale-while-revalidate`). | +| `BYPASS` | Caching explicitly skipped, e.g. a `no-cache` rule or cookie. | +| `DYNAMIC` | Not eligible for caching (often HTML or API responses). | +| `UNKNOWN` | No cache headers detected — there may be no CDN at all. | + +The vendor headers behind it: + +| CDN | Header | Example | +| --- | --- | --- | +| Cloudflare | `cf-cache-status` | `HIT` | +| Amazon CloudFront | `x-cache` | `Hit from cloudfront` | +| Fastly / Varnish | `x-cache` | `HIT, MISS` | +| Akamai | `x-cache` | `TCP_HIT` | +| Vercel | `x-vercel-cache` | `STALE` | +| RFC 9211 (Netlify, …) | `cache-status` | `"Netlify Edge"; hit` | +| Generic | `age` + `cache-control` | `age: 842` | + +### Anycast vs unicast + +If every region receives a response from the same edge IP, the CDN is using **anycast**: one IP announced from all locations, routed by the network to the nearest edge (Cloudflare, Fastly). If regions resolve to different IPs, the CDN uses **unicast/GeoDNS**: DNS decides per region (CloudFront, Akamai). Neither is wrong — anycast tends to fail over faster, GeoDNS gives finer routing control — but knowing which one you run matters when debugging regional anomalies. + +### Check cache headers from your terminal + +For a quick single-location check, inspect the headers with cURL: + +```bash +curl -sI https://example.com/asset.js | grep -iE 'cf-cache-status|x-cache|x-vercel-cache|age|cache-control' +``` + +Need a more complex request? Build it with the [cURL Builder](/play/curl). Want latency instead of cache state? Use the [Global Speed Checker](/play/checker). + +--- + +With OpenStatus, you can: + +- Verify your CDN serves cache HITs from every region after a config change. +- Debug `cf-cache-status: MISS` and origin load spikes region by region. +- Detect which CDN a website uses and which edge PoP answered. +- Monitor cache status continuously with header assertions and get alerted when caching breaks. + +If you'd like to request additional test regions or providers, feel free to contact us at [ping@openstatus.dev](mailto:ping@openstatus.dev). diff --git a/apps/web/src/lib/cdn-checker/dev-probe.ts b/apps/web/src/lib/cdn-checker/dev-probe.ts new file mode 100644 index 00000000..939659f2 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/dev-probe.ts @@ -0,0 +1,73 @@ +import type { Region } from "@openstatus/db/src/schema/constants"; + +import type { Timing } from "@/lib/checker/utils"; +import { wait } from "@/lib/utils"; + +import { PROBE_TIMEOUT_MS, mapCheckToCdnResult } from "./probe"; +import type { CdnRegionResponse } from "./schema"; + +function makeTiming(ttfb: number, total: number): Timing { + return { + dnsStart: 0, + dnsDone: 0, + connectStart: 0, + connectDone: 0, + tlsHandshakeStart: 0, + tlsHandshakeDone: 0, + firstByteStart: 0, + firstByteDone: ttfb, + transferStart: ttfb, + transferDone: total, + }; +} + +// dev runs without CRON_SECRET so the checker fleet is unreachable: probe the +// URL directly from the local machine instead. Headers and cache status are +// real; the vantage point is not — every "region" sees the same nearest edge. +export async function devProbeCdnRegion({ + url, + region, +}: { + url: string; + region: Region; +}): Promise { + // jitter so rows stream progressively like the real fan-out + await wait(50 + Math.random() * 800); + + try { + const start = performance.now(); + const response = await fetch(url, { + method: "GET", + redirect: "follow", + cache: "no-store", + signal: AbortSignal.timeout(PROBE_TIMEOUT_MS), + }); + const ttfb = Math.round(performance.now() - start); + const body = await response.arrayBuffer(); + const total = Math.round(performance.now() - start); + + const headers: Record = {}; + response.headers.forEach((value, key) => { + headers[key] = value; + }); + // fetch strips content-length on decompressed responses + headers["content-length"] ??= String(body.byteLength); + + return mapCheckToCdnResult({ + type: "http", + state: "success", + region, + status: response.status, + latency: total, + timestamp: Date.now(), + timing: makeTiming(ttfb, total), + headers, + }); + } catch (error) { + return { + state: "error", + region, + message: error instanceof Error ? error.message : "Request failed", + }; + } +} diff --git a/apps/web/src/lib/cdn-checker/guards.ts b/apps/web/src/lib/cdn-checker/guards.ts new file mode 100644 index 00000000..1c758a8b --- /dev/null +++ b/apps/web/src/lib/cdn-checker/guards.ts @@ -0,0 +1,47 @@ +import { assertSafeUrlSync } from "@openstatus/utils"; + +type UrlGuardResult = + | { ok: true } + | { ok: false; error: string; status: number }; + +export function validateCdnUrl(url: string): UrlGuardResult { + try { + // protocol check + private/loopback/metadata-host block + assertSafeUrlSync(url); + } catch (err) { + return { + ok: false, + error: err instanceof Error ? err.message : "Invalid URL", + status: 400, + }; + } + + const urlObject = new URL(url); + const hostname = urlObject.hostname.toLowerCase(); + if ( + (hostname === "openstatus.dev" || hostname.endsWith(".openstatus.dev")) && + urlObject.pathname.startsWith("/play/cdn-checker/api") + ) { + return { ok: false, error: "Self-requests are not allowed", status: 400 }; + } + + const blacklistPatterns = (process.env.BLACKLIST_URL ?? "") + .split(",") + .map((p) => p.trim()) + .filter(Boolean); + for (const pattern of blacklistPatterns) { + let matches = false; + try { + matches = new RegExp(pattern).test(url); + } catch (error) { + // skip the bad pattern so it can't silently disable the whole guard + console.error("Invalid blacklist pattern", pattern, error); + continue; + } + if (matches) { + return { ok: false, error: "This URL is not allowed", status: 403 }; + } + } + + return { ok: true }; +} diff --git a/apps/web/src/lib/cdn-checker/probe.test.ts b/apps/web/src/lib/cdn-checker/probe.test.ts new file mode 100644 index 00000000..1871d007 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/probe.test.ts @@ -0,0 +1,142 @@ +import { expect } from "@std/expect"; +import { afterEach, describe, test } from "@std/testing/bdd"; + +import type { RegionCheckerResponse } from "@/lib/checker/utils"; + +import { mapCheckToCdnResult, probeCdnRegion } from "./probe"; + +const timing = { + dnsStart: 0, + dnsDone: 2, + connectStart: 2, + connectDone: 3, + tlsHandshakeStart: 3, + tlsHandshakeDone: 8, + firstByteStart: 8, + firstByteDone: 46, + transferStart: 46, + transferDone: 49, +}; + +describe("mapCheckToCdnResult", () => { + test("maps a cloudflare HIT", () => { + const check: RegionCheckerResponse = { + type: "http", + state: "success", + region: "iad", + status: 200, + latency: 71, + timestamp: 0, + timing, + headers: { + "Cf-Cache-Status": "HIT", + "Cf-Ray": "8c9a1b2c3d4e5f6a-IAD", + Server: "cloudflare", + Age: "842", + "Cache-Control": "public, max-age=3600", + Etag: 'W/"abc123"', + "Content-Length": "18233", + }, + }; + const result = mapCheckToCdnResult(check); + if (result.state !== "success") throw new Error("expected success"); + expect(result.cacheStatus).toBe("HIT"); + expect(result.cacheStatusRaw).toBe("cf-cache-status: HIT"); + expect(result.cdn).toBe("cloudflare"); + expect(result.edgePop).toBe("IAD"); + expect(result.ttfbMs).toBe(38); + expect(result.totalMs).toBe(71); + expect(result.responseSize).toBe(18233); + expect(result.age).toBe(842); + expect(result.etag).toBe('W/"abc123"'); + expect(result.edgeIp).toBeNull(); + }); + + test("falls back to body byte length without content-length", () => { + const check: RegionCheckerResponse = { + type: "http", + state: "success", + region: "ams", + status: 200, + latency: 100, + timestamp: 0, + timing, + headers: {}, + body: "hello", + }; + const result = mapCheckToCdnResult(check); + if (result.state !== "success") throw new Error("expected success"); + expect(result.responseSize).toBe(5); + expect(result.cacheStatus).toBe("UNKNOWN"); + expect(result.cdn).toBeNull(); + }); + + test("passes error responses through", () => { + const check: RegionCheckerResponse = { + state: "error", + region: "syd", + message: "connection refused", + }; + const result = mapCheckToCdnResult(check); + expect(result).toEqual({ + state: "error", + region: "syd", + message: "connection refused", + }); + }); +}); + +describe("probeCdnRegion abort propagation", () => { + const realFetch = globalThis.fetch; + afterEach(() => { + globalThis.fetch = realFetch; + }); + + test("forwards an abort signal to the underlying fetch", async () => { + let received: AbortSignal | undefined; + globalThis.fetch = (async (_input: unknown, init?: RequestInit) => { + received = init?.signal ?? undefined; + return new Response( + JSON.stringify({ + type: "http", + state: "success", + status: 200, + latency: 10, + headers: { "Cf-Cache-Status": "HIT", "Cf-Ray": "abc-FRA" }, + timestamp: 0, + timing, + }), + { status: 200 }, + ); + }) as typeof fetch; + + const result = await probeCdnRegion({ + url: "https://example.com", + region: "fra", + }); + expect(result.state).toBe("success"); + expect(received).toBeInstanceOf(AbortSignal); + }); + + test("aborts the fetch when the timeout elapses and returns a Timeout row", async () => { + globalThis.fetch = ((_input: unknown, init?: RequestInit) => { + // resolve only when the signal aborts, mirroring a hung request + return new Promise((_resolve, reject) => { + init?.signal?.addEventListener("abort", () => + reject(init.signal?.reason ?? new Error("aborted")), + ); + }); + }) as typeof fetch; + + const result = await probeCdnRegion({ + url: "https://example.com", + region: "fra", + timeoutMs: 20, + }); + expect(result).toEqual({ + state: "error", + region: "fra", + message: "Timeout", + }); + }); +}); diff --git a/apps/web/src/lib/cdn-checker/probe.ts b/apps/web/src/lib/cdn-checker/probe.ts new file mode 100644 index 00000000..16ef08f6 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/probe.ts @@ -0,0 +1,92 @@ +import type { Region } from "@openstatus/db/src/schema/constants"; +import { + detectCdn, + extractEdgePop, + getHeader, + normalizeCacheStatus, +} from "@openstatus/header-analysis"; + +import { + type RegionCheckerResponse, + checkRegion, + getTimingPhases, +} from "@/lib/checker/utils"; + +import type { CdnRegionResponse } from "./schema"; + +// the checker downloads the full body before responding; capping after +// headers needs a Go-side change, so keep a generous per-region budget +export const PROBE_TIMEOUT_MS = 12_000; + +export function mapCheckToCdnResult( + check: RegionCheckerResponse, +): CdnRegionResponse { + if (check.state === "error") { + return { state: "error", region: check.region, message: check.message }; + } + + const { headers } = check; + const cache = normalizeCacheStatus(headers); + const { provider } = detectCdn(headers); + const { pop, location } = extractEdgePop(headers, provider); + + const contentLength = getHeader(headers, "content-length"); + const responseSize = contentLength + ? Number.parseInt(contentLength, 10) + : check.body + ? new TextEncoder().encode(check.body).length + : null; + + const age = getHeader(headers, "age"); + const parsedAge = age ? Number.parseInt(age, 10) : Number.NaN; + + return { + state: "success", + region: check.region, + cacheStatus: cache.status, + cacheStatusRaw: cache.source ? `${cache.source}: ${cache.raw}` : null, + edgeIp: null, // requires a checker-side change to capture; see plan phase 5 + edgePop: pop, + edgePopLocation: location, + ttfbMs: Math.round(getTimingPhases(check.timing).ttfb), + totalMs: Math.round(check.latency), + statusCode: check.status, + responseSize: Number.isNaN(responseSize ?? Number.NaN) + ? null + : responseSize, + age: Number.isNaN(parsedAge) ? null : parsedAge, + cacheControl: getHeader(headers, "cache-control"), + etag: getHeader(headers, "etag"), + cdn: provider, + }; +} + +export async function probeCdnRegion({ + url, + region, + timeoutMs = PROBE_TIMEOUT_MS, +}: { + url: string; + region: Region; + timeoutMs?: number; +}): Promise { + try { + const check = await checkRegion({ + url, + region, + method: "GET", + // hard abort, not a soft race: the underlying fetch must not keep + // running (and consuming the edge function budget) after timeout + signal: AbortSignal.timeout(timeoutMs), + }); + return mapCheckToCdnResult(check); + } catch (error) { + const message = + error instanceof Error + ? error.name === "TimeoutError" + ? "Timeout" + : error.message + : "Request failed"; + return { state: "error", region, message }; + } +} diff --git a/apps/web/src/lib/cdn-checker/ratelimit.ts b/apps/web/src/lib/cdn-checker/ratelimit.ts new file mode 100644 index 00000000..71c70959 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/ratelimit.ts @@ -0,0 +1,47 @@ +export const RATE_LIMIT_WINDOW = 60; +export const MAX_REQUESTS_PER_WINDOW = 3; + +type CdnRateLimit = + | { status: "skipped" } + | { status: "no-client-ip" } + | { + status: "ok" | "limited"; + limit: number; + remaining: number; + reset: number; + }; + +// dev runs without Upstash credentials and the redis client throws at module +// evaluation, so the limiter is only imported (and enforced) in production +export async function rateLimitCdnRequest( + prefix: string, + headers: Headers, +): Promise { + if (process.env.NODE_ENV !== "production") return { status: "skipped" }; + + const { getClientIP, ratelimit } = await import("@/lib/ratelimit"); + + const clientIP = getClientIP(headers); + if (!clientIP) return { status: "no-client-ip" }; + + const rl = await ratelimit(`${prefix}:${clientIP}`, { + window: RATE_LIMIT_WINDOW, + limit: MAX_REQUESTS_PER_WINDOW, + }); + + return { + status: rl.success ? "ok" : "limited", + limit: rl.limit, + remaining: rl.remaining, + reset: rl.reset, + }; +} + +export function rateLimitHeaders(rl: CdnRateLimit): Record { + if (rl.status !== "ok" && rl.status !== "limited") return {}; + return { + "X-RateLimit-Limit": rl.limit.toString(), + "X-RateLimit-Remaining": rl.remaining.toString(), + "X-RateLimit-Reset": rl.reset.toString(), + }; +} diff --git a/apps/web/src/lib/cdn-checker/schema.ts b/apps/web/src/lib/cdn-checker/schema.ts new file mode 100644 index 00000000..6bd00693 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/schema.ts @@ -0,0 +1,54 @@ +import { monitorRegionSchema } from "@openstatus/db/src/schema/constants"; +import { CACHE_STATUSES, CDN_PROVIDERS } from "@openstatus/header-analysis"; +import { z } from "zod"; + +const cacheStatusSchema = z.enum(CACHE_STATUSES); +const cdnProviderSchema = z.enum(CDN_PROVIDERS); + +export const cdnRegionResultSchema = z.object({ + state: z.literal("success").prefault("success"), + region: monitorRegionSchema, + cacheStatus: cacheStatusSchema, + /** `header-name: value` pair that determined the status */ + cacheStatusRaw: z.string().nullable(), + edgeIp: z.string().nullable(), + edgePop: z.string().nullable(), + edgePopLocation: z.string().nullable(), + ttfbMs: z.number(), + totalMs: z.number(), + statusCode: z.number(), + responseSize: z.number().nullable(), + age: z.number().nullable(), + cacheControl: z.string().nullable(), + etag: z.string().nullable(), + cdn: cdnProviderSchema.nullable(), +}); + +const cdnRegionErrorSchema = z.object({ + state: z.literal("error"), + region: monitorRegionSchema, + message: z.string(), +}); + +export const cdnRegionResponseSchema = z.discriminatedUnion("state", [ + cdnRegionResultSchema, + cdnRegionErrorSchema, +]); + +export const cdnSummarySchema = z.object({ + type: z.literal("summary").prefault("summary"), + totalRegions: z.number(), + respondedRegions: z.number(), + cachedRegions: z.number(), + uncachedRegions: monitorRegionSchema.array(), + unreachableRegions: monitorRegionSchema.array(), + cdn: cdnProviderSchema.nullable(), + /** more than one provider detected across regions (multi-CDN or mixed setup) */ + mixedCdn: z.boolean(), + topology: z.enum(["anycast", "unicast", "unknown"]), + topologyBasis: z.enum(["edge-ips", "provider"]).nullable(), +}); + +export type CdnRegionResult = z.infer; +export type CdnRegionResponse = z.infer; +export type CdnSummary = z.infer; diff --git a/apps/web/src/lib/cdn-checker/summary.test.ts b/apps/web/src/lib/cdn-checker/summary.test.ts new file mode 100644 index 00000000..51401c76 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/summary.test.ts @@ -0,0 +1,100 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import type { CdnRegionResponse, CdnRegionResult } from "./schema"; +import { computeCdnSummary } from "./summary"; + +function makeRow(overrides: Partial = {}): CdnRegionResult { + return { + state: "success", + region: "iad", + cacheStatus: "HIT", + cacheStatusRaw: "cf-cache-status: HIT", + edgeIp: null, + edgePop: "IAD", + edgePopLocation: "Ashburn, USA", + ttfbMs: 38, + totalMs: 71, + statusCode: 200, + responseSize: 18233, + age: 842, + cacheControl: "public, max-age=3600", + etag: 'W/"abc123"', + cdn: "cloudflare", + ...overrides, + }; +} + +describe("computeCdnSummary", () => { + test("counts HIT and STALE as cached, lists the rest as uncached", () => { + const rows: CdnRegionResponse[] = [ + makeRow({ region: "iad", cacheStatus: "HIT" }), + makeRow({ region: "ams", cacheStatus: "STALE" }), + makeRow({ region: "gru", cacheStatus: "MISS" }), + makeRow({ region: "syd", cacheStatus: "EXPIRED" }), + ]; + const summary = computeCdnSummary(rows); + expect(summary.cachedRegions).toBe(2); + expect(summary.respondedRegions).toBe(4); + expect(summary.uncachedRegions).toEqual(["gru", "syd"]); + }); + + test("error rows count as unreachable, not uncached", () => { + const rows: CdnRegionResponse[] = [ + makeRow({ region: "iad" }), + { state: "error", region: "syd", message: "Timeout" }, + ]; + const summary = computeCdnSummary(rows); + expect(summary.totalRegions).toBe(2); + expect(summary.respondedRegions).toBe(1); + expect(summary.unreachableRegions).toEqual(["syd"]); + expect(summary.uncachedRegions).toEqual([]); + }); + + test("majority provider wins, mixedCdn flags disagreement", () => { + const rows: CdnRegionResponse[] = [ + makeRow({ region: "iad", cdn: "cloudflare" }), + makeRow({ region: "ams", cdn: "cloudflare" }), + makeRow({ region: "syd", cdn: "fastly" }), + ]; + const summary = computeCdnSummary(rows); + expect(summary.cdn).toBe("cloudflare"); + expect(summary.mixedCdn).toBe(true); + }); + + test("tied providers -> null cdn instead of an arbitrary winner", () => { + const rows: CdnRegionResponse[] = [ + makeRow({ region: "iad", cdn: "cloudflare" }), + makeRow({ region: "syd", cdn: "fastly" }), + ]; + const summary = computeCdnSummary(rows); + expect(summary.cdn).toBeNull(); + expect(summary.mixedCdn).toBe(true); + }); + + test("no provider detected -> null cdn, unknown topology", () => { + const rows: CdnRegionResponse[] = [makeRow({ cdn: null })]; + const summary = computeCdnSummary(rows); + expect(summary.cdn).toBeNull(); + expect(summary.mixedCdn).toBe(false); + expect(summary.topology).toBe("unknown"); + expect(summary.topologyBasis).toBeNull(); + }); + + test("topology falls back to provider heuristic without edge IPs", () => { + const rows: CdnRegionResponse[] = [ + makeRow({ region: "iad" }), + makeRow({ region: "ams" }), + ]; + const summary = computeCdnSummary(rows); + expect(summary.topology).toBe("anycast"); + expect(summary.topologyBasis).toBe("provider"); + }); + + test("empty input", () => { + const summary = computeCdnSummary([]); + expect(summary.totalRegions).toBe(0); + expect(summary.cachedRegions).toBe(0); + expect(summary.cdn).toBeNull(); + }); +}); diff --git a/apps/web/src/lib/cdn-checker/summary.ts b/apps/web/src/lib/cdn-checker/summary.ts new file mode 100644 index 00000000..e86a5724 --- /dev/null +++ b/apps/web/src/lib/cdn-checker/summary.ts @@ -0,0 +1,44 @@ +import { type CdnProvider, inferTopology } from "@openstatus/header-analysis"; + +import type { CdnRegionResponse, CdnSummary } from "./schema"; + +// STALE counts as cached: the response was served from the edge cache +// (stale-while-revalidate), not from origin +const CACHED_STATUSES = new Set(["HIT", "STALE"]); + +export function computeCdnSummary(rows: CdnRegionResponse[]): CdnSummary { + const responded = rows.filter((row) => row.state === "success"); + const unreachable = rows.filter((row) => row.state === "error"); + + const cached = responded.filter((row) => + CACHED_STATUSES.has(row.cacheStatus), + ); + const uncached = responded.filter( + (row) => !CACHED_STATUSES.has(row.cacheStatus), + ); + + const providerCounts = new Map(); + for (const row of responded) { + if (!row.cdn) continue; + providerCounts.set(row.cdn, (providerCounts.get(row.cdn) ?? 0) + 1); + } + const ranked = [...providerCounts.entries()].sort((a, b) => b[1] - a[1]); + // a tie means no true majority: report null instead of an arbitrary winner + const hasTie = ranked.length > 1 && ranked[0][1] === ranked[1][1]; + const cdn = ranked[0] && !hasTie ? ranked[0][0] : null; + + const topology = inferTopology(responded, cdn); + + return { + type: "summary", + totalRegions: rows.length, + respondedRegions: responded.length, + cachedRegions: cached.length, + uncachedRegions: uncached.map((row) => row.region), + unreachableRegions: unreachable.map((row) => row.region), + cdn, + mixedCdn: providerCounts.size > 1, + topology: topology.topology, + topologyBasis: topology.basis, + }; +} diff --git a/apps/web/src/lib/checker/utils.ts b/apps/web/src/lib/checker/utils.ts index 8b3eed94..72ca2ff7 100644 --- a/apps/web/src/lib/checker/utils.ts +++ b/apps/web/src/lib/checker/utils.ts @@ -175,6 +175,7 @@ type CheckRegionRequest = { method?: Method; headers?: { value: string; key: string }[]; body?: string; + signal?: AbortSignal; }; // ============================================================================ @@ -184,7 +185,7 @@ type CheckRegionRequest = { export async function checkRegion( props: CheckRegionRequest, ): Promise { - const { url, region, method, headers, body } = props; + const { url, region, method, headers, body, signal } = props; const regionInfo = regionDict[region]; let endpoint = ""; @@ -227,6 +228,7 @@ export async function checkRegion( ), body: body ? body : undefined, }), + signal, next: { revalidate: 0 }, }); diff --git a/packages/analytics/src/events.ts b/packages/analytics/src/events.ts index e28573eb..220b61b9 100644 --- a/packages/analytics/src/events.ts +++ b/packages/analytics/src/events.ts @@ -204,4 +204,8 @@ export const Events = { name: "mcp_health_check", channel: "checker", }, + CdnChecker: { + name: "cdn_checker", + channel: "checker", + }, } as const satisfies Record; diff --git a/packages/header-analysis/src/cdn/detect-cdn.test.ts b/packages/header-analysis/src/cdn/detect-cdn.test.ts new file mode 100644 index 00000000..7d7def9e --- /dev/null +++ b/packages/header-analysis/src/cdn/detect-cdn.test.ts @@ -0,0 +1,108 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { detectCdn } from "./detect-cdn"; + +describe("detectCdn", () => { + test("cloudflare via cf-ray", () => { + const result = detectCdn({ + "Cf-Ray": "8c9a1b2c3d4e5f6a-FRA", + Server: "cloudflare", + }); + expect(result.provider).toBe("cloudflare"); + expect(result.evidence).toContain("cf-ray"); + }); + + test("cloudfront via x-amz-cf-id", () => { + const result = detectCdn({ + "X-Amz-Cf-Id": "abc123", + "X-Amz-Cf-Pop": "FRA56-P5", + Via: "1.1 abc.cloudfront.net (CloudFront)", + }); + expect(result.provider).toBe("cloudfront"); + }); + + test("fastly via x-served-by corroborated by x-cache", () => { + const result = detectCdn({ + "X-Served-By": "cache-fra-etou8220141-FRA", + "X-Cache": "HIT", + }); + expect(result.provider).toBe("fastly"); + }); + + test("fastly via x-fastly-request-id alone", () => { + const result = detectCdn({ "X-Fastly-Request-Id": "abc123" }); + expect(result.provider).toBe("fastly"); + }); + + test("bare `x-served-by: cache-` is not fastly (generic varnish prefix)", () => { + const result = detectCdn({ "X-Served-By": "cache-mia-kmia1234-MIA" }); + expect(result.provider).toBeNull(); + expect(result.evidence).toEqual([]); + }); + + test("bare `x-cache` is not fastly (shared cache header)", () => { + const result = detectCdn({ "X-Cache": "HIT" }); + expect(result.provider).toBeNull(); + expect(result.evidence).toEqual([]); + }); + + test("akamai via x-check-cacheable", () => { + const result = detectCdn({ + "X-Check-Cacheable": "YES", + "X-Cache": "TCP_HIT", + }); + expect(result.provider).toBe("akamai"); + }); + + test("vercel via x-vercel-id", () => { + const result = detectCdn({ + "X-Vercel-Id": "fra1::82mqm-1724415466843-d608bd28fa1c", + Server: "Vercel", + }); + expect(result.provider).toBe("vercel"); + }); + + test("bunny via server header", () => { + const result = detectCdn({ Server: "BunnyCDN-DE1-1042" }); + expect(result.provider).toBe("bunny"); + }); + + test("netlify via x-nf-request-id", () => { + const result = detectCdn({ "X-Nf-Request-Id": "abc" }); + expect(result.provider).toBe("netlify"); + }); + + test("google cloud cdn: via corroborated by x-goog-cache-status", () => { + const result = detectCdn({ + Via: "1.1 google", + "X-Goog-Cache-Status": "hit", + }); + expect(result.provider).toBe("google"); + expect(result.evidence).toContain("x-goog-cache-status"); + }); + + test("bare `via: 1.1 google` is not a CDN (load balancer / translate proxy)", () => { + const result = detectCdn({ Via: "1.1 google" }); + expect(result.provider).toBeNull(); + expect(result.evidence).toEqual([]); + }); + + test("outermost proxy wins when stacked (cloudflare in front of vercel)", () => { + const result = detectCdn({ + "Cf-Ray": "8c9a1b2c3d4e5f6a-FRA", + "X-Vercel-Id": "fra1::82mqm", + "X-Vercel-Cache": "HIT", + }); + expect(result.provider).toBe("cloudflare"); + }); + + test("no CDN headers -> null", () => { + const result = detectCdn({ + "Content-Type": "text/html", + Server: "nginx/1.25", + }); + expect(result.provider).toBeNull(); + expect(result.evidence).toEqual([]); + }); +}); diff --git a/packages/header-analysis/src/cdn/detect-cdn.ts b/packages/header-analysis/src/cdn/detect-cdn.ts new file mode 100644 index 00000000..383874a9 --- /dev/null +++ b/packages/header-analysis/src/cdn/detect-cdn.ts @@ -0,0 +1,166 @@ +import { getHeader } from "./get-header"; + +export const CDN_PROVIDERS = [ + "cloudflare", + "cloudfront", + "fastly", + "akamai", + "vercel", + "bunny", + "netlify", + "keycdn", + "imperva", + "sucuri", + "azure-front-door", + "google", +] as const; + +export type CdnProvider = (typeof CDN_PROVIDERS)[number]; + +export const CDN_LABELS: Record = { + cloudflare: "Cloudflare", + cloudfront: "Amazon CloudFront", + fastly: "Fastly", + akamai: "Akamai", + vercel: "Vercel", + bunny: "Bunny CDN", + netlify: "Netlify", + keycdn: "KeyCDN", + imperva: "Imperva", + sucuri: "Sucuri", + "azure-front-door": "Azure Front Door", + google: "Google Cloud CDN", +}; + +export interface CdnDetection { + provider: CdnProvider | null; + /** header names (or `header: value` pairs) that matched */ + evidence: string[]; +} + +type Fingerprint = { + provider: CdnProvider; + headers?: string[]; + /** presence-only signals too generic to be strong (e.g. `x-cache`) */ + broadHeaders?: string[]; + /** substring match against the given header's value (lowercased) */ + contains?: { + header: string; + value: string; + /** + * broad signal shared with non-CDN infra (e.g. `via: 1.1 google` is also + * sent by Google's load balancer/translate proxy): never matches on its + * own — needs a strong signal or a second broad signal to corroborate + */ + broad?: boolean; + }[]; +}; + +// ordered outermost-proxy first: when stacked (e.g. Cloudflare in front of +// Vercel) the first match is the network that actually served the client +const FINGERPRINTS: Fingerprint[] = [ + { + provider: "cloudflare", + headers: ["cf-ray", "cf-cache-status"], + contains: [{ header: "server", value: "cloudflare" }], + }, + { + provider: "akamai", + headers: [ + "x-akamai-request-id", + "x-akamai-transformed", + "x-check-cacheable", + ], + contains: [{ header: "server", value: "akamaighost" }], + }, + { + provider: "imperva", + headers: ["x-iinfo"], + contains: [{ header: "x-cdn", value: "incapsula" }], + }, + { + provider: "sucuri", + headers: ["x-sucuri-id", "x-sucuri-cache"], + }, + { + provider: "fastly", + headers: ["x-fastly-request-id", "fastly-debug-digest"], + // `x-served-by: cache-` is a generic Varnish prefix and `x-cache`/`x-timer` + // are shared cache headers: any one alone must not claim Fastly + broadHeaders: ["x-cache", "x-timer"], + contains: [ + { header: "x-served-by", value: "cache-", broad: true }, + { header: "via", value: "fastly" }, + ], + }, + { + provider: "cloudfront", + headers: ["x-amz-cf-id", "x-amz-cf-pop"], + contains: [{ header: "via", value: "cloudfront" }], + }, + { + provider: "bunny", + headers: ["cdn-pullzone", "cdn-requestid"], + contains: [{ header: "server", value: "bunnycdn" }], + }, + { + provider: "keycdn", + contains: [{ header: "server", value: "keycdn" }], + }, + { + provider: "azure-front-door", + headers: ["x-azure-ref"], + }, + { + provider: "google", + headers: ["x-goog-cache-status", "x-google-cache-control"], + contains: [{ header: "via", value: "1.1 google", broad: true }], + }, + { + provider: "netlify", + headers: ["x-nf-request-id"], + contains: [{ header: "server", value: "netlify" }], + }, + { + provider: "vercel", + headers: ["x-vercel-id", "x-vercel-cache"], + contains: [{ header: "server", value: "vercel" }], + }, +]; + +export function detectCdn(headers: Record): CdnDetection { + for (const fingerprint of FINGERPRINTS) { + const evidence: string[] = []; + // a single broad signal (e.g. `via: 1.1 google`, `x-served-by: cache-`) + // can't match alone — require a strong signal or two broad ones agreeing + let strongMatches = 0; + let broadMatches = 0; + + for (const name of fingerprint.headers ?? []) { + if (getHeader(headers, name)) { + evidence.push(name); + strongMatches++; + } + } + for (const name of fingerprint.broadHeaders ?? []) { + if (getHeader(headers, name)) { + evidence.push(name); + broadMatches++; + } + } + for (const { header, value, broad } of fingerprint.contains ?? []) { + const actual = getHeader(headers, header); + if (actual?.toLowerCase().includes(value)) { + evidence.push(`${header}: ${actual}`); + if (broad) broadMatches++; + else strongMatches++; + } + } + + if (strongMatches > 0 || broadMatches >= 2) { + return { provider: fingerprint.provider, evidence }; + } + } + + return { provider: null, evidence: [] }; +} diff --git a/packages/header-analysis/src/cdn/edge-pop.test.ts b/packages/header-analysis/src/cdn/edge-pop.test.ts new file mode 100644 index 00000000..bbec53c1 --- /dev/null +++ b/packages/header-analysis/src/cdn/edge-pop.test.ts @@ -0,0 +1,56 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { extractEdgePop } from "./edge-pop"; + +describe("extractEdgePop", () => { + test("cloudflare colo from cf-ray", () => { + const result = extractEdgePop( + { "Cf-Ray": "8c9a1b2c3d4e5f6a-FRA" }, + "cloudflare", + ); + expect(result.pop).toBe("FRA"); + expect(result.location).toContain("Frankfurt"); + }); + + test("cloudfront pop from x-amz-cf-pop", () => { + const result = extractEdgePop({ "X-Amz-Cf-Pop": "FRA56-P5" }, "cloudfront"); + expect(result.pop).toBe("FRA56-P5"); + expect(result.location).toContain("Frankfurt"); + }); + + test("fastly pop from x-served-by", () => { + const result = extractEdgePop( + { "X-Served-By": "cache-fra-etou8220141-FRA" }, + "fastly", + ); + expect(result.pop).toBe("FRA"); + expect(result.location).toContain("Frankfurt"); + }); + + test("vercel edge from x-vercel-id first segment", () => { + const result = extractEdgePop( + { "X-Vercel-Id": "fra1::iad1::82mqm-1724415466843-d608bd28fa1c" }, + "vercel", + ); + expect(result.pop).toBe("fra1"); + expect(result.location).toContain("Frankfurt"); + }); + + test("vercel pops resolve via the vercel region map (not IATA)", () => { + const result = extractEdgePop({ "X-Vercel-Id": "cle1::abc" }, "vercel"); + expect(result.pop).toBe("cle1"); + expect(result.location).toContain("Cleveland"); + }); + + test("unknown provider -> null", () => { + const result = extractEdgePop({ "X-Cache": "HIT" }, null); + expect(result.pop).toBeNull(); + expect(result.location).toBeNull(); + }); + + test("missing header -> null", () => { + const result = extractEdgePop({}, "cloudflare"); + expect(result.pop).toBeNull(); + }); +}); diff --git a/packages/header-analysis/src/cdn/edge-pop.ts b/packages/header-analysis/src/cdn/edge-pop.ts new file mode 100644 index 00000000..f818be0f --- /dev/null +++ b/packages/header-analysis/src/cdn/edge-pop.ts @@ -0,0 +1,68 @@ +import { parseCfRay } from "../parser/cf-ray"; +import { regions as iataRegions } from "../regions/cloudflare"; +import { regions as vercelRegions } from "../regions/vercel"; +import type { CdnProvider } from "./detect-cdn"; +import { getHeader } from "./get-header"; + +export interface EdgePop { + /** PoP/colo code, e.g. "FRA" or "fra1" */ + pop: string | null; + /** best-effort city name resolved from the IATA code */ + location: string | null; +} + +// the cloudflare map is keyed by IATA airport codes, so it doubles as a +// generic IATA → city lookup for other vendors' PoP codes +function lookupIata(code: string): string | null { + return iataRegions[code.toUpperCase()]?.location ?? null; +} + +export function extractEdgePop( + headers: Record, + provider: CdnProvider | null, +): EdgePop { + switch (provider) { + case "cloudflare": { + const ray = getHeader(headers, "cf-ray"); + if (!ray) break; + const parsed = parseCfRay(ray); + if (parsed.status === "success") { + return { pop: parsed.data.code, location: parsed.data.location }; + } + const code = ray.match(/\b([A-Z]{3})\b/)?.[1]; + if (code) return { pop: code, location: lookupIata(code) }; + break; + } + case "cloudfront": { + // e.g. "FRA56-P5" — leading 3 letters are the IATA code + const pop = getHeader(headers, "x-amz-cf-pop"); + const code = pop?.match(/^([A-Z]{3})/)?.[1]; + if (pop && code) return { pop, location: lookupIata(code) }; + break; + } + case "fastly": { + // e.g. "cache-fra-etou8220141-FRA" — trailing segment is the IATA code + const servedBy = getHeader(headers, "x-served-by"); + const code = servedBy?.match(/-([A-Z]{3})$/)?.[1]; + if (code) return { pop: code, location: lookupIata(code) }; + break; + } + case "vercel": { + // e.g. "fra1::iad1::82mqm-..." — first segment is the serving edge + const id = getHeader(headers, "x-vercel-id"); + const pop = id?.match(/^([a-z]{3}\d*)/)?.[1]; + if (pop) { + const known = vercelRegions[pop]; + return { + pop, + location: known?.location ?? lookupIata(pop.slice(0, 3)), + }; + } + break; + } + default: + break; + } + + return { pop: null, location: null }; +} diff --git a/packages/header-analysis/src/cdn/get-header.ts b/packages/header-analysis/src/cdn/get-header.ts new file mode 100644 index 00000000..df118695 --- /dev/null +++ b/packages/header-analysis/src/cdn/get-header.ts @@ -0,0 +1,11 @@ +// Header keys arrive in mixed casing (Go canonicalizes, fetch lowercases). +export function getHeader( + headers: Record, + name: string, +): string | null { + const lower = name.toLowerCase(); + for (const [key, value] of Object.entries(headers)) { + if (key.toLowerCase() === lower) return value; + } + return null; +} diff --git a/packages/header-analysis/src/cdn/infer-topology.test.ts b/packages/header-analysis/src/cdn/infer-topology.test.ts new file mode 100644 index 00000000..05eeb786 --- /dev/null +++ b/packages/header-analysis/src/cdn/infer-topology.test.ts @@ -0,0 +1,68 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { inferTopology } from "./infer-topology"; + +describe("inferTopology", () => { + test("same IP from many regions -> anycast (measured)", () => { + const rows = [ + { edgeIp: "104.16.0.1" }, + { edgeIp: "104.16.0.1" }, + { edgeIp: "104.16.0.1" }, + ]; + expect(inferTopology(rows, null)).toEqual({ + topology: "anycast", + basis: "edge-ips", + }); + }); + + test("different IPs -> unicast (measured)", () => { + const rows = [{ edgeIp: "1.2.3.4" }, { edgeIp: "5.6.7.8" }]; + expect(inferTopology(rows, null)).toEqual({ + topology: "unicast", + basis: "edge-ips", + }); + }); + + test("single IP but too few vantage points -> falls through", () => { + const rows = [{ edgeIp: "1.2.3.4" }, { edgeIp: null }]; + expect(inferTopology(rows, null).topology).toBe("unknown"); + }); + + test("null-IP rows are not vantage points", () => { + const rows = [ + { edgeIp: "1.2.3.4" }, + { edgeIp: null }, + { edgeIp: null }, + { edgeIp: null }, + ]; + expect(inferTopology(rows, null)).toEqual({ + topology: "unknown", + basis: null, + }); + }); + + test("no IPs, known-anycast provider -> provider heuristic", () => { + const rows = [{ edgeIp: null }, { edgeIp: null }]; + expect(inferTopology(rows, "cloudflare")).toEqual({ + topology: "anycast", + basis: "provider", + }); + expect(inferTopology(rows, "cloudfront")).toEqual({ + topology: "unicast", + basis: "provider", + }); + }); + + test("no IPs, unknown provider -> unknown", () => { + expect(inferTopology([{ edgeIp: null }], null)).toEqual({ + topology: "unknown", + basis: null, + }); + }); + + test("measured IPs win over provider heuristic", () => { + const rows = [{ edgeIp: "1.2.3.4" }, { edgeIp: "5.6.7.8" }]; + expect(inferTopology(rows, "cloudflare").topology).toBe("unicast"); + }); +}); diff --git a/packages/header-analysis/src/cdn/infer-topology.ts b/packages/header-analysis/src/cdn/infer-topology.ts new file mode 100644 index 00000000..a0194e61 --- /dev/null +++ b/packages/header-analysis/src/cdn/infer-topology.ts @@ -0,0 +1,41 @@ +import type { CdnProvider } from "./detect-cdn"; + +export type Topology = "anycast" | "unicast" | "unknown"; + +export interface TopologyInference { + topology: Topology; + /** "edge-ips" is measured; "provider" is a known-architecture heuristic */ + basis: "edge-ips" | "provider" | null; +} + +// networks with a publicly documented anycast (or geo-routed) architecture — +// used only when edge IPs are unavailable +const PROVIDER_TOPOLOGY: Partial> = { + cloudflare: "anycast", + fastly: "anycast", + vercel: "anycast", + cloudfront: "unicast", + akamai: "unicast", +}; + +export function inferTopology( + rows: { edgeIp: string | null }[], + provider: CdnProvider | null, +): TopologyInference { + const measured = rows + .map((row) => row.edgeIp) + .filter((ip): ip is string => Boolean(ip)); + const ips = new Set(measured); + + if (ips.size >= 2) return { topology: "unicast", basis: "edge-ips" }; + // a single IP only signals anycast with enough measured vantage points — + // rows without an edge IP are not evidence + if (ips.size === 1 && measured.length >= 3) { + return { topology: "anycast", basis: "edge-ips" }; + } + + const fromProvider = provider ? PROVIDER_TOPOLOGY[provider] : undefined; + if (fromProvider) return { topology: fromProvider, basis: "provider" }; + + return { topology: "unknown", basis: null }; +} diff --git a/packages/header-analysis/src/cdn/normalize-cache-status.test.ts b/packages/header-analysis/src/cdn/normalize-cache-status.test.ts new file mode 100644 index 00000000..1e736d9e --- /dev/null +++ b/packages/header-analysis/src/cdn/normalize-cache-status.test.ts @@ -0,0 +1,140 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { normalizeCacheStatus } from "./normalize-cache-status"; + +describe("cloudflare", () => { + for (const [raw, status] of [ + ["HIT", "HIT"], + ["MISS", "MISS"], + ["EXPIRED", "EXPIRED"], + ["STALE", "STALE"], + ["UPDATING", "STALE"], + ["REVALIDATED", "HIT"], + ["BYPASS", "BYPASS"], + ["DYNAMIC", "DYNAMIC"], + ] as const) { + test(`cf-cache-status: ${raw} -> ${status}`, () => { + const result = normalizeCacheStatus({ "Cf-Cache-Status": raw }); + expect(result.status).toBe(status); + expect(result.source).toBe("cf-cache-status"); + expect(result.raw).toBe(raw); + }); + } +}); + +describe("vercel", () => { + for (const [raw, status] of [ + ["HIT", "HIT"], + ["MISS", "MISS"], + ["STALE", "STALE"], + ["PRERENDER", "HIT"], + ["REVALIDATED", "HIT"], + ["BYPASS", "BYPASS"], + ] as const) { + test(`x-vercel-cache: ${raw} -> ${status}`, () => { + const result = normalizeCacheStatus({ "X-Vercel-Cache": raw }); + expect(result.status).toBe(status); + expect(result.source).toBe("x-vercel-cache"); + }); + } +}); + +describe("cloudfront / fastly / akamai (x-cache)", () => { + for (const [raw, status] of [ + ["Hit from cloudfront", "HIT"], + ["Miss from cloudfront", "MISS"], + ["RefreshHit from cloudfront", "EXPIRED"], + ["HIT", "HIT"], + ["MISS, HIT", "HIT"], + [ + "TCP_HIT from a23-45-67-89.deploy.akamaitechnologies.com (AkamaiGHost)", + "HIT", + ], + ["TCP_MEM_HIT", "HIT"], + ["TCP_MISS", "MISS"], + ["TCP_REFRESH_HIT", "EXPIRED"], + ["TCP_EXPIRED_MISS", "EXPIRED"], + ] as const) { + test(`x-cache: ${raw} -> ${status}`, () => { + const result = normalizeCacheStatus({ "X-Cache": raw }); + expect(result.status).toBe(status); + expect(result.source).toBe("x-cache"); + }); + } +}); + +describe("rfc 9211 cache-status", () => { + for (const [raw, status] of [ + ['"Netlify Edge"; hit', "HIT"], + ["ExampleCache; fwd=miss; stored", "MISS"], + ["ExampleCache; fwd=stale", "EXPIRED"], + ["ExampleCache; fwd=bypass", "BYPASS"], + ] as const) { + test(`cache-status: ${raw} -> ${status}`, () => { + const result = normalizeCacheStatus({ "Cache-Status": raw }); + expect(result.status).toBe(status); + expect(result.source).toBe("cache-status"); + }); + } +}); + +describe("vendor header priority", () => { + test("cf-cache-status wins over x-cache", () => { + const result = normalizeCacheStatus({ + "Cf-Cache-Status": "HIT", + "X-Cache": "MISS", + }); + expect(result.status).toBe("HIT"); + expect(result.source).toBe("cf-cache-status"); + }); +}); + +describe("generic fallback", () => { + test("age > 0 with cacheable cache-control -> HIT", () => { + const result = normalizeCacheStatus({ + Age: "842", + "Cache-Control": "public, max-age=3600", + }); + expect(result.status).toBe("HIT"); + expect(result.source).toBe("age"); + }); + + test("no-store -> DYNAMIC", () => { + const result = normalizeCacheStatus({ + "Cache-Control": "private, no-cache, no-store, max-age=0", + }); + expect(result.status).toBe("DYNAMIC"); + expect(result.source).toBe("cache-control"); + }); + + test("mixed-case directives are matched (RFC 9111)", () => { + const result = normalizeCacheStatus({ + "Cache-Control": "Private, No-Store", + }); + expect(result.status).toBe("DYNAMIC"); + }); + + test("age 0 with cacheable cache-control -> UNKNOWN", () => { + const result = normalizeCacheStatus({ + Age: "0", + "Cache-Control": "public, max-age=3600", + }); + expect(result.status).toBe("UNKNOWN"); + }); + + test("no caching headers at all -> UNKNOWN", () => { + const result = normalizeCacheStatus({ + "Content-Type": "text/html", + Server: "nginx", + }); + expect(result.status).toBe("UNKNOWN"); + expect(result.raw).toBeNull(); + expect(result.source).toBeNull(); + }); + + test("lowercase header keys are matched", () => { + const result = normalizeCacheStatus({ "cf-cache-status": "HIT" }); + expect(result.status).toBe("HIT"); + }); +}); diff --git a/packages/header-analysis/src/cdn/normalize-cache-status.ts b/packages/header-analysis/src/cdn/normalize-cache-status.ts new file mode 100644 index 00000000..54a5c923 --- /dev/null +++ b/packages/header-analysis/src/cdn/normalize-cache-status.ts @@ -0,0 +1,91 @@ +import { parseCacheControlHeader } from "../parser/cache-control"; +import { getHeader } from "./get-header"; + +export const CACHE_STATUSES = [ + "HIT", + "MISS", + "EXPIRED", + "STALE", + "BYPASS", + "DYNAMIC", + "UNKNOWN", +] as const; + +export type CacheStatus = (typeof CACHE_STATUSES)[number]; + +export interface NormalizedCacheStatus { + status: CacheStatus; + /** original header value, e.g. "Hit from cloudfront" */ + raw: string | null; + /** header name that determined the status, e.g. "cf-cache-status" */ + source: string | null; +} + +function fromToken(value: string): CacheStatus | null { + const token = value.toUpperCase(); + // order matters: "REFRESH_HIT" and "EXPIRED_MISS" must not match plain HIT/MISS + if (token.includes("STALE")) return "STALE"; + if (token.includes("UPDATING")) return "STALE"; + if (token.includes("EXPIRED")) return "EXPIRED"; + if (token.includes("REFRESH")) return "EXPIRED"; + if (token.includes("REVALIDATED")) return "HIT"; + if (token.includes("PRERENDER")) return "HIT"; + if (token.includes("BYPASS")) return "BYPASS"; + if (token.includes("DYNAMIC")) return "DYNAMIC"; + if (token.includes("HIT")) return "HIT"; + if (token.includes("MISS")) return "MISS"; + if (token.includes("PASS")) return "BYPASS"; + return null; +} + +// RFC 9211, e.g. `"Netlify Edge"; hit` or `ExampleCache; fwd=miss; stored` +function fromCacheStatusHeader(value: string): CacheStatus | null { + const lower = value.toLowerCase(); + if (/;\s*hit/.test(lower)) return "HIT"; + const fwd = lower.match(/fwd=([a-z-]+)/)?.[1]; + if (!fwd) return null; + if (fwd === "bypass") return "BYPASS"; + if (fwd === "stale") return "EXPIRED"; + return "MISS"; +} + +const VENDOR_HEADERS = [ + "cf-cache-status", + "x-vercel-cache", + "cache-status", + "x-cache", + "x-cache-status", + "cdn-cache", + "x-cache-lookup", +] as const; + +export function normalizeCacheStatus( + headers: Record, +): NormalizedCacheStatus { + for (const name of VENDOR_HEADERS) { + const value = getHeader(headers, name); + if (!value) continue; + const status = + name === "cache-status" ? fromCacheStatusHeader(value) : fromToken(value); + if (status) return { status, raw: value, source: name }; + } + + // no vendor header: infer from standard caching headers + const age = getHeader(headers, "age"); + const cacheControl = getHeader(headers, "cache-control"); + + if (cacheControl) { + const directives = parseCacheControlHeader(cacheControl); + // directive names are case-insensitive per RFC 9111 + const has = (name: string) => + directives.some((d) => d.name.toLowerCase() === name); + if (has("no-store") || has("private")) { + return { status: "DYNAMIC", raw: cacheControl, source: "cache-control" }; + } + if (age && Number.parseInt(age, 10) > 0) { + return { status: "HIT", raw: age, source: "age" }; + } + } + + return { status: "UNKNOWN", raw: null, source: null }; +} diff --git a/packages/header-analysis/src/index.ts b/packages/header-analysis/src/index.ts index 31f6cd60..e4023189 100644 --- a/packages/header-analysis/src/index.ts +++ b/packages/header-analysis/src/index.ts @@ -4,3 +4,8 @@ export * from "./parser/cf-ray"; export * from "./parser/fly-request-id"; export * from "./parser/x-vercel-cache"; export * from "./parser/x-vercel-id"; +export * from "./cdn/detect-cdn"; +export * from "./cdn/edge-pop"; +export * from "./cdn/get-header"; +export * from "./cdn/infer-topology"; +export * from "./cdn/normalize-cache-status"; -- 2.51.2 From 827f59ed3c9c9a01c4761272e48ff0a8472608eb Mon Sep 17 00:00:00 2001 From: Maximilian Kaske Date: Sun, 5 Jul 2026 20:28:48 +0200 Subject: [PATCH 27/69] chore: minor stuff --- .../[id]/status-reports/[reportId]/page.tsx | 38 ++++++--------- .../status-report-updates/data-table.tsx | 47 +++++++++---------- .../components/forms/components/update.tsx | 28 +++++------ .../components/forms/monitor/form-general.tsx | 3 +- .../src/data/status-report-updates.client.ts | 44 +++++++++++++++++ packages/api/src/router/page.ts | 15 +++--- 6 files changed, 102 insertions(+), 73 deletions(-) diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx index 3e24d35b..fe4410e0 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx @@ -27,8 +27,10 @@ import { } from "@/components/forms/status-report-update/form-status-report"; import { FormSheetStatusReportUpdate } from "@/components/forms/status-report-update/sheet"; import { + defaultComponentImpacts, getNextStatus, impactsEqual, + toCreateStatusReportUpdateInput, } from "@/data/status-report-updates.client"; import { useTRPC } from "@/lib/trpc/client"; @@ -104,36 +106,24 @@ export default function Page() { ({ - pageComponentId: c.id, - impact: - nextStatus === "resolved" - ? "operational" - : (currentImpacts.get(c.id) ?? "operational"), - })), + componentImpacts: defaultComponentImpacts({ + components: statusReport.pageComponents, + currentImpacts, + nextStatus, + }), }} components={statusReport.pageComponents.map((c) => ({ id: c.id, name: c.name, }))} onSubmit={async (values: FormValues) => { - // a legacy report stays legacy unless the operator actively - // sets a non-operational impact — never silently flip it green - const sendImpacts = - reportHasImpacts || - values.componentImpacts?.some( - (ci) => ci.impact !== "operational", - ); - await createStatusReportUpdateMutation.mutateAsync({ - statusReportId: statusReport.id, - message: values.message, - status: values.status, - componentImpacts: sendImpacts - ? values.componentImpacts - : undefined, - date: values.date, - notifySubscribers: values.notifySubscribers, - }); + await createStatusReportUpdateMutation.mutateAsync( + toCreateStatusReportUpdateInput({ + statusReportId: statusReport.id, + values, + reportHasImpacts, + }), + ); }} > + + + + + + + maintenanceButtonRef.current?.click()} + > + + Create Maintenance + + + + + + + +
+ ); +} diff --git a/apps/dashboard/src/app/(dashboard)/overview/data-table-status-reports.tsx b/apps/dashboard/src/app/(dashboard)/overview/data-table-status-reports.tsx deleted file mode 100644 index 3e21a7b1..00000000 --- a/apps/dashboard/src/app/(dashboard)/overview/data-table-status-reports.tsx +++ /dev/null @@ -1,31 +0,0 @@ -"use client"; - -import type { RouterOutputs } from "@openstatus/api"; - -import { DataTable as UpdatesDataTable } from "@/components/data-table/status-report-updates/data-table"; -import { columns as statusReportsColumns } from "@/components/data-table/status-reports/columns"; -import { DataTable } from "@/components/ui/data-table/data-table"; - -type StatusReport = RouterOutputs["statusReport"]["list"][number]; - -export function DataTableStatusReports({ - statusReports, -}: { - statusReports: StatusReport[]; -}) { - return ( - - row.getCanExpand() ? row.toggleExpanded() : undefined - } - rowComponent={({ row }) => ( - - )} - /> - ); -} diff --git a/apps/dashboard/src/app/(dashboard)/overview/layout.tsx b/apps/dashboard/src/app/(dashboard)/overview/layout.tsx index b205d9c8..5c7e0e83 100644 --- a/apps/dashboard/src/app/(dashboard)/overview/layout.tsx +++ b/apps/dashboard/src/app/(dashboard)/overview/layout.tsx @@ -18,21 +18,10 @@ export default async function Layout({ await queryClient.prefetchQuery(trpc.monitor.list.queryOptions()); await queryClient.prefetchQuery(trpc.page.list.queryOptions()); - await queryClient.prefetchQuery( - trpc.incident.list.queryOptions({ - period: "7d", - }), - ); - await queryClient.prefetchQuery( - trpc.statusReport.list.queryOptions({ - period: "7d", - }), - ); - await queryClient.prefetchQuery( - trpc.maintenance.list.queryOptions({ - period: "7d", - }), - ); + // inputs must match page.tsx's queries exactly — a differing input misses the cache + await queryClient.prefetchQuery(trpc.incident.list.queryOptions()); + await queryClient.prefetchQuery(trpc.statusReport.list.queryOptions({})); + await queryClient.prefetchQuery(trpc.maintenance.list.queryOptions()); return ( diff --git a/apps/dashboard/src/app/(dashboard)/overview/page.tsx b/apps/dashboard/src/app/(dashboard)/overview/page.tsx index 8bf22cc3..dd9ac4f0 100644 --- a/apps/dashboard/src/app/(dashboard)/overview/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/overview/page.tsx @@ -1,11 +1,11 @@ "use client"; import { useQuery } from "@tanstack/react-query"; -import { formatDistanceToNowStrict } from "date-fns"; -import { Bot, List, Search } from "lucide-react"; +import { Bot } from "lucide-react"; import Link from "next/link"; -import { Note, NoteButton } from "@/components/common/note"; +import { NoteButton } from "@/components/common/note"; +import { NoteDismissible } from "@/components/common/note-dismissible"; import { EmptyStateContainer, EmptyStateTitle, @@ -14,146 +14,72 @@ import { SectionDescription, SectionGroup, SectionHeader, + SectionHeaderRow, SectionTitle, } from "@/components/content/section"; import { Section } from "@/components/content/section"; -import { columns as incidentsColumns } from "@/components/data-table/incidents/columns"; -import { columns as maintenancesColumns } from "@/components/data-table/maintenances/columns"; +import { columns } from "@/components/data-table/overview-events/columns"; import { MetricCard, MetricCardGroup, MetricCardHeader, + MetricCardLink, MetricCardTitle, MetricCardValue, } from "@/components/metric/metric-card"; import { DataTable } from "@/components/ui/data-table/data-table"; +import { buildOverviewData } from "@/data/overview-events.client"; import { useTRPC } from "@/lib/trpc/client"; -import { cn } from "@/lib/utils"; -import { DataTableStatusReports } from "./data-table-status-reports"; - -// FIXME: the page is server side -// whenever I change the maintenances, the page is not updated -// we need to move the queryClient to the layout and prefetch the data there +import { CreateEventButtonGroup } from "./create-event-button-group"; export default function Page() { const trpc = useTRPC(); const { data: monitors } = useQuery(trpc.monitor.list.queryOptions()); const { data: pages } = useQuery(trpc.page.list.queryOptions()); - const { data: incidents } = useQuery( - trpc.incident.list.queryOptions({ - period: "7d", - }), - ); + // no period — an incident open for weeks must still surface here + const { data: incidents } = useQuery(trpc.incident.list.queryOptions()); const { data: statusReports } = useQuery( - trpc.statusReport.list.queryOptions({ - period: "7d", - }), - ); - const { data: maintenances } = useQuery( - trpc.maintenance.list.queryOptions({ - period: "7d", - }), + trpc.statusReport.list.queryOptions({}), ); + const { data: maintenances } = useQuery(trpc.maintenance.list.queryOptions()); if (!monitors || !pages || !incidents || !statusReports || !maintenances) return null; - const lastIncident = incidents.length > 0 ? incidents[0] : null; - const lastStatusReport = statusReports.length > 0 ? statusReports[0] : null; - const lastMaintenance = maintenances.length > 0 ? maintenances[0] : null; - - const incidentDistance = lastIncident - ? formatDistanceToNowStrict(lastIncident.startedAt, { - addSuffix: true, - }) - : "None"; - - const statusReportDistance = lastStatusReport?.createdAt - ? formatDistanceToNowStrict(lastStatusReport.createdAt, { - addSuffix: true, - }) - : "None"; - - const maintenanceDistance = lastMaintenance?.createdAt - ? formatDistanceToNowStrict(lastMaintenance.createdAt, { - addSuffix: true, - }) - : "None"; - - const metrics = [ - { - title: "Monitors", - value: monitors.length, - href: "/monitors", - variant: "default" as const, - icon: List, - }, - { - title: "Status Pages", - value: pages.length, - href: "/status-pages", - variant: "default" as const, - icon: List, - }, - { - title: - lastIncident?.resolvedAt === undefined && lastIncident - ? "Active Incident" - : "Recent Incident", - value: incidentDistance, - disabled: !lastIncident?.monitorId, - href: `/monitors/${lastIncident?.monitorId}/incidents`, - variant: - lastIncident?.resolvedAt === undefined && lastIncident - ? ("warning" as const) - : ("default" as const), - icon: Search, - }, - { - title: "Last Report", - value: statusReportDistance, - disabled: !lastStatusReport?.pageId, - href: `/status-pages/${lastStatusReport?.pageId}/status-reports`, - variant: "default" as const, - icon: Search, - }, - { - title: "Last Maintenance", - value: maintenanceDistance, - disabled: !lastMaintenance?.pageId, - href: `/status-pages/${lastMaintenance?.pageId}/maintenances`, - variant: "default" as const, - icon: Search, - }, - ]; + const { needsAttention, upcomingMaintenances, recentlyResolved, metrics } = + buildOverviewData({ + monitors, + pages, + incidents, + statusReports, + maintenances, + }); return ( - + Use our Slack agent to manage your status pages and incidents. Learn more - +
- - Overview - - Welcome to your OpenStatus dashboard. - - + + + Overview + + Welcome to your OpenStatus dashboard. + + + {pages.length > 0 ? : null} + - {metrics.map((metric) => ( - - + {metrics.map((metric) => { + const content = ( + <> {metric.title} @@ -161,51 +87,80 @@ export default function Page() { {metric.value} + + ); + return metric.href ? ( + + {content} + + ) : ( + + {content} - - ))} + ); + })}
- Incidents + Needs Attention - Incidents over the last 7 days. + Everything currently unresolved, newest first. - {incidents.length > 0 ? ( - - ) : ( - - No incidents found - - )} -
-
- - Reports - Reports over the last 7 days. - - {statusReports.length > 0 ? ( - + {needsAttention.length > 0 ? ( + ) : ( - No reports found + + All clear - nothing needs your attention + )}
+ {upcomingMaintenances.length > 0 ? ( +
+ + Scheduled Maintenance + + Upcoming and in-progress maintenance windows. + + + +
+ ) : null}
- Maintenance + Recent Activity - Maintenance over the last 7 days. + Resolved incidents and reports, and completed maintenances from the + last 7 days. - {maintenances.length > 0 ? ( - + {recentlyResolved.length > 0 ? ( + ) : ( - No maintenances found + No recent activity )}
diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx index 57874403..d9c98e80 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/(list)/client.tsx @@ -4,7 +4,8 @@ import { useQuery } from "@tanstack/react-query"; import { Palette } from "lucide-react"; import Link from "next/link"; -import { Note, NoteButton } from "@/components/common/note"; +import { NoteButton } from "@/components/common/note"; +import { NoteDismissible } from "@/components/common/note-dismissible"; import { SectionDescription, SectionGroup, @@ -25,7 +26,7 @@ export function Client() { return ( - + Create your own custom themes for your status pages. @@ -33,7 +34,7 @@ export function Client() { Learn more - + Status Pages diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx index 120a0315..f7b0a679 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/history/client.tsx @@ -8,7 +8,8 @@ import { useParams } from "next/navigation"; import { useQueryStates } from "nuqs"; import { useMemo, useState } from "react"; -import { Note, NoteButton } from "@/components/common/note"; +import { NoteButton } from "@/components/common/note"; +import { NoteDismissible } from "@/components/common/note-dismissible"; import { BillingOverlay, BillingOverlayButton, @@ -265,13 +266,13 @@ export function Client() { {!isLimited ? ( - + If there are any missing months, please contact us. Request Backfill - + ) : null} diff --git a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx index a9608cd8..65c1e5aa 100644 --- a/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx @@ -7,7 +7,8 @@ import NextLink from "next/link"; import { useParams } from "next/navigation"; import { Link } from "@/components/common/link"; -import { Note, NoteButton } from "@/components/common/note"; +import { NoteButton } from "@/components/common/note"; +import { NoteDismissible } from "@/components/common/note-dismissible"; import { Section, SectionDescription, @@ -60,7 +61,7 @@ export default function Page() { return ( - + Status reports now support per-component impacts. @@ -71,7 +72,7 @@ export default function Page() { Learn more - +
diff --git a/apps/dashboard/src/components/common/note-dismissible.tsx b/apps/dashboard/src/components/common/note-dismissible.tsx new file mode 100644 index 00000000..462e2d3c --- /dev/null +++ b/apps/dashboard/src/components/common/note-dismissible.tsx @@ -0,0 +1,48 @@ +"use client"; + +import { useCookieState } from "@openstatus/ui/hooks/use-cookie-state"; +import { createContext, useContext } from "react"; + +import { Note, NoteButtonClose } from "@/components/common/note"; + +const DismissedNotesContext = createContext([]); + +/** Server layout seeds the dismissed `note_*` cookie keys to avoid a flash before hydration. */ +export function DismissedNotesProvider({ + dismissed, + children, +}: { + dismissed: string[]; + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} + +export function NoteDismissible({ + cookieKey, + children, + ...props +}: React.ComponentProps & { + // the layout seeds dismissed state only for cookies matching this prefix + cookieKey: `note_${string}`; +}) { + const dismissed = useContext(DismissedNotesContext); + // no config: the hook's number `expires` builds an invalid cookie (session-only); the bare setter uses a valid 1y expiry + const [open, setOpen] = useCookieState<"true" | "false">(cookieKey); + + const visible = + open === undefined ? !dismissed.includes(cookieKey) : open === "true"; + + if (!visible) return null; + + return ( + + {children} + setOpen("false")} /> + + ); +} diff --git a/apps/dashboard/src/components/common/note.tsx b/apps/dashboard/src/components/common/note.tsx index 85f81ca5..09a9b0d4 100644 --- a/apps/dashboard/src/components/common/note.tsx +++ b/apps/dashboard/src/components/common/note.tsx @@ -1,6 +1,7 @@ import { Button } from "@openstatus/ui/components/ui/button"; import { cn } from "@openstatus/ui/lib/utils"; import { type VariantProps, cva } from "class-variance-authority"; +import { X } from "lucide-react"; const noteVariants = cva( "flex items-center gap-2 rounded-lg border [&>svg]:shrink-0 [&>svg]:text-current", @@ -64,3 +65,21 @@ export function NoteButton({ ); } + +export function NoteButtonClose({ + className, + ...props +}: Omit, "children">) { + return ( + + ); +} diff --git a/apps/dashboard/src/components/data-table/incidents/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/incidents/data-table-row-actions.tsx index 490c5c61..65cbf6ae 100644 --- a/apps/dashboard/src/components/data-table/incidents/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/incidents/data-table-row-actions.tsx @@ -1,151 +1,68 @@ "use client"; import type { RouterOutputs } from "@openstatus/api"; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, -} from "@openstatus/ui/components/ui/alert-dialog"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import type { Row } from "@tanstack/react-table"; -import { isTRPCClientError } from "@trpc/client"; -import { useMemo, useState, useTransition } from "react"; -import { toast } from "sonner"; +import { useState } from "react"; import { QuickActions } from "@/components/dropdowns/quick-actions"; import { getActions } from "@/data/incidents.client"; import { useTRPC } from "@/lib/trpc/client"; +import { + DialogConfirmIncident, + type IncidentConfirmType, +} from "./dialog-confirm"; + type Incident = RouterOutputs["incident"]["list"][number]; -interface DataTableRowActionsProps { - row: Row; +export function DataTableRowActions({ row }: { row: Row }) { + return ; } -export function DataTableRowActions({ row }: DataTableRowActionsProps) { - const [isPending, startTransition] = useTransition(); +export function IncidentRowActions({ incident }: { incident: Incident }) { const trpc = useTRPC(); const queryClient = useQueryClient(); - const acknowledgeIncidentMutation = useMutation( - trpc.incident.acknowledge.mutationOptions({ - onSuccess: () => { - queryClient.refetchQueries({ - queryKey: trpc.incident.list.queryKey({ - monitorId: row.original.monitorId, - }), - }); - }, - }), - ); - const resolveIncidentMutation = useMutation( - trpc.incident.resolve.mutationOptions({ - onSuccess: () => { - queryClient.refetchQueries({ - queryKey: trpc.incident.list.queryKey({ - monitorId: row.original.monitorId, - }), - }); - }, - }), - ); const deleteIncidentMutation = useMutation( trpc.incident.delete.mutationOptions({ - onSuccess: () => { - queryClient.refetchQueries({ - queryKey: trpc.incident.list.queryKey({ - monitorId: row.original.monitorId, - }), - }); - }, + onSuccess: () => + // no-input prefix key — matches every incident.list query (overview, monitor detail) + queryClient.invalidateQueries({ + queryKey: trpc.incident.list.queryKey(), + }), }), ); - const [type, setType] = useState<"acknowledge" | "resolve" | null>(null); - const open = useMemo(() => type !== null, [type]); + const [type, setType] = useState(null); const actions = getActions({ - acknowledge: row.original.acknowledgedAt + acknowledge: incident.acknowledgedAt ? undefined : () => setType("acknowledge"), - resolve: row.original.resolvedAt ? undefined : () => setType("resolve"), + resolve: incident.resolvedAt ? undefined : () => setType("resolve"), }); - const handleConfirm = async () => { - try { - startTransition(async () => { - const promise = - type === "acknowledge" - ? acknowledgeIncidentMutation.mutateAsync({ - id: row.original.id, - }) - : resolveIncidentMutation.mutateAsync({ - id: row.original.id, - }); - toast.promise(promise, { - loading: "Confirming...", - success: "Confirmed", - error: (error) => { - if (isTRPCClientError(error)) { - return error.message; - } - return "Failed to confirm"; - }, - }); - await promise; - setType(null); - }); - } catch (error) { - console.error("Failed to confirm:", error); - } - }; - return ( <> { await deleteIncidentMutation.mutateAsync({ - id: row.original.id, + id: incident.id, }); }, }} /> - setType(null)}> - { - // NOTE: bug where the body is not clickable after closing the alert dialog - event.preventDefault(); - document.body.style.pointerEvents = ""; - }} - > - - Confirm your action - - You are about to {type}{" "} - this incident. - - - - Cancel - { - e.preventDefault(); - handleConfirm(); - }} - disabled={isPending} - > - {isPending ? "Confirming..." : "Confirm"} - - - - + { + if (!open) setType(null); + }} + /> ); } diff --git a/apps/dashboard/src/components/data-table/incidents/dialog-confirm.tsx b/apps/dashboard/src/components/data-table/incidents/dialog-confirm.tsx new file mode 100644 index 00000000..85b4cd9a --- /dev/null +++ b/apps/dashboard/src/components/data-table/incidents/dialog-confirm.tsx @@ -0,0 +1,108 @@ +"use client"; + +import type { RouterOutputs } from "@openstatus/api"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@openstatus/ui/components/ui/alert-dialog"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { isTRPCClientError } from "@trpc/client"; +import { useTransition } from "react"; +import { toast } from "sonner"; + +import { useTRPC } from "@/lib/trpc/client"; + +type Incident = RouterOutputs["incident"]["list"][number]; + +export type IncidentConfirmType = "acknowledge" | "resolve"; + +/** Controlled acknowledge/resolve confirmation — stays open on error so the action can be retried. */ +export function DialogConfirmIncident({ + incident, + type, + open, + onOpenChange, +}: { + incident: Incident; + type: IncidentConfirmType | null; + open: boolean; + onOpenChange: (open: boolean) => void; +}) { + const [isPending, startTransition] = useTransition(); + const trpc = useTRPC(); + const queryClient = useQueryClient(); + // no-input prefix key — matches every incident.list query (overview, monitor detail) + const invalidateList = () => + queryClient.invalidateQueries({ + queryKey: trpc.incident.list.queryKey(), + }); + const acknowledgeIncidentMutation = useMutation( + trpc.incident.acknowledge.mutationOptions({ onSuccess: invalidateList }), + ); + const resolveIncidentMutation = useMutation( + trpc.incident.resolve.mutationOptions({ onSuccess: invalidateList }), + ); + + const handleConfirm = () => { + startTransition(async () => { + const promise = + type === "acknowledge" + ? acknowledgeIncidentMutation.mutateAsync({ id: incident.id }) + : resolveIncidentMutation.mutateAsync({ id: incident.id }); + toast.promise(promise, { + loading: "Confirming...", + success: "Confirmed", + error: (error) => { + if (isTRPCClientError(error)) { + return error.message; + } + return "Failed to confirm"; + }, + }); + try { + await promise; + onOpenChange(false); + } catch (error) { + console.error("Failed to confirm:", error); + } + }); + }; + + return ( + + { + // NOTE: bug where the body is not clickable after closing the alert dialog + event.preventDefault(); + document.body.style.pointerEvents = ""; + }} + > + + Confirm your action + + You are about to {type} this + incident. + + + + Cancel + { + e.preventDefault(); + handleConfirm(); + }} + disabled={isPending} + > + {isPending ? "Confirming..." : "Confirm"} + + + + + ); +} diff --git a/apps/dashboard/src/components/data-table/maintenances/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/maintenances/data-table-row-actions.tsx index d6288cd5..051c54bf 100644 --- a/apps/dashboard/src/components/data-table/maintenances/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/maintenances/data-table-row-actions.tsx @@ -14,51 +14,38 @@ import { useTRPC } from "@/lib/trpc/client"; type Maintenance = RouterOutputs["maintenance"]["list"][number]; -interface DataTableRowActionsProps { - row: Row; +export function DataTableRowActions({ row }: { row: Row }) { + return ; } -export function DataTableRowActions({ row }: DataTableRowActionsProps) { +export function MaintenanceRowActions({ + maintenance, +}: { + maintenance: Maintenance; +}) { const trpc = useTRPC(); const buttonRef = useRef(null); const actions = getActions({ edit: () => buttonRef.current?.click(), }); const { data: statusPage } = useQuery( - trpc.page.get.queryOptions({ id: row.original.pageId ?? 0 }), + trpc.page.get.queryOptions({ id: maintenance.pageId ?? 0 }), ); const queryClient = useQueryClient(); + // no-input prefix key — matches every maintenance.list query (overview, page detail) + const invalidateList = () => + queryClient.invalidateQueries({ + queryKey: trpc.maintenance.list.queryKey(), + }); const updateMaintenanceMutation = useMutation( trpc.maintenance.update.mutationOptions({ - onSuccess: () => { - queryClient.refetchQueries({ - queryKey: trpc.maintenance.list.queryKey({ - pageId: row.original.pageId ?? undefined, - }), - }); - queryClient.invalidateQueries({ - queryKey: trpc.maintenance.list.queryKey({ - period: "7d", - }), - }); - }, + onSuccess: invalidateList, }), ); const deleteMaintenanceMutation = useMutation( trpc.maintenance.delete.mutationOptions({ - onSuccess: () => { - queryClient.refetchQueries({ - queryKey: trpc.maintenance.list.queryKey({ - pageId: row.original.pageId ?? undefined, - }), - }); - queryClient.invalidateQueries({ - queryKey: trpc.maintenance.list.queryKey({ - period: "7d", - }), - }); - }, + onSuccess: invalidateList, }), ); @@ -67,10 +54,10 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { { await deleteMaintenanceMutation.mutateAsync({ - id: row.original.id, + id: maintenance.id, }); }, }} @@ -81,15 +68,15 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { statusPage?.pageComponentGroups ?? [], )} defaultValues={{ - title: row.original.title, - message: row.original.message, - startDate: row.original.from, - endDate: row.original.to, - pageComponents: row.original.pageComponents?.map((c) => c.id) ?? [], + title: maintenance.title, + message: maintenance.message, + startDate: maintenance.from, + endDate: maintenance.to, + pageComponents: maintenance.pageComponents?.map((c) => c.id) ?? [], }} onSubmit={async (values) => { await updateMaintenanceMutation.mutateAsync({ - id: row.original.id, + id: maintenance.id, title: values.title, message: values.message, startDate: values.startDate, diff --git a/apps/dashboard/src/components/data-table/overview-events/columns.tsx b/apps/dashboard/src/components/data-table/overview-events/columns.tsx new file mode 100644 index 00000000..82980b3d --- /dev/null +++ b/apps/dashboard/src/components/data-table/overview-events/columns.tsx @@ -0,0 +1,205 @@ +"use client"; + +import { Button } from "@openstatus/ui/components/ui/button"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@openstatus/ui/components/ui/tooltip"; +import { cn } from "@openstatus/ui/lib/utils"; +import type { ColumnDef } from "@tanstack/react-table"; +import { formatDistanceStrict } from "date-fns"; + +import { IncidentRowActions } from "@/components/data-table/incidents/data-table-row-actions"; +import { MaintenanceRowActions } from "@/components/data-table/maintenances/data-table-row-actions"; +import { StatusReportRowActions } from "@/components/data-table/status-reports/data-table-row-actions"; +import { TableCellDate } from "@/components/data-table/table-cell-date"; +import { TableCellLink } from "@/components/data-table/table-cell-link"; +import { TableCellNumber } from "@/components/data-table/table-cell-number"; +import { FormSheetStatusReportUpdateCreate } from "@/components/forms/status-report-update/sheet-create"; +import { DataTableColumnHeader } from "@/components/ui/data-table/data-table-column-header"; +import { + type OverviewEvent, + eventTypeConfig, + getIncidentStatus, + getMaintenanceStatus, + getResolvedAt, + getStartedAt, + incidentStatusConfig, + maintenanceStatusConfig, +} from "@/data/overview-events.client"; +import { colors } from "@/data/status-report-updates.client"; + +import { IncidentActionCell } from "./incident-action-cell"; + +function getStatus(event: OverviewEvent): { label: string; color: string } { + switch (event.type) { + case "incident": + return incidentStatusConfig[getIncidentStatus(event.incident)]; + case "report": + return { label: event.report.status, color: colors[event.report.status] }; + case "maintenance": + return maintenanceStatusConfig[getMaintenanceStatus(event.maintenance)]; + } +} + +function getTitle(event: OverviewEvent): { title: string; href: string } { + switch (event.type) { + case "incident": + return { + title: event.incident.monitor.name, + href: `/monitors/${event.incident.monitor.id}/incidents`, + }; + case "report": + return { + title: event.report.title, + href: `/status-pages/${event.report.pageId}/status-reports/${event.report.id}`, + }; + case "maintenance": + return { + title: event.maintenance.title, + href: `/status-pages/${event.maintenance.pageId}/maintenances`, + }; + } +} + +function getDuration(event: OverviewEvent): string | null { + const startedAt = getStartedAt(event); + const resolvedAt = getResolvedAt(event); + if (!resolvedAt) return null; + return formatDistanceStrict(startedAt, resolvedAt); +} + +export const columns: ColumnDef[] = [ + { + id: "type", + accessorFn: (row) => row.type, + header: () => null, + cell: ({ row }) => { + const config = eventTypeConfig[row.original.type]; + return ( + + + + + + {config.label} + + ); + }, + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: "w-8", + }, + }, + { + id: "title", + accessorFn: (row) => getTitle(row).title, + header: "Title", + cell: ({ row }) => { + const { title, href } = getTitle(row.original); + return ; + }, + enableSorting: false, + enableHiding: false, + meta: { + cellClassName: "max-w-[200px] truncate", + }, + }, + { + id: "status", + accessorFn: (row) => getStatus(row).label, + header: "Status", + cell: ({ row }) => { + const { label, color } = getStatus(row.original); + return
{label}
; + }, + enableSorting: false, + enableHiding: false, + }, + { + id: "startedAt", + accessorFn: (row) => getStartedAt(row), + header: ({ column }) => ( + + ), + cell: ({ row }) => , + enableHiding: false, + meta: { + cellClassName: "w-[170px]", + }, + }, + { + id: "endsAt", + accessorFn: (row) => getResolvedAt(row), + header: "End", + cell: ({ row }) => , + enableSorting: false, + meta: { + cellClassName: "w-[170px]", + }, + }, + { + id: "duration", + accessorFn: (row) => getDuration(row), + header: "Duration", + cell: ({ row }) => { + const value = row.getValue("duration"); + if (typeof value !== "string") { + return
ongoing
; + } + const [amount, unit] = value.split(" "); + return ; + }, + enableSorting: false, + }, + { + id: "action", + header: () => null, + cell: ({ row }) => { + const event = row.original; + switch (event.type) { + case "incident": + return ; + case "report": + if (event.report.status === "resolved") return null; + return ( + + + + ); + case "maintenance": + return null; + } + }, + enableSorting: false, + meta: { + cellClassName: "w-[110px] text-right", + }, + }, + { + id: "actions", + cell: ({ row }) => { + const event = row.original; + switch (event.type) { + case "incident": + return ; + case "report": + return ; + case "maintenance": + return ; + } + }, + meta: { + cellClassName: "w-8", + }, + }, +]; diff --git a/apps/dashboard/src/components/data-table/overview-events/incident-action-cell.tsx b/apps/dashboard/src/components/data-table/overview-events/incident-action-cell.tsx new file mode 100644 index 00000000..a6cdd87d --- /dev/null +++ b/apps/dashboard/src/components/data-table/overview-events/incident-action-cell.tsx @@ -0,0 +1,44 @@ +"use client"; + +import type { RouterOutputs } from "@openstatus/api"; +import { Button } from "@openstatus/ui/components/ui/button"; +import { useState } from "react"; + +import { + DialogConfirmIncident, + type IncidentConfirmType, +} from "@/components/data-table/incidents/dialog-confirm"; + +type Incident = RouterOutputs["incident"]["list"][number]; + +export function IncidentActionCell({ incident }: { incident: Incident }) { + // capture the action at click time so a background refetch can't flip it mid-dialog + const [type, setType] = useState(null); + + if (incident.resolvedAt) return null; + const nextAction = incident.acknowledgedAt ? "resolve" : "acknowledge"; + + return ( + <> + + { + if (!open) setType(null); + }} + /> + + ); +} diff --git a/apps/dashboard/src/components/data-table/response-logs/data-table-sheet-test.tsx b/apps/dashboard/src/components/data-table/response-logs/data-table-sheet-test.tsx index fc9a2222..b01dd701 100644 --- a/apps/dashboard/src/components/data-table/response-logs/data-table-sheet-test.tsx +++ b/apps/dashboard/src/components/data-table/response-logs/data-table-sheet-test.tsx @@ -1,6 +1,7 @@ "use client"; import type { RouterOutputs } from "@openstatus/api"; +import { calculateTiming } from "@openstatus/tinybird/src/schema"; import { DataTableSheet, @@ -58,13 +59,7 @@ function mapping(data: TestTCP | TestHTTP | TestDNS, monitor: Monitor) { headers: data.headers, region: data.region, latency: data.latency, - timing: { - dns: data.timing.dnsDone - data.timing.dnsStart, - connect: data.timing.connectDone - data.timing.connectStart, - tls: data.timing.tlsHandshakeDone - data.timing.tlsHandshakeStart, - ttfb: data.timing.firstByteDone - data.timing.firstByteStart, - transfer: data.timing.transferDone - data.timing.transferStart, - }, + timing: calculateTiming(data.timing), url: monitor.url, workspaceId: String(monitor.workspaceId), error: false, diff --git a/apps/dashboard/src/components/data-table/status-reports/columns.tsx b/apps/dashboard/src/components/data-table/status-reports/columns.tsx index 03aad1d5..80d9d61e 100644 --- a/apps/dashboard/src/components/data-table/status-reports/columns.tsx +++ b/apps/dashboard/src/components/data-table/status-reports/columns.tsx @@ -120,7 +120,9 @@ export const columns: ColumnDef[] = [ const impact = row.getValue("impact"); const config = impact ? impactConfig[impact] : untriagedImpact; return ( -
{config.label}
+
+ {config.label} +
); }, enableSorting: false, diff --git a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx index b449ac83..1a6c9a5e 100644 --- a/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx @@ -1,30 +1,27 @@ "use client"; import type { RouterOutputs } from "@openstatus/api"; -import { currentImpactsFromUpdates } from "@openstatus/db/src/schema/page_components/constants"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { Row } from "@tanstack/react-table"; import { useRef } from "react"; import { QuickActions } from "@/components/dropdowns/quick-actions"; -import { FormSheetStatusReportUpdate } from "@/components/forms/status-report-update/sheet"; +import { FormSheetStatusReportUpdateCreate } from "@/components/forms/status-report-update/sheet-create"; import { FormSheetStatusReport } from "@/components/forms/status-report/sheet"; import { toCheckboxTreeItems } from "@/components/ui/checkbox-tree"; -import { getNextStatus } from "@/data/status-report-updates.client"; import { getActions } from "@/data/status-reports.client"; import { useTRPC } from "@/lib/trpc/client"; type StatusReport = RouterOutputs["statusReport"]["list"][number]; -interface DataTableRowActionsProps { - row: Row; -} - // NOTE: avoid using useParams to get status page :id // because we are using the table in the /overview page -export function DataTableRowActions({ row }: DataTableRowActionsProps) { - if (!row.original.pageId) return null; +export function DataTableRowActions({ row }: { row: Row }) { + return ; +} + +export function StatusReportRowActions({ report }: { report: StatusReport }) { const buttonCreateRef = useRef(null); const buttonUpdateRef = useRef(null); const actions = getActions({ @@ -34,9 +31,8 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { if (typeof window !== "undefined") { window.open( `https://${ - row.original.page.customDomain || - `${row.original.page.slug}.openstatus.dev` - }/events/report/${row.original.id}`, + report.page.customDomain || `${report.page.slug}.openstatus.dev` + }/events/report/${report.id}`, "_blank", ); } @@ -45,88 +41,42 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { const trpc = useTRPC(); const queryClient = useQueryClient(); const { data: page } = useQuery( - trpc.page.get.queryOptions({ id: row.original.pageId }), - ); - const reportComponents = - row.original.pageComponents?.map((c) => ({ id: c.id, name: c.name })) ?? []; - const reportHasImpacts = row.original.updates.some( - (u) => u.componentImpacts.length > 0, - ); - const currentImpacts = currentImpactsFromUpdates(row.original.updates); - const nextStatus = getNextStatus(row.original.status); - const sendStatusReportUpdateMutation = useMutation( - trpc.subscriberNotification.statusReport.mutationOptions(), + trpc.page.get.queryOptions( + { id: report.pageId ?? 0 }, + { enabled: report.pageId !== null }, + ), ); + // no-input prefix key — matches every statusReport.list query (overview, page detail) + const invalidateLists = () => { + queryClient.invalidateQueries({ + queryKey: trpc.statusReport.list.queryKey(), + }); + queryClient.invalidateQueries({ + queryKey: trpc.page.list.queryKey(), + }); + }; const updateStatusReportMutation = useMutation( trpc.statusReport.updateStatus.mutationOptions({ - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - pageId: row.original.pageId ?? undefined, - }), - }); - queryClient.invalidateQueries({ - queryKey: trpc.page.list.queryKey(), - }); - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - period: "7d", - }), - }); - }, - }), - ); - const createStatusReportUpdateMutation = useMutation( - trpc.statusReport.createStatusReportUpdate.mutationOptions({ - onSuccess: (update) => { - if (update?.notifySubscribers) { - sendStatusReportUpdateMutation.mutate({ id: update.id }); - } - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - pageId: row.original.pageId ?? undefined, - }), - }); - queryClient.invalidateQueries({ - queryKey: trpc.page.list.queryKey(), - }); - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - period: "7d", - }), - }); - }, + onSuccess: invalidateLists, }), ); const deleteStatusReportMutation = useMutation( trpc.statusReport.delete.mutationOptions({ - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - pageId: row.original.pageId ?? undefined, - }), - }); - queryClient.invalidateQueries({ - queryKey: trpc.page.list.queryKey(), - }); - queryClient.invalidateQueries({ - queryKey: trpc.statusReport.list.queryKey({ - period: "7d", - }), - }); - }, + onSuccess: invalidateLists, }), ); + if (!report.pageId) return null; + return ( <> { await deleteStatusReportMutation.mutateAsync({ - id: row.original.id, + id: report.id, }); }, }} @@ -137,16 +87,16 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { page?.pageComponentGroups ?? [], )} defaultValues={{ - title: row.original.title, - status: row.original.status, - pageComponents: row.original.pageComponents?.map((c) => c.id) ?? [], + title: report.title, + status: report.status, + pageComponents: report.pageComponents?.map((c) => c.id) ?? [], }} onSubmit={async (values) => { const hasComponents = (page?.pageComponents?.length ?? 0) > 0 || (page?.pageComponentGroups?.length ?? 0) > 0; await updateStatusReportMutation.mutateAsync({ - id: row.original.id, + id: report.id, pageComponents: hasComponents ? values.pageComponents : undefined, title: values.title, status: values.status, @@ -157,38 +107,11 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { Open sheet - ({ - pageComponentId: c.id, - impact: - nextStatus === "resolved" - ? "operational" - : (currentImpacts.get(c.id) ?? "operational"), - })), - }} - components={reportComponents} - onSubmit={async (values) => { - // a legacy report stays legacy unless the operator actively - // sets a non-operational impact - const sendImpacts = - reportHasImpacts || - values.componentImpacts?.some((ci) => ci.impact !== "operational"); - await createStatusReportUpdateMutation.mutateAsync({ - statusReportId: row.original.id, - message: values.message, - status: values.status, - componentImpacts: sendImpacts ? values.componentImpacts : undefined, - date: values.date, - notifySubscribers: values.notifySubscribers, - }); - }} - > + - + ); } diff --git a/apps/dashboard/src/components/data-table/table-cell-link.tsx b/apps/dashboard/src/components/data-table/table-cell-link.tsx index 1f9d13b3..ff650b3e 100644 --- a/apps/dashboard/src/components/data-table/table-cell-link.tsx +++ b/apps/dashboard/src/components/data-table/table-cell-link.tsx @@ -19,7 +19,7 @@ export function TableCellLink({ return ( Learn more about{" "} - + page components . diff --git a/apps/dashboard/src/components/forms/components/update.tsx b/apps/dashboard/src/components/forms/components/update.tsx index 10261ef8..b5dc196f 100644 --- a/apps/dashboard/src/components/forms/components/update.tsx +++ b/apps/dashboard/src/components/forms/components/update.tsx @@ -1,7 +1,7 @@ "use client"; import type { PageConfiguration } from "@openstatus/db/src/schema"; -import { useMutation, useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useParams } from "next/navigation"; import { useState } from "react"; @@ -15,6 +15,7 @@ import { FormImport, type ImportFormValues } from "./form-import"; export function FormComponentsUpdate() { const { id } = useParams<{ id: string }>(); const trpc = useTRPC(); + const queryClient = useQueryClient(); const [formKey, setFormKey] = useState(0); const { data: statusPage, refetch } = useQuery( trpc.page.get.queryOptions({ id: Number.parseInt(id) }), @@ -35,6 +36,10 @@ export function FormComponentsUpdate() { // "removed" (delete) and placeholders as "new" (create). const refetchAndRemount = async (...refetches: Promise[]) => { await Promise.all(refetches); + // invalidate workspace to update the usage (getting-started checklist) + queryClient.invalidateQueries({ + queryKey: trpc.workspace.get.queryKey(), + }); setFormKey((k) => k + 1); }; diff --git a/apps/dashboard/src/components/forms/maintenance/sheet-create.tsx b/apps/dashboard/src/components/forms/maintenance/sheet-create.tsx new file mode 100644 index 00000000..d6d12c70 --- /dev/null +++ b/apps/dashboard/src/components/forms/maintenance/sheet-create.tsx @@ -0,0 +1,156 @@ +"use client"; + +import { Button } from "@openstatus/ui/components/ui/button"; +import { Label } from "@openstatus/ui/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@openstatus/ui/components/ui/select"; +import { Separator } from "@openstatus/ui/components/ui/separator"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; + +import { + EmptyStateContainer, + EmptyStateTitle, +} from "@/components/content/empty-state"; +import { FormCard, FormCardGroup } from "@/components/forms/form-card"; +import { + FormSheetContent, + FormSheetDescription, + FormSheetFooter, + FormSheetHeader, + FormSheetTitle, + FormSheetTrigger, + FormSheetWithDirtyProtection, +} from "@/components/forms/form-sheet"; +import { FormMaintenance } from "@/components/forms/maintenance/form"; +import { toCheckboxTreeItems } from "@/components/ui/checkbox-tree"; +import { useTRPC } from "@/lib/trpc/client"; + +/** + * Create-maintenance sheet with a status page selector — for surfaces that + * are not scoped to a single page (e.g. /overview). `children` is the trigger. + */ +export function FormSheetMaintenanceCreate({ + children, +}: { + children: React.ReactNode; +}) { + const [open, setOpen] = useState(false); + const [selectedPageId, setSelectedPageId] = useState(null); + const trpc = useTRPC(); + const queryClient = useQueryClient(); + const { data: pages } = useQuery(trpc.page.list.queryOptions()); + + const pageId = + pages?.length === 1 ? pages[0].id : (selectedPageId ?? undefined); + + const { data: page } = useQuery( + trpc.page.get.queryOptions( + { id: pageId ?? 0 }, + { enabled: pageId !== undefined }, + ), + ); + + const sendMaintenanceUpdateMutation = useMutation( + trpc.subscriberNotification.maintenance.mutationOptions(), + ); + const createMaintenanceMutation = useMutation( + trpc.maintenance.new.mutationOptions({ + onSuccess: (maintenance) => { + if (maintenance.notifySubscribers) { + sendMaintenanceUpdateMutation.mutate({ id: maintenance.id }); + } + // no-input prefix key — matches every maintenance.list query + queryClient.invalidateQueries({ + queryKey: trpc.maintenance.list.queryKey(), + }); + }, + }), + ); + + return ( + + {children} + + + Maintenance + + Configure and update the maintenance. + + + {pages && pages.length > 1 ? ( + <> +
+ + +
+ + + ) : null} + {pageId !== undefined ? ( + + + { + await createMaintenanceMutation.mutateAsync({ + pageId, + title: values.title, + message: values.message, + startDate: values.startDate, + endDate: values.endDate, + pageComponents: values.pageComponents, + notifySubscribers: values.notifySubscribers, + }); + setOpen(false); + }} + /> + + + ) : ( + + + {pages?.length === 0 + ? "No status pages found" + : "Select a status page"} + + + )} + + + +
+
+ ); +} diff --git a/apps/dashboard/src/components/forms/status-report-update/sheet-create.tsx b/apps/dashboard/src/components/forms/status-report-update/sheet-create.tsx new file mode 100644 index 00000000..f1e11c6f --- /dev/null +++ b/apps/dashboard/src/components/forms/status-report-update/sheet-create.tsx @@ -0,0 +1,82 @@ +"use client"; + +import type { RouterOutputs } from "@openstatus/api"; +import { currentImpactsFromUpdates } from "@openstatus/db/src/schema/page_components/constants"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { FormSheetStatusReportUpdate } from "@/components/forms/status-report-update/sheet"; +import { getNextStatus } from "@/data/status-report-updates.client"; +import { useTRPC } from "@/lib/trpc/client"; + +type StatusReport = RouterOutputs["statusReport"]["list"][number]; + +/** Create-update sheet prefilled with the report's next status — `children` is the trigger. */ +export function FormSheetStatusReportUpdateCreate({ + report, + children, +}: { + report: StatusReport; + children: React.ReactNode; +}) { + const trpc = useTRPC(); + const queryClient = useQueryClient(); + const reportComponents = + report.pageComponents?.map((c) => ({ id: c.id, name: c.name })) ?? []; + const reportHasImpacts = report.updates.some( + (u) => u.componentImpacts.length > 0, + ); + const currentImpacts = currentImpactsFromUpdates(report.updates); + const nextStatus = getNextStatus(report.status); + const sendStatusReportUpdateMutation = useMutation( + trpc.subscriberNotification.statusReport.mutationOptions(), + ); + const createStatusReportUpdateMutation = useMutation( + trpc.statusReport.createStatusReportUpdate.mutationOptions({ + onSuccess: (update) => { + if (update?.notifySubscribers) { + sendStatusReportUpdateMutation.mutate({ id: update.id }); + } + // no-input prefix key — matches every statusReport.list query + queryClient.invalidateQueries({ + queryKey: trpc.statusReport.list.queryKey(), + }); + queryClient.invalidateQueries({ + queryKey: trpc.page.list.queryKey(), + }); + }, + }), + ); + + return ( + ({ + pageComponentId: c.id, + impact: + nextStatus === "resolved" + ? "operational" + : (currentImpacts.get(c.id) ?? "operational"), + })), + }} + components={reportComponents} + onSubmit={async (values) => { + // a legacy report stays legacy unless the operator actively + // sets a non-operational impact + const sendImpacts = + reportHasImpacts || + values.componentImpacts?.some((ci) => ci.impact !== "operational"); + await createStatusReportUpdateMutation.mutateAsync({ + statusReportId: report.id, + message: values.message, + status: values.status, + componentImpacts: sendImpacts ? values.componentImpacts : undefined, + date: values.date, + notifySubscribers: values.notifySubscribers, + }); + }} + > + {children} + + ); +} diff --git a/apps/dashboard/src/components/forms/status-report/sheet-create.tsx b/apps/dashboard/src/components/forms/status-report/sheet-create.tsx new file mode 100644 index 00000000..7f1bdc94 --- /dev/null +++ b/apps/dashboard/src/components/forms/status-report/sheet-create.tsx @@ -0,0 +1,196 @@ +"use client"; + +import { Button } from "@openstatus/ui/components/ui/button"; +import { Label } from "@openstatus/ui/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@openstatus/ui/components/ui/select"; +import { Separator } from "@openstatus/ui/components/ui/separator"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useRef, useState } from "react"; + +import { + EmptyStateContainer, + EmptyStateTitle, +} from "@/components/content/empty-state"; +import { FormCard, FormCardGroup } from "@/components/forms/form-card"; +import { + FormSheetContent, + FormSheetDescription, + FormSheetFooter, + FormSheetHeader, + FormSheetTitle, + FormSheetTrigger, + FormSheetWithDirtyProtection, +} from "@/components/forms/form-sheet"; +import { FormStatusReport } from "@/components/forms/status-report/form"; +import { toCheckboxTreeItems } from "@/components/ui/checkbox-tree"; +import { useTRPC } from "@/lib/trpc/client"; + +/** + * Create-report sheet with a status page selector — for surfaces that are + * not scoped to a single page (e.g. /overview). `children` is the trigger. + */ +export function FormSheetStatusReportCreate({ + children, +}: { + children: React.ReactNode; +}) { + const [open, setOpen] = useState(false); + const [selectedPageId, setSelectedPageId] = useState(null); + const trpc = useTRPC(); + const queryClient = useQueryClient(); + const { data: pages } = useQuery(trpc.page.list.queryOptions()); + const { data: statusReports } = useQuery( + trpc.statusReport.list.queryOptions({}), + ); + + const pageId = + pages?.length === 1 ? pages[0].id : (selectedPageId ?? undefined); + + const { data: page } = useQuery( + trpc.page.get.queryOptions( + { id: pageId ?? 0 }, + { enabled: pageId !== undefined }, + ), + ); + + const sendStatusReportUpdateMutation = useMutation( + trpc.subscriberNotification.statusReport.mutationOptions(), + ); + const createStatusReportMutation = useMutation( + trpc.statusReport.create.mutationOptions({ + onSuccess: (statusReport) => { + if (statusReport.notifySubscribers) { + sendStatusReportUpdateMutation.mutate({ id: statusReport.id }); + } + // no-input prefix key — matches every statusReport.list query + queryClient.invalidateQueries({ + queryKey: trpc.statusReport.list.queryKey(), + }); + queryClient.invalidateQueries({ + queryKey: trpc.page.list.queryKey(), + }); + }, + }), + ); + + const unresolvedReport = + pageId !== undefined + ? statusReports?.find( + (r) => r.pageId === pageId && r.status !== "resolved", + ) + : undefined; + + return ( + + {children} + + + Status Report + + Configure and update the status of your report. + + + {pages && pages.length > 1 ? ( + <> +
+ + +
+ + + ) : null} + {unresolvedReport ? ( + <> +

+ An unresolved report already exists for this page. Consider adding + a status report update{" "} + instead. +

+ + + ) : null} + {pageId !== undefined ? ( + + + { + // NOTE: for type safety, we need to check if the values have a date property + // because of the union type + if ("date" in values) { + // every selected component gets an impact row — fresh + // reports are never legacy; fallback must match the + // picker's defaultImpact + const componentImpacts = values.pageComponents.map( + (pageComponentId) => ({ + pageComponentId, + impact: + values.componentImpacts?.find( + (ci) => ci.pageComponentId === pageComponentId, + )?.impact ?? ("degraded_performance" as const), + }), + ); + await createStatusReportMutation.mutateAsync({ + title: values.title, + status: values.status, + pageId, + pageComponents: values.pageComponents, + componentImpacts, + date: values.date, + message: values.message, + notifySubscribers: values.notifySubscribers, + }); + setOpen(false); + } + }} + /> + + + ) : ( + + + {pages?.length === 0 + ? "No status pages found" + : "Select a status page"} + + + )} + + + +
+
+ ); +} diff --git a/apps/dashboard/src/components/metric/metric-card.tsx b/apps/dashboard/src/components/metric/metric-card.tsx index c838f601..51589096 100644 --- a/apps/dashboard/src/components/metric/metric-card.tsx +++ b/apps/dashboard/src/components/metric/metric-card.tsx @@ -4,6 +4,7 @@ import { cn } from "@openstatus/ui/lib/utils"; import type { VariantProps } from "class-variance-authority"; import { cva } from "class-variance-authority"; import { ChevronDown, ChevronUp } from "lucide-react"; +import Link from "next/link"; import type React from "react"; const metricCardVariants = cva( @@ -16,6 +17,7 @@ const metricCardVariants = cva( destructive: "border-destructive/80 bg-destructive/10", success: "border-success/80 bg-success/10", warning: "border-warning/80 bg-warning/10", + info: "border-info/80 bg-info/10", }, }, defaultVariants: { @@ -71,6 +73,7 @@ export function MetricCardHeader({ "group-data-[variant=destructive]:text-destructive", "group-data-[variant=success]:text-success", "group-data-[variant=warning]:text-warning", + "group-data-[variant=info]:text-info", className, )} {...props} @@ -183,6 +186,27 @@ export function MetricCardButton({ ); } +export function MetricCardLink({ + children, + className, + variant, + ...props +}: React.ComponentProps & + VariantProps) { + return ( + + {children} + + ); +} + export function MetricCardSkeleton({ className, ...props @@ -193,6 +217,7 @@ export function MetricCardSkeleton({ "group-data-[variant=destructive]:bg-destructive/50", "group-data-[variant=success]:bg-success/50", "group-data-[variant=warning]:bg-warning/50", + "group-data-[variant=info]:bg-info/50", className, )} {...props} diff --git a/apps/dashboard/src/components/nav/nav-banner-checklist.tsx b/apps/dashboard/src/components/nav/nav-banner-checklist.tsx index 4bbef8ab..18fe04ac 100644 --- a/apps/dashboard/src/components/nav/nav-banner-checklist.tsx +++ b/apps/dashboard/src/components/nav/nav-banner-checklist.tsx @@ -8,7 +8,7 @@ import { SidebarMenuItem, } from "@openstatus/ui/components/ui/sidebar"; import { useQuery } from "@tanstack/react-query"; -import { CircleCheck, CircleDashed, X } from "lucide-react"; +import { ArrowUpRight, CircleCheck, CircleDashed, X } from "lucide-react"; import { Link } from "@/components/common/link"; import { useTRPC } from "@/lib/trpc/client"; @@ -20,14 +20,17 @@ export function NavBannerChecklist({ }) { const trpc = useTRPC(); const { data: workspace } = useQuery(trpc.workspace.get.queryOptions()); + const { data: pages } = useQuery(trpc.page.list.queryOptions()); if (!workspace) return null; + const onlyPage = pages?.length === 1 ? pages[0] : undefined; + const hasMonitors = (workspace.usage?.monitors ?? 0) > 0; const hasStatusPages = (workspace.usage?.pages ?? 0) > 0; - const hastNotifications = (workspace.usage?.notifications ?? 0) > 0; - - if (hasMonitors && hasStatusPages && hastNotifications) return null; + const hasPageComponents = (workspace.usage?.pageComponents ?? 0) > 0; + const hasNotifications = (workspace.usage?.notifications ?? 0) > 0; + const hasStatusReports = (workspace.usage?.statusReports ?? 0) > 0; const items = [ { @@ -40,17 +43,36 @@ export function NavBannerChecklist({ checked: hasStatusPages, href: "/status-pages/create", }, + { + title: "Add Page Components", + checked: hasPageComponents, + href: onlyPage + ? `/status-pages/${onlyPage.id}/components` + : "/status-pages", + }, + { + title: "Create Status Report", + checked: hasStatusReports, + href: onlyPage + ? `/status-pages/${onlyPage.id}/status-reports` + : "/status-pages", + }, { title: "Create Notification", - checked: hastNotifications, + checked: hasNotifications, href: "/notifications", }, ]; + if (items.every((i) => i.checked)) return null; + return ( - Getting Started + + Getting Started ({items.filter((i) => i.checked).length}/ + {items.length}) + ))} + + + + Read the Docs + + ); diff --git a/apps/dashboard/src/components/onboarding/checks-table-adapter.ts b/apps/dashboard/src/components/onboarding/checks-table-adapter.ts index e07e9673..b82aec82 100644 --- a/apps/dashboard/src/components/onboarding/checks-table-adapter.ts +++ b/apps/dashboard/src/components/onboarding/checks-table-adapter.ts @@ -1,20 +1,8 @@ -import type { - CheckResult, - CheckResultSuccess, -} from "@openstatus/services/monitor"; +import type { CheckResult } from "@openstatus/services/monitor"; +import { calculateTiming } from "@openstatus/tinybird/src/schema"; import type { OnboardingChecksRow } from "./checks-table"; -function calculatePhases(timing: CheckResultSuccess["timing"]) { - return { - dns: timing.dnsDone - timing.dnsStart, - connect: timing.connectDone - timing.connectStart, - tls: timing.tlsHandshakeDone - timing.tlsHandshakeStart, - ttfb: timing.firstByteDone - timing.firstByteStart, - transfer: timing.transferDone - timing.transferStart, - }; -} - /** * Adapt a Go-checker preview result into the `ResponseLog` shape * `getColumns` and `` expect. The synthesized row is "rich enough" @@ -22,8 +10,7 @@ function calculatePhases(timing: CheckResultSuccess["timing"]) { * * - `id` is set to `region` — synthetic but stable for selection. * - `requestStatus` derived from status + state. - * - `timing` is the raw start/done timestamps that `` - * diffs into phases. + * - `timing` is the phase durations `` renders. * - `workspaceId` is intentionally `""` — no current row renderer * (`columns.tsx`, `data-table-basics.tsx`, `data-table-sheet.tsx`) * reads it. If a future renderer constructs a URL from `workspaceId`, @@ -62,7 +49,7 @@ export function checkResultToResponseLog( const requestStatus = result.status >= 400 ? "error" : result.status >= 200 ? "success" : "error"; - const phases = result.timing ? calculatePhases(result.timing) : null; + const phases = result.timing ? calculateTiming(result.timing) : null; return { type: "http", diff --git a/apps/dashboard/src/data/overview-events.client.ts b/apps/dashboard/src/data/overview-events.client.ts new file mode 100644 index 00000000..02e8aab4 --- /dev/null +++ b/apps/dashboard/src/data/overview-events.client.ts @@ -0,0 +1,202 @@ +import type { RouterOutputs } from "@openstatus/api"; +import { + Activity, + type LucideIcon, + Megaphone, + PanelTop, + Siren, + Wrench, +} from "lucide-react"; + +type Incident = RouterOutputs["incident"]["list"][number]; +type StatusReport = RouterOutputs["statusReport"]["list"][number]; +type Maintenance = RouterOutputs["maintenance"]["list"][number]; + +export type OverviewEvent = + | { type: "incident"; incident: Incident } + | { type: "report"; report: StatusReport } + | { type: "maintenance"; maintenance: Maintenance }; + +export const eventTypeConfig = { + incident: { label: "Incident", icon: Siren }, + report: { label: "Status Report", icon: Megaphone }, + maintenance: { label: "Maintenance", icon: Wrench }, +} as const; + +export type OverviewEventType = keyof typeof eventTypeConfig; + +export const incidentStatusConfig = { + ongoing: { label: "Ongoing", color: "text-destructive/80" }, + acknowledged: { label: "Acknowledged", color: "text-warning/80" }, + resolved: { label: "Resolved", color: "text-success/80" }, +} as const; + +export type IncidentStatus = keyof typeof incidentStatusConfig; + +export const maintenanceStatusConfig = { + scheduled: { label: "Scheduled", color: "text-info/80" }, + "in-progress": { label: "In Progress", color: "text-info/80" }, + completed: { label: "Completed", color: "text-info/80" }, +} as const; + +export type MaintenanceStatus = keyof typeof maintenanceStatusConfig; + +export function getIncidentStatus(incident: { + acknowledgedAt: Date | null; + resolvedAt: Date | null; +}): IncidentStatus { + if (incident.resolvedAt) return "resolved"; + if (incident.acknowledgedAt) return "acknowledged"; + return "ongoing"; +} + +export function getMaintenanceStatus( + maintenance: { from: Date; to: Date }, + now = new Date(), +): MaintenanceStatus { + if (now < maintenance.from) return "scheduled"; + if (now > maintenance.to) return "completed"; + return "in-progress"; +} + +function reportStartedAt(report: StatusReport): Date { + const dates = report.updates.map((u) => u.date.getTime()); + if (dates.length) return new Date(Math.min(...dates)); + return report.createdAt ?? new Date(0); +} + +function reportResolvedAt(report: StatusReport): Date | null { + if (report.status !== "resolved") return null; + const dates = report.updates.map((u) => u.date.getTime()); + // legacy resolved report without updates: fall back to updatedAt + if (!dates.length) return report.updatedAt ?? report.createdAt; + return new Date(Math.max(...dates)); +} + +export function getStartedAt(event: OverviewEvent): Date { + switch (event.type) { + case "incident": + return event.incident.startedAt; + case "report": + return reportStartedAt(event.report); + case "maintenance": + return event.maintenance.from; + } +} + +export function getResolvedAt(event: OverviewEvent): Date | null { + switch (event.type) { + case "incident": + return event.incident.resolvedAt; + case "report": + return reportResolvedAt(event.report); + case "maintenance": + return event.maintenance.to; + } +} + +function isOpen(event: OverviewEvent, now: Date): boolean { + switch (event.type) { + case "incident": + return !event.incident.resolvedAt; + case "report": + return event.report.status !== "resolved"; + case "maintenance": + return event.maintenance.to >= now; + } +} + +export type OverviewMetric = { + title: string; + value: number; + href?: string; + variant: "default" | "destructive" | "warning" | "info"; + icon: LucideIcon; +}; + +export function buildOverviewData( + { + monitors, + pages, + incidents, + statusReports, + maintenances, + }: { + monitors: RouterOutputs["monitor"]["list"]; + pages: RouterOutputs["page"]["list"]; + incidents: Incident[]; + statusReports: StatusReport[]; + maintenances: Maintenance[]; + }, + now = new Date(), +) { + const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); + + const events: OverviewEvent[] = [ + ...incidents.map((incident) => ({ type: "incident" as const, incident })), + ...statusReports.map((report) => ({ type: "report" as const, report })), + ...maintenances.map((maintenance) => ({ + type: "maintenance" as const, + maintenance, + })), + ]; + + const needsAttention = events.filter( + (event) => event.type !== "maintenance" && isOpen(event, now), + ); + // calendar, not triage — scheduled/in-progress maintenance gets its own section + const upcomingMaintenances = events.filter( + (event) => event.type === "maintenance" && isOpen(event, now), + ); + const recentlyResolved = events.filter((event) => { + if (isOpen(event, now)) return false; + const resolvedAt = getResolvedAt(event); + return resolvedAt !== null && resolvedAt >= sevenDaysAgo; + }); + + const openIncidents = incidents.filter((i) => !i.resolvedAt); + const openReports = statusReports.filter((r) => r.status !== "resolved"); + const activeMaintenances = maintenances.filter((m) => m.to >= now); + + const metrics: OverviewMetric[] = [ + { + title: "Monitors", + value: monitors.length, + href: "/monitors", + variant: "default", + icon: Activity, + }, + { + title: "Status Pages", + value: pages.length, + href: "/status-pages", + variant: "default", + icon: PanelTop, + }, + { + title: "Open Incidents", + value: openIncidents.length, + variant: openIncidents.length > 0 ? "destructive" : "default", + icon: eventTypeConfig.incident.icon, + }, + { + title: "Open Reports", + value: openReports.length, + variant: openReports.length > 0 ? "warning" : "default", + icon: eventTypeConfig.report.icon, + }, + { + title: "Scheduled Maintenances", + value: activeMaintenances.length, + variant: activeMaintenances.length > 0 ? "info" : "default", + icon: eventTypeConfig.maintenance.icon, + }, + ]; + + return { + needsAttention, + upcomingMaintenances, + recentlyResolved, + metrics, + }; +} diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index 733b425e..1ad64dcc 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -50,17 +50,43 @@ async function addDomainToVercel(domain: string) { if (!response.ok) { const error = await response.json().catch(() => ({})); + const code = error?.error?.code; console.error("Failed to add domain to Vercel:", { domain, error }); - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - message: - "Failed to add custom domain. Please try again. If it continues, contact support.", - }); + throw toDomainError(domain, code); } return response.json(); } +// Vercel messages leak internal project details, so map known codes to our own copy. +function toDomainError(domain: string, code?: string): TRPCError { + switch (code) { + case "domain_already_in_use": + return new TRPCError({ + code: "CONFLICT", + message: `The domain '${domain}' is already in use by another status page. Remove it there first or contact support.`, + }); + case "invalid_domain": + case "not_found": + return new TRPCError({ + code: "BAD_REQUEST", + message: `The domain '${domain}' is invalid.`, + }); + case "forbidden": + case "domain_taken": + return new TRPCError({ + code: "FORBIDDEN", + message: `The domain '${domain}' belongs to another team on our hosting provider. Contact support if you own it.`, + }); + default: + return new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: + "Failed to add custom domain. Please try again. If it continues, contact support.", + }); + } +} + async function removeDomainFromVercel(domain: string) { const response = await fetch( `https://api.vercel.com/v9/projects/${env.PROJECT_ID_VERCEL}/domains/${domain}?teamId=${env.TEAM_ID_VERCEL}`, diff --git a/packages/db/src/schema/workspaces/validation.ts b/packages/db/src/schema/workspaces/validation.ts index 5d9deb0b..b8e514be 100644 --- a/packages/db/src/schema/workspaces/validation.ts +++ b/packages/db/src/schema/workspaces/validation.ts @@ -56,6 +56,7 @@ export const selectWorkspaceSchema = createSelectSchema(workspace) notifications: z.number().prefault(0), pages: z.number().prefault(0), pageComponents: z.number().prefault(0), + statusReports: z.number().prefault(0), // checks: z.number().default(0), }) .nullish(), diff --git a/packages/db/src/schema/workspaces/workspace.ts b/packages/db/src/schema/workspaces/workspace.ts index 5b529af2..e9269b8e 100644 --- a/packages/db/src/schema/workspaces/workspace.ts +++ b/packages/db/src/schema/workspaces/workspace.ts @@ -4,6 +4,7 @@ import { integer, sqliteTable, text, unique } from "drizzle-orm/sqlite-core"; import { monitor } from "../monitors"; import { notification } from "../notifications"; import { page } from "../pages"; +import { statusReport } from "../status_reports"; import { usersToWorkspaces } from "../users"; import { workspacePlans } from "./constants"; @@ -39,5 +40,6 @@ export const workspaceRelations = relations(workspace, ({ many }) => ({ pages: many(page), monitors: many(monitor), notifications: many(notification), + statusReports: many(statusReport), // TODO: add checks or monitorRuns })); diff --git a/packages/services/src/workspace/__tests__/workspace.test.ts b/packages/services/src/workspace/__tests__/workspace.test.ts index 6efc00f5..46cc4e38 100644 --- a/packages/services/src/workspace/__tests__/workspace.test.ts +++ b/packages/services/src/workspace/__tests__/workspace.test.ts @@ -1,5 +1,5 @@ import { eq } from "@openstatus/db"; -import { workspace } from "@openstatus/db/src/schema"; +import { statusReport, workspace } from "@openstatus/db/src/schema"; import { expect } from "@std/expect"; import { beforeAll, describe, test } from "@std/testing/bdd"; @@ -57,6 +57,7 @@ describe("getWorkspaceWithUsage", () => { "notifications", "pages", "pageComponents", + "statusReports", "checks", ] as const) { const value = result.usage[key]; @@ -68,6 +69,20 @@ describe("getWorkspaceWithUsage", () => { expect(result.usage.checks).toBe(0); }); }); + + test("counts workspace-scoped status reports", async () => { + await withTestTransaction(async (tx) => { + await tx.insert(statusReport).values({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + status: "investigating", + title: "svc-ws-test-status-report", + }); + const result = await getWorkspaceWithUsage({ + ctx: { ...teamCtx, db: tx }, + }); + expect(result.usage.statusReports).toBeGreaterThanOrEqual(1); + }); + }); }); describe("listWorkspaces", () => { diff --git a/packages/services/src/workspace/list.ts b/packages/services/src/workspace/list.ts index 6c82a085..ba9f4521 100644 --- a/packages/services/src/workspace/list.ts +++ b/packages/services/src/workspace/list.ts @@ -24,6 +24,7 @@ export type WorkspaceUsage = { notifications: number; pages: number; pageComponents: number; + statusReports: number; checks: number; }; @@ -71,6 +72,7 @@ export async function getWorkspaceWithUsage(args: { where: isNull(monitor.deletedAt), }, notifications: true, + statusReports: { columns: { id: true } }, }, }); @@ -86,6 +88,7 @@ export async function getWorkspaceWithUsage(args: { pages: result.pages?.length ?? 0, pageComponents: result.pages?.flatMap((page) => page.pageComponents)?.length ?? 0, + statusReports: result.statusReports?.length ?? 0, // Parity with the legacy router — checks usage was previously commented // out pending a real source and left as 0. Preserved here. checks: 0, diff --git a/packages/tinybird/package.json b/packages/tinybird/package.json index c575aa6a..2084c0f5 100644 --- a/packages/tinybird/package.json +++ b/packages/tinybird/package.json @@ -4,7 +4,8 @@ "license": "MIT", "main": "src/index.ts", "scripts": { - "check": "deno check --sloppy-imports ." + "check": "deno check --sloppy-imports .", + "test": "deno test --parallel -A --no-check --sloppy-imports" }, "dependencies": { "@chronark/zod-bird": "catalog:", @@ -15,6 +16,8 @@ "@openstatus/db": "workspace:*", "@openstatus/tsconfig": "workspace:*", "@openstatus/utils": "workspace:*", + "@std/expect": "jsr:^1.0.19", + "@std/testing": "jsr:^1.0.19", "@types/node": "catalog:", "drizzle-orm": "catalog:", "typescript": "catalog:" diff --git a/packages/tinybird/src/schema.test.ts b/packages/tinybird/src/schema.test.ts new file mode 100644 index 00000000..de42ed20 --- /dev/null +++ b/packages/tinybird/src/schema.test.ts @@ -0,0 +1,74 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { calculateTiming } from "./schema"; + +// Absolute epoch-ms timestamps, as emitted by the checker's httptrace hooks. +const base = 1_782_880_607_000; +const completeTiming = { + dnsStart: base, + dnsDone: base + 5, + connectStart: base + 5, + connectDone: base + 6, + tlsHandshakeStart: base + 6, + tlsHandshakeDone: base + 16, + firstByteStart: base + 16, + firstByteDone: base + 116, + transferStart: base + 116, + transferDone: base + 120, +}; + +describe("calculateTiming", () => { + test("computes phase durations from complete timing", () => { + expect(calculateTiming(completeTiming)).toEqual({ + dns: 5, + connect: 1, + tls: 10, + ttfb: 100, + transfer: 4, + }); + }); + + test("clamps phases whose end hook never fired to 0", () => { + // timeout after connect: first byte never arrived + const timing = { + ...completeTiming, + firstByteDone: 0, + transferStart: 0, + transferDone: 0, + }; + + expect(calculateTiming(timing)).toEqual({ + dns: 5, + connect: 1, + tls: 10, + ttfb: 0, + transfer: 0, + }); + }); + + test("clamps phases whose start hook never fired to 0", () => { + const timing = { ...completeTiming, transferStart: 0 }; + + expect(calculateTiming(timing)?.transfer).toBe(0); + }); + + test("never returns negative durations for unmeasured phases", () => { + const timing = { + dnsStart: 0, + dnsDone: 0, + connectStart: 0, + connectDone: 0, + tlsHandshakeStart: 0, + tlsHandshakeDone: 0, + firstByteStart: base, + firstByteDone: 0, + transferStart: 0, + transferDone: 0, + }; + + for (const value of Object.values(calculateTiming(timing) ?? {})) { + expect(value).toBe(0); + } + }); +}); diff --git a/packages/tinybird/src/schema.ts b/packages/tinybird/src/schema.ts index 81e0772e..aae67c4e 100644 --- a/packages/tinybird/src/schema.ts +++ b/packages/tinybird/src/schema.ts @@ -43,15 +43,22 @@ export function transformTiming(val: string) { return null; } +// 0 = phase hook never fired (e.g. timeout before first byte); subtracting +// absolute epoch timestamps would yield huge negative durations. +function phaseDuration(start: number, done: number) { + if (start === 0 || done === 0) return 0; + return done - start; +} + export function calculateTiming(obj: z.infer) { if (!obj) return null; return { - dns: obj.dnsDone - obj.dnsStart, - connect: obj.connectDone - obj.connectStart, - tls: obj.tlsHandshakeDone - obj.tlsHandshakeStart, - ttfb: obj.firstByteDone - obj.firstByteStart, - transfer: obj.transferDone - obj.transferStart, + dns: phaseDuration(obj.dnsStart, obj.dnsDone), + connect: phaseDuration(obj.connectStart, obj.connectDone), + tls: phaseDuration(obj.tlsHandshakeStart, obj.tlsHandshakeDone), + ttfb: phaseDuration(obj.firstByteStart, obj.firstByteDone), + transfer: phaseDuration(obj.transferStart, obj.transferDone), }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43da4219..fd4f9cdd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -769,7 +769,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -1216,7 +1216,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-intl: specifier: 'catalog:' version: 4.12.0(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(typescript@5.9.3) @@ -1484,7 +1484,7 @@ importers: version: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) next-mdx-remote: specifier: 'catalog:' version: 6.0.0(@types/react@19.2.15)(react@19.2.6) @@ -1992,7 +1992,7 @@ importers: version: 0.31.10 next-auth: specifier: 'catalog:' - version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + version: 5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) typescript: specifier: 'catalog:' version: 5.9.3 @@ -2806,6 +2806,12 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../utils + '@std/expect': + specifier: jsr:^1.0.19 + version: '@jsr/std__expect@1.0.19' + '@std/testing': + specifier: jsr:^1.0.19 + version: '@jsr/std__testing@1.0.19' '@types/node': specifier: 'catalog:' version: 24.12.4 @@ -18334,7 +18340,7 @@ snapshots: neverthrow@7.2.0: {} - next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): + next-auth@5.0.0-beta.31(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6): dependencies: '@auth/core': 0.41.2 next: 16.2.6(@babel/core@7.28.5)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) -- 2.51.2 From 66ab77a10b52f10487003e53d00222659df6c434 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 11:07:25 +0200 Subject: [PATCH 29/69] slack: display componenent name (#2348) * slack: display componenent name * add more tests * update pr --- .../src/libs/test/doubles/page-urls.mock.ts | 15 + apps/server/src/routes/slack/blocks.test.ts | 360 ++++++++++++++++-- apps/server/src/routes/slack/blocks.ts | 101 ++++- apps/server/src/routes/slack/handler.ts | 20 +- apps/server/src/routes/slack/page-urls.ts | 60 ++- deno.lock | 226 +++++++++++ .../__tests__/summary-refs.test.ts | 102 +++++ packages/services/src/agent-tools/index.ts | 1 + .../services/src/agent-tools/maintenance.ts | 10 +- .../services/src/agent-tools/status-report.ts | 30 +- packages/services/src/agent-tools/types.ts | 20 +- 11 files changed, 902 insertions(+), 43 deletions(-) create mode 100644 packages/services/src/agent-tools/__tests__/summary-refs.test.ts diff --git a/apps/server/src/libs/test/doubles/page-urls.mock.ts b/apps/server/src/libs/test/doubles/page-urls.mock.ts index b4e18132..424e115b 100644 --- a/apps/server/src/libs/test/doubles/page-urls.mock.ts +++ b/apps/server/src/libs/test/doubles/page-urls.mock.ts @@ -8,3 +8,18 @@ export const getReportUrl = ( reportId: number, ): Promise => Promise.resolve(`https://example.openstatus.dev/events/report/${reportId}`); + +export const getPageDashboardLink = ( + _workspaceId: number, + pageId: number, +): Promise<{ title: string; url: string } | null> => + Promise.resolve({ + title: `Page ${pageId}`, + url: `https://app.openstatus.dev/status-pages/${pageId}`, + }); + +export const getComponentNames = ( + _workspaceId: number, + ids: number[], +): Promise> => + Promise.resolve(new Map(ids.map((id) => [id, `Component ${id}`]))); diff --git a/apps/server/src/routes/slack/blocks.test.ts b/apps/server/src/routes/slack/blocks.test.ts index ceac36c3..eeb1b2a3 100644 --- a/apps/server/src/routes/slack/blocks.test.ts +++ b/apps/server/src/routes/slack/blocks.test.ts @@ -6,12 +6,13 @@ import { buildConfirmationBlocks, getConfirmationText, parseActionId, + type RefResolvers, } from "./blocks"; describe("buildConfirmationBlocks", () => { - test("create_status_report has approve / approve_flag / cancel", () => { + test("create_status_report has approve / approve_flag / cancel", async () => { const tool = agentTools.create_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "abc123", tool, input: { @@ -39,9 +40,303 @@ describe("buildConfirmationBlocks", () => { expect(actions.elements[2].action_id).toBe("cancel_abc123"); }); - test("create_status_report shows components when provided", () => { + const stubResolvers: RefResolvers = { + page: (pageId) => + Promise.resolve({ + title: "Acme Status", + url: `https://app.openstatus.dev/status-pages/${pageId}`, + }), + componentNames: (ids) => + Promise.resolve(new Map(ids.map((id) => [id, `Svc ${id}`]))), + }; + + test("create_status_report links the page name when resolvers resolve", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "link1", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 2705, + pageComponentIds: [], + }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain( + "*Page:* ", + ); + expect(text).not.toContain("Page ID"); + }); + + test("create_status_report falls back to page id when the page can't be resolved", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "link2", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 2705, + pageComponentIds: [], + }, + resolvers: { ...stubResolvers, page: () => Promise.resolve(null) }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Page ID:* 2705"); + }); + + test("create_status_report shows component names when resolvers resolve", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "cn1", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [101, 102], + componentImpacts: [{ pageComponentId: 101, impact: "major_outage" }], + }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* Svc 101, Svc 102"); + expect(text).toContain("*Impacts:* Svc 101 → major_outage"); + }); + + test("component line falls back to raw id when a name is missing", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "cn2", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [101, 999], + }, + resolvers: { + ...stubResolvers, + componentNames: () => Promise.resolve(new Map([[101, "Svc 101"]])), + }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* Svc 101, 999"); + }); + + test("degrades to raw page id (card intact) when the page resolver rejects", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "rej1", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 2705, + pageComponentIds: [], + }, + resolvers: { + ...stubResolvers, + page: () => Promise.reject(new Error("db down")), + }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Page ID:* 2705"); + // The rest of the card must still build — a flaky lookup degrades one line. + const actions = blocks.find((b) => b.type === "actions") as { + elements: unknown[]; + }; + expect(actions.elements).toHaveLength(3); + }); + + test("degrades to raw component ids when the component resolver rejects", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "rej2", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [101, 102], + componentImpacts: [{ pageComponentId: 101, impact: "major_outage" }], + }, + resolvers: { + ...stubResolvers, + componentNames: () => Promise.reject(new Error("db down")), + }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* 101, 102"); + expect(text).toContain("*Impacts:* 101 → major_outage"); + }); + + test("escapes mrkdwn-significant chars in the page link text", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "esc1", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [], + }, + resolvers: { + ...stubResolvers, + page: () => + Promise.resolve({ title: "A & B |d", url: "https://x/1" }), + }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain(""); + }); + + test("escapes mrkdwn-significant chars in component names", async () => { + const tool = agentTools.create_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "esc2", + tool, + input: { + title: "Outage", + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [101], + }, + resolvers: { + ...stubResolvers, + componentNames: () => Promise.resolve(new Map([[101, "API & "]])), + }, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* API & <Web>"); + }); + + test("escapes mrkdwn in the title header and un-refed line values", async () => { + const tool = agentTools.create_status_report; + const evil = ""; + const blocks = await buildConfirmationBlocks({ + actionId: "esc3", + tool, + input: { + title: evil, + status: "investigating", + message: "msg", + pageId: 1, + pageComponentIds: [], + }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + // Header ("Create Status Report: ") and the "Title" line both escape. + expect(text).not.toContain(evil); + expect(text).toContain("<http://evil.example|Click here>"); + }); + + test("add_status_report_update resolves impact component names", async () => { + const tool = agentTools.add_status_report_update; + const blocks = await buildConfirmationBlocks({ + actionId: "au1", + tool, + input: { + statusReportId: 42, + status: "monitoring", + message: "recovering", + componentImpacts: [{ pageComponentId: 7, impact: "partial_outage" }], + }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Impacts:* Svc 7 → partial_outage"); + expect(text).not.toContain("*Impacts:* 7 →"); + }); + + test("update_status_report resolves component names", async () => { + const tool = agentTools.update_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "up1", + tool, + input: { statusReportId: 10, pageComponentIds: [1, 2] }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* Svc 1, Svc 2"); + }); + + test("update_status_report keeps '(clear all)' literal even with resolvers", async () => { + const tool = agentTools.update_status_report; + const blocks = await buildConfirmationBlocks({ + actionId: "up2", + tool, + input: { statusReportId: 10, pageComponentIds: [] }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain("*Components:* (clear all)"); + }); + + test("create_maintenance resolves the page link and component names", async () => { + const tool = agentTools.create_maintenance; + const blocks = await buildConfirmationBlocks({ + actionId: "mn1", + tool, + input: { + title: "DB Upgrade", + message: "Restarting replicas", + from: "2026-06-01T00:00:00Z", + to: "2026-06-01T01:00:00Z", + pageId: 7, + pageComponentIds: [1, 2], + }, + resolvers: stubResolvers, + }); + const text = ( + blocks.find((b) => b.type === "section") as { text: { text: string } } + ).text.text; + expect(text).toContain( + "*Page:* ", + ); + expect(text).toContain("*Components:* Svc 1, Svc 2"); + expect(text).not.toContain("Page ID"); + }); + + test("create_status_report shows components when provided", async () => { const tool = agentTools.create_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "id1", tool, input: { @@ -58,9 +353,9 @@ describe("buildConfirmationBlocks", () => { expect(section.text.text).toContain("101, 102"); }); - test("create_status_report shows impacts when provided", () => { + test("create_status_report shows impacts when provided", async () => { const tool = agentTools.create_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "i1", tool, input: { @@ -83,9 +378,9 @@ describe("buildConfirmationBlocks", () => { expect(section.text.text).toContain("102 → degraded_performance"); }); - test("add_status_report_update shows impacts when provided", () => { + test("add_status_report_update shows impacts when provided", async () => { const tool = agentTools.add_status_report_update; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "i2", tool, input: { @@ -102,9 +397,9 @@ describe("buildConfirmationBlocks", () => { expect(section.text.text).toContain("7 → partial_outage"); }); - test("add_status_report_update has 3 buttons", () => { + test("add_status_report_update has 3 buttons", async () => { const tool = agentTools.add_status_report_update; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "abc", tool, input: { @@ -126,11 +421,11 @@ describe("buildConfirmationBlocks", () => { expect(actions.elements).toHaveLength(3); }); - test("update_status_report distinguishes 'clear all' from 'no change' for components", () => { + test("update_status_report distinguishes 'clear all' from 'no change' for components", async () => { const tool = agentTools.update_status_report; // pageComponentIds undefined → no Components line at all - const noChange = buildConfirmationBlocks({ + const noChange = await buildConfirmationBlocks({ actionId: "u1", tool, input: { statusReportId: 10, title: "X" }, @@ -143,7 +438,7 @@ describe("buildConfirmationBlocks", () => { expect(noChangeText).not.toContain("Components"); // pageComponentIds: [] → "(clear all)" - const clearAll = buildConfirmationBlocks({ + const clearAll = await buildConfirmationBlocks({ actionId: "u2", tool, input: { statusReportId: 10, pageComponentIds: [] }, @@ -156,7 +451,7 @@ describe("buildConfirmationBlocks", () => { expect(clearAllText).toContain("(clear all)"); // pageComponentIds: [1,2] → list - const withIds = buildConfirmationBlocks({ + const withIds = await buildConfirmationBlocks({ actionId: "u3", tool, input: { statusReportId: 10, pageComponentIds: [1, 2] }, @@ -169,9 +464,9 @@ describe("buildConfirmationBlocks", () => { expect(withIdsText).toContain("1, 2"); }); - test("update_status_report has 2 buttons (no notify flag)", () => { + test("update_status_report has 2 buttons (no notify flag)", async () => { const tool = agentTools.update_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "xyz", tool, input: { statusReportId: 10, title: "Updated Title" }, @@ -190,9 +485,9 @@ describe("buildConfirmationBlocks", () => { expect(actions.elements[1].action_id).toBe("cancel_xyz"); }); - test("create_maintenance card shows pageId", () => { + test("create_maintenance card shows pageId", async () => { const tool = agentTools.create_maintenance; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "m1", tool, input: { @@ -213,9 +508,9 @@ describe("buildConfirmationBlocks", () => { expect(text).toContain("7"); }); - test("resolve_status_report has 3 buttons", () => { + test("resolve_status_report has 3 buttons", async () => { const tool = agentTools.resolve_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "res1", tool, input: { statusReportId: 5, message: "Issue has been resolved" }, @@ -233,9 +528,9 @@ describe("buildConfirmationBlocks", () => { expect(actions.elements).toHaveLength(3); }); - test("all blocks include a divider", () => { + test("all blocks include a divider", async () => { const tool = agentTools.create_status_report; - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: "d1", tool, input: { @@ -283,14 +578,29 @@ describe("getConfirmationText", () => { }), ).toBe("Resolve Status Report"); }); + + test("escapes mrkdwn in the title (message text field)", () => { + expect( + getConfirmationText({ + tool: agentTools.create_status_report, + input: { + title: "", + status: "investigating", + message: "m", + pageId: 1, + pageComponentIds: [], + }, + }), + ).toBe("Create Status Report: <http://evil.example|Click here>"); + }); }); describe("buildConfirmationBlocks (error paths)", () => { - test("throws when the tool has no approval metadata", () => { + test("rejects when the tool has no approval metadata", async () => { const readTool = agentTools.list_status_pages; - expect(() => + await expect( buildConfirmationBlocks({ actionId: "x", tool: readTool, input: {} }), - ).toThrow(/no approval metadata/); + ).rejects.toThrow(/no approval metadata/); }); }); diff --git a/apps/server/src/routes/slack/blocks.ts b/apps/server/src/routes/slack/blocks.ts index 338ea8ac..3e8dd0a7 100644 --- a/apps/server/src/routes/slack/blocks.ts +++ b/apps/server/src/routes/slack/blocks.ts @@ -1,4 +1,8 @@ -import type { AnyAgentTool, ExtraFlag } from "@openstatus/services/agent-tools"; +import type { + AnyAgentTool, + ExtraFlag, + SummaryLine, +} from "@openstatus/services/agent-tools"; interface TextObject { type: "plain_text" | "mrkdwn"; @@ -87,16 +91,90 @@ export function parseActionId(actionId: string): ParsedActionId | undefined { return undefined; } +/** Escape `& < >` so Slack renders them as literal mrkdwn text. */ +function escapeText(text: string): string { + return text + .replace(/&/g, "&") + .replace(//g, ">"); +} + +/** Escape a string for use as Slack mrkdwn link text (``). */ +function escapeLinkText(text: string): string { + return escapeText(text).replace(/\|/g, "❘"); +} + +/** + * Data resolvers the Slack surface injects so `buildConfirmationBlocks` can + * turn `SummaryLineRef` descriptors into names. Resolution needs DB access, + * which the edge-safe services layer that produces the refs must not do. + */ +export interface RefResolvers { + /** Page id → dashboard link, or null when the page no longer exists. */ + page: (pageId: number) => Promise<{ title: string; url: string } | null>; + /** Page-component ids → their names (missing ids simply absent). */ + componentNames: (ids: number[]) => Promise>; +} + +async function renderLine( + line: SummaryLine, + resolvers?: RefResolvers, +): Promise { + const ref = line.ref; + if (ref && resolvers) { + try { + switch (ref.kind) { + case "page": { + const link = await resolvers.page(ref.pageId); + if (link) { + return `*Page:* <${link.url}|${escapeLinkText(link.title)}>`; + } + break; + } + case "components": { + const names = await resolvers.componentNames(ref.componentIds); + const value = ref.componentIds + .map((id) => nameOrId(names, id)) + .join(", "); + return `*${line.label}:* ${value}`; + } + case "componentImpacts": { + const names = await resolvers.componentNames( + ref.impacts.map((i) => i.pageComponentId), + ); + const value = ref.impacts + .map((i) => `${nameOrId(names, i.pageComponentId)} → ${i.impact}`) + .join(", "); + return `*${line.label}:* ${value}`; + } + } + } catch { + // A transient name/link lookup failure degrades just this line to its + // raw id value below, rather than aborting the whole confirmation card. + } + } + return `*${line.label}:* ${escapeText(line.value)}`; +} + +function nameOrId(names: Map, id: number): string { + const name = names.get(id); + return name ? escapeText(name) : String(id); +} + /** * Build the Block Kit confirmation card from a tool's `approval.summarize()`. - * Two affirmative buttons when an extraFlag exists; one otherwise. + * Two affirmative buttons when an extraFlag exists; one otherwise. When a + * summary line carries a `ref` and `resolvers` are supplied, raw ids are + * replaced by entity names (a dashboard link for pages, component names for + * component ids). */ -export function buildConfirmationBlocks(args: { +export async function buildConfirmationBlocks(args: { actionId: string; tool: AnyAgentTool; input: unknown; -}): Block[] { - const { actionId, tool, input } = args; + resolvers?: RefResolvers; +}): Promise { + const { actionId, tool, input, resolvers } = args; if (!tool.approval) { throw new Error( `slack blocks: tool "${tool.name}" has no approval metadata`, @@ -105,7 +183,9 @@ export function buildConfirmationBlocks(args: { const summary = tool.approval.summarize(input); const flag: ExtraFlag | undefined = tool.approval.extraFlags?.[0]; - const lines = summary.lines.map((l) => `*${l.label}:* ${l.value}`).join("\n"); + const lines = ( + await Promise.all(summary.lines.map((l) => renderLine(l, resolvers))) + ).join("\n"); const buttons: ButtonElement[] = [ { @@ -137,7 +217,10 @@ export function buildConfirmationBlocks(args: { return [ { type: "section", - text: { type: "mrkdwn", text: `*${summary.title}*\n\n${lines}` }, + text: { + type: "mrkdwn", + text: `*${escapeText(summary.title)}*\n\n${lines}`, + }, }, { type: "divider" }, { type: "actions", elements: buttons }, @@ -149,5 +232,7 @@ export function getConfirmationText(args: { input: unknown; }): string { if (!args.tool.approval) return `Confirm ${args.tool.name}`; - return args.tool.approval.summarize(args.input).title; + // Rendered as the message `text` field, which Slack parses as mrkdwn — escape + // so an LLM/user-controlled title can't inject a link or other markup. + return escapeText(args.tool.approval.summarize(args.input).title); } diff --git a/apps/server/src/routes/slack/handler.ts b/apps/server/src/routes/slack/handler.ts index a075966c..2e2012f4 100644 --- a/apps/server/src/routes/slack/handler.ts +++ b/apps/server/src/routes/slack/handler.ts @@ -6,12 +6,24 @@ import type { Context } from "hono"; import { z } from "zod"; import { runAgent } from "./agent"; -import { buildConfirmationBlocks, getConfirmationText } from "./blocks"; +import { + buildConfirmationBlocks, + getConfirmationText, + type RefResolvers, +} from "./blocks"; import { findByThread, replace, store } from "./confirmation-store"; import type { PendingPayload } from "./confirmation-store"; +import { getComponentNames, getPageDashboardLink } from "./page-urls"; import { getRegistryTool, isSlackToolDraft } from "./registry-runner"; import { resolveWorkspace } from "./workspace-resolver"; +function makeRefResolvers(workspaceId: number): RefResolvers { + return { + page: (pageId) => getPageDashboardLink(workspaceId, pageId), + componentNames: (ids) => getComponentNames(workspaceId, ids), + }; +} + const logger = getLogger("api-server"); const processedEvents = new Map(); @@ -342,10 +354,11 @@ async function handleConfirmation( if (existing) { await replace(existing.id, payload); - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId: existing.id, tool, input: draft.displayInput, + resolvers: makeRefResolvers(workspaceId), }); await slack.chat.update({ channel, ts: thinkingTs, text, blocks }); await slack.chat.update({ @@ -365,10 +378,11 @@ async function handleConfirmation( payload, }); - const blocks = buildConfirmationBlocks({ + const blocks = await buildConfirmationBlocks({ actionId, tool, input: draft.displayInput, + resolvers: makeRefResolvers(workspaceId), }); await slack.chat.update({ channel, ts: thinkingTs, text, blocks }); } diff --git a/apps/server/src/routes/slack/page-urls.ts b/apps/server/src/routes/slack/page-urls.ts index 8aab57f4..8d210c91 100644 --- a/apps/server/src/routes/slack/page-urls.ts +++ b/apps/server/src/routes/slack/page-urls.ts @@ -1,5 +1,7 @@ -import { db, eq } from "@openstatus/db"; -import { page } from "@openstatus/db/src/schema"; +import { and, db, eq, inArray } from "@openstatus/db"; +import { page, pageComponent } from "@openstatus/db/src/schema"; + +import { env } from "@/env"; /** * Slack-message URL helpers. Pure transport-layer formatting — lives here @@ -21,6 +23,60 @@ export async function getPageUrl(pageId: number): Promise { : `https://${statusPage.slug}.openstatus.dev`; } +function getDashboardBaseUrl(): string { + return env.NODE_ENV === "production" + ? "https://app.openstatus.dev" + : "http://localhost:3000"; +} + +/** + * Resolve a page id to its dashboard link — the page title plus the internal + * dashboard URL (not the public status page). Scoped to the workspace so a + * spoofed id from another workspace never leaks its title into the preview + * card (pageId on the draft is only validated against the workspace at execute + * time). Returns null when the page doesn't exist in the workspace so callers + * can fall back to the raw id. + */ +export async function getPageDashboardLink( + workspaceId: number, + pageId: number, +): Promise<{ title: string; url: string } | null> { + const statusPage = await db + .select({ title: page.title }) + .from(page) + .where(and(eq(page.workspaceId, workspaceId), eq(page.id, pageId))) + .get(); + + if (!statusPage) return null; + return { + title: statusPage.title, + url: `${getDashboardBaseUrl()}/status-pages/${pageId}`, + }; +} + +/** + * Resolve page-component ids to their names, scoped to the workspace so a + * spoofed id from another workspace never leaks a name. Missing ids are + * simply absent from the map — callers fall back to the raw id. + */ +export async function getComponentNames( + workspaceId: number, + ids: number[], +): Promise> { + if (ids.length === 0) return new Map(); + const rows = await db + .select({ id: pageComponent.id, name: pageComponent.name }) + .from(pageComponent) + .where( + and( + eq(pageComponent.workspaceId, workspaceId), + inArray(pageComponent.id, ids), + ), + ) + .all(); + return new Map(rows.map((r: { id: number; name: string }) => [r.id, r.name])); +} + export async function getReportUrl( pageId: number, reportId: number, diff --git a/deno.lock b/deno.lock index 0fb0ec68..ce3a1683 100644 --- a/deno.lock +++ b/deno.lock @@ -54,6 +54,232 @@ "dependencies": [ "npm:turbo@2.9.14" ] + }, + "members": { + "apps/server": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/status-page": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "apps/web": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/ai": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/api": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/db": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/emails": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/header-analysis": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/importers": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/base": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/bird-whatsapp": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/discord": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/google-chat": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/grafana-oncall": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ms-teams": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/ntfy": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/opsgenie": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/pagerduty": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/slack": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/telegram": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/twillio-sms": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/notifications/webhook": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/services": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/status-fetcher": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/subscriptions": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/test-utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/tracker": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, + "packages/utils": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + } } } } diff --git a/packages/services/src/agent-tools/__tests__/summary-refs.test.ts b/packages/services/src/agent-tools/__tests__/summary-refs.test.ts new file mode 100644 index 00000000..1c47d822 --- /dev/null +++ b/packages/services/src/agent-tools/__tests__/summary-refs.test.ts @@ -0,0 +1,102 @@ +import { expect } from "@std/expect"; +import { describe, test } from "@std/testing/bdd"; + +import { agentTools } from "../index"; +import type { AnyAgentTool, SummaryLine } from "../types"; + +function summarize( + toolName: keyof typeof agentTools, + input: unknown, +): SummaryLine[] { + const tool = agentTools[toolName] as AnyAgentTool; + if (!tool.approval) throw new Error(`${toolName} has no approval`); + return tool.approval.summarize(input).lines; +} + +function line(lines: SummaryLine[], label: string): SummaryLine { + const found = lines.find((l) => l.label === label); + if (!found) throw new Error(`no "${label}" line`); + return found; +} + +describe("summary-line refs", () => { + test("create_status_report tags the page line with a page ref", () => { + const lines = summarize("create_status_report", { + title: "Outage", + status: "investigating", + message: "m", + pageId: 2705, + pageComponentIds: [], + }); + expect(line(lines, "Page ID").ref).toEqual({ kind: "page", pageId: 2705 }); + }); + + test("create_status_report tags components and impacts with refs", () => { + const lines = summarize("create_status_report", { + title: "Outage", + status: "investigating", + message: "m", + pageId: 1, + pageComponentIds: [101, 102], + componentImpacts: [{ pageComponentId: 101, impact: "major_outage" }], + }); + expect(line(lines, "Components").ref).toEqual({ + kind: "components", + componentIds: [101, 102], + }); + expect(line(lines, "Impacts").ref).toEqual({ + kind: "componentImpacts", + impacts: [{ pageComponentId: 101, impact: "major_outage" }], + }); + }); + + test("add_status_report_update tags impacts with a componentImpacts ref", () => { + const lines = summarize("add_status_report_update", { + statusReportId: 42, + status: "monitoring", + message: "m", + componentImpacts: [{ pageComponentId: 7, impact: "partial_outage" }], + }); + expect(line(lines, "Impacts").ref).toEqual({ + kind: "componentImpacts", + impacts: [{ pageComponentId: 7, impact: "partial_outage" }], + }); + }); + + test("create_maintenance tags the page and components lines", () => { + const lines = summarize("create_maintenance", { + title: "DB Upgrade", + message: "m", + from: "2026-06-01T00:00:00Z", + to: "2026-06-01T01:00:00Z", + pageId: 7, + pageComponentIds: [1, 2], + }); + expect(line(lines, "Page ID").ref).toEqual({ kind: "page", pageId: 7 }); + expect(line(lines, "Components").ref).toEqual({ + kind: "components", + componentIds: [1, 2], + }); + }); + + test("update_status_report tags components when ids are present", () => { + const lines = summarize("update_status_report", { + statusReportId: 10, + pageComponentIds: [1, 2], + }); + expect(line(lines, "Components").ref).toEqual({ + kind: "components", + componentIds: [1, 2], + }); + }); + + test("update_status_report leaves the '(clear all)' line ref-less", () => { + const lines = summarize("update_status_report", { + statusReportId: 10, + pageComponentIds: [], + }); + const components = line(lines, "Components"); + expect(components.value).toBe("(clear all)"); + expect(components.ref).toBeUndefined(); + }); +}); diff --git a/packages/services/src/agent-tools/index.ts b/packages/services/src/agent-tools/index.ts index 64db2717..71a81abe 100644 --- a/packages/services/src/agent-tools/index.ts +++ b/packages/services/src/agent-tools/index.ts @@ -53,6 +53,7 @@ export type { InferAgentToolInput, InferAgentToolOutput, SummaryLine, + SummaryLineRef, } from "./types"; export { type AgentSystemPromptOptions, diff --git a/packages/services/src/agent-tools/maintenance.ts b/packages/services/src/agent-tools/maintenance.ts index 5833e350..8934efc5 100644 --- a/packages/services/src/agent-tools/maintenance.ts +++ b/packages/services/src/agent-tools/maintenance.ts @@ -167,7 +167,11 @@ export const createMaintenanceTool: AgentTool< title: `Schedule Maintenance: ${input.title}`, lines: [ { label: "Title", value: input.title }, - { label: "Page ID", value: String(input.pageId) }, + { + label: "Page ID", + value: String(input.pageId), + ref: { kind: "page", pageId: input.pageId }, + }, { label: "From", value: formatMaintenanceDate(input.from) }, { label: "To", value: formatMaintenanceDate(input.to) }, ...(input.pageComponentIds?.length @@ -175,6 +179,10 @@ export const createMaintenanceTool: AgentTool< { label: "Components", value: input.pageComponentIds.join(", "), + ref: { + kind: "components" as const, + componentIds: input.pageComponentIds, + }, }, ] : []), diff --git a/packages/services/src/agent-tools/status-report.ts b/packages/services/src/agent-tools/status-report.ts index a5e032f3..453fcaa2 100644 --- a/packages/services/src/agent-tools/status-report.ts +++ b/packages/services/src/agent-tools/status-report.ts @@ -20,7 +20,7 @@ import { type StatusReportStatus, } from "../status-report/schemas"; import { formatComponentImpacts } from "../status-report/utils"; -import type { AgentTool } from "./types"; +import type { AgentTool, SummaryLine } from "./types"; // Agent surfaces send only the impacts that CHANGED (see system prompt). Carry // the report's current non-operational impacts into the update so each update's @@ -243,12 +243,20 @@ export const createStatusReportTool: AgentTool< lines: [ { label: "Title", value: input.title }, { label: "Status", value: input.status }, - { label: "Page ID", value: String(input.pageId) }, + { + label: "Page ID", + value: String(input.pageId), + ref: { kind: "page", pageId: input.pageId }, + }, ...(input.pageComponentIds?.length ? [ { label: "Components", value: input.pageComponentIds.join(", "), + ref: { + kind: "components" as const, + componentIds: input.pageComponentIds, + }, }, ] : []), @@ -259,6 +267,10 @@ export const createStatusReportTool: AgentTool< value: formatComponentImpacts(input.componentImpacts).join( ", ", ), + ref: { + kind: "componentImpacts" as const, + impacts: input.componentImpacts, + }, }, ] : []), @@ -379,6 +391,10 @@ export const addStatusReportUpdateTool: AgentTool< value: formatComponentImpacts(input.componentImpacts).join( ", ", ), + ref: { + kind: "componentImpacts" as const, + impacts: input.componentImpacts, + }, }, ] : []), @@ -473,7 +489,7 @@ export const updateStatusReportTool: AgentTool< outputSchema: UpdateStatusReportOutput, approval: { summarize: (input) => { - const lines: { label: string; value: string }[] = [ + const lines: SummaryLine[] = [ { label: "Report ID", value: String(input.statusReportId) }, ]; if (input.title) lines.push({ label: "New Title", value: input.title }); @@ -488,6 +504,14 @@ export const updateStatusReportTool: AgentTool< value: input.pageComponentIds.length ? input.pageComponentIds.join(", ") : "(clear all)", + ...(input.pageComponentIds.length + ? { + ref: { + kind: "components" as const, + componentIds: input.pageComponentIds, + }, + } + : {}), }); } return { diff --git a/packages/services/src/agent-tools/types.ts b/packages/services/src/agent-tools/types.ts index d0338200..48d29cdf 100644 --- a/packages/services/src/agent-tools/types.ts +++ b/packages/services/src/agent-tools/types.ts @@ -47,7 +47,25 @@ export type ExtraFlag = { default?: boolean; }; -export type SummaryLine = { label: string; value: string }; +/** + * Structured reference a rendering surface can resolve into entity names + * (e.g. a dashboard link, or component names in place of ids), replacing the + * raw `value`. Kept as a descriptor — resolution needs DB access, which the + * edge-safe services layer must not do. + */ +export type SummaryLineRef = + | { kind: "page"; pageId: number } + | { kind: "components"; componentIds: number[] } + | { + kind: "componentImpacts"; + impacts: readonly { pageComponentId: number; impact: string }[]; + }; + +export type SummaryLine = { + label: string; + value: string; + ref?: SummaryLineRef; +}; export type ApprovalMeta = { /** -- 2.51.2 From d940385d34837241171718c35cac4456ddec29c8 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 15:43:25 +0200 Subject: [PATCH 30/69] slack app: subscribe to status page (#2318) * slack app: subscribe to status page * ci: apply automated fixes * merge * merge conflict * fix tests * fix tests * fix builds * fix builds * ci: apply automated fixes * rename command --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- apps/dashboard/next-env.d.ts | 2 +- apps/dashboard/src/app/api/chat/route.ts | 2 - .../src/app/api/onboarding/checks/route.ts | 2 - .../src/app/api/trpc/edge/[trpc]/route.ts | 24 - .../src/app/api/trpc/lambda/[trpc]/route.ts | 10 +- .../data-table/subscribers/columns.tsx | 4 +- .../subscribers/data-table-row-actions.tsx | 23 +- apps/dashboard/src/lib/trpc/shared.ts | 48 +- .../rpc/handlers/status-page/converters.ts | 2 +- .../interceptors/__tests__/tracking.test.ts | 2 +- apps/server/src/routes/slack/commands.ts | 153 + apps/server/src/routes/slack/handler.ts | 14 +- apps/server/src/routes/slack/index.ts | 2 + apps/server/src/routes/slack/oauth.ts | 2 + apps/server/src/routes/slack/resolve-page.ts | 69 + apps/server/src/routes/slack/verify.ts | 7 +- apps/status-page/next-env.d.ts | 2 +- .../src/app/api/trpc/edge/[trpc]/route.ts | 24 - .../src/app/api/trpc/lambda/[trpc]/route.ts | 10 +- apps/status-page/src/lib/trpc/shared.ts | 41 +- apps/web/next-env.d.ts | 2 +- .../web/src/app/api/trpc/edge/[trpc]/route.ts | 23 - .../src/app/api/trpc/lambda/[trpc]/route.ts | 10 +- apps/web/src/trpc/shared.ts | 39 +- deno.lock | 8 + packages/analytics/src/server.ts | 27 +- packages/db/drizzle/0078_yellow_thor_girl.sql | 28 + packages/db/drizzle/meta/0078_snapshot.json | 4712 +++++++++++++++++ packages/db/drizzle/meta/_journal.json | 9 +- .../page_subscribers/page_subscribers.ts | 18 +- .../src/schema/page_subscribers/validation.ts | 44 +- packages/services/src/invitation/create.ts | 2 +- .../__tests__/page-subscriber.test.ts | 32 +- .../page-subscriber/__tests__/slack.test.ts | 170 + .../src/page-subscriber/get-by-token.ts | 2 +- .../services/src/page-subscriber/index.ts | 10 + packages/services/src/page-subscriber/list.ts | 2 +- .../services/src/page-subscriber/schemas.ts | 27 + .../services/src/page-subscriber/slack.ts | 255 + .../services/src/page-subscriber/upsert.ts | 2 +- .../services/src/page-subscriber/verify.ts | 2 +- .../src/workspace/__tests__/workspace.test.ts | 2 +- packages/subscriptions/package.json | 2 + .../subscriptions/src/channels/index.test.ts | 9 +- packages/subscriptions/src/channels/index.ts | 8 + .../src/channels/slack-blocks.test.ts | 78 + .../src/channels/slack-blocks.ts | 140 + .../subscriptions/src/channels/slack-store.ts | 112 + .../subscriptions/src/channels/slack.test.ts | 267 + packages/subscriptions/src/channels/slack.ts | 265 + packages/subscriptions/src/dispatcher.ts | 3 +- packages/subscriptions/src/index.ts | 12 + packages/subscriptions/src/types.ts | 5 +- pnpm-lock.yaml | 6 + 54 files changed, 6533 insertions(+), 243 deletions(-) delete mode 100644 apps/dashboard/src/app/api/trpc/edge/[trpc]/route.ts create mode 100644 apps/server/src/routes/slack/commands.ts create mode 100644 apps/server/src/routes/slack/resolve-page.ts delete mode 100644 apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts delete mode 100644 apps/web/src/app/api/trpc/edge/[trpc]/route.ts create mode 100644 packages/db/drizzle/0078_yellow_thor_girl.sql create mode 100644 packages/db/drizzle/meta/0078_snapshot.json create mode 100644 packages/services/src/page-subscriber/__tests__/slack.test.ts create mode 100644 packages/services/src/page-subscriber/slack.ts create mode 100644 packages/subscriptions/src/channels/slack-blocks.test.ts create mode 100644 packages/subscriptions/src/channels/slack-blocks.ts create mode 100644 packages/subscriptions/src/channels/slack-store.ts create mode 100644 packages/subscriptions/src/channels/slack.test.ts create mode 100644 packages/subscriptions/src/channels/slack.ts diff --git a/apps/dashboard/next-env.d.ts b/apps/dashboard/next-env.d.ts index c4b7818f..9edff1c7 100644 --- a/apps/dashboard/next-env.d.ts +++ b/apps/dashboard/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/dashboard/src/app/api/chat/route.ts b/apps/dashboard/src/app/api/chat/route.ts index ecf80b68..546e6b96 100644 --- a/apps/dashboard/src/app/api/chat/route.ts +++ b/apps/dashboard/src/app/api/chat/route.ts @@ -26,8 +26,6 @@ import { toAiSdkTools } from "@/lib/agent-tools/adapter"; import { getChatServiceContext } from "@/lib/agent-tools/context"; import { chatRateLimit } from "@/lib/rate-limit/chat"; -export const runtime = "edge"; - // Drop tool parts that have no result the SDK can turn into a tool_result // block. `ignoreIncompleteToolCalls` doesn't cover `approval-requested`, so // a mid-confirmation reload would otherwise replay an orphan `tool_use` to diff --git a/apps/dashboard/src/app/api/onboarding/checks/route.ts b/apps/dashboard/src/app/api/onboarding/checks/route.ts index eb01a9ab..a0ae5d81 100644 --- a/apps/dashboard/src/app/api/onboarding/checks/route.ts +++ b/apps/dashboard/src/app/api/onboarding/checks/route.ts @@ -8,8 +8,6 @@ import { z } from "zod"; import { getServiceContextFromRequest } from "@/lib/edge-context"; -export const runtime = "edge"; - const SERVICE_ERROR_STATUS: Record = { NOT_FOUND: 404, FORBIDDEN: 403, diff --git a/apps/dashboard/src/app/api/trpc/edge/[trpc]/route.ts b/apps/dashboard/src/app/api/trpc/edge/[trpc]/route.ts deleted file mode 100644 index 9dd8225b..00000000 --- a/apps/dashboard/src/app/api/trpc/edge/[trpc]/route.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { createTRPCContext } from "@openstatus/api"; -import { edgeRouter } from "@openstatus/api/src/edge"; -import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import type { NextRequest } from "next/server"; - -import { auth } from "@/lib/auth"; -import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; - -export const runtime = "edge"; - -const handler = (req: NextRequest) => { - const blocked = guardTRPCSource(req); - if (blocked) return blocked; - - return fetchRequestHandler({ - endpoint: "/api/trpc/edge", - router: edgeRouter, - req: req, - createContext: () => createTRPCContext({ req, auth }), - onError: createOnError("edge"), - }); -}; - -export { handler as GET, handler as POST }; diff --git a/apps/dashboard/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/dashboard/src/app/api/trpc/lambda/[trpc]/route.ts index 944ea4af..0ebe3609 100644 --- a/apps/dashboard/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/dashboard/src/app/api/trpc/lambda/[trpc]/route.ts @@ -1,13 +1,13 @@ -import { createTRPCContext } from "@openstatus/api"; -import { lambdaRouter } from "@openstatus/api/src/lambda"; +import { appRouter, createTRPCContext } from "@openstatus/api"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; import { auth } from "@/lib/auth"; import { createOnError, guardTRPCSource } from "@/lib/trpc/shared"; -// Stripe is incompatible with Edge runtimes due to using Node.js events -// export const runtime = "edge"; +// Runs on the Node.js runtime (Vercel Fluid compute). The whole tRPC surface +// is served here — several routers pull Node-only deps (@slack/web-api, email +// and notification SDKs) that are not Edge-safe. const handler = (req: NextRequest) => { const blocked = guardTRPCSource(req); @@ -15,7 +15,7 @@ const handler = (req: NextRequest) => { return fetchRequestHandler({ endpoint: "/api/trpc/lambda", - router: lambdaRouter, + router: appRouter, req: req, createContext: () => createTRPCContext({ req, auth }), onError: createOnError("lambda"), diff --git a/apps/dashboard/src/components/data-table/subscribers/columns.tsx b/apps/dashboard/src/components/data-table/subscribers/columns.tsx index f011edf2..eccab528 100644 --- a/apps/dashboard/src/components/data-table/subscribers/columns.tsx +++ b/apps/dashboard/src/components/data-table/subscribers/columns.tsx @@ -40,7 +40,9 @@ export const columns: ColumnDef[] = [ const flavor = sub.channelType === "webhook" ? detectFlavorBadge(sub.webhookUrl) - : null; + : sub.channelType === "slack" + ? "Slack" + : null; return (
diff --git a/apps/dashboard/src/components/data-table/subscribers/data-table-row-actions.tsx b/apps/dashboard/src/components/data-table/subscribers/data-table-row-actions.tsx index 25c6a430..34b93dac 100644 --- a/apps/dashboard/src/components/data-table/subscribers/data-table-row-actions.tsx +++ b/apps/dashboard/src/components/data-table/subscribers/data-table-row-actions.tsx @@ -61,19 +61,20 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) { statusPage?.pageComponentGroups ?? [], ); - const editDefaults = isVendorAdded - ? { - channelType: sub.channelType, - name: sub.name ?? "", - email: sub.email ?? "", - webhookUrl: sub.webhookUrl ?? "", - headers: parseHeaders(sub.channelConfig), - componentIds: sub.components.map((c) => c.id), - } - : undefined; + const editDefaults = + isVendorAdded && sub.channelType !== "slack" + ? { + channelType: sub.channelType, + name: sub.name ?? "", + email: sub.email ?? "", + webhookUrl: sub.webhookUrl ?? "", + headers: parseHeaders(sub.channelConfig), + componentIds: sub.components.map((c) => c.id), + } + : undefined; const actions = [ - ...(isVendorAdded + ...(isVendorAdded && sub.channelType !== "slack" ? [ { id: "edit", diff --git a/apps/dashboard/src/lib/trpc/shared.ts b/apps/dashboard/src/lib/trpc/shared.ts index 23187324..41f74d6f 100644 --- a/apps/dashboard/src/lib/trpc/shared.ts +++ b/apps/dashboard/src/lib/trpc/shared.ts @@ -34,44 +34,18 @@ const getBaseUrl = () => { return "http://localhost:3000"; // Local dev and Docker (internal calls) }; -const lambdas = [ - "stripeRouter", - "emailRouter", - "apiKeyRouter", - "integrationRouter", - "blob", - "subscriberNotification", -]; - -export const endingLink = (opts?: { - fetch?: typeof fetch; - headers?: HTTPHeaders | (() => HTTPHeaders | Promise); -}) => - ((runtime) => { - const sharedOpts = { +// The whole tRPC surface is served from a single Node.js endpoint — there is +// no longer an Edge/Node split, so all calls go to one link. +export const endingLink = + (opts?: { + fetch?: typeof fetch; + headers?: HTTPHeaders | (() => HTTPHeaders | Promise); + }): TRPCLink => + (runtime) => + httpBatchLink({ headers: opts?.headers, fetch: opts?.fetch, transformer: superjson, - // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any - } satisfies Partial>; - - const edgeLink = httpBatchLink({ - ...sharedOpts, - url: `${getBaseUrl()}/api/trpc/edge`, - })(runtime); - const lambdaLink = httpBatchLink({ - ...sharedOpts, url: `${getBaseUrl()}/api/trpc/lambda`, - })(runtime); - - return (ctx) => { - const path = ctx.op.path.split(".") as [string, ...string[]]; - const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; - - const newCtx = { - ...ctx, - op: { ...ctx.op, path: path.join(".") }, - }; - return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); - }; - }) satisfies TRPCLink; + // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any + } satisfies Partial>)(runtime); diff --git a/apps/server/src/routes/rpc/handlers/status-page/converters.ts b/apps/server/src/routes/rpc/handlers/status-page/converters.ts index 8803c847..5452c018 100644 --- a/apps/server/src/routes/rpc/handlers/status-page/converters.ts +++ b/apps/server/src/routes/rpc/handlers/status-page/converters.ts @@ -77,7 +77,7 @@ export type DBPageSubscriber = { updatedAt: Date | null; source: "self_signup" | "vendor" | "import"; name: string | null; - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; webhookUrl: string | null; channelConfig: string | null; componentIds?: number[]; diff --git a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts index 234213c1..38a05bdb 100644 --- a/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts +++ b/apps/server/src/routes/rpc/interceptors/__tests__/tracking.test.ts @@ -1,7 +1,7 @@ import type { Interceptor } from "@connectrpc/connect"; import { Events } from "@openstatus/analytics"; // @ts-nocheck — ConnectRPC's deep generic types (AnyFn, UnaryResponse, etc.) -// are incompatible with bun:test mocks. All runtime behavior is correct. +// are incompatible with the test mocks. All runtime behavior is correct. import { beforeEach, describe, diff --git a/apps/server/src/routes/slack/commands.ts b/apps/server/src/routes/slack/commands.ts new file mode 100644 index 00000000..1a4e0900 --- /dev/null +++ b/apps/server/src/routes/slack/commands.ts @@ -0,0 +1,153 @@ +import { ForbiddenError } from "@openstatus/services"; +import { + createSlackSubscriber, + listSlackSubscribersForChannel, + removeSlackSubscriber, +} from "@openstatus/services/page-subscriber"; +import { WebClient } from "@slack/web-api"; +import type { Context } from "hono"; +import { z } from "zod"; + +import { resolvePageFromUrl } from "./resolve-page"; +import { resolveWorkspace } from "./workspace-resolver"; + +const slashCommandSchema = z.object({ + text: z.string().optional().default(""), + team_id: z.string(), + channel_id: z.string(), + channel_name: z.string().optional(), +}); + +const HELP = [ + "*openstatus*", + "• `/openstatus subscribe ` — subscribe this channel to a status page", + "• `/openstatus unsubscribe ` — unsubscribe", + "• `/openstatus subscriptions` — show this channel's subscriptions", +].join("\n"); + +function ephemeral(c: Context, text: string) { + return c.json({ response_type: "ephemeral", text }); +} + +async function joinChannel(teamId: string, channelId: string): Promise { + try { + const resolved = await resolveWorkspace(teamId); + if (!resolved) return; + const client = new WebClient(resolved.botToken); + await client.conversations.join({ channel: channelId }); + } catch (error) { + // Private channels can't be self-joined — the bot must be /invited. + if (error instanceof Error) { + console.error( + `slack: conversations.join failed for ${channelId}: ${error.message}`, + ); + } + } +} + +export async function handleSlackCommand(c: Context) { + const parsed = slashCommandSchema.safeParse(c.get("slackBody")); + if (!parsed.success) { + return ephemeral(c, "Could not read the command."); + } + const { text, team_id, channel_id, channel_name } = parsed.data; + + const tokens = text.trim().split(/\s+/).filter(Boolean); + const sub = (tokens[0] ?? "help").toLowerCase(); + const arg = tokens[1]; + + if (sub === "subscribe") { + if (!arg) { + return ephemeral(c, "Usage: `/openstatus subscribe `"); + } + const page = await resolvePageFromUrl(arg); + if (!page) { + return ephemeral(c, `Couldn't find a status page at \`${arg}\`.`); + } + try { + const result = await createSlackSubscriber({ + input: { + pageId: page.id, + teamId: team_id, + channelId: channel_id, + channelName: channel_name, + }, + }); + await joinChannel(team_id, channel_id); + if (result.alreadySubscribed) { + return ephemeral( + c, + `This channel is already subscribed to *${page.title}*.`, + ); + } + return ephemeral( + c, + `📡 This channel is now subscribed to *${page.title}*. Incident updates will appear here.`, + ); + } catch (error) { + if (error instanceof ForbiddenError) { + return ephemeral( + c, + `*${page.title}* isn't on a plan that supports subscribers.`, + ); + } + console.error("slack /openstatus subscribe failed:", error); + return ephemeral(c, "Something went wrong subscribing this channel."); + } + } + + if (sub === "unsubscribe") { + if (!arg) { + const subs = await listSlackSubscribersForChannel({ + input: { teamId: team_id, channelId: channel_id }, + }); + if (subs.length === 0) { + return ephemeral( + c, + "This channel isn't subscribed to any status page.", + ); + } + if (subs.length === 1) { + await removeSlackSubscriber({ + input: { + pageId: subs[0].pageId, + teamId: team_id, + channelId: channel_id, + }, + }); + return ephemeral(c, `Unsubscribed from *${subs[0].pageName}*.`); + } + const list = subs.map((s) => `• ${s.pageName}`).join("\n"); + return ephemeral( + c, + `This channel is subscribed to several pages — specify which:\n${list}\n\nUsage: \`/openstatus unsubscribe \``, + ); + } + const page = await resolvePageFromUrl(arg); + if (!page) { + return ephemeral(c, `Couldn't find a status page at \`${arg}\`.`); + } + const { removed } = await removeSlackSubscriber({ + input: { pageId: page.id, teamId: team_id, channelId: channel_id }, + }); + return ephemeral( + c, + removed + ? `Unsubscribed from *${page.title}*.` + : `This channel wasn't subscribed to *${page.title}*.`, + ); + } + + if (sub === "subscriptions") { + const subs = await listSlackSubscribersForChannel({ + input: { teamId: team_id, channelId: channel_id }, + }); + if (subs.length === 0) { + return ephemeral(c, "This channel isn't subscribed to any status page."); + } + const list = subs.map((s) => `• *${s.pageName}*`).join("\n"); + return ephemeral(c, `This channel is subscribed to:\n${list}`); + } + + return ephemeral(c, HELP); +} diff --git a/apps/server/src/routes/slack/handler.ts b/apps/server/src/routes/slack/handler.ts index 2e2012f4..1c972321 100644 --- a/apps/server/src/routes/slack/handler.ts +++ b/apps/server/src/routes/slack/handler.ts @@ -1,6 +1,6 @@ import { getLogger } from "@logtape/logtape"; -import { and, db, eq } from "@openstatus/db"; -import { integration } from "@openstatus/db/src/schema"; +import { and, db, eq, isNull, sql } from "@openstatus/db"; +import { integration, pageSubscriber } from "@openstatus/db/src/schema"; import { WebClient } from "@slack/web-api"; import type { Context } from "hono"; import { z } from "zod"; @@ -123,6 +123,16 @@ async function processEvent(body: SlackEvent) { eq(integration.externalId, teamId), ), ); + await db + .update(pageSubscriber) + .set({ unsubscribedAt: new Date(), updatedAt: new Date() }) + .where( + and( + eq(pageSubscriber.channelType, "slack"), + isNull(pageSubscriber.unsubscribedAt), + sql`json_extract(${pageSubscriber.channelConfig}, '$.teamId') = ${teamId}`, + ), + ); logger.info("slack integration cleaned up", { teamId }); } return; diff --git a/apps/server/src/routes/slack/index.ts b/apps/server/src/routes/slack/index.ts index 74dbde0d..050b687d 100644 --- a/apps/server/src/routes/slack/index.ts +++ b/apps/server/src/routes/slack/index.ts @@ -2,6 +2,7 @@ import { Hono } from "hono"; import { env } from "@/env"; +import { handleSlackCommand } from "./commands"; import { handleSlackEvent } from "./handler"; import { handleSlackInteraction } from "./interactions"; import { handleSlackInstall, handleSlackOAuthCallback } from "./oauth"; @@ -28,5 +29,6 @@ slack.get("/oauth/callback", handleSlackOAuthCallback); slack.post("/events", verifySlackSignature, handleSlackEvent); slack.post("/interactions", verifySlackSignature, handleSlackInteraction); +slack.post("/commands", verifySlackSignature, handleSlackCommand); export { slack as slackRoute }; diff --git a/apps/server/src/routes/slack/oauth.ts b/apps/server/src/routes/slack/oauth.ts index ae88c3ed..636fedd9 100644 --- a/apps/server/src/routes/slack/oauth.ts +++ b/apps/server/src/routes/slack/oauth.ts @@ -19,7 +19,9 @@ const SLACK_TOKEN_URL = "https://slack.com/api/oauth.v2.access"; const BOT_SCOPES = [ "app_mentions:read", "channels:history", + "channels:join", "chat:write", + "commands", "groups:history", "groups:read", "groups:write", diff --git a/apps/server/src/routes/slack/resolve-page.ts b/apps/server/src/routes/slack/resolve-page.ts new file mode 100644 index 00000000..6efa6216 --- /dev/null +++ b/apps/server/src/routes/slack/resolve-page.ts @@ -0,0 +1,69 @@ +import { db, eq, or, sql } from "@openstatus/db"; +import { page } from "@openstatus/db/src/schema"; + +const BASE_DOMAIN_SUFFIX = ".openstatus.dev"; + +export interface ResolvedPage { + id: number; + title: string; + slug: string; + customDomain: string | null; +} + +function hostFromInput(raw: string): string | null { + const trimmed = raw.trim(); + if (!trimmed) return null; + const withScheme = /^https?:\/\//i.test(trimmed) + ? trimmed + : `https://${trimmed}`; + try { + return new URL(withScheme).hostname.toLowerCase(); + } catch { + return null; + } +} + +/** + * Resolve a public status-page URL (or bare host) to its page. Cross-workspace + * by design — Slack subscriptions are public self-signup, like email. + */ +export async function resolvePageFromUrl( + raw: string, +): Promise { + const host = hostFromInput(raw); + if (!host) return null; + + if (host.endsWith(BASE_DOMAIN_SUFFIX)) { + const slug = host.slice(0, -BASE_DOMAIN_SUFFIX.length); + if (!slug || slug.includes(".")) return null; + const row = await db + .select({ + id: page.id, + title: page.title, + slug: page.slug, + customDomain: page.customDomain, + }) + .from(page) + .where(eq(page.slug, slug)) + .get(); + return row ?? null; + } + + const bareHost = host.startsWith("www.") ? host.slice(4) : host; + const row = await db + .select({ + id: page.id, + title: page.title, + slug: page.slug, + customDomain: page.customDomain, + }) + .from(page) + .where( + or( + sql`LOWER(${page.customDomain}) = ${host}`, + sql`LOWER(${page.customDomain}) = ${bareHost}`, + ), + ) + .get(); + return row ?? null; +} diff --git a/apps/server/src/routes/slack/verify.ts b/apps/server/src/routes/slack/verify.ts index 3b1d3fa2..569d30f7 100644 --- a/apps/server/src/routes/slack/verify.ts +++ b/apps/server/src/routes/slack/verify.ts @@ -59,7 +59,12 @@ export const verifySlackSignature = createMiddleware<{ } else if (contentType.includes("application/x-www-form-urlencoded")) { const params = new URLSearchParams(rawBody); const payload = params.get("payload"); - c.set("slackBody", payload ? JSON.parse(payload) : {}); + // Interactions arrive as a `payload` field; slash commands arrive as the + // flat form fields themselves. + c.set( + "slackBody", + payload ? JSON.parse(payload) : Object.fromEntries(params), + ); } await next(); diff --git a/apps/status-page/next-env.d.ts b/apps/status-page/next-env.d.ts index c4b7818f..9edff1c7 100644 --- a/apps/status-page/next-env.d.ts +++ b/apps/status-page/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts deleted file mode 100644 index c05e3b01..00000000 --- a/apps/status-page/src/app/api/trpc/edge/[trpc]/route.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { createTRPCContext } from "@openstatus/api"; -import { edgeRouter } from "@openstatus/api/src/edge"; -import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import type { NextRequest } from "next/server"; - -import { auth } from "../../../../../lib/auth"; -import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; - -export const runtime = "edge"; - -const handler = (req: NextRequest) => { - const blocked = guardTRPCSource(req); - if (blocked) return blocked; - - return fetchRequestHandler({ - endpoint: "/api/trpc/edge", - router: edgeRouter, - req: req, - createContext: () => createTRPCContext({ req, auth }), - onError: createOnError("edge"), - }); -}; - -export { handler as GET, handler as POST }; diff --git a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts index f17aa817..f3c1eef8 100644 --- a/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/status-page/src/app/api/trpc/lambda/[trpc]/route.ts @@ -1,13 +1,13 @@ -import { createTRPCContext } from "@openstatus/api"; -import { lambdaRouter } from "@openstatus/api/src/lambda"; +import { appRouter, createTRPCContext } from "@openstatus/api"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; import { auth } from "../../../../../lib/auth"; import { createOnError, guardTRPCSource } from "../../../../../lib/trpc/shared"; -// Stripe is incompatible with Edge runtimes due to using Node.js events -// export const runtime = "edge"; +// Runs on the Node.js runtime (Vercel Fluid compute). The whole tRPC surface +// is served here — several routers pull Node-only deps (@slack/web-api, email +// and notification SDKs) that are not Edge-safe. const handler = (req: NextRequest) => { const blocked = guardTRPCSource(req); @@ -15,7 +15,7 @@ const handler = (req: NextRequest) => { return fetchRequestHandler({ endpoint: "/api/trpc/lambda", - router: lambdaRouter, + router: appRouter, req: req, createContext: () => createTRPCContext({ req, auth }), onError: createOnError("lambda"), diff --git a/apps/status-page/src/lib/trpc/shared.ts b/apps/status-page/src/lib/trpc/shared.ts index 23df75bf..f1b1516d 100644 --- a/apps/status-page/src/lib/trpc/shared.ts +++ b/apps/status-page/src/lib/trpc/shared.ts @@ -48,37 +48,18 @@ const getBaseUrl = () => { return "http://localhost:3000"; // Local dev and Docker (internal calls) }; -const lambdas = ["stripeRouter", "emailRouter"]; - -export const endingLink = (opts?: { - fetch?: typeof fetch; - headers?: HTTPHeaders | (() => HTTPHeaders | Promise); -}) => - ((runtime) => { - const sharedOpts = { +// The whole tRPC surface is served from a single Node.js endpoint — there is +// no longer an Edge/Node split, so all calls go to one link. +export const endingLink = + (opts?: { + fetch?: typeof fetch; + headers?: HTTPHeaders | (() => HTTPHeaders | Promise); + }): TRPCLink => + (runtime) => + httpBatchLink({ headers: opts?.headers, fetch: opts?.fetch, transformer: superjson, - // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any - } satisfies Partial>; - - const edgeLink = httpBatchLink({ - ...sharedOpts, - url: `${getBaseUrl()}/api/trpc/edge`, - })(runtime); - const lambdaLink = httpBatchLink({ - ...sharedOpts, url: `${getBaseUrl()}/api/trpc/lambda`, - })(runtime); - - return (ctx) => { - const path = ctx.op.path.split(".") as [string, ...string[]]; - const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; - - const newCtx = { - ...ctx, - op: { ...ctx.op, path: path.join(".") }, - }; - return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); - }; - }) satisfies TRPCLink; + // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any + } satisfies Partial>)(runtime); diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index c4b7818f..9edff1c7 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts b/apps/web/src/app/api/trpc/edge/[trpc]/route.ts deleted file mode 100644 index 5a339780..00000000 --- a/apps/web/src/app/api/trpc/edge/[trpc]/route.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createTRPCContext } from "@openstatus/api"; -import { edgeRouter } from "@openstatus/api/src/edge"; -import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; -import type { NextRequest } from "next/server"; - -import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; - -export const runtime = "edge"; - -const handler = (req: NextRequest) => { - const blocked = guardTRPCSource(req); - if (blocked) return blocked; - - return fetchRequestHandler({ - endpoint: "/api/trpc/edge", - router: edgeRouter, - req: req, - createContext: () => createTRPCContext({ req }), - onError: createOnError("edge"), - }); -}; - -export { handler as GET, handler as POST }; diff --git a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts index ddbd1dbb..477427b3 100644 --- a/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/lambda/[trpc]/route.ts @@ -1,12 +1,12 @@ -import { createTRPCContext } from "@openstatus/api"; -import { lambdaRouter } from "@openstatus/api/src/lambda"; +import { appRouter, createTRPCContext } from "@openstatus/api"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import type { NextRequest } from "next/server"; import { createOnError, guardTRPCSource } from "../../../../../trpc/shared"; -// Stripe is incompatible with Edge runtimes due to using Node.js events -// export const runtime = "edge"; +// Runs on the Node.js runtime (Vercel Fluid compute). The whole tRPC surface +// is served here — several routers pull Node-only deps (@slack/web-api, email +// and notification SDKs) that are not Edge-safe. const handler = (req: NextRequest) => { const blocked = guardTRPCSource(req); @@ -14,7 +14,7 @@ const handler = (req: NextRequest) => { return fetchRequestHandler({ endpoint: "/api/trpc/lambda", - router: lambdaRouter, + router: appRouter, req: req, createContext: () => createTRPCContext({ req }), onError: createOnError("lambda"), diff --git a/apps/web/src/trpc/shared.ts b/apps/web/src/trpc/shared.ts index 22730388..72087789 100644 --- a/apps/web/src/trpc/shared.ts +++ b/apps/web/src/trpc/shared.ts @@ -35,35 +35,16 @@ const getBaseUrl = () => { return "http://localhost:3000"; // Local dev }; -const lambdas = ["stripeRouter", "emailRouter"]; - -export const endingLink = (opts?: { - headers?: HTTPHeaders | (() => HTTPHeaders | Promise); -}) => - ((runtime) => { - const sharedOpts = { +// The whole tRPC surface is served from a single Node.js endpoint — there is +// no longer an Edge/Node split, so all calls go to one link. +export const endingLink = + (opts?: { + headers?: HTTPHeaders | (() => HTTPHeaders | Promise); + }): TRPCLink => + (runtime) => + httpBatchLink({ headers: opts?.headers, // REMINDER: fails when trying to `getTotalActiveMonitors()` transformer: superjson, - // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any - } satisfies Partial>; - - const edgeLink = httpBatchLink({ - ...sharedOpts, - url: `${getBaseUrl()}/api/trpc/edge`, - })(runtime); - const lambdaLink = httpBatchLink({ - ...sharedOpts, url: `${getBaseUrl()}/api/trpc/lambda`, - })(runtime); - - return (ctx) => { - const path = ctx.op.path.split(".") as [string, ...string[]]; - const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; - - const newCtx = { - ...ctx, - op: { ...ctx.op, path: path.join(".") }, - }; - return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); - }; - }) satisfies TRPCLink; + // oxlint-disable-next-line typescript/no-explicit-any -- FIXME: remove any + } satisfies Partial>)(runtime); diff --git a/deno.lock b/deno.lock index ce3a1683..89e71aa7 100644 --- a/deno.lock +++ b/deno.lock @@ -264,6 +264,14 @@ ] } }, + "packages/tinybird": { + "packageJson": { + "dependencies": [ + "npm:@jsr/std__expect@^1.0.19", + "npm:@jsr/std__testing@^1.0.19" + ] + } + }, "packages/tracker": { "packageJson": { "dependencies": [ diff --git a/packages/analytics/src/server.ts b/packages/analytics/src/server.ts index 780ef16e..799266b9 100644 --- a/packages/analytics/src/server.ts +++ b/packages/analytics/src/server.ts @@ -3,15 +3,24 @@ import { OpenPanel, type TrackProperties } from "@openpanel/sdk"; import { env } from "../env"; import type { EventProps } from "./events"; -const op = new OpenPanel({ - clientId: env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID, - clientSecret: env.OPENPANEL_CLIENT_SECRET, -}); +// Lazily instantiate so importing this module has no side effects — a top-level +// `new OpenPanel()` runs the node SDK at import time, which breaks bundling the +// tRPC context into the Edge runtime. +let client: OpenPanel | undefined; -op.setGlobalProperties({ - env: process.env.VERCEL_ENV || process.env.NODE_ENV || "localhost", - // app_version -}); +function getClient() { + if (!client) { + client = new OpenPanel({ + clientId: env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID, + clientSecret: env.OPENPANEL_CLIENT_SECRET, + }); + client.setGlobalProperties({ + env: process.env.VERCEL_ENV || process.env.NODE_ENV || "localhost", + // app_version + }); + } + return client; +} export type IdentifyProps = { userId?: string; @@ -29,6 +38,8 @@ export async function setupAnalytics(props: IdentifyProps) { return noop(); } + const op = getClient(); + if (props.location) { op.api.addHeader("x-client-ip", props.location); } diff --git a/packages/db/drizzle/0078_yellow_thor_girl.sql b/packages/db/drizzle/0078_yellow_thor_girl.sql new file mode 100644 index 00000000..c9acaa90 --- /dev/null +++ b/packages/db/drizzle/0078_yellow_thor_girl.sql @@ -0,0 +1,28 @@ +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_page_subscriber` ( + `id` integer PRIMARY KEY NOT NULL, + `email` text, + `page_id` integer NOT NULL, + `channel_type` text DEFAULT 'email' NOT NULL, + `webhook_url` text, + `channel_config` text, + `slack_channel_id` text, + `source` text DEFAULT 'self_signup' NOT NULL, + `name` text, + `token` text, + `accepted_at` integer, + `expires_at` integer, + `unsubscribed_at` integer, + `created_at` integer DEFAULT (strftime('%s', 'now')), + `updated_at` integer DEFAULT (strftime('%s', 'now')), + FOREIGN KEY (`page_id`) REFERENCES `page`(`id`) ON UPDATE no action ON DELETE cascade, + CONSTRAINT "page_subscriber_channel_check" CHECK(("__new_page_subscriber"."channel_type" = 'email' AND "__new_page_subscriber"."email" IS NOT NULL AND "__new_page_subscriber"."webhook_url" IS NULL) OR ("__new_page_subscriber"."channel_type" = 'webhook' AND "__new_page_subscriber"."webhook_url" IS NOT NULL AND "__new_page_subscriber"."email" IS NULL) OR ("__new_page_subscriber"."channel_type" = 'slack' AND "__new_page_subscriber"."slack_channel_id" IS NOT NULL AND "__new_page_subscriber"."email" IS NULL AND "__new_page_subscriber"."webhook_url" IS NULL)) +); +--> statement-breakpoint +INSERT INTO `__new_page_subscriber`("id", "email", "page_id", "channel_type", "webhook_url", "channel_config", "slack_channel_id", "source", "name", "token", "accepted_at", "expires_at", "unsubscribed_at", "created_at", "updated_at") SELECT "id", "email", "page_id", "channel_type", "webhook_url", "channel_config", NULL, "source", "name", "token", "accepted_at", "expires_at", "unsubscribed_at", "created_at", "updated_at" FROM `page_subscriber`;--> statement-breakpoint +DROP TABLE `page_subscriber`;--> statement-breakpoint +ALTER TABLE `__new_page_subscriber` RENAME TO `page_subscriber`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +CREATE UNIQUE INDEX `idx_page_subscriber_email_page_active` ON `page_subscriber` (LOWER("email"), `page_id`) WHERE "page_subscriber"."unsubscribed_at" IS NULL AND "page_subscriber"."channel_type" = 'email';--> statement-breakpoint +CREATE UNIQUE INDEX `idx_page_subscriber_webhook_page_active` ON `page_subscriber` (LOWER("webhook_url"), `page_id`) WHERE "page_subscriber"."unsubscribed_at" IS NULL AND "page_subscriber"."channel_type" = 'webhook';--> statement-breakpoint +CREATE UNIQUE INDEX `idx_page_subscriber_slack_channel_page_active` ON `page_subscriber` (`slack_channel_id`, `page_id`) WHERE "page_subscriber"."unsubscribed_at" IS NULL AND "page_subscriber"."channel_type" = 'slack'; diff --git a/packages/db/drizzle/meta/0078_snapshot.json b/packages/db/drizzle/meta/0078_snapshot.json new file mode 100644 index 00000000..8230a90f --- /dev/null +++ b/packages/db/drizzle/meta/0078_snapshot.json @@ -0,0 +1,4712 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "80571dfe-ab0e-4531-823b-33173cedf9a2", + "prevId": "e88d56a5-ae87-4b25-9d59-1153f97a63bb", + "tables": { + "workspace": { + "name": "workspace", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ends_at": { + "name": "ends_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "paid_until": { + "name": "paid_until", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "limits": { + "name": "limits", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "dsn": { + "name": "dsn", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "workspace_slug_unique": { + "name": "workspace_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "workspace_stripe_id_unique": { + "name": "workspace_stripe_id_unique", + "columns": [ + "stripe_id" + ], + "isUnique": true + }, + "workspace_id_dsn_unique": { + "name": "workspace_id_dsn_unique", + "columns": [ + "id", + "dsn" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "account": { + "name": "account", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_provider_account_id_pk": { + "columns": [ + "provider", + "provider_account_id" + ], + "name": "account_provider_provider_account_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "tenant_id": { + "name": "tenant_id", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "photo_url": { + "name": "photo_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "emailVerified": { + "name": "emailVerified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_tenant_id_unique": { + "name": "user_tenant_id_unique", + "columns": [ + "tenant_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users_to_workspaces": { + "name": "users_to_workspaces", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "users_to_workspaces_workspace_id_idx": { + "name": "users_to_workspaces_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "users_to_workspaces_user_id_user_id_fk": { + "name": "users_to_workspaces_user_id_user_id_fk", + "tableFrom": "users_to_workspaces", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "users_to_workspaces_workspace_id_workspace_id_fk": { + "name": "users_to_workspaces_workspace_id_workspace_id_fk", + "tableFrom": "users_to_workspaces", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "users_to_workspaces_user_id_workspace_id_pk": { + "columns": [ + "user_id", + "workspace_id" + ], + "name": "users_to_workspaces_user_id_workspace_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "verification_token": { + "name": "verification_token", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verification_token_identifier_token_pk": { + "columns": [ + "identifier", + "token" + ], + "name": "verification_token_identifier_token_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report": { + "name": "status_report", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_workspace_created_idx": { + "name": "status_report_workspace_created_idx", + "columns": [ + "workspace_id", + "created_at" + ], + "isUnique": false + }, + "status_report_page_id_idx": { + "name": "status_report_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_workspace_id_workspace_id_fk": { + "name": "status_report_workspace_id_workspace_id_fk", + "tableFrom": "status_report", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "status_report_page_id_page_id_fk": { + "name": "status_report_page_id_page_id_fk", + "tableFrom": "status_report", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report_update": { + "name": "status_report_update", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status_report_id": { + "name": "status_report_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_update_status_report_id_idx": { + "name": "status_report_update_status_report_id_idx", + "columns": [ + "status_report_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_update_status_report_id_status_report_id_fk": { + "name": "status_report_update_status_report_id_status_report_id_fk", + "tableFrom": "status_report_update", + "tableTo": "status_report", + "columnsFrom": [ + "status_report_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integration": { + "name": "integration", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credential": { + "name": "credential", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "integration_workspace_id_idx": { + "name": "integration_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integration_workspace_id_workspace_id_fk": { + "name": "integration_workspace_id_workspace_id_fk", + "tableFrom": "integration", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page": { + "name": "page", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "slug": { + "name": "slug", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "custom_domain": { + "name": "custom_domain", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "published": { + "name": "published", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "force_theme": { + "name": "force_theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'system'" + }, + "password": { + "name": "password", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password_protected": { + "name": "password_protected", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "access_type": { + "name": "access_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'public'" + }, + "auth_email_domains": { + "name": "auth_email_domains", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allowed_ip_ranges": { + "name": "allowed_ip_ranges", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "homepage_url": { + "name": "homepage_url", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "contact_url": { + "name": "contact_url", + "type": "text(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_locale": { + "name": "default_locale", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'en'" + }, + "locales": { + "name": "locales", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "legacy_page": { + "name": "legacy_page", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "configuration": { + "name": "configuration", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allow_index": { + "name": "allow_index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "show_monitor_values": { + "name": "show_monitor_values", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_slug_unique": { + "name": "page_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "page_lower_slug_idx": { + "name": "page_lower_slug_idx", + "columns": [ + "LOWER(\"slug\")" + ], + "isUnique": false + }, + "page_lower_custom_domain_idx": { + "name": "page_lower_custom_domain_idx", + "columns": [ + "LOWER(\"custom_domain\")" + ], + "isUnique": false + }, + "page_workspace_id_idx": { + "name": "page_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "page_workspace_id_workspace_id_fk": { + "name": "page_workspace_id_workspace_id_fk", + "tableFrom": "page", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor": { + "name": "monitor", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "job_type": { + "name": "job_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'http'" + }, + "periodicity": { + "name": "periodicity", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'other'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "active": { + "name": "active", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "regions": { + "name": "regions", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "url": { + "name": "url", + "type": "text(2048)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "external_name": { + "name": "external_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "headers": { + "name": "headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'GET'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "timeout": { + "name": "timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 45000 + }, + "degraded_after": { + "name": "degraded_after", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "assertions": { + "name": "assertions", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "otel_endpoint": { + "name": "otel_endpoint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "otel_headers": { + "name": "otel_headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public": { + "name": "public", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "retry": { + "name": "retry", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 3 + }, + "follow_redirects": { + "name": "follow_redirects", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "monitor_workspace_id_active_idx": { + "name": "monitor_workspace_id_active_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false, + "where": "\"monitor\".\"deleted_at\" IS NULL" + } + }, + "foreignKeys": { + "monitor_workspace_id_workspace_id_fk": { + "name": "monitor_workspace_id_workspace_id_fk", + "tableFrom": "monitor", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_subscriber": { + "name": "page_subscriber", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_type": { + "name": "channel_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'email'" + }, + "webhook_url": { + "name": "webhook_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "channel_config": { + "name": "channel_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "slack_channel_id": { + "name": "slack_channel_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'self_signup'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "accepted_at": { + "name": "accepted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "unsubscribed_at": { + "name": "unsubscribed_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "idx_page_subscriber_email_page_active": { + "name": "idx_page_subscriber_email_page_active", + "columns": [ + "LOWER(\"email\")", + "page_id" + ], + "isUnique": true, + "where": "\"page_subscriber\".\"unsubscribed_at\" IS NULL AND \"page_subscriber\".\"channel_type\" = 'email'" + }, + "idx_page_subscriber_webhook_page_active": { + "name": "idx_page_subscriber_webhook_page_active", + "columns": [ + "LOWER(\"webhook_url\")", + "page_id" + ], + "isUnique": true, + "where": "\"page_subscriber\".\"unsubscribed_at\" IS NULL AND \"page_subscriber\".\"channel_type\" = 'webhook'" + }, + "idx_page_subscriber_slack_channel_page_active": { + "name": "idx_page_subscriber_slack_channel_page_active", + "columns": [ + "slack_channel_id", + "page_id" + ], + "isUnique": true, + "where": "\"page_subscriber\".\"unsubscribed_at\" IS NULL AND \"page_subscriber\".\"channel_type\" = 'slack'" + } + }, + "foreignKeys": { + "page_subscriber_page_id_page_id_fk": { + "name": "page_subscriber_page_id_page_id_fk", + "tableFrom": "page_subscriber", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "page_subscriber_channel_check": { + "name": "page_subscriber_channel_check", + "value": "(\"page_subscriber\".\"channel_type\" = 'email' AND \"page_subscriber\".\"email\" IS NOT NULL AND \"page_subscriber\".\"webhook_url\" IS NULL) OR (\"page_subscriber\".\"channel_type\" = 'webhook' AND \"page_subscriber\".\"webhook_url\" IS NOT NULL AND \"page_subscriber\".\"email\" IS NULL) OR (\"page_subscriber\".\"channel_type\" = 'slack' AND \"page_subscriber\".\"slack_channel_id\" IS NOT NULL AND \"page_subscriber\".\"email\" IS NULL AND \"page_subscriber\".\"webhook_url\" IS NULL)" + } + } + }, + "page_subscriber_to_page_component": { + "name": "page_subscriber_to_page_component", + "columns": { + "page_subscriber_id": { + "name": "page_subscriber_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": {}, + "foreignKeys": { + "page_subscriber_to_page_component_page_subscriber_id_page_subscriber_id_fk": { + "name": "page_subscriber_to_page_component_page_subscriber_id_page_subscriber_id_fk", + "tableFrom": "page_subscriber_to_page_component", + "tableTo": "page_subscriber", + "columnsFrom": [ + "page_subscriber_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_subscriber_to_page_component_page_component_id_page_component_id_fk": { + "name": "page_subscriber_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "page_subscriber_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "page_subscriber_to_page_component_page_subscriber_id_page_component_id_pk": { + "columns": [ + "page_subscriber_id", + "page_component_id" + ], + "name": "page_subscriber_to_page_component_page_subscriber_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notification": { + "name": "notification", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'{}'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "notification_workspace_id_idx": { + "name": "notification_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "notification_workspace_id_workspace_id_fk": { + "name": "notification_workspace_id_workspace_id_fk", + "tableFrom": "notification", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notification_trigger": { + "name": "notification_trigger", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "notification_id": { + "name": "notification_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "cron_timestamp": { + "name": "cron_timestamp", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "notification_id_monitor_id_crontimestampe": { + "name": "notification_id_monitor_id_crontimestampe", + "columns": [ + "notification_id", + "monitor_id", + "cron_timestamp" + ], + "isUnique": true + } + }, + "foreignKeys": { + "notification_trigger_monitor_id_monitor_id_fk": { + "name": "notification_trigger_monitor_id_monitor_id_fk", + "tableFrom": "notification_trigger", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_trigger_notification_id_notification_id_fk": { + "name": "notification_trigger_notification_id_notification_id_fk", + "tableFrom": "notification_trigger", + "tableTo": "notification", + "columnsFrom": [ + "notification_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "notifications_to_monitors": { + "name": "notifications_to_monitors", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notification_id": { + "name": "notification_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "notifications_to_monitors_notification_id_idx": { + "name": "notifications_to_monitors_notification_id_idx", + "columns": [ + "notification_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "notifications_to_monitors_monitor_id_monitor_id_fk": { + "name": "notifications_to_monitors_monitor_id_monitor_id_fk", + "tableFrom": "notifications_to_monitors", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notifications_to_monitors_notification_id_notification_id_fk": { + "name": "notifications_to_monitors_notification_id_notification_id_fk", + "tableFrom": "notifications_to_monitors", + "tableTo": "notification", + "columnsFrom": [ + "notification_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "notifications_to_monitors_monitor_id_notification_id_pk": { + "columns": [ + "monitor_id", + "notification_id" + ], + "name": "notifications_to_monitors_monitor_id_notification_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_status": { + "name": "monitor_status", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'active'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_status_idx": { + "name": "monitor_status_idx", + "columns": [ + "monitor_id", + "region" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_status_monitor_id_monitor_id_fk": { + "name": "monitor_status_monitor_id_monitor_id_fk", + "tableFrom": "monitor_status", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "monitor_status_monitor_id_region_pk": { + "columns": [ + "monitor_id", + "region" + ], + "name": "monitor_status_monitor_id_region_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "invitation": { + "name": "invitation", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'member'" + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "accepted_at": { + "name": "accepted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "invitation_workspace_id_idx": { + "name": "invitation_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "incident": { + "name": "incident", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'triage'" + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "acknowledged_at": { + "name": "acknowledged_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "acknowledged_by": { + "name": "acknowledged_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolved_by": { + "name": "resolved_by", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "incident_screenshot_url": { + "name": "incident_screenshot_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "recovery_screenshot_url": { + "name": "recovery_screenshot_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "auto_resolved": { + "name": "auto_resolved", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "incident_workspace_id_idx": { + "name": "incident_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "incident_monitor_id_started_at_unique": { + "name": "incident_monitor_id_started_at_unique", + "columns": [ + "monitor_id", + "started_at" + ], + "isUnique": true + } + }, + "foreignKeys": { + "incident_monitor_id_monitor_id_fk": { + "name": "incident_monitor_id_monitor_id_fk", + "tableFrom": "incident", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set default", + "onUpdate": "no action" + }, + "incident_workspace_id_workspace_id_fk": { + "name": "incident_workspace_id_workspace_id_fk", + "tableFrom": "incident", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "incident_acknowledged_by_user_id_fk": { + "name": "incident_acknowledged_by_user_id_fk", + "tableFrom": "incident", + "tableTo": "user", + "columnsFrom": [ + "acknowledged_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "incident_resolved_by_user_id_fk": { + "name": "incident_resolved_by_user_id_fk", + "tableFrom": "incident", + "tableTo": "user", + "columnsFrom": [ + "resolved_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_tag": { + "name": "monitor_tag", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_tag_workspace_id_idx": { + "name": "monitor_tag_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_tag_workspace_id_workspace_id_fk": { + "name": "monitor_tag_workspace_id_workspace_id_fk", + "tableFrom": "monitor_tag", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_tag_to_monitor": { + "name": "monitor_tag_to_monitor", + "columns": { + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monitor_tag_id": { + "name": "monitor_tag_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_tag_to_monitor_monitor_tag_id_idx": { + "name": "monitor_tag_to_monitor_monitor_tag_id_idx", + "columns": [ + "monitor_tag_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_tag_to_monitor_monitor_id_monitor_id_fk": { + "name": "monitor_tag_to_monitor_monitor_id_monitor_id_fk", + "tableFrom": "monitor_tag_to_monitor", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk": { + "name": "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk", + "tableFrom": "monitor_tag_to_monitor", + "tableTo": "monitor_tag", + "columnsFrom": [ + "monitor_tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk": { + "columns": [ + "monitor_id", + "monitor_tag_id" + ], + "name": "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "application": { + "name": "application", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dsn": { + "name": "dsn", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "application_dsn_unique": { + "name": "application_dsn_unique", + "columns": [ + "dsn" + ], + "isUnique": true + }, + "application_workspace_id_idx": { + "name": "application_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "application_workspace_id_workspace_id_fk": { + "name": "application_workspace_id_workspace_id_fk", + "tableFrom": "application", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance": { + "name": "maintenance", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "from": { + "name": "from", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "to": { + "name": "to", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "maintenance_page_id_idx": { + "name": "maintenance_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + }, + "maintenance_workspace_id_idx": { + "name": "maintenance_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "maintenance_workspace_id_workspace_id_fk": { + "name": "maintenance_workspace_id_workspace_id_fk", + "tableFrom": "maintenance", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "maintenance_page_id_page_id_fk": { + "name": "maintenance_page_id_page_id_fk", + "tableFrom": "maintenance", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "check": { + "name": "check", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "regions": { + "name": "regions", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "url": { + "name": "url", + "type": "text(4096)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "headers": { + "name": "headers", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "''" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'GET'" + }, + "count_requests": { + "name": "count_requests", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 1 + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "check_workspace_id_idx": { + "name": "check_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "check_workspace_id_workspace_id_fk": { + "name": "check_workspace_id_workspace_id_fk", + "tableFrom": "check", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_run": { + "name": "monitor_run", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "runned_at": { + "name": "runned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_run_workspace_id_idx": { + "name": "monitor_run_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "monitor_run_monitor_id_idx": { + "name": "monitor_run_monitor_id_idx", + "columns": [ + "monitor_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_run_workspace_id_workspace_id_fk": { + "name": "monitor_run_workspace_id_workspace_id_fk", + "tableFrom": "monitor_run", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "monitor_run_monitor_id_monitor_id_fk": { + "name": "monitor_run_monitor_id_monitor_id_fk", + "tableFrom": "monitor_run", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "private_location": { + "name": "private_location", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "private_location_workspace_id_idx": { + "name": "private_location_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "private_location_workspace_id_workspace_id_fk": { + "name": "private_location_workspace_id_workspace_id_fk", + "tableFrom": "private_location", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "private_location_to_monitor": { + "name": "private_location_to_monitor", + "columns": { + "private_location_id": { + "name": "private_location_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "private_location_to_monitor_private_location_id_idx": { + "name": "private_location_to_monitor_private_location_id_idx", + "columns": [ + "private_location_id" + ], + "isUnique": false + }, + "private_location_to_monitor_monitor_id_idx": { + "name": "private_location_to_monitor_monitor_id_idx", + "columns": [ + "monitor_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "private_location_to_monitor_private_location_id_private_location_id_fk": { + "name": "private_location_to_monitor_private_location_id_private_location_id_fk", + "tableFrom": "private_location_to_monitor", + "tableTo": "private_location", + "columnsFrom": [ + "private_location_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "private_location_to_monitor_monitor_id_monitor_id_fk": { + "name": "private_location_to_monitor_monitor_id_monitor_id_fk", + "tableFrom": "private_location_to_monitor", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "monitor_group": { + "name": "monitor_group", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "monitor_group_workspace_id_idx": { + "name": "monitor_group_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "monitor_group_page_id_idx": { + "name": "monitor_group_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "monitor_group_workspace_id_workspace_id_fk": { + "name": "monitor_group_workspace_id_workspace_id_fk", + "tableFrom": "monitor_group", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "monitor_group_page_id_page_id_fk": { + "name": "monitor_group_page_id_page_id_fk", + "tableFrom": "monitor_group", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer": { + "name": "viewer", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "emailVerified": { + "name": "emailVerified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "viewer_email_unique": { + "name": "viewer_email_unique", + "columns": [ + "email" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer_accounts": { + "name": "viewer_accounts", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "viewer_accounts_user_id_viewer_id_fk": { + "name": "viewer_accounts_user_id_viewer_id_fk", + "tableFrom": "viewer_accounts", + "tableTo": "viewer", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "viewer_accounts_provider_providerAccountId_pk": { + "columns": [ + "provider", + "providerAccountId" + ], + "name": "viewer_accounts_provider_providerAccountId_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "viewer_session": { + "name": "viewer_session", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "viewer_session_user_id_viewer_id_fk": { + "name": "viewer_session_user_id_viewer_id_fk", + "tableFrom": "viewer_session", + "tableTo": "viewer", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "api_key": { + "name": "api_key", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "hashed_token": { + "name": "hashed_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "scopes": { + "name": "scopes", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[\"write\"]'" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "api_key_prefix_unique": { + "name": "api_key_prefix_unique", + "columns": [ + "prefix" + ], + "isUnique": true + }, + "api_key_hashed_token_unique": { + "name": "api_key_hashed_token_unique", + "columns": [ + "hashed_token" + ], + "isUnique": true + }, + "api_key_prefix_idx": { + "name": "api_key_prefix_idx", + "columns": [ + "prefix" + ], + "isUnique": false + }, + "api_key_workspace_id_idx": { + "name": "api_key_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "api_key_workspace_id_workspace_id_fk": { + "name": "api_key_workspace_id_workspace_id_fk", + "tableFrom": "api_key", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "api_key_created_by_id_user_id_fk": { + "name": "api_key_created_by_id_user_id_fk", + "tableFrom": "api_key", + "tableTo": "user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance_to_page_component": { + "name": "maintenance_to_page_component", + "columns": { + "maintenance_id": { + "name": "maintenance_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "maintenance_to_page_component_page_component_id_idx": { + "name": "maintenance_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "maintenance_to_page_component_maintenance_id_maintenance_id_fk": { + "name": "maintenance_to_page_component_maintenance_id_maintenance_id_fk", + "tableFrom": "maintenance_to_page_component", + "tableTo": "maintenance", + "columnsFrom": [ + "maintenance_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "maintenance_to_page_component_page_component_id_page_component_id_fk": { + "name": "maintenance_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "maintenance_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "maintenance_to_page_component_maintenance_id_page_component_id_pk": { + "columns": [ + "maintenance_id", + "page_component_id" + ], + "name": "maintenance_to_page_component_maintenance_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_component": { + "name": "page_component", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'monitor'" + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_order": { + "name": "group_order", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_component_workspace_id_idx": { + "name": "page_component_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "page_component_page_id_monitor_id_unique": { + "name": "page_component_page_id_monitor_id_unique", + "columns": [ + "page_id", + "monitor_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "page_component_workspace_id_workspace_id_fk": { + "name": "page_component_workspace_id_workspace_id_fk", + "tableFrom": "page_component", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_page_id_page_id_fk": { + "name": "page_component_page_id_page_id_fk", + "tableFrom": "page_component", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_monitor_id_monitor_id_fk": { + "name": "page_component_monitor_id_monitor_id_fk", + "tableFrom": "page_component", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_group_id_page_component_groups_id_fk": { + "name": "page_component_group_id_page_component_groups_id_fk", + "tableFrom": "page_component", + "tableTo": "page_component_groups", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "page_component_type_check": { + "name": "page_component_type_check", + "value": "\"page_component\".\"type\" = 'monitor' AND \"page_component\".\"monitor_id\" IS NOT NULL OR \"page_component\".\"type\" = 'static' AND \"page_component\".\"monitor_id\" IS NULL" + } + } + }, + "status_report_update_to_page_component": { + "name": "status_report_update_to_page_component", + "columns": { + "status_report_update_id": { + "name": "status_report_update_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "impact": { + "name": "impact", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_update_to_page_component_page_component_id_idx": { + "name": "status_report_update_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_update_to_page_component_status_report_update_id_status_report_update_id_fk": { + "name": "status_report_update_to_page_component_status_report_update_id_status_report_update_id_fk", + "tableFrom": "status_report_update_to_page_component", + "tableTo": "status_report_update", + "columnsFrom": [ + "status_report_update_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "status_report_update_to_page_component_page_component_id_page_component_id_fk": { + "name": "status_report_update_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "status_report_update_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "status_report_update_to_page_component_status_report_update_id_page_component_id_pk": { + "columns": [ + "status_report_update_id", + "page_component_id" + ], + "name": "status_report_update_to_page_component_status_report_update_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "status_report_to_page_component": { + "name": "status_report_to_page_component", + "columns": { + "status_report_id": { + "name": "status_report_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_component_id": { + "name": "page_component_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "status_report_to_page_component_page_component_id_idx": { + "name": "status_report_to_page_component_page_component_id_idx", + "columns": [ + "page_component_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "status_report_to_page_component_status_report_id_status_report_id_fk": { + "name": "status_report_to_page_component_status_report_id_status_report_id_fk", + "tableFrom": "status_report_to_page_component", + "tableTo": "status_report", + "columnsFrom": [ + "status_report_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "status_report_to_page_component_page_component_id_page_component_id_fk": { + "name": "status_report_to_page_component_page_component_id_page_component_id_fk", + "tableFrom": "status_report_to_page_component", + "tableTo": "page_component", + "columnsFrom": [ + "page_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "status_report_to_page_component_status_report_id_page_component_id_pk": { + "columns": [ + "status_report_id", + "page_component_id" + ], + "name": "status_report_to_page_component_status_report_id_page_component_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "page_component_groups": { + "name": "page_component_groups", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "page_id": { + "name": "page_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_open": { + "name": "default_open", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "page_component_groups_page_id_idx": { + "name": "page_component_groups_page_id_idx", + "columns": [ + "page_id" + ], + "isUnique": false + }, + "page_component_groups_workspace_id_idx": { + "name": "page_component_groups_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "page_component_groups_workspace_id_workspace_id_fk": { + "name": "page_component_groups_workspace_id_workspace_id_fk", + "tableFrom": "page_component_groups", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "page_component_groups_page_id_page_id_fk": { + "name": "page_component_groups_page_id_page_id_fk", + "tableFrom": "page_component_groups", + "tableTo": "page", + "columnsFrom": [ + "page_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "feedback": { + "name": "feedback", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "blocker": { + "name": "blocker", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "feedback_workspace_id_idx": { + "name": "feedback_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "feedback_workspace_id_workspace_id_fk": { + "name": "feedback_workspace_id_workspace_id_fk", + "tableFrom": "feedback", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "feedback_user_id_user_id_fk": { + "name": "feedback_user_id_user_id_fk", + "tableFrom": "feedback", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "audit_log": { + "name": "audit_log", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_type": { + "name": "actor_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "before": { + "name": "before", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "after": { + "name": "after", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "changed_fields": { + "name": "changed_fields", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "audit_log_workspace_created_idx": { + "name": "audit_log_workspace_created_idx", + "columns": [ + "workspace_id", + "created_at" + ], + "isUnique": false + }, + "audit_log_entity_idx": { + "name": "audit_log_entity_idx", + "columns": [ + "workspace_id", + "entity_type", + "entity_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service": { + "name": "external_service", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "aliases": { + "name": "aliases", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(json_array())" + }, + "name": { + "name": "name", + "type": "text(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status_page_url": { + "name": "status_page_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "industry": { + "name": "industry", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "api_config": { + "name": "api_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_slug_unique": { + "name": "external_service_slug_unique", + "columns": [ + "slug" + ], + "isUnique": true + }, + "external_service_deleted_at_idx": { + "name": "external_service_deleted_at_idx", + "columns": [ + "deleted_at" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_component": { + "name": "external_service_component", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "upstream_component_id": { + "name": "upstream_component_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "aliases": { + "name": "aliases", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(json_array())" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + }, + "indicator": { + "name": "indicator", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_component_unique_idx": { + "name": "external_service_component_unique_idx", + "columns": [ + "external_service_id", + "upstream_component_id" + ], + "isUnique": true + }, + "external_service_component_slug_unique_idx": { + "name": "external_service_component_slug_unique_idx", + "columns": [ + "external_service_id", + "slug" + ], + "isUnique": true + } + }, + "foreignKeys": { + "external_service_component_external_service_id_external_service_id_fk": { + "name": "external_service_component_external_service_id_external_service_id_fk", + "tableFrom": "external_service_component", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_incident": { + "name": "external_service_incident", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_incident_id": { + "name": "provider_incident_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "impact": { + "name": "impact", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "shortlink": { + "name": "shortlink", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "started_at": { + "name": "started_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "affected_component_ids": { + "name": "affected_component_ids", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'[]'" + }, + "raw_payload": { + "name": "raw_payload", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "raw_payload_purged_at": { + "name": "raw_payload_purged_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_incident_unique_idx": { + "name": "external_service_incident_unique_idx", + "columns": [ + "external_service_id", + "provider_incident_id" + ], + "isUnique": true + }, + "external_service_incident_started_at_idx": { + "name": "external_service_incident_started_at_idx", + "columns": [ + "external_service_id", + "started_at" + ], + "isUnique": false + }, + "external_service_incident_resolved_at_idx": { + "name": "external_service_incident_resolved_at_idx", + "columns": [ + "resolved_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_service_incident_external_service_id_external_service_id_fk": { + "name": "external_service_incident_external_service_id_external_service_id_fk", + "tableFrom": "external_service_incident", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_service_report": { + "name": "external_service_report", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "external_service_id": { + "name": "external_service_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_service_component_id": { + "name": "external_service_component_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "reporter_hash": { + "name": "reporter_hash", + "type": "text(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "country": { + "name": "country", + "type": "text(2)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "external_service_report_service_idx": { + "name": "external_service_report_service_idx", + "columns": [ + "external_service_id", + "created_at" + ], + "isUnique": false + }, + "external_service_report_component_idx": { + "name": "external_service_report_component_idx", + "columns": [ + "external_service_component_id", + "created_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_service_report_external_service_id_external_service_id_fk": { + "name": "external_service_report_external_service_id_external_service_id_fk", + "tableFrom": "external_service_report", + "tableTo": "external_service", + "columnsFrom": [ + "external_service_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "external_service_report_external_service_component_id_external_service_component_id_fk": { + "name": "external_service_report_external_service_component_id_external_service_component_id_fk", + "tableFrom": "external_service_report", + "tableTo": "external_service_component", + "columnsFrom": [ + "external_service_component_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "chat_session": { + "name": "chat_session", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "messages": { + "name": "messages", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "chat_session_workspace_user_updated_idx": { + "name": "chat_session_workspace_user_updated_idx", + "columns": [ + "workspace_id", + "user_id", + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "chat_session_workspace_id_workspace_id_fk": { + "name": "chat_session_workspace_id_workspace_id_fk", + "tableFrom": "chat_session", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "chat_session_user_id_user_id_fk": { + "name": "chat_session_user_id_user_id_fk", + "tableFrom": "chat_session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "frozen_monitor_uptime": { + "name": "frozen_monitor_uptime", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "monitor_id": { + "name": "monitor_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "month": { + "name": "month", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "days": { + "name": "days", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(strftime('%s', 'now'))" + } + }, + "indexes": { + "frozen_monitor_uptime_workspace_id_idx": { + "name": "frozen_monitor_uptime_workspace_id_idx", + "columns": [ + "workspace_id" + ], + "isUnique": false + }, + "frozen_monitor_uptime_monitor_id_month_unique": { + "name": "frozen_monitor_uptime_monitor_id_month_unique", + "columns": [ + "monitor_id", + "month" + ], + "isUnique": true + } + }, + "foreignKeys": { + "frozen_monitor_uptime_workspace_id_workspace_id_fk": { + "name": "frozen_monitor_uptime_workspace_id_workspace_id_fk", + "tableFrom": "frozen_monitor_uptime", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "frozen_monitor_uptime_monitor_id_monitor_id_fk": { + "name": "frozen_monitor_uptime_monitor_id_monitor_id_fk", + "tableFrom": "frozen_monitor_uptime", + "tableTo": "monitor", + "columnsFrom": [ + "monitor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": { + "page_lower_slug_idx": { + "columns": { + "LOWER(\"slug\")": { + "isExpression": true + } + } + }, + "page_lower_custom_domain_idx": { + "columns": { + "LOWER(\"custom_domain\")": { + "isExpression": true + } + } + }, + "idx_page_subscriber_email_page_active": { + "columns": { + "LOWER(\"email\")": { + "isExpression": true + } + } + }, + "idx_page_subscriber_webhook_page_active": { + "columns": { + "LOWER(\"webhook_url\")": { + "isExpression": true + } + } + } + } + } +} diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index 13a807b7..393d75df 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -544,9 +544,16 @@ { "idx": 77, "version": "6", - "when": 1782994900937, + "when": 1782504784306, "tag": "0077_military_jackpot", "breakpoints": true + }, + { + "idx": 78, + "version": "6", + "when": 1782994900937, + "tag": "0078_yellow_thor_girl", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/page_subscribers/page_subscribers.ts b/packages/db/src/schema/page_subscribers/page_subscribers.ts index ae77ee02..7e2ceea9 100644 --- a/packages/db/src/schema/page_subscribers/page_subscribers.ts +++ b/packages/db/src/schema/page_subscribers/page_subscribers.ts @@ -22,7 +22,7 @@ export const pageSubscriber = sqliteTable( // Added: channel type discriminator channelType: text("channel_type", { - enum: ["email", "webhook"], + enum: ["email", "webhook", "slack"], }) .notNull() .default("email"), @@ -31,6 +31,11 @@ export const pageSubscriber = sqliteTable( webhookUrl: text("webhook_url"), channelConfig: text("channel_config"), + // Slack channel id (null for non-slack channels). teamId + channelName + // live in channelConfig; the bot token is resolved from the integration + // row at send time, never persisted here. + slackChannelId: text("slack_channel_id"), + // How the subscription was created. Vendor-added rows skip verification // and are editable from the dashboard. source: text("source", { @@ -69,10 +74,19 @@ export const pageSubscriber = sqliteTable( sql`${table.unsubscribedAt} IS NULL AND ${table.channelType} = 'webhook'`, ), + // Partial unique index: one active slack subscription per (channel, page). + slackChannelPageActiveIdx: uniqueIndex( + "idx_page_subscriber_slack_channel_page_active", + ) + .on(table.slackChannelId, table.pageId) + .where( + sql`${table.unsubscribedAt} IS NULL AND ${table.channelType} = 'slack'`, + ), + // CHECK constraint: only correct identifier populated per channel type channelCheck: check( "page_subscriber_channel_check", - sql`(${table.channelType} = 'email' AND ${table.email} IS NOT NULL AND ${table.webhookUrl} IS NULL) OR (${table.channelType} = 'webhook' AND ${table.webhookUrl} IS NOT NULL AND ${table.email} IS NULL)`, + sql`(${table.channelType} = 'email' AND ${table.email} IS NOT NULL AND ${table.webhookUrl} IS NULL) OR (${table.channelType} = 'webhook' AND ${table.webhookUrl} IS NOT NULL AND ${table.email} IS NULL) OR (${table.channelType} = 'slack' AND ${table.slackChannelId} IS NOT NULL AND ${table.email} IS NULL AND ${table.webhookUrl} IS NULL)`, ), }), ); diff --git a/packages/db/src/schema/page_subscribers/validation.ts b/packages/db/src/schema/page_subscribers/validation.ts index 0603d3c5..4765fef3 100644 --- a/packages/db/src/schema/page_subscribers/validation.ts +++ b/packages/db/src/schema/page_subscribers/validation.ts @@ -22,6 +22,15 @@ export const webhookChannelConfigSchema = z.object({ secret: z.string().optional(), }); +// Channel config schema for slack. The bot token is resolved from the +// integration row by teamId at send time, never stored here. +export const slackChannelConfigSchema = z.object({ + teamId: z.string().min(1), + channelId: z.string().min(1), + channelName: z.string().optional(), +}); +export type SlackChannelConfig = z.infer; + export const subscriberSourceSchema = z .enum(["self_signup", "vendor", "import"]) .default("self_signup"); @@ -73,11 +82,40 @@ export const pageSubscriberSchema = z.discriminatedUnion("channelType", [ createdAt: z.date().nullable(), updatedAt: z.date().nullable(), }), + // Slack channel + z.object({ + id: z.number(), + pageId: z.number(), + channelType: z.literal("slack"), + email: z.null(), + webhookUrl: z.null(), + slackChannelId: z.string(), + channelConfig: z + .string() + .nullable() + .transform((str) => { + if (!str) return null; + try { + return JSON.parse(str); + } catch { + return null; + } + }) + .pipe(slackChannelConfigSchema.nullable()), + source: subscriberSourceSchema, + name: z.string().nullable(), + token: z.string().nullable(), + acceptedAt: z.date().nullable(), + expiresAt: z.date().nullable(), + unsubscribedAt: z.date().nullable(), + createdAt: z.date().nullable(), + updatedAt: z.date().nullable(), + }), ]); export type InsertPageSubscriber = z.infer; export type PageSubscriber = z.infer; -export type ChannelType = "email" | "webhook"; +export type ChannelType = "email" | "webhook" | "slack"; export type SubscriberSource = z.infer; export type EmailSubscriber = Extract< z.infer, @@ -87,3 +125,7 @@ export type WebhookSubscriber = Extract< z.infer, { channelType: "webhook" } >; +export type SlackSubscriber = Extract< + z.infer, + { channelType: "slack" } +>; diff --git a/packages/services/src/invitation/create.ts b/packages/services/src/invitation/create.ts index 29eb7c47..98d09f56 100644 --- a/packages/services/src/invitation/create.ts +++ b/packages/services/src/invitation/create.ts @@ -82,7 +82,7 @@ export async function createInvitation(args: { // Dev-mode convenience: echo the invite URL so the developer can // click it straight from the terminal without checking the DB. - // Strict equality on `"development"` so bun:test (which sets + // Strict equality on `"development"` so the test runner (which sets // `NODE_ENV=test`) and CI (typically `undefined` or `"test"`) don't // leak tokens into logs. if (process.env.NODE_ENV === "development") { diff --git a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts index 3fa02a4c..58f2a1fe 100644 --- a/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts +++ b/packages/services/src/page-subscriber/__tests__/page-subscriber.test.ts @@ -290,26 +290,28 @@ describe("upsertSelfSignupSubscriber", () => { }); test("rejects when the workspace plan disables status-subscribers", async () => { - const freePage = await db - .insert(page) - .values({ - workspaceId: SEEDED_WORKSPACE_FREE_ID, - title: "plan-gate", - description: "plan-gate", - slug: `plan-gate-${Date.now()}`, - customDomain: "", - }) - .returning() - .get(); - try { + // Rolled-back tx so the free-workspace page never commits — a + // committed page would trip `page.test.ts`'s free-plan + // `status-pages` quota assertions under `deno test --parallel`. + await withTestTransaction(async (tx) => { + const freePage = await tx + .insert(page) + .values({ + workspaceId: SEEDED_WORKSPACE_FREE_ID, + title: "plan-gate", + description: "plan-gate", + slug: `plan-gate-${Date.now()}`, + customDomain: "", + }) + .returning() + .get(); await expect( upsertSelfSignupSubscriber({ input: { email: EMAILS.planGate, pageId: freePage.id }, + db: tx, }), ).rejects.toThrow("Upgrade to use status subscribers"); - } finally { - await db.delete(page).where(eq(page.id, freePage.id)); - } + }); }); }); diff --git a/packages/services/src/page-subscriber/__tests__/slack.test.ts b/packages/services/src/page-subscriber/__tests__/slack.test.ts new file mode 100644 index 00000000..84e61bc1 --- /dev/null +++ b/packages/services/src/page-subscriber/__tests__/slack.test.ts @@ -0,0 +1,170 @@ +import { db, eq, inArray } from "@openstatus/db"; +import { pageSubscriber } from "@openstatus/db/src/schema"; +import { expect } from "@std/expect"; +import { afterAll, beforeAll, describe, test } from "@std/testing/bdd"; + +import { SEEDED_WORKSPACE_TEAM_ID } from "../../../test/fixtures"; +import { expectAuditRow } from "../../../test/helpers"; +import { + createSlackSubscriber, + listSlackSubscribersForChannel, + removeSlackSubscriber, +} from "../index"; + +// page 1 = slug "status", workspace 1 (team plan, status-subscribers=true). +const PAGE_ID = 1; +const TEAM_ID = "T_SLACK_TEST"; +const CHANNELS = { + create: "C_SLACK_CREATE", + dedup: "C_SLACK_DEDUP", + reactivate: "C_SLACK_REACTIVATE", + remove: "C_SLACK_REMOVE", + list: "C_SLACK_LIST", +}; + +// Scope cleanup to this suite's own slack channels. A workspace-wide +// clearAuditLog would race sibling suites that share workspace 1 under +// `deno test --parallel`; our assertions filter by unique entityId, so +// stale audit rows can't match anyway. +async function cleanAll() { + await db + .delete(pageSubscriber) + .where(inArray(pageSubscriber.slackChannelId, Object.values(CHANNELS))); +} + +beforeAll(cleanAll); +afterAll(cleanAll); + +describe("createSlackSubscriber", () => { + test("creates an auto-accepted self-signup slack row + audit", async () => { + const result = await createSlackSubscriber({ + input: { + pageId: PAGE_ID, + teamId: TEAM_ID, + channelId: CHANNELS.create, + channelName: "incidents", + }, + }); + + expect(result.alreadySubscribed).toBe(false); + expect(result.pageName).toBeDefined(); + + const row = await db.query.pageSubscriber.findFirst({ + where: eq(pageSubscriber.id, result.id), + }); + expect(row?.channelType).toBe("slack"); + expect(row?.slackChannelId).toBe(CHANNELS.create); + expect(row?.source).toBe("self_signup"); + expect(row?.acceptedAt).not.toBeNull(); + expect(row?.name).toBe("#incidents"); + + await expectAuditRow({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + action: "page_subscriber.create", + entityType: "page_subscriber", + entityId: result.id, + actorType: "subscriber", + }); + }); + + test("second call is idempotent (alreadySubscribed, no duplicate)", async () => { + const first = await createSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.dedup }, + }); + const second = await createSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.dedup }, + }); + + expect(first.alreadySubscribed).toBe(false); + expect(second.alreadySubscribed).toBe(true); + + const rows = await db.query.pageSubscriber.findMany({ + where: eq(pageSubscriber.slackChannelId, CHANNELS.dedup), + }); + expect(rows).toHaveLength(1); + }); + + test("re-activates a previously removed channel", async () => { + await createSlackSubscriber({ + input: { + pageId: PAGE_ID, + teamId: TEAM_ID, + channelId: CHANNELS.reactivate, + }, + }); + await removeSlackSubscriber({ + input: { + pageId: PAGE_ID, + teamId: TEAM_ID, + channelId: CHANNELS.reactivate, + }, + }); + const reactivated = await createSlackSubscriber({ + input: { + pageId: PAGE_ID, + teamId: TEAM_ID, + channelId: CHANNELS.reactivate, + }, + }); + + expect(reactivated.alreadySubscribed).toBe(false); + const rows = await db.query.pageSubscriber.findMany({ + where: eq(pageSubscriber.slackChannelId, CHANNELS.reactivate), + }); + expect(rows).toHaveLength(1); + expect(rows[0]?.unsubscribedAt).toBeNull(); + }); +}); + +describe("removeSlackSubscriber", () => { + test("soft-deletes the active row and audits the update", async () => { + const created = await createSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.remove }, + }); + const result = await removeSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.remove }, + }); + + expect(result.removed).toBe(true); + const row = await db.query.pageSubscriber.findFirst({ + where: eq(pageSubscriber.id, created.id), + }); + expect(row?.unsubscribedAt).not.toBeNull(); + + await expectAuditRow({ + workspaceId: SEEDED_WORKSPACE_TEAM_ID, + action: "page_subscriber.update", + entityType: "page_subscriber", + entityId: created.id, + actorType: "subscriber", + }); + }); + + test("returns removed=false when nothing is subscribed", async () => { + const result = await removeSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: "C_SLACK_NEVER" }, + }); + expect(result.removed).toBe(false); + }); +}); + +describe("listSlackSubscribersForChannel", () => { + test("lists active subscriptions for the channel", async () => { + await createSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.list }, + }); + const subs = await listSlackSubscribersForChannel({ + input: { teamId: TEAM_ID, channelId: CHANNELS.list }, + }); + expect(subs).toHaveLength(1); + expect(subs[0]?.pageId).toBe(PAGE_ID); + + await removeSlackSubscriber({ + input: { pageId: PAGE_ID, teamId: TEAM_ID, channelId: CHANNELS.list }, + }); + const after = await listSlackSubscribersForChannel({ + input: { teamId: TEAM_ID, channelId: CHANNELS.list }, + }); + expect(after).toHaveLength(0); + }); +}); diff --git a/packages/services/src/page-subscriber/get-by-token.ts b/packages/services/src/page-subscriber/get-by-token.ts index 62088614..d746125d 100644 --- a/packages/services/src/page-subscriber/get-by-token.ts +++ b/packages/services/src/page-subscriber/get-by-token.ts @@ -23,7 +23,7 @@ export type SubscriberByTokenResult = { pageName: string; pageSlug: string; customDomain: string | null; - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; email?: string; webhookUrl?: string; acceptedAt: Date | null; diff --git a/packages/services/src/page-subscriber/index.ts b/packages/services/src/page-subscriber/index.ts index 18deac3d..793b3503 100644 --- a/packages/services/src/page-subscriber/index.ts +++ b/packages/services/src/page-subscriber/index.ts @@ -10,6 +10,13 @@ export { export { hasPendingSubscriber } from "./has-pending"; export { listPageSubscribers, type PageSubscriberListItem } from "./list"; export { sendPageSubscriberTestWebhook } from "./send-test-webhook"; +export { + createSlackSubscriber, + listSlackSubscribersForChannel, + removeSlackSubscriber, + type SlackSubscriberResult, + type SlackSubscriptionSummary, +} from "./slack"; export { unsubscribeSubscriber } from "./unsubscribe"; export { updatePageSubscriberChannel } from "./update"; export { updateSubscriberScope } from "./update-scope"; @@ -20,10 +27,13 @@ export { export { type VerifyResult, verifySelfSignupSubscriber } from "./verify"; export { CreatePageSubscriberInput, + CreateSlackSubscriberInput, DeletePageSubscriberInput, GetSubscriberByTokenInput, HasPendingSubscriberInput, ListPageSubscribersInput, + ListSlackSubscribersInput, + RemoveSlackSubscriberInput, SendPageSubscriberTestWebhookInput, UnsubscribeSubscriberInput, UpdatePageSubscriberChannelInput, diff --git a/packages/services/src/page-subscriber/list.ts b/packages/services/src/page-subscriber/list.ts index 2e434312..b8c3cec5 100644 --- a/packages/services/src/page-subscriber/list.ts +++ b/packages/services/src/page-subscriber/list.ts @@ -34,7 +34,7 @@ function webhookUrlForList( export type PageSubscriberListItem = { id: number; - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; email: string | null; webhookUrl: string | null; channelConfig: string | null; diff --git a/packages/services/src/page-subscriber/schemas.ts b/packages/services/src/page-subscriber/schemas.ts index da196c5e..5db26ade 100644 --- a/packages/services/src/page-subscriber/schemas.ts +++ b/packages/services/src/page-subscriber/schemas.ts @@ -38,6 +38,33 @@ export type CreatePageSubscriberInput = z.infer< typeof CreatePageSubscriberInput >; +export const CreateSlackSubscriberInput = z.object({ + pageId: z.number().int().positive(), + teamId: z.string().min(1), + channelId: z.string().min(1), + channelName: z.string().max(255).optional(), +}); +export type CreateSlackSubscriberInput = z.infer< + typeof CreateSlackSubscriberInput +>; + +export const RemoveSlackSubscriberInput = z.object({ + pageId: z.number().int().positive(), + teamId: z.string().min(1), + channelId: z.string().min(1), +}); +export type RemoveSlackSubscriberInput = z.infer< + typeof RemoveSlackSubscriberInput +>; + +export const ListSlackSubscribersInput = z.object({ + teamId: z.string().min(1), + channelId: z.string().min(1), +}); +export type ListSlackSubscribersInput = z.infer< + typeof ListSlackSubscribersInput +>; + export const UpdatePageSubscriberChannelInput = z.object({ subscriberId: z.number().int().positive(), pageId: z.number().int().positive(), diff --git a/packages/services/src/page-subscriber/slack.ts b/packages/services/src/page-subscriber/slack.ts new file mode 100644 index 00000000..dafb488b --- /dev/null +++ b/packages/services/src/page-subscriber/slack.ts @@ -0,0 +1,255 @@ +import { and, eq, isNull, sql } from "@openstatus/db"; +import { + page, + pageSubscriber, + selectPageSubscriberSchema, +} from "@openstatus/db/src/schema"; + +import { emitAudit } from "../audit"; +import { + type DB, + type ServiceContext, + getReadDb, + withTransaction, +} from "../context"; +import { NotFoundError } from "../errors"; +import { assertSubscribersAllowed, parseWorkspaceForContext } from "./internal"; +import { + type CreateSlackSubscriberInput, + type ListSlackSubscribersInput, + type RemoveSlackSubscriberInput, + CreateSlackSubscriberInput as CreateSlackSubscriberSchema, + ListSlackSubscribersInput as ListSlackSubscribersSchema, + RemoveSlackSubscriberInput as RemoveSlackSubscriberSchema, +} from "./schemas"; + +export interface SlackSubscriberResult { + id: number; + pageId: number; + pageName: string; + pageSlug: string; + customDomain: string | null; + alreadySubscribed: boolean; +} + +function channelLabel(channelId: string, channelName?: string): string { + return channelName ? `#${channelName}` : channelId; +} + +/** + * Self-signup for a Slack channel via `/openstatus add `. There is no + * authenticated workspace at the call site — both workspace and audit actor + * are resolved from the page. Auto-accepted (the slash command is consent). + */ +export async function createSlackSubscriber(args: { + input: CreateSlackSubscriberInput; + db?: DB; +}): Promise { + const input = CreateSlackSubscriberSchema.parse(args.input); + + const readDb = getReadDb({ db: args.db } as ServiceContext); + const pageData = await readDb.query.page.findFirst({ + where: eq(page.id, input.pageId), + with: { workspace: true }, + }); + if (!pageData) { + throw new NotFoundError("page", input.pageId); + } + const workspace = parseWorkspaceForContext(pageData.workspace); + assertSubscribersAllowed(workspace); + + const channelConfig = JSON.stringify({ + teamId: input.teamId, + channelId: input.channelId, + channelName: input.channelName, + }); + const name = channelLabel(input.channelId, input.channelName); + + return withTransaction({ db: args.db } as ServiceContext, async (tx) => { + const existing = await tx.query.pageSubscriber.findFirst({ + where: and( + eq(pageSubscriber.pageId, input.pageId), + eq(pageSubscriber.slackChannelId, input.channelId), + eq(pageSubscriber.channelType, "slack"), + ), + }); + + if (existing && !existing.unsubscribedAt) { + return { + id: existing.id, + pageId: pageData.id, + pageName: pageData.title, + pageSlug: pageData.slug, + customDomain: pageData.customDomain, + alreadySubscribed: true, + }; + } + + if (existing) { + const before = selectPageSubscriberSchema.parse(existing); + const updated = await tx + .update(pageSubscriber) + .set({ + unsubscribedAt: null, + acceptedAt: new Date(), + channelConfig, + name, + updatedAt: new Date(), + }) + .where(eq(pageSubscriber.id, existing.id)) + .returning() + .get(); + const after = selectPageSubscriberSchema.parse(updated ?? existing); + + const auditCtx: ServiceContext = { + workspace, + actor: { type: "subscriber", subscriberId: existing.id }, + db: tx, + }; + const { token: _bt, ...beforeSnap } = before; + const { token: _at, ...afterSnap } = after; + await emitAudit(tx, auditCtx, { + action: "page_subscriber.update", + entityType: "page_subscriber", + entityId: existing.id, + before: beforeSnap, + after: afterSnap, + }); + + return { + id: existing.id, + pageId: pageData.id, + pageName: pageData.title, + pageSlug: pageData.slug, + customDomain: pageData.customDomain, + alreadySubscribed: false, + }; + } + + const inserted = await tx + .insert(pageSubscriber) + .values({ + channelType: "slack", + slackChannelId: input.channelId, + channelConfig, + pageId: input.pageId, + source: "self_signup", + name, + acceptedAt: new Date(), + }) + .returning() + .get(); + + const auditCtx: ServiceContext = { + workspace, + actor: { type: "subscriber", subscriberId: inserted.id }, + db: tx, + }; + const { token: _t, ...after } = selectPageSubscriberSchema.parse(inserted); + await emitAudit(tx, auditCtx, { + action: "page_subscriber.create", + entityType: "page_subscriber", + entityId: inserted.id, + after, + }); + + return { + id: inserted.id, + pageId: pageData.id, + pageName: pageData.title, + pageSlug: pageData.slug, + customDomain: pageData.customDomain, + alreadySubscribed: false, + }; + }); +} + +export async function removeSlackSubscriber(args: { + input: RemoveSlackSubscriberInput; + db?: DB; +}): Promise<{ removed: boolean }> { + const input = RemoveSlackSubscriberSchema.parse(args.input); + + const readDb = getReadDb({ db: args.db } as ServiceContext); + const pageData = await readDb.query.page.findFirst({ + where: eq(page.id, input.pageId), + with: { workspace: true }, + }); + if (!pageData) { + throw new NotFoundError("page", input.pageId); + } + const workspace = parseWorkspaceForContext(pageData.workspace); + + return withTransaction({ db: args.db } as ServiceContext, async (tx) => { + const existing = await tx.query.pageSubscriber.findFirst({ + where: and( + eq(pageSubscriber.pageId, input.pageId), + eq(pageSubscriber.slackChannelId, input.channelId), + eq(pageSubscriber.channelType, "slack"), + sql`json_extract(${pageSubscriber.channelConfig}, '$.teamId') = ${input.teamId}`, + isNull(pageSubscriber.unsubscribedAt), + ), + }); + if (!existing) return { removed: false }; + + const before = selectPageSubscriberSchema.parse(existing); + const updated = await tx + .update(pageSubscriber) + .set({ unsubscribedAt: new Date(), updatedAt: new Date() }) + .where(eq(pageSubscriber.id, existing.id)) + .returning() + .get(); + const after = selectPageSubscriberSchema.parse(updated ?? existing); + + const auditCtx: ServiceContext = { + workspace, + actor: { type: "subscriber", subscriberId: existing.id }, + db: tx, + }; + const { token: _bt, ...beforeSnap } = before; + const { token: _at, ...afterSnap } = after; + await emitAudit(tx, auditCtx, { + action: "page_subscriber.update", + entityType: "page_subscriber", + entityId: existing.id, + before: beforeSnap, + after: afterSnap, + }); + + return { removed: true }; + }); +} + +export interface SlackSubscriptionSummary { + id: number; + pageId: number; + pageName: string; + pageSlug: string; + customDomain: string | null; +} + +export async function listSlackSubscribersForChannel(args: { + input: ListSlackSubscribersInput; + db?: DB; +}): Promise { + const input = ListSlackSubscribersSchema.parse(args.input); + const readDb = getReadDb({ db: args.db } as ServiceContext); + + const rows = await readDb.query.pageSubscriber.findMany({ + where: and( + eq(pageSubscriber.slackChannelId, input.channelId), + eq(pageSubscriber.channelType, "slack"), + sql`json_extract(${pageSubscriber.channelConfig}, '$.teamId') = ${input.teamId}`, + isNull(pageSubscriber.unsubscribedAt), + ), + with: { page: true }, + }); + + return rows.map((row) => ({ + id: row.id, + pageId: row.pageId, + pageName: row.page.title, + pageSlug: row.page.slug, + customDomain: row.page.customDomain, + })); +} diff --git a/packages/services/src/page-subscriber/upsert.ts b/packages/services/src/page-subscriber/upsert.ts index 1d291d9c..fab85bf9 100644 --- a/packages/services/src/page-subscriber/upsert.ts +++ b/packages/services/src/page-subscriber/upsert.ts @@ -26,7 +26,7 @@ export type UpsertSelfSignupResult = { pageName: string; pageSlug: string; customDomain: string | null; - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; email: string; token: string | null; acceptedAt: Date | null; diff --git a/packages/services/src/page-subscriber/verify.ts b/packages/services/src/page-subscriber/verify.ts index 7fa885b7..f4f96bb8 100644 --- a/packages/services/src/page-subscriber/verify.ts +++ b/packages/services/src/page-subscriber/verify.ts @@ -16,7 +16,7 @@ export type VerifyResult = { pageName: string; pageSlug: string; customDomain: string | null; - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; email: string | null; webhookUrl?: string | null; token: string | null; diff --git a/packages/services/src/workspace/__tests__/workspace.test.ts b/packages/services/src/workspace/__tests__/workspace.test.ts index 46cc4e38..576efa1b 100644 --- a/packages/services/src/workspace/__tests__/workspace.test.ts +++ b/packages/services/src/workspace/__tests__/workspace.test.ts @@ -46,7 +46,7 @@ describe("getWorkspaceWithUsage", () => { expect(result.id).toBe(SEEDED_WORKSPACE_TEAM_ID); // Iterate the usage object *before* any `toMatchObject` call — - // bun:test's `toMatchObject` implementation mutates the received + // the `toMatchObject` implementation mutates the received // object in place, replacing number fields with the // `expect.any(Number)` asymmetric-matcher stub on the expected // side. Subsequent reads of `result.usage.` then return the diff --git a/packages/subscriptions/package.json b/packages/subscriptions/package.json index ada82745..1a3537a4 100644 --- a/packages/subscriptions/package.json +++ b/packages/subscriptions/package.json @@ -23,6 +23,8 @@ "@openstatus/emails": "workspace:*", "@openstatus/notification-base": "workspace:*", "@openstatus/utils": "workspace:*", + "@slack/web-api": "catalog:", + "@upstash/redis": "catalog:", "effect": "catalog:", "zod": "catalog:" }, diff --git a/packages/subscriptions/src/channels/index.test.ts b/packages/subscriptions/src/channels/index.test.ts index d635918b..7d2263e0 100644 --- a/packages/subscriptions/src/channels/index.test.ts +++ b/packages/subscriptions/src/channels/index.test.ts @@ -23,9 +23,16 @@ describe("getChannel", () => { expect(typeof channel?.validateConfig).toBe("function"); }); + test('returns slack channel for "slack"', () => { + const channel = getChannel("slack"); + expect(channel).not.toBeNull(); + expect(channel?.id).toBe("slack"); + expect(typeof channel?.sendNotifications).toBe("function"); + expect(typeof channel?.validateConfig).toBe("function"); + }); + test("returns null for unknown channel types", () => { expect(getChannel("sms")).toBeNull(); - expect(getChannel("slack")).toBeNull(); expect(getChannel("")).toBeNull(); }); }); diff --git a/packages/subscriptions/src/channels/index.ts b/packages/subscriptions/src/channels/index.ts index 5bdccda6..5fac4cc1 100644 --- a/packages/subscriptions/src/channels/index.ts +++ b/packages/subscriptions/src/channels/index.ts @@ -4,6 +4,7 @@ import { sendEmailVerification, validateEmailConfig, } from "./email"; +import { sendSlackNotifications, validateSlackConfig } from "./slack"; import { sendWebhookNotifications, sendWebhookVerification, @@ -28,6 +29,13 @@ export function getChannel(channelType: string): SubscriptionChannel | null { validateConfig: validateWebhookConfig, }; } + case "slack": { + return { + id: "slack", + sendNotifications: sendSlackNotifications, + validateConfig: validateSlackConfig, + }; + } default: return null; } diff --git a/packages/subscriptions/src/channels/slack-blocks.test.ts b/packages/subscriptions/src/channels/slack-blocks.test.ts new file mode 100644 index 00000000..63f5443a --- /dev/null +++ b/packages/subscriptions/src/channels/slack-blocks.test.ts @@ -0,0 +1,78 @@ +import { expect } from "@std/expect"; +import { describe, it as test } from "@std/testing/bdd"; + +import type { PageUpdate, Subscription } from "../types"; +import { buildReplyMessage, buildRootMessage } from "./slack-blocks"; + +function makeSub(over: Partial = {}): Subscription { + return { + id: 1, + pageId: 1, + pageName: "Acme Status", + pageSlug: "acme", + customDomain: null, + componentIds: [], + channelType: "slack", + slackChannelId: "C1", + ...over, + }; +} + +function makeUpdate(over: Partial = {}): PageUpdate { + return { + id: 10, + pageId: 1, + title: "API degraded", + status: "investigating", + message: "We are investigating elevated errors.", + pageComponentIds: [], + pageComponents: [], + date: "2026-01-01T10:00:00.000Z", + updateId: 100, + ...over, + }; +} + +describe("buildRootMessage", () => { + test("investigating header carries the magnifier emoji + label", () => { + const root = buildRootMessage(makeUpdate(), makeSub()); + expect(root.text).toContain("🔍"); + expect(root.text).toContain("Investigating"); + expect(root.text).toContain("API degraded"); + expect(root.attachments[0]?.color).toBeDefined(); + }); + + test("resolved switches to the check mark and green bar", () => { + const resolvedRoot = buildRootMessage( + makeUpdate({ status: "resolved" }), + makeSub(), + ); + const investigatingRoot = buildRootMessage(makeUpdate(), makeSub()); + expect(resolvedRoot.text).toContain("✅"); + expect(resolvedRoot.text).toContain("Resolved"); + expect(resolvedRoot.attachments[0]?.color).not.toBe( + investigatingRoot.attachments[0]?.color, + ); + }); + + test("uses the custom domain origin when present", () => { + const root = buildRootMessage( + makeUpdate(), + makeSub({ customDomain: "status.acme.com" }), + ); + expect(JSON.stringify(root.attachments)).toContain( + "https://status.acme.com", + ); + }); +}); + +describe("buildReplyMessage", () => { + test("reply carries status label and message", () => { + const reply = buildReplyMessage( + makeUpdate({ status: "monitoring", message: "Fix deployed." }), + ); + expect(reply.text).toContain("Monitoring"); + expect(reply.text).toContain("Fix deployed."); + expect(reply.blocks.length).toBeGreaterThan(0); + }); +}); diff --git a/packages/subscriptions/src/channels/slack-blocks.ts b/packages/subscriptions/src/channels/slack-blocks.ts new file mode 100644 index 00000000..32004f2b --- /dev/null +++ b/packages/subscriptions/src/channels/slack-blocks.ts @@ -0,0 +1,140 @@ +import { COLORS } from "@openstatus/notification-base"; +import type { KnownBlock, MessageAttachment } from "@slack/web-api"; + +import type { PageUpdate, Subscription } from "../types"; + +type StatusColor = "red" | "yellow" | "green" | "blue"; + +const STATUS_EMOJI: Record = { + investigating: "🔍", + identified: "🔴", + monitoring: "👀", + resolved: "✅", + maintenance: "🔧", +}; + +const STATUS_LABEL: Record = { + investigating: "Investigating", + identified: "Identified", + monitoring: "Monitoring", + resolved: "Resolved", + maintenance: "Maintenance", +}; + +function statusColor(status: PageUpdate["status"]): StatusColor { + switch (status) { + case "investigating": + case "identified": + return "red"; + case "monitoring": + return "yellow"; + case "resolved": + return "green"; + case "maintenance": + return "blue"; + } +} + +function pageOrigin(subscription: Subscription): string { + return subscription.customDomain + ? `https://${subscription.customDomain}` + : `https://${subscription.pageSlug}.openstatus.dev`; +} + +function eventUrl(pageUpdate: PageUpdate, subscription: Subscription): string { + const kind = pageUpdate.status === "maintenance" ? "maintenance" : "report"; + return `${pageOrigin(subscription)}/events/${kind}/${pageUpdate.id}`; +} + +export interface SlackRootMessage { + text: string; + attachments: MessageAttachment[]; +} + +export interface SlackReplyMessage { + text: string; + blocks: KnownBlock[]; +} + +export function buildRootMessage( + pageUpdate: PageUpdate, + subscription: Subscription, +): SlackRootMessage { + const emoji = STATUS_EMOJI[pageUpdate.status]; + const label = STATUS_LABEL[pageUpdate.status]; + const origin = pageOrigin(subscription); + + const blocks: KnownBlock[] = [ + { + type: "header", + text: { + type: "plain_text", + text: `${emoji} ${pageUpdate.title} — ${label}`, + emoji: true, + }, + }, + { + type: "section", + fields: [ + { type: "mrkdwn", text: `*Status*\n${label}` }, + { + type: "mrkdwn", + text: `*Page*\n<${origin}|${subscription.pageName}>`, + }, + ], + }, + ]; + + if (pageUpdate.message) { + blocks.push({ + type: "section", + text: { type: "mrkdwn", text: pageUpdate.message }, + }); + } + + if (pageUpdate.pageComponents.length > 0) { + blocks.push({ + type: "section", + text: { + type: "mrkdwn", + text: `*Affected*\n${pageUpdate.pageComponents.join(", ")}`, + }, + }); + } + + blocks.push({ + type: "context", + elements: [ + { + type: "mrkdwn", + text: `Updated ${pageUpdate.date} · <${eventUrl(pageUpdate, subscription)}|View details> · Manage with \`/openstatus remove\``, + }, + ], + }); + + return { + text: `${emoji} ${pageUpdate.title} — ${label}`, + attachments: [{ color: COLORS[statusColor(pageUpdate.status)], blocks }], + }; +} + +export function buildReplyMessage(pageUpdate: PageUpdate): SlackReplyMessage { + const emoji = STATUS_EMOJI[pageUpdate.status]; + const label = STATUS_LABEL[pageUpdate.status]; + const heading = `${emoji} *${label}* · ${pageUpdate.date}`; + + return { + text: pageUpdate.message ? `${label}: ${pageUpdate.message}` : label, + blocks: [ + { + type: "section", + text: { + type: "mrkdwn", + text: pageUpdate.message + ? `${heading}\n${pageUpdate.message}` + : heading, + }, + }, + ], + }; +} diff --git a/packages/subscriptions/src/channels/slack-store.ts b/packages/subscriptions/src/channels/slack-store.ts new file mode 100644 index 00000000..77d0e38c --- /dev/null +++ b/packages/subscriptions/src/channels/slack-store.ts @@ -0,0 +1,112 @@ +import { Redis } from "@upstash/redis"; + +export interface SlackThreadAnchor { + ts: string; + channelId: string; +} + +export interface SlackAnchorStore { + getAnchor( + reportId: number, + subscriberId: number, + ): Promise; + setAnchor( + reportId: number, + subscriberId: number, + anchor: SlackThreadAnchor, + ): Promise; + clearAnchor(reportId: number, subscriberId: number): Promise; + // Atomically claim delivery of (report, subscriber, update). Returns true only + // for the caller that wins the claim; concurrent callers get false and must + // skip. This is the dedupe reservation — a single atomic op, not a + // read-then-write pair, so two dispatchers can't both post the same message. + reserveDelivery( + reportId: number, + subscriberId: number, + updateId: number, + ): Promise; + // Release a reservation whose post failed, so the delivery can be retried. + releaseDelivery( + reportId: number, + subscriberId: number, + updateId: number, + ): Promise; +} + +const TTL_SECONDS = 90 * 24 * 60 * 60; + +function anchorKey(reportId: number, subscriberId: number): string { + return `slack:report:${reportId}:sub:${subscriberId}`; +} + +function deliveredKey( + reportId: number, + subscriberId: number, + updateId: number, +): string { + return `${anchorKey(reportId, subscriberId)}:update:${updateId}`; +} + +let redisClient: Redis | null = null; + +function getRedis(): Redis { + if (!redisClient) { + redisClient = Redis.fromEnv(); + } + return redisClient; +} + +export function createRedisAnchorStore(): SlackAnchorStore { + return { + async getAnchor(reportId, subscriberId) { + const raw = await getRedis().get( + anchorKey(reportId, subscriberId), + ); + return raw ?? null; + }, + async setAnchor(reportId, subscriberId, anchor) { + await getRedis().set(anchorKey(reportId, subscriberId), anchor, { + ex: TTL_SECONDS, + }); + }, + async clearAnchor(reportId, subscriberId) { + await getRedis().del(anchorKey(reportId, subscriberId)); + }, + async reserveDelivery(reportId, subscriberId, updateId) { + const res = await getRedis().set( + deliveredKey(reportId, subscriberId, updateId), + 1, + { ex: TTL_SECONDS, nx: true }, + ); + return res === "OK"; + }, + async releaseDelivery(reportId, subscriberId, updateId) { + await getRedis().del(deliveredKey(reportId, subscriberId, updateId)); + }, + }; +} + +export function createMemoryAnchorStore(): SlackAnchorStore { + const anchors = new Map(); + const delivered = new Set(); + return { + async getAnchor(reportId, subscriberId) { + return anchors.get(anchorKey(reportId, subscriberId)) ?? null; + }, + async setAnchor(reportId, subscriberId, anchor) { + anchors.set(anchorKey(reportId, subscriberId), anchor); + }, + async clearAnchor(reportId, subscriberId) { + anchors.delete(anchorKey(reportId, subscriberId)); + }, + async reserveDelivery(reportId, subscriberId, updateId) { + const key = deliveredKey(reportId, subscriberId, updateId); + if (delivered.has(key)) return false; + delivered.add(key); + return true; + }, + async releaseDelivery(reportId, subscriberId, updateId) { + delivered.delete(deliveredKey(reportId, subscriberId, updateId)); + }, + }; +} diff --git a/packages/subscriptions/src/channels/slack.test.ts b/packages/subscriptions/src/channels/slack.test.ts new file mode 100644 index 00000000..a9084853 --- /dev/null +++ b/packages/subscriptions/src/channels/slack.test.ts @@ -0,0 +1,267 @@ +import { expect } from "@std/expect"; +import { describe, it as test } from "@std/testing/bdd"; + +import type { PageUpdate, Subscription } from "../types"; +import { + type SlackClient, + createSlackChannel, + validateSlackConfig, +} from "./slack"; +import { createMemoryAnchorStore } from "./slack-store"; + +interface RecordedCall { + method: "post" | "update"; + channel: string; + thread_ts?: string; + ts?: string; +} + +function makeClient(opts: { failPostWith?: string } = {}) { + const calls: RecordedCall[] = []; + let counter = 0; + const client: SlackClient = { + async postMessage(args) { + calls.push({ + method: "post", + channel: args.channel, + thread_ts: args.thread_ts, + }); + if (opts.failPostWith) { + const error = new Error("slack error") as Error & { + data?: { error?: string }; + }; + error.data = { error: opts.failPostWith }; + throw error; + } + counter += 1; + return { ts: `1700000000.000${counter}` }; + }, + async update(args) { + calls.push({ method: "update", channel: args.channel, ts: args.ts }); + return { ts: args.ts }; + }, + }; + return { client, calls }; +} + +function makeSub(over: Partial = {}): Subscription { + return { + id: 1, + pageId: 1, + pageName: "Acme", + pageSlug: "acme", + customDomain: null, + componentIds: [], + channelType: "slack", + slackChannelId: "C1", + channelConfig: JSON.stringify({ teamId: "T1", channelId: "C1" }), + ...over, + }; +} + +function makeUpdate(over: Partial = {}): PageUpdate { + return { + id: 10, + pageId: 1, + title: "API degraded", + status: "investigating", + message: "investigating", + pageComponentIds: [], + pageComponents: [], + date: "2026-01-01T10:00:00.000Z", + updateId: 100, + ...over, + }; +} + +const noopUnsub = async () => {}; +const token = async () => "xoxb-test"; + +describe("createSlackChannel", () => { + test("first update opens the thread (root post, no update, anchor set)", async () => { + const { client, calls } = makeClient(); + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications([makeSub()], makeUpdate()); + + expect(calls.filter((c) => c.method === "post").length).toBe(1); + expect(calls[0]?.thread_ts).toBeUndefined(); + expect(calls.some((c) => c.method === "update")).toBe(false); + expect(await store.getAnchor(10, 1)).not.toBeNull(); + }); + + test("subsequent update replies in thread and re-renders root", async () => { + const { client, calls } = makeClient(); + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); + await channel.sendNotifications( + [makeSub()], + makeUpdate({ updateId: 101, status: "monitoring" }), + ); + + const posts = calls.filter((c) => c.method === "post"); + expect(posts.length).toBe(2); + expect(posts[1]?.thread_ts).toBe("1700000000.0001"); + expect(calls.some((c) => c.method === "update")).toBe(true); + }); + + test("same update delivered twice posts once (idempotent)", async () => { + const { client, calls } = makeClient(); + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); + await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); + + expect(calls.filter((c) => c.method === "post").length).toBe(1); + }); + + test("failed post releases the reservation so a retry re-posts", async () => { + let attempts = 0; + const posts: number[] = []; + const client: SlackClient = { + async postMessage() { + attempts += 1; + posts.push(attempts); + if (attempts === 1) { + // Non-terminal error: runSlack returns null, no soft-unsubscribe. + const error = new Error("slack error") as Error & { + data?: { error?: string }; + }; + error.data = { error: "ratelimited" }; + throw error; + } + return { ts: "1700000000.0001" }; + }, + async update(args) { + return { ts: args.ts }; + }, + }; + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); + await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); + + // First attempt failed and released; second attempt reserved again and posted. + expect(posts.length).toBe(2); + }); + + test("missing bot token delivers nothing", async () => { + const { client, calls } = makeClient(); + const channel = createSlackChannel({ + store: createMemoryAnchorStore(), + createClient: () => client, + getBotToken: async () => null, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications([makeSub()], makeUpdate()); + expect(calls.length).toBe(0); + }); + + test("terminal error soft-unsubscribes the row", async () => { + const { client } = makeClient({ failPostWith: "channel_not_found" }); + const unsubscribed: number[] = []; + const channel = createSlackChannel({ + store: createMemoryAnchorStore(), + createClient: () => client, + getBotToken: token, + softUnsubscribe: async (id) => { + unsubscribed.push(id); + }, + }); + + await channel.sendNotifications([makeSub({ id: 7 })], makeUpdate()); + expect(unsubscribed).toEqual([7]); + }); + + test("maintenance posts once with no thread and no anchor", async () => { + const { client, calls } = makeClient(); + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications( + [makeSub()], + makeUpdate({ status: "maintenance", updateId: undefined }), + ); + + expect(calls.filter((c) => c.method === "post").length).toBe(1); + expect(calls.some((c) => c.method === "update")).toBe(false); + expect(await store.getAnchor(10, 1)).toBeNull(); + }); +}); + +describe("validateSlackConfig", () => { + test("accepts non-empty teamId and channelId strings", async () => { + const result = await validateSlackConfig({ + teamId: "T1", + channelId: "C1", + }); + expect(result.valid).toBe(true); + }); + + const invalidConfigs: Array<{ label: string; config: unknown }> = [ + { label: "null config", config: null }, + { label: "non-object", config: "T1" }, + { label: "missing teamId", config: { channelId: "C1" } }, + { label: "missing channelId", config: { teamId: "T1" } }, + { label: "null teamId", config: { teamId: null, channelId: "C1" } }, + { label: "numeric channelId", config: { teamId: "T1", channelId: 42 } }, + { label: "empty teamId", config: { teamId: "", channelId: "C1" } }, + { label: "empty channelId", config: { teamId: "T1", channelId: "" } }, + ]; + + for (const { label, config } of invalidConfigs) { + test(`rejects ${label}`, async () => { + const result = await validateSlackConfig(config); + expect(result.valid).toBe(false); + expect(result.error).toBeDefined(); + }); + } +}); + +describe("reserveDelivery (memory store)", () => { + test("only the first reservation for a key wins", async () => { + const store = createMemoryAnchorStore(); + expect(await store.reserveDelivery(1, 2, 3)).toBe(true); + expect(await store.reserveDelivery(1, 2, 3)).toBe(false); + // A different updateId is an independent reservation. + expect(await store.reserveDelivery(1, 2, 4)).toBe(true); + }); + + test("releaseDelivery makes the key reservable again", async () => { + const store = createMemoryAnchorStore(); + expect(await store.reserveDelivery(1, 2, 3)).toBe(true); + await store.releaseDelivery(1, 2, 3); + expect(await store.reserveDelivery(1, 2, 3)).toBe(true); + }); +}); diff --git a/packages/subscriptions/src/channels/slack.ts b/packages/subscriptions/src/channels/slack.ts new file mode 100644 index 00000000..e469020a --- /dev/null +++ b/packages/subscriptions/src/channels/slack.ts @@ -0,0 +1,265 @@ +import { and, db, eq } from "@openstatus/db"; +import { integration, pageSubscriber } from "@openstatus/db/src/schema"; +import type { + ChatPostMessageArguments, + ChatUpdateArguments, +} from "@slack/web-api"; +import { WebClient } from "@slack/web-api"; + +import type { PageUpdate, Subscription } from "../types"; +import { buildReplyMessage, buildRootMessage } from "./slack-blocks"; +import { type SlackAnchorStore, createRedisAnchorStore } from "./slack-store"; + +interface SlackPostResult { + ts?: string; +} + +export interface SlackClient { + postMessage(args: ChatPostMessageArguments): Promise; + update(args: ChatUpdateArguments): Promise; +} + +export interface SlackChannelDeps { + store: SlackAnchorStore; + createClient: (token: string) => SlackClient; + getBotToken: (teamId: string) => Promise; + softUnsubscribe: (subscriberId: number) => Promise; +} + +// Errors that can never succeed on retry — the channel/app is gone, so we +// stop delivering to that subscriber instead of failing on every update. +const TERMINAL_SLACK_ERRORS = new Set([ + "channel_not_found", + "is_archived", + "channel_is_archived", + "account_inactive", + "token_revoked", + "not_in_channel", + "not_authed", + "invalid_auth", +]); + +// WebClient throws `WebAPIPlatformError` carrying `data.error`; this is the +// only place we reach into that SDK error shape. +function slackErrorCode(error: Error): string | undefined { + const data = (error as Error & { data?: { error?: string } }).data; + return typeof data?.error === "string" ? data.error : undefined; +} + +function parseTeamId(channelConfig?: string): string | null { + if (!channelConfig) return null; + try { + const parsed = JSON.parse(channelConfig) as { teamId?: string }; + return parsed.teamId ?? null; + } catch { + return null; + } +} + +async function getBotTokenFromDb(teamId: string): Promise { + const row = await db + .select({ credential: integration.credential }) + .from(integration) + .where( + and( + eq(integration.name, "slack-agent"), + eq(integration.externalId, teamId), + ), + ) + .get(); + const credential = row?.credential as { botToken?: string } | null; + return credential?.botToken ?? null; +} + +async function softUnsubscribeInDb(subscriberId: number): Promise { + await db + .update(pageSubscriber) + .set({ unsubscribedAt: new Date(), updatedAt: new Date() }) + .where(eq(pageSubscriber.id, subscriberId)) + .run(); +} + +export function createSlackChannel(deps: SlackChannelDeps) { + async function runSlack( + subscriberId: number, + fn: () => Promise, + ): Promise { + try { + return await fn(); + } catch (error) { + if (error instanceof Error) { + const code = slackErrorCode(error); + if (code && TERMINAL_SLACK_ERRORS.has(code)) { + await deps.softUnsubscribe(subscriberId); + console.error( + `slack: terminal error '${code}' for subscriber ${subscriberId} — unsubscribed`, + ); + return null; + } + console.error( + `slack: delivery failed for subscriber ${subscriberId}: ${error.message}`, + ); + } else { + console.error(`slack: delivery failed for subscriber ${subscriberId}`); + } + return null; + } + } + + async function deliverMaintenance( + client: SlackClient, + sub: Subscription, + channelId: string, + pageUpdate: PageUpdate, + ): Promise { + const root = buildRootMessage(pageUpdate, sub); + await runSlack(sub.id, () => + client.postMessage({ + channel: channelId, + text: root.text, + attachments: root.attachments, + }), + ); + } + + async function deliverReport( + client: SlackClient, + sub: Subscription, + channelId: string, + pageUpdate: PageUpdate, + ): Promise { + const reportId = pageUpdate.id; + const updateId = pageUpdate.updateId; + if (updateId == null) { + console.error(`slack: status report update ${reportId} missing updateId`); + return; + } + + // Atomic dedupe: only the caller that wins this reservation posts. On a + // failed post we release it below so the delivery stays retriable. + if (!(await deps.store.reserveDelivery(reportId, sub.id, updateId))) return; + + const anchor = await deps.store.getAnchor(reportId, sub.id); + const root = buildRootMessage(pageUpdate, sub); + + if (!anchor) { + const res = await runSlack(sub.id, () => + client.postMessage({ + channel: channelId, + text: root.text, + attachments: root.attachments, + }), + ); + if (!res) { + await deps.store.releaseDelivery(reportId, sub.id, updateId); + return; + } + if (res.ts) { + await deps.store.setAnchor(reportId, sub.id, { ts: res.ts, channelId }); + } + return; + } + + const reply = buildReplyMessage(pageUpdate); + const replyRes = await runSlack(sub.id, () => + client.postMessage({ + channel: anchor.channelId, + thread_ts: anchor.ts, + text: reply.text, + blocks: reply.blocks, + }), + ); + if (!replyRes) { + await deps.store.releaseDelivery(reportId, sub.id, updateId); + return; + } + + // Re-render the root so its emoji/status track the latest state. + await runSlack(sub.id, () => + client.update({ + channel: anchor.channelId, + ts: anchor.ts, + text: root.text, + attachments: root.attachments, + }), + ); + } + + async function sendNotifications( + subscriptions: Subscription[], + pageUpdate: PageUpdate, + ): Promise { + const byTeam = new Map< + string, + { sub: Subscription; channelId: string }[] + >(); + for (const sub of subscriptions) { + if (sub.channelType !== "slack") continue; + const channelId = sub.slackChannelId; + const teamId = parseTeamId(sub.channelConfig); + if (!channelId || !teamId) { + console.error(`slack: subscriber ${sub.id} missing channelId/teamId`); + continue; + } + const members = byTeam.get(teamId) ?? []; + members.push({ sub, channelId }); + byTeam.set(teamId, members); + } + + await Promise.allSettled( + [...byTeam.entries()].map(async ([teamId, members]) => { + const token = await deps.getBotToken(teamId); + if (!token) { + console.error(`slack: no bot token for team ${teamId}`); + return; + } + const client = deps.createClient(token); + await Promise.allSettled( + members.map(({ sub, channelId }) => + pageUpdate.status === "maintenance" + ? deliverMaintenance(client, sub, channelId, pageUpdate) + : deliverReport(client, sub, channelId, pageUpdate), + ), + ); + }), + ); + } + + return { sendNotifications }; +} + +const defaultChannel = createSlackChannel({ + store: createRedisAnchorStore(), + createClient: (token) => { + const web = new WebClient(token); + return { + postMessage: (args) => web.chat.postMessage(args), + update: (args) => web.chat.update(args), + }; + }, + getBotToken: getBotTokenFromDb, + softUnsubscribe: softUnsubscribeInDb, +}); + +export async function sendSlackNotifications( + subscriptions: Subscription[], + pageUpdate: PageUpdate, +): Promise { + return defaultChannel.sendNotifications(subscriptions, pageUpdate); +} + +export async function validateSlackConfig( + config: unknown, +): Promise<{ valid: boolean; error?: string }> { + if ( + config !== null && + typeof config === "object" && + typeof (config as { teamId?: unknown }).teamId === "string" && + (config as { teamId: string }).teamId.length > 0 && + typeof (config as { channelId?: unknown }).channelId === "string" && + (config as { channelId: string }).channelId.length > 0 + ) { + return { valid: true }; + } + return { valid: false, error: "slack config requires teamId and channelId" }; +} diff --git a/packages/subscriptions/src/dispatcher.ts b/packages/subscriptions/src/dispatcher.ts index 08e51301..f687e566 100644 --- a/packages/subscriptions/src/dispatcher.ts +++ b/packages/subscriptions/src/dispatcher.ts @@ -167,9 +167,10 @@ export async function dispatchPageUpdate(pageUpdate: PageUpdate) { pageName: pageData.name, pageSlug: pageData.slug, customDomain: pageData.customDomain, - channelType: sub.channelType as "email" | "webhook", + channelType: sub.channelType as "email" | "webhook" | "slack", email: sub.email ?? undefined, webhookUrl: sub.webhookUrl ?? undefined, + slackChannelId: sub.slackChannelId ?? undefined, channelConfig: sub.channelConfig ?? undefined, token: sub.token ?? undefined, acceptedAt: sub.acceptedAt ?? undefined, diff --git a/packages/subscriptions/src/index.ts b/packages/subscriptions/src/index.ts index b161ad00..be5a387c 100644 --- a/packages/subscriptions/src/index.ts +++ b/packages/subscriptions/src/index.ts @@ -13,6 +13,18 @@ export { validateWebhookConfig, } from "./channels/webhook"; export type { WebhookFlavor } from "./channels/webhook"; +export { + createSlackChannel, + sendSlackNotifications, + validateSlackConfig, +} from "./channels/slack"; +export type { SlackChannelDeps, SlackClient } from "./channels/slack"; +export { buildReplyMessage, buildRootMessage } from "./channels/slack-blocks"; +export { + createMemoryAnchorStore, + createRedisAnchorStore, +} from "./channels/slack-store"; +export type { SlackAnchorStore } from "./channels/slack-store"; export { getChannel } from "./channels/index"; // Export dispatcher functions diff --git a/packages/subscriptions/src/types.ts b/packages/subscriptions/src/types.ts index f0c95d7c..d1cdf9c5 100644 --- a/packages/subscriptions/src/types.ts +++ b/packages/subscriptions/src/types.ts @@ -11,10 +11,11 @@ export interface Subscription { componentIds: number[]; // Empty = entire page // Only ONE identifier populated based on channelType - channelType: "email" | "webhook"; + channelType: "email" | "webhook" | "slack"; email?: string; webhookUrl?: string; - channelConfig?: string; // JSON string for headers, secrets, etc. + slackChannelId?: string; + channelConfig?: string; // JSON string for headers, secrets, slack teamId, etc. token?: string; acceptedAt?: Date; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd4f9cdd..2853e3e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2740,6 +2740,12 @@ importers: '@openstatus/utils': specifier: workspace:* version: link:../utils + '@slack/web-api': + specifier: 'catalog:' + version: 7.16.0 + '@upstash/redis': + specifier: 'catalog:' + version: 1.38.0 effect: specifier: 'catalog:' version: 3.21.2 -- 2.51.2 From 5540567d7c2ce0c17a32866e088c73a95a2707f1 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 17:08:17 +0200 Subject: [PATCH 31/69] slack app: fix (#2350) * slack app: fix * ci: apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- apps/server/slack-manifest.json | 64 ++++++++++++++++++ .../subscriptions/src/channels/slack.test.ts | 25 +++++++ packages/subscriptions/src/channels/slack.ts | 65 +++++++++++++------ 3 files changed, 133 insertions(+), 21 deletions(-) create mode 100644 apps/server/slack-manifest.json diff --git a/apps/server/slack-manifest.json b/apps/server/slack-manifest.json new file mode 100644 index 00000000..f882dc5f --- /dev/null +++ b/apps/server/slack-manifest.json @@ -0,0 +1,64 @@ +{ + "display_information": { + "name": "openstatus", + "description": "Manage incidents and status pages directly from Slack.", + "background_color": "#000000", + "long_description": "openstatus brings incident management into your team's Slack workspace. Mention the bot or send it a direct message to create, update, and resolve status reports — no context switching required.\n\n How it works:\n :one: Describe the issue by mentioning @openstatus in any channel or thread\n :two: The assistant reads the conversation, queries your status pages, and drafts a status update\n :three: Review the proposed action and click Approve, Approve & Notify, or Cancel\n\n What you can do:\n :white_check_mark: Create status reports from natural conversation\n :white_check_mark: Post progress updates as incidents evolve\n :white_check_mark: Resolve incidents when the issue is fixed\n :white_check_mark: Notify your status page subscribers with one click\n :white_check_mark: Edit report titles and affected components\n\n The assistant understands context — tag it in an ongoing thread and it will synthesize the discussion into a clear, public-facing status update. It infers incident status automatically: \"we found the root cause\" becomes Identified, \"it's fixed\" becomes Resolved.\n\n AI disclaimer: openstatus uses large language models (LLMs) to summarize conversations, draft status updates, and infer incident status. AI-generated content may sometimes be inaccurate, incomplete, or misleading. Always review every draft before approving it — nothing is posted to your status page until you explicitly confirm. Only the person who triggered the action can approve it, and you can edit or cancel any draft." + }, + "features": { + "app_home": { + "home_tab_enabled": true, + "messages_tab_enabled": false, + "messages_tab_read_only_enabled": true + }, + "bot_user": { + "display_name": "openstatus", + "always_online": true + }, + "slash_commands": [ + { + "command": "/openstatus", + "url": "https://api.openstatus.dev/slack/commands", + "description": "Subscribe this channel to a status page", + "usage_hint": "subscribe | unsubscribe | subscriptions ", + "should_escape": false + } + ] + }, + "oauth_config": { + "redirect_urls": ["https://api.openstatus.dev/slack/oauth/callback"], + "scopes": { + "user": ["groups:write"], + "user_optional": ["groups:write"], + "bot": [ + "app_mentions:read", + "channels:history", + "channels:join", + "chat:write", + "commands", + "groups:history", + "groups:read", + "groups:write", + "im:history", + "im:read", + "im:write", + "mpim:history" + ] + }, + "pkce_enabled": false + }, + "settings": { + "event_subscriptions": { + "request_url": "https://api.openstatus.dev/slack/events", + "bot_events": ["app_home_opened", "message.channels", "message.groups"] + }, + "interactivity": { + "is_enabled": true, + "request_url": "https://api.openstatus.dev/slack/interactions" + }, + "org_deploy_enabled": true, + "socket_mode_enabled": false, + "token_rotation_enabled": false, + "is_mcp_enabled": false + } +} diff --git a/packages/subscriptions/src/channels/slack.test.ts b/packages/subscriptions/src/channels/slack.test.ts index a9084853..d4494cf3 100644 --- a/packages/subscriptions/src/channels/slack.test.ts +++ b/packages/subscriptions/src/channels/slack.test.ts @@ -199,6 +199,31 @@ describe("createSlackChannel", () => { expect(unsubscribed).toEqual([7]); }); + test("token error leaves subscribers intact and aborts the team batch", async () => { + const { client, calls } = makeClient({ failPostWith: "invalid_auth" }); + const unsubscribed: number[] = []; + const channel = createSlackChannel({ + store: createMemoryAnchorStore(), + createClient: () => client, + getBotToken: token, + softUnsubscribe: async (id) => { + unsubscribed.push(id); + }, + }); + + await channel.sendNotifications( + [ + makeSub({ id: 1, slackChannelId: "C1" }), + makeSub({ id: 2, slackChannelId: "C2" }), + ], + makeUpdate(), + ); + + // No subscriber unsubscribed, and the second member is never attempted. + expect(unsubscribed).toEqual([]); + expect(calls.filter((c) => c.method === "post").length).toBe(1); + }); + test("maintenance posts once with no thread and no anchor", async () => { const { client, calls } = makeClient(); const store = createMemoryAnchorStore(); diff --git a/packages/subscriptions/src/channels/slack.ts b/packages/subscriptions/src/channels/slack.ts index e469020a..6759e688 100644 --- a/packages/subscriptions/src/channels/slack.ts +++ b/packages/subscriptions/src/channels/slack.ts @@ -26,19 +26,30 @@ export interface SlackChannelDeps { softUnsubscribe: (subscriberId: number) => Promise; } -// Errors that can never succeed on retry — the channel/app is gone, so we -// stop delivering to that subscriber instead of failing on every update. -const TERMINAL_SLACK_ERRORS = new Set([ +// Channel-scoped terminal errors: this subscriber's destination is gone for +// good, so we stop delivering to that one subscriber. +const CHANNEL_TERMINAL_ERRORS = new Set([ "channel_not_found", "is_archived", "channel_is_archived", +]); + +// Token-scoped errors: the team's bot token is invalid. This affects every +// subscriber on the team and is recoverable by reinstalling the app, so we +// abort the team's batch WITHOUT unsubscribing anyone — otherwise a broken +// token silently and permanently drops every subscription on the team. +const TOKEN_TERMINAL_ERRORS = new Set([ + "invalid_auth", "account_inactive", "token_revoked", - "not_in_channel", "not_authed", - "invalid_auth", ]); +// Returned by a delivery when the team token is invalid, signalling the caller +// to abort the remaining members of that team. +const TEAM_TOKEN_INVALID = Symbol("slack_team_token_invalid"); +type DeliveryOutcome = typeof TEAM_TOKEN_INVALID | undefined; + // WebClient throws `WebAPIPlatformError` carrying `data.error`; this is the // only place we reach into that SDK error shape. function slackErrorCode(error: Error): string | undefined { @@ -83,13 +94,16 @@ export function createSlackChannel(deps: SlackChannelDeps) { async function runSlack( subscriberId: number, fn: () => Promise, - ): Promise { + ): Promise { try { return await fn(); } catch (error) { if (error instanceof Error) { const code = slackErrorCode(error); - if (code && TERMINAL_SLACK_ERRORS.has(code)) { + if (code && TOKEN_TERMINAL_ERRORS.has(code)) { + return TEAM_TOKEN_INVALID; + } + if (code && CHANNEL_TERMINAL_ERRORS.has(code)) { await deps.softUnsubscribe(subscriberId); console.error( `slack: terminal error '${code}' for subscriber ${subscriberId} — unsubscribed`, @@ -111,15 +125,16 @@ export function createSlackChannel(deps: SlackChannelDeps) { sub: Subscription, channelId: string, pageUpdate: PageUpdate, - ): Promise { + ): Promise { const root = buildRootMessage(pageUpdate, sub); - await runSlack(sub.id, () => + const res = await runSlack(sub.id, () => client.postMessage({ channel: channelId, text: root.text, attachments: root.attachments, }), ); + if (res === TEAM_TOKEN_INVALID) return TEAM_TOKEN_INVALID; } async function deliverReport( @@ -127,7 +142,7 @@ export function createSlackChannel(deps: SlackChannelDeps) { sub: Subscription, channelId: string, pageUpdate: PageUpdate, - ): Promise { + ): Promise { const reportId = pageUpdate.id; const updateId = pageUpdate.updateId; if (updateId == null) { @@ -150,9 +165,9 @@ export function createSlackChannel(deps: SlackChannelDeps) { attachments: root.attachments, }), ); - if (!res) { + if (!res || res === TEAM_TOKEN_INVALID) { await deps.store.releaseDelivery(reportId, sub.id, updateId); - return; + return res === TEAM_TOKEN_INVALID ? TEAM_TOKEN_INVALID : undefined; } if (res.ts) { await deps.store.setAnchor(reportId, sub.id, { ts: res.ts, channelId }); @@ -169,13 +184,13 @@ export function createSlackChannel(deps: SlackChannelDeps) { blocks: reply.blocks, }), ); - if (!replyRes) { + if (!replyRes || replyRes === TEAM_TOKEN_INVALID) { await deps.store.releaseDelivery(reportId, sub.id, updateId); - return; + return replyRes === TEAM_TOKEN_INVALID ? TEAM_TOKEN_INVALID : undefined; } // Re-render the root so its emoji/status track the latest state. - await runSlack(sub.id, () => + const updateRes = await runSlack(sub.id, () => client.update({ channel: anchor.channelId, ts: anchor.ts, @@ -183,6 +198,7 @@ export function createSlackChannel(deps: SlackChannelDeps) { attachments: root.attachments, }), ); + if (updateRes === TEAM_TOKEN_INVALID) return TEAM_TOKEN_INVALID; } async function sendNotifications( @@ -214,13 +230,20 @@ export function createSlackChannel(deps: SlackChannelDeps) { return; } const client = deps.createClient(token); - await Promise.allSettled( - members.map(({ sub, channelId }) => + // Sequential per team so a token failure aborts the batch before + // hammering Slack with N calls that will all fail identically. + for (const { sub, channelId } of members) { + const outcome = pageUpdate.status === "maintenance" - ? deliverMaintenance(client, sub, channelId, pageUpdate) - : deliverReport(client, sub, channelId, pageUpdate), - ), - ); + ? await deliverMaintenance(client, sub, channelId, pageUpdate) + : await deliverReport(client, sub, channelId, pageUpdate); + if (outcome === TEAM_TOKEN_INVALID) { + console.error( + `slack: team ${teamId} bot token invalid — aborting ${members.length} deliveries; subscribers left intact (reconnect the Slack app)`, + ); + break; + } + } }), ); } -- 2.51.2 From aa93e7423cbc2025fa49f3e602cd1c98d60b33cb Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 19:49:06 +0200 Subject: [PATCH 32/69] slack app: fix (#2351) --- apps/server/src/routes/slack/workspace-resolver.ts | 6 +++++- packages/subscriptions/src/channels/slack.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/server/src/routes/slack/workspace-resolver.ts b/apps/server/src/routes/slack/workspace-resolver.ts index 750110ca..ec01c8b9 100644 --- a/apps/server/src/routes/slack/workspace-resolver.ts +++ b/apps/server/src/routes/slack/workspace-resolver.ts @@ -1,4 +1,4 @@ -import { and, db, eq } from "@openstatus/db"; +import { and, db, desc, eq } from "@openstatus/db"; import { integration, selectWorkspaceSchema, @@ -32,6 +32,10 @@ export async function resolveWorkspace( eq(integration.externalId, teamId), ), ) + // Slack keeps one live token per (app, team); a reinstall invalidates all + // earlier ones. If the team is linked to several workspaces, the newest row + // is the only one holding a valid token. + .orderBy(desc(integration.updatedAt)) .get(); if (!row?.workspaceId) return null; diff --git a/packages/subscriptions/src/channels/slack.ts b/packages/subscriptions/src/channels/slack.ts index 6759e688..f70589e1 100644 --- a/packages/subscriptions/src/channels/slack.ts +++ b/packages/subscriptions/src/channels/slack.ts @@ -1,4 +1,4 @@ -import { and, db, eq } from "@openstatus/db"; +import { and, db, desc, eq } from "@openstatus/db"; import { integration, pageSubscriber } from "@openstatus/db/src/schema"; import type { ChatPostMessageArguments, @@ -77,6 +77,10 @@ async function getBotTokenFromDb(teamId: string): Promise { eq(integration.externalId, teamId), ), ) + // Slack keeps one live token per (app, team); a reinstall invalidates all + // earlier ones. If the team is linked to several workspaces, the newest row + // is the only one holding a valid token. + .orderBy(desc(integration.updatedAt)) .get(); const credential = row?.credential as { botToken?: string } | null; return credential?.botToken ?? null; -- 2.51.2 From 32dc4be8ed1e3968d19bdec5b4f0093915afa2b7 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 21:22:04 +0200 Subject: [PATCH 33/69] slack app: improvment (#2352) * slack app: improvment * ci: apply automated fixes * slack app: improvment --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- apps/server/slack-manifest.json | 19 +++---- .../libs/test/doubles/slack-web-api.mock.ts | 6 +++ apps/server/src/routes/slack/handler.test.ts | 45 ++++++++++++++-- apps/server/src/routes/slack/handler.ts | 21 +++++++- apps/server/src/routes/slack/home.ts | 54 +++++++++++++++++++ apps/server/src/routes/slack/oauth.test.ts | 4 -- apps/server/src/routes/slack/oauth.ts | 4 -- .../src/channels/slack-blocks.ts | 16 ++++-- .../subscriptions/src/channels/slack-store.ts | 6 +++ .../subscriptions/src/channels/slack.test.ts | 51 ++++++++++++++++-- packages/subscriptions/src/channels/slack.ts | 37 +++++++++++-- 11 files changed, 230 insertions(+), 33 deletions(-) create mode 100644 apps/server/src/routes/slack/home.ts diff --git a/apps/server/slack-manifest.json b/apps/server/slack-manifest.json index f882dc5f..b6574141 100644 --- a/apps/server/slack-manifest.json +++ b/apps/server/slack-manifest.json @@ -3,7 +3,7 @@ "name": "openstatus", "description": "Manage incidents and status pages directly from Slack.", "background_color": "#000000", - "long_description": "openstatus brings incident management into your team's Slack workspace. Mention the bot or send it a direct message to create, update, and resolve status reports — no context switching required.\n\n How it works:\n :one: Describe the issue by mentioning @openstatus in any channel or thread\n :two: The assistant reads the conversation, queries your status pages, and drafts a status update\n :three: Review the proposed action and click Approve, Approve & Notify, or Cancel\n\n What you can do:\n :white_check_mark: Create status reports from natural conversation\n :white_check_mark: Post progress updates as incidents evolve\n :white_check_mark: Resolve incidents when the issue is fixed\n :white_check_mark: Notify your status page subscribers with one click\n :white_check_mark: Edit report titles and affected components\n\n The assistant understands context — tag it in an ongoing thread and it will synthesize the discussion into a clear, public-facing status update. It infers incident status automatically: \"we found the root cause\" becomes Identified, \"it's fixed\" becomes Resolved.\n\n AI disclaimer: openstatus uses large language models (LLMs) to summarize conversations, draft status updates, and infer incident status. AI-generated content may sometimes be inaccurate, incomplete, or misleading. Always review every draft before approving it — nothing is posted to your status page until you explicitly confirm. Only the person who triggered the action can approve it, and you can edit or cancel any draft." + "long_description": "openstatus brings incident management into your team's Slack workspace. Mention the bot in any channel to create, update, and resolve status reports — no context switching required.\n\n How it works:\n :one: Describe the issue by mentioning @openstatus in any channel or thread\n :two: The assistant reads the conversation, queries your status pages, and drafts a status update\n :three: Review the proposed action and click Approve, Approve & Notify, or Cancel\n\n What you can do:\n :white_check_mark: Create status reports from natural conversation\n :white_check_mark: Post progress updates as incidents evolve\n :white_check_mark: Resolve incidents when the issue is fixed\n :white_check_mark: Notify your status page subscribers with one click\n :white_check_mark: Edit report titles and affected components\n\n The assistant understands context — tag it in an ongoing thread and it will synthesize the discussion into a clear, public-facing status update. It infers incident status automatically: \"we found the root cause\" becomes Identified, \"it's fixed\" becomes Resolved.\n\n AI disclaimer: openstatus uses large language models (LLMs) to summarize conversations, draft status updates, and infer incident status. AI-generated content may sometimes be inaccurate, incomplete, or misleading. Always review every draft before approving it — nothing is posted to your status page until you explicitly confirm. Only the person who triggered the action can approve it, and you can edit or cancel any draft." }, "features": { "app_home": { @@ -19,8 +19,8 @@ { "command": "/openstatus", "url": "https://api.openstatus.dev/slack/commands", - "description": "Subscribe this channel to a status page", - "usage_hint": "subscribe | unsubscribe | subscriptions ", + "description": "Manage this channel's status page subscriptions", + "usage_hint": "subscribe | unsubscribe | subscriptions | help", "should_escape": false } ] @@ -38,11 +38,7 @@ "commands", "groups:history", "groups:read", - "groups:write", - "im:history", - "im:read", - "im:write", - "mpim:history" + "groups:write" ] }, "pkce_enabled": false @@ -50,7 +46,12 @@ "settings": { "event_subscriptions": { "request_url": "https://api.openstatus.dev/slack/events", - "bot_events": ["app_home_opened", "message.channels", "message.groups"] + "bot_events": [ + "app_home_opened", + "app_mention", + "message.channels", + "message.groups" + ] }, "interactivity": { "is_enabled": true, diff --git a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts index fd8d3c93..c4479e9e 100644 --- a/apps/server/src/libs/test/doubles/slack-web-api.mock.ts +++ b/apps/server/src/libs/test/doubles/slack-web-api.mock.ts @@ -23,4 +23,10 @@ export class WebClient { conversations = { replies: () => s.repliesImpl(), }; + views = { + publish: (args: Record) => { + s.calls.push({ method: "views.publish", args }); + return Promise.resolve({ ok: true }); + }, + }; } diff --git a/apps/server/src/routes/slack/handler.test.ts b/apps/server/src/routes/slack/handler.test.ts index 0bfcfbad..0c49074f 100644 --- a/apps/server/src/routes/slack/handler.test.ts +++ b/apps/server/src/routes/slack/handler.test.ts @@ -110,6 +110,46 @@ describe("handleSlackEvent", () => { expect(json.ok).toBe(true); }); + test("publishes the home view on app_home_opened", async () => { + const res = await signAndPost(app, { + type: "event_callback", + team_id: "T_KNOWN", + event_id: `evt_home_${Date.now()}`, + event: { + type: "app_home_opened", + tab: "home", + user: "U1", + }, + }); + + expect(res.status).toBe(200); + await new Promise((r) => setTimeout(r, 50)); + + const publish = slackTestState.calls.find( + (m) => m.method === "views.publish", + ); + expect(publish).toBeDefined(); + expect((publish?.args.view as { type: string }).type).toBe("home"); + expect(publish?.args.user_id).toBe("U1"); + }); + + test("ignores app_home_opened for the messages tab", async () => { + const res = await signAndPost(app, { + type: "event_callback", + team_id: "T_KNOWN", + event_id: `evt_home_msgs_${Date.now()}`, + event: { + type: "app_home_opened", + tab: "messages", + user: "U1", + }, + }); + + expect(res.status).toBe(200); + await new Promise((r) => setTimeout(r, 50)); + expect(slackTestState.calls.length).toBe(0); + }); + test("handles app_uninstalled event", async () => { const res = await signAndPost(app, { type: "event_callback", @@ -219,7 +259,7 @@ describe("handleSlackEvent", () => { expect(slackTestState.calls.length).toBe(0); }); - test("processes DM messages without bot mention", async () => { + test("ignores DM messages", async () => { const res = await signAndPost(app, { type: "event_callback", team_id: "T_KNOWN", @@ -236,8 +276,7 @@ describe("handleSlackEvent", () => { expect(res.status).toBe(200); await new Promise((r) => setTimeout(r, 50)); - // DM should trigger a response (postMessage for "Thinking...") - expect(slackTestState.calls.length).toBeGreaterThan(0); + expect(slackTestState.calls.length).toBe(0); }); test("ignores events without channel", async () => { diff --git a/apps/server/src/routes/slack/handler.ts b/apps/server/src/routes/slack/handler.ts index 1c972321..fbdaf05d 100644 --- a/apps/server/src/routes/slack/handler.ts +++ b/apps/server/src/routes/slack/handler.ts @@ -13,6 +13,7 @@ import { } from "./blocks"; import { findByThread, replace, store } from "./confirmation-store"; import type { PendingPayload } from "./confirmation-store"; +import { publishHomeView } from "./home"; import { getComponentNames, getPageDashboardLink } from "./page-urls"; import { getRegistryTool, isSlackToolDraft } from "./registry-runner"; import { resolveWorkspace } from "./workspace-resolver"; @@ -51,6 +52,7 @@ const slackEventSchema = z.object({ ts: z.string().optional(), thread_ts: z.string().optional(), bot_id: z.string().optional(), + tab: z.string().optional(), }) .optional(), event_id: z.string().optional(), @@ -138,6 +140,21 @@ async function processEvent(body: SlackEvent) { return; } + if (event.type === "app_home_opened") { + if (event.tab && event.tab !== "home") return; + const teamId = body.team_id; + const userId = event.user; + if (!teamId || !userId) return; + const resolved = await resolveWorkspace(teamId); + if (!resolved) return; + try { + await publishHomeView(new WebClient(resolved.botToken), userId); + } catch (err) { + logger.error("slack failed to publish home view", { error: err, teamId }); + } + return; + } + if (event.type !== "app_mention" && event.type !== "message") return; if (event.type === "message" && event.bot_id) return; @@ -163,8 +180,8 @@ async function processEvent(body: SlackEvent) { const botUserId = resolved.botUserId; const threadTs = event.thread_ts ?? event.ts; - if (event.type === "message" && event.channel_type !== "im") { - if (!event.text?.includes(`<@${botUserId}>`)) return; + if (event.type === "message" && !event.text?.includes(`<@${botUserId}>`)) { + return; } logger.info("slack event received", { diff --git a/apps/server/src/routes/slack/home.ts b/apps/server/src/routes/slack/home.ts new file mode 100644 index 00000000..a7030af6 --- /dev/null +++ b/apps/server/src/routes/slack/home.ts @@ -0,0 +1,54 @@ +import type { WebClient } from "@slack/web-api"; +import type { KnownBlock } from "@slack/web-api"; + +const DOCS_URL = "https://www.openstatus.dev/docs"; + +export function buildHomeBlocks(): KnownBlock[] { + return [ + { + type: "header", + text: { type: "plain_text", text: "openstatus", emoji: true }, + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "Manage incidents and status pages without leaving Slack. Mention *@openstatus* in any channel or thread and it drafts a status update from the conversation — nothing is published until you approve it.", + }, + }, + { type: "divider" }, + { + type: "section", + text: { + type: "mrkdwn", + text: '*Create & update incidents*\nMention `@openstatus` describing the issue. It reads the thread, drafts a report, and you click *Approve*, *Approve & Notify*, or *Cancel*. Say _"we found the cause"_ or _"it\'s fixed"_ and it moves the incident to Identified or Resolved.', + }, + }, + { + type: "section", + text: { + type: "mrkdwn", + text: "*Slash commands*\n• `/openstatus subscribe ` — subscribe this channel to a status page\n• `/openstatus unsubscribe ` — unsubscribe this channel\n• `/openstatus subscriptions` — list this channel's subscriptions\n• `/openstatus help` — show these commands", + }, + }, + { + type: "context", + elements: [ + { + type: "mrkdwn", + text: `<${DOCS_URL}|Documentation> · Updates from subscribed status pages appear as threaded messages in the channel.`, + }, + ], + }, + ]; +} + +export async function publishHomeView( + slack: WebClient, + userId: string, +): Promise { + await slack.views.publish({ + user_id: userId, + view: { type: "home", blocks: buildHomeBlocks() }, + }); +} diff --git a/apps/server/src/routes/slack/oauth.test.ts b/apps/server/src/routes/slack/oauth.test.ts index 19624dd0..cb99f265 100644 --- a/apps/server/src/routes/slack/oauth.test.ts +++ b/apps/server/src/routes/slack/oauth.test.ts @@ -98,10 +98,6 @@ describe("handleSlackInstall", () => { "groups:history", "groups:read", "groups:write", - "im:history", - "im:read", - "im:write", - "mpim:history", ]; for (const s of expectedScopes) { diff --git a/apps/server/src/routes/slack/oauth.ts b/apps/server/src/routes/slack/oauth.ts index 636fedd9..9faaa2ae 100644 --- a/apps/server/src/routes/slack/oauth.ts +++ b/apps/server/src/routes/slack/oauth.ts @@ -25,10 +25,6 @@ const BOT_SCOPES = [ "groups:history", "groups:read", "groups:write", - "im:history", - "im:read", - "im:write", - "mpim:history", ].join(","); interface OAuthState { diff --git a/packages/subscriptions/src/channels/slack-blocks.ts b/packages/subscriptions/src/channels/slack-blocks.ts index 32004f2b..be418d37 100644 --- a/packages/subscriptions/src/channels/slack-blocks.ts +++ b/packages/subscriptions/src/channels/slack-blocks.ts @@ -107,14 +107,24 @@ export function buildRootMessage( elements: [ { type: "mrkdwn", - text: `Updated ${pageUpdate.date} · <${eventUrl(pageUpdate, subscription)}|View details> · Manage with \`/openstatus remove\``, + text: `Updated ${pageUpdate.date} · <${eventUrl(pageUpdate, subscription)}|View details> · Manage with \`/openstatus unsubscribe\``, }, ], }); + const title = `${emoji} ${pageUpdate.title} — ${label}`; return { - text: `${emoji} ${pageUpdate.title} — ${label}`, - attachments: [{ color: COLORS[statusColor(pageUpdate.status)], blocks }], + // `text` is the notification/accessibility fallback only — it is NOT sent + // as the message body, otherwise the title renders twice (once here, once + // in the card's header block). See the root post/update calls in slack.ts. + text: title, + attachments: [ + { + color: COLORS[statusColor(pageUpdate.status)], + fallback: title, + blocks, + }, + ], }; } diff --git a/packages/subscriptions/src/channels/slack-store.ts b/packages/subscriptions/src/channels/slack-store.ts index 77d0e38c..a635cf80 100644 --- a/packages/subscriptions/src/channels/slack-store.ts +++ b/packages/subscriptions/src/channels/slack-store.ts @@ -1,8 +1,14 @@ import { Redis } from "@upstash/redis"; +import type { SlackReplyMessage } from "./slack-blocks"; + export interface SlackThreadAnchor { ts: string; channelId: string; + // The first update lives only in the root message until a second update + // arrives and re-renders the root. We stash its reply payload here so the + // next update can backfill it into the thread before it's overwritten. + pendingRootReply?: SlackReplyMessage; } export interface SlackAnchorStore { diff --git a/packages/subscriptions/src/channels/slack.test.ts b/packages/subscriptions/src/channels/slack.test.ts index d4494cf3..8dabbe03 100644 --- a/packages/subscriptions/src/channels/slack.test.ts +++ b/packages/subscriptions/src/channels/slack.test.ts @@ -14,6 +14,7 @@ interface RecordedCall { channel: string; thread_ts?: string; ts?: string; + text?: string; } function makeClient(opts: { failPostWith?: string } = {}) { @@ -25,6 +26,7 @@ function makeClient(opts: { failPostWith?: string } = {}) { method: "post", channel: args.channel, thread_ts: args.thread_ts, + text: (args as { text?: string }).text, }); if (opts.failPostWith) { const error = new Error("slack error") as Error & { @@ -96,7 +98,7 @@ describe("createSlackChannel", () => { expect(await store.getAnchor(10, 1)).not.toBeNull(); }); - test("subsequent update replies in thread and re-renders root", async () => { + test("subsequent update backfills the first update then replies in thread and re-renders root", async () => { const { client, calls } = makeClient(); const store = createMemoryAnchorStore(); const channel = createSlackChannel({ @@ -106,18 +108,59 @@ describe("createSlackChannel", () => { softUnsubscribe: noopUnsub, }); - await channel.sendNotifications([makeSub()], makeUpdate({ updateId: 100 })); await channel.sendNotifications( [makeSub()], - makeUpdate({ updateId: 101, status: "monitoring" }), + makeUpdate({ updateId: 100, message: "first update" }), + ); + await channel.sendNotifications( + [makeSub()], + makeUpdate({ + updateId: 101, + status: "monitoring", + message: "second update", + }), ); const posts = calls.filter((c) => c.method === "post"); - expect(posts.length).toBe(2); + // root post + backfill of the first update + reply for the second update + expect(posts.length).toBe(3); + // The first update is preserved in the thread, not lost to the root re-render. expect(posts[1]?.thread_ts).toBe("1700000000.0001"); + expect(posts[1]?.text).toContain("first update"); + expect(posts[2]?.thread_ts).toBe("1700000000.0001"); + expect(posts[2]?.text).toContain("second update"); expect(calls.some((c) => c.method === "update")).toBe(true); }); + test("third update does not backfill the first update again", async () => { + const { client, calls } = makeClient(); + const store = createMemoryAnchorStore(); + const channel = createSlackChannel({ + store, + createClient: () => client, + getBotToken: token, + softUnsubscribe: noopUnsub, + }); + + await channel.sendNotifications( + [makeSub()], + makeUpdate({ updateId: 100, message: "first update" }), + ); + await channel.sendNotifications( + [makeSub()], + makeUpdate({ updateId: 101, message: "second update" }), + ); + await channel.sendNotifications( + [makeSub()], + makeUpdate({ updateId: 102, message: "third update" }), + ); + + const backfills = calls.filter( + (c) => c.method === "post" && c.text?.includes("first update"), + ); + expect(backfills.length).toBe(1); + }); + test("same update delivered twice posts once (idempotent)", async () => { const { client, calls } = makeClient(); const store = createMemoryAnchorStore(); diff --git a/packages/subscriptions/src/channels/slack.ts b/packages/subscriptions/src/channels/slack.ts index f70589e1..0c81d01c 100644 --- a/packages/subscriptions/src/channels/slack.ts +++ b/packages/subscriptions/src/channels/slack.ts @@ -134,7 +134,6 @@ export function createSlackChannel(deps: SlackChannelDeps) { const res = await runSlack(sub.id, () => client.postMessage({ channel: channelId, - text: root.text, attachments: root.attachments, }), ); @@ -165,7 +164,6 @@ export function createSlackChannel(deps: SlackChannelDeps) { const res = await runSlack(sub.id, () => client.postMessage({ channel: channelId, - text: root.text, attachments: root.attachments, }), ); @@ -174,11 +172,43 @@ export function createSlackChannel(deps: SlackChannelDeps) { return res === TEAM_TOKEN_INVALID ? TEAM_TOKEN_INVALID : undefined; } if (res.ts) { - await deps.store.setAnchor(reportId, sub.id, { ts: res.ts, channelId }); + // Stash this first update so the next one can backfill it into the + // thread before the root is re-rendered and its content lost. + await deps.store.setAnchor(reportId, sub.id, { + ts: res.ts, + channelId, + pendingRootReply: buildReplyMessage(pageUpdate), + }); } return; } + // The first update only ever lived in the root. Before we overwrite the + // root below, post it into the thread so its history is preserved. + if (anchor.pendingRootReply) { + const backfill = anchor.pendingRootReply; + const backfillRes = await runSlack(sub.id, () => + client.postMessage({ + channel: anchor.channelId, + thread_ts: anchor.ts, + text: backfill.text, + blocks: backfill.blocks, + }), + ); + if (!backfillRes || backfillRes === TEAM_TOKEN_INVALID) { + await deps.store.releaseDelivery(reportId, sub.id, updateId); + return backfillRes === TEAM_TOKEN_INVALID + ? TEAM_TOKEN_INVALID + : undefined; + } + // Clear before posting the current reply: if that reply fails and the + // delivery is retried, the first update must not be backfilled twice. + await deps.store.setAnchor(reportId, sub.id, { + ts: anchor.ts, + channelId: anchor.channelId, + }); + } + const reply = buildReplyMessage(pageUpdate); const replyRes = await runSlack(sub.id, () => client.postMessage({ @@ -198,7 +228,6 @@ export function createSlackChannel(deps: SlackChannelDeps) { client.update({ channel: anchor.channelId, ts: anchor.ts, - text: root.text, attachments: root.attachments, }), ); -- 2.51.2 From 7c4ddd7d2af4edefa840676dc8b15b822ea90304 Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Mon, 6 Jul 2026 21:47:44 +0200 Subject: [PATCH 34/69] slack app: dedupe event (#2353) --- apps/server/src/routes/slack/handler.test.ts | 33 ++++++++++++++++++++ apps/server/src/routes/slack/handler.ts | 6 ++++ 2 files changed, 39 insertions(+) diff --git a/apps/server/src/routes/slack/handler.test.ts b/apps/server/src/routes/slack/handler.test.ts index 0c49074f..feca71bc 100644 --- a/apps/server/src/routes/slack/handler.test.ts +++ b/apps/server/src/routes/slack/handler.test.ts @@ -150,6 +150,39 @@ describe("handleSlackEvent", () => { expect(slackTestState.calls.length).toBe(0); }); + test("responds once when a mention arrives as app_mention and message", async () => { + const ts = `${Date.now()}.55`; + const base = { + type: "event_callback", + team_id: "T_KNOWN", + event: { + text: "<@UBOT> create an incident", + user: "U1", + channel: "C1", + channel_type: "channel", + ts, + }, + }; + + // Same underlying message, delivered as two distinct events. + await signAndPost(app, { + ...base, + event_id: `evt_mention_${ts}`, + event: { ...base.event, type: "app_mention" }, + }); + await signAndPost(app, { + ...base, + event_id: `evt_message_${ts}`, + event: { ...base.event, type: "message" }, + }); + await new Promise((r) => setTimeout(r, 100)); + + const thinking = slackTestState.calls.filter( + (m) => m.method === "postMessage", + ); + expect(thinking.length).toBe(1); + }); + test("handles app_uninstalled event", async () => { const res = await signAndPost(app, { type: "event_callback", diff --git a/apps/server/src/routes/slack/handler.ts b/apps/server/src/routes/slack/handler.ts index fbdaf05d..8d6a54da 100644 --- a/apps/server/src/routes/slack/handler.ts +++ b/apps/server/src/routes/slack/handler.ts @@ -170,6 +170,12 @@ async function processEvent(body: SlackEvent) { const teamId = body.team_id; if (!teamId || !event.channel || !event.ts) return; + // A single mention arrives as BOTH an `app_mention` and a `message.*` event + // (distinct event_ids, same message ts), so the event_id dedup above doesn't + // catch the pair. Dedup on the message identity so we only respond once. + // Runs before the first `await` so concurrent deliveries can't both pass. + if (dedup(`msg:${event.channel}:${event.ts}`)) return; + const resolved = await resolveWorkspace(teamId); if (!resolved) { logger.warn("slack integration not found", { teamId }); -- 2.51.2 From 2b819590b49a2dcac1c80466221791d5c158ee5a Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:13:54 +0200 Subject: [PATCH 35/69] Add Commit Mono font and configure monospace font stack (#2356) * feat(web): use Commit Mono as the monospace font Load CommitMono via next/font/local in the root layout and map Tailwind's --font-mono to it, matching the dashboard and status-page apps. All existing font-mono usage now renders in Commit Mono. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011v4nLgnniGav1frub1yxJ9 * fix(web): map --font-mono via @theme inline so it resolves under body The plain @theme block emits the variable on :root, where next/font's --font-commit-mono (set on body) is undefined, breaking every font-mono utility. @theme inline inlines the reference so it resolves at the element, matching the dashboard and status-page setup. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011v4nLgnniGav1frub1yxJ9 --------- Co-authored-by: Claude --- apps/web/src/app/layout.tsx | 28 +++++++++++++++++++++++++++- apps/web/src/styles/globals.css | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index cdd6ea15..a4059156 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -25,6 +25,32 @@ const calSans = LocalFont({ variable: "--font-cal", }); +const commitMono = LocalFont({ + src: [ + { + path: "../public/fonts/CommitMono-400-Regular.otf", + weight: "400", + style: "normal", + }, + { + path: "../public/fonts/CommitMono-400-Italic.otf", + weight: "400", + style: "italic", + }, + { + path: "../public/fonts/CommitMono-700-Regular.otf", + weight: "700", + style: "normal", + }, + { + path: "../public/fonts/CommitMono-700-Italic.otf", + weight: "700", + style: "italic", + }, + ], + variable: "--font-commit-mono", +}); + export const metadata: Metadata = { ...defaultMetadata, twitter: { @@ -45,7 +71,7 @@ export default function RootLayout({ diff --git a/apps/web/src/styles/globals.css b/apps/web/src/styles/globals.css index deae2997..eb5746e5 100644 --- a/apps/web/src/styles/globals.css +++ b/apps/web/src/styles/globals.css @@ -44,6 +44,10 @@ } } +@theme inline { + --font-mono: var(--font-commit-mono); +} + @utility container { margin-inline: auto; padding-inline: 2rem; -- 2.51.2 From e5e3848e3ef980eaf647e17d1d7304c525792965 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Wed, 8 Jul 2026 21:27:15 +0200 Subject: [PATCH 36/69] Add custom theme support for status pages (#2354) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(status-page): add custom CSS gated by new custom-css plan limit - add "custom-css" boolean limit (team + scale only) and page.custom_css column - add sanitizeCustomCss / hasCustomCss / generatePageStyles to theme-store with tests - add updatePageCustomCss service verb (scope check, plan gate, audit) + tRPC endpoint - add FormCustomCss dashboard card with upgrade overlay when not eligible - render custom CSS after the theme on status pages so it wins the cascade, nulled out server-side when the workspace plan no longer includes the limit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * chore: retrigger CI (flaky subscriptions dispatcher test) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * feat(status-page): full css-var placeholder + custom css validation - generateCustomCssTemplate lists every THEME_VAR_NAMES entry pre-filled with the page's selected theme values; used as the textarea placeholder - validateCustomCss (theme-store) checks length, '<' breakouts, brace balance (comment/string aware) and presence of declaration blocks - wired into the dashboard form schema and UpdatePageCustomCssInput Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * fix(theme-store): linear-time css scan + align service test with validation - replace the lazy comment/string regexes with a single-pass scanner (CodeQL js/polynomial-redos on repeated unclosed "/*") and early-return on over-length input so the scan is bounded - update the service test: '<' in custom css is now rejected at the boundary instead of silently sanitized; add reject cases for breakout and unbalanced braces Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * chore: retrigger CI (flaky subscriptions dispatcher test) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * fix(theme-store): comment out unset vars in the custom css template An empty `--x: ;` from the saved template would override the global default with an empty value (custom css wins the cascade). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * chore: retrigger CI (flaky monitor quota test) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * wip: custom theme * fix(theme-store): linear declaration parser + drop duplicate migration - parseThemeVarsText: manual colon-split instead of a lazy regex that backtracks quadratically on hostile input (CodeQL js/polynomial-redos) - remove 0079_parched_sugar_man.sql — double-generate artifact not referenced by the drizzle journal Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * fix(subscriptions): deflake dispatcher entire-page assertion Package test suites run in parallel against the same seeded page, so an exact recipient count races with subscribers inserted by other suites. Assert against this suite's own subscriber emails instead. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011R5Sq8Hcmzw1n6QVpVGyNM * chore: changelog --------- Co-authored-by: Claude --- .../forms/status-page/form-custom-theme.tsx | 216 + .../components/forms/status-page/update.tsx | 18 + apps/dashboard/src/data/plans.ts | 4 + .../src/app/(status-page)/[domain]/layout.tsx | 10 +- .../status-page/floating-button.tsx | 16 +- .../changelog/status-page-custom-theme.png | Bin 0 -> 206752 bytes .../changelog/status-page-custom-theme.mdx | 16 + .../pages/docs/reference/status-page.mdx | 69 + .../src/content/pages/unrelated/pricing.mdx | 1 + deno.lock | 234 - packages/api/src/router/page.ts | 16 + packages/api/src/router/statusPage.ts | 10 + .../db/drizzle/0079_fixed_spencer_smythe.sql | 1 + packages/db/drizzle/meta/0079_snapshot.json | 4719 +++++++++++++++++ packages/db/drizzle/meta/_journal.json | 7 + packages/db/src/schema/pages/page.ts | 5 + packages/db/src/schema/pages/validation.ts | 10 + packages/db/src/schema/plan/config.ts | 4 + packages/db/src/schema/plan/schema.ts | 1 + .../services/src/page/__tests__/page.test.ts | 136 +- packages/services/src/page/index.ts | 2 + packages/services/src/page/schemas.ts | 38 +- packages/services/src/page/update.ts | 37 + packages/subscriptions/src/dispatcher.test.ts | 10 +- packages/theme-store/package.json | 5 +- .../src/__tests__/custom-theme.test.ts | 204 + packages/theme-store/src/custom-theme.ts | 139 + packages/theme-store/src/index.ts | 23 + pnpm-lock.yaml | 6 + 29 files changed, 5713 insertions(+), 244 deletions(-) create mode 100644 apps/dashboard/src/components/forms/status-page/form-custom-theme.tsx create mode 100644 apps/web/public/assets/changelog/status-page-custom-theme.png create mode 100644 apps/web/src/content/pages/changelog/status-page-custom-theme.mdx create mode 100644 packages/db/drizzle/0079_fixed_spencer_smythe.sql create mode 100644 packages/db/drizzle/meta/0079_snapshot.json create mode 100644 packages/theme-store/src/__tests__/custom-theme.test.ts create mode 100644 packages/theme-store/src/custom-theme.ts diff --git a/apps/dashboard/src/components/forms/status-page/form-custom-theme.tsx b/apps/dashboard/src/components/forms/status-page/form-custom-theme.tsx new file mode 100644 index 00000000..dab6f3ce --- /dev/null +++ b/apps/dashboard/src/components/forms/status-page/form-custom-theme.tsx @@ -0,0 +1,216 @@ +import { zodResolver } from "@hookform/resolvers/zod"; +import { + type CustomTheme, + formatThemeVars, + generateThemeVarsTemplate, + parseThemeVarsText, + THEMES, + type ThemeMode, +} from "@openstatus/theme-store"; +import { Button } from "@openstatus/ui/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormMessage, +} from "@openstatus/ui/components/ui/form"; +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@openstatus/ui/components/ui/tabs"; +import { Textarea } from "@openstatus/ui/components/ui/textarea"; +import { cn } from "@openstatus/ui/lib/utils"; +import { isTRPCClientError } from "@trpc/client"; +import { ChevronsDownUp, ChevronsUpDown, Lock } from "lucide-react"; +import { useState, useTransition } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; + +import { Link } from "@/components/common/link"; +import { + FormCard, + FormCardContent, + FormCardDescription, + FormCardFooter, + FormCardFooterInfo, + FormCardHeader, + FormCardSeparator, + FormCardTitle, + FormCardUpgrade, +} from "@/components/forms/form-card"; + +const MODES = ["light", "dark"] as const; + +const modeText = z.string().superRefine((value, ctx) => { + for (const message of parseThemeVarsText(value).errors) { + ctx.addIssue({ code: "custom", message }); + } +}); + +const schema = z.object({ light: modeText, dark: modeText }); + +type FormValues = z.infer; + +export function FormCustomTheme({ + defaultValue, + onSubmit, + locked, + themeKey, +}: { + defaultValue?: CustomTheme | null; + onSubmit: (values: { customTheme: CustomTheme }) => Promise; + locked?: boolean; + themeKey?: string; +}) { + const theme = THEMES[themeKey ?? "default"] ?? THEMES.default; + const [mode, setMode] = useState("light"); + const [extended, setExtended] = useState(false); + const [isPending, startTransition] = useTransition(); + const form = useForm({ + resolver: zodResolver(schema), + defaultValues: { + light: formatThemeVars(defaultValue?.light), + dark: formatThemeVars(defaultValue?.dark), + }, + }); + + function submitAction(values: FormValues) { + if (isPending) return; + + startTransition(async () => { + try { + const promise = onSubmit({ + customTheme: { + light: parseThemeVarsText(values.light).vars, + dark: parseThemeVarsText(values.dark).vars, + }, + }); + toast.promise(promise, { + loading: "Saving...", + success: "Saved", + error: (error) => { + if (isTRPCClientError(error)) { + return error.message; + } + return "Failed to save"; + }, + }); + await promise; + } catch (error) { + console.error(error); + } + }); + } + + return ( +
+ { + // jump to the first tab with a validation error + const errored = MODES.find((m) => errors[m]); + if (errored) setMode(errored); + })} + > + + {locked ? : null} + + Custom Theme + + Override the selected theme's CSS variables with your own + values for light and dark mode. + + + + + setMode(v as ThemeMode)}> +
+ + Light + Dark + + +
+ {MODES.map((m) => ( + + ( + + +