astro 4.4.9 → 4.4.11

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.9";
1
+ const ASTRO_VERSION = "4.4.11";
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.9";
26
+ const currentVersion = "4.4.11";
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.9";
39
+ const version = "4.4.11";
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.9"}`
264
+ `v${"4.4.11"}`
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 = {
@@ -49,25 +49,6 @@ if (inBrowser) {
49
49
  history.scrollRestoration = "manual";
50
50
  }
51
51
  }
52
- const throttle = (cb, delay) => {
53
- let wait = false;
54
- let onceMore = false;
55
- return (...args) => {
56
- if (wait) {
57
- onceMore = true;
58
- return;
59
- }
60
- cb(...args);
61
- wait = true;
62
- setTimeout(() => {
63
- if (onceMore) {
64
- onceMore = false;
65
- cb(...args);
66
- }
67
- wait = false;
68
- }, delay);
69
- };
70
- };
71
52
  async function fetchHTML(href, init) {
72
53
  try {
73
54
  const res = await fetch(href, init);
@@ -414,8 +395,10 @@ function onPopState(ev) {
414
395
  currentHistoryIndex = nextIndex;
415
396
  transition(direction, originalLocation, new URL(location.href), {}, state);
416
397
  }
417
- const onScroll = () => {
418
- updateScrollPosition({ scrollX, scrollY });
398
+ const onScrollEnd = () => {
399
+ if (scrollX !== history.state.scrollX || scrollY !== history.state.scrollY) {
400
+ updateScrollPosition({ scrollX, scrollY });
401
+ }
419
402
  };
420
403
  if (inBrowser) {
421
404
  if (supportsViewTransitions || getFallback() !== "none") {
@@ -423,9 +406,35 @@ if (inBrowser) {
423
406
  addEventListener("popstate", onPopState);
424
407
  addEventListener("load", onPageLoad);
425
408
  if ("onscrollend" in window)
426
- addEventListener("scrollend", onScroll);
427
- else
428
- addEventListener("scroll", throttle(onScroll, 350), { passive: true });
409
+ addEventListener("scrollend", onScrollEnd);
410
+ else {
411
+ let intervalId, lastY, lastX, lastIndex;
412
+ const scrollInterval = () => {
413
+ if (lastIndex !== history.state?.index) {
414
+ clearInterval(intervalId);
415
+ intervalId = void 0;
416
+ return;
417
+ }
418
+ if (lastY === scrollY && lastX === scrollX) {
419
+ clearInterval(intervalId);
420
+ intervalId = void 0;
421
+ onScrollEnd();
422
+ return;
423
+ } else {
424
+ lastY = scrollY, lastX = scrollX;
425
+ }
426
+ };
427
+ addEventListener(
428
+ "scroll",
429
+ () => {
430
+ if (intervalId !== void 0)
431
+ return;
432
+ lastIndex = history.state.index, lastY = scrollY, lastX = scrollX;
433
+ intervalId = window.setInterval(scrollInterval, 50);
434
+ },
435
+ { passive: true }
436
+ );
437
+ }
429
438
  }
430
439
  for (const script of document.scripts) {
431
440
  script.dataset.astroExec = "";
@@ -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.9",
3
+ "version": "4.4.11",
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",