astro 4.9.2 → 4.10.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 (76) hide show
  1. package/client.d.ts +8 -0
  2. package/components/Picture.astro +2 -1
  3. package/config.d.ts +6 -0
  4. package/config.mjs +1 -0
  5. package/dist/@types/astro.d.ts +124 -0
  6. package/dist/assets/utils/proxy.js +1 -1
  7. package/dist/cli/add/babel.d.ts +1 -1
  8. package/dist/cli/install-package.d.ts +1 -1
  9. package/dist/cli/install-package.js +1 -1
  10. package/dist/config/index.js +2 -2
  11. package/dist/container/index.d.ts +11 -15
  12. package/dist/container/index.js +29 -27
  13. package/dist/container/pipeline.d.ts +1 -0
  14. package/dist/container/pipeline.js +8 -1
  15. package/dist/content/types-generator.js +5 -5
  16. package/dist/content/utils.d.ts +2 -3
  17. package/dist/content/utils.js +3 -4
  18. package/dist/content/vite-plugin-content-virtual-mod.d.ts +1 -1
  19. package/dist/core/app/pipeline.d.ts +2 -1
  20. package/dist/core/app/pipeline.js +44 -19
  21. package/dist/core/app/types.d.ts +1 -0
  22. package/dist/core/base-pipeline.d.ts +15 -3
  23. package/dist/core/base-pipeline.js +10 -1
  24. package/dist/core/build/generate.js +14 -4
  25. package/dist/core/build/pipeline.d.ts +2 -1
  26. package/dist/core/build/pipeline.js +31 -19
  27. package/dist/core/build/plugins/plugin-content.js +2 -1
  28. package/dist/core/build/plugins/plugin-manifest.js +2 -1
  29. package/dist/core/config/config.js +1 -1
  30. package/dist/core/config/schema.d.ts +644 -0
  31. package/dist/core/config/schema.js +5 -1
  32. package/dist/core/config/settings.js +1 -0
  33. package/dist/core/constants.d.ts +1 -1
  34. package/dist/core/constants.js +2 -2
  35. package/dist/core/create-vite.js +2 -0
  36. package/dist/core/dev/dev.js +1 -1
  37. package/dist/core/errors/errors-data.d.ts +61 -1
  38. package/dist/core/errors/errors-data.js +39 -0
  39. package/dist/core/logger/core.d.ts +1 -1
  40. package/dist/core/messages.js +2 -2
  41. package/dist/core/render-context.d.ts +1 -0
  42. package/dist/core/render-context.js +74 -57
  43. package/dist/core/routing/astro-designed-error-pages.d.ts +8 -1
  44. package/dist/core/routing/astro-designed-error-pages.js +29 -12
  45. package/dist/env/config.d.ts +9 -0
  46. package/dist/env/config.js +17 -0
  47. package/dist/env/constants.d.ts +11 -0
  48. package/dist/env/constants.js +21 -0
  49. package/dist/env/runtime.d.ts +6 -0
  50. package/dist/env/runtime.js +21 -0
  51. package/dist/env/schema.d.ts +387 -0
  52. package/dist/env/schema.js +113 -0
  53. package/dist/env/validators.d.ts +13 -0
  54. package/dist/env/validators.js +57 -0
  55. package/dist/env/vite-plugin-env.d.ts +11 -0
  56. package/dist/env/vite-plugin-env.js +174 -0
  57. package/dist/integrations/features-validation.js +9 -1
  58. package/dist/jsx/server.js +2 -1
  59. package/dist/runtime/server/render/astro/render.js +15 -1
  60. package/dist/runtime/server/util.js +1 -1
  61. package/dist/virtual-modules/container.d.ts +16 -0
  62. package/dist/virtual-modules/container.js +18 -0
  63. package/dist/virtual-modules/env-setup.d.ts +1 -0
  64. package/dist/virtual-modules/env-setup.js +4 -0
  65. package/dist/vite-plugin-astro-server/pipeline.d.ts +3 -2
  66. package/dist/vite-plugin-astro-server/pipeline.js +34 -20
  67. package/dist/vite-plugin-astro-server/plugin.js +1 -0
  68. package/dist/vite-plugin-astro-server/response.d.ts +0 -6
  69. package/dist/vite-plugin-astro-server/response.js +0 -13
  70. package/dist/vite-plugin-astro-server/route.js +2 -1
  71. package/dist/vite-plugin-inject-env-ts/index.js +46 -38
  72. package/package.json +19 -20
  73. package/templates/env/module.mjs +18 -0
  74. package/templates/env/types.d.ts +20 -0
  75. /package/{content-module.template.mjs → templates/content/module.mjs} +0 -0
  76. /package/{content-types.template.d.ts → templates/content/types.d.ts} +0 -0
@@ -1,7 +1,10 @@
1
1
  import { Pipeline } from "../base-pipeline.js";
2
2
  import { DEFAULT_404_COMPONENT } from "../constants.js";
3
+ import { RewriteEncounteredAnError } from "../errors/errors-data.js";
4
+ import { AstroError } from "../errors/index.js";
3
5
  import { RedirectSinglePageBuiltModule } from "../redirects/component.js";
4
6
  import { createModuleScriptElement, createStylesheetElementSet } from "../render/ssr-element.js";
7
+ import { DEFAULT_404_ROUTE } from "../routing/astro-designed-error-pages.js";
5
8
  class AppPipeline extends Pipeline {
6
9
  #manifestData;
7
10
  static create(manifestData, {
@@ -20,7 +23,16 @@ class AppPipeline extends Pipeline {
20
23
  renderers,
21
24
  resolve,
22
25
  serverLike,
23
- streaming
26
+ streaming,
27
+ void 0,
28
+ void 0,
29
+ void 0,
30
+ void 0,
31
+ void 0,
32
+ void 0,
33
+ void 0,
34
+ void 0,
35
+ false
24
36
  );
25
37
  pipeline.#manifestData = manifestData;
26
38
  return pipeline;
@@ -50,33 +62,38 @@ class AppPipeline extends Pipeline {
50
62
  const module = await this.getModuleForRoute(routeData);
51
63
  return module.page();
52
64
  }
53
- async tryRewrite(payload, request) {
65
+ async tryRewrite(payload, request, sourceRoute) {
54
66
  let foundRoute;
55
67
  for (const route of this.#manifestData.routes) {
68
+ let finalUrl = void 0;
56
69
  if (payload instanceof URL) {
57
- if (route.pattern.test(payload.pathname)) {
58
- foundRoute = route;
59
- break;
60
- }
70
+ finalUrl = payload;
61
71
  } else if (payload instanceof Request) {
62
- const url = new URL(payload.url);
63
- if (route.pattern.test(url.pathname)) {
64
- foundRoute = route;
65
- break;
66
- }
72
+ finalUrl = new URL(payload.url);
67
73
  } else {
68
- const newUrl = new URL(payload, new URL(request.url).origin);
69
- if (route.pattern.test(decodeURI(newUrl.pathname))) {
70
- foundRoute = route;
71
- break;
72
- }
74
+ finalUrl = new URL(payload, new URL(request.url).origin);
75
+ }
76
+ if (route.pattern.test(decodeURI(finalUrl.pathname))) {
77
+ foundRoute = route;
78
+ break;
79
+ } else if (finalUrl.pathname === "/404") {
80
+ foundRoute = DEFAULT_404_ROUTE;
81
+ break;
73
82
  }
74
83
  }
75
84
  if (foundRoute) {
76
- const componentInstance = await this.getComponentByRoute(foundRoute);
77
- return [foundRoute, componentInstance];
85
+ if (foundRoute.pathname === "/404") {
86
+ const componentInstance = this.rewriteKnownRoute(foundRoute.pathname, sourceRoute);
87
+ return [foundRoute, componentInstance];
88
+ } else {
89
+ const componentInstance = await this.getComponentByRoute(foundRoute);
90
+ return [foundRoute, componentInstance];
91
+ }
78
92
  }
79
- throw new Error("Route not found");
93
+ throw new AstroError({
94
+ ...RewriteEncounteredAnError,
95
+ message: RewriteEncounteredAnError.message(payload.toString())
96
+ });
80
97
  }
81
98
  async getModuleForRoute(route) {
82
99
  if (route.component === DEFAULT_404_COMPONENT) {
@@ -104,6 +121,14 @@ class AppPipeline extends Pipeline {
104
121
  );
105
122
  }
106
123
  }
124
+ // We don't need to check the source route, we already are in SSR
125
+ rewriteKnownRoute(pathname, _sourceRoute) {
126
+ if (pathname === "/404") {
127
+ return { default: () => new Response(null, { status: 404 }) };
128
+ } else {
129
+ return { default: () => new Response(null, { status: 500 }) };
130
+ }
131
+ }
107
132
  }
108
133
  export {
109
134
  AppPipeline
@@ -53,6 +53,7 @@ export type SSRManifest = {
53
53
  middleware: MiddlewareHandler;
54
54
  checkOrigin: boolean;
55
55
  rewritingEnabled: boolean;
56
+ experimentalEnvGetSecretEnabled: boolean;
56
57
  };
57
58
  export type SSRManifestI18n = {
58
59
  fallback: Record<string, string> | undefined;
@@ -35,6 +35,7 @@ export declare abstract class Pipeline {
35
35
  * Used for `Astro.site`.
36
36
  */
37
37
  readonly site: URL | undefined;
38
+ readonly callSetGetEnv: boolean;
38
39
  readonly internalMiddleware: MiddlewareHandler[];
39
40
  constructor(logger: Logger, manifest: SSRManifest,
40
41
  /**
@@ -52,7 +53,7 @@ export declare abstract class Pipeline {
52
53
  /**
53
54
  * Used for `Astro.site`.
54
55
  */
55
- site?: URL | undefined);
56
+ site?: URL | undefined, callSetGetEnv?: boolean);
56
57
  abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
57
58
  abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
58
59
  /**
@@ -62,14 +63,25 @@ export declare abstract class Pipeline {
62
63
  *
63
64
  * - if not `RouteData` is found
64
65
  *
65
- * @param {RewritePayload} rewritePayload
66
+ * @param {RewritePayload} rewritePayload The payload provided by the user
67
+ * @param {Request} request The original request
68
+ * @param {RouteData} sourceRoute The original `RouteData`
66
69
  */
67
- abstract tryRewrite(rewritePayload: RewritePayload, request: Request): Promise<[RouteData, ComponentInstance]>;
70
+ abstract tryRewrite(rewritePayload: RewritePayload, request: Request, sourceRoute: RouteData): Promise<[RouteData, ComponentInstance]>;
68
71
  /**
69
72
  * Tells the pipeline how to retrieve a component give a `RouteData`
70
73
  * @param routeData
71
74
  */
72
75
  abstract getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
76
+ /**
77
+ * Attempts to execute a rewrite of a known Astro route:
78
+ * - /404 -> src/pages/404.astro -> template
79
+ * - /500 -> src/pages/500.astro
80
+ *
81
+ * @param pathname The pathname where the user wants to rewrite e.g. "/404"
82
+ * @param sourceRoute The original route where the first request started. This is needed in case a pipeline wants to check if the current route is pre-rendered or not
83
+ */
84
+ abstract rewriteKnownRoute(pathname: string, sourceRoute: RouteData): ComponentInstance;
73
85
  }
74
86
  export interface HeadElements extends Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
75
87
  }
@@ -1,7 +1,10 @@
1
+ import { setGetEnv } from "../env/runtime.js";
1
2
  import { createI18nMiddleware } from "../i18n/middleware.js";
3
+ import { AstroError } from "./errors/errors.js";
4
+ import { AstroErrorData } from "./errors/index.js";
2
5
  import { RouteCache } from "./render/route-cache.js";
3
6
  class Pipeline {
4
- constructor(logger, manifest, mode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, mode), site = manifest.site ? new URL(manifest.site) : void 0) {
7
+ constructor(logger, manifest, mode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, mode), site = manifest.site ? new URL(manifest.site) : void 0, callSetGetEnv = true) {
5
8
  this.logger = logger;
6
9
  this.manifest = manifest;
7
10
  this.mode = mode;
@@ -17,12 +20,18 @@ class Pipeline {
17
20
  this.middleware = middleware;
18
21
  this.routeCache = routeCache;
19
22
  this.site = site;
23
+ this.callSetGetEnv = callSetGetEnv;
20
24
  this.internalMiddleware = [];
21
25
  if (i18n?.strategy !== "manual") {
22
26
  this.internalMiddleware.push(
23
27
  createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat)
24
28
  );
25
29
  }
30
+ if (callSetGetEnv && manifest.experimentalEnvGetSecretEnabled) {
31
+ setGetEnv(() => {
32
+ throw new AstroError(AstroErrorData.EnvUnsupportedGetSecret);
33
+ });
34
+ }
26
35
  }
27
36
  internalMiddleware;
28
37
  }
@@ -30,8 +30,6 @@ import { getOutputFilename, isServerLikeOutput } from "../util.js";
30
30
  import { getOutDirWithinCwd, getOutFile, getOutFolder } from "./common.js";
31
31
  import { cssOrder, mergeInlineCss } from "./internal.js";
32
32
  import { BuildPipeline } from "./pipeline.js";
33
- import { ASTRO_PAGE_MODULE_ID } from "./plugins/plugin-pages.js";
34
- import { getVirtualModulePageName } from "./plugins/util.js";
35
33
  import { getTimeStat, shouldAppendForwardSlash } from "./util.js";
36
34
  function createEntryURL(filePath, outFolder) {
37
35
  return new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
@@ -264,7 +262,18 @@ function addPageName(pathname, opts) {
264
262
  opts.pageNames.push(pageName);
265
263
  }
266
264
  function getUrlForPath(pathname, base, origin, format, trailingSlash, routeType) {
267
- const ending = format === "directory" ? trailingSlash === "never" ? "" : "/" : ".html";
265
+ let ending;
266
+ switch (format) {
267
+ case "directory":
268
+ case "preserve": {
269
+ ending = trailingSlash === "never" ? "" : "/";
270
+ break;
271
+ }
272
+ default: {
273
+ ending = ".html";
274
+ break;
275
+ }
276
+ }
268
277
  let buildPathname;
269
278
  if (pathname === "/" || pathname === "") {
270
279
  buildPathname = base;
@@ -388,7 +397,8 @@ function createBuildManifest(settings, internals, renderers, middleware) {
388
397
  buildFormat: settings.config.build.format,
389
398
  middleware,
390
399
  rewritingEnabled: settings.config.experimental.rewriting,
391
- checkOrigin: settings.config.security?.checkOrigin ?? false
400
+ checkOrigin: settings.config.security?.checkOrigin ?? false,
401
+ experimentalEnvGetSecretEnabled: false
392
402
  };
393
403
  }
394
404
  export {
@@ -38,6 +38,7 @@ export declare class BuildPipeline extends Pipeline {
38
38
  */
39
39
  retrieveRoutesToGenerate(): Map<PageBuildData, string>;
40
40
  getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
41
- tryRewrite(payload: RewritePayload, request: Request): Promise<[RouteData, ComponentInstance]>;
41
+ tryRewrite(payload: RewritePayload, request: Request, sourceRoute: RouteData): Promise<[RouteData, ComponentInstance]>;
42
42
  retrieveSsrEntry(route: RouteData, filePath: string): Promise<SinglePageBuiltModule>;
43
+ rewriteKnownRoute(_pathname: string, sourceRoute: RouteData): ComponentInstance;
43
44
  }
@@ -1,6 +1,6 @@
1
1
  import { getOutputDirectory } from "../../prerender/utils.js";
2
2
  import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
3
- import { RouteNotFound } from "../errors/errors-data.js";
3
+ import { InvalidRewrite404, RewriteEncounteredAnError } from "../errors/errors-data.js";
4
4
  import { AstroError } from "../errors/index.js";
5
5
  import { routeIsFallback, routeIsRedirect } from "../redirects/helpers.js";
6
6
  import { RedirectSinglePageBuiltModule } from "../redirects/index.js";
@@ -10,6 +10,7 @@ import {
10
10
  createModuleScriptsSet,
11
11
  createStylesheetElementSet
12
12
  } from "../render/ssr-element.js";
13
+ import { DEFAULT_404_ROUTE } from "../routing/astro-designed-error-pages.js";
13
14
  import { isServerLikeOutput } from "../util.js";
14
15
  import { getOutDirWithinCwd } from "./common.js";
15
16
  import { cssOrder, getPageData, mergeInlineCss } from "./internal.js";
@@ -206,33 +207,38 @@ class BuildPipeline extends Pipeline {
206
207
  return module.page();
207
208
  }
208
209
  }
209
- async tryRewrite(payload, request) {
210
+ async tryRewrite(payload, request, sourceRoute) {
210
211
  let foundRoute;
211
212
  for (const route of this.options.manifest.routes) {
213
+ let finalUrl = void 0;
212
214
  if (payload instanceof URL) {
213
- if (route.pattern.test(payload.pathname)) {
214
- foundRoute = route;
215
- break;
216
- }
215
+ finalUrl = payload;
217
216
  } else if (payload instanceof Request) {
218
- const url = new URL(payload.url);
219
- if (route.pattern.test(url.pathname)) {
220
- foundRoute = route;
221
- break;
222
- }
217
+ finalUrl = new URL(payload.url);
223
218
  } else {
224
- const newUrl = new URL(payload, new URL(request.url).origin);
225
- if (route.pattern.test(decodeURI(newUrl.pathname))) {
226
- foundRoute = route;
227
- break;
228
- }
219
+ finalUrl = new URL(payload, new URL(request.url).origin);
220
+ }
221
+ if (route.pattern.test(decodeURI(finalUrl.pathname))) {
222
+ foundRoute = route;
223
+ break;
224
+ } else if (finalUrl.pathname === "/404") {
225
+ foundRoute = DEFAULT_404_ROUTE;
226
+ break;
229
227
  }
230
228
  }
231
229
  if (foundRoute) {
232
- const componentInstance = await this.getComponentByRoute(foundRoute);
233
- return [foundRoute, componentInstance];
230
+ if (foundRoute.pathname === "/404") {
231
+ const componentInstance = await this.rewriteKnownRoute(foundRoute.pathname, sourceRoute);
232
+ return [foundRoute, componentInstance];
233
+ } else {
234
+ const componentInstance = await this.getComponentByRoute(foundRoute);
235
+ return [foundRoute, componentInstance];
236
+ }
234
237
  } else {
235
- throw new AstroError(RouteNotFound);
238
+ throw new AstroError({
239
+ ...RewriteEncounteredAnError,
240
+ message: RewriteEncounteredAnError.message(payload.toString())
241
+ });
236
242
  }
237
243
  }
238
244
  async retrieveSsrEntry(route, filePath) {
@@ -279,6 +285,12 @@ class BuildPipeline extends Pipeline {
279
285
  }
280
286
  return RedirectSinglePageBuiltModule;
281
287
  }
288
+ rewriteKnownRoute(_pathname, sourceRoute) {
289
+ if (!isServerLikeOutput(this.config) || sourceRoute.prerender) {
290
+ throw new AstroError(InvalidRewrite404);
291
+ }
292
+ throw new Error(`Unreachable, in SSG this route shouldn't be generated`);
293
+ }
282
294
  }
283
295
  function createEntryURL(filePath, outFolder) {
284
296
  return new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
@@ -192,7 +192,8 @@ export default {}`
192
192
  const clientComponents = /* @__PURE__ */ new Set([
193
193
  ...oldManifest.clientEntries,
194
194
  ...internals.discoveredHydratedComponents.keys(),
195
- ...internals.discoveredClientOnlyComponents.keys()
195
+ ...internals.discoveredClientOnlyComponents.keys(),
196
+ ...internals.discoveredScripts
196
197
  ]);
197
198
  const serverComponents = /* @__PURE__ */ new Set([
198
199
  ...oldManifest.serverEntries,
@@ -213,7 +213,8 @@ function buildManifest(opts, internals, staticFiles) {
213
213
  i18n: i18nManifest,
214
214
  buildFormat: settings.config.build.format,
215
215
  checkOrigin: settings.config.security?.checkOrigin ?? false,
216
- rewritingEnabled: settings.config.experimental.rewriting
216
+ rewritingEnabled: settings.config.experimental.rewriting,
217
+ experimentalEnvGetSecretEnabled: settings.config.experimental.env !== void 0 && (settings.adapter?.supportedAstroFeatures.envGetSecret ?? "unsupported") !== "unsupported"
217
218
  };
218
219
  }
219
220
  export {
@@ -114,7 +114,7 @@ async function resolveConfig(inlineConfig, command, fsMod = fs) {
114
114
  const userConfig = await loadConfig(root, inlineOnlyConfig.configFile, fsMod);
115
115
  const mergedConfig = mergeConfig(userConfig, inlineUserConfig);
116
116
  const astroConfig = await validateConfig(mergedConfig, root, command);
117
- return { userConfig, astroConfig };
117
+ return { userConfig: mergedConfig, astroConfig };
118
118
  }
119
119
  export {
120
120
  configPaths,