{"_id":"@dxmd/eslint-plugin-i18n-messages","name":"@dxmd/eslint-plugin-i18n-messages","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@dxmd/eslint-plugin-i18n-messages","version":"1.0.0","description":"ESLint plugin to enforce identical keys across i18n message files","main":"dist/index.js","types":"dist/index.d.ts","keywords":["eslint","eslintplugin","eslint-plugin","i18n","internationalization","locale","translation","json"],"author":"","license":"MIT","repository":{"type":"git","url":""},"dependencies":{"minimatch":"^9.0.3","jsonc-eslint-parser":"^2.0.0"},"peerDependencies":{"eslint":">=8.0.0"},"devDependencies":{"@types/eslint":"^8.56.0","@types/node":"^20.0.0","typescript":"^5.3.0"},"engines":{"node":">=16.0.0"},"scripts":{"build":"tsc","clean":"rm -rf dist","prebuild":"npm run clean"},"_id":"@dxmd/eslint-plugin-i18n-messages@1.0.0","_integrity":"sha512-VrMP7vhr44EX8xF3dEwUKlV1gVt8LriNsq8LlE5A8TvPdcyno1IxoRKAjDvwlmt40waaZCSkjv3jW36tBLS/qQ==","_resolved":"/private/var/folders/bj/txjxx34n3tj9gx02qm5_5lx00000gn/T/5a3df6143abfc8bd84748bb250f25198/dxmd-eslint-plugin-i18n-messages-1.0.0.tgz","_from":"file:dxmd-eslint-plugin-i18n-messages-1.0.0.tgz","_nodeVersion":"20.16.0","_npmVersion":"10.8.3","dist":{"integrity":"sha512-VrMP7vhr44EX8xF3dEwUKlV1gVt8LriNsq8LlE5A8TvPdcyno1IxoRKAjDvwlmt40waaZCSkjv3jW36tBLS/qQ==","shasum":"14de60fcc33498c3828315a1498ea7f66aeb935e","tarball":"https://registry.npmjs.org/@dxmd/eslint-plugin-i18n-messages/-/eslint-plugin-i18n-messages-1.0.0.tgz","fileCount":18,"unpackedSize":27154,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD2vJBLS11GkVHvGH5sBl7p0Mm7viZmrpegXUQbux6tsAIgPB23EoTO+jlhLMuZMgsozwDEAN8rxH/lPUcWWQAQ5KM="}]},"_npmUser":{"name":"orindholt","email":"oliver.rindholt@gmail.com"},"directories":{},"maintainers":[{"name":"orindholt","email":"oliver.rindholt@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-plugin-i18n-messages_1.0.0_1762777501596_0.4850251007886701"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-10T12:25:01.498Z","1.0.0":"2025-11-10T12:25:01.768Z","modified":"2025-11-10T12:25:02.133Z"},"maintainers":[{"name":"orindholt","email":"oliver.rindholt@gmail.com"}],"description":"ESLint plugin to enforce identical keys across i18n message files","keywords":["eslint","eslintplugin","eslint-plugin","i18n","internationalization","locale","translation","json"],"repository":{"type":"git","url":""},"license":"MIT","readme":"# eslint-plugin-i18n-messages\n\n[![npm version](https://img.shields.io/npm/v/eslint-plugin-i18n-messages.svg)](https://www.npmjs.com/package/eslint-plugin-i18n-messages)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nESLint plugin to enforce identical keys across i18n/locale message files. Helps prevent missing translations by ensuring all locale files have the same structure.\n\n## Features\n\n- ✅ Validates JSON locale files against a reference file\n- ✅ Detects missing keys (in reference but not in current file)\n- ✅ Detects extra keys (in current file but not in reference)\n- ✅ Supports nested object structures with dot notation\n- ✅ Glob pattern support for reference file\n- ✅ Bundles JSON parser - no additional dependencies needed\n- ✅ Works with both ESLint flat config and legacy config\n\n## Installation\n\n```bash\nnpm install --save-dev eslint-plugin-i18n-messages\n```\n\nThe plugin bundles `jsonc-eslint-parser`, so you don't need to install it separately.\n\n## Requirements\n\n- Node.js >= 16.0.0\n- ESLint >= 8.0.0\n\n## Usage\n\nThis plugin helps ensure all your locale/translation files have the same keys, preventing missing translations in your application.\n\n### Flat Config (eslint.config.js)\n\n```javascript\nimport i18nMessages from 'eslint-plugin-i18n-messages';\n\nexport default [\n  {\n    files: ['**/*.json'],\n    languageOptions: {\n      parser: i18nMessages.parser  // Use the bundled parser\n    },\n    plugins: {\n      'i18n-messages': i18nMessages\n    },\n    rules: {\n      'i18n-messages/identical-keys': ['error', {\n        referenceFile: 'locales/en.json'\n      }]\n    }\n  }\n];\n```\n\nOr if you prefer to use your own parser installation:\n\n```javascript\nimport i18nMessages from 'eslint-plugin-i18n-messages';\nimport jsoncParser from 'jsonc-eslint-parser';\n\nexport default [\n  {\n    files: ['**/*.json'],\n    languageOptions: {\n      parser: jsoncParser\n    },\n    plugins: {\n      'i18n-messages': i18nMessages\n    },\n    rules: {\n      'i18n-messages/identical-keys': ['error', {\n        referenceFile: 'locales/en.json'\n      }]\n    }\n  }\n];\n```\n\n### Legacy Config (.eslintrc.js)\n\n```javascript\nmodule.exports = {\n  overrides: [\n    {\n      files: ['*.json'],\n      parser: 'jsonc-eslint-parser',\n      plugins: ['i18n-messages'],\n      rules: {\n        'i18n-messages/identical-keys': ['error', {\n          referenceFile: 'locales/en.json'\n        }]\n      }\n    }\n  ]\n};\n```\n\n### Using the Recommended Config (Legacy only)\n\n```javascript\nmodule.exports = {\n  extends: ['plugin:i18n-messages/recommended'],\n  rules: {\n    'i18n-messages/identical-keys': ['error', {\n      referenceFile: 'locales/en.json'  // You still need to specify your reference file\n    }]\n  }\n};\n```\n\n## Rule: `identical-keys`\n\nEnsures all locale files have identical keys to a reference file.\n\n### Options\n\n- `referenceFile` (required): Path to the reference locale file. Supports glob patterns.\n- `excludeReference` (optional, default: `true`): Whether to exclude the reference file from linting.\n\n### Examples\n\n#### Basic usage\n\n```javascript\n{\n  'i18n-messages/identical-keys': ['error', {\n    referenceFile: 'src/locales/en.json'\n  }]\n}\n```\n\n#### Using glob patterns\n\n```javascript\n{\n  'i18n-messages/identical-keys': ['error', {\n    referenceFile: 'src/locales/**/en.json'\n  }]\n}\n```\n\n#### Include reference file in linting\n\n```javascript\n{\n  'i18n-messages/identical-keys': ['error', {\n    referenceFile: 'src/locales/en.json',\n    excludeReference: false\n  }]\n}\n```\n\n## How it works\n\nThe plugin compares the keys in each locale file against the reference file and reports:\n\n- **Missing keys**: Keys that exist in the reference file but not in the current file\n- **Extra keys**: Keys that exist in the current file but not in the reference file\n\n### Example\n\nGiven a reference file `en.json`:\n```json\n{\n  \"welcome\": \"Welcome\",\n  \"goodbye\": \"Goodbye\"\n}\n```\n\nAnd a locale file `fr.json`:\n```json\n{\n  \"welcome\": \"Bienvenue\"\n}\n```\n\nESLint will report:\n```\nMissing 1 key from reference file (locales/en.json): \"goodbye\"\n```\n\n### Nested keys\n\nThe plugin supports nested object structures:\n\n```json\n{\n  \"auth\": {\n    \"login\": \"Login\",\n    \"logout\": \"Logout\"\n  }\n}\n```\n\nKeys are flattened as `auth.login` and `auth.logout` for comparison.\n\n## Requirements\n\n- Node.js >= 16.0.0\n- ESLint >= 8.0.0\n- jsonc-eslint-parser >= 2.0.0 (bundled)\n\n## Project Structure\n\n```\nsrc/\n├── index.ts              # Main plugin entry point\n├── types.ts              # TypeScript type definitions\n├── rules/\n│   └── identical-keys.ts # Main rule implementation\n└── utils/\n    ├── ast-helpers.ts         # AST node finding utilities\n    ├── find-project-root.ts   # Project root detection\n    ├── find-reference-file.ts # Reference file resolution\n    ├── get-keys.ts            # Key extraction from objects\n    └── index.ts               # Utility exports\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-995f0c96912aaaca06c5d27933842379"}