@nkzw/eslint-plugin-fbtee 0.1.3 → 0.2.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 +14 -4
- package/docs/rules/no-unhelpful-desc.md +1 -1
- package/docs/rules/no-unwrapped-strings.md +55 -0
- package/lib/index.cjs +194 -39
- package/lib/index.d.cts +10 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +191 -36
- package/package.json +3 -3
- package/src/__tests__/no-empty-strings-test.tsx +93 -3
- package/src/__tests__/no-unhelpful-desc-test.tsx +20 -0
- package/src/__tests__/no-untranslated-strings-test.tsx +279 -0
- package/src/index.tsx +9 -0
- package/src/rules/no-empty-strings.tsx +37 -41
- package/src/rules/no-unhelpful-desc.tsx +3 -6
- package/src/rules/no-untranslated-strings.tsx +141 -0
- package/src/utils.tsx +64 -2
package/README.md
CHANGED
|
@@ -18,13 +18,13 @@ This is a fork of Facebook's original `fbt` library, which has been archived. Th
|
|
|
18
18
|
**fbtee** requires at least Node 22, and React 19 if you are using React.
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npm install fbtee @nkzw/babel-fbtee
|
|
21
|
+
npm install fbtee @nkzw/babel-preset-fbtee
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
In your `vite.config.ts`:
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
|
-
import fbteePreset from '@nkzw/babel-fbtee';
|
|
27
|
+
import fbteePreset from '@nkzw/babel-preset-fbtee';
|
|
28
28
|
import react from '@vitejs/plugin-react';
|
|
29
29
|
|
|
30
30
|
export default {
|
|
@@ -136,7 +136,7 @@ const Greeting = ({ name }) => (
|
|
|
136
136
|
);
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
_Note: `<fbt>` is auto-imported for you by the `@nkzw/babel-fbtee` plugin._
|
|
139
|
+
_Note: `<fbt>` is auto-imported for you by the `@nkzw/babel-preset-fbtee` plugin._
|
|
140
140
|
|
|
141
141
|
After marking your strings for translation with `<fbt>`, run the following commands to extract, and compile translations:
|
|
142
142
|
|
|
@@ -162,6 +162,15 @@ npm install @nkzw/eslint-plugin-fbtee
|
|
|
162
162
|
|
|
163
163
|
Add the following configuration to your ESLint configuration:
|
|
164
164
|
|
|
165
|
+
```js
|
|
166
|
+
{
|
|
167
|
+
extends: ['plugin:@nkzw/eslint-plugin-fbtee/recommended'],
|
|
168
|
+
plugins: ['@nkzw/eslint-plugin-fbtee'],
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
If you want stricter enforcement of translation rules, you can use the strict configuration, which enables the `no-untranslated-strings` rule. This ensures that all strings in your codebase are marked for translation.
|
|
173
|
+
|
|
165
174
|
```js
|
|
166
175
|
{
|
|
167
176
|
extends: ['plugin:@nkzw/eslint-plugin-fbtee/strict'],
|
|
@@ -177,6 +186,7 @@ Or, if you'd like more granular control over the rules:
|
|
|
177
186
|
rules: {
|
|
178
187
|
'@nkzw/fbtee/no-empty-strings': 'error',
|
|
179
188
|
'@nkzw/fbtee/no-unhelpful-desc': 'error',
|
|
189
|
+
'@nkzw/fbtee/no-untranslated-strings': 'error',
|
|
180
190
|
},
|
|
181
191
|
}
|
|
182
192
|
```
|
|
@@ -190,7 +200,7 @@ The open-source version of `fbt`, however, became unmaintained, difficult to set
|
|
|
190
200
|
- **Easier Setup:** fbtee works with modern tools like Vite.
|
|
191
201
|
- **Statically Typed:** The fbtee compiler ensures correct usage of fbtee, libary TypeScript types are provided, and an eslint plugin helps fix common mistakes.
|
|
192
202
|
- **Improved React Compatibility:** Removed React-specific hacks and added support for implicit React fragments (`<>`).
|
|
193
|
-
- **Enhanced Features:** Fixed and exported `
|
|
203
|
+
- **Enhanced Features:** Fixed and exported `inltList` as a new `<fbt:list>` construt, which was not functional in the original `fbt`.
|
|
194
204
|
- **Modernized Codebase:** Rewritten using TypeScript, ES modules (ESM), eslint, and modern JavaScript standards. Removed cruft and legacy code.
|
|
195
205
|
- **Updated Tooling:** Uses modern tools like pnpm, Vite, and esbuild for faster and more efficient development of **fbtee**.
|
|
196
206
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Rule Details
|
|
4
4
|
|
|
5
|
-
This rule enforces that meaningful and non-empty descriptions are provided to
|
|
5
|
+
This rule enforces that meaningful and non-empty descriptions are provided to `<fbt>` elements and fbt()/fbs() function calls. Descriptions (desc) are crucial for ensuring proper translation context and avoiding ambiguous or unhelpful translations.
|
|
6
6
|
|
|
7
7
|
Examples of **incorrect** code for this rule:
|
|
8
8
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Enforce strings to be wrapped with `<fbt>` (fbtee/no-untranslated-strings)
|
|
2
|
+
|
|
3
|
+
## Rule Details
|
|
4
|
+
|
|
5
|
+
This rule enforces that all literal strings in your JSX are wrapped with an `<fbt>` tag, or translated using `fbt()`/`fbs()` functions, ensuring they are properly marked for translation.
|
|
6
|
+
|
|
7
|
+
Examples of **incorrect** code for this rule:
|
|
8
|
+
|
|
9
|
+
```jsx
|
|
10
|
+
<h1>Hello</h1>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<h1>{`Hello`}</h1>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
<span title="Hello" />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Examples of **correct** code for this rule:
|
|
22
|
+
|
|
23
|
+
```jsx
|
|
24
|
+
<h1>
|
|
25
|
+
<fbt desc="Greeting">Hello</fbt>
|
|
26
|
+
</h1>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
<h1>{fbt('Hello', 'Greeting')}</h1>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
<span title={fbs('Hello', 'Greeting')} />
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Rule Options
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
...
|
|
41
|
+
"fbt/no-untranslated-strings": [<enabled>, {"ignoredWords": Array<string>}]
|
|
42
|
+
...
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `ignoredWords`
|
|
46
|
+
|
|
47
|
+
A list of words that are not required to be translated. Like so:
|
|
48
|
+
|
|
49
|
+
```jsx
|
|
50
|
+
"fbt/no-untranslated-strings": ["warn", { "ignoredWords": ["GitHub"] }]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## When Not To Use It
|
|
54
|
+
|
|
55
|
+
If you do not want to enforce all strings to be marked for translation, then you can disable this rule.
|
package/lib/index.cjs
CHANGED
|
@@ -18,18 +18,18 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.tsx
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
23
|
configs: () => configs,
|
|
24
24
|
meta: () => meta,
|
|
25
25
|
rules: () => rules
|
|
26
26
|
});
|
|
27
|
-
module.exports = __toCommonJS(
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
28
|
|
|
29
29
|
// package.json
|
|
30
30
|
var package_default = {
|
|
31
31
|
name: "@nkzw/eslint-plugin-fbtee",
|
|
32
|
-
version: "0.
|
|
32
|
+
version: "0.2.0",
|
|
33
33
|
description: "",
|
|
34
34
|
keywords: [],
|
|
35
35
|
repository: {
|
|
@@ -47,17 +47,17 @@ var package_default = {
|
|
|
47
47
|
build: "tsup src/index.tsx -d lib --target=node22 --format=esm,cjs --clean --no-splitting --dts"
|
|
48
48
|
},
|
|
49
49
|
dependencies: {
|
|
50
|
-
"@typescript-eslint/utils": "^8.18.
|
|
50
|
+
"@typescript-eslint/utils": "^8.18.2"
|
|
51
51
|
},
|
|
52
52
|
devDependencies: {
|
|
53
|
-
"@typescript-eslint/rule-tester": "^8.18.
|
|
53
|
+
"@typescript-eslint/rule-tester": "^8.18.2"
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
// src/utils.tsx
|
|
58
58
|
var import_utils = require("@typescript-eslint/utils");
|
|
59
59
|
var createRule = import_utils.ESLintUtils.RuleCreator(
|
|
60
|
-
(name) => `https://github.com/nkzw-tech/fbtee/
|
|
60
|
+
(name) => `https://github.com/nkzw-tech/fbtee/blob/main/packages/eslint-plugin-fbtee/docs/rules/${name}.md`
|
|
61
61
|
);
|
|
62
62
|
function resolveMemberExpressions(object, property) {
|
|
63
63
|
if (object.type === "JSXMemberExpression") {
|
|
@@ -121,15 +121,59 @@ function resolveNodeValue(node) {
|
|
|
121
121
|
if (node.type === "JSXExpressionContainer") {
|
|
122
122
|
return resolveNodeValue(node.expression);
|
|
123
123
|
}
|
|
124
|
+
if (node.type === "ConditionalExpression") {
|
|
125
|
+
const consequent = resolveNodeValue(node.consequent);
|
|
126
|
+
const alternate = resolveNodeValue(node.alternate);
|
|
127
|
+
return consequent || alternate || null;
|
|
128
|
+
}
|
|
129
|
+
if (node.type === "LogicalExpression") {
|
|
130
|
+
const left = resolveNodeValue(node.left);
|
|
131
|
+
const right = resolveNodeValue(node.right);
|
|
132
|
+
return left || right || null;
|
|
133
|
+
}
|
|
124
134
|
return null;
|
|
125
135
|
}
|
|
136
|
+
function getPropName(prop) {
|
|
137
|
+
if (prop.name.type === "JSXNamespacedName") {
|
|
138
|
+
return `${prop.name.namespace.name}:${prop.name.name.name}`;
|
|
139
|
+
}
|
|
140
|
+
return prop.name.name;
|
|
141
|
+
}
|
|
142
|
+
function hasFbtParent(node) {
|
|
143
|
+
let current = node.parent;
|
|
144
|
+
while (current) {
|
|
145
|
+
if (isFbtNode(current)) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
current = current.parent;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
function isFbtNode(node) {
|
|
153
|
+
if (!node) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
if (node.type === "JSXElement") {
|
|
157
|
+
const name = elementType(node);
|
|
158
|
+
return name === "fbt" || name === "fbs" || name?.startsWith("fbt:");
|
|
159
|
+
}
|
|
160
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
161
|
+
const name = node.callee.name;
|
|
162
|
+
return name === "fbt" || name === "fbs";
|
|
163
|
+
}
|
|
164
|
+
if (node.type === "MemberExpression" && node.object.type === "CallExpression" && node.object.callee.type === "Identifier") {
|
|
165
|
+
const name = node.object.callee.name;
|
|
166
|
+
return name === "fbt" || name === "fbs";
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
126
170
|
|
|
127
171
|
// src/rules/no-empty-strings.tsx
|
|
128
172
|
var no_empty_strings_default = createRule({
|
|
129
173
|
create(context) {
|
|
130
174
|
return {
|
|
131
175
|
CallExpression(node) {
|
|
132
|
-
if (
|
|
176
|
+
if (!isFbtNode(node)) {
|
|
133
177
|
return;
|
|
134
178
|
}
|
|
135
179
|
const [text] = node.arguments;
|
|
@@ -141,18 +185,18 @@ var no_empty_strings_default = createRule({
|
|
|
141
185
|
}
|
|
142
186
|
},
|
|
143
187
|
JSXElement(node) {
|
|
144
|
-
if (
|
|
188
|
+
if (!isFbtNode(node)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (node.openingElement.name.type === "JSXNamespacedName") {
|
|
145
192
|
return;
|
|
146
193
|
}
|
|
147
|
-
const
|
|
148
|
-
const hasTextContent = validateChildren(node, nodesToReport);
|
|
194
|
+
const hasTextContent = validateChildren(node);
|
|
149
195
|
if (!hasTextContent) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
155
|
-
}
|
|
196
|
+
context.report({
|
|
197
|
+
messageId: "jsxEmptyString",
|
|
198
|
+
node
|
|
199
|
+
});
|
|
156
200
|
}
|
|
157
201
|
}
|
|
158
202
|
};
|
|
@@ -163,30 +207,30 @@ var no_empty_strings_default = createRule({
|
|
|
163
207
|
description: "Disallow empty strings in fbt elements or function calls."
|
|
164
208
|
},
|
|
165
209
|
messages: {
|
|
166
|
-
emptyString: "Empty strings are not allowed in fbt()
|
|
167
|
-
jsxEmptyString: "Empty strings are not allowed as children of
|
|
210
|
+
emptyString: "Empty strings are not allowed in fbt() and fbs() function arguments.",
|
|
211
|
+
jsxEmptyString: "Empty strings are not allowed as children of `<fbt>` and `<fbs>` tags."
|
|
168
212
|
},
|
|
169
213
|
schema: [],
|
|
170
214
|
type: "problem"
|
|
171
215
|
},
|
|
172
216
|
name: "no-empty-strings"
|
|
173
217
|
});
|
|
174
|
-
function validateChildren(node
|
|
218
|
+
function validateChildren(node) {
|
|
175
219
|
let hasTextContent = false;
|
|
176
220
|
for (const child of node.children) {
|
|
177
|
-
if (child.type === "JSXText" &&
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
221
|
+
if (child.type === "JSXText" && child.value.trim() !== "") {
|
|
222
|
+
hasTextContent = true;
|
|
223
|
+
}
|
|
224
|
+
if (child.type === "JSXExpressionContainer") {
|
|
225
|
+
if (child.expression.type === "JSXEmptyExpression") {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (child.expression.type === "Identifier" && child.expression.name !== "undefined") {
|
|
181
229
|
hasTextContent = true;
|
|
230
|
+
continue;
|
|
182
231
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (isEmptyString(child.expression) && (node.children.length === 1 || node.children.every(
|
|
186
|
-
(otherChild) => child === otherChild || otherChild.type === "JSXText" && otherChild.value.trim() === ""
|
|
187
|
-
))) {
|
|
188
|
-
nodesToReport.add(child.expression);
|
|
189
|
-
} else {
|
|
232
|
+
const value = resolveNodeValue(child.expression)?.trim();
|
|
233
|
+
if (value) {
|
|
190
234
|
hasTextContent = true;
|
|
191
235
|
}
|
|
192
236
|
}
|
|
@@ -196,15 +240,12 @@ function validateChildren(node, nodesToReport) {
|
|
|
196
240
|
hasTextContent = true;
|
|
197
241
|
continue;
|
|
198
242
|
}
|
|
199
|
-
hasTextContent ||= validateChildren(child
|
|
243
|
+
hasTextContent ||= validateChildren(child);
|
|
200
244
|
}
|
|
201
245
|
if (hasTextContent) {
|
|
202
246
|
break;
|
|
203
247
|
}
|
|
204
248
|
}
|
|
205
|
-
if (!hasTextContent && nodesToReport.size === 0) {
|
|
206
|
-
nodesToReport.add(node);
|
|
207
|
-
}
|
|
208
249
|
return hasTextContent;
|
|
209
250
|
}
|
|
210
251
|
function isEmptyString(node) {
|
|
@@ -216,7 +257,7 @@ var no_unhelpful_desc_default = createRule({
|
|
|
216
257
|
create(context) {
|
|
217
258
|
return {
|
|
218
259
|
CallExpression(node) {
|
|
219
|
-
if (
|
|
260
|
+
if (!isFbtNode(node)) {
|
|
220
261
|
return;
|
|
221
262
|
}
|
|
222
263
|
const [textArg, descArg] = node.arguments;
|
|
@@ -244,7 +285,7 @@ var no_unhelpful_desc_default = createRule({
|
|
|
244
285
|
}
|
|
245
286
|
},
|
|
246
287
|
JSXAttribute(node) {
|
|
247
|
-
if (
|
|
288
|
+
if (!isFbtNode(node.parent.parent)) {
|
|
248
289
|
return;
|
|
249
290
|
}
|
|
250
291
|
if (node.name.name !== "desc" || !node.value) {
|
|
@@ -295,6 +336,112 @@ var no_unhelpful_desc_default = createRule({
|
|
|
295
336
|
name: "no-unhelpful-desc"
|
|
296
337
|
});
|
|
297
338
|
|
|
339
|
+
// src/rules/no-untranslated-strings.tsx
|
|
340
|
+
var attributes = /* @__PURE__ */ new Set([
|
|
341
|
+
"title",
|
|
342
|
+
"placeholder",
|
|
343
|
+
"alt",
|
|
344
|
+
"label",
|
|
345
|
+
"aria-label",
|
|
346
|
+
"aria-errormessage"
|
|
347
|
+
]);
|
|
348
|
+
var no_untranslated_strings_default = createRule({
|
|
349
|
+
create(context, options) {
|
|
350
|
+
const ignoredWords = new Set(
|
|
351
|
+
options[0].ignoredWords.map((s) => s.trim().toLowerCase())
|
|
352
|
+
);
|
|
353
|
+
function isIgnoredWord(value) {
|
|
354
|
+
return ignoredWords.has(value.trim().toLowerCase());
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
JSXAttribute(node) {
|
|
358
|
+
const propName = getPropName(node);
|
|
359
|
+
if (!attributes.has(propName)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const value = node.value ? resolveNodeValue(node.value) : null;
|
|
363
|
+
if (!value) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (isIgnoredWord(value)) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (node.value?.type === "JSXExpressionContainer" && isFbtNode(node.value.expression)) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
context.report({
|
|
373
|
+
messageId: "unwrappedString",
|
|
374
|
+
node
|
|
375
|
+
});
|
|
376
|
+
},
|
|
377
|
+
JSXExpressionContainer(node) {
|
|
378
|
+
if (node.parent.type === "JSXAttribute") {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const value = resolveNodeValue(node.expression);
|
|
382
|
+
if (!value) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (isIgnoredWord(value)) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (!hasFbtParent(node)) {
|
|
389
|
+
context.report({
|
|
390
|
+
messageId: "unwrappedString",
|
|
391
|
+
node
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
JSXText(node) {
|
|
396
|
+
const value = node.value.trim();
|
|
397
|
+
if (!value) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (isIgnoredWord(value)) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (!hasFbtParent(node)) {
|
|
404
|
+
const startOffset = node.range[0] + node.value.indexOf(value);
|
|
405
|
+
const endOffset = startOffset + value.length;
|
|
406
|
+
context.report({
|
|
407
|
+
loc: {
|
|
408
|
+
end: context.sourceCode.getLocFromIndex(endOffset),
|
|
409
|
+
start: context.sourceCode.getLocFromIndex(startOffset)
|
|
410
|
+
},
|
|
411
|
+
messageId: "unwrappedString"
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
},
|
|
417
|
+
defaultOptions: [{ ignoredWords: [] }],
|
|
418
|
+
meta: {
|
|
419
|
+
docs: {
|
|
420
|
+
description: "Enforce text content to be wrapped with `<fbt>`, `fbt()` or `fbs()`"
|
|
421
|
+
},
|
|
422
|
+
messages: {
|
|
423
|
+
unwrappedString: "Text content must be wrapped in `<fbt>`, `fbt()` or `fbs()`"
|
|
424
|
+
},
|
|
425
|
+
schema: [
|
|
426
|
+
{
|
|
427
|
+
additionalProperties: false,
|
|
428
|
+
properties: {
|
|
429
|
+
ignoredWords: {
|
|
430
|
+
items: {
|
|
431
|
+
type: "string"
|
|
432
|
+
},
|
|
433
|
+
type: "array",
|
|
434
|
+
uniqueItems: true
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
type: "object"
|
|
438
|
+
}
|
|
439
|
+
],
|
|
440
|
+
type: "problem"
|
|
441
|
+
},
|
|
442
|
+
name: "no-untranslated-strings"
|
|
443
|
+
});
|
|
444
|
+
|
|
298
445
|
// src/index.tsx
|
|
299
446
|
var meta = {
|
|
300
447
|
name: package_default.name,
|
|
@@ -302,14 +449,22 @@ var meta = {
|
|
|
302
449
|
};
|
|
303
450
|
var rules = {
|
|
304
451
|
"no-empty-strings": no_empty_strings_default,
|
|
305
|
-
"no-unhelpful-desc": no_unhelpful_desc_default
|
|
452
|
+
"no-unhelpful-desc": no_unhelpful_desc_default,
|
|
453
|
+
"no-untranslated-strings": no_untranslated_strings_default
|
|
306
454
|
};
|
|
307
455
|
var configs = {
|
|
308
|
-
|
|
456
|
+
recommended: {
|
|
309
457
|
rules: {
|
|
310
458
|
"@nkzw/fbtee/no-empty-strings": 2,
|
|
311
459
|
"@nkzw/fbtee/no-unhelpful-desc": 2
|
|
312
460
|
}
|
|
461
|
+
},
|
|
462
|
+
strict: {
|
|
463
|
+
rules: {
|
|
464
|
+
"@nkzw/fbtee/no-empty-strings": 2,
|
|
465
|
+
"@nkzw/fbtee/no-unhelpful-desc": 2,
|
|
466
|
+
"@nkzw/fbtee/no-untranslated-strings": 2
|
|
467
|
+
}
|
|
313
468
|
}
|
|
314
469
|
};
|
|
315
470
|
// Annotate the CommonJS export names for ESM import in node:
|
package/lib/index.d.cts
CHANGED
|
@@ -7,12 +7,22 @@ declare const meta: {
|
|
|
7
7
|
declare const rules: {
|
|
8
8
|
'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
9
9
|
'no-unhelpful-desc': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyDesc" | "jsxEmptyDesc" | "duplicateDesc" | "shortDesc", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
10
|
+
'no-untranslated-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"unwrappedString", [{
|
|
11
|
+
ignoredWords: Array<string>;
|
|
12
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
10
13
|
};
|
|
11
14
|
declare const configs: {
|
|
15
|
+
recommended: {
|
|
16
|
+
rules: {
|
|
17
|
+
'@nkzw/fbtee/no-empty-strings': number;
|
|
18
|
+
'@nkzw/fbtee/no-unhelpful-desc': number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
12
21
|
strict: {
|
|
13
22
|
rules: {
|
|
14
23
|
'@nkzw/fbtee/no-empty-strings': number;
|
|
15
24
|
'@nkzw/fbtee/no-unhelpful-desc': number;
|
|
25
|
+
'@nkzw/fbtee/no-untranslated-strings': number;
|
|
16
26
|
};
|
|
17
27
|
};
|
|
18
28
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -7,12 +7,22 @@ declare const meta: {
|
|
|
7
7
|
declare const rules: {
|
|
8
8
|
'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
9
9
|
'no-unhelpful-desc': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyDesc" | "jsxEmptyDesc" | "duplicateDesc" | "shortDesc", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
10
|
+
'no-untranslated-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"unwrappedString", [{
|
|
11
|
+
ignoredWords: Array<string>;
|
|
12
|
+
}], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
|
|
10
13
|
};
|
|
11
14
|
declare const configs: {
|
|
15
|
+
recommended: {
|
|
16
|
+
rules: {
|
|
17
|
+
'@nkzw/fbtee/no-empty-strings': number;
|
|
18
|
+
'@nkzw/fbtee/no-unhelpful-desc': number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
12
21
|
strict: {
|
|
13
22
|
rules: {
|
|
14
23
|
'@nkzw/fbtee/no-empty-strings': number;
|
|
15
24
|
'@nkzw/fbtee/no-unhelpful-desc': number;
|
|
25
|
+
'@nkzw/fbtee/no-untranslated-strings': number;
|
|
16
26
|
};
|
|
17
27
|
};
|
|
18
28
|
};
|