From 27074030956301ba593f03d1b00c71a8f4209ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Kubern=C3=A1t?= Date: Mon, 11 Nov 2024 11:42:00 +0100 Subject: [PATCH 1/2] Add configurable JSON indentation --- README.md | 12 ++++++++++++ bin/vue-i18n-extract.js | 4 ++++ src/create-report/index.ts | 3 ++- src/create-report/language-files.ts | 10 +++++----- src/types.ts | 1 + 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f5e3ea46..a31d9a52 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ - [`exclude`](#exclude) - [`noEmptyTranslation`](#noemptytranslation) - [`missingtranslationstring`](#missingtranslationstring) + - [`jsonIndentation`](#jsonIndentation) - [Supported `vue-i18n` Formats](#supported-vue-i18n-formats) - [Why?](#why) - [Contribution](#contribution) @@ -221,6 +222,17 @@ You can generate a default configuration file using `npx vue-i18n-extract init` * `'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. +### `jsonIndentation` + +* Name: `jsonIndentation` +* CLI argument: `--json-indentation`, `--jsonIndentation` +* Required: No +* Default: `2` +* Type: `number` or `null` +* Description: Number of spaces to use when writing JSON files. +* Examples: + * `4` + ## Supported `vue-i18n` Formats - Static in template or script: diff --git a/bin/vue-i18n-extract.js b/bin/vue-i18n-extract.js index 8773ec8d..2026d6da 100755 --- a/bin/vue-i18n-extract.js +++ b/bin/vue-i18n-extract.js @@ -47,6 +47,10 @@ cli '--missingTranslationString', 'Default string for missing translations.' ) + .option( + '--jsonIndentation', + 'Indentation to be used when writing JSON files.' + ) .option( '--detect ', '[string] The type of issues you want to detect (ex. --detect missing) ', diff --git a/src/create-report/index.ts b/src/create-report/index.ts index 9fdce702..b7756603 100644 --- a/src/create-report/index.ts +++ b/src/create-report/index.ts @@ -17,6 +17,7 @@ export async function createI18NReport (options: ReportOptions): Promise { const languageFileContent = JSON.parse(languageFile.content); @@ -73,11 +73,11 @@ export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], } }); - writeLanguageFile(languageFile, languageFileContent); + writeLanguageFile(languageFile, languageFileContent, jsonIndentation); }); } -export function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot): void { +export function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot, jsonIndentation = 2): void { parsedLanguageFiles.forEach(languageFile => { const languageFileContent = JSON.parse(languageFile.content); @@ -91,10 +91,10 @@ export function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[] }); } -function writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown) { +function writeLanguageFile (languageFile: SimpleFile, newLanguageFileContent: unknown, jsonIndentation = 2) { const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1); const filePath = languageFile.path; - const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2); + const stringifiedContent = JSON.stringify(newLanguageFileContent, null, jsonIndentation); if (fileExtension === 'json') { fs.writeFileSync(filePath, stringifiedContent); diff --git a/src/types.ts b/src/types.ts index 288cd126..cf7b19a6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,6 +9,7 @@ export type ReportOptions = { separator?: string; noEmptyTranslation?: string; missingTranslationString?: string; + jsonIndentation?: number; detect?: DetectionType[]; } From 4c4f046bd07840779fa3fdcab7cb5af702094bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Kubern=C3=A1t?= Date: Mon, 11 Nov 2024 11:45:11 +0100 Subject: [PATCH 2/2] Update dist files --- dist/create-report/language-files.d.ts | 4 +- dist/types.d.ts | 13 ++-- dist/vue-i18n-extract.modern.mjs | 91 +++++----------------- dist/vue-i18n-extract.modern.mjs.map | 2 +- dist/vue-i18n-extract.umd.js | 102 ++++++------------------- dist/vue-i18n-extract.umd.js.map | 2 +- 6 files changed, 56 insertions(+), 158 deletions(-) diff --git a/dist/create-report/language-files.d.ts b/dist/create-report/language-files.d.ts index f3800866..d6f7ec2c 100644 --- a/dist/create-report/language-files.d.ts +++ b/dist/create-report/language-files.d.ts @@ -2,6 +2,6 @@ import { SimpleFile, I18NLanguage, I18NItem } from '../types'; export declare function readLanguageFiles(src: string): SimpleFile[]; export declare function extractI18NLanguageFromLanguageFiles(languageFiles: SimpleFile[], dot?: DotObject.Dot): I18NLanguage; -export declare function writeMissingToLanguageFiles(parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot?: DotObject.Dot, noEmptyTranslation?: string, missingTranslationString?: string): void; -export declare function removeUnusedFromLanguageFiles(parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot?: DotObject.Dot): void; +export declare function writeMissingToLanguageFiles(parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot?: DotObject.Dot, noEmptyTranslation?: string, missingTranslationString?: string, jsonIndentation?: number): void; +export declare function removeUnusedFromLanguageFiles(parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot?: DotObject.Dot, jsonIndentation?: number): void; export declare function parselanguageFiles(languageFiles: string, dot?: DotObject.Dot): I18NLanguage; diff --git a/dist/types.d.ts b/dist/types.d.ts index f912a4f7..4824ac59 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; @@ -9,6 +9,7 @@ export declare type ReportOptions = { separator?: string; noEmptyTranslation?: string; missingTranslationString?: string; + jsonIndentation?: number; detect?: DetectionType[]; }; export declare enum DetectionType { @@ -16,25 +17,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..fc1ae2f5 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({ @@ -227,7 +195,7 @@ function extractI18NLanguageFromLanguageFiles(languageFiles, dot = Dot) { return accumulator; }, {}); } -function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot, noEmptyTranslation = '', missingTranslationString = '') { +function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot, noEmptyTranslation = '', missingTranslationString = '', jsonIndentation = 2) { parsedLanguageFiles.forEach(languageFile => { const languageFileContent = JSON.parse(languageFile.content); missingKeys.forEach(item => { @@ -236,10 +204,10 @@ function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent); } }); - writeLanguageFile(languageFile, languageFileContent); + writeLanguageFile(languageFile, languageFileContent, jsonIndentation); }); } -function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Dot) { +function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Dot, jsonIndentation = 2) { parsedLanguageFiles.forEach(languageFile => { const languageFileContent = JSON.parse(languageFile.content); unusedKeys.forEach(item => { @@ -250,12 +218,10 @@ function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Do writeLanguageFile(languageFile, languageFileContent); }); } - -function writeLanguageFile(languageFile, newLanguageFileContent) { +function writeLanguageFile(languageFile, newLanguageFileContent, jsonIndentation = 2) { const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1); const filePath = languageFile.path; - const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2); - + const stringifiedContent = JSON.stringify(newLanguageFileContent, null, jsonIndentation); if (fileExtension === 'json') { fs.writeFileSync(filePath, stringifiedContent); } else if (fileExtension === 'js') { @@ -267,9 +233,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 +246,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 +286,6 @@ async function writeReportToFile(report, writePath) { reject(err); return; } - resolve(); }); }); @@ -345,17 +303,16 @@ async function createI18NReport(options) { separator, noEmptyTranslation = '', missingTranslationString = '', + jsonIndentation = 2, detect = [DetectionType.Missing, DetectionType.Unused, DetectionType.Dynamic] } = options; if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.'); 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 +323,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); + writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString, jsonIndentation); 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..87c8b2cf 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":"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"} \ 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/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","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 = '', jsonIndentation = 2): 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, jsonIndentation);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot, jsonIndentation = 2): 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, jsonIndentation = 2) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, jsonIndentation);\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 jsonIndentation = 2,\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, jsonIndentation);\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","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","parse","argv","run","options","pathToConfigFile","resolve","configOptions","require","console","info","_extends","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","fileName","f","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","indexOf","charAt","pathAtIndex","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","jsonIndentation","languageFile","languageFileContent","item","includes","addDefaultTranslation","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","stringifiedContent","stripBounding","mightBeDynamic","previousCharacter","nextCharacter","extractI18NReport","vueItems","detect","DetectionType","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","maybeDynamicKeys","writeReportToFile","report","writePath","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","Array","isArray","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","err","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..e71fc729 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({ @@ -234,7 +195,7 @@ return accumulator; }, {}); } - function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot__default["default"], noEmptyTranslation = '', missingTranslationString = '') { + function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = Dot__default["default"], noEmptyTranslation = '', missingTranslationString = '', jsonIndentation = 2) { parsedLanguageFiles.forEach(languageFile => { const languageFileContent = JSON.parse(languageFile.content); missingKeys.forEach(item => { @@ -243,10 +204,10 @@ dot.str(item.path, addDefaultTranslation ? item.path : missingTranslationString === 'null' ? null : missingTranslationString, languageFileContent); } }); - writeLanguageFile(languageFile, languageFileContent); + writeLanguageFile(languageFile, languageFileContent, jsonIndentation); }); } - function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Dot__default["default"]) { + function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = Dot__default["default"], jsonIndentation = 2) { parsedLanguageFiles.forEach(languageFile => { const languageFileContent = JSON.parse(languageFile.content); unusedKeys.forEach(item => { @@ -257,12 +218,10 @@ writeLanguageFile(languageFile, languageFileContent); }); } - - function writeLanguageFile(languageFile, newLanguageFileContent) { + function writeLanguageFile(languageFile, newLanguageFileContent, jsonIndentation = 2) { const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1); const filePath = languageFile.path; - const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2); - + const stringifiedContent = JSON.stringify(newLanguageFileContent, null, jsonIndentation); if (fileExtension === 'json') { fs__default["default"].writeFileSync(filePath, stringifiedContent); } else if (fileExtension === 'js') { @@ -274,9 +233,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 +246,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 +288,6 @@ reject(err); return; } - resolve(); }); }); @@ -352,17 +305,16 @@ separator, noEmptyTranslation = '', missingTranslationString = '', + jsonIndentation = 2, detect = [exports.DetectionType.Missing, exports.DetectionType.Unused, exports.DetectionType.Dynamic] } = options; if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.'); 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 +325,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); + writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation, missingTranslationString, jsonIndentation); 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..fb6de221 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/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","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 = '', jsonIndentation = 2): 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, jsonIndentation);\n });\n}\n\nexport function removeUnusedFromLanguageFiles (parsedLanguageFiles: SimpleFile[], unusedKeys: I18NItem[], dot: DotObject.Dot = Dot, jsonIndentation = 2): 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, jsonIndentation = 2) {\n const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);\n const filePath = languageFile.path;\n const stringifiedContent = JSON.stringify(newLanguageFileContent, null, jsonIndentation);\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 jsonIndentation = 2,\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, jsonIndentation);\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","process","cwd","JSON","stringify","defaultConfig","resolveConfig","argvOptions","parse","argv","run","options","pathToConfigFile","resolve","configOptions","require","console","info","readVueFiles","src","normalizedSrc","replace","isValidGlob","Error","targetFiles","glob","sync","length","map","fileName","f","content","readFileSync","getMatches","file","regExp","captureGroup","match","exec","indexOf","charAt","pathAtIndex","line","substring","index","extractMethodMatches","methodRegExp","extractComponentMatches","componentRegExp","extractDirectiveMatches","directiveRegExp","extractI18NItemsFromVueFiles","sourceFiles","reduce","accumulator","methodMatches","componentMatches","directiveMatches","readLanguageFiles","langPath","extension","lastIndexOf","toLowerCase","isJSON","isYAML","langObj","load","eval","extractI18NLanguageFromLanguageFiles","dot","Dot","language","flattenedObject","Object","keys","forEach","key","push","writeMissingToLanguageFiles","parsedLanguageFiles","missingKeys","jsonIndentation","languageFile","languageFileContent","item","includes","addDefaultTranslation","str","writeLanguageFile","removeUnusedFromLanguageFiles","unusedKeys","delete","newLanguageFileContent","fileExtension","stringifiedContent","stripBounding","mightBeDynamic","previousCharacter","nextCharacter","extractI18NReport","vueItems","detect","DetectionType","Dynamic","filter","vueItem","languageItems","Missing","missingKeysInLanguage","some","languageItem","Unused","unusedKeysInLanguage","startsWith","maybeDynamicKeys","writeReportToFile","report","writePath","createI18NReport","vueFilesGlob","languageFilesGlob","issuesToDetect","Array","isArray","invalidDetectOptions","values","I18NItems","I18NLanguage","excluded","table","warn","on","error","err","exit"],"mappings":"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"} \ No newline at end of file