Repository: tailwindlabs/tailwindcss
File: packages/@tailwindcss-upgrade/src/codemods/config/migrate-js-config.ts (TypeScript)

Code before:
      return Object.values(value).every(isSimpleValue)
    }
    return ['string', 'number', 'boolean', 'undefined'].includes(typeof value)
  }

  // `theme` and `plugins` are handled separately and allowed to be more complex
  let { plugins, theme, ...remainder } = unresolvedConfig
  if (!isSimpleValue(remainder)) {
    return false
  }

  // The file may only contain known-migratable top-level properties
  let knownProperties = [
    'darkMode',
    'content',
    'theme',
    'plugins',
    'presets',
    'prefix', // Prefix is handled in the dedicated prefix migrator
    'corePlugins',
  ]

  if (Object.keys(unresolvedConfig).some((key) => !knownProperties.includes(key))) {
    return false
  }

  if (findStaticPlugins(source) === null) {
    return false
  }

  if (unresolvedConfig.presets && unresolvedConfig.presets.length > 0) {
    return false
  }

  // Only migrate the config file if all top-level theme keys are allowed to be
  // migrated
  if (theme && typeof theme === 'object') {
    if (theme.extend && !onlyAllowedThemeValues(theme.extend)) return false
    let { extend: _extend, ...themeCopy } = theme
    if (!onlyAllowedThemeValues(themeCopy)) return false
  }

  return true
}

const ALLOWED_THEME_KEYS = [
  ...Object.keys(defaultTheme),
  // Used by @tailwindcss/container-queries
  'containers',
]
function onlyAllowedThemeValues(theme: ThemeConfig): boolean {

Review comment (suggestion):
👋 bye bye blocked theme keys

We still have `aria`, `data` and `supports` handling in: https://github.com/tailwindlabs/tailwindcss/blob/feat%2Fupgrade-supports-theme/packages/tailwindcss/src/compat/theme-variants.ts

This is still necessary in case the config file could not be migrated due to other issues. So didn't get rid of that part.

Code after:
    if (typeof value === 'object' && value !== null) {
      return Object.values(value).every(isSimpleValue)
    }
    return ['string', 'number', 'boolean', 'undefined'].includes(typeof value)
  }

  // `theme` and `plugins` are handled separately and allowed to be more complex
  let { plugins, theme, ...remainder } = unresolvedConfig
  if (!isSimpleValue(remainder)) {
    return false
  }

  // The file may only contain known-migratable top-level properties
  let knownProperties = [
    'darkMode',
    'content',
    'theme',
    'plugins',
    'presets',
    'prefix', // Prefix is handled in the dedicated prefix migrator
    'corePlugins',
  ]

  if (Object.keys(unresolvedConfig).some((key) => !knownProperties.includes(key))) {
    return false
  }

  if (findStaticPlugins(source) === null) {
    return false
  }

  if (unresolvedConfig.presets && unresolvedConfig.presets.length > 0) {
    return false
  }

  // Only migrate the config file if all top-level theme keys are allowed to be
  // migrated
  if (theme && typeof theme === 'object') {
    if (theme.extend && !onlyAllowedThemeValues(theme.extend)) return false
    let { extend: _extend, ...themeCopy } = theme
    if (!onlyAllowedThemeValues(themeCopy)) return false
  }

  return true
}

const ALLOWED_THEME_KEYS = [
  ...Object.keys(defaultTheme),
  // Used by @tailwindcss/container-queries
  'containers',
]