i18ntk 3.3.0 → 4.1.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 +84 -16
- package/README.md +160 -15
- package/SECURITY.md +16 -8
- package/main/i18ntk-backup.js +370 -73
- package/main/i18ntk-scanner.js +190 -49
- package/main/i18ntk-sizing.js +241 -79
- package/main/i18ntk-usage.js +221 -46
- package/main/i18ntk-validate.js +114 -5
- package/main/manage/commands/FixerCommand.js +23 -21
- package/main/manage/index.js +13 -7
- package/main/manage/services/FileManagementService.js +12 -6
- package/package.json +46 -2
- package/runtime/i18ntk.d.ts +22 -16
- package/runtime/index.d.ts +9 -7
- package/runtime/index.js +246 -50
- package/ui-locales/en.json +1 -1
- package/utils/translate/protection.js +153 -7
- package/utils/watch-locales.js +194 -36
package/CHANGELOG.md
CHANGED
|
@@ -5,17 +5,85 @@ 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
|
-
## [
|
|
8
|
+
## [4.1.0] - 2026-05-21
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Runtime: stale manifest entries (deleted files after manifest construction) no longer cause unhandled exceptions; loadedFiles set before load with try/catch guard.
|
|
12
|
+
- Runtime: `refresh()` now correctly clears the key manifest for the refreshed language, preventing stale file references.
|
|
13
|
+
- Runtime: null `baseDir` guard prevents cascading `validatePath(null)` errors in `loadKeyManifestFromDir`.
|
|
14
|
+
- 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.
|
|
15
|
+
- Backup: `cleanupOldBackups` and `handleCleanup` now preserve parent backups of incremental chains by scanning kept backups for `_meta.parent` references before deletion.
|
|
16
|
+
- Backup: `--incremental=false` is now correctly parsed as falsy (string-to-boolean conversion fixed).
|
|
17
|
+
- Backup: `buildRestoreChain` detects circular parent references via visited-set traversal.
|
|
18
|
+
- Sizing: `this.adminAuth` undefined crash in `run()` fixed — changed to correct `adminAuth` local variable.
|
|
19
|
+
- Sizing: duplicate `analyze()` method removed; format-based display logic (`--format=json` vs table) restored to the surviving method.
|
|
20
|
+
- Sizing: setup-check IIFE now guarded with `require.main === module`, preventing unexpected `process.exit()` on `require()`.
|
|
21
|
+
- Scanner: `frameworks.vanilla` key added to `getFrameworkSpecific` — no longer returns `undefined` for vanilla projects.
|
|
22
|
+
- Scanner: `--source-language` CLI flag now correctly propagates through config chain to `scanFile` and `generateSuggestion` (camelCase vs hyphen key mismatch fixed).
|
|
23
|
+
- Scanner: `isTextInLanguage` now always validates character ratio unconditionally even for no-stopword language profiles.
|
|
24
|
+
- Watch: `{ onChange: fn }` object-format callbacks are now properly subscribed to change/add/unlink events.
|
|
25
|
+
- Watch: debounce `setTimeout` timers are now stored per-watcher and cleared on `emitter.stop()`, preventing memory leaks and spurious I/O after stop.
|
|
26
|
+
- Watch: `'unlink'` events are now subscribed for backward-compatible plain-function callback users.
|
|
27
|
+
- Usage: duplicate `require.main === module` block removed (caused `TypeError: Identifier 'main' has already been declared` at execution).
|
|
28
|
+
- 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.
|
|
29
|
+
- Usage: `--cleanup=false` and `--dry-run-delete=false` now correctly parse as falsy via `toBool()` helper.
|
|
30
|
+
- Usage: broken `detectFrameworkPatterns()` call with `undefined` arguments removed.
|
|
31
|
+
- Usage: dead `return;` in `analyze()` removed so the result object is now actually returned.
|
|
32
|
+
- Validator: missing `try` block in `run()` added so errors are caught by the existing `catch(error)` handler.
|
|
33
|
+
- Validator: `--enforce-key-style=true/false` now correctly parsed (previously silently ignored due to `!includes('=')` guard).
|
|
34
|
+
- Validator: `flat` style no longer produces false positives for nested keys — validates only the leaf segment (last `.`-delimited part).
|
|
35
|
+
- Validator: `suggestKeyFix` for `flat` style now returns `segments.map(s => s.toLowerCase()).join('')` instead of camelCase.
|
|
36
|
+
- Validator: `getLanguageFiles` no longer crashes when `excludeFiles` config property is undefined.
|
|
37
|
+
- Validator: `enforceKeyStyle` now correctly propagated from CLI args to `this.config.enforceKeyStyle` in `run()`.
|
|
38
|
+
- Protection: `standalone` mode boundary check now handles opening/closing punctuation (`(`, `[`, `{`, `"`, `'`, `-`, `–`, `—`) and CJK marks (`。`, `、`, `」`).
|
|
39
|
+
- Protection: `\b` word-boundary assertions replaced with Unicode-aware `(^|[\s\p{P}])` / `([\s\p{P}]|$)` patterns with `u` flag for non-ASCII language support.
|
|
40
|
+
- Protection: `surrounded` context rule parser now uses `indexOf(',')` split instead of greedy `(.+,.+)` regex to correctly parse multi-word right-side expressions.
|
|
41
|
+
- Protection: `hasProtectionRules` no longer throws `TypeError` when `terms` property is undefined.
|
|
42
|
+
- Protection: `shouldPreserveWholeValue` now respects context rules by only matching `type === 'global'` entries.
|
|
43
|
+
- Manager option 7 ("Fix placeholder translations") now interpolates fixer status values correctly instead of printing raw `{languages}`, `{sourceDir}`, `{skipped}`, or `{totalIssues}` placeholders.
|
|
44
|
+
- Delete Reports settings now include cache cleanup targets.
|
|
45
|
+
- Public package metadata updated.
|
|
46
|
+
|
|
47
|
+
### Security
|
|
48
|
+
- Watch module: debounce timers properly cleaned up on stop and callback subscriptions corrected for object-format and unlink handlers.
|
|
49
|
+
- Runtime: loadedFiles lock-before-load pattern prevents duplicate I/O and stale manifest crash.
|
|
50
|
+
- Backup: circular parent reference detection; `--incremental=false` string truthy bypass closed.
|
|
51
|
+
- Sizing: adminAuth variable reference corrected; require()-time `process.exit()` guarded.
|
|
52
|
+
- Scanner: vanilla framework key prevents `undefined` return; stopword-less validRatio enforced.
|
|
53
|
+
- Usage: O(n+m) comment scanning prevents DoS via large codebase with many dead keys; `toBool()` prevents flag injection.
|
|
54
|
+
- Validator: try/catch pairing restored; `flat` leaf-segment prevents false-positive flood.
|
|
55
|
+
- Protection: Unicode-aware punctuation boundaries for CJK/Cyrillic/Arabic; standalone boundaries include the expanded punctuation set.
|
|
56
|
+
|
|
57
|
+
## [4.0.0] - 2026-05-21
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- **Sizing Expansion Prediction**: `i18ntk-sizing` now supports `--predict-expansion` flag that computes per-key character-count expansion ratios across languages and classifies them into Safe/Warning/Critical risk tiers for UI layout planning. Includes a built-in language-pair expansion reference table (EN→DE 35%, EN→RU 50%, EN→JA -40%, etc.).
|
|
61
|
+
- **Watch Hot Reload**: `utils/watch-locales.js` rewritten as an EventEmitter-compatible watcher with debouncing (300ms default) and SHA-256 hash tracking to skip no-change saves. Returns a callable watcher object with `change`, `add`, `unlink`, `error` events and `stop()`.
|
|
62
|
+
- **Usage Dead Key Detection**: `i18ntk-usage` adds `--cleanup` and `--dry-run-delete` flags that identify unused translation keys with confidence scores (0.0–1.0) factoring dynamic access patterns, comment references, and file recency. Produces a `.dead-keys.json` report for safe review before deletion.
|
|
63
|
+
- **Validator Key Naming Convention**: `i18ntk-validate` adds `--enforce-key-style` flag and `keyStyle` config setting supporting `dot.notation`, `snake_case`, `camelCase`, `kebab-case`, and `flat` conventions. Reports all violating keys with suggested canonical forms.
|
|
64
|
+
- **Scanner Multi-Language Detection**: `i18ntk-scanner` adds `--source-language` flag with character-class profiles for 12+ languages (English, German, French, Spanish, Japanese, Chinese, Russian, Korean, Arabic, Hindi, etc.). Language-specific stopword lists and key generation with transliteration for non-Latin scripts.
|
|
65
|
+
- **Backup Incremental Mode**: `i18ntk-backup` adds `--incremental` flag producing differential backups with SHA-256 file hashing, parent-chain metadata, and chained restore (oldest full → incremental diffs in order). `verify` validates the hash chain. Chain depth capped at 10.
|
|
66
|
+
- **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.
|
|
67
|
+
- **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.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
- `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.
|
|
9
71
|
|
|
10
72
|
### Changed
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
73
|
+
- `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.
|
|
74
|
+
- **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.
|
|
75
|
+
|
|
76
|
+
## [3.3.0] - 2026-05-20
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
- Auto Translate now supports `--provider google|deepl|libretranslate`; DeepL uses `DEEPL_API_KEY`, while LibreTranslate supports `LIBRETRANSLATE_URL` and optional `LIBRETRANSLATE_API_KEY`.
|
|
80
|
+
- Auto Translate provider networking now keeps HTTPS, host allowlist, response-size, private-network, and redacted security logging protections in place for additional providers.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
- `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.
|
|
84
|
+
|
|
85
|
+
### Security
|
|
86
|
+
- 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.
|
|
19
87
|
- Added `SecurityUtils.validatePath()` gate around the remaining dynamic `require()` in `i18ntk-translate.js` `loadCustomTranslateFn`.
|
|
20
88
|
- 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.
|
|
21
89
|
- Replaced direct `https.get` call in `utils/translate/api.js` with `safeHttpGet` from the safe-network wrapper.
|
|
@@ -27,18 +95,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
27
95
|
|
|
28
96
|
### Socket.dev Analysis Disclaimer
|
|
29
97
|
|
|
30
|
-
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**:
|
|
98
|
+
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**:
|
|
31
99
|
|
|
32
100
|
| Alert | Why it's expected |
|
|
33
101
|
|---|---|
|
|
34
|
-
| 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. |
|
|
102
|
+
| 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. |
|
|
35
103
|
| Environment variable access | Centralized through `env-manager.js` with a strict allowlist. Blocks `SECRET`, `PASSWORD`, `KEY`, `TOKEN`, `AWS_*`, `NPM_*`, and 15+ other patterns. |
|
|
36
104
|
| Filesystem access | Reads/writes only project locale files and reports within validated paths. All FS operations gated by `SecurityUtils.validatePath`. |
|
|
37
|
-
| URL strings | Hardcoded default provider URLs for Google, DeepL, and LibreTranslate used only for auto-translation. No external resource loading. |
|
|
38
|
-
|
|
39
|
-
The v3.3.0 release resolves the actionable dynamic-require alert by eliminating all 21 instances.
|
|
40
|
-
|
|
41
|
-
## [3.2.0] - 2026-05-16
|
|
105
|
+
| URL strings | Hardcoded default provider URLs for Google, DeepL, and LibreTranslate used only for auto-translation. No external resource loading. |
|
|
106
|
+
|
|
107
|
+
The v3.3.0 release resolves the actionable dynamic-require alert by eliminating all 21 instances.
|
|
108
|
+
|
|
109
|
+
## [3.2.0] - 2026-05-16
|
|
42
110
|
|
|
43
111
|
### Security
|
|
44
112
|
- **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
|
|
1
|
+
# i18ntk v4.1.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.1.0)
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -30,12 +30,20 @@ Requirements:
|
|
|
30
30
|
- npm `>=8.0.0`
|
|
31
31
|
- No runtime dependencies
|
|
32
32
|
|
|
33
|
-
## What's New in
|
|
33
|
+
## What's New in 4.1.0
|
|
34
34
|
|
|
35
|
-
- **
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
- **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.
|
|
36
|
+
|
|
37
|
+
## What's New in 4.0.0
|
|
38
|
+
|
|
39
|
+
- **SIZING**: `--predict-expansion` flag computes per-key expansion ratios across languages with Safe/Warning/Critical risk tiers for UI layout planning.
|
|
40
|
+
- **WATCH**: `watchLocales()` now returns an EventEmitter-compatible watcher with debounced `change`/`add`/`unlink`/`error` events and SHA-256 hash tracking.
|
|
41
|
+
- **USAGE**: `--cleanup` and `--dry-run-delete` flags identify dead translation keys with confidence scores.
|
|
42
|
+
- **VALIDATOR**: `--enforce-key-style` enforces dot.notation, snake_case, camelCase, kebab-case, or flat naming conventions.
|
|
43
|
+
- **SCANNER**: `--source-language` supports multi-language hardcoded text detection with 12+ language profiles.
|
|
44
|
+
- **BACKUP**: `--incremental` flag creates differential backups with SHA-256 hashing and chained restores.
|
|
45
|
+
- **RUNTIME**: `lazy: true` option defers locale file loading until first key access for lower memory usage.
|
|
46
|
+
- **PROTECTION**: Context-aware rules (`after:word`, `before:word`, `standalone`, `surrounded:left,right`) for precise term masking.
|
|
39
47
|
|
|
40
48
|
See [CHANGELOG.md](./CHANGELOG.md) for more release details.
|
|
41
49
|
|
|
@@ -214,7 +222,12 @@ Example `i18ntk-auto-translate.json`:
|
|
|
214
222
|
```json
|
|
215
223
|
{
|
|
216
224
|
"version": 1,
|
|
217
|
-
"terms": [
|
|
225
|
+
"terms": [
|
|
226
|
+
"BrandName",
|
|
227
|
+
"PRODUCT_CODE",
|
|
228
|
+
{ "value": "OK", "context": "after:Click|Press|Tap" },
|
|
229
|
+
{ "value": "API", "context": "standalone" }
|
|
230
|
+
],
|
|
218
231
|
"keys": ["app.brandName", "legal.companyName", "product.*.symbol"],
|
|
219
232
|
"values": ["BrandName Ltd", "support@example.com"],
|
|
220
233
|
"patterns": ["[A-Z]{2,}-\\d+"]
|
|
@@ -222,6 +235,8 @@ Example `i18ntk-auto-translate.json`:
|
|
|
222
235
|
```
|
|
223
236
|
|
|
224
237
|
- `terms` are masked before translation and restored exactly afterward.
|
|
238
|
+
- **Plain strings**: masked everywhere (backward compatible).
|
|
239
|
+
- **Context objects**: masked only in specific contexts (`after:word`, `before:word`, `standalone`, `surrounded:left,right`).
|
|
225
240
|
- `keys` are exact key paths or `*` wildcard paths copied unchanged.
|
|
226
241
|
- `values` are exact source values copied unchanged.
|
|
227
242
|
- `patterns` are JavaScript regex strings for advanced protected substrings.
|
|
@@ -272,6 +287,136 @@ i18ntk-sizing --source-dir ./locales --detailed --output-dir ./i18ntk-reports
|
|
|
272
287
|
|
|
273
288
|
Use `--detailed` to print per-file rows in the terminal.
|
|
274
289
|
|
|
290
|
+
### Expansion Prediction (New in 4.0.0)
|
|
291
|
+
|
|
292
|
+
Predict UI layout overflow risk by analyzing per-key character-count expansion across languages:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
i18ntk-sizing --source-dir ./locales --predict-expansion --output-report
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Expansion ratios are classified into risk tiers:
|
|
299
|
+
|
|
300
|
+
- **Safe** (<30% expansion): no UI impact expected
|
|
301
|
+
- **Warning** (30–50%): may overflow in tight layouts — test on target languages
|
|
302
|
+
- **Critical** (>50%): high risk of truncation — review UI element sizing
|
|
303
|
+
|
|
304
|
+
The report includes a built-in language-pair expansion reference table (EN→DE +35%, EN→RU +50%, EN→JA −40%, etc.) and lists the top-30 most-expanded keys.
|
|
305
|
+
|
|
306
|
+
## Scanner: Multi-Language Detection (New in 4.0.0)
|
|
307
|
+
|
|
308
|
+
`i18ntk-scanner` now supports detecting hardcoded text in multiple source languages beyond English:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
i18ntk-scanner --source-dir ./src --source-language de
|
|
312
|
+
i18ntk-scanner --source-dir ./src --source-language ja --output-report
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Supported language profiles (12+): English, German, French, Spanish, Japanese, Chinese, Russian, Korean, Arabic, Hindi, and more. Each profile includes language-specific character ranges, stopword lists for false-positive filtering, and transliteration rules for key generation.
|
|
316
|
+
|
|
317
|
+
## Usage: Dead Key Detection (New in 4.0.0)
|
|
318
|
+
|
|
319
|
+
`i18ntk-usage` can identify translation keys that are defined but never referenced in source code:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
i18ntk-usage --source-dir ./src --i18n-dir ./locales --cleanup
|
|
323
|
+
i18ntk-usage --source-dir ./src --i18n-dir ./locales --cleanup --dry-run-delete
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Each dead key receives a confidence score (0.0–1.0) factoring:
|
|
327
|
+
- Dynamic key patterns (e.g., `` t(`prefix.${dynamic}`) ``) — lower score
|
|
328
|
+
- Key appears in source code comments or JSDoc — medium score
|
|
329
|
+
- Parent file recently modified (<30 days) — medium score
|
|
330
|
+
- No references found anywhere — high score (>0.8)
|
|
331
|
+
|
|
332
|
+
The `--dry-run-delete` flag writes a `.dead-keys.json` report for review before any destructive action.
|
|
333
|
+
|
|
334
|
+
## Validator: Key Naming Conventions (New in 4.0.0)
|
|
335
|
+
|
|
336
|
+
Enforce consistent translation key naming across your project:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
i18ntk-validate --enforce-key-style
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Configure the expected style in `.i18ntk-config`:
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"keyStyle": "dot.notation"
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Supported styles: `dot.notation`, `snake_case`, `camelCase`, `kebab-case`, `flat`. Violations are reported as warnings with suggested canonical forms.
|
|
351
|
+
|
|
352
|
+
## Watch: Hot Reload (New in 4.0.0)
|
|
353
|
+
|
|
354
|
+
`utils/watch-locales.js` now provides debounced file watching with EventEmitter support:
|
|
355
|
+
|
|
356
|
+
```js
|
|
357
|
+
const watchLocales = require('i18ntk/utils/watch-locales');
|
|
358
|
+
const watcher = watchLocales('./locales');
|
|
359
|
+
|
|
360
|
+
watcher.on('change', (filePath) => {
|
|
361
|
+
console.log('Locale changed:', filePath);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
watcher.on('add', (filePath) => {
|
|
365
|
+
console.log('Locale added:', filePath);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Later:
|
|
369
|
+
watcher.stop();
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Features: 300ms debounce (configurable), SHA-256 hash tracking to skip no-change saves, and a maximum of 50 watched directories.
|
|
373
|
+
|
|
374
|
+
### Migration
|
|
375
|
+
|
|
376
|
+
The `watchLocales` return value gained EventEmitter methods in v4.0.0. Existing stop-function usage still works:
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
const stop = watchLocales('./locales', onChange);
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Can be updated to:
|
|
383
|
+
|
|
384
|
+
```js
|
|
385
|
+
const watcher = watchLocales('./locales');
|
|
386
|
+
watcher.on('change', onChange);
|
|
387
|
+
watcher.stop();
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Passing a callback as the second argument is still supported — it auto-subscribes to `change` and `add` events.
|
|
391
|
+
|
|
392
|
+
## Backup: Incremental Mode (New in 4.0.0)
|
|
393
|
+
|
|
394
|
+
Create differential backups that only include changed files:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
i18ntk-backup create ./locales --incremental
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Incremental backups store SHA-256 hashes per file and a parent-chain reference. Restoring an incremental backup automatically chains from the oldest full backup through each incremental diff in order. Chain depth is capped at 10 increments. Use `verify` to validate the hash chain.
|
|
401
|
+
|
|
402
|
+
## Runtime: Lazy Loading (New in 4.0.0)
|
|
403
|
+
|
|
404
|
+
Reduce memory usage by deferring locale file loads until first key access:
|
|
405
|
+
|
|
406
|
+
```js
|
|
407
|
+
const runtime = require('i18ntk/runtime');
|
|
408
|
+
|
|
409
|
+
const i18n = runtime.initRuntime({
|
|
410
|
+
baseDir: './locales',
|
|
411
|
+
language: 'en',
|
|
412
|
+
lazy: true
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
console.log(i18n.t('common.hello')); // loads common.json on first access
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
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.
|
|
419
|
+
|
|
275
420
|
## Runtime API
|
|
276
421
|
|
|
277
422
|
Use `i18ntk/runtime` when an application needs to read locale JSON files at runtime.
|
|
@@ -279,7 +424,7 @@ Use `i18ntk/runtime` when an application needs to read locale JSON files at runt
|
|
|
279
424
|
```js
|
|
280
425
|
const runtime = require('i18ntk/runtime');
|
|
281
426
|
|
|
282
|
-
runtime.initRuntime({
|
|
427
|
+
const i18n = runtime.initRuntime({
|
|
283
428
|
baseDir: './locales',
|
|
284
429
|
language: 'en',
|
|
285
430
|
fallbackLanguage: 'en',
|
|
@@ -287,11 +432,11 @@ runtime.initRuntime({
|
|
|
287
432
|
preload: true
|
|
288
433
|
});
|
|
289
434
|
|
|
290
|
-
console.log(
|
|
291
|
-
|
|
292
|
-
console.log(
|
|
293
|
-
console.log(
|
|
294
|
-
|
|
435
|
+
console.log(i18n.t('common.hello'));
|
|
436
|
+
i18n.setLanguage('fr');
|
|
437
|
+
console.log(i18n.getLanguage());
|
|
438
|
+
console.log(i18n.getAvailableLanguages());
|
|
439
|
+
i18n.refresh('fr');
|
|
295
440
|
```
|
|
296
441
|
|
|
297
442
|
See [docs/runtime.md](./docs/runtime.md) for runtime details.
|
|
@@ -304,7 +449,7 @@ Example:
|
|
|
304
449
|
|
|
305
450
|
```json
|
|
306
451
|
{
|
|
307
|
-
"version": "
|
|
452
|
+
"version": "4.1.0",
|
|
308
453
|
"sourceDir": "./locales",
|
|
309
454
|
"i18nDir": "./locales",
|
|
310
455
|
"outputDir": "./i18ntk-reports",
|
package/SECURITY.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Security Policy
|
|
2
2
|
|
|
3
|
-
## Supported Versions
|
|
4
|
-
|
|
5
|
-
The supported production line is `
|
|
6
|
-
|
|
7
|
-
Versions earlier than `
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
The supported production line is `4.x`.
|
|
6
|
+
|
|
7
|
+
Versions earlier than `4.1.0` are not recommended for production use because later releases include Auto Translate provider hardening, dynamic-require elimination, path-validation hardening, 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
|
|
|
@@ -35,8 +35,16 @@ Socket.dev scans the published npm package and may flag the following alerts. Th
|
|
|
35
35
|
| **Filesystem access** | Reads/writes locale JSON files, config files, and reports within the user's project. Core function of the toolkit. | All FS operations are gated by `SecurityUtils.validatePath()` with path-traversal detection, symlink resolution, and base-path containment checks. |
|
|
36
36
|
| **URL strings** | Contains hardcoded translation provider endpoint URLs for Google, DeepL, and LibreTranslate defaults. | Only used when user invokes `i18ntk-translate`. Custom provider URLs remain HTTPS-only and are validated before use. |
|
|
37
37
|
|
|
38
|
-
The v3.3.0 release **resolved** the previously actionable Socket.dev alert:
|
|
39
|
-
- **Dynamic require** — all 21 instances eliminated (20 converted to static string literals, 1 gated with `SecurityUtils.validatePath`).
|
|
38
|
+
The v3.3.0 release **resolved** the previously actionable Socket.dev alert:
|
|
39
|
+
- **Dynamic require** — all 21 instances eliminated (20 converted to static string literals, 1 gated with `SecurityUtils.validatePath`).
|
|
40
|
+
|
|
41
|
+
The v4.0.0 release adds the following security hardening:
|
|
42
|
+
- **Watch module**: all watched directories validated against project root with containment checks; capped at 50 directories.
|
|
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; 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.
|
|
40
48
|
|
|
41
49
|
## Reporting Vulnerabilities
|
|
42
50
|
|
|
@@ -60,7 +68,7 @@ Security reports are reviewed privately first. Confirmed issues should receive:
|
|
|
60
68
|
|
|
61
69
|
## User Guidance
|
|
62
70
|
|
|
63
|
-
- Keep i18ntk updated to `
|
|
71
|
+
- Keep i18ntk updated to `4.1.0` or newer.
|
|
64
72
|
- Do not commit `.i18ntk-config`, admin PIN files, backup directories, generated reports, logs, npm credentials, or secret material.
|
|
65
73
|
- Run i18ntk only in project directories you trust.
|
|
66
74
|
- Review generated translation changes before committing them.
|