@generaltranslation/gt-next-lint 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -202
- package/dist/configs/recommended.d.ts +2 -1
- package/dist/configs/recommended.d.ts.map +1 -1
- package/dist/configs/recommended.js +2 -1
- package/dist/configs/recommended.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/rules/{no-unwrapped-dynamic-content.d.ts → no-dynamic-jsx.d.ts} +3 -3
- package/dist/rules/no-dynamic-jsx.d.ts.map +1 -0
- package/dist/rules/{no-unwrapped-dynamic-content.js → no-dynamic-jsx.js} +52 -20
- package/dist/rules/no-dynamic-jsx.js.map +1 -0
- package/dist/rules/no-dynamic-string.d.ts +10 -0
- package/dist/rules/no-dynamic-string.d.ts.map +1 -0
- package/dist/rules/no-dynamic-string.js +186 -0
- package/dist/rules/no-dynamic-string.js.map +1 -0
- package/package.json +4 -2
- package/dist/rules/no-unwrapped-dynamic-content.d.ts.map +0 -1
- package/dist/rules/no-unwrapped-dynamic-content.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,244 +1,68 @@
|
|
|
1
1
|
# @generaltranslation/gt-next-lint
|
|
2
2
|
|
|
3
|
-
ESLint plugin
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Automatic Detection**: Finds dynamic content (`{expressions}`) inside `<T>` components
|
|
8
|
-
- **Precise Error Reporting**: Shows exact file locations and line numbers
|
|
9
|
-
- **Framework Agnostic**: Works with Next.js, React, and other JSX frameworks
|
|
10
|
-
- **Zero Configuration**: Works out of the box with sensible defaults
|
|
11
|
-
- **TypeScript Support**: Full TypeScript support with type definitions
|
|
3
|
+
ESLint plugin that catches common translation errors in gt-next components.
|
|
12
4
|
|
|
13
5
|
## Installation
|
|
14
6
|
|
|
15
|
-
### Automatic Setup (Recommended)
|
|
16
|
-
|
|
17
|
-
If you're already using `gt-next`, the ESLint plugin will be automatically configured when you install it:
|
|
18
|
-
|
|
19
7
|
```bash
|
|
20
8
|
npm install --save-dev @generaltranslation/gt-next-lint
|
|
21
|
-
# or
|
|
22
|
-
yarn add --dev @generaltranslation/gt-next-lint
|
|
23
9
|
```
|
|
24
10
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### Manual Setup
|
|
11
|
+
## Configuration
|
|
28
12
|
|
|
29
|
-
|
|
13
|
+
Add to your `eslint.config.mjs`:
|
|
30
14
|
|
|
31
15
|
```javascript
|
|
32
|
-
// eslint.config.mjs
|
|
33
16
|
import gtNext from '@generaltranslation/gt-next-lint';
|
|
34
17
|
|
|
35
18
|
export default [
|
|
36
19
|
{
|
|
37
|
-
|
|
38
|
-
plugins: {
|
|
39
|
-
'gt-next': gtNext,
|
|
40
|
-
},
|
|
20
|
+
plugins: { 'gt-next': gtNext },
|
|
41
21
|
rules: {
|
|
42
|
-
'gt-next/no-
|
|
43
|
-
|
|
44
|
-
languageOptions: {
|
|
45
|
-
ecmaVersion: 2020,
|
|
46
|
-
sourceType: 'module',
|
|
47
|
-
parserOptions: {
|
|
48
|
-
ecmaFeatures: {
|
|
49
|
-
jsx: true,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
22
|
+
'gt-next/no-dynamic-jsx': 'error',
|
|
23
|
+
'gt-next/no-dynamic-string': 'error',
|
|
52
24
|
},
|
|
53
25
|
},
|
|
54
26
|
];
|
|
55
27
|
```
|
|
56
28
|
|
|
57
|
-
### withGTConfig Integration
|
|
58
|
-
|
|
59
|
-
You can customize the ESLint integration in your Next.js config:
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
// next.config.mjs
|
|
63
|
-
import { withGTConfig } from 'gt-next/config';
|
|
64
|
-
|
|
65
|
-
export default withGTConfig(nextConfig, {
|
|
66
|
-
projectId: 'your-project-id',
|
|
67
|
-
// ESLint options
|
|
68
|
-
eslint: true, // Enable ESLint integration (default: true)
|
|
69
|
-
eslintSeverity: 'error', // 'error' or 'warn' (default: 'warn')
|
|
70
|
-
overwriteESLintConfig: false, // Overwrite existing eslint.config.mjs (default: false)
|
|
71
|
-
});
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Using Recommended Configuration
|
|
75
|
-
|
|
76
|
-
For the easiest setup, use the recommended configuration:
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
// eslint.config.mjs
|
|
80
|
-
import gtNext from '@generaltranslation/gt-next-lint';
|
|
81
|
-
|
|
82
|
-
export default [
|
|
83
|
-
gtNext.configs.recommended,
|
|
84
|
-
];
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Legacy ESLint Configuration (.eslintrc)
|
|
88
|
-
|
|
89
|
-
```json
|
|
90
|
-
{
|
|
91
|
-
"plugins": ["gt-next"],
|
|
92
|
-
"rules": {
|
|
93
|
-
"gt-next/no-unwrapped-dynamic-content": "warn"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
29
|
## Rules
|
|
99
30
|
|
|
100
|
-
### `no-
|
|
101
|
-
|
|
102
|
-
Detects unwrapped dynamic content in GT-Next translation components.
|
|
31
|
+
### `no-dynamic-jsx`
|
|
103
32
|
|
|
104
|
-
|
|
33
|
+
Wraps dynamic content in `<T>` components with variable components.
|
|
105
34
|
|
|
106
35
|
```jsx
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// Error: Dynamic content should be wrapped
|
|
36
|
+
// ❌ Wrong
|
|
110
37
|
<T>Hello {userName}!</T>
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
#### ✅ Correct
|
|
114
|
-
|
|
115
|
-
```jsx
|
|
116
|
-
import { T, Var } from 'gt-next';
|
|
117
38
|
|
|
118
|
-
// Correct
|
|
39
|
+
// ✅ Correct
|
|
119
40
|
<T>Hello <Var>{userName}</Var>!</T>
|
|
120
41
|
```
|
|
121
42
|
|
|
122
|
-
|
|
43
|
+
### `no-dynamic-string`
|
|
123
44
|
|
|
124
|
-
|
|
45
|
+
Only allows string literals in translation functions.
|
|
125
46
|
|
|
126
|
-
**Named Imports**
|
|
127
47
|
```jsx
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<T>
|
|
131
|
-
Hello <Var>{name}</Var>!
|
|
132
|
-
Today is <DateTime>{date}</DateTime>.
|
|
133
|
-
Price: <Currency>{price}</Currency>
|
|
134
|
-
Count: <Num>{count}</Num>
|
|
135
|
-
</T>
|
|
136
|
-
```
|
|
48
|
+
const t = useGT();
|
|
137
49
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
50
|
+
// ❌ Wrong
|
|
51
|
+
t(`Hello ${name}`)
|
|
52
|
+
t('Hello ' + name)
|
|
141
53
|
|
|
142
|
-
|
|
54
|
+
// ✅ Correct
|
|
55
|
+
t('Hello, {name}!', { name })
|
|
143
56
|
```
|
|
144
57
|
|
|
145
|
-
|
|
146
|
-
```jsx
|
|
147
|
-
import { T, Var } from 'gt-next';
|
|
148
|
-
|
|
149
|
-
const MyT = T;
|
|
150
|
-
const MyVar = Var;
|
|
151
|
-
|
|
152
|
-
<MyT>Hello <MyVar>{userName}</MyVar>!</MyT>
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
**Different Import Sources**
|
|
156
|
-
- `gt-next`
|
|
157
|
-
- `gt-next/client`
|
|
158
|
-
- `gt-next/server`
|
|
159
|
-
|
|
160
|
-
#### Rule Options
|
|
161
|
-
|
|
162
|
-
```javascript
|
|
163
|
-
{
|
|
164
|
-
"gt-next/no-unwrapped-dynamic-content": ["warn", {
|
|
165
|
-
"severity": "warn" // "warn" or "error"
|
|
166
|
-
}]
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Integration with Next.js
|
|
171
|
-
|
|
172
|
-
This ESLint plugin works perfectly alongside the GT-Next package:
|
|
173
|
-
|
|
174
|
-
1. **Install GT-Next**:
|
|
175
|
-
```bash
|
|
176
|
-
npm install gt-next
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. **Configure Next.js**:
|
|
180
|
-
```javascript
|
|
181
|
-
// next.config.mjs
|
|
182
|
-
import { withGTConfig } from 'gt-next/config';
|
|
183
|
-
|
|
184
|
-
export default withGTConfig(nextConfig, {
|
|
185
|
-
projectId: 'your-project-id',
|
|
186
|
-
locales: ['en', 'es', 'fr'],
|
|
187
|
-
});
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
3. **Add ESLint Plugin**:
|
|
191
|
-
```javascript
|
|
192
|
-
// eslint.config.mjs
|
|
193
|
-
import gtNext from '@generaltranslation/gt-next-lint';
|
|
194
|
-
|
|
195
|
-
export default [gtNext.configs.recommended];
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## When Linting Runs
|
|
199
|
-
|
|
200
|
-
- **During Development**: Shows warnings in your IDE (VS Code, WebStorm, etc.)
|
|
201
|
-
- **During Build**: Runs as part of `npm run build` and `next build`
|
|
202
|
-
- **In CI/CD**: Catches issues in your continuous integration pipeline
|
|
203
|
-
|
|
204
|
-
## Comparison with SWC Plugin
|
|
205
|
-
|
|
206
|
-
This ESLint plugin provides better developer experience compared to the SWC plugin:
|
|
207
|
-
|
|
208
|
-
| Feature | ESLint Plugin | SWC Plugin |
|
|
209
|
-
|---------|---------------|------------|
|
|
210
|
-
| **Error Location** | ✅ Exact file:line | ❌ Console logs only |
|
|
211
|
-
| **IDE Integration** | ✅ Real-time warnings | ❌ Build-time only |
|
|
212
|
-
| **Customizable Rules** | ✅ Full ESLint config | ❌ Limited options |
|
|
213
|
-
| **Performance** | ✅ Fast linting | ✅ Fast compilation |
|
|
214
|
-
|
|
215
|
-
## Monorepo Support
|
|
216
|
-
|
|
217
|
-
The plugin works seamlessly in monorepo setups:
|
|
218
|
-
|
|
219
|
-
```javascript
|
|
220
|
-
// packages/app/eslint.config.mjs
|
|
221
|
-
import gtNext from '@generaltranslation/gt-next-lint';
|
|
222
|
-
|
|
223
|
-
export default [
|
|
224
|
-
{
|
|
225
|
-
...gtNext.configs.recommended,
|
|
226
|
-
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
227
|
-
// Will detect GT-Next usage across your entire monorepo
|
|
228
|
-
},
|
|
229
|
-
];
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Contributing
|
|
233
|
-
|
|
234
|
-
Issues and pull requests are welcome! Please see our [Contributing Guide](../../CONTRIBUTING.md).
|
|
235
|
-
|
|
236
|
-
## License
|
|
58
|
+
## Supported Components
|
|
237
59
|
|
|
238
|
-
|
|
60
|
+
- `<Var>` - Variables
|
|
61
|
+
- `<DateTime>` - Dates
|
|
62
|
+
- `<Num>` - Numbers
|
|
63
|
+
- `<Currency>` - Currency
|
|
239
64
|
|
|
240
|
-
##
|
|
65
|
+
## Supported Functions
|
|
241
66
|
|
|
242
|
-
-
|
|
243
|
-
-
|
|
244
|
-
- 💬 [Discussions](https://github.com/generaltranslation/gt/discussions)
|
|
67
|
+
- `useGT()` - Client translations
|
|
68
|
+
- `getGT()` - Server translations
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;CAWvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,WAAW,GAAG;IACzB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,KAAK,EAAE;QACL,
|
|
1
|
+
{"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,WAAW,GAAG;IACzB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,KAAK,EAAE;QACL,wBAAwB,EAAE,IAAI;QAC9B,2BAA2B,EAAE,IAAI;KAClC;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ;SAClB;KACF;CACF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,13 +11,15 @@ declare const plugin: {
|
|
|
11
11
|
version: string;
|
|
12
12
|
};
|
|
13
13
|
rules: {
|
|
14
|
-
'no-
|
|
14
|
+
'no-dynamic-jsx': import("eslint").Rule.RuleModule;
|
|
15
|
+
'no-dynamic-string': import("eslint").Rule.RuleModule;
|
|
15
16
|
};
|
|
16
17
|
configs: {
|
|
17
18
|
recommended: {
|
|
18
19
|
plugins: string[];
|
|
19
20
|
rules: {
|
|
20
|
-
'gt-next/no-
|
|
21
|
+
'gt-next/no-dynamic-jsx': boolean;
|
|
22
|
+
'gt-next/no-dynamic-string': boolean;
|
|
21
23
|
};
|
|
22
24
|
settings: {
|
|
23
25
|
react: {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;CAYX,CAAC;AAEF,SAAS,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* This plugin detects unwrapped dynamic content in translation components
|
|
7
7
|
* and provides better error reporting with file locations and line numbers.
|
|
8
8
|
*/
|
|
9
|
-
const
|
|
9
|
+
const no_dynamic_jsx_1 = require("./rules/no-dynamic-jsx");
|
|
10
|
+
const no_dynamic_string_1 = require("./rules/no-dynamic-string");
|
|
10
11
|
const recommended_1 = require("./configs/recommended");
|
|
11
12
|
const plugin = {
|
|
12
13
|
meta: {
|
|
@@ -14,7 +15,8 @@ const plugin = {
|
|
|
14
15
|
version: '1.0.0',
|
|
15
16
|
},
|
|
16
17
|
rules: {
|
|
17
|
-
'no-
|
|
18
|
+
'no-dynamic-jsx': no_dynamic_jsx_1.noDynamicJsx,
|
|
19
|
+
'no-dynamic-string': no_dynamic_string_1.noDynamicString,
|
|
18
20
|
},
|
|
19
21
|
configs: {
|
|
20
22
|
recommended: recommended_1.recommended,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,2DAAsD;AACtD,iEAA4D;AAC5D,uDAAoD;AAEpD,MAAM,MAAM,GAAG;IACb,IAAI,EAAE;QACJ,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,OAAO;KACjB;IACD,KAAK,EAAE;QACL,gBAAgB,EAAE,6BAAY;QAC9B,mBAAmB,EAAE,mCAAe;KACrC;IACD,OAAO,EAAE;QACP,WAAW,EAAX,yBAAW;KACZ;CACF,CAAC;AAEF,iBAAS,MAAM,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ESLint rule: no-
|
|
2
|
+
* ESLint rule: no-dynamic-jsx
|
|
3
3
|
*
|
|
4
4
|
* Detects unwrapped dynamic content in GT-Next translation components.
|
|
5
5
|
* Equivalent to the SWC plugin functionality but with proper ESLint error reporting.
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
* that are not wrapped in variable components (<Var>, <DateTime>, <Num>, <Currency>).
|
|
9
9
|
*/
|
|
10
10
|
import type { Rule } from 'eslint';
|
|
11
|
-
export declare const
|
|
12
|
-
//# sourceMappingURL=no-
|
|
11
|
+
export declare const noDynamicJsx: Rule.RuleModule;
|
|
12
|
+
//# sourceMappingURL=no-dynamic-jsx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-dynamic-jsx.d.ts","sourceRoot":"","sources":["../../src/rules/no-dynamic-jsx.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAkBnC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,UAyN/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* ESLint rule: no-
|
|
3
|
+
* ESLint rule: no-dynamic-jsx
|
|
4
4
|
*
|
|
5
5
|
* Detects unwrapped dynamic content in GT-Next translation components.
|
|
6
6
|
* Equivalent to the SWC plugin functionality but with proper ESLint error reporting.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* that are not wrapped in variable components (<Var>, <DateTime>, <Num>, <Currency>).
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.noDynamicJsx = void 0;
|
|
13
13
|
const GT_MODULES = ['gt-next', 'gt-next/client', 'gt-next/server'];
|
|
14
14
|
const TRANSLATION_COMPONENTS = ['T'];
|
|
15
15
|
const VARIABLE_COMPONENTS = ['Var', 'DateTime', 'Num', 'Currency'];
|
|
@@ -22,31 +22,19 @@ function isTranslationComponent(name) {
|
|
|
22
22
|
function isVariableComponent(name) {
|
|
23
23
|
return VARIABLE_COMPONENTS.includes(name);
|
|
24
24
|
}
|
|
25
|
-
exports.
|
|
25
|
+
exports.noDynamicJsx = {
|
|
26
26
|
meta: {
|
|
27
27
|
type: 'problem',
|
|
28
28
|
docs: {
|
|
29
29
|
description: 'Detect unwrapped dynamic content in GT-Next translation components',
|
|
30
30
|
category: 'Best Practices',
|
|
31
31
|
recommended: true,
|
|
32
|
-
url: 'https://github.com/generaltranslation/gt/tree/main/packages/next-lint#no-
|
|
32
|
+
url: 'https://github.com/generaltranslation/gt/tree/main/packages/next-lint#no-dynamic-jsx',
|
|
33
33
|
},
|
|
34
34
|
fixable: undefined,
|
|
35
|
-
schema: [
|
|
36
|
-
{
|
|
37
|
-
type: 'object',
|
|
38
|
-
properties: {
|
|
39
|
-
severity: {
|
|
40
|
-
type: 'string',
|
|
41
|
-
enum: ['error', 'warn'],
|
|
42
|
-
default: 'warn',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
additionalProperties: false,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
35
|
+
schema: [],
|
|
48
36
|
messages: {
|
|
49
|
-
|
|
37
|
+
dynamicJsx: 'Dynamic content in <T> component should be wrapped in a variable component (<Var>, <DateTime>, <Num>, or <Currency>)',
|
|
50
38
|
},
|
|
51
39
|
},
|
|
52
40
|
create(context) {
|
|
@@ -95,6 +83,38 @@ exports.noUnwrappedDynamicContent = {
|
|
|
95
83
|
}
|
|
96
84
|
return false;
|
|
97
85
|
}
|
|
86
|
+
function isInsideJSXAttribute(node) {
|
|
87
|
+
// Walk up the AST to check if this expression is inside a JSX attribute
|
|
88
|
+
let currentNode = node.parent;
|
|
89
|
+
while (currentNode) {
|
|
90
|
+
if (currentNode.type === 'JSXAttribute') {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
// If we reach a JSX element, we're in element content, not attributes
|
|
94
|
+
if (currentNode.type === 'JSXElement') {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
currentNode = currentNode.parent;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
// Check if the node is a string literal or template literal
|
|
102
|
+
function isStringLiteral(expression) {
|
|
103
|
+
// For JSXExpressionContainer, check the expression inside
|
|
104
|
+
return ((expression.type === 'Literal' &&
|
|
105
|
+
typeof expression.value === 'string') ||
|
|
106
|
+
(expression.type === 'TemplateLiteral' &&
|
|
107
|
+
expression.expressions.length === 0) // No interpolation
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
// Check if the node is a comment
|
|
111
|
+
function isComment(expression) {
|
|
112
|
+
return expression.type === 'Block' || expression.type === 'Line';
|
|
113
|
+
}
|
|
114
|
+
// Check if empty
|
|
115
|
+
function isEmpty(expression) {
|
|
116
|
+
return expression.type === 'JSXEmptyExpression';
|
|
117
|
+
}
|
|
98
118
|
return {
|
|
99
119
|
// Track imports from GT-Next modules
|
|
100
120
|
ImportDeclaration(node) {
|
|
@@ -137,6 +157,18 @@ exports.noUnwrappedDynamicContent = {
|
|
|
137
157
|
},
|
|
138
158
|
// Detect unwrapped dynamic content
|
|
139
159
|
JSXExpressionContainer(node) {
|
|
160
|
+
// Skip expressions inside JSX attributes (e.g., <Image width={16} />)
|
|
161
|
+
if (isInsideJSXAttribute(node)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Skip expressions with just a string literal (e.g., {'Hello'})
|
|
165
|
+
// Skip expressions with just a comment
|
|
166
|
+
// Skip expressions with just an empty statement
|
|
167
|
+
if ((node.expression && isStringLiteral(node.expression)) ||
|
|
168
|
+
isComment(node.expression) ||
|
|
169
|
+
isEmpty(node.expression)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
140
172
|
// Check if this expression is inside a translation component but not inside a variable component
|
|
141
173
|
let inTranslationComponent = false;
|
|
142
174
|
let inVariableComponent = false;
|
|
@@ -167,11 +199,11 @@ exports.noUnwrappedDynamicContent = {
|
|
|
167
199
|
if (inTranslationComponent && !inVariableComponent) {
|
|
168
200
|
context.report({
|
|
169
201
|
node,
|
|
170
|
-
messageId: '
|
|
202
|
+
messageId: 'dynamicJsx',
|
|
171
203
|
});
|
|
172
204
|
}
|
|
173
205
|
},
|
|
174
206
|
};
|
|
175
207
|
},
|
|
176
208
|
};
|
|
177
|
-
//# sourceMappingURL=no-
|
|
209
|
+
//# sourceMappingURL=no-dynamic-jsx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-dynamic-jsx.js","sourceRoot":"","sources":["../../src/rules/no-dynamic-jsx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule: no-dynamic-string
|
|
3
|
+
*
|
|
4
|
+
* Ensures translation functions (t, useGT, getGT) only accept string literals
|
|
5
|
+
* as their first argument. Dynamic content like template literals or string
|
|
6
|
+
* concatenation is prohibited to ensure consistent translation keys.
|
|
7
|
+
*/
|
|
8
|
+
import type { Rule } from 'eslint';
|
|
9
|
+
export declare const noDynamicString: Rule.RuleModule;
|
|
10
|
+
//# sourceMappingURL=no-dynamic-string.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-dynamic-string.d.ts","sourceRoot":"","sources":["../../src/rules/no-dynamic-string.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAkBnC,eAAO,MAAM,eAAe,EAAE,IAAI,CAAC,UA8LlC,CAAC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESLint rule: no-dynamic-string
|
|
4
|
+
*
|
|
5
|
+
* Ensures translation functions (t, useGT, getGT) only accept string literals
|
|
6
|
+
* as their first argument. Dynamic content like template literals or string
|
|
7
|
+
* concatenation is prohibited to ensure consistent translation keys.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.noDynamicString = void 0;
|
|
11
|
+
const GT_MODULES = ['gt-next', 'gt-next/client', 'gt-next/server'];
|
|
12
|
+
const TRANSLATION_FUNCTIONS = ['useGT', 'getGT'];
|
|
13
|
+
function isGTModule(source) {
|
|
14
|
+
return GT_MODULES.includes(source);
|
|
15
|
+
}
|
|
16
|
+
function isTranslationFunction(name) {
|
|
17
|
+
return TRANSLATION_FUNCTIONS.includes(name);
|
|
18
|
+
}
|
|
19
|
+
exports.noDynamicString = {
|
|
20
|
+
meta: {
|
|
21
|
+
type: 'problem',
|
|
22
|
+
docs: {
|
|
23
|
+
description: 'Translation functions must use string literals as the first argument',
|
|
24
|
+
category: 'Best Practices',
|
|
25
|
+
recommended: true,
|
|
26
|
+
url: 'https://github.com/generaltranslation/gt/tree/main/packages/next-lint#no-dynamic-string',
|
|
27
|
+
},
|
|
28
|
+
fixable: undefined,
|
|
29
|
+
schema: [],
|
|
30
|
+
messages: {
|
|
31
|
+
dynamicString: "Translation function must use a constant string literal as the first argument. Use t('Hello, {name}!', { name: value }) instead of template literals or string concatenation.",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
create(context) {
|
|
35
|
+
// Track imported GT functions and their aliases
|
|
36
|
+
const trackedFunctions = new Map();
|
|
37
|
+
// Track variables assigned from translation function calls
|
|
38
|
+
const translationVariables = new Set();
|
|
39
|
+
function trackImport(localName, importedName, source) {
|
|
40
|
+
if (isGTModule(source) && isTranslationFunction(importedName)) {
|
|
41
|
+
trackedFunctions.set(localName, {
|
|
42
|
+
name: importedName,
|
|
43
|
+
isTranslationFunction: true,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function trackNamespaceImport(localName, source) {
|
|
48
|
+
if (isGTModule(source)) {
|
|
49
|
+
trackedFunctions.set(localName, {
|
|
50
|
+
name: localName,
|
|
51
|
+
isTranslationFunction: false, // It's a namespace, not directly callable
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isStringLiteral(node) {
|
|
56
|
+
return ((node.type === 'Literal' && typeof node.value === 'string') ||
|
|
57
|
+
(node.type === 'TemplateLiteral' && node.expressions.length === 0) // Template literal with no interpolation
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function validateTranslationCall(node) {
|
|
61
|
+
const firstArg = node.arguments[0];
|
|
62
|
+
if (!firstArg)
|
|
63
|
+
return; // No arguments
|
|
64
|
+
if (!isStringLiteral(firstArg)) {
|
|
65
|
+
context.report({
|
|
66
|
+
node: firstArg,
|
|
67
|
+
messageId: 'dynamicString',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function handleCallExpression(node) {
|
|
72
|
+
if (node.callee.type === 'Identifier') {
|
|
73
|
+
// Direct function calls: t(), useGT(), etc.
|
|
74
|
+
const functionName = node.callee.name;
|
|
75
|
+
if (trackedFunctions.has(functionName)) {
|
|
76
|
+
const tracked = trackedFunctions.get(functionName);
|
|
77
|
+
if (tracked.isTranslationFunction) {
|
|
78
|
+
validateTranslationCall(node);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (translationVariables.has(functionName)) {
|
|
82
|
+
// Variable assigned from translation function
|
|
83
|
+
validateTranslationCall(node);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (node.callee.type === 'MemberExpression') {
|
|
87
|
+
// Member expressions: GT.tx(), namespace.function()
|
|
88
|
+
const objectName = node.callee.object.name;
|
|
89
|
+
const propertyName = node.callee.property.name;
|
|
90
|
+
if (trackedFunctions.has(objectName) &&
|
|
91
|
+
isTranslationFunction(propertyName)) {
|
|
92
|
+
validateTranslationCall(node);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function handleAssignment(node) {
|
|
97
|
+
// Track variables assigned from translation function calls
|
|
98
|
+
if (node.type === 'VariableDeclarator' &&
|
|
99
|
+
node.id.type === 'Identifier' &&
|
|
100
|
+
node.init) {
|
|
101
|
+
if (node.init.type === 'CallExpression') {
|
|
102
|
+
const callExpression = node.init;
|
|
103
|
+
if (callExpression.callee.type === 'Identifier') {
|
|
104
|
+
const functionName = callExpression.callee.name;
|
|
105
|
+
if (trackedFunctions.has(functionName)) {
|
|
106
|
+
const tracked = trackedFunctions.get(functionName);
|
|
107
|
+
if (tracked.isTranslationFunction) {
|
|
108
|
+
// This variable now holds a translation function
|
|
109
|
+
translationVariables.add(node.id.name);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (callExpression.callee.type === 'MemberExpression') {
|
|
114
|
+
// Handle namespace calls like: const t = GT.useGT();
|
|
115
|
+
const objectName = callExpression.callee.object.name;
|
|
116
|
+
const propertyName = callExpression.callee.property.name;
|
|
117
|
+
if (trackedFunctions.has(objectName) &&
|
|
118
|
+
isTranslationFunction(propertyName)) {
|
|
119
|
+
// This variable now holds a translation function
|
|
120
|
+
translationVariables.add(node.id.name);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (node.init.type === 'AwaitExpression' &&
|
|
125
|
+
node.init.argument.type === 'CallExpression') {
|
|
126
|
+
// Handle await getGT() case
|
|
127
|
+
const callExpression = node.init.argument;
|
|
128
|
+
if (callExpression.callee.type === 'Identifier') {
|
|
129
|
+
const functionName = callExpression.callee.name;
|
|
130
|
+
if (trackedFunctions.has(functionName)) {
|
|
131
|
+
const tracked = trackedFunctions.get(functionName);
|
|
132
|
+
if (tracked.isTranslationFunction) {
|
|
133
|
+
// This variable now holds a translation function (from awaited promise)
|
|
134
|
+
translationVariables.add(node.id.name);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (callExpression.callee.type === 'MemberExpression') {
|
|
139
|
+
// Handle namespace calls like: const t = await GT.getGT();
|
|
140
|
+
const objectName = callExpression.callee.object.name;
|
|
141
|
+
const propertyName = callExpression.callee.property.name;
|
|
142
|
+
if (trackedFunctions.has(objectName) &&
|
|
143
|
+
isTranslationFunction(propertyName)) {
|
|
144
|
+
// This variable now holds a translation function (from awaited promise)
|
|
145
|
+
translationVariables.add(node.id.name);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (node.init.type === 'Identifier') {
|
|
150
|
+
// Handle reassignment: const t = getTranslation;
|
|
151
|
+
const assignedFrom = node.init.name;
|
|
152
|
+
if (translationVariables.has(assignedFrom)) {
|
|
153
|
+
translationVariables.add(node.id.name);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
ImportDeclaration(node) {
|
|
160
|
+
const source = node.source.value;
|
|
161
|
+
if (!isGTModule(source))
|
|
162
|
+
return;
|
|
163
|
+
for (const specifier of node.specifiers) {
|
|
164
|
+
if (specifier.type === 'ImportSpecifier') {
|
|
165
|
+
// import { useGT, tx as serverTx } from 'gt-next'
|
|
166
|
+
const importedName = specifier.imported.name;
|
|
167
|
+
const localName = specifier.local.name;
|
|
168
|
+
trackImport(localName, importedName, source);
|
|
169
|
+
}
|
|
170
|
+
else if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
171
|
+
// import * as GT from 'gt-next'
|
|
172
|
+
const localName = specifier.local.name;
|
|
173
|
+
trackNamespaceImport(localName, source);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
VariableDeclarator(node) {
|
|
178
|
+
handleAssignment(node);
|
|
179
|
+
},
|
|
180
|
+
CallExpression(node) {
|
|
181
|
+
handleCallExpression(node);
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=no-dynamic-string.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-dynamic-string.js","sourceRoot":"","sources":["../../src/rules/no-dynamic-string.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@generaltranslation/gt-next-lint",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "ESLint plugin for General Translation Next.js integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -52,7 +52,9 @@
|
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"eslint": "^8.0.0 || ^9.0.0",
|
|
55
|
-
"gt-next": "^6.
|
|
55
|
+
"gt-next": "^6.2.0",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
57
|
+
"@typescript-eslint/parser": "^8.0.0"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
60
|
"@types/eslint": "^8.56.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"no-unwrapped-dynamic-content.d.ts","sourceRoot":"","sources":["../../src/rules/no-unwrapped-dynamic-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAkBnC,eAAO,MAAM,yBAAyB,EAAE,IAAI,CAAC,UAgL5C,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"no-unwrapped-dynamic-content.js","sourceRoot":"","sources":["../../src/rules/no-unwrapped-dynamic-content.ts"],"names":[],"mappings":"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"}
|