Skip to content

Commit 437c3b2

Browse files
set config via feature flags (#6590)
In cloud environment, allow all the config values to be set by the feature flag endpoint and be updated dynamically (on 30s poll). Retain origianl behavior for OSS. On cloud, config changes shouldn't be changed via redeploy and the promoted image should match the staging image. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6590-set-config-via-feature-flags-2a26d73d3650819f8084eb2695c51f22) by [Unito](https://www.unito.io) --------- Co-authored-by: DrJKL <[email protected]>
1 parent 549ef79 commit 437c3b2

File tree

15 files changed

+200
-43
lines changed

15 files changed

+200
-43
lines changed

global.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,21 @@ declare const __USE_PROD_CONFIG__: boolean
88
interface Window {
99
__CONFIG__: {
1010
mixpanel_token?: string
11+
require_whitelist?: boolean
1112
subscription_required?: boolean
13+
max_upload_size?: number
14+
comfy_api_base_url?: string
15+
comfy_platform_base_url?: string
16+
firebase_config?: {
17+
apiKey: string
18+
authDomain: string
19+
databaseURL?: string
20+
projectId: string
21+
storageBucket: string
22+
messagingSenderId: string
23+
appId: string
24+
measurementId?: string
25+
}
1226
server_health_alert?: {
1327
message: string
1428
tooltip?: string

src/components/dialog/content/SignInContent.vue

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
<small class="text-center text-muted">
9797
{{ t('auth.apiKey.helpText') }}
9898
<a
99-
:href="`${COMFY_PLATFORM_BASE_URL}/login`"
99+
:href="`${comfyPlatformBaseUrl}/login`"
100100
target="_blank"
101101
class="cursor-pointer text-blue-500"
102102
>
@@ -145,11 +145,15 @@
145145
import Button from 'primevue/button'
146146
import Divider from 'primevue/divider'
147147
import Message from 'primevue/message'
148-
import { onMounted, onUnmounted, ref } from 'vue'
148+
import { computed, onMounted, onUnmounted, ref } from 'vue'
149149
import { useI18n } from 'vue-i18n'
150150
151151
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
152-
import { COMFY_PLATFORM_BASE_URL } from '@/config/comfyApi'
152+
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
153+
import {
154+
configValueOrDefault,
155+
remoteConfig
156+
} from '@/platform/remoteConfig/remoteConfig'
153157
import type { SignInData, SignUpData } from '@/schemas/signInSchema'
154158
import { isHostWhitelisted, normalizeHost } from '@/utils/hostWhitelist'
155159
import { isInChina } from '@/utils/networkUtil'
@@ -168,6 +172,13 @@ const isSecureContext = window.isSecureContext
168172
const isSignIn = ref(true)
169173
const showApiKeyForm = ref(false)
170174
const ssoAllowed = isHostWhitelisted(normalizeHost(window.location.hostname))
175+
const comfyPlatformBaseUrl = computed(() =>
176+
configValueOrDefault(
177+
remoteConfig.value,
178+
'comfy_platform_base_url',
179+
getComfyPlatformBaseUrl()
180+
)
181+
)
171182
172183
const toggleState = () => {
173184
isSignIn.value = !isSignIn.value

src/components/dialog/content/signin/ApiKeyForm.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
99
import { createApp } from 'vue'
1010
import { createI18n } from 'vue-i18n'
1111

12-
import { COMFY_PLATFORM_BASE_URL } from '@/config/comfyApi'
12+
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
1313

1414
import ApiKeyForm from './ApiKeyForm.vue'
1515

@@ -111,7 +111,7 @@ describe('ApiKeyForm', () => {
111111
const helpText = wrapper.find('small')
112112
expect(helpText.text()).toContain('Need an API key?')
113113
expect(helpText.find('a').attributes('href')).toBe(
114-
`${COMFY_PLATFORM_BASE_URL}/login`
114+
`${getComfyPlatformBaseUrl()}/login`
115115
)
116116
})
117117
})

src/components/dialog/content/signin/ApiKeyForm.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<small class="text-muted">
4949
{{ t('auth.apiKey.helpText') }}
5050
<a
51-
:href="`${COMFY_PLATFORM_BASE_URL}/login`"
51+
:href="`${comfyPlatformBaseUrl}/login`"
5252
target="_blank"
5353
class="cursor-pointer text-blue-500"
5454
>
@@ -88,14 +88,25 @@ import Message from 'primevue/message'
8888
import { computed } from 'vue'
8989
import { useI18n } from 'vue-i18n'
9090
91-
import { COMFY_PLATFORM_BASE_URL } from '@/config/comfyApi'
91+
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
92+
import {
93+
configValueOrDefault,
94+
remoteConfig
95+
} from '@/platform/remoteConfig/remoteConfig'
9296
import { apiKeySchema } from '@/schemas/signInSchema'
9397
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
9498
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
9599
96100
const authStore = useFirebaseAuthStore()
97101
const apiKeyStore = useApiKeyAuthStore()
98102
const loading = computed(() => authStore.loading)
103+
const comfyPlatformBaseUrl = computed(() =>
104+
configValueOrDefault(
105+
remoteConfig.value,
106+
'comfy_platform_base_url',
107+
getComfyPlatformBaseUrl()
108+
)
109+
)
99110
100111
const { t } = useI18n()
101112

src/config/comfyApi.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,43 @@
1-
export const COMFY_API_BASE_URL = __USE_PROD_CONFIG__
2-
? 'https://api.comfy.org'
3-
: 'https://stagingapi.comfy.org'
1+
import { isCloud } from '@/platform/distribution/types'
2+
import {
3+
configValueOrDefault,
4+
remoteConfig
5+
} from '@/platform/remoteConfig/remoteConfig'
46

5-
export const COMFY_PLATFORM_BASE_URL = __USE_PROD_CONFIG__
6-
? 'https://platform.comfy.org'
7-
: 'https://stagingplatform.comfy.org'
7+
const PROD_API_BASE_URL = 'https://api.comfy.org'
8+
const STAGING_API_BASE_URL = 'https://stagingapi.comfy.org'
9+
10+
const PROD_PLATFORM_BASE_URL = 'https://platform.comfy.org'
11+
const STAGING_PLATFORM_BASE_URL = 'https://stagingplatform.comfy.org'
12+
13+
const BUILD_TIME_API_BASE_URL = __USE_PROD_CONFIG__
14+
? PROD_API_BASE_URL
15+
: STAGING_API_BASE_URL
16+
17+
const BUILD_TIME_PLATFORM_BASE_URL = __USE_PROD_CONFIG__
18+
? PROD_PLATFORM_BASE_URL
19+
: STAGING_PLATFORM_BASE_URL
20+
21+
export function getComfyApiBaseUrl(): string {
22+
if (!isCloud) {
23+
return BUILD_TIME_API_BASE_URL
24+
}
25+
26+
return configValueOrDefault(
27+
remoteConfig.value,
28+
'comfy_api_base_url',
29+
BUILD_TIME_API_BASE_URL
30+
)
31+
}
32+
33+
export function getComfyPlatformBaseUrl(): string {
34+
if (!isCloud) {
35+
return BUILD_TIME_PLATFORM_BASE_URL
36+
}
37+
38+
return configValueOrDefault(
39+
remoteConfig.value,
40+
'comfy_platform_base_url',
41+
BUILD_TIME_PLATFORM_BASE_URL
42+
)
43+
}

src/config/firebase.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import type { FirebaseOptions } from 'firebase/app'
22

3+
import { isCloud } from '@/platform/distribution/types'
4+
import { remoteConfig } from '@/platform/remoteConfig/remoteConfig'
5+
36
const DEV_CONFIG: FirebaseOptions = {
47
apiKey: 'AIzaSyDa_YMeyzV0SkVe92vBZ1tVikWBmOU5KVE',
58
authDomain: 'dreamboothy-dev.firebaseapp.com',
@@ -22,7 +25,18 @@ const PROD_CONFIG: FirebaseOptions = {
2225
measurementId: 'G-3ZBD3MBTG4'
2326
}
2427

25-
// To test with prod config while using dev server, set USE_PROD_CONFIG=true in .env
26-
export const FIREBASE_CONFIG: FirebaseOptions = __USE_PROD_CONFIG__
27-
? PROD_CONFIG
28-
: DEV_CONFIG
28+
const BUILD_TIME_CONFIG = __USE_PROD_CONFIG__ ? PROD_CONFIG : DEV_CONFIG
29+
30+
/**
31+
* Returns the Firebase configuration for the current environment.
32+
* - Cloud builds use runtime configuration delivered via feature flags
33+
* - OSS / localhost builds fall back to the build-time config determined by __USE_PROD_CONFIG__
34+
*/
35+
export function getFirebaseConfig(): FirebaseOptions {
36+
if (!isCloud) {
37+
return BUILD_TIME_CONFIG
38+
}
39+
40+
const runtimeConfig = remoteConfig.value.firebase_config
41+
return runtimeConfig ?? BUILD_TIME_CONFIG
42+
}

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Tooltip from 'primevue/tooltip'
1111
import { createApp } from 'vue'
1212
import { VueFire, VueFireAuth } from 'vuefire'
1313

14-
import { FIREBASE_CONFIG } from '@/config/firebase'
14+
import { getFirebaseConfig } from '@/config/firebase'
1515
import '@/lib/litegraph/public/css/litegraph.css'
1616
import router from '@/router'
1717

@@ -40,7 +40,7 @@ const ComfyUIPreset = definePreset(Aura, {
4040
}
4141
})
4242

43-
const firebaseApp = initializeApp(FIREBASE_CONFIG)
43+
const firebaseApp = initializeApp(getFirebaseConfig())
4444

4545
const app = createApp(App)
4646
const pinia = createPinia()

src/platform/cloud/subscription/composables/useSubscription.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createSharedComposable } from '@vueuse/core'
44
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
55
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
66
import { useErrorHandling } from '@/composables/useErrorHandling'
7-
import { COMFY_API_BASE_URL } from '@/config/comfyApi'
7+
import { getComfyApiBaseUrl, getComfyPlatformBaseUrl } from '@/config/comfyApi'
88
import { MONTHLY_SUBSCRIPTION_PRICE } from '@/config/subscriptionPricesConfig'
99
import { t } from '@/i18n'
1010
import { isCloud } from '@/platform/distribution/types'
@@ -74,6 +74,8 @@ function useSubscriptionInternal() {
7474
() => `$${MONTHLY_SUBSCRIPTION_PRICE.toFixed(0)}`
7575
)
7676

77+
const buildApiUrl = (path: string) => `${getComfyApiBaseUrl()}${path}`
78+
7779
const fetchStatus = wrapWithErrorHandlingAsync(
7880
fetchSubscriptionStatus,
7981
reportError
@@ -114,7 +116,7 @@ function useSubscriptionInternal() {
114116
}
115117

116118
const handleViewUsageHistory = () => {
117-
window.open('https://platform.comfy.org/profile/usage', '_blank')
119+
window.open(`${getComfyPlatformBaseUrl()}/profile/usage`, '_blank')
118120
}
119121

120122
const handleLearnMore = () => {
@@ -136,7 +138,7 @@ function useSubscriptionInternal() {
136138
}
137139

138140
const response = await fetch(
139-
`${COMFY_API_BASE_URL}/customers/cloud-subscription-status`,
141+
buildApiUrl('/customers/cloud-subscription-status'),
140142
{
141143
headers: {
142144
...authHeader,
@@ -181,7 +183,7 @@ function useSubscriptionInternal() {
181183
}
182184

183185
const response = await fetch(
184-
`${COMFY_API_BASE_URL}/customers/cloud-subscription-checkout`,
186+
buildApiUrl('/customers/cloud-subscription-checkout'),
185187
{
186188
method: 'POST',
187189
headers: {

src/platform/remoteConfig/remoteConfig.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ import type { RemoteConfig } from './types'
2121
*/
2222
export const remoteConfig = ref<RemoteConfig>({})
2323

24+
export function configValueOrDefault<K extends keyof RemoteConfig>(
25+
remoteConfig: RemoteConfig,
26+
key: K,
27+
defaultValue: NonNullable<RemoteConfig[K]>
28+
): NonNullable<RemoteConfig[K]> {
29+
const configValue = remoteConfig[key]
30+
return configValue || defaultValue
31+
}
32+
2433
/**
2534
* Loads remote configuration from the backend /api/features endpoint
2635
* and updates the reactive remoteConfig ref

src/platform/remoteConfig/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ type ServerHealthAlert = {
88
badge?: string
99
}
1010

11+
type FirebaseRuntimeConfig = {
12+
apiKey: string
13+
authDomain: string
14+
databaseURL?: string
15+
projectId: string
16+
storageBucket: string
17+
messagingSenderId: string
18+
appId: string
19+
measurementId?: string
20+
}
21+
1122
/**
1223
* Remote configuration type
1324
* Configuration fetched from the server at runtime
@@ -16,4 +27,8 @@ export type RemoteConfig = {
1627
mixpanel_token?: string
1728
subscription_required?: boolean
1829
server_health_alert?: ServerHealthAlert
30+
max_upload_size?: number
31+
comfy_api_base_url?: string
32+
comfy_platform_base_url?: string
33+
firebase_config?: FirebaseRuntimeConfig
1934
}

0 commit comments

Comments
 (0)