Skip to content

Commit

Permalink
feat: add keepMissing option (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
freakzlike authored Sep 28, 2024
1 parent f9b85da commit d091e45
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 8 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ module.exports = {
// Optional: Default value for new translations
defaultValue: '__MISSING_TRANSLATION__',
// Optional: Regex to extract transations from source code
parseRegex: /\B\$t\s*\(\s*['"]([\w/: ._-]+)['"]/g
parseRegex: /\B\$t\s*\(\s*['"]([\w/: ._-]+)['"]/g,
// Optional: Keep missing translations and not delete them
keepMissing: false
}
```
3 changes: 2 additions & 1 deletion examples/default/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"key_2": "Key 2 DE",
"key_4": "Key 4 DE",
"context": {
"key_1": "Context Key 1 DE",
"key_2": "Context Key 2 DE",
"key_1": "Context Key 1 DE",
"nested": {
"old": "Old nested key DE",
"key": "Nested Key DE"
}
},
Expand Down
3 changes: 2 additions & 1 deletion examples/default/locales/en-GB.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"key_2": "Key 2 EN",
"key_4": "Key 4 EN",
"context": {
"key_1": "Context Key 1 EN",
"key_2": "Context Key 2 EN",
"key_1": "Context Key 1 EN",
"nested": {
"old": "Old nested key EN",
"key": "Nested Key EN"
}
},
Expand Down
9 changes: 8 additions & 1 deletion src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ export const writeTranslations = async (
): Promise<void> => {
await Promise.all(Object.values(translationResults).map(async (languageTranslations) => {
await Promise.all(Object.values(languageTranslations).map(async ({ filePath, translations }) => {
const content = JSON.stringify(translations, undefined, 2)

// Sort all keys
const allKeys = new Set<string>()
JSON.stringify(translations, (key, value) => {
allKeys.add(key)
return value
})
const content = JSON.stringify(translations, Array.from(allKeys).sort(), 2)

const directory = dirname(filePath)
if (!existsSync(directory)) {
Expand Down
7 changes: 5 additions & 2 deletions src/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ export const generateNewTranslations = async (
options: I18nExtractOptions
): Promise<TranslationMapWrite> => {
return generateTranslationMap(options, async ({ language, namespace }) => {
let translations: TranslationStructure = {}
const _existingTranslations = existingTranslations[language]?.[namespace]?.translations || {}

let translations: TranslationStructure = options.keepMissing
? JSON.parse(JSON.stringify(_existingTranslations))
: {}
let result: TranslationResultWrite = {
translations,
untranslatedCount: 0
}

const _translationKeys = translationKeys[namespace] || []
const _existingTranslations = existingTranslations[language]?.[namespace]?.translations || {}
for (const translationKey of _translationKeys) {
[translations, result] = await writeTranslationStructure(
translationKey,
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export interface I18nExtractOptions {
namespaces?: Namespace[]
defaultValue?: string
parseRegex?: RegExp
keepMissing?: boolean
}
45 changes: 45 additions & 0 deletions tests/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,51 @@ describe('i18nExtract', () => {
}))
})

it('should extract translations and keep old', async () => {
const options = await import('../examples/default/i18n-extract.config.cjs')
await i18nExtract({
...options.default,
keepMissing: true
})

expect(mockedMkdir).not.toHaveBeenCalled()

expect(mockedWriteFile).toHaveBeenCalledTimes(2)

expect(mockedWriteFile).toHaveBeenCalledWith('examples/default/locales/de.json', toJSON({
context: {
key_1: 'Context Key 1 DE',
key_2: 'Context Key 2 DE',
nested: {
key: 'Nested Key DE',
old: 'Old nested key DE'
}
},
key_1: 'Key 1 DE',
key_2: 'Key 2 DE',
key_3: 'Key 3 DE',
key_4: 'Key 4 DE',
new_key: '__MISSING_TRANSLATION__',
old_key: 'Old key'
}))
expect(mockedWriteFile).toHaveBeenCalledWith('examples/default/locales/en-GB.json', toJSON({
context: {
key_1: 'Context Key 1 EN',
key_2: 'Context Key 2 EN',
nested: {
key: 'Nested Key EN',
old: 'Old nested key EN'
}
},
key_1: 'Key 1 EN',
key_2: 'Key 2 EN',
key_3: 'Key 3 EN',
key_4: 'Key 4 EN',
new_key: '__MISSING_TRANSLATION__',
old_key: 'Old key'
}))
})

it('should extract with missing translations', async () => {
const options = await import('../examples/default/i18n-extract.config.cjs')
await i18nExtract({
Expand Down
6 changes: 4 additions & 2 deletions tests/load.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ describe('loadTranslations', () => {
key_2: 'Key 2 DE',
key_4: 'Key 4 DE',
context: {
key_1: 'Context Key 1 DE',
key_2: 'Context Key 2 DE',
key_1: 'Context Key 1 DE',
nested: {
old: 'Old nested key DE',
key: 'Nested Key DE'
}
},
Expand All @@ -98,9 +99,10 @@ describe('loadTranslations', () => {
key_2: 'Key 2 EN',
key_4: 'Key 4 EN',
context: {
key_1: 'Context Key 1 EN',
key_2: 'Context Key 2 EN',
key_1: 'Context Key 1 EN',
nested: {
old: 'Old nested key EN',
key: 'Nested Key EN'
}
},
Expand Down

0 comments on commit d091e45

Please sign in to comment.