From c90e807ce35187d739e11725ad6f3a3524cbeebb Mon Sep 17 00:00:00 2001 From: BART! Date: Sun, 17 Aug 2025 21:43:31 +0200 Subject: [PATCH 1/4] feat(missing-translation): add translation var --- src/create-report/language-files.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/create-report/language-files.ts b/src/create-report/language-files.ts index 5e638f1f..720dc2a4 100644 --- a/src/create-report/language-files.ts +++ b/src/create-report/language-files.ts @@ -69,7 +69,17 @@ export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys.forEach(item => { if (item.language && languageFile.fileName.includes(item.language) || !item.language) { const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language)); - dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent); + let value: string | null = null; + if (addDefaultTranslation) { + value = item.path; + } else if (missingTranslationString === 'null') { + value = null; + } else if (missingTranslationString.includes('{{t}}')) { + value = missingTranslationString.replace('{{t}}', item.path); + } else { + value = missingTranslationString; + } + dot.str(item.path, value, languageFileContent); } }); From 47558d14cb2bf9126b9cdd8fc6afcdfb86f9630e Mon Sep 17 00:00:00 2001 From: BART! Date: Sun, 17 Aug 2025 21:46:19 +0200 Subject: [PATCH 2/4] feat(build): build dist --- dist/types.d.ts | 12 ++-- dist/vue-i18n-extract.modern.mjs | 90 +++++++----------------- dist/vue-i18n-extract.modern.mjs.map | 2 +- dist/vue-i18n-extract.umd.js | 101 ++++++++------------------- dist/vue-i18n-extract.umd.js.map | 2 +- 5 files changed, 61 insertions(+), 146 deletions(-) diff --git a/dist/types.d.ts b/dist/types.d.ts index f912a4f7..504e7f94 100644 --- a/dist/types.d.ts +++ b/dist/types.d.ts @@ -1,4 +1,4 @@ -export declare type ReportOptions = { +export type ReportOptions = { vueFiles: string; languageFiles: string; output?: string; @@ -16,25 +16,25 @@ export declare enum DetectionType { Unused = "unused", Dynamic = "dynamic" } -export declare type SimpleFile = { +export type SimpleFile = { fileName: string; path: string; content: string; }; -export declare type I18NItem = { +export type I18NItem = { line?: number; path: string; file?: string; language?: string; }; -export declare type I18NItemWithBounding = I18NItem & { +export type I18NItemWithBounding = I18NItem & { previousCharacter: string; nextCharacter: string; }; -export declare type I18NLanguage = { +export type I18NLanguage = { [language: string]: I18NItem[]; }; -export declare type I18NReport = { +export type I18NReport = { missingKeys: I18NItem[]; unusedKeys: I18NItem[]; maybeDynamicKeys: I18NItem[]; diff --git a/dist/vue-i18n-extract.modern.mjs b/dist/vue-i18n-extract.modern.mjs index e37ff64b..449713c3 100644 --- a/dist/vue-i18n-extract.modern.mjs +++ b/dist/vue-i18n-extract.modern.mjs @@ -7,21 +7,13 @@ import Dot from 'dot-object'; import yaml from 'js-yaml'; function _extends() { - _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } + return _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } - - return target; - }; - - return _extends.apply(this, arguments); + return n; + }, _extends.apply(null, arguments); } var defaultConfig = { @@ -46,24 +38,20 @@ function resolveConfig() { run: false }).options; let options; - try { - const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js'); // eslint-disable-next-line @typescript-eslint/no-var-requires - + const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js'); + // eslint-disable-next-line @typescript-eslint/no-var-requires const configOptions = require(pathToConfigFile); - console.info(`\nUsing config file found at ${pathToConfigFile}`); options = _extends({}, configOptions, argvOptions); } catch (_unused) { options = argvOptions; } - options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude]; return options; } var DetectionType; - (function (DetectionType) { DetectionType["Missing"] = "missing"; DetectionType["Unused"] = "unused"; @@ -74,17 +62,13 @@ function readVueFiles(src) { // Replace backslash path segments to make the path work with the glob package. // https://github.com/Spittal/vue-i18n-extract/issues/159 const normalizedSrc = src.replace(/\\/g, '/'); - if (!isValidGlob(normalizedSrc)) { throw new Error(`vueFiles isn't a valid glob pattern.`); } - const targetFiles = glob.sync(normalizedSrc); - if (targetFiles.length === 0) { throw new Error('vueFiles glob has no files.'); } - return targetFiles.map(f => { const fileName = f.replace(process.cwd(), '.'); return { @@ -94,15 +78,12 @@ function readVueFiles(src) { }; }); } - function* getMatches(file, regExp, captureGroup = 1) { while (true) { const match = regExp.exec(file.content); - if (match === null) { break; } - const path = match[captureGroup]; const pathAtIndex = file.content.indexOf(path); const previousCharacter = file.content.charAt(pathAtIndex - 1); @@ -141,23 +122,18 @@ function* getMatches(file, regExp, captureGroup = 1) { * @param file a file object * @returns a list of translation keys found in `file`. */ - - function extractMethodMatches(file) { const methodRegExp = /(?:[$\s.:"'`+\(\[\{]t[cm]?)\(\s*?(["'`])((?:[^\\]|\\.)*?)\1/g; return [...getMatches(file, methodRegExp, 2)]; } - function extractComponentMatches(file) { const componentRegExp = /(?:(?:<|h\()(?:i18n|Translation))(?:.|\n)*?(?:\s(?:(?:key)?)path(?:=|: )("|'))((?:[^\\]|\\.)*?)\1/gi; return [...getMatches(file, componentRegExp, 2)]; } - function extractDirectiveMatches(file) { const directiveRegExp = /\bv-t(?:\.[\w-]+)?="'((?:[^\\]|\\.)*?)'"/g; return [...getMatches(file, directiveRegExp)]; } - function extractI18NItemsFromVueFiles(sourceFiles) { return sourceFiles.reduce((accumulator, file) => { const methodMatches = extractMethodMatches(file); @@ -165,8 +141,8 @@ function extractI18NItemsFromVueFiles(sourceFiles) { const directiveMatches = extractDirectiveMatches(file); return [...accumulator, ...methodMatches, ...componentMatches, ...directiveMatches]; }, []); -} // This is a convenience function for users implementing in their own projects, and isn't used internally - +} +// This is a convenience function for users implementing in their own projects, and isn't used internally function parseVueFiles(vueFiles) { return extractI18NItemsFromVueFiles(readVueFiles(vueFiles)); } @@ -175,24 +151,19 @@ function readLanguageFiles(src) { // Replace backslash path segments to make the path work with the glob package. // https://github.com/Spittal/vue-i18n-extract/issues/159 const normalizedSrc = src.replace(/\\/g, '/'); - if (!isValidGlob(normalizedSrc)) { throw new Error(`languageFiles isn't a valid glob pattern.`); } - const targetFiles = glob.sync(normalizedSrc); - if (targetFiles.length === 0) { throw new Error('languageFiles glob has no files.'); } - return targetFiles.map(f => { const langPath = path.resolve(process.cwd(), f); const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase(); const isJSON = extension === '.json'; const isYAML = extension === '.yaml' || extension === '.yml'; let langObj; - if (isJSON) { langObj = JSON.parse(fs.readFileSync(langPath, 'utf8')); } else if (isYAML) { @@ -200,7 +171,6 @@ function readLanguageFiles(src) { } else { langObj = eval(fs.readFileSync(langPath, 'utf8')); } - const fileName = f.replace(process.cwd(), '.'); return { path: f, @@ -212,11 +182,9 @@ function readLanguageFiles(src) { function extractI18NLanguageFromLanguageFiles(languageFiles, dot = Dot) { return languageFiles.reduce((accumulator, file) => { const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.')); - if (!accumulator[language]) { accumulator[language] = []; } - const flattenedObject = dot.dot(JSON.parse(file.content)); Object.keys(flattenedObject).forEach(key => { accumulator[language].push({ @@ -233,7 +201,17 @@ function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot missingKeys.forEach(item => { if (item.language && languageFile.fileName.includes(item.language) || !item.language) { const addDefaultTranslation = noEmptyTranslation && (noEmptyTranslation === '*' || noEmptyTranslation === item.language); - dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent); + let value = null; + if (addDefaultTranslation) { + value = item.path; + } else if (missingTranslationString === 'null') { + value = null; + } else if (missingTranslationString.includes('{{t}}')) { + value = missingTranslationString.replace('{{t}}', item.path); + } else { + value = missingTranslationString; + } + dot.str(item.path, value, languageFileContent); } }); writeLanguageFile(languageFile, languageFileContent); @@ -250,12 +228,10 @@ function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Do writeLanguageFile(languageFile, languageFileContent); }); } - function writeLanguageFile(languageFile, newLanguageFileContent) { const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1); const filePath = languageFile.path; const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2); - if (fileExtension === 'json') { fs.writeFileSync(filePath, stringifiedContent); } else if (fileExtension === 'js') { @@ -267,9 +243,8 @@ function writeLanguageFile(languageFile, newLanguageFileContent) { } else { throw new Error(`Language filetype of ${fileExtension} not supported.`); } -} // This is a convenience function for users implementing in their own projects, and isn't used internally - - +} +// This is a convenience function for users implementing in their own projects, and isn't used internally function parselanguageFiles(languageFiles, dot = Dot) { return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot); } @@ -281,31 +256,25 @@ function stripBounding(item) { line: item.line }; } - function mightBeDynamic(item) { return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g); -} // Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off. - - +} +// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off. function extractI18NReport(vueItems, languageFiles, detect) { const missingKeys = []; const unusedKeys = []; const maybeDynamicKeys = []; - if (detect.includes(DetectionType.Dynamic)) { maybeDynamicKeys.push(...vueItems.filter(vueItem => mightBeDynamic(vueItem)).map(vueItem => stripBounding(vueItem))); } - Object.keys(languageFiles).forEach(language => { const languageItems = languageFiles[language]; - if (detect.includes(DetectionType.Missing)) { const missingKeysInLanguage = vueItems.filter(vueItem => !mightBeDynamic(vueItem)).filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path)).map(vueItem => _extends({}, stripBounding(vueItem), { language })); missingKeys.push(...missingKeysInLanguage); } - if (detect.includes(DetectionType.Unused)) { const unusedKeysInLanguage = languageItems.filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.'))).map(languageItem => _extends({}, languageItem, { language @@ -327,7 +296,6 @@ async function writeReportToFile(report, writePath) { reject(err); return; } - resolve(); }); }); @@ -351,11 +319,9 @@ async function createI18NReport(options) { if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.'); let issuesToDetect = Array.isArray(detect) ? detect : [detect]; const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(DetectionType).includes(item)); - if (invalidDetectOptions.length) { throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`); } - const dot = typeof separator === 'string' ? new Dot(separator) : Dot; const vueFiles = readVueFiles(path.resolve(process.cwd(), vueFilesGlob)); const languageFiles = readLanguageFiles(path.resolve(process.cwd(), languageFilesGlob)); @@ -366,30 +332,24 @@ async function createI18NReport(options) { if (report.missingKeys.length) console.info('\nMissing Keys'), console.table(report.missingKeys); if (report.unusedKeys.length) console.info('\nUnused Keys'), console.table(report.unusedKeys); if (report.maybeDynamicKeys.length) console.warn('\nSuspected Dynamic Keys Found\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys); - if (output) { await writeReportToFile(report, path.resolve(process.cwd(), output)); console.info(`\nThe report has been has been saved to ${output}`); } - if (remove && report.unusedKeys.length) { removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot); console.info('\nThe unused keys have been removed from your language files.'); } - if (add && report.missingKeys.length) { writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString); console.info('\nThe missing keys have been added to your language files.'); } - if (ci && report.missingKeys.length) { throw new Error(`${report.missingKeys.length} missing keys found.`); } - if (ci && report.unusedKeys.length) { throw new Error(`${report.unusedKeys.length} unused keys found.`); } - return report; } diff --git a/dist/vue-i18n-extract.modern.mjs.map b/dist/vue-i18n-extract.modern.mjs.map index a0d5823c..1a1727af 100644 --- a/dist/vue-i18n-extract.modern.mjs.map +++ b/dist/vue-i18n-extract.modern.mjs.map @@ -1 +1 @@ -{"version":3,"file":"vue-i18n-extract.modern.mjs","sources":["../src/config-file/vue-i18n-extract.config.ts","../src/config-file/index.ts","../src/types.ts","../src/create-report/vue-files.ts","../src/create-report/language-files.ts","../src/create-report/report.ts","../src/create-report/index.ts","../src/index.ts"],"sourcesContent":["export default {\n // Options documented in vue-i18n-extract readme.\n vueFiles: './src/**/*.?(js|vue)',\n languageFiles: './lang/**/*.?(json|yaml|yml|js)',\n exclude: [],\n output: false,\n add: false,\n remove: false,\n ci: false,\n separator: '.',\n noEmptyTranslation: '',\n missingTranslationString: '',\n};\n","import cac from 'cac';\nimport fs from 'fs';\nimport path from 'path';\nimport defaultConfig from './vue-i18n-extract.config';\n\nexport function initCommand(): void {\n fs.writeFileSync(\n path.resolve(process.cwd(), './vue-i18n-extract.config.js'),\n `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`,\n );\n}\n\nexport function resolveConfig (): Record {\n const argvOptions = cac().parse(process.argv, { run: false }).options;\n\n let options;\n\n try {\n const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const configOptions = require(pathToConfigFile);\n\n console.info(`\\nUsing config file found at ${pathToConfigFile}`);\n\n options = {\n ...configOptions,\n ...argvOptions\n };\n } catch {\n options = argvOptions;\n }\n\n options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude];\n\n return options;\n}\n","export type ReportOptions = {\n vueFiles: string;\n languageFiles: string;\n output?: string;\n exclude?: string[];\n add?: boolean;\n remove?: boolean;\n ci?: boolean;\n separator?: string;\n noEmptyTranslation?: string;\n missingTranslationString?: string;\n detect?: DetectionType[];\n}\n\nexport enum DetectionType {\n Missing = \"missing\",\n Unused = \"unused\",\n Dynamic = \"dynamic\"\n}\n\nexport type SimpleFile = {\n fileName: string;\n path: string;\n content: string;\n}\n\nexport type I18NItem = {\n line?: number;\n path: string;\n file?: string;\n language?: string;\n}\n\nexport type I18NItemWithBounding = I18NItem & {\n previousCharacter: string;\n nextCharacter: string;\n}\n\nexport type I18NLanguage = {\n [language: string]: I18NItem[];\n}\n\nexport type I18NReport = {\n missingKeys: I18NItem[];\n unusedKeys: I18NItem[];\n maybeDynamicKeys: I18NItem[];\n}\n","import { SimpleFile, I18NItemWithBounding } from '../types';\nimport isValidGlob from 'is-valid-glob';\nimport glob from 'glob';\nimport fs from 'fs';\n\nexport function readVueFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`vueFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('vueFiles glob has no files.');\n }\n\n return targetFiles.map((f) => {\n const fileName = f.replace(process.cwd(), '.');\n return { fileName, path: f, content: fs.readFileSync(f, 'utf8') };\n });\n}\n\nfunction* getMatches (file: SimpleFile, regExp: RegExp, captureGroup = 1): IterableIterator {\n while (true) {\n const match = regExp.exec(file.content);\n if (match === null) {\n break;\n }\n const path = match[captureGroup];\n\n const pathAtIndex = file.content.indexOf(path);\n const previousCharacter = file.content.charAt(pathAtIndex - 1);\n const nextCharacter = file.content.charAt(pathAtIndex + path.length);\n\n const line = (file.content.substring(0, match.index).match(/\\n/g) || []).length + 1;\n yield {\n path,\n previousCharacter,\n nextCharacter,\n file: file.fileName,\n line,\n };\n }\n}\n\n/**\n * Extracts translation keys from methods such as `$t` and `$tc`.\n *\n * - **regexp pattern**: (?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\n *\n * **description**: Matches the sequence t(, tc( or tm(, optionally with either “$”, SPACE, “.”, “:”, “\"”, “'”,\n * “`”, \"+\", \"(\", \"[\" or \"{\" in front of it.\n *\n * - **regexp pattern**: ([\"'`])\n *\n * **description**: 1. capturing group. Matches either “\"”, “'”, or “`”.\n *\n * - **regexp pattern**: ((?:[^\\\\]|\\\\.)*?)\n *\n * **description**: 2. capturing group. Matches anything except a backslash\n * *or* matches any backslash followed by any character (e.g. “\\\"”, “\\`”, “\\t”, etc.)\n *\n * - **regexp pattern**: \\1\n *\n * **description**: matches whatever was matched by capturing group 1 (e.g. the starting string character)\n *\n * @param file a file object\n * @returns a list of translation keys found in `file`.\n */\n function extractMethodMatches (file: SimpleFile): I18NItemWithBounding[] {\n const methodRegExp = /(?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\\s*?([\"'`])((?:[^\\\\]|\\\\.)*?)\\1/g;\n return [ ...getMatches(file, methodRegExp, 2) ];\n}\n\nfunction extractComponentMatches (file: SimpleFile): I18NItemWithBounding[] {\n const componentRegExp = /(?:(?:<|h\\()(?:i18n|Translation))(?:.|\\n)*?(?:\\s(?:(?:key)?)path(?:=|: )(\"|'))((?:[^\\\\]|\\\\.)*?)\\1/gi;\n return [ ...getMatches(file, componentRegExp, 2) ];\n}\n\nfunction extractDirectiveMatches (file: SimpleFile): I18NItemWithBounding[] {\n const directiveRegExp = /\\bv-t(?:\\.[\\w-]+)?=\"'((?:[^\\\\]|\\\\.)*?)'\"/g;\n return [ ...getMatches(file, directiveRegExp) ];\n}\n\nexport function extractI18NItemsFromVueFiles (sourceFiles: SimpleFile[]): I18NItemWithBounding[] {\n return sourceFiles.reduce((accumulator, file) => {\n const methodMatches = extractMethodMatches(file);\n const componentMatches = extractComponentMatches(file);\n const directiveMatches = extractDirectiveMatches(file);\n return [\n ...accumulator,\n ...methodMatches,\n ...componentMatches,\n ...directiveMatches,\n ];\n }, [] as I18NItemWithBounding[]);\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parseVueFiles (vueFiles: string): I18NItemWithBounding[] {\n return extractI18NItemsFromVueFiles(readVueFiles(vueFiles));\n}\n","import path from 'path';\nimport fs from 'fs';\nimport glob from 'glob';\nimport Dot from 'dot-object';\nimport yaml from 'js-yaml';\nimport isValidGlob from 'is-valid-glob';\nimport { SimpleFile, I18NLanguage, I18NItem } from '../types';\n\nexport function readLanguageFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`languageFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('languageFiles glob has no files.');\n }\n\n return targetFiles.map(f => {\n const langPath = path.resolve(process.cwd(), f);\n\n const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase();\n const isJSON = extension === '.json';\n const isYAML = extension === '.yaml' || extension === '.yml';\n\n let langObj;\n if (isJSON) {\n langObj = JSON.parse(fs.readFileSync(langPath, 'utf8'));\n } else if (isYAML) {\n langObj = yaml.load(fs.readFileSync(langPath, 'utf8'));\n } else {\n langObj = eval(fs.readFileSync(langPath, 'utf8'));\n }\n\n const fileName = f.replace(process.cwd(), '.');\n\n return { path: f, fileName, content: JSON.stringify(langObj) };\n });\n}\n\nexport function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[], dot: DotObject.Dot = Dot): I18NLanguage {\n return languageFiles.reduce((accumulator, file) => {\n const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.'));\n\n if (!accumulator[language]) {\n accumulator[language] = [];\n }\n\n const flattenedObject = dot.dot(JSON.parse(file.content));\n Object.keys(flattenedObject).forEach((key) => {\n accumulator[language].push({\n path: key,\n file: file.fileName,\n });\n });\n\n return accumulator;\n }, {});\n}\n\nexport function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = '', missingTranslationString = ''): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n missingKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language) || !item.language) {\n const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));\n dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n unusedKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language)) {\n dot.delete(item.path, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nfunction writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2);\n\n if (fileExtension === 'json') {\n fs.writeFileSync(filePath, stringifiedContent);\n } else if (fileExtension === 'js') {\n const jsFile = `module.exports = ${stringifiedContent}; \\n`;\n fs.writeFileSync(filePath, jsFile);\n } else if (fileExtension === 'yaml' || fileExtension === 'yml') {\n const yamlFile = yaml.dump(newLanguageFileContent);\n fs.writeFileSync(filePath, yamlFile);\n } else {\n throw new Error(`Language filetype of ${fileExtension} not supported.`)\n }\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parselanguageFiles (languageFiles: string, dot: DotObject.Dot = Dot): I18NLanguage {\n return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot);\n}\n","import fs from 'fs';\nimport { DetectionType, I18NItem, I18NItemWithBounding, I18NLanguage, I18NReport } from '../types';\n\nfunction stripBounding (item: I18NItemWithBounding): I18NItem {\n return {\n path: item.path,\n file: item.file,\n line: item.line,\n }\n}\n\nfunction mightBeDynamic (item: I18NItemWithBounding): boolean {\n return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g);\n}\n\n// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off.\nexport function extractI18NReport (vueItems: I18NItemWithBounding[], languageFiles: I18NLanguage, detect: DetectionType[]): I18NReport {\n const missingKeys: I18NItem[] = [];\n const unusedKeys: I18NItem[] = [];\n const maybeDynamicKeys: I18NItem[] = [];\n\n if (detect.includes(DetectionType.Dynamic)) {\n maybeDynamicKeys. push( ...vueItems\n .filter(vueItem => mightBeDynamic(vueItem))\n .map(vueItem => stripBounding(vueItem)));\n }\n\n Object.keys(languageFiles).forEach(language => {\n const languageItems = languageFiles[language];\n\n if (detect.includes(DetectionType.Missing)) {\n const missingKeysInLanguage = vueItems\n .filter(vueItem => !mightBeDynamic(vueItem))\n .filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path))\n .map(vueItem => ({ ...stripBounding(vueItem), language }));\n\n missingKeys.push(...missingKeysInLanguage);\n }\n\n if (detect.includes(DetectionType.Unused)) {\n const unusedKeysInLanguage = languageItems\n .filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.')))\n .map(languageItem => ({ ...languageItem, language }));\n\n unusedKeys.push(...unusedKeysInLanguage);\n }\n });\n\n return {\n missingKeys,\n unusedKeys,\n maybeDynamicKeys,\n };\n}\n\nexport async function writeReportToFile (report: I18NReport, writePath: string): Promise {\n const reportString = JSON.stringify(report);\n return new Promise((resolve, reject) => {\n fs.writeFile(\n writePath,\n reportString,\n (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n },\n );\n });\n}\n\n","import path from 'path';\nimport { ReportOptions, I18NReport, DetectionType } from '../types';\nimport { readVueFiles, extractI18NItemsFromVueFiles } from './vue-files';\nimport { readLanguageFiles, extractI18NLanguageFromLanguageFiles, removeUnusedFromLanguageFiles, writeMissingToLanguageFiles } from './language-files';\nimport { extractI18NReport, writeReportToFile } from './report';\nimport Dot from 'dot-object';\n\nexport async function createI18NReport (options: ReportOptions): Promise {\n const {\n vueFiles: vueFilesGlob,\n languageFiles: languageFilesGlob,\n output,\n add,\n remove,\n exclude = [],\n ci,\n separator,\n noEmptyTranslation = '',\n missingTranslationString = '',\n detect = [DetectionType.Missing, DetectionType.Unused, DetectionType.Dynamic]\n } = options;\n\n if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');\n if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.');\n\n let issuesToDetect = Array.isArray(detect) ? detect : [detect];\n const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(DetectionType).includes(item));\n if (invalidDetectOptions.length) {\n throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`);\n }\n\n const dot = typeof separator === 'string' ? new Dot(separator) : Dot;\n const vueFiles = readVueFiles(path.resolve(process.cwd(), vueFilesGlob));\n const languageFiles = readLanguageFiles(path.resolve(process.cwd(), languageFilesGlob));\n\n const I18NItems = extractI18NItemsFromVueFiles(vueFiles);\n const I18NLanguage = extractI18NLanguageFromLanguageFiles(languageFiles, dot);\n\n const report = extractI18NReport(I18NItems, I18NLanguage, issuesToDetect);\n\n report.unusedKeys = report.unusedKeys.filter(key =>\n !exclude.filter(excluded => key.path.startsWith(excluded)).length)\n\n if (report.missingKeys.length) console.info('\\nMissing Keys'), console.table(report.missingKeys);\n if (report.unusedKeys.length) console.info('\\nUnused Keys'), console.table(report.unusedKeys);\n if (report.maybeDynamicKeys.length) console.warn('\\nSuspected Dynamic Keys Found\\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys);\n\n if (output) {\n await writeReportToFile(report, path.resolve(process.cwd(), output));\n console.info(`\\nThe report has been has been saved to ${output}`);\n }\n\n if (remove && report.unusedKeys.length) {\n removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot);\n console.info('\\nThe unused keys have been removed from your language files.');\n }\n\n if (add && report.missingKeys.length) {\n writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString);\n console.info('\\nThe missing keys have been added to your language files.');\n }\n\n if (ci && report.missingKeys.length) {\n throw new Error(`${report.missingKeys.length} missing keys found.`);\n }\n\n if (ci && report.unusedKeys.length) {\n throw new Error(`${report.unusedKeys.length} unused keys found.`);\n }\n\n return report;\n}\n\nexport * from './vue-files';\nexport * from './language-files';\nexport * from './report';\n","export * from './config-file';\nexport * from './create-report';\nexport * from './types';\n\nprocess.on('uncaughtException', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n"],"names":["vueFiles","languageFiles","exclude","output","add","remove","ci","separator","noEmptyTranslation","missingTranslationString","initCommand","fs","writeFileSync","path","resolve","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","cac","parse","argv","run","options","pathToConfigFile","configOptions","require","console","info","Array","isArray","DetectionType","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","f","fileName","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","pathAtIndex","indexOf","previousCharacter","charAt","nextCharacter","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","parseVueFiles","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","yaml","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","languageFile","languageFileContent","item","includes","addDefaultTranslation","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","filePath","stringifiedContent","jsFile","yamlFile","dump","parselanguageFiles","stripBounding","mightBeDynamic","extractI18NReport","vueItems","detect","maybeDynamicKeys","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","writeReportToFile","report","writePath","reportString","Promise","reject","writeFile","err","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","exit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oBAAe;AACb;AACAA,EAAAA,QAAQ,EAAE,sBAFG;AAGbC,EAAAA,aAAa,EAAE,iCAHF;AAIbC,EAAAA,OAAO,EAAE,EAJI;AAKbC,EAAAA,MAAM,EAAE,KALK;AAMbC,EAAAA,GAAG,EAAE,KANQ;AAObC,EAAAA,MAAM,EAAE,KAPK;AAQbC,EAAAA,EAAE,EAAE,KARS;AASbC,EAAAA,SAAS,EAAE,GATE;AAUbC,EAAAA,kBAAkB,EAAE,EAVP;AAWbC,EAAAA,wBAAwB,EAAE,EAAA;AAXb,CAAf;;SCKgBC,cAAW;AACzBC,EAAAA,EAAE,CAACC,aAAH,CACEC,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4B,8BAA5B,CADF,EAEE,CAAA,iBAAA,EAAoBC,IAAI,CAACC,SAAL,CAAeC,aAAf,EAA8B,IAA9B,EAAoC,CAApC,CAAwC,CAF9D,CAAA,CAAA,CAAA;AAID,CAAA;SAEeC,gBAAa;AAC3B,EAAMC,MAAAA,WAAW,GAAGC,GAAG,EAAA,CAAGC,KAAN,CAAYR,OAAO,CAACS,IAApB,EAA0B;AAAEC,IAAAA,GAAG,EAAE,KAAA;AAAP,GAA1B,EAA0CC,OAA9D,CAAA;AAEA,EAAA,IAAIA,OAAJ,CAAA;;AAEA,EAAI,IAAA;AACF,IAAA,MAAMC,gBAAgB,GAAGd,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4B,8BAA5B,CAAzB,CADE;;AAGF,IAAA,MAAMY,aAAa,GAAGC,OAAO,CAACF,gBAAD,CAA7B,CAAA;;AAEAG,IAAAA,OAAO,CAACC,IAAR,iCAA6CJ,gBAAgB,CAA7D,CAAA,CAAA,CAAA;AAEAD,IAAAA,OAAO,GAAA,QAAA,CAAA,EAAA,EACFE,aADE,EAEFP,WAFE,CAAP,CAAA;AAID,GAXD,CAWE,OAAM,OAAA,EAAA;AACNK,IAAAA,OAAO,GAAGL,WAAV,CAAA;AACD,GAAA;;AAEDK,EAAAA,OAAO,CAACxB,OAAR,GAAkB8B,KAAK,CAACC,OAAN,CAAcP,OAAO,CAACxB,OAAtB,CAAiCwB,GAAAA,OAAO,CAACxB,OAAzC,GAAmD,CAACwB,OAAO,CAACxB,OAAT,CAArE,CAAA;AAEA,EAAA,OAAOwB,OAAP,CAAA;AACD;;ICrBWQ,cAAZ;;AAAA,CAAA,UAAYA,aAAZ,EAAyB;AACvBA,EAAAA,aAAA,CAAA,SAAA,CAAA,GAAA,SAAA,CAAA;AACAA,EAAAA,aAAA,CAAA,QAAA,CAAA,GAAA,QAAA,CAAA;AACAA,EAAAA,aAAA,CAAA,SAAA,CAAA,GAAA,SAAA,CAAA;AACD,CAJD,EAAYA,aAAa,KAAbA,aAAa,GAIxB,EAJwB,CAAzB,CAAA;;ACTM,SAAUC,YAAV,CAAwBC,GAAxB,EAAmC;AACvC;AACA;AACA,EAAMC,MAAAA,aAAa,GAAGD,GAAG,CAACE,OAAJ,CAAY,KAAZ,EAAmB,GAAnB,CAAtB,CAAA;;AACA,EAAA,IAAI,CAACC,WAAW,CAACF,aAAD,CAAhB,EAAiC;AAC/B,IAAA,MAAM,IAAIG,KAAJ,CAAU,CAAA,oCAAA,CAAV,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,MAAMC,WAAW,GAAGC,IAAI,CAACC,IAAL,CAAUN,aAAV,CAApB,CAAA;;AAEA,EAAA,IAAII,WAAW,CAACG,MAAZ,KAAuB,CAA3B,EAA8B;AAC5B,IAAA,MAAM,IAAIJ,KAAJ,CAAU,6BAAV,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,OAAOC,WAAW,CAACI,GAAZ,CAAiBC,CAAD,IAAM;AAC3B,IAAA,MAAMC,QAAQ,GAAGD,CAAC,CAACR,OAAF,CAAUvB,OAAO,CAACC,GAAR,EAAV,EAAyB,GAAzB,CAAjB,CAAA;AACA,IAAO,OAAA;AAAE+B,MAAAA,QAAF;AAAYlC,MAAAA,IAAI,EAAEiC,CAAlB;AAAqBE,MAAAA,OAAO,EAAErC,EAAE,CAACsC,YAAH,CAAgBH,CAAhB,EAAmB,MAAnB,CAAA;AAA9B,KAAP,CAAA;AACD,GAHM,CAAP,CAAA;AAID,CAAA;;AAED,UAAUI,UAAV,CAAsBC,IAAtB,EAAwCC,MAAxC,EAAwDC,YAAY,GAAG,CAAvE,EAAwE;AACtE,EAAA,OAAO,IAAP,EAAa;AACX,IAAMC,MAAAA,KAAK,GAAGF,MAAM,CAACG,IAAP,CAAYJ,IAAI,CAACH,OAAjB,CAAd,CAAA;;AACA,IAAIM,IAAAA,KAAK,KAAK,IAAd,EAAoB;AAClB,MAAA,MAAA;AACD,KAAA;;AACD,IAAA,MAAMzC,IAAI,GAAGyC,KAAK,CAACD,YAAD,CAAlB,CAAA;AAEA,IAAMG,MAAAA,WAAW,GAAGL,IAAI,CAACH,OAAL,CAAaS,OAAb,CAAqB5C,IAArB,CAApB,CAAA;AACA,IAAM6C,MAAAA,iBAAiB,GAAGP,IAAI,CAACH,OAAL,CAAaW,MAAb,CAAoBH,WAAW,GAAG,CAAlC,CAA1B,CAAA;AACA,IAAA,MAAMI,aAAa,GAAGT,IAAI,CAACH,OAAL,CAAaW,MAAb,CAAoBH,WAAW,GAAG3C,IAAI,CAAC+B,MAAvC,CAAtB,CAAA;AAEA,IAAMiB,MAAAA,IAAI,GAAG,CAACV,IAAI,CAACH,OAAL,CAAac,SAAb,CAAuB,CAAvB,EAA0BR,KAAK,CAACS,KAAhC,CAAuCT,CAAAA,KAAvC,CAA6C,KAA7C,KAAuD,EAAxD,EAA4DV,MAA5D,GAAqE,CAAlF,CAAA;AACA,IAAM,MAAA;AACJ/B,MAAAA,IADI;AAEJ6C,MAAAA,iBAFI;AAGJE,MAAAA,aAHI;AAIJT,MAAAA,IAAI,EAAEA,IAAI,CAACJ,QAJP;AAKJc,MAAAA,IAAAA;AALI,KAAN,CAAA;AAOD,GAAA;AACF,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;AAuBG;;;AACF,SAASG,oBAAT,CAA+Bb,IAA/B,EAA+C;AAC9C,EAAMc,MAAAA,YAAY,GAAG,8DAArB,CAAA;AACA,EAAO,OAAA,CAAE,GAAGf,UAAU,CAACC,IAAD,EAAOc,YAAP,EAAqB,CAArB,CAAf,CAAP,CAAA;AACD,CAAA;;AAED,SAASC,uBAAT,CAAkCf,IAAlC,EAAkD;AAChD,EAAMgB,MAAAA,eAAe,GAAG,qGAAxB,CAAA;AACA,EAAO,OAAA,CAAE,GAAGjB,UAAU,CAACC,IAAD,EAAOgB,eAAP,EAAwB,CAAxB,CAAf,CAAP,CAAA;AACD,CAAA;;AAED,SAASC,uBAAT,CAAkCjB,IAAlC,EAAkD;AAChD,EAAMkB,MAAAA,eAAe,GAAG,2CAAxB,CAAA;AACA,EAAO,OAAA,CAAE,GAAGnB,UAAU,CAACC,IAAD,EAAOkB,eAAP,CAAf,CAAP,CAAA;AACD,CAAA;;AAEK,SAAUC,4BAAV,CAAwCC,WAAxC,EAAiE;AACrE,EAAOA,OAAAA,WAAW,CAACC,MAAZ,CAAmB,CAACC,WAAD,EAActB,IAAd,KAAsB;AAC9C,IAAA,MAAMuB,aAAa,GAAGV,oBAAoB,CAACb,IAAD,CAA1C,CAAA;AACA,IAAA,MAAMwB,gBAAgB,GAAGT,uBAAuB,CAACf,IAAD,CAAhD,CAAA;AACA,IAAA,MAAMyB,gBAAgB,GAAGR,uBAAuB,CAACjB,IAAD,CAAhD,CAAA;AACA,IAAA,OAAO,CACL,GAAGsB,WADE,EAEL,GAAGC,aAFE,EAGL,GAAGC,gBAHE,EAIL,GAAGC,gBAJE,CAAP,CAAA;AAMD,GAVM,EAUJ,EAVI,CAAP,CAAA;AAWD;;AAGK,SAAUC,aAAV,CAAyB7E,QAAzB,EAAyC;AAC7C,EAAA,OAAOsE,4BAA4B,CAACnC,YAAY,CAACnC,QAAD,CAAb,CAAnC,CAAA;AACD;;AChGK,SAAU8E,iBAAV,CAA6B1C,GAA7B,EAAwC;AAC5C;AACA;AACA,EAAMC,MAAAA,aAAa,GAAGD,GAAG,CAACE,OAAJ,CAAY,KAAZ,EAAmB,GAAnB,CAAtB,CAAA;;AACA,EAAA,IAAI,CAACC,WAAW,CAACF,aAAD,CAAhB,EAAiC;AAC/B,IAAA,MAAM,IAAIG,KAAJ,CAAU,CAAA,yCAAA,CAAV,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,MAAMC,WAAW,GAAGC,IAAI,CAACC,IAAL,CAAUN,aAAV,CAApB,CAAA;;AAEA,EAAA,IAAII,WAAW,CAACG,MAAZ,KAAuB,CAA3B,EAA8B;AAC5B,IAAA,MAAM,IAAIJ,KAAJ,CAAU,kCAAV,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,OAAOC,WAAW,CAACI,GAAZ,CAAgBC,CAAC,IAAG;AACzB,IAAA,MAAMiC,QAAQ,GAAGlE,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4B8B,CAA5B,CAAjB,CAAA;AAEA,IAAA,MAAMkC,SAAS,GAAGD,QAAQ,CAACjB,SAAT,CAAmBiB,QAAQ,CAACE,WAAT,CAAqB,GAArB,CAAnB,CAAA,CAA8CC,WAA9C,EAAlB,CAAA;AACA,IAAA,MAAMC,MAAM,GAAGH,SAAS,KAAK,OAA7B,CAAA;AACA,IAAMI,MAAAA,MAAM,GAAGJ,SAAS,KAAK,OAAd,IAAyBA,SAAS,KAAK,MAAtD,CAAA;AAEA,IAAA,IAAIK,OAAJ,CAAA;;AACA,IAAA,IAAIF,MAAJ,EAAY;AACVE,MAAAA,OAAO,GAAGpE,IAAI,CAACM,KAAL,CAAWZ,EAAE,CAACsC,YAAH,CAAgB8B,QAAhB,EAA0B,MAA1B,CAAX,CAAV,CAAA;AACD,KAFD,MAEO,IAAIK,MAAJ,EAAY;AACjBC,MAAAA,OAAO,GAAGC,IAAI,CAACC,IAAL,CAAU5E,EAAE,CAACsC,YAAH,CAAgB8B,QAAhB,EAA0B,MAA1B,CAAV,CAAV,CAAA;AACD,KAFM,MAEA;AACLM,MAAAA,OAAO,GAAGG,IAAI,CAAC7E,EAAE,CAACsC,YAAH,CAAgB8B,QAAhB,EAA0B,MAA1B,CAAD,CAAd,CAAA;AACD,KAAA;;AAED,IAAA,MAAMhC,QAAQ,GAAGD,CAAC,CAACR,OAAF,CAAUvB,OAAO,CAACC,GAAR,EAAV,EAAyB,GAAzB,CAAjB,CAAA;AAEA,IAAO,OAAA;AAAEH,MAAAA,IAAI,EAAEiC,CAAR;AAAWC,MAAAA,QAAX;AAAqBC,MAAAA,OAAO,EAAE/B,IAAI,CAACC,SAAL,CAAemE,OAAf,CAAA;AAA9B,KAAP,CAAA;AACD,GAnBM,CAAP,CAAA;AAoBD,CAAA;SAEeI,qCAAsCxF,eAA6ByF,MAAqBC,KAAG;AACzG,EAAO1F,OAAAA,aAAa,CAACuE,MAAd,CAAqB,CAACC,WAAD,EAActB,IAAd,KAAsB;AAChD,IAAMyC,MAAAA,QAAQ,GAAGzC,IAAI,CAACJ,QAAL,CAAce,SAAd,CAAwBX,IAAI,CAACJ,QAAL,CAAckC,WAAd,CAA0B,GAA1B,CAAA,GAAiC,CAAzD,EAA4D9B,IAAI,CAACJ,QAAL,CAAckC,WAAd,CAA0B,GAA1B,CAA5D,CAAjB,CAAA;;AAEA,IAAA,IAAI,CAACR,WAAW,CAACmB,QAAD,CAAhB,EAA4B;AAC1BnB,MAAAA,WAAW,CAACmB,QAAD,CAAX,GAAwB,EAAxB,CAAA;AACD,KAAA;;AAED,IAAA,MAAMC,eAAe,GAAGH,GAAG,CAACA,GAAJ,CAAQzE,IAAI,CAACM,KAAL,CAAW4B,IAAI,CAACH,OAAhB,CAAR,CAAxB,CAAA;AACA8C,IAAAA,MAAM,CAACC,IAAP,CAAYF,eAAZ,CAA6BG,CAAAA,OAA7B,CAAsCC,GAAD,IAAQ;AAC3CxB,MAAAA,WAAW,CAACmB,QAAD,CAAX,CAAsBM,IAAtB,CAA2B;AACzBrF,QAAAA,IAAI,EAAEoF,GADmB;AAEzB9C,QAAAA,IAAI,EAAEA,IAAI,CAACJ,QAAAA;AAFc,OAA3B,CAAA,CAAA;AAID,KALD,CAAA,CAAA;AAOA,IAAA,OAAO0B,WAAP,CAAA;AACD,GAhBM,EAgBJ,EAhBI,CAAP,CAAA;AAiBD,CAAA;SAEe0B,4BAA6BC,qBAAmCC,aAAyBX,GAAA,GAAqBC,KAAKnF,kBAAkB,GAAG,IAAIC,wBAAwB,GAAG,IAAE;AACvL2F,EAAAA,mBAAmB,CAACJ,OAApB,CAA4BM,YAAY,IAAG;AACzC,IAAMC,MAAAA,mBAAmB,GAAGtF,IAAI,CAACM,KAAL,CAAW+E,YAAY,CAACtD,OAAxB,CAA5B,CAAA;AAEAqD,IAAAA,WAAW,CAACL,OAAZ,CAAoBQ,IAAI,IAAG;AACzB,MAAA,IAAIA,IAAI,CAACZ,QAAL,IAAiBU,YAAY,CAACvD,QAAb,CAAsB0D,QAAtB,CAA+BD,IAAI,CAACZ,QAApC,CAAjB,IAAkE,CAACY,IAAI,CAACZ,QAA5E,EAAsF;AACpF,QAAA,MAAMc,qBAAqB,GAAIlG,kBAAD,KAA0BA,kBAAkB,KAAK,GAAxB,IAAiCA,kBAAkB,KAAKgG,IAAI,CAACZ,QAAtF,CAA9B,CAAA;AACAF,QAAAA,GAAG,CAACiB,GAAJ,CAAQH,IAAI,CAAC3F,IAAb,EAAmB6F,qBAAqB,GAAGF,IAAI,CAAC3F,IAAR,GAAeJ,wBAAwB,KAAK,MAA7B,GAAsC,IAAtC,GAA6CA,wBAApG,EAA8H8F,mBAA9H,CAAA,CAAA;AACD,OAAA;AACF,KALD,CAAA,CAAA;AAOAK,IAAAA,iBAAiB,CAACN,YAAD,EAAeC,mBAAf,CAAjB,CAAA;AACD,GAXD,CAAA,CAAA;AAYD,CAAA;AAEK,SAAUM,6BAAV,CAAyCT,mBAAzC,EAA4EU,UAA5E,EAAoGpB,MAAqBC,GAAzH,EAA4H;AAChIS,EAAAA,mBAAmB,CAACJ,OAApB,CAA4BM,YAAY,IAAG;AACzC,IAAMC,MAAAA,mBAAmB,GAAGtF,IAAI,CAACM,KAAL,CAAW+E,YAAY,CAACtD,OAAxB,CAA5B,CAAA;AAEA8D,IAAAA,UAAU,CAACd,OAAX,CAAmBQ,IAAI,IAAG;AACxB,MAAA,IAAIA,IAAI,CAACZ,QAAL,IAAiBU,YAAY,CAACvD,QAAb,CAAsB0D,QAAtB,CAA+BD,IAAI,CAACZ,QAApC,CAArB,EAAoE;AAClEF,QAAAA,GAAG,CAACqB,MAAJ,CAAWP,IAAI,CAAC3F,IAAhB,EAAsB0F,mBAAtB,CAAA,CAAA;AACD,OAAA;AACF,KAJD,CAAA,CAAA;AAMAK,IAAAA,iBAAiB,CAACN,YAAD,EAAeC,mBAAf,CAAjB,CAAA;AACD,GAVD,CAAA,CAAA;AAWD,CAAA;;AAED,SAASK,iBAAT,CAA4BN,YAA5B,EAAsDU,sBAAtD,EAAqF;AACnF,EAAA,MAAMC,aAAa,GAAGX,YAAY,CAACvD,QAAb,CAAsBe,SAAtB,CAAgCwC,YAAY,CAACvD,QAAb,CAAsBkC,WAAtB,CAAkC,GAAlC,CAAA,GAAyC,CAAzE,CAAtB,CAAA;AACE,EAAA,MAAMiC,QAAQ,GAAGZ,YAAY,CAACzF,IAA9B,CAAA;AACA,EAAMsG,MAAAA,kBAAkB,GAAGlG,IAAI,CAACC,SAAL,CAAe8F,sBAAf,EAAuC,IAAvC,EAA6C,CAA7C,CAA3B,CAAA;;AAEA,EAAIC,IAAAA,aAAa,KAAK,MAAtB,EAA8B;AAC5BtG,IAAAA,EAAE,CAACC,aAAH,CAAiBsG,QAAjB,EAA2BC,kBAA3B,CAAA,CAAA;AACD,GAFD,MAEO,IAAIF,aAAa,KAAK,IAAtB,EAA4B;AACjC,IAAA,MAAMG,MAAM,GAAuB,CAAAD,iBAAAA,EAAAA,mBAAnC,IAAA,CAAA,CAAA;AACAxG,IAAAA,EAAE,CAACC,aAAH,CAAiBsG,QAAjB,EAA2BE,MAA3B,CAAA,CAAA;AACD,GAHM,MAGA,IAAIH,aAAa,KAAK,MAAlB,IAA4BA,aAAa,KAAK,KAAlD,EAAyD;AAC9D,IAAA,MAAMI,QAAQ,GAAG/B,IAAI,CAACgC,IAAL,CAAUN,sBAAV,CAAjB,CAAA;AACArG,IAAAA,EAAE,CAACC,aAAH,CAAiBsG,QAAjB,EAA2BG,QAA3B,CAAA,CAAA;AACD,GAHM,MAGA;AACL,IAAA,MAAM,IAAI7E,KAAJ,EAAkCyE,qBAAAA,EAAAA,aAAa,iBAA/C,CAAN,CAAA;AACD,GAAA;AACJ;;;SAGeM,mBAAoBtH,eAAuByF,MAAqBC,KAAG;AACjF,EAAOF,OAAAA,oCAAoC,CAACX,iBAAiB,CAAC7E,aAAD,CAAlB,EAAmCyF,GAAnC,CAA3C,CAAA;AACD;;AC/GD,SAAS8B,aAAT,CAAwBhB,IAAxB,EAAkD;AAChD,EAAO,OAAA;AACL3F,IAAAA,IAAI,EAAE2F,IAAI,CAAC3F,IADN;AAELsC,IAAAA,IAAI,EAAEqD,IAAI,CAACrD,IAFN;AAGLU,IAAAA,IAAI,EAAE2C,IAAI,CAAC3C,IAAAA;AAHN,GAAP,CAAA;AAKD,CAAA;;AAED,SAAS4D,cAAT,CAAyBjB,IAAzB,EAAmD;AACjD,EAAA,OAAOA,IAAI,CAAC3F,IAAL,CAAU4F,QAAV,CAAmB,IAAnB,CAAA,IAA4B,CAAC,CAACD,IAAI,CAAC9C,iBAAL,CAAuBJ,KAAvB,CAA6B,IAA7B,CAA9B,IAAoE,CAAC,CAACkD,IAAI,CAAC5C,aAAL,CAAmBN,KAAnB,CAAyB,IAAzB,CAA7E,CAAA;AACD;;;SAGeoE,kBAAmBC,UAAkC1H,eAA6B2H,QAAuB;AACvH,EAAMvB,MAAAA,WAAW,GAAe,EAAhC,CAAA;AACA,EAAMS,MAAAA,UAAU,GAAe,EAA/B,CAAA;AACA,EAAMe,MAAAA,gBAAgB,GAAe,EAArC,CAAA;;AAEA,EAAID,IAAAA,MAAM,CAACnB,QAAP,CAAgBvE,aAAa,CAAC4F,OAA9B,CAAJ,EAA4C;AAC3CD,IAAAA,gBAAgB,CAAE3B,IAAlB,CAAwB,GAAGyB,QAAQ,CACjCI,MADyB,CAClBC,OAAO,IAAIP,cAAc,CAACO,OAAD,CADP,CAEzBnF,CAAAA,GAFyB,CAErBmF,OAAO,IAAIR,aAAa,CAACQ,OAAD,CAFH,CAA3B,CAAA,CAAA;AAGC,GAAA;;AAEFlC,EAAAA,MAAM,CAACC,IAAP,CAAY9F,aAAZ,CAA2B+F,CAAAA,OAA3B,CAAmCJ,QAAQ,IAAG;AAC5C,IAAA,MAAMqC,aAAa,GAAGhI,aAAa,CAAC2F,QAAD,CAAnC,CAAA;;AAEA,IAAIgC,IAAAA,MAAM,CAACnB,QAAP,CAAgBvE,aAAa,CAACgG,OAA9B,CAAJ,EAA4C;AAC5C,MAAA,MAAMC,qBAAqB,GAAGR,QAAQ,CACnCI,MAD2B,CACpBC,OAAO,IAAI,CAACP,cAAc,CAACO,OAAD,CADN,CAAA,CAE3BD,MAF2B,CAEpBC,OAAO,IAAI,CAACC,aAAa,CAACG,IAAd,CAAmBC,YAAY,IAAIL,OAAO,CAACnH,IAAR,KAAiBwH,YAAY,CAACxH,IAAjE,CAFQ,CAAA,CAG3BgC,GAH2B,CAGvBmF,OAAO,iBAAUR,aAAa,CAACQ,OAAD,CAAvB,EAAA;AAAkCpC,QAAAA,QAAAA;AAAlC,OAAA,CAHgB,CAA9B,CAAA;AAKAS,MAAAA,WAAW,CAACH,IAAZ,CAAiB,GAAGiC,qBAApB,CAAA,CAAA;AACC,KAAA;;AAED,IAAIP,IAAAA,MAAM,CAACnB,QAAP,CAAgBvE,aAAa,CAACoG,MAA9B,CAAJ,EAA2C;AAC3C,MAAA,MAAMC,oBAAoB,GAAGN,aAAa,CACvCF,MAD0B,CACnBM,YAAY,IAAI,CAACV,QAAQ,CAACS,IAAT,CAAcJ,OAAO,IAAIK,YAAY,CAACxH,IAAb,KAAsBmH,OAAO,CAACnH,IAA9B,IAAsCwH,YAAY,CAACxH,IAAb,CAAkB2H,UAAlB,CAA6BR,OAAO,CAACnH,IAAR,GAAe,GAA5C,CAA/D,CADE,CAAA,CAE1BgC,GAF0B,CAEtBwF,YAAY,iBAAUA,YAAV,EAAA;AAAwBzC,QAAAA,QAAAA;AAAxB,OAAA,CAFU,CAA7B,CAAA;AAIAkB,MAAAA,UAAU,CAACZ,IAAX,CAAgB,GAAGqC,oBAAnB,CAAA,CAAA;AACC,KAAA;AACF,GAnBD,CAAA,CAAA;AAqBA,EAAO,OAAA;AACLlC,IAAAA,WADK;AAELS,IAAAA,UAFK;AAGLe,IAAAA,gBAAAA;AAHK,GAAP,CAAA;AAKD,CAAA;AAEM,eAAeY,iBAAf,CAAkCC,MAAlC,EAAsDC,SAAtD,EAAuE;AAC5E,EAAA,MAAMC,YAAY,GAAG3H,IAAI,CAACC,SAAL,CAAewH,MAAf,CAArB,CAAA;AACA,EAAA,OAAO,IAAIG,OAAJ,CAAY,CAAC/H,OAAD,EAAUgI,MAAV,KAAoB;AACrCnI,IAAAA,EAAE,CAACoI,SAAH,CACEJ,SADF,EAEEC,YAFF,EAGGI,GAAD,IAAQ;AACN,MAAA,IAAIA,GAAJ,EAAS;AACPF,QAAAA,MAAM,CAACE,GAAD,CAAN,CAAA;AACA,QAAA,OAAA;AACD,OAAA;;AACDlI,MAAAA,OAAO,EAAA,CAAA;AACR,KATH,CAAA,CAAA;AAWD,GAZM,CAAP,CAAA;AAaD;;AC/DM,eAAemI,gBAAf,CAAiCvH,OAAjC,EAAuD;AAC5D,EAAM,MAAA;AACJ1B,IAAAA,QAAQ,EAAEkJ,YADN;AAEJjJ,IAAAA,aAAa,EAAEkJ,iBAFX;AAGJhJ,IAAAA,MAHI;AAIJC,IAAAA,GAJI;AAKJC,IAAAA,MALI;AAMJH,IAAAA,OAAO,GAAG,EANN;AAOJI,IAAAA,EAPI;AAQJC,IAAAA,SARI;AASJC,IAAAA,kBAAkB,GAAG,EATjB;AAUJC,IAAAA,wBAAwB,GAAG,EAVvB;AAWJmH,IAAAA,MAAM,GAAG,CAAC1F,aAAa,CAACgG,OAAf,EAAwBhG,aAAa,CAACoG,MAAtC,EAA8CpG,aAAa,CAAC4F,OAA5D,CAAA;AAXL,GAAA,GAYFpG,OAZJ,CAAA;AAcA,EAAI,IAAA,CAACwH,YAAL,EAAmB,MAAM,IAAI1G,KAAJ,CAAU,6CAAV,CAAN,CAAA;AACnB,EAAI,IAAA,CAAC2G,iBAAL,EAAwB,MAAM,IAAI3G,KAAJ,CAAU,kDAAV,CAAN,CAAA;AAExB,EAAA,IAAI4G,cAAc,GAAGpH,KAAK,CAACC,OAAN,CAAc2F,MAAd,CAAA,GAAwBA,MAAxB,GAAiC,CAACA,MAAD,CAAtD,CAAA;AACA,EAAA,MAAMyB,oBAAoB,GAAGD,cAAc,CAACrB,MAAf,CAAsBvB,IAAI,IAAI,CAACV,MAAM,CAACwD,MAAP,CAAcpH,aAAd,CAAA,CAA6BuE,QAA7B,CAAsCD,IAAtC,CAA/B,CAA7B,CAAA;;AACA,EAAI6C,IAAAA,oBAAoB,CAACzG,MAAzB,EAAiC;AAC/B,IAAA,MAAM,IAAIJ,KAAJ,EAAwC6G,2BAAAA,EAAAA,oBAAoB,EAA5D,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,MAAM3D,GAAG,GAAG,OAAOnF,SAAP,KAAqB,QAArB,GAAgC,IAAIoF,GAAJ,CAAQpF,SAAR,CAAhC,GAAqDoF,GAAjE,CAAA;AACA,EAAA,MAAM3F,QAAQ,GAAGmC,YAAY,CAACtB,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4BkI,YAA5B,CAAD,CAA7B,CAAA;AACA,EAAA,MAAMjJ,aAAa,GAAG6E,iBAAiB,CAACjE,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4BmI,iBAA5B,CAAD,CAAvC,CAAA;AAEA,EAAA,MAAMI,SAAS,GAAGjF,4BAA4B,CAACtE,QAAD,CAA9C,CAAA;AACA,EAAA,MAAMwJ,YAAY,GAAG/D,oCAAoC,CAACxF,aAAD,EAAgByF,GAAhB,CAAzD,CAAA;AAEA,EAAMgD,MAAAA,MAAM,GAAGhB,iBAAiB,CAAC6B,SAAD,EAAYC,YAAZ,EAA0BJ,cAA1B,CAAhC,CAAA;AAEAV,EAAAA,MAAM,CAAC5B,UAAP,GAAoB4B,MAAM,CAAC5B,UAAP,CAAkBiB,MAAlB,CAAyB9B,GAAG,IAC5C,CAAC/F,OAAO,CAAC6H,MAAR,CAAe0B,QAAQ,IAAIxD,GAAG,CAACpF,IAAJ,CAAS2H,UAAT,CAAoBiB,QAApB,CAA3B,CAAA,CAA0D7G,MAD3C,CAApB,CAAA;AAGA,EAAA,IAAI8F,MAAM,CAACrC,WAAP,CAAmBzD,MAAvB,EAA+Bd,OAAO,CAACC,IAAR,CAAa,gBAAb,CAAA,EAAgCD,OAAO,CAAC4H,KAAR,CAAchB,MAAM,CAACrC,WAArB,CAAhC,CAAA;AAC/B,EAAA,IAAIqC,MAAM,CAAC5B,UAAP,CAAkBlE,MAAtB,EAA8Bd,OAAO,CAACC,IAAR,CAAa,eAAb,CAAA,EAA+BD,OAAO,CAAC4H,KAAR,CAAchB,MAAM,CAAC5B,UAArB,CAA/B,CAAA;AAC9B,EAAA,IAAI4B,MAAM,CAACb,gBAAP,CAAwBjF,MAA5B,EAAoCd,OAAO,CAAC6H,IAAR,CAAa,qJAAb,CAAA,EAAqK7H,OAAO,CAAC4H,KAAR,CAAchB,MAAM,CAACb,gBAArB,CAArK,CAAA;;AAEpC,EAAA,IAAI1H,MAAJ,EAAY;AACV,IAAA,MAAMsI,iBAAiB,CAACC,MAAD,EAAS7H,IAAI,CAACC,OAAL,CAAaC,OAAO,CAACC,GAAR,EAAb,EAA4Bb,MAA5B,CAAT,CAAvB,CAAA;AACA2B,IAAAA,OAAO,CAACC,IAAR,4CAAwD5B,MAAM,CAA9D,CAAA,CAAA,CAAA;AACD,GAAA;;AAED,EAAA,IAAIE,MAAM,IAAIqI,MAAM,CAAC5B,UAAP,CAAkBlE,MAAhC,EAAwC;AACtCiE,IAAAA,6BAA6B,CAAC5G,aAAD,EAAgByI,MAAM,CAAC5B,UAAvB,EAAmCpB,GAAnC,CAA7B,CAAA;AACA5D,IAAAA,OAAO,CAACC,IAAR,CAAa,+DAAb,CAAA,CAAA;AACD,GAAA;;AAED,EAAA,IAAI3B,GAAG,IAAIsI,MAAM,CAACrC,WAAP,CAAmBzD,MAA9B,EAAsC;AACpCuD,IAAAA,2BAA2B,CAAClG,aAAD,EAAgByI,MAAM,CAACrC,WAAvB,EAAoCX,GAApC,EAAyClF,kBAAzC,EAA6DC,wBAA7D,CAA3B,CAAA;AACAqB,IAAAA,OAAO,CAACC,IAAR,CAAa,4DAAb,CAAA,CAAA;AACD,GAAA;;AAED,EAAA,IAAIzB,EAAE,IAAIoI,MAAM,CAACrC,WAAP,CAAmBzD,MAA7B,EAAqC;AACnC,IAAM,MAAA,IAAIJ,KAAJ,CAAa,CAAAkG,EAAAA,MAAM,CAACrC,WAAP,CAAmBzD,MAA4B,CAAA,oBAAA,CAA5D,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,IAAItC,EAAE,IAAIoI,MAAM,CAAC5B,UAAP,CAAkBlE,MAA5B,EAAoC;AAClC,IAAM,MAAA,IAAIJ,KAAJ,CAAa,CAAAkG,EAAAA,MAAM,CAAC5B,UAAP,CAAkBlE,MAA2B,CAAA,mBAAA,CAA1D,CAAN,CAAA;AACD,GAAA;;AAED,EAAA,OAAO8F,MAAP,CAAA;AACD;;ACnED3H,OAAO,CAAC6I,EAAR,CAAW,mBAAX,EAAiCZ,GAAD,IAAQ;AACtClH,EAAAA,OAAO,CAAC+H,KAAR,CAAc,oBAAd,EAAoCb,GAApC,CAAA,CAAA;AACAjI,EAAAA,OAAO,CAAC+I,IAAR,CAAa,CAAb,CAAA,CAAA;AACD,CAHD,CAAA,CAAA;AAKA/I,OAAO,CAAC6I,EAAR,CAAW,oBAAX,EAAkCZ,GAAD,IAAQ;AACvClH,EAAAA,OAAO,CAAC+H,KAAR,CAAc,oBAAd,EAAoCb,GAApC,CAAA,CAAA;AACAjI,EAAAA,OAAO,CAAC+I,IAAR,CAAa,CAAb,CAAA,CAAA;AACD,CAHD,CAAA;;;;"} \ No newline at end of file +{"version":3,"file":"vue-i18n-extract.modern.mjs","sources":["../src/config-file/vue-i18n-extract.config.ts","../src/config-file/index.ts","../src/types.ts","../src/create-report/vue-files.ts","../src/create-report/language-files.ts","../src/create-report/report.ts","../src/create-report/index.ts","../src/index.ts"],"sourcesContent":["export default {\n // Options documented in vue-i18n-extract readme.\n vueFiles: './src/**/*.?(js|vue)',\n languageFiles: './lang/**/*.?(json|yaml|yml|js)',\n exclude: [],\n output: false,\n add: false,\n remove: false,\n ci: false,\n separator: '.',\n noEmptyTranslation: '',\n missingTranslationString: '',\n};\n","import cac from 'cac';\nimport fs from 'fs';\nimport path from 'path';\nimport defaultConfig from './vue-i18n-extract.config';\n\nexport function initCommand(): void {\n fs.writeFileSync(\n path.resolve(process.cwd(), './vue-i18n-extract.config.js'),\n `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`,\n );\n}\n\nexport function resolveConfig (): Record {\n const argvOptions = cac().parse(process.argv, { run: false }).options;\n\n let options;\n\n try {\n const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const configOptions = require(pathToConfigFile);\n\n console.info(`\\nUsing config file found at ${pathToConfigFile}`);\n\n options = {\n ...configOptions,\n ...argvOptions\n };\n } catch {\n options = argvOptions;\n }\n\n options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude];\n\n return options;\n}\n","export type ReportOptions = {\n vueFiles: string;\n languageFiles: string;\n output?: string;\n exclude?: string[];\n add?: boolean;\n remove?: boolean;\n ci?: boolean;\n separator?: string;\n noEmptyTranslation?: string;\n missingTranslationString?: string;\n detect?: DetectionType[];\n}\n\nexport enum DetectionType {\n Missing = \"missing\",\n Unused = \"unused\",\n Dynamic = \"dynamic\"\n}\n\nexport type SimpleFile = {\n fileName: string;\n path: string;\n content: string;\n}\n\nexport type I18NItem = {\n line?: number;\n path: string;\n file?: string;\n language?: string;\n}\n\nexport type I18NItemWithBounding = I18NItem & {\n previousCharacter: string;\n nextCharacter: string;\n}\n\nexport type I18NLanguage = {\n [language: string]: I18NItem[];\n}\n\nexport type I18NReport = {\n missingKeys: I18NItem[];\n unusedKeys: I18NItem[];\n maybeDynamicKeys: I18NItem[];\n}\n","import { SimpleFile, I18NItemWithBounding } from '../types';\nimport isValidGlob from 'is-valid-glob';\nimport glob from 'glob';\nimport fs from 'fs';\n\nexport function readVueFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`vueFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('vueFiles glob has no files.');\n }\n\n return targetFiles.map((f) => {\n const fileName = f.replace(process.cwd(), '.');\n return { fileName, path: f, content: fs.readFileSync(f, 'utf8') };\n });\n}\n\nfunction* getMatches (file: SimpleFile, regExp: RegExp, captureGroup = 1): IterableIterator {\n while (true) {\n const match = regExp.exec(file.content);\n if (match === null) {\n break;\n }\n const path = match[captureGroup];\n\n const pathAtIndex = file.content.indexOf(path);\n const previousCharacter = file.content.charAt(pathAtIndex - 1);\n const nextCharacter = file.content.charAt(pathAtIndex + path.length);\n\n const line = (file.content.substring(0, match.index).match(/\\n/g) || []).length + 1;\n yield {\n path,\n previousCharacter,\n nextCharacter,\n file: file.fileName,\n line,\n };\n }\n}\n\n/**\n * Extracts translation keys from methods such as `$t` and `$tc`.\n *\n * - **regexp pattern**: (?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\n *\n * **description**: Matches the sequence t(, tc( or tm(, optionally with either “$”, SPACE, “.”, “:”, “\"”, “'”,\n * “`”, \"+\", \"(\", \"[\" or \"{\" in front of it.\n *\n * - **regexp pattern**: ([\"'`])\n *\n * **description**: 1. capturing group. Matches either “\"”, “'”, or “`”.\n *\n * - **regexp pattern**: ((?:[^\\\\]|\\\\.)*?)\n *\n * **description**: 2. capturing group. Matches anything except a backslash\n * *or* matches any backslash followed by any character (e.g. “\\\"”, “\\`”, “\\t”, etc.)\n *\n * - **regexp pattern**: \\1\n *\n * **description**: matches whatever was matched by capturing group 1 (e.g. the starting string character)\n *\n * @param file a file object\n * @returns a list of translation keys found in `file`.\n */\n function extractMethodMatches (file: SimpleFile): I18NItemWithBounding[] {\n const methodRegExp = /(?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\\s*?([\"'`])((?:[^\\\\]|\\\\.)*?)\\1/g;\n return [ ...getMatches(file, methodRegExp, 2) ];\n}\n\nfunction extractComponentMatches (file: SimpleFile): I18NItemWithBounding[] {\n const componentRegExp = /(?:(?:<|h\\()(?:i18n|Translation))(?:.|\\n)*?(?:\\s(?:(?:key)?)path(?:=|: )(\"|'))((?:[^\\\\]|\\\\.)*?)\\1/gi;\n return [ ...getMatches(file, componentRegExp, 2) ];\n}\n\nfunction extractDirectiveMatches (file: SimpleFile): I18NItemWithBounding[] {\n const directiveRegExp = /\\bv-t(?:\\.[\\w-]+)?=\"'((?:[^\\\\]|\\\\.)*?)'\"/g;\n return [ ...getMatches(file, directiveRegExp) ];\n}\n\nexport function extractI18NItemsFromVueFiles (sourceFiles: SimpleFile[]): I18NItemWithBounding[] {\n return sourceFiles.reduce((accumulator, file) => {\n const methodMatches = extractMethodMatches(file);\n const componentMatches = extractComponentMatches(file);\n const directiveMatches = extractDirectiveMatches(file);\n return [\n ...accumulator,\n ...methodMatches,\n ...componentMatches,\n ...directiveMatches,\n ];\n }, [] as I18NItemWithBounding[]);\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parseVueFiles (vueFiles: string): I18NItemWithBounding[] {\n return extractI18NItemsFromVueFiles(readVueFiles(vueFiles));\n}\n","import path from 'path';\nimport fs from 'fs';\nimport glob from 'glob';\nimport Dot from 'dot-object';\nimport yaml from 'js-yaml';\nimport isValidGlob from 'is-valid-glob';\nimport { SimpleFile, I18NLanguage, I18NItem } from '../types';\n\nexport function readLanguageFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`languageFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('languageFiles glob has no files.');\n }\n\n return targetFiles.map(f => {\n const langPath = path.resolve(process.cwd(), f);\n\n const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase();\n const isJSON = extension === '.json';\n const isYAML = extension === '.yaml' || extension === '.yml';\n\n let langObj;\n if (isJSON) {\n langObj = JSON.parse(fs.readFileSync(langPath, 'utf8'));\n } else if (isYAML) {\n langObj = yaml.load(fs.readFileSync(langPath, 'utf8'));\n } else {\n langObj = eval(fs.readFileSync(langPath, 'utf8'));\n }\n\n const fileName = f.replace(process.cwd(), '.');\n\n return { path: f, fileName, content: JSON.stringify(langObj) };\n });\n}\n\nexport function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[], dot: DotObject.Dot = Dot): I18NLanguage {\n return languageFiles.reduce((accumulator, file) => {\n const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.'));\n\n if (!accumulator[language]) {\n accumulator[language] = [];\n }\n\n const flattenedObject = dot.dot(JSON.parse(file.content));\n Object.keys(flattenedObject).forEach((key) => {\n accumulator[language].push({\n path: key,\n file: file.fileName,\n });\n });\n\n return accumulator;\n }, {});\n}\n\nexport function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = '', missingTranslationString = ''): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n missingKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language) || !item.language) {\n const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));\n let value: string | null = null;\n if (addDefaultTranslation) {\n value = item.path;\n } else if (missingTranslationString === 'null') {\n value = null;\n } else if (missingTranslationString.includes('{{t}}')) {\n value = missingTranslationString.replace('{{t}}', item.path);\n } else {\n value = missingTranslationString;\n }\n dot.str(item.path, value, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n unusedKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language)) {\n dot.delete(item.path, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nfunction writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2);\n\n if (fileExtension === 'json') {\n fs.writeFileSync(filePath, stringifiedContent);\n } else if (fileExtension === 'js') {\n const jsFile = `module.exports = ${stringifiedContent}; \\n`;\n fs.writeFileSync(filePath, jsFile);\n } else if (fileExtension === 'yaml' || fileExtension === 'yml') {\n const yamlFile = yaml.dump(newLanguageFileContent);\n fs.writeFileSync(filePath, yamlFile);\n } else {\n throw new Error(`Language filetype of ${fileExtension} not supported.`)\n }\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parselanguageFiles (languageFiles: string, dot: DotObject.Dot = Dot): I18NLanguage {\n return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot);\n}\n","import fs from 'fs';\nimport { DetectionType, I18NItem, I18NItemWithBounding, I18NLanguage, I18NReport } from '../types';\n\nfunction stripBounding (item: I18NItemWithBounding): I18NItem {\n return {\n path: item.path,\n file: item.file,\n line: item.line,\n }\n}\n\nfunction mightBeDynamic (item: I18NItemWithBounding): boolean {\n return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g);\n}\n\n// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off.\nexport function extractI18NReport (vueItems: I18NItemWithBounding[], languageFiles: I18NLanguage, detect: DetectionType[]): I18NReport {\n const missingKeys: I18NItem[] = [];\n const unusedKeys: I18NItem[] = [];\n const maybeDynamicKeys: I18NItem[] = [];\n\n if (detect.includes(DetectionType.Dynamic)) {\n maybeDynamicKeys. push( ...vueItems\n .filter(vueItem => mightBeDynamic(vueItem))\n .map(vueItem => stripBounding(vueItem)));\n }\n\n Object.keys(languageFiles).forEach(language => {\n const languageItems = languageFiles[language];\n\n if (detect.includes(DetectionType.Missing)) {\n const missingKeysInLanguage = vueItems\n .filter(vueItem => !mightBeDynamic(vueItem))\n .filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path))\n .map(vueItem => ({ ...stripBounding(vueItem), language }));\n\n missingKeys.push(...missingKeysInLanguage);\n }\n\n if (detect.includes(DetectionType.Unused)) {\n const unusedKeysInLanguage = languageItems\n .filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.')))\n .map(languageItem => ({ ...languageItem, language }));\n\n unusedKeys.push(...unusedKeysInLanguage);\n }\n });\n\n return {\n missingKeys,\n unusedKeys,\n maybeDynamicKeys,\n };\n}\n\nexport async function writeReportToFile (report: I18NReport, writePath: string): Promise {\n const reportString = JSON.stringify(report);\n return new Promise((resolve, reject) => {\n fs.writeFile(\n writePath,\n reportString,\n (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n },\n );\n });\n}\n\n","import path from 'path';\nimport { ReportOptions, I18NReport, DetectionType } from '../types';\nimport { readVueFiles, extractI18NItemsFromVueFiles } from './vue-files';\nimport { readLanguageFiles, extractI18NLanguageFromLanguageFiles, removeUnusedFromLanguageFiles, writeMissingToLanguageFiles } from './language-files';\nimport { extractI18NReport, writeReportToFile } from './report';\nimport Dot from 'dot-object';\n\nexport async function createI18NReport (options: ReportOptions): Promise {\n const {\n vueFiles: vueFilesGlob,\n languageFiles: languageFilesGlob,\n output,\n add,\n remove,\n exclude = [],\n ci,\n separator,\n noEmptyTranslation = '',\n missingTranslationString = '',\n detect = [DetectionType.Missing, DetectionType.Unused, DetectionType.Dynamic]\n } = options;\n\n if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');\n if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.');\n\n let issuesToDetect = Array.isArray(detect) ? detect : [detect];\n const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(DetectionType).includes(item));\n if (invalidDetectOptions.length) {\n throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`);\n }\n\n const dot = typeof separator === 'string' ? new Dot(separator) : Dot;\n const vueFiles = readVueFiles(path.resolve(process.cwd(), vueFilesGlob));\n const languageFiles = readLanguageFiles(path.resolve(process.cwd(), languageFilesGlob));\n\n const I18NItems = extractI18NItemsFromVueFiles(vueFiles);\n const I18NLanguage = extractI18NLanguageFromLanguageFiles(languageFiles, dot);\n\n const report = extractI18NReport(I18NItems, I18NLanguage, issuesToDetect);\n\n report.unusedKeys = report.unusedKeys.filter(key =>\n !exclude.filter(excluded => key.path.startsWith(excluded)).length)\n\n if (report.missingKeys.length) console.info('\\nMissing Keys'), console.table(report.missingKeys);\n if (report.unusedKeys.length) console.info('\\nUnused Keys'), console.table(report.unusedKeys);\n if (report.maybeDynamicKeys.length) console.warn('\\nSuspected Dynamic Keys Found\\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys);\n\n if (output) {\n await writeReportToFile(report, path.resolve(process.cwd(), output));\n console.info(`\\nThe report has been has been saved to ${output}`);\n }\n\n if (remove && report.unusedKeys.length) {\n removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot);\n console.info('\\nThe unused keys have been removed from your language files.');\n }\n\n if (add && report.missingKeys.length) {\n writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString);\n console.info('\\nThe missing keys have been added to your language files.');\n }\n\n if (ci && report.missingKeys.length) {\n throw new Error(`${report.missingKeys.length} missing keys found.`);\n }\n\n if (ci && report.unusedKeys.length) {\n throw new Error(`${report.unusedKeys.length} unused keys found.`);\n }\n\n return report;\n}\n\nexport * from './vue-files';\nexport * from './language-files';\nexport * from './report';\n","export * from './config-file';\nexport * from './create-report';\nexport * from './types';\n\nprocess.on('uncaughtException', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n"],"names":["vueFiles","languageFiles","exclude","output","add","remove","ci","separator","noEmptyTranslation","missingTranslationString","initCommand","fs","writeFileSync","path","resolve","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","cac","parse","argv","run","options","pathToConfigFile","configOptions","require","console","info","_extends","_unused","Array","isArray","DetectionType","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","f","fileName","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","pathAtIndex","indexOf","previousCharacter","charAt","nextCharacter","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","parseVueFiles","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","yaml","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","languageFile","languageFileContent","item","includes","addDefaultTranslation","value","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","filePath","stringifiedContent","jsFile","yamlFile","dump","parselanguageFiles","stripBounding","mightBeDynamic","extractI18NReport","vueItems","detect","maybeDynamicKeys","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","writeReportToFile","report","writePath","reportString","Promise","reject","writeFile","err","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","exit"],"mappings":"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"} \ No newline at end of file diff --git a/dist/vue-i18n-extract.umd.js b/dist/vue-i18n-extract.umd.js index 3d3efb38..511e922b 100644 --- a/dist/vue-i18n-extract.umd.js +++ b/dist/vue-i18n-extract.umd.js @@ -13,24 +13,6 @@ var Dot__default = /*#__PURE__*/_interopDefaultLegacy(Dot); var yaml__default = /*#__PURE__*/_interopDefaultLegacy(yaml); - function _extends() { - _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - }; - - return _extends.apply(this, arguments); - } - var defaultConfig = { // Options documented in vue-i18n-extract readme. vueFiles: './src/**/*.?(js|vue)', @@ -53,24 +35,23 @@ run: false }).options; let options; - try { - const pathToConfigFile = path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.js'); // eslint-disable-next-line @typescript-eslint/no-var-requires - + const pathToConfigFile = path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.js'); + // eslint-disable-next-line @typescript-eslint/no-var-requires const configOptions = require(pathToConfigFile); - console.info(`\nUsing config file found at ${pathToConfigFile}`); - options = _extends({}, configOptions, argvOptions); - } catch (_unused) { + options = { + ...configOptions, + ...argvOptions + }; + } catch { options = argvOptions; } - options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude]; return options; } exports.DetectionType = void 0; - (function (DetectionType) { DetectionType["Missing"] = "missing"; DetectionType["Unused"] = "unused"; @@ -81,17 +62,13 @@ // Replace backslash path segments to make the path work with the glob package. // https://github.com/Spittal/vue-i18n-extract/issues/159 const normalizedSrc = src.replace(/\\/g, '/'); - if (!isValidGlob__default["default"](normalizedSrc)) { throw new Error(`vueFiles isn't a valid glob pattern.`); } - const targetFiles = glob__default["default"].sync(normalizedSrc); - if (targetFiles.length === 0) { throw new Error('vueFiles glob has no files.'); } - return targetFiles.map(f => { const fileName = f.replace(process.cwd(), '.'); return { @@ -101,15 +78,12 @@ }; }); } - function* getMatches(file, regExp, captureGroup = 1) { while (true) { const match = regExp.exec(file.content); - if (match === null) { break; } - const path = match[captureGroup]; const pathAtIndex = file.content.indexOf(path); const previousCharacter = file.content.charAt(pathAtIndex - 1); @@ -148,23 +122,18 @@ * @param file a file object * @returns a list of translation keys found in `file`. */ - - function extractMethodMatches(file) { const methodRegExp = /(?:[$\s.:"'`+\(\[\{]t[cm]?)\(\s*?(["'`])((?:[^\\]|\\.)*?)\1/g; return [...getMatches(file, methodRegExp, 2)]; } - function extractComponentMatches(file) { const componentRegExp = /(?:(?:<|h\()(?:i18n|Translation))(?:.|\n)*?(?:\s(?:(?:key)?)path(?:=|: )("|'))((?:[^\\]|\\.)*?)\1/gi; return [...getMatches(file, componentRegExp, 2)]; } - function extractDirectiveMatches(file) { const directiveRegExp = /\bv-t(?:\.[\w-]+)?="'((?:[^\\]|\\.)*?)'"/g; return [...getMatches(file, directiveRegExp)]; } - function extractI18NItemsFromVueFiles(sourceFiles) { return sourceFiles.reduce((accumulator, file) => { const methodMatches = extractMethodMatches(file); @@ -172,8 +141,8 @@ const directiveMatches = extractDirectiveMatches(file); return [...accumulator, ...methodMatches, ...componentMatches, ...directiveMatches]; }, []); - } // This is a convenience function for users implementing in their own projects, and isn't used internally - + } + // This is a convenience function for users implementing in their own projects, and isn't used internally function parseVueFiles(vueFiles) { return extractI18NItemsFromVueFiles(readVueFiles(vueFiles)); } @@ -182,24 +151,19 @@ // Replace backslash path segments to make the path work with the glob package. // https://github.com/Spittal/vue-i18n-extract/issues/159 const normalizedSrc = src.replace(/\\/g, '/'); - if (!isValidGlob__default["default"](normalizedSrc)) { throw new Error(`languageFiles isn't a valid glob pattern.`); } - const targetFiles = glob__default["default"].sync(normalizedSrc); - if (targetFiles.length === 0) { throw new Error('languageFiles glob has no files.'); } - return targetFiles.map(f => { const langPath = path__default["default"].resolve(process.cwd(), f); const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase(); const isJSON = extension === '.json'; const isYAML = extension === '.yaml' || extension === '.yml'; let langObj; - if (isJSON) { langObj = JSON.parse(fs__default["default"].readFileSync(langPath, 'utf8')); } else if (isYAML) { @@ -207,7 +171,6 @@ } else { langObj = eval(fs__default["default"].readFileSync(langPath, 'utf8')); } - const fileName = f.replace(process.cwd(), '.'); return { path: f, @@ -219,11 +182,9 @@ function extractI18NLanguageFromLanguageFiles(languageFiles, dot = Dot__default["default"]) { return languageFiles.reduce((accumulator, file) => { const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.')); - if (!accumulator[language]) { accumulator[language] = []; } - const flattenedObject = dot.dot(JSON.parse(file.content)); Object.keys(flattenedObject).forEach(key => { accumulator[language].push({ @@ -240,7 +201,17 @@ missingKeys.forEach(item => { if (item.language && languageFile.fileName.includes(item.language) || !item.language) { const addDefaultTranslation = noEmptyTranslation && (noEmptyTranslation === '*' || noEmptyTranslation === item.language); - dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent); + let value = null; + if (addDefaultTranslation) { + value = item.path; + } else if (missingTranslationString === 'null') { + value = null; + } else if (missingTranslationString.includes('{{t}}')) { + value = missingTranslationString.replace('{{t}}', item.path); + } else { + value = missingTranslationString; + } + dot.str(item.path, value, languageFileContent); } }); writeLanguageFile(languageFile, languageFileContent); @@ -257,12 +228,10 @@ writeLanguageFile(languageFile, languageFileContent); }); } - function writeLanguageFile(languageFile, newLanguageFileContent) { const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1); const filePath = languageFile.path; const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2); - if (fileExtension === 'json') { fs__default["default"].writeFileSync(filePath, stringifiedContent); } else if (fileExtension === 'js') { @@ -274,9 +243,8 @@ } else { throw new Error(`Language filetype of ${fileExtension} not supported.`); } - } // This is a convenience function for users implementing in their own projects, and isn't used internally - - + } + // This is a convenience function for users implementing in their own projects, and isn't used internally function parselanguageFiles(languageFiles, dot = Dot__default["default"]) { return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot); } @@ -288,33 +256,29 @@ line: item.line }; } - function mightBeDynamic(item) { return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g); - } // Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off. - - + } + // Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off. function extractI18NReport(vueItems, languageFiles, detect) { const missingKeys = []; const unusedKeys = []; const maybeDynamicKeys = []; - if (detect.includes(exports.DetectionType.Dynamic)) { maybeDynamicKeys.push(...vueItems.filter(vueItem => mightBeDynamic(vueItem)).map(vueItem => stripBounding(vueItem))); } - Object.keys(languageFiles).forEach(language => { const languageItems = languageFiles[language]; - if (detect.includes(exports.DetectionType.Missing)) { - const missingKeysInLanguage = vueItems.filter(vueItem => !mightBeDynamic(vueItem)).filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path)).map(vueItem => _extends({}, stripBounding(vueItem), { + const missingKeysInLanguage = vueItems.filter(vueItem => !mightBeDynamic(vueItem)).filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path)).map(vueItem => ({ + ...stripBounding(vueItem), language })); missingKeys.push(...missingKeysInLanguage); } - if (detect.includes(exports.DetectionType.Unused)) { - const unusedKeysInLanguage = languageItems.filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.'))).map(languageItem => _extends({}, languageItem, { + const unusedKeysInLanguage = languageItems.filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.'))).map(languageItem => ({ + ...languageItem, language })); unusedKeys.push(...unusedKeysInLanguage); @@ -334,7 +298,6 @@ reject(err); return; } - resolve(); }); }); @@ -358,11 +321,9 @@ if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.'); let issuesToDetect = Array.isArray(detect) ? detect : [detect]; const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(exports.DetectionType).includes(item)); - if (invalidDetectOptions.length) { throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`); } - const dot = typeof separator === 'string' ? new Dot__default["default"](separator) : Dot__default["default"]; const vueFiles = readVueFiles(path__default["default"].resolve(process.cwd(), vueFilesGlob)); const languageFiles = readLanguageFiles(path__default["default"].resolve(process.cwd(), languageFilesGlob)); @@ -373,30 +334,24 @@ if (report.missingKeys.length) console.info('\nMissing Keys'), console.table(report.missingKeys); if (report.unusedKeys.length) console.info('\nUnused Keys'), console.table(report.unusedKeys); if (report.maybeDynamicKeys.length) console.warn('\nSuspected Dynamic Keys Found\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys); - if (output) { await writeReportToFile(report, path__default["default"].resolve(process.cwd(), output)); console.info(`\nThe report has been has been saved to ${output}`); } - if (remove && report.unusedKeys.length) { removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot); console.info('\nThe unused keys have been removed from your language files.'); } - if (add && report.missingKeys.length) { writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString); console.info('\nThe missing keys have been added to your language files.'); } - if (ci && report.missingKeys.length) { throw new Error(`${report.missingKeys.length} missing keys found.`); } - if (ci && report.unusedKeys.length) { throw new Error(`${report.unusedKeys.length} unused keys found.`); } - return report; } diff --git a/dist/vue-i18n-extract.umd.js.map b/dist/vue-i18n-extract.umd.js.map index 74343b14..e8e41d97 100644 --- a/dist/vue-i18n-extract.umd.js.map +++ b/dist/vue-i18n-extract.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"vue-i18n-extract.umd.js","sources":["../src/config-file/vue-i18n-extract.config.ts","../src/config-file/index.ts","../src/types.ts","../src/create-report/vue-files.ts","../src/create-report/language-files.ts","../src/create-report/report.ts","../src/create-report/index.ts","../src/index.ts"],"sourcesContent":["export default {\n // Options documented in vue-i18n-extract readme.\n vueFiles: './src/**/*.?(js|vue)',\n languageFiles: './lang/**/*.?(json|yaml|yml|js)',\n exclude: [],\n output: false,\n add: false,\n remove: false,\n ci: false,\n separator: '.',\n noEmptyTranslation: '',\n missingTranslationString: '',\n};\n","import cac from 'cac';\nimport fs from 'fs';\nimport path from 'path';\nimport defaultConfig from './vue-i18n-extract.config';\n\nexport function initCommand(): void {\n fs.writeFileSync(\n path.resolve(process.cwd(), './vue-i18n-extract.config.js'),\n `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`,\n );\n}\n\nexport function resolveConfig (): Record {\n const argvOptions = cac().parse(process.argv, { run: false }).options;\n\n let options;\n\n try {\n const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const configOptions = require(pathToConfigFile);\n\n console.info(`\\nUsing config file found at ${pathToConfigFile}`);\n\n options = {\n ...configOptions,\n ...argvOptions\n };\n } catch {\n options = argvOptions;\n }\n\n options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude];\n\n return options;\n}\n","export type ReportOptions = {\n vueFiles: string;\n languageFiles: string;\n output?: string;\n exclude?: string[];\n add?: boolean;\n remove?: boolean;\n ci?: boolean;\n separator?: string;\n noEmptyTranslation?: string;\n missingTranslationString?: string;\n detect?: DetectionType[];\n}\n\nexport enum DetectionType {\n Missing = \"missing\",\n Unused = \"unused\",\n Dynamic = \"dynamic\"\n}\n\nexport type SimpleFile = {\n fileName: string;\n path: string;\n content: string;\n}\n\nexport type I18NItem = {\n line?: number;\n path: string;\n file?: string;\n language?: string;\n}\n\nexport type I18NItemWithBounding = I18NItem & {\n previousCharacter: string;\n nextCharacter: string;\n}\n\nexport type I18NLanguage = {\n [language: string]: I18NItem[];\n}\n\nexport type I18NReport = {\n missingKeys: I18NItem[];\n unusedKeys: I18NItem[];\n maybeDynamicKeys: I18NItem[];\n}\n","import { SimpleFile, I18NItemWithBounding } from '../types';\nimport isValidGlob from 'is-valid-glob';\nimport glob from 'glob';\nimport fs from 'fs';\n\nexport function readVueFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`vueFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('vueFiles glob has no files.');\n }\n\n return targetFiles.map((f) => {\n const fileName = f.replace(process.cwd(), '.');\n return { fileName, path: f, content: fs.readFileSync(f, 'utf8') };\n });\n}\n\nfunction* getMatches (file: SimpleFile, regExp: RegExp, captureGroup = 1): IterableIterator {\n while (true) {\n const match = regExp.exec(file.content);\n if (match === null) {\n break;\n }\n const path = match[captureGroup];\n\n const pathAtIndex = file.content.indexOf(path);\n const previousCharacter = file.content.charAt(pathAtIndex - 1);\n const nextCharacter = file.content.charAt(pathAtIndex + path.length);\n\n const line = (file.content.substring(0, match.index).match(/\\n/g) || []).length + 1;\n yield {\n path,\n previousCharacter,\n nextCharacter,\n file: file.fileName,\n line,\n };\n }\n}\n\n/**\n * Extracts translation keys from methods such as `$t` and `$tc`.\n *\n * - **regexp pattern**: (?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\n *\n * **description**: Matches the sequence t(, tc( or tm(, optionally with either “$”, SPACE, “.”, “:”, “\"”, “'”,\n * “`”, \"+\", \"(\", \"[\" or \"{\" in front of it.\n *\n * - **regexp pattern**: ([\"'`])\n *\n * **description**: 1. capturing group. Matches either “\"”, “'”, or “`”.\n *\n * - **regexp pattern**: ((?:[^\\\\]|\\\\.)*?)\n *\n * **description**: 2. capturing group. Matches anything except a backslash\n * *or* matches any backslash followed by any character (e.g. “\\\"”, “\\`”, “\\t”, etc.)\n *\n * - **regexp pattern**: \\1\n *\n * **description**: matches whatever was matched by capturing group 1 (e.g. the starting string character)\n *\n * @param file a file object\n * @returns a list of translation keys found in `file`.\n */\n function extractMethodMatches (file: SimpleFile): I18NItemWithBounding[] {\n const methodRegExp = /(?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\\s*?([\"'`])((?:[^\\\\]|\\\\.)*?)\\1/g;\n return [ ...getMatches(file, methodRegExp, 2) ];\n}\n\nfunction extractComponentMatches (file: SimpleFile): I18NItemWithBounding[] {\n const componentRegExp = /(?:(?:<|h\\()(?:i18n|Translation))(?:.|\\n)*?(?:\\s(?:(?:key)?)path(?:=|: )(\"|'))((?:[^\\\\]|\\\\.)*?)\\1/gi;\n return [ ...getMatches(file, componentRegExp, 2) ];\n}\n\nfunction extractDirectiveMatches (file: SimpleFile): I18NItemWithBounding[] {\n const directiveRegExp = /\\bv-t(?:\\.[\\w-]+)?=\"'((?:[^\\\\]|\\\\.)*?)'\"/g;\n return [ ...getMatches(file, directiveRegExp) ];\n}\n\nexport function extractI18NItemsFromVueFiles (sourceFiles: SimpleFile[]): I18NItemWithBounding[] {\n return sourceFiles.reduce((accumulator, file) => {\n const methodMatches = extractMethodMatches(file);\n const componentMatches = extractComponentMatches(file);\n const directiveMatches = extractDirectiveMatches(file);\n return [\n ...accumulator,\n ...methodMatches,\n ...componentMatches,\n ...directiveMatches,\n ];\n }, [] as I18NItemWithBounding[]);\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parseVueFiles (vueFiles: string): I18NItemWithBounding[] {\n return extractI18NItemsFromVueFiles(readVueFiles(vueFiles));\n}\n","import path from 'path';\nimport fs from 'fs';\nimport glob from 'glob';\nimport Dot from 'dot-object';\nimport yaml from 'js-yaml';\nimport isValidGlob from 'is-valid-glob';\nimport { SimpleFile, I18NLanguage, I18NItem } from '../types';\n\nexport function readLanguageFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`languageFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('languageFiles glob has no files.');\n }\n\n return targetFiles.map(f => {\n const langPath = path.resolve(process.cwd(), f);\n\n const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase();\n const isJSON = extension === '.json';\n const isYAML = extension === '.yaml' || extension === '.yml';\n\n let langObj;\n if (isJSON) {\n langObj = JSON.parse(fs.readFileSync(langPath, 'utf8'));\n } else if (isYAML) {\n langObj = yaml.load(fs.readFileSync(langPath, 'utf8'));\n } else {\n langObj = eval(fs.readFileSync(langPath, 'utf8'));\n }\n\n const fileName = f.replace(process.cwd(), '.');\n\n return { path: f, fileName, content: JSON.stringify(langObj) };\n });\n}\n\nexport function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[], dot: DotObject.Dot = Dot): I18NLanguage {\n return languageFiles.reduce((accumulator, file) => {\n const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.'));\n\n if (!accumulator[language]) {\n accumulator[language] = [];\n }\n\n const flattenedObject = dot.dot(JSON.parse(file.content));\n Object.keys(flattenedObject).forEach((key) => {\n accumulator[language].push({\n path: key,\n file: file.fileName,\n });\n });\n\n return accumulator;\n }, {});\n}\n\nexport function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = '', missingTranslationString = ''): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n missingKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language) || !item.language) {\n const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));\n dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n unusedKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language)) {\n dot.delete(item.path, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nfunction writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2);\n\n if (fileExtension === 'json') {\n fs.writeFileSync(filePath, stringifiedContent);\n } else if (fileExtension === 'js') {\n const jsFile = `module.exports = ${stringifiedContent}; \\n`;\n fs.writeFileSync(filePath, jsFile);\n } else if (fileExtension === 'yaml' || fileExtension === 'yml') {\n const yamlFile = yaml.dump(newLanguageFileContent);\n fs.writeFileSync(filePath, yamlFile);\n } else {\n throw new Error(`Language filetype of ${fileExtension} not supported.`)\n }\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parselanguageFiles (languageFiles: string, dot: DotObject.Dot = Dot): I18NLanguage {\n return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot);\n}\n","import fs from 'fs';\nimport { DetectionType, I18NItem, I18NItemWithBounding, I18NLanguage, I18NReport } from '../types';\n\nfunction stripBounding (item: I18NItemWithBounding): I18NItem {\n return {\n path: item.path,\n file: item.file,\n line: item.line,\n }\n}\n\nfunction mightBeDynamic (item: I18NItemWithBounding): boolean {\n return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g);\n}\n\n// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off.\nexport function extractI18NReport (vueItems: I18NItemWithBounding[], languageFiles: I18NLanguage, detect: DetectionType[]): I18NReport {\n const missingKeys: I18NItem[] = [];\n const unusedKeys: I18NItem[] = [];\n const maybeDynamicKeys: I18NItem[] = [];\n\n if (detect.includes(DetectionType.Dynamic)) {\n maybeDynamicKeys. push( ...vueItems\n .filter(vueItem => mightBeDynamic(vueItem))\n .map(vueItem => stripBounding(vueItem)));\n }\n\n Object.keys(languageFiles).forEach(language => {\n const languageItems = languageFiles[language];\n\n if (detect.includes(DetectionType.Missing)) {\n const missingKeysInLanguage = vueItems\n .filter(vueItem => !mightBeDynamic(vueItem))\n .filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path))\n .map(vueItem => ({ ...stripBounding(vueItem), language }));\n\n missingKeys.push(...missingKeysInLanguage);\n }\n\n if (detect.includes(DetectionType.Unused)) {\n const unusedKeysInLanguage = languageItems\n .filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.')))\n .map(languageItem => ({ ...languageItem, language }));\n\n unusedKeys.push(...unusedKeysInLanguage);\n }\n });\n\n return {\n missingKeys,\n unusedKeys,\n maybeDynamicKeys,\n };\n}\n\nexport async function writeReportToFile (report: I18NReport, writePath: string): Promise {\n const reportString = JSON.stringify(report);\n return new Promise((resolve, reject) => {\n fs.writeFile(\n writePath,\n reportString,\n (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n },\n );\n });\n}\n\n","import path from 'path';\nimport { ReportOptions, I18NReport, DetectionType } from '../types';\nimport { readVueFiles, extractI18NItemsFromVueFiles } from './vue-files';\nimport { readLanguageFiles, extractI18NLanguageFromLanguageFiles, removeUnusedFromLanguageFiles, writeMissingToLanguageFiles } from './language-files';\nimport { extractI18NReport, writeReportToFile } from './report';\nimport Dot from 'dot-object';\n\nexport async function createI18NReport (options: ReportOptions): Promise {\n const {\n vueFiles: vueFilesGlob,\n languageFiles: languageFilesGlob,\n output,\n add,\n remove,\n exclude = [],\n ci,\n separator,\n noEmptyTranslation = '',\n missingTranslationString = '',\n detect = [DetectionType.Missing, DetectionType.Unused, DetectionType.Dynamic]\n } = options;\n\n if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');\n if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.');\n\n let issuesToDetect = Array.isArray(detect) ? detect : [detect];\n const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(DetectionType).includes(item));\n if (invalidDetectOptions.length) {\n throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`);\n }\n\n const dot = typeof separator === 'string' ? new Dot(separator) : Dot;\n const vueFiles = readVueFiles(path.resolve(process.cwd(), vueFilesGlob));\n const languageFiles = readLanguageFiles(path.resolve(process.cwd(), languageFilesGlob));\n\n const I18NItems = extractI18NItemsFromVueFiles(vueFiles);\n const I18NLanguage = extractI18NLanguageFromLanguageFiles(languageFiles, dot);\n\n const report = extractI18NReport(I18NItems, I18NLanguage, issuesToDetect);\n\n report.unusedKeys = report.unusedKeys.filter(key =>\n !exclude.filter(excluded => key.path.startsWith(excluded)).length)\n\n if (report.missingKeys.length) console.info('\\nMissing Keys'), console.table(report.missingKeys);\n if (report.unusedKeys.length) console.info('\\nUnused Keys'), console.table(report.unusedKeys);\n if (report.maybeDynamicKeys.length) console.warn('\\nSuspected Dynamic Keys Found\\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys);\n\n if (output) {\n await writeReportToFile(report, path.resolve(process.cwd(), output));\n console.info(`\\nThe report has been has been saved to ${output}`);\n }\n\n if (remove && report.unusedKeys.length) {\n removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot);\n console.info('\\nThe unused keys have been removed from your language files.');\n }\n\n if (add && report.missingKeys.length) {\n writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString);\n console.info('\\nThe missing keys have been added to your language files.');\n }\n\n if (ci && report.missingKeys.length) {\n throw new Error(`${report.missingKeys.length} missing keys found.`);\n }\n\n if (ci && report.unusedKeys.length) {\n throw new Error(`${report.unusedKeys.length} unused keys found.`);\n }\n\n return report;\n}\n\nexport * from './vue-files';\nexport * from './language-files';\nexport * from './report';\n","export * from './config-file';\nexport * from './create-report';\nexport * from './types';\n\nprocess.on('uncaughtException', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n"],"names":["vueFiles","languageFiles","exclude","output","add","remove","ci","separator","noEmptyTranslation","missingTranslationString","initCommand","fs","writeFileSync","path","resolve","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","cac","parse","argv","run","options","pathToConfigFile","configOptions","require","console","info","Array","isArray","DetectionType","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","f","fileName","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","pathAtIndex","indexOf","previousCharacter","charAt","nextCharacter","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","parseVueFiles","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","yaml","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","languageFile","languageFileContent","item","includes","addDefaultTranslation","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","filePath","stringifiedContent","jsFile","yamlFile","dump","parselanguageFiles","stripBounding","mightBeDynamic","extractI18NReport","vueItems","detect","maybeDynamicKeys","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","writeReportToFile","report","writePath","reportString","Promise","reject","writeFile","err","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","exit"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"vue-i18n-extract.umd.js","sources":["../src/config-file/vue-i18n-extract.config.ts","../src/config-file/index.ts","../src/types.ts","../src/create-report/vue-files.ts","../src/create-report/language-files.ts","../src/create-report/report.ts","../src/create-report/index.ts","../src/index.ts"],"sourcesContent":["export default {\n // Options documented in vue-i18n-extract readme.\n vueFiles: './src/**/*.?(js|vue)',\n languageFiles: './lang/**/*.?(json|yaml|yml|js)',\n exclude: [],\n output: false,\n add: false,\n remove: false,\n ci: false,\n separator: '.',\n noEmptyTranslation: '',\n missingTranslationString: '',\n};\n","import cac from 'cac';\nimport fs from 'fs';\nimport path from 'path';\nimport defaultConfig from './vue-i18n-extract.config';\n\nexport function initCommand(): void {\n fs.writeFileSync(\n path.resolve(process.cwd(), './vue-i18n-extract.config.js'),\n `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`,\n );\n}\n\nexport function resolveConfig (): Record {\n const argvOptions = cac().parse(process.argv, { run: false }).options;\n\n let options;\n\n try {\n const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const configOptions = require(pathToConfigFile);\n\n console.info(`\\nUsing config file found at ${pathToConfigFile}`);\n\n options = {\n ...configOptions,\n ...argvOptions\n };\n } catch {\n options = argvOptions;\n }\n\n options.exclude = Array.isArray(options.exclude) ? options.exclude : [options.exclude];\n\n return options;\n}\n","export type ReportOptions = {\n vueFiles: string;\n languageFiles: string;\n output?: string;\n exclude?: string[];\n add?: boolean;\n remove?: boolean;\n ci?: boolean;\n separator?: string;\n noEmptyTranslation?: string;\n missingTranslationString?: string;\n detect?: DetectionType[];\n}\n\nexport enum DetectionType {\n Missing = \"missing\",\n Unused = \"unused\",\n Dynamic = \"dynamic\"\n}\n\nexport type SimpleFile = {\n fileName: string;\n path: string;\n content: string;\n}\n\nexport type I18NItem = {\n line?: number;\n path: string;\n file?: string;\n language?: string;\n}\n\nexport type I18NItemWithBounding = I18NItem & {\n previousCharacter: string;\n nextCharacter: string;\n}\n\nexport type I18NLanguage = {\n [language: string]: I18NItem[];\n}\n\nexport type I18NReport = {\n missingKeys: I18NItem[];\n unusedKeys: I18NItem[];\n maybeDynamicKeys: I18NItem[];\n}\n","import { SimpleFile, I18NItemWithBounding } from '../types';\nimport isValidGlob from 'is-valid-glob';\nimport glob from 'glob';\nimport fs from 'fs';\n\nexport function readVueFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`vueFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('vueFiles glob has no files.');\n }\n\n return targetFiles.map((f) => {\n const fileName = f.replace(process.cwd(), '.');\n return { fileName, path: f, content: fs.readFileSync(f, 'utf8') };\n });\n}\n\nfunction* getMatches (file: SimpleFile, regExp: RegExp, captureGroup = 1): IterableIterator {\n while (true) {\n const match = regExp.exec(file.content);\n if (match === null) {\n break;\n }\n const path = match[captureGroup];\n\n const pathAtIndex = file.content.indexOf(path);\n const previousCharacter = file.content.charAt(pathAtIndex - 1);\n const nextCharacter = file.content.charAt(pathAtIndex + path.length);\n\n const line = (file.content.substring(0, match.index).match(/\\n/g) || []).length + 1;\n yield {\n path,\n previousCharacter,\n nextCharacter,\n file: file.fileName,\n line,\n };\n }\n}\n\n/**\n * Extracts translation keys from methods such as `$t` and `$tc`.\n *\n * - **regexp pattern**: (?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\n *\n * **description**: Matches the sequence t(, tc( or tm(, optionally with either “$”, SPACE, “.”, “:”, “\"”, “'”,\n * “`”, \"+\", \"(\", \"[\" or \"{\" in front of it.\n *\n * - **regexp pattern**: ([\"'`])\n *\n * **description**: 1. capturing group. Matches either “\"”, “'”, or “`”.\n *\n * - **regexp pattern**: ((?:[^\\\\]|\\\\.)*?)\n *\n * **description**: 2. capturing group. Matches anything except a backslash\n * *or* matches any backslash followed by any character (e.g. “\\\"”, “\\`”, “\\t”, etc.)\n *\n * - **regexp pattern**: \\1\n *\n * **description**: matches whatever was matched by capturing group 1 (e.g. the starting string character)\n *\n * @param file a file object\n * @returns a list of translation keys found in `file`.\n */\n function extractMethodMatches (file: SimpleFile): I18NItemWithBounding[] {\n const methodRegExp = /(?:[$\\s.:\"'`+\\(\\[\\{]t[cm]?)\\(\\s*?([\"'`])((?:[^\\\\]|\\\\.)*?)\\1/g;\n return [ ...getMatches(file, methodRegExp, 2) ];\n}\n\nfunction extractComponentMatches (file: SimpleFile): I18NItemWithBounding[] {\n const componentRegExp = /(?:(?:<|h\\()(?:i18n|Translation))(?:.|\\n)*?(?:\\s(?:(?:key)?)path(?:=|: )(\"|'))((?:[^\\\\]|\\\\.)*?)\\1/gi;\n return [ ...getMatches(file, componentRegExp, 2) ];\n}\n\nfunction extractDirectiveMatches (file: SimpleFile): I18NItemWithBounding[] {\n const directiveRegExp = /\\bv-t(?:\\.[\\w-]+)?=\"'((?:[^\\\\]|\\\\.)*?)'\"/g;\n return [ ...getMatches(file, directiveRegExp) ];\n}\n\nexport function extractI18NItemsFromVueFiles (sourceFiles: SimpleFile[]): I18NItemWithBounding[] {\n return sourceFiles.reduce((accumulator, file) => {\n const methodMatches = extractMethodMatches(file);\n const componentMatches = extractComponentMatches(file);\n const directiveMatches = extractDirectiveMatches(file);\n return [\n ...accumulator,\n ...methodMatches,\n ...componentMatches,\n ...directiveMatches,\n ];\n }, [] as I18NItemWithBounding[]);\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parseVueFiles (vueFiles: string): I18NItemWithBounding[] {\n return extractI18NItemsFromVueFiles(readVueFiles(vueFiles));\n}\n","import path from 'path';\nimport fs from 'fs';\nimport glob from 'glob';\nimport Dot from 'dot-object';\nimport yaml from 'js-yaml';\nimport isValidGlob from 'is-valid-glob';\nimport { SimpleFile, I18NLanguage, I18NItem } from '../types';\n\nexport function readLanguageFiles (src: string): SimpleFile[] {\n // Replace backslash path segments to make the path work with the glob package.\n // https://github.com/Spittal/vue-i18n-extract/issues/159\n const normalizedSrc = src.replace(/\\\\/g, '/');\n if (!isValidGlob(normalizedSrc)) {\n throw new Error(`languageFiles isn't a valid glob pattern.`);\n }\n\n const targetFiles = glob.sync(normalizedSrc);\n\n if (targetFiles.length === 0) {\n throw new Error('languageFiles glob has no files.');\n }\n\n return targetFiles.map(f => {\n const langPath = path.resolve(process.cwd(), f);\n\n const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase();\n const isJSON = extension === '.json';\n const isYAML = extension === '.yaml' || extension === '.yml';\n\n let langObj;\n if (isJSON) {\n langObj = JSON.parse(fs.readFileSync(langPath, 'utf8'));\n } else if (isYAML) {\n langObj = yaml.load(fs.readFileSync(langPath, 'utf8'));\n } else {\n langObj = eval(fs.readFileSync(langPath, 'utf8'));\n }\n\n const fileName = f.replace(process.cwd(), '.');\n\n return { path: f, fileName, content: JSON.stringify(langObj) };\n });\n}\n\nexport function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[], dot: DotObject.Dot = Dot): I18NLanguage {\n return languageFiles.reduce((accumulator, file) => {\n const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.'));\n\n if (!accumulator[language]) {\n accumulator[language] = [];\n }\n\n const flattenedObject = dot.dot(JSON.parse(file.content));\n Object.keys(flattenedObject).forEach((key) => {\n accumulator[language].push({\n path: key,\n file: file.fileName,\n });\n });\n\n return accumulator;\n }, {});\n}\n\nexport function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = '', missingTranslationString = ''): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n missingKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language) || !item.language) {\n const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));\n let value: string | null = null;\n if (addDefaultTranslation) {\n value = item.path;\n } else if (missingTranslationString === 'null') {\n value = null;\n } else if (missingTranslationString.includes('{{t}}')) {\n value = missingTranslationString.replace('{{t}}', item.path);\n } else {\n value = missingTranslationString;\n }\n dot.str(item.path, value, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot): void {\n parsedLanguageFiles.forEach(languageFile => {\n const languageFileContent = JSON.parse(languageFile.content);\n\n unusedKeys.forEach(item => {\n if (item.language && languageFile.fileName.includes(item.language)) {\n dot.delete(item.path, languageFileContent);\n }\n });\n\n writeLanguageFile(languageFile, languageFileContent);\n });\n}\n\nfunction writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2);\n\n if (fileExtension === 'json') {\n fs.writeFileSync(filePath, stringifiedContent);\n } else if (fileExtension === 'js') {\n const jsFile = `module.exports = ${stringifiedContent}; \\n`;\n fs.writeFileSync(filePath, jsFile);\n } else if (fileExtension === 'yaml' || fileExtension === 'yml') {\n const yamlFile = yaml.dump(newLanguageFileContent);\n fs.writeFileSync(filePath, yamlFile);\n } else {\n throw new Error(`Language filetype of ${fileExtension} not supported.`)\n }\n}\n\n// This is a convenience function for users implementing in their own projects, and isn't used internally\nexport function parselanguageFiles (languageFiles: string, dot: DotObject.Dot = Dot): I18NLanguage {\n return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot);\n}\n","import fs from 'fs';\nimport { DetectionType, I18NItem, I18NItemWithBounding, I18NLanguage, I18NReport } from '../types';\n\nfunction stripBounding (item: I18NItemWithBounding): I18NItem {\n return {\n path: item.path,\n file: item.file,\n line: item.line,\n }\n}\n\nfunction mightBeDynamic (item: I18NItemWithBounding): boolean {\n return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g);\n}\n\n// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off.\nexport function extractI18NReport (vueItems: I18NItemWithBounding[], languageFiles: I18NLanguage, detect: DetectionType[]): I18NReport {\n const missingKeys: I18NItem[] = [];\n const unusedKeys: I18NItem[] = [];\n const maybeDynamicKeys: I18NItem[] = [];\n\n if (detect.includes(DetectionType.Dynamic)) {\n maybeDynamicKeys. push( ...vueItems\n .filter(vueItem => mightBeDynamic(vueItem))\n .map(vueItem => stripBounding(vueItem)));\n }\n\n Object.keys(languageFiles).forEach(language => {\n const languageItems = languageFiles[language];\n\n if (detect.includes(DetectionType.Missing)) {\n const missingKeysInLanguage = vueItems\n .filter(vueItem => !mightBeDynamic(vueItem))\n .filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path))\n .map(vueItem => ({ ...stripBounding(vueItem), language }));\n\n missingKeys.push(...missingKeysInLanguage);\n }\n\n if (detect.includes(DetectionType.Unused)) {\n const unusedKeysInLanguage = languageItems\n .filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.')))\n .map(languageItem => ({ ...languageItem, language }));\n\n unusedKeys.push(...unusedKeysInLanguage);\n }\n });\n\n return {\n missingKeys,\n unusedKeys,\n maybeDynamicKeys,\n };\n}\n\nexport async function writeReportToFile (report: I18NReport, writePath: string): Promise {\n const reportString = JSON.stringify(report);\n return new Promise((resolve, reject) => {\n fs.writeFile(\n writePath,\n reportString,\n (err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n },\n );\n });\n}\n\n","import path from 'path';\nimport { ReportOptions, I18NReport, DetectionType } from '../types';\nimport { readVueFiles, extractI18NItemsFromVueFiles } from './vue-files';\nimport { readLanguageFiles, extractI18NLanguageFromLanguageFiles, removeUnusedFromLanguageFiles, writeMissingToLanguageFiles } from './language-files';\nimport { extractI18NReport, writeReportToFile } from './report';\nimport Dot from 'dot-object';\n\nexport async function createI18NReport (options: ReportOptions): Promise {\n const {\n vueFiles: vueFilesGlob,\n languageFiles: languageFilesGlob,\n output,\n add,\n remove,\n exclude = [],\n ci,\n separator,\n noEmptyTranslation = '',\n missingTranslationString = '',\n detect = [DetectionType.Missing, DetectionType.Unused, DetectionType.Dynamic]\n } = options;\n\n if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');\n if (!languageFilesGlob) throw new Error('Required configuration languageFiles is missing.');\n\n let issuesToDetect = Array.isArray(detect) ? detect : [detect];\n const invalidDetectOptions = issuesToDetect.filter(item => !Object.values(DetectionType).includes(item));\n if (invalidDetectOptions.length) {\n throw new Error(`Invalid 'detect' value(s): ${invalidDetectOptions}`);\n }\n\n const dot = typeof separator === 'string' ? new Dot(separator) : Dot;\n const vueFiles = readVueFiles(path.resolve(process.cwd(), vueFilesGlob));\n const languageFiles = readLanguageFiles(path.resolve(process.cwd(), languageFilesGlob));\n\n const I18NItems = extractI18NItemsFromVueFiles(vueFiles);\n const I18NLanguage = extractI18NLanguageFromLanguageFiles(languageFiles, dot);\n\n const report = extractI18NReport(I18NItems, I18NLanguage, issuesToDetect);\n\n report.unusedKeys = report.unusedKeys.filter(key =>\n !exclude.filter(excluded => key.path.startsWith(excluded)).length)\n\n if (report.missingKeys.length) console.info('\\nMissing Keys'), console.table(report.missingKeys);\n if (report.unusedKeys.length) console.info('\\nUnused Keys'), console.table(report.unusedKeys);\n if (report.maybeDynamicKeys.length) console.warn('\\nSuspected Dynamic Keys Found\\nvue-i18n-extract does not compile Vue templates and therefore can not infer the correct key for the following keys.'), console.table(report.maybeDynamicKeys);\n\n if (output) {\n await writeReportToFile(report, path.resolve(process.cwd(), output));\n console.info(`\\nThe report has been has been saved to ${output}`);\n }\n\n if (remove && report.unusedKeys.length) {\n removeUnusedFromLanguageFiles(languageFiles, report.unusedKeys, dot);\n console.info('\\nThe unused keys have been removed from your language files.');\n }\n\n if (add && report.missingKeys.length) {\n writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString);\n console.info('\\nThe missing keys have been added to your language files.');\n }\n\n if (ci && report.missingKeys.length) {\n throw new Error(`${report.missingKeys.length} missing keys found.`);\n }\n\n if (ci && report.unusedKeys.length) {\n throw new Error(`${report.unusedKeys.length} unused keys found.`);\n }\n\n return report;\n}\n\nexport * from './vue-files';\nexport * from './language-files';\nexport * from './report';\n","export * from './config-file';\nexport * from './create-report';\nexport * from './types';\n\nprocess.on('uncaughtException', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (err) => {\n console.error('[vue-i18n-extract]', err);\n process.exit(1);\n});\n"],"names":["vueFiles","languageFiles","exclude","output","add","remove","ci","separator","noEmptyTranslation","missingTranslationString","initCommand","fs","writeFileSync","path","resolve","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","cac","parse","argv","run","options","pathToConfigFile","configOptions","require","console","info","Array","isArray","DetectionType","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","f","fileName","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","pathAtIndex","indexOf","previousCharacter","charAt","nextCharacter","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","parseVueFiles","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","yaml","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","languageFile","languageFileContent","item","includes","addDefaultTranslation","value","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","filePath","stringifiedContent","jsFile","yamlFile","dump","parselanguageFiles","stripBounding","mightBeDynamic","extractI18NReport","vueItems","detect","maybeDynamicKeys","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","writeReportToFile","report","writePath","reportString","Promise","reject","writeFile","err","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","exit"],"mappings":";;;;;;;;;;;;;;;AAAA,sBAAe;EACb;EACAA,EAAAA,QAAQ,EAAE,sBAAsB;EAChCC,EAAAA,aAAa,EAAE,iCAAiC;EAChDC,EAAAA,OAAO,EAAE,EAAE;EACXC,EAAAA,MAAM,EAAE,KAAK;EACbC,EAAAA,GAAG,EAAE,KAAK;EACVC,EAAAA,MAAM,EAAE,KAAK;EACbC,EAAAA,EAAE,EAAE,KAAK;EACTC,EAAAA,SAAS,EAAE,GAAG;EACdC,EAAAA,kBAAkB,EAAE,EAAE;EACtBC,EAAAA,wBAAwB,EAAE,EAAA;GAC3B;;WCPeC,WAAWA,GAAA;EACzBC,EAAAA,sBAAE,CAACC,aAAa,CACdC,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAE,8BAA8B,CAAC,EAC3D,CAAoBC,iBAAAA,EAAAA,IAAI,CAACC,SAAS,CAACC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,CAAE,CAC7D,CAAA;EACH,CAAA;WAEgBC,aAAaA,GAAA;IAC3B,MAAMC,WAAW,GAAGC,uBAAG,EAAE,CAACC,KAAK,CAACR,OAAO,CAACS,IAAI,EAAE;EAAEC,IAAAA,GAAG,EAAE,KAAA;KAAO,CAAC,CAACC,OAAO,CAAA;EAErE,EAAA,IAAIA,OAAO,CAAA;IAEX,IAAI;EACF,IAAA,MAAMC,gBAAgB,GAAGd,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAA;EACpF;EACA,IAAA,MAAMY,aAAa,GAAGC,OAAO,CAACF,gBAAgB,CAAC,CAAA;EAE/CG,IAAAA,OAAO,CAACC,IAAI,CAAC,CAAgCJ,6BAAAA,EAAAA,gBAAgB,EAAE,CAAC,CAAA;EAEhED,IAAAA,OAAO,GAAG;EACR,MAAA,GAAGE,aAAa;QAChB,GAAGP,WAAAA;OACJ,CAAA;EACF,GAAA,CAAC,MAAM;EACNK,IAAAA,OAAO,GAAGL,WAAW,CAAA;EACtB,GAAA;IAEDK,OAAO,CAACxB,OAAO,GAAG8B,KAAK,CAACC,OAAO,CAACP,OAAO,CAACxB,OAAO,CAAC,GAAGwB,OAAO,CAACxB,OAAO,GAAG,CAACwB,OAAO,CAACxB,OAAO,CAAC,CAAA;EAEtF,EAAA,OAAOwB,OAAO,CAAA;EAChB;;ACrBYQ,iCAIX;EAJD,CAAA,UAAYA,aAAa,EAAA;EACvBA,EAAAA,aAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;EACnBA,EAAAA,aAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;EACjBA,EAAAA,aAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;EACrB,CAAC,EAJWA,qBAAa,KAAbA,qBAAa,GAIxB,EAAA,CAAA,CAAA;;ECbK,SAAUC,YAAYA,CAAEC,GAAW,EAAA;EACvC;EACA;IACA,MAAMC,aAAa,GAAGD,GAAG,CAACE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;EAC7C,EAAA,IAAI,CAACC,+BAAW,CAACF,aAAa,CAAC,EAAE;EAC/B,IAAA,MAAM,IAAIG,KAAK,CAAC,CAAA,oCAAA,CAAsC,CAAC,CAAA;EACxD,GAAA;EAED,EAAA,MAAMC,WAAW,GAAGC,wBAAI,CAACC,IAAI,CAACN,aAAa,CAAC,CAAA;EAE5C,EAAA,IAAII,WAAW,CAACG,MAAM,KAAK,CAAC,EAAE;EAC5B,IAAA,MAAM,IAAIJ,KAAK,CAAC,6BAA6B,CAAC,CAAA;EAC/C,GAAA;EAED,EAAA,OAAOC,WAAW,CAACI,GAAG,CAAEC,CAAC,IAAI;EAC3B,IAAA,MAAMC,QAAQ,GAAGD,CAAC,CAACR,OAAO,CAACvB,OAAO,CAACC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;MAC9C,OAAO;QAAE+B,QAAQ;EAAElC,MAAAA,IAAI,EAAEiC,CAAC;EAAEE,MAAAA,OAAO,EAAErC,sBAAE,CAACsC,YAAY,CAACH,CAAC,EAAE,MAAM,CAAA;OAAG,CAAA;EACnE,GAAC,CAAC,CAAA;EACJ,CAAA;EAEA,UAAUI,UAAUA,CAAEC,IAAgB,EAAEC,MAAc,EAAEC,YAAY,GAAG,CAAC,EAAA;EACtE,EAAA,OAAO,IAAI,EAAE;MACX,MAAMC,KAAK,GAAGF,MAAM,CAACG,IAAI,CAACJ,IAAI,CAACH,OAAO,CAAC,CAAA;MACvC,IAAIM,KAAK,KAAK,IAAI,EAAE;EAClB,MAAA,MAAA;EACD,KAAA;EACD,IAAA,MAAMzC,IAAI,GAAGyC,KAAK,CAACD,YAAY,CAAC,CAAA;MAEhC,MAAMG,WAAW,GAAGL,IAAI,CAACH,OAAO,CAACS,OAAO,CAAC5C,IAAI,CAAC,CAAA;MAC9C,MAAM6C,iBAAiB,GAAGP,IAAI,CAACH,OAAO,CAACW,MAAM,CAACH,WAAW,GAAG,CAAC,CAAC,CAAA;EAC9D,IAAA,MAAMI,aAAa,GAAGT,IAAI,CAACH,OAAO,CAACW,MAAM,CAACH,WAAW,GAAG3C,IAAI,CAAC+B,MAAM,CAAC,CAAA;MAEpE,MAAMiB,IAAI,GAAG,CAACV,IAAI,CAACH,OAAO,CAACc,SAAS,CAAC,CAAC,EAAER,KAAK,CAACS,KAAK,CAAC,CAACT,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAEV,MAAM,GAAG,CAAC,CAAA;MACnF,MAAM;QACJ/B,IAAI;QACJ6C,iBAAiB;QACjBE,aAAa;QACbT,IAAI,EAAEA,IAAI,CAACJ,QAAQ;EACnBc,MAAAA,IAAAA;OACD,CAAA;EACF,GAAA;EACH,CAAA;EAEA;;;;;;;;;;;;;;;;;;;;;;;EAuBG;EACF,SAASG,oBAAoBA,CAAEb,IAAgB,EAAA;IAC9C,MAAMc,YAAY,GAAG,8DAA8D,CAAA;IACnF,OAAO,CAAE,GAAGf,UAAU,CAACC,IAAI,EAAEc,YAAY,EAAE,CAAC,CAAC,CAAE,CAAA;EACjD,CAAA;EAEA,SAASC,uBAAuBA,CAAEf,IAAgB,EAAA;IAChD,MAAMgB,eAAe,GAAG,qGAAqG,CAAA;IAC7H,OAAO,CAAE,GAAGjB,UAAU,CAACC,IAAI,EAAEgB,eAAe,EAAE,CAAC,CAAC,CAAE,CAAA;EACpD,CAAA;EAEA,SAASC,uBAAuBA,CAAEjB,IAAgB,EAAA;IAChD,MAAMkB,eAAe,GAAG,2CAA2C,CAAA;IACnE,OAAO,CAAE,GAAGnB,UAAU,CAACC,IAAI,EAAEkB,eAAe,CAAC,CAAE,CAAA;EACjD,CAAA;EAEM,SAAUC,4BAA4BA,CAAEC,WAAyB,EAAA;IACrE,OAAOA,WAAW,CAACC,MAAM,CAAC,CAACC,WAAW,EAAEtB,IAAI,KAAI;EAC9C,IAAA,MAAMuB,aAAa,GAAGV,oBAAoB,CAACb,IAAI,CAAC,CAAA;EAChD,IAAA,MAAMwB,gBAAgB,GAAGT,uBAAuB,CAACf,IAAI,CAAC,CAAA;EACtD,IAAA,MAAMyB,gBAAgB,GAAGR,uBAAuB,CAACjB,IAAI,CAAC,CAAA;EACtD,IAAA,OAAO,CACL,GAAGsB,WAAW,EACd,GAAGC,aAAa,EAChB,GAAGC,gBAAgB,EACnB,GAAGC,gBAAgB,CACpB,CAAA;KACF,EAAE,EAA4B,CAAC,CAAA;EAClC,CAAA;EAEA;EACM,SAAUC,aAAaA,CAAE7E,QAAgB,EAAA;EAC7C,EAAA,OAAOsE,4BAA4B,CAACnC,YAAY,CAACnC,QAAQ,CAAC,CAAC,CAAA;EAC7D;;EChGM,SAAU8E,iBAAiBA,CAAE1C,GAAW,EAAA;EAC5C;EACA;IACA,MAAMC,aAAa,GAAGD,GAAG,CAACE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;EAC7C,EAAA,IAAI,CAACC,+BAAW,CAACF,aAAa,CAAC,EAAE;EAC/B,IAAA,MAAM,IAAIG,KAAK,CAAC,CAAA,yCAAA,CAA2C,CAAC,CAAA;EAC7D,GAAA;EAED,EAAA,MAAMC,WAAW,GAAGC,wBAAI,CAACC,IAAI,CAACN,aAAa,CAAC,CAAA;EAE5C,EAAA,IAAII,WAAW,CAACG,MAAM,KAAK,CAAC,EAAE;EAC5B,IAAA,MAAM,IAAIJ,KAAK,CAAC,kCAAkC,CAAC,CAAA;EACpD,GAAA;EAED,EAAA,OAAOC,WAAW,CAACI,GAAG,CAACC,CAAC,IAAG;EACzB,IAAA,MAAMiC,QAAQ,GAAGlE,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAE8B,CAAC,CAAC,CAAA;EAE/C,IAAA,MAAMkC,SAAS,GAAGD,QAAQ,CAACjB,SAAS,CAACiB,QAAQ,CAACE,WAAW,CAAC,GAAG,CAAC,CAAC,CAACC,WAAW,EAAE,CAAA;EAC7E,IAAA,MAAMC,MAAM,GAAGH,SAAS,KAAK,OAAO,CAAA;MACpC,MAAMI,MAAM,GAAGJ,SAAS,KAAK,OAAO,IAAIA,SAAS,KAAK,MAAM,CAAA;EAE5D,IAAA,IAAIK,OAAO,CAAA;EACX,IAAA,IAAIF,MAAM,EAAE;EACVE,MAAAA,OAAO,GAAGpE,IAAI,CAACM,KAAK,CAACZ,sBAAE,CAACsC,YAAY,CAAC8B,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;OACxD,MAAM,IAAIK,MAAM,EAAE;EACjBC,MAAAA,OAAO,GAAGC,wBAAI,CAACC,IAAI,CAAC5E,sBAAE,CAACsC,YAAY,CAAC8B,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;EACvD,KAAA,MAAM;QACLM,OAAO,GAAGG,IAAI,CAAC7E,sBAAE,CAACsC,YAAY,CAAC8B,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;EAClD,KAAA;EAED,IAAA,MAAMhC,QAAQ,GAAGD,CAAC,CAACR,OAAO,CAACvB,OAAO,CAACC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;MAE9C,OAAO;EAAEH,MAAAA,IAAI,EAAEiC,CAAC;QAAEC,QAAQ;EAAEC,MAAAA,OAAO,EAAE/B,IAAI,CAACC,SAAS,CAACmE,OAAO,CAAA;OAAG,CAAA;EAChE,GAAC,CAAC,CAAA;EACJ,CAAA;WAEgBI,oCAAoCA,CAAExF,aAA2B,EAAEyF,MAAqBC,uBAAG,EAAA;IACzG,OAAO1F,aAAa,CAACuE,MAAM,CAAC,CAACC,WAAW,EAAEtB,IAAI,KAAI;MAChD,MAAMyC,QAAQ,GAAGzC,IAAI,CAACJ,QAAQ,CAACe,SAAS,CAACX,IAAI,CAACJ,QAAQ,CAACkC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE9B,IAAI,CAACJ,QAAQ,CAACkC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;EAE5G,IAAA,IAAI,CAACR,WAAW,CAACmB,QAAQ,CAAC,EAAE;EAC1BnB,MAAAA,WAAW,CAACmB,QAAQ,CAAC,GAAG,EAAE,CAAA;EAC3B,KAAA;EAED,IAAA,MAAMC,eAAe,GAAGH,GAAG,CAACA,GAAG,CAACzE,IAAI,CAACM,KAAK,CAAC4B,IAAI,CAACH,OAAO,CAAC,CAAC,CAAA;MACzD8C,MAAM,CAACC,IAAI,CAACF,eAAe,CAAC,CAACG,OAAO,CAAEC,GAAG,IAAI;EAC3CxB,MAAAA,WAAW,CAACmB,QAAQ,CAAC,CAACM,IAAI,CAAC;EACzBrF,QAAAA,IAAI,EAAEoF,GAAG;UACT9C,IAAI,EAAEA,IAAI,CAACJ,QAAAA;EACZ,OAAA,CAAC,CAAA;EACJ,KAAC,CAAC,CAAA;EAEF,IAAA,OAAO0B,WAAW,CAAA;KACnB,EAAE,EAAE,CAAC,CAAA;EACR,CAAA;WAEgB0B,2BAA2BA,CAAEC,mBAAiC,EAAEC,WAAuB,EAAEX,GAAA,GAAqBC,uBAAG,EAAEnF,kBAAkB,GAAG,EAAE,EAAEC,wBAAwB,GAAG,EAAE,EAAA;EACvL2F,EAAAA,mBAAmB,CAACJ,OAAO,CAACM,YAAY,IAAG;MACzC,MAAMC,mBAAmB,GAAGtF,IAAI,CAACM,KAAK,CAAC+E,YAAY,CAACtD,OAAO,CAAC,CAAA;EAE5DqD,IAAAA,WAAW,CAACL,OAAO,CAACQ,IAAI,IAAG;EACzB,MAAA,IAAIA,IAAI,CAACZ,QAAQ,IAAIU,YAAY,CAACvD,QAAQ,CAAC0D,QAAQ,CAACD,IAAI,CAACZ,QAAQ,CAAC,IAAI,CAACY,IAAI,CAACZ,QAAQ,EAAE;EACpF,QAAA,MAAMc,qBAAqB,GAAIlG,kBAAkB,KAAOA,kBAAkB,KAAK,GAAG,IAAMA,kBAAkB,KAAKgG,IAAI,CAACZ,QAAS,CAAC,CAAA;UAC9H,IAAIe,KAAK,GAAkB,IAAI,CAAA;EAC/B,QAAA,IAAID,qBAAqB,EAAE;YACzBC,KAAK,GAAGH,IAAI,CAAC3F,IAAI,CAAA;EAClB,SAAA,MAAM,IAAIJ,wBAAwB,KAAK,MAAM,EAAE;EAC9CkG,UAAAA,KAAK,GAAG,IAAI,CAAA;WACb,MAAM,IAAIlG,wBAAwB,CAACgG,QAAQ,CAAC,OAAO,CAAC,EAAE;YACrDE,KAAK,GAAGlG,wBAAwB,CAAC6B,OAAO,CAAC,OAAO,EAAEkE,IAAI,CAAC3F,IAAI,CAAC,CAAA;EAC7D,SAAA,MAAM;EACL8F,UAAAA,KAAK,GAAGlG,wBAAwB,CAAA;EACjC,SAAA;UACDiF,GAAG,CAACkB,GAAG,CAACJ,IAAI,CAAC3F,IAAI,EAAE8F,KAAK,EAAEJ,mBAAmB,CAAC,CAAA;EAC/C,OAAA;EACH,KAAC,CAAC,CAAA;EAEFM,IAAAA,iBAAiB,CAACP,YAAY,EAAEC,mBAAmB,CAAC,CAAA;EACtD,GAAC,CAAC,CAAA;EACJ,CAAA;EAEM,SAAUO,6BAA6BA,CAAEV,mBAAiC,EAAEW,UAAsB,EAAErB,MAAqBC,uBAAG,EAAA;EAChIS,EAAAA,mBAAmB,CAACJ,OAAO,CAACM,YAAY,IAAG;MACzC,MAAMC,mBAAmB,GAAGtF,IAAI,CAACM,KAAK,CAAC+E,YAAY,CAACtD,OAAO,CAAC,CAAA;EAE5D+D,IAAAA,UAAU,CAACf,OAAO,CAACQ,IAAI,IAAG;EACxB,MAAA,IAAIA,IAAI,CAACZ,QAAQ,IAAIU,YAAY,CAACvD,QAAQ,CAAC0D,QAAQ,CAACD,IAAI,CAACZ,QAAQ,CAAC,EAAE;UAClEF,GAAG,CAACsB,MAAM,CAACR,IAAI,CAAC3F,IAAI,EAAE0F,mBAAmB,CAAC,CAAA;EAC3C,OAAA;EACH,KAAC,CAAC,CAAA;EAEFM,IAAAA,iBAAiB,CAACP,YAAY,EAAEC,mBAAmB,CAAC,CAAA;EACtD,GAAC,CAAC,CAAA;EACJ,CAAA;EAEA,SAASM,iBAAiBA,CAAEP,YAAwB,EAAEW,sBAA+B,EAAA;EACnF,EAAA,MAAMC,aAAa,GAAGZ,YAAY,CAACvD,QAAQ,CAACe,SAAS,CAACwC,YAAY,CAACvD,QAAQ,CAACkC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;EAC/F,EAAA,MAAMkC,QAAQ,GAAGb,YAAY,CAACzF,IAAI,CAAA;IAClC,MAAMuG,kBAAkB,GAAGnG,IAAI,CAACC,SAAS,CAAC+F,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAE1E,IAAIC,aAAa,KAAK,MAAM,EAAE;EAC5BvG,IAAAA,sBAAE,CAACC,aAAa,CAACuG,QAAQ,EAAEC,kBAAkB,CAAC,CAAA;EAC/C,GAAA,MAAM,IAAIF,aAAa,KAAK,IAAI,EAAE;EACjC,IAAA,MAAMG,MAAM,GAAG,CAAoBD,iBAAAA,EAAAA,kBAAkB,CAAM,IAAA,CAAA,CAAA;EAC3DzG,IAAAA,sBAAE,CAACC,aAAa,CAACuG,QAAQ,EAAEE,MAAM,CAAC,CAAA;KACnC,MAAM,IAAIH,aAAa,KAAK,MAAM,IAAIA,aAAa,KAAK,KAAK,EAAE;EAC9D,IAAA,MAAMI,QAAQ,GAAGhC,wBAAI,CAACiC,IAAI,CAACN,sBAAsB,CAAC,CAAA;EAClDtG,IAAAA,sBAAE,CAACC,aAAa,CAACuG,QAAQ,EAAEG,QAAQ,CAAC,CAAA;EACrC,GAAA,MAAM;EACL,IAAA,MAAM,IAAI9E,KAAK,CAAC,CAAwB0E,qBAAAA,EAAAA,aAAa,iBAAiB,CAAC,CAAA;EACxE,GAAA;EACL,CAAA;EAEA;WACgBM,kBAAkBA,CAAEvH,aAAqB,EAAEyF,MAAqBC,uBAAG,EAAA;IACjF,OAAOF,oCAAoC,CAACX,iBAAiB,CAAC7E,aAAa,CAAC,EAAEyF,GAAG,CAAC,CAAA;EACpF;;ECzHA,SAAS+B,aAAaA,CAAEjB,IAA0B,EAAA;IAChD,OAAO;MACL3F,IAAI,EAAE2F,IAAI,CAAC3F,IAAI;MACfsC,IAAI,EAAEqD,IAAI,CAACrD,IAAI;MACfU,IAAI,EAAE2C,IAAI,CAAC3C,IAAAA;KACZ,CAAA;EACH,CAAA;EAEA,SAAS6D,cAAcA,CAAElB,IAA0B,EAAA;EACjD,EAAA,OAAOA,IAAI,CAAC3F,IAAI,CAAC4F,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAACD,IAAI,CAAC9C,iBAAiB,CAACJ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAACkD,IAAI,CAAC5C,aAAa,CAACN,KAAK,CAAC,IAAI,CAAC,CAAA;EAC7G,CAAA;EAEA;WACgBqE,iBAAiBA,CAAEC,QAAgC,EAAE3H,aAA2B,EAAE4H,MAAuB,EAAA;IACvH,MAAMxB,WAAW,GAAe,EAAE,CAAA;IAClC,MAAMU,UAAU,GAAe,EAAE,CAAA;IACjC,MAAMe,gBAAgB,GAAe,EAAE,CAAA;IAEvC,IAAID,MAAM,CAACpB,QAAQ,CAACvE,qBAAa,CAAC6F,OAAO,CAAC,EAAE;MAC3CD,gBAAgB,CAAE5B,IAAI,CAAE,GAAG0B,QAAQ,CACjCI,MAAM,CAACC,OAAO,IAAIP,cAAc,CAACO,OAAO,CAAC,CAAC,CAC1CpF,GAAG,CAACoF,OAAO,IAAIR,aAAa,CAACQ,OAAO,CAAC,CAAC,CAAC,CAAA;EACxC,GAAA;IAEFnC,MAAM,CAACC,IAAI,CAAC9F,aAAa,CAAC,CAAC+F,OAAO,CAACJ,QAAQ,IAAG;EAC5C,IAAA,MAAMsC,aAAa,GAAGjI,aAAa,CAAC2F,QAAQ,CAAC,CAAA;MAE7C,IAAIiC,MAAM,CAACpB,QAAQ,CAACvE,qBAAa,CAACiG,OAAO,CAAC,EAAE;EAC5C,MAAA,MAAMC,qBAAqB,GAAGR,QAAQ,CACnCI,MAAM,CAACC,OAAO,IAAI,CAACP,cAAc,CAACO,OAAO,CAAC,CAAC,CAC3CD,MAAM,CAACC,OAAO,IAAI,CAACC,aAAa,CAACG,IAAI,CAACC,YAAY,IAAIL,OAAO,CAACpH,IAAI,KAAKyH,YAAY,CAACzH,IAAI,CAAC,CAAC,CAC1FgC,GAAG,CAACoF,OAAO,KAAK;UAAE,GAAGR,aAAa,CAACQ,OAAO,CAAC;EAAErC,QAAAA,QAAAA;EAAU,OAAA,CAAC,CAAC,CAAA;EAE5DS,MAAAA,WAAW,CAACH,IAAI,CAAC,GAAGkC,qBAAqB,CAAC,CAAA;EACzC,KAAA;MAED,IAAIP,MAAM,CAACpB,QAAQ,CAACvE,qBAAa,CAACqG,MAAM,CAAC,EAAE;EAC3C,MAAA,MAAMC,oBAAoB,GAAGN,aAAa,CACvCF,MAAM,CAACM,YAAY,IAAI,CAACV,QAAQ,CAACS,IAAI,CAACJ,OAAO,IAAIK,YAAY,CAACzH,IAAI,KAAKoH,OAAO,CAACpH,IAAI,IAAIyH,YAAY,CAACzH,IAAI,CAAC4H,UAAU,CAACR,OAAO,CAACpH,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CACzIgC,GAAG,CAACyF,YAAY,KAAK;EAAE,QAAA,GAAGA,YAAY;EAAE1C,QAAAA,QAAAA;EAAU,OAAA,CAAC,CAAC,CAAA;EAEvDmB,MAAAA,UAAU,CAACb,IAAI,CAAC,GAAGsC,oBAAoB,CAAC,CAAA;EACvC,KAAA;EACH,GAAC,CAAC,CAAA;IAEF,OAAO;MACLnC,WAAW;MACXU,UAAU;EACVe,IAAAA,gBAAAA;KACD,CAAA;EACH,CAAA;EAEO,eAAeY,iBAAiBA,CAAEC,MAAkB,EAAEC,SAAiB,EAAA;EAC5E,EAAA,MAAMC,YAAY,GAAG5H,IAAI,CAACC,SAAS,CAACyH,MAAM,CAAC,CAAA;EAC3C,EAAA,OAAO,IAAIG,OAAO,CAAC,CAAChI,OAAO,EAAEiI,MAAM,KAAI;MACrCpI,sBAAE,CAACqI,SAAS,CACVJ,SAAS,EACTC,YAAY,EACXI,GAAG,IAAI;EACN,MAAA,IAAIA,GAAG,EAAE;UACPF,MAAM,CAACE,GAAG,CAAC,CAAA;EACX,QAAA,OAAA;EACD,OAAA;EACDnI,MAAAA,OAAO,EAAE,CAAA;EACX,KAAC,CACF,CAAA;EACH,GAAC,CAAC,CAAA;EACJ;;EC/DO,eAAeoI,gBAAgBA,CAAExH,OAAsB,EAAA;IAC5D,MAAM;EACJ1B,IAAAA,QAAQ,EAAEmJ,YAAY;EACtBlJ,IAAAA,aAAa,EAAEmJ,iBAAiB;MAChCjJ,MAAM;MACNC,GAAG;MACHC,MAAM;EACNH,IAAAA,OAAO,GAAG,EAAE;MACZI,EAAE;MACFC,SAAS;EACTC,IAAAA,kBAAkB,GAAG,EAAE;EACvBC,IAAAA,wBAAwB,GAAG,EAAE;EAC7BoH,IAAAA,MAAM,GAAG,CAAC3F,qBAAa,CAACiG,OAAO,EAAEjG,qBAAa,CAACqG,MAAM,EAAErG,qBAAa,CAAC6F,OAAO,CAAA;EAAC,GAC9E,GAAGrG,OAAO,CAAA;IAEX,IAAI,CAACyH,YAAY,EAAE,MAAM,IAAI3G,KAAK,CAAC,6CAA6C,CAAC,CAAA;IACjF,IAAI,CAAC4G,iBAAiB,EAAE,MAAM,IAAI5G,KAAK,CAAC,kDAAkD,CAAC,CAAA;EAE3F,EAAA,IAAI6G,cAAc,GAAGrH,KAAK,CAACC,OAAO,CAAC4F,MAAM,CAAC,GAAGA,MAAM,GAAG,CAACA,MAAM,CAAC,CAAA;IAC9D,MAAMyB,oBAAoB,GAAGD,cAAc,CAACrB,MAAM,CAACxB,IAAI,IAAI,CAACV,MAAM,CAACyD,MAAM,CAACrH,qBAAa,CAAC,CAACuE,QAAQ,CAACD,IAAI,CAAC,CAAC,CAAA;IACxG,IAAI8C,oBAAoB,CAAC1G,MAAM,EAAE;EAC/B,IAAA,MAAM,IAAIJ,KAAK,CAAC,CAA8B8G,2BAAAA,EAAAA,oBAAoB,EAAE,CAAC,CAAA;EACtE,GAAA;EAED,EAAA,MAAM5D,GAAG,GAAG,OAAOnF,SAAS,KAAK,QAAQ,GAAG,IAAIoF,uBAAG,CAACpF,SAAS,CAAC,GAAGoF,uBAAG,CAAA;EACpE,EAAA,MAAM3F,QAAQ,GAAGmC,YAAY,CAACtB,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAEmI,YAAY,CAAC,CAAC,CAAA;EACxE,EAAA,MAAMlJ,aAAa,GAAG6E,iBAAiB,CAACjE,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAEoI,iBAAiB,CAAC,CAAC,CAAA;EAEvF,EAAA,MAAMI,SAAS,GAAGlF,4BAA4B,CAACtE,QAAQ,CAAC,CAAA;EACxD,EAAA,MAAMyJ,YAAY,GAAGhE,oCAAoC,CAACxF,aAAa,EAAEyF,GAAG,CAAC,CAAA;IAE7E,MAAMiD,MAAM,GAAGhB,iBAAiB,CAAC6B,SAAS,EAAEC,YAAY,EAAEJ,cAAc,CAAC,CAAA;EAEzEV,EAAAA,MAAM,CAAC5B,UAAU,GAAG4B,MAAM,CAAC5B,UAAU,CAACiB,MAAM,CAAC/B,GAAG,IAC5C,CAAC/F,OAAO,CAAC8H,MAAM,CAAC0B,QAAQ,IAAIzD,GAAG,CAACpF,IAAI,CAAC4H,UAAU,CAACiB,QAAQ,CAAC,CAAC,CAAC9G,MAAM,CAAC,CAAA;IAEtE,IAAI+F,MAAM,CAACtC,WAAW,CAACzD,MAAM,EAAEd,OAAO,CAACC,IAAI,CAAC,gBAAgB,CAAC,EAAED,OAAO,CAAC6H,KAAK,CAAChB,MAAM,CAACtC,WAAW,CAAC,CAAA;IAChG,IAAIsC,MAAM,CAAC5B,UAAU,CAACnE,MAAM,EAAEd,OAAO,CAACC,IAAI,CAAC,eAAe,CAAC,EAAED,OAAO,CAAC6H,KAAK,CAAChB,MAAM,CAAC5B,UAAU,CAAC,CAAA;IAC7F,IAAI4B,MAAM,CAACb,gBAAgB,CAAClF,MAAM,EAAEd,OAAO,CAAC8H,IAAI,CAAC,qJAAqJ,CAAC,EAAE9H,OAAO,CAAC6H,KAAK,CAAChB,MAAM,CAACb,gBAAgB,CAAC,CAAA;EAE/O,EAAA,IAAI3H,MAAM,EAAE;EACV,IAAA,MAAMuI,iBAAiB,CAACC,MAAM,EAAE9H,wBAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAEb,MAAM,CAAC,CAAC,CAAA;EACpE2B,IAAAA,OAAO,CAACC,IAAI,CAAC,CAA2C5B,wCAAAA,EAAAA,MAAM,EAAE,CAAC,CAAA;EAClE,GAAA;EAED,EAAA,IAAIE,MAAM,IAAIsI,MAAM,CAAC5B,UAAU,CAACnE,MAAM,EAAE;MACtCkE,6BAA6B,CAAC7G,aAAa,EAAE0I,MAAM,CAAC5B,UAAU,EAAErB,GAAG,CAAC,CAAA;EACpE5D,IAAAA,OAAO,CAACC,IAAI,CAAC,+DAA+D,CAAC,CAAA;EAC9E,GAAA;EAED,EAAA,IAAI3B,GAAG,IAAIuI,MAAM,CAACtC,WAAW,CAACzD,MAAM,EAAE;EACpCuD,IAAAA,2BAA2B,CAAClG,aAAa,EAAE0I,MAAM,CAACtC,WAAW,EAAEX,GAAG,EAAElF,kBAAkB,EAAEC,wBAAwB,CAAC,CAAA;EACjHqB,IAAAA,OAAO,CAACC,IAAI,CAAC,4DAA4D,CAAC,CAAA;EAC3E,GAAA;EAED,EAAA,IAAIzB,EAAE,IAAIqI,MAAM,CAACtC,WAAW,CAACzD,MAAM,EAAE;MACnC,MAAM,IAAIJ,KAAK,CAAC,CAAGmG,EAAAA,MAAM,CAACtC,WAAW,CAACzD,MAAM,CAAA,oBAAA,CAAsB,CAAC,CAAA;EACpE,GAAA;EAED,EAAA,IAAItC,EAAE,IAAIqI,MAAM,CAAC5B,UAAU,CAACnE,MAAM,EAAE;MAClC,MAAM,IAAIJ,KAAK,CAAC,CAAGmG,EAAAA,MAAM,CAAC5B,UAAU,CAACnE,MAAM,CAAA,mBAAA,CAAqB,CAAC,CAAA;EAClE,GAAA;EAED,EAAA,OAAO+F,MAAM,CAAA;EACf;;ECnEA5H,OAAO,CAAC8I,EAAE,CAAC,mBAAmB,EAAGZ,GAAG,IAAI;EACtCnH,EAAAA,OAAO,CAACgI,KAAK,CAAC,oBAAoB,EAAEb,GAAG,CAAC,CAAA;EACxClI,EAAAA,OAAO,CAACgJ,IAAI,CAAC,CAAC,CAAC,CAAA;EACjB,CAAC,CAAC,CAAA;EAEFhJ,OAAO,CAAC8I,EAAE,CAAC,oBAAoB,EAAGZ,GAAG,IAAI;EACvCnH,EAAAA,OAAO,CAACgI,KAAK,CAAC,oBAAoB,EAAEb,GAAG,CAAC,CAAA;EACxClI,EAAAA,OAAO,CAACgJ,IAAI,CAAC,CAAC,CAAC,CAAA;EACjB,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file From 98d36f3c468c3e49a43071e58aed88b7918bc425 Mon Sep 17 00:00:00 2001 From: BART! Date: Sun, 17 Aug 2025 22:00:49 +0200 Subject: [PATCH 3/4] fix(module): incorrect file linking --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4728eac3..7d60d40c 100755 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "source": "src/index.ts", "bin": "bin/vue-i18n-extract.js", "main": "dist/vue-i18n-extract.umd.js", - "module": "dist/vue-i18n-extract.modern.js", + "module": "dist/vue-i18n-extract.modern.mjs", "types": "dist/index.d.ts", "files": [ "bin", @@ -61,4 +61,4 @@ "ts-jest": "^27.1.4", "typescript": "^4.6.3" } -} +} \ No newline at end of file From 54f87e4b6462103b6e60ac789c6e46e0f8008e14 Mon Sep 17 00:00:00 2001 From: BART! Date: Sun, 17 Aug 2025 22:23:51 +0200 Subject: [PATCH 4/4] docs(readme): add placeholder variable --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f5e3ea46..bf067ea0 100644 --- a/README.md +++ b/README.md @@ -215,11 +215,16 @@ You can generate a default configuration file using `npx vue-i18n-extract init` * CLI argument: `--missing-translation-string`, `--missingTranslationString` * Required: No * Default: `''` -* Type: `string` or `null` +* Type: `string` or `null` or a placeholder variable `{{t}}` * Description: Text to use when missing translations are added to the translation files. -* Examples: - * `'Translation missing'`: Use "Translation missing" as default key. - * `null`: Add the translation key to the file, but don't add a default translation. This will trigger `vue-i18n`'s the missingHandler. +- Examples: + - `'Translation missing'`: Use "Translation missing" as default key. + - `null`: Add the translation key to the file, but don't add a default translation. This will trigger `vue-i18n`'s the missingHandler. + - `{{t}}`: This is a placeholder variable used for translation keys in your project. When processing templates or content, this placeholder will be replaced with the appropriate translation key. You can use this variable in different contexts such as: + - Inside double brackets: `[[{{t}}]]` + - As part of todo comments: `TODO: {{t}}` + - In any other text where a translation key needs to be inserted + - For example, if your key is "user.greeting", using `'Missing: {{t}}'` would generate "Missing: user.greeting" as the default text. ## Supported `vue-i18n` Formats