{"_id":"@altwaireb/tring","_rev":"2-4c599830360f65fa0c100c326b03f3af","name":"@altwaireb/tring","dist-tags":{"latest":"1.2.0"},"versions":{"1.1.0":{"name":"@altwaireb/tring","version":"1.1.0","keywords":["i18n","l10n","localization","translation","json","cli","typescript"],"author":{"name":"Abdulmajeed Altwaireb"},"license":"MIT","_id":"@altwaireb/tring@1.1.0","maintainers":[{"name":"altwaireb","email":"altwaireb@gmail.com"}],"homepage":"https://github.com/altwaireb/tring","bugs":{"url":"https://github.com/altwaireb/tring/issues"},"bin":{"tring":"dist/cli-entry.mjs"},"dist":{"shasum":"7b5dd15f47102d0066a6c7e89cd2309de1b74856","tarball":"https://registry.npmjs.org/@altwaireb/tring/-/tring-1.1.0.tgz","fileCount":12,"integrity":"sha512-/SGuvLeNMug3BZ/gyjk0hFUEqOMtO059n+t2c5HgTMVoroP+2AVuhr9aoP3Oyhh8n7qovJcEBeWwdBzE5N7oMQ==","signatures":[{"sig":"MEYCIQDzubTn5kOpitnRqIrWNVmN9L3URoCIV/ml6XotcU6SVAIhAP7aT5rUTidyINi7O7DrpW1ePI7/dzYdPmzjCcB3Nm1h","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":268675},"type":"module","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"gitHead":"acb68f6f2f85acb464ffed6690307b2f5ab14451","scripts":{"dev":"tsx src/index.ts","lint":"biome check .","test":"vitest run","build":"tsdown","check":"tsc --noEmit","format":"biome format --write ."},"_npmUser":{"name":"altwaireb","email":"altwaireb@gmail.com"},"repository":{"url":"git+https://github.com/altwaireb/tring.git","type":"git"},"_npmVersion":"11.16.0","description":"A developer-first toolkit for managing JSON translations.","directories":{},"_nodeVersion":"24.18.0","allowScripts":{"esbuild@0.28.2":true},"dependencies":{"c12":"4.0.0-beta.5","ora":"^9.4.1","chalk":"^6.0.0","citty":"^0.2.2","ts-morph":"^28.0.0","@inquirer/prompts":"^8.5.2"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.17.1","devDependencies":{"tsx":"^4.23.8","tsdown":"^0.22.14","vitest":"^4.1.10","typescript":"^6.0.3","@types/node":"^26.1.2","@biomejs/biome":"^2.5.7"},"_npmOperationalInternal":{"tmp":"tmp/tring_1.1.0_1788390593074_0.05778747485801583","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@altwaireb/tring","version":"1.2.0","description":"A developer-first toolkit for managing JSON translations.","keywords":["i18n","l10n","localization","translation","json","cli","typescript"],"homepage":"https://github.com/altwaireb/tring","repository":{"type":"git","url":"git+https://github.com/altwaireb/tring.git"},"bugs":{"url":"https://github.com/altwaireb/tring/issues"},"license":"MIT","author":{"name":"Abdulmajeed Altwaireb"},"type":"module","bin":{"tring":"dist/cli-entry.mjs"},"exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"}},"engines":{"node":">=22"},"scripts":{"dev":"tsx src/index.ts","build":"tsdown","test":"vitest run","format":"biome format --write .","lint":"biome check .","check":"tsc --noEmit"},"packageManager":"pnpm@10.17.1","dependencies":{"@inquirer/prompts":"^8.5.2","c12":"4.0.0-beta.5","chalk":"^6.0.0","citty":"^0.2.2","ora":"^9.4.1","ts-morph":"^28.0.0"},"devDependencies":{"@biomejs/biome":"^2.5.7","@types/node":"^26.1.2","tsdown":"^0.22.14","tsx":"^4.23.8","typescript":"^6.0.3","vitest":"^4.1.10"},"allowScripts":{"esbuild@0.28.2":true},"gitHead":"3855c01d8a86ac90aec71feb1d6acc28d6901371","_id":"@altwaireb/tring@1.2.0","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-G3jgaqZGXujAvt1b+QPXPtJHEC6VSQCZf3lUT5oBPKin9QRtxwdSvEhrmWcKBh072TGGTjBcQsufpBiQPW7xww==","shasum":"c03e040828e5c394be66f9e5dba89cbb90cce1ce","tarball":"https://registry.npmjs.org/@altwaireb/tring/-/tring-1.2.0.tgz","fileCount":12,"unpackedSize":275071,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDEJenqI20/Tw2yFc2TJ7qlV2Xe1xFxbeBcRK/K2yxB0AIhALKWijbKzjHUudE60KwjoB+epuiP7naM22yLzFGPfOHr"}]},"_npmUser":{"name":"altwaireb","email":"altwaireb@gmail.com"},"directories":{},"maintainers":[{"name":"altwaireb","email":"altwaireb@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tring_1.2.0_1788459411305_0.4868273565677472"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-02T23:09:52.945Z","modified":"2026-09-03T18:16:51.625Z","1.1.0":"2026-09-02T23:09:53.209Z","1.2.0":"2026-09-03T18:16:51.449Z"},"bugs":{"url":"https://github.com/altwaireb/tring/issues"},"author":{"name":"Abdulmajeed Altwaireb"},"license":"MIT","homepage":"https://github.com/altwaireb/tring","keywords":["i18n","l10n","localization","translation","json","cli","typescript"],"repository":{"type":"git","url":"git+https://github.com/altwaireb/tring.git"},"description":"A developer-first toolkit for managing JSON translations.","maintainers":[{"name":"altwaireb","email":"altwaireb@gmail.com"}],"readme":"# Tring\n\n[![npm version](https://img.shields.io/npm/v/%40altwaireb%2Ftring)](https://www.npmjs.com/package/%40altwaireb%2Ftring)\n[![CI Status](https://img.shields.io/github/actions/workflow/status/altwaireb/tring/ci.yml)](https://github.com/altwaireb/tring/actions)\n\n> Keep translations in sync. Keep developers in control.\n\nA developer-first toolkit for managing JSON translations.\n\nTring provides a focused CLI workflow for creating, analyzing, validating, organizing, comparing, and synchronizing localized resources across your project.\n\n## Features\n\n- Analyze translations across configured target locales.\n- Detect missing and extra translation files and keys.\n- Detect empty translation values and unsorted keys.\n- Compare and synchronize translation resources automatically or with empty placeholders.\n- Support nested translation directories and multiple layout structures (`directories` or `files`).\n- TypeScript configuration with full type safety (`tring.config.ts`).\n- CI-friendly non-zero exit codes with GitHub Actions annotation formatting.\n- Lightweight and fast CLI built with Citty.\n\n## Installation\n\n```bash\npnpm add -D @altwaireb/tring\n# or npm\nnpm install --save-dev @altwaireb/tring\n# or yarn\nyarn add --dev @altwaireb/tring\n```\n\n## Quick Start\n\n```bash\ntring init      # Create configuration file\ntring doctor    # Validate setup & project structure\ntring analyze   # Run analysis on all target locales\ntring check     # Validate translation files for issues\n```\n\n## Configuration\n\nTring uses a TypeScript configuration file named `tring.config.ts`:\n\n```ts\nimport {\n\tdefineConfig,\n\tTranslationKeyRule,\n\tTranslationLayout,\n} from \"@altwaireb/tring\";\n\nexport default defineConfig({\n\tdirectory: \"app/i18n\",\n\tlayout: TranslationLayout.directories,\n\tsource: \"en-US\",\n\tlocales: [\"ar-SA\", \"fr-FR\"],\n\n\t// Translation key validation rule.\n\t// Default: TranslationKeyRule.alphaDash\n\t// Available: alpha, alphaNumeric, alphaDash, ascii, asciiSpaces\n\tkeyRule: TranslationKeyRule.alphaDash,\n});\n```\n\n### Configuration Options\n\n| Option | Description |\n| --- | --- |\n| `directory` | Root directory containing translation resources. |\n| `layout` | Translation file layout (`directories` or `files`). |\n| `source` | Source locale used as the translation reference. |\n| `locales` | Target locales to analyze and synchronize. |\n| `keyRule` | Translation key validation rule. Defaults to `TranslationKeyRule.alphaDash`. |\n\n## Translation Key Rules\n\nTring validates translation keys according to the configured `keyRule`.\n\nIf no rule is specified, Tring uses `TranslationKeyRule.alphaDash`.\n\n| Rule | Allowed characters |\n| --- | --- |\n| `alpha` | ASCII letters only (`A-Z`, `a-z`). |\n| `alphaNumeric` | ASCII letters and digits. Digits are allowed at the beginning. |\n| `alphaDash` | ASCII letters, digits, `_`, and `-`. `_` and `-` cannot appear at the beginning or end. |\n| `ascii` | Printable ASCII characters except spaces. |\n| `asciiSpaces` | Printable ASCII characters, including spaces. |\n\nFor example:\n\n```ts\nkeyRule: TranslationKeyRule.alphaNumeric,\n```\n\nThis allows keys such as:\n\n```json\n{\n\t\"2FA\": \"Two-factor authentication\",\n\t\"123days\": \"123 days\",\n\t\"APIV2\": \"API version 2\"\n}\n```\n\nFor keys that contain spaces:\n\n```ts\nkeyRule: TranslationKeyRule.asciiSpaces,\n```\n\nThe built-in rules support ASCII characters only. Non-ASCII characters such as Arabic, Japanese, and Chinese are not accepted.\n\n## Translation Layouts\n\n### Directories\n\nEach locale has its own directory. Nested directories are supported and identified relative to the locale folder:\n\n```text\napp/\n└── i18n/\n    ├── en-US/\n    │   ├── common.json\n    │   └── admin/\n    │       └── users.json\n    └── ar-SA/\n        ├── common.json\n        └── admin/\n            └── users.json\n```\n\n### Files\n\nEach locale is represented by a single JSON file:\n\n```text\napp/\n└── i18n/\n    ├── en-US.json\n    └── ar-SA.json\n```\n\n## Commands Overview\n\nAll commands support short aliases for faster workflow:\n\n| Command | Alias | Description |\n| --- | --- | --- |\n| `init` | `i` | Create a new Tring configuration file. |\n| `doctor` | `d` | Validate configuration and directory setup. |\n| `analyze` | `n` | Analyze all configured locales. |\n| `analyze-only` | `no` | Analyze a single specified locale. |\n| `check` | `c` | Check translation files for structural or content issues. |\n| `add` | `a` | Add missing translation keys to target locales. |\n| `sync` | `y` | Synchronize translation resources with the source locale. |\n| `compare` | `o` | Compare translation values for a file or key across locales. |\n| `missing` | `m` | Find missing keys and empty translation values. |\n| `sort` | `s` | Sort translation keys alphabetically. |\n| `list` | `l` | List translation resources. |\n\n---\n\n## Command Reference & Options\n\n### `tring add` (`a`)\n\nAdd missing translation keys to configured locales.\n\n```bash\ntring add [-e|--empty] [-l|--locale=<locale>] [-f|--file=<file>]\n```\n\n- `-e, --empty` — Use empty values for missing translation keys.\n- `-l, --locale` — Add missing translation keys only for the specified locale.\n- `-f, --file` — Add the specified translation file to all configured locales.\n\n### `tring analyze` (`n`)\n\nAnalyze all configured locales.\n\n```bash\ntring analyze [-f|--showFiles]\n```\n\n- `-f, --showFiles` — Show all translation files.\n\n### `tring analyze-only` (`no`)\n\nAnalyze a specific locale.\n\n```bash\ntring analyze-only [-f|--showFiles] <locale>\n```\n\n- `-f, --showFiles` — Show all translation files.\n- `<locale>` — The locale to analyze.\n\n### `tring check` (`c`)\n\nCheck translation files for structural or content issues.\n\n```bash\ntring check [--skip-empty] [--skip-sort] [--github]\n```\n\n- `--skip-empty` — Skip empty translation value checks.\n- `--skip-sort` — Skip translation key sorting checks.\n- `--github` — Format issues as GitHub workflow annotations.\n\n**GitHub Workflow Output Example:**\n\n```text\n::error file=app/i18n/de-DE/admin/users.json,title=Missing key::Missing translation key: status.active\n::warning file=app/i18n/fr-FR/settings.json,title=Empty value::Empty translation value: status.active\n```\n\n### `tring sync` (`y`)\n\nSynchronize translation files.\n\n```bash\ntring sync [--dry-run] [--apply] [--empty] [--locale=<locale>] [--file=<file>]\n```\n\n- `-d, --dry-run` — Preview translation changes without modifying files.\n- `-a, --apply` — Apply the planned translation changes.\n- `-e, --empty` — Use empty values for missing translation keys when applying changes.\n- `-l, --locale` — Synchronize only the specified locale.\n- `-f, --file` — Synchronize only the specified translation file.\n\n`--dryRun` and `--apply` cannot be used together.\n\nFor the `files` translation layout, `--file` is not supported.\n\n### `tring compare` (`o`)\n\nCompare translation values for a specific resource or key across locales.\n\n```bash\ntring compare\ntring compare --file auth.json\ntring compare --key login.title\n```\n\n- `-f, --file` — Translation resource file to compare.\n- `-k, --key` — Translation key to compare.\n\n### `tring doctor` (`d`)\n\nCheck your Tring project setup.\n\n```bash\ntring doctor\n```\n\n### `tring init` (`i`)\n\nCreate a new Tring configuration file.\n\n```bash\ntring init [--force]\n```\n\n- `--force` — Overwrite the existing configuration file.\n\n### `tring list` (`l`)\n\nList translation resources.\n\n```bash\ntring list [OPTIONS]\n```\n\n- `-f, --showFiles` — Show all translation files.\n\n### `tring missing` (`m`)\n\nFind missing translations.\n\n```bash\ntring missing [OPTIONS]\n```\n\n- `-e, --empty` — Include empty translations.\n- `-o, --only-empty` — Show only empty translations.\n\n### `tring sort` (`s`)\n\nSort translation keys alphabetically.\n\n```bash\ntring sort [-f|--file=<file>] [-l|--locale=<locale>]\n```\n\n- `-f, --file` — Translation file path starting with the locale (for example, `en-US/admin/roles.json`).\n- `-l, --locale` — Sort translation files for a specific locale.\n\n`--file` and `--locale` cannot be used together.\n\n---\n\n## Exit Codes & CI Integration\n\n| Exit Code | Meaning |\n| ---: | --- |\n| `0` | Command completed successfully without a command error. |\n| `1` | Translation issues were detected or the command could not complete successfully. |\n\n**GitHub Actions Workflow Integration:**\n```yaml\n- name: Validate Translations\n  run: pnpm exec tring check --github\n```\n\n---\n\n## Development\n\nClone the repository and install dependencies:\n\n```bash\ngit clone https://github.com/altwaireb/tring.git\ncd tring\npnpm install\n```\n\n### Quality Checks\n\nEnsure all checks pass before submitting pull requests:\n\n```bash\npnpm format\npnpm lint\npnpm check\npnpm test\npnpm build\n```\n\n## Package Testing\n\nTo test the published package from the example project:\n\n```bash\ncd examples/basic\npnpm update @altwaireb/tring --latest\n```\n\nRun the CLI:\n\n```bash\npnpm exec tring doctor\npnpm exec tring analyze\npnpm exec tring check\n```\n\n## Contributing\n\nContributions are welcome.\n\nBefore submitting a change, make sure all development checks pass.\n\nFor CLI changes, also test the published package from the example project.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}