1- import { createEnv } from "@t3-oss/env-nextjs " ;
1+ import { createEnv } from "@t3-oss/env-core " ;
22import { z } from "zod" ;
3- import { SOURCEBOT_CLOUD_ENVIRONMENT } from "@sourcebot/shared/client" ;
3+ import { SourcebotConfig } from "@sourcebot/schemas/v3/index.type" ;
4+ import { getTokenFromConfig } from "./crypto.js" ;
5+ import { loadConfig } from "./utils.js" ;
6+ import { tenancyModeSchema } from "./types.js" ;
47
58// Booleans are specified as 'true' or 'false' strings.
69const booleanSchema = z . enum ( [ "true" , "false" ] ) ;
7- export const tenancyModeSchema = z . enum ( [ "multi" , "single" ] ) ;
810
911// Numbers are treated as strings in .env files.
1012// coerce helps us convert them to numbers.
1113// @see : https://zod.dev/?id=coercion-for-primitives
1214const numberSchema = z . coerce . number ( ) ;
1315
16+
17+ const resolveEnvironmentVariableOverridesFromConfig = async ( config : SourcebotConfig ) : Promise < Record < string , string > > => {
18+ if ( ! config . environmentOverrides ) {
19+ return { } ;
20+ }
21+
22+ const resolved : Record < string , string > = { } ;
23+ console . debug ( 'resolving environment variable overrides' ) ;
24+
25+ for ( const [ key , override ] of Object . entries ( config . environmentOverrides ) ) {
26+ switch ( override . type ) {
27+ case 'token' :
28+ resolved [ key ] = await getTokenFromConfig ( override . value ) ;
29+ break ;
30+ case 'boolean' :
31+ resolved [ key ] = override . value ? 'true' : 'false' ;
32+ break ;
33+ case 'number' :
34+ resolved [ key ] = override . value . toString ( ) ;
35+ break ;
36+ case 'string' :
37+ resolved [ key ] = override . value ;
38+ break ;
39+ }
40+ }
41+
42+ return resolved ;
43+ }
44+
45+ // Merge process.env with environment variables resolved from config.json
46+ const runtimeEnv = await ( async ( ) => {
47+ const configPath = process . env . CONFIG_PATH ;
48+ if ( ! configPath ) {
49+ return process . env ;
50+ }
51+
52+ const config = await loadConfig ( configPath ) ;
53+ const overrides = await resolveEnvironmentVariableOverridesFromConfig ( config ) ;
54+ return {
55+ ...process . env ,
56+ ...overrides ,
57+ }
58+ } ) ( ) ;
59+
1460export const env = createEnv ( {
1561 server : {
1662 // Zoekt
1763 ZOEKT_WEBSERVER_URL : z . string ( ) . url ( ) . default ( "http://localhost:6070" ) ,
1864
1965 // Auth
2066 FORCE_ENABLE_ANONYMOUS_ACCESS : booleanSchema . default ( 'false' ) ,
21-
2267 AUTH_SECRET : z . string ( ) ,
2368 AUTH_URL : z . string ( ) . url ( ) ,
2469 AUTH_CREDENTIALS_LOGIN_ENABLED : booleanSchema . default ( 'true' ) ,
@@ -75,7 +120,7 @@ export const env = createEnv({
75120 DATABASE_URL : z . string ( ) . url ( ) ,
76121
77122 SOURCEBOT_TENANCY_MODE : tenancyModeSchema . default ( "single" ) ,
78- CONFIG_PATH : z . string ( ) . optional ( ) ,
123+ CONFIG_PATH : z . string ( ) ,
79124
80125 // Misc UI flags
81126 SECURITY_CARD_ENABLED : booleanSchema . default ( 'false' ) ,
@@ -137,31 +182,30 @@ export const env = createEnv({
137182 // @NOTE : Take care to update actions.ts when changing the name of this.
138183 EXPERIMENT_SELF_SERVE_REPO_INDEXING_GITHUB_TOKEN : z . string ( ) . optional ( ) ,
139184 EXPERIMENT_EE_PERMISSION_SYNC_ENABLED : booleanSchema . default ( 'false' ) ,
140- } ,
141- // @NOTE : Please make sure of the following:
142- // - Make sure you destructure all client variables in
143- // the `experimental__runtimeEnv` block below.
144- // - Update the Dockerfile to pass these variables as build-args.
145- client : {
146- // PostHog
147- NEXT_PUBLIC_POSTHOG_PAPIK : z . string ( ) . optional ( ) ,
148185
149- // Misc
150- NEXT_PUBLIC_SOURCEBOT_VERSION : z . string ( ) . default ( ' unknown' ) ,
186+ SOURCEBOT_ENCRYPTION_KEY : z . string ( ) ,
187+ SOURCEBOT_INSTALL_ID : z . string ( ) . default ( " unknown" ) ,
151188
152- NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT : z . enum ( SOURCEBOT_CLOUD_ENVIRONMENT ) . optional ( ) ,
189+ FALLBACK_GITHUB_CLOUD_TOKEN : z . string ( ) . optional ( ) ,
190+ FALLBACK_GITLAB_CLOUD_TOKEN : z . string ( ) . optional ( ) ,
191+ FALLBACK_GITEA_CLOUD_TOKEN : z . string ( ) . optional ( ) ,
153192
154- NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY : z . string ( ) . optional ( ) ,
155- NEXT_PUBLIC_LANGFUSE_BASE_URL : z . string ( ) . optional ( )
156- } ,
157- // For Next.js >= 13.4.4, you only need to destructure client variables:
158- experimental__runtimeEnv : {
159- NEXT_PUBLIC_POSTHOG_PAPIK : process . env . NEXT_PUBLIC_POSTHOG_PAPIK ,
160- NEXT_PUBLIC_SOURCEBOT_VERSION : process . env . NEXT_PUBLIC_SOURCEBOT_VERSION ,
161- NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT : process . env . NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT ,
162- NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY : process . env . NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY ,
163- NEXT_PUBLIC_LANGFUSE_BASE_URL : process . env . NEXT_PUBLIC_LANGFUSE_BASE_URL ,
193+ REDIS_URL : z . string ( ) . url ( ) . default ( "redis://localhost:6379" ) ,
194+ REDIS_REMOVE_ON_COMPLETE : numberSchema . default ( 0 ) ,
195+ REDIS_REMOVE_ON_FAIL : numberSchema . default ( 100 ) ,
196+
197+ DEBUG_ENABLE_GROUPMQ_LOGGING : booleanSchema . default ( 'false' ) ,
198+
199+ CONNECTION_MANAGER_UPSERT_TIMEOUT_MS : numberSchema . default ( 300000 ) ,
200+ REPO_SYNC_RETRY_BASE_SLEEP_SECONDS : numberSchema . default ( 60 ) ,
201+
202+ GITLAB_CLIENT_QUERY_TIMEOUT_SECONDS : numberSchema . default ( 60 * 10 ) ,
203+
204+ SOURCEBOT_LOG_LEVEL : z . enum ( [ "info" , "debug" , "warn" , "error" ] ) . default ( "info" ) ,
205+ SOURCEBOT_STRUCTURED_LOGGING_ENABLED : booleanSchema . default ( "false" ) ,
206+ SOURCEBOT_STRUCTURED_LOGGING_FILE : z . string ( ) . optional ( ) ,
164207 } ,
165- skipValidation : process . env . SKIP_ENV_VALIDATION === "1" ,
208+ runtimeEnv ,
166209 emptyStringAsUndefined : true ,
210+ skipValidation : process . env . SKIP_ENV_VALIDATION === "1" ,
167211} ) ;
0 commit comments