@@ -7,11 +7,6 @@ import stripJsonComments from "strip-json-comments";
77import { z } from "zod" ;
88import { getTokenFromConfig } from "./crypto.js" ;
99
10- export type NormalizedIdentityProviders = Record < string , IdentityProviderConfig > ;
11- export type NormalizedSourcebotConfig = Omit < SourcebotConfig , "identityProviders" > & {
12- identityProviders ?: NormalizedIdentityProviders ;
13- } ;
14-
1510// Booleans are specified as 'true' or 'false' strings.
1611const booleanSchema = z . enum ( [ "true" , "false" ] ) ;
1712
@@ -25,7 +20,7 @@ const ajv = new Ajv({
2520 validateFormats : false ,
2621} ) ;
2722
28- export const resolveEnvironmentVariableOverridesFromConfig = async ( config : NormalizedSourcebotConfig ) : Promise < Record < string , string > > => {
23+ export const resolveEnvironmentVariableOverridesFromConfig = async ( config : SourcebotConfig ) : Promise < Record < string , string > > => {
2924 if ( ! config . environmentOverrides ) {
3025 return { } ;
3126 }
@@ -61,39 +56,8 @@ export const isRemotePath = (path: string) => {
6156 return path . startsWith ( 'https://' ) || path . startsWith ( 'http://' ) ;
6257}
6358
64- /**
65- * Collapses the dual-form `identityProviders` field into the canonical object
66- * form keyed by id. The array form is deprecated and only supports a single
67- * instance per provider type - its synthesized id is `entry.provider`, which
68- * matches the value historically stored in `Account.provider` for those users,
69- * so existing single-instance deployments don't need a data migration.
70- */
71- const normalizeIdentityProviders = (
72- raw : SourcebotConfig [ "identityProviders" ] ,
73- ) : NormalizedIdentityProviders | undefined => {
74- if ( ! raw ) {
75- return undefined ;
76- }
77- if ( ! Array . isArray ( raw ) ) {
78- return raw ;
79- }
80-
81- const result : NormalizedIdentityProviders = { } ;
82- for ( const entry of raw ) {
83- const id = entry . provider ;
84- if ( result [ id ] ) {
85- throw new Error (
86- `Duplicate identity provider id "${ id } " in array-form \`identityProviders\`. ` +
87- `The array form is deprecated and only supports one instance per provider type. ` +
88- `Migrate to the object form (keyed by id) to configure multiple instances.` ,
89- ) ;
90- }
91- result [ id ] = entry ;
92- }
93- return result ;
94- } ;
9559
96- export const loadConfig = async ( configPath ?: string ) : Promise < NormalizedSourcebotConfig > => {
60+ export const loadConfig = async ( configPath ?: string ) : Promise < SourcebotConfig > => {
9761 if ( ! configPath ) {
9862 throw new Error ( 'CONFIG_PATH is required but not provided' ) ;
9963 }
@@ -147,10 +111,45 @@ export const loadConfig = async (configPath?: string): Promise<NormalizedSourceb
147111 throw new Error ( `Config file '${ configPath } ' is invalid: ${ ajv . errorsText ( ajv . errors ) } ` ) ;
148112 }
149113
150- return {
151- ...config ,
152- identityProviders : normalizeIdentityProviders ( config . identityProviders ) ,
153- } ;
114+ return config ;
115+ }
116+
117+
118+ export const getIdentityProviderConfigs = async ( ) : Promise < Record < string , IdentityProviderConfig > > => {
119+ const config = await loadConfig ( env . CONFIG_PATH ) ;
120+
121+ // Collapses the dual-form `identityProviders` field into the canonical object
122+ // form keyed by id.
123+ const idpConfigs = ( ( ) => {
124+ if ( ! config . identityProviders ) {
125+ return undefined ;
126+ }
127+ if ( ! Array . isArray ( config . identityProviders ) ) {
128+ return config . identityProviders ;
129+ }
130+
131+ const result : Record < string , IdentityProviderConfig > = { } ;
132+ for ( const entry of config . identityProviders ) {
133+ const id = entry . provider ;
134+ if ( result [ id ] ) {
135+ throw new Error (
136+ `Duplicate identity provider id "${ id } " in array-form \`identityProviders\`. ` +
137+ `The array form is deprecated and only supports one instance per provider type. ` +
138+ `Migrate to the object form (keyed by id) to configure multiple instances.` ,
139+ ) ;
140+ }
141+ result [ id ] = entry ;
142+ }
143+ return result ;
144+ } ) ( ) ;
145+
146+ return idpConfigs ?? { } ;
147+ }
148+
149+ export const getIdentityProviderConfig = async ( id : string ) : Promise < IdentityProviderConfig | undefined > => {
150+ const idps = await getIdentityProviderConfigs ( ) ;
151+ const idp = idps [ id ] as IdentityProviderConfig | undefined ;
152+ return idp ;
154153}
155154
156155// Merge process.env with environment variables resolved from config.json
0 commit comments