messageformat-validator
Advanced tools
Comparing version
@@ -5,12 +5,12 @@ #!/usr/bin/env -S node --no-warnings --experimental-json-modules | ||
import { readdir, readFile, writeFile } from 'node:fs/promises'; | ||
import { parseLocales, structureRegEx, validateLocales } from '../src/validate.js'; | ||
import { readFile, readdir, writeFile } from 'node:fs/promises'; | ||
import chalk from 'chalk'; | ||
import findConfig from 'find-config'; | ||
import glob from 'glob'; | ||
import pkg from '../package.json' with { type: 'json' }; | ||
import { program } from 'commander'; | ||
import findConfig from 'find-config'; | ||
import pkg from '../package.json' with { type: 'json' }; | ||
import { validateLocales, parseLocales, structureRegEx } from '../src/validate.js'; | ||
const configPath = findConfig('mfv.config.json'); | ||
const { path, source: globalSource, locales: globalLocales, jsonObj: globalJsonObj } = configPath ? (await import(`file://${configPath}`, { with: { type: 'json' }}))?.default : {}; | ||
const { path, source: globalSource, locales: globalLocales, jsonObj: globalJsonObj } = configPath ? (await import(`file://${configPath}`, { with: { type: 'json' } }))?.default ?? {} : {}; | ||
@@ -81,6 +81,8 @@ program | ||
const { source, locales: configLocales, jsonObj } = subConfigPath ? (await import(`file://${subConfigPath}`, { with: { type: 'json' }}))?.default : {}; /* eslint-disable-line global-require */ | ||
const { source, locales: configLocales, jsonObj } = subConfigPath ? (await import(`file://${subConfigPath}`, { with: { type: 'json' } }))?.default ?? {} : {}; /* eslint-disable-line global-require */ | ||
const files = await readdir(absLocalesPath).catch(err => console.log(`Failed to read ${absLocalesPath}`)); | ||
if (!files) return; | ||
const files = await readdir(absLocalesPath).catch(err => { | ||
console.log(`Failed to read ${absLocalesPath}\n`); | ||
throw err; | ||
}); | ||
@@ -108,3 +110,3 @@ const sourceLocale = program.sourceLocale || source || globalSource; | ||
const resources = await Promise.all(filteredFiles.map(file => readFile(absLocalesPath + file, 'utf8'))) | ||
.then(files => files.map((contents, idx) => ({ | ||
.then(readFiles => readFiles.map((contents, idx) => ({ | ||
file: filteredFiles[idx], | ||
@@ -157,3 +159,3 @@ contents | ||
let count = 0; | ||
Object.keys(locales).forEach(async locale => { | ||
await Promise.all(Object.keys(locales).map(async locale => { | ||
if (!allowedLocales || allowedLocales.includes(locale)) { | ||
@@ -178,3 +180,3 @@ | ||
} | ||
}); | ||
})); | ||
@@ -190,3 +192,3 @@ const cliReport = `\n ${chalk.green('\u2714')} Renamed ${count} strings`; | ||
output.forEach(async(locale, idx) => { | ||
await Promise.all(output.map(async(locale, idx) => { | ||
const localePath = `${absLocalesPath}${locales[locale.locale].file}`; | ||
@@ -216,3 +218,3 @@ | ||
locale.issues.forEach((issue) => { | ||
locale.issues.forEach(issue => { | ||
if (program.removeExtraneous) { | ||
@@ -248,3 +250,7 @@ if (issue.type === 'extraneous') { | ||
} | ||
else if (!program.ignoreIssueTypes || !program.ignoreIssueTypes.replace(' ','').split(',').includes(issue.type)) { | ||
else if (!program.ignoreIssueTypes || !program.ignoreIssueTypes | ||
.replace(' ','') | ||
.split(',') | ||
.includes(issue.type) | ||
) { | ||
console.log([ | ||
@@ -297,8 +303,8 @@ ' ', chalk.grey(`${issue.line}:${issue.column}`), | ||
} | ||
}); | ||
})); | ||
if (program.throwErrors && output.some(locale => locale.report.totals.errors)) { | ||
console.error('\nErrors were reported in at least one locale. See details above.'); | ||
process.exitCode = 1; | ||
return 1; | ||
} | ||
}); |
{ | ||
"name": "messageformat-validator", | ||
"version": "2.6.7", | ||
"version": "2.7.0", | ||
"description": "Validates that ICU MessageFormat strings are well-formed, and that translated target strings are compatible with their source.", | ||
@@ -12,5 +12,7 @@ "type": "module", | ||
"scripts": { | ||
"start": "node index.js", | ||
"test": "mocha 'test/**/*.test.js'", | ||
"prepublish": "npm t" | ||
"lint": "npm run lint:eslint", | ||
"lint:eslint": "eslint . --ext .js --ignore-path .gitignore", | ||
"test": "npm run lint && npm run test:unit", | ||
"test:unit": "mocha 'test/**/*.test.js'", | ||
"prepublishOnly": "npm t" | ||
}, | ||
@@ -34,9 +36,16 @@ "bin": { | ||
"glob": "^7.1.6", | ||
"make-plural": "^6.2.2", | ||
"make-plural": "^7.4.0", | ||
"messageformat-parser": "^4.1.3" | ||
}, | ||
"devDependencies": { | ||
"@babel/eslint-parser": "^7.25.1", | ||
"@babel/plugin-syntax-import-attributes": "^7.25.6", | ||
"@eslint/compat": "^1.1.1", | ||
"@eslint/eslintrc": "^3.1.0", | ||
"@eslint/js": "^9.10.0", | ||
"chai": "^5.1.1", | ||
"eslint": "^8.57.0", | ||
"globals": "^15.9.0", | ||
"mocha": "^10.7.3" | ||
} | ||
} |
export { Reporter } from './reporter.js'; | ||
export { validateMessage } from './validate.js'; | ||
export { structureRegEx, validateMessage } from './validate.js'; |
@@ -15,3 +15,3 @@ export function Reporter(locale, fileContents = '') { | ||
Reporter.prototype.log = function(level, type, msg, column = 0, line) { | ||
Reporter.prototype.log = function(level, type, msg, column = 0, givenLine) { | ||
const levels = level + 's'; | ||
@@ -24,5 +24,5 @@ this.report.totals[levels]++; | ||
const start = Math.max(this._config.fileContents.indexOf(this._config.target), 0) + column; | ||
const start = Math.max(this._config.fileContents.indexOf(this._config.target), 0) + column | ||
const newlines = this._config.target.split(this._config.target.val)[0].match(/\n/)?.length || 0; | ||
line = line || this._config.fileContents.substring(0, start).split('\n').length + newlines; | ||
const line = givenLine || this._config.fileContents.substring(0, start).split('\n').length + newlines; | ||
@@ -29,0 +29,0 @@ const issue = { |
@@ -33,3 +33,4 @@ import * as pluralCats from 'make-plural/pluralCategories' | ||
reporter.error('extraneous', 'This string does not exist in the source file.'); | ||
} else { | ||
} | ||
else { | ||
if (locales[targetLocale].duplicateKeys.has(key)) reporter.error('duplicate-keys', 'Key appears multiple times'); | ||
@@ -173,3 +174,2 @@ | ||
const hasPlural = targetMap.cases.find(c => Boolean(c.match(/^\|(plural|selectordinal)\|/))); | ||
const firstPlural = targetMap.cases.findIndex(i => i.match(/^.+\|(plural|selectordinal)\|/)) + 1; | ||
@@ -176,0 +176,0 @@ const lastSelect = targetMap.cases.findLastIndex(i => i.match(/^.+\|select\|/)) + 1; |
29545
1.41%558
1.09%9
350%+ Added
- Removed
Updated