Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
2.4 kB ยท 79 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980import { eq, sql } from "@openstatus/db";import { integration } from "@openstatus/db/src/schema";import { z } from "zod";
import { type ServiceContext, getReadDb } from "../context";import { ListIntegrationsInput } from "./schemas";
const integrationSummarySchema = z.object({ id: z.number(), name: z.string(), externalId: z.string(), data: z.record(z.string(), z.unknown()), createdAt: z.coerce.date().nullable(),});
export type IntegrationSummary = z.infer<typeof integrationSummarySchema>;
function safeJsonParse( rowId: number, value: string | null,): Record<string, unknown> { if (!value) return {}; let parsed: unknown; try { parsed = JSON.parse(value); } catch (cause) { console.warn("integration row has malformed `data` JSON", { integrationId: rowId, cause: cause instanceof Error ? cause.message : "unknown", }); return {}; } // Valid JSON but wrong shape (string, number, array, null) would fail // the row-level `z.record` check and crash the whole list. if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) { console.warn("integration row has non-object `data` JSON", { integrationId: rowId, }); return {}; } return parsed as Record<string, unknown>;}
/** * List integrations for the caller's workspace. `data` is stored as a * JSON-mode text column; we force-cast to raw text with `sql<string>` so * malformed rows don't break the whole list (fall back to `{}`). The * `credential` column is never selected โ it carries secrets and is not * part of the list contract. */export async function listIntegrations(args: { ctx: ServiceContext; input?: ListIntegrationsInput;}): Promise<IntegrationSummary[]> { ListIntegrationsInput.parse(args.input ?? {}); const db = getReadDb(args.ctx);
const rows = await db .select({ id: integration.id, name: integration.name, externalId: integration.externalId, rawData: sql<string>`${integration.data}`, createdAt: integration.createdAt, }) .from(integration) .where(eq(integration.workspaceId, args.ctx.workspace.id)) .all();
return integrationSummarySchema.array().parse( rows.map((row) => ({ id: row.id, name: row.name, externalId: row.externalId, data: safeJsonParse(row.id, row.rawData), createdAt: row.createdAt, })), );}