@absolutejs/absolute 0.19.0-beta.967 → 0.19.0-beta.968

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.
@@ -2960,6 +2960,16 @@ var init_logger = __esm(() => {
2960
2960
  };
2961
2961
  });
2962
2962
 
2963
+ // src/utils/generatedDir.ts
2964
+ var exports_generatedDir = {};
2965
+ __export(exports_generatedDir, {
2966
+ getGeneratedRoot: () => getGeneratedRoot,
2967
+ getFrameworkGeneratedDir: () => getFrameworkGeneratedDir
2968
+ });
2969
+ import { join as join6 } from "path";
2970
+ var GENERATED_DIR_NAME = "generated", ABSOLUTE_CACHE_DIR_NAME = ".absolutejs", getGeneratedRoot = (projectRoot = process.cwd()) => join6(projectRoot, ABSOLUTE_CACHE_DIR_NAME, GENERATED_DIR_NAME), getFrameworkGeneratedDir = (framework, projectRoot = process.cwd()) => join6(getGeneratedRoot(projectRoot), framework);
2971
+ var init_generatedDir = () => {};
2972
+
2963
2973
  // src/islands/sourceMetadata.ts
2964
2974
  var islandFrameworks2, islandHydrationModes2, isIslandFramework2 = (value) => islandFrameworks2.some((framework) => framework === value), isIslandHydrate2 = (value) => islandHydrationModes2.some((hydrate) => hydrate === value), parseIslandTagAttributes = (attributeString) => {
2965
2975
  const frameworkMatch = attributeString.match(/\bframework\s*=\s*["']([^"']+)["']/);
@@ -3498,16 +3508,6 @@ var init_lowerDeferSyntax = __esm(() => {
3498
3508
  init_constants();
3499
3509
  });
3500
3510
 
3501
- // src/utils/generatedDir.ts
3502
- var exports_generatedDir = {};
3503
- __export(exports_generatedDir, {
3504
- getGeneratedRoot: () => getGeneratedRoot,
3505
- getFrameworkGeneratedDir: () => getFrameworkGeneratedDir
3506
- });
3507
- import { join as join6 } from "path";
3508
- var GENERATED_DIR_NAME = "generated", ABSOLUTE_CACHE_DIR_NAME = ".absolutejs", getGeneratedRoot = (projectRoot = process.cwd()) => join6(projectRoot, ABSOLUTE_CACHE_DIR_NAME, GENERATED_DIR_NAME), getFrameworkGeneratedDir = (framework, projectRoot = process.cwd()) => join6(getGeneratedRoot(projectRoot), framework);
3509
- var init_generatedDir = () => {};
3510
-
3511
3511
  // src/build/compileAngular.ts
3512
3512
  var exports_compileAngular = {};
3513
3513
  __export(exports_compileAngular, {
@@ -3517,8 +3517,8 @@ __export(exports_compileAngular, {
3517
3517
  compileAngularFile: () => compileAngularFile,
3518
3518
  compileAngular: () => compileAngular
3519
3519
  });
3520
- import { existsSync as existsSync4, readFileSync as readFileSync4, promises as fs } from "fs";
3521
- import { join as join7, basename as basename3, sep, dirname as dirname4, resolve as resolve6, relative as relative4 } from "path";
3520
+ import { existsSync as existsSync5, readFileSync as readFileSync4, promises as fs } from "fs";
3521
+ import { join as join8, basename as basename3, sep, dirname as dirname4, resolve as resolve6, relative as relative4 } from "path";
3522
3522
  var {Glob } = globalThis.Bun;
3523
3523
  import ts from "typescript";
3524
3524
  var traceAngularPhase = async (name, fn, metadata) => {
@@ -3561,12 +3561,12 @@ var traceAngularPhase = async (name, fn, metadata) => {
3561
3561
  `${candidate}.tsx`,
3562
3562
  `${candidate}.js`,
3563
3563
  `${candidate}.jsx`,
3564
- join7(candidate, "index.ts"),
3565
- join7(candidate, "index.tsx"),
3566
- join7(candidate, "index.js"),
3567
- join7(candidate, "index.jsx")
3564
+ join8(candidate, "index.ts"),
3565
+ join8(candidate, "index.tsx"),
3566
+ join8(candidate, "index.js"),
3567
+ join8(candidate, "index.jsx")
3568
3568
  ];
3569
- return candidates.find((file) => existsSync4(file));
3569
+ return candidates.find((file) => existsSync5(file));
3570
3570
  }, createLegacyAngularAnimationUsageResolver = (rootDir) => {
3571
3571
  const baseDir = resolve6(rootDir);
3572
3572
  const tsconfigAliases = readTsconfigPathAliases();
@@ -3600,9 +3600,9 @@ var traceAngularPhase = async (name, fn, metadata) => {
3600
3600
  });
3601
3601
  }
3602
3602
  const resolved = resolve6(actualPath);
3603
- const cached = scanCache.get(resolved);
3604
- if (cached)
3605
- return cached;
3603
+ const cached2 = scanCache.get(resolved);
3604
+ if (cached2)
3605
+ return cached2;
3606
3606
  const promise = (async () => {
3607
3607
  let sourceCode;
3608
3608
  try {
@@ -3647,11 +3647,11 @@ var traceAngularPhase = async (name, fn, metadata) => {
3647
3647
  }, resolveDevClientDir = () => {
3648
3648
  const projectRoot = process.cwd();
3649
3649
  const fromSource = resolve6(import.meta.dir, "../dev/client");
3650
- if (existsSync4(fromSource) && fromSource.startsWith(projectRoot)) {
3650
+ if (existsSync5(fromSource) && fromSource.startsWith(projectRoot)) {
3651
3651
  return fromSource;
3652
3652
  }
3653
3653
  const fromNodeModules = resolve6(projectRoot, "node_modules/@absolutejs/absolute/dist/dev/client");
3654
- if (existsSync4(fromNodeModules))
3654
+ if (existsSync5(fromNodeModules))
3655
3655
  return fromNodeModules;
3656
3656
  return resolve6(import.meta.dir, "./dev/client");
3657
3657
  }, devClientDir, hmrClientPath, formatDiagnosticMessage = (diagnostic) => {
@@ -3697,11 +3697,11 @@ var traceAngularPhase = async (name, fn, metadata) => {
3697
3697
  return `${path}${query}`;
3698
3698
  const importerDir = dirname4(importerOutputPath);
3699
3699
  const fileCandidate = resolve6(importerDir, `${path}.js`);
3700
- if (outputFiles?.has(fileCandidate) || existsSync4(fileCandidate)) {
3700
+ if (outputFiles?.has(fileCandidate) || existsSync5(fileCandidate)) {
3701
3701
  return `${path}.js${query}`;
3702
3702
  }
3703
3703
  const indexCandidate = resolve6(importerDir, path, "index.js");
3704
- if (outputFiles?.has(indexCandidate) || existsSync4(indexCandidate)) {
3704
+ if (outputFiles?.has(indexCandidate) || existsSync5(indexCandidate)) {
3705
3705
  return `${path}/index.js${query}`;
3706
3706
  }
3707
3707
  return `${path}.js${query}`;
@@ -3734,12 +3734,12 @@ var traceAngularPhase = async (name, fn, metadata) => {
3734
3734
  `${basePath}.tsx`,
3735
3735
  `${basePath}.mts`,
3736
3736
  `${basePath}.cts`,
3737
- join7(basePath, "index.ts"),
3738
- join7(basePath, "index.tsx"),
3739
- join7(basePath, "index.mts"),
3740
- join7(basePath, "index.cts")
3737
+ join8(basePath, "index.ts"),
3738
+ join8(basePath, "index.tsx"),
3739
+ join8(basePath, "index.mts"),
3740
+ join8(basePath, "index.cts")
3741
3741
  ];
3742
- return candidates.map((candidate) => resolve6(candidate)).find((candidate) => existsSync4(candidate) && !candidate.endsWith(".d.ts")) ?? null;
3742
+ return candidates.map((candidate) => resolve6(candidate)).find((candidate) => existsSync5(candidate) && !candidate.endsWith(".d.ts")) ?? null;
3743
3743
  }, readFileForAotTransform = async (fileName, readFile2) => {
3744
3744
  const hostSource = readFile2?.(fileName);
3745
3745
  if (typeof hostSource === "string")
@@ -3763,15 +3763,15 @@ var traceAngularPhase = async (name, fn, metadata) => {
3763
3763
  const paths = [];
3764
3764
  const templateUrlMatch = findUncommentedMatch(source, /templateUrl\s*:\s*['"]([^'"]+)['"]/);
3765
3765
  if (templateUrlMatch?.[1])
3766
- paths.push(join7(fileDir, templateUrlMatch[1]));
3766
+ paths.push(join8(fileDir, templateUrlMatch[1]));
3767
3767
  const styleUrlMatch = findUncommentedMatch(source, /styleUrl\s*:\s*['"]([^'"]+)['"]/);
3768
3768
  if (styleUrlMatch?.[1])
3769
- paths.push(join7(fileDir, styleUrlMatch[1]));
3769
+ paths.push(join8(fileDir, styleUrlMatch[1]));
3770
3770
  const styleUrlsMatch = findUncommentedMatch(source, /styleUrls\s*:\s*\[([^\]]+)\]/);
3771
3771
  const urlMatches = styleUrlsMatch?.[1]?.match(/['"]([^'"]+)['"]/g);
3772
3772
  if (urlMatches) {
3773
3773
  for (const urlMatch of urlMatches) {
3774
- paths.push(join7(fileDir, urlMatch.replace(/['"]/g, "")));
3774
+ paths.push(join8(fileDir, urlMatch.replace(/['"]/g, "")));
3775
3775
  }
3776
3776
  }
3777
3777
  return paths.map((path) => resolve6(path));
@@ -3805,7 +3805,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
3805
3805
  safeStableStringify(stylePreprocessors ?? null)
3806
3806
  ].join("\x00");
3807
3807
  const cacheKey = Bun.hash(cacheInput).toString(BASE_36_RADIX);
3808
- return join7(process.cwd(), ".absolutejs", "cache", "angular-resources", `${cacheKey}.json`);
3808
+ return join8(process.cwd(), ".absolutejs", "cache", "angular-resources", `${cacheKey}.json`);
3809
3809
  }, precomputeAotResourceTransforms = async (inputPaths, readFile2, stylePreprocessors) => {
3810
3810
  const transformedSources = new Map;
3811
3811
  const visited = new Set;
@@ -3820,16 +3820,16 @@ var traceAngularPhase = async (name, fn, metadata) => {
3820
3820
  if (visited.has(resolvedPath))
3821
3821
  return;
3822
3822
  visited.add(resolvedPath);
3823
- if (!existsSync4(resolvedPath) || resolvedPath.endsWith(".d.ts"))
3823
+ if (!existsSync5(resolvedPath) || resolvedPath.endsWith(".d.ts"))
3824
3824
  return;
3825
3825
  stats.filesVisited += 1;
3826
3826
  const source = await readFileForAotTransform(resolvedPath, readFile2);
3827
3827
  const cachePath = await resolveResourceTransformCachePath(resolvedPath, source, stylePreprocessors);
3828
- const cached = await readResourceCacheFile(cachePath);
3828
+ const cached2 = await readResourceCacheFile(cachePath);
3829
3829
  let transformedSource;
3830
- if (cached) {
3830
+ if (cached2) {
3831
3831
  stats.cacheHits += 1;
3832
- transformedSource = cached.source;
3832
+ transformedSource = cached2.source;
3833
3833
  } else {
3834
3834
  stats.cacheMisses += 1;
3835
3835
  const transformed = await inlineResources(source, dirname4(resolvedPath), stylePreprocessors);
@@ -3851,7 +3851,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
3851
3851
  return { stats, transformedSources };
3852
3852
  }, compileAngularFiles = async (inputPaths, outDir, stylePreprocessors) => {
3853
3853
  const islandMetadataByOutputPath = await traceAngularPhase("aot/island-metadata", () => new Map(inputPaths.map((inputPath) => {
3854
- const outputPath = resolve6(join7(outDir, relative4(process.cwd(), resolve6(inputPath)).replace(/\.[cm]?[tj]sx?$/, ".js")));
3854
+ const outputPath = resolve6(join8(outDir, relative4(process.cwd(), resolve6(inputPath)).replace(/\.[cm]?[tj]sx?$/, ".js")));
3855
3855
  return [
3856
3856
  outputPath,
3857
3857
  buildIslandMetadataExports(readFileSync4(inputPath, "utf-8"))
@@ -3898,7 +3898,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
3898
3898
  const originalGetSourceFile = host.getSourceFile;
3899
3899
  host.getSourceFile = (fileName, languageVersion, onError) => {
3900
3900
  if (fileName.startsWith("lib.") && fileName.endsWith(".d.ts") && tsLibDir) {
3901
- const resolvedPath = join7(tsLibDir, fileName);
3901
+ const resolvedPath = join8(tsLibDir, fileName);
3902
3902
  return originalGetSourceFile?.call(host, resolvedPath, languageVersion, onError);
3903
3903
  }
3904
3904
  return originalGetSourceFile?.call(host, fileName, languageVersion, onError);
@@ -3953,7 +3953,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
3953
3953
  const entries = await traceAngularPhase("aot/postprocess-emitted-js", () => {
3954
3954
  const rawEntries = Object.entries(emitted).filter(([fileName]) => fileName.endsWith(".js")).map(([fileName, content]) => ({
3955
3955
  content,
3956
- target: join7(outDir, fileName)
3956
+ target: join8(outDir, fileName)
3957
3957
  }));
3958
3958
  const outputFiles = new Set(rawEntries.map(({ target }) => resolve6(target)));
3959
3959
  return rawEntries.map(({ content, target }) => {
@@ -3994,7 +3994,7 @@ var traceAngularPhase = async (name, fn, metadata) => {
3994
3994
  return null;
3995
3995
  }, resolveAngularDeferImportSpecifier = () => {
3996
3996
  const sourceEntry = resolve6(import.meta.dir, "../angular/components/index.ts");
3997
- if (existsSync4(sourceEntry)) {
3997
+ if (existsSync5(sourceEntry)) {
3998
3998
  return sourceEntry.replace(/\\/g, "/");
3999
3999
  }
4000
4000
  return "@absolutejs/absolute/angular/components";
@@ -4122,7 +4122,7 @@ ${slot.resolvedBindings.map((binding) => ` "${binding.key}": this.__absoluteDef
4122
4122
  ${fields}
4123
4123
  `);
4124
4124
  }, readAndEscapeFile = async (filePath, stylePreprocessors) => {
4125
- if (!existsSync4(filePath)) {
4125
+ if (!existsSync5(filePath)) {
4126
4126
  throw new Error(`Unable to inline Angular style resource: file not found at ${filePath}`);
4127
4127
  }
4128
4128
  const content = await compileStyleFileIfNeeded(filePath, stylePreprocessors);
@@ -4130,8 +4130,8 @@ ${fields}
4130
4130
  }, inlineTemplateAndLowerDefer = async (source, fileDir) => {
4131
4131
  const templateUrlMatch = findUncommentedMatch(source, /templateUrl\s*:\s*['"]([^'"]+)['"]/);
4132
4132
  if (templateUrlMatch?.[1]) {
4133
- const templatePath = join7(fileDir, templateUrlMatch[1]);
4134
- if (!existsSync4(templatePath)) {
4133
+ const templatePath = join8(fileDir, templateUrlMatch[1]);
4134
+ if (!existsSync5(templatePath)) {
4135
4135
  throw new Error(`Unable to inline Angular templateUrl "${templateUrlMatch[1]}": file not found at ${templatePath}`);
4136
4136
  }
4137
4137
  const templateRaw2 = await fs.readFile(templatePath, "utf-8");
@@ -4161,8 +4161,8 @@ ${fields}
4161
4161
  }, inlineTemplateAndLowerDeferSync = (source, fileDir) => {
4162
4162
  const templateUrlMatch = findUncommentedMatch(source, /templateUrl\s*:\s*['"]([^'"]+)['"]/);
4163
4163
  if (templateUrlMatch?.[1]) {
4164
- const templatePath = join7(fileDir, templateUrlMatch[1]);
4165
- if (!existsSync4(templatePath)) {
4164
+ const templatePath = join8(fileDir, templateUrlMatch[1]);
4165
+ if (!existsSync5(templatePath)) {
4166
4166
  throw new Error(`Unable to inline Angular templateUrl "${templateUrlMatch[1]}": file not found at ${templatePath}`);
4167
4167
  }
4168
4168
  const templateRaw2 = readFileSync4(templatePath, "utf-8");
@@ -4198,7 +4198,7 @@ ${fields}
4198
4198
  return source;
4199
4199
  const stylePromises = urlMatches.map((urlMatch) => {
4200
4200
  const styleUrl = urlMatch.replace(/['"]/g, "");
4201
- return readAndEscapeFile(join7(fileDir, styleUrl), stylePreprocessors);
4201
+ return readAndEscapeFile(join8(fileDir, styleUrl), stylePreprocessors);
4202
4202
  });
4203
4203
  const results = await Promise.all(stylePromises);
4204
4204
  const inlinedStyles = results.filter(Boolean).map((escaped) => `\`${escaped}\``);
@@ -4209,7 +4209,7 @@ ${fields}
4209
4209
  const styleUrlMatch = findUncommentedMatch(source, /styleUrl\s*:\s*['"]([^'"]+)['"]/);
4210
4210
  if (!styleUrlMatch?.[1])
4211
4211
  return source;
4212
- const escaped = await readAndEscapeFile(join7(fileDir, styleUrlMatch[1]), stylePreprocessors);
4212
+ const escaped = await readAndEscapeFile(join8(fileDir, styleUrlMatch[1]), stylePreprocessors);
4213
4213
  if (!escaped)
4214
4214
  return source;
4215
4215
  return source.slice(0, styleUrlMatch.index) + `styles: [\`${escaped}\`]` + source.slice(styleUrlMatch.index + styleUrlMatch[0].length);
@@ -4245,12 +4245,12 @@ ${fields}
4245
4245
  `${candidate}.js`,
4246
4246
  `${candidate}.jsx`,
4247
4247
  `${candidate}.json`,
4248
- join7(candidate, "index.ts"),
4249
- join7(candidate, "index.tsx"),
4250
- join7(candidate, "index.js"),
4251
- join7(candidate, "index.jsx")
4248
+ join8(candidate, "index.ts"),
4249
+ join8(candidate, "index.tsx"),
4250
+ join8(candidate, "index.js"),
4251
+ join8(candidate, "index.jsx")
4252
4252
  ];
4253
- return candidates.find((file) => existsSync4(file));
4253
+ return candidates.find((file) => existsSync5(file));
4254
4254
  };
4255
4255
  const resolveLocalImport = (specifier, fromDir) => {
4256
4256
  if (specifier.startsWith(".") || specifier.startsWith("/")) {
@@ -4275,7 +4275,7 @@ ${fields}
4275
4275
  const inputDir = dirname4(sourcePath);
4276
4276
  const relativeDir = inputDir.startsWith(baseDir) ? inputDir.substring(baseDir.length + 1) : inputDir;
4277
4277
  const fileBase = basename3(sourcePath).replace(/\.[cm]?[tj]sx?$/, ".js");
4278
- return join7(outDir, relativeDir, fileBase);
4278
+ return join8(outDir, relativeDir, fileBase);
4279
4279
  };
4280
4280
  const withCacheBuster = (specifier) => {
4281
4281
  if (!cacheBuster)
@@ -4322,11 +4322,11 @@ ${fields}
4322
4322
  if (visited.has(resolved))
4323
4323
  return;
4324
4324
  visited.add(resolved);
4325
- if (resolved.endsWith(".json") && existsSync4(resolved)) {
4325
+ if (resolved.endsWith(".json") && existsSync5(resolved)) {
4326
4326
  const inputDir2 = dirname4(resolved);
4327
4327
  const relativeDir2 = inputDir2.startsWith(baseDir) ? inputDir2.substring(baseDir.length + 1) : inputDir2;
4328
- const targetDir2 = join7(outDir, relativeDir2);
4329
- const targetPath2 = join7(targetDir2, basename3(resolved));
4328
+ const targetDir2 = join8(outDir, relativeDir2);
4329
+ const targetPath2 = join8(targetDir2, basename3(resolved));
4330
4330
  await fs.mkdir(targetDir2, { recursive: true });
4331
4331
  await fs.copyFile(resolved, targetPath2);
4332
4332
  allOutputs.push(targetPath2);
@@ -4335,7 +4335,7 @@ ${fields}
4335
4335
  let actualPath = resolved;
4336
4336
  if (!actualPath.endsWith(".ts"))
4337
4337
  actualPath += ".ts";
4338
- if (!existsSync4(actualPath))
4338
+ if (!existsSync5(actualPath))
4339
4339
  return;
4340
4340
  let sourceCode = await fs.readFile(actualPath, "utf-8");
4341
4341
  const inlined = await inlineResources(sourceCode, dirname4(actualPath), stylePreprocessors);
@@ -4343,7 +4343,7 @@ ${fields}
4343
4343
  const inputDir = dirname4(actualPath);
4344
4344
  const relativeDir = inputDir.startsWith(baseDir) ? inputDir.substring(baseDir.length + 1) : inputDir;
4345
4345
  const fileBase = basename3(actualPath).replace(/\.[cm]?[tj]sx?$/, ".js");
4346
- const targetDir = join7(outDir, relativeDir);
4346
+ const targetDir = join8(outDir, relativeDir);
4347
4347
  const targetPath = toOutputPath(actualPath);
4348
4348
  const localImports = [];
4349
4349
  const importRewrites = new Map;
@@ -4373,7 +4373,7 @@ ${fields}
4373
4373
  const isEntry = resolve6(actualPath) === resolve6(entryPath);
4374
4374
  const contentHash = Bun.hash(sourceCode).toString(BASE_36_RADIX);
4375
4375
  const cacheKey = actualPath;
4376
- const shouldWriteFile = cacheBuster && isEntry ? true : jitContentCache.get(cacheKey) !== contentHash || !existsSync4(targetPath);
4376
+ const shouldWriteFile = cacheBuster && isEntry ? true : jitContentCache.get(cacheKey) !== contentHash || !existsSync5(targetPath);
4377
4377
  if (shouldWriteFile) {
4378
4378
  const processedContent = transpileAndRewrite(sourceCode, relativeDir, actualPath, importRewrites);
4379
4379
  await fs.mkdir(targetDir, { recursive: true });
@@ -4385,7 +4385,7 @@ ${fields}
4385
4385
  };
4386
4386
  await transpileFile(inputPath);
4387
4387
  const entryOutputPath = toOutputPath(entryPath);
4388
- if (existsSync4(entryOutputPath)) {
4388
+ if (existsSync5(entryOutputPath)) {
4389
4389
  const entryOutput = await fs.readFile(entryOutputPath, "utf-8");
4390
4390
  const withoutLegacyFlag = entryOutput.replace(/\nexport const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;\n?/g, `
4391
4391
  `);
@@ -4404,23 +4404,23 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
4404
4404
  return { clientPaths: [...emptyPaths], serverPaths: [...emptyPaths] };
4405
4405
  }
4406
4406
  const compiledRoot = compiledParent;
4407
- const indexesDir = join7(compiledParent, "indexes");
4407
+ const indexesDir = join8(compiledParent, "indexes");
4408
4408
  await traceAngularPhase("setup/create-indexes-dir", () => fs.mkdir(indexesDir, { recursive: true }));
4409
4409
  const aotOutputs = hmr ? [] : await traceAngularPhase("aot/compile-files", () => compileAngularFiles(entryPoints.map((entry) => resolve6(entry)), compiledRoot, stylePreprocessors), { entries: entryPoints.length });
4410
4410
  if (!hmr) {
4411
4411
  await traceAngularPhase("aot/copy-json-resources", async () => {
4412
4412
  const cwd = process.cwd();
4413
4413
  const angularSrcDir = resolve6(outRoot);
4414
- if (!existsSync4(angularSrcDir))
4414
+ if (!existsSync5(angularSrcDir))
4415
4415
  return;
4416
4416
  const jsonGlob = new Glob("**/*.json");
4417
4417
  for (const rel of jsonGlob.scanSync({
4418
4418
  absolute: false,
4419
4419
  cwd: angularSrcDir
4420
4420
  })) {
4421
- const sourcePath = join7(angularSrcDir, rel);
4421
+ const sourcePath = join8(angularSrcDir, rel);
4422
4422
  const cwdRel = relative4(cwd, sourcePath);
4423
- const targetPath = join7(compiledRoot, cwdRel);
4423
+ const targetPath = join8(compiledRoot, cwdRel);
4424
4424
  await fs.mkdir(dirname4(targetPath), { recursive: true });
4425
4425
  await fs.copyFile(sourcePath, targetPath);
4426
4426
  }
@@ -4437,24 +4437,24 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
4437
4437
  const fileBase = basename3(resolvedEntry).replace(/\.[tj]s$/, "");
4438
4438
  const jsName = `${fileBase}.js`;
4439
4439
  const compiledFallbackPaths = [
4440
- join7(compiledRoot, relativeEntry),
4441
- join7(compiledRoot, "pages", jsName),
4442
- join7(compiledRoot, jsName)
4440
+ join8(compiledRoot, relativeEntry),
4441
+ join8(compiledRoot, "pages", jsName),
4442
+ join8(compiledRoot, jsName)
4443
4443
  ].map((file) => resolve6(file));
4444
4444
  const resolveRawServerFile = (candidatePaths) => {
4445
4445
  const normalizedCandidates = [
4446
4446
  ...candidatePaths.map((file) => resolve6(file)),
4447
4447
  ...compiledFallbackPaths
4448
4448
  ];
4449
- let candidate = normalizedCandidates.find((file) => existsSync4(file) && file.endsWith(`${sep}${relativeEntry}`));
4449
+ let candidate = normalizedCandidates.find((file) => existsSync5(file) && file.endsWith(`${sep}${relativeEntry}`));
4450
4450
  if (!candidate) {
4451
- candidate = normalizedCandidates.find((file) => existsSync4(file) && file.endsWith(`${sep}pages${sep}${jsName}`));
4451
+ candidate = normalizedCandidates.find((file) => existsSync5(file) && file.endsWith(`${sep}pages${sep}${jsName}`));
4452
4452
  }
4453
4453
  if (!candidate) {
4454
- candidate = normalizedCandidates.find((file) => existsSync4(file) && file.endsWith(`${sep}${jsName}`));
4454
+ candidate = normalizedCandidates.find((file) => existsSync5(file) && file.endsWith(`${sep}${jsName}`));
4455
4455
  }
4456
4456
  if (!candidate) {
4457
- candidate = normalizedCandidates.find((file) => existsSync4(file));
4457
+ candidate = normalizedCandidates.find((file) => existsSync5(file));
4458
4458
  }
4459
4459
  return candidate;
4460
4460
  };
@@ -4462,11 +4462,11 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
4462
4462
  if (!rawServerFile) {
4463
4463
  rawServerFile = await traceAngularPhase("wrapper/resolve-server-output-fallback", () => resolveRawServerFile([]), { entry: resolvedEntry });
4464
4464
  }
4465
- if (rawServerFile && !existsSync4(rawServerFile)) {
4465
+ if (rawServerFile && !existsSync5(rawServerFile)) {
4466
4466
  outputs = hmr ? await compileEntry() : aotOutputs;
4467
4467
  rawServerFile = await traceAngularPhase("wrapper/resolve-server-output-retry", () => resolveRawServerFile(outputs), { entry: resolvedEntry });
4468
4468
  }
4469
- if (!rawServerFile || !existsSync4(rawServerFile)) {
4469
+ if (!rawServerFile || !existsSync5(rawServerFile)) {
4470
4470
  throw new Error(`Compiled output not found for ${entry}. Looking for: ${jsName}. Available: ${[
4471
4471
  ...outputs,
4472
4472
  ...compiledFallbackPaths
@@ -4487,8 +4487,8 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
4487
4487
  const usesLegacyAnimations = await traceAngularPhase("wrapper/detect-legacy-animations", () => usesLegacyAngularAnimations(resolvedEntry), { entry: resolvedEntry });
4488
4488
  const serverContentHash = Bun.hash(original).toString(BASE_36_RADIX);
4489
4489
  const cachedWrapper = wrapperOutputCache.get(resolvedEntry);
4490
- const clientFile = join7(indexesDir, jsName);
4491
- if (hmr && cachedWrapper && cachedWrapper.serverHash === serverContentHash && existsSync4(clientFile) && (usesLegacyAnimations || !original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__")) && (!usesLegacyAnimations || original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__"))) {
4490
+ const clientFile = join8(indexesDir, jsName);
4491
+ if (hmr && cachedWrapper && cachedWrapper.serverHash === serverContentHash && existsSync5(clientFile) && (usesLegacyAnimations || !original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__")) && (!usesLegacyAnimations || original.includes("__ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__"))) {
4492
4492
  return {
4493
4493
  clientPath: clientFile,
4494
4494
  indexUnchanged: true,
@@ -4515,6 +4515,14 @@ export const __ABSOLUTE_PAGE_USES_LEGACY_ANIMATIONS__ = true;
4515
4515
  await traceAngularPhase("wrapper/write-server-output", () => fs.writeFile(rawServerFile, rewritten, "utf-8"), { entry: resolvedEntry });
4516
4516
  const relativePath = relative4(indexesDir, rawServerFile).replace(/\\/g, "/");
4517
4517
  const normalizedImportPath = relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
4518
+ const manifestKeyForProviders = toPascal(fileBase);
4519
+ const providersFilePath = join8(compiledParent, "providers", `${manifestKeyForProviders}.providers.ts`);
4520
+ const hasGeneratedProviders = existsSync5(providersFilePath);
4521
+ const providersImportPath = hasGeneratedProviders ? (() => {
4522
+ const rel = relative4(indexesDir, providersFilePath.replace(/\.ts$/, "")).replace(/\\/g, "/");
4523
+ return rel.startsWith(".") ? rel : `./${rel}`;
4524
+ })() : null;
4525
+ const generatedProvidersImport = providersImportPath ? `import { providers as generatedProviders } from '${providersImportPath}';` : "var generatedProviders = null;";
4518
4526
  const hmrPreamble = hmr ? `window.__HMR_FRAMEWORK__ = "angular";
4519
4527
  import "${hmrClientPath}";
4520
4528
  ` : "";
@@ -4525,6 +4533,7 @@ import { provideClientHydration } from '@angular/platform-browser';
4525
4533
  import { withHttpTransferCacheOptions } from '@angular/platform-browser';
4526
4534
  import { provideZonelessChangeDetection, REQUEST_CONTEXT } from '@angular/core';
4527
4535
  import * as pageModule from '${normalizedImportPath}';
4536
+ ${generatedProvidersImport}
4528
4537
 
4529
4538
  var ${componentClassName} = pageModule.default;
4530
4539
  // REQUEST_CONTEXT is hydrated from the SSR-serialized payload so client-side
@@ -4538,12 +4547,15 @@ var pageHasIslands = Boolean(pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__) || Boolea
4538
4547
  var pageHasRawStreamingSlots = Boolean(document.querySelector('[data-absolute-raw-slot="true"]'));
4539
4548
  var pageHasStreamingSlots = Boolean(document.querySelector('[data-absolute-slot="true"]'));
4540
4549
  var contextProviders = [{ provide: REQUEST_CONTEXT, useValue: requestContext }];
4541
- // Page-level providers, opt-in via \`export const providers = [...]\` in the
4542
- // page module. Required so DI tokens that the component (or any service it
4543
- // injects) needs are available client-side too \u2014 without these, services
4544
- // that worked in SSR fail with NG0201 after hydration.
4545
- var maybePageProviders = Reflect.get(pageModule, 'providers');
4546
- var pageProviders = Array.isArray(maybePageProviders) ? maybePageProviders : [];
4550
+ // Page-level providers come from the build-generated providers file
4551
+ // (emitted by \`runAngularHandlerScan\` based on the page's
4552
+ // \`handleAngularPageRequest({...})\` call). Falls back to the legacy
4553
+ // \`export const providers\` on the page module for projects that
4554
+ // haven't migrated yet.
4555
+ var legacyPageProviders = Reflect.get(pageModule, 'providers');
4556
+ var pageProviders = Array.isArray(generatedProviders)
4557
+ ? generatedProviders
4558
+ : (Array.isArray(legacyPageProviders) ? legacyPageProviders : []);
4547
4559
  var absoluteHttpTransferCacheOptions = {
4548
4560
  includePostRequests: false,
4549
4561
  includeRequestsWithAuthHeaders: false,
@@ -4620,6 +4632,7 @@ import { provideClientHydration } from '@angular/platform-browser';
4620
4632
  import { withHttpTransferCacheOptions } from '@angular/platform-browser';
4621
4633
  import { enableProdMode, provideZonelessChangeDetection, REQUEST_CONTEXT } from '@angular/core';
4622
4634
  import * as pageModule from '${normalizedImportPath}';
4635
+ ${generatedProvidersImport}
4623
4636
 
4624
4637
  var ${componentClassName} = pageModule.default;
4625
4638
  // REQUEST_CONTEXT is hydrated from the SSR-serialized payload so client-side
@@ -4633,12 +4646,15 @@ var pageHasIslands = Boolean(pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__) || Boolea
4633
4646
  var pageHasRawStreamingSlots = Boolean(document.querySelector('[data-absolute-raw-slot="true"]'));
4634
4647
  var pageHasStreamingSlots = Boolean(document.querySelector('[data-absolute-slot="true"]'));
4635
4648
  var contextProviders = [{ provide: REQUEST_CONTEXT, useValue: requestContext }];
4636
- // Page-level providers, opt-in via \`export const providers = [...]\` in the
4637
- // page module. Required so DI tokens that the component (or any service it
4638
- // injects) needs are available client-side too \u2014 without these, services
4639
- // that worked in SSR fail with NG0201 after hydration.
4640
- var maybePageProviders = Reflect.get(pageModule, 'providers');
4641
- var pageProviders = Array.isArray(maybePageProviders) ? maybePageProviders : [];
4649
+ // Page-level providers come from the build-generated providers file
4650
+ // (emitted by \`runAngularHandlerScan\` based on the page's
4651
+ // \`handleAngularPageRequest({...})\` call). Falls back to the legacy
4652
+ // \`export const providers\` on the page module for projects that
4653
+ // haven't migrated yet.
4654
+ var legacyPageProviders = Reflect.get(pageModule, 'providers');
4655
+ var pageProviders = Array.isArray(generatedProviders)
4656
+ ? generatedProviders
4657
+ : (Array.isArray(legacyPageProviders) ? legacyPageProviders : []);
4642
4658
  var absoluteHttpTransferCacheOptions = {
4643
4659
  includePostRequests: false,
4644
4660
  includeRequestsWithAuthHeaders: false,
@@ -4707,7 +4723,7 @@ var init_compileAngular = __esm(() => {
4707
4723
  init_stylePreprocessor();
4708
4724
  init_generatedDir();
4709
4725
  devClientDir = resolveDevClientDir();
4710
- hmrClientPath = join7(devClientDir, "hmrClient.ts").replace(/\\/g, "/");
4726
+ hmrClientPath = join8(devClientDir, "hmrClient.ts").replace(/\\/g, "/");
4711
4727
  jitContentCache = new Map;
4712
4728
  wrapperOutputCache = new Map;
4713
4729
  });
@@ -4877,7 +4893,7 @@ init_constants();
4877
4893
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
4878
4894
  import { mkdir as mkdir3, symlink } from "fs/promises";
4879
4895
  import { tmpdir } from "os";
4880
- import { basename as basename4, dirname as dirname5, join as join8, resolve as resolve7 } from "path";
4896
+ import { basename as basename4, dirname as dirname5, join as join9, resolve as resolve7 } from "path";
4881
4897
  import { pathToFileURL as pathToFileURL2 } from "url";
4882
4898
 
4883
4899
  // src/core/islandPageContext.ts
@@ -5714,6 +5730,38 @@ var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage(
5714
5730
 
5715
5731
  // src/angular/pageHandler.ts
5716
5732
  init_ssrRender();
5733
+
5734
+ // src/angular/loadRouteMounts.ts
5735
+ init_generatedDir();
5736
+ import { existsSync as existsSync4 } from "fs";
5737
+ import { join as join7 } from "path";
5738
+ var cached = null;
5739
+ var loadAngularRouteMounts = async () => {
5740
+ if (cached)
5741
+ return cached;
5742
+ const filePath = join7(getFrameworkGeneratedDir("angular", process.cwd()), "route-mounts.ts");
5743
+ if (!existsSync4(filePath)) {
5744
+ cached = [];
5745
+ return cached;
5746
+ }
5747
+ try {
5748
+ const mod = await import(filePath);
5749
+ cached = mod.routeMounts ?? [];
5750
+ } catch (error) {
5751
+ console.warn("[absolute/angular] failed to load route-mounts:", error);
5752
+ cached = [];
5753
+ }
5754
+ return cached;
5755
+ };
5756
+ var matchAngularBasePath = (mounts, urlPath) => {
5757
+ for (const mount of mounts) {
5758
+ if (mount.pattern.test(urlPath))
5759
+ return mount.basePath;
5760
+ }
5761
+ return "/";
5762
+ };
5763
+
5764
+ // src/angular/pageHandler.ts
5717
5765
  var lastSelector = "angular-page";
5718
5766
  var isRecord5 = (value) => typeof value === "object" && value !== null;
5719
5767
  var isAngularComponent2 = (value) => typeof value === "function";
@@ -5734,11 +5782,11 @@ var ensureAngularCompiler = () => {
5734
5782
  return compilerImportPromise;
5735
5783
  };
5736
5784
  var readAngularPageModule = (value) => isRecord5(value) ? value : null;
5737
- var resolveAngularSsrOutDir = () => process.env.ABSOLUTE_ANGULAR_SSR_OUTDIR ?? join8(tmpdir(), "absolutejs", "generated", "angular-ssr");
5785
+ var resolveAngularSsrOutDir = () => process.env.ABSOLUTE_ANGULAR_SSR_OUTDIR ?? join9(tmpdir(), "absolutejs", "generated", "angular-ssr");
5738
5786
  var createAngularRuntimeCacheBuster = () => `${Date.now().toString(BASE_36_RADIX)}.${Math.random().toString(BASE_36_RADIX).substring(2, RANDOM_ID_END_INDEX)}`;
5739
5787
  var ensureAngularSsrNodeModules = async (outDir) => {
5740
5788
  const outRoot = resolve7(dirname5(dirname5(outDir)));
5741
- const nodeModulesLink = join8(outRoot, "node_modules");
5789
+ const nodeModulesLink = join9(outRoot, "node_modules");
5742
5790
  if (process.env.ABSOLUTE_ANGULAR_SSR_OUTDIR) {
5743
5791
  return;
5744
5792
  }
@@ -5813,11 +5861,6 @@ var resolveRequestRenderUrl = (request) => {
5813
5861
  return "/";
5814
5862
  }
5815
5863
  };
5816
- var assertNoHandlerProviders = (input) => {
5817
- if (!("providers" in input))
5818
- return;
5819
- throw new Error("Angular handler providers are not supported. Export `providers` from the Angular page module, or inject REQUEST / REQUEST_CONTEXT for request-scoped data.");
5820
- };
5821
5864
  var angularSsrContext = new AsyncLocalStorage3;
5822
5865
  setSsrContextGetter(() => angularSsrContext.getStore());
5823
5866
  var handleAngularPageRequest = async (input) => {
@@ -5836,7 +5879,6 @@ var handleAngularPageRequest = async (input) => {
5836
5879
  requestContext: maybeRequestContext
5837
5880
  });
5838
5881
  try {
5839
- assertNoHandlerProviders(input);
5840
5882
  const handlerCallsite = options?.collectStreamingSlots === true ? undefined : getCurrentRouteRegistrationCallsite() ?? captureStreamingSlotWarningCallsite();
5841
5883
  const renderPageResponse = async () => {
5842
5884
  const baseDeps = await getAngularDeps();
@@ -5858,11 +5900,23 @@ var handleAngularPageRequest = async (input) => {
5858
5900
  const htmlString = `<!DOCTYPE html><html>${resolvedHeadTag}<body><${selector}></${selector}></body></html>`;
5859
5901
  resetSsrSanitizer();
5860
5902
  const sanitizer = getSsrSanitizer(deps);
5861
- const pageProvidersExport = Reflect.get(pageModule, "providers");
5862
- const pageProviders = Array.isArray(pageProvidersExport) ? pageProvidersExport : [];
5903
+ const handlerProviders = Array.isArray(input.providers) ? input.providers : [];
5904
+ const legacyProvidersExport = Reflect.get(pageModule, "providers");
5905
+ const legacyPageProviders = handlerProviders.length > 0 ? [] : Array.isArray(legacyProvidersExport) ? legacyProvidersExport : [];
5906
+ const routeMounts = await loadAngularRouteMounts();
5907
+ const requestUrlPath = input.request ? new URL(input.request.url).pathname : "/";
5908
+ const inferredBasePath = matchAngularBasePath(routeMounts, requestUrlPath);
5909
+ const inferredBasePathProvider = inferredBasePath === "/" ? [] : [
5910
+ {
5911
+ provide: deps.APP_BASE_HREF,
5912
+ useValue: inferredBasePath
5913
+ }
5914
+ ];
5863
5915
  const combinedProviders = [
5864
5916
  ...await buildRouterRedirectProviders(deps, responseInit),
5865
- ...pageProviders,
5917
+ ...inferredBasePathProvider,
5918
+ ...handlerProviders,
5919
+ ...legacyPageProviders,
5866
5920
  ...await buildServerAnimationProviders(usesLegacyAnimations)
5867
5921
  ];
5868
5922
  const providers = buildProviders(deps, sanitizer, input.request, maybeRequestContext, responseInit, combinedProviders);
@@ -5908,5 +5962,5 @@ export {
5908
5962
  ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
5909
5963
  };
5910
5964
 
5911
- //# debugId=FD8A1A3E7357C71B64756E2164756E21
5965
+ //# debugId=B1E43B86788CDDEA64756E2164756E21
5912
5966
  //# sourceMappingURL=server.js.map