diff --git a/bun.lockb b/bun.lockb index 103e57f4..2b0a8fae 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/services/dub/config.json b/services/dub/config.json index c3fb85ec..dd3691c4 100644 --- a/services/dub/config.json +++ b/services/dub/config.json @@ -1,5 +1,11 @@ { "name": "dub", + "envs": { + "DUB_API_KEY": { + "description": "The API key to use for Dub", + "required": true + } + }, "generate": { "src/index.ts": "apps/app/src/libs/dub.ts" } diff --git a/services/openpanel/config.json b/services/openpanel/config.json index 3dd5f927..1186691f 100644 --- a/services/openpanel/config.json +++ b/services/openpanel/config.json @@ -1,3 +1,13 @@ { - "name": "openpanel" + "name": "openpanel", + "envs": { + "OPENPANEL_API_KEY": { + "description": "The API key to use for OpenPanel", + "required": true + }, + "OPENPANEL_PROJECT_ID": { + "description": "The project ID to use for OpenPanel", + "required": true + } + } } diff --git a/services/openpanel/tsconfig.json b/services/openpanel/tsconfig.json index 134d6142..087d49f2 100644 --- a/services/openpanel/tsconfig.json +++ b/services/openpanel/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./src/*"], - "@v1/ui/*": ["../ui/src/*"] + "@/*": ["./src/*"] } }, "include": ["."], diff --git a/services/resend/config.json b/services/resend/config.json index b5821bf6..2826708b 100644 --- a/services/resend/config.json +++ b/services/resend/config.json @@ -1,3 +1,9 @@ { - "name": "resend" + "name": "resend", + "envs": { + "RESEND_API_KEY": { + "description": "The API key to use for Resend", + "required": true + } + } } diff --git a/services/resend/src/index.ts b/services/resend/src/index.ts index e69de29b..295c0330 100644 --- a/services/resend/src/index.ts +++ b/services/resend/src/index.ts @@ -0,0 +1,3 @@ +import { Resend } from "resend"; + +export const resend = new Resend(process.env.RESEND_API_KEY!); diff --git a/services/sentry/config.json b/services/sentry/config.json new file mode 100644 index 00000000..eb15b556 --- /dev/null +++ b/services/sentry/config.json @@ -0,0 +1,20 @@ +{ + "name": "sentry", + "envs": { + "SENTRY_AUTH_TOKEN": { + "description": "The auth token to use for Sentry", + "required": true + }, + "NEXT_PUBLIC_SENTRY_DSN": { + "description": "The DSN to use for Sentry", + "required": true + } + }, + "generate": { + "src/instrumentation/src/index.ts": "apps/app/src/instrumentation.ts", + "src/global-error.tsx": "apps/app/src/global-error.tsx", + "src/sentry.server.config.ts": "apps/app/src/sentry.server.config.ts", + "src/sentry.edge.config.ts": "apps/app/src/sentry.edge.config.ts", + "src/sentry.client.config.ts": "apps/app/src/sentry.client.config.ts" + } +} diff --git a/services/sentry/package.json b/services/sentry/package.json new file mode 100644 index 00000000..13e658f9 --- /dev/null +++ b/services/sentry/package.json @@ -0,0 +1,15 @@ +{ + "name": "@v1/sentry", + "version": "1.0.0", + "private": true, + "scripts": { + "clean": "rm -rf .turbo node_modules", + "lint": "biome check .", + "format": "biome format --write .", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@sentry/nextjs": "^8", + "@supabase/sentry-js-integration": "^0.3.0" + } +} diff --git a/apps/app/src/app/global-error.tsx b/services/sentry/src/global-error.tsx similarity index 100% rename from apps/app/src/app/global-error.tsx rename to services/sentry/src/global-error.tsx diff --git a/services/sentry/src/instrumentation/index.ts b/services/sentry/src/instrumentation/index.ts new file mode 100644 index 00000000..10aaacea --- /dev/null +++ b/services/sentry/src/instrumentation/index.ts @@ -0,0 +1,9 @@ +export async function register() { + if (process.env.NEXT_RUNTIME === "nodejs") { + await import("../sentry.server.config"); + } + + if (process.env.NEXT_RUNTIME === "edge") { + await import("../sentry.edge.config"); + } +} diff --git a/services/sentry/src/next.config.mjs b/services/sentry/src/next.config.mjs new file mode 100644 index 00000000..15854529 --- /dev/null +++ b/services/sentry/src/next.config.mjs @@ -0,0 +1,19 @@ +import "./src/env.mjs"; +import { withSentryConfig } from "@sentry/nextjs"; + +/** @type {import('next').NextConfig} */ +const nextConfig = { + transpilePackages: ["@v1/supabase"], + experimental: { + instrumentationHook: process.env.NODE_ENV === "production", + }, +}; + +export default withSentryConfig(nextConfig, { + silent: !process.env.CI, + telemetry: false, + widenClientFileUpload: true, + hideSourceMaps: true, + disableLogger: true, + tunnelRoute: "/monitoring", +}); diff --git a/services/sentry/src/sentry.client.config.ts b/services/sentry/src/sentry.client.config.ts new file mode 100644 index 00000000..18f63c3b --- /dev/null +++ b/services/sentry/src/sentry.client.config.ts @@ -0,0 +1,19 @@ +import * as Sentry from "@sentry/nextjs"; +import { supabaseIntegration } from "@supabase/sentry-js-integration"; +import { createClient } from "@v1/supabase/client"; + +const client = createClient(); + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + tracesSampleRate: 1, + debug: false, + enabled: process.env.NODE_ENV === "production", + integrations: [ + supabaseIntegration(client, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + ], +}); diff --git a/services/sentry/src/sentry.edge.config.ts b/services/sentry/src/sentry.edge.config.ts new file mode 100644 index 00000000..e33dc67b --- /dev/null +++ b/services/sentry/src/sentry.edge.config.ts @@ -0,0 +1,8 @@ +import * as Sentry from "@sentry/nextjs"; + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + enabled: process.env.NODE_ENV === "production", + tracesSampleRate: 1, + debug: false, +}); diff --git a/services/sentry/src/sentry.server.config.ts b/services/sentry/src/sentry.server.config.ts new file mode 100644 index 00000000..18f63c3b --- /dev/null +++ b/services/sentry/src/sentry.server.config.ts @@ -0,0 +1,19 @@ +import * as Sentry from "@sentry/nextjs"; +import { supabaseIntegration } from "@supabase/sentry-js-integration"; +import { createClient } from "@v1/supabase/client"; + +const client = createClient(); + +Sentry.init({ + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + tracesSampleRate: 1, + debug: false, + enabled: process.env.NODE_ENV === "production", + integrations: [ + supabaseIntegration(client, Sentry, { + tracing: true, + breadcrumbs: true, + errors: true, + }), + ], +}); diff --git a/services/sentry/tsconfig.json b/services/sentry/tsconfig.json new file mode 100644 index 00000000..087d49f2 --- /dev/null +++ b/services/sentry/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@v1/typescript/react-library.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["."], + "exclude": ["node_modules"] +} diff --git a/services/trigger/config.json b/services/trigger/config.json index e04a393d..a97dd4c9 100644 --- a/services/trigger/config.json +++ b/services/trigger/config.json @@ -1,3 +1,13 @@ { - "name": "trigger" + "name": "trigger", + "envs": { + "TRIGGER_API_KEY": { + "description": "The API key to use for Trigger", + "required": true + }, + "TRIGGER_PROJECT_ID": { + "description": "The project ID to use for Trigger (https://trigger.dev/docs/trigger-config)", + "required": true + } + } } diff --git a/services/trigger/trigger.config.ts b/services/trigger/trigger.config.ts index 30bf16a0..04d87a0a 100644 --- a/services/trigger/trigger.config.ts +++ b/services/trigger/trigger.config.ts @@ -1,8 +1,7 @@ import type { TriggerConfig } from "@trigger.dev/sdk/v3"; export const config: TriggerConfig = { - // Replace with your project id: https://trigger.dev/docs/trigger-config - project: "", + project: process.env.TRIGGER_PROJECT_ID!, logLevel: "log", retries: { enabledInDev: true, diff --git a/services/upstash/config.json b/services/upstash/config.json index 6c28eede..7fb34103 100644 --- a/services/upstash/config.json +++ b/services/upstash/config.json @@ -1,3 +1,13 @@ { - "name": "upstash" + "name": "upstash", + "envs": { + "UPSTASH_REDIS_REST_URL": { + "description": "The URL to use for Upstash", + "required": true + }, + "UPSTASH_REDIS_REST_TOKEN": { + "description": "The token to use for Upstash", + "required": true + } + } }