@apappas1129/ngx-fluent-extract
v0.1.0
Published
Extraction report CLI for ngx-fluent: diffs translation keys used in an Angular app's code against each locale's .ftl file.
Maintainers
Readme
@apappas1129/ngx-fluent-extract
A report-only extraction CLI for ngx-fluent. It diffs the translation keys used in your Angular app's code against each locale's .ftl file, and tells you what's missing (used in code, not defined) and orphaned (defined, never used).
It never writes to .ftl files. Fluent messages can carry variants, attributes, and term references that a generated stub can't meaningfully guess — so this tool only reports, it doesn't scaffold.
When you'd need this
Nothing in ngx-fluent stops your app from compiling or running if a translation key is missing — the fluent pipe just falls back to showing the raw key string ('welcome-user' instead of "Welcome!"). That's silent in dev and in code review; the first anyone notices is usually a user seeing a raw key in production, or a translator asking why a locale looks half-finished. Reach for this CLI when:
- You're about to add a new locale. Point the config at the new
.ftlfile and see exactly which keys it's missing before you ship it, instead of finding out from a user. - You just refactored or deleted a component. The
.ftlentries it used don't get cleaned up automatically —orphanedtells you what's now dead weight in your translation files. - You want a CI check on PRs that touch templates or translations. A key typo'd in a template, or added in code but never given a translation, exits non-zero — catch it before merge instead of after a user reports it.
- A
.ftlfile came back from a translator or survived a merge conflict. Malformed Fluent syntax fails silently at runtime (the bundle just drops the broken entry); this CLI'sparseErrorsurfaces it as a build-breaking problem, not a runtime mystery.
If none of that applies — small app, one locale, translations always land alongside the code that uses them — you probably don't need this yet.
Install
npm install --save-dev @apappas1129/ngx-fluent-extractRequires TypeScript as a peer dependency (already present in any Angular project).
Usage
npx ngx-fluent-extract [scanRoot] [options]scanRoot— directory to scan from. Defaults to the current directory (likecode ./code <path>).--config <path>— path to the extraction config. Defaults to<scanRoot>/ngx-fluent-extract.config.json.--project <path>— path to atsconfig.json. Defaults to auto-discovery fromscanRoot(followingreferencesone level).--json— print the report as JSON instead of human-readable text.--help— show usage.
Exit code is non-zero only when a locale has missing keys or a parse error. Orphaned keys alone don't fail the run — they're hygiene, not a defect users will see.
Config
ngx-fluent-extract.config.json, at the scan root:
{
"locales": {
"en": "public/i18n/en.ftl",
"sv": "public/i18n/sv.ftl"
}
}Paths are resolved relative to the config file's own directory. There's no source-glob field — source files are discovered from the resolved tsconfig.json's file list plus each @Component's templateUrl/inline template, not by pattern matching.
What it detects
'key' | fluentpipe usage in templates (inline or external, viatemplateUrl)NgxFluentService.translate('key', ...)calls in TypeScript, matched type-aware (via the TypeScript Compiler API) rather than by name alone, so an unrelated.translate()method on another class isn't mistaken for this library's
A key that isn't a string literal (a variable, a function call) can't be resolved statically. Those surface as dynamic key warnings — file and line — rather than being silently dropped, so they don't corrupt the missing/orphaned counts.
Out of scope for v1
- Message attributes (
login-button.title) —NgxFluentService.translate()doesn't expose attribute lookup at all yet, so there's nothing in code for an attribute-aware report to check against. - Fluent terms (
-brand-name) — terms are only referenced from within other messages, never from code. Checking whether a term is used anywhere in a.ftlfile is a different job (dead-code-within-.ftl) from this tool's code-vs-translation-file diff.
Why a standalone CLI, not an ng builder
An Angular builder (ng run ... :extract-i18n-style) would need @angular-devkit/architect and an angular.json target for what's fundamentally a diagnostic side-channel, not a build step. A plain CLI runs anywhere — this repo's own example apps, any CI pipeline — without that coupling. It ships as its own package rather than bundled into @apappas1129/ngx-fluent because that library is built with ng-packagr for Angular consumption, which can't produce a runnable bin script.
A thin Angular builder that wraps this same CLI is a good scope for a community PR if there's demand — issues and PRs welcome.
