-
Notifications
You must be signed in to change notification settings - Fork 841
Add ESLint rule to validate translator key destructuring #13932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Add ESLint rule to validate translator key destructuring #13932
Conversation
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
WalkthroughIntroduces a new ESLint rule Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/eslint-plugin-kolibri/lib/rules/no-undefined-translator-keys.js (1)
11-13: Consider cache invalidation strategy.The global cache improves performance but has no invalidation mechanism. In long-running processes (like IDE language servers), this could serve stale data if source files change, or grow unbounded over time. For typical CLI usage this is fine, but consider adding cache clearing on file changes or a size limit for language server scenarios.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
packages/eslint-plugin-kolibri/lib/rules/no-undefined-translator-keys.js(1 hunks)packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/defaultExport.js(1 hunks)packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/malformed.js(1 hunks)packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/reExport.js(1 hunks)packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/testStrings.js(1 hunks)packages/eslint-plugin-kolibri/tests/lib/rules/no-undefined-translator-keys.spec.js(1 hunks)packages/kolibri-format/.eslintrc.js(1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/malformed.js
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: Expected a semicolon or an implicit semicolon after a statement, but found none
An explicit or implicit semicolon is expected here...
...Which is required to end this statement
(parse)
[error] 6-6: expected } but instead the file ends
the file ends here
(parse)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
- GitHub Check: Python unit tests on Mac OS (3.10)
- GitHub Check: Python unit tests for currently supported Python versions (3.13)
- GitHub Check: Python unit tests for currently supported Python versions (3.11)
- GitHub Check: Python unit tests for currently supported Python versions (3.12)
- GitHub Check: Python unit tests for currently supported Python versions (3.10)
- GitHub Check: Python unit tests for currently supported Python versions (3.9)
- GitHub Check: Python unit tests on Windows Server (3.8)
- GitHub Check: Python unit tests for EOL Python versions (3.7)
- GitHub Check: Python unit tests for EOL Python versions (3.8)
- GitHub Check: Python unit tests for EOL Python versions (3.6)
- GitHub Check: Python postgres unit tests
- GitHub Check: Frontend tests
- GitHub Check: All file linting
- GitHub Check: Build WHL file / Build WHL
🔇 Additional comments (14)
packages/kolibri-format/.eslintrc.js (1)
255-255: LGTM!The rule is correctly configured with ERROR severity and appropriately placed among the other translator-related rules.
packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/defaultExport.js (1)
1-7: LGTM!This fixture correctly demonstrates the default export pattern for translators, providing good test coverage for that scenario.
packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/malformed.js (1)
1-6: LGTM!This malformed fixture correctly serves its purpose of testing the rule's resilience to parsing errors. The static analysis errors are expected and intentional for this test file.
packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/reExport.js (1)
1-9: LGTM!This fixture effectively demonstrates the re-export pattern (separate declaration and export), providing necessary test coverage for this common code pattern.
packages/eslint-plugin-kolibri/tests/lib/rules/no-undefined-translator-keys.spec.js (1)
1-691: Excellent test coverage!This test suite is comprehensive and well-structured:
- Covers a wide range of valid scenarios (basic destructuring, cross-file imports, default/re-exports, object-format messages, aliasing)
- Thoroughly tests invalid cases with precise error message validation
- Clear section organization with helpful comments
- Proper handling of edge cases (malformed files, non-existent imports, empty destructuring)
The test quality demonstrates careful consideration of real-world usage patterns.
packages/eslint-plugin-kolibri/tests/lib/rules/fixtures/testStrings.js (1)
1-32: LGTM!This fixture provides excellent test coverage with:
- Multiple translator instances for testing cross-translator scenarios
- Both string and object-format message patterns
- Clear demonstration of the message-with-context pattern used in Kolibri
The variety helps ensure the rule handles different translation patterns correctly.
packages/eslint-plugin-kolibri/lib/rules/no-undefined-translator-keys.js (8)
20-54: LGTM!These helper functions correctly identify
createTranslatorcalls and extract message keys, properly handling both identifier and literal property keys.
61-97: LGTM!These functions correctly traverse the AST to extract variable names and export names, handling the appropriate node types and parent relationships.
104-158: LGTM!The import resolution logic correctly handles both relative and absolute imports with appropriate error handling. The use of
require.resolvefor absolute imports (likekolibri/utils/i18n) is wrapped in try-catch, gracefully skipping validation when modules can't be resolved.
165-262: LGTM!The AST walking logic comprehensively handles all translator export patterns:
- Direct named exports
- Default exports
- Re-export patterns (declare then export)
The recursive walking correctly traverses the entire AST to discover all translator definitions.
270-302: LGTM!The file parsing logic correctly:
- Leverages caching for performance
- Handles parse failures gracefully by returning null
- Uses appropriate espree configuration for modern JavaScript
Note: TypeScript files (
.ts,.tsx) will fail to parse with espree and be silently skipped, which is acceptable per the design.
311-369: LGTM!The validation logic correctly:
- Requires trailing
$suffix on destructured keys- Validates keys exist in the translator definition
- Provides helpful error messages with available keys
- Properly handles spread operators, aliasing, and computed properties
371-462: LGTM!The rule implementation correctly:
- Tracks local translator definitions from
createTranslatorcalls- Resolves and tracks imported translators (both named and default imports)
- Validates destructuring against both local and imported translators
- Properly integrates with ESLint's visitor pattern
464-481: LGTM!The rule metadata and message definitions follow ESLint conventions correctly:
- Appropriate rule type and category
- Clear, actionable error messages
- Standard module exports structure
87879db to
ee70880
Compare
Build Artifacts
|
ba86935 to
53ac121
Compare
Implements no-undefined-translator-keys rule that prevents destructuring undefined keys from createTranslator objects. Validates both same-file and cross-file imports using AST parsing and Node.js module resolution.
53ac121 to
9834a4d
Compare
rtibbles
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This provides good test coverage of the rule, so I feel pretty confident about our using this.
| }, | ||
| }); | ||
|
|
||
| tester.run('no-undefined-translator-keys', rule, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that this seamlessly integrates with jest - as when I run this locally, it reports 52 tests running and passing.
Summary
Implements no-undefined-translator-keys rule that prevents destructuring undefined keys from createTranslator objects. Validates both same-file and cross-file imports using AST parsing and Node.js module resolution.
References
No open issue, but observed as a problem during recent string updates for release
Reviewer guidance
🤖 This was created by Claude Code. @rtibbles then reviewed the generated output, and did iterative rounds of updates before making it ready for review 🤖