i18ntk 4.0.0 → 4.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/CHANGELOG.md +116 -29
- package/README.md +83 -18
- package/SECURITY.md +13 -5
- package/main/i18ntk-analyze.js +10 -20
- package/main/i18ntk-backup.js +227 -111
- package/main/i18ntk-init.js +153 -157
- package/main/i18ntk-scanner.js +9 -7
- package/main/i18ntk-setup.js +36 -13
- package/main/i18ntk-sizing.js +18 -50
- package/main/i18ntk-translate.js +169 -21
- package/main/i18ntk-usage.js +298 -154
- package/main/i18ntk-validate.js +49 -37
- package/main/manage/commands/AnalyzeCommand.js +7 -17
- package/main/manage/commands/CommandRouter.js +6 -6
- package/main/manage/commands/TranslateCommand.js +65 -56
- package/main/manage/commands/ValidateCommand.js +34 -26
- package/main/manage/index.js +11 -42
- package/main/manage/managers/InteractiveMenu.js +11 -40
- package/main/manage/services/InitService.js +114 -118
- package/main/manage/services/UsageService.js +244 -85
- package/package.json +55 -4
- package/runtime/enhanced.d.ts +5 -5
- package/runtime/enhanced.js +49 -25
- package/runtime/i18ntk.d.ts +30 -7
- package/runtime/index.d.ts +48 -19
- package/runtime/index.js +188 -97
- package/settings/settings-cli.js +115 -38
- package/settings/settings-manager.js +24 -6
- package/ui-locales/de.json +192 -11
- package/ui-locales/en.json +182 -8
- package/ui-locales/es.json +193 -12
- package/ui-locales/fr.json +189 -8
- package/ui-locales/ja.json +190 -8
- package/ui-locales/ru.json +191 -9
- package/ui-locales/zh.json +194 -9
- package/utils/cli-helper.js +8 -12
- package/utils/config-helper.js +1 -1
- package/utils/config-manager.js +8 -6
- package/utils/localized-confirm.js +55 -0
- package/utils/menu-layout.js +41 -0
- package/utils/report-writer.js +110 -0
- package/utils/security.js +15 -22
- package/utils/translate/api.js +31 -3
- package/utils/translate/placeholder.js +42 -1
- package/utils/translate/protection.js +17 -12
- package/utils/translate/report.js +3 -2
- package/utils/translate/safe-network.js +24 -4
- package/utils/usage-insights.js +435 -0
- package/utils/usage-source.js +50 -0
- package/utils/watch-locales.js +13 -9
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,101 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.2.0] - 2026-05-30
|
|
9
|
+
|
|
10
|
+
### Security
|
|
11
|
+
- Shared path validation no longer permits artifact-like filenames such as `.lock` or `.temp-config.json` to bypass base-directory containment.
|
|
12
|
+
- Shared path validation now rejects Windows cross-drive escape cases where `path.relative()` returns an absolute path.
|
|
13
|
+
- Custom `I18NTK_INTERNAL_PATH_PREFIXES` entries can no longer mark arbitrary outside directories as internal roots.
|
|
14
|
+
- Backup restore now rejects backup entry names containing path separators, absolute paths, traversal, or non-JSON names before writing restored files.
|
|
15
|
+
- Runtime locale loading now validates language identifiers before resolving single-file or directory locale paths, blocking `../` language names from reading JSON outside `baseDir`.
|
|
16
|
+
- Auto Translate provider URL validation now blocks IPv4-mapped IPv6 loopback/private hosts.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Main runtime now includes production-safe features from the enhanced runtime surface: per-call language overrides, synchronous `translateBatch()`, and `clearCache()` / `getCacheInfo()` helpers.
|
|
20
|
+
- `i18ntk/runtime/enhanced` remains available as a legacy public subpath for compatibility, while new production integrations should prefer the lightweight `i18ntk/runtime` API.
|
|
21
|
+
- Usage analysis now indexes known translation keys back to source files, including direct i18n calls and literal key references that were previously missed.
|
|
22
|
+
- Usage analysis now expands simple dynamic templates backed by literal constants, bounded literal arrays, object maps, and ternaries to exact available keys before falling back to unresolved dynamic-expression reporting.
|
|
23
|
+
- Usage reports now list unresolved dynamic key expressions separately instead of treating broad wildcard prefixes as proof that every matching key is used.
|
|
24
|
+
- Usage reports now include namespace/file naming recommendations such as preferring `shop.*` keys and `shop.json` for `/shop` page or route files.
|
|
25
|
+
- Usage reports now list likely hardcoded user-facing text with suggested translation keys, and prefer an existing source key when the inline text matches a source translation value.
|
|
26
|
+
- Translation analysis and init reports now default to Markdown for readable output, with `reports.format` supporting `markdown`, `json`, or `text` through settings and config.
|
|
27
|
+
- Init default target languages now include English (`en`) before `de`, `es`, `fr`, and `ru` when the UI is running in another language.
|
|
28
|
+
- Confirmation prompts now accept localized native yes/no input for supported UI languages while retaining English fallback tokens.
|
|
29
|
+
- Auto Translate has moved out of beta in menus and documentation, and its settings are exposed with localized labels.
|
|
30
|
+
- Auto Translate now keeps existing translated target values by default and only translates missing, marker, source-copy, or likely English target strings; use `--translate-all` to force a full re-translation.
|
|
31
|
+
- Auto Translate now treats visibly corrupt target strings such as `?????`, Unicode replacement characters, and common mojibake as needing retranslation from the source language.
|
|
32
|
+
- Auto Translate now defaults to 12 concurrent provider requests and allows Google concurrency up to 100 instead of the old 25-request cap; DeepL and LibreTranslate remain capped lower to avoid provider/account throttling.
|
|
33
|
+
- Auto Translate progress output now separates string translation from placeholder-safe text-segment translation and shows the active key path during progress updates.
|
|
34
|
+
- Placeholder detection now covers ICU plural/select blocks, i18next nested `$t(...)` references, and wider named printf formats such as `%(total).2f`.
|
|
35
|
+
- Manager menu output is now grouped with clearer spacing and aligned option numbers.
|
|
36
|
+
- Documentation now consolidates migration guidance around `4.2.0` and removes stale old per-version migration guides from the working docs tree.
|
|
37
|
+
- Removed stale duplicate development artifacts `main/manage/index-fixed.js` and `utils/security-fixed.js` to reduce audit drift and prevent accidental reuse.
|
|
38
|
+
- Updated public, root, and development package metadata for the 4.2.0 release line.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- Runtime JSON loading now preserves valid translation strings containing comment-like text such as `/* token */` by parsing valid JSON before using the comment-stripping fallback.
|
|
42
|
+
- Enhanced runtime now exports the top-level `translateBatch()`, `translateBatchEncrypted()`, and `tTyped()` helpers declared by its TypeScript definitions, and those declarations now reflect async return values.
|
|
43
|
+
- Usage analysis no longer scans the project root when `sourceDir` and `i18nDir` both point at the locale directory; it now uses a detected app source directory or disables usage scanning with a clear warning.
|
|
44
|
+
- Init backup prompts, completion summaries, report prompts, and report status text now use bundled UI locale keys instead of hard-coded English.
|
|
45
|
+
- Bundled UI locales were regenerated from `ui-locales/en.json` for newly added, source-copy, and corrupt target strings.
|
|
46
|
+
- JSON report output is now pretty-printed object JSON instead of a single JSON string containing escaped newlines.
|
|
47
|
+
- The managed Auto Translate command no longer forces UI translations back to English after the user has selected another UI language.
|
|
48
|
+
- Manager validation output no longer prints duplicate source/i18n/output directory blocks before the validator summary.
|
|
49
|
+
- `i18ntk-setup --help` now exits after printing help instead of running setup and writing project files.
|
|
50
|
+
- `npm run languages:list` and `npm run languages:status` now produce non-interactive output instead of opening the settings menu.
|
|
51
|
+
- `i18ntk-backup create locales` now recursively backs up modular locale layouts such as `locales/en/common.json`, and restore safely recreates nested JSON paths without allowing traversal.
|
|
52
|
+
- Removed a stale bundled `locales/es/navigation.json` fixture that made `i18ntk-doctor` report a dangling namespace after setup/init tests.
|
|
53
|
+
|
|
54
|
+
## [4.1.0] - 2026-05-21
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- Runtime: stale manifest entries (deleted files after manifest construction) no longer cause unhandled exceptions; loadedFiles set before load with try/catch guard.
|
|
58
|
+
- Runtime: `refresh()` now correctly clears the key manifest for the refreshed language, preventing stale file references.
|
|
59
|
+
- Runtime: null `baseDir` guard prevents cascading `validatePath(null)` errors in `loadKeyManifestFromDir`.
|
|
60
|
+
- Backup: `handleVerify` hash-chain verification rewritten for incremental backups — rebuilds full state oldest→newest before per-entry hash comparison; no longer reports false "Missing file" errors for unchanged files.
|
|
61
|
+
- Backup: `cleanupOldBackups` and `handleCleanup` now preserve parent backups of incremental chains by scanning kept backups for `_meta.parent` references before deletion.
|
|
62
|
+
- Backup: `--incremental=false` is now correctly parsed as falsy (string-to-boolean conversion fixed).
|
|
63
|
+
- Backup: `buildRestoreChain` detects circular parent references via visited-set traversal.
|
|
64
|
+
- Sizing: `this.adminAuth` undefined crash in `run()` fixed — changed to correct `adminAuth` local variable.
|
|
65
|
+
- Sizing: duplicate `analyze()` method removed; format-based display logic (`--format=json` vs table) restored to the surviving method.
|
|
66
|
+
- Sizing: setup-check IIFE now guarded with `require.main === module`, preventing unexpected `process.exit()` on `require()`.
|
|
67
|
+
- Scanner: `frameworks.vanilla` key added to `getFrameworkSpecific` — no longer returns `undefined` for vanilla projects.
|
|
68
|
+
- Scanner: `--source-language` CLI flag now correctly propagates through config chain to `scanFile` and `generateSuggestion` (camelCase vs hyphen key mismatch fixed).
|
|
69
|
+
- Scanner: `isTextInLanguage` now always validates character ratio unconditionally even for no-stopword language profiles.
|
|
70
|
+
- Watch: `{ onChange: fn }` object-format callbacks are now properly subscribed to change/add/unlink events.
|
|
71
|
+
- Watch: debounce `setTimeout` timers are now stored per-watcher and cleared on `emitter.stop()`, preventing memory leaks and spurious I/O after stop.
|
|
72
|
+
- Watch: `'unlink'` events are now subscribed for backward-compatible plain-function callback users.
|
|
73
|
+
- Usage: duplicate `require.main === module` block removed (caused `TypeError: Identifier 'main' has already been declared` at execution).
|
|
74
|
+
- Usage: `_keyInSourceComments` optimized from O(n*m) to O(n+m) by pre-computing a `Set` of all comment strings once before the dead key loop.
|
|
75
|
+
- Usage: `--cleanup=false` and `--dry-run-delete=false` now correctly parse as falsy via `toBool()` helper.
|
|
76
|
+
- Usage: broken `detectFrameworkPatterns()` call with `undefined` arguments removed.
|
|
77
|
+
- Usage: dead `return;` in `analyze()` removed so the result object is now actually returned.
|
|
78
|
+
- Validator: missing `try` block in `run()` added so errors are caught by the existing `catch(error)` handler.
|
|
79
|
+
- Validator: `--enforce-key-style=true/false` now correctly parsed (previously silently ignored due to `!includes('=')` guard).
|
|
80
|
+
- Validator: `flat` style no longer produces false positives for nested keys — validates only the leaf segment (last `.`-delimited part).
|
|
81
|
+
- Validator: `suggestKeyFix` for `flat` style now returns `segments.map(s => s.toLowerCase()).join('')` instead of camelCase.
|
|
82
|
+
- Validator: `getLanguageFiles` no longer crashes when `excludeFiles` config property is undefined.
|
|
83
|
+
- Validator: `enforceKeyStyle` now correctly propagated from CLI args to `this.config.enforceKeyStyle` in `run()`.
|
|
84
|
+
- Protection: `standalone` mode boundary check now handles opening/closing punctuation (`(`, `[`, `{`, `"`, `'`, `-`, `–`, `—`) and CJK marks (`。`, `、`, `」`).
|
|
85
|
+
- Protection: `\b` word-boundary assertions replaced with Unicode-aware `(^|[\s\p{P}])` / `([\s\p{P}]|$)` patterns with `u` flag for non-ASCII language support.
|
|
86
|
+
- Protection: `surrounded` context rule parser now uses `indexOf(',')` split instead of greedy `(.+,.+)` regex to correctly parse multi-word right-side expressions.
|
|
87
|
+
- Protection: `hasProtectionRules` no longer throws `TypeError` when `terms` property is undefined.
|
|
88
|
+
- Protection: `shouldPreserveWholeValue` now respects context rules by only matching `type === 'global'` entries.
|
|
89
|
+
- Manager option 7 ("Fix placeholder translations") now interpolates fixer status values correctly instead of printing raw `{languages}`, `{sourceDir}`, `{skipped}`, or `{totalIssues}` placeholders.
|
|
90
|
+
- Delete Reports settings now include cache cleanup targets.
|
|
91
|
+
- Public package metadata updated.
|
|
92
|
+
|
|
93
|
+
### Security
|
|
94
|
+
- Watch module: debounce timers properly cleaned up on stop and callback subscriptions corrected for object-format and unlink handlers.
|
|
95
|
+
- Runtime: loadedFiles lock-before-load pattern prevents duplicate I/O and stale manifest crash.
|
|
96
|
+
- Backup: circular parent reference detection; `--incremental=false` string truthy bypass closed.
|
|
97
|
+
- Sizing: adminAuth variable reference corrected; require()-time `process.exit()` guarded.
|
|
98
|
+
- Scanner: vanilla framework key prevents `undefined` return; stopword-less validRatio enforced.
|
|
99
|
+
- Usage: O(n+m) comment scanning prevents DoS via large codebase with many dead keys; `toBool()` prevents flag injection.
|
|
100
|
+
- Validator: try/catch pairing restored; `flat` leaf-segment prevents false-positive flood.
|
|
101
|
+
- Protection: Unicode-aware punctuation boundaries for CJK/Cyrillic/Arabic; standalone boundaries include the expanded punctuation set.
|
|
102
|
+
|
|
8
103
|
## [4.0.0] - 2026-05-21
|
|
9
104
|
|
|
10
105
|
### Added
|
|
@@ -17,32 +112,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
112
|
- **Runtime Lazy Loading**: `runtime/index.js` adds `lazy: true` option to `initRuntime()`. Defers locale file loading until the first key access, guided by an auto-generated key-to-file manifest. Falls back to eager loading if manifest is missing. Manifest capped at 100KB with path containment validation.
|
|
18
113
|
- **Protection Context-Aware Rules**: `utils/translate/protection.js` extends the protection config schema to support context rules (`after:word`, `before:word`, `standalone`, `surrounded:left,right`). Plain string terms remain fully backward compatible. Total context rules capped at 100.
|
|
19
114
|
|
|
20
|
-
### Fixed
|
|
21
|
-
- `i18ntk/runtime` `initRuntime()` now returns independent runtime instances with separate language, fallback language, base directory, and cache state. Later `initRuntime()` calls no longer overwrite earlier returned runtimes or the module-level compatibility singleton.
|
|
22
|
-
- Manager option 7 ("Fix placeholder translations") now interpolates fixer status values correctly instead of printing raw `{languages}`, `{sourceDir}`, `{skipped}`, or `{totalIssues}` placeholders.
|
|
115
|
+
### Fixed
|
|
116
|
+
- `i18ntk/runtime` `initRuntime()` now returns independent runtime instances with separate language, fallback language, base directory, and cache state. Later `initRuntime()` calls no longer overwrite earlier returned runtimes or the module-level compatibility singleton.
|
|
23
117
|
|
|
24
|
-
### Changed
|
|
25
|
-
- `watchLocales()` now returns a callable watcher object with EventEmitter methods instead of only a bare `stop` function. Existing `const stop = watchLocales(...); stop();` usage remains supported. The returned object fires `change`, `add`, `unlink`, `error` events. If a callback function is passed as the second argument, it is auto-subscribed to `change` and `add` for backward compatibility.
|
|
118
|
+
### Changed
|
|
119
|
+
- `watchLocales()` now returns a callable watcher object with EventEmitter methods instead of only a bare `stop` function. Existing `const stop = watchLocales(...); stop();` usage remains supported. The returned object fires `change`, `add`, `unlink`, `error` events. If a callback function is passed as the second argument, it is auto-subscribed to `change` and `add` for backward compatibility.
|
|
26
120
|
- **BREAKING**: `i18ntk-sizing` JSON reports now include `expansionPredictions` at the top level when `--predict-expansion` is used. This field is additive — existing report fields are preserved.
|
|
27
121
|
|
|
28
|
-
|
|
29
|
-
- All new features reuse existing `SecurityUtils.safe*` wrappers for file I/O, path validation, and input sanitization.
|
|
30
|
-
- Watch module validates all directory paths against project root with containment checks and caps at 50 directories.
|
|
31
|
-
- Runtime lazy-loading manifest entries validated for path containment and size-limited to 100KB.
|
|
32
|
-
- Protection context rules parsed from constrained DSL — never accepts raw user-controlled regex from config.
|
|
33
|
-
- Backup incremental chain depth capped at 10 to prevent resource exhaustion; hash chain verified before restore.
|
|
34
|
-
|
|
35
|
-
## [3.3.0] - 2026-05-20
|
|
122
|
+
## [3.3.0] - 2026-05-20
|
|
36
123
|
|
|
37
|
-
### Changed
|
|
38
|
-
- Auto Translate now supports `--provider google|deepl|libretranslate`; DeepL uses `DEEPL_API_KEY`, while LibreTranslate supports `LIBRETRANSLATE_URL` and optional `LIBRETRANSLATE_API_KEY`.
|
|
39
|
-
- Auto Translate provider networking now keeps HTTPS, host allowlist, response-size, private-network, and redacted security logging protections in place for additional providers.
|
|
40
|
-
|
|
41
|
-
### Fixed
|
|
42
|
-
- `i18ntk-complete` now fills missing target-language keys from the English source value with a language prefix such as `[DE] Home` instead of writing `NOT_TRANSLATED`; this works for both `locales/en/*.json` and monolith `locales/en.json` layouts.
|
|
43
|
-
|
|
44
|
-
### Security
|
|
45
|
-
- Eliminated all 21 dynamic `require()` calls flagged by Socket.dev: 20 `require(path.join(__dirname, ...))` patterns in `i18ntk-js.js`, `i18ntk-py.js`, `i18ntk-java.js`, `i18ntk-php.js`, and `i18ntk-go.js` converted to static string literal requires.
|
|
124
|
+
### Changed
|
|
125
|
+
- Auto Translate now supports `--provider google|deepl|libretranslate`; DeepL uses `DEEPL_API_KEY`, while LibreTranslate supports `LIBRETRANSLATE_URL` and optional `LIBRETRANSLATE_API_KEY`.
|
|
126
|
+
- Auto Translate provider networking now keeps HTTPS, host allowlist, response-size, private-network, and redacted security logging protections in place for additional providers.
|
|
127
|
+
|
|
128
|
+
### Fixed
|
|
129
|
+
- `i18ntk-complete` now fills missing target-language keys from the English source value with a language prefix such as `[DE] Home` instead of writing `NOT_TRANSLATED`; this works for both `locales/en/*.json` and monolith `locales/en.json` layouts.
|
|
130
|
+
|
|
131
|
+
### Security
|
|
132
|
+
- Eliminated all 21 dynamic `require()` calls flagged by Socket.dev: 20 `require(path.join(__dirname, ...))` patterns in `i18ntk-js.js`, `i18ntk-py.js`, `i18ntk-java.js`, `i18ntk-php.js`, and `i18ntk-go.js` converted to static string literal requires.
|
|
46
133
|
- Added `SecurityUtils.validatePath()` gate around the remaining dynamic `require()` in `i18ntk-translate.js` `loadCustomTranslateFn`.
|
|
47
134
|
- Created `utils/translate/safe-network.js` — a secure HTTPS wrapper with URL host/path allowlist validation, response size limits (100KB), suspicious query parameter detection, and security event logging. All outbound network access now flows through this validated layer.
|
|
48
135
|
- Replaced direct `https.get` call in `utils/translate/api.js` with `safeHttpGet` from the safe-network wrapper.
|
|
@@ -54,18 +141,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
54
141
|
|
|
55
142
|
### Socket.dev Analysis Disclaimer
|
|
56
143
|
|
|
57
|
-
This package is a developer CLI and runtime helper that performs file I/O, network access (translation provider APIs on user request), and environment variable access. As such, Socket.dev will flag the following alerts that are **expected and by design**:
|
|
144
|
+
This package is a developer CLI and runtime helper that performs file I/O, network access (translation provider APIs on user request), and environment variable access. As such, Socket.dev will flag the following alerts that are **expected and by design**:
|
|
58
145
|
|
|
59
146
|
| Alert | Why it's expected |
|
|
60
147
|
|---|---|
|
|
61
|
-
| Network access | Only contacts configured translation providers via HTTPS when user invokes auto-translate. All outbound calls flow through `safe-network.js` with host/path allowlist validation, response size limits, private-network blocking, and redacted security event logging. No telemetry, no unexpected outbound calls. |
|
|
148
|
+
| Network access | Only contacts configured translation providers via HTTPS when user invokes auto-translate. All outbound calls flow through `safe-network.js` with host/path allowlist validation, response size limits, private-network blocking, and redacted security event logging. No telemetry, no unexpected outbound calls. |
|
|
62
149
|
| Environment variable access | Centralized through `env-manager.js` with a strict allowlist. Blocks `SECRET`, `PASSWORD`, `KEY`, `TOKEN`, `AWS_*`, `NPM_*`, and 15+ other patterns. |
|
|
63
150
|
| Filesystem access | Reads/writes only project locale files and reports within validated paths. All FS operations gated by `SecurityUtils.validatePath`. |
|
|
64
|
-
| URL strings | Hardcoded default provider URLs for Google, DeepL, and LibreTranslate used only for auto-translation. No external resource loading. |
|
|
65
|
-
|
|
66
|
-
The v3.3.0 release resolves the actionable dynamic-require alert by eliminating all 21 instances.
|
|
67
|
-
|
|
68
|
-
## [3.2.0] - 2026-05-16
|
|
151
|
+
| URL strings | Hardcoded default provider URLs for Google, DeepL, and LibreTranslate used only for auto-translation. No external resource loading. |
|
|
152
|
+
|
|
153
|
+
The v3.3.0 release resolves the actionable dynamic-require alert by eliminating all 21 instances.
|
|
154
|
+
|
|
155
|
+
## [3.2.0] - 2026-05-16
|
|
69
156
|
|
|
70
157
|
### Security
|
|
71
158
|
- **CRITICAL**: Fixed invalid `crypto.createCipherGCM`/`createDecipherGCM` API calls in `admin-pin.js` — replaced with `crypto.createCipheriv`/`createDecipheriv`.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# i18ntk v4.
|
|
1
|
+
# i18ntk v4.2.0
|
|
2
2
|
|
|
3
3
|
A i18n toolkit - A zero-dependency internationalization toolkit for setup, scanning, analysis, validation, usage tracking, translation completion, automatic JSON locale translation, reporting, and runtime translation loading.
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ A i18n toolkit - A zero-dependency internationalization toolkit for setup, scann
|
|
|
9
9
|
[](https://nodejs.org)
|
|
10
10
|
[](https://www.npmjs.com/package/i18ntk)
|
|
11
11
|
[](LICENSE)
|
|
12
|
-
[](https://socket.dev/npm/package/i18ntk/overview/4.2.0)
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -30,6 +30,25 @@ Requirements:
|
|
|
30
30
|
- npm `>=8.0.0`
|
|
31
31
|
- No runtime dependencies
|
|
32
32
|
|
|
33
|
+
## What's New in 4.2.0
|
|
34
|
+
|
|
35
|
+
- **SECURITY**: Hardened path containment for restore and shared filesystem helpers, including artifact-like filenames, environment-added internal prefixes, and Windows cross-drive paths.
|
|
36
|
+
- **SECURITY**: Runtime locale loading now rejects unsafe language identifiers before resolving locale files, preventing `../` language names from reading JSON outside the configured locale base.
|
|
37
|
+
- **SECURITY**: Auto Translate provider URL checks now block IPv4-mapped IPv6 private/loopback hosts.
|
|
38
|
+
- **REPORTS**: Init and analysis reports now default to readable Markdown. Set `reports.format` to `markdown`, `json`, or `text` in Settings or `.i18ntk-config`.
|
|
39
|
+
- **USAGE**: Usage analysis no longer scans the project root when locales are also configured as the source directory, avoiding inflated missing-key counts.
|
|
40
|
+
- **I18N UX**: Init backup prompts, completion summaries, report prompts, default target languages, and native yes/no confirmations are now localized.
|
|
41
|
+
- **AUTO TRANSLATE**: Auto Translate is out of beta, keeps existing translated target values by default, and only sends missing/source-copy/likely-English strings unless `--translate-all` is used.
|
|
42
|
+
- **AUTO TRANSLATE**: Google Auto Translate concurrency now defaults to 12 and can be raised up to 100 for larger locale sets.
|
|
43
|
+
- **AUTO TRANSLATE**: Corrupt target strings such as `?????`, replacement characters, and common mojibake are now repaired from the English source, and progress output distinguishes key translation from placeholder-safe text-segment translation.
|
|
44
|
+
- **CLI UX**: Manager menu spacing is grouped and aligned, and validation no longer prints duplicate source/i18n/output directory blocks.
|
|
45
|
+
- **DOCS**: Versioned docs and migration guidance now reflect the current 4.2.0 command surface.
|
|
46
|
+
- **CLEANUP**: Removed stale duplicate fixed artifacts from the development tree to reduce audit and supply-chain drift.
|
|
47
|
+
|
|
48
|
+
## What's New in 4.1.0
|
|
49
|
+
|
|
50
|
+
- **FIX**: Critical and high-impact bugs resolved across the v4.0.0 feature set — runtime staleness crashes, backup hash-chain verification, sizing adminAuth crash, scanner `--source-language` propagation, watch callback subscriptions, dead key detection performance, validator key style enforcement, and protection Unicode boundary handling. See [CHANGELOG.md](./CHANGELOG.md) for complete details.
|
|
51
|
+
|
|
33
52
|
## What's New in 4.0.0
|
|
34
53
|
|
|
35
54
|
- **SIZING**: `--predict-expansion` flag computes per-key expansion ratios across languages with Safe/Warning/Critical risk tiers for UI layout planning.
|
|
@@ -40,7 +59,6 @@ Requirements:
|
|
|
40
59
|
- **BACKUP**: `--incremental` flag creates differential backups with SHA-256 hashing and chained restores.
|
|
41
60
|
- **RUNTIME**: `lazy: true` option defers locale file loading until first key access for lower memory usage.
|
|
42
61
|
- **PROTECTION**: Context-aware rules (`after:word`, `before:word`, `standalone`, `surrounded:left,right`) for precise term masking.
|
|
43
|
-
- **FIX**: `initRuntime()` now returns independent instances with isolated language and cache state.
|
|
44
62
|
|
|
45
63
|
See [CHANGELOG.md](./CHANGELOG.md) for more release details.
|
|
46
64
|
|
|
@@ -97,7 +115,6 @@ i18ntk --command=sizing
|
|
|
97
115
|
i18ntk --command=complete
|
|
98
116
|
i18ntk --command=translate
|
|
99
117
|
i18ntk --command=summary
|
|
100
|
-
i18ntk --command=debug
|
|
101
118
|
```
|
|
102
119
|
|
|
103
120
|
Standalone executables:
|
|
@@ -116,12 +133,29 @@ i18ntk-fixer
|
|
|
116
133
|
i18ntk-backup
|
|
117
134
|
i18ntk-translate
|
|
118
135
|
```
|
|
119
|
-
|
|
120
|
-
Note: manager route `i18ntk --command=backup` is disabled in current builds. Use `i18ntk-backup`
|
|
136
|
+
|
|
137
|
+
Note: manager route `i18ntk --command=backup` is disabled in current builds. Use `i18ntk-backup` directly for backup operations.
|
|
138
|
+
|
|
139
|
+
## Command Reference
|
|
140
|
+
|
|
141
|
+
| Command | What it does | Looks for | Writes or changes |
|
|
142
|
+
| --- | --- | --- | --- |
|
|
143
|
+
| `i18ntk` | Opens the interactive management menu. | Project config, setup state, available commands. | Only changes files after you choose a command that writes. |
|
|
144
|
+
| `i18ntk --command=init` / `i18ntk-init` | Sets up locale folders and missing target-language files. | Source language files and selected target languages. | Locale JSON files, `.i18ntk-config`, optional reports/backups. |
|
|
145
|
+
| `i18ntk --command=analyze` / `i18ntk-analyze` | Compares source and target translation coverage. | Missing keys, extra keys, untranslated markers, completion by language. | Markdown/JSON/text reports when report output is enabled. |
|
|
146
|
+
| `i18ntk --command=validate` / `i18ntk-validate` | Validates structure and translation quality risks. | Placeholder mismatches, missing keys, risky URLs/emails/secrets, likely English target text. | Validation summary report. Does not edit locale files. |
|
|
147
|
+
| `i18ntk --command=usage` / `i18ntk-usage` | Maps translation keys to source files and finds unused/missing keys. | Direct i18n calls, literal known-key references, bounded dynamic templates/object maps, unresolved dynamic expressions, hardcoded text candidates, namespace/file naming mismatches. | Usage report with key locations, namespace recommendations, unresolved dynamic expressions, hardcoded text suggestions, and optional dead-key report. Does not delete unless cleanup deletion is explicitly enabled. |
|
|
148
|
+
| `i18ntk --command=scanner` / `i18ntk-scanner` | Scans source for i18n issues and hardcoded user-facing text. | JSX/template text, common text attributes, i18n usage patterns, source-language text profiles. | Scanner report. Does not edit files. |
|
|
149
|
+
| `i18ntk --command=complete` / `i18ntk-complete` | Adds missing keys to target language files for 100% key coverage. | Source-language keys missing from targets. | Target locale JSON files, using missing translation markers/prefixes. |
|
|
150
|
+
| `i18ntk --command=translate` / `i18ntk-translate` | Auto-translates locale JSON using configured provider behavior. | Missing, empty, untranslated-marker, source-copy, likely-English, or visibly corrupt target values by default. | Target locale JSON files and translation reports. Existing translated values are kept unless `--translate-all` is used. |
|
|
151
|
+
| `i18ntk --command=sizing` / `i18ntk-sizing` | Estimates translated string length expansion and layout risk. | Text length, expansion ratios, placeholder-bearing strings. | Sizing report. Does not edit locale files. |
|
|
152
|
+
| `i18ntk --command=summary` / `i18ntk-summary` | Shows project translation status. | Configured locales, reports, completeness status. | Console/report output only. |
|
|
153
|
+
| `i18ntk-fixer` | Fixes placeholder and missing-marker issues. | Placeholder corruption, missing translation markers, configured language files. | Locale JSON files when fixes are applied. Use dry-run options where available before bulk edits. |
|
|
154
|
+
| `i18ntk-backup` | Creates, verifies, restores, and cleans locale backups. | Locale JSON files and backup manifests. | Backup archives/manifests, or restored locale files when using restore. |
|
|
121
155
|
|
|
122
156
|
## Common Options
|
|
123
157
|
|
|
124
|
-
|
|
158
|
+
Many commands support:
|
|
125
159
|
|
|
126
160
|
- `--source-dir <path>`
|
|
127
161
|
- `--i18n-dir <path>`
|
|
@@ -129,9 +163,10 @@ Most commands support:
|
|
|
129
163
|
- `--source-language <code>`
|
|
130
164
|
- `--ui-language <code>`
|
|
131
165
|
- `--no-prompt`
|
|
132
|
-
- `--dry-run`
|
|
133
166
|
- `--help`
|
|
134
167
|
|
|
168
|
+
Command-specific tools add their own flags such as `--dry-run`, `--output-report`, `--cleanup`, `--predict-expansion`, or Auto Translate provider options.
|
|
169
|
+
|
|
135
170
|
Example:
|
|
136
171
|
|
|
137
172
|
```bash
|
|
@@ -144,7 +179,7 @@ Interactive manager flow:
|
|
|
144
179
|
|
|
145
180
|
```bash
|
|
146
181
|
i18ntk
|
|
147
|
-
# choose "Auto Translate
|
|
182
|
+
# choose "Auto Translate"
|
|
148
183
|
```
|
|
149
184
|
|
|
150
185
|
Direct CLI examples:
|
|
@@ -187,6 +222,8 @@ locales/de/common.json
|
|
|
187
222
|
locales/fr/common.json
|
|
188
223
|
```
|
|
189
224
|
|
|
225
|
+
Auto Translate is target-aware by default. When a target file already exists, it keeps translated target values and only sends values that are missing, empty, marked as untranslated, still identical to the source, likely still English, or visibly corrupt from encoding damage such as `?????`, replacement characters, or common mojibake. Use `--translate-all` when you intentionally want to re-translate every source string.
|
|
226
|
+
|
|
190
227
|
### Placeholder Handling
|
|
191
228
|
|
|
192
229
|
Auto Translate detects common placeholders such as:
|
|
@@ -198,6 +235,9 @@ Auto Translate detects common placeholders such as:
|
|
|
198
235
|
- `:id`
|
|
199
236
|
- `%{name}`
|
|
200
237
|
- `${value}`
|
|
238
|
+
- `{count, plural, one {# item} other {# items}}`
|
|
239
|
+
- `$t(common.save)`
|
|
240
|
+
- `%(total).2f`
|
|
201
241
|
|
|
202
242
|
Useful flags:
|
|
203
243
|
|
|
@@ -205,6 +245,10 @@ Useful flags:
|
|
|
205
245
|
- `--skip-placeholders`: copy placeholder-bearing strings unchanged
|
|
206
246
|
- `--send-placeholders`: send placeholder-bearing strings through translation after masking
|
|
207
247
|
- `--custom-regex <regex>`: add project-specific placeholder detection
|
|
248
|
+
- `--only-missing`: keep existing translated target values and translate only missing/source-copy/likely English values (default)
|
|
249
|
+
- `--translate-all`: re-translate every source string
|
|
250
|
+
|
|
251
|
+
Progress output is stage-aware for large files. Normal keys are reported as `Translating strings`, while preserve-mode placeholder work is reported as `Translating placeholder-safe text segments`; each progress update includes the current key path when available.
|
|
208
252
|
|
|
209
253
|
### Protected Terms and Keys
|
|
210
254
|
|
|
@@ -244,7 +288,7 @@ Useful flags:
|
|
|
244
288
|
- `--create-protection-file`
|
|
245
289
|
- `--no-protection`
|
|
246
290
|
|
|
247
|
-
Open Settings and choose `Auto Translate
|
|
291
|
+
Open Settings and choose `Auto Translate` to edit defaults for placeholder mode, translate-only-needed mode, concurrency, batch size, retry settings, report output, BOM output, protection file path, first-run setup prompt, and update prompt.
|
|
248
292
|
|
|
249
293
|
See [docs/auto-translate.md](./docs/auto-translate.md) for the full Auto Translate guide.
|
|
250
294
|
|
|
@@ -252,7 +296,7 @@ See [docs/auto-translate.md](./docs/auto-translate.md) for the full Auto Transla
|
|
|
252
296
|
|
|
253
297
|
Validation checks locale structure, completeness, placeholders, and content risks.
|
|
254
298
|
|
|
255
|
-
|
|
299
|
+
Validation warning types are specific:
|
|
256
300
|
|
|
257
301
|
- `Potential risky content`: URL, email address, or secret-like value
|
|
258
302
|
- `Possible untranslated English content`: target-language value appears to contain too much English
|
|
@@ -321,7 +365,7 @@ i18ntk-usage --source-dir ./src --i18n-dir ./locales --cleanup --dry-run-delete
|
|
|
321
365
|
```
|
|
322
366
|
|
|
323
367
|
Each dead key receives a confidence score (0.0–1.0) factoring:
|
|
324
|
-
-
|
|
368
|
+
- Unresolved dynamic key patterns (e.g., `` t(`prefix.${dynamic}`) ``) — lower score and listed in the usage report; simple consts, bounded arrays, object maps, and ternaries are expanded to exact keys where possible
|
|
325
369
|
- Key appears in source code comments or JSDoc — medium score
|
|
326
370
|
- Parent file recently modified (<30 days) — medium score
|
|
327
371
|
- No references found anywhere — high score (>0.8)
|
|
@@ -414,6 +458,16 @@ console.log(i18n.t('common.hello')); // loads common.json on first access
|
|
|
414
458
|
|
|
415
459
|
When `lazy: true`, the runtime builds a key-to-file manifest on first access and loads individual files on demand. Files are loaded once and cached. If the manifest is missing or incomplete, the runtime falls back to full eager loading for that language. Manifest size is capped at 100KB with path containment validation.
|
|
416
460
|
|
|
461
|
+
Production guidance:
|
|
462
|
+
|
|
463
|
+
- Prefer the object returned from `initRuntime()` instead of module-level `runtime.t()` in apps with multiple tenants, projects, or locale roots.
|
|
464
|
+
- Use `lazy: true` for large modular locale folders where lower steady-state memory matters more than a small first-key lookup cost.
|
|
465
|
+
- Use `preload: true` without `lazy` for small locale sets or latency-sensitive startup paths.
|
|
466
|
+
- Call `refresh(language)` after deploying or writing changed locale files so cached data and lazy manifests are rebuilt.
|
|
467
|
+
- Use per-call language overrides when rendering one-off alternate-language strings: `i18n.t('common.hello', {}, { language: 'de' })`.
|
|
468
|
+
- Use `translateBatch()` for small groups of labels and `clearCache()` / `getCacheInfo()` for cache maintenance and diagnostics.
|
|
469
|
+
- `i18ntk/runtime/enhanced` remains available for compatibility with existing async/encryption users, but new production integrations should start with `i18ntk/runtime`.
|
|
470
|
+
|
|
417
471
|
## Runtime API
|
|
418
472
|
|
|
419
473
|
Use `i18ntk/runtime` when an application needs to read locale JSON files at runtime.
|
|
@@ -436,6 +490,15 @@ console.log(i18n.getAvailableLanguages());
|
|
|
436
490
|
i18n.refresh('fr');
|
|
437
491
|
```
|
|
438
492
|
|
|
493
|
+
Useful production helpers:
|
|
494
|
+
|
|
495
|
+
```js
|
|
496
|
+
i18n.t('common.hello', {}, { language: 'de' }); // per-call language override
|
|
497
|
+
i18n.translateBatch(['menu.home', 'menu.settings']);
|
|
498
|
+
i18n.clearCache('fr');
|
|
499
|
+
console.log(i18n.getCacheInfo());
|
|
500
|
+
```
|
|
501
|
+
|
|
439
502
|
See [docs/runtime.md](./docs/runtime.md) for runtime details.
|
|
440
503
|
|
|
441
504
|
## Configuration
|
|
@@ -446,23 +509,27 @@ Example:
|
|
|
446
509
|
|
|
447
510
|
```json
|
|
448
511
|
{
|
|
449
|
-
"version": "4.
|
|
512
|
+
"version": "4.2.0",
|
|
450
513
|
"sourceDir": "./locales",
|
|
451
514
|
"i18nDir": "./locales",
|
|
452
515
|
"outputDir": "./i18ntk-reports",
|
|
453
516
|
"sourceLanguage": "en",
|
|
454
|
-
"defaultLanguages": ["de", "es", "fr", "ru"],
|
|
517
|
+
"defaultLanguages": ["en", "de", "es", "fr", "ru"],
|
|
518
|
+
"reports": {
|
|
519
|
+
"format": "markdown"
|
|
520
|
+
},
|
|
455
521
|
"englishContentThresholdPercent": 10,
|
|
456
522
|
"allowedEnglishTerms": ["BrandName", "PRODUCT_CODE"],
|
|
457
523
|
"autoTranslate": {
|
|
458
524
|
"placeholderMode": "preserve",
|
|
459
|
-
"concurrency":
|
|
525
|
+
"concurrency": 12,
|
|
460
526
|
"batchSize": 100,
|
|
461
527
|
"progressInterval": 25,
|
|
462
528
|
"retryCount": 3,
|
|
463
529
|
"retryDelay": 1000,
|
|
464
530
|
"timeout": 15000,
|
|
465
531
|
"dryRunFirst": true,
|
|
532
|
+
"onlyMissingOrEnglish": true,
|
|
466
533
|
"reportStdout": true,
|
|
467
534
|
"bom": false,
|
|
468
535
|
"protectionEnabled": true,
|
|
@@ -504,9 +571,7 @@ The public package manifest includes `readmeFilename: "README.md"`, and the rele
|
|
|
504
571
|
- [Auto Translate Guide](./docs/auto-translate.md)
|
|
505
572
|
- [Scanner Guide](./docs/scanner-guide.md)
|
|
506
573
|
- [Environment Variables](./docs/environment-variables.md)
|
|
507
|
-
- [Migration Guide
|
|
508
|
-
- [Migration Guide v3.1.1](./docs/migration-guide-v3.1.1.md)
|
|
509
|
-
- [Migration Guide v3.0.0](./docs/migration-guide-v3.0.0.md)
|
|
574
|
+
- [Migration Guide v4.2.0](./docs/migration-guide-v4.2.0.md)
|
|
510
575
|
|
|
511
576
|
## Security
|
|
512
577
|
|
package/SECURITY.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
The supported production line is `4.x`.
|
|
6
6
|
|
|
7
|
-
Versions earlier than `4.
|
|
7
|
+
Versions earlier than `4.2.0` are not recommended for production use because later releases include Auto Translate provider hardening, dynamic-require elimination, path-validation hardening, runtime language validation, lazy loading with manifest validation, incremental backup hash-chain verification, and post-4.0.0 critical bug fixes for runtime staleness, backup verification, and CLI flag parsing.
|
|
8
8
|
|
|
9
9
|
## Security Model
|
|
10
10
|
|
|
@@ -38,11 +38,19 @@ Socket.dev scans the published npm package and may flag the following alerts. Th
|
|
|
38
38
|
The v3.3.0 release **resolved** the previously actionable Socket.dev alert:
|
|
39
39
|
- **Dynamic require** — all 21 instances eliminated (20 converted to static string literals, 1 gated with `SecurityUtils.validatePath`).
|
|
40
40
|
|
|
41
|
-
The v4.0.0 release adds the following security hardening:
|
|
41
|
+
The v4.0.0 release adds the following security hardening:
|
|
42
42
|
- **Watch module**: all watched directories validated against project root with containment checks; capped at 50 directories.
|
|
43
43
|
- **Runtime lazy loading**: key-to-file manifest entries validated for path containment; manifest size capped at 100KB.
|
|
44
|
-
- **Incremental backups**: hash-chain verification before restore; chain depth capped at 10 increments.
|
|
45
|
-
- **Protection context rules**: DSL-parsed context rules — never raw user-controlled regex from config; bounded at 200 chars per rule, 100 rules total.
|
|
44
|
+
- **Incremental backups**: hash-chain verification before restore; chain depth capped at 10 increments; circular parent references detected.
|
|
45
|
+
- **Protection context rules**: DSL-parsed context rules — never raw user-controlled regex from config; bounded at 200 chars per rule, 100 rules total; Unicode-aware `\p{P}` word boundaries for non-ASCII language support.
|
|
46
|
+
- **Scanner multi-language detection**: source-language propagation fixed; stopword-less language profiles now still enforce valid-character ratios.
|
|
47
|
+
- **Usage dead key detection**: optimized O(n+m) comment scanning instead of O(n*m); all CLI boolean flags validated with strict `toBool()` conversion.
|
|
48
|
+
|
|
49
|
+
The v4.2.0 release adds the following security hardening:
|
|
50
|
+
- **Shared path validation**: artifact-like filenames no longer bypass base containment; cross-drive absolute paths and environment-added internal prefixes are constrained.
|
|
51
|
+
- **Backup restore**: backup entry names must be plain `.json` filenames and are restored through stable output-directory containment.
|
|
52
|
+
- **Runtime locale loading**: language identifiers are validated before locale path resolution.
|
|
53
|
+
- **Auto Translate networking**: IPv4-mapped IPv6 loopback/private hosts are blocked by provider URL validation.
|
|
46
54
|
|
|
47
55
|
## Reporting Vulnerabilities
|
|
48
56
|
|
|
@@ -66,7 +74,7 @@ Security reports are reviewed privately first. Confirmed issues should receive:
|
|
|
66
74
|
|
|
67
75
|
## User Guidance
|
|
68
76
|
|
|
69
|
-
- Keep i18ntk updated to `4.
|
|
77
|
+
- Keep i18ntk updated to `4.2.0` or newer.
|
|
70
78
|
- Do not commit `.i18ntk-config`, admin PIN files, backup directories, generated reports, logs, npm credentials, or secret material.
|
|
71
79
|
- Run i18ntk only in project directories you trust.
|
|
72
80
|
- Review generated translation changes before committing them.
|
package/main/i18ntk-analyze.js
CHANGED
|
@@ -13,9 +13,11 @@ const { loadTranslations, t } = require('../utils/i18n-helper');
|
|
|
13
13
|
const { getUnifiedConfig, parseCommonArgs, displayHelp } = require('../utils/config-helper');
|
|
14
14
|
const SecurityUtils = require('../utils/security');
|
|
15
15
|
const AdminCLI = require('../utils/admin-cli');
|
|
16
|
-
const watchLocales = require('../utils/watch-locales');
|
|
17
|
-
const JsonOutput = require('../utils/json-output');
|
|
18
|
-
const SetupEnforcer = require('../utils/setup-enforcer');
|
|
16
|
+
const watchLocales = require('../utils/watch-locales');
|
|
17
|
+
const JsonOutput = require('../utils/json-output');
|
|
18
|
+
const SetupEnforcer = require('../utils/setup-enforcer');
|
|
19
|
+
const configManager = require('../utils/config-manager');
|
|
20
|
+
const { normalizeReportFormat, writeReportFile } = require('../utils/report-writer');
|
|
19
21
|
|
|
20
22
|
// Ensure setup is complete before running
|
|
21
23
|
(async () => {
|
|
@@ -696,23 +698,11 @@ try {
|
|
|
696
698
|
return null;
|
|
697
699
|
}
|
|
698
700
|
|
|
699
|
-
|
|
700
|
-
const
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
if (!reportPath.startsWith(validatedOutputDir)) {
|
|
705
|
-
console.error('Invalid report path detected, potential directory traversal attack');
|
|
706
|
-
return null;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// Use safeWriteFile for secure file writing
|
|
710
|
-
const success = await SecurityUtils.safeWriteFile(reportPath, JSON.stringify(report, null, 2), process.cwd(), 'utf8');
|
|
711
|
-
if (!success) {
|
|
712
|
-
throw new Error(t('analyze.failedToWriteReportFile') || 'Failed to write report file securely');
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
return reportPath;
|
|
701
|
+
const safeLanguage = language.replace(/[^\w-]/g, '_');
|
|
702
|
+
const settings = configManager.getConfig ? configManager.getConfig() : {};
|
|
703
|
+
const format = normalizeReportFormat(this.config?.reports?.format || settings.reports?.format || this.config?.reportFormat || 'markdown');
|
|
704
|
+
const reportPath = await writeReportFile(validatedOutputDir, `translation-report-${safeLanguage}`, report, { format, title: `Translation Report ${safeLanguage.toUpperCase()}` });
|
|
705
|
+
return reportPath;
|
|
716
706
|
|
|
717
707
|
} catch (error) {
|
|
718
708
|
console.error(`Failed to save report for ${language}:`, error.message);
|