@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 CHANGED
@@ -1,244 +1,68 @@
1
1
  # @generaltranslation/gt-next-lint
2
2
 
3
- ESLint plugin for General Translation Next.js integration. Provides automatic linting for GT-Next translation components to catch common mistakes and ensure proper usage.
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
- The plugin works automatically with your existing `withGTConfig` setup. No additional configuration needed!
26
-
27
- ### Manual Setup
11
+ ## Configuration
28
12
 
29
- If you want to configure it manually, add the plugin to your ESLint configuration:
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
- files: ['**/*.{js,jsx,ts,tsx}'],
38
- plugins: {
39
- 'gt-next': gtNext,
40
- },
20
+ plugins: { 'gt-next': gtNext },
41
21
  rules: {
42
- 'gt-next/no-unwrapped-dynamic-content': 'warn',
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-unwrapped-dynamic-content`
101
-
102
- Detects unwrapped dynamic content in GT-Next translation components.
31
+ ### `no-dynamic-jsx`
103
32
 
104
- #### Incorrect
33
+ Wraps dynamic content in `<T>` components with variable components.
105
34
 
106
35
  ```jsx
107
- import { T } from 'gt-next';
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: Dynamic content is properly wrapped
39
+ // Correct
119
40
  <T>Hello <Var>{userName}</Var>!</T>
120
41
  ```
121
42
 
122
- #### Supported Patterns
43
+ ### `no-dynamic-string`
123
44
 
124
- The rule understands various import and usage patterns:
45
+ Only allows string literals in translation functions.
125
46
 
126
- **Named Imports**
127
47
  ```jsx
128
- import { T, Var, DateTime, Num, Currency } from 'gt-next';
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
- **Namespace Imports**
139
- ```jsx
140
- import * as GT from 'gt-next';
50
+ // ❌ Wrong
51
+ t(`Hello ${name}`)
52
+ t('Hello ' + name)
141
53
 
142
- <GT.T>Hello <GT.Var>{userName}</GT.Var>!</GT.T>
54
+ // ✅ Correct
55
+ t('Hello, {name}!', { name })
143
56
  ```
144
57
 
145
- **Variable Assignments**
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
- FSL-1.1-ALv2 - see [LICENSE](../../LICENSE) for details.
60
+ - `<Var>` - Variables
61
+ - `<DateTime>` - Dates
62
+ - `<Num>` - Numbers
63
+ - `<Currency>` - Currency
239
64
 
240
- ## Support
65
+ ## Supported Functions
241
66
 
242
- - 📖 [Documentation](https://generaltranslation.com/docs)
243
- - 🐛 [Issues](https://github.com/generaltranslation/gt/issues)
244
- - 💬 [Discussions](https://github.com/generaltranslation/gt/discussions)
67
+ - `useGT()` - Client translations
68
+ - `getGT()` - Server translations
@@ -4,7 +4,8 @@
4
4
  export declare const recommended: {
5
5
  plugins: string[];
6
6
  rules: {
7
- 'gt-next/no-unwrapped-dynamic-content': string;
7
+ 'gt-next/no-dynamic-jsx': boolean;
8
+ 'gt-next/no-dynamic-string': boolean;
8
9
  };
9
10
  settings: {
10
11
  react: {
@@ -1 +1 @@
1
- {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;CAUvB,CAAC"}
1
+ {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;CAWvB,CAAC"}
@@ -7,7 +7,8 @@ exports.recommended = void 0;
7
7
  exports.recommended = {
8
8
  plugins: ['gt-next'],
9
9
  rules: {
10
- 'gt-next/no-unwrapped-dynamic-content': 'warn',
10
+ 'gt-next/no-dynamic-jsx': true,
11
+ 'gt-next/no-dynamic-string': true,
11
12
  },
12
13
  settings: {
13
14
  react: {
@@ -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,sCAAsC,EAAE,MAAM;KAC/C;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ;SAClB;KACF;CACF,CAAC"}
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-unwrapped-dynamic-content': import("eslint").Rule.RuleModule;
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-unwrapped-dynamic-content': string;
21
+ 'gt-next/no-dynamic-jsx': boolean;
22
+ 'gt-next/no-dynamic-string': boolean;
21
23
  };
22
24
  settings: {
23
25
  react: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;CAWX,CAAC;AAEF,SAAS,MAAM,CAAC"}
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 no_unwrapped_dynamic_content_1 = require("./rules/no-unwrapped-dynamic-content");
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-unwrapped-dynamic-content': no_unwrapped_dynamic_content_1.noUnwrappedDynamicContent,
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,uFAAiF;AACjF,uDAAoD;AAEpD,MAAM,MAAM,GAAG;IACb,IAAI,EAAE;QACJ,IAAI,EAAE,kCAAkC;QACxC,OAAO,EAAE,OAAO;KACjB;IACD,KAAK,EAAE;QACL,8BAA8B,EAAE,wDAAyB;KAC1D;IACD,OAAO,EAAE;QACP,WAAW,EAAX,yBAAW;KACZ;CACF,CAAC;AAEF,iBAAS,MAAM,CAAC"}
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-unwrapped-dynamic-content
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 noUnwrappedDynamicContent: Rule.RuleModule;
12
- //# sourceMappingURL=no-unwrapped-dynamic-content.d.ts.map
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-unwrapped-dynamic-content
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.noUnwrappedDynamicContent = void 0;
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.noUnwrappedDynamicContent = {
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-unwrapped-dynamic-content',
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
- unwrappedDynamicContent: 'Dynamic content in <T> component should be wrapped in a variable component (<Var>, <DateTime>, <Num>, or <Currency>)',
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: 'unwrappedDynamicContent',
202
+ messageId: 'dynamicJsx',
171
203
  });
172
204
  }
173
205
  },
174
206
  };
175
207
  },
176
208
  };
177
- //# sourceMappingURL=no-unwrapped-dynamic-content.js.map
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": "0.0.0",
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.0.0"
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":";AAAA;;;;;;;;GAQG;;;AAIH,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;AACnE,MAAM,sBAAsB,GAAG,CAAC,GAAG,CAAC,CAAC;AACrC,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;AAEnE,SAAS,UAAU,CAAC,MAAc;IAChC,OAAO,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY;IAC1C,OAAO,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAEY,QAAA,yBAAyB,GAAoB;IACxD,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,oEAAoE;YACtE,QAAQ,EAAE,gBAAgB;YAC1B,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,oGAAoG;SAC1G;QACD,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,QAAQ,EAAE;wBACR,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;wBACvB,OAAO,EAAE,MAAM;qBAChB;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,uBAAuB,EACrB,sHAAsH;SACzH;KACF;IAED,MAAM,CAAC,OAAO;QACZ,MAAM,KAAK,GAAG;YACZ,gBAAgB,EAAE,CAAC;YACnB,aAAa,EAAE,CAAC;YAChB,OAAO,EAAE;gBACP,qBAAqB,EAAE,IAAI,GAAG,EAAU;gBACxC,kBAAkB,EAAE,IAAI,GAAG,EAAU;gBACrC,gBAAgB,EAAE,IAAI,GAAG,EAAU;gBACnC,6BAA6B,EAAE,IAAI,GAAG,EAAU;gBAChD,0BAA0B,EAAE,IAAI,GAAG,EAAU;aAC9C;SACF,CAAC;QAEF,SAAS,cAAc,CAAC,IAAS;YAC/B,MAAM,IAAI,GAAG,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC;YACxC,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC;YAEvB,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC,IAAI,CAAC;YACnB,CAAC;YAED,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAC3B,IAAI,GAAG,EAAE,IAAI,KAAK,eAAe,IAAI,IAAI,EAAE,IAAI,KAAK,eAAe,EAAE,CAAC;oBACpE,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAED,SAAS,+BAA+B,CAAC,WAAmB;YAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;gBACrC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC;oBAC7C,sBAAsB,CAAC,SAAS,CAAC,CAClC,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,4BAA4B,CAAC,WAAmB;YACvD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;gBACrC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC;oBAC7C,mBAAmB,CAAC,SAAS,CAAC,CAC/B,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO;YACL,qCAAqC;YACrC,iBAAiB,CAAC,IAAS;gBACzB,IACE,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS;oBAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,EACrC,CAAC;oBACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;oBAEjC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;wBACvB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;4BAC9C,IAAI,SAAS,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gCACzC,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;gCACpD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;gCAE9C,IAAI,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC;oCACzC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gCACrD,CAAC;qCAAM,IAAI,mBAAmB,CAAC,YAAY,CAAC,EAAE,CAAC;oCAC7C,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gCAClD,CAAC;4BACH,CAAC;iCAAM,IAAI,SAAS,CAAC,IAAI,KAAK,0BAA0B,EAAE,CAAC;gCACzD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;gCAC9C,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;4BAChD,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,gDAAgD;YAChD,kBAAkB,CAAC,IAAS;gBAC1B,IACE,IAAI,CAAC,EAAE,EAAE,IAAI,KAAK,YAAY;oBAC9B,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,YAAY,EAChC,CAAC;oBACD,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;oBAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;oBAEpC,IAAI,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC1D,KAAK,CAAC,OAAO,CAAC,6BAA6B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAC3D,CAAC;yBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC9D,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACxD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,sBAAsB,CAAC,IAAS;gBAC9B,iGAAiG;gBACjG,IAAI,sBAAsB,GAAG,KAAK,CAAC;gBACnC,IAAI,mBAAmB,GAAG,KAAK,CAAC;gBAEhC,8CAA8C;gBAC9C,IAAI,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC9B,OAAO,WAAW,EAAE,CAAC;oBACnB,IAAI,WAAW,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;wBACtC,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;wBAChD,IAAI,WAAW,EAAE,CAAC;4BAChB,wCAAwC;4BACxC,IACE,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC;gCACjD,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,GAAG,CAAC,WAAW,CAAC;gCACzD,4BAA4B,CAAC,WAAW,CAAC,EACzC,CAAC;gCACD,mBAAmB,GAAG,IAAI,CAAC;gCAC3B,MAAM,CAAC,kEAAkE;4BAC3E,CAAC;4BACD,2CAA2C;iCACtC,IACH,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC;gCACpD,KAAK,CAAC,OAAO,CAAC,6BAA6B,CAAC,GAAG,CAAC,WAAW,CAAC;gCAC5D,+BAA+B,CAAC,WAAW,CAAC,EAC5C,CAAC;gCACD,sBAAsB,GAAG,IAAI,CAAC;4BAChC,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;gBACnC,CAAC;gBAED,qFAAqF;gBACrF,IAAI,sBAAsB,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBACnD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,yBAAyB;qBACrC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}