validate static method

ValidationResult validate(
  1. List<ParsedLocaleFile> localeFiles, {
  2. String? baseLocale,
})

Validates locale files and returns a ValidationResult.

baseLocale is the schema of truth. Extra keys in non-base locales are errors. Missing keys in non-base locales are warnings.

Implementation

static ValidationResult validate(
  List<ParsedLocaleFile> localeFiles, {
  String? baseLocale,
}) {
  if (localeFiles.isEmpty) {
    return const ValidationResult(
      isValid: false,
      errors: ['No locale files provided'],
      warnings: [],
    );
  }

  final base = baseLocale ?? localeFiles.first.languageCode;
  final baseFile = localeFiles.firstWhere(
    (f) => f.languageCode == base,
    orElse: () => throw SwayValidationException(
      'Base locale "$base" not found among provided locale files',
      errors: ['Base locale file missing'],
    ),
  );

  final errors = <String>[];
  final warnings = <String>[];
  final baseKeys = _flattenKeys(baseFile.data);

  // Validate base locale file key names
  _validateKeyNames(baseFile, errors);

  // Validate base locale has no duplicate keys
  _validateNoDuplicateKeys(baseFile, errors);

  // Validate each non-base locale
  for (final file in localeFiles) {
    if (file.languageCode == base) continue;

    _validateKeyNames(file, errors);
    _validateNoDuplicateKeys(file, errors);

    final localeKeys = _flattenKeys(file.data);

    // Check for extra keys (error — base is schema of truth)
    for (final key in localeKeys) {
      if (!baseKeys.contains(key)) {
        errors.add(
          '${file.languageCode}: has extra key "$key" not in base locale',
        );
      }
    }

    // Check for missing keys (warning)
    final missingKeys = <String>[];
    for (final key in baseKeys) {
      if (!localeKeys.contains(key)) {
        missingKeys.add(key);
      }
    }
    if (missingKeys.isNotEmpty) {
      warnings.add(
        '${file.languageCode}: missing keys: ${missingKeys.join(', ')}',
      );
    }
  }

  // Validate placeholders across locales
  _validatePlaceholders(localeFiles, baseFile, errors);

  // Validate plural categories across locales
  _validatePluralCategories(localeFiles, errors, warnings);

  return ValidationResult(
    isValid: errors.isEmpty,
    errors: errors,
    warnings: warnings,
  );
}