i18next-cli 0.9.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +489 -0
  4. package/dist/cjs/cli.js +2 -0
  5. package/dist/cjs/config.js +1 -0
  6. package/dist/cjs/extractor/core/extractor.js +1 -0
  7. package/dist/cjs/extractor/core/key-finder.js +1 -0
  8. package/dist/cjs/extractor/core/translation-manager.js +1 -0
  9. package/dist/cjs/extractor/parsers/ast-visitors.js +1 -0
  10. package/dist/cjs/extractor/parsers/comment-parser.js +1 -0
  11. package/dist/cjs/extractor/parsers/jsx-parser.js +1 -0
  12. package/dist/cjs/extractor/plugin-manager.js +1 -0
  13. package/dist/cjs/heuristic-config.js +1 -0
  14. package/dist/cjs/index.js +1 -0
  15. package/dist/cjs/init.js +1 -0
  16. package/dist/cjs/linter.js +1 -0
  17. package/dist/cjs/locize.js +1 -0
  18. package/dist/cjs/migrator.js +1 -0
  19. package/dist/cjs/package.json +1 -0
  20. package/dist/cjs/status.js +1 -0
  21. package/dist/cjs/syncer.js +1 -0
  22. package/dist/cjs/types-generator.js +1 -0
  23. package/dist/cjs/utils/file-utils.js +1 -0
  24. package/dist/cjs/utils/logger.js +1 -0
  25. package/dist/cjs/utils/nested-object.js +1 -0
  26. package/dist/cjs/utils/validation.js +1 -0
  27. package/dist/esm/cli.js +2 -0
  28. package/dist/esm/config.js +1 -0
  29. package/dist/esm/extractor/core/extractor.js +1 -0
  30. package/dist/esm/extractor/core/key-finder.js +1 -0
  31. package/dist/esm/extractor/core/translation-manager.js +1 -0
  32. package/dist/esm/extractor/parsers/ast-visitors.js +1 -0
  33. package/dist/esm/extractor/parsers/comment-parser.js +1 -0
  34. package/dist/esm/extractor/parsers/jsx-parser.js +1 -0
  35. package/dist/esm/extractor/plugin-manager.js +1 -0
  36. package/dist/esm/heuristic-config.js +1 -0
  37. package/dist/esm/index.js +1 -0
  38. package/dist/esm/init.js +1 -0
  39. package/dist/esm/linter.js +1 -0
  40. package/dist/esm/locize.js +1 -0
  41. package/dist/esm/migrator.js +1 -0
  42. package/dist/esm/status.js +1 -0
  43. package/dist/esm/syncer.js +1 -0
  44. package/dist/esm/types-generator.js +1 -0
  45. package/dist/esm/utils/file-utils.js +1 -0
  46. package/dist/esm/utils/logger.js +1 -0
  47. package/dist/esm/utils/nested-object.js +1 -0
  48. package/dist/esm/utils/validation.js +1 -0
  49. package/package.json +81 -0
  50. package/src/cli.ts +166 -0
  51. package/src/config.ts +158 -0
  52. package/src/extractor/core/extractor.ts +195 -0
  53. package/src/extractor/core/key-finder.ts +70 -0
  54. package/src/extractor/core/translation-manager.ts +115 -0
  55. package/src/extractor/index.ts +7 -0
  56. package/src/extractor/parsers/ast-visitors.ts +637 -0
  57. package/src/extractor/parsers/comment-parser.ts +125 -0
  58. package/src/extractor/parsers/jsx-parser.ts +166 -0
  59. package/src/extractor/plugin-manager.ts +54 -0
  60. package/src/extractor.ts +15 -0
  61. package/src/heuristic-config.ts +64 -0
  62. package/src/index.ts +12 -0
  63. package/src/init.ts +156 -0
  64. package/src/linter.ts +191 -0
  65. package/src/locize.ts +251 -0
  66. package/src/migrator.ts +139 -0
  67. package/src/status.ts +192 -0
  68. package/src/syncer.ts +114 -0
  69. package/src/types-generator.ts +116 -0
  70. package/src/types.ts +312 -0
  71. package/src/utils/file-utils.ts +81 -0
  72. package/src/utils/logger.ts +36 -0
  73. package/src/utils/nested-object.ts +113 -0
  74. package/src/utils/validation.ts +69 -0
  75. package/tryme.js +8 -0
  76. package/tsconfig.json +71 -0
  77. package/types/cli.d.ts +3 -0
  78. package/types/cli.d.ts.map +1 -0
  79. package/types/config.d.ts +50 -0
  80. package/types/config.d.ts.map +1 -0
  81. package/types/extractor/core/extractor.d.ts +66 -0
  82. package/types/extractor/core/extractor.d.ts.map +1 -0
  83. package/types/extractor/core/key-finder.d.ts +31 -0
  84. package/types/extractor/core/key-finder.d.ts.map +1 -0
  85. package/types/extractor/core/translation-manager.d.ts +31 -0
  86. package/types/extractor/core/translation-manager.d.ts.map +1 -0
  87. package/types/extractor/index.d.ts +8 -0
  88. package/types/extractor/index.d.ts.map +1 -0
  89. package/types/extractor/parsers/ast-visitors.d.ts +235 -0
  90. package/types/extractor/parsers/ast-visitors.d.ts.map +1 -0
  91. package/types/extractor/parsers/comment-parser.d.ts +24 -0
  92. package/types/extractor/parsers/comment-parser.d.ts.map +1 -0
  93. package/types/extractor/parsers/jsx-parser.d.ts +35 -0
  94. package/types/extractor/parsers/jsx-parser.d.ts.map +1 -0
  95. package/types/extractor/plugin-manager.d.ts +37 -0
  96. package/types/extractor/plugin-manager.d.ts.map +1 -0
  97. package/types/extractor.d.ts +7 -0
  98. package/types/extractor.d.ts.map +1 -0
  99. package/types/heuristic-config.d.ts +10 -0
  100. package/types/heuristic-config.d.ts.map +1 -0
  101. package/types/index.d.ts +4 -0
  102. package/types/index.d.ts.map +1 -0
  103. package/types/init.d.ts +29 -0
  104. package/types/init.d.ts.map +1 -0
  105. package/types/linter.d.ts +33 -0
  106. package/types/linter.d.ts.map +1 -0
  107. package/types/locize.d.ts +5 -0
  108. package/types/locize.d.ts.map +1 -0
  109. package/types/migrator.d.ts +37 -0
  110. package/types/migrator.d.ts.map +1 -0
  111. package/types/status.d.ts +20 -0
  112. package/types/status.d.ts.map +1 -0
  113. package/types/syncer.d.ts +33 -0
  114. package/types/syncer.d.ts.map +1 -0
  115. package/types/types-generator.d.ts +29 -0
  116. package/types/types-generator.d.ts.map +1 -0
  117. package/types/types.d.ts +268 -0
  118. package/types/types.d.ts.map +1 -0
  119. package/types/utils/file-utils.d.ts +61 -0
  120. package/types/utils/file-utils.d.ts.map +1 -0
  121. package/types/utils/logger.d.ts +34 -0
  122. package/types/utils/logger.d.ts.map +1 -0
  123. package/types/utils/nested-object.d.ts +71 -0
  124. package/types/utils/nested-object.d.ts.map +1 -0
  125. package/types/utils/validation.d.ts +47 -0
  126. package/types/utils/validation.d.ts.map +1 -0
  127. package/vitest.config.ts +13 -0
@@ -0,0 +1,10 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ /**
3
+ * Attempts to automatically detect the project's i18n structure by searching for
4
+ * common translation file locations.
5
+ *
6
+ * @returns A promise that resolves to a partial I18nextToolkitConfig if detection
7
+ * is successful, otherwise null.
8
+ */
9
+ export declare function detectConfig(): Promise<Partial<I18nextToolkitConfig> | null>;
10
+ //# sourceMappingURL=heuristic-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heuristic-config.d.ts","sourceRoot":"","sources":["../src/heuristic-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAcnD;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAK,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,CAuCnF"}
@@ -0,0 +1,4 @@
1
+ export type { I18nextToolkitConfig, Plugin, PluginContext, ExtractedKey } from './types';
2
+ export { defineConfig } from './config';
3
+ export { extract, findKeys, getTranslations } from './extractor';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,MAAM,EACN,aAAa,EACb,YAAY,EACb,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EACL,OAAO,EACP,QAAQ,EACR,eAAe,EAChB,MAAM,aAAa,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Interactive setup wizard for creating a new i18next-cli configuration file.
3
+ *
4
+ * This function provides a guided setup experience that:
5
+ * 1. Asks the user for their preferred configuration file type (TypeScript or JavaScript)
6
+ * 2. Collects basic project settings (locales, input patterns, output paths)
7
+ * 3. Detects the project module system (ESM vs CommonJS) for JavaScript files
8
+ * 4. Generates an appropriate configuration file with proper syntax
9
+ * 5. Provides helpful defaults for common use cases
10
+ *
11
+ * The generated configuration includes:
12
+ * - Locale specification
13
+ * - Input file patterns for source scanning
14
+ * - Output path templates with placeholders
15
+ * - Proper imports and exports for the detected module system
16
+ * - JSDoc type annotations for JavaScript files
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Run the interactive setup
21
+ * await runInit()
22
+ *
23
+ * // This will create either:
24
+ * // - i18next.config.ts (TypeScript)
25
+ * // - i18next.config.js (JavaScript ESM/CommonJS)
26
+ * ```
27
+ */
28
+ export declare function runInit(): Promise<void>;
29
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,OAAO,kBAiG5B"}
@@ -0,0 +1,33 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ /**
3
+ * Runs the i18next linter to detect hardcoded strings and other potential issues.
4
+ *
5
+ * This function performs static analysis on source files to identify:
6
+ * - Hardcoded text strings in JSX elements
7
+ * - Hardcoded strings in JSX attributes (like alt text, titles, etc.)
8
+ * - Text that should be extracted for translation
9
+ *
10
+ * The linter respects configuration settings:
11
+ * - Uses the same input patterns as the extractor
12
+ * - Ignores content inside configured Trans components
13
+ * - Skips technical content like script/style tags
14
+ * - Identifies numeric values and interpolation syntax to avoid false positives
15
+ *
16
+ * @param config - The toolkit configuration with input patterns and component names
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const config = {
21
+ * extract: {
22
+ * input: ['src/**\/*.{ts,tsx}'],
23
+ * transComponents: ['Trans', 'Translation']
24
+ * }
25
+ * }
26
+ *
27
+ * await runLinter(config)
28
+ * // Outputs issues found or success message
29
+ * // Exits with code 1 if issues found, 0 if clean
30
+ * ```
31
+ */
32
+ export declare function runLinter(config: I18nextToolkitConfig): Promise<void>;
33
+ //# sourceMappingURL=linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,iBAsC5D"}
@@ -0,0 +1,5 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ export declare const runLocizeSync: (config: I18nextToolkitConfig, cliOptions?: any) => Promise<void>;
3
+ export declare const runLocizeDownload: (config: I18nextToolkitConfig, cliOptions?: any) => Promise<void>;
4
+ export declare const runLocizeMigrate: (config: I18nextToolkitConfig, cliOptions?: any) => Promise<void>;
5
+ //# sourceMappingURL=locize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locize.d.ts","sourceRoot":"","sources":["../src/locize.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAmPnD,eAAO,MAAM,aAAa,GAAI,QAAQ,oBAAoB,EAAE,aAAa,GAAG,kBAAiD,CAAA;AAC7H,eAAO,MAAM,iBAAiB,GAAI,QAAQ,oBAAoB,EAAE,aAAa,GAAG,kBAAqD,CAAA;AACrI,eAAO,MAAM,gBAAgB,GAAI,QAAQ,oBAAoB,EAAE,aAAa,GAAG,kBAAoD,CAAA"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Migrates a legacy i18next-parser.config.js configuration file to the new
3
+ * i18next-cli configuration format.
4
+ *
5
+ * This function:
6
+ * 1. Checks if a legacy config file exists
7
+ * 2. Prevents migration if any new config file already exists
8
+ * 3. Dynamically imports the old configuration
9
+ * 4. Maps old configuration properties to new format:
10
+ * - `$LOCALE` → `{{language}}`
11
+ * - `$NAMESPACE` → `{{namespace}}`
12
+ * - Maps lexer functions and components
13
+ * - Creates sensible defaults for new features
14
+ * 5. Generates a new TypeScript configuration file
15
+ * 6. Provides warnings for deprecated features
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Legacy config (i18next-parser.config.js):
20
+ * module.exports = {
21
+ * locales: ['en', 'de'],
22
+ * output: 'locales/$LOCALE/$NAMESPACE.json',
23
+ * input: ['src/**\/*.js']
24
+ * }
25
+ *
26
+ * // After migration (i18next.config.ts):
27
+ * export default defineConfig({
28
+ * locales: ['en', 'de'],
29
+ * extract: {
30
+ * input: ['src/**\/*.js'],
31
+ * output: 'locales/{{language}}/{{namespace}}.json'
32
+ * }
33
+ * })
34
+ * ```
35
+ */
36
+ export declare function runMigrator(): Promise<void>;
37
+ //# sourceMappingURL=migrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,WAAW,kBA+EhC"}
@@ -0,0 +1,20 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ interface StatusOptions {
3
+ detail?: string;
4
+ }
5
+ /**
6
+ * Runs a health check on the project's i18next translations and displays a status report.
7
+ *
8
+ * This command provides a high-level overview of the localization status by:
9
+ * 1. Extracting all keys from the source code using the core extractor.
10
+ * 2. Reading all existing translation files for each locale.
11
+ * 3. Calculating the translation completeness for each secondary language against the primary.
12
+ * 4. Displaying a formatted report with key counts, locales, and progress bars.
13
+ * 5. Serving as a value-driven funnel to introduce the locize commercial service.
14
+ *
15
+ * @param config - The i18next toolkit configuration object.
16
+ * @param options Options object, may contain a `detail` property with a locale string.
17
+ */
18
+ export declare function runStatus(config: I18nextToolkitConfig, options?: StatusOptions): Promise<void>;
19
+ export {};
20
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAgB,MAAM,SAAS,CAAA;AAGjE,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAE,aAAkB,iBAYzF"}
@@ -0,0 +1,33 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ /**
3
+ * Synchronizes translation files across different locales by ensuring all secondary
4
+ * language files contain the same keys as the primary language file.
5
+ *
6
+ * This function:
7
+ * 1. Reads the primary language translation file
8
+ * 2. Extracts all translation keys from the primary file
9
+ * 3. For each secondary language:
10
+ * - Preserves existing translations
11
+ * - Adds missing keys with empty values or configured default
12
+ * - Removes keys that no longer exist in primary
13
+ * 4. Only writes files that have changes
14
+ *
15
+ * @param config - The i18next toolkit configuration object
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Configuration
20
+ * const config = {
21
+ * locales: ['en', 'de', 'fr'],
22
+ * extract: {
23
+ * output: 'locales/{{language}}/{{namespace}}.json',
24
+ * defaultNS: 'translation'
25
+ * defaultValue: '[MISSING]'
26
+ * }
27
+ * }
28
+ *
29
+ * await runSyncer(config)
30
+ * ```
31
+ */
32
+ export declare function runSyncer(config: I18nextToolkitConfig): Promise<void>;
33
+ //# sourceMappingURL=syncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../src/syncer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAInD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,SAAS,CAAE,MAAM,EAAE,oBAAoB,iBA2E5D"}
@@ -0,0 +1,29 @@
1
+ import type { I18nextToolkitConfig } from './types';
2
+ /**
3
+ * Generates TypeScript type definitions for i18next translations.
4
+ *
5
+ * This function:
6
+ * 1. Reads translation files based on the input glob patterns
7
+ * 2. Generates TypeScript interfaces using i18next-resources-for-ts
8
+ * 3. Creates separate resources.d.ts and main i18next.d.ts files
9
+ * 4. Handles namespace detection from filenames
10
+ * 5. Supports type-safe selector API when enabled
11
+ *
12
+ * @param config - The i18next toolkit configuration object
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // Configuration
17
+ * const config = {
18
+ * types: {
19
+ * input: ['locales/en/*.json'],
20
+ * output: 'src/types/i18next.d.ts',
21
+ * enableSelector: true
22
+ * }
23
+ * }
24
+ *
25
+ * await runTypesGenerator(config)
26
+ * ```
27
+ */
28
+ export declare function runTypesGenerator(config: I18nextToolkitConfig): Promise<void>;
29
+ //# sourceMappingURL=types-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-generator.d.ts","sourceRoot":"","sources":["../src/types-generator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAYnD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,iBAAiB,CAAE,MAAM,EAAE,oBAAoB,iBAuEpE"}
@@ -0,0 +1,268 @@
1
+ import type { Node } from '@swc/core';
2
+ /**
3
+ * Main configuration interface for the i18next toolkit.
4
+ * Defines all available options for extraction, type generation, synchronization, and integrations.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const config: I18nextToolkitConfig = {
9
+ * locales: ['en', 'de', 'fr'],
10
+ * extract: {
11
+ * input: ['src/**\/*.{ts,tsx}'],
12
+ * output: 'locales/{{language}}/{{namespace}}.json',
13
+ * functions: ['t', 'i18n.t'],
14
+ * transComponents: ['Trans', 'Translation']
15
+ * },
16
+ * types: {
17
+ * input: ['locales/en/*.json'],
18
+ * output: 'src/types/i18next.d.ts'
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ export interface I18nextToolkitConfig {
24
+ /** Array of supported locale codes (e.g., ['en', 'de', 'fr']) */
25
+ locales: string[];
26
+ /** Configuration options for translation key extraction */
27
+ extract: {
28
+ /** Glob pattern(s) for source files to scan for translation keys */
29
+ input: string | string[];
30
+ /** Output path template with placeholders: {{language}} for locale, {{namespace}} for namespace */
31
+ output: string;
32
+ /** Default namespace when none is specified (default: 'translation') */
33
+ defaultNS?: string;
34
+ /** Separator for nested keys, or false for flat keys (default: '.') */
35
+ keySeparator?: string | false | null;
36
+ /** Separator between namespace and key, or false to disable (default: ':') */
37
+ nsSeparator?: string | false | null;
38
+ /** Separator for context variants (default: '_') */
39
+ contextSeparator?: string;
40
+ /** Separator for plural variants (default: '_') */
41
+ pluralSeparator?: string;
42
+ /** Function names to extract translation calls from (default: ['t']) */
43
+ functions?: string[];
44
+ /** JSX component names to extract translations from (default: ['Trans']) */
45
+ transComponents?: string[];
46
+ /** Hook function names that return translation functions (default: ['useTranslation']) */
47
+ useTranslationNames?: string[];
48
+ /** A list of JSX attribute names to ignore when linting for hardcoded strings. */
49
+ ignoredAttributes?: string[];
50
+ /** HTML tags to preserve in Trans component serialization (default: ['br', 'strong', 'i']) */
51
+ transKeepBasicHtmlNodesFor?: string[];
52
+ /** Glob patterns for keys to preserve even if not found in source (for dynamic keys) */
53
+ preservePatterns?: string[];
54
+ /** Whether to sort keys alphabetically in output files (default: true) */
55
+ sort?: boolean;
56
+ /** Number of spaces for JSON indentation (default: 2) */
57
+ indentation?: number;
58
+ /** Default value to use for missing translations in secondary languages */
59
+ defaultValue?: string;
60
+ /** Primary language that provides default values (default: first locale) */
61
+ primaryLanguage?: string;
62
+ /** Secondary languages that get empty values initially */
63
+ secondaryLanguages?: string[];
64
+ };
65
+ /** Configuration options for TypeScript type generation */
66
+ types?: {
67
+ /** Glob pattern(s) for translation files to generate types from */
68
+ input: string | string[];
69
+ /** Output path for the main TypeScript definition file */
70
+ output: string;
71
+ /** Enable type-safe selector API (boolean or 'optimize' for smaller types) */
72
+ enableSelector?: boolean | 'optimize';
73
+ /** Path for the separate resources interface file */
74
+ resourcesFile?: string;
75
+ };
76
+ /** Array of plugins to extend functionality */
77
+ plugins?: Plugin[];
78
+ /** Configuration for Locize integration */
79
+ locize?: {
80
+ /** Locize project ID */
81
+ projectId?: string;
82
+ /** Locize API key (recommended to use environment variables) */
83
+ apiKey?: string;
84
+ /** Version to sync with (default: 'latest') */
85
+ version?: string;
86
+ /** Whether to update existing translation values on Locize */
87
+ updateValues?: boolean;
88
+ /** Only sync the source language to Locize */
89
+ sourceLanguageOnly?: boolean;
90
+ /** Compare modification times when syncing */
91
+ compareModificationTime?: boolean;
92
+ /** Preview changes without making them */
93
+ dryRun?: boolean;
94
+ };
95
+ }
96
+ /**
97
+ * Plugin interface for extending the i18next toolkit functionality.
98
+ * Plugins can hook into various stages of the extraction process.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const myPlugin = (): Plugin => ({
103
+ * name: 'my-custom-plugin',
104
+ *
105
+ * setup: async () => {
106
+ * console.log('Plugin initialized')
107
+ * },
108
+ *
109
+ * onLoad: (code, filePath) => {
110
+ * // Transform code before parsing
111
+ * return code.replace(/OLD_PATTERN/g, 'NEW_PATTERN')
112
+ * },
113
+ *
114
+ * onVisitNode: (node, context) => {
115
+ * if (node.type === 'CallExpression') {
116
+ * // Custom extraction logic
117
+ * context.addKey({ key: 'custom.key', defaultValue: 'Custom Value' })
118
+ * }
119
+ * },
120
+ *
121
+ * onEnd: async (allKeys) => {
122
+ * console.log(`Found ${allKeys.size} total keys`)
123
+ * }
124
+ * })
125
+ * ```
126
+ */
127
+ export interface Plugin {
128
+ /** Unique name for the plugin */
129
+ name: string;
130
+ /**
131
+ * Hook called once at the beginning of the extraction process.
132
+ * Use for initialization tasks like setting up resources or validating configuration.
133
+ */
134
+ setup?: () => void | Promise<void>;
135
+ /**
136
+ * Hook called for each source file before it's parsed.
137
+ * Allows transformation of source code before AST generation.
138
+ *
139
+ * @param code - The source code content
140
+ * @param path - The file path being processed
141
+ * @returns The transformed code (or undefined to keep original)
142
+ */
143
+ onLoad?: (code: string, path: string) => string | Promise<string>;
144
+ /**
145
+ * Hook called for each AST node during traversal.
146
+ * Enables custom extraction logic by examining syntax nodes.
147
+ *
148
+ * @param node - The current AST node being visited
149
+ * @param context - Context object with helper methods
150
+ */
151
+ onVisitNode?: (node: Node, context: PluginContext) => void;
152
+ /**
153
+ * Hook called after all files have been processed.
154
+ * Useful for post-processing, validation, or reporting.
155
+ *
156
+ * @param keys - Final map of all extracted keys
157
+ */
158
+ onEnd?: (keys: Map<string, {
159
+ key: string;
160
+ defaultValue?: string;
161
+ }>) => void | Promise<void>;
162
+ }
163
+ /**
164
+ * Represents an extracted translation key with its metadata.
165
+ * Contains all information needed to generate translation files.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const extractedKey: ExtractedKey = {
170
+ * key: 'user.profile.name',
171
+ * defaultValue: 'Full Name',
172
+ * ns: 'common',
173
+ * hasCount: false
174
+ * }
175
+ * ```
176
+ */
177
+ export interface ExtractedKey {
178
+ /** The translation key (may be nested with separators) */
179
+ key: string;
180
+ /** Default value to use in the primary language */
181
+ defaultValue?: string;
182
+ /** Namespace this key belongs to */
183
+ ns?: string;
184
+ /** Whether this key is used with pluralization (count parameter) */
185
+ hasCount?: boolean;
186
+ }
187
+ /**
188
+ * Result of processing translation files for a specific locale and namespace.
189
+ * Contains the generated translations and metadata about changes.
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const result: TranslationResult = {
194
+ * path: '/project/locales/en/common.json',
195
+ * updated: true,
196
+ * newTranslations: { button: { save: 'Save', cancel: 'Cancel' } },
197
+ * existingTranslations: { button: { save: 'Save' } }
198
+ * }
199
+ * ```
200
+ */
201
+ export interface TranslationResult {
202
+ /** Full file system path where the translation file will be written */
203
+ path: string;
204
+ /** Whether the file content changed and needs to be written */
205
+ updated: boolean;
206
+ /** The new translation object to be written to the file */
207
+ newTranslations: Record<string, any>;
208
+ /** The existing translation object that was read from the file */
209
+ existingTranslations: Record<string, any>;
210
+ }
211
+ /**
212
+ * Logger interface for consistent output formatting across the toolkit.
213
+ * Implementations can customize how messages are displayed or stored.
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * class FileLogger implements Logger {
218
+ * info(message: string) { fs.appendFileSync('info.log', message) }
219
+ * warn(message: string) { fs.appendFileSync('warn.log', message) }
220
+ * error(message: string) { fs.appendFileSync('error.log', message) }
221
+ * }
222
+ * ```
223
+ */
224
+ export interface Logger {
225
+ /**
226
+ * Logs an informational message.
227
+ * @param message - The message to log
228
+ */
229
+ info(message: string): void;
230
+ /**
231
+ * Logs a warning message.
232
+ * @param message - The warning message to log
233
+ */
234
+ warn(message: string): void;
235
+ /**
236
+ * Logs an error message.
237
+ * @param message - The error message to log
238
+ */
239
+ error(message: string): void;
240
+ }
241
+ /**
242
+ * Context object provided to plugins during AST traversal.
243
+ * Provides helper methods for plugins to interact with the extraction process.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * // Inside a plugin's onVisitNode hook:
248
+ * onVisitNode(node, context) {
249
+ * if (isCustomTranslationCall(node)) {
250
+ * context.addKey({
251
+ * key: extractKeyFromNode(node),
252
+ * defaultValue: extractDefaultFromNode(node),
253
+ * ns: 'custom'
254
+ * })
255
+ * }
256
+ * }
257
+ * ```
258
+ */
259
+ export interface PluginContext {
260
+ /**
261
+ * Adds a translation key to the extraction results.
262
+ * Keys are automatically deduplicated by their namespace:key combination.
263
+ *
264
+ * @param keyInfo - The extracted key information
265
+ */
266
+ addKey: (keyInfo: ExtractedKey) => void;
267
+ }
268
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Ensures that the directory for a given file path exists.
3
+ * Creates all necessary parent directories recursively if they don't exist.
4
+ *
5
+ * @param filePath - The file path for which to ensure the directory exists
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * await ensureDirectoryExists('/path/to/nested/file.json')
10
+ * // Creates /path/to/nested/ directory if it doesn't exist
11
+ * ```
12
+ */
13
+ export declare function ensureDirectoryExists(filePath: string): Promise<void>;
14
+ /**
15
+ * Reads a file asynchronously and returns its content as a UTF-8 string.
16
+ *
17
+ * @param filePath - The path to the file to read
18
+ * @returns Promise resolving to the file content as a string
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const content = await readFileAsync('./config.json')
23
+ * const config = JSON.parse(content)
24
+ * ```
25
+ */
26
+ export declare function readFileAsync(filePath: string): Promise<string>;
27
+ /**
28
+ * Writes data to a file asynchronously.
29
+ *
30
+ * @param filePath - The path where to write the file
31
+ * @param data - The string data to write to the file
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const jsonData = JSON.stringify({ key: 'value' }, null, 2)
36
+ * await writeFileAsync('./output.json', jsonData)
37
+ * ```
38
+ */
39
+ export declare function writeFileAsync(filePath: string, data: string): Promise<void>;
40
+ /**
41
+ * Generates a file path by replacing template placeholders with actual values.
42
+ * Supports both legacy and modern placeholder formats for language and namespace.
43
+ *
44
+ * @param template - The template string containing placeholders
45
+ * @param locale - The locale/language code to substitute
46
+ * @param namespace - The namespace to substitute
47
+ * @returns The resolved file path with placeholders replaced
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // Modern format
52
+ * getOutputPath('locales/{{language}}/{{namespace}}.json', 'de', 'validation')
53
+ * // Returns: 'locales/de/validation.json'
54
+ *
55
+ * // Legacy format (also supported)
56
+ * getOutputPath('locales/{{lng}}/{{ns}}.json', 'en', 'common')
57
+ * // Returns: 'locales/en/common.json'
58
+ * ```
59
+ */
60
+ export declare function getOutputPath(template: string, locale: string, namespace: string): string;
61
+ //# sourceMappingURL=file-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAIR"}
@@ -0,0 +1,34 @@
1
+ import type { Logger } from '../types';
2
+ /**
3
+ * Default console-based logger implementation for the i18next toolkit.
4
+ * Provides basic logging functionality with different severity levels.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const logger = new ConsoleLogger()
9
+ * logger.info('Extraction started')
10
+ * logger.warn('Deprecated configuration option used')
11
+ * logger.error('Failed to parse file')
12
+ * ```
13
+ */
14
+ export declare class ConsoleLogger implements Logger {
15
+ /**
16
+ * Logs an informational message to the console.
17
+ *
18
+ * @param message - The message to log
19
+ */
20
+ info(message: string): void;
21
+ /**
22
+ * Logs a warning message to the console.
23
+ *
24
+ * @param message - The warning message to log
25
+ */
26
+ warn(message: string): void;
27
+ /**
28
+ * Logs an error message to the console.
29
+ *
30
+ * @param message - The error message to log
31
+ */
32
+ error(message: string): void;
33
+ }
34
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC;;;;;;;;;;;GAWG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC1C;;;;OAIG;IACH,IAAI,CAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAE5B;;;;OAIG;IACH,IAAI,CAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAE5B;;;;OAIG;IACH,KAAK,CAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAC9B"}