chki18n 1.1.0 copy "chki18n: ^1.1.0" to clipboard
chki18n: ^1.1.0 copied to clipboard

Checks that your i18n translation files agree with each other — missing keys, untranslated values, broken placeholders. No dependencies, pure Dart.

chki18n

chki18n for Dart #

license pub package pub points

📘 chki18n.cdget.com #

Every check, every option and every example. This README is just the quick start.


chki18n checks that your i18n translation files agree with each other. Point it at a folder of JSON, name the language everything is compared against, and it reports what is missing, what was never translated and what quietly broke.

  • Twenty-five checks — missing keys, a language file nobody created, keys defined twice, empty values, untranslated strings, mismatched interpolation placeholders, dropped markup, changed numbers, invisible characters, drifting terminology, missing plural forms, and — pointed at your sources — keys nothing references and keys nothing defines.
  • Every layout — one file per locale, one folder per locale, or one file holding them all.
  • CLI and library share one set of checks and one set of options.
  • A report you can act on — grouped by language, check, file or nothing; rendered for a terminal, for grep, as JSON, as Markdown or as GitHub Actions annotations; saved to a file on request.
  • No dependencies, and package:chki18n/core.dart imports no dart:io, so the comparison runs in a Flutter web build too.

Install #

dart pub add chki18n

Requires Dart 3.7 or newer. In a Flutter project use flutter pub add chki18n.

From the command line #

dart pub global activate chki18n
chki18n ./locales --target en
  Path     ./locales
  Target   en
  Locales  en, ko
  Layout   single, 1 group, 10 keys

 ko ──────────────────────────────────────────────────────────────────────── 1 error · 1 warning

  ERROR  NO_KEY (1)
         The key exists in the target language but is missing here.
    attr.folder  en: "Folder"

  WARN   NOT_TRANSLATED_VALUE (1)
         The value is identical to the target language, so the translation may be incomplete.
    desc.no-str  en: "12345"

 Summary ───────────────────────────────────────────────────────────────────────────────────────

  Compared 10 keys across 2 locales in 1 group. (3ms)
  1 error · 1 warning
  Clean: en

  FAIL  1 error must be fixed before this passes.

Exits with 1 when an error level issue was found, so a CI job fails on it. chki18n --help lists every flag. Inside a project that already depends on the package, dart run chki18n does the same thing without installing it globally.

--group-by decides what a section is (locale, code, group, file or none), --reporter decides the shape (pretty, list, json, markdown or github), and --output keeps a copy:

chki18n ./locales --target en --reporter json > report.json
chki18n ./locales --target en --output translation-report.md

From Dart #

Four entry points, depending on who owns the translations:

import 'package:chki18n/chki18n.dart';

// Check a directory once — the same thing the CLI does.
final result = await checkTranslationFiles(
  path: './locales',
  options: const Chki18nOptions(target: 'en'),
);

result.success; // false
result.issues; // every issue, with its level, key, locale and file

// Check data you already have, with no file system work at all.
analyzeTranslations(
  Chki18nInput(locales: {'en': en, 'ko': ko}),
  options: const Chki18nOptions(target: 'en'),
);

// Read a directory once, then check it as often as you like.
final session = await loadTranslations(
  path: './locales',
  options: const Chki18nOptions(target: 'en'),
);
session.set('ko', 'desc.hello', '안녕하세요'); // the issues for that key

// Or let your own application own the values and ask only for a verdict.
createAnalyzer(options: const Chki18nOptions(target: 'en')).checkEntry(
  const Chki18nEntry(
    key: 'desc.hello',
    values: {'en': 'Hello {name}', 'ko': '안녕하세요'},
  ),
);
// [NO_INTERPOLATION_KEY error ko desc.hello: ...]

The last two do no file system work and are also published as package:chki18n/core.dart, which imports no dart:io and runs in a Flutter web build or anywhere else the file system is not there.

Every option is one object with named parameters, so a flag and its Dart counterpart are the same thing:

const Chki18nOptions(
  target: 'en',
  ignoreChecks: [Chki18nCheckCode.suspiciousLength],
  levels: {Chki18nCheckCode.emptyValue: Chki18nLevel.error},
  keyCase: Chki18nKeyCase.kebab,
  reporter: Chki18nReporter.markdown,
);

The documentation site covers every check, every option and how to render a result.

Contributing #

Anyone can contribute by reporting an issue or opening a pull request. See CONTRIBUTING.md.

License #

Released under the MIT License.

0
likes
160
points
145
downloads

Documentation

API reference

Publisher

verified publishercdget.com

Weekly Downloads

Checks that your i18n translation files agree with each other — missing keys, untranslated values, broken placeholders. No dependencies, pure Dart.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#i18n #translation #validation #cli

License

MIT (license)

More

Packages that depend on chki18n