@chipmobilesdk/rn-i18n-tooling 0.0.0-stage → 0.1.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 +77 -0
- package/README.md +64 -2
- package/bin/chip-i18n.mjs +17 -0
- package/lib/cli.d.ts +5 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +91 -0
- package/lib/cli.js.map +1 -0
- package/lib/generateKeys.d.ts +14 -0
- package/lib/generateKeys.d.ts.map +1 -0
- package/lib/generateKeys.js +51 -0
- package/lib/generateKeys.js.map +1 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +13 -0
- package/lib/index.js.map +1 -0
- package/lib/report.d.ts +10 -0
- package/lib/report.d.ts.map +1 -0
- package/lib/report.js +89 -0
- package/lib/report.js.map +1 -0
- package/lib/runner.d.ts +21 -0
- package/lib/runner.d.ts.map +1 -0
- package/lib/runner.js +88 -0
- package/lib/runner.js.map +1 -0
- package/lib/scan.d.ts +22 -0
- package/lib/scan.d.ts.map +1 -0
- package/lib/scan.js +227 -0
- package/lib/scan.js.map +1 -0
- package/lib/sync.d.ts +18 -0
- package/lib/sync.d.ts.map +1 -0
- package/lib/sync.js +173 -0
- package/lib/sync.js.map +1 -0
- package/lib/types.d.ts +123 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -0
- package/package.json +38 -5
package/lib/scan.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PatternConfig, TranslationTemplate } from './types.ts';
|
|
2
|
+
/** Converts a glob (`**`, `*`, `?`, `{a,b}`) to an anchored RegExp. */
|
|
3
|
+
export declare function globToRegExp(glob: string): RegExp;
|
|
4
|
+
/**
|
|
5
|
+
* The deepest directory a glob can only match inside: everything before its
|
|
6
|
+
* first wildcard, truncated to a directory boundary. `src/screens/**\/*.tsx`
|
|
7
|
+
* gives `src/screens`, so the walk never leaves it — scanning started at the
|
|
8
|
+
* project root and threw away almost everything it read, which on a React
|
|
9
|
+
* Native checkout means `android/`, `ios/` and every build directory inside
|
|
10
|
+
* them (I18N-15).
|
|
11
|
+
*/
|
|
12
|
+
export declare function globBaseDir(glob: string): string;
|
|
13
|
+
/** Lists project-relative source files matching the configured globs. */
|
|
14
|
+
export declare function listSourceFiles(rootDir: string, sourceGlobs: readonly string[]): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Scans the source tree with the app-configured i18n usage regex patterns and
|
|
17
|
+
* builds the source-of-truth translation template: discovered keys with
|
|
18
|
+
* default text and `file:line` locations, ambiguous dynamic usages, and
|
|
19
|
+
* conflicting duplicate keys (FR-024…FR-026, FR-031).
|
|
20
|
+
*/
|
|
21
|
+
export declare function scanSource(rootDir: string, sourceGlobs: readonly string[], patterns: readonly PatternConfig[]): TranslationTemplate;
|
|
22
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGX,aAAa,EAGb,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAIpB,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsCjD;AAgBD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAqBzF;AAuDD;;;;;GAKG;AACH,wBAAgB,UAAU,CACzB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,QAAQ,EAAE,SAAS,aAAa,EAAE,GAChC,mBAAmB,CAgFrB"}
|
package/lib/scan.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const IGNORED_DIRECTORIES = new Set(['node_modules', '.git', 'build', 'dist', 'Pods']);
|
|
4
|
+
/** Converts a glob (`**`, `*`, `?`, `{a,b}`) to an anchored RegExp. */
|
|
5
|
+
export function globToRegExp(glob) {
|
|
6
|
+
let source = '';
|
|
7
|
+
let index = 0;
|
|
8
|
+
while (index < glob.length) {
|
|
9
|
+
const char = glob[index];
|
|
10
|
+
if (char === '*') {
|
|
11
|
+
if (glob[index + 1] === '*') {
|
|
12
|
+
// `**/` matches zero or more directories; trailing `**` matches all.
|
|
13
|
+
if (glob[index + 2] === '/') {
|
|
14
|
+
source += '(?:.*/)?';
|
|
15
|
+
index += 3;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
source += '.*';
|
|
19
|
+
index += 2;
|
|
20
|
+
}
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
source += '[^/]*';
|
|
24
|
+
}
|
|
25
|
+
else if (char === '?') {
|
|
26
|
+
source += '[^/]';
|
|
27
|
+
}
|
|
28
|
+
else if (char === '{') {
|
|
29
|
+
const end = glob.indexOf('}', index);
|
|
30
|
+
if (end === -1) {
|
|
31
|
+
source += '\\{';
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const alternatives = glob
|
|
35
|
+
.slice(index + 1, end)
|
|
36
|
+
.split(',')
|
|
37
|
+
.map(alternative => alternative.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
38
|
+
source += `(?:${alternatives.join('|')})`;
|
|
39
|
+
index = end;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
source += char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
44
|
+
}
|
|
45
|
+
index += 1;
|
|
46
|
+
}
|
|
47
|
+
return new RegExp(`^${source}$`);
|
|
48
|
+
}
|
|
49
|
+
function walkDirectory(rootDir, current, files) {
|
|
50
|
+
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
51
|
+
if (entry.isDirectory()) {
|
|
52
|
+
if (!IGNORED_DIRECTORIES.has(entry.name)) {
|
|
53
|
+
walkDirectory(rootDir, path.join(current, entry.name), files);
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (entry.isFile()) {
|
|
58
|
+
files.push(path.relative(rootDir, path.join(current, entry.name)).replace(/\\/g, '/'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The deepest directory a glob can only match inside: everything before its
|
|
64
|
+
* first wildcard, truncated to a directory boundary. `src/screens/**\/*.tsx`
|
|
65
|
+
* gives `src/screens`, so the walk never leaves it — scanning started at the
|
|
66
|
+
* project root and threw away almost everything it read, which on a React
|
|
67
|
+
* Native checkout means `android/`, `ios/` and every build directory inside
|
|
68
|
+
* them (I18N-15).
|
|
69
|
+
*/
|
|
70
|
+
export function globBaseDir(glob) {
|
|
71
|
+
const wildcard = glob.search(/[*?{[]/);
|
|
72
|
+
const literal = wildcard === -1 ? glob : glob.slice(0, wildcard);
|
|
73
|
+
const cut = literal.lastIndexOf('/');
|
|
74
|
+
return cut === -1 ? '' : literal.slice(0, cut);
|
|
75
|
+
}
|
|
76
|
+
/** Lists project-relative source files matching the configured globs. */
|
|
77
|
+
export function listSourceFiles(rootDir, sourceGlobs) {
|
|
78
|
+
const found = new Set();
|
|
79
|
+
// One walk per distinct base directory, not per glob: two globs under the same
|
|
80
|
+
// directory would otherwise read it twice.
|
|
81
|
+
const bases = new Map();
|
|
82
|
+
for (const glob of sourceGlobs) {
|
|
83
|
+
const base = globBaseDir(glob);
|
|
84
|
+
const matchers = bases.get(base) ?? [];
|
|
85
|
+
matchers.push(globToRegExp(glob));
|
|
86
|
+
bases.set(base, matchers);
|
|
87
|
+
}
|
|
88
|
+
for (const [base, matchers] of bases) {
|
|
89
|
+
const directory = base === '' ? rootDir : path.join(rootDir, base);
|
|
90
|
+
if (!fs.existsSync(directory))
|
|
91
|
+
continue;
|
|
92
|
+
const files = [];
|
|
93
|
+
walkDirectory(rootDir, directory, files);
|
|
94
|
+
for (const file of files) {
|
|
95
|
+
if (matchers.some(matcher => matcher.test(file)))
|
|
96
|
+
found.add(file);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return [...found].sort();
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Offsets of the start of every line, so a match offset becomes a line number in
|
|
103
|
+
* a binary search rather than a scan from the top of the file. Counting newlines
|
|
104
|
+
* per match made a file with many keys quadratic in its own length.
|
|
105
|
+
*/
|
|
106
|
+
function lineStartsOf(text) {
|
|
107
|
+
const starts = [0];
|
|
108
|
+
for (let position = text.indexOf('\n'); position !== -1; position = text.indexOf('\n', position + 1)) {
|
|
109
|
+
starts.push(position + 1);
|
|
110
|
+
}
|
|
111
|
+
return starts;
|
|
112
|
+
}
|
|
113
|
+
/** 1-based line number of `index`, by binary search over `lineStarts`. */
|
|
114
|
+
function lineOfIndex(lineStarts, index) {
|
|
115
|
+
let low = 0;
|
|
116
|
+
let high = lineStarts.length - 1;
|
|
117
|
+
while (low < high) {
|
|
118
|
+
const middle = Math.floor((low + high + 1) / 2);
|
|
119
|
+
if (lineStarts[middle] <= index)
|
|
120
|
+
low = middle;
|
|
121
|
+
else
|
|
122
|
+
high = middle - 1;
|
|
123
|
+
}
|
|
124
|
+
return low + 1;
|
|
125
|
+
}
|
|
126
|
+
/** The text of a 1-based line, without its terminator. */
|
|
127
|
+
function lineText(text, lineStarts, line) {
|
|
128
|
+
const start = lineStarts[line - 1] ?? 0;
|
|
129
|
+
const end = lineStarts[line] ?? text.length + 1;
|
|
130
|
+
return text.slice(start, Math.max(start, end - 1));
|
|
131
|
+
}
|
|
132
|
+
function compilePatterns(patterns) {
|
|
133
|
+
return patterns.map(pattern => {
|
|
134
|
+
const flags = [...new Set(`g${pattern.flags ?? ''}`)].join('');
|
|
135
|
+
return {
|
|
136
|
+
keyRegex: new RegExp(pattern.regex, flags),
|
|
137
|
+
ambiguousRegex: pattern.ambiguousRegex
|
|
138
|
+
? new RegExp(pattern.ambiguousRegex, flags)
|
|
139
|
+
: undefined,
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Scans the source tree with the app-configured i18n usage regex patterns and
|
|
145
|
+
* builds the source-of-truth translation template: discovered keys with
|
|
146
|
+
* default text and `file:line` locations, ambiguous dynamic usages, and
|
|
147
|
+
* conflicting duplicate keys (FR-024…FR-026, FR-031).
|
|
148
|
+
*/
|
|
149
|
+
export function scanSource(rootDir, sourceGlobs, patterns) {
|
|
150
|
+
const compiled = compilePatterns(patterns);
|
|
151
|
+
const files = listSourceFiles(rootDir, sourceGlobs);
|
|
152
|
+
const keys = new Map();
|
|
153
|
+
const valuesByKey = new Map();
|
|
154
|
+
const ambiguous = [];
|
|
155
|
+
for (const file of files) {
|
|
156
|
+
const text = fs.readFileSync(path.join(rootDir, file), 'utf8');
|
|
157
|
+
const lineStarts = lineStartsOf(text);
|
|
158
|
+
const matchedSpans = [];
|
|
159
|
+
for (const pattern of compiled) {
|
|
160
|
+
pattern.keyRegex.lastIndex = 0;
|
|
161
|
+
for (const match of text.matchAll(pattern.keyRegex)) {
|
|
162
|
+
const key = match.groups?.key;
|
|
163
|
+
if (!key) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const startIndex = match.index ?? 0;
|
|
167
|
+
matchedSpans.push([startIndex, startIndex + match[0].length]);
|
|
168
|
+
const location = {
|
|
169
|
+
file,
|
|
170
|
+
line: lineOfIndex(lineStarts, startIndex),
|
|
171
|
+
};
|
|
172
|
+
const existing = keys.get(key);
|
|
173
|
+
if (existing) {
|
|
174
|
+
existing.locations.push(location);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
keys.set(key, { key, locations: [location] });
|
|
178
|
+
}
|
|
179
|
+
const defaultText = match.groups?.defaultText;
|
|
180
|
+
if (defaultText !== undefined) {
|
|
181
|
+
const values = valuesByKey.get(key) ?? [];
|
|
182
|
+
values.push({ text: defaultText, location });
|
|
183
|
+
valuesByKey.set(key, values);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const pattern of compiled) {
|
|
188
|
+
if (!pattern.ambiguousRegex) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
pattern.ambiguousRegex.lastIndex = 0;
|
|
192
|
+
for (const match of text.matchAll(pattern.ambiguousRegex)) {
|
|
193
|
+
const start = match.index ?? 0;
|
|
194
|
+
const overlapsKeyMatch = matchedSpans.some(([from, to]) => start >= from && start < to);
|
|
195
|
+
if (overlapsKeyMatch) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const lineNumber = lineOfIndex(lineStarts, start);
|
|
199
|
+
ambiguous.push({
|
|
200
|
+
file,
|
|
201
|
+
line: lineNumber,
|
|
202
|
+
snippet: lineText(text, lineStarts, lineNumber).trim() || match[0],
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const conflicts = [];
|
|
208
|
+
for (const [key, values] of valuesByKey) {
|
|
209
|
+
const distinct = [...new Set(values.map(value => value.text))];
|
|
210
|
+
if (distinct.length > 1) {
|
|
211
|
+
conflicts.push({ key, values });
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const templateKey = keys.get(key);
|
|
215
|
+
if (templateKey) {
|
|
216
|
+
templateKey.defaultText = values[0].text;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
keys: [...keys.values()].sort((a, b) => a.key.localeCompare(b.key)),
|
|
222
|
+
ambiguous,
|
|
223
|
+
conflicts: conflicts.sort((a, b) => a.key.localeCompare(b.key)),
|
|
224
|
+
scannedFiles: files.length,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=scan.js.map
|
package/lib/scan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
package/lib/sync.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LocaleSyncResult, RuntimeEntryConfig, SyncConfig, TranslationTemplate } from './types.ts';
|
|
2
|
+
type JsonValue = string | {
|
|
3
|
+
[key: string]: JsonValue;
|
|
4
|
+
};
|
|
5
|
+
/** Flattens nested locale JSON into dot-path keys with leaf values. */
|
|
6
|
+
export declare function flattenTranslations(node: JsonValue, prefix?: string, into?: Map<string, JsonValue>): Map<string, JsonValue>;
|
|
7
|
+
/** Rebuilds the nested JSON object with deterministically sorted keys. */
|
|
8
|
+
export declare function nestTranslations(flat: Map<string, JsonValue>): JsonValue;
|
|
9
|
+
/**
|
|
10
|
+
* Synchronizes every configured locale JSON file against the scanned
|
|
11
|
+
* template: creates missing files, adds missing keys with the configured
|
|
12
|
+
* placeholder, preserves existing translations verbatim, removes stale keys,
|
|
13
|
+
* and protects declared runtime-only entries (FR-027…FR-030, FR-034/FR-035).
|
|
14
|
+
* Conflicted keys are never added or overwritten while the conflict is open.
|
|
15
|
+
*/
|
|
16
|
+
export declare function syncLocaleFiles(rootDir: string, config: SyncConfig, template: TranslationTemplate, runtimeEntries: readonly RuntimeEntryConfig[]): LocaleSyncResult[];
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAEpB,KAAK,SAAS,GAAG,MAAM,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAoBvD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,SAAS,EACf,MAAM,SAAK,EACX,IAAI,GAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAa,GACtC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CASxB;AAaD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,CAiBxE;AAuCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,mBAAmB,EAC7B,cAAc,EAAE,SAAS,kBAAkB,EAAE,GAC3C,gBAAgB,EAAE,CAiFpB"}
|
package/lib/sync.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const PLURAL_CATEGORIES = new Set(['zero', 'one', 'two', 'few', 'many', 'other']);
|
|
4
|
+
/**
|
|
5
|
+
* Mirrors the runtime plural-group leaf rule (translation/plurals.ts) so a
|
|
6
|
+
* plural variant object is synchronized as one key, not per category.
|
|
7
|
+
*/
|
|
8
|
+
function isPluralGroupValue(value) {
|
|
9
|
+
if (typeof value !== 'object' || value === null) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const keys = Object.keys(value);
|
|
13
|
+
return (keys.length > 0 &&
|
|
14
|
+
'other' in value &&
|
|
15
|
+
keys.every(key => PLURAL_CATEGORIES.has(key) && typeof value[key] === 'string'));
|
|
16
|
+
}
|
|
17
|
+
/** Flattens nested locale JSON into dot-path keys with leaf values. */
|
|
18
|
+
export function flattenTranslations(node, prefix = '', into = new Map()) {
|
|
19
|
+
if (typeof node === 'string' || isPluralGroupValue(node)) {
|
|
20
|
+
into.set(prefix, node);
|
|
21
|
+
return into;
|
|
22
|
+
}
|
|
23
|
+
for (const [key, value] of Object.entries(node)) {
|
|
24
|
+
flattenTranslations(value, prefix ? `${prefix}.${key}` : key, into);
|
|
25
|
+
}
|
|
26
|
+
return into;
|
|
27
|
+
}
|
|
28
|
+
function sortValue(value) {
|
|
29
|
+
if (typeof value === 'string') {
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
const sorted = {};
|
|
33
|
+
for (const key of Object.keys(value).sort((a, b) => a.localeCompare(b, 'en'))) {
|
|
34
|
+
sorted[key] = sortValue(value[key]);
|
|
35
|
+
}
|
|
36
|
+
return sorted;
|
|
37
|
+
}
|
|
38
|
+
/** Rebuilds the nested JSON object with deterministically sorted keys. */
|
|
39
|
+
export function nestTranslations(flat) {
|
|
40
|
+
const root = {};
|
|
41
|
+
const sortedKeys = [...flat.keys()].sort((a, b) => a.localeCompare(b, 'en'));
|
|
42
|
+
for (const flatKey of sortedKeys) {
|
|
43
|
+
const segments = flatKey.split('.');
|
|
44
|
+
let node = root;
|
|
45
|
+
for (let index = 0; index < segments.length - 1; index += 1) {
|
|
46
|
+
const segment = segments[index];
|
|
47
|
+
const next = node[segment];
|
|
48
|
+
if (typeof next !== 'object' || next === null || isPluralGroupValue(next)) {
|
|
49
|
+
node[segment] = {};
|
|
50
|
+
}
|
|
51
|
+
node = node[segment];
|
|
52
|
+
}
|
|
53
|
+
node[segments[segments.length - 1]] = sortValue(flat.get(flatKey));
|
|
54
|
+
}
|
|
55
|
+
return root;
|
|
56
|
+
}
|
|
57
|
+
function placeholderValue(config, locale, key, defaultText) {
|
|
58
|
+
const placeholder = config.placeholder ?? 'template';
|
|
59
|
+
if (placeholder === 'template') {
|
|
60
|
+
return defaultText ?? key;
|
|
61
|
+
}
|
|
62
|
+
if (typeof placeholder === 'string') {
|
|
63
|
+
return placeholder;
|
|
64
|
+
}
|
|
65
|
+
return placeholder[locale] ?? defaultText ?? key;
|
|
66
|
+
}
|
|
67
|
+
/** Writes the file unless it already holds exactly this; returns whether it wrote. */
|
|
68
|
+
function writeLocaleFile(filePath, content) {
|
|
69
|
+
const json = `${JSON.stringify(content, null, '\t')}\n`;
|
|
70
|
+
if (fs.existsSync(filePath)) {
|
|
71
|
+
try {
|
|
72
|
+
// Compared with line endings normalised, which is how git sees the file: a
|
|
73
|
+
// Windows checkout materialises CRLF, and rewriting every locale file in LF
|
|
74
|
+
// to "fix" that is exactly the churn this check exists to avoid. The file
|
|
75
|
+
// keeps whatever endings it has as long as the content matches.
|
|
76
|
+
if (fs.readFileSync(filePath, 'utf8').replace(/\r\n/g, '\n') === json)
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Unreadable: fall through and write, which is the repair.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Atomic per-file write: a failed run never leaves a partial locale file.
|
|
84
|
+
const temporaryPath = `${filePath}.tmp`;
|
|
85
|
+
fs.writeFileSync(temporaryPath, json, 'utf8');
|
|
86
|
+
fs.renameSync(temporaryPath, filePath);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Synchronizes every configured locale JSON file against the scanned
|
|
91
|
+
* template: creates missing files, adds missing keys with the configured
|
|
92
|
+
* placeholder, preserves existing translations verbatim, removes stale keys,
|
|
93
|
+
* and protects declared runtime-only entries (FR-027…FR-030, FR-034/FR-035).
|
|
94
|
+
* Conflicted keys are never added or overwritten while the conflict is open.
|
|
95
|
+
*/
|
|
96
|
+
export function syncLocaleFiles(rootDir, config, template, runtimeEntries) {
|
|
97
|
+
const templateByKey = new Map(template.keys.map(key => [key.key, key]));
|
|
98
|
+
const conflictedKeys = new Set(template.conflicts.map(conflict => conflict.key));
|
|
99
|
+
const runtimeByKey = new Map(runtimeEntries.map(entry => [entry.key, entry]));
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const locale of config.locales) {
|
|
102
|
+
const filePath = path.join(rootDir, config.localesDir, `${locale}.json`);
|
|
103
|
+
const result = {
|
|
104
|
+
locale,
|
|
105
|
+
filePath,
|
|
106
|
+
created: false,
|
|
107
|
+
addedKeys: [],
|
|
108
|
+
preservedKeys: [],
|
|
109
|
+
removedKeys: [],
|
|
110
|
+
runtimePreserved: [],
|
|
111
|
+
runtimeAdded: [],
|
|
112
|
+
runtimeReported: [],
|
|
113
|
+
written: false,
|
|
114
|
+
};
|
|
115
|
+
results.push(result);
|
|
116
|
+
let existing = new Map();
|
|
117
|
+
if (fs.existsSync(filePath)) {
|
|
118
|
+
try {
|
|
119
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
120
|
+
existing = flattenTranslations(parsed);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
result.error = `Malformed locale file ${locale}.json: ${String(error)}`;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
result.created = true;
|
|
129
|
+
}
|
|
130
|
+
const next = new Map();
|
|
131
|
+
for (const [key, templateKey] of templateByKey) {
|
|
132
|
+
const current = existing.get(key);
|
|
133
|
+
if (current !== undefined) {
|
|
134
|
+
next.set(key, current);
|
|
135
|
+
result.preservedKeys.push(key);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (conflictedKeys.has(key)) {
|
|
139
|
+
// Reported for manual review; never silently added (FR-031).
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
next.set(key, placeholderValue(config, locale, key, templateKey.defaultText));
|
|
143
|
+
result.addedKeys.push(key);
|
|
144
|
+
}
|
|
145
|
+
for (const [key, entry] of runtimeByKey) {
|
|
146
|
+
const current = existing.get(key);
|
|
147
|
+
if (current !== undefined) {
|
|
148
|
+
next.set(key, current);
|
|
149
|
+
result.runtimePreserved.push(key);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if ((entry.policy ?? 'report') === 'add') {
|
|
153
|
+
next.set(key, placeholderValue(config, locale, key, entry.defaultText));
|
|
154
|
+
result.runtimeAdded.push(key);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
result.runtimeReported.push(key);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
for (const key of existing.keys()) {
|
|
161
|
+
if (!next.has(key) && !runtimeByKey.has(key) && !conflictedKeys.has(key)) {
|
|
162
|
+
result.removedKeys.push(key);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
166
|
+
result.written = writeLocaleFile(filePath, nestTranslations(next));
|
|
167
|
+
result.addedKeys.sort((a, b) => a.localeCompare(b, 'en'));
|
|
168
|
+
result.preservedKeys.sort((a, b) => a.localeCompare(b, 'en'));
|
|
169
|
+
result.removedKeys.sort((a, b) => a.localeCompare(b, 'en'));
|
|
170
|
+
}
|
|
171
|
+
return results;
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=sync.js.map
|
package/lib/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contracts for the Node-only extraction and synchronization tooling.
|
|
3
|
+
* This module must stay free of React Native imports; it is consumed through
|
|
4
|
+
* this package's entrypoint and its `chip-i18n` command.
|
|
5
|
+
*/
|
|
6
|
+
export interface PatternConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Regex source with a named `key` capture group for statically resolvable
|
|
9
|
+
* keys, and an optional named `defaultText` group for template values.
|
|
10
|
+
*/
|
|
11
|
+
regex: string;
|
|
12
|
+
/** Extra regex flags; `g` is always applied. */
|
|
13
|
+
flags?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional regex matching dynamic usages of the same call style. Matches
|
|
16
|
+
* that do not overlap a static key match are reported as ambiguous.
|
|
17
|
+
*/
|
|
18
|
+
ambiguousRegex?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SyncConfig {
|
|
21
|
+
/** Globs relative to the project root, e.g. `src/**\/*.{ts,tsx}`. */
|
|
22
|
+
sourceGlobs: string[];
|
|
23
|
+
patterns: PatternConfig[];
|
|
24
|
+
/** Directory containing `<locale>.json` files. */
|
|
25
|
+
localesDir: string;
|
|
26
|
+
locales: string[];
|
|
27
|
+
/** Module exporting the declared runtime-only entries. */
|
|
28
|
+
runtimeEntriesFile?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Value written for newly added keys: `template` uses the discovered
|
|
31
|
+
* default text (falling back to the key), a string is used verbatim, and
|
|
32
|
+
* a map selects per locale. Default: `template`.
|
|
33
|
+
*/
|
|
34
|
+
placeholder?: 'template' | string | Record<string, string>;
|
|
35
|
+
/** Optional JSON report output path. */
|
|
36
|
+
reportPath?: string;
|
|
37
|
+
/** Generated typed key artifact path, e.g. `src/i18n/keys.generated.ts`. */
|
|
38
|
+
generateKeysFile?: string;
|
|
39
|
+
/** Exported key type name. Default: `AppI18nKey`. */
|
|
40
|
+
keysTypeName?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface RuntimeEntryConfig {
|
|
43
|
+
key: string;
|
|
44
|
+
defaultText: string;
|
|
45
|
+
policy?: 'add' | 'report';
|
|
46
|
+
description?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface SourceLocation {
|
|
49
|
+
file: string;
|
|
50
|
+
line: number;
|
|
51
|
+
}
|
|
52
|
+
export interface TemplateKey {
|
|
53
|
+
key: string;
|
|
54
|
+
defaultText?: string;
|
|
55
|
+
locations: SourceLocation[];
|
|
56
|
+
}
|
|
57
|
+
export interface AmbiguousUsage {
|
|
58
|
+
file: string;
|
|
59
|
+
line: number;
|
|
60
|
+
snippet: string;
|
|
61
|
+
}
|
|
62
|
+
export interface KeyConflict {
|
|
63
|
+
key: string;
|
|
64
|
+
values: {
|
|
65
|
+
text: string;
|
|
66
|
+
location: SourceLocation;
|
|
67
|
+
}[];
|
|
68
|
+
}
|
|
69
|
+
export interface TranslationTemplate {
|
|
70
|
+
/** Discovered keys sorted by key name. */
|
|
71
|
+
keys: TemplateKey[];
|
|
72
|
+
ambiguous: AmbiguousUsage[];
|
|
73
|
+
conflicts: KeyConflict[];
|
|
74
|
+
scannedFiles: number;
|
|
75
|
+
}
|
|
76
|
+
export interface LocaleSyncResult {
|
|
77
|
+
locale: string;
|
|
78
|
+
filePath: string;
|
|
79
|
+
created: boolean;
|
|
80
|
+
addedKeys: string[];
|
|
81
|
+
preservedKeys: string[];
|
|
82
|
+
removedKeys: string[];
|
|
83
|
+
runtimePreserved: string[];
|
|
84
|
+
runtimeAdded: string[];
|
|
85
|
+
runtimeReported: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Whether the file on disk changed. A sync that finds nothing to do writes
|
|
88
|
+
* nothing: rewriting identical bytes churned every locale file's mtime, so a
|
|
89
|
+
* watcher rebuilt and `git status` showed work that had not happened.
|
|
90
|
+
*/
|
|
91
|
+
written: boolean;
|
|
92
|
+
/** Set when the locale file is malformed; no write happened. */
|
|
93
|
+
error?: string;
|
|
94
|
+
}
|
|
95
|
+
export type ReportOutcome = 'success' | 'completedWithWarnings' | 'failed';
|
|
96
|
+
export interface ExtractionReport {
|
|
97
|
+
outcome: ReportOutcome;
|
|
98
|
+
discovered: {
|
|
99
|
+
key: string;
|
|
100
|
+
defaultText?: string;
|
|
101
|
+
locations: string[];
|
|
102
|
+
}[];
|
|
103
|
+
createdLocaleFiles: {
|
|
104
|
+
locale: string;
|
|
105
|
+
filePath: string;
|
|
106
|
+
}[];
|
|
107
|
+
/** Locales whose file on disk actually changed; empty when the sync was a no-op. */
|
|
108
|
+
writtenLocaleFiles: string[];
|
|
109
|
+
addedKeys: Record<string, string[]>;
|
|
110
|
+
preservedKeys: Record<string, string[]>;
|
|
111
|
+
removedStaleKeys: Record<string, string[]>;
|
|
112
|
+
missingPerLocale: Record<string, string[]>;
|
|
113
|
+
runtimeOnly: {
|
|
114
|
+
declared: string[];
|
|
115
|
+
preserved: Record<string, string[]>;
|
|
116
|
+
added: Record<string, string[]>;
|
|
117
|
+
reported: Record<string, string[]>;
|
|
118
|
+
};
|
|
119
|
+
ambiguous: AmbiguousUsage[];
|
|
120
|
+
conflicts: KeyConflict[];
|
|
121
|
+
errors: string[];
|
|
122
|
+
}
|
|
123
|
+
//# 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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"}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contracts for the Node-only extraction and synchronization tooling.
|
|
3
|
+
* This module must stay free of React Native imports; it is consumed through
|
|
4
|
+
* this package's entrypoint and its `chip-i18n` command.
|
|
5
|
+
*/
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|