@scoutello/i18n-magic 0.18.0 → 0.20.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/README.md +55 -44
- package/dist/cli.js +0 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/clean.d.ts.map +1 -1
- package/dist/commands/clean.js +16 -28
- package/dist/commands/clean.js.map +1 -1
- package/dist/commands/create-pruned-namespace.d.ts.map +1 -1
- package/dist/commands/create-pruned-namespace.js +2 -1
- package/dist/commands/create-pruned-namespace.js.map +1 -1
- package/dist/commands/replace.d.ts.map +1 -1
- package/dist/commands/replace.js +79 -32
- package/dist/commands/replace.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +4 -6
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +27 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +93 -14
- package/dist/lib/utils.js.map +1 -1
- package/package.json +3 -2
- package/src/cli.ts +1 -6
- package/src/commands/clean.ts +19 -29
- package/src/commands/replace.ts +97 -46
- package/src/index.ts +3 -8
- package/src/lib/types.ts +4 -6
- package/src/lib/utils.ts +127 -19
- package/src/commands/create-pruned-namespace-automated.ts +0 -165
- package/src/commands/create-pruned-namespace.ts +0 -165
package/src/lib/utils.ts
CHANGED
|
@@ -5,7 +5,7 @@ import path from "node:path"
|
|
|
5
5
|
import type OpenAI from "openai"
|
|
6
6
|
import prompts from "prompts"
|
|
7
7
|
import { languages } from "./languges"
|
|
8
|
-
import type { Configuration } from "./types"
|
|
8
|
+
import type { Configuration, GlobPatternConfig } from "./types"
|
|
9
9
|
|
|
10
10
|
export const loadConfig = ({
|
|
11
11
|
configPath = "i18n-magic.js",
|
|
@@ -180,33 +180,145 @@ export const getPureKey = (
|
|
|
180
180
|
return null
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Extracts all glob patterns from the configuration, handling both string and object formats
|
|
185
|
+
*/
|
|
186
|
+
export const extractGlobPatterns = (
|
|
187
|
+
globPatterns: (string | GlobPatternConfig)[],
|
|
188
|
+
): string[] => {
|
|
189
|
+
return globPatterns.map((pattern) =>
|
|
190
|
+
typeof pattern === "string" ? pattern : pattern.pattern,
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Gets the namespaces associated with a specific file path based on glob pattern configuration
|
|
196
|
+
*/
|
|
197
|
+
export const getNamespacesForFile = (
|
|
198
|
+
filePath: string,
|
|
199
|
+
globPatterns: (string | { pattern: string; namespaces: string[] })[],
|
|
200
|
+
defaultNamespace: string,
|
|
201
|
+
): string[] => {
|
|
202
|
+
const matchingNamespaces: string[] = []
|
|
203
|
+
|
|
204
|
+
for (const pattern of globPatterns) {
|
|
205
|
+
if (typeof pattern === "object") {
|
|
206
|
+
// Use minimatch or similar logic to check if file matches pattern
|
|
207
|
+
const globPattern = pattern.pattern
|
|
208
|
+
// For now, using a simple includes check - in production you'd want proper glob matching
|
|
209
|
+
if (filePath.includes(globPattern.replace("**/*", "").replace("*", ""))) {
|
|
210
|
+
matchingNamespaces.push(...pattern.namespaces)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// If no specific namespaces found, use default namespace
|
|
216
|
+
return matchingNamespaces.length > 0
|
|
217
|
+
? [...new Set(matchingNamespaces)]
|
|
218
|
+
: [defaultNamespace]
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Gets all glob patterns that should be used for a specific namespace
|
|
223
|
+
*/
|
|
224
|
+
export const getGlobPatternsForNamespace = (
|
|
225
|
+
namespace: string,
|
|
226
|
+
globPatterns: (string | { pattern: string; namespaces: string[] })[],
|
|
227
|
+
): string[] => {
|
|
228
|
+
const patterns: string[] = []
|
|
229
|
+
|
|
230
|
+
for (const pattern of globPatterns) {
|
|
231
|
+
if (typeof pattern === "string") {
|
|
232
|
+
// String patterns apply to all namespaces
|
|
233
|
+
patterns.push(pattern)
|
|
234
|
+
} else if (pattern.namespaces.includes(namespace)) {
|
|
235
|
+
// Object patterns only apply to specified namespaces
|
|
236
|
+
patterns.push(pattern.pattern)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return patterns
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Extracts keys with their associated namespaces based on the files they're found in
|
|
245
|
+
*/
|
|
246
|
+
export const getKeysWithNamespaces = async ({
|
|
184
247
|
globPatterns,
|
|
185
|
-
namespaces,
|
|
186
248
|
defaultNamespace,
|
|
187
|
-
|
|
188
|
-
loadPath,
|
|
189
|
-
}: Configuration) => {
|
|
249
|
+
}: Pick<Configuration, "globPatterns" | "defaultNamespace">) => {
|
|
190
250
|
const parser = new Parser({
|
|
191
251
|
nsSeparator: false,
|
|
192
252
|
keySeparator: false,
|
|
193
253
|
})
|
|
194
254
|
|
|
195
|
-
const
|
|
255
|
+
const allPatterns = extractGlobPatterns(globPatterns)
|
|
256
|
+
const files = await glob([...allPatterns, "!**/node_modules/**"])
|
|
196
257
|
|
|
197
|
-
const
|
|
258
|
+
const keysWithNamespaces: Array<{
|
|
259
|
+
key: string
|
|
260
|
+
namespaces: string[]
|
|
261
|
+
file: string
|
|
262
|
+
}> = []
|
|
198
263
|
|
|
199
264
|
for (const file of files) {
|
|
200
265
|
const content = fs.readFileSync(file, "utf-8")
|
|
266
|
+
const fileKeys: string[] = []
|
|
267
|
+
|
|
201
268
|
parser.parseFuncFromString(content, { list: ["t"] }, (key: string) => {
|
|
202
|
-
|
|
269
|
+
fileKeys.push(key)
|
|
203
270
|
})
|
|
271
|
+
|
|
272
|
+
// Get namespaces for this file
|
|
273
|
+
const fileNamespaces = getNamespacesForFile(
|
|
274
|
+
file,
|
|
275
|
+
globPatterns,
|
|
276
|
+
defaultNamespace,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
// Add each key with its associated namespaces
|
|
280
|
+
for (const key of fileKeys) {
|
|
281
|
+
keysWithNamespaces.push({
|
|
282
|
+
key,
|
|
283
|
+
namespaces: fileNamespaces,
|
|
284
|
+
file,
|
|
285
|
+
})
|
|
286
|
+
}
|
|
204
287
|
}
|
|
205
288
|
|
|
206
|
-
|
|
289
|
+
return keysWithNamespaces
|
|
290
|
+
}
|
|
207
291
|
|
|
292
|
+
export const getMissingKeys = async ({
|
|
293
|
+
globPatterns,
|
|
294
|
+
namespaces,
|
|
295
|
+
defaultNamespace,
|
|
296
|
+
defaultLocale,
|
|
297
|
+
loadPath,
|
|
298
|
+
}: Configuration) => {
|
|
299
|
+
const keysWithNamespaces = await getKeysWithNamespaces({
|
|
300
|
+
globPatterns,
|
|
301
|
+
defaultNamespace,
|
|
302
|
+
})
|
|
208
303
|
const newKeys = []
|
|
209
304
|
|
|
305
|
+
// Group keys by namespace
|
|
306
|
+
const keysByNamespace: Record<string, Set<string>> = {}
|
|
307
|
+
|
|
308
|
+
for (const { key, namespaces: keyNamespaces } of keysWithNamespaces) {
|
|
309
|
+
for (const namespace of keyNamespaces) {
|
|
310
|
+
if (!keysByNamespace[namespace]) {
|
|
311
|
+
keysByNamespace[namespace] = new Set()
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const pureKey = getPureKey(key, namespace, namespace === defaultNamespace)
|
|
315
|
+
if (pureKey) {
|
|
316
|
+
keysByNamespace[namespace].add(pureKey)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Check for missing keys in each namespace
|
|
210
322
|
for (const namespace of namespaces) {
|
|
211
323
|
const existingKeys = await loadLocalesFile(
|
|
212
324
|
loadPath,
|
|
@@ -214,17 +326,13 @@ export const getMissingKeys = async ({
|
|
|
214
326
|
namespace,
|
|
215
327
|
)
|
|
216
328
|
|
|
217
|
-
console.log(Object.keys(existingKeys).length, "existing keys")
|
|
329
|
+
console.log(Object.keys(existingKeys).length, "existing keys in", namespace)
|
|
218
330
|
|
|
219
|
-
|
|
220
|
-
const pureKey = getPureKey(key, namespace, namespace === defaultNamespace)
|
|
221
|
-
|
|
222
|
-
if (!pureKey) {
|
|
223
|
-
continue
|
|
224
|
-
}
|
|
331
|
+
const keysForNamespace = keysByNamespace[namespace] || new Set()
|
|
225
332
|
|
|
226
|
-
|
|
227
|
-
|
|
333
|
+
for (const key of keysForNamespace) {
|
|
334
|
+
if (!existingKeys[key]) {
|
|
335
|
+
newKeys.push({ key, namespace })
|
|
228
336
|
}
|
|
229
337
|
}
|
|
230
338
|
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import glob from "fast-glob"
|
|
2
|
-
import { Parser } from "i18next-scanner"
|
|
3
|
-
import fs from "node:fs"
|
|
4
|
-
import type { Configuration } from "../lib/types"
|
|
5
|
-
import {
|
|
6
|
-
getPureKey,
|
|
7
|
-
loadLocalesFile,
|
|
8
|
-
removeDuplicatesFromArray,
|
|
9
|
-
writeLocalesFile,
|
|
10
|
-
} from "../lib/utils"
|
|
11
|
-
|
|
12
|
-
export interface PruneOptions {
|
|
13
|
-
sourceNamespace: string
|
|
14
|
-
newNamespace: string
|
|
15
|
-
globPatterns: string[]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface PruneResult {
|
|
19
|
-
locale: string
|
|
20
|
-
keyCount: number
|
|
21
|
-
success: boolean
|
|
22
|
-
error?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface PruneResponse {
|
|
26
|
-
success: boolean
|
|
27
|
-
message: string
|
|
28
|
-
keysCount: number
|
|
29
|
-
results?: PruneResult[]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const createPrunedNamespaceAutomated = async (
|
|
33
|
-
config: Configuration,
|
|
34
|
-
options: PruneOptions,
|
|
35
|
-
): Promise<PruneResponse> => {
|
|
36
|
-
const { namespaces, loadPath, savePath, locales, defaultNamespace } = config
|
|
37
|
-
const { sourceNamespace, newNamespace, globPatterns } = options
|
|
38
|
-
|
|
39
|
-
// Validate inputs
|
|
40
|
-
if (!namespaces.includes(sourceNamespace)) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
`Source namespace '${sourceNamespace}' not found in configuration`,
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (namespaces.includes(newNamespace)) {
|
|
47
|
-
throw new Error(`Namespace '${newNamespace}' already exists`)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
console.log(
|
|
51
|
-
`Creating pruned namespace '${newNamespace}' from '${sourceNamespace}'`,
|
|
52
|
-
)
|
|
53
|
-
console.log(`Using glob patterns: ${globPatterns.join(", ")}`)
|
|
54
|
-
|
|
55
|
-
// Extract keys from files matching the glob patterns
|
|
56
|
-
const parser = new Parser({
|
|
57
|
-
nsSeparator: false,
|
|
58
|
-
keySeparator: false,
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
const files = await glob([...globPatterns, "!**/node_modules/**"])
|
|
62
|
-
console.log(`Found ${files.length} files to scan`)
|
|
63
|
-
|
|
64
|
-
const extractedKeys = []
|
|
65
|
-
|
|
66
|
-
for (const file of files) {
|
|
67
|
-
const content = fs.readFileSync(file, "utf-8")
|
|
68
|
-
parser.parseFuncFromString(content, { list: ["t"] }, (key: string) => {
|
|
69
|
-
extractedKeys.push(key)
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const uniqueExtractedKeys = removeDuplicatesFromArray(extractedKeys)
|
|
74
|
-
console.log(`Found ${uniqueExtractedKeys.length} unique translation keys`)
|
|
75
|
-
|
|
76
|
-
// Filter keys that belong to the source namespace
|
|
77
|
-
const relevantKeys = []
|
|
78
|
-
|
|
79
|
-
for (const key of uniqueExtractedKeys) {
|
|
80
|
-
const pureKey = getPureKey(
|
|
81
|
-
key,
|
|
82
|
-
sourceNamespace,
|
|
83
|
-
sourceNamespace === defaultNamespace,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
if (pureKey) {
|
|
87
|
-
relevantKeys.push(pureKey)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log(
|
|
92
|
-
`Found ${relevantKeys.length} keys from namespace '${sourceNamespace}'`,
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
if (relevantKeys.length === 0) {
|
|
96
|
-
console.log("No relevant keys found. Exiting...")
|
|
97
|
-
return {
|
|
98
|
-
success: false,
|
|
99
|
-
message: "No relevant keys found",
|
|
100
|
-
keysCount: 0,
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Get translations from source namespace and create new namespace files
|
|
105
|
-
const results: PruneResult[] = []
|
|
106
|
-
|
|
107
|
-
for (const locale of locales) {
|
|
108
|
-
try {
|
|
109
|
-
// Load source namespace translations
|
|
110
|
-
const sourceTranslations = await loadLocalesFile(
|
|
111
|
-
loadPath,
|
|
112
|
-
locale,
|
|
113
|
-
sourceNamespace,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
// Create new namespace with only the keys used in the glob pattern files
|
|
117
|
-
const newNamespaceTranslations: Record<string, string> = {}
|
|
118
|
-
|
|
119
|
-
for (const key of relevantKeys) {
|
|
120
|
-
if (sourceTranslations[key]) {
|
|
121
|
-
newNamespaceTranslations[key] = sourceTranslations[key]
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Write the new namespace file
|
|
126
|
-
await writeLocalesFile(
|
|
127
|
-
savePath,
|
|
128
|
-
locale,
|
|
129
|
-
newNamespace,
|
|
130
|
-
newNamespaceTranslations,
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
const keyCount = Object.keys(newNamespaceTranslations).length
|
|
134
|
-
console.log(
|
|
135
|
-
`Created pruned namespace '${newNamespace}' for locale '${locale}' with ${keyCount} keys`,
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
results.push({
|
|
139
|
-
locale,
|
|
140
|
-
keyCount,
|
|
141
|
-
success: true,
|
|
142
|
-
})
|
|
143
|
-
} catch (error) {
|
|
144
|
-
console.error(
|
|
145
|
-
`Error creating pruned namespace for locale '${locale}':`,
|
|
146
|
-
error,
|
|
147
|
-
)
|
|
148
|
-
results.push({
|
|
149
|
-
locale,
|
|
150
|
-
keyCount: 0,
|
|
151
|
-
success: false,
|
|
152
|
-
error: error instanceof Error ? error.message : String(error),
|
|
153
|
-
})
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.log(`✅ Successfully created pruned namespace '${newNamespace}'`)
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
success: true,
|
|
161
|
-
message: `Created pruned namespace '${newNamespace}' with ${relevantKeys.length} keys`,
|
|
162
|
-
keysCount: relevantKeys.length,
|
|
163
|
-
results,
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import glob from "fast-glob"
|
|
2
|
-
import { Parser } from "i18next-scanner"
|
|
3
|
-
import fs from "node:fs"
|
|
4
|
-
import prompts from "prompts"
|
|
5
|
-
import type { Configuration } from "../lib/types"
|
|
6
|
-
import {
|
|
7
|
-
getPureKey,
|
|
8
|
-
loadLocalesFile,
|
|
9
|
-
removeDuplicatesFromArray,
|
|
10
|
-
writeLocalesFile,
|
|
11
|
-
} from "../lib/utils"
|
|
12
|
-
|
|
13
|
-
export const createPrunedNamespace = async (config: Configuration) => {
|
|
14
|
-
const { namespaces, loadPath, savePath, locales, defaultNamespace } = config
|
|
15
|
-
|
|
16
|
-
// Step 1: Ask for source namespace
|
|
17
|
-
const sourceNamespaceResponse = await prompts({
|
|
18
|
-
type: "select",
|
|
19
|
-
name: "value",
|
|
20
|
-
message: "Select source namespace to create pruned version from:",
|
|
21
|
-
choices: namespaces.map((namespace) => ({
|
|
22
|
-
title: namespace,
|
|
23
|
-
value: namespace,
|
|
24
|
-
})),
|
|
25
|
-
onState: (state) => {
|
|
26
|
-
if (state.aborted) {
|
|
27
|
-
process.nextTick(() => {
|
|
28
|
-
process.exit(0)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const sourceNamespace = sourceNamespaceResponse.value
|
|
35
|
-
|
|
36
|
-
// Step 2: Ask for new namespace name
|
|
37
|
-
const newNamespaceResponse = await prompts({
|
|
38
|
-
type: "text",
|
|
39
|
-
name: "value",
|
|
40
|
-
message: "Enter the name for the new namespace:",
|
|
41
|
-
validate: (value) => {
|
|
42
|
-
if (!value) return "Namespace name cannot be empty"
|
|
43
|
-
if (namespaces.includes(value)) return "Namespace already exists"
|
|
44
|
-
return true
|
|
45
|
-
},
|
|
46
|
-
onState: (state) => {
|
|
47
|
-
if (state.aborted) {
|
|
48
|
-
process.nextTick(() => {
|
|
49
|
-
process.exit(0)
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const newNamespace = newNamespaceResponse.value
|
|
56
|
-
|
|
57
|
-
// Step 3: Ask for glob patterns to find relevant keys
|
|
58
|
-
const globPatternsResponse = await prompts({
|
|
59
|
-
type: "list",
|
|
60
|
-
name: "value",
|
|
61
|
-
message: "Enter glob patterns to find relevant keys (comma separated):",
|
|
62
|
-
initial: config.globPatterns.join(","),
|
|
63
|
-
separator: ",",
|
|
64
|
-
onState: (state) => {
|
|
65
|
-
if (state.aborted) {
|
|
66
|
-
process.nextTick(() => {
|
|
67
|
-
process.exit(0)
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
const selectedGlobPatterns = globPatternsResponse.value
|
|
74
|
-
|
|
75
|
-
console.log(
|
|
76
|
-
`Finding keys used in files matching: ${selectedGlobPatterns.join(", ")}`,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
// Extract keys from files matching the glob patterns
|
|
80
|
-
const parser = new Parser({
|
|
81
|
-
nsSeparator: false,
|
|
82
|
-
keySeparator: false,
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
const files = await glob([...selectedGlobPatterns, "!**/node_modules/**"])
|
|
86
|
-
console.log(`Found ${files.length} files to scan`)
|
|
87
|
-
|
|
88
|
-
const extractedKeys = []
|
|
89
|
-
|
|
90
|
-
for (const file of files) {
|
|
91
|
-
const content = fs.readFileSync(file, "utf-8")
|
|
92
|
-
parser.parseFuncFromString(content, { list: ["t"] }, (key: string) => {
|
|
93
|
-
extractedKeys.push(key)
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const uniqueExtractedKeys = removeDuplicatesFromArray(extractedKeys)
|
|
98
|
-
console.log(`Found ${uniqueExtractedKeys.length} unique translation keys`)
|
|
99
|
-
|
|
100
|
-
// Filter keys that belong to the source namespace
|
|
101
|
-
const relevantKeys = []
|
|
102
|
-
|
|
103
|
-
for (const key of uniqueExtractedKeys) {
|
|
104
|
-
const pureKey = getPureKey(
|
|
105
|
-
key,
|
|
106
|
-
sourceNamespace,
|
|
107
|
-
sourceNamespace === defaultNamespace,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
if (pureKey) {
|
|
111
|
-
relevantKeys.push(pureKey)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log(
|
|
116
|
-
`Found ${relevantKeys.length} keys from namespace '${sourceNamespace}'`,
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
if (relevantKeys.length === 0) {
|
|
120
|
-
console.log("No relevant keys found. Exiting...")
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Get translations from source namespace and create new namespace files
|
|
125
|
-
for (const locale of locales) {
|
|
126
|
-
try {
|
|
127
|
-
// Load source namespace translations
|
|
128
|
-
const sourceTranslations = await loadLocalesFile(
|
|
129
|
-
loadPath,
|
|
130
|
-
locale,
|
|
131
|
-
sourceNamespace,
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
// Create new namespace with only the keys used in the glob pattern files
|
|
135
|
-
const newNamespaceTranslations: Record<string, string> = {}
|
|
136
|
-
|
|
137
|
-
for (const key of relevantKeys) {
|
|
138
|
-
if (sourceTranslations[key]) {
|
|
139
|
-
newNamespaceTranslations[key] = sourceTranslations[key]
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Write the new namespace file
|
|
144
|
-
await writeLocalesFile(
|
|
145
|
-
savePath,
|
|
146
|
-
locale,
|
|
147
|
-
newNamespace,
|
|
148
|
-
newNamespaceTranslations,
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
console.log(
|
|
152
|
-
`Created pruned namespace '${newNamespace}' for locale '${locale}' with ${
|
|
153
|
-
Object.keys(newNamespaceTranslations).length
|
|
154
|
-
} keys`,
|
|
155
|
-
)
|
|
156
|
-
} catch (error) {
|
|
157
|
-
console.error(
|
|
158
|
-
`Error creating pruned namespace for locale '${locale}':`,
|
|
159
|
-
error,
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
console.log(`✅ Successfully created pruned namespace '${newNamespace}'`)
|
|
165
|
-
}
|