@absolutejs/absolute 0.19.0-beta.1095 → 0.19.0-beta.1097

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.
@@ -98,6 +98,351 @@ var init_constants = __esm(() => {
98
98
  TWO_THIRDS = 2 / 3;
99
99
  });
100
100
 
101
+ // src/utils/stringModifiers.ts
102
+ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
103
+ if (!str.includes("-") && !str.includes("_")) {
104
+ return str.charAt(0).toUpperCase() + str.slice(1);
105
+ }
106
+ return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
107
+ };
108
+
109
+ // src/utils/resolveConvention.ts
110
+ import { basename } from "path";
111
+ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
112
+ const value = Reflect.get(globalThis, CONVENTIONS_KEY);
113
+ if (isConventionsMap(value))
114
+ return value;
115
+ const empty = {};
116
+ return empty;
117
+ }, derivePageName = (pagePath) => {
118
+ const base = basename(pagePath);
119
+ const dotIndex = base.indexOf(".");
120
+ const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
121
+ return toPascal(name);
122
+ }, normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, ""), hasErrorConvention = (framework) => {
123
+ const conventions = getMap()[framework];
124
+ if (!conventions)
125
+ return false;
126
+ if (conventions.defaults?.error)
127
+ return true;
128
+ return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
129
+ }, resolveErrorConventionPath = (framework, pageName) => {
130
+ const conventions = getMap()[framework];
131
+ if (!conventions)
132
+ return;
133
+ const exact = conventions.pages?.[pageName]?.error;
134
+ if (exact)
135
+ return exact;
136
+ const normalizedPageName = normalizeConventionPageName(pageName);
137
+ for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
138
+ if (normalizeConventionPageName(candidate) === normalizedPageName) {
139
+ return page.error ?? conventions.defaults?.error;
140
+ }
141
+ }
142
+ return conventions.defaults?.error;
143
+ }, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
144
+ Reflect.set(globalThis, CONVENTIONS_KEY, map);
145
+ }, isDev = () => true, buildErrorProps = (error) => {
146
+ if (error instanceof Error) {
147
+ return {
148
+ name: error.name,
149
+ message: error.message,
150
+ ...isDev() && error.stack ? { stack: error.stack } : {}
151
+ };
152
+ }
153
+ return { message: String(error), name: "Error" };
154
+ }, renderReactError = async (conventionPath, errorProps) => {
155
+ const { createElement } = await import("react");
156
+ const { renderToReadableStream } = await import("react-dom/server");
157
+ const mod = await import(conventionPath);
158
+ const ErrorComponent = mod.default;
159
+ if (typeof ErrorComponent !== "function")
160
+ return null;
161
+ const element = createElement(ErrorComponent, errorProps);
162
+ const stream = await renderToReadableStream(element);
163
+ return new Response(stream, {
164
+ headers: { "Content-Type": "text/html" },
165
+ status: 500
166
+ });
167
+ }, renderSvelteError = async (conventionPath, errorProps) => {
168
+ const { render } = await import("svelte/server");
169
+ const mod = await import(conventionPath);
170
+ const ErrorComponent = mod.default;
171
+ if (!ErrorComponent)
172
+ return null;
173
+ const { head, body } = render(ErrorComponent, {
174
+ props: errorProps
175
+ });
176
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
177
+ return new Response(html, {
178
+ headers: { "Content-Type": "text/html" },
179
+ status: 500
180
+ });
181
+ }, unescapeVueStyles = (ssrBody) => {
182
+ let styles = "";
183
+ const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
184
+ styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
185
+ return "";
186
+ });
187
+ return { body, styles };
188
+ }, renderVueError = async (conventionPath, errorProps) => {
189
+ const { createSSRApp, h } = await import("vue");
190
+ const { renderToString } = await import("vue/server-renderer");
191
+ const mod = await import(conventionPath);
192
+ const ErrorComponent = mod.default;
193
+ if (!ErrorComponent)
194
+ return null;
195
+ const app = createSSRApp({
196
+ render: () => h(ErrorComponent, errorProps)
197
+ });
198
+ const rawBody = await renderToString(app);
199
+ const { styles, body } = unescapeVueStyles(rawBody);
200
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
201
+ return new Response(html, {
202
+ headers: { "Content-Type": "text/html" },
203
+ status: 500
204
+ });
205
+ }, renderAngularError = async (conventionPath, errorProps) => {
206
+ const mod = await import(conventionPath);
207
+ const renderFn = mod.default;
208
+ if (typeof renderFn !== "function")
209
+ return null;
210
+ const html = renderFn(errorProps);
211
+ return new Response(html, {
212
+ headers: { "Content-Type": "text/html" },
213
+ status: 500
214
+ });
215
+ }, escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"), replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : ""), renderHtmlError = async (conventionPath, errorProps) => {
216
+ const template = await Bun.file(conventionPath).text();
217
+ const html = replaceErrorTokens(template, errorProps);
218
+ return new Response(html, {
219
+ headers: { "Content-Type": "text/html" },
220
+ status: 500
221
+ });
222
+ }, logConventionRenderError = (framework, label, renderError) => {
223
+ const message = renderError instanceof Error ? renderError.message : "";
224
+ if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
225
+ console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
226
+ return;
227
+ }
228
+ console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
229
+ }, renderEmberError = async () => null, renderEmberNotFound = async () => null, ERROR_RENDERERS, tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
230
+ let conventionPath = resolveErrorConventionPath(framework, pageName);
231
+ if (!conventionPath && error instanceof Error && error.stack) {
232
+ for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
233
+ const candidate = match[1];
234
+ if (!candidate)
235
+ continue;
236
+ conventionPath = resolveErrorConventionPath(framework, candidate);
237
+ if (conventionPath)
238
+ break;
239
+ }
240
+ }
241
+ if (!conventionPath)
242
+ return null;
243
+ const renderer = ERROR_RENDERERS[framework];
244
+ if (!renderer)
245
+ return null;
246
+ try {
247
+ return await renderer(conventionPath, errorProps);
248
+ } catch (renderError) {
249
+ logConventionRenderError(framework, "error", renderError);
250
+ }
251
+ return null;
252
+ }, renderConventionError = async (framework, pageName, error) => {
253
+ const errorProps = buildErrorProps(error);
254
+ const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
255
+ if (frameworkResponse)
256
+ return frameworkResponse;
257
+ if (framework !== "html") {
258
+ const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
259
+ if (htmlResponse)
260
+ return htmlResponse;
261
+ }
262
+ return null;
263
+ }, renderReactNotFound = async (conventionPath) => {
264
+ const { createElement } = await import("react");
265
+ const { renderToReadableStream } = await import("react-dom/server");
266
+ const mod = await import(conventionPath);
267
+ const NotFoundComponent = mod.default;
268
+ if (typeof NotFoundComponent !== "function")
269
+ return null;
270
+ const element = createElement(NotFoundComponent);
271
+ const stream = await renderToReadableStream(element);
272
+ return new Response(stream, {
273
+ headers: { "Content-Type": "text/html" },
274
+ status: 404
275
+ });
276
+ }, renderSvelteNotFound = async (conventionPath) => {
277
+ const { render } = await import("svelte/server");
278
+ const mod = await import(conventionPath);
279
+ const NotFoundComponent = mod.default;
280
+ if (!NotFoundComponent)
281
+ return null;
282
+ const { head, body } = render(NotFoundComponent);
283
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
284
+ return new Response(html, {
285
+ headers: { "Content-Type": "text/html" },
286
+ status: 404
287
+ });
288
+ }, renderVueNotFound = async (conventionPath) => {
289
+ const { createSSRApp, h } = await import("vue");
290
+ const { renderToString } = await import("vue/server-renderer");
291
+ const mod = await import(conventionPath);
292
+ const NotFoundComponent = mod.default;
293
+ if (!NotFoundComponent)
294
+ return null;
295
+ const app = createSSRApp({
296
+ render: () => h(NotFoundComponent)
297
+ });
298
+ const rawBody = await renderToString(app);
299
+ const { styles, body } = unescapeVueStyles(rawBody);
300
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
301
+ return new Response(html, {
302
+ headers: { "Content-Type": "text/html" },
303
+ status: 404
304
+ });
305
+ }, renderAngularNotFound = async (conventionPath) => {
306
+ const mod = await import(conventionPath);
307
+ const renderFn = mod.default;
308
+ if (typeof renderFn !== "function")
309
+ return null;
310
+ const html = renderFn();
311
+ return new Response(html, {
312
+ headers: { "Content-Type": "text/html" },
313
+ status: 404
314
+ });
315
+ }, renderHtmlNotFound = async (conventionPath) => {
316
+ const html = await Bun.file(conventionPath).text();
317
+ return new Response(html, {
318
+ headers: { "Content-Type": "text/html" },
319
+ status: 404
320
+ });
321
+ }, NOT_FOUND_RENDERERS, renderConventionNotFound = async (framework) => {
322
+ const conventionPath = resolveNotFoundConventionPath(framework);
323
+ if (!conventionPath)
324
+ return null;
325
+ const renderer = NOT_FOUND_RENDERERS[framework];
326
+ if (!renderer)
327
+ return null;
328
+ try {
329
+ return await renderer(conventionPath);
330
+ } catch (renderError) {
331
+ logConventionRenderError(framework, "not-found", renderError);
332
+ }
333
+ return null;
334
+ }, NOT_FOUND_PRIORITY, renderFirstNotFound = async () => {
335
+ const renderNext = async (frameworks) => {
336
+ const [framework, ...remaining] = frameworks;
337
+ if (!framework) {
338
+ return null;
339
+ }
340
+ if (!getMap()[framework]?.defaults?.notFound) {
341
+ return renderNext(remaining);
342
+ }
343
+ const response = await renderConventionNotFound(framework);
344
+ if (response) {
345
+ return response;
346
+ }
347
+ return renderNext(remaining);
348
+ };
349
+ return renderNext(NOT_FOUND_PRIORITY);
350
+ };
351
+ var init_resolveConvention = __esm(() => {
352
+ ERROR_RENDERERS = {
353
+ angular: renderAngularError,
354
+ ember: renderEmberError,
355
+ html: renderHtmlError,
356
+ react: renderReactError,
357
+ svelte: renderSvelteError,
358
+ vue: renderVueError
359
+ };
360
+ NOT_FOUND_RENDERERS = {
361
+ angular: renderAngularNotFound,
362
+ ember: renderEmberNotFound,
363
+ html: renderHtmlNotFound,
364
+ react: renderReactNotFound,
365
+ svelte: renderSvelteNotFound,
366
+ vue: renderVueNotFound
367
+ };
368
+ NOT_FOUND_PRIORITY = [
369
+ "react",
370
+ "svelte",
371
+ "vue",
372
+ "angular",
373
+ "html"
374
+ ];
375
+ });
376
+
377
+ // src/utils/spaRouteManifest.ts
378
+ import { basename as basename2 } from "path";
379
+ var SPA_ROUTES_KEY = "__absoluteSpaRoutes", setSpaRouteManifest = (hosts) => {
380
+ Reflect.set(globalThis, SPA_ROUTES_KEY, hosts);
381
+ }, getSpaRouteManifest = () => {
382
+ const value = Reflect.get(globalThis, SPA_ROUTES_KEY);
383
+ return Array.isArray(value) ? value : [];
384
+ }, normalizePath = (path) => {
385
+ const withLeadingSlash = path.startsWith("/") ? path : `/${path}`;
386
+ const trimmed = withLeadingSlash.replace(/\/+$/, "");
387
+ return trimmed || "/";
388
+ }, fullRoutePath = (baseHref, routePath) => {
389
+ const base = normalizePath(baseHref);
390
+ const route = normalizePath(routePath);
391
+ if (base !== "/" && (route === base || route.startsWith(`${base}/`))) {
392
+ return route;
393
+ }
394
+ if (base === "/")
395
+ return route;
396
+ return normalizePath(`${base}/${route.replace(/^\/+/, "")}`);
397
+ }, routePattern = (path) => {
398
+ const segments = normalizePath(path).split("/").filter(Boolean);
399
+ let expression = "^";
400
+ for (const segment of segments) {
401
+ if (segment === "*" || segment === "**") {
402
+ expression += "(?:/.*)?";
403
+ continue;
404
+ }
405
+ const parameter = /^:[A-Za-z_$][A-Za-z0-9_$]*(?:\((.*)\))?(\?)?$/.exec(segment);
406
+ if (parameter) {
407
+ const valuePattern = parameter[1] || "[^/]+";
408
+ expression += parameter[2] ? `(?:/${valuePattern})?` : `/${valuePattern}`;
409
+ continue;
410
+ }
411
+ expression += `/${segment.replace(/[.+?^${}()|[\]\\]/g, "\\$&")}`;
412
+ }
413
+ return new RegExp(`${expression || "^/"}/?$`);
414
+ }, sourcePageName = (sourceFile) => basename2(sourceFile).replace(/\.[^.]+$/, "").toLowerCase(), isKnownSpaRoute = (framework, pageName, request) => {
415
+ if (!request)
416
+ return true;
417
+ let pathname;
418
+ try {
419
+ pathname = normalizePath(new URL(request.url).pathname);
420
+ } catch {
421
+ return true;
422
+ }
423
+ const hosts = getSpaRouteManifest().filter((host) => {
424
+ if (host.framework !== framework)
425
+ return false;
426
+ if (sourcePageName(host.sourceFile) !== pageName.toLowerCase())
427
+ return false;
428
+ const base = normalizePath(host.baseHref);
429
+ return base === "/" || pathname === base || pathname.startsWith(`${base}/`);
430
+ });
431
+ if (hosts.length === 0)
432
+ return true;
433
+ return hosts.some((host) => host.routes.some((route) => routePattern(fullRoutePath(host.baseHref, route.path)).test(pathname)));
434
+ }, renderSpaNotFound = async (framework, pageName, request) => {
435
+ if (isKnownSpaRoute(framework, pageName, request))
436
+ return null;
437
+ return await renderFirstNotFound() ?? new Response("Not found", {
438
+ headers: { "Content-Type": "text/plain" },
439
+ status: 404
440
+ });
441
+ };
442
+ var init_spaRouteManifest = __esm(() => {
443
+ init_resolveConvention();
444
+ });
445
+
101
446
  // src/core/devRouteRegistrationCallsite.ts
102
447
  var exports_devRouteRegistrationCallsite = {};
103
448
  __export(exports_devRouteRegistrationCallsite, {
@@ -1121,14 +1466,6 @@ body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,r
1121
1466
  </html>`;
1122
1467
  };
1123
1468
 
1124
- // src/utils/stringModifiers.ts
1125
- var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
1126
- if (!str.includes("-") && !str.includes("_")) {
1127
- return str.charAt(0).toUpperCase() + str.slice(1);
1128
- }
1129
- return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
1130
- };
1131
-
1132
1469
  // src/cli/scripts/telemetry.ts
1133
1470
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
1134
1471
  import { homedir } from "os";
@@ -1365,7 +1702,7 @@ var runWithStreamingSlotRegistry = async (task) => {
1365
1702
  // src/vue/pageHandler.ts
1366
1703
  init_constants();
1367
1704
  import { readdir } from "fs/promises";
1368
- import { basename as basename2, dirname as dirname3 } from "path";
1705
+ import { basename as basename3, dirname as dirname3 } from "path";
1369
1706
 
1370
1707
  // src/utils/inlinePageCss.ts
1371
1708
  var siblingCssCache = new Map;
@@ -1479,6 +1816,9 @@ var resolveSpaChildCss = async (siblingJsPath, requestUrl) => {
1479
1816
  `);
1480
1817
  };
1481
1818
 
1819
+ // src/vue/pageHandler.ts
1820
+ init_spaRouteManifest();
1821
+
1482
1822
  // src/core/islandPageContext.ts
1483
1823
  var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient";
1484
1824
  var ISLAND_MARKER = 'data-island="true"';
@@ -1811,303 +2151,9 @@ var captureStreamingSlotWarningCallsite = () => {
1811
2151
  return extractCallsiteFromStack(stack);
1812
2152
  };
1813
2153
  var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage().run({ handlerCallsite: metadata?.handlerCallsite, hasWarned: false }, task);
1814
- // src/utils/resolveConvention.ts
1815
- import { basename } from "path";
1816
- var CONVENTIONS_KEY = "__absoluteConventions";
1817
- var isConventionsMap = (value) => Boolean(value) && typeof value === "object";
1818
- var getMap = () => {
1819
- const value = Reflect.get(globalThis, CONVENTIONS_KEY);
1820
- if (isConventionsMap(value))
1821
- return value;
1822
- const empty = {};
1823
- return empty;
1824
- };
1825
- var derivePageName = (pagePath) => {
1826
- const base = basename(pagePath);
1827
- const dotIndex = base.indexOf(".");
1828
- const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
1829
- return toPascal(name);
1830
- };
1831
- var normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, "");
1832
- var hasErrorConvention = (framework) => {
1833
- const conventions = getMap()[framework];
1834
- if (!conventions)
1835
- return false;
1836
- if (conventions.defaults?.error)
1837
- return true;
1838
- return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
1839
- };
1840
- var resolveErrorConventionPath = (framework, pageName) => {
1841
- const conventions = getMap()[framework];
1842
- if (!conventions)
1843
- return;
1844
- const exact = conventions.pages?.[pageName]?.error;
1845
- if (exact)
1846
- return exact;
1847
- const normalizedPageName = normalizeConventionPageName(pageName);
1848
- for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
1849
- if (normalizeConventionPageName(candidate) === normalizedPageName) {
1850
- return page.error ?? conventions.defaults?.error;
1851
- }
1852
- }
1853
- return conventions.defaults?.error;
1854
- };
1855
- var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
1856
- var setConventions = (map) => {
1857
- Reflect.set(globalThis, CONVENTIONS_KEY, map);
1858
- };
1859
- var isDev = () => true;
1860
- var buildErrorProps = (error) => {
1861
- if (error instanceof Error) {
1862
- return {
1863
- name: error.name,
1864
- message: error.message,
1865
- ...isDev() && error.stack ? { stack: error.stack } : {}
1866
- };
1867
- }
1868
- return { message: String(error), name: "Error" };
1869
- };
1870
- var renderReactError = async (conventionPath, errorProps) => {
1871
- const { createElement } = await import("react");
1872
- const { renderToReadableStream } = await import("react-dom/server");
1873
- const mod = await import(conventionPath);
1874
- const ErrorComponent = mod.default;
1875
- if (typeof ErrorComponent !== "function")
1876
- return null;
1877
- const element = createElement(ErrorComponent, errorProps);
1878
- const stream = await renderToReadableStream(element);
1879
- return new Response(stream, {
1880
- headers: { "Content-Type": "text/html" },
1881
- status: 500
1882
- });
1883
- };
1884
- var renderSvelteError = async (conventionPath, errorProps) => {
1885
- const { render } = await import("svelte/server");
1886
- const mod = await import(conventionPath);
1887
- const ErrorComponent = mod.default;
1888
- if (!ErrorComponent)
1889
- return null;
1890
- const { head, body } = render(ErrorComponent, {
1891
- props: errorProps
1892
- });
1893
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
1894
- return new Response(html, {
1895
- headers: { "Content-Type": "text/html" },
1896
- status: 500
1897
- });
1898
- };
1899
- var unescapeVueStyles = (ssrBody) => {
1900
- let styles = "";
1901
- const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
1902
- styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
1903
- return "";
1904
- });
1905
- return { body, styles };
1906
- };
1907
- var renderVueError = async (conventionPath, errorProps) => {
1908
- const { createSSRApp, h } = await import("vue");
1909
- const { renderToString } = await import("vue/server-renderer");
1910
- const mod = await import(conventionPath);
1911
- const ErrorComponent = mod.default;
1912
- if (!ErrorComponent)
1913
- return null;
1914
- const app = createSSRApp({
1915
- render: () => h(ErrorComponent, errorProps)
1916
- });
1917
- const rawBody = await renderToString(app);
1918
- const { styles, body } = unescapeVueStyles(rawBody);
1919
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
1920
- return new Response(html, {
1921
- headers: { "Content-Type": "text/html" },
1922
- status: 500
1923
- });
1924
- };
1925
- var renderAngularError = async (conventionPath, errorProps) => {
1926
- const mod = await import(conventionPath);
1927
- const renderFn = mod.default;
1928
- if (typeof renderFn !== "function")
1929
- return null;
1930
- const html = renderFn(errorProps);
1931
- return new Response(html, {
1932
- headers: { "Content-Type": "text/html" },
1933
- status: 500
1934
- });
1935
- };
1936
- var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1937
- var replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : "");
1938
- var renderHtmlError = async (conventionPath, errorProps) => {
1939
- const template = await Bun.file(conventionPath).text();
1940
- const html = replaceErrorTokens(template, errorProps);
1941
- return new Response(html, {
1942
- headers: { "Content-Type": "text/html" },
1943
- status: 500
1944
- });
1945
- };
1946
- var logConventionRenderError = (framework, label, renderError) => {
1947
- const message = renderError instanceof Error ? renderError.message : "";
1948
- if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
1949
- console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
1950
- return;
1951
- }
1952
- console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
1953
- };
1954
- var renderEmberError = async () => null;
1955
- var renderEmberNotFound = async () => null;
1956
- var ERROR_RENDERERS = {
1957
- angular: renderAngularError,
1958
- ember: renderEmberError,
1959
- html: renderHtmlError,
1960
- react: renderReactError,
1961
- svelte: renderSvelteError,
1962
- vue: renderVueError
1963
- };
1964
- var tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
1965
- let conventionPath = resolveErrorConventionPath(framework, pageName);
1966
- if (!conventionPath && error instanceof Error && error.stack) {
1967
- for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
1968
- const candidate = match[1];
1969
- if (!candidate)
1970
- continue;
1971
- conventionPath = resolveErrorConventionPath(framework, candidate);
1972
- if (conventionPath)
1973
- break;
1974
- }
1975
- }
1976
- if (!conventionPath)
1977
- return null;
1978
- const renderer = ERROR_RENDERERS[framework];
1979
- if (!renderer)
1980
- return null;
1981
- try {
1982
- return await renderer(conventionPath, errorProps);
1983
- } catch (renderError) {
1984
- logConventionRenderError(framework, "error", renderError);
1985
- }
1986
- return null;
1987
- };
1988
- var renderConventionError = async (framework, pageName, error) => {
1989
- const errorProps = buildErrorProps(error);
1990
- const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
1991
- if (frameworkResponse)
1992
- return frameworkResponse;
1993
- if (framework !== "html") {
1994
- const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
1995
- if (htmlResponse)
1996
- return htmlResponse;
1997
- }
1998
- return null;
1999
- };
2000
- var renderReactNotFound = async (conventionPath) => {
2001
- const { createElement } = await import("react");
2002
- const { renderToReadableStream } = await import("react-dom/server");
2003
- const mod = await import(conventionPath);
2004
- const NotFoundComponent = mod.default;
2005
- if (typeof NotFoundComponent !== "function")
2006
- return null;
2007
- const element = createElement(NotFoundComponent);
2008
- const stream = await renderToReadableStream(element);
2009
- return new Response(stream, {
2010
- headers: { "Content-Type": "text/html" },
2011
- status: 404
2012
- });
2013
- };
2014
- var renderSvelteNotFound = async (conventionPath) => {
2015
- const { render } = await import("svelte/server");
2016
- const mod = await import(conventionPath);
2017
- const NotFoundComponent = mod.default;
2018
- if (!NotFoundComponent)
2019
- return null;
2020
- const { head, body } = render(NotFoundComponent);
2021
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
2022
- return new Response(html, {
2023
- headers: { "Content-Type": "text/html" },
2024
- status: 404
2025
- });
2026
- };
2027
- var renderVueNotFound = async (conventionPath) => {
2028
- const { createSSRApp, h } = await import("vue");
2029
- const { renderToString } = await import("vue/server-renderer");
2030
- const mod = await import(conventionPath);
2031
- const NotFoundComponent = mod.default;
2032
- if (!NotFoundComponent)
2033
- return null;
2034
- const app = createSSRApp({
2035
- render: () => h(NotFoundComponent)
2036
- });
2037
- const rawBody = await renderToString(app);
2038
- const { styles, body } = unescapeVueStyles(rawBody);
2039
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
2040
- return new Response(html, {
2041
- headers: { "Content-Type": "text/html" },
2042
- status: 404
2043
- });
2044
- };
2045
- var renderAngularNotFound = async (conventionPath) => {
2046
- const mod = await import(conventionPath);
2047
- const renderFn = mod.default;
2048
- if (typeof renderFn !== "function")
2049
- return null;
2050
- const html = renderFn();
2051
- return new Response(html, {
2052
- headers: { "Content-Type": "text/html" },
2053
- status: 404
2054
- });
2055
- };
2056
- var renderHtmlNotFound = async (conventionPath) => {
2057
- const html = await Bun.file(conventionPath).text();
2058
- return new Response(html, {
2059
- headers: { "Content-Type": "text/html" },
2060
- status: 404
2061
- });
2062
- };
2063
- var NOT_FOUND_RENDERERS = {
2064
- angular: renderAngularNotFound,
2065
- ember: renderEmberNotFound,
2066
- html: renderHtmlNotFound,
2067
- react: renderReactNotFound,
2068
- svelte: renderSvelteNotFound,
2069
- vue: renderVueNotFound
2070
- };
2071
- var renderConventionNotFound = async (framework) => {
2072
- const conventionPath = resolveNotFoundConventionPath(framework);
2073
- if (!conventionPath)
2074
- return null;
2075
- const renderer = NOT_FOUND_RENDERERS[framework];
2076
- if (!renderer)
2077
- return null;
2078
- try {
2079
- return await renderer(conventionPath);
2080
- } catch (renderError) {
2081
- logConventionRenderError(framework, "not-found", renderError);
2082
- }
2083
- return null;
2084
- };
2085
- var NOT_FOUND_PRIORITY = [
2086
- "react",
2087
- "svelte",
2088
- "vue",
2089
- "angular",
2090
- "html"
2091
- ];
2092
- var renderFirstNotFound = async () => {
2093
- const renderNext = async (frameworks) => {
2094
- const [framework, ...remaining] = frameworks;
2095
- if (!framework) {
2096
- return null;
2097
- }
2098
- if (!getMap()[framework]?.defaults?.notFound) {
2099
- return renderNext(remaining);
2100
- }
2101
- const response = await renderConventionNotFound(framework);
2102
- if (response) {
2103
- return response;
2104
- }
2105
- return renderNext(remaining);
2106
- };
2107
- return renderNext(NOT_FOUND_PRIORITY);
2108
- };
2109
2154
 
2110
2155
  // src/vue/pageHandler.ts
2156
+ init_resolveConvention();
2111
2157
  var isRecord2 = (value) => typeof value === "object" && value !== null;
2112
2158
  var isGenericVueComponent = (value) => typeof value === "function" || isRecord2(value);
2113
2159
  var readHasIslands = (value) => {
@@ -2126,7 +2172,7 @@ var readHasSpaRoutes = (value) => isRecord2(value) && Array.isArray(value["route
2126
2172
  var readDefaultExport = (value) => isRecord2(value) ? value.default : undefined;
2127
2173
  var resolveCurrentGeneratedVueModulePath = async (pagePath) => {
2128
2174
  const pageDirectory = dirname3(pagePath);
2129
- const expectedPrefix = `${basename2(pagePath, ".js").split(".")[0]}.`;
2175
+ const expectedPrefix = `${basename3(pagePath, ".js").split(".")[0]}.`;
2130
2176
  try {
2131
2177
  const pageEntries = await readdir(pageDirectory, {
2132
2178
  withFileTypes: true
@@ -2183,6 +2229,9 @@ var handleVuePageRequest = async (input) => {
2183
2229
  throw new Error('handleVuePageRequest: `indexPath` is required when `client` is `"auto"` (the default). Pass `client: "none"` to ship a SSR-only page with no client bundle.');
2184
2230
  }
2185
2231
  try {
2232
+ const spaNotFound = await renderSpaNotFound("vue", derivePageName(resolvedPagePath), input.request);
2233
+ if (spaNotFound)
2234
+ return withPageCacheHeaders(spaNotFound, input.request);
2186
2235
  const handlerCallsite = resolvedOptions?.collectStreamingSlots === true ? undefined : getCurrentRouteRegistrationCallsite() ?? captureStreamingSlotWarningCallsite();
2187
2236
  const renderPageResponse = async () => {
2188
2237
  const resolvePageComponent = async () => {
@@ -2318,5 +2367,5 @@ export {
2318
2367
  applyVueRouterRedirect
2319
2368
  };
2320
2369
 
2321
- //# debugId=8B4147EC9E185DDA64756E2164756E21
2370
+ //# debugId=C241B2CD56B37B8A64756E2164756E21
2322
2371
  //# sourceMappingURL=server.js.map