env.ts60 lines · main
| 1 | import { loadEnv } from '@briven/shared'; |
| 2 | import { z } from 'zod'; |
| 3 | |
| 4 | const envSchema = z.object({ |
| 5 | BRIVEN_ENV: z.enum(['development', 'staging', 'production']).default('development'), |
| 6 | BRIVEN_RUNTIME_PORT: z.coerce.number().int().positive().default(3003), |
| 7 | BRIVEN_RUNTIME_BUNDLE_DIR: z.string().default('./data/bundles'), |
| 8 | BRIVEN_LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'), |
| 9 | |
| 10 | // Strategy for executing user code. `inline` runs it in this process |
| 11 | // (Phase 1 dev only — NOT isolated, not safe for untrusted code). |
| 12 | // `deno` spawns a Deno subprocess per project with a locked-down permission |
| 13 | // set (Phase 2 — customer-facing). |
| 14 | BRIVEN_RUNTIME_EXECUTOR: z.enum(['inline', 'deno']).default('inline'), |
| 15 | |
| 16 | // Shared secret between apps/api (control plane) and apps/runtime. |
| 17 | // Every invoke from the api carries this in `Authorization: Bearer <secret>`. |
| 18 | // The runtime reuses it the other direction when fetching bundles from the |
| 19 | // api's /v1/internal/* endpoints. |
| 20 | BRIVEN_RUNTIME_SHARED_SECRET: z.string().min(32).optional(), |
| 21 | |
| 22 | // Internal apps/api URL, reachable on the swarm overlay network. Used |
| 23 | // only for bundle fetches; never the public api.briven.tech hostname. |
| 24 | BRIVEN_API_INTERNAL_URL: z.string().url().default('http://localhost:3001'), |
| 25 | |
| 26 | // @README-BRIVEN ADR 0001 — DoltGres (Postgres-wire) data-plane URL. |
| 27 | // DoltGres speaks the Postgres protocol, so the runtime uses the |
| 28 | // postgres.js driver. Postgres has no `USE`: the runtime opens one |
| 29 | // client per project, each bound to that project's DoltGres database |
| 30 | // (`proj_<id>`) via the `database:` connect option, and reuses it across |
| 31 | // invocations. Mirror of apps/api/src/env.ts:BRIVEN_DATA_PLANE_URL. |
| 32 | BRIVEN_DATA_PLANE_URL: z.string().url().optional(), |
| 33 | |
| 34 | // Redis URL — used to publish function invocation log envelopes as a |
| 35 | // stream. Optional: when unset the publisher is a no-op and invocations |
| 36 | // still succeed, they're just not tailable via `briven logs`. |
| 37 | BRIVEN_REDIS_URL: z.string().url().optional(), |
| 38 | |
| 39 | // Cap on retained stream entries per project before Redis trims the head. |
| 40 | // `MAXLEN ~` uses approximate trimming so the cap isn't exact, which is |
| 41 | // what we want — fast writes, bounded memory. |
| 42 | BRIVEN_LOGS_STREAM_MAX: z.coerce.number().int().positive().default(10_000), |
| 43 | |
| 44 | // Deno isolate pool control: max concurrent isolates, per-isolate memory cap, |
| 45 | // invocation timeout, idle kill threshold, and crash-loop detection breaker. |
| 46 | // Also: tmp directory for isolate scratch and deno binary path. |
| 47 | BRIVEN_RUNTIME_MAX_ISOLATES: z.coerce.number().int().positive().default(50), |
| 48 | BRIVEN_RUNTIME_ISOLATE_MAX_MEMORY_MB: z.coerce.number().int().positive().default(128), |
| 49 | BRIVEN_RUNTIME_INVOCATION_TIMEOUT_MS: z.coerce.number().int().positive().default(30_000), |
| 50 | BRIVEN_RUNTIME_IDLE_KILL_MS: z.coerce.number().int().positive().default(10 * 60 * 1000), |
| 51 | BRIVEN_RUNTIME_MAX_INVOCATIONS_PER_ISOLATE: z.coerce.number().int().positive().default(1000), |
| 52 | BRIVEN_RUNTIME_CRASH_LOOP_THRESHOLD: z.coerce.number().int().positive().default(3), |
| 53 | BRIVEN_RUNTIME_CRASH_LOOP_WINDOW_MS: z.coerce.number().int().positive().default(60_000), |
| 54 | BRIVEN_RUNTIME_TMP_DIR: z.string().default('/tmp'), |
| 55 | BRIVEN_RUNTIME_DENO_PATH: z.string().default('deno'), |
| 56 | }); |
| 57 | |
| 58 | export type Env = z.infer<typeof envSchema>; |
| 59 | |
| 60 | export const env = loadEnv(envSchema); |