overrides.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import enabledFeaturesRaw from './enabled-features.json' with { type: 'json' }
  2. const knownFeatureKeys = Object.keys(enabledFeaturesRaw).filter((key) => key !== '$schema')
  3. const ENV_PREFIX = 'ENABLED_FEATURES_'
  4. // Server-only env var that short-circuits feature resolution; handled by
  5. // isFeatureEnabled directly, not by this parser.
  6. const RESERVED_ENV_NAMES = new Set<string>(['ENABLED_FEATURES_OVERRIDE_DISABLE_ALL'])
  7. function featureKeyToEnvName(feature: string): string {
  8. return ENV_PREFIX + feature.toUpperCase().replace(/[^A-Z0-9]/g, '_')
  9. }
  10. function parseBooleanEnv(raw: string): boolean | null {
  11. const normalized = raw.trim().toLowerCase()
  12. if (normalized === 'true') return true
  13. if (normalized === 'false') return false
  14. return null
  15. }
  16. /**
  17. * Returns the list of feature keys disabled by ENABLED_FEATURES_* env vars.
  18. * Server-only — these are not NEXT_PUBLIC_* and must be read at request time.
  19. * Invalid values and prefixed env vars that don't match a known feature are
  20. * logged and ignored.
  21. */
  22. export function getEnabledFeaturesOverrideDisabledList(
  23. env: Record<string, string | undefined>
  24. ): string[] {
  25. const expected = new Map<string, string>()
  26. for (const key of knownFeatureKeys) {
  27. expected.set(featureKeyToEnvName(key), key)
  28. }
  29. const disabled: string[] = []
  30. for (const [envName, featureKey] of expected) {
  31. const raw = env[envName]
  32. if (raw === undefined || raw === '') continue
  33. const parsed = parseBooleanEnv(raw)
  34. if (parsed === null) {
  35. console.warn(
  36. `[enabled-features] ${envName} must be "true" or "false" (got "${raw}"); ignoring.`
  37. )
  38. continue
  39. }
  40. if (parsed === false) disabled.push(featureKey)
  41. }
  42. for (const envName of Object.keys(env)) {
  43. if (!envName.startsWith(ENV_PREFIX)) continue
  44. if (expected.has(envName)) continue
  45. if (RESERVED_ENV_NAMES.has(envName)) continue
  46. console.warn(`[enabled-features] ${envName} does not match any known feature; ignoring.`)
  47. }
  48. return disabled
  49. }