astro 4.0.7 → 4.0.9

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 (37) hide show
  1. package/README.md +1 -1
  2. package/astro-jsx.d.ts +1 -0
  3. package/content-types.template.d.ts +2 -2
  4. package/dist/@types/astro.d.ts +4 -2
  5. package/dist/assets/build/generate.js +0 -1
  6. package/dist/assets/utils/transformToPath.js +1 -1
  7. package/dist/assets/vite-plugin-assets.js +2 -2
  8. package/dist/cli/add/index.js +1 -0
  9. package/dist/cli/preview/index.js +3 -0
  10. package/dist/content/vite-plugin-content-assets.js +1 -5
  11. package/dist/content/vite-plugin-content-virtual-mod.js +6 -1
  12. package/dist/core/constants.js +1 -1
  13. package/dist/core/dev/dev.js +1 -1
  14. package/dist/core/errors/dev/utils.js +5 -2
  15. package/dist/core/errors/dev/vite.d.ts +1 -1
  16. package/dist/core/errors/errors-data.d.ts +1 -1
  17. package/dist/core/errors/errors-data.js +6 -2
  18. package/dist/core/errors/errors.d.ts +3 -3
  19. package/dist/core/errors/errors.js +6 -6
  20. package/dist/core/errors/overlay.js +2 -2
  21. package/dist/core/messages.js +2 -2
  22. package/dist/core/middleware/loadMiddleware.js +1 -1
  23. package/dist/core/routing/params.js +2 -2
  24. package/dist/i18n/index.d.ts +1 -1
  25. package/dist/i18n/index.js +6 -3
  26. package/dist/i18n/vite-plugin-i18n.js +1 -1
  27. package/dist/runtime/client/dev-overlay/overlay.js +8 -2
  28. package/dist/runtime/client/dev-overlay/plugins/utils/highlight.js +3 -0
  29. package/dist/runtime/server/endpoint.js +15 -27
  30. package/dist/vite-plugin-astro-server/base.js +6 -1
  31. package/dist/vite-plugin-astro-server/css.d.ts +1 -2
  32. package/dist/vite-plugin-astro-server/css.js +21 -15
  33. package/dist/vite-plugin-astro-server/error.js +4 -2
  34. package/dist/vite-plugin-astro-server/request.js +1 -1
  35. package/dist/vite-plugin-astro-server/route.js +1 -5
  36. package/jsx-runtime.d.ts +6 -0
  37. package/package.json +7 -5
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <br/>
2
2
  <p align="center">
3
- <img src="../../.github/assets/banner.png" alt="Build the web you want">
3
+ <img src="../../.github/assets/banner.jpg" alt="Build the web you want">
4
4
  <br/><br/>
5
5
  <a href="https://astro.build">Astro</a> is the all-in-one web framework designed for speed.
6
6
  <br/>
package/astro-jsx.d.ts CHANGED
@@ -627,6 +627,7 @@ declare namespace astroHTML.JSX {
627
627
  }
628
628
 
629
629
  interface ButtonHTMLAttributes extends HTMLAttributes {
630
+ autocomplete?: string | undefined | null;
630
631
  disabled?: boolean | string | undefined | null;
631
632
  form?: string | undefined | null;
632
633
  formaction?: string | undefined | null;
@@ -155,11 +155,11 @@ declare module 'astro:content' {
155
155
  ? {
156
156
  collection: C;
157
157
  slug: ValidContentEntrySlug<C>;
158
- }
158
+ }
159
159
  : {
160
160
  collection: C;
161
161
  id: keyof DataEntryMap[C];
162
- }
162
+ }
163
163
  >;
164
164
  // Allow generic `string` to avoid excessive type errors in the config
165
165
  // if `dev` is not running to update as you edit.
@@ -632,7 +632,7 @@ export interface AstroUserConfig {
632
632
  * @typeraw {('file' | 'directory')}
633
633
  * @default `'directory'`
634
634
  * @description
635
- * Control the output file format of each page.
635
+ * Control the output file format of each page. This value may be set by an adapter for you.
636
636
  * - If `'file'`, Astro will generate an HTML file (ex: "/foo.html") for each page.
637
637
  * - If `'directory'`, Astro will generate a directory with a nested `index.html` file (ex: "/foo/index.html") for each page.
638
638
  *
@@ -645,6 +645,8 @@ export interface AstroUserConfig {
645
645
  * }
646
646
  * ```
647
647
  *
648
+ *
649
+ *
648
650
  * #### Effect on Astro.url
649
651
  * Setting `build.format` controls what `Astro.url` is set to during the build. When it is:
650
652
  * - `directory` - The `Astro.url.pathname` will include a trailing slash to mimic folder behavior; ie `/foo/`.
@@ -2000,7 +2002,7 @@ export interface APIContext<Props extends Record<string, any> = Record<string, a
2000
2002
  }
2001
2003
  export type APIRoute<Props extends Record<string, any> = Record<string, any>> = (context: APIContext<Props>) => Response | Promise<Response>;
2002
2004
  export interface EndpointHandler {
2003
- [method: string]: APIRoute | ((params: Params, request: Request) => Response);
2005
+ [method: string]: APIRoute;
2004
2006
  }
2005
2007
  export type Props = Record<string, unknown>;
2006
2008
  export interface AstroRenderer {
@@ -131,7 +131,6 @@ async function generateImagesForPath(originalFilePath, transformsAndPath, env, q
131
131
  ...AstroErrorData.CouldNotTransformImage,
132
132
  message: AstroErrorData.CouldNotTransformImage.message(originalFilePath)
133
133
  },
134
- void 0,
135
134
  { cause: e }
136
135
  );
137
136
  throw error;
@@ -8,7 +8,7 @@ function propsToFilename(transform, hash) {
8
8
  isESMImportedImage(transform.src) ? transform.src.src : transform.src
9
9
  );
10
10
  const ext = extname(filename);
11
- filename = basename(filename, ext);
11
+ filename = decodeURIComponent(basename(filename, ext));
12
12
  let outputExt = transform.format ? `.${transform.format}` : ext;
13
13
  return `/${filename}_${hash}${outputExt}`;
14
14
  }
@@ -100,9 +100,9 @@ function assets({
100
100
  });
101
101
  }
102
102
  if (settings.config.build.assetsPrefix) {
103
- return joinPaths(settings.config.build.assetsPrefix, finalFilePath);
103
+ return encodeURI(joinPaths(settings.config.build.assetsPrefix, finalFilePath));
104
104
  } else {
105
- return prependForwardSlash(joinPaths(settings.config.base, finalFilePath));
105
+ return encodeURI(prependForwardSlash(joinPaths(settings.config.base, finalFilePath)));
106
106
  }
107
107
  };
108
108
  },
@@ -93,6 +93,7 @@ async function add(names, { flags }) {
93
93
  ["lit", "astro add lit"],
94
94
  ["alpinejs", "astro add alpinejs"]
95
95
  ],
96
+ "Documentation Frameworks": [["starlight", "astro add starlight"]],
96
97
  "SSR Adapters": [
97
98
  ["netlify", "astro add netlify"],
98
99
  ["vercel", "astro add vercel"],
@@ -9,6 +9,9 @@ async function preview({ flags }) {
9
9
  usage: "[...flags]",
10
10
  tables: {
11
11
  Flags: [
12
+ ["--port", `Specify which port to run on. Defaults to 4321.`],
13
+ ["--host", `Listen on all addresses, including LAN and public addresses.`],
14
+ ["--host <custom-address>", `Expose on a network IP address at <custom-address>`],
12
15
  ["--open", "Automatically open the app in the browser on server start"],
13
16
  ["--help (-h)", "See all available flags."]
14
17
  ]
@@ -49,11 +49,7 @@ function astroContentAssetPropagationPlugin({
49
49
  if (!devModuleLoader.getModuleById(basePath)?.ssrModule) {
50
50
  await devModuleLoader.import(basePath);
51
51
  }
52
- const { styles, urls } = await getStylesForURL(
53
- pathToFileURL(basePath),
54
- devModuleLoader,
55
- "development"
56
- );
52
+ const { styles, urls } = await getStylesForURL(pathToFileURL(basePath), devModuleLoader);
57
53
  const hoistedScripts = await getScriptsForURL(
58
54
  pathToFileURL(basePath),
59
55
  settings.config.root,
@@ -209,7 +209,12 @@ async function generateLookupMap({
209
209
  if (lookupMap[collection]?.entries?.[slug]) {
210
210
  throw new AstroError({
211
211
  ...AstroErrorData.DuplicateContentEntrySlugError,
212
- message: AstroErrorData.DuplicateContentEntrySlugError.message(collection, slug),
212
+ message: AstroErrorData.DuplicateContentEntrySlugError.message(
213
+ collection,
214
+ slug,
215
+ lookupMap[collection].entries[slug],
216
+ rootRelativePath(root, filePath)
217
+ ),
213
218
  hint: slug !== generatedSlug ? `Check the \`slug\` frontmatter property in **${id}**.` : void 0
214
219
  });
215
220
  }
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "4.0.7";
1
+ const ASTRO_VERSION = "4.0.9";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -21,7 +21,7 @@ async function dev(inlineConfig) {
21
21
  base: restart.container.settings.config.base
22
22
  })
23
23
  );
24
- const currentVersion = "4.0.7";
24
+ const currentVersion = "4.0.9";
25
25
  if (currentVersion.includes("-")) {
26
26
  logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
27
27
  }
@@ -15,7 +15,7 @@ function collectErrorMetadata(e, rootFolder) {
15
15
  err.forEach((error) => {
16
16
  if (e.stack) {
17
17
  const stackInfo = collectInfoFromStacktrace(e);
18
- error.stack = stackInfo.stack;
18
+ error.stack = stripAnsi(stackInfo.stack);
19
19
  error.loc = stackInfo.loc;
20
20
  error.plugin = stackInfo.plugin;
21
21
  error.pluginCode = stackInfo.pluginCode;
@@ -30,7 +30,7 @@ function collectErrorMetadata(e, rootFolder) {
30
30
  const fileContents = fs.readFileSync(error.loc.file, "utf8");
31
31
  if (!error.frame) {
32
32
  const frame = codeFrame(fileContents, error.loc);
33
- error.frame = frame;
33
+ error.frame = stripAnsi(frame);
34
34
  }
35
35
  if (!error.fullCode) {
36
36
  error.fullCode = fileContents;
@@ -39,6 +39,9 @@ function collectErrorMetadata(e, rootFolder) {
39
39
  }
40
40
  }
41
41
  error.hint = generateHint(e);
42
+ if (error.message) {
43
+ error.message = stripAnsi(error.message);
44
+ }
42
45
  });
43
46
  if (!AggregateError.is(e) && Array.isArray(e.errors)) {
44
47
  e.errors.forEach((buildError, i) => {
@@ -16,7 +16,7 @@ export interface AstroErrorPayload {
16
16
  hint?: string;
17
17
  docslink?: string;
18
18
  highlightedCode?: string;
19
- loc: {
19
+ loc?: {
20
20
  file?: string;
21
21
  line?: number;
22
22
  column?: number;
@@ -1159,7 +1159,7 @@ export declare const DataCollectionEntryParseError: {
1159
1159
  export declare const DuplicateContentEntrySlugError: {
1160
1160
  name: string;
1161
1161
  title: string;
1162
- message: (collection: string, slug: string) => string;
1162
+ message: (collection: string, slug: string, preExisting: string, alsoFound: string) => string;
1163
1163
  };
1164
1164
  /**
1165
1165
  * @docs
@@ -426,8 +426,12 @@ const DataCollectionEntryParseError = {
426
426
  const DuplicateContentEntrySlugError = {
427
427
  name: "DuplicateContentEntrySlugError",
428
428
  title: "Duplicate content entry slug.",
429
- message: (collection, slug) => {
430
- return `**${collection}** contains multiple entries with the same slug: \`${slug}\`. Slugs must be unique.`;
429
+ message: (collection, slug, preExisting, alsoFound) => {
430
+ return `**${collection}** contains multiple entries with the same slug: \`${slug}\`. Slugs must be unique.
431
+
432
+ Entries:
433
+ - ${preExisting}
434
+ - ${alsoFound}`;
431
435
  }
432
436
  };
433
437
  const UnsupportedConfigTransformError = {
@@ -21,7 +21,7 @@ export declare class AstroError extends Error {
21
21
  hint: string | undefined;
22
22
  frame: string | undefined;
23
23
  type: ErrorTypes;
24
- constructor(props: ErrorProperties, ...params: any);
24
+ constructor(props: ErrorProperties, options?: ErrorOptions);
25
25
  setLocation(location: ErrorLocation): void;
26
26
  setName(name: string): void;
27
27
  setMessage(message: string): void;
@@ -31,7 +31,7 @@ export declare class AstroError extends Error {
31
31
  }
32
32
  export declare class CompilerError extends AstroError {
33
33
  type: ErrorTypes;
34
- constructor(props: ErrorProperties, ...params: any);
34
+ constructor(props: ErrorProperties, options?: ErrorOptions);
35
35
  static is(err: unknown): err is CompilerError;
36
36
  }
37
37
  export declare class CSSError extends AstroError {
@@ -51,7 +51,7 @@ export declare class AggregateError extends AstroError {
51
51
  errors: AstroError[];
52
52
  constructor(props: ErrorProperties & {
53
53
  errors: AstroError[];
54
- }, ...params: any);
54
+ }, options?: ErrorOptions);
55
55
  static is(err: unknown): err is AggregateError;
56
56
  }
57
57
  /**
@@ -8,9 +8,9 @@ class AstroError extends Error {
8
8
  hint;
9
9
  frame;
10
10
  type = "AstroError";
11
- constructor(props, ...params) {
12
- super(...params);
11
+ constructor(props, options) {
13
12
  const { name, title, message, stack, location, hint, frame } = props;
13
+ super(message, options);
14
14
  this.title = title;
15
15
  this.name = name;
16
16
  if (message)
@@ -41,8 +41,8 @@ class AstroError extends Error {
41
41
  }
42
42
  class CompilerError extends AstroError {
43
43
  type = "CompilerError";
44
- constructor(props, ...params) {
45
- super(props, ...params);
44
+ constructor(props, options) {
45
+ super(props, options);
46
46
  }
47
47
  static is(err) {
48
48
  return err.type === "CompilerError";
@@ -71,8 +71,8 @@ class AggregateError extends AstroError {
71
71
  errors;
72
72
  // Despite being a collection of errors, AggregateError still needs to have a main error attached to it
73
73
  // This is because Vite expects every thrown errors handled during HMR to be, well, Error and have a message
74
- constructor(props, ...params) {
75
- super(props, ...params);
74
+ constructor(props, options) {
75
+ super(props, options);
76
76
  this.errors = props.errors;
77
77
  }
78
78
  static is(err) {
@@ -621,7 +621,7 @@ class ErrorOverlay extends HTMLElement {
621
621
  docslink.appendChild(this.createLink(`See Docs Reference${openNewWindowIcon}`, err.docslink));
622
622
  }
623
623
  const code = this.root.querySelector("#code");
624
- if (code && err.loc.file) {
624
+ if (code && err.loc?.file) {
625
625
  code.style.display = "block";
626
626
  const codeHeader = code.querySelector("#code header");
627
627
  const codeContent = code.querySelector("#code-content");
@@ -647,7 +647,7 @@ class ErrorOverlay extends HTMLElement {
647
647
  if (errorLine.parentElement?.parentElement) {
648
648
  errorLine.parentElement.parentElement.scrollTop = errorLine.offsetTop - errorLine.parentElement.parentElement.offsetTop - 8;
649
649
  }
650
- if (err.loc.column) {
650
+ if (err.loc?.column) {
651
651
  errorLine.insertAdjacentHTML(
652
652
  "afterend",
653
653
  `
@@ -36,7 +36,7 @@ function serverStart({
36
36
  host,
37
37
  base
38
38
  }) {
39
- const version = "4.0.7";
39
+ const version = "4.0.9";
40
40
  const localPrefix = `${dim("\u2503")} Local `;
41
41
  const networkPrefix = `${dim("\u2503")} Network `;
42
42
  const emptyPrefix = " ".repeat(11);
@@ -258,7 +258,7 @@ function printHelp({
258
258
  message.push(
259
259
  linebreak(),
260
260
  ` ${bgGreen(black(` ${commandName} `))} ${green(
261
- `v${"4.0.7"}`
261
+ `v${"4.0.9"}`
262
262
  )} ${headline}`
263
263
  );
264
264
  }
@@ -5,7 +5,7 @@ async function loadMiddleware(moduleLoader) {
5
5
  try {
6
6
  return await moduleLoader.import(MIDDLEWARE_MODULE_ID);
7
7
  } catch (error) {
8
- const astroError = new AstroError(MiddlewareCantBeLoaded, void 0, { cause: error });
8
+ const astroError = new AstroError(MiddlewareCantBeLoaded, { cause: error });
9
9
  throw astroError;
10
10
  }
11
11
  }
@@ -5,9 +5,9 @@ function getParams(array) {
5
5
  const params = {};
6
6
  array.forEach((key, i) => {
7
7
  if (key.startsWith("...")) {
8
- params[key.slice(3)] = match[i + 1] ? decodeURIComponent(match[i + 1]) : void 0;
8
+ params[key.slice(3)] = match[i + 1] ? match[i + 1] : void 0;
9
9
  } else {
10
- params[key] = decodeURIComponent(match[i + 1]);
10
+ params[key] = match[i + 1];
11
11
  }
12
12
  });
13
13
  return params;
@@ -53,7 +53,7 @@ export declare function getPathByLocale(locale: string, locales: Locales): strin
53
53
  /**
54
54
  * An utility function that retrieves the preferred locale that correspond to a path.
55
55
  *
56
- * @param locale
56
+ * @param path
57
57
  * @param locales
58
58
  */
59
59
  export declare function getLocaleByPath(path: string, locales: Locales): string | undefined;
@@ -99,10 +99,13 @@ function getPathByLocale(locale, locales) {
99
99
  function getLocaleByPath(path, locales) {
100
100
  for (const locale of locales) {
101
101
  if (typeof locale !== "string") {
102
- const code = locale.codes.at(0);
103
- return code;
102
+ if (locale.path === path) {
103
+ const code = locale.codes.at(0);
104
+ return code;
105
+ }
106
+ } else if (locale === path) {
107
+ return locale;
104
108
  }
105
- 1;
106
109
  }
107
110
  return void 0;
108
111
  }
@@ -54,7 +54,7 @@ function astroInternationalization({
54
54
  export const getAbsoluteLocaleUrlList = (path = "", opts) => _getLocaleAbsoluteUrlList({ base, path, trailingSlash, format, site, ...i18n, ...opts });
55
55
 
56
56
  export const getPathByLocale = (locale) => _getPathByLocale(locale, i18n.locales);
57
- export const getLocaleByPath = (locale) => _getLocaleByPath(locale, i18n.locales);
57
+ export const getLocaleByPath = (path) => _getLocaleByPath(path, i18n.locales);
58
58
  `;
59
59
  }
60
60
  }
@@ -3,6 +3,7 @@ import { getIconElement, isDefinedIcon } from "./ui-library/icons.js";
3
3
  const WS_EVENT_NAME = "astro-dev-toolbar";
4
4
  const WS_EVENT_NAME_DEPRECATED = "astro-dev-overlay";
5
5
  const HOVER_DELAY = 2 * 1e3;
6
+ const DEVBAR_HITBOX_ABOVE = 42;
6
7
  class AstroDevOverlay extends HTMLElement {
7
8
  shadowRoot;
8
9
  delayedHideTimeout;
@@ -62,7 +63,7 @@ class AstroDevOverlay extends HTMLElement {
62
63
  pointer-events: auto;
63
64
  }
64
65
  #dev-bar-hitbox-above {
65
- height: 42px;
66
+ height: ${DEVBAR_HITBOX_ABOVE}px;
66
67
  }
67
68
  #dev-bar-hitbox-below {
68
69
  height: 16px;
@@ -131,7 +132,7 @@ class AstroDevOverlay extends HTMLElement {
131
132
  border-radius: 4px;
132
133
  padding: 4px 8px;
133
134
  position: absolute;
134
- top: 4px;
135
+ top: ${4 - DEVBAR_HITBOX_ABOVE}px;
135
136
  font-size: 14px;
136
137
  opacity: 0;
137
138
  transition: opacity 0.2s ease-in-out 0s;
@@ -423,16 +424,21 @@ class AstroDevOverlay extends HTMLElement {
423
424
  setOverlayVisible(newStatus) {
424
425
  const barContainer = this.shadowRoot.querySelector("#bar-container");
425
426
  const devBar = this.shadowRoot.querySelector("#dev-bar");
427
+ const devBarHitboxAbove = this.shadowRoot.querySelector("#dev-bar-hitbox-above");
426
428
  if (newStatus === true) {
427
429
  this.devOverlay?.removeAttribute("data-hidden");
428
430
  barContainer?.removeAttribute("inert");
429
431
  devBar?.removeAttribute("tabindex");
432
+ if (devBarHitboxAbove)
433
+ devBarHitboxAbove.style.height = "0";
430
434
  return;
431
435
  }
432
436
  if (newStatus === false) {
433
437
  this.devOverlay?.setAttribute("data-hidden", "");
434
438
  barContainer?.setAttribute("inert", "");
435
439
  devBar?.setAttribute("tabindex", "0");
440
+ if (devBarHitboxAbove)
441
+ devBarHitboxAbove.style.height = `${DEVBAR_HITBOX_ABOVE}px`;
436
442
  return;
437
443
  }
438
444
  }
@@ -44,6 +44,9 @@ function attachTooltipToHighlight(highlight, tooltip, originalElement) {
44
44
  } else {
45
45
  tooltip.style.top = `-${tooltip.offsetHeight}px`;
46
46
  }
47
+ if (dialogRect.right > document.documentElement.clientWidth) {
48
+ tooltip.style.right = "0px";
49
+ }
47
50
  });
48
51
  });
49
52
  ["mouseout", "blur"].forEach((event) => {
@@ -1,44 +1,32 @@
1
1
  import { bold } from "kleur/colors";
2
- function getHandlerFromModule(mod, method) {
3
- if (mod[method]) {
4
- return mod[method];
5
- }
6
- if (mod["ALL"]) {
7
- return mod["ALL"];
8
- }
9
- return void 0;
10
- }
11
2
  async function renderEndpoint(mod, context, ssr, logger) {
12
3
  const { request, url } = context;
13
- const chosenMethod = request.method?.toUpperCase();
14
- const handler = getHandlerFromModule(mod, chosenMethod);
15
- if (!ssr && ssr === false && chosenMethod && chosenMethod !== "GET") {
4
+ const method = request.method.toUpperCase();
5
+ const handler = mod[method] ?? mod["ALL"];
6
+ if (!ssr && ssr === false && method !== "GET") {
16
7
  logger.warn(
17
- null,
8
+ "router",
18
9
  `${url.pathname} ${bold(
19
- chosenMethod
10
+ method
20
11
  )} requests are not available for a static site. Update your config to \`output: 'server'\` or \`output: 'hybrid'\` to enable.`
21
12
  );
22
13
  }
23
- if (!handler || typeof handler !== "function") {
24
- let response = new Response(null, {
14
+ if (typeof handler !== "function") {
15
+ logger.warn(
16
+ "router",
17
+ `No API Route handler exists for the method "${method}" for the route ${url.pathname}.
18
+ Found handlers: ${Object.keys(mod).map((exp) => JSON.stringify(exp)).join(", ")}
19
+ ` + ("all" in mod ? `One of the exported handlers is "all" (lowercase), did you mean to export 'ALL'?
20
+ ` : "")
21
+ );
22
+ return new Response(null, {
25
23
  status: 404,
26
24
  headers: {
27
25
  "X-Astro-Response": "Not-Found"
28
26
  }
29
27
  });
30
- return response;
31
28
  }
32
- const proxy = new Proxy(context, {
33
- get(target, prop) {
34
- if (prop in target) {
35
- return Reflect.get(target, prop);
36
- } else {
37
- return void 0;
38
- }
39
- }
40
- });
41
- return handler.call(mod, proxy, request);
29
+ return handler.call(mod, context);
42
30
  }
43
31
  export {
44
32
  renderEndpoint
@@ -10,7 +10,12 @@ function baseMiddleware(settings, logger) {
10
10
  const devRootReplacement = devRoot.endsWith("/") ? "/" : "";
11
11
  return function devBaseMiddleware(req, res, next) {
12
12
  const url = req.url;
13
- const pathname = decodeURI(new URL(url, "http://localhost").pathname);
13
+ let pathname;
14
+ try {
15
+ pathname = decodeURI(new URL(url, "http://localhost").pathname);
16
+ } catch (e) {
17
+ return next(e);
18
+ }
14
19
  if (pathname.startsWith(devRoot)) {
15
20
  req.url = url.replace(devRoot, devRootReplacement);
16
21
  return next();
@@ -1,4 +1,3 @@
1
- import type { RuntimeMode } from '../@types/astro.js';
2
1
  import type { ModuleLoader } from '../core/module-loader/index.js';
3
2
  interface ImportedStyle {
4
3
  id: string;
@@ -6,7 +5,7 @@ interface ImportedStyle {
6
5
  content: string;
7
6
  }
8
7
  /** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
9
- export declare function getStylesForURL(filePath: URL, loader: ModuleLoader, mode: RuntimeMode): Promise<{
8
+ export declare function getStylesForURL(filePath: URL, loader: ModuleLoader): Promise<{
10
9
  urls: Set<string>;
11
10
  styles: ImportedStyle[];
12
11
  }>;
@@ -1,27 +1,33 @@
1
1
  import { viteID } from "../core/util.js";
2
2
  import { isBuildableCSSRequest } from "./util.js";
3
3
  import { crawlGraph } from "./vite.js";
4
- async function getStylesForURL(filePath, loader, mode) {
4
+ async function getStylesForURL(filePath, loader) {
5
5
  const importedCssUrls = /* @__PURE__ */ new Set();
6
6
  const importedStylesMap = /* @__PURE__ */ new Map();
7
7
  for await (const importedModule of crawlGraph(loader, viteID(filePath), true)) {
8
8
  if (isBuildableCSSRequest(importedModule.url)) {
9
- let ssrModule;
10
- try {
11
- ssrModule = importedModule.ssrModule ?? await loader.import(importedModule.url);
12
- } catch {
13
- continue;
14
- }
15
- if (mode === "development" && // only inline in development
16
- typeof ssrModule?.default === "string") {
17
- importedStylesMap.set(importedModule.url, {
18
- id: importedModule.id ?? importedModule.url,
19
- url: importedModule.url,
20
- content: ssrModule.default
21
- });
9
+ let css = "";
10
+ if (typeof importedModule.ssrModule?.default === "string") {
11
+ css = importedModule.ssrModule.default;
22
12
  } else {
23
- importedCssUrls.add(importedModule.url);
13
+ const url = new URL(importedModule.url, "http://localhost");
14
+ url.searchParams.set("inline", "");
15
+ const modId = `${decodeURI(url.pathname)}${url.search}`;
16
+ try {
17
+ const ssrModule = await loader.import(modId);
18
+ css = ssrModule.default;
19
+ } catch {
20
+ if (modId.includes(".module.")) {
21
+ importedCssUrls.add(importedModule.url);
22
+ }
23
+ continue;
24
+ }
24
25
  }
26
+ importedStylesMap.set(importedModule.url, {
27
+ id: importedModule.id ?? importedModule.url,
28
+ url: importedModule.url,
29
+ content: css
30
+ });
25
31
  }
26
32
  }
27
33
  return {
@@ -1,5 +1,5 @@
1
1
  import { collectErrorMetadata } from "../core/errors/dev/index.js";
2
- import { createSafeError } from "../core/errors/index.js";
2
+ import { createSafeError, AstroErrorData } from "../core/errors/index.js";
3
3
  import { formatErrorMessage } from "../core/messages.js";
4
4
  import { eventError, telemetry } from "../events/index.js";
5
5
  function recordServerError(loader, config, pipeline, _err) {
@@ -9,7 +9,9 @@ function recordServerError(loader, config, pipeline, _err) {
9
9
  } catch {
10
10
  }
11
11
  const errorWithMetadata = collectErrorMetadata(err, config.root);
12
- telemetry.record(eventError({ cmd: "dev", err: errorWithMetadata, isFatal: false }));
12
+ if (errorWithMetadata.name !== AstroErrorData.UnhandledRejection.name) {
13
+ telemetry.record(eventError({ cmd: "dev", err: errorWithMetadata, isFatal: false }));
14
+ }
13
15
  pipeline.logger.error(
14
16
  null,
15
17
  formatErrorMessage(errorWithMetadata, pipeline.logger.level() === "debug")
@@ -21,7 +21,7 @@ async function handleRequest({
21
21
  if (config.trailingSlash === "never" && !incomingRequest.url) {
22
22
  pathname = "";
23
23
  } else {
24
- pathname = decodeURI(url.pathname);
24
+ pathname = url.pathname;
25
25
  }
26
26
  url.pathname = removeTrailingForwardSlash(config.base) + url.pathname;
27
27
  if (!buildingToSSR && pathname !== "/_image") {
@@ -330,11 +330,7 @@ async function getScriptsAndStyles({ pipeline, filePath }) {
330
330
  });
331
331
  }
332
332
  }
333
- const { urls: styleUrls, styles: importedStyles } = await getStylesForURL(
334
- filePath,
335
- moduleLoader,
336
- mode
337
- );
333
+ const { urls: styleUrls, styles: importedStyles } = await getStylesForURL(filePath, moduleLoader);
338
334
  let links = /* @__PURE__ */ new Set();
339
335
  [...styleUrls].forEach((href) => {
340
336
  links.add({
@@ -0,0 +1,6 @@
1
+ // Q: Why this file?
2
+ // A: Our language tooling needs to access the JSX types from `astro/jsx-runtime`, due to TS limitations, however we
3
+ // can't import `astro-jsx` types inside the actual `jsx-runtime/index.js` file due to circular dependency issues.
4
+ import './astro-jsx.js';
5
+ export * from './dist/jsx-runtime/index.js';
6
+ export import JSX = astroHTML.JSX;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "4.0.7",
3
+ "version": "4.0.9",
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",
@@ -34,12 +34,14 @@
34
34
  "./env": "./env.d.ts",
35
35
  "./types": "./types.d.ts",
36
36
  "./client": "./client.d.ts",
37
- "./import-meta": "./import-meta.d.ts",
38
37
  "./astro-jsx": "./astro-jsx.d.ts",
39
38
  "./tsconfigs/*.json": "./tsconfigs/*",
40
39
  "./tsconfigs/*": "./tsconfigs/*.json",
41
40
  "./jsx/*": "./dist/jsx/*",
42
- "./jsx-runtime": "./dist/jsx-runtime/index.js",
41
+ "./jsx-runtime": {
42
+ "types": "./jsx-runtime.d.ts",
43
+ "default": "./dist/jsx-runtime/index.js"
44
+ },
43
45
  "./compiler-runtime": "./dist/runtime/compiler/index.js",
44
46
  "./runtime/*": "./dist/runtime/*",
45
47
  "./config": {
@@ -90,9 +92,9 @@
90
92
  "zod.mjs",
91
93
  "env.d.ts",
92
94
  "client.d.ts",
95
+ "jsx-runtime.d.ts",
93
96
  "content-types.template.d.ts",
94
97
  "content-module.template.mjs",
95
- "import-meta.d.ts",
96
98
  "astro-jsx.d.ts",
97
99
  "types.d.ts",
98
100
  "README.md",
@@ -162,7 +164,7 @@
162
164
  "@astrojs/telemetry": "3.0.4"
163
165
  },
164
166
  "optionalDependencies": {
165
- "sharp": "^0.32.5"
167
+ "sharp": "^0.33.1"
166
168
  },
167
169
  "devDependencies": {
168
170
  "@astrojs/check": "^0.3.1",