env.ts60 lines · main
1import { loadEnv } from '@briven/shared';
2import { z } from 'zod';
3
4const 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
58export type Env = z.infer<typeof envSchema>;
59
60export const env = loadEnv(envSchema);