astro 6.4.3 → 6.4.5

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.
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "6.4.3";
3
+ version = "6.4.5";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -197,7 +197,7 @@ ${contentConfig.error.message}`
197
197
  logger.info("Content config changed");
198
198
  shouldClear = true;
199
199
  }
200
- if (previousAstroVersion && previousAstroVersion !== "6.4.3") {
200
+ if (previousAstroVersion && previousAstroVersion !== "6.4.5") {
201
201
  logger.info("Astro version changed");
202
202
  shouldClear = true;
203
203
  }
@@ -205,8 +205,8 @@ ${contentConfig.error.message}`
205
205
  logger.info("Clearing content store");
206
206
  this.#store.clearAll();
207
207
  }
208
- if ("6.4.3") {
209
- this.#store.metaStore().set("astro-version", "6.4.3");
208
+ if ("6.4.5") {
209
+ this.#store.metaStore().set("astro-version", "6.4.5");
210
210
  }
211
211
  if (currentConfigDigest) {
212
212
  this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -131,6 +131,15 @@ export declare abstract class BaseApp<P extends Pipeline = AppPipeline> {
131
131
  abstract createPipeline(streaming: boolean, manifest: SSRManifest, ...args: any[]): P;
132
132
  set setManifestData(newManifestData: RoutesList);
133
133
  removeBase(pathname: string): string;
134
+ /**
135
+ * Decodes a pathname with `decodeURI`, falling back to the raw pathname when it
136
+ * contains an invalid percent-sequence (e.g. `%C0%AF`, an overlong-UTF-8 encoding of
137
+ * `/` commonly sent by path-traversal scanners). A raw `decodeURI()` would throw
138
+ * `URIError: URI malformed`, and because `match()` runs before `render()` that error
139
+ * escapes the adapter's request handler as an uncaught exception (HTTP 500) that user
140
+ * middleware can't catch.
141
+ */
142
+ private safeDecodeURI;
134
143
  /**
135
144
  * Extracts the base-stripped, decoded pathname from a request.
136
145
  * Used by adapters to compute the pathname for dev-mode route matching.
@@ -1,12 +1,10 @@
1
1
  import {
2
- appendForwardSlash,
3
2
  collapseDuplicateLeadingSlashes,
4
- joinPaths,
5
3
  prependForwardSlash,
6
4
  removeTrailingForwardSlash
7
5
  } from "@astrojs/internal-helpers/path";
8
6
  import { matchPattern } from "@astrojs/internal-helpers/remote";
9
- import { normalizeTheLocale } from "../../i18n/index.js";
7
+ import { computePathnameFromDomain } from "../i18n/domain.js";
10
8
  import { PipelineFeatures } from "../base-pipeline.js";
11
9
  import { ASTRO_ERROR_HEADER, clientAddressSymbol } from "../constants.js";
12
10
  import { getSetCookiesFromResponse } from "../cookies/index.js";
@@ -46,11 +44,9 @@ class BaseApp {
46
44
  return this.pipeline.logger;
47
45
  }
48
46
  get adapterLogger() {
49
- if (!this.#adapterLogger) {
50
- this.#adapterLogger = new AstroIntegrationLogger(
51
- this.logger.options,
52
- this.manifest.adapterName
53
- );
47
+ const currentOptions = this.logger.options;
48
+ if (!this.#adapterLogger || this.#adapterLogger.options !== currentOptions) {
49
+ this.#adapterLogger = new AstroIntegrationLogger(currentOptions, this.manifest.adapterName);
54
50
  }
55
51
  return this.#adapterLogger;
56
52
  }
@@ -117,19 +113,30 @@ class BaseApp {
117
113
  return pathname;
118
114
  }
119
115
  /**
120
- * Extracts the base-stripped, decoded pathname from a request.
121
- * Used by adapters to compute the pathname for dev-mode route matching.
116
+ * Decodes a pathname with `decodeURI`, falling back to the raw pathname when it
117
+ * contains an invalid percent-sequence (e.g. `%C0%AF`, an overlong-UTF-8 encoding of
118
+ * `/` commonly sent by path-traversal scanners). A raw `decodeURI()` would throw
119
+ * `URIError: URI malformed`, and because `match()` runs before `render()` that error
120
+ * escapes the adapter's request handler as an uncaught exception (HTTP 500) that user
121
+ * middleware can't catch.
122
122
  */
123
- getPathnameFromRequest(request) {
124
- const url = new URL(request.url);
125
- const pathname = prependForwardSlash(this.removeBase(url.pathname));
123
+ safeDecodeURI(pathname) {
126
124
  try {
127
125
  return decodeURI(pathname);
128
126
  } catch (e) {
129
- this.adapterLogger.error(e.toString());
127
+ this.adapterLogger.debug(e.toString());
130
128
  return pathname;
131
129
  }
132
130
  }
131
+ /**
132
+ * Extracts the base-stripped, decoded pathname from a request.
133
+ * Used by adapters to compute the pathname for dev-mode route matching.
134
+ */
135
+ getPathnameFromRequest(request) {
136
+ const url = new URL(request.url);
137
+ const pathname = prependForwardSlash(this.removeBase(url.pathname));
138
+ return this.safeDecodeURI(pathname);
139
+ }
133
140
  /**
134
141
  * Given a `Request`, it returns the `RouteData` that matches its `pathname`. By default, prerendered
135
142
  * routes aren't returned, even if they are matched.
@@ -145,14 +152,14 @@ class BaseApp {
145
152
  if (!pathname) {
146
153
  pathname = prependForwardSlash(this.removeBase(url.pathname));
147
154
  }
148
- const routeData = this.pipeline.matchRoute(decodeURI(pathname));
155
+ const routeData = this.pipeline.matchRoute(this.safeDecodeURI(pathname));
149
156
  if (!routeData) return void 0;
150
157
  if (allowPrerenderedRoutes) {
151
158
  return routeData;
152
159
  }
153
160
  if (routeData.prerender) {
154
161
  if (routeData.params.length > 0) {
155
- const allMatches = this.pipeline.matchAllRoutes(decodeURI(pathname));
162
+ const allMatches = this.pipeline.matchAllRoutes(this.safeDecodeURI(pathname));
156
163
  return allMatches.find((r) => !r.prerender);
157
164
  }
158
165
  return void 0;
@@ -170,55 +177,14 @@ class BaseApp {
170
177
  return void 0;
171
178
  }
172
179
  computePathnameFromDomain(request) {
173
- let pathname = void 0;
174
- const url = new URL(request.url);
175
- if (this.manifest.i18n && (this.manifest.i18n.strategy === "domains-prefix-always" || this.manifest.i18n.strategy === "domains-prefix-other-locales" || this.manifest.i18n.strategy === "domains-prefix-always-no-redirect")) {
176
- let host = request.headers.get("X-Forwarded-Host");
177
- let protocol = request.headers.get("X-Forwarded-Proto");
178
- if (protocol) {
179
- protocol = protocol + ":";
180
- } else {
181
- protocol = url.protocol;
182
- }
183
- if (!host) {
184
- host = request.headers.get("Host");
185
- }
186
- if (host && protocol) {
187
- host = host.split(":")[0];
188
- try {
189
- let locale;
190
- const hostAsUrl = new URL(`${protocol}//${host}`);
191
- for (const [domainKey, localeValue] of Object.entries(
192
- this.manifest.i18n.domainLookupTable
193
- )) {
194
- const domainKeyAsUrl = new URL(domainKey);
195
- if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) {
196
- locale = localeValue;
197
- break;
198
- }
199
- }
200
- if (locale) {
201
- pathname = prependForwardSlash(
202
- joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname))
203
- );
204
- if (this.manifest.trailingSlash === "always") {
205
- pathname = appendForwardSlash(pathname);
206
- } else if (this.manifest.trailingSlash === "never") {
207
- pathname = removeTrailingForwardSlash(pathname);
208
- } else if (url.pathname.endsWith("/")) {
209
- pathname = appendForwardSlash(pathname);
210
- }
211
- }
212
- } catch (e) {
213
- this.logger.error(
214
- "router",
215
- `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`
216
- );
217
- this.logger.error("router", `Error: ${e}`);
218
- }
219
- }
220
- }
221
- return pathname;
180
+ return computePathnameFromDomain(
181
+ request,
182
+ new URL(request.url),
183
+ this.manifest.i18n,
184
+ this.manifest.base,
185
+ this.manifest.trailingSlash,
186
+ this.logger
187
+ );
222
188
  }
223
189
  async render(request, {
224
190
  addCookieHeader = false,
@@ -259,7 +225,7 @@ class BaseApp {
259
225
  if (!routeData) {
260
226
  const domainPathname = this.computePathnameFromDomain(request);
261
227
  if (domainPathname) {
262
- routeData = this.pipeline.matchRoute(decodeURI(domainPathname));
228
+ routeData = this.pipeline.matchRoute(this.safeDecodeURI(domainPathname));
263
229
  }
264
230
  }
265
231
  const resolvedOptions = {
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "6.4.3";
1
+ const ASTRO_VERSION = "6.4.5";
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";
@@ -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.4.3";
40
+ const currentVersion = "6.4.5";
41
41
  const isPrerelease = currentVersion.includes("-");
42
42
  if (!isPrerelease) {
43
43
  try {
@@ -185,8 +185,8 @@ export declare const NoClientOnlyHint: {
185
185
  * ---
186
186
  * export async function getStaticPaths() {
187
187
  * return [
188
- * { params: { slug: "blog" } },
189
- * { params: { slug: "about" } }
188
+ * { params: { id: "blog" } },
189
+ * { params: { id: "about" } }
190
190
  * ];
191
191
  *}
192
192
  *---
@@ -208,8 +208,8 @@ export declare const InvalidGetStaticPathParam: {
208
208
  * ```ts title="pages/blog/[id].astro"
209
209
  * export async function getStaticPaths() {
210
210
  * return [ // <-- Array
211
- * { params: { slug: "blog" } }, // <-- Object
212
- * { params: { slug: "about" } }
211
+ * { params: { id: "blog" } }, // <-- Object
212
+ * { params: { id: "about" } }
213
213
  * ];
214
214
  *}
215
215
  * ```
@@ -231,8 +231,8 @@ export declare const InvalidGetStaticPathsEntry: {
231
231
  * ```ts title="pages/blog/[id].astro"
232
232
  * export async function getStaticPaths() {
233
233
  * return [ // <-- Array
234
- * { params: { slug: "blog" } },
235
- * { params: { slug: "about" } }
234
+ * { params: { id: "blog" } },
235
+ * { params: { id: "about" } }
236
236
  * ];
237
237
  *}
238
238
  * ```
@@ -9,6 +9,7 @@ import { createCallAction, createGetActionResult, hasActionPayload } from "../..
9
9
  import { AstroCookies } from "../cookies/index.js";
10
10
  import { Slots } from "../render/index.js";
11
11
  import {
12
+ appSymbol,
12
13
  ASTRO_GENERATOR,
13
14
  fetchStateSymbol,
14
15
  originPathnameSymbol,
@@ -29,6 +30,7 @@ import { Rewrites } from "../rewrites/handler.js";
29
30
  import { isRoute404or500, isRouteServerIsland } from "../routing/match.js";
30
31
  import { normalizeUrl } from "../util/normalized-url.js";
31
32
  import { getOriginPathname, setOriginPathname } from "../routing/rewrite.js";
33
+ import { computePathnameFromDomain } from "../i18n/domain.js";
32
34
  import { getCustom404Route, routeHasHtmlExtension } from "../routing/helpers.js";
33
35
  import { getRenderOptions } from "../app/render-options.js";
34
36
  import { getFirstForwardedValue, validateForwardedHeaders } from "../app/validate-headers.js";
@@ -136,6 +138,13 @@ class FetchState {
136
138
  #rewrites;
137
139
  /** Memoized Astro page partial. */
138
140
  #astroPagePartial;
141
+ /**
142
+ * Locale-prefixed pathname derived from the Host header for domain-based
143
+ * i18n routing (e.g. `/en/boats/1/foo`), or `undefined` when the request
144
+ * isn't served from a locale-mapped domain. When set, `this.pathname` is
145
+ * derived from it so locale/param resolution match the route pattern.
146
+ */
147
+ #domainPathname;
139
148
  /** Memoized current locale. */
140
149
  #currentLocale;
141
150
  /** Memoized preferred locale. */
@@ -158,7 +167,24 @@ class FetchState {
158
167
  this.componentInstance = void 0;
159
168
  this.slots = void 0;
160
169
  const url = new URL(request.url);
161
- this.pathname = this.#computePathname(url);
170
+ const domainPathname = computePathnameFromDomain(
171
+ request,
172
+ url,
173
+ pipeline.manifest.i18n,
174
+ pipeline.manifest.base,
175
+ pipeline.manifest.trailingSlash,
176
+ pipeline.logger
177
+ );
178
+ if (domainPathname) {
179
+ this.#domainPathname = domainPathname;
180
+ try {
181
+ this.pathname = decodeURI(domainPathname);
182
+ } catch {
183
+ this.pathname = domainPathname;
184
+ }
185
+ } else {
186
+ this.pathname = this.#computePathname(url);
187
+ }
162
188
  this.timeStart = performance.now();
163
189
  this.clientAddress = options?.clientAddress;
164
190
  this.locals = options?.locals ?? {};
@@ -167,9 +193,9 @@ class FetchState {
167
193
  if (pipeline.manifest.allowedDomains && pipeline.manifest.allowedDomains.length > 0) {
168
194
  this.#applyForwardedHeaders();
169
195
  }
170
- if (!Reflect.get(request, originPathnameSymbol)) {
196
+ if (!Reflect.get(this.request, originPathnameSymbol)) {
171
197
  setOriginPathname(
172
- request,
198
+ this.request,
173
199
  this.pathname,
174
200
  pipeline.manifest.trailingSlash,
175
201
  pipeline.manifest.buildFormat
@@ -462,7 +488,9 @@ class FetchState {
462
488
  }
463
489
  } else {
464
490
  let pathname = routeData.pathname;
465
- if (url && !routeData.pattern.test(url.pathname)) {
491
+ if (this.#domainPathname) {
492
+ pathname = this.pathname;
493
+ } else if (url && !routeData.pattern.test(url.pathname)) {
466
494
  for (const fallbackRoute of routeData.fallbackRoutes) {
467
495
  if (fallbackRoute.pattern.test(url.pathname)) {
468
496
  pathname = fallbackRoute.pathname;
@@ -589,11 +617,14 @@ class FetchState {
589
617
  */
590
618
  /**
591
619
  * Strip `.html` / `/index.html` suffixes from the pathname so the
592
- * rendering pipeline sees the canonical route path. Skipped when the
593
- * matched route itself has an `.html` extension in its definition.
620
+ * rendering pipeline sees the canonical route path. Only applies to
621
+ * page routes where `.html` is framework-injected. Endpoint routes
622
+ * preserve `.html` because any such suffix is user-provided (e.g.
623
+ * from `getStaticPaths` params). Skipped when the matched route
624
+ * itself has an `.html` extension in its definition.
594
625
  */
595
626
  #stripHtmlExtension() {
596
- if (this.routeData && !routeHasHtmlExtension(this.routeData)) {
627
+ if (this.routeData && this.routeData.type === "page" && !routeHasHtmlExtension(this.routeData)) {
597
628
  this.pathname = this.pathname.replace(/\/index\.html$/, "/").replace(/\.html$/, "");
598
629
  }
599
630
  }
@@ -697,6 +728,12 @@ class FetchState {
697
728
  this.clientAddress = forwardedFor;
698
729
  }
699
730
  }
731
+ const oldRequest = this.request;
732
+ this.request = new Request(this.url, oldRequest);
733
+ const app = Reflect.get(oldRequest, appSymbol);
734
+ if (app !== void 0) {
735
+ Reflect.set(this.request, appSymbol, app);
736
+ }
700
737
  }
701
738
  /**
702
739
  * Returns the resolved `props` for this render, computing them lazily
@@ -0,0 +1,12 @@
1
+ import type { SSRManifest } from '../app/types.js';
2
+ import type { AstroLogger } from '../logger/core.js';
3
+ /**
4
+ * For domain-based i18n routing strategies, derives the locale-prefixed
5
+ * pathname from the request's `Host` header rather than its URL. For example,
6
+ * a request for `/foo` served from `https://example.fr` resolves to `/fr/foo`.
7
+ *
8
+ * Returns `undefined` when the strategy isn't domain-based or the host isn't
9
+ * mapped to a locale — in which case normal pathname routing applies.
10
+ *
11
+ */
12
+ export declare function computePathnameFromDomain(request: Request, url: URL, i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'], logger: AstroLogger): string | undefined;
@@ -0,0 +1,66 @@
1
+ import {
2
+ appendForwardSlash,
3
+ collapseDuplicateLeadingSlashes,
4
+ joinPaths,
5
+ prependForwardSlash,
6
+ removeTrailingForwardSlash
7
+ } from "@astrojs/internal-helpers/path";
8
+ import { normalizeTheLocale } from "../../i18n/index.js";
9
+ function computePathnameFromDomain(request, url, i18n, base, trailingSlash, logger) {
10
+ let pathname = void 0;
11
+ if (i18n && (i18n.strategy === "domains-prefix-always" || i18n.strategy === "domains-prefix-other-locales" || i18n.strategy === "domains-prefix-always-no-redirect")) {
12
+ let host = request.headers.get("X-Forwarded-Host");
13
+ let protocol = request.headers.get("X-Forwarded-Proto");
14
+ if (protocol) {
15
+ protocol = protocol + ":";
16
+ } else {
17
+ protocol = url.protocol;
18
+ }
19
+ if (!host) {
20
+ host = request.headers.get("Host");
21
+ }
22
+ if (host && protocol) {
23
+ host = host.split(":")[0];
24
+ try {
25
+ let locale;
26
+ const hostAsUrl = new URL(`${protocol}//${host}`);
27
+ for (const [domainKey, localeValue] of Object.entries(i18n.domainLookupTable)) {
28
+ const domainKeyAsUrl = new URL(domainKey);
29
+ if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) {
30
+ locale = localeValue;
31
+ break;
32
+ }
33
+ }
34
+ if (locale) {
35
+ pathname = prependForwardSlash(
36
+ joinPaths(normalizeTheLocale(locale), removeBase(url.pathname, base))
37
+ );
38
+ if (trailingSlash === "always") {
39
+ pathname = appendForwardSlash(pathname);
40
+ } else if (trailingSlash === "never") {
41
+ pathname = removeTrailingForwardSlash(pathname);
42
+ } else if (url.pathname.endsWith("/")) {
43
+ pathname = appendForwardSlash(pathname);
44
+ }
45
+ }
46
+ } catch (e) {
47
+ logger.error(
48
+ "router",
49
+ `Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`
50
+ );
51
+ logger.error("router", `Error: ${e}`);
52
+ }
53
+ }
54
+ }
55
+ return pathname;
56
+ }
57
+ function removeBase(pathname, base) {
58
+ pathname = collapseDuplicateLeadingSlashes(pathname);
59
+ if (pathname.startsWith(base)) {
60
+ return pathname.slice(removeTrailingForwardSlash(base).length + 1);
61
+ }
62
+ return pathname;
63
+ }
64
+ export {
65
+ computePathnameFromDomain
66
+ };
@@ -84,7 +84,7 @@ export declare class AstroLogger {
84
84
  */
85
85
  close(): void;
86
86
  /**
87
- * It calls the `flush` function of the provided destinatin, if it exists.
87
+ * It calls the `flush` function of the provided destination, if it exists.
88
88
  */
89
89
  flush(): void;
90
90
  }
@@ -136,7 +136,7 @@ class AstroLogger {
136
136
  }
137
137
  }
138
138
  /**
139
- * It calls the `flush` function of the provided destinatin, if it exists.
139
+ * It calls the `flush` function of the provided destination, if it exists.
140
140
  */
141
141
  flush() {
142
142
  if (this.options.destination.flush) {
@@ -276,7 +276,7 @@ function printHelp({
276
276
  message.push(
277
277
  linebreak(),
278
278
  ` ${bgGreen(black(` ${commandName} `))} ${green(
279
- `v${"6.4.3"}`
279
+ `v${"6.4.5"}`
280
280
  )} ${headline}`
281
281
  );
282
282
  }
@@ -677,7 +677,7 @@ function joinSegments(segments) {
677
677
  const arr = segments.map((segment) => {
678
678
  return segment.map((rp) => rp.dynamic ? `[${rp.content}]` : rp.content).join("");
679
679
  });
680
- return `/${arr.join("/")}`.toLowerCase();
680
+ return `/${arr.join("/")}`;
681
681
  }
682
682
  function replaceOrKeep(original, from, to) {
683
683
  if (original.startsWith(`/${to}/`) || original === `/${to}`) return original;
@@ -58,7 +58,7 @@ function joinSegments(segments) {
58
58
  const arr = segments.map((segment) => {
59
59
  return segment.map((part) => part.dynamic ? `[${part.content}]` : part.content).join("");
60
60
  });
61
- return `/${arr.join("/")}`.toLowerCase();
61
+ return `/${arr.join("/")}`;
62
62
  }
63
63
  export {
64
64
  parseRoute
@@ -101,7 +101,7 @@ function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) {
101
101
  signal: oldRequest.signal,
102
102
  keepalive: oldRequest.keepalive,
103
103
  // https://fetch.spec.whatwg.org/#dom-request-duplex
104
- // @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
104
+ // @ts-expect-error It isn't part of the types, but undici accepts it and it allows carrying over the body to a new request
105
105
  duplex: "half"
106
106
  }
107
107
  });
@@ -52,11 +52,7 @@ function renderAllHeadContent(result) {
52
52
  (link) => renderElement("link", link, false)
53
53
  );
54
54
  content += styles.join("\n") + links.join("\n") + scripts.join("\n");
55
- if (result._metadata.extraHead.length > 0) {
56
- for (const part of result._metadata.extraHead) {
57
- content += part;
58
- }
59
- }
55
+ content += result._metadata.extraHead.join("");
60
56
  return markHTMLString(content);
61
57
  }
62
58
  function renderHead() {
@@ -67,6 +67,9 @@ function hmrReload() {
67
67
  if (hasSkippedStyleModules) {
68
68
  return [];
69
69
  }
70
+ if (modules.length > 0) {
71
+ return [];
72
+ }
70
73
  }
71
74
  }
72
75
  };
@@ -26,12 +26,18 @@ function normalizeFilename(filename, root) {
26
26
  } else if (filename.startsWith(".")) {
27
27
  const url = new URL(filename, root);
28
28
  filename = viteID(url);
29
- } else if (filename.startsWith("/") && !commonAncestorPath(filename, fileURLToPath(root))) {
29
+ } else if (filename.startsWith("/") && !isPathInRoot(filename, fileURLToPath(root))) {
30
30
  const url = new URL("." + filename, root);
31
31
  filename = viteID(url);
32
32
  }
33
33
  return removeLeadingForwardSlashWindows(filename);
34
34
  }
35
+ function isPathInRoot(filename, rootPath) {
36
+ if (commonAncestorPath(filename, rootPath)) {
37
+ return true;
38
+ }
39
+ return commonAncestorPath(filename.toLowerCase(), rootPath.toLowerCase()) !== "";
40
+ }
35
41
  const postfixRE = /[?#].*$/s;
36
42
  function cleanUrl(url) {
37
43
  return url.replace(postfixRE, "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "6.4.3",
3
+ "version": "6.4.5",
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",