flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS
131 lines (128 loc) • 5.47 kB
JavaScript
import { parse } from '@typescript-eslint/typescript-estree';
import * as recast from 'recast';
function addToConfig({
content,
targetPath,
valueGenerator
}) {
const ast = recast.parse(content, {
parser: {
parse: (source) => parse(source, {
loc: true,
range: true,
tokens: true,
comment: true
})
}
});
const configMap = /* @__PURE__ */ new Map();
recast.types.visit(ast, {
visitVariableDeclarator(path) {
const { node } = path;
if (node.id.type === "Identifier" && node.init.type === "CallExpression" && node.init.callee.type === "Identifier" && node.init.arguments.length > 0 && node.init.arguments[0].type === "ObjectExpression") {
configMap.set(node.id.name, node.init.arguments[0]);
} else if (node.id.type === "Identifier" && node.init.type === "ObjectExpression") {
configMap.set(node.id.name, node.init);
}
return false;
},
visitExportDefaultDeclaration(path) {
const { node } = path;
if (node.declaration.type === "TSAsExpression" || node.declaration.type === "TSSatisfiesExpression") {
ensureArrayProperty(node.declaration.expression, targetPath, valueGenerator);
} else if (node.declaration.type === "ObjectExpression") {
ensureArrayProperty(node.declaration, targetPath, valueGenerator);
} else if (node.declaration.type === "Identifier") {
const configForId = configMap.get(node.declaration.name);
if (configForId) {
ensureArrayProperty(configForId, targetPath, valueGenerator);
}
} else if (node.declaration.type === "CallExpression" && node.declaration.callee.type === "Identifier" && node.declaration.arguments.length > 0) {
const arg = node.declaration.arguments[0];
if (arg.type === "ObjectExpression") {
ensureArrayProperty(arg, targetPath, valueGenerator);
} else if (arg.type === "Identifier") {
const configForId = configMap.get(arg.name);
if (configForId) {
ensureArrayProperty(configForId, targetPath, valueGenerator);
}
}
}
return false;
},
visitAssignmentExpression(path) {
const { node } = path;
if (node.left.type === "MemberExpression" && node.left.object.type === "Identifier" && node.left.object.name === "module" && node.left.property.type === "Identifier" && node.left.property.name === "exports") {
if (node.right.type === "ObjectExpression") {
ensureArrayProperty(node.right, targetPath, valueGenerator);
} else if (node.right.type === "Identifier") {
const configForId = configMap.get(node.right.name);
if (configForId) {
ensureArrayProperty(configForId, targetPath, valueGenerator);
}
} else if (node.right.type === "CallExpression" && node.right.arguments.length > 0 && node.right.arguments[0].type === "ObjectExpression") {
ensureArrayProperty(node.right.arguments[0], targetPath, valueGenerator);
}
}
return false;
}
});
return recast.print(ast).code;
}
function ensureArrayProperty(objExpr, path, valueGenerator) {
const b = recast.types.builders;
const keys = path.split(".");
let current = objExpr;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
let prop = current.properties.find((p) => {
if (p.type !== "Property") return false;
const propKey = p.key;
return propKey.type === "Identifier" && propKey.name === key || propKey.type === "Literal" && propKey.value === key;
});
if (!prop) {
const value = i === keys.length - 1 ? b.arrayExpression([]) : b.objectExpression([]);
prop = b.property("init", b.identifier(key), value);
current.properties.push(prop);
}
if (prop.type === "Property") {
if (i === keys.length - 1 && prop.value.type === "CallExpression") {
const currentExpr = prop.value;
while (currentExpr.type === "CallExpression" && currentExpr.callee.type === "MemberExpression" && currentExpr.callee.object.type === "ArrayExpression") {
current = currentExpr.callee.object;
break;
}
if (current !== objExpr) {
continue;
}
}
if (i < keys.length - 1 && prop.value.type !== "ObjectExpression") {
prop.value = b.objectExpression([]);
} else if (i === keys.length - 1 && prop.value.type !== "ArrayExpression") {
prop.value = b.arrayExpression([]);
}
current = prop.value;
}
}
if (current.type === "ArrayExpression") {
const value = valueGenerator(b);
const exists = current.elements.some((el) => {
if (!el) return false;
if ((el.type === "StringLiteral" || el.type === "Literal") && (value.type === "StringLiteral" || value.type === "Literal") && typeof el.value === "string" && typeof value.value === "string") {
return el.value === value.value;
}
if (el.type === "CallExpression" && value.type === "CallExpression" && el.callee?.type === "Identifier" && value.callee?.type === "Identifier") {
return el.callee.name === value.callee.name;
}
if (el.type === "Identifier" && value.type === "Identifier") {
return el.name === value.name;
}
return false;
});
if (!exists) {
current.elements.push(value);
}
}
}
export { addToConfig };
//# sourceMappingURL=add-to-config.js.map