@lovable.dev/vite-tanstack-config 2.7.5-rc.6 → 2.7.6
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.
- package/dist/index.cjs +591 -725
- package/dist/index.d.cts +56 -55
- package/dist/index.d.ts +56 -55
- package/dist/index.js +574 -697
- package/package.json +10 -10
package/dist/index.cjs
CHANGED
|
@@ -1,604 +1,505 @@
|
|
|
1
|
-
"
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
9
|
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
19
18
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
var HOP_BY_HOP = /* @__PURE__ */ new Set([
|
|
44
|
-
"host",
|
|
45
|
-
"connection",
|
|
46
|
-
"keep-alive",
|
|
47
|
-
"proxy-authenticate",
|
|
48
|
-
"proxy-authorization",
|
|
49
|
-
"te",
|
|
50
|
-
"trailer",
|
|
51
|
-
"transfer-encoding",
|
|
52
|
-
"upgrade",
|
|
53
|
-
"content-length",
|
|
54
|
-
"cookie"
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let vite = require("vite");
|
|
25
|
+
let node_https = require("node:https");
|
|
26
|
+
node_https = __toESM(node_https, 1);
|
|
27
|
+
//#region src/assetsProxyPlugin.ts
|
|
28
|
+
const ASSET_RE = /^\/__l5e\/assets-v1\//;
|
|
29
|
+
const PREVIEW_HOST_ENV = "LOVABLE_PREVIEW_HOST";
|
|
30
|
+
const HOP_BY_HOP = /* @__PURE__ */ new Set([
|
|
31
|
+
"host",
|
|
32
|
+
"connection",
|
|
33
|
+
"keep-alive",
|
|
34
|
+
"proxy-authenticate",
|
|
35
|
+
"proxy-authorization",
|
|
36
|
+
"te",
|
|
37
|
+
"trailer",
|
|
38
|
+
"transfer-encoding",
|
|
39
|
+
"upgrade",
|
|
40
|
+
"content-length",
|
|
41
|
+
"cookie"
|
|
55
42
|
]);
|
|
56
43
|
function pickRequestHeaders(src) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
44
|
+
const out = {};
|
|
45
|
+
for (const [k, v] of Object.entries(src)) {
|
|
46
|
+
if (v === void 0) continue;
|
|
47
|
+
if (HOP_BY_HOP.has(k.toLowerCase())) continue;
|
|
48
|
+
out[k] = v;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
66
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Forwards `/__l5e/assets-v1/*` requests from the Vite dev server to the
|
|
54
|
+
* Lovable preview proxy so assets resolve when the page is loaded directly
|
|
55
|
+
* from the sandbox dev server (e.g. `localhost:8080`) instead of via
|
|
56
|
+
* `*.lovable.app` / `*.lovableproject.com`.
|
|
57
|
+
*
|
|
58
|
+
* No-op unless `LOVABLE_PREVIEW_HOST` is set (host only, no scheme), e.g.
|
|
59
|
+
* `id-preview--<project-id>.lovable.app`.
|
|
60
|
+
*/
|
|
67
61
|
function lovableAssetsProxyPlugin() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
res.destroy(err);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
req.pipe(upstream);
|
|
111
|
-
};
|
|
112
|
-
server.middlewares.use(middleware);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
62
|
+
const previewHost = process.env[PREVIEW_HOST_ENV]?.trim();
|
|
63
|
+
return {
|
|
64
|
+
name: "lovable:assets-proxy",
|
|
65
|
+
apply: "serve",
|
|
66
|
+
configureServer(server) {
|
|
67
|
+
if (!previewHost) return;
|
|
68
|
+
const middleware = (req, res, next) => {
|
|
69
|
+
const url = req.url ?? "";
|
|
70
|
+
if (!ASSET_RE.test(url)) return next();
|
|
71
|
+
const upstream = node_https.default.request({
|
|
72
|
+
host: previewHost,
|
|
73
|
+
port: 443,
|
|
74
|
+
method: req.method,
|
|
75
|
+
path: url,
|
|
76
|
+
headers: {
|
|
77
|
+
...pickRequestHeaders(req.headers),
|
|
78
|
+
host: previewHost
|
|
79
|
+
}
|
|
80
|
+
}, (upRes) => {
|
|
81
|
+
res.statusCode = upRes.statusCode ?? 502;
|
|
82
|
+
for (const [k, v] of Object.entries(upRes.headers)) {
|
|
83
|
+
if (v === void 0) continue;
|
|
84
|
+
if (HOP_BY_HOP.has(k.toLowerCase())) continue;
|
|
85
|
+
res.setHeader(k, v);
|
|
86
|
+
}
|
|
87
|
+
upRes.pipe(res);
|
|
88
|
+
});
|
|
89
|
+
upstream.on("error", (err) => {
|
|
90
|
+
server.config.logger.warn(`[@lovable.dev/vite-tanstack-config] asset proxy ${url} → ${previewHost} failed: ${err.message}`);
|
|
91
|
+
if (!res.headersSent) {
|
|
92
|
+
res.statusCode = 502;
|
|
93
|
+
res.end();
|
|
94
|
+
} else res.destroy(err);
|
|
95
|
+
});
|
|
96
|
+
req.pipe(upstream);
|
|
97
|
+
};
|
|
98
|
+
server.middlewares.use(middleware);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
115
101
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/index.ts
|
|
104
|
+
const SANDBOX_ENV_VAR = "DEV_SERVER__PROJECT_PATH";
|
|
105
|
+
const LOVABLE_SANDBOX_ENV_VAR = "LOVABLE_SANDBOX";
|
|
120
106
|
function isSandboxEnvironment() {
|
|
121
|
-
|
|
107
|
+
return process.env[LOVABLE_SANDBOX_ENV_VAR] === "1" || !!process.env[SANDBOX_ENV_VAR];
|
|
122
108
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
109
|
+
const TOOL_MANAGED_WATCH_IGNORES = [
|
|
110
|
+
"**/.workspace/**",
|
|
111
|
+
"**/.agents/**",
|
|
112
|
+
"**/.claude/**",
|
|
113
|
+
"**/.lovable/**",
|
|
114
|
+
"**/.tanstack/tmp/**"
|
|
129
115
|
];
|
|
130
116
|
function logWarning(message) {
|
|
131
|
-
|
|
117
|
+
console.warn(`[@lovable.dev/vite-tanstack-config] ${message}`);
|
|
132
118
|
}
|
|
133
|
-
|
|
119
|
+
const NITRO_DEFAULT_PRESET_MIN = [
|
|
120
|
+
3,
|
|
121
|
+
0,
|
|
122
|
+
260603
|
|
123
|
+
];
|
|
134
124
|
async function nitroSupportsDefaultPreset() {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
125
|
+
try {
|
|
126
|
+
const { createRequire } = await import("node:module");
|
|
127
|
+
const { version } = createRequire(`${process.cwd()}/package.json`)("nitro/package.json");
|
|
128
|
+
const match = typeof version === "string" ? /^(\d+)\.(\d+)\.(\d+)/.exec(version) : null;
|
|
129
|
+
if (!match) return true;
|
|
130
|
+
const parts = [
|
|
131
|
+
Number(match[1]),
|
|
132
|
+
Number(match[2]),
|
|
133
|
+
Number(match[3])
|
|
134
|
+
];
|
|
135
|
+
for (let i = 0; i < 3; i++) if (parts[i] !== NITRO_DEFAULT_PRESET_MIN[i]) return parts[i] > NITRO_DEFAULT_PRESET_MIN[i];
|
|
136
|
+
return true;
|
|
137
|
+
} catch {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
151
140
|
}
|
|
152
141
|
function validateHeaders(config) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (headerKeys.length > 0) {
|
|
158
|
-
logWarning(`Your config includes server headers that will be removed in sandbox mode: ${headerKeys.join(", ")}`);
|
|
159
|
-
}
|
|
142
|
+
const headers = config.server?.headers;
|
|
143
|
+
if (!headers) return;
|
|
144
|
+
const headerKeys = Object.keys(headers);
|
|
145
|
+
if (headerKeys.length > 0) logWarning(`Your config includes server headers that will be removed in sandbox mode: ${headerKeys.join(", ")}`);
|
|
160
146
|
}
|
|
161
147
|
function isExternalUrl(url) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
148
|
+
try {
|
|
149
|
+
const parsed = new URL(url);
|
|
150
|
+
return ![
|
|
151
|
+
"localhost",
|
|
152
|
+
"127.0.0.1",
|
|
153
|
+
"::1",
|
|
154
|
+
"0.0.0.0",
|
|
155
|
+
"::"
|
|
156
|
+
].includes(parsed.hostname);
|
|
157
|
+
} catch {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
168
160
|
}
|
|
169
161
|
function validateProxy(config) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
} else if (proxyConfig) {
|
|
181
|
-
const target = typeof proxyConfig.target === "string" ? proxyConfig.target : void 0;
|
|
182
|
-
if (target && isExternalUrl(target)) {
|
|
183
|
-
logWarning(
|
|
184
|
-
`Proxy '${path}' targets external URL: ${target}. This may cause issues in the sandbox environment.`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
if (proxyConfig.ws) {
|
|
188
|
-
logWarning(`Proxy '${path}' enables WebSocket proxying, which may interfere with HMR.`);
|
|
189
|
-
}
|
|
190
|
-
if (proxyConfig.changeOrigin) {
|
|
191
|
-
logWarning(`Proxy '${path}' changes origin, which may cause CORS issues.`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
162
|
+
const proxy = config.server?.proxy;
|
|
163
|
+
if (!proxy) return;
|
|
164
|
+
for (const [path, proxyConfig] of Object.entries(proxy)) if (typeof proxyConfig === "string") {
|
|
165
|
+
if (isExternalUrl(proxyConfig)) logWarning(`Proxy '${path}' targets external URL: ${proxyConfig}. This may cause issues in the sandbox environment.`);
|
|
166
|
+
} else if (proxyConfig) {
|
|
167
|
+
const target = typeof proxyConfig.target === "string" ? proxyConfig.target : void 0;
|
|
168
|
+
if (target && isExternalUrl(target)) logWarning(`Proxy '${path}' targets external URL: ${target}. This may cause issues in the sandbox environment.`);
|
|
169
|
+
if (proxyConfig.ws) logWarning(`Proxy '${path}' enables WebSocket proxying, which may interfere with HMR.`);
|
|
170
|
+
if (proxyConfig.changeOrigin) logWarning(`Proxy '${path}' changes origin, which may cause CORS issues.`);
|
|
171
|
+
}
|
|
195
172
|
}
|
|
196
173
|
function validateCors(config) {
|
|
197
|
-
|
|
198
|
-
logWarning("Custom CORS config detected. Sandbox requires specific CORS settings for proxy compatibility.");
|
|
199
|
-
}
|
|
174
|
+
if (config.server?.cors && typeof config.server.cors !== "boolean" && config.server.cors !== null) logWarning("Custom CORS config detected. Sandbox requires specific CORS settings for proxy compatibility.");
|
|
200
175
|
}
|
|
201
176
|
function validatePort(config) {
|
|
202
|
-
|
|
203
|
-
logWarning(`Port ${config.server.port} configured, but sandbox requires port 8080. Using 8080.`);
|
|
204
|
-
}
|
|
177
|
+
if (config.server?.port && config.server.port !== 8080) logWarning(`Port ${config.server.port} configured, but sandbox requires port 8080. Using 8080.`);
|
|
205
178
|
}
|
|
206
179
|
function validateConfig(config) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
180
|
+
validateHeaders(config);
|
|
181
|
+
validateProxy(config);
|
|
182
|
+
validateCors(config);
|
|
183
|
+
validatePort(config);
|
|
211
184
|
}
|
|
212
185
|
function cleanServerConfig(config) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
186
|
+
if (config.server?.headers || config.server?.cors || config.server?.proxy) {
|
|
187
|
+
const { headers: _headers, cors: _cors, proxy: _proxy, ...serverRest } = config.server;
|
|
188
|
+
return {
|
|
189
|
+
...config,
|
|
190
|
+
server: serverRest
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return config;
|
|
221
194
|
}
|
|
222
195
|
function applyWatchDebounceDefaults(config) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
});
|
|
196
|
+
const existingWatch = config.server?.watch ?? {};
|
|
197
|
+
const existingAwaitWriteFinish = existingWatch.awaitWriteFinish;
|
|
198
|
+
const hasAwaitWriteFinishObject = !!existingAwaitWriteFinish && typeof existingAwaitWriteFinish === "object" && !Array.isArray(existingAwaitWriteFinish);
|
|
199
|
+
return (0, vite.mergeConfig)(config, { server: { watch: {
|
|
200
|
+
...existingWatch,
|
|
201
|
+
awaitWriteFinish: {
|
|
202
|
+
...hasAwaitWriteFinishObject ? existingAwaitWriteFinish : {},
|
|
203
|
+
stabilityThreshold: 1e3,
|
|
204
|
+
pollInterval: 100
|
|
205
|
+
}
|
|
206
|
+
} } });
|
|
238
207
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
208
|
+
const SSR_CAPTURE_KEY = "__LOVABLE_TANSTACK_CAPTURE_SSR_ERROR__";
|
|
209
|
+
const HANDLER_RAN_KEY = "__LOVABLE_TANSTACK_HANDLER_RAN__";
|
|
210
|
+
const BUILD_ERROR_MESSAGE = /transform failed with \d+ error|failed to parse source/i;
|
|
242
211
|
function isBuildError(error) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return true;
|
|
252
|
-
if (Array.isArray(e.errors) && e.errors.length > 0 && e.errors.every((x) => x != null && typeof x === "object" && "text" in x && "location" in x)) {
|
|
253
|
-
return true;
|
|
254
|
-
}
|
|
255
|
-
const message = typeof e.message === "string" ? e.message : "";
|
|
256
|
-
return BUILD_ERROR_MESSAGE.test(message);
|
|
212
|
+
if (typeof error === "string") return BUILD_ERROR_MESSAGE.test(error);
|
|
213
|
+
if (!error || typeof error !== "object") return false;
|
|
214
|
+
const e = error;
|
|
215
|
+
if (typeof e.plugin === "string" && (e.plugin.startsWith("vite:") || e.plugin.startsWith("esbuild:"))) return true;
|
|
216
|
+
if (e.frame != null && e.loc != null) return true;
|
|
217
|
+
if (Array.isArray(e.errors) && e.errors.length > 0 && e.errors.every((x) => x != null && typeof x === "object" && "text" in x && "location" in x)) return true;
|
|
218
|
+
const message = typeof e.message === "string" ? e.message : "";
|
|
219
|
+
return BUILD_ERROR_MESSAGE.test(message);
|
|
257
220
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
221
|
+
const BUILD_DIAGNOSTICS_PLUGIN_NAME = "lovable-build-error-diagnostics";
|
|
222
|
+
const MAX_DIAGNOSTIC_JSON_LENGTH = 6e3;
|
|
223
|
+
const MAX_DIAGNOSTIC_STRING_LENGTH = 2e3;
|
|
224
|
+
const MAX_DIAGNOSTIC_NESTED_ERRORS = 20;
|
|
225
|
+
const MAX_DIAGNOSTIC_DEPTH = 4;
|
|
226
|
+
const COMPACT_DIAGNOSTIC_STRING_LENGTH = 300;
|
|
227
|
+
const COMPACT_DIAGNOSTIC_NESTED_ERRORS = 3;
|
|
228
|
+
const COMPACT_DIAGNOSTIC_DEPTH = 3;
|
|
229
|
+
const DIAGNOSTIC_ERROR_FIELDS = [
|
|
230
|
+
"name",
|
|
231
|
+
"message",
|
|
232
|
+
"plugin",
|
|
233
|
+
"pluginCode",
|
|
234
|
+
"id",
|
|
235
|
+
"moduleId",
|
|
236
|
+
"hook",
|
|
237
|
+
"code",
|
|
238
|
+
"loc",
|
|
239
|
+
"frame",
|
|
240
|
+
"stack",
|
|
241
|
+
"cause"
|
|
279
242
|
];
|
|
280
243
|
function truncateDiagnosticString(value) {
|
|
281
|
-
|
|
244
|
+
return truncateDiagnosticStringTo(value, MAX_DIAGNOSTIC_STRING_LENGTH);
|
|
282
245
|
}
|
|
283
246
|
function truncateDiagnosticStringTo(value, maxLength) {
|
|
284
|
-
|
|
247
|
+
return value.length > maxLength ? `${value.slice(0, maxLength)}...[truncated]` : value;
|
|
285
248
|
}
|
|
286
249
|
function readDiagnosticProperty(value, key) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
250
|
+
try {
|
|
251
|
+
return value[key];
|
|
252
|
+
} catch (error) {
|
|
253
|
+
return `[unreadable: ${error instanceof Error ? error.message : String(error)}]`;
|
|
254
|
+
}
|
|
292
255
|
}
|
|
293
256
|
function serializeOwnDiagnosticProperties(value, depth, seen) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
output.properties_truncated = keys.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
304
|
-
}
|
|
305
|
-
return output;
|
|
257
|
+
const keys = Object.keys(value);
|
|
258
|
+
const output = {};
|
|
259
|
+
for (const key of keys.slice(0, MAX_DIAGNOSTIC_NESTED_ERRORS)) {
|
|
260
|
+
const nested = readDiagnosticProperty(value, key);
|
|
261
|
+
if (nested == null || nested === "") continue;
|
|
262
|
+
output[key] = serializeDiagnosticValue(nested, depth + 1, seen);
|
|
263
|
+
}
|
|
264
|
+
if (keys.length > MAX_DIAGNOSTIC_NESTED_ERRORS) output.properties_truncated = keys.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
265
|
+
return output;
|
|
306
266
|
}
|
|
307
267
|
function describeDiagnosticPrimitive(value) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (typeof value === "function")
|
|
313
|
-
return `[function ${value.name || "anonymous"}]`;
|
|
314
|
-
return String(value);
|
|
268
|
+
if (typeof value === "symbol") return value.description ? `Symbol(${value.description})` : "Symbol()";
|
|
269
|
+
if (typeof value === "bigint") return value.toString();
|
|
270
|
+
if (typeof value === "function") return `[function ${value.name || "anonymous"}]`;
|
|
271
|
+
return String(value);
|
|
315
272
|
}
|
|
316
273
|
function describeDiagnosticObject(value) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
return Object.prototype.toString.call(value);
|
|
274
|
+
const constructorName = value.constructor?.name;
|
|
275
|
+
if (typeof constructorName === "string" && constructorName !== "" && constructorName !== "Object") return `[${constructorName}]`;
|
|
276
|
+
return Object.prototype.toString.call(value);
|
|
322
277
|
}
|
|
323
278
|
function serializeDiagnosticValue(value, depth, seen) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
if (nestedErrors.length > MAX_DIAGNOSTIC_NESTED_ERRORS) {
|
|
355
|
-
output.errors_truncated = nestedErrors.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
356
|
-
}
|
|
357
|
-
} else if (nestedErrors != null && nestedErrors !== "") {
|
|
358
|
-
output.errors = serializeDiagnosticValue(nestedErrors, depth + 1, seen);
|
|
359
|
-
}
|
|
360
|
-
if (Object.keys(output).length > 0)
|
|
361
|
-
return output;
|
|
362
|
-
const ownProperties = serializeOwnDiagnosticProperties(record, depth, seen);
|
|
363
|
-
return Object.keys(ownProperties).length > 0 ? ownProperties : describeDiagnosticObject(value);
|
|
364
|
-
} catch (error) {
|
|
365
|
-
return `[unreadable object: ${error instanceof Error ? error.message : String(error)}]`;
|
|
366
|
-
} finally {
|
|
367
|
-
seen.delete(value);
|
|
368
|
-
}
|
|
279
|
+
if (value == null) return value;
|
|
280
|
+
if (typeof value === "string") return truncateDiagnosticString(value);
|
|
281
|
+
if (typeof value === "number" || typeof value === "boolean") return value;
|
|
282
|
+
if (typeof value !== "object") return describeDiagnosticPrimitive(value);
|
|
283
|
+
if (seen.has(value)) return "[circular]";
|
|
284
|
+
if (depth >= MAX_DIAGNOSTIC_DEPTH) return "[max depth]";
|
|
285
|
+
seen.add(value);
|
|
286
|
+
try {
|
|
287
|
+
if (Array.isArray(value)) return value.slice(0, MAX_DIAGNOSTIC_NESTED_ERRORS).map((item) => serializeDiagnosticValue(item, depth + 1, seen));
|
|
288
|
+
const record = value;
|
|
289
|
+
const output = {};
|
|
290
|
+
for (const field of DIAGNOSTIC_ERROR_FIELDS) {
|
|
291
|
+
if (!(field in record)) continue;
|
|
292
|
+
const nested = readDiagnosticProperty(record, field);
|
|
293
|
+
if (nested == null || nested === "") continue;
|
|
294
|
+
output[field] = serializeDiagnosticValue(nested, depth + 1, seen);
|
|
295
|
+
}
|
|
296
|
+
const nestedErrors = readDiagnosticProperty(record, "errors");
|
|
297
|
+
if (Array.isArray(nestedErrors)) {
|
|
298
|
+
output.errors = nestedErrors.slice(0, MAX_DIAGNOSTIC_NESTED_ERRORS).map((item) => serializeDiagnosticValue(item, depth + 1, seen));
|
|
299
|
+
if (nestedErrors.length > MAX_DIAGNOSTIC_NESTED_ERRORS) output.errors_truncated = nestedErrors.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
300
|
+
} else if (nestedErrors != null && nestedErrors !== "") output.errors = serializeDiagnosticValue(nestedErrors, depth + 1, seen);
|
|
301
|
+
if (Object.keys(output).length > 0) return output;
|
|
302
|
+
const ownProperties = serializeOwnDiagnosticProperties(record, depth, seen);
|
|
303
|
+
return Object.keys(ownProperties).length > 0 ? ownProperties : describeDiagnosticObject(value);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
return `[unreadable object: ${error instanceof Error ? error.message : String(error)}]`;
|
|
306
|
+
} finally {
|
|
307
|
+
seen.delete(value);
|
|
308
|
+
}
|
|
369
309
|
}
|
|
370
310
|
function compactDiagnosticValue(value, depth) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
continue;
|
|
396
|
-
output[key] = compactDiagnosticValue(nested, depth + 1);
|
|
397
|
-
}
|
|
398
|
-
if (keys.length > MAX_DIAGNOSTIC_NESTED_ERRORS) {
|
|
399
|
-
output.properties_truncated = keys.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
400
|
-
}
|
|
401
|
-
return output;
|
|
402
|
-
} catch (error) {
|
|
403
|
-
return `[unreadable object: ${error instanceof Error ? error.message : String(error)}]`;
|
|
404
|
-
}
|
|
311
|
+
if (value == null) return value;
|
|
312
|
+
if (typeof value === "string") return truncateDiagnosticStringTo(value, COMPACT_DIAGNOSTIC_STRING_LENGTH);
|
|
313
|
+
if (typeof value === "number" || typeof value === "boolean") return value;
|
|
314
|
+
if (typeof value !== "object") return describeDiagnosticPrimitive(value);
|
|
315
|
+
if (depth >= COMPACT_DIAGNOSTIC_DEPTH) return "[max depth]";
|
|
316
|
+
try {
|
|
317
|
+
if (Array.isArray(value)) {
|
|
318
|
+
const items = value.slice(0, COMPACT_DIAGNOSTIC_NESTED_ERRORS).map((item) => compactDiagnosticValue(item, depth + 1));
|
|
319
|
+
if (value.length > COMPACT_DIAGNOSTIC_NESTED_ERRORS) items.push(`[${value.length - COMPACT_DIAGNOSTIC_NESTED_ERRORS} items truncated]`);
|
|
320
|
+
return items;
|
|
321
|
+
}
|
|
322
|
+
const record = value;
|
|
323
|
+
const output = {};
|
|
324
|
+
const keys = Object.keys(record);
|
|
325
|
+
for (const key of keys.slice(0, MAX_DIAGNOSTIC_NESTED_ERRORS)) {
|
|
326
|
+
const nested = readDiagnosticProperty(record, key);
|
|
327
|
+
if (nested == null || nested === "") continue;
|
|
328
|
+
output[key] = compactDiagnosticValue(nested, depth + 1);
|
|
329
|
+
}
|
|
330
|
+
if (keys.length > MAX_DIAGNOSTIC_NESTED_ERRORS) output.properties_truncated = keys.length - MAX_DIAGNOSTIC_NESTED_ERRORS;
|
|
331
|
+
return output;
|
|
332
|
+
} catch (error) {
|
|
333
|
+
return `[unreadable object: ${error instanceof Error ? error.message : String(error)}]`;
|
|
334
|
+
}
|
|
405
335
|
}
|
|
406
336
|
function stringifyDiagnosticPayload(diagnostics) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
337
|
+
const full = JSON.stringify(diagnostics);
|
|
338
|
+
if (full && full.length <= MAX_DIAGNOSTIC_JSON_LENGTH) return full;
|
|
339
|
+
const compact = compactDiagnosticValue(diagnostics, 0);
|
|
340
|
+
const compactPayload = compact != null && typeof compact === "object" && !Array.isArray(compact) ? {
|
|
341
|
+
...compact,
|
|
342
|
+
diagnostics_truncated: true
|
|
343
|
+
} : {
|
|
344
|
+
diagnostics_truncated: true,
|
|
345
|
+
value: compact
|
|
346
|
+
};
|
|
347
|
+
const compactJson = JSON.stringify(compactPayload);
|
|
348
|
+
if (compactJson.length <= MAX_DIAGNOSTIC_JSON_LENGTH) return compactJson;
|
|
349
|
+
return JSON.stringify({
|
|
350
|
+
diagnostics_truncated: true,
|
|
351
|
+
message: "Diagnostic payload exceeded output budget."
|
|
352
|
+
});
|
|
419
353
|
}
|
|
420
354
|
function lovableBuildErrorDiagnostics() {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
name: BUILD_DIAGNOSTICS_PLUGIN_NAME,
|
|
450
|
-
apply: "build",
|
|
451
|
-
buildEnd(error) {
|
|
452
|
-
emitDiagnostics(error);
|
|
453
|
-
},
|
|
454
|
-
// Rolldown raises output-phase errors after a clean buildEnd; only
|
|
455
|
-
// renderError sees them.
|
|
456
|
-
renderError(error) {
|
|
457
|
-
emitDiagnostics(error);
|
|
458
|
-
}
|
|
459
|
-
};
|
|
355
|
+
let emitted = false;
|
|
356
|
+
const emitDiagnostics = (error) => {
|
|
357
|
+
if (!error || emitted) return;
|
|
358
|
+
emitted = true;
|
|
359
|
+
try {
|
|
360
|
+
const output = `\n[lovable-build-error-diagnostics]\n${stringifyDiagnosticPayload(serializeDiagnosticValue(error, 0, /* @__PURE__ */ new WeakSet()))}\n[/lovable-build-error-diagnostics]\n`;
|
|
361
|
+
let written = false;
|
|
362
|
+
const write = () => {
|
|
363
|
+
if (written) return;
|
|
364
|
+
written = true;
|
|
365
|
+
try {
|
|
366
|
+
process.stderr.write(output);
|
|
367
|
+
} catch {}
|
|
368
|
+
};
|
|
369
|
+
setImmediate(write);
|
|
370
|
+
process.once("exit", write);
|
|
371
|
+
} catch {}
|
|
372
|
+
};
|
|
373
|
+
return {
|
|
374
|
+
name: BUILD_DIAGNOSTICS_PLUGIN_NAME,
|
|
375
|
+
apply: "build",
|
|
376
|
+
buildEnd(error) {
|
|
377
|
+
emitDiagnostics(error);
|
|
378
|
+
},
|
|
379
|
+
renderError(error) {
|
|
380
|
+
emitDiagnostics(error);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
460
383
|
}
|
|
461
384
|
function devSsrErrorLogger() {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const normalizedId = id.replace(/\\/g, "/");
|
|
559
|
-
const isTargetModule = normalizedId.includes("/@tanstack/start-server-core/src/request-response.ts") || normalizedId.includes("/@tanstack/start-server-core/dist/esm/request-response.js");
|
|
560
|
-
if (!isTargetModule) {
|
|
561
|
-
return null;
|
|
562
|
-
}
|
|
563
|
-
const needle = "handler(request, requestOpts)";
|
|
564
|
-
if (!code.includes(needle)) {
|
|
565
|
-
return null;
|
|
566
|
-
}
|
|
567
|
-
return code.replace(
|
|
568
|
-
needle,
|
|
569
|
-
`(globalThis.${HANDLER_RAN_KEY}?.(typeof h3Event === "undefined" ? undefined : h3Event), Promise.resolve(${needle}).catch((err) => { globalThis.${SSR_CAPTURE_KEY}?.(err); throw err; }))`
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
|
-
};
|
|
385
|
+
let lastCapture;
|
|
386
|
+
const CAPTURE_TTL_MS = 5e3;
|
|
387
|
+
const handlerRanFlag = Symbol("lovableHandlerRan");
|
|
388
|
+
const capture = (error) => {
|
|
389
|
+
lastCapture = {
|
|
390
|
+
error,
|
|
391
|
+
at: Date.now()
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
const consumeCapture = () => {
|
|
395
|
+
if (!lastCapture) return void 0;
|
|
396
|
+
if (Date.now() - lastCapture.at > CAPTURE_TTL_MS) {
|
|
397
|
+
lastCapture = void 0;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const { error } = lastCapture;
|
|
401
|
+
lastCapture = void 0;
|
|
402
|
+
return error;
|
|
403
|
+
};
|
|
404
|
+
return {
|
|
405
|
+
name: "dev-ssr-error-logger",
|
|
406
|
+
apply: "serve",
|
|
407
|
+
configureServer(server) {
|
|
408
|
+
globalThis[SSR_CAPTURE_KEY] = capture;
|
|
409
|
+
globalThis[HANDLER_RAN_KEY] = (event) => {
|
|
410
|
+
const res = event?.node?.res;
|
|
411
|
+
if (res) res[handlerRanFlag] = true;
|
|
412
|
+
};
|
|
413
|
+
const g = globalThis;
|
|
414
|
+
if (typeof g.addEventListener === "function") {
|
|
415
|
+
const addListener = g.addEventListener;
|
|
416
|
+
addListener("error", (e) => capture(e.error ?? e));
|
|
417
|
+
addListener("unhandledrejection", (e) => capture(e.reason));
|
|
418
|
+
}
|
|
419
|
+
const onUnhandledRejection = (reason) => capture(reason);
|
|
420
|
+
process.on("unhandledRejection", onUnhandledRejection);
|
|
421
|
+
server.httpServer?.once("close", () => {
|
|
422
|
+
process.off("unhandledRejection", onUnhandledRejection);
|
|
423
|
+
});
|
|
424
|
+
server.middlewares.use((req, res, next) => {
|
|
425
|
+
let handled = false;
|
|
426
|
+
const handleErrorResponse = () => {
|
|
427
|
+
if (handled || res.statusCode < 500) return;
|
|
428
|
+
handled = true;
|
|
429
|
+
const captured = consumeCapture();
|
|
430
|
+
const ranHandler = Boolean(res[handlerRanFlag]);
|
|
431
|
+
let source;
|
|
432
|
+
if (!ranHandler) source = "vite";
|
|
433
|
+
else if (isBuildError(captured)) source = "build";
|
|
434
|
+
else source = "app";
|
|
435
|
+
if (!res.headersSent) try {
|
|
436
|
+
res.setHeader("x-lovable-error-source", source);
|
|
437
|
+
} catch {}
|
|
438
|
+
const where = [req.method, req.url].filter(Boolean).join(" ") || "the request";
|
|
439
|
+
let data;
|
|
440
|
+
if (captured instanceof Error) data = {
|
|
441
|
+
name: captured.name,
|
|
442
|
+
message: captured.message,
|
|
443
|
+
stack: captured.stack
|
|
444
|
+
};
|
|
445
|
+
else if (typeof captured === "string" && captured.length > 0) data = {
|
|
446
|
+
name: "Error",
|
|
447
|
+
message: captured
|
|
448
|
+
};
|
|
449
|
+
else if (ranHandler) data = { message: `The app returned ${res.statusCode} while handling ${where}. The error was handled by a route or error boundary, so no stack was captured — check the failing loader/route code and the dev server output.` };
|
|
450
|
+
else data = { message: `Dev server returned ${res.statusCode} for ${where} before the app handler ran. This is usually a Vite build/transform error — check the dev server output for the underlying error.` };
|
|
451
|
+
try {
|
|
452
|
+
server.ws.send({
|
|
453
|
+
type: "custom",
|
|
454
|
+
event: "server-ssr-error",
|
|
455
|
+
data
|
|
456
|
+
});
|
|
457
|
+
} catch {}
|
|
458
|
+
};
|
|
459
|
+
const origWriteHead = res.writeHead.bind(res);
|
|
460
|
+
res.writeHead = (...args) => {
|
|
461
|
+
if (typeof args[0] === "number") res.statusCode = args[0];
|
|
462
|
+
handleErrorResponse();
|
|
463
|
+
return origWriteHead(...args);
|
|
464
|
+
};
|
|
465
|
+
const origEnd = res.end.bind(res);
|
|
466
|
+
res.end = (...args) => {
|
|
467
|
+
handleErrorResponse();
|
|
468
|
+
return origEnd(...args);
|
|
469
|
+
};
|
|
470
|
+
next();
|
|
471
|
+
});
|
|
472
|
+
},
|
|
473
|
+
transform(code, id) {
|
|
474
|
+
const normalizedId = id.replace(/\\/g, "/");
|
|
475
|
+
if (!(normalizedId.includes("/@tanstack/start-server-core/src/request-response.ts") || normalizedId.includes("/@tanstack/start-server-core/dist/esm/request-response.js"))) return null;
|
|
476
|
+
const needle = "handler(request, requestOpts)";
|
|
477
|
+
if (!code.includes(needle)) return null;
|
|
478
|
+
return code.replace(needle, `(globalThis.${HANDLER_RAN_KEY}?.(typeof h3Event === "undefined" ? undefined : h3Event), Promise.resolve(${needle}).catch((err) => { globalThis.${SSR_CAPTURE_KEY}?.(err); throw err; }))`);
|
|
479
|
+
}
|
|
480
|
+
};
|
|
573
481
|
}
|
|
574
482
|
function devServerFnErrorLogger() {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const needle = "const unwrapped = res.result || res.error";
|
|
596
|
-
if (!code.includes(needle)) {
|
|
597
|
-
return null;
|
|
598
|
-
}
|
|
599
|
-
return code.replace(
|
|
600
|
-
needle,
|
|
601
|
-
`${needle}
|
|
483
|
+
const HMR_SEND_KEY = "__TANSTACK_SERVER_FN_HMR_SEND__";
|
|
484
|
+
return {
|
|
485
|
+
name: "dev-server-fn-error-logger",
|
|
486
|
+
apply: "serve",
|
|
487
|
+
enforce: "pre",
|
|
488
|
+
configureServer(server) {
|
|
489
|
+
globalThis[HMR_SEND_KEY] = (data) => {
|
|
490
|
+
server.ws.send({
|
|
491
|
+
type: "custom",
|
|
492
|
+
event: "server-fn-error",
|
|
493
|
+
data
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
},
|
|
497
|
+
transform(code, id) {
|
|
498
|
+
const normalizedId = id.replace(/\\/g, "/");
|
|
499
|
+
if (!(normalizedId.includes("/@tanstack/start-server-core/src/server-functions-handler.ts") || normalizedId.includes("/@tanstack/start-server-core/dist/esm/server-functions-handler.js"))) return null;
|
|
500
|
+
const needle = "const unwrapped = res.result || res.error";
|
|
501
|
+
if (!code.includes(needle)) return null;
|
|
502
|
+
return code.replace(needle, `${needle}
|
|
602
503
|
|
|
603
504
|
if (res?.error) {
|
|
604
505
|
const err = res.error
|
|
@@ -612,192 +513,157 @@ function devServerFnErrorLogger() {
|
|
|
612
513
|
stack: typeof err?.stack === 'string' ? err.stack : undefined,
|
|
613
514
|
}
|
|
614
515
|
globalThis.${HMR_SEND_KEY}?.(payload)
|
|
615
|
-
}`
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
};
|
|
516
|
+
}`);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
619
519
|
}
|
|
620
520
|
function defineConfig(configOrOptions = {}) {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
"@tanstack/react-query",
|
|
767
|
-
"@tanstack/query-core"
|
|
768
|
-
]
|
|
769
|
-
},
|
|
770
|
-
// Dep re-optimization rotates the optimized-dep hash and 504s tabs holding
|
|
771
|
-
// the old one; pre-bundle the always-present client deps + tolerate stale
|
|
772
|
-
// requests. React core only — including @tanstack/react-start would pull its
|
|
773
|
-
// node:async_hooks server entry into the client bundle and crash hydration.
|
|
774
|
-
optimizeDeps: {
|
|
775
|
-
include: ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "react/jsx-dev-runtime"],
|
|
776
|
-
ignoreOutdatedRequests: true
|
|
777
|
-
},
|
|
778
|
-
plugins: [...internalPlugins, ...options.plugins ?? []]
|
|
779
|
-
};
|
|
780
|
-
if (options.vite) {
|
|
781
|
-
config = (0, import_vite.mergeConfig)(config, options.vite);
|
|
782
|
-
}
|
|
783
|
-
if (isSandbox) {
|
|
784
|
-
validateConfig(config);
|
|
785
|
-
config = cleanServerConfig(
|
|
786
|
-
(0, import_vite.mergeConfig)(config, {
|
|
787
|
-
server: { host: "::", port: 8080, strictPort: true, watch: { ignored: [...TOOL_MANAGED_WATCH_IGNORES] } }
|
|
788
|
-
})
|
|
789
|
-
);
|
|
790
|
-
} else {
|
|
791
|
-
config = (0, import_vite.mergeConfig)({ server: { host: "::", port: 8080 } }, config);
|
|
792
|
-
}
|
|
793
|
-
if (isSandbox) {
|
|
794
|
-
return config;
|
|
795
|
-
}
|
|
796
|
-
return applyWatchDebounceDefaults(config);
|
|
797
|
-
};
|
|
521
|
+
return async (env) => {
|
|
522
|
+
const { command, mode } = env;
|
|
523
|
+
const isSandbox = isSandboxEnvironment();
|
|
524
|
+
const isDevBuild = command === "build" && mode === "development";
|
|
525
|
+
let options;
|
|
526
|
+
if (typeof configOrOptions === "function") options = { vite: await Promise.resolve(configOrOptions(env)) };
|
|
527
|
+
else if (configOrOptions instanceof Promise) options = { vite: await configOrOptions };
|
|
528
|
+
else {
|
|
529
|
+
const optionObject = configOrOptions && typeof configOrOptions === "object" ? configOrOptions : {};
|
|
530
|
+
if ("cloudflare" in optionObject) if (optionObject.cloudflare === false && !("nitro" in optionObject)) {
|
|
531
|
+
optionObject.nitro = false;
|
|
532
|
+
logWarning("`cloudflare: false` is deprecated in v2 — migrated to `nitro: false`. Update your config to drop the warning.");
|
|
533
|
+
} else logWarning("The `cloudflare` option was removed in v2. Use `nitro: false` to disable the deploy plugin, or `nitro: { preset: '...' }` to configure it. The `cloudflare` setting is being ignored.");
|
|
534
|
+
options = "vite" in optionObject || "serverFnErrorLogger" in optionObject || "ssrErrorLogger" in optionObject || "nitro" in optionObject || "tanstackStart" in optionObject || "react" in optionObject || "envDefine" in optionObject || "hmrGate" in optionObject ? optionObject : { vite: optionObject };
|
|
535
|
+
}
|
|
536
|
+
const internalPlugins = [];
|
|
537
|
+
if (mode === "development") {
|
|
538
|
+
const { devtools } = await import("@tanstack/devtools-vite");
|
|
539
|
+
internalPlugins.push(devtools({
|
|
540
|
+
logging: false,
|
|
541
|
+
eventBusConfig: { enabled: false },
|
|
542
|
+
enhancedLogs: { enabled: false },
|
|
543
|
+
consolePiping: { enabled: false },
|
|
544
|
+
removeDevtoolsOnBuild: false,
|
|
545
|
+
injectSource: { enabled: true }
|
|
546
|
+
}));
|
|
547
|
+
}
|
|
548
|
+
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
549
|
+
internalPlugins.push(tailwindcss());
|
|
550
|
+
const tsConfigPaths = (await import("vite-tsconfig-paths")).default;
|
|
551
|
+
internalPlugins.push(tsConfigPaths({ projects: ["./tsconfig.json"] }));
|
|
552
|
+
if (options.serverFnErrorLogger !== false) internalPlugins.push(devServerFnErrorLogger());
|
|
553
|
+
if (options.ssrErrorLogger !== false) internalPlugins.push(devSsrErrorLogger());
|
|
554
|
+
if (command === "build" && isSandbox) internalPlugins.push(lovableBuildErrorDiagnostics());
|
|
555
|
+
const { tanstackStart } = await import("@tanstack/react-start/plugin/vite");
|
|
556
|
+
const tanstackStartOptions = (0, vite.mergeConfig)({ importProtection: {
|
|
557
|
+
behavior: "error",
|
|
558
|
+
client: {
|
|
559
|
+
files: ["**/server/**"],
|
|
560
|
+
specifiers: ["server-only"]
|
|
561
|
+
}
|
|
562
|
+
} }, options.tanstackStart ?? {});
|
|
563
|
+
internalPlugins.push(tanstackStart(tanstackStartOptions));
|
|
564
|
+
const explicitNitro = options.nitro === true || typeof options.nitro === "object" && options.nitro !== null;
|
|
565
|
+
if (options.nitro !== false && command === "build") {
|
|
566
|
+
let nitroMod;
|
|
567
|
+
try {
|
|
568
|
+
nitroMod = await import("nitro/vite");
|
|
569
|
+
} catch (err) {
|
|
570
|
+
if (explicitNitro || isSandbox) {
|
|
571
|
+
const reason = explicitNitro ? `an explicit \`nitro\` option (${options.nitro === true ? "true" : "{ ... }"}) was set in vite.config.ts` : "running inside a Lovable sandbox";
|
|
572
|
+
throw new Error(`[@lovable.dev/vite-tanstack-config] ${reason}, but the \`nitro\` package isn't installed. Add \`nitro\` to your devDependencies (matches peerDependency >=3.0.260429-beta). Original import error: ${err instanceof Error ? err.message : String(err)}`);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (nitroMod) {
|
|
576
|
+
const { nitro } = nitroMod;
|
|
577
|
+
const userNitroOpts = typeof options.nitro === "object" && options.nitro ? options.nitro : {};
|
|
578
|
+
const nitroOpts = {
|
|
579
|
+
defaultPreset: "cloudflare-module",
|
|
580
|
+
...userNitroOpts
|
|
581
|
+
};
|
|
582
|
+
if (isSandbox) {
|
|
583
|
+
delete nitroOpts.defaultPreset;
|
|
584
|
+
nitroOpts.preset = "cloudflare-module";
|
|
585
|
+
nitroOpts.output = {
|
|
586
|
+
dir: "dist",
|
|
587
|
+
serverDir: "dist/server",
|
|
588
|
+
publicDir: "dist/client"
|
|
589
|
+
};
|
|
590
|
+
nitroOpts.cloudflare = {
|
|
591
|
+
nodeCompat: true,
|
|
592
|
+
deployConfig: true,
|
|
593
|
+
...userNitroOpts.cloudflare
|
|
594
|
+
};
|
|
595
|
+
} else if (!nitroOpts.preset && !await nitroSupportsDefaultPreset()) logWarning("The installed `nitro` predates the `defaultPreset` option (3.0.260603-beta), so the Cloudflare fallback is ignored and a zero-config build may target Node instead. Upgrade nitro to >=3.0.260603-beta, or set an explicit `nitro: { preset: \"cloudflare-module\" }`.");
|
|
596
|
+
internalPlugins.push(nitro(nitroOpts));
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
const viteReact = (await import("@vitejs/plugin-react")).default;
|
|
600
|
+
internalPlugins.push(viteReact(options.react));
|
|
601
|
+
if (command === "serve") {
|
|
602
|
+
const hmrGateOpt = options.hmrGate;
|
|
603
|
+
if (isSandbox ? hmrGateOpt !== false : !!hmrGateOpt) {
|
|
604
|
+
const { hmrGatePlugin } = await import("@lovable.dev/vite-plugin-hmr-gate");
|
|
605
|
+
const hmrGateOptions = typeof hmrGateOpt === "object" ? hmrGateOpt : {};
|
|
606
|
+
internalPlugins.push(hmrGatePlugin(hmrGateOptions));
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (command === "serve" && isSandbox) {
|
|
610
|
+
const { devServerBridgePlugin } = await import("@lovable.dev/vite-plugin-dev-server-bridge");
|
|
611
|
+
internalPlugins.push(devServerBridgePlugin());
|
|
612
|
+
}
|
|
613
|
+
if (command === "serve") internalPlugins.push(lovableAssetsProxyPlugin());
|
|
614
|
+
let envDefine = {};
|
|
615
|
+
if (options.envDefine !== false) {
|
|
616
|
+
const loadedEnv = (0, vite.loadEnv)(mode, process.cwd(), "VITE_");
|
|
617
|
+
for (const [key, value] of Object.entries(loadedEnv)) envDefine[`import.meta.env.${key}`] = JSON.stringify(value);
|
|
618
|
+
}
|
|
619
|
+
let config = {
|
|
620
|
+
define: envDefine,
|
|
621
|
+
...isDevBuild ? {
|
|
622
|
+
environments: { client: { define: { "process.env.NODE_ENV": JSON.stringify("development") } } },
|
|
623
|
+
esbuild: { keepNames: true }
|
|
624
|
+
} : {},
|
|
625
|
+
css: { transformer: "lightningcss" },
|
|
626
|
+
resolve: {
|
|
627
|
+
alias: { "@": `${process.cwd()}/src` },
|
|
628
|
+
dedupe: [
|
|
629
|
+
"react",
|
|
630
|
+
"react-dom",
|
|
631
|
+
"react/jsx-runtime",
|
|
632
|
+
"react/jsx-dev-runtime",
|
|
633
|
+
"@tanstack/react-query",
|
|
634
|
+
"@tanstack/query-core"
|
|
635
|
+
]
|
|
636
|
+
},
|
|
637
|
+
optimizeDeps: {
|
|
638
|
+
include: [
|
|
639
|
+
"react",
|
|
640
|
+
"react-dom",
|
|
641
|
+
"react-dom/client",
|
|
642
|
+
"react/jsx-runtime",
|
|
643
|
+
"react/jsx-dev-runtime"
|
|
644
|
+
],
|
|
645
|
+
ignoreOutdatedRequests: true
|
|
646
|
+
},
|
|
647
|
+
plugins: [...internalPlugins, ...options.plugins ?? []]
|
|
648
|
+
};
|
|
649
|
+
if (options.vite) config = (0, vite.mergeConfig)(config, options.vite);
|
|
650
|
+
if (isSandbox) {
|
|
651
|
+
validateConfig(config);
|
|
652
|
+
config = cleanServerConfig((0, vite.mergeConfig)(config, { server: {
|
|
653
|
+
host: "::",
|
|
654
|
+
port: 8080,
|
|
655
|
+
strictPort: true,
|
|
656
|
+
watch: { ignored: [...TOOL_MANAGED_WATCH_IGNORES] },
|
|
657
|
+
hmr: { overlay: false }
|
|
658
|
+
} }));
|
|
659
|
+
} else config = (0, vite.mergeConfig)({ server: {
|
|
660
|
+
host: "::",
|
|
661
|
+
port: 8080
|
|
662
|
+
} }, config);
|
|
663
|
+
if (isSandbox) return config;
|
|
664
|
+
return applyWatchDebounceDefaults(config);
|
|
665
|
+
};
|
|
798
666
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
lovableAssetsProxyPlugin
|
|
803
|
-
});
|
|
667
|
+
//#endregion
|
|
668
|
+
exports.defineConfig = defineConfig;
|
|
669
|
+
exports.lovableAssetsProxyPlugin = lovableAssetsProxyPlugin;
|