export function validateConfigs()

in src/config-loader.ts [61:139]


export function validateConfigs(mergedFlags: FeatureFlag[]) {
  const duplicationFeatureFlags = mergedFlags.reduce<{ [key: string]: number }>(
    (acc, ff) => {
      if (!ff.id) {
        throw new ValidationError('Feature flag id is missing')
      }
      const { id } = ff
      acc[id] = (acc[id] || 0) + 1
      return acc
    },
    {}
  )

  const duplicates = mergedFlags.filter(
    ff => duplicationFeatureFlags[ff.id] > 1
  )

  if (duplicates.length > 0) {
    const duplicateIds = duplicates.map(ff => ff.id).join(', ')
    const message = `Feature flag is defined multiple times which is not allowed: ${duplicateIds}`
    core.error(message)
    throw new ArgumentError(message)
  }

  core.info(`Found ${mergedFlags.length} feature flags in configuration files`)

  // default_when_enabled is required
  const defaultWhenEnabledErrors = mergedFlags.map(f => {
    if (!f.allocation?.default_when_enabled) {
      const message = `Feature flag ${f.id} is missing default_when_enabled`
      core.error(message)
      return {
        message,
        isValid: false
      }
    }
    return { isValid: true }
  })

  if (defaultWhenEnabledErrors.some(e => !e.isValid)) {
    throw new ValidationError(
      'Default_when_enabled is required: ' +
        defaultWhenEnabledErrors.map(e => e.message).join(', ')
    )
  }

  const allocationErrors = mergedFlags.map(f => {
    // allocation should only refer to existing variants
    const variantNames = f.variants?.map(v => v.name) || []
    const allocationVariants =
      f.allocation?.percentile?.map(p => p.variant) || []
    if (!!f.allocation?.default_when_enabled) {
      allocationVariants.push(f.allocation.default_when_enabled)
    }
    if (!!f.allocation?.default_when_disabled) {
      allocationVariants.push(f.allocation.default_when_disabled)
    }

    const invalidVariants = allocationVariants.filter(
      v => !variantNames.includes(v)
    )

    if (invalidVariants.length > 0) {
      const message = `Feature flag ${f.id} has allocation to non-existing variants: ${invalidVariants}`
      core.error(message)
      return {
        message,
        isValid: false
      }
    }
    return { isValid: true }
  })

  if (allocationErrors.some(e => !e.isValid)) {
    throw new ValidationError(
      'Allocation error: ' + allocationErrors.map(e => e.message).join(', ')
    )
  }
}