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

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),
@@ -14535,7 +14872,7 @@ init_constants();
14535
14872
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
14536
14873
  import { mkdir as mkdir4, symlink } from "fs/promises";
14537
14874
  import { tmpdir } from "os";
14538
- import { basename as basename4, dirname as dirname6, join as join10, resolve as resolve8 } from "path";
14875
+ import { basename as basename5, dirname as dirname6, join as join10, resolve as resolve8 } from "path";
14539
14876
  import { pathToFileURL as pathToFileURL2 } from "url";
14540
14877
 
14541
14878
  // src/core/islandPageContext.ts
@@ -14784,303 +15121,9 @@ var readSiblingCss = async (siblingJsPath) => {
14784
15121
  return "";
14785
15122
  }
14786
15123
  };
14787
- // src/utils/resolveConvention.ts
14788
- import { basename } from "path";
14789
- var CONVENTIONS_KEY = "__absoluteConventions";
14790
- var isConventionsMap = (value) => Boolean(value) && typeof value === "object";
14791
- var getMap = () => {
14792
- const value = Reflect.get(globalThis, CONVENTIONS_KEY);
14793
- if (isConventionsMap(value))
14794
- return value;
14795
- const empty = {};
14796
- return empty;
14797
- };
14798
- var derivePageName = (pagePath) => {
14799
- const base = basename(pagePath);
14800
- const dotIndex = base.indexOf(".");
14801
- const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
14802
- return toPascal(name);
14803
- };
14804
- var normalizeConventionPageName = (name) => toPascal(name).replace(/\d+$/, "");
14805
- var hasErrorConvention = (framework) => {
14806
- const conventions = getMap()[framework];
14807
- if (!conventions)
14808
- return false;
14809
- if (conventions.defaults?.error)
14810
- return true;
14811
- return Object.values(conventions.pages ?? {}).some((page) => Boolean(page.error));
14812
- };
14813
- var resolveErrorConventionPath = (framework, pageName) => {
14814
- const conventions = getMap()[framework];
14815
- if (!conventions)
14816
- return;
14817
- const exact = conventions.pages?.[pageName]?.error;
14818
- if (exact)
14819
- return exact;
14820
- const normalizedPageName = normalizeConventionPageName(pageName);
14821
- for (const [candidate, page] of Object.entries(conventions.pages ?? {})) {
14822
- if (normalizeConventionPageName(candidate) === normalizedPageName) {
14823
- return page.error ?? conventions.defaults?.error;
14824
- }
14825
- }
14826
- return conventions.defaults?.error;
14827
- };
14828
- var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
14829
- var setConventions = (map) => {
14830
- Reflect.set(globalThis, CONVENTIONS_KEY, map);
14831
- };
14832
- var isDev = () => true;
14833
- var buildErrorProps = (error) => {
14834
- if (error instanceof Error) {
14835
- return {
14836
- name: error.name,
14837
- message: error.message,
14838
- ...isDev() && error.stack ? { stack: error.stack } : {}
14839
- };
14840
- }
14841
- return { message: String(error), name: "Error" };
14842
- };
14843
- var renderReactError = async (conventionPath, errorProps) => {
14844
- const { createElement } = await import("react");
14845
- const { renderToReadableStream } = await import("react-dom/server");
14846
- const mod = await import(conventionPath);
14847
- const ErrorComponent = mod.default;
14848
- if (typeof ErrorComponent !== "function")
14849
- return null;
14850
- const element = createElement(ErrorComponent, errorProps);
14851
- const stream = await renderToReadableStream(element);
14852
- return new Response(stream, {
14853
- headers: { "Content-Type": "text/html" },
14854
- status: 500
14855
- });
14856
- };
14857
- var renderSvelteError = async (conventionPath, errorProps) => {
14858
- const { render } = await import("svelte/server");
14859
- const mod = await import(conventionPath);
14860
- const ErrorComponent = mod.default;
14861
- if (!ErrorComponent)
14862
- return null;
14863
- const { head, body } = render(ErrorComponent, {
14864
- props: errorProps
14865
- });
14866
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
14867
- return new Response(html, {
14868
- headers: { "Content-Type": "text/html" },
14869
- status: 500
14870
- });
14871
- };
14872
- var unescapeVueStyles = (ssrBody) => {
14873
- let styles = "";
14874
- const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
14875
- styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
14876
- return "";
14877
- });
14878
- return { body, styles };
14879
- };
14880
- var renderVueError = async (conventionPath, errorProps) => {
14881
- const { createSSRApp, h } = await import("vue");
14882
- const { renderToString } = await import("vue/server-renderer");
14883
- const mod = await import(conventionPath);
14884
- const ErrorComponent = mod.default;
14885
- if (!ErrorComponent)
14886
- return null;
14887
- const app = createSSRApp({
14888
- render: () => h(ErrorComponent, errorProps)
14889
- });
14890
- const rawBody = await renderToString(app);
14891
- const { styles, body } = unescapeVueStyles(rawBody);
14892
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
14893
- return new Response(html, {
14894
- headers: { "Content-Type": "text/html" },
14895
- status: 500
14896
- });
14897
- };
14898
- var renderAngularError = async (conventionPath, errorProps) => {
14899
- const mod = await import(conventionPath);
14900
- const renderFn = mod.default;
14901
- if (typeof renderFn !== "function")
14902
- return null;
14903
- const html = renderFn(errorProps);
14904
- return new Response(html, {
14905
- headers: { "Content-Type": "text/html" },
14906
- status: 500
14907
- });
14908
- };
14909
- var escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
14910
- 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) : "");
14911
- var renderHtmlError = async (conventionPath, errorProps) => {
14912
- const template = await Bun.file(conventionPath).text();
14913
- const html = replaceErrorTokens(template, errorProps);
14914
- return new Response(html, {
14915
- headers: { "Content-Type": "text/html" },
14916
- status: 500
14917
- });
14918
- };
14919
- var logConventionRenderError = (framework, label, renderError) => {
14920
- const message = renderError instanceof Error ? renderError.message : "";
14921
- if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
14922
- 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}).`);
14923
- return;
14924
- }
14925
- console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
14926
- };
14927
- var renderEmberError = async () => null;
14928
- var renderEmberNotFound = async () => null;
14929
- var ERROR_RENDERERS = {
14930
- angular: renderAngularError,
14931
- ember: renderEmberError,
14932
- html: renderHtmlError,
14933
- react: renderReactError,
14934
- svelte: renderSvelteError,
14935
- vue: renderVueError
14936
- };
14937
- var tryFrameworkErrorConvention = async (framework, pageName, errorProps, error) => {
14938
- let conventionPath = resolveErrorConventionPath(framework, pageName);
14939
- if (!conventionPath && error instanceof Error && error.stack) {
14940
- for (const match of error.stack.matchAll(/^\s*at\s+([A-Za-z_$][\w$]*)/gm)) {
14941
- const candidate = match[1];
14942
- if (!candidate)
14943
- continue;
14944
- conventionPath = resolveErrorConventionPath(framework, candidate);
14945
- if (conventionPath)
14946
- break;
14947
- }
14948
- }
14949
- if (!conventionPath)
14950
- return null;
14951
- const renderer = ERROR_RENDERERS[framework];
14952
- if (!renderer)
14953
- return null;
14954
- try {
14955
- return await renderer(conventionPath, errorProps);
14956
- } catch (renderError) {
14957
- logConventionRenderError(framework, "error", renderError);
14958
- }
14959
- return null;
14960
- };
14961
- var renderConventionError = async (framework, pageName, error) => {
14962
- const errorProps = buildErrorProps(error);
14963
- const frameworkResponse = await tryFrameworkErrorConvention(framework, pageName, errorProps, error);
14964
- if (frameworkResponse)
14965
- return frameworkResponse;
14966
- if (framework !== "html") {
14967
- const htmlResponse = await tryFrameworkErrorConvention("html", pageName, errorProps, error);
14968
- if (htmlResponse)
14969
- return htmlResponse;
14970
- }
14971
- return null;
14972
- };
14973
- var renderReactNotFound = async (conventionPath) => {
14974
- const { createElement } = await import("react");
14975
- const { renderToReadableStream } = await import("react-dom/server");
14976
- const mod = await import(conventionPath);
14977
- const NotFoundComponent = mod.default;
14978
- if (typeof NotFoundComponent !== "function")
14979
- return null;
14980
- const element = createElement(NotFoundComponent);
14981
- const stream = await renderToReadableStream(element);
14982
- return new Response(stream, {
14983
- headers: { "Content-Type": "text/html" },
14984
- status: 404
14985
- });
14986
- };
14987
- var renderSvelteNotFound = async (conventionPath) => {
14988
- const { render } = await import("svelte/server");
14989
- const mod = await import(conventionPath);
14990
- const NotFoundComponent = mod.default;
14991
- if (!NotFoundComponent)
14992
- return null;
14993
- const { head, body } = render(NotFoundComponent);
14994
- const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
14995
- return new Response(html, {
14996
- headers: { "Content-Type": "text/html" },
14997
- status: 404
14998
- });
14999
- };
15000
- var renderVueNotFound = async (conventionPath) => {
15001
- const { createSSRApp, h } = await import("vue");
15002
- const { renderToString } = await import("vue/server-renderer");
15003
- const mod = await import(conventionPath);
15004
- const NotFoundComponent = mod.default;
15005
- if (!NotFoundComponent)
15006
- return null;
15007
- const app = createSSRApp({
15008
- render: () => h(NotFoundComponent)
15009
- });
15010
- const rawBody = await renderToString(app);
15011
- const { styles, body } = unescapeVueStyles(rawBody);
15012
- const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
15013
- return new Response(html, {
15014
- headers: { "Content-Type": "text/html" },
15015
- status: 404
15016
- });
15017
- };
15018
- var renderAngularNotFound = async (conventionPath) => {
15019
- const mod = await import(conventionPath);
15020
- const renderFn = mod.default;
15021
- if (typeof renderFn !== "function")
15022
- return null;
15023
- const html = renderFn();
15024
- return new Response(html, {
15025
- headers: { "Content-Type": "text/html" },
15026
- status: 404
15027
- });
15028
- };
15029
- var renderHtmlNotFound = async (conventionPath) => {
15030
- const html = await Bun.file(conventionPath).text();
15031
- return new Response(html, {
15032
- headers: { "Content-Type": "text/html" },
15033
- status: 404
15034
- });
15035
- };
15036
- var NOT_FOUND_RENDERERS = {
15037
- angular: renderAngularNotFound,
15038
- ember: renderEmberNotFound,
15039
- html: renderHtmlNotFound,
15040
- react: renderReactNotFound,
15041
- svelte: renderSvelteNotFound,
15042
- vue: renderVueNotFound
15043
- };
15044
- var renderConventionNotFound = async (framework) => {
15045
- const conventionPath = resolveNotFoundConventionPath(framework);
15046
- if (!conventionPath)
15047
- return null;
15048
- const renderer = NOT_FOUND_RENDERERS[framework];
15049
- if (!renderer)
15050
- return null;
15051
- try {
15052
- return await renderer(conventionPath);
15053
- } catch (renderError) {
15054
- logConventionRenderError(framework, "not-found", renderError);
15055
- }
15056
- return null;
15057
- };
15058
- var NOT_FOUND_PRIORITY = [
15059
- "react",
15060
- "svelte",
15061
- "vue",
15062
- "angular",
15063
- "html"
15064
- ];
15065
- var renderFirstNotFound = async () => {
15066
- const renderNext = async (frameworks) => {
15067
- const [framework, ...remaining] = frameworks;
15068
- if (!framework) {
15069
- return null;
15070
- }
15071
- if (!getMap()[framework]?.defaults?.notFound) {
15072
- return renderNext(remaining);
15073
- }
15074
- const response = await renderConventionNotFound(framework);
15075
- if (response) {
15076
- return response;
15077
- }
15078
- return renderNext(remaining);
15079
- };
15080
- return renderNext(NOT_FOUND_PRIORITY);
15081
- };
15082
15124
 
15083
15125
  // src/angular/pageHandler.ts
15126
+ init_resolveConvention();
15084
15127
  init_registerClientScript();
15085
15128
  init_angularDeps();
15086
15129
 
@@ -15159,6 +15202,9 @@ var buildRouterRedirectProviders = async (deps, responseInit) => {
15159
15202
  ];
15160
15203
  };
15161
15204
 
15205
+ // src/angular/pageHandler.ts
15206
+ init_spaRouteManifest();
15207
+
15162
15208
  // src/angular/lowerServerIslands.ts
15163
15209
  init_renderIslandMarkup();
15164
15210
  var ANGULAR_ISLAND_TAG_RE = /<absolute-island\b([^>]*)>[\s\S]*?<\/absolute-island>/gi;
@@ -15502,7 +15548,7 @@ var resolveRuntimeAngularModulePath = async (pagePath) => {
15502
15548
  const { compileAngularFileJIT: compileAngularFileJIT2 } = await Promise.resolve().then(() => (init_compileAngular(), exports_compileAngular));
15503
15549
  const cacheBuster = createAngularRuntimeCacheBuster();
15504
15550
  const outputs = await compileAngularFileJIT2(pagePath, outDir, process.cwd(), undefined, cacheBuster);
15505
- const expectedFileName = basename4(pagePath).replace(/\.ts$/, ".js");
15551
+ const expectedFileName = basename5(pagePath).replace(/\.ts$/, ".js");
15506
15552
  const runtimePagePath = outputs.find((output) => output.endsWith(`/${expectedFileName}`)) ?? outputs.find((output) => output.endsWith(`\\${expectedFileName}`)) ?? outputs[0] ?? pagePath;
15507
15553
  return {
15508
15554
  cacheBuster,
@@ -15539,6 +15585,9 @@ setSsrContextGetter(() => angularSsrContext.getStore());
15539
15585
  var handleAngularPageRequest = async (input) => {
15540
15586
  const requestId = `angular_${Date.now()}_${Math.random().toString(BASE_36_RADIX).substring(2, RANDOM_ID_END_INDEX)}`;
15541
15587
  return angularSsrContext.run(requestId, async () => {
15588
+ const spaNotFound = await renderSpaNotFound("angular", derivePageName(input.pagePath), input.request);
15589
+ if (spaNotFound)
15590
+ return withPageCacheHeaders(spaNotFound, input.request);
15542
15591
  await ensureAngularCompiler();
15543
15592
  const userHeadTag = input.headTag ?? "<head></head>";
15544
15593
  const resolvedIndexPath = input.indexPath;
@@ -16124,5 +16173,5 @@ export {
16124
16173
  ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
16125
16174
  };
16126
16175
 
16127
- //# debugId=BA705493D94D3D1B64756E2164756E21
16176
+ //# debugId=ADB7CF56A32A483D64756E2164756E21
16128
16177
  //# sourceMappingURL=index.js.map