astro 6.1.2 → 6.1.4

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.
Files changed (60) hide show
  1. package/dist/actions/integration.js +2 -2
  2. package/dist/assets/utils/index.d.ts +1 -1
  3. package/dist/assets/utils/index.js +1 -9
  4. package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +2 -2
  5. package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +5 -3
  6. package/dist/cli/add/index.js +37 -44
  7. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  8. package/dist/content/content-layer.js +3 -3
  9. package/dist/content/loaders/errors.d.ts +2 -2
  10. package/dist/content/loaders/errors.js +3 -0
  11. package/dist/content/loaders/glob.js +6 -2
  12. package/dist/content/mutable-data-store.js +26 -0
  13. package/dist/core/app/base.js +1 -1
  14. package/dist/core/app/dev/pipeline.js +4 -0
  15. package/dist/core/base-pipeline.d.ts +22 -35
  16. package/dist/core/base-pipeline.js +41 -8
  17. package/dist/core/build/generate.js +9 -1
  18. package/dist/core/build/pipeline.d.ts +3 -7
  19. package/dist/core/build/pipeline.js +30 -28
  20. package/dist/core/build/plugins/index.js +3 -1
  21. package/dist/core/build/plugins/plugin-chunk-imports.d.ts +10 -0
  22. package/dist/core/build/plugins/plugin-chunk-imports.js +38 -0
  23. package/dist/core/build/plugins/plugin-css.js +7 -2
  24. package/dist/core/config/schemas/refined-validators.d.ts +44 -0
  25. package/dist/core/config/schemas/refined-validators.js +168 -0
  26. package/dist/core/config/schemas/refined.js +28 -141
  27. package/dist/core/constants.js +1 -1
  28. package/dist/core/cookies/cookies.d.ts +1 -1
  29. package/dist/core/cookies/cookies.js +1 -0
  30. package/dist/core/dev/dev.js +1 -1
  31. package/dist/core/dev/restart.js +63 -68
  32. package/dist/core/messages/runtime.js +1 -1
  33. package/dist/core/render-context.d.ts +2 -2
  34. package/dist/core/render-context.js +20 -0
  35. package/dist/core/routing/create-manifest.js +12 -4
  36. package/dist/core/routing/default.d.ts +2 -3
  37. package/dist/core/routing/dev.js +0 -1
  38. package/dist/core/routing/helpers.d.ts +4 -2
  39. package/dist/core/routing/helpers.js +5 -3
  40. package/dist/integrations/features-validation.d.ts +3 -1
  41. package/dist/integrations/features-validation.js +2 -0
  42. package/dist/preferences/store.js +2 -1
  43. package/dist/prerender/routing.d.ts +1 -3
  44. package/dist/prerender/routing.js +1 -6
  45. package/dist/runtime/server/escape.d.ts +2 -1
  46. package/dist/runtime/server/escape.js +4 -5
  47. package/dist/runtime/server/transition.d.ts +2 -2
  48. package/dist/runtime/server/transition.js +4 -2
  49. package/dist/vite-plugin-app/pipeline.d.ts +4 -13
  50. package/dist/vite-plugin-app/pipeline.js +27 -12
  51. package/dist/vite-plugin-astro-server/base.d.ts +52 -0
  52. package/dist/vite-plugin-astro-server/base.js +66 -36
  53. package/dist/vite-plugin-astro-server/plugin.d.ts +0 -8
  54. package/dist/vite-plugin-astro-server/plugin.js +0 -107
  55. package/dist/vite-plugin-astro-server/trailing-slash.d.ts +34 -0
  56. package/dist/vite-plugin-astro-server/trailing-slash.js +24 -11
  57. package/dist/vite-plugin-head/index.js +40 -2
  58. package/dist/vite-plugin-hmr-reload/index.js +2 -2
  59. package/dist/vite-plugin-renderers/index.js +4 -3
  60. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  import { AstroError } from "../core/errors/errors.js";
2
2
  import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
3
- import { hasNonPrerenderedProjectRoute } from "../core/routing/helpers.js";
3
+ import { hasNonPrerenderedRoute } from "../core/routing/helpers.js";
4
4
  import { viteID } from "../core/util.js";
5
5
  import { ACTION_RPC_ROUTE_PATTERN, ACTIONS_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
6
6
  function astroIntegrationActionsRouteHandler({
@@ -30,7 +30,7 @@ function astroIntegrationActionsRouteHandler({
30
30
  });
31
31
  },
32
32
  "astro:routes:resolved": ({ routes }) => {
33
- if (!hasNonPrerenderedProjectRoute(routes)) {
33
+ if (!hasNonPrerenderedRoute(routes)) {
34
34
  const error = new AstroError(ActionsWithoutServerOutputError);
35
35
  error.stack = void 0;
36
36
  throw error;
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * If some functions don't need to be exposed, just import the file that contains the functions.
6
6
  */
7
- export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from '@astrojs/internal-helpers/remote';
7
+ export { isRemoteAllowed, matchPattern, type RemotePattern, } from '@astrojs/internal-helpers/remote';
8
8
  export { emitClientAsset } from './assets.js';
9
9
  export { isESMImportedImage, isRemoteImage, resolveSrc } from './imageKind.js';
10
10
  export { imageMetadata } from './metadata.js';
@@ -1,10 +1,6 @@
1
1
  import {
2
2
  isRemoteAllowed,
3
- matchHostname,
4
- matchPathname,
5
- matchPattern,
6
- matchPort,
7
- matchProtocol
3
+ matchPattern
8
4
  } from "@astrojs/internal-helpers/remote";
9
5
  import { emitClientAsset } from "./assets.js";
10
6
  import { isESMImportedImage, isRemoteImage, resolveSrc } from "./imageKind.js";
@@ -19,10 +15,6 @@ export {
19
15
  isESMImportedImage,
20
16
  isRemoteAllowed,
21
17
  isRemoteImage,
22
- matchHostname,
23
- matchPathname,
24
18
  matchPattern,
25
- matchPort,
26
- matchProtocol,
27
19
  resolveSrc
28
20
  };
@@ -1,9 +1,9 @@
1
1
  /** This class helps read Uint8Array bit-by-bit */
2
2
  export declare class BitReader {
3
- private readonly input;
4
- private readonly endianness;
5
3
  private byteOffset;
6
4
  private bitOffset;
5
+ private readonly input;
6
+ private readonly endianness;
7
7
  constructor(input: Uint8Array, endianness: 'big-endian' | 'little-endian');
8
8
  /** Reads a specified number of bits, and move the offset */
9
9
  getBits(length?: number): number;
@@ -1,11 +1,13 @@
1
1
  class BitReader {
2
+ // Skip the first 16 bits (2 bytes) of signature
3
+ byteOffset = 2;
4
+ bitOffset = 0;
5
+ input;
6
+ endianness;
2
7
  constructor(input, endianness) {
3
8
  this.input = input;
4
9
  this.endianness = endianness;
5
10
  }
6
- // Skip the first 16 bits (2 bytes) of signature
7
- byteOffset = 2;
8
- bitOffset = 0;
9
11
  /** Reads a specified number of bits, and move the offset */
10
12
  getBits(length = 1) {
11
13
  let result = 0;
@@ -170,7 +170,7 @@ async function add(names, { flags }) {
170
170
  return null;
171
171
  }
172
172
  switch (installResult) {
173
- case 1 /* updated */: {
173
+ case "updated": {
174
174
  if (hasCloudflareIntegration) {
175
175
  const wranglerConfigURL = new URL("./wrangler.jsonc", configURL);
176
176
  if (!existsSync(wranglerConfigURL)) {
@@ -332,7 +332,7 @@ ${gitignoreEntry}
332
332
  }
333
333
  break;
334
334
  }
335
- case 2 /* cancelled */: {
335
+ case "cancelled": {
336
336
  logger.info(
337
337
  "SKIP_FORMAT",
338
338
  msg.cancelled(
@@ -342,10 +342,10 @@ ${gitignoreEntry}
342
342
  );
343
343
  break;
344
344
  }
345
- case 3 /* failure */: {
345
+ case "failure": {
346
346
  throw createPrettyError(new Error(`Unable to install dependencies`));
347
347
  }
348
- case 0 /* none */:
348
+ case "none":
349
349
  break;
350
350
  }
351
351
  let mod;
@@ -402,14 +402,14 @@ ${gitignoreEntry}
402
402
  }
403
403
  }
404
404
  switch (configResult) {
405
- case 2 /* cancelled */: {
405
+ case "cancelled": {
406
406
  logger.info(
407
407
  "SKIP_FORMAT",
408
408
  msg.cancelled(`Your configuration has ${bold("NOT")} been updated.`)
409
409
  );
410
410
  break;
411
411
  }
412
- case 0 /* none */: {
412
+ case "none": {
413
413
  const data = await getPackageJson();
414
414
  if (data) {
415
415
  const { dependencies = {}, devDependencies = {} } = data;
@@ -426,9 +426,9 @@ ${gitignoreEntry}
426
426
  break;
427
427
  }
428
428
  // NOTE: failure shouldn't happen in practice because `updateAstroConfig` doesn't return that.
429
- // Pipe this to the same handling as `UpdateResult.updated` for now.
430
- case 3 /* failure */:
431
- case 1 /* updated */:
429
+ // Pipe this to the same handling as `'updated'` for now.
430
+ case "failure":
431
+ case "updated":
432
432
  case void 0: {
433
433
  const list = integrations.map((integration) => ` - ${integration.integrationName}`).join("\n");
434
434
  logger.info(
@@ -461,22 +461,22 @@ ${list}`
461
461
  addIncludes: hasCloudflareIntegration ? ["./worker-configuration.d.ts"] : []
462
462
  });
463
463
  switch (updateTSConfigResult) {
464
- case 0 /* none */: {
464
+ case "none": {
465
465
  break;
466
466
  }
467
- case 2 /* cancelled */: {
467
+ case "cancelled": {
468
468
  logger.info(
469
469
  "SKIP_FORMAT",
470
470
  msg.cancelled(`Your TypeScript configuration has ${bold("NOT")} been updated.`)
471
471
  );
472
472
  break;
473
473
  }
474
- case 3 /* failure */: {
474
+ case "failure": {
475
475
  throw new Error(
476
476
  `Unknown error parsing tsconfig.json or jsconfig.json. Could not update TypeScript settings.`
477
477
  );
478
478
  }
479
- case 1 /* updated */:
479
+ case "updated":
480
480
  logger.info("SKIP_FORMAT", msg.success(`Successfully updated tsconfig`));
481
481
  }
482
482
  }
@@ -548,13 +548,6 @@ function setAdapter(mod, adapter, exportName) {
548
548
  break;
549
549
  }
550
550
  }
551
- var UpdateResult = /* @__PURE__ */ ((UpdateResult2) => {
552
- UpdateResult2[UpdateResult2["none"] = 0] = "none";
553
- UpdateResult2[UpdateResult2["updated"] = 1] = "updated";
554
- UpdateResult2[UpdateResult2["cancelled"] = 2] = "cancelled";
555
- UpdateResult2[UpdateResult2["failure"] = 3] = "failure";
556
- return UpdateResult2;
557
- })(UpdateResult || {});
558
551
  async function updateAstroConfig({
559
552
  configURL,
560
553
  mod,
@@ -571,11 +564,11 @@ async function updateAstroConfig({
571
564
  }
572
565
  }).code;
573
566
  if (input === output) {
574
- return 0 /* none */;
567
+ return "none";
575
568
  }
576
569
  const diff = getDiffContent(input, output);
577
570
  if (!diff) {
578
- return 0 /* none */;
571
+ return "none";
579
572
  }
580
573
  logger.info(
581
574
  "SKIP_FORMAT",
@@ -602,9 +595,9 @@ async function updateAstroConfig({
602
595
  if (await askToContinue({ flags, logger })) {
603
596
  await fs.writeFile(fileURLToPath(configURL), output, { encoding: "utf-8" });
604
597
  logger.debug("add", `Updated astro config`);
605
- return 1 /* updated */;
598
+ return "updated";
606
599
  } else {
607
- return 2 /* cancelled */;
600
+ return "cancelled";
608
601
  }
609
602
  }
610
603
  async function updatePackageJsonOverrides({
@@ -616,7 +609,7 @@ async function updatePackageJsonOverrides({
616
609
  const pkgURL = new URL("./package.json", configURL);
617
610
  if (!existsSync(pkgURL)) {
618
611
  logger.debug("add", "No package.json found, skipping overrides update");
619
- return 0 /* none */;
612
+ return "none";
620
613
  }
621
614
  const pkgPath = fileURLToPath(pkgURL);
622
615
  const input = await fs.readFile(pkgPath, { encoding: "utf-8" });
@@ -630,12 +623,12 @@ async function updatePackageJsonOverrides({
630
623
  }
631
624
  }
632
625
  if (!hasChanges) {
633
- return 0 /* none */;
626
+ return "none";
634
627
  }
635
628
  const output = JSON.stringify(pkgJson, null, 2);
636
629
  const diff = getDiffContent(input, output);
637
630
  if (!diff) {
638
- return 0 /* none */;
631
+ return "none";
639
632
  }
640
633
  logger.info(
641
634
  "SKIP_FORMAT",
@@ -650,9 +643,9 @@ async function updatePackageJsonOverrides({
650
643
  if (await askToContinue({ flags, logger })) {
651
644
  await fs.writeFile(pkgPath, output, { encoding: "utf-8" });
652
645
  logger.debug("add", "Updated package.json overrides");
653
- return 1 /* updated */;
646
+ return "updated";
654
647
  } else {
655
- return 2 /* cancelled */;
648
+ return "cancelled";
656
649
  }
657
650
  }
658
651
  async function updatePackageJsonScripts({
@@ -664,7 +657,7 @@ async function updatePackageJsonScripts({
664
657
  const pkgURL = new URL("./package.json", configURL);
665
658
  if (!existsSync(pkgURL)) {
666
659
  logger.debug("add", "No package.json found, skipping scripts update");
667
- return 0 /* none */;
660
+ return "none";
668
661
  }
669
662
  const pkgPath = fileURLToPath(pkgURL);
670
663
  const input = await fs.readFile(pkgPath, { encoding: "utf-8" });
@@ -678,12 +671,12 @@ async function updatePackageJsonScripts({
678
671
  }
679
672
  }
680
673
  if (!hasChanges) {
681
- return 0 /* none */;
674
+ return "none";
682
675
  }
683
676
  const output = JSON.stringify(pkgJson, null, 2);
684
677
  const diff = getDiffContent(input, output);
685
678
  if (!diff) {
686
- return 0 /* none */;
679
+ return "none";
687
680
  }
688
681
  logger.info(
689
682
  "SKIP_FORMAT",
@@ -698,9 +691,9 @@ async function updatePackageJsonScripts({
698
691
  if (await askToContinue({ flags, logger })) {
699
692
  await fs.writeFile(pkgPath, output, { encoding: "utf-8" });
700
693
  logger.debug("add", "Updated package.json scripts");
701
- return 1 /* updated */;
694
+ return "updated";
702
695
  } else {
703
- return 2 /* cancelled */;
696
+ return "cancelled";
704
697
  }
705
698
  }
706
699
  async function convertIntegrationsToInstallSpecifiers(integrations) {
@@ -744,7 +737,7 @@ async function tryToInstallIntegrations({
744
737
  strategies: ["install-metadata", "lockfile", "packageManager-field"]
745
738
  });
746
739
  logger.debug("add", `package manager: "${packageManager?.name}"`);
747
- if (!packageManager) return 0 /* none */;
740
+ if (!packageManager) return "none";
748
741
  const inheritedFlags = Object.entries(flags).map(([flag]) => {
749
742
  if (flag === "_") return;
750
743
  if (INHERITED_FLAGS.has(flag)) {
@@ -753,7 +746,7 @@ async function tryToInstallIntegrations({
753
746
  }
754
747
  }).filter(Boolean).flat();
755
748
  const installCommand = resolveCommand(packageManager?.agent ?? "npm", "add", inheritedFlags);
756
- if (!installCommand) return 0 /* none */;
749
+ if (!installCommand) return "none";
757
750
  const installSpecifiers = await convertIntegrationsToInstallSpecifiers(integrations).then(
758
751
  (specifiers) => installCommand.command === "deno" ? specifiers.map((specifier) => `npm:${specifier}`) : specifiers
759
752
  );
@@ -783,15 +776,15 @@ async function tryToInstallIntegrations({
783
776
  }
784
777
  });
785
778
  spinner.stop("Dependencies installed.");
786
- return 1 /* updated */;
779
+ return "updated";
787
780
  } catch (err) {
788
781
  spinner.error("Error installing dependencies.");
789
782
  logger.debug("add", "Error installing dependencies", err);
790
783
  console.error("\n", err.stdout || err.message, "\n");
791
- return 3 /* failure */;
784
+ return "failure";
792
785
  }
793
786
  } else {
794
- return 2 /* cancelled */;
787
+ return "cancelled";
795
788
  }
796
789
  }
797
790
  async function validateIntegrations(integrations, flags, logger) {
@@ -911,12 +904,12 @@ async function updateTSConfig(cwd = process.cwd(), logger, integrationsInfo, fla
911
904
  (integration) => presets.has(integration)
912
905
  );
913
906
  if (!firstIntegrationWithTSSettings && includesToAppend.length === 0) {
914
- return 0 /* none */;
907
+ return "none";
915
908
  }
916
909
  let inputConfig = await loadTSConfig(cwd);
917
910
  let inputConfigText = "";
918
911
  if (inputConfig === "invalid-config" || inputConfig === "unknown-error") {
919
- return 3 /* failure */;
912
+ return "failure";
920
913
  } else if (inputConfig === "missing-config") {
921
914
  logger.debug("add", "Couldn't find tsconfig.json or jsconfig.json, generating one");
922
915
  inputConfig = {
@@ -938,7 +931,7 @@ async function updateTSConfig(cwd = process.cwd(), logger, integrationsInfo, fla
938
931
  const output = JSON.stringify(outputConfig, null, 2);
939
932
  const diff = getDiffContent(inputConfigText, output);
940
933
  if (!diff) {
941
- return 0 /* none */;
934
+ return "none";
942
935
  }
943
936
  logger.info(
944
937
  "SKIP_FORMAT",
@@ -975,9 +968,9 @@ async function updateTSConfig(cwd = process.cwd(), logger, integrationsInfo, fla
975
968
  encoding: "utf-8"
976
969
  });
977
970
  logger.debug("add", `Updated ${configFileName} file`);
978
- return 1 /* updated */;
971
+ return "updated";
979
972
  } else {
980
- return 2 /* cancelled */;
973
+ return "cancelled";
981
974
  }
982
975
  }
983
976
  function parseIntegrationName(spec) {
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "6.1.2";
3
+ version = "6.1.4";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
192
192
  logger.info("Content config changed");
193
193
  shouldClear = true;
194
194
  }
195
- if (previousAstroVersion && previousAstroVersion !== "6.1.2") {
195
+ if (previousAstroVersion && previousAstroVersion !== "6.1.4") {
196
196
  logger.info("Astro version changed");
197
197
  shouldClear = true;
198
198
  }
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
200
200
  logger.info("Clearing content store");
201
201
  this.#store.clearAll();
202
202
  }
203
- if ("6.1.2") {
204
- this.#store.metaStore().set("astro-version", "6.1.2");
203
+ if ("6.1.4") {
204
+ this.#store.metaStore().set("astro-version", "6.1.4");
205
205
  }
206
206
  if (currentConfigDigest) {
207
207
  this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -2,8 +2,8 @@ import type * as z from 'zod/v4/core';
2
2
  export declare class LiveCollectionError extends Error {
3
3
  readonly collection: string;
4
4
  readonly message: string;
5
- readonly cause?: Error | undefined;
6
- constructor(collection: string, message: string, cause?: Error | undefined);
5
+ readonly cause?: Error;
6
+ constructor(collection: string, message: string, cause?: Error);
7
7
  static is(error: unknown): error is LiveCollectionError;
8
8
  }
9
9
  export declare class LiveEntryNotFoundError extends LiveCollectionError {
@@ -2,6 +2,9 @@ function formatZodError(error) {
2
2
  return error.issues.map((issue) => ` **${issue.path.join(".")}**: ${issue.message}`);
3
3
  }
4
4
  class LiveCollectionError extends Error {
5
+ collection;
6
+ message;
7
+ cause;
5
8
  constructor(collection, message, cause) {
6
9
  super(message);
7
10
  this.collection = collection;
@@ -242,8 +242,12 @@ function glob(globOptions) {
242
242
  const entryType = configForFile(changedPath);
243
243
  const baseUrl = pathToFileURL(basePath);
244
244
  const oldId = fileToIdMap.get(changedPath);
245
- await syncData(entry, baseUrl, entryType, oldId);
246
- logger.info(`Reloaded data from ${colors.green(entry)}`);
245
+ try {
246
+ await syncData(entry, baseUrl, entryType, oldId);
247
+ logger.info(`Reloaded data from ${colors.green(entry)}`);
248
+ } catch (e) {
249
+ logger.error(`Failed to reload ${entry}: ${e.message}`);
250
+ }
247
251
  }
248
252
  watcher.on("change", onChange);
249
253
  watcher.on("add", onChange);
@@ -35,15 +35,18 @@ class MutableDataStore extends ImmutableDataStore {
35
35
  if (collection) {
36
36
  collection.delete(String(key));
37
37
  this.#saveToDiskDebounced();
38
+ this.#writeAssetsImportsDebounced();
38
39
  }
39
40
  }
40
41
  clear(collectionName) {
41
42
  this._collections.delete(collectionName);
42
43
  this.#saveToDiskDebounced();
44
+ this.#writeAssetsImportsDebounced();
43
45
  }
44
46
  clearAll() {
45
47
  this._collections.clear();
46
48
  this.#saveToDiskDebounced();
49
+ this.#writeAssetsImportsDebounced();
47
50
  }
48
51
  addAssetImport(assetImport, filePath) {
49
52
  const id = imageSrcToImportId(assetImport, filePath);
@@ -62,8 +65,31 @@ class MutableDataStore extends ImmutableDataStore {
62
65
  this.#writeModulesImportsDebounced();
63
66
  }
64
67
  }
68
+ /**
69
+ * Rebuilds #assetImports from the current entries in _collections.
70
+ * This ensures stale import IDs are removed when entries are updated or deleted,
71
+ * preventing unrecoverable ImageNotFound errors in astro dev after a content entry's
72
+ * image path is temporarily set to an invalid value and then restored.
73
+ */
74
+ #rebuildAssetImports() {
75
+ this.#assetImports.clear();
76
+ for (const collection of this._collections.values()) {
77
+ for (const entry of collection.values()) {
78
+ const typedEntry = entry;
79
+ if (typedEntry.assetImports?.length) {
80
+ for (const assetImport of typedEntry.assetImports) {
81
+ const id = imageSrcToImportId(assetImport, typedEntry.filePath);
82
+ if (id) {
83
+ this.#assetImports.add(id);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
65
90
  async writeAssetImports(filePath) {
66
91
  this.#assetsFile = filePath;
92
+ this.#rebuildAssetImports();
67
93
  if (this.#assetImports.size === 0) {
68
94
  try {
69
95
  await this.#writeFileAtomic(filePath, "export default new Map();");
@@ -8,7 +8,7 @@ import {
8
8
  prependForwardSlash,
9
9
  removeTrailingForwardSlash
10
10
  } from "@astrojs/internal-helpers/path";
11
- import { matchPattern } from "../../assets/utils/index.js";
11
+ import { matchPattern } from "@astrojs/internal-helpers/remote";
12
12
  import { normalizeTheLocale } from "../../i18n/index.js";
13
13
  import {
14
14
  clientAddressSymbol,
@@ -42,6 +42,10 @@ class NonRunnablePipeline extends Pipeline {
42
42
  return pipeline;
43
43
  }
44
44
  async headElements(routeData) {
45
+ const { componentMetadataEntries } = await import("virtual:astro:component-metadata");
46
+ for (const [id, entry] of componentMetadataEntries) {
47
+ this.manifest.componentMetadata.set(id, entry);
48
+ }
45
49
  const { assetsPrefix, base } = this.manifest;
46
50
  const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
47
51
  const links = /* @__PURE__ */ new Set();
@@ -8,6 +8,7 @@ import type { ServerIslandMappings } from './app/types.js';
8
8
  import type { SinglePageBuiltModule } from './build/types.js';
9
9
  import type { Logger } from './logger/core.js';
10
10
  import { RouteCache } from './render/route-cache.js';
11
+ import { type DefaultRouteParams } from './routing/default.js';
11
12
  import type { CacheProvider, CacheProviderFactory } from './cache/types.js';
12
13
  import type { CompiledCacheRoute } from './cache/runtime/route-matching.js';
13
14
  import type { SessionDriverFactory } from './session/types.js';
@@ -20,6 +21,14 @@ import { HTMLStringCache } from '../runtime/server/html-string-cache.js';
20
21
  * Thus, a `Pipeline` is created once at process start and then used by every `RenderContext`.
21
22
  */
22
23
  export declare abstract class Pipeline {
24
+ readonly internalMiddleware: MiddlewareHandler[];
25
+ resolvedMiddleware: MiddlewareHandler | undefined;
26
+ resolvedActions: SSRActions | undefined;
27
+ resolvedSessionDriver: SessionDriverFactory | null | undefined;
28
+ resolvedCacheProvider: CacheProvider | null | undefined;
29
+ compiledCacheRoutes: CompiledCacheRoute[] | undefined;
30
+ nodePool: NodePool | undefined;
31
+ htmlStringCache: HTMLStringCache | undefined;
23
32
  readonly logger: Logger;
24
33
  readonly manifest: SSRManifest;
25
34
  /**
@@ -32,12 +41,12 @@ export declare abstract class Pipeline {
32
41
  /**
33
42
  * Used to provide better error messages for `Astro.clientAddress`
34
43
  */
35
- readonly adapterName: string;
36
- readonly clientDirectives: Map<string, string>;
37
- readonly inlinedScripts: Map<string, string>;
38
- readonly compressHTML: boolean;
39
- readonly i18n: import("./app/types.js").SSRManifestI18n | undefined;
40
- readonly middleware: (() => Promise<import("../types/public/common.js").AstroMiddlewareInstance> | import("../types/public/common.js").AstroMiddlewareInstance) | undefined;
44
+ readonly adapterName: SSRManifest['adapterName'];
45
+ readonly clientDirectives: SSRManifest['clientDirectives'];
46
+ readonly inlinedScripts: SSRManifest['inlinedScripts'];
47
+ readonly compressHTML: SSRManifest['compressHTML'];
48
+ readonly i18n: SSRManifest['i18n'];
49
+ readonly middleware: SSRManifest['middleware'];
41
50
  readonly routeCache: RouteCache;
42
51
  /**
43
52
  * Used for `Astro.site`.
@@ -47,29 +56,12 @@ export declare abstract class Pipeline {
47
56
  * Array of built-in, internal, routes.
48
57
  * Used to find the route module
49
58
  */
50
- readonly defaultRoutes: {
51
- instance: ComponentInstance;
52
- matchesComponent(filePath: URL): boolean;
53
- route: string;
54
- component: string;
55
- }[];
56
- readonly actions: (() => Promise<SSRActions> | SSRActions) | undefined;
57
- readonly sessionDriver: (() => Promise<{
58
- default: SessionDriverFactory | null;
59
- }>) | undefined;
60
- readonly cacheProvider: (() => Promise<{
61
- default: CacheProviderFactory | null;
62
- }>) | undefined;
63
- readonly cacheConfig: import("./cache/types.js").SSRManifestCache | undefined;
64
- readonly serverIslands: (() => Promise<ServerIslandMappings> | ServerIslandMappings) | undefined;
65
- readonly internalMiddleware: MiddlewareHandler[];
66
- resolvedMiddleware: MiddlewareHandler | undefined;
67
- resolvedActions: SSRActions | undefined;
68
- resolvedSessionDriver: SessionDriverFactory | null | undefined;
69
- resolvedCacheProvider: CacheProvider | null | undefined;
70
- compiledCacheRoutes: CompiledCacheRoute[] | undefined;
71
- nodePool: NodePool | undefined;
72
- htmlStringCache: HTMLStringCache | undefined;
59
+ readonly defaultRoutes: Array<DefaultRouteParams>;
60
+ readonly actions: SSRManifest['actions'];
61
+ readonly sessionDriver: SSRManifest['sessionDriver'];
62
+ readonly cacheProvider: SSRManifest['cacheProvider'];
63
+ readonly cacheConfig: SSRManifest['cacheConfig'];
64
+ readonly serverIslands: SSRManifest['serverIslandMappings'];
73
65
  constructor(logger: Logger, manifest: SSRManifest,
74
66
  /**
75
67
  * "development" or "production" only
@@ -87,12 +79,7 @@ export declare abstract class Pipeline {
87
79
  * Array of built-in, internal, routes.
88
80
  * Used to find the route module
89
81
  */
90
- defaultRoutes?: {
91
- instance: ComponentInstance;
92
- matchesComponent(filePath: URL): boolean;
93
- route: string;
94
- component: string;
95
- }[], actions?: (() => Promise<SSRActions> | SSRActions) | undefined, sessionDriver?: (() => Promise<{
82
+ defaultRoutes?: DefaultRouteParams[], actions?: (() => Promise<SSRActions> | SSRActions) | undefined, sessionDriver?: (() => Promise<{
96
83
  default: SessionDriverFactory | null;
97
84
  }>) | undefined, cacheProvider?: (() => Promise<{
98
85
  default: CacheProviderFactory | null;
@@ -11,6 +11,47 @@ import { createDefaultRoutes } from "./routing/default.js";
11
11
  import { NodePool } from "../runtime/server/render/queue/pool.js";
12
12
  import { HTMLStringCache } from "../runtime/server/html-string-cache.js";
13
13
  class Pipeline {
14
+ internalMiddleware;
15
+ resolvedMiddleware = void 0;
16
+ resolvedActions = void 0;
17
+ resolvedSessionDriver = void 0;
18
+ resolvedCacheProvider = void 0;
19
+ compiledCacheRoutes = void 0;
20
+ nodePool;
21
+ htmlStringCache;
22
+ logger;
23
+ manifest;
24
+ /**
25
+ * "development" or "production" only
26
+ */
27
+ runtimeMode;
28
+ renderers;
29
+ resolve;
30
+ streaming;
31
+ /**
32
+ * Used to provide better error messages for `Astro.clientAddress`
33
+ */
34
+ adapterName;
35
+ clientDirectives;
36
+ inlinedScripts;
37
+ compressHTML;
38
+ i18n;
39
+ middleware;
40
+ routeCache;
41
+ /**
42
+ * Used for `Astro.site`.
43
+ */
44
+ site;
45
+ /**
46
+ * Array of built-in, internal, routes.
47
+ * Used to find the route module
48
+ */
49
+ defaultRoutes;
50
+ actions;
51
+ sessionDriver;
52
+ cacheProvider;
53
+ cacheConfig;
54
+ serverIslands;
14
55
  constructor(logger, manifest, runtimeMode, renderers, resolve, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions, sessionDriver = manifest.sessionDriver, cacheProvider = manifest.cacheProvider, cacheConfig = manifest.cacheConfig, serverIslands = manifest.serverIslandMappings) {
15
56
  this.logger = logger;
16
57
  this.manifest = manifest;
@@ -48,14 +89,6 @@ class Pipeline {
48
89
  }
49
90
  }
50
91
  }
51
- internalMiddleware;
52
- resolvedMiddleware = void 0;
53
- resolvedActions = void 0;
54
- resolvedSessionDriver = void 0;
55
- resolvedCacheProvider = void 0;
56
- compiledCacheRoutes = void 0;
57
- nodePool;
58
- htmlStringCache;
59
92
  /**
60
93
  * Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
61
94
  * it returns a no-op function
@@ -9,7 +9,9 @@ import {
9
9
  prepareAssetsGenerationEnv
10
10
  } from "../../assets/build/generate.js";
11
11
  import {
12
+ appendForwardSlash,
12
13
  collapseDuplicateTrailingSlashes,
14
+ hasFileExtension,
13
15
  joinPaths,
14
16
  removeLeadingForwardSlash,
15
17
  removeTrailingForwardSlash,
@@ -359,7 +361,13 @@ function getUrlForPath(pathname, base, origin, format, trailingSlash, routeType)
359
361
  }
360
362
  } else if (routeType === "endpoint") {
361
363
  const buildPathRelative = removeLeadingForwardSlash(pathname);
362
- buildPathname = joinPaths(base, buildPathRelative);
364
+ let endpointPathname = joinPaths(base, buildPathRelative);
365
+ if (trailingSlash === "always" && !hasFileExtension(pathname)) {
366
+ endpointPathname = appendForwardSlash(endpointPathname);
367
+ } else if (trailingSlash === "never") {
368
+ endpointPathname = removeTrailingForwardSlash(endpointPathname);
369
+ }
370
+ buildPathname = endpointPathname;
363
371
  } else {
364
372
  const buildPathRelative = removeTrailingForwardSlash(removeLeadingForwardSlash(pathname)) + ending;
365
373
  buildPathname = joinPaths(base, buildPathRelative);