astro 4.4.10 → 4.4.12

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.
@@ -241,7 +241,7 @@ async function getPathsForRoute(route, mod, pipeline, builtPaths) {
241
241
  let paths = [];
242
242
  if (route.pathname) {
243
243
  paths.push(route.pathname);
244
- builtPaths.add(route.pathname);
244
+ builtPaths.add(removeTrailingForwardSlash(route.pathname));
245
245
  } else {
246
246
  const staticPaths = await callGetStaticPaths({
247
247
  mod,
@@ -364,7 +364,7 @@ async function generatePath(pathname, pipeline, gopts, route) {
364
364
  throw err;
365
365
  }
366
366
  if (response.status >= 300 && response.status < 400) {
367
- if (!config.build.redirects) {
367
+ if (routeIsRedirect(route) && !config.build.redirects) {
368
368
  return;
369
369
  }
370
370
  const locationSite = getRedirectLocationOrThrow(response.headers);
@@ -12,11 +12,9 @@ import {
12
12
  getPageDataByComponent,
13
13
  mergeInlineCss
14
14
  } from "./internal.js";
15
- import {
16
- ASTRO_PAGE_RESOLVED_MODULE_ID,
17
- getVirtualModulePageNameFromPath
18
- } from "./plugins/plugin-pages.js";
15
+ import { ASTRO_PAGE_MODULE_ID, ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
19
16
  import { RESOLVED_SPLIT_MODULE_ID } from "./plugins/plugin-ssr.js";
17
+ import { getVirtualModulePageNameFromPath } from "./plugins/util.js";
20
18
  import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
21
19
  import { i18nHasFallback } from "./util.js";
22
20
  class BuildPipeline extends Pipeline {
@@ -165,7 +163,7 @@ class BuildPipeline extends Pipeline {
165
163
  if (routeIsRedirect(pageData.route)) {
166
164
  pages.set(pageData, path);
167
165
  } else if (routeIsFallback(pageData.route) && (i18nHasFallback(this.config) || routeIsFallback(pageData.route) && pageData.route.route === "/")) {
168
- const moduleSpecifier = getVirtualModulePageNameFromPath(path);
166
+ const moduleSpecifier = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
169
167
  const filePath = this.internals.entrySpecifierToBundleMap.get(moduleSpecifier);
170
168
  if (filePath) {
171
169
  pages.set(pageData, filePath);
@@ -3,12 +3,5 @@ import type { AstroBuildPlugin } from '../plugin.js';
3
3
  import type { StaticBuildOptions } from '../types.js';
4
4
  export declare const ASTRO_PAGE_MODULE_ID = "@astro-page:";
5
5
  export declare const ASTRO_PAGE_RESOLVED_MODULE_ID: string;
6
- /**
7
- * 1. We add a fixed prefix, which is used as virtual module naming convention;
8
- * 2. We replace the dot that belongs extension with an arbitrary string.
9
- *
10
- * @param path
11
- */
12
- export declare function getVirtualModulePageNameFromPath(path: string): string;
13
6
  export declare function getVirtualModulePageIdFromPath(path: string): string;
14
7
  export declare function pluginPages(opts: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
@@ -1,20 +1,12 @@
1
- import { extname } from "node:path";
2
1
  import { routeIsRedirect } from "../../redirects/index.js";
3
2
  import { addRollupInput } from "../add-rollup-input.js";
4
3
  import { eachPageFromAllPages } from "../internal.js";
5
4
  import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
6
- import { ASTRO_PAGE_EXTENSION_POST_PATTERN, getPathFromVirtualModulePageName } from "./util.js";
5
+ import { getPathFromVirtualModulePageName, getVirtualModulePageNameFromPath } from "./util.js";
7
6
  const ASTRO_PAGE_MODULE_ID = "@astro-page:";
8
7
  const ASTRO_PAGE_RESOLVED_MODULE_ID = "\0" + ASTRO_PAGE_MODULE_ID;
9
- function getVirtualModulePageNameFromPath(path) {
10
- const extension = extname(path);
11
- return `${ASTRO_PAGE_MODULE_ID}${path.replace(
12
- extension,
13
- extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN)
14
- )}`;
15
- }
16
8
  function getVirtualModulePageIdFromPath(path) {
17
- const name = getVirtualModulePageNameFromPath(path);
9
+ const name = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
18
10
  return "\0" + name;
19
11
  }
20
12
  function vitePluginPages(opts, internals) {
@@ -27,7 +19,7 @@ function vitePluginPages(opts, internals) {
27
19
  if (routeIsRedirect(pageData.route)) {
28
20
  continue;
29
21
  }
30
- inputs.add(getVirtualModulePageNameFromPath(path));
22
+ inputs.add(getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path));
31
23
  }
32
24
  return addRollupInput(options, Array.from(inputs));
33
25
  }
@@ -73,6 +65,5 @@ export {
73
65
  ASTRO_PAGE_MODULE_ID,
74
66
  ASTRO_PAGE_RESOLVED_MODULE_ID,
75
67
  getVirtualModulePageIdFromPath,
76
- getVirtualModulePageNameFromPath,
77
68
  pluginPages
78
69
  };
@@ -8,8 +8,10 @@ type ExtendManualChunksHooks = {
8
8
  export declare function extendManualChunks(outputOptions: OutputOptions, hooks: ExtendManualChunksHooks): void;
9
9
  export declare const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
10
10
  /**
11
- * 1. We add a fixed prefix, which is used as virtual module naming convention;
12
- * 2. We replace the dot that belongs extension with an arbitrary string.
11
+ * Prevents Rollup from triggering other plugins in the process by masking the extension (hence the virtual file).
12
+ *
13
+ * 1. We add a fixed prefix, which is used as virtual module naming convention
14
+ * 2. If the path has an extension (at the end of the path), we replace the dot that belongs to the extension with an arbitrary string.
13
15
  *
14
16
  * @param virtualModulePrefix
15
17
  * @param path
@@ -28,10 +28,7 @@ function extendManualChunks(outputOptions, hooks) {
28
28
  const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
29
29
  function getVirtualModulePageNameFromPath(virtualModulePrefix, path) {
30
30
  const extension = extname(path);
31
- return `${virtualModulePrefix}${path.replace(
32
- extension,
33
- extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN)
34
- )}`;
31
+ return virtualModulePrefix + (extension.startsWith(".") ? path.slice(0, -extension.length) + extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN) : path);
35
32
  }
36
33
  function getPathFromVirtualModulePageName(virtualModulePrefix, id) {
37
34
  const pageName = id.slice(virtualModulePrefix.length);
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "4.4.10";
1
+ const ASTRO_VERSION = "4.4.12";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const ROUTE_TYPE_HEADER = "X-Astro-Route-Type";
4
4
  const REROUTABLE_STATUS_CODES = [404, 500];
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
23
23
  base: restart.container.settings.config.base
24
24
  })
25
25
  );
26
- const currentVersion = "4.4.10";
26
+ const currentVersion = "4.4.12";
27
27
  if (currentVersion.includes("-")) {
28
28
  logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
29
29
  }
@@ -36,7 +36,7 @@ function serverStart({
36
36
  host,
37
37
  base
38
38
  }) {
39
- const version = "4.4.10";
39
+ const version = "4.4.12";
40
40
  const localPrefix = `${dim("\u2503")} Local `;
41
41
  const networkPrefix = `${dim("\u2503")} Network `;
42
42
  const emptyPrefix = " ".repeat(11);
@@ -261,7 +261,7 @@ function printHelp({
261
261
  message.push(
262
262
  linebreak(),
263
263
  ` ${bgGreen(black(` ${commandName} `))} ${green(
264
- `v${"4.4.10"}`
264
+ `v${"4.4.12"}`
265
265
  )} ${headline}`
266
266
  );
267
267
  }
@@ -7,6 +7,7 @@ import { renderEndpoint } from "../runtime/server/endpoint.js";
7
7
  import { renderPage } from "../runtime/server/index.js";
8
8
  import {
9
9
  ASTRO_VERSION,
10
+ REROUTE_DIRECTIVE_HEADER,
10
11
  ROUTE_TYPE_HEADER,
11
12
  clientAddressSymbol,
12
13
  clientLocalsSymbol
@@ -86,6 +87,9 @@ class RenderContext {
86
87
  routeData
87
88
  );
88
89
  response2.headers.set(ROUTE_TYPE_HEADER, "page");
90
+ if (routeData.route === "/404" || routeData.route === "/500") {
91
+ response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
92
+ }
89
93
  return response2;
90
94
  } : type === "fallback" ? () => new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }) : () => {
91
95
  throw new Error("Unknown type of route: " + type);
@@ -1,2 +1,2 @@
1
1
  import type { AstroConfig, RoutePart } from '../../../@types/astro.js';
2
- export declare function getRouteGenerator(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']): import("path-to-regexp").PathFunction<object>;
2
+ export declare function getRouteGenerator(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']): (params: object) => string;
@@ -16,7 +16,10 @@ function getRouteGenerator(segments, addTrailingSlash) {
16
16
  trailing = "/";
17
17
  }
18
18
  const toPath = compile(template + trailing);
19
- return toPath;
19
+ return (params) => {
20
+ const path = toPath(params);
21
+ return path || "/";
22
+ };
20
23
  }
21
24
  export {
22
25
  getRouteGenerator
@@ -1,6 +1,6 @@
1
1
  import { appendForwardSlash, joinPaths } from "@astrojs/internal-helpers/path";
2
2
  import { shouldAppendForwardSlash } from "../core/build/util.js";
3
- import { ROUTE_TYPE_HEADER } from "../core/constants.js";
3
+ import { REROUTE_DIRECTIVE_HEADER, ROUTE_TYPE_HEADER } from "../core/constants.js";
4
4
  import { getPathByLocale, normalizeTheLocale } from "./index.js";
5
5
  function pathnameHasLocale(pathname, locales) {
6
6
  const segments = pathname.split("/");
@@ -28,10 +28,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
28
28
  return context.redirect(`${joinPaths(base, i18n.defaultLocale)}`);
29
29
  }
30
30
  } else if (!pathnameHasLocale(url.pathname, i18n.locales)) {
31
- return new Response(null, {
32
- status: 404,
33
- headers: response.headers
34
- });
31
+ return notFound(response);
35
32
  }
36
33
  return void 0;
37
34
  };
@@ -46,20 +43,14 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
46
43
  if (pathnameContainsDefaultLocale) {
47
44
  const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, "");
48
45
  response.headers.set("Location", newLocation);
49
- return new Response(null, {
50
- status: 404,
51
- headers: response.headers
52
- });
46
+ return notFound(response);
53
47
  }
54
48
  return void 0;
55
49
  };
56
50
  const prefixAlwaysNoRedirect = (url, response) => {
57
51
  const isRoot = url.pathname === base + "/" || url.pathname === base;
58
52
  if (!(isRoot || pathnameHasLocale(url.pathname, i18n.locales))) {
59
- return new Response(null, {
60
- status: 404,
61
- headers: response.headers
62
- });
53
+ return notFound(response);
63
54
  }
64
55
  return void 0;
65
56
  };
@@ -151,6 +142,14 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
151
142
  return response;
152
143
  };
153
144
  }
145
+ function notFound(response) {
146
+ if (response.headers.get(REROUTE_DIRECTIVE_HEADER) === "no")
147
+ return response;
148
+ return new Response(null, {
149
+ status: 404,
150
+ headers: response.headers
151
+ });
152
+ }
154
153
  function localeHasntDomain(i18n, currentLocale) {
155
154
  for (const domainLocale of Object.values(i18n.domainLookupTable)) {
156
155
  if (domainLocale === currentLocale) {
@@ -127,9 +127,12 @@ async function renderToAsyncIterable(result, componentFactory, props, children,
127
127
  }
128
128
  let error = null;
129
129
  let next = promiseWithResolvers();
130
+ let cancelled = false;
130
131
  const buffer = [];
131
132
  const iterator = {
132
133
  async next() {
134
+ if (cancelled)
135
+ return { done: true, value: void 0 };
133
136
  await next.promise;
134
137
  if (error) {
135
138
  throw error;
@@ -152,6 +155,10 @@ async function renderToAsyncIterable(result, componentFactory, props, children,
152
155
  value: mergedArray
153
156
  };
154
157
  return returnValue;
158
+ },
159
+ async return() {
160
+ cancelled = true;
161
+ return { done: true, value: void 0 };
155
162
  }
156
163
  };
157
164
  const destination = {
@@ -29,9 +29,15 @@ async function renderSlotToString(result, slotted, fallback) {
29
29
  let instructions = null;
30
30
  const temporaryDestination = {
31
31
  write(chunk) {
32
- if (chunk instanceof Response)
32
+ if (chunk instanceof SlotString) {
33
+ content += chunk;
34
+ if (chunk.instructions) {
35
+ instructions ??= [];
36
+ instructions.push(...chunk.instructions);
37
+ }
38
+ } else if (chunk instanceof Response)
33
39
  return;
34
- if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") {
40
+ else if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") {
35
41
  if (instructions === null) {
36
42
  instructions = [];
37
43
  }
@@ -208,7 +208,7 @@ async function handleRoute({
208
208
  }
209
209
  if (response.status === 404 && has404Route(manifestData) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
210
210
  const fourOhFourRoute = await matchRoute("/404", manifestData, pipeline);
211
- if (options && fourOhFourRoute?.route !== options.route)
211
+ if (options)
212
212
  return handleRoute({
213
213
  ...options,
214
214
  matchedRoute: fourOhFourRoute,
@@ -222,6 +222,9 @@ async function handleRoute({
222
222
  incomingResponse
223
223
  });
224
224
  }
225
+ if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
226
+ response.headers.delete(REROUTE_DIRECTIVE_HEADER);
227
+ }
225
228
  if (route.type === "endpoint") {
226
229
  await writeWebResponse(incomingResponse, response);
227
230
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "4.4.10",
3
+ "version": "4.4.12",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",
@@ -163,8 +163,8 @@
163
163
  "which-pm": "^2.1.1",
164
164
  "yargs-parser": "^21.1.1",
165
165
  "zod": "^3.22.4",
166
- "@astrojs/markdown-remark": "4.2.1",
167
166
  "@astrojs/internal-helpers": "0.2.1",
167
+ "@astrojs/markdown-remark": "4.2.1",
168
168
  "@astrojs/telemetry": "3.0.4"
169
169
  },
170
170
  "optionalDependencies": {
@@ -1,22 +0,0 @@
1
- import type { APIContext, Locales, Params } from '../../@types/astro.js';
2
- import { type RoutingStrategies } from '../../i18n/utils.js';
3
- import type { AstroCookies } from '../cookies/index.js';
4
- type CreateAPIContext = {
5
- request: Request;
6
- params: Params;
7
- site?: string;
8
- props: Record<string, any>;
9
- adapterName?: string;
10
- locales: Locales | undefined;
11
- routingStrategy: RoutingStrategies | undefined;
12
- defaultLocale: string | undefined;
13
- route: string;
14
- cookies: AstroCookies;
15
- };
16
- /**
17
- * Creates a context that holds all the information needed to handle an Astro endpoint.
18
- *
19
- * @param {CreateAPIContext} payload
20
- */
21
- export declare function createAPIContext({ request, params, site, props, adapterName, locales, routingStrategy, defaultLocale, route, cookies, }: CreateAPIContext): APIContext;
22
- export {};
@@ -1,105 +0,0 @@
1
- import {
2
- computeCurrentLocale,
3
- computePreferredLocale,
4
- computePreferredLocaleList
5
- } from "../../i18n/utils.js";
6
- import { ASTRO_VERSION, clientAddressSymbol, clientLocalsSymbol } from "../constants.js";
7
- import { AstroError, AstroErrorData } from "../errors/index.js";
8
- function createAPIContext({
9
- request,
10
- params,
11
- site,
12
- props,
13
- adapterName,
14
- locales,
15
- routingStrategy,
16
- defaultLocale,
17
- route,
18
- cookies
19
- }) {
20
- let preferredLocale = void 0;
21
- let preferredLocaleList = void 0;
22
- let currentLocale = void 0;
23
- const context = {
24
- cookies,
25
- request,
26
- params,
27
- site: site ? new URL(site) : void 0,
28
- generator: `Astro v${ASTRO_VERSION}`,
29
- props,
30
- redirect(path, status) {
31
- return new Response(null, {
32
- status: status || 302,
33
- headers: {
34
- Location: path
35
- }
36
- });
37
- },
38
- get preferredLocale() {
39
- if (preferredLocale) {
40
- return preferredLocale;
41
- }
42
- if (locales) {
43
- preferredLocale = computePreferredLocale(request, locales);
44
- return preferredLocale;
45
- }
46
- return void 0;
47
- },
48
- get preferredLocaleList() {
49
- if (preferredLocaleList) {
50
- return preferredLocaleList;
51
- }
52
- if (locales) {
53
- preferredLocaleList = computePreferredLocaleList(request, locales);
54
- return preferredLocaleList;
55
- }
56
- return void 0;
57
- },
58
- get currentLocale() {
59
- if (currentLocale) {
60
- return currentLocale;
61
- }
62
- if (locales) {
63
- currentLocale = computeCurrentLocale(route, locales, routingStrategy, defaultLocale);
64
- }
65
- return currentLocale;
66
- },
67
- url: new URL(request.url),
68
- get clientAddress() {
69
- if (clientAddressSymbol in request) {
70
- return Reflect.get(request, clientAddressSymbol);
71
- }
72
- if (adapterName) {
73
- throw new AstroError({
74
- ...AstroErrorData.ClientAddressNotAvailable,
75
- message: AstroErrorData.ClientAddressNotAvailable.message(adapterName)
76
- });
77
- } else {
78
- throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
79
- }
80
- },
81
- get locals() {
82
- let locals = Reflect.get(request, clientLocalsSymbol);
83
- if (locals === void 0) {
84
- locals = {};
85
- Reflect.set(request, clientLocalsSymbol, locals);
86
- }
87
- if (typeof locals !== "object") {
88
- throw new AstroError(AstroErrorData.LocalsNotAnObject);
89
- }
90
- return locals;
91
- },
92
- // We define a custom property, so we can check the value passed to locals
93
- set locals(val) {
94
- if (typeof val !== "object") {
95
- throw new AstroError(AstroErrorData.LocalsNotAnObject);
96
- } else {
97
- Reflect.set(request, clientLocalsSymbol, val);
98
- }
99
- }
100
- };
101
- return context;
102
- }
103
- export {
104
- createAPIContext
105
- };