i18ntk 3.3.0 → 4.0.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 +29 -2
- package/README.md +157 -15
- package/SECURITY.md +14 -8
- package/main/i18ntk-backup.js +305 -62
- package/main/i18ntk-scanner.js +188 -49
- package/main/i18ntk-sizing.js +223 -29
- package/main/i18ntk-usage.js +203 -3
- package/main/i18ntk-validate.js +107 -3
- 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 +2 -2
- package/runtime/i18ntk.d.ts +22 -16
- package/runtime/index.d.ts +9 -7
- package/runtime/index.js +240 -50
- package/ui-locales/en.json +1 -1
- package/utils/translate/protection.js +147 -6
- package/utils/watch-locales.js +183 -36
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [4.0.0] - 2026-05-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **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.).
|
|
12
|
+
- **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()`.
|
|
13
|
+
- **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.
|
|
14
|
+
- **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.
|
|
15
|
+
- **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.
|
|
16
|
+
- **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.
|
|
17
|
+
- **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
|
+
- **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
|
+
|
|
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.
|
|
7
23
|
|
|
8
|
-
|
|
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.
|
|
26
|
+
- **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
|
+
|
|
28
|
+
### Security
|
|
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
|
|
9
36
|
|
|
10
37
|
### Changed
|
|
11
38
|
- Auto Translate now supports `--provider google|deepl|libretranslate`; DeepL uses `DEEPL_API_KEY`, while LibreTranslate supports `LIBRETRANSLATE_URL` and optional `LIBRETRANSLATE_API_KEY`.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# i18ntk
|
|
1
|
+
# i18ntk v4.0.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.0.0)
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -30,12 +30,17 @@ 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.0.0
|
|
34
34
|
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
35
|
+
- **SIZING**: `--predict-expansion` flag computes per-key expansion ratios across languages with Safe/Warning/Critical risk tiers for UI layout planning.
|
|
36
|
+
- **WATCH**: `watchLocales()` now returns an EventEmitter-compatible watcher with debounced `change`/`add`/`unlink`/`error` events and SHA-256 hash tracking.
|
|
37
|
+
- **USAGE**: `--cleanup` and `--dry-run-delete` flags identify dead translation keys with confidence scores.
|
|
38
|
+
- **VALIDATOR**: `--enforce-key-style` enforces dot.notation, snake_case, camelCase, kebab-case, or flat naming conventions.
|
|
39
|
+
- **SCANNER**: `--source-language` supports multi-language hardcoded text detection with 12+ language profiles.
|
|
40
|
+
- **BACKUP**: `--incremental` flag creates differential backups with SHA-256 hashing and chained restores.
|
|
41
|
+
- **RUNTIME**: `lazy: true` option defers locale file loading until first key access for lower memory usage.
|
|
42
|
+
- **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.
|
|
39
44
|
|
|
40
45
|
See [CHANGELOG.md](./CHANGELOG.md) for more release details.
|
|
41
46
|
|
|
@@ -214,7 +219,12 @@ Example `i18ntk-auto-translate.json`:
|
|
|
214
219
|
```json
|
|
215
220
|
{
|
|
216
221
|
"version": 1,
|
|
217
|
-
"terms": [
|
|
222
|
+
"terms": [
|
|
223
|
+
"BrandName",
|
|
224
|
+
"PRODUCT_CODE",
|
|
225
|
+
{ "value": "OK", "context": "after:Click|Press|Tap" },
|
|
226
|
+
{ "value": "API", "context": "standalone" }
|
|
227
|
+
],
|
|
218
228
|
"keys": ["app.brandName", "legal.companyName", "product.*.symbol"],
|
|
219
229
|
"values": ["BrandName Ltd", "support@example.com"],
|
|
220
230
|
"patterns": ["[A-Z]{2,}-\\d+"]
|
|
@@ -222,6 +232,8 @@ Example `i18ntk-auto-translate.json`:
|
|
|
222
232
|
```
|
|
223
233
|
|
|
224
234
|
- `terms` are masked before translation and restored exactly afterward.
|
|
235
|
+
- **Plain strings**: masked everywhere (backward compatible).
|
|
236
|
+
- **Context objects**: masked only in specific contexts (`after:word`, `before:word`, `standalone`, `surrounded:left,right`).
|
|
225
237
|
- `keys` are exact key paths or `*` wildcard paths copied unchanged.
|
|
226
238
|
- `values` are exact source values copied unchanged.
|
|
227
239
|
- `patterns` are JavaScript regex strings for advanced protected substrings.
|
|
@@ -272,6 +284,136 @@ i18ntk-sizing --source-dir ./locales --detailed --output-dir ./i18ntk-reports
|
|
|
272
284
|
|
|
273
285
|
Use `--detailed` to print per-file rows in the terminal.
|
|
274
286
|
|
|
287
|
+
### Expansion Prediction (New in 4.0.0)
|
|
288
|
+
|
|
289
|
+
Predict UI layout overflow risk by analyzing per-key character-count expansion across languages:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
i18ntk-sizing --source-dir ./locales --predict-expansion --output-report
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Expansion ratios are classified into risk tiers:
|
|
296
|
+
|
|
297
|
+
- **Safe** (<30% expansion): no UI impact expected
|
|
298
|
+
- **Warning** (30–50%): may overflow in tight layouts — test on target languages
|
|
299
|
+
- **Critical** (>50%): high risk of truncation — review UI element sizing
|
|
300
|
+
|
|
301
|
+
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.
|
|
302
|
+
|
|
303
|
+
## Scanner: Multi-Language Detection (New in 4.0.0)
|
|
304
|
+
|
|
305
|
+
`i18ntk-scanner` now supports detecting hardcoded text in multiple source languages beyond English:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
i18ntk-scanner --source-dir ./src --source-language de
|
|
309
|
+
i18ntk-scanner --source-dir ./src --source-language ja --output-report
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
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.
|
|
313
|
+
|
|
314
|
+
## Usage: Dead Key Detection (New in 4.0.0)
|
|
315
|
+
|
|
316
|
+
`i18ntk-usage` can identify translation keys that are defined but never referenced in source code:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
i18ntk-usage --source-dir ./src --i18n-dir ./locales --cleanup
|
|
320
|
+
i18ntk-usage --source-dir ./src --i18n-dir ./locales --cleanup --dry-run-delete
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Each dead key receives a confidence score (0.0–1.0) factoring:
|
|
324
|
+
- Dynamic key patterns (e.g., `` t(`prefix.${dynamic}`) ``) — lower score
|
|
325
|
+
- Key appears in source code comments or JSDoc — medium score
|
|
326
|
+
- Parent file recently modified (<30 days) — medium score
|
|
327
|
+
- No references found anywhere — high score (>0.8)
|
|
328
|
+
|
|
329
|
+
The `--dry-run-delete` flag writes a `.dead-keys.json` report for review before any destructive action.
|
|
330
|
+
|
|
331
|
+
## Validator: Key Naming Conventions (New in 4.0.0)
|
|
332
|
+
|
|
333
|
+
Enforce consistent translation key naming across your project:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
i18ntk-validate --enforce-key-style
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Configure the expected style in `.i18ntk-config`:
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"keyStyle": "dot.notation"
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Supported styles: `dot.notation`, `snake_case`, `camelCase`, `kebab-case`, `flat`. Violations are reported as warnings with suggested canonical forms.
|
|
348
|
+
|
|
349
|
+
## Watch: Hot Reload (New in 4.0.0)
|
|
350
|
+
|
|
351
|
+
`utils/watch-locales.js` now provides debounced file watching with EventEmitter support:
|
|
352
|
+
|
|
353
|
+
```js
|
|
354
|
+
const watchLocales = require('i18ntk/utils/watch-locales');
|
|
355
|
+
const watcher = watchLocales('./locales');
|
|
356
|
+
|
|
357
|
+
watcher.on('change', (filePath) => {
|
|
358
|
+
console.log('Locale changed:', filePath);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
watcher.on('add', (filePath) => {
|
|
362
|
+
console.log('Locale added:', filePath);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Later:
|
|
366
|
+
watcher.stop();
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Features: 300ms debounce (configurable), SHA-256 hash tracking to skip no-change saves, and a maximum of 50 watched directories.
|
|
370
|
+
|
|
371
|
+
### Migration
|
|
372
|
+
|
|
373
|
+
The `watchLocales` return value gained EventEmitter methods in v4.0.0. Existing stop-function usage still works:
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
const stop = watchLocales('./locales', onChange);
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Can be updated to:
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
const watcher = watchLocales('./locales');
|
|
383
|
+
watcher.on('change', onChange);
|
|
384
|
+
watcher.stop();
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Passing a callback as the second argument is still supported — it auto-subscribes to `change` and `add` events.
|
|
388
|
+
|
|
389
|
+
## Backup: Incremental Mode (New in 4.0.0)
|
|
390
|
+
|
|
391
|
+
Create differential backups that only include changed files:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
i18ntk-backup create ./locales --incremental
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
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.
|
|
398
|
+
|
|
399
|
+
## Runtime: Lazy Loading (New in 4.0.0)
|
|
400
|
+
|
|
401
|
+
Reduce memory usage by deferring locale file loads until first key access:
|
|
402
|
+
|
|
403
|
+
```js
|
|
404
|
+
const runtime = require('i18ntk/runtime');
|
|
405
|
+
|
|
406
|
+
const i18n = runtime.initRuntime({
|
|
407
|
+
baseDir: './locales',
|
|
408
|
+
language: 'en',
|
|
409
|
+
lazy: true
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
console.log(i18n.t('common.hello')); // loads common.json on first access
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
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
|
+
|
|
275
417
|
## Runtime API
|
|
276
418
|
|
|
277
419
|
Use `i18ntk/runtime` when an application needs to read locale JSON files at runtime.
|
|
@@ -279,7 +421,7 @@ Use `i18ntk/runtime` when an application needs to read locale JSON files at runt
|
|
|
279
421
|
```js
|
|
280
422
|
const runtime = require('i18ntk/runtime');
|
|
281
423
|
|
|
282
|
-
runtime.initRuntime({
|
|
424
|
+
const i18n = runtime.initRuntime({
|
|
283
425
|
baseDir: './locales',
|
|
284
426
|
language: 'en',
|
|
285
427
|
fallbackLanguage: 'en',
|
|
@@ -287,11 +429,11 @@ runtime.initRuntime({
|
|
|
287
429
|
preload: true
|
|
288
430
|
});
|
|
289
431
|
|
|
290
|
-
console.log(
|
|
291
|
-
|
|
292
|
-
console.log(
|
|
293
|
-
console.log(
|
|
294
|
-
|
|
432
|
+
console.log(i18n.t('common.hello'));
|
|
433
|
+
i18n.setLanguage('fr');
|
|
434
|
+
console.log(i18n.getLanguage());
|
|
435
|
+
console.log(i18n.getAvailableLanguages());
|
|
436
|
+
i18n.refresh('fr');
|
|
295
437
|
```
|
|
296
438
|
|
|
297
439
|
See [docs/runtime.md](./docs/runtime.md) for runtime details.
|
|
@@ -304,7 +446,7 @@ Example:
|
|
|
304
446
|
|
|
305
447
|
```json
|
|
306
448
|
{
|
|
307
|
-
"version": "
|
|
449
|
+
"version": "4.0.0",
|
|
308
450
|
"sourceDir": "./locales",
|
|
309
451
|
"i18nDir": "./locales",
|
|
310
452
|
"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.0.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, and incremental backup hash-chain verification.
|
|
8
8
|
|
|
9
9
|
## Security Model
|
|
10
10
|
|
|
@@ -35,8 +35,14 @@ 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.
|
|
45
|
+
- **Protection context rules**: DSL-parsed context rules — never raw user-controlled regex from config; bounded at 200 chars per rule, 100 rules total.
|
|
40
46
|
|
|
41
47
|
## Reporting Vulnerabilities
|
|
42
48
|
|
|
@@ -60,7 +66,7 @@ Security reports are reviewed privately first. Confirmed issues should receive:
|
|
|
60
66
|
|
|
61
67
|
## User Guidance
|
|
62
68
|
|
|
63
|
-
- Keep i18ntk updated to `
|
|
69
|
+
- Keep i18ntk updated to `4.0.0` or newer.
|
|
64
70
|
- Do not commit `.i18ntk-config`, admin PIN files, backup directories, generated reports, logs, npm credentials, or secret material.
|
|
65
71
|
- Run i18ntk only in project directories you trust.
|
|
66
72
|
- Review generated translation changes before committing them.
|