@braineet/eslint-plugin
Version:
87 lines (73 loc) • 2.66 kB
JavaScript
/* eslint-disable import/no-extraneous-dependencies */
const { getStaticValue } = require('eslint-utils');
const { closest } = require('fastest-levenshtein');
const { getSettings } = require('../utils/settings');
const {
getTranslations,
getKeysFromTranslations,
} = require('../utils/translations');
const MESSAGE =
'The key "{{ key }}" does not exist in any of the translation files. Did you mean "{{ closestKey }}"? To add a new key make sure to define it in the translation files';
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: 'Validate i18next non existing keys',
recommended: true,
},
fixable: null,
},
create(context) {
if (!context.getCwd) {
throw new Error("can't get cwd");
}
const cwd = context.getCwd();
const settings = getSettings(context);
const translations = getTranslations(
cwd,
settings.translationFiles.location,
);
const keys = getKeysFromTranslations(translations);
const keysArray = Array.from(keys);
const validateStaticValue = (node, staticValue) => {
if (!staticValue || !staticValue.value) return;
const key = staticValue.value;
if (
!keys.has(key) &&
!keys.has(`${key}_one`) &&
!keys.has(`${key}_other`)
) {
context.report({
message: MESSAGE,
node,
data: {
key,
closestKey: closest(key, keysArray),
},
});
}
};
return {
CallExpression: expression => {
const calleeName =
expression.callee.type === 'MemberExpression'
? expression.callee.property.name
: expression.callee.name;
if (calleeName !== 't') {
return;
}
if (!expression.arguments.length) {
return;
}
const [firstArgument] = expression.arguments;
const staticValue = getStaticValue(
firstArgument,
context.getScope(),
);
validateStaticValue(firstArgument, staticValue);
},
};
},
};