eslint-plugin-lit
Version:
lit-html support for ESLint
90 lines (89 loc) • 3.51 kB
JavaScript
/**
* @fileoverview Detects usages of legacy lit imports
* @author James Garbutt <https://github.com/43081j>
*/
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
export const rule = {
meta: {
docs: {
description: 'Detects usages of legacy lit imports',
recommended: false,
url: 'https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/no-legacy-imports.md'
},
fixable: 'code',
schema: [],
messages: {
legacyDecorator: 'Legacy decorators should no longer be used, did you mean to use ' +
"the '{{replacement}}' decorator from the 'lit/decorators' module?",
movedDecorator: "Decorators should now be imported from the 'lit/decorators' module",
movedSource: 'Imported module has moved in lit 2, did you mean ' +
'to use "{{replacement}}"?'
}
},
create(context) {
const legacyDecorators = {
internalProperty: 'state'
};
const movedDecorators = [
'customElement',
'eventOptions',
'property',
'query',
'queryAll',
'queryAssignedNodes',
'queryAsync'
];
const movedSources = [
{ from: /^lit-element$/, to: 'lit' },
{ from: /^lit-html$/, to: 'lit' },
{
from: /^lit-element\/lib\/updating-element(?:\.js)?$/,
to: '@lit/reactive-element'
},
{
from: /^lit-html\/directives\/(.+)$/,
to: 'lit/directives/$1'
}
];
return {
ImportDeclaration: (node) => {
if (node.source.value === 'lit-element') {
for (const specifier of node.specifiers) {
if (specifier.type === 'ImportSpecifier') {
const replacement = legacyDecorators[specifier.imported.name];
if (replacement) {
context.report({
node: specifier,
messageId: 'legacyDecorator',
data: { replacement }
});
}
else if (movedDecorators.includes(specifier.imported.name)) {
context.report({
node: specifier,
messageId: 'movedDecorator'
});
}
}
}
}
const source = node.source.value;
if (typeof source === 'string') {
const mapping = movedSources.find((s) => s.from.test(source));
if (mapping) {
const replacement = source.replace(mapping.from, mapping.to);
context.report({
node: node.source,
messageId: 'movedSource',
data: {
replacement
}
});
}
}
}
};
}
};