@base44-preview/vite-plugin 0.1.0-dev.c16b316 → 0.1.0-dev.ec354c8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ const { base44 } = require("./base44Client.cjs");
2
+
3
+ module.exports = new Proxy(
4
+ {},
5
+ {
6
+ get: (_, prop) => {
7
+ if (prop === "agentSDK" || prop === "default") {
8
+ return base44.agents;
9
+ }
10
+ return base44.agents[prop];
11
+ },
12
+ }
13
+ );
@@ -0,0 +1,12 @@
1
+ declare const HTMLElement: {
2
+ new (): {};
3
+ };
4
+ export declare class ErrorOverlay extends HTMLElement {
5
+ static getOverlayHTML(): string;
6
+ close(): void;
7
+ static sendErrorToParent(error: Error, title: string, details: string | undefined, componentName: string | undefined): void;
8
+ constructor(error: Error);
9
+ }
10
+ export declare const errorOverlayCode: string;
11
+ export {};
12
+ //# sourceMappingURL=ErrorOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorOverlay.d.ts","sourceRoot":"","sources":["../src/ErrorOverlay.ts"],"names":[],"mappings":"AAGA,QAAA,MAAQ,WAAW;;CAA0B,CAAC;AAE9C,qBAAa,YAAa,SAAQ,WAAW;IAC3C,MAAM,CAAC,cAAc;IAMrB,KAAK;IAIL,MAAM,CAAC,iBAAiB,CACtB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,aAAa,EAAE,MAAM,GAAG,SAAS;gBAqBvB,KAAK,EAAE,KAAK;CAuBzB;AAGD,eAAO,MAAM,gBAAgB,QAG5B,CAAC"}
@@ -0,0 +1,51 @@
1
+ /// <reference lib="dom" />
2
+ // Make HTMLElement available in non-browser environments
3
+ const { HTMLElement = class {
4
+ } } = globalThis;
5
+ export class ErrorOverlay extends HTMLElement {
6
+ static getOverlayHTML() {
7
+ return `
8
+ <div>
9
+ </div>
10
+ `;
11
+ }
12
+ close() {
13
+ this.parentNode?.removeChild(this);
14
+ }
15
+ static sendErrorToParent(error, title, details, componentName) {
16
+ // Send error to parent using framewire
17
+ if (globalThis.window?.parent) {
18
+ try {
19
+ globalThis.window.parent?.postMessage({
20
+ type: "app_error",
21
+ error: { title, details, componentName, originalError: error },
22
+ }, "*");
23
+ }
24
+ catch (error) {
25
+ console.warn("Failed to send error to iframe parent:", error?.message);
26
+ }
27
+ }
28
+ }
29
+ constructor(error) {
30
+ super();
31
+ const stack = error?.stack;
32
+ let componentName = stack?.match(/at\s+(\w+)\s+\(eval/)?.[1];
33
+ if (componentName === "eval") {
34
+ componentName = undefined;
35
+ }
36
+ const title = componentName
37
+ ? `in ${componentName}: ${error.message?.toString()}`
38
+ : error.message?.toString();
39
+ const details = error?.stack;
40
+ // Call editor frame with the error (via post message)
41
+ ErrorOverlay.sendErrorToParent(error, title, details, componentName);
42
+ // Create the overlay element using HTML template
43
+ const overlay = document.createElement("div");
44
+ overlay.innerHTML = ErrorOverlay.getOverlayHTML();
45
+ // Add to DOM
46
+ document.body.appendChild(overlay);
47
+ }
48
+ }
49
+ // vite/react-plugin transpiles classes with _SomeClass, so we need to replace all _ErrorOverlay with ErrorOverlay
50
+ export const errorOverlayCode = ErrorOverlay.toString().replaceAll("_ErrorOverlay", "ErrorOverlay");
51
+ //# sourceMappingURL=ErrorOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorOverlay.js","sourceRoot":"","sources":["../src/ErrorOverlay.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,yDAAyD;AACzD,MAAM,EAAE,WAAW,GAAG;CAAQ,EAAE,GAAG,UAAU,CAAC;AAE9C,MAAM,OAAO,YAAa,SAAQ,WAAW;IAC3C,MAAM,CAAC,cAAc;QACnB,OAAO;;;KAGN,CAAC;IACJ,CAAC;IACD,KAAK;QACF,IAAY,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,CAAC,iBAAiB,CACtB,KAAY,EACZ,KAAa,EACb,OAA2B,EAC3B,aAAiC;QAEjC,uCAAuC;QACvC,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CACnC;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE;iBAC/D,EACD,GAAG,CACJ,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CACV,wCAAwC,EACvC,KAAe,EAAE,OAAO,CAC1B,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY,KAAY;QACtB,KAAK,EAAE,CAAC;QAER,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAC;QAC3B,IAAI,aAAa,GAAG,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7D,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;YAC7B,aAAa,GAAG,SAAS,CAAC;QAC5B,CAAC;QACD,MAAM,KAAK,GAAG,aAAa;YACzB,CAAC,CAAC,MAAM,aAAa,KAAK,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;YACrD,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,EAAE,KAAK,CAAC;QAE7B,sDAAsD;QACtD,YAAY,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QAErE,iDAAiD;QACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,cAAc,EAAE,CAAC;QAElD,aAAa;QACb,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF;AAED,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC,UAAU,CAChE,eAAe,EACf,cAAc,CACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "vite";
2
+ export declare function errorOverlayPlugin(): Plugin;
3
+ //# sourceMappingURL=error-overlay-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-overlay-plugin.d.ts","sourceRoot":"","sources":["../src/error-overlay-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,wBAAgB,kBAAkB,IAa3B,MAAM,CACZ"}
@@ -0,0 +1,14 @@
1
+ import { errorOverlayCode } from "./ErrorOverlay.js";
2
+ export function errorOverlayPlugin() {
3
+ return {
4
+ name: "error-overlay",
5
+ transform(code, id, opts = {}) {
6
+ if (opts?.ssr)
7
+ return;
8
+ if (!id.includes("vite/dist/client/client.mjs"))
9
+ return;
10
+ return code.replace("class ErrorOverlay", errorOverlayCode + "\nclass OldErrorOverlay");
11
+ },
12
+ };
13
+ }
14
+ //# sourceMappingURL=error-overlay-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-overlay-plugin.js","sourceRoot":"","sources":["../src/error-overlay-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,EAAE;YAC3B,IAAI,IAAI,EAAE,GAAG;gBAAE,OAAO;YAEtB,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;gBAAE,OAAO;YAExD,OAAO,IAAI,CAAC,OAAO,CACjB,oBAAoB,EACpB,gBAAgB,GAAG,yBAAyB,CAC7C,CAAC;QACJ,CAAC;KACQ,CAAC;AACd,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from "vite";
2
+ export default function vitePlugin(opts?: {
3
+ legacySDKImports?: boolean;
4
+ }): Plugin;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAC;AAK/C,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,IAAI,GAAE;IACJ,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,GAiID,MAAM,CACZ"}
package/dist/index.js ADDED
@@ -0,0 +1,103 @@
1
+ import { loadEnv } from "vite";
2
+ import { errorOverlayPlugin } from "./error-overlay-plugin.js";
3
+ import { visualEditPlugin } from "./visual-edit-plugin.js";
4
+ export default function vitePlugin(opts = {}) {
5
+ const { legacySDKImports = false } = opts;
6
+ return {
7
+ name: "base44",
8
+ enforce: "pre",
9
+ config: ({ mode }) => {
10
+ const env = loadEnv(mode ?? "development", process.cwd(), "");
11
+ const isRunningInSandbox = env.BASE44_SANDBOX_MODE === "true";
12
+ return {
13
+ resolve: {
14
+ alias: {
15
+ "@/": "/src/",
16
+ },
17
+ },
18
+ ...(isRunningInSandbox
19
+ ? {
20
+ plugins: [
21
+ {
22
+ name: "iframe-hmr",
23
+ configureServer(server) {
24
+ server.middlewares.use((req, res, next) => {
25
+ // Allow iframe embedding
26
+ res.setHeader("X-Frame-Options", "ALLOWALL");
27
+ res.setHeader("Content-Security-Policy", "frame-ancestors *;");
28
+ next();
29
+ });
30
+ },
31
+ },
32
+ ...(mode === "development"
33
+ ? [errorOverlayPlugin(), visualEditPlugin()]
34
+ : []),
35
+ ],
36
+ server: {
37
+ host: "0.0.0.0", // Bind to all interfaces for container access
38
+ port: 5173,
39
+ strictPort: true,
40
+ // Allow all hosts - essential for Modal tunnel URLs
41
+ allowedHosts: true,
42
+ watch: {
43
+ // Enable polling for better file change detection in containers
44
+ usePolling: true,
45
+ interval: 100, // Check every 100ms for responsive HMR
46
+ },
47
+ hmr: {
48
+ protocol: "wss",
49
+ clientPort: 443,
50
+ },
51
+ },
52
+ build: {
53
+ rollupOptions: {
54
+ onwarn(warning, warn) {
55
+ // Treat import errors as fatal errors
56
+ if (warning.code === "UNRESOLVED_IMPORT" ||
57
+ warning.code === "MISSING_EXPORT") {
58
+ throw new Error(`Build failed: ${warning.message}`);
59
+ }
60
+ // Use default for other warnings
61
+ warn(warning);
62
+ },
63
+ },
64
+ },
65
+ }
66
+ : {}),
67
+ optimizeDeps: {
68
+ esbuildOptions: {
69
+ loader: {
70
+ ".js": "jsx",
71
+ },
72
+ ...(legacySDKImports
73
+ ? {
74
+ define: {
75
+ "process.env.VITE_BASE44_APP_ID": JSON.stringify(env.VITE_BASE44_APP_ID),
76
+ "process.env.VITE_BASE44_BACKEND_URL": JSON.stringify(env.VITE_BASE44_BACKEND_URL),
77
+ },
78
+ }
79
+ : {}),
80
+ },
81
+ },
82
+ };
83
+ },
84
+ resolveId(source, importer, options) {
85
+ if (legacySDKImports) {
86
+ if (source.includes("/entities")) {
87
+ return this.resolve("@base44/vite-plugin/compat/entities.cjs", importer, options);
88
+ }
89
+ if (source.includes("/functions")) {
90
+ return this.resolve("@base44/vite-plugin/compat/functions.cjs", importer, options);
91
+ }
92
+ if (source.includes("/integrations")) {
93
+ return this.resolve("@base44/vite-plugin/compat/integrations.cjs", importer, options);
94
+ }
95
+ if (source.includes("@/agents")) {
96
+ return this.resolve("@base44/vite-plugin/compat/agents.cjs", importer, options);
97
+ }
98
+ }
99
+ return null;
100
+ },
101
+ };
102
+ }
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare function visualEditPlugin(): {
2
+ name: string;
3
+ enforce: string;
4
+ order: string;
5
+ transformIndexHtml(html: any): any;
6
+ transform(code: any, id: any): {
7
+ code: any;
8
+ map: null;
9
+ } | null;
10
+ };
11
+ //# sourceMappingURL=visual-edit-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-edit-plugin.d.ts","sourceRoot":"","sources":["../src/visual-edit-plugin.ts"],"names":[],"mappings":"AAkGA,wBAAgB,gBAAgB;;;;6BAMH,GAAG;oBAKZ,GAAG,MAAM,GAAG;;;;EA4J/B"}
@@ -0,0 +1,228 @@
1
+ import { parse } from "@babel/parser";
2
+ import { default as traverse } from "@babel/traverse";
3
+ import { default as generate } from "@babel/generator";
4
+ import * as t from "@babel/types";
5
+ // Helper function to check if JSX element contains dynamic content
6
+ function checkIfElementHasDynamicContent(jsxElement) {
7
+ let hasDynamicContent = false;
8
+ // Helper function to check if any node contains dynamic patterns
9
+ function checkNodeForDynamicContent(node) {
10
+ // JSX expressions like {variable}, {func()}, {obj.prop}
11
+ if (t.isJSXExpressionContainer(node)) {
12
+ const expression = node.expression;
13
+ // Skip empty expressions {}
14
+ if (t.isJSXEmptyExpression(expression)) {
15
+ return false;
16
+ }
17
+ // Any non-literal expression is considered dynamic
18
+ if (!t.isLiteral(expression)) {
19
+ return true;
20
+ }
21
+ }
22
+ // Template literals with expressions `Hello ${name}`
23
+ if (t.isTemplateLiteral(node) && node.expressions.length > 0) {
24
+ return true;
25
+ }
26
+ // Member expressions like props.title, state.value
27
+ if (t.isMemberExpression(node)) {
28
+ return true;
29
+ }
30
+ // Function calls like getData(), format()
31
+ if (t.isCallExpression(node)) {
32
+ return true;
33
+ }
34
+ // Conditional expressions like condition ? "yes" : "no"
35
+ if (t.isConditionalExpression(node)) {
36
+ return true;
37
+ }
38
+ // Identifier references (could be props, state, variables)
39
+ if (t.isIdentifier(node)) {
40
+ // Common dynamic identifiers
41
+ const dynamicNames = [
42
+ "props",
43
+ "state",
44
+ "data",
45
+ "item",
46
+ "value",
47
+ "text",
48
+ "content",
49
+ ];
50
+ if (dynamicNames.some((name) => node.name.includes(name))) {
51
+ return true;
52
+ }
53
+ }
54
+ return false;
55
+ }
56
+ // Recursively traverse all child nodes
57
+ function traverseNode(node) {
58
+ if (checkNodeForDynamicContent(node)) {
59
+ hasDynamicContent = true;
60
+ return;
61
+ }
62
+ // Recursively check child nodes
63
+ Object.keys(node).forEach((key) => {
64
+ const value = node[key];
65
+ if (Array.isArray(value)) {
66
+ value.forEach((child) => {
67
+ if (child && typeof child === "object" && child.type) {
68
+ traverseNode(child);
69
+ }
70
+ });
71
+ }
72
+ else if (value && typeof value === "object" && value.type) {
73
+ traverseNode(value);
74
+ }
75
+ });
76
+ }
77
+ // Check all children of the JSX element
78
+ jsxElement.children.forEach((child) => {
79
+ if (hasDynamicContent)
80
+ return; // Early exit if already found dynamic content
81
+ traverseNode(child);
82
+ });
83
+ return hasDynamicContent;
84
+ }
85
+ export function visualEditPlugin() {
86
+ return {
87
+ name: "visual-edit-transform",
88
+ enforce: "pre",
89
+ order: "pre",
90
+ // Inject Tailwind CDN for visual editing capabilities
91
+ transformIndexHtml(html) {
92
+ // Inject the Tailwind CSS CDN script right before the closing </head> tag
93
+ const tailwindScript = ` <!-- Tailwind CSS CDN for visual editing -->\n <script src="https://cdn.tailwindcss.com"></script>\n `;
94
+ return html.replace("</head>", tailwindScript + "</head>");
95
+ },
96
+ transform(code, id) {
97
+ // Skip node_modules and visual-edit-agent itself
98
+ if (id.includes("node_modules") || id.includes("visual-edit-agent")) {
99
+ return null;
100
+ }
101
+ // Process JS/JSX/TS/TSX files
102
+ if (!id.match(/\.(jsx?|tsx?)$/)) {
103
+ return null;
104
+ }
105
+ // Extract filename from path, preserving pages/ or components/ structure
106
+ const pathParts = id.split("/");
107
+ let filename;
108
+ // Check if this is a pages or components file
109
+ if (id.includes("/pages/")) {
110
+ const pagesIndex = pathParts.findIndex((part) => part === "pages");
111
+ if (pagesIndex >= 0 && pagesIndex < pathParts.length - 1) {
112
+ // Get all parts from 'pages' to the file, preserving nested structure
113
+ const relevantParts = pathParts.slice(pagesIndex, pathParts.length);
114
+ const lastPart = relevantParts[relevantParts.length - 1];
115
+ // Remove file extension from the last part
116
+ relevantParts[relevantParts.length - 1] = lastPart.includes(".")
117
+ ? lastPart.split(".")[0]
118
+ : lastPart;
119
+ filename = relevantParts.join("/");
120
+ }
121
+ else {
122
+ filename = pathParts[pathParts.length - 1];
123
+ if (filename.includes(".")) {
124
+ filename = filename.split(".")[0];
125
+ }
126
+ }
127
+ }
128
+ else if (id.includes("/components/")) {
129
+ const componentsIndex = pathParts.findIndex((part) => part === "components");
130
+ if (componentsIndex >= 0 && componentsIndex < pathParts.length - 1) {
131
+ // Get all parts from 'components' to the file, preserving nested structure
132
+ const relevantParts = pathParts.slice(componentsIndex, pathParts.length);
133
+ const lastPart = relevantParts[relevantParts.length - 1];
134
+ // Remove file extension from the last part
135
+ relevantParts[relevantParts.length - 1] = lastPart.includes(".")
136
+ ? lastPart.split(".")[0]
137
+ : lastPart;
138
+ filename = relevantParts.join("/");
139
+ }
140
+ else {
141
+ filename = pathParts[pathParts.length - 1];
142
+ if (filename.includes(".")) {
143
+ filename = filename.split(".")[0];
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ // For other files (like layout), just use the filename
149
+ filename = pathParts[pathParts.length - 1];
150
+ if (filename.includes(".")) {
151
+ filename = filename.split(".")[0];
152
+ }
153
+ }
154
+ try {
155
+ // Parse the code into an AST
156
+ const ast = parse(code, {
157
+ sourceType: "module",
158
+ plugins: [
159
+ "jsx",
160
+ "typescript",
161
+ "decorators-legacy",
162
+ "classProperties",
163
+ "objectRestSpread",
164
+ "functionBind",
165
+ "exportDefaultFrom",
166
+ "exportNamespaceFrom",
167
+ "dynamicImport",
168
+ "nullishCoalescingOperator",
169
+ "optionalChaining",
170
+ "asyncGenerators",
171
+ "bigInt",
172
+ "optionalCatchBinding",
173
+ "throwExpressions",
174
+ ],
175
+ });
176
+ // Traverse the AST and add source location and dynamic content attributes to JSX elements
177
+ let elementsProcessed = 0;
178
+ traverse.default(ast, {
179
+ JSXElement(path) {
180
+ const jsxElement = path.node;
181
+ const openingElement = jsxElement.openingElement;
182
+ // Skip fragments
183
+ if (t.isJSXFragment(jsxElement))
184
+ return;
185
+ // Skip if already has source location attribute
186
+ const hasSourceLocation = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
187
+ t.isJSXIdentifier(attr.name) &&
188
+ attr.name.name === "data-source-location");
189
+ if (hasSourceLocation)
190
+ return;
191
+ // Get line and column from AST node location
192
+ const { line, column } = openingElement.loc?.start || {
193
+ line: 1,
194
+ column: 0,
195
+ };
196
+ // Create the source location attribute
197
+ const sourceLocationAttr = t.jsxAttribute(t.jsxIdentifier("data-source-location"), t.stringLiteral(`${filename}:${line}:${column}`));
198
+ // Check if element has dynamic content
199
+ const isDynamic = checkIfElementHasDynamicContent(jsxElement);
200
+ // Create the dynamic content attribute
201
+ const dynamicContentAttr = t.jsxAttribute(t.jsxIdentifier("data-dynamic-content"), t.stringLiteral(isDynamic ? "true" : "false"));
202
+ // Add both attributes to the beginning of the attributes array
203
+ openingElement.attributes.unshift(sourceLocationAttr, dynamicContentAttr);
204
+ elementsProcessed++;
205
+ },
206
+ });
207
+ // Generate the code back from the AST
208
+ const result = generate.default(ast, {
209
+ compact: false,
210
+ concise: false,
211
+ retainLines: true,
212
+ });
213
+ return {
214
+ code: result.code,
215
+ map: null,
216
+ };
217
+ }
218
+ catch (error) {
219
+ console.error("Failed to add source location to JSX:", error);
220
+ return {
221
+ code: code, // Return original code on failure
222
+ map: null,
223
+ };
224
+ }
225
+ },
226
+ };
227
+ }
228
+ //# sourceMappingURL=visual-edit-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-edit-plugin.js","sourceRoot":"","sources":["../src/visual-edit-plugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,32 @@
1
1
  {
2
2
  "name": "@base44-preview/vite-plugin",
3
- "version": "0.1.0-dev.c16b316",
3
+ "version": "0.1.0-dev.ec354c8",
4
4
  "description": "The Vite plugin for base44 based applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "exports": {
8
- ".": "./dist/index.js"
8
+ ".": "./dist/index.js",
9
+ "./compat/*": "./compat/*"
9
10
  },
11
+ "files": [
12
+ "dist",
13
+ "src",
14
+ "compat"
15
+ ],
10
16
  "scripts": {
11
17
  "build": "tsc"
12
18
  },
13
19
  "devDependencies": {
20
+ "@types/babel__generator": "^7.27.0",
21
+ "@types/babel__traverse": "^7.28.0",
14
22
  "@types/node": "^24.6.2",
15
23
  "typescript": "^5.9.3",
16
24
  "vite": "^7.1.9"
25
+ },
26
+ "dependencies": {
27
+ "@babel/generator": "^7.28.5",
28
+ "@babel/parser": "^7.28.5",
29
+ "@babel/traverse": "^7.28.5",
30
+ "@babel/types": "^7.28.5"
17
31
  }
18
32
  }
@@ -0,0 +1,71 @@
1
+ /// <reference lib="dom" />
2
+
3
+ // Make HTMLElement available in non-browser environments
4
+ const { HTMLElement = class {} } = globalThis;
5
+
6
+ export class ErrorOverlay extends HTMLElement {
7
+ static getOverlayHTML() {
8
+ return `
9
+ <div>
10
+ </div>
11
+ `;
12
+ }
13
+ close() {
14
+ (this as any).parentNode?.removeChild(this);
15
+ }
16
+
17
+ static sendErrorToParent(
18
+ error: Error,
19
+ title: string,
20
+ details: string | undefined,
21
+ componentName: string | undefined
22
+ ) {
23
+ // Send error to parent using framewire
24
+ if (globalThis.window?.parent) {
25
+ try {
26
+ globalThis.window.parent?.postMessage(
27
+ {
28
+ type: "app_error",
29
+ error: { title, details, componentName, originalError: error },
30
+ },
31
+ "*"
32
+ );
33
+ } catch (error) {
34
+ console.warn(
35
+ "Failed to send error to iframe parent:",
36
+ (error as Error)?.message
37
+ );
38
+ }
39
+ }
40
+ }
41
+
42
+ constructor(error: Error) {
43
+ super();
44
+
45
+ const stack = error?.stack;
46
+ let componentName = stack?.match(/at\s+(\w+)\s+\(eval/)?.[1];
47
+ if (componentName === "eval") {
48
+ componentName = undefined;
49
+ }
50
+ const title = componentName
51
+ ? `in ${componentName}: ${error.message?.toString()}`
52
+ : error.message?.toString();
53
+ const details = error?.stack;
54
+
55
+ // Call editor frame with the error (via post message)
56
+ ErrorOverlay.sendErrorToParent(error, title, details, componentName);
57
+
58
+ // Create the overlay element using HTML template
59
+ const overlay = document.createElement("div");
60
+ overlay.innerHTML = ErrorOverlay.getOverlayHTML();
61
+
62
+ // Add to DOM
63
+ document.body.appendChild(overlay);
64
+ }
65
+ }
66
+
67
+ // vite/react-plugin transpiles classes with _SomeClass, so we need to replace all _ErrorOverlay with ErrorOverlay
68
+ export const errorOverlayCode = ErrorOverlay.toString().replaceAll(
69
+ "_ErrorOverlay",
70
+ "ErrorOverlay"
71
+ );
@@ -0,0 +1,18 @@
1
+ import { errorOverlayCode } from "./ErrorOverlay.js";
2
+ import type { Plugin } from "vite";
3
+
4
+ export function errorOverlayPlugin() {
5
+ return {
6
+ name: "error-overlay",
7
+ transform(code, id, opts = {}) {
8
+ if (opts?.ssr) return;
9
+
10
+ if (!id.includes("vite/dist/client/client.mjs")) return;
11
+
12
+ return code.replace(
13
+ "class ErrorOverlay",
14
+ errorOverlayCode + "\nclass OldErrorOverlay"
15
+ );
16
+ },
17
+ } as Plugin;
18
+ }