ai-localize-codemods 2.0.0 → 2.0.1

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # ai-localize-codemods
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - ai-localize-shared@2.0.1
9
+
3
10
  ## 2.0.0
4
11
 
5
12
  ### Major Changes
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { DetectedText, CloudFrontAsset, LegacyCdnUrl, LocalizationConfig } from 'ai-localize-shared';
1
+ import { DetectedText, CodemodConfig, CloudFrontAsset, LegacyCdnUrl, LocalizationConfig } from 'ai-localize-shared';
2
2
 
3
3
  interface CodemodResult {
4
4
  filePath: string;
@@ -10,50 +10,102 @@ interface CodemodResult {
10
10
  replacedTexts: number;
11
11
  }
12
12
  /**
13
- * React i18n codemod: wraps hardcoded JSX text / string literals with t() calls.
13
+ * React i18n codemod: wraps hardcoded JSX text / string literals with t() or t[''] calls.
14
14
  * Preserves formatting, comments, and import order.
15
+ *
16
+ * ### Local hook import paths
17
+ *
18
+ * When `codemodConfig.importPackage` is a project-relative path (e.g. `"src/Locales/translate"`),
19
+ * the codemod computes the correct **relative import path for each file** it transforms:
20
+ *
21
+ * src/components/Button.tsx → `"../../Locales/translate"`
22
+ * src/pages/dashboard/Header.tsx → `"../../../Locales/translate"`
23
+ *
24
+ * npm package names (no `/` prefix, not starting with `.`) are injected verbatim.
25
+ *
26
+ * ### Accessor styles
27
+ * accessorStyle "function" (default) → t('key')
28
+ * accessorStyle "bracket" → t['key']
15
29
  */
16
30
  declare class ReactCodemod {
17
31
  private filePath;
18
32
  private content;
19
33
  private texts;
20
- constructor(filePath: string, content: string, texts: DetectedText[]);
34
+ /** Resolved import specifier string (may differ per file for local paths) */
35
+ private importSpecifier;
36
+ private hookName;
37
+ private translationFn;
38
+ private namespace?;
39
+ private accessorStyle;
40
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig, cwd?: string);
21
41
  transform(): CodemodResult;
22
- private injectUseTranslationHook;
42
+ private injectHook;
23
43
  }
44
+ /**
45
+ * Determines the import specifier string to inject for a given `importPackage`
46
+ * config value and the file being transformed.
47
+ *
48
+ * Rules:
49
+ * 1. If `importPackage` looks like an npm package name (no leading `.` or `/`
50
+ * and no path separators in a way that suggests a local path starting with
51
+ * a known directory like `src/`) → return verbatim.
52
+ *
53
+ * 2. If `importPackage` is an absolute path → compute `path.relative(fileDir, importPackage)`
54
+ * and ensure it starts with `./` or `../`.
55
+ *
56
+ * 3. If `importPackage` is a project-relative path (starts with `src/`, `app/`,
57
+ * `lib/`, `hooks/`, `utils/`, or any path without a leading `.`) that is NOT
58
+ * a bare npm package name → resolve it relative to `cwd` first, then compute
59
+ * `path.relative(fileDir, resolvedPath)`.
60
+ *
61
+ * 4. If `importPackage` starts with `./` or `../` → treat as a path relative to
62
+ * `cwd` (config file location), resolve it, then compute relative to each file.
63
+ */
64
+ declare function resolveImportSpecifier(importPackage: string, filePath: string, cwd: string): string;
24
65
  /**
25
66
  * Applies the React codemod to a file in-place.
26
67
  */
27
- declare function applyReactCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
68
+ declare function applyReactCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig, cwd?: string): CodemodResult;
28
69
 
29
70
  /**
30
- * Vue i18n codemod: wraps hardcoded text with $t() calls in Vue SFCs.
31
- * Handles both Options API and Composition API.
71
+ * Vue i18n codemod: wraps hardcoded text with $t() / t() calls in Vue SFCs.
72
+ * Handles both Options API (global $t) and Composition API (useI18n / useTranslation).
73
+ *
74
+ * The translation function name can be overridden via the `codemods.translationFunction`
75
+ * config field (default: "$t").
32
76
  */
33
77
  declare class VueCodemod {
34
78
  private filePath;
35
79
  private content;
36
80
  private texts;
37
- constructor(filePath: string, content: string, texts: DetectedText[]);
81
+ private translationFn;
82
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig);
38
83
  transform(): CodemodResult;
39
84
  private unchanged;
40
85
  }
41
- declare function applyVueCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
86
+ declare function applyVueCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig): CodemodResult;
42
87
 
43
88
  /**
44
89
  * Angular ngx-translate codemod:
45
90
  * - In templates: wraps text with {{ 'key' | translate }}
46
91
  * - In TS: replaces string literals with this.translateService.instant('key')
92
+ *
93
+ * The pipe name used in templates can be overridden via
94
+ * `codemods.translationFunction` (default: "translate").
95
+ * The TS service call can be overridden via `codemods.hookName`
96
+ * (default: "this.translateService.instant").
47
97
  */
48
98
  declare class AngularCodemod {
49
99
  private filePath;
50
100
  private content;
51
101
  private texts;
52
- constructor(filePath: string, content: string, texts: DetectedText[]);
102
+ private templatePipe;
103
+ private tsServiceCall;
104
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig);
53
105
  transform(): CodemodResult;
54
106
  private unchanged;
55
107
  }
56
- declare function applyAngularCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
108
+ declare function applyAngularCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig): CodemodResult;
57
109
 
58
110
  interface CdnReplacementResult {
59
111
  filePath: string;
@@ -92,14 +144,25 @@ interface CodemodRunSummary {
92
144
  }
93
145
  /**
94
146
  * Orchestrates codemods across all detected files.
95
- * Groups detected texts by file and applies the appropriate codemod
96
- * based on the project framework.
147
+ *
148
+ * Groups detected texts by file and applies the appropriate codemod based on
149
+ * the project framework. Codemod behaviour (import package, hook name,
150
+ * translation function, namespace, accessor style) is driven by `config.codemods`
151
+ * so the user can override defaults in their ai-localize.config.json.
152
+ *
153
+ * ### Local hook import path resolution
154
+ * When `config.codemods.importPackage` is a project-relative path (e.g.
155
+ * `"src/Locales/translate"`), `cwd` is forwarded to `applyReactCodemod` so it
156
+ * can compute the correct relative import path for each individual file:
157
+ * src/components/Button.tsx → `"../../Locales/translate"`
158
+ * src/pages/dashboard/Header.tsx → `"../../../Locales/translate"`
97
159
  */
98
160
  declare class CodemodRunner {
99
161
  private config;
100
- constructor(config: LocalizationConfig);
162
+ private cwd;
163
+ constructor(config: LocalizationConfig, cwd?: string);
101
164
  run(detectedTexts: DetectedText[], options?: CodemodRunOptions): Promise<CodemodRunSummary>;
102
165
  private applyCodemod;
103
166
  }
104
167
 
105
- export { AngularCodemod, type CdnReplacementResult, CdnReplacer, type CodemodResult, type CodemodRunOptions, type CodemodRunSummary, CodemodRunner, ReactCodemod, VueCodemod, applyAngularCodemod, applyReactCodemod, applyVueCodemod, batchReplaceCdnUrls };
168
+ export { AngularCodemod, type CdnReplacementResult, CdnReplacer, type CodemodResult, type CodemodRunOptions, type CodemodRunSummary, CodemodRunner, ReactCodemod, VueCodemod, applyAngularCodemod, applyReactCodemod, applyVueCodemod, batchReplaceCdnUrls, resolveImportSpecifier };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { DetectedText, CloudFrontAsset, LegacyCdnUrl, LocalizationConfig } from 'ai-localize-shared';
1
+ import { DetectedText, CodemodConfig, CloudFrontAsset, LegacyCdnUrl, LocalizationConfig } from 'ai-localize-shared';
2
2
 
3
3
  interface CodemodResult {
4
4
  filePath: string;
@@ -10,50 +10,102 @@ interface CodemodResult {
10
10
  replacedTexts: number;
11
11
  }
12
12
  /**
13
- * React i18n codemod: wraps hardcoded JSX text / string literals with t() calls.
13
+ * React i18n codemod: wraps hardcoded JSX text / string literals with t() or t[''] calls.
14
14
  * Preserves formatting, comments, and import order.
15
+ *
16
+ * ### Local hook import paths
17
+ *
18
+ * When `codemodConfig.importPackage` is a project-relative path (e.g. `"src/Locales/translate"`),
19
+ * the codemod computes the correct **relative import path for each file** it transforms:
20
+ *
21
+ * src/components/Button.tsx → `"../../Locales/translate"`
22
+ * src/pages/dashboard/Header.tsx → `"../../../Locales/translate"`
23
+ *
24
+ * npm package names (no `/` prefix, not starting with `.`) are injected verbatim.
25
+ *
26
+ * ### Accessor styles
27
+ * accessorStyle "function" (default) → t('key')
28
+ * accessorStyle "bracket" → t['key']
15
29
  */
16
30
  declare class ReactCodemod {
17
31
  private filePath;
18
32
  private content;
19
33
  private texts;
20
- constructor(filePath: string, content: string, texts: DetectedText[]);
34
+ /** Resolved import specifier string (may differ per file for local paths) */
35
+ private importSpecifier;
36
+ private hookName;
37
+ private translationFn;
38
+ private namespace?;
39
+ private accessorStyle;
40
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig, cwd?: string);
21
41
  transform(): CodemodResult;
22
- private injectUseTranslationHook;
42
+ private injectHook;
23
43
  }
44
+ /**
45
+ * Determines the import specifier string to inject for a given `importPackage`
46
+ * config value and the file being transformed.
47
+ *
48
+ * Rules:
49
+ * 1. If `importPackage` looks like an npm package name (no leading `.` or `/`
50
+ * and no path separators in a way that suggests a local path starting with
51
+ * a known directory like `src/`) → return verbatim.
52
+ *
53
+ * 2. If `importPackage` is an absolute path → compute `path.relative(fileDir, importPackage)`
54
+ * and ensure it starts with `./` or `../`.
55
+ *
56
+ * 3. If `importPackage` is a project-relative path (starts with `src/`, `app/`,
57
+ * `lib/`, `hooks/`, `utils/`, or any path without a leading `.`) that is NOT
58
+ * a bare npm package name → resolve it relative to `cwd` first, then compute
59
+ * `path.relative(fileDir, resolvedPath)`.
60
+ *
61
+ * 4. If `importPackage` starts with `./` or `../` → treat as a path relative to
62
+ * `cwd` (config file location), resolve it, then compute relative to each file.
63
+ */
64
+ declare function resolveImportSpecifier(importPackage: string, filePath: string, cwd: string): string;
24
65
  /**
25
66
  * Applies the React codemod to a file in-place.
26
67
  */
27
- declare function applyReactCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
68
+ declare function applyReactCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig, cwd?: string): CodemodResult;
28
69
 
29
70
  /**
30
- * Vue i18n codemod: wraps hardcoded text with $t() calls in Vue SFCs.
31
- * Handles both Options API and Composition API.
71
+ * Vue i18n codemod: wraps hardcoded text with $t() / t() calls in Vue SFCs.
72
+ * Handles both Options API (global $t) and Composition API (useI18n / useTranslation).
73
+ *
74
+ * The translation function name can be overridden via the `codemods.translationFunction`
75
+ * config field (default: "$t").
32
76
  */
33
77
  declare class VueCodemod {
34
78
  private filePath;
35
79
  private content;
36
80
  private texts;
37
- constructor(filePath: string, content: string, texts: DetectedText[]);
81
+ private translationFn;
82
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig);
38
83
  transform(): CodemodResult;
39
84
  private unchanged;
40
85
  }
41
- declare function applyVueCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
86
+ declare function applyVueCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig): CodemodResult;
42
87
 
43
88
  /**
44
89
  * Angular ngx-translate codemod:
45
90
  * - In templates: wraps text with {{ 'key' | translate }}
46
91
  * - In TS: replaces string literals with this.translateService.instant('key')
92
+ *
93
+ * The pipe name used in templates can be overridden via
94
+ * `codemods.translationFunction` (default: "translate").
95
+ * The TS service call can be overridden via `codemods.hookName`
96
+ * (default: "this.translateService.instant").
47
97
  */
48
98
  declare class AngularCodemod {
49
99
  private filePath;
50
100
  private content;
51
101
  private texts;
52
- constructor(filePath: string, content: string, texts: DetectedText[]);
102
+ private templatePipe;
103
+ private tsServiceCall;
104
+ constructor(filePath: string, content: string, texts: DetectedText[], codemodConfig?: CodemodConfig);
53
105
  transform(): CodemodResult;
54
106
  private unchanged;
55
107
  }
56
- declare function applyAngularCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean): CodemodResult;
108
+ declare function applyAngularCodemod(filePath: string, texts: DetectedText[], dryRun?: boolean, codemodConfig?: CodemodConfig): CodemodResult;
57
109
 
58
110
  interface CdnReplacementResult {
59
111
  filePath: string;
@@ -92,14 +144,25 @@ interface CodemodRunSummary {
92
144
  }
93
145
  /**
94
146
  * Orchestrates codemods across all detected files.
95
- * Groups detected texts by file and applies the appropriate codemod
96
- * based on the project framework.
147
+ *
148
+ * Groups detected texts by file and applies the appropriate codemod based on
149
+ * the project framework. Codemod behaviour (import package, hook name,
150
+ * translation function, namespace, accessor style) is driven by `config.codemods`
151
+ * so the user can override defaults in their ai-localize.config.json.
152
+ *
153
+ * ### Local hook import path resolution
154
+ * When `config.codemods.importPackage` is a project-relative path (e.g.
155
+ * `"src/Locales/translate"`), `cwd` is forwarded to `applyReactCodemod` so it
156
+ * can compute the correct relative import path for each individual file:
157
+ * src/components/Button.tsx → `"../../Locales/translate"`
158
+ * src/pages/dashboard/Header.tsx → `"../../../Locales/translate"`
97
159
  */
98
160
  declare class CodemodRunner {
99
161
  private config;
100
- constructor(config: LocalizationConfig);
162
+ private cwd;
163
+ constructor(config: LocalizationConfig, cwd?: string);
101
164
  run(detectedTexts: DetectedText[], options?: CodemodRunOptions): Promise<CodemodRunSummary>;
102
165
  private applyCodemod;
103
166
  }
104
167
 
105
- export { AngularCodemod, type CdnReplacementResult, CdnReplacer, type CodemodResult, type CodemodRunOptions, type CodemodRunSummary, CodemodRunner, ReactCodemod, VueCodemod, applyAngularCodemod, applyReactCodemod, applyVueCodemod, batchReplaceCdnUrls };
168
+ export { AngularCodemod, type CdnReplacementResult, CdnReplacer, type CodemodResult, type CodemodRunOptions, type CodemodRunSummary, CodemodRunner, ReactCodemod, VueCodemod, applyAngularCodemod, applyReactCodemod, applyVueCodemod, batchReplaceCdnUrls, resolveImportSpecifier };