@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.
@@ -177,6 +177,274 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
177
177
  return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
178
178
  };
179
179
 
180
+ // src/utils/resolveConvention.ts
181
+ import { basename } from "path";
182
+ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
183
+ const value = Reflect.get(globalThis, CONVENTIONS_KEY);
184
+ if (isConventionsMap(value))
185
+ return value;
186
+ const empty = {};
187
+ return empty;
188
+ }, derivePageName = (pagePath) => {
189
+ const base = basename(pagePath);
190
+ const dotIndex = base.indexOf(".");
191
+ const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
192
+ return toPascal(name);
193
+ }, normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, ""), hasErrorConvention = (framework) => {
194
+ const conventions = getMap()[framework];
195
+ if (!conventions)
196
+ return false;
197
+ if (conventions.defaults?.error)
198
+ return true;
199
+ return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
200
+ }, resolveErrorConventionPath = (framework, pageName) => {
201
+ const conventions = getMap()[framework];
202
+ if (!conventions)
203
+ return;
204
+ const exact = conventions.pages?.[pageName]?.error;
205
+ if (exact)
206
+ return exact;
207
+ const normalizedPageName = normalizeConventionPageName(pageName);
208
+ for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
209
+ if (normalizeConventionPageName(candidate) === normalizedPageName) {
210
+ return page.error ?? conventions.defaults?.error;
211
+ }
212
+ }
213
+ return conventions.defaults?.error;
214
+ }, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
215
+ Reflect.set(globalThis, CONVENTIONS_KEY, map);
216
+ }, isDev = () => true, buildErrorProps = (error) => {
217
+ if (error instanceof Error) {
218
+ return {
219
+ name: error.name,
220
+ message: error.message,
221
+ ...isDev() && error.stack ? { stack: error.stack } : {}
222
+ };
223
+ }
224
+ return { message: String(error), name: "Error" };
225
+ }, renderReactError = async (conventionPath, errorProps) => {
226
+ const { createElement } = await import("react");
227
+ const { renderToReadableStream } = await import("react-dom/server");
228
+ const mod = await import(conventionPath);
229
+ const ErrorComponent = mod.default;
230
+ if (typeof ErrorComponent !== "function")
231
+ return null;
232
+ const element = createElement(ErrorComponent, errorProps);
233
+ const stream = await renderToReadableStream(element);
234
+ return new Response(stream, {
235
+ headers: { "Content-Type": "text/html" },
236
+ status: 500
237
+ });
238
+ }, renderSvelteError = async (conventionPath, errorProps) => {
239
+ const { render } = await import("svelte/server");
240
+ const mod = await import(conventionPath);
241
+ const ErrorComponent = mod.default;
242
+ if (!ErrorComponent)
243
+ return null;
244
+ const { head, body } = render(ErrorComponent, {
245
+ props: errorProps
246
+ });
247
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
248
+ return new Response(html, {
249
+ headers: { "Content-Type": "text/html" },
250
+ status: 500
251
+ });
252
+ }, unescapeVueStyles = (ssrBody) => {
253
+ let styles = "";
254
+ const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
255
+ styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
256
+ return "";
257
+ });
258
+ return { body, styles };
259
+ }, renderVueError = async (conventionPath, errorProps) => {
260
+ const { createSSRApp, h } = await import("vue");
261
+ const { renderToString } = await import("vue/server-renderer");
262
+ const mod = await import(conventionPath);
263
+ const ErrorComponent = mod.default;
264
+ if (!ErrorComponent)
265
+ return null;
266
+ const app = createSSRApp({
267
+ render: () => h(ErrorComponent, errorProps)
268
+ });
269
+ const rawBody = await renderToString(app);
270
+ const { styles, body } = unescapeVueStyles(rawBody);
271
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
272
+ return new Response(html, {
273
+ headers: { "Content-Type": "text/html" },
274
+ status: 500
275
+ });
276
+ }, renderAngularError = async (conventionPath, errorProps) => {
277
+ const mod = await import(conventionPath);
278
+ const renderFn = mod.default;
279
+ if (typeof renderFn !== "function")
280
+ return null;
281
+ const html = renderFn(errorProps);
282
+ return new Response(html, {
283
+ headers: { "Content-Type": "text/html" },
284
+ status: 500
285
+ });
286
+ }, 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) => {
287
+ const template = await Bun.file(conventionPath).text();
288
+ const html = replaceErrorTokens(template, errorProps);
289
+ return new Response(html, {
290
+ headers: { "Content-Type": "text/html" },
291
+ status: 500
292
+ });
293
+ }, logConventionRenderError = (framework, label, renderError) => {
294
+ const message = renderError instanceof Error ? renderError.message : "";
295
+ if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
296
+ 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}).`);
297
+ return;
298
+ }
299
+ console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
300
+ }, renderEmberError = async () => null, renderEmberNotFound = async () => null, ERROR_RENDERERS, tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
301
+ let conventionPath = resolveErrorConventionPath(framework, pageName);
302
+ if (!conventionPath && error instanceof Error && error.stack) {
303
+ for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
304
+ const candidate = match[1];
305
+ if (!candidate)
306
+ continue;
307
+ conventionPath = resolveErrorConventionPath(framework, candidate);
308
+ if (conventionPath)
309
+ break;
310
+ }
311
+ }
312
+ if (!conventionPath)
313
+ return null;
314
+ const renderer = ERROR_RENDERERS[framework];
315
+ if (!renderer)
316
+ return null;
317
+ try {
318
+ return await renderer(conventionPath, errorProps);
319
+ } catch (renderError) {
320
+ logConventionRenderError(framework, "error", renderError);
321
+ }
322
+ return null;
323
+ }, renderConventionError = async (framework, pageName, error) => {
324
+ const errorProps = buildErrorProps(error);
325
+ const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
326
+ if (frameworkResponse)
327
+ return frameworkResponse;
328
+ if (framework !== "html") {
329
+ const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
330
+ if (htmlResponse)
331
+ return htmlResponse;
332
+ }
333
+ return null;
334
+ }, renderReactNotFound = async (conventionPath) => {
335
+ const { createElement } = await import("react");
336
+ const { renderToReadableStream } = await import("react-dom/server");
337
+ const mod = await import(conventionPath);
338
+ const NotFoundComponent = mod.default;
339
+ if (typeof NotFoundComponent !== "function")
340
+ return null;
341
+ const element = createElement(NotFoundComponent);
342
+ const stream = await renderToReadableStream(element);
343
+ return new Response(stream, {
344
+ headers: { "Content-Type": "text/html" },
345
+ status: 404
346
+ });
347
+ }, renderSvelteNotFound = async (conventionPath) => {
348
+ const { render } = await import("svelte/server");
349
+ const mod = await import(conventionPath);
350
+ const NotFoundComponent = mod.default;
351
+ if (!NotFoundComponent)
352
+ return null;
353
+ const { head, body } = render(NotFoundComponent);
354
+ const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
355
+ return new Response(html, {
356
+ headers: { "Content-Type": "text/html" },
357
+ status: 404
358
+ });
359
+ }, renderVueNotFound = async (conventionPath) => {
360
+ const { createSSRApp, h } = await import("vue");
361
+ const { renderToString } = await import("vue/server-renderer");
362
+ const mod = await import(conventionPath);
363
+ const NotFoundComponent = mod.default;
364
+ if (!NotFoundComponent)
365
+ return null;
366
+ const app = createSSRApp({
367
+ render: () => h(NotFoundComponent)
368
+ });
369
+ const rawBody = await renderToString(app);
370
+ const { styles, body } = unescapeVueStyles(rawBody);
371
+ const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
372
+ return new Response(html, {
373
+ headers: { "Content-Type": "text/html" },
374
+ status: 404
375
+ });
376
+ }, renderAngularNotFound = async (conventionPath) => {
377
+ const mod = await import(conventionPath);
378
+ const renderFn = mod.default;
379
+ if (typeof renderFn !== "function")
380
+ return null;
381
+ const html = renderFn();
382
+ return new Response(html, {
383
+ headers: { "Content-Type": "text/html" },
384
+ status: 404
385
+ });
386
+ }, renderHtmlNotFound = async (conventionPath) => {
387
+ const html = await Bun.file(conventionPath).text();
388
+ return new Response(html, {
389
+ headers: { "Content-Type": "text/html" },
390
+ status: 404
391
+ });
392
+ }, NOT_FOUND_RENDERERS, renderConventionNotFound = async (framework) => {
393
+ const conventionPath = resolveNotFoundConventionPath(framework);
394
+ if (!conventionPath)
395
+ return null;
396
+ const renderer = NOT_FOUND_RENDERERS[framework];
397
+ if (!renderer)
398
+ return null;
399
+ try {
400
+ return await renderer(conventionPath);
401
+ } catch (renderError) {
402
+ logConventionRenderError(framework, "not-found", renderError);
403
+ }
404
+ return null;
405
+ }, NOT_FOUND_PRIORITY, renderFirstNotFound = async () => {
406
+ const renderNext = async (frameworks) => {
407
+ const [framework, ...remaining] = frameworks;
408
+ if (!framework) {
409
+ return null;
410
+ }
411
+ if (!getMap()[framework]?.defaults?.notFound) {
412
+ return renderNext(remaining);
413
+ }
414
+ const response = await renderConventionNotFound(framework);
415
+ if (response) {
416
+ return response;
417
+ }
418
+ return renderNext(remaining);
419
+ };
420
+ return renderNext(NOT_FOUND_PRIORITY);
421
+ };
422
+ var init_resolveConvention = __esm(() => {
423
+ ERROR_RENDERERS = {
424
+ angular: renderAngularError,
425
+ ember: renderEmberError,
426
+ html: renderHtmlError,
427
+ react: renderReactError,
428
+ svelte: renderSvelteError,
429
+ vue: renderVueError
430
+ };
431
+ NOT_FOUND_RENDERERS = {
432
+ angular: renderAngularNotFound,
433
+ ember: renderEmberNotFound,
434
+ html: renderHtmlNotFound,
435
+ react: renderReactNotFound,
436
+ svelte: renderSvelteNotFound,
437
+ vue: renderVueNotFound
438
+ };
439
+ NOT_FOUND_PRIORITY = [
440
+ "react",
441
+ "svelte",
442
+ "vue",
443
+ "angular",
444
+ "html"
445
+ ];
446
+ });
447
+
180
448
  // src/utils/registerClientScript.ts
181
449
  var scriptRegistry, requestCounter = 0, getRequestId = () => `req_${Date.now()}_${++requestCounter}`, ssrContextGetter = null, getSsrContextId = () => ssrContextGetter?.() || Object.getOwnPropertyDescriptor(globalThis, "__absolutejs_requestId")?.value, registerClientScript = (script, requestId) => {
182
450
  const id = requestId || getSsrContextId() || getRequestId();
@@ -504,6 +772,75 @@ var init_angularDeps = __esm(() => {
504
772
  init_resolveAngularPackage();
505
773
  });
506
774
 
775
+ // src/utils/spaRouteManifest.ts
776
+ import { basename as basename2 } from "path";
777
+ var SPA_ROUTES_KEY = "__absoluteSpaRoutes", setSpaRouteManifest = (hosts) => {
778
+ Reflect.set(globalThis, SPA_ROUTES_KEY, hosts);
779
+ }, getSpaRouteManifest = () => {
780
+ const value = Reflect.get(globalThis, SPA_ROUTES_KEY);
781
+ return Array.isArray(value) ? value : [];
782
+ }, normalizePath = (path) => {
783
+ const withLeadingSlash = path.startsWith("/") ? path : `/${path}`;
784
+ const trimmed = withLeadingSlash.replace(/\/+$/, "");
785
+ return trimmed || "/";
786
+ }, fullRoutePath = (baseHref, routePath) => {
787
+ const base = normalizePath(baseHref);
788
+ const route = normalizePath(routePath);
789
+ if (base !== "/" && (route === base || route.startsWith(`${base}/`))) {
790
+ return route;
791
+ }
792
+ if (base === "/")
793
+ return route;
794
+ return normalizePath(`${base}/${route.replace(/^\/+/, "")}`);
795
+ }, routePattern = (path) => {
796
+ const segments = normalizePath(path).split("/").filter(Boolean);
797
+ let expression = "^";
798
+ for (const segment of segments) {
799
+ if (segment === "*" || segment === "**") {
800
+ expression += "(?:/.*)?";
801
+ continue;
802
+ }
803
+ const parameter = /^:[A-Za-z_$][A-Za-z0-9_$]*(?:\((.*)\))?(\?)?$/.exec(segment);
804
+ if (parameter) {
805
+ const valuePattern = parameter[1] || "[^/]+";
806
+ expression += parameter[2] ? `(?:/${valuePattern})?` : `/${valuePattern}`;
807
+ continue;
808
+ }
809
+ expression += `/${segment.replace(/[.+?^${}()|[\]\\]/g, "\\$&")}`;
810
+ }
811
+ return new RegExp(`${expression || "^/"}/?$`);
812
+ }, sourcePageName = (sourceFile) => basename2(sourceFile).replace(/\.[^.]+$/, "").toLowerCase(), isKnownSpaRoute = (framework, pageName, request) => {
813
+ if (!request)
814
+ return true;
815
+ let pathname;
816
+ try {
817
+ pathname = normalizePath(new URL(request.url).pathname);
818
+ } catch {
819
+ return true;
820
+ }
821
+ const hosts = getSpaRouteManifest().filter((host) => {
822
+ if (host.framework !== framework)
823
+ return false;
824
+ if (sourcePageName(host.sourceFile) !== pageName.toLowerCase())
825
+ return false;
826
+ const base = normalizePath(host.baseHref);
827
+ return base === "/" || pathname === base || pathname.startsWith(`${base}/`);
828
+ });
829
+ if (hosts.length === 0)
830
+ return true;
831
+ return hosts.some((host) => host.routes.some((route) => routePattern(fullRoutePath(host.baseHref, route.path)).test(pathname)));
832
+ }, renderSpaNotFound = async (framework, pageName, request) => {
833
+ if (isKnownSpaRoute(framework, pageName, request))
834
+ return null;
835
+ return await renderFirstNotFound() ?? new Response("Not found", {
836
+ headers: { "Content-Type": "text/plain" },
837
+ status: 404
838
+ });
839
+ };
840
+ var init_spaRouteManifest = __esm(() => {
841
+ init_resolveConvention();
842
+ });
843
+
507
844
  // src/core/currentIslandRegistry.ts
508
845
  var requireCurrentIslandRegistry = () => {
509
846
  const registry = globalThis.__absoluteIslandRegistry;
@@ -2106,7 +2443,7 @@ var init_stylePreprocessor = __esm(() => {
2106
2443
 
2107
2444
  // src/core/svelteServerModule.ts
2108
2445
  import { mkdir as mkdir2, readdir as readdir2 } from "fs/promises";
2109
- import { basename as basename2, dirname as dirname3, extname as extname2, join as join6, relative as relative3, resolve as resolve5 } from "path";
2446
+ import { basename as basename3, dirname as dirname3, extname as extname2, join as join6, relative as relative3, resolve as resolve5 } from "path";
2110
2447
  var serverCacheRoot2, compiledModuleCache2, originalSourcePathCache, transpiler, ensureRelativeImportPath = (from, target) => {
2111
2448
  const importPath = relative3(dirname3(from), target).replace(/\\/g, "/");
2112
2449
  return importPath.startsWith(".") ? importPath : `./${importPath}`;
@@ -2137,7 +2474,7 @@ var serverCacheRoot2, compiledModuleCache2, originalSourcePathCache, transpiler,
2137
2474
  return found;
2138
2475
  }
2139
2476
  return searchDirectoryLevel(nextStack, targetFileName);
2140
- }, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename2(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
2477
+ }, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename3(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
2141
2478
  const cachedPath = originalSourcePathCache.get(sourcePath);
2142
2479
  if (cachedPath !== undefined) {
2143
2480
  return cachedPath;
@@ -4126,7 +4463,7 @@ __export(exports_compileAngular, {
4126
4463
  compileAngular: () => compileAngular
4127
4464
  });
4128
4465
  import { existsSync as existsSync5, readFileSync as readFileSync5, promises as fs } from "fs";
4129
- import { join as join9, basename as basename3, sep, dirname as dirname5, resolve as resolve7, relative as relative5 } from "path";
4466
+ import { join as join9, basename as basename4, sep, dirname as dirname5, resolve as resolve7, relative as relative5 } from "path";
4130
4467
  var {Glob } = globalThis.Bun;
4131
4468
  import ts from "typescript";
4132
4469
  var traceAngularPhase = async (name, fn, metadata) => {
@@ -4501,7 +4838,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
4501
4838
  const originalGetDefaultLibFileName = host.getDefaultLibFileName;
4502
4839
  host.getDefaultLibFileName = (opts) => {
4503
4840
  const fileName = originalGetDefaultLibFileName ? originalGetDefaultLibFileName(opts) : "lib.d.ts";
4504
- return basename3(fileName);
4841
+ return basename4(fileName);
4505
4842
  };
4506
4843
  const originalGetSourceFile = host.getSourceFile;
4507
4844
  host.getSourceFile = (fileName, languageVersion, onError) => {
@@ -4934,7 +5271,7 @@ ${fields}
4934
5271
  };
4935
5272
  const toOutputPath = (sourcePath) => {
4936
5273
  const inputDir = dirname5(sourcePath);
4937
- const fileBase = basename3(sourcePath).replace(/\.[cm]?[tj]sx?$/, ".js");
5274
+ const fileBase = basename4(sourcePath).replace(/\.[cm]?[tj]sx?$/, ".js");
4938
5275
  if (inputDir === outDir || inputDir.startsWith(`${outDir}${sep}`)) {
4939
5276
  return join9(inputDir, fileBase);
4940
5277
  }
@@ -4990,7 +5327,7 @@ ${fields}
4990
5327
  const inputDir2 = dirname5(resolved);
4991
5328
  const relativeDir2 = inputDir2.startsWith(baseDir) ? inputDir2.substring(baseDir.length + 1) : inputDir2;
4992
5329
  const targetDir2 = join9(outDir, relativeDir2);
4993
- const targetPath2 = join9(targetDir2, basename3(resolved));
5330
+ const targetPath2 = join9(targetDir2, basename4(resolved));
4994
5331
  await fs.mkdir(targetDir2, { recursive: true });
4995
5332
  await fs.copyFile(resolved, targetPath2);
4996
5333
  allOutputs.push(targetPath2);
@@ -5005,7 +5342,7 @@ ${fields}
5005
5342
  const inlined = await inlineResources(sourceCode, dirname5(actualPath), stylePreprocessors);
5006
5343
  sourceCode = inlineTemplateAndLowerDeferSync(inlined.source, dirname5(actualPath)).source;
5007
5344
  const inputDir = dirname5(actualPath);
5008
- const fileBase = basename3(actualPath).replace(/\.[cm]?[tj]sx?$/, ".js");
5345
+ const fileBase = basename4(actualPath).replace(/\.[cm]?[tj]sx?$/, ".js");
5009
5346
  const targetPath = toOutputPath(actualPath);
5010
5347
  const targetDir = dirname5(targetPath);
5011
5348
  const relativeDir = relative5(outDir, targetDir).replace(/\\/g, "/");
@@ -5098,7 +5435,7 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
5098
5435
  let outputs = hmr ? await traceAngularPhase("jit/compile-entry", compileEntry, {
5099
5436
  entry: resolvedEntry
5100
5437
  }) : aotOutputs;
5101
- const fileBase = basename3(resolvedEntry).replace(/\.[tj]s$/, "");
5438
+ const fileBase = basename4(resolvedEntry).replace(/\.[tj]s$/, "");
5102
5439
  const jsName = `${fileBase}.js`;
5103
5440
  const compiledFallbackPaths = [
5104
5441
  join9(compiledRoot, relativeEntry),
@@ -5594,7 +5931,7 @@ init_constants();
5594
5931
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
5595
5932
  import { mkdir as mkdir4, symlink } from "fs/promises";
5596
5933
  import { tmpdir } from "os";
5597
- import { basename as basename4, dirname as dirname6, join as join10, resolve as resolve8 } from "path";
5934
+ import { basename as basename5, dirname as dirname6, join as join10, resolve as resolve8 } from "path";
5598
5935
  import { pathToFileURL as pathToFileURL2 } from "url";
5599
5936
 
5600
5937
  // src/core/islandPageContext.ts
@@ -5843,303 +6180,9 @@ var readSiblingCss = async (siblingJsPath) => {
5843
6180
  return "";
5844
6181
  }
5845
6182
  };
5846
- // src/utils/resolveConvention.ts
5847
- import { basename } from "path";
5848
- var CONVENTIONS_KEY = "__absoluteConventions";
5849
- var isConventionsMap = (value) => Boolean(value) && typeof value === "object";
5850
- var getMap = () => {
5851
- const value = Reflect.get(globalThis, CONVENTIONS_KEY);
5852
- if (isConventionsMap(value))
5853
- return value;
5854
- const empty = {};
5855
- return empty;
5856
- };
5857
- var derivePageName = (pagePath) => {
5858
- const base = basename(pagePath);
5859
- const dotIndex = base.indexOf(".");
5860
- const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
5861
- return toPascal(name);
5862
- };
5863
- var normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, "");
5864
- var hasErrorConvention = (framework) => {
5865
- const conventions = getMap()[framework];
5866
- if (!conventions)
5867
- return false;
5868
- if (conventions.defaults?.error)
5869
- return true;
5870
- return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
5871
- };
5872
- var resolveErrorConventionPath = (framework, pageName) => {
5873
- const conventions = getMap()[framework];
5874
- if (!conventions)
5875
- return;
5876
- const exact = conventions.pages?.[pageName]?.error;
5877
- if (exact)
5878
- return exact;
5879
- const normalizedPageName = normalizeConventionPageName(pageName);
5880
- for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
5881
- if (normalizeConventionPageName(candidate) === normalizedPageName) {
5882
- return page.error ?? conventions.defaults?.error;
5883
- }
5884
- }
5885
- return conventions.defaults?.error;
5886
- };
5887
- var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
5888
- var setConventions = (map) => {
5889
- Reflect.set(globalThis, CONVENTIONS_KEY, map);
5890
- };
5891
- var isDev = () => true;
5892
- var buildErrorProps = (error) => {
5893
- if (error instanceof Error) {
5894
- return {
5895
- name: error.name,
5896
- message: error.message,
5897
- ...isDev() && error.stack ? { stack: error.stack } : {}
5898
- };
5899
- }
5900
- return { message: String(error), name: "Error" };
5901
- };
5902
- var renderReactError = async (conventionPath, errorProps) => {
5903
- const { createElement } = await import("react");
5904
- const { renderToReadableStream } = await import("react-dom/server");
5905
- const mod = await import(conventionPath);
5906
- const ErrorComponent = mod.default;
5907
- if (typeof ErrorComponent !== "function")
5908
- return null;
5909
- const element = createElement(ErrorComponent, errorProps);
5910
- const stream = await renderToReadableStream(element);
5911
- return new Response(stream, {
5912
- headers: { "Content-Type": "text/html" },
5913
- status: 500
5914
- });
5915
- };
5916
- var renderSvelteError = async (conventionPath, errorProps) => {
5917
- const { render } = await import("svelte/server");
5918
- const mod = await import(conventionPath);
5919
- const ErrorComponent = mod.default;
5920
- if (!ErrorComponent)
5921
- return null;
5922
- const { head, body } = render(ErrorComponent, {
5923
- props: errorProps
5924
- });
5925
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
5926
- return new Response(html, {
5927
- headers: { "Content-Type": "text/html" },
5928
- status: 500
5929
- });
5930
- };
5931
- var unescapeVueStyles = (ssrBody) => {
5932
- let styles = "";
5933
- const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
5934
- styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
5935
- return "";
5936
- });
5937
- return { body, styles };
5938
- };
5939
- var renderVueError = async (conventionPath, errorProps) => {
5940
- const { createSSRApp, h } = await import("vue");
5941
- const { renderToString } = await import("vue/server-renderer");
5942
- const mod = await import(conventionPath);
5943
- const ErrorComponent = mod.default;
5944
- if (!ErrorComponent)
5945
- return null;
5946
- const app = createSSRApp({
5947
- render: () => h(ErrorComponent, errorProps)
5948
- });
5949
- const rawBody = await renderToString(app);
5950
- const { styles, body } = unescapeVueStyles(rawBody);
5951
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
5952
- return new Response(html, {
5953
- headers: { "Content-Type": "text/html" },
5954
- status: 500
5955
- });
5956
- };
5957
- var renderAngularError = async (conventionPath, errorProps) => {
5958
- const mod = await import(conventionPath);
5959
- const renderFn = mod.default;
5960
- if (typeof renderFn !== "function")
5961
- return null;
5962
- const html = renderFn(errorProps);
5963
- return new Response(html, {
5964
- headers: { "Content-Type": "text/html" },
5965
- status: 500
5966
- });
5967
- };
5968
- var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5969
- 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) : "");
5970
- var renderHtmlError = async (conventionPath, errorProps) => {
5971
- const template = await Bun.file(conventionPath).text();
5972
- const html = replaceErrorTokens(template, errorProps);
5973
- return new Response(html, {
5974
- headers: { "Content-Type": "text/html" },
5975
- status: 500
5976
- });
5977
- };
5978
- var logConventionRenderError = (framework, label, renderError) => {
5979
- const message = renderError instanceof Error ? renderError.message : "";
5980
- if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
5981
- 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}).`);
5982
- return;
5983
- }
5984
- console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
5985
- };
5986
- var renderEmberError = async () => null;
5987
- var renderEmberNotFound = async () => null;
5988
- var ERROR_RENDERERS = {
5989
- angular: renderAngularError,
5990
- ember: renderEmberError,
5991
- html: renderHtmlError,
5992
- react: renderReactError,
5993
- svelte: renderSvelteError,
5994
- vue: renderVueError
5995
- };
5996
- var tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
5997
- let conventionPath = resolveErrorConventionPath(framework, pageName);
5998
- if (!conventionPath && error instanceof Error && error.stack) {
5999
- for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
6000
- const candidate = match[1];
6001
- if (!candidate)
6002
- continue;
6003
- conventionPath = resolveErrorConventionPath(framework, candidate);
6004
- if (conventionPath)
6005
- break;
6006
- }
6007
- }
6008
- if (!conventionPath)
6009
- return null;
6010
- const renderer = ERROR_RENDERERS[framework];
6011
- if (!renderer)
6012
- return null;
6013
- try {
6014
- return await renderer(conventionPath, errorProps);
6015
- } catch (renderError) {
6016
- logConventionRenderError(framework, "error", renderError);
6017
- }
6018
- return null;
6019
- };
6020
- var renderConventionError = async (framework, pageName, error) => {
6021
- const errorProps = buildErrorProps(error);
6022
- const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
6023
- if (frameworkResponse)
6024
- return frameworkResponse;
6025
- if (framework !== "html") {
6026
- const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
6027
- if (htmlResponse)
6028
- return htmlResponse;
6029
- }
6030
- return null;
6031
- };
6032
- var renderReactNotFound = async (conventionPath) => {
6033
- const { createElement } = await import("react");
6034
- const { renderToReadableStream } = await import("react-dom/server");
6035
- const mod = await import(conventionPath);
6036
- const NotFoundComponent = mod.default;
6037
- if (typeof NotFoundComponent !== "function")
6038
- return null;
6039
- const element = createElement(NotFoundComponent);
6040
- const stream = await renderToReadableStream(element);
6041
- return new Response(stream, {
6042
- headers: { "Content-Type": "text/html" },
6043
- status: 404
6044
- });
6045
- };
6046
- var renderSvelteNotFound = async (conventionPath) => {
6047
- const { render } = await import("svelte/server");
6048
- const mod = await import(conventionPath);
6049
- const NotFoundComponent = mod.default;
6050
- if (!NotFoundComponent)
6051
- return null;
6052
- const { head, body } = render(NotFoundComponent);
6053
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
6054
- return new Response(html, {
6055
- headers: { "Content-Type": "text/html" },
6056
- status: 404
6057
- });
6058
- };
6059
- var renderVueNotFound = async (conventionPath) => {
6060
- const { createSSRApp, h } = await import("vue");
6061
- const { renderToString } = await import("vue/server-renderer");
6062
- const mod = await import(conventionPath);
6063
- const NotFoundComponent = mod.default;
6064
- if (!NotFoundComponent)
6065
- return null;
6066
- const app = createSSRApp({
6067
- render: () => h(NotFoundComponent)
6068
- });
6069
- const rawBody = await renderToString(app);
6070
- const { styles, body } = unescapeVueStyles(rawBody);
6071
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
6072
- return new Response(html, {
6073
- headers: { "Content-Type": "text/html" },
6074
- status: 404
6075
- });
6076
- };
6077
- var renderAngularNotFound = async (conventionPath) => {
6078
- const mod = await import(conventionPath);
6079
- const renderFn = mod.default;
6080
- if (typeof renderFn !== "function")
6081
- return null;
6082
- const html = renderFn();
6083
- return new Response(html, {
6084
- headers: { "Content-Type": "text/html" },
6085
- status: 404
6086
- });
6087
- };
6088
- var renderHtmlNotFound = async (conventionPath) => {
6089
- const html = await Bun.file(conventionPath).text();
6090
- return new Response(html, {
6091
- headers: { "Content-Type": "text/html" },
6092
- status: 404
6093
- });
6094
- };
6095
- var NOT_FOUND_RENDERERS = {
6096
- angular: renderAngularNotFound,
6097
- ember: renderEmberNotFound,
6098
- html: renderHtmlNotFound,
6099
- react: renderReactNotFound,
6100
- svelte: renderSvelteNotFound,
6101
- vue: renderVueNotFound
6102
- };
6103
- var renderConventionNotFound = async (framework) => {
6104
- const conventionPath = resolveNotFoundConventionPath(framework);
6105
- if (!conventionPath)
6106
- return null;
6107
- const renderer = NOT_FOUND_RENDERERS[framework];
6108
- if (!renderer)
6109
- return null;
6110
- try {
6111
- return await renderer(conventionPath);
6112
- } catch (renderError) {
6113
- logConventionRenderError(framework, "not-found", renderError);
6114
- }
6115
- return null;
6116
- };
6117
- var NOT_FOUND_PRIORITY = [
6118
- "react",
6119
- "svelte",
6120
- "vue",
6121
- "angular",
6122
- "html"
6123
- ];
6124
- var renderFirstNotFound = async () => {
6125
- const renderNext = async (frameworks) => {
6126
- const [framework, ...remaining] = frameworks;
6127
- if (!framework) {
6128
- return null;
6129
- }
6130
- if (!getMap()[framework]?.defaults?.notFound) {
6131
- return renderNext(remaining);
6132
- }
6133
- const response = await renderConventionNotFound(framework);
6134
- if (response) {
6135
- return response;
6136
- }
6137
- return renderNext(remaining);
6138
- };
6139
- return renderNext(NOT_FOUND_PRIORITY);
6140
- };
6141
6183
 
6142
6184
  // src/angular/pageHandler.ts
6185
+ init_resolveConvention();
6143
6186
  init_registerClientScript();
6144
6187
  init_angularDeps();
6145
6188
 
@@ -6218,6 +6261,9 @@ var buildRouterRedirectProviders = async (deps, responseInit) => {
6218
6261
  ];
6219
6262
  };
6220
6263
 
6264
+ // src/angular/pageHandler.ts
6265
+ init_spaRouteManifest();
6266
+
6221
6267
  // src/angular/lowerServerIslands.ts
6222
6268
  init_renderIslandMarkup();
6223
6269
  var ANGULAR_ISLAND_TAG_RE = /<absolute-island\b([^>]*)>[\s\S]*?<\/absolute-island>/gi;
@@ -6561,7 +6607,7 @@ var resolveRuntimeAngularModulePath = async (pagePath) => {
6561
6607
  const { compileAngularFileJIT: compileAngularFileJIT2 } = await Promise.resolve().then(() => (init_compileAngular(), exports_compileAngular));
6562
6608
  const cacheBuster = createAngularRuntimeCacheBuster();
6563
6609
  const outputs = await compileAngularFileJIT2(pagePath, outDir, process.cwd(), undefined, cacheBuster);
6564
- const expectedFileName = basename4(pagePath).replace(/\.ts$/, ".js");
6610
+ const expectedFileName = basename5(pagePath).replace(/\.ts$/, ".js");
6565
6611
  const runtimePagePath = outputs.find((output) => output.endsWith(`/${expectedFileName}`)) ?? outputs.find((output) => output.endsWith(`\\${expectedFileName}`)) ?? outputs[0] ?? pagePath;
6566
6612
  return {
6567
6613
  cacheBuster,
@@ -6598,6 +6644,9 @@ setSsrContextGetter(() => angularSsrContext.getStore());
6598
6644
  var handleAngularPageRequest = async (input) => {
6599
6645
  const requestId = `angular_${Date.now()}_${Math.random().toString(BASE_36_RADIX).substring(2, RANDOM_ID_END_INDEX)}`;
6600
6646
  return angularSsrContext.run(requestId, async () => {
6647
+ const spaNotFound = await renderSpaNotFound("angular", derivePageName(input.pagePath), input.request);
6648
+ if (spaNotFound)
6649
+ return withPageCacheHeaders(spaNotFound, input.request);
6601
6650
  await ensureAngularCompiler();
6602
6651
  const userHeadTag = input.headTag ?? "<head></head>";
6603
6652
  const resolvedIndexPath = input.indexPath;
@@ -6688,5 +6737,5 @@ export {
6688
6737
  ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
6689
6738
  };
6690
6739
 
6691
- //# debugId=23A0F9CA53938AFB64756E2164756E21
6740
+ //# debugId=F995F63C979D22B664756E2164756E21
6692
6741
  //# sourceMappingURL=server.js.map