@nkzw/eslint-plugin-fbtee 0.2.0 → 0.2.1

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
@@ -18,7 +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-preset-fbtee
21
+ npm install fbtee
22
+ ```
23
+
24
+ In addition to `fbtee`, you need to install the Babel preset and React plugin for Vite:
25
+
26
+ ```bash
27
+ npm install -D @nkzw/babel-preset-fbtee @vitejs/plugin-react
22
28
  ```
23
29
 
24
30
  In your `vite.config.ts`:
@@ -43,20 +49,26 @@ export default {
43
49
  ```json
44
50
  {
45
51
  "scripts": {
46
- "fbtee:collect": "fbtee collect --manifest < .src_manifest.json > .source_strings.json",
47
52
  "fbtee:manifest": "fbtee manifest --src src",
53
+ "fbtee:collect": "fbtee collect --manifest < .src_manifest.json > .source_strings.json",
48
54
  "fbtee:translate": "fbtee translate --translations translations/*.json --jenkins > src/translations.json"
49
55
  }
50
56
  }
51
57
  ```
52
58
 
53
- Run these commands to set up the initial translation files:
59
+ Here is what each command does:
60
+
61
+ - `fbtee manifest --src src` searches through files in the `src` directory and generates a manifest file (`.src_manifest.json`) that lists all the files translatable strings marked with `<fbt>`. In addition it creates `.enum_manifest.json` which lists all the files containing `<fbt:enum>` tags. Since these files are auto-generated, we recommend adding them to your `.gitignore`.
62
+ - `fbtee collect --manifest < .src_manifest.json > .source_strings.json` reads the manifest file and extracts all the strings marked for translation into a `.source_strings.json` file. This file should be uploaded to your translation provider as the source for your translations.
63
+ - `fbtee translate --translations translations/*.json --jenkins > src/translations.json` reads all the translations in the `translations/` directory and compiles them into a single `src/translations.json` file. This file is used by **fbtee** to display translated content in your app. The `--translations` parameter specifies the path to the translation files. The `--jenkins` flag is used to define the utilized [hash function](https://en.wikipedia.org/wiki/Jenkins_hash_function). You can adjust the `--translations` parameter to point to your translation directory. If your translations are within your app directory in a folder called `i18n`, for example, you'd use `--translations app/i18n/*.json`. The output is the translation file used by **fbtee**. This file is going to be referred to in your applications entry point, therefor it needs to be generated as part of the build, but should not be part of version control. This command requires the translations to be present in the `translations/` directory, created based on real translations of what was previously collected using the `collect` command.
64
+
65
+ Now, the first step is to run these commands to set up the initial strings for translation:
54
66
 
55
67
  ```bash
56
- npm run fbtee:manifest && npm run fbtee:collect && npm run fbtee:translate
68
+ npm run fbtee:manifest && npm run fbtee:collect
57
69
  ```
58
70
 
59
- The files generated by these commands are auto-generated and should not be checked into version control. Add the following entries to your `.gitignore`:
71
+ The files generated by these commands should be added to `.gitignore`:
60
72
 
61
73
  ```
62
74
  .src_manifest.json
@@ -82,13 +94,13 @@ setupFbtee({
82
94
  });
83
95
  ```
84
96
 
85
- Finally, if you are using React and TypeScript in your project, you need to add TypeScript types for **fbtee** to enable proper type checking in JSX. You can do this by referencing the `ReactTypes.d.ts` file in your main `index.tsx` file or a global type declaration file (e.g., `types.d.ts`):
97
+ Next up, if you are using React and TypeScript in your project, you need to add TypeScript types for **fbtee** to enable proper type checking in JSX. You can do this by referencing the `ReactTypes.d.ts` file in your main `index.tsx` file or a global type declaration file (e.g., `types.d.ts`):
86
98
 
87
99
  ```tsx
88
100
  /// <reference types="fbtee/ReactTypes.d.ts" />
89
101
  ```
90
102
 
91
- _You’re now ready to go!_
103
+ _You’re now ready to define your first translatable element!_
92
104
 
93
105
  ## Usage
94
106
 
@@ -141,16 +153,102 @@ _Note: `<fbt>` is auto-imported for you by the `@nkzw/babel-preset-fbtee` plugin
141
153
  After marking your strings for translation with `<fbt>`, run the following commands to extract, and compile translations:
142
154
 
143
155
  ```bash
144
- npm run fbtee:collect
156
+ npm run fbtee:manifest && npm run fbtee:collect
157
+ ```
158
+
159
+ You can now upload the `.source_strings.json` file to your translation provider. One sample for such a translation provider is [Crowdin](https://crowdin.com/).
160
+
161
+ ### Generated File Structure
162
+
163
+ Your `.source_strings.json` might look like this:
164
+
165
+ ```json
166
+ {
167
+ "childParentMappings": {},
168
+ "phrases": [
169
+ {
170
+ "hashToLeaf": {
171
+ "MB6OYuvCF1VzjOmqinI42g==": {
172
+ "desc": "What's next question",
173
+ "text": "What's next?"
174
+ }
175
+ },
176
+ "col_beg": 12,
177
+ "col_end": 68,
178
+ "filepath": "app/welcome/welcome.tsx",
179
+ "line_beg": 43,
180
+ "line_end": 43,
181
+ "project": "",
182
+ "jsfbt": {
183
+ "m": [],
184
+ "t": {
185
+ "desc": "What's next question",
186
+ "text": "What's next?"
187
+ }
188
+ }
189
+ }
190
+ ]
191
+ }
192
+ ```
193
+
194
+ Based on the above source string, the US English translation (ie. `translations/en_US.json`) might look like this:
195
+
196
+ ```json
197
+ {
198
+ "fb-locale": "en_US",
199
+ "translations": {
200
+ "MB6OYuvCF1VzjOmqinI42g==": {
201
+ "tokens": [],
202
+ "types": [],
203
+ "translations": [
204
+ {
205
+ "translation": "What's next?",
206
+ "variations": []
207
+ }
208
+ ]
209
+ }
210
+ }
211
+ }
145
212
  ```
146
213
 
147
- You can now upload the `.source_strings.json` file to your translation provider. Once you have the translated strings stored in a `translations/` folder as JSON files, you can run the following command to generate the translations file:
214
+ And German (`translations/de_DE.json`) might look like this:
215
+
216
+ ```json
217
+ {
218
+ "fb-locale": "de_DE",
219
+ "translations": {
220
+ "MB6OYuvCF1VzjOmqinI42g==": {
221
+ "tokens": [],
222
+ "types": [],
223
+ "translations": [
224
+ {
225
+ "translation": "Was kommt jetzt?",
226
+ "variations": []
227
+ }
228
+ ]
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ Once you have the translated strings stored in a `translations/` folder as JSON files, you can run the following command to generate the translations file:
148
235
 
149
236
  ```bash
150
237
  npm run fbtee:translate
151
238
  ```
152
239
 
153
- After generating the translations file, your app is ready to display translated content in other languages.
240
+ This will generate the `translation.json` file referred to in the setup done before. This file might look like this:
241
+
242
+ ```json
243
+ {
244
+ "de_DE": { "2HVYhv": "Was kommt jetzt?" },
245
+ "en_US": { "2HVYhv": "What's next?" }
246
+ }
247
+ ```
248
+
249
+ After generating the translations file, your app is ready to display translated content in other languages. The error you had until now in the `setupFbtee` with regards to the imported translations file should be resolved now.
250
+
251
+ Since the `translations.json` is an auto-generated file part of your build process, the `fbtee:translate` command should be added to your build step.
154
252
 
155
253
  ## ESLint Plugin
156
254
 
package/lib/index.cjs CHANGED
@@ -20,16 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.tsx
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- configs: () => configs,
24
- meta: () => meta,
25
- rules: () => rules
23
+ default: () => index_default
26
24
  });
27
25
  module.exports = __toCommonJS(index_exports);
28
26
 
29
27
  // package.json
30
28
  var package_default = {
31
29
  name: "@nkzw/eslint-plugin-fbtee",
32
- version: "0.2.0",
30
+ version: "0.2.1",
33
31
  description: "",
34
32
  keywords: [],
35
33
  repository: {
@@ -43,14 +41,15 @@ var package_default = {
43
41
  import: "./lib/index.js",
44
42
  require: "./lib/index.cjs"
45
43
  },
44
+ main: "lib/index.cjs",
46
45
  scripts: {
47
46
  build: "tsup src/index.tsx -d lib --target=node22 --format=esm,cjs --clean --no-splitting --dts"
48
47
  },
49
48
  dependencies: {
50
- "@typescript-eslint/utils": "^8.18.2"
49
+ "@typescript-eslint/utils": "^8.19.1"
51
50
  },
52
51
  devDependencies: {
53
- "@typescript-eslint/rule-tester": "^8.18.2"
52
+ "@typescript-eslint/rule-tester": "^8.19.1"
54
53
  }
55
54
  };
56
55
 
@@ -443,33 +442,29 @@ var no_untranslated_strings_default = createRule({
443
442
  });
444
443
 
445
444
  // src/index.tsx
446
- var meta = {
447
- name: package_default.name,
448
- version: package_default.version
449
- };
450
- var rules = {
451
- "no-empty-strings": no_empty_strings_default,
452
- "no-unhelpful-desc": no_unhelpful_desc_default,
453
- "no-untranslated-strings": no_untranslated_strings_default
454
- };
455
- var configs = {
456
- recommended: {
457
- rules: {
458
- "@nkzw/fbtee/no-empty-strings": 2,
459
- "@nkzw/fbtee/no-unhelpful-desc": 2
445
+ var index_default = {
446
+ configs: {
447
+ recommended: {
448
+ rules: {
449
+ "@nkzw/fbtee/no-empty-strings": 2,
450
+ "@nkzw/fbtee/no-unhelpful-desc": 2
451
+ }
452
+ },
453
+ strict: {
454
+ rules: {
455
+ "@nkzw/fbtee/no-empty-strings": 2,
456
+ "@nkzw/fbtee/no-unhelpful-desc": 2,
457
+ "@nkzw/fbtee/no-untranslated-strings": 2
458
+ }
460
459
  }
461
460
  },
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
- }
461
+ meta: {
462
+ name: package_default.name,
463
+ version: package_default.version
464
+ },
465
+ rules: {
466
+ "no-empty-strings": no_empty_strings_default,
467
+ "no-unhelpful-desc": no_unhelpful_desc_default,
468
+ "no-untranslated-strings": no_untranslated_strings_default
468
469
  }
469
470
  };
470
- // Annotate the CommonJS export names for ESM import in node:
471
- 0 && (module.exports = {
472
- configs,
473
- meta,
474
- rules
475
- });
package/lib/index.d.cts CHANGED
@@ -1,30 +1,32 @@
1
1
  import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- declare const meta: {
4
- name: string;
5
- version: string;
6
- };
7
- declare const rules: {
8
- 'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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>;
13
- };
14
- declare const configs: {
15
- recommended: {
16
- rules: {
17
- '@nkzw/fbtee/no-empty-strings': number;
18
- '@nkzw/fbtee/no-unhelpful-desc': number;
3
+ declare const _default: {
4
+ configs: {
5
+ recommended: {
6
+ rules: {
7
+ '@nkzw/fbtee/no-empty-strings': number;
8
+ '@nkzw/fbtee/no-unhelpful-desc': number;
9
+ };
19
10
  };
20
- };
21
- strict: {
22
- rules: {
23
- '@nkzw/fbtee/no-empty-strings': number;
24
- '@nkzw/fbtee/no-unhelpful-desc': number;
25
- '@nkzw/fbtee/no-untranslated-strings': number;
11
+ strict: {
12
+ rules: {
13
+ '@nkzw/fbtee/no-empty-strings': number;
14
+ '@nkzw/fbtee/no-unhelpful-desc': number;
15
+ '@nkzw/fbtee/no-untranslated-strings': number;
16
+ };
26
17
  };
27
18
  };
19
+ meta: {
20
+ name: string;
21
+ version: string;
22
+ };
23
+ rules: {
24
+ 'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
+ 'no-unhelpful-desc': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyDesc" | "jsxEmptyDesc" | "duplicateDesc" | "shortDesc", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
+ 'no-untranslated-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"unwrappedString", [{
27
+ ignoredWords: Array<string>;
28
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
29
+ };
28
30
  };
29
31
 
30
- export { configs, meta, rules };
32
+ export { _default as default };
package/lib/index.d.ts CHANGED
@@ -1,30 +1,32 @@
1
1
  import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- declare const meta: {
4
- name: string;
5
- version: string;
6
- };
7
- declare const rules: {
8
- 'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
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>;
13
- };
14
- declare const configs: {
15
- recommended: {
16
- rules: {
17
- '@nkzw/fbtee/no-empty-strings': number;
18
- '@nkzw/fbtee/no-unhelpful-desc': number;
3
+ declare const _default: {
4
+ configs: {
5
+ recommended: {
6
+ rules: {
7
+ '@nkzw/fbtee/no-empty-strings': number;
8
+ '@nkzw/fbtee/no-unhelpful-desc': number;
9
+ };
19
10
  };
20
- };
21
- strict: {
22
- rules: {
23
- '@nkzw/fbtee/no-empty-strings': number;
24
- '@nkzw/fbtee/no-unhelpful-desc': number;
25
- '@nkzw/fbtee/no-untranslated-strings': number;
11
+ strict: {
12
+ rules: {
13
+ '@nkzw/fbtee/no-empty-strings': number;
14
+ '@nkzw/fbtee/no-unhelpful-desc': number;
15
+ '@nkzw/fbtee/no-untranslated-strings': number;
16
+ };
26
17
  };
27
18
  };
19
+ meta: {
20
+ name: string;
21
+ version: string;
22
+ };
23
+ rules: {
24
+ 'no-empty-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyString" | "jsxEmptyString", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
+ 'no-unhelpful-desc': _typescript_eslint_utils_ts_eslint.RuleModule<"emptyDesc" | "jsxEmptyDesc" | "duplicateDesc" | "shortDesc", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
+ 'no-untranslated-strings': _typescript_eslint_utils_ts_eslint.RuleModule<"unwrappedString", [{
27
+ ignoredWords: Array<string>;
28
+ }], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
29
+ };
28
30
  };
29
31
 
30
- export { configs, meta, rules };
32
+ export { _default as default };
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@nkzw/eslint-plugin-fbtee",
4
- version: "0.2.0",
4
+ version: "0.2.1",
5
5
  description: "",
6
6
  keywords: [],
7
7
  repository: {
@@ -15,14 +15,15 @@ var package_default = {
15
15
  import: "./lib/index.js",
16
16
  require: "./lib/index.cjs"
17
17
  },
18
+ main: "lib/index.cjs",
18
19
  scripts: {
19
20
  build: "tsup src/index.tsx -d lib --target=node22 --format=esm,cjs --clean --no-splitting --dts"
20
21
  },
21
22
  dependencies: {
22
- "@typescript-eslint/utils": "^8.18.2"
23
+ "@typescript-eslint/utils": "^8.19.1"
23
24
  },
24
25
  devDependencies: {
25
- "@typescript-eslint/rule-tester": "^8.18.2"
26
+ "@typescript-eslint/rule-tester": "^8.19.1"
26
27
  }
27
28
  };
28
29
 
@@ -415,32 +416,32 @@ var no_untranslated_strings_default = createRule({
415
416
  });
416
417
 
417
418
  // src/index.tsx
418
- var meta = {
419
- name: package_default.name,
420
- version: package_default.version
421
- };
422
- var rules = {
423
- "no-empty-strings": no_empty_strings_default,
424
- "no-unhelpful-desc": no_unhelpful_desc_default,
425
- "no-untranslated-strings": no_untranslated_strings_default
426
- };
427
- var configs = {
428
- recommended: {
429
- rules: {
430
- "@nkzw/fbtee/no-empty-strings": 2,
431
- "@nkzw/fbtee/no-unhelpful-desc": 2
419
+ var index_default = {
420
+ configs: {
421
+ recommended: {
422
+ rules: {
423
+ "@nkzw/fbtee/no-empty-strings": 2,
424
+ "@nkzw/fbtee/no-unhelpful-desc": 2
425
+ }
426
+ },
427
+ strict: {
428
+ rules: {
429
+ "@nkzw/fbtee/no-empty-strings": 2,
430
+ "@nkzw/fbtee/no-unhelpful-desc": 2,
431
+ "@nkzw/fbtee/no-untranslated-strings": 2
432
+ }
432
433
  }
433
434
  },
434
- strict: {
435
- rules: {
436
- "@nkzw/fbtee/no-empty-strings": 2,
437
- "@nkzw/fbtee/no-unhelpful-desc": 2,
438
- "@nkzw/fbtee/no-untranslated-strings": 2
439
- }
435
+ meta: {
436
+ name: package_default.name,
437
+ version: package_default.version
438
+ },
439
+ rules: {
440
+ "no-empty-strings": no_empty_strings_default,
441
+ "no-unhelpful-desc": no_unhelpful_desc_default,
442
+ "no-untranslated-strings": no_untranslated_strings_default
440
443
  }
441
444
  };
442
445
  export {
443
- configs,
444
- meta,
445
- rules
446
+ index_default as default
446
447
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nkzw/eslint-plugin-fbtee",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -14,11 +14,12 @@
14
14
  "import": "./lib/index.js",
15
15
  "require": "./lib/index.cjs"
16
16
  },
17
+ "main": "lib/index.cjs",
17
18
  "dependencies": {
18
- "@typescript-eslint/utils": "^8.18.2"
19
+ "@typescript-eslint/utils": "^8.19.1"
19
20
  },
20
21
  "devDependencies": {
21
- "@typescript-eslint/rule-tester": "^8.18.2"
22
+ "@typescript-eslint/rule-tester": "^8.19.1"
22
23
  },
23
24
  "scripts": {
24
25
  "build": "tsup src/index.tsx -d lib --target=node22 --format=esm,cjs --clean --no-splitting --dts"
package/src/index.tsx CHANGED
@@ -3,29 +3,29 @@ import noEmptyStringsRule from './rules/no-empty-strings.tsx';
3
3
  import noUnhelpfulDesc from './rules/no-unhelpful-desc.tsx';
4
4
  import noUntranslatedStrings from './rules/no-untranslated-strings.tsx';
5
5
 
6
- export const meta = {
7
- name: packageJson.name,
8
- version: packageJson.version,
9
- };
10
-
11
- export const rules = {
12
- 'no-empty-strings': noEmptyStringsRule,
13
- 'no-unhelpful-desc': noUnhelpfulDesc,
14
- 'no-untranslated-strings': noUntranslatedStrings,
15
- };
16
-
17
- export const configs = {
18
- recommended: {
19
- rules: {
20
- '@nkzw/fbtee/no-empty-strings': 2,
21
- '@nkzw/fbtee/no-unhelpful-desc': 2,
6
+ export default {
7
+ configs: {
8
+ recommended: {
9
+ rules: {
10
+ '@nkzw/fbtee/no-empty-strings': 2,
11
+ '@nkzw/fbtee/no-unhelpful-desc': 2,
12
+ },
22
13
  },
23
- },
24
- strict: {
25
- rules: {
26
- '@nkzw/fbtee/no-empty-strings': 2,
27
- '@nkzw/fbtee/no-unhelpful-desc': 2,
28
- '@nkzw/fbtee/no-untranslated-strings': 2,
14
+ strict: {
15
+ rules: {
16
+ '@nkzw/fbtee/no-empty-strings': 2,
17
+ '@nkzw/fbtee/no-unhelpful-desc': 2,
18
+ '@nkzw/fbtee/no-untranslated-strings': 2,
19
+ },
29
20
  },
30
21
  },
22
+ meta: {
23
+ name: packageJson.name,
24
+ version: packageJson.version,
25
+ },
26
+ rules: {
27
+ 'no-empty-strings': noEmptyStringsRule,
28
+ 'no-unhelpful-desc': noUnhelpfulDesc,
29
+ 'no-untranslated-strings': noUntranslatedStrings,
30
+ },
31
31
  };