astro 6.2.1 → 6.3.0

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 (137) hide show
  1. package/dist/actions/handler.d.ts +32 -0
  2. package/dist/actions/handler.js +45 -0
  3. package/dist/actions/runtime/server.js +1 -1
  4. package/dist/assets/build/generate.js +1 -1
  5. package/dist/assets/build/remote.d.ts +3 -2
  6. package/dist/assets/build/remote.js +16 -9
  7. package/dist/assets/endpoint/generic.js +4 -7
  8. package/dist/assets/endpoint/shared.js +7 -2
  9. package/dist/assets/index.d.ts +1 -0
  10. package/dist/assets/index.js +2 -0
  11. package/dist/assets/internal.js +16 -1
  12. package/dist/assets/services/sharp.js +16 -1
  13. package/dist/assets/utils/index.d.ts +1 -0
  14. package/dist/assets/utils/index.js +2 -0
  15. package/dist/assets/utils/redirectValidation.d.ts +48 -0
  16. package/dist/assets/utils/redirectValidation.js +48 -0
  17. package/dist/assets/utils/remoteProbe.js +25 -2
  18. package/dist/cli/add/index.js +7 -4
  19. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  20. package/dist/container/index.js +18 -14
  21. package/dist/content/content-layer.js +3 -4
  22. package/dist/content/loaders/types.d.ts +1 -1
  23. package/dist/content/server-listeners.js +0 -4
  24. package/dist/content/vite-plugin-content-virtual-mod.js +9 -1
  25. package/dist/core/app/base.d.ts +33 -15
  26. package/dist/core/app/base.js +120 -324
  27. package/dist/core/app/dev/app.d.ts +3 -2
  28. package/dist/core/app/dev/app.js +4 -60
  29. package/dist/core/app/entrypoints/virtual/dev.js +2 -0
  30. package/dist/core/app/entrypoints/virtual/prod.js +4 -1
  31. package/dist/core/app/prepare-response.d.ts +11 -0
  32. package/dist/core/app/prepare-response.js +18 -0
  33. package/dist/core/app/render-options.d.ts +11 -0
  34. package/dist/core/app/render-options.js +11 -0
  35. package/dist/core/base-pipeline.d.ts +38 -1
  36. package/dist/core/base-pipeline.js +50 -7
  37. package/dist/core/build/app.d.ts +3 -4
  38. package/dist/core/build/app.js +3 -17
  39. package/dist/core/build/plugins/plugin-css.js +7 -1
  40. package/dist/core/build/plugins/plugin-manifest.js +11 -1
  41. package/dist/core/build/static-build.js +16 -2
  42. package/dist/core/cache/handler.d.ts +29 -0
  43. package/dist/core/cache/handler.js +81 -0
  44. package/dist/core/compile/style.js +18 -1
  45. package/dist/core/config/index.d.ts +1 -1
  46. package/dist/core/config/index.js +4 -1
  47. package/dist/core/config/schemas/base.d.ts +4 -0
  48. package/dist/core/config/schemas/base.js +4 -0
  49. package/dist/core/config/schemas/relative.d.ts +6 -0
  50. package/dist/core/config/settings.js +2 -4
  51. package/dist/core/config/tsconfig.d.ts +24 -9
  52. package/dist/core/config/tsconfig.js +54 -45
  53. package/dist/core/constants.d.ts +27 -1
  54. package/dist/core/constants.js +14 -1
  55. package/dist/core/cookies/cookies.d.ts +7 -2
  56. package/dist/core/cookies/cookies.js +11 -4
  57. package/dist/core/cookies/response.d.ts +1 -1
  58. package/dist/core/cookies/response.js +1 -2
  59. package/dist/core/create-vite.js +15 -0
  60. package/dist/core/csp/runtime.js +6 -4
  61. package/dist/core/dev/dev.js +1 -1
  62. package/dist/core/errors/build-handler.d.ts +17 -0
  63. package/dist/core/errors/build-handler.js +22 -0
  64. package/dist/core/errors/default-handler.d.ts +14 -0
  65. package/dist/core/errors/default-handler.js +144 -0
  66. package/dist/core/errors/dev-handler.d.ts +21 -0
  67. package/dist/core/errors/dev-handler.js +82 -0
  68. package/dist/core/errors/handler.d.ts +9 -0
  69. package/dist/core/errors/handler.js +0 -0
  70. package/dist/core/fetch/default-handler.d.ts +17 -0
  71. package/dist/core/fetch/default-handler.js +45 -0
  72. package/dist/core/fetch/fetch-state.d.ts +244 -0
  73. package/dist/core/fetch/fetch-state.js +779 -0
  74. package/dist/core/fetch/index.d.ts +61 -0
  75. package/dist/core/fetch/index.js +121 -0
  76. package/dist/core/fetch/types.d.ts +6 -0
  77. package/dist/core/fetch/types.js +0 -0
  78. package/dist/core/fetch/vite-plugin.d.ts +5 -0
  79. package/dist/core/fetch/vite-plugin.js +69 -0
  80. package/dist/core/hono/index.d.ts +21 -0
  81. package/dist/core/hono/index.js +98 -0
  82. package/dist/core/i18n/handler.d.ts +18 -0
  83. package/dist/core/i18n/handler.js +119 -0
  84. package/dist/core/logger/core.d.ts +8 -0
  85. package/dist/core/logger/core.js +16 -0
  86. package/dist/core/messages/runtime.js +1 -1
  87. package/dist/core/middleware/astro-middleware.d.ts +27 -0
  88. package/dist/core/middleware/astro-middleware.js +53 -0
  89. package/dist/core/pages/handler.d.ts +20 -0
  90. package/dist/core/pages/handler.js +74 -0
  91. package/dist/core/redirects/render.d.ts +2 -2
  92. package/dist/core/redirects/render.js +7 -8
  93. package/dist/core/render/params-and-props.js +1 -1
  94. package/dist/core/render/slots.js +9 -2
  95. package/dist/core/rewrites/handler.d.ts +37 -0
  96. package/dist/core/rewrites/handler.js +67 -0
  97. package/dist/core/routing/3xx.js +8 -4
  98. package/dist/core/routing/handler.d.ts +17 -0
  99. package/dist/core/routing/handler.js +172 -0
  100. package/dist/core/routing/match.d.ts +0 -7
  101. package/dist/core/routing/match.js +0 -5
  102. package/dist/core/routing/pattern.js +1 -1
  103. package/dist/core/routing/rewrite.js +1 -4
  104. package/dist/core/routing/trailing-slash-handler.d.ts +18 -0
  105. package/dist/core/routing/trailing-slash-handler.js +67 -0
  106. package/dist/core/session/drivers.d.ts +1 -1
  107. package/dist/core/session/handler.d.ts +11 -0
  108. package/dist/core/session/handler.js +33 -0
  109. package/dist/core/session/runtime.js +7 -2
  110. package/dist/core/util/normalized-url.d.ts +10 -0
  111. package/dist/core/util/normalized-url.js +21 -0
  112. package/dist/i18n/middleware.d.ts +10 -0
  113. package/dist/i18n/middleware.js +4 -88
  114. package/dist/i18n/utils.js +2 -2
  115. package/dist/prefetch/index.js +12 -7
  116. package/dist/runtime/server/astro-island.js +57 -20
  117. package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +1 -1
  118. package/dist/runtime/server/astro-island.prebuilt-dev.js +1 -1
  119. package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
  120. package/dist/runtime/server/astro-island.prebuilt.js +1 -1
  121. package/dist/runtime/server/render/common.js +10 -4
  122. package/dist/runtime/server/render/server-islands.js +2 -1
  123. package/dist/runtime/server/scripts.js +6 -0
  124. package/dist/types/public/config.d.ts +46 -12
  125. package/dist/types/public/content.d.ts +4 -4
  126. package/dist/types/public/internal.d.ts +1 -1
  127. package/dist/vite-plugin-app/app.d.ts +4 -5
  128. package/dist/vite-plugin-app/app.js +20 -68
  129. package/dist/vite-plugin-astro/compile.js +2 -2
  130. package/dist/vite-plugin-astro/utils.d.ts +1 -0
  131. package/dist/vite-plugin-astro/utils.js +9 -1
  132. package/dist/vite-plugin-head/index.js +36 -19
  133. package/dist/vite-plugin-utils/index.d.ts +1 -0
  134. package/dist/vite-plugin-utils/index.js +3 -0
  135. package/package.json +13 -6
  136. package/dist/core/render-context.d.ts +0 -77
  137. package/dist/core/render-context.js +0 -826
@@ -43,6 +43,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
43
43
  entrypoint: "astro/assets/services/sharp";
44
44
  config: {};
45
45
  };
46
+ dangerouslyProcessSVG: false;
46
47
  responsiveStyles: false;
47
48
  };
48
49
  devToolbar: {
@@ -75,6 +76,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
75
76
  };
76
77
  prerenderConflictBehavior: "warn";
77
78
  experimental: {
79
+ advancedRouting: false;
78
80
  clientPrerender: false;
79
81
  contentIntellisense: false;
80
82
  chromeDevtoolsWorkspace: false;
@@ -153,6 +155,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
153
155
  entrypoint: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"astro/assets/services/sharp">, z.ZodString]>>;
154
156
  config: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
155
157
  }, z.core.$strip>>;
158
+ dangerouslyProcessSVG: z.ZodDefault<z.ZodBoolean>;
156
159
  domains: z.ZodDefault<z.ZodArray<z.ZodString>>;
157
160
  remotePatterns: z.ZodDefault<z.ZodArray<z.ZodObject<{
158
161
  protocol: z.ZodOptional<z.ZodString>;
@@ -498,6 +501,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
498
501
  options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
499
502
  }, z.core.$strict>>>;
500
503
  experimental: z.ZodPrefault<z.ZodObject<{
504
+ advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
501
505
  clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
502
506
  contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
503
507
  chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -28,6 +28,7 @@ const ASTRO_CONFIG_DEFAULTS = {
28
28
  image: {
29
29
  endpoint: { entrypoint: void 0, route: "/_image" },
30
30
  service: { entrypoint: "astro/assets/services/sharp", config: {} },
31
+ dangerouslyProcessSVG: false,
31
32
  responsiveStyles: false
32
33
  },
33
34
  devToolbar: {
@@ -60,6 +61,7 @@ const ASTRO_CONFIG_DEFAULTS = {
60
61
  },
61
62
  prerenderConflictBehavior: "warn",
62
63
  experimental: {
64
+ advancedRouting: false,
63
65
  clientPrerender: false,
64
66
  contentIntellisense: false,
65
67
  chromeDevtoolsWorkspace: false,
@@ -171,6 +173,7 @@ const AstroConfigSchema = z.object({
171
173
  entrypoint: z.union([z.literal("astro/assets/services/sharp"), z.string()]).default(ASTRO_CONFIG_DEFAULTS.image.service.entrypoint),
172
174
  config: z.record(z.string(), z.any()).default({})
173
175
  }).default(ASTRO_CONFIG_DEFAULTS.image.service),
176
+ dangerouslyProcessSVG: z.boolean().default(ASTRO_CONFIG_DEFAULTS.image.dangerouslyProcessSVG),
174
177
  domains: z.array(z.string()).default([]),
175
178
  remotePatterns: z.array(
176
179
  z.object({
@@ -307,6 +310,7 @@ const AstroConfigSchema = z.object({
307
310
  prerenderConflictBehavior: z.enum(["error", "warn", "ignore"]).optional().default(ASTRO_CONFIG_DEFAULTS.prerenderConflictBehavior),
308
311
  fonts: z.array(FontFamilySchema).optional(),
309
312
  experimental: z.strictObject({
313
+ advancedRouting: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.advancedRouting),
310
314
  clientPrerender: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender),
311
315
  contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
312
316
  chromeDevtoolsWorkspace: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.chromeDevtoolsWorkspace),
@@ -36,6 +36,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
36
36
  entrypoint: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"astro/assets/services/sharp">, z.ZodString]>>;
37
37
  config: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
38
38
  }, z.core.$strip>>;
39
+ dangerouslyProcessSVG: z.ZodDefault<z.ZodBoolean>;
39
40
  domains: z.ZodDefault<z.ZodArray<z.ZodString>>;
40
41
  remotePatterns: z.ZodDefault<z.ZodArray<z.ZodObject<{
41
42
  protocol: z.ZodOptional<z.ZodString>;
@@ -381,6 +382,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
381
382
  options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
382
383
  }, z.core.$strict>>>;
383
384
  experimental: z.ZodPrefault<z.ZodObject<{
385
+ advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
384
386
  clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
385
387
  contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
386
388
  chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -468,6 +470,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
468
470
  entrypoint: string;
469
471
  config: Record<string, any>;
470
472
  };
473
+ dangerouslyProcessSVG: boolean;
471
474
  domains: string[];
472
475
  remotePatterns: {
473
476
  protocol?: string | undefined;
@@ -573,6 +576,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
573
576
  };
574
577
  prerenderConflictBehavior: "error" | "ignore" | "warn";
575
578
  experimental: {
579
+ advancedRouting: boolean;
576
580
  clientPrerender: boolean;
577
581
  contentIntellisense: boolean;
578
582
  chromeDevtoolsWorkspace: boolean;
@@ -716,6 +720,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
716
720
  entrypoint: string;
717
721
  config: Record<string, any>;
718
722
  };
723
+ dangerouslyProcessSVG: boolean;
719
724
  domains: string[];
720
725
  remotePatterns: {
721
726
  protocol?: string | undefined;
@@ -821,6 +826,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
821
826
  };
822
827
  prerenderConflictBehavior: "error" | "ignore" | "warn";
823
828
  experimental: {
829
+ advancedRouting: boolean;
824
830
  clientPrerender: boolean;
825
831
  contentIntellisense: boolean;
826
832
  chromeDevtoolsWorkspace: boolean;
@@ -149,10 +149,8 @@ async function createSettings(config, logLevel, cwd) {
149
149
  if (cwd) {
150
150
  watchFiles.push(fileURLToPath(new URL("./package.json", pathToFileURL(cwd))));
151
151
  }
152
- if (typeof tsconfig !== "string") {
153
- watchFiles.push(
154
- ...[tsconfig.tsconfigFile, ...(tsconfig.extended ?? []).map((e) => e.tsconfigFile)]
155
- );
152
+ if (!tsconfig.error) {
153
+ watchFiles.push(...tsconfig.sources);
156
154
  settings.tsConfig = tsconfig.tsconfig;
157
155
  settings.tsConfigPath = tsconfig.tsconfigFile;
158
156
  }
@@ -1,17 +1,32 @@
1
- import { type TSConfckParseResult } from 'tsconfck';
2
1
  import type { CompilerOptions, TypeAcquisition } from 'typescript';
3
2
  export declare const defaultTSConfig: TSConfig;
4
3
  export type frameworkWithTSSettings = 'vue' | 'react' | 'preact' | 'solid-js';
5
4
  export declare const presets: Map<frameworkWithTSSettings, TSConfig>;
6
- type TSConfigResult<T = object> = Promise<(TSConfckParseResult & T) | 'invalid-config' | 'missing-config' | 'unknown-error'>;
5
+ export interface TSConfigLoadedResult {
6
+ error?: undefined;
7
+ /** Absolute path of the root tsconfig/jsconfig file that was loaded. */
8
+ tsconfigFile: string;
9
+ /** The merged/resolved config (after `extends` are walked). */
10
+ tsconfig: TSConfig;
11
+ /** The user-written, un-merged config. Used by `astro add` to round-trip. */
12
+ rawConfig: TSConfig;
13
+ /**
14
+ * Every tsconfig file that contributed via `extends`, root-first.
15
+ * Includes `tsconfigFile`. Used to populate the dev-server watch list.
16
+ */
17
+ sources: string[];
18
+ }
19
+ export type TSConfigResult = TSConfigLoadedResult | {
20
+ error: 'invalid-config';
21
+ message: string;
22
+ } | {
23
+ error: 'missing-config';
24
+ };
7
25
  /**
8
- * Load a tsconfig.json or jsconfig.json is the former is not found
9
- * @param root The root directory to search in, defaults to `process.cwd()`.
10
- * @param findUp Whether to search for the config file in parent directories, by default only the root directory is searched.
26
+ * Load a tsconfig.json or jsconfig.json if the former is not found.
27
+ * @param root The directory to search in, defaults to `process.cwd()`.
11
28
  */
12
- export declare function loadTSConfig(root: string | undefined, findUp?: boolean): Promise<TSConfigResult<{
13
- rawConfig: TSConfig;
14
- }>>;
29
+ export declare function loadTSConfig(root: string | undefined): Promise<TSConfigResult>;
15
30
  export declare function updateTSConfigForFramework(target: TSConfig, framework: frameworkWithTSSettings): TSConfig;
16
31
  type StripEnums<T extends Record<string, any>> = {
17
32
  [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array<any> ? T[K] : T[K] extends undefined ? undefined : any;
@@ -19,7 +34,7 @@ type StripEnums<T extends Record<string, any>> = {
19
34
  export interface TSConfig {
20
35
  compilerOptions?: StripEnums<CompilerOptions>;
21
36
  compileOnSave?: boolean;
22
- extends?: string;
37
+ extends?: string | string[];
23
38
  files?: string[];
24
39
  include?: string[];
25
40
  exclude?: string[];
@@ -1,11 +1,7 @@
1
- import { readFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import {
4
- find,
5
- parse,
6
- TSConfckParseError,
7
- toJson
8
- } from "tsconfck";
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { join, normalize } from "node:path";
3
+ import { readTsconfig } from "get-tsconfig";
4
+ import { parse as parseJsonc } from "jsonc-parser";
9
5
  const defaultTSConfig = { extends: "astro/tsconfigs/base" };
10
6
  const presets = /* @__PURE__ */ new Map([
11
7
  [
@@ -48,50 +44,63 @@ const presets = /* @__PURE__ */ new Map([
48
44
  }
49
45
  ]
50
46
  ]);
51
- async function loadTSConfig(root, findUp = false) {
52
- const safeCwd = root ?? process.cwd();
53
- const [jsconfig, tsconfig] = await Promise.all(
54
- ["jsconfig.json", "tsconfig.json"].map(
55
- (configName) => (
56
- // `tsconfck` expects its first argument to be a file path, not a directory path, so we'll fake one
57
- find(join(safeCwd, "./dummy.txt"), {
58
- root: findUp ? void 0 : root,
59
- configName
60
- })
61
- )
62
- )
63
- );
64
- if (tsconfig) {
65
- const parsedConfig = await safeParse(tsconfig, { root });
66
- if (typeof parsedConfig === "string") {
67
- return parsedConfig;
47
+ async function loadTSConfig(root) {
48
+ const safeCwd = root || process.cwd();
49
+ let tsconfigPath;
50
+ for (const configName of ["tsconfig.json", "jsconfig.json"]) {
51
+ const possiblePath = join(safeCwd, configName);
52
+ if (existsSync(possiblePath)) {
53
+ tsconfigPath = possiblePath;
54
+ break;
68
55
  }
69
- const rawConfig = await readFile(tsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
70
- return { ...parsedConfig, rawConfig };
71
56
  }
72
- if (jsconfig) {
73
- const parsedConfig = await safeParse(jsconfig, { root });
74
- if (typeof parsedConfig === "string") {
75
- return parsedConfig;
76
- }
77
- const rawConfig = await readFile(jsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
78
- return { ...parsedConfig, rawConfig };
57
+ if (!tsconfigPath) {
58
+ return {
59
+ error: "missing-config"
60
+ };
79
61
  }
80
- return "missing-config";
81
- }
82
- async function safeParse(tsconfigPath, options = {}) {
62
+ let rawConfig;
83
63
  try {
84
- const parseResult = await parse(tsconfigPath, options);
85
- if (parseResult.tsconfig == null) {
86
- return "missing-config";
64
+ const text = readFileSync(tsconfigPath, "utf-8");
65
+ const errors = [];
66
+ const parsed = parseJsonc(text, errors, { allowTrailingComma: true });
67
+ if (errors.length > 0) {
68
+ const first = errors[0];
69
+ return {
70
+ error: "invalid-config",
71
+ message: `Failed to parse ${tsconfigPath}: Malformed JSONC (error code ${first.error}) at offset ${first.offset}`
72
+ };
87
73
  }
88
- return parseResult;
74
+ rawConfig = parsed;
89
75
  } catch (e) {
90
- if (e instanceof TSConfckParseError) {
91
- return "invalid-config";
92
- }
93
- return "unknown-error";
76
+ const message = e instanceof Error ? e.message : String(e);
77
+ return {
78
+ error: "invalid-config",
79
+ message: `Failed to parse ${tsconfigPath}: ${message}`
80
+ };
81
+ }
82
+ if (!rawConfig) {
83
+ return {
84
+ error: "invalid-config",
85
+ message: `Failed to parse ${tsconfigPath}: Unknown error`
86
+ };
87
+ }
88
+ let resolved;
89
+ try {
90
+ resolved = readTsconfig(tsconfigPath);
91
+ } catch (e) {
92
+ const message = e instanceof Error ? e.message : String(e);
93
+ return {
94
+ error: "invalid-config",
95
+ message: `Failed to resolve ${tsconfigPath}: ${message}`
96
+ };
94
97
  }
98
+ return {
99
+ tsconfigFile: normalize(resolved.path),
100
+ tsconfig: resolved.config,
101
+ rawConfig,
102
+ sources: (resolved.sources || [resolved.path]).map(normalize)
103
+ };
95
104
  }
96
105
  function updateTSConfigForFramework(target, framework) {
97
106
  if (!presets.has(framework)) {
@@ -35,6 +35,17 @@ export declare const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop";
35
35
  * The name for the header used to help i18n middleware, which only needs to act on "page" and "fallback" route types.
36
36
  */
37
37
  export declare const ROUTE_TYPE_HEADER = "X-Astro-Route-Type";
38
+ /**
39
+ * Internal headers that should be stripped from the response before
40
+ * sending it to the user agent. Add new internal headers here so
41
+ * `prepareResponse` removes them automatically.
42
+ */
43
+ export declare const INTERNAL_RESPONSE_HEADERS: readonly ["X-Astro-Reroute", "X-Astro-Rewrite", "X-Astro-Noop", "X-Astro-Route-Type"];
44
+ /**
45
+ * Set by internal handlers (e.g. PagesHandler) to signal that a
46
+ * response should be replaced with the corresponding error page.
47
+ */
48
+ export declare const ASTRO_ERROR_HEADER = "X-Astro-Error";
38
49
  /**
39
50
  * The value of the `component` field of the default 404 page, which is used when there is no user-provided 404.astro page.
40
51
  */
@@ -55,7 +66,7 @@ export declare const REROUTABLE_STATUS_CODES: number[];
55
66
  export declare const clientAddressSymbol: unique symbol;
56
67
  /**
57
68
  * The symbol used as a field on the request object to store the object to be made available to Astro APIs as `locals`.
58
- * Use judiciously, as locals are now stored within `RenderContext` by default. Tacking it onto request is no longer necessary.
69
+ * Use judiciously, as locals are now stored within `FetchState` by default. Tacking it onto request is no longer necessary.
59
70
  */
60
71
  export declare const clientLocalsSymbol: unique symbol;
61
72
  /**
@@ -66,6 +77,21 @@ export declare const originPathnameSymbol: unique symbol;
66
77
  * Use this symbol to set and retrieve the pipeline.
67
78
  */
68
79
  export declare const pipelineSymbol: unique symbol;
80
+ /**
81
+ * Use this symbol to stash the active `FetchState` on an `APIContext`
82
+ * (or `ActionAPIContext`). Consumed by internal shims that need access
83
+ * to per-request state without appearing in the public context shape
84
+ * — e.g. the manual-strategy i18n middleware wrapper in
85
+ * `src/i18n/middleware.ts`.
86
+ */
87
+ export declare const fetchStateSymbol: unique symbol;
88
+ /**
89
+ * Use this symbol to stash the `BaseApp` on an incoming `Request` at the
90
+ * top of the pipeline. Fetch handlers loaded from `virtual:astro:fetchable`
91
+ * (including `DefaultFetchHandler`) read it to find the app associated
92
+ * with the current request without needing App passed to their constructor.
93
+ */
94
+ export declare const appSymbol: unique symbol;
69
95
  /**
70
96
  * Use this symbol to opt into handling prerender routes in Astro core dev middleware.
71
97
  */
@@ -1,10 +1,17 @@
1
- const ASTRO_VERSION = "6.2.1";
1
+ const ASTRO_VERSION = "6.3.0";
2
2
  const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`;
3
3
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
4
4
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
5
5
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
6
6
  const NOOP_MIDDLEWARE_HEADER = "X-Astro-Noop";
7
7
  const ROUTE_TYPE_HEADER = "X-Astro-Route-Type";
8
+ const INTERNAL_RESPONSE_HEADERS = [
9
+ REROUTE_DIRECTIVE_HEADER,
10
+ REWRITE_DIRECTIVE_HEADER_KEY,
11
+ NOOP_MIDDLEWARE_HEADER,
12
+ ROUTE_TYPE_HEADER
13
+ ];
14
+ const ASTRO_ERROR_HEADER = "X-Astro-Error";
8
15
  const DEFAULT_404_COMPONENT = "astro-default-404.astro";
9
16
  const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308, 300, 304];
10
17
  const REROUTABLE_STATUS_CODES = [404, 500];
@@ -12,6 +19,8 @@ const clientAddressSymbol = /* @__PURE__ */ Symbol.for("astro.clientAddress");
12
19
  const clientLocalsSymbol = /* @__PURE__ */ Symbol.for("astro.locals");
13
20
  const originPathnameSymbol = /* @__PURE__ */ Symbol.for("astro.originPathname");
14
21
  const pipelineSymbol = /* @__PURE__ */ Symbol.for("astro.pipeline");
22
+ const fetchStateSymbol = /* @__PURE__ */ Symbol.for("astro.fetchState");
23
+ const appSymbol = /* @__PURE__ */ Symbol.for("astro.app");
15
24
  const devPrerenderMiddlewareSymbol = /* @__PURE__ */ Symbol.for("astro.devPrerenderMiddleware");
16
25
  const nodeRequestAbortControllerCleanupSymbol = /* @__PURE__ */ Symbol.for(
17
26
  "astro.nodeRequestAbortControllerCleanup"
@@ -43,10 +52,12 @@ const ASTRO_VITE_ENVIRONMENT_NAMES = {
43
52
  prerender: "prerender"
44
53
  };
45
54
  export {
55
+ ASTRO_ERROR_HEADER,
46
56
  ASTRO_GENERATOR,
47
57
  ASTRO_VERSION,
48
58
  ASTRO_VITE_ENVIRONMENT_NAMES,
49
59
  DEFAULT_404_COMPONENT,
60
+ INTERNAL_RESPONSE_HEADERS,
50
61
  MIDDLEWARE_PATH_SEGMENT_NAME,
51
62
  NOOP_MIDDLEWARE_HEADER,
52
63
  REDIRECT_STATUS_CODES,
@@ -56,9 +67,11 @@ export {
56
67
  REWRITE_DIRECTIVE_HEADER_VALUE,
57
68
  ROUTE_TYPE_HEADER,
58
69
  SUPPORTED_MARKDOWN_FILE_EXTENSIONS,
70
+ appSymbol,
59
71
  clientAddressSymbol,
60
72
  clientLocalsSymbol,
61
73
  devPrerenderMiddlewareSymbol,
74
+ fetchStateSymbol,
62
75
  nodeRequestAbortControllerCleanupSymbol,
63
76
  originPathnameSymbol,
64
77
  pipelineSymbol,
@@ -72,8 +72,13 @@ declare class AstroCookies implements AstroCookiesInterface {
72
72
  */
73
73
  headers(): Generator<string, void, unknown>;
74
74
  /**
75
- * Behaves the same as AstroCookies.prototype.headers(),
76
- * but allows a warning when cookies are set after the instance is consumed.
75
+ * Marks the cookies as consumed and returns the header values.
76
+ * After consumption, any subsequent `set()` calls will warn.
77
+ */
78
+ consume(): Generator<string, void, unknown>;
79
+ /**
80
+ * @deprecated Use the instance method `cookies.consume()` instead.
81
+ * Kept for backward compatibility with adapters.
77
82
  */
78
83
  static consume(cookies: AstroCookies): Generator<string, void, unknown>;
79
84
  }
@@ -173,12 +173,19 @@ class AstroCookies {
173
173
  }
174
174
  }
175
175
  /**
176
- * Behaves the same as AstroCookies.prototype.headers(),
177
- * but allows a warning when cookies are set after the instance is consumed.
176
+ * Marks the cookies as consumed and returns the header values.
177
+ * After consumption, any subsequent `set()` calls will warn.
178
+ */
179
+ consume() {
180
+ this.#consumed = true;
181
+ return this.headers();
182
+ }
183
+ /**
184
+ * @deprecated Use the instance method `cookies.consume()` instead.
185
+ * Kept for backward compatibility with adapters.
178
186
  */
179
187
  static consume(cookies) {
180
- cookies.#consumed = true;
181
- return cookies.headers();
188
+ return cookies.consume();
182
189
  }
183
190
  #ensureParsed() {
184
191
  if (!this.#requestValues) {
@@ -1,4 +1,4 @@
1
- import { AstroCookies } from './cookies.js';
1
+ import type { AstroCookies } from './cookies.js';
2
2
  export declare function attachCookiesToResponse(response: Response, cookies: AstroCookies): void;
3
3
  export declare function getCookiesFromResponse(response: Response): AstroCookies | undefined;
4
4
  export declare function getSetCookiesFromResponse(response: Response): Generator<string, string[]>;
@@ -1,4 +1,3 @@
1
- import { AstroCookies } from "./cookies.js";
2
1
  const astroCookiesSymbol = /* @__PURE__ */ Symbol.for("astro.cookies");
3
2
  function attachCookiesToResponse(response, cookies) {
4
3
  Reflect.set(response, astroCookiesSymbol, cookies);
@@ -16,7 +15,7 @@ function* getSetCookiesFromResponse(response) {
16
15
  if (!cookies) {
17
16
  return [];
18
17
  }
19
- for (const headerValue of AstroCookies.consume(cookies)) {
18
+ for (const headerValue of cookies.consume()) {
20
19
  yield headerValue;
21
20
  }
22
21
  return [];
@@ -23,6 +23,7 @@ import astroDevToolbar from "../toolbar/vite-plugin-dev-toolbar.js";
23
23
  import astroTransitions from "../transitions/vite-plugin-transitions.js";
24
24
  import { vitePluginAdapterConfig } from "../vite-plugin-adapter-config/index.js";
25
25
  import { vitePluginApp } from "../vite-plugin-app/index.js";
26
+ import { vitePluginFetchable } from "./fetch/vite-plugin.js";
26
27
  import astroVitePlugin from "../vite-plugin-astro/index.js";
27
28
  import { vitePluginAstroServer } from "../vite-plugin-astro-server/index.js";
28
29
  import configAliasVitePlugin from "../vite-plugin-config-alias/index.js";
@@ -118,6 +119,19 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
118
119
  customLogger: createViteLogger(logger, settings.config.vite.logLevel),
119
120
  appType: "custom",
120
121
  plugins: [
122
+ // Raise the watcher's maxListeners limit before any other plugin's
123
+ // configureServer hook can add listeners. Astro registers 12+ change
124
+ // listeners across its built-in Vite plugins, easily exceeding
125
+ // Node's default limit of 10.
126
+ {
127
+ name: "astro:watcher-max-listeners",
128
+ configureServer(server) {
129
+ const current = server.watcher.getMaxListeners();
130
+ if (current !== 0 && current < 50) {
131
+ server.watcher.setMaxListeners(50);
132
+ }
133
+ }
134
+ },
121
135
  serializedManifestPlugin({ settings, command, sync }),
122
136
  vitePluginRenderers({
123
137
  settings,
@@ -138,6 +152,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
138
152
  // The server plugin is for dev only and having it run during the build causes
139
153
  // the build to run very slow as the filewatcher is triggered often.
140
154
  vitePluginApp(),
155
+ vitePluginFetchable({ settings }),
141
156
  command === "dev" && vitePluginAstroServer({ settings, logger }),
142
157
  command === "dev" && vitePluginAstroServerClient(),
143
158
  astroDevCssPlugin({ routesList, command }),
@@ -8,25 +8,27 @@ function deduplicateDirectiveValues(existingDirective, newDirective) {
8
8
  return `${directiveName} ${finalDirectives.join(" ")}`;
9
9
  }
10
10
  function pushDirective(directives, newDirective) {
11
- let deduplicated = false;
12
11
  if (directives.length === 0) {
13
12
  return [newDirective];
14
13
  }
15
14
  const finalDirectives = [];
15
+ let matched = false;
16
16
  for (const directive of directives) {
17
- if (deduplicated) {
17
+ if (matched) {
18
18
  finalDirectives.push(directive);
19
19
  continue;
20
20
  }
21
21
  const result = deduplicateDirectiveValues(directive, newDirective);
22
22
  if (result) {
23
23
  finalDirectives.push(result);
24
- deduplicated = true;
24
+ matched = true;
25
25
  } else {
26
26
  finalDirectives.push(directive);
27
- finalDirectives.push(newDirective);
28
27
  }
29
28
  }
29
+ if (!matched) {
30
+ finalDirectives.push(newDirective);
31
+ }
30
32
  return finalDirectives;
31
33
  }
32
34
  export {
@@ -37,7 +37,7 @@ async function dev(inlineConfig) {
37
37
  await telemetry.record([]);
38
38
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
39
39
  const logger = restart.container.logger;
40
- const currentVersion = "6.2.1";
40
+ const currentVersion = "6.3.0";
41
41
  const isPrerelease = currentVersion.includes("-");
42
42
  if (!isPrerelease) {
43
43
  try {
@@ -0,0 +1,17 @@
1
+ import type { BaseApp, RenderErrorOptions } from '../app/base.js';
2
+ import type { Pipeline } from '../base-pipeline.js';
3
+ import type { ErrorHandler } from './handler.js';
4
+ /**
5
+ * The error handler used during static build / prerendering.
6
+ *
7
+ * - For 500 errors, returns the original response if present, otherwise
8
+ * throws so the build surfaces the underlying error to the developer.
9
+ * - For other errors (e.g. 404), delegates to `DefaultErrorHandler` with
10
+ * `prerenderedErrorPageFetch` cleared (the build pipeline can't fetch
11
+ * prerendered pages the way production SSR can).
12
+ */
13
+ export declare class BuildErrorHandler implements ErrorHandler {
14
+ #private;
15
+ constructor(app: BaseApp<Pipeline>);
16
+ renderError(request: Request, options: RenderErrorOptions): Promise<Response>;
17
+ }
@@ -0,0 +1,22 @@
1
+ import { DefaultErrorHandler } from "./default-handler.js";
2
+ class BuildErrorHandler {
3
+ #default;
4
+ constructor(app) {
5
+ this.#default = new DefaultErrorHandler(app);
6
+ }
7
+ async renderError(request, options) {
8
+ if (options.status === 500) {
9
+ if (options.response) {
10
+ return options.response;
11
+ }
12
+ throw options.error;
13
+ }
14
+ return this.#default.renderError(request, {
15
+ ...options,
16
+ prerenderedErrorPageFetch: void 0
17
+ });
18
+ }
19
+ }
20
+ export {
21
+ BuildErrorHandler
22
+ };
@@ -0,0 +1,14 @@
1
+ import type { BaseApp, RenderErrorOptions } from '../app/base.js';
2
+ import type { Pipeline } from '../base-pipeline.js';
3
+ import type { ErrorHandler } from './handler.js';
4
+ /**
5
+ * The default error handler used in production SSR. Attempts to render the
6
+ * matching error route (404.astro / 500.astro), falling back to a plain
7
+ * response with the given status. Handles prerendered error pages via
8
+ * `prerenderedErrorPageFetch`.
9
+ */
10
+ export declare class DefaultErrorHandler implements ErrorHandler {
11
+ #private;
12
+ constructor(app: BaseApp<Pipeline>);
13
+ renderError(request: Request, { status, response: originalResponse, skipMiddleware, error, pathname, ...resolvedRenderOptions }: RenderErrorOptions): Promise<Response>;
14
+ }