@ansstory/hias 1.0.4 → 1.0.6

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/.gitattributes CHANGED
@@ -1 +1 @@
1
- * text=auto eol=lf
1
+ * text=auto eol=lf
@@ -0,0 +1,8 @@
1
+ {
2
+ "i18n-ally.localesPaths": [
3
+ "lib/i18n/**/*",
4
+ ],
5
+ "i18n-ally.keystyle": "nested",
6
+ "i18n-ally.sourceLanguage": "zh-CN",
7
+ "i18n-ally.displayLanguage": "zh-CN",
8
+ }
package/LICENSE CHANGED
@@ -1,22 +1,22 @@
1
- The MIT License (MIT)
2
-
3
- Copyright © 2025
4
-
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the “Software”), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2025
4
+
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the “Software”), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,11 +1,533 @@
1
- # hias-cli
2
- ```sh
3
- npm i hias -g
4
- hias -h
5
- hias create xxx
6
- hias adv Demo -d src/components
7
- hias adr Demo -d src/components
8
- hias adrt Demo -d src/components
9
- hias adrd useDemoStore -d src/store/modules
10
- hias adrdt useDemoStore -d src/store/modules
11
- ```
1
+ # hias-cli
2
+
3
+ > Personal scaffolding CLI with built-in i18n translation toolkit.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm i @ansstory/hias -g
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ hias <command> [options]
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Quick Start (i18n Translation)
20
+
21
+ ### 1. Set up API credentials
22
+
23
+ Register a translation provider and create a config file in your project:
24
+
25
+ ```sh
26
+ hias setting
27
+ ```
28
+
29
+ Edit `.hias/setting.json` with your `appId` and `secretKey`:
30
+
31
+ ```json
32
+ {
33
+ "translationSetting": {
34
+ "appId": "your_app_id",
35
+ "secretKey": "your_secret_key",
36
+ "provider": "baidu"
37
+ }
38
+ }
39
+ ```
40
+
41
+ > **No API key?** Leave both empty for fallback mode — Chinese text is used as keys directly. The i18n migration still completes.
42
+
43
+ ### 2. Preview changes (recommended)
44
+
45
+ ```sh
46
+ hias tfo src/views myNamespace --dry-run
47
+ ```
48
+
49
+ Shows a line-level diff and prompts `Apply changes? (y/N)`.
50
+
51
+ ### 3. Apply translation
52
+
53
+ ```sh
54
+ hias tfo src/views myNamespace
55
+ ```
56
+
57
+ Locale files are written to `.hias/lang/myNamespace/`. If `replaceOriginalFile` is `true`, source files are overwritten in place.
58
+
59
+ ---
60
+
61
+ ## Commands
62
+
63
+ ### `create <project>` (alias: `crt`)
64
+
65
+ Create a project from a framework template.
66
+
67
+ An interactive prompt will list all available frameworks. After selection, the template is downloaded from Gitee and placed into `<project>/`.
68
+
69
+ ```sh
70
+ hias create my-app
71
+ ```
72
+
73
+ **Available frameworks:**
74
+
75
+ | Name | Description |
76
+ | ------------ | --------------------------- |
77
+ | `vue2` | Vue 2 template |
78
+ | `vue3` | Vue 3 template |
79
+ | `vue-ts` | Vue 3 + TypeScript template |
80
+ | `uni-vite` | uni-app + Vite template |
81
+ | `nuxt-web` | Nuxt.js web template |
82
+ | `vue-screen` | Vue data screen template |
83
+ | `react` | React JSX template |
84
+ | `react-ts` | React TypeScript template |
85
+
86
+ ---
87
+
88
+ ### `adv <name> [options]`
89
+
90
+ Add a Vue component file.
91
+
92
+ ```sh
93
+ hias adv Demo -d src/components
94
+ hias adv index -d src/views/demo
95
+ ```
96
+
97
+ ### `adr <name> [options]`
98
+
99
+ Add a React JSX component file.
100
+
101
+ ```sh
102
+ hias adr Demo -d src/components
103
+ ```
104
+
105
+ ### `adrt <name> [options]`
106
+
107
+ Add a React TSX component file.
108
+
109
+ ```sh
110
+ hias adrt Demo -d src/components
111
+ ```
112
+
113
+ ### `adrd <name> [options]`
114
+
115
+ Add a Redux JSX store file.
116
+
117
+ ```sh
118
+ hias adrd useDemoStore -d src/store/modules
119
+ ```
120
+
121
+ ### `adrdt <name> [options]`
122
+
123
+ Add a Redux TSX store file.
124
+
125
+ ```sh
126
+ hias adrdt useDemoStore -d src/store/modules
127
+ ```
128
+
129
+ #### Common options for component commands
130
+
131
+ | Option | Description |
132
+ | ------------------- | ----------------------------------------------------------------------------- |
133
+ | `-d, --dest <path>` | Target folder. Defaults to `src/components`. Accepts Windows backslash paths. |
134
+
135
+ If `name` is `index`, the component file is named after the parent folder instead.
136
+
137
+ ---
138
+
139
+ ### `close-port <ports...>`
140
+
141
+ Kill processes occupying one or more ports.
142
+
143
+ ```sh
144
+ hias close-port 8076 8077
145
+ hias close-port 8076,8077
146
+ hias close-port 3000
147
+ ```
148
+
149
+ Supports both space-separated and comma-separated port lists. Works on Windows (`netstat` + `taskkill`), macOS, and Linux (`lsof` + `kill`).
150
+
151
+ ---
152
+
153
+ ### `lang [language]`
154
+
155
+ Set or view the CLI language.
156
+
157
+ ```sh
158
+ hias lang zh-CN
159
+ hias lang en
160
+ hias lang -l # show current language
161
+ ```
162
+
163
+ | Option | Description |
164
+ | ------------ | ------------------------------------- |
165
+ | `-l, --list` | Display the currently active language |
166
+
167
+ Supported languages: `en`, `zh-CN`.
168
+
169
+ Language preference is stored in `~/.hias-cli/config.json`.
170
+
171
+ ---
172
+
173
+ ### Translation Commands
174
+
175
+ The translation system extracts Chinese text from source files, replaces it with `$t()` i18n calls, and generates locale JSON files. Supports Baidu Translate API and Tencent Cloud TMT API.
176
+
177
+ #### `tf [file] [name]`
178
+
179
+ Translate a single file.
180
+
181
+ ```sh
182
+ hias tf src/views/index.vue vue
183
+ hias tf src/views/index.vue vue --verbose
184
+ ```
185
+
186
+ | Argument / Option | Description |
187
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
188
+ | `file` (positional) | Path to the file to translate |
189
+ | `name` (positional) | i18n namespace key (defaults to parent directory name) |
190
+ | `-n, --name <name>` | Alternative way to specify the namespace |
191
+ | `--dry-run` | Preview changes without modifying files (shows line-level diff, prompts to apply) |
192
+ | `-v, --verbose` | Show detailed per-file logs instead of a progress spinner |
193
+ | `--show-extractions` | Only display all extracted Chinese texts with file paths and positions, without performing translation or making API calls |
194
+
195
+ **Supported file types:** `.vue`, `.js`, `.ts`, `.jsx`, `.tsx`, `.json`
196
+
197
+ #### `tfo [folder] [name]`
198
+
199
+ Recursively translate all supported files in a folder.
200
+
201
+ ```sh
202
+ hias tfo src/views views
203
+ hias tfo src/views views --verbose
204
+ ```
205
+
206
+ | Argument / Option | Description |
207
+ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
208
+ | `folder` (positional) | Path to the folder |
209
+ | `name` (positional) | i18n namespace key (defaults to folder name) |
210
+ | `-n, --name <name>` | Alternative way to specify the namespace |
211
+ | `--dry-run` | Preview changes without modifying files (shows line-level diff, prompts to apply) |
212
+ | `-v, --verbose` | Show detailed per-file logs instead of a progress spinner |
213
+ | `--exclude <pattern>` | Exclude files matching a glob pattern (e.g. `**/*.test.js`, `node_modules/**`). Uses minimatch. Can be specified multiple times. |
214
+ | `--show-extractions` | Only display all extracted Chinese texts with file paths and positions, without performing translation or making API calls |
215
+
216
+ #### `setting`
217
+
218
+ Generate a project-level translation config file.
219
+
220
+ ```sh
221
+ hias setting
222
+ ```
223
+
224
+ Creates `.hias/setting.json` in the current project directory.
225
+
226
+ #### `globalsetting`
227
+
228
+ Generate a global translation config file.
229
+
230
+ ```sh
231
+ hias globalsetting
232
+ ```
233
+
234
+ Creates or updates `~/.hias-cli/config.json`. Preserves any existing `language` setting.
235
+
236
+ #### `gitignore`
237
+
238
+ Add `.hias` to the project's `.gitignore` file. Creates `.gitignore` if it doesn't exist, or appends the entry if it already exists.
239
+
240
+ ```sh
241
+ hias gitignore
242
+ ```
243
+
244
+ After running, the `.gitignore` file will contain an entry for `.hias`.
245
+
246
+ ---
247
+
248
+ #### `rollback`
249
+
250
+ Restore files from the last translation operation and clean up generated output.
251
+
252
+ Each translation run creates a snapshot in `.hias/.langbackup/<timestamp>_<name>/`. Running `rollback` restores the most recent snapshot and removes it, preserving older snapshots for further step-by-step rollback.
253
+
254
+ ```sh
255
+ hias rollback
256
+ hias rollback --list # list available backups
257
+ hias rollback --name 20250101_120000_vue # rollback a specific backup
258
+ hias rollback --keep 3 # keep only the 3 most recent backups, remove older ones
259
+ ```
260
+
261
+ **Behavior:** When `replaceOriginalFile` was `true`, original source files are restored; when it was `false`, only the output directory `.hias/lang/<name>/` is removed.
262
+
263
+ **`--keep` behavior:** Backups are sorted by directory name (timestamp), the oldest ones are removed until only N remain. No action if total backups ≤ N.
264
+
265
+ | Option | Description |
266
+ | ---------------- | ------------------------------------------------------ |
267
+ | `-l, --list` | List all available backups |
268
+ | `--name <name>` | Rollback a specific backup by name |
269
+ | `--keep <count>` | Keep only the N most recent backups, remove older ones |
270
+
271
+ ---
272
+
273
+ ## Configuration
274
+
275
+ ### Config Cascade
276
+
277
+ Translation settings are resolved in the following priority order:
278
+
279
+ 1. **Project-level** — `.hias/setting.json` in the current working directory
280
+ 2. **Global** — `~/.hias-cli/config.json` (created by `hias globalsetting`)
281
+ 3. **Defaults** — hardcoded defaults (shown below)
282
+
283
+ ### Setting File Format
284
+
285
+ ```json
286
+ {
287
+ "translationSetting": {
288
+ "locales": ["zh-CN", "en-US"],
289
+ "outDir": ".hias/lang",
290
+ "fallbackToKey": true,
291
+ "replaceOriginalFile": false,
292
+ "provider": "tencent",
293
+ "_provider_hint": "'baidu','tencent'",
294
+ "i18nCallTemplate": "$t",
295
+ "extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
296
+ "appId": "",
297
+ "secretKey": ""
298
+ }
299
+ }
300
+ ```
301
+
302
+ ### Configuration Fields
303
+
304
+ | Field | Type | Default | Description |
305
+ | --------------------- | ---------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
306
+ | `locales` | `string[]` | `["zh-CN", "en-US"]` | Locale code list. **First entry is the source language**, the rest are target languages. E.g. `["zh-CN", "en-US", "ja-JP", "ko-KR"]` generates English, Japanese, and Korean locale files in one pass |
307
+ | `outDir` | `string` | `".hias/lang"` | Output directory for generated locale files and translated copies |
308
+ | `fallbackToKey` | `boolean` | `true` | Whether to generate keys when translation API is unavailable |
309
+ | `replaceOriginalFile` | `boolean` | `false` | When `true`, overwrites source files in place (no copy to `outDir`) |
310
+ | `provider` | `string` | `"tencent"` | Translation provider: `"baidu"` or `"tencent"` |
311
+ | `i18nCallTemplate` | `string` | `"$t"` | i18n function name. When containing `{{key}}`, it's replaced with `namespace.subKey`; otherwise the function wraps it as `$t('key')` |
312
+ | `extensions` | `string[]` | — | Override supported file extensions (e.g. `[".vue", ".ts"]`). Defaults to all supported types |
313
+ | `appId` | `string` | `""` | Baidu AppId or Tencent SecretId |
314
+ | `secretKey` | `string` | `""` | Baidu SecretKey or Tencent SecretKey |
315
+
316
+ ### Translation Providers
317
+
318
+ | Provider | `provider` value | `appId` | `secretKey` |
319
+ | ----------------- | ---------------- | ---------------- | ----------------- |
320
+ | Baidu Translate | `"baidu"` | Baidu AppId | Baidu SecretKey |
321
+ | Tencent Cloud TMT | `"tencent"` | Tencent SecretId | Tencent SecretKey |
322
+
323
+ Leave both `appId` and `secretKey` empty to use fallback mode (Chinese text is used as-is for both key and value in locale files).
324
+
325
+ > **Config validation:** Settings are automatically validated when loaded (e.g., `locales` must be an array, `provider` must be a supported enum value, `appId`/`secretKey` must be strings). Invalid values trigger a warning and are reset to defaults without interrupting the workflow.
326
+
327
+ ### API Provider Setup
328
+
329
+ #### Baidu Translate
330
+
331
+ 1. Visit [Baidu Translate Open Platform](https://fanyi-api.baidu.com/) and register
332
+ 2. Create an application to get **AppId** and **SecretKey**
333
+ 3. Set `"provider": "baidu"` in config
334
+
335
+ #### Tencent Cloud TMT
336
+
337
+ 1. Visit [Tencent Cloud TMT](https://console.cloud.tencent.com/tmt) and enable the service
338
+ 2. Create an API key to get **SecretId** (→ `appId`) and **SecretKey**
339
+ 3. Set `"provider": "tencent"` in config
340
+
341
+ ---
342
+
343
+ ## Output Structure
344
+
345
+ After translation, the following directory structure is created (assuming `locales: ["zh-CN", "en-US", "ja-JP"]`):
346
+
347
+ ```
348
+ .hias/
349
+ ├── setting.json # project-level config
350
+ ├── lang/
351
+ │ └── <namespace>/
352
+ │ ├── zh-CN.json # source locale
353
+ │ ├── en-US.json # target locale ①
354
+ │ ├── ja-JP.json # target locale ②
355
+ │ └── <file>.vue # translated copy (only if replaceOriginalFile=false)
356
+ ├── .translation-cache.json # translation cache (auto-generated)
357
+ └── .langbackup/
358
+ └── <timestamp>_<namespace>/
359
+ └── <file>.vue.bak # original file backup
360
+ ```
361
+
362
+ Locale files use a nested `{ namespace: { key: value } }` format, making them ready for use with `vue-i18n` or similar libraries via module registration.
363
+
364
+ ---
365
+
366
+ ## Translation Behavior
367
+
368
+ ### Source Code Extraction
369
+
370
+ The tool scans source files and extracts Chinese text from:
371
+
372
+ - **Quoted strings**: `'中文'`, `"中文"`, `` `中文{expr}文` `` (template literals with expressions are split, only static Chinese segments extracted)
373
+ - **Vue templates**: `{{ '中文' }}`, `<div>中文</div>`, `:title="'中文'"`
374
+ - **Vue complex expressions**: `{{ isHidden || '中文' }}`, `{{ isHidden ?? '中文' }}` (extracts inline quoted strings from expressions)
375
+ - **Vue directives**: `v-if="text1 == '中文'"`, `v-for="..."` (extracts inline strings from directive expressions)
376
+ - **JSX/TSX text nodes**: `<span>中文 {name}</span>` (mixed text with expressions supported)
377
+ - **JSX/TSX attributes**: `<div title="中文">` or `<div title={'中文'}>`
378
+ - **JSON values**: `"key": "中文值"`
379
+ - **Plain HTML attributes**: `<div title="兴趣">` in Vue templates
380
+
381
+ Comments (`//`, `/* */`, `<!-- -->`) are correctly skipped. `data-*` and `aria-*` attributes are excluded.
382
+
383
+ ### Replacement Pattern
384
+
385
+ | Context | Before | After |
386
+ | -------------------------- | ------------------------- | -------------------------------------------------- |
387
+ | Vue template text node | `<div>兴趣</div>` | `<div>{{ $t('demo.interest') }}</div>` |
388
+ | Vue template interpolation | `{{ '兴趣' }}` | `{{ $t('demo.interest') }}` |
389
+ | Vue complex expression | <code>{{ isHidden &#124;&#124; '兴趣' }}</code> | <code>{{ isHidden &#124;&#124; $t('demo.interest') }}</code> |
390
+ | Vue directive expression | `v-if="text1 == '文本'"` | `v-if="text1 == $t('demo.text')"` |
391
+ | Vue script / JS / TS | `'兴趣'` | `$t('demo.interest')` |
392
+ | JSX text node | `<div>兴趣</div>` | `<div>{$t('demo.interest')}</div>` |
393
+ | JSX attribute | `<div title="兴趣">` | `<div title={$t('demo.interest')}>` |
394
+ | Vue v-bind attribute | `<div :title="'兴趣'">` | `<div :title="$t('demo.interest')">` |
395
+ | Template literal | `` `中文 ${name} 测试` `` | `` `$t('demo.chinese') ${name} $t('demo.test')` `` |
396
+ | JSON value | `"兴趣"` | `"interest"` (replaced with translation directly) |
397
+
398
+ ### Locale File Format
399
+
400
+ **When translation succeeds** (English-based keys, truncated to 40 characters):
401
+
402
+ ```json
403
+ // zh-CN.json
404
+ { "demo": { "interest": "兴趣", "test": "测试" } }
405
+ // en-US.json
406
+ { "demo": { "interest": "interest", "test": "test" } }
407
+ // ja-JP.json (if locales includes ja-JP)
408
+ { "demo": { "interest": "興味", "test": "テスト" } }
409
+ ```
410
+
411
+ **When translation fails** (auto-generated short keys from Chinese, truncated to 40 characters):
412
+
413
+ ```json
414
+ // zh-CN.json and en-US.json
415
+ { "demo": { "提起妈妈的手_一股酸痛便涌上心头": "提起妈妈的手,一股酸痛便涌上心头...", "test": "测试" } }
416
+ ```
417
+
418
+ ### Key Generation Rules
419
+
420
+ | Scenario | Source | Key Generation | Max Length |
421
+ | ------------ | ------------------ | --------------------------------------- | ---------- |
422
+ | API success | Translated English | snake_case of translation | 40 chars |
423
+ | API fallback | Original Chinese | first-line punctuation → `_`, truncated | 40 chars |
424
+
425
+ Keys are deduplicated: if two texts produce the same truncated key, `_1`, `_2`, etc. are appended.
426
+
427
+ ### Translation API Fallback Warning
428
+
429
+ When the translation API call fails (network error, invalid credentials, or rate limit), the tool logs a warning message to the console, e.g.:
430
+
431
+ ```
432
+ ⚠ Translation API failed, falling back to Chinese keys for this batch
433
+ ```
434
+
435
+ It then falls back to Chinese-based auto-generated keys (see [Key Generation Rules](#key-generation-rules) above). This ensures the i18n migration can proceed even without API connectivity.
436
+
437
+ > **Per-text fallback:** If some texts in a batch succeed while others fail, only the failed texts use fallback mode — successful texts still use English keys. This prevents a single failure from degrading the entire batch to Chinese keys.
438
+
439
+ ### Translation Cache
440
+
441
+ Successful API translation results are cached to `.hias/.translation-cache.json`. The next time the same text is encountered (regardless of namespace), it's served from cache, avoiding redundant network requests and API costs.
442
+
443
+ - Cache is keyed by original text with target language as sub-key: `{ "text": { "en": "translated" } }`
444
+ - Corrupted or malformed cache files are silently ignored without affecting the normal flow
445
+ - Writes are deferred (`setImmediate`) to avoid blocking the translation pipeline
446
+
447
+ ### Unused Translation Cleanup
448
+
449
+ After replacing Chinese text with `$t()` calls, the tool checks existing locale JSON files and **removes keys that are no longer referenced anywhere in the source code**. This prevents locale files from accumulating stale entries over time.
450
+
451
+ Cleanup runs against the same namespace used for the current translation operation, and only affects keys that have zero references across all scanned source files.
452
+
453
+ ### Namespace Normalization
454
+
455
+ Existing `$t('oldNamespace.key')` calls in source files are automatically updated to the current namespace name during translation.
456
+
457
+ ### Dry-Run Mode
458
+
459
+ When `--dry-run` is specified, the tool shows a line-level diff of all changes without actually modifying files. After the preview, it prompts `Apply changes? (y/N)` — entering `y` or `yes` executes the changes, anything else cancels.
460
+
461
+ ### `i18nCallTemplate` Customization
462
+
463
+ The `i18nCallTemplate` field controls the i18n function name and call format:
464
+
465
+ | Template Value | Generated Output |
466
+ | ---------------------------- | ------------------------------------------- |
467
+ | `"$t"` (default) | `$t('demo.interest')` |
468
+ | `"$te"` | `$te('demo.interest')` |
469
+ | `"{{key}}"` | `demo.interest` (raw key, no function call) |
470
+ | `"t('{{key}}')"` | `t('demo.interest')` |
471
+ | `"i18n.global.t('{{key}}')"` | `i18n.global.t('demo.interest')` |
472
+
473
+ When the template **contains** `{{key}}`, it's a template string where `{{key}}` is replaced with `namespace.subKey`. When it does **not** contain `{{key}}`, it wraps as `template('namespace.subKey')`.
474
+
475
+ ### Workflow Tips
476
+
477
+ - **Always run `--dry-run` first** when trying translation on a new codebase to verify the extraction results
478
+ - **Use `tfo` with a single file's parent folder** for targeted translation: `hias tfo src/views/MyComponent myComp`
479
+ - **Use `--exclude` to skip config or generated files**: `hias tfo src/views views --exclude "**/*.test.js" --exclude node_modules`
480
+ - **Use separate namespaces per module** to keep locale files small and focused. For example, `src/views/user/` → namespace `user`, `src/views/admin/` → namespace `admin`
481
+ - **Run rollback after verifying** if `replaceOriginalFile` was on: `hias rollback`
482
+ - **Multiple rollbacks**: each `rollback` undoes one snapshot. Run repeatedly to go back further
483
+ - **Re-running translation**: existing `$t()` calls are stripped before re-extraction, so running twice is safe and will only add new translations for any remaining Chinese text
484
+
485
+ ---
486
+
487
+ ## Global Config
488
+
489
+ The global config file is located at `~/.hias-cli/config.json` and is shared by both the language setting and translation settings:
490
+
491
+ ```json
492
+ {
493
+ "language": "zh-CN",
494
+ "translationSetting": {
495
+ "locales": ["zh-CN", "en-US"],
496
+ "outDir": ".hias/lang",
497
+ "fallbackToKey": true,
498
+ "replaceOriginalFile": false,
499
+ "provider": "tencent",
500
+ "_provider_hint": "'baidu','tencent'",
501
+ "i18nCallTemplate": "$t",
502
+ "extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
503
+ "appId": "",
504
+ "secretKey": ""
505
+ }
506
+ }
507
+ ```
508
+
509
+ Managed by:
510
+
511
+ - **`hias lang <language>`** — sets `language`
512
+ - **`hias globalsetting`** — creates/updates `translationSetting`
513
+
514
+ ---
515
+
516
+ ## All Commands Reference
517
+
518
+ | Command | Alias | Description |
519
+ | ----------------------- | ----- | ----------------------------------------- |
520
+ | `create <project>` | `crt` | Create project from framework template |
521
+ | `adv <name>` | – | Add Vue component |
522
+ | `adr <name>` | – | Add React JSX component |
523
+ | `adrt <name>` | – | Add React TSX component |
524
+ | `adrd <name>` | – | Add Redux JSX store |
525
+ | `adrdt <name>` | – | Add Redux TSX store |
526
+ | `close-port <ports...>` | – | Kill processes on ports |
527
+ | `lang [language]` | – | Set or view CLI language |
528
+ | `tf [file] [name]` | – | Translate a single file |
529
+ | `tfo [folder] [name]` | – | Translate all files in a folder |
530
+ | `setting` | – | Generate project-level translation config |
531
+ | `globalsetting` | – | Generate global translation config |
532
+ | `gitignore` | – | Add `.hias` to `.gitignore` |
533
+ | `rollback` | – | Roll back the last translation operation |