Files
Housekeeping-web-admin/node_modules/@base44/vite-plugin/dist/visual-edit-plugin.js
T
2026-06-24 09:48:54 +02:00

100 lines
3.7 KiB
JavaScript

import { parse } from "@babel/parser";
import { default as traverse } from "@babel/traverse";
import { default as generate } from "@babel/generator";
import * as t from "@babel/types";
import { JSXProcessor } from "./jsx-processor.js";
import { JSXUtils } from "./jsx-utils.js";
export function visualEditPlugin() {
return {
name: "visual-edit-transform",
apply: (config) => config.mode === "development",
enforce: "pre",
order: "pre",
transformIndexHtml(html) {
const tailwindScript = ` <!-- Tailwind CSS CDN for visual editing -->\n <script src="https://cdn.tailwindcss.com"></script>\n `;
return html.replace("</head>", tailwindScript + "</head>");
},
transform(code, id) {
if (id.includes("node_modules") || id.includes("visual-edit-agent")) {
return null;
}
if (!id.match(/\.(jsx?|tsx?)$/)) {
return null;
}
const filename = extractFilename(id);
try {
const ast = parse(code, {
sourceType: "module",
plugins: [
"jsx",
"typescript",
"decorators-legacy",
"classProperties",
"objectRestSpread",
"functionBind",
"exportDefaultFrom",
"exportNamespaceFrom",
"dynamicImport",
"nullishCoalescingOperator",
"optionalChaining",
"asyncGenerators",
"bigInt",
"optionalCatchBinding",
"throwExpressions",
],
});
JSXUtils.init(t);
const processor = new JSXProcessor(t, filename);
traverse.default(ast, {
JSXElement(path) {
const jsxElement = path.node;
if (t.isJSXFragment(jsxElement))
return;
processor.processJSXElement(path.get("openingElement"));
},
});
const result = generate.default(ast, {
compact: false,
concise: false,
retainLines: true,
});
return {
code: result.code,
map: null,
};
}
catch (error) {
console.error("Failed to add source location to JSX:", error);
return {
code: code,
map: null,
};
}
},
};
}
function extractFilename(id) {
const pathParts = id.split("/");
const segmentIndex = findSegmentIndex(pathParts, ["pages", "components"]);
if (segmentIndex >= 0 && segmentIndex < pathParts.length - 1) {
const relevantParts = pathParts.slice(segmentIndex);
const last = relevantParts[relevantParts.length - 1];
relevantParts[relevantParts.length - 1] = stripExtension(last ?? "");
return relevantParts.join("/");
}
const lastPart = pathParts[pathParts.length - 1] ?? "";
return stripExtension(lastPart);
}
function findSegmentIndex(parts, segments) {
for (const segment of segments) {
const idx = parts.findIndex((part) => part === segment);
if (idx >= 0)
return idx;
}
return -1;
}
function stripExtension(filename) {
const dotIndex = filename.indexOf(".");
return dotIndex >= 0 ? filename.substring(0, dotIndex) : filename;
}
//# sourceMappingURL=visual-edit-plugin.js.map