89 lines
2.9 KiB
JavaScript
89 lines
2.9 KiB
JavaScript
/* eslint-disable no-param-reassign */
|
|
const {
|
|
renameAndStoreImports,
|
|
generateImportStatements,
|
|
replaceTagImports,
|
|
} = require('./handleImports.js');
|
|
const { validateOptions } = require('./validateOptions.js');
|
|
|
|
function replaceTemplateElements({ path, opts }) {
|
|
const replaceTag = (value, from, to) =>
|
|
value
|
|
.replace(new RegExp(`<${from}(?=\\s|>)`, 'g'), `<${to}`) // positive lookahead for '>' or ' ' after the tagName
|
|
.replace(new RegExp(`/${from}>`, 'g'), `/${to}>`);
|
|
path.node.quasi.quasis.forEach(quasi => {
|
|
opts.changes.forEach(change => {
|
|
if (change.tag && quasi.value.raw.match(change.tag.from)) {
|
|
quasi.value.raw = replaceTag(quasi.value.raw, change.tag.from, change.tag.to);
|
|
if (typeof quasi.value.cooked === 'string') {
|
|
quasi.value.cooked = replaceTag(quasi.value.cooked, change.tag.from, change.tag.to);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function replaceTagName(tagName, opts) {
|
|
for (const change of opts.changes) {
|
|
if (change.tag && change.tag.from === tagName) {
|
|
return change.tag.to;
|
|
}
|
|
}
|
|
return tagName;
|
|
}
|
|
|
|
function insertImportStatements({ imports, path }) {
|
|
path.node.body = [...imports, ...path.node.body];
|
|
}
|
|
|
|
module.exports = ({ types: t }) => ({
|
|
visitor: {
|
|
ImportDeclaration(path, state) {
|
|
if (path.node.specifiers.length > 0) {
|
|
renameAndStoreImports({ path, state, opts: state.opts, types: t });
|
|
} else {
|
|
replaceTagImports({ path, state, opts: state.opts, types: t });
|
|
}
|
|
},
|
|
ClassMethod(path, state) {
|
|
// replace keys (= tag names) in static get scopedElements()
|
|
if (path.node.static === true && path.node.key.name === 'scopedElements') {
|
|
if (
|
|
path.node.body.type === 'BlockStatement' &&
|
|
path.node.body.body[0].type === 'ReturnStatement'
|
|
) {
|
|
const { argument } = path.node.body.body[0];
|
|
for (const prop of argument.properties) {
|
|
prop.key.value = replaceTagName(prop.key.value, state.opts);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
ClassProperty(path, state) {
|
|
// replace keys (= tag names) in scopedElements =
|
|
if (path.node.static === true && path.node.key.name === 'scopedElements') {
|
|
if (path.node.value.type === 'ObjectExpression') {
|
|
for (const prop of path.node.value.properties) {
|
|
prop.key.value = replaceTagName(prop.key.value, state.opts);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
TaggedTemplateExpression(path, state) {
|
|
if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'html') {
|
|
replaceTemplateElements({ path, opts: state.opts });
|
|
}
|
|
},
|
|
Program: {
|
|
enter: (path, state) => {
|
|
validateOptions(state.opts);
|
|
|
|
state.importedStorage = [];
|
|
},
|
|
exit: (path, state) => {
|
|
const imports = generateImportStatements({ state, types: t });
|
|
insertImportStatements({ imports, path });
|
|
},
|
|
},
|
|
},
|
|
});
|