astro 2.1.6 → 2.1.8

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 (66) hide show
  1. package/astro-jsx.d.ts +3 -3
  2. package/dist/@types/astro.d.ts +9 -2
  3. package/dist/assets/index.d.ts +1 -0
  4. package/dist/assets/index.js +2 -0
  5. package/dist/assets/internal.js +12 -2
  6. package/dist/assets/utils/emitAsset.d.ts +2 -1
  7. package/dist/assets/utils/emitAsset.js +18 -3
  8. package/dist/assets/utils/transformToPath.d.ts +1 -1
  9. package/dist/assets/utils/transformToPath.js +4 -2
  10. package/dist/assets/vite-plugin-assets.js +2 -3
  11. package/dist/cli/index.js +7 -1
  12. package/dist/content/runtime.js +1 -8
  13. package/dist/content/types-generator.js +7 -1
  14. package/dist/content/vite-plugin-content-imports.js +1 -1
  15. package/dist/core/app/common.js +2 -2
  16. package/dist/core/app/index.js +1 -1
  17. package/dist/core/app/node.d.ts +10 -3
  18. package/dist/core/app/node.js +15 -0
  19. package/dist/core/app/types.d.ts +4 -4
  20. package/dist/core/build/generate.js +1 -1
  21. package/dist/core/build/internal.d.ts +1 -1
  22. package/dist/core/build/internal.js +1 -1
  23. package/dist/core/build/plugins/index.js +2 -2
  24. package/dist/core/build/plugins/plugin-ssr.js +1 -1
  25. package/dist/core/config/config.js +4 -0
  26. package/dist/core/config/schema.d.ts +11 -0
  27. package/dist/core/config/schema.js +4 -1
  28. package/dist/core/constants.js +1 -1
  29. package/dist/core/create-vite.js +2 -2
  30. package/dist/core/dev/container.js +2 -2
  31. package/dist/core/dev/dev.js +2 -1
  32. package/dist/core/errors/errors-data.d.ts +16 -0
  33. package/dist/core/errors/errors-data.js +16 -0
  34. package/dist/core/messages.js +2 -2
  35. package/dist/core/preview/index.js +4 -1
  36. package/dist/core/preview/static-preview-server.js +2 -1
  37. package/dist/core/render/context.d.ts +1 -1
  38. package/dist/core/render/core.js +16 -1
  39. package/dist/core/render/dev/index.js +5 -5
  40. package/dist/core/render/dev/metadata.d.ts +3 -0
  41. package/dist/core/render/dev/metadata.js +36 -0
  42. package/dist/core/render/result.d.ts +1 -1
  43. package/dist/core/render/result.js +11 -14
  44. package/dist/jsx/babel.js +1 -0
  45. package/dist/runtime/server/index.d.ts +1 -1
  46. package/dist/runtime/server/index.js +0 -8
  47. package/dist/runtime/server/jsx.js +1 -3
  48. package/dist/runtime/server/render/astro/factory.js +3 -5
  49. package/dist/runtime/server/render/astro/instance.js +1 -3
  50. package/dist/runtime/server/render/common.js +1 -34
  51. package/dist/runtime/server/render/index.d.ts +0 -1
  52. package/dist/runtime/server/render/index.js +0 -5
  53. package/dist/runtime/server/render/page.js +12 -8
  54. package/dist/runtime/server/render/slot.js +1 -3
  55. package/dist/vite-plugin-astro/index.js +1 -0
  56. package/dist/vite-plugin-astro/types.d.ts +1 -0
  57. package/dist/vite-plugin-head/index.d.ts +9 -0
  58. package/dist/vite-plugin-head/index.js +95 -0
  59. package/dist/vite-plugin-markdown/index.js +1 -0
  60. package/package.json +2 -2
  61. package/dist/core/render/dev/head.d.ts +0 -3
  62. package/dist/core/render/dev/head.js +0 -26
  63. package/dist/runtime/server/render/scope.d.ts +0 -14
  64. package/dist/runtime/server/render/scope.js +0 -40
  65. package/dist/vite-plugin-head-propagation/index.d.ts +0 -15
  66. package/dist/vite-plugin-head-propagation/index.js +0 -86
package/astro-jsx.d.ts CHANGED
@@ -789,9 +789,9 @@ declare namespace astroHTML.JSX {
789
789
  fetchpriority?: 'auto' | 'high' | 'low' | undefined | null;
790
790
  integrity?: string | undefined | null;
791
791
  media?: string | undefined | null;
792
- imageSrcSet?: string | undefined | null;
793
- imageSizes?: string | undefined | null;
794
- referrerPolicy?: HTMLAttributeReferrerPolicy | undefined | null;
792
+ imagesrcset?: string | undefined | null;
793
+ imagesizes?: string | undefined | null;
794
+ referrerpolicy?: HTMLAttributeReferrerPolicy | undefined | null;
795
795
  rel?: string | undefined | null;
796
796
  sizes?: string | undefined | null;
797
797
  type?: string | undefined | null;
@@ -68,6 +68,7 @@ export interface CLIFlags {
68
68
  port?: number;
69
69
  config?: string;
70
70
  drafts?: boolean;
71
+ open?: boolean;
71
72
  experimentalAssets?: boolean;
72
73
  }
73
74
  export interface BuildConfig {
@@ -974,7 +975,8 @@ export interface ContentEntryType {
974
975
  fileUrl: URL;
975
976
  contents: string;
976
977
  }): GetEntryInfoReturnType | Promise<GetEntryInfoReturnType>;
977
- getRenderModule?(params: {
978
+ getRenderModule?(this: rollup.PluginContext, params: {
979
+ viteId: string;
978
980
  entry: ContentEntryModule;
979
981
  }): rollup.LoadResult | Promise<rollup.LoadResult>;
980
982
  contentModuleTypes?: string;
@@ -1422,6 +1424,7 @@ export interface SSRMetadata {
1422
1424
  hasHydrationScript: boolean;
1423
1425
  hasDirectives: Set<string>;
1424
1426
  hasRenderedHead: boolean;
1427
+ headInTree: boolean;
1425
1428
  }
1426
1429
  /**
1427
1430
  * A hint on whether the Astro runtime needs to wait on a component to render head
@@ -1434,11 +1437,15 @@ export interface SSRMetadata {
1434
1437
  * These are used within the runtime to know whether or not a component should be waited on.
1435
1438
  */
1436
1439
  export type PropagationHint = 'none' | 'self' | 'in-tree';
1440
+ export type SSRComponentMetadata = {
1441
+ propagation: PropagationHint;
1442
+ containsHead: boolean;
1443
+ };
1437
1444
  export interface SSRResult {
1438
1445
  styles: Set<SSRElement>;
1439
1446
  scripts: Set<SSRElement>;
1440
1447
  links: Set<SSRElement>;
1441
- propagation: Map<string, PropagationHint>;
1448
+ componentMetadata: Map<string, SSRComponentMetadata>;
1442
1449
  propagators: Map<AstroComponentFactory, AstroComponentInstance>;
1443
1450
  extraHead: Array<string>;
1444
1451
  cookies: AstroCookies | undefined;
@@ -1,4 +1,5 @@
1
1
  export { getConfiguredImageService, getImage } from './internal.js';
2
2
  export { baseService } from './services/service.js';
3
3
  export { type LocalImageProps, type RemoteImageProps } from './types.js';
4
+ export { emitESMImage } from './utils/emitAsset.js';
4
5
  export { imageMetadata } from './utils/metadata.js';
@@ -1,9 +1,11 @@
1
1
  import { getConfiguredImageService, getImage } from "./internal.js";
2
2
  import { baseService } from "./services/service.js";
3
3
  import {} from "./types.js";
4
+ import { emitESMImage } from "./utils/emitAsset.js";
4
5
  import { imageMetadata } from "./utils/metadata.js";
5
6
  export {
6
7
  baseService,
8
+ emitESMImage,
7
9
  getConfiguredImageService,
8
10
  getImage,
9
11
  imageMetadata
@@ -1,5 +1,7 @@
1
1
  import fs from "node:fs";
2
+ import { basename, join } from "node:path/posix";
2
3
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
4
+ import { prependForwardSlash } from "../core/path.js";
3
5
  import { isLocalService } from "./services/service.js";
4
6
  function isESMImportedImage(src) {
5
7
  return typeof src === "object";
@@ -53,8 +55,16 @@ async function generateImage(buildOpts, options, filepath) {
53
55
  serverRoot = buildOpts.settings.config.outDir;
54
56
  clientRoot = buildOpts.settings.config.outDir;
55
57
  }
56
- const fileData = await fs.promises.readFile(new URL("." + options.src.src, serverRoot));
57
- const resultData = await imageService.transform(fileData, { ...options, src: options.src.src });
58
+ const originalImagePath = options.src.src;
59
+ const fileData = await fs.promises.readFile(
60
+ new URL(
61
+ "." + prependForwardSlash(
62
+ join(buildOpts.settings.config.build.assets, basename(originalImagePath))
63
+ ),
64
+ serverRoot
65
+ )
66
+ );
67
+ const resultData = await imageService.transform(fileData, { ...options, src: originalImagePath });
58
68
  const finalFileURL = new URL("." + filepath, clientRoot);
59
69
  const finalFolderURL = new URL("./", finalFileURL);
60
70
  await fs.promises.mkdir(finalFolderURL, { recursive: true });
@@ -1,2 +1,3 @@
1
1
  import type { AstroSettings } from '../../@types/astro';
2
- export declare function emitESMImage(id: string, watchMode: boolean, fileEmitter: any, settings: AstroSettings): Promise<import("./metadata.js").Metadata | undefined>;
2
+ export declare function emitESMImage(id: string, watchMode: boolean, fileEmitter: any, settings: Pick<AstroSettings, 'config'>): Promise<import("./metadata.js").Metadata | undefined>;
3
+ export declare function emoji(char: string, fallback: string): string;
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { rootRelativePath } from "../../core/util.js";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import slash from "slash";
5
5
  import { imageMetadata } from "./metadata.js";
6
6
  async function emitESMImage(id, watchMode, fileEmitter, settings) {
7
7
  const url = pathToFileURL(id);
@@ -26,6 +26,21 @@ async function emitESMImage(id, watchMode, fileEmitter, settings) {
26
26
  }
27
27
  return meta;
28
28
  }
29
+ function rootRelativePath(config, url) {
30
+ const basePath = fileURLToNormalizedPath(url);
31
+ const rootPath = fileURLToNormalizedPath(config.root);
32
+ return prependForwardSlash(basePath.slice(rootPath.length));
33
+ }
34
+ function prependForwardSlash(filePath) {
35
+ return filePath[0] === "/" ? filePath : "/" + filePath;
36
+ }
37
+ function fileURLToNormalizedPath(filePath) {
38
+ return slash(fileURLToPath(filePath) + filePath.search).replace(/\\/g, "/");
39
+ }
40
+ function emoji(char, fallback) {
41
+ return process.platform !== "win32" ? char : fallback;
42
+ }
29
43
  export {
30
- emitESMImage
44
+ emitESMImage,
45
+ emoji
31
46
  };
@@ -1,2 +1,2 @@
1
1
  import type { ImageTransform } from '../types.js';
2
- export declare function propsToFilename(transform: ImageTransform): string;
2
+ export declare function propsToFilename(transform: ImageTransform, imageService: string): string;
@@ -2,15 +2,17 @@ import { basename, extname } from "path";
2
2
  import { removeQueryString } from "../../core/path.js";
3
3
  import { shorthash } from "../../runtime/server/shorthash.js";
4
4
  import { isESMImportedImage } from "../internal.js";
5
- function propsToFilename(transform) {
5
+ function propsToFilename(transform, imageService) {
6
6
  if (!isESMImportedImage(transform.src)) {
7
7
  return transform.src;
8
8
  }
9
9
  let filename = removeQueryString(transform.src.src);
10
10
  const ext = extname(filename);
11
11
  filename = basename(filename, ext);
12
+ const { alt, ...rest } = transform;
13
+ const hashFields = { ...rest, imageService };
12
14
  const outputExt = transform.format ? `.${transform.format}` : ext;
13
- return `/${filename}_${shorthash(JSON.stringify(transform))}${outputExt}`;
15
+ return `/${filename}_${shorthash(JSON.stringify(hashFields))}${outputExt}`;
14
16
  }
15
17
  export {
16
18
  propsToFilename
@@ -135,14 +135,13 @@ function assets({
135
135
  }
136
136
  filePath = prependForwardSlash(
137
137
  joinPaths(
138
- settings.config.base,
139
138
  settings.config.build.assets,
140
- propsToFilename(options)
139
+ propsToFilename(options, settings.config.image.service)
141
140
  )
142
141
  );
143
142
  globalThis.astroAsset.staticImages.set(options, filePath);
144
143
  }
145
- return filePath;
144
+ return prependForwardSlash(joinPaths(settings.config.base, filePath));
146
145
  };
147
146
  },
148
147
  async buildEnd() {
package/dist/cli/index.js CHANGED
@@ -165,7 +165,13 @@ async function runCommand(cmd, flags) {
165
165
  }
166
166
  case "build": {
167
167
  const { default: build } = await import("../core/build/index.js");
168
- return await build(settings, { flags, logging, telemetry, teardownCompiler: true });
168
+ return await build(settings, {
169
+ flags,
170
+ logging,
171
+ telemetry,
172
+ teardownCompiler: true,
173
+ mode: flags.mode
174
+ });
169
175
  }
170
176
  case "check": {
171
177
  const checkServer = await check(settings, { flags, logging });
@@ -3,7 +3,6 @@ import { prependForwardSlash } from "../core/path.js";
3
3
  import {
4
4
  createComponent,
5
5
  createHeadAndContent,
6
- createScopedResult,
7
6
  renderComponent,
8
7
  renderScriptElement,
9
8
  renderStyleElement,
@@ -147,13 +146,7 @@ async function render({
147
146
  }
148
147
  return createHeadAndContent(
149
148
  unescapeHTML(styles + links + scripts),
150
- renderTemplate`${renderComponent(
151
- createScopedResult(result),
152
- "Content",
153
- mod.Content,
154
- props,
155
- slots
156
- )}`
149
+ renderTemplate`${renderComponent(result, "Content", mod.Content, props, slots)}`
157
150
  );
158
151
  },
159
152
  propagation: "self"
@@ -173,8 +173,14 @@ async function createContentTypesGenerator({
173
173
  return;
174
174
  events.push(event);
175
175
  debounceTimeout && clearTimeout(debounceTimeout);
176
+ const runEventsSafe = async () => {
177
+ try {
178
+ await runEvents(opts);
179
+ } catch {
180
+ }
181
+ };
176
182
  debounceTimeout = setTimeout(
177
- async () => runEvents(opts),
183
+ runEventsSafe,
178
184
  50
179
185
  /* debounce to batch chokidar events */
180
186
  );
@@ -106,7 +106,7 @@ export const _internal = {
106
106
  )}. Did you import this module directly without using a content collection query?`
107
107
  });
108
108
  }
109
- return contentRenderer({ entry });
109
+ return contentRenderer.bind(this)({ entry, viteId });
110
110
  }
111
111
  });
112
112
  }
@@ -10,11 +10,11 @@ function deserializeManifest(serializedManifest) {
10
10
  route.routeData = deserializeRouteData(serializedRoute.routeData);
11
11
  }
12
12
  const assets = new Set(serializedManifest.assets);
13
- const propagation = new Map(serializedManifest.propagation);
13
+ const componentMetadata = new Map(serializedManifest.componentMetadata);
14
14
  return {
15
15
  ...serializedManifest,
16
16
  assets,
17
- propagation,
17
+ componentMetadata,
18
18
  routes
19
19
  };
20
20
  }
@@ -161,7 +161,7 @@ class App {
161
161
  request,
162
162
  origin: url.origin,
163
163
  pathname,
164
- propagation: this.#manifest.propagation,
164
+ componentMetadata: this.#manifest.componentMetadata,
165
165
  scripts,
166
166
  links,
167
167
  route: routeData,
@@ -1,11 +1,18 @@
1
1
  /// <reference types="node" />
2
2
  import type { RouteData } from '../../@types/astro';
3
3
  import type { SSRManifest } from './types';
4
- import type { IncomingMessage } from 'http';
4
+ import { IncomingMessage } from 'http';
5
5
  import { App, type MatchOptions } from './index.js';
6
+ declare class NodeIncomingMessage extends IncomingMessage {
7
+ /**
8
+ * The read-only body property of the Request interface contains a ReadableStream with the body contents that have been added to the request.
9
+ */
10
+ body?: any | undefined;
11
+ }
6
12
  export declare class NodeApp extends App {
7
- match(req: IncomingMessage | Request, opts?: MatchOptions): RouteData | undefined;
8
- render(req: IncomingMessage | Request, routeData?: RouteData): Promise<Response>;
13
+ match(req: NodeIncomingMessage | Request, opts?: MatchOptions): RouteData | undefined;
14
+ render(req: NodeIncomingMessage | Request, routeData?: RouteData): Promise<Response>;
9
15
  }
10
16
  export declare function loadManifest(rootFolder: URL): Promise<SSRManifest>;
11
17
  export declare function loadApp(rootFolder: URL): Promise<NodeApp>;
18
+ export {};
@@ -1,4 +1,5 @@
1
1
  import * as fs from "fs";
2
+ import { IncomingMessage } from "http";
2
3
  import { TLSSocket } from "tls";
3
4
  import { deserializeManifest } from "./common.js";
4
5
  import { App } from "./index.js";
@@ -20,11 +21,25 @@ function createRequestFromNodeRequest(req, body) {
20
21
  }
21
22
  return request;
22
23
  }
24
+ class NodeIncomingMessage extends IncomingMessage {
25
+ }
23
26
  class NodeApp extends App {
24
27
  match(req, opts = {}) {
25
28
  return super.match(req instanceof Request ? req : createRequestFromNodeRequest(req), opts);
26
29
  }
27
30
  render(req, routeData) {
31
+ if (typeof req.body === "string" && req.body.length > 0) {
32
+ return super.render(
33
+ req instanceof Request ? req : createRequestFromNodeRequest(req, Buffer.from(req.body)),
34
+ routeData
35
+ );
36
+ }
37
+ if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) {
38
+ return super.render(
39
+ req instanceof Request ? req : createRequestFromNodeRequest(req, Buffer.from(JSON.stringify(req.body))),
40
+ routeData
41
+ );
42
+ }
28
43
  if ("on" in req) {
29
44
  let body = Buffer.from([]);
30
45
  let reqBodyComplete = new Promise((resolve, reject) => {
@@ -1,5 +1,5 @@
1
1
  import type { MarkdownRenderingOptions } from '@astrojs/markdown-remark';
2
- import type { ComponentInstance, PropagationHint, RouteData, SerializedRouteData, SSRLoadedRenderer, SSRResult } from '../../@types/astro';
2
+ import type { ComponentInstance, RouteData, SerializedRouteData, SSRComponentMetadata, SSRLoadedRenderer, SSRResult } from '../../@types/astro';
3
3
  export type ComponentPath = string;
4
4
  export interface RouteInfo {
5
5
  routeData: RouteData;
@@ -26,11 +26,11 @@ export interface SSRManifest {
26
26
  renderers: SSRLoadedRenderer[];
27
27
  entryModules: Record<string, string>;
28
28
  assets: Set<string>;
29
- propagation: SSRResult['propagation'];
29
+ componentMetadata: SSRResult['componentMetadata'];
30
30
  }
31
- export type SerializedSSRManifest = Omit<SSRManifest, 'routes' | 'assets' | 'propagation'> & {
31
+ export type SerializedSSRManifest = Omit<SSRManifest, 'routes' | 'assets' | 'componentMetadata'> & {
32
32
  routes: SerializedRouteInfo[];
33
33
  assets: string[];
34
- propagation: readonly [string, PropagationHint][];
34
+ componentMetadata: [string, SSRComponentMetadata][];
35
35
  };
36
36
  export type AdapterCreateExports<T = any> = (manifest: SSRManifest, args?: T) => Record<string, any>;
@@ -291,7 +291,7 @@ async function generatePath(pathname, opts, gopts) {
291
291
  origin,
292
292
  pathname,
293
293
  request: createRequest({ url, headers: new Headers(), logging, ssr }),
294
- propagation: internals.propagation,
294
+ componentMetadata: internals.componentMetadata,
295
295
  scripts,
296
296
  links,
297
297
  route: pageData.route
@@ -58,7 +58,7 @@ export interface BuildInternals {
58
58
  discoveredScripts: Set<string>;
59
59
  staticFiles: Set<string>;
60
60
  ssrEntryChunk?: OutputChunk;
61
- propagation: SSRResult['propagation'];
61
+ componentMetadata: SSRResult['componentMetadata'];
62
62
  }
63
63
  /**
64
64
  * Creates internal maps used to coordinate the CSS and HTML plugins.
@@ -17,7 +17,7 @@ function createBuildInternals() {
17
17
  discoveredClientOnlyComponents: /* @__PURE__ */ new Map(),
18
18
  discoveredScripts: /* @__PURE__ */ new Set(),
19
19
  staticFiles: /* @__PURE__ */ new Set(),
20
- propagation: /* @__PURE__ */ new Map()
20
+ componentMetadata: /* @__PURE__ */ new Map()
21
21
  };
22
22
  }
23
23
  function trackPageData(internals, component, pageData, componentModuleId, componentURL) {
@@ -1,5 +1,5 @@
1
1
  import { astroConfigBuildPlugin } from "../../../content/vite-plugin-content-assets.js";
2
- import { astroHeadPropagationBuildPlugin } from "../../../vite-plugin-head-propagation/index.js";
2
+ import { astroHeadBuildPlugin } from "../../../vite-plugin-head/index.js";
3
3
  import { pluginAliasResolve } from "./plugin-alias-resolve.js";
4
4
  import { pluginAnalyzer } from "./plugin-analyzer.js";
5
5
  import { pluginComponentEntry } from "./plugin-component-entry.js";
@@ -16,7 +16,7 @@ function registerAllPlugins({ internals, options, register }) {
16
16
  register(pluginInternals(internals));
17
17
  register(pluginPages(options, internals));
18
18
  register(pluginCSS(options, internals));
19
- register(astroHeadPropagationBuildPlugin(options, internals));
19
+ register(astroHeadBuildPlugin(options, internals));
20
20
  register(pluginPrerender(options, internals));
21
21
  register(astroConfigBuildPlugin(options, internals));
22
22
  register(pluginHoistedScripts(options, internals));
@@ -168,7 +168,7 @@ function buildManifest(opts, internals, staticFiles) {
168
168
  base: settings.config.base,
169
169
  markdown: settings.config.markdown,
170
170
  pageMap: null,
171
- propagation: Array.from(internals.propagation),
171
+ componentMetadata: Array.from(internals.componentMetadata),
172
172
  renderers: [],
173
173
  entryModules,
174
174
  assets: staticFiles.map((s) => settings.config.base + s)
@@ -71,6 +71,7 @@ function resolveFlags(flags) {
71
71
  site: typeof flags.site === "string" ? flags.site : void 0,
72
72
  base: typeof flags.base === "string" ? flags.base : void 0,
73
73
  port: typeof flags.port === "number" ? flags.port : void 0,
74
+ open: typeof flags.open === "boolean" ? flags.open : void 0,
74
75
  config: typeof flags.config === "string" ? flags.config : void 0,
75
76
  host: typeof flags.host === "string" || typeof flags.host === "boolean" ? flags.host : void 0,
76
77
  drafts: typeof flags.drafts === "boolean" ? flags.drafts : void 0,
@@ -99,6 +100,9 @@ function mergeCLIFlags(astroConfig, flags) {
99
100
  if (typeof flags.host === "string" || typeof flags.host === "boolean") {
100
101
  astroConfig.server.host = flags.host;
101
102
  }
103
+ if (typeof flags.open === "boolean") {
104
+ astroConfig.server.open = flags.open;
105
+ }
102
106
  return astroConfig;
103
107
  }
104
108
  async function search(fsMod, root) {
@@ -56,19 +56,23 @@ export declare const AstroConfigSchema: z.ZodObject<{
56
56
  serverEntry?: string | undefined;
57
57
  }>>>;
58
58
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodObject<{
59
+ open: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
59
60
  host: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
60
61
  port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
61
62
  headers: z.ZodOptional<z.ZodType<OutgoingHttpHeaders, z.ZodTypeDef, OutgoingHttpHeaders>>;
62
63
  }, "strip", z.ZodTypeAny, {
63
64
  headers?: OutgoingHttpHeaders | undefined;
65
+ open: boolean;
64
66
  host: string | boolean;
65
67
  port: number;
66
68
  }, {
69
+ open?: boolean | undefined;
67
70
  host?: string | boolean | undefined;
68
71
  port?: number | undefined;
69
72
  headers?: OutgoingHttpHeaders | undefined;
70
73
  }>>>, {
71
74
  headers?: OutgoingHttpHeaders | undefined;
75
+ open: boolean;
72
76
  host: string | boolean;
73
77
  port: number;
74
78
  }, unknown>;
@@ -165,6 +169,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
165
169
  trailingSlash: "never" | "always" | "ignore";
166
170
  server: {
167
171
  headers?: OutgoingHttpHeaders | undefined;
172
+ open: boolean;
168
173
  host: string | boolean;
169
174
  port: number;
170
175
  };
@@ -350,20 +355,24 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
350
355
  server: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodObject<{
351
356
  host: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
352
357
  port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
358
+ open: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
353
359
  headers: z.ZodOptional<z.ZodType<OutgoingHttpHeaders, z.ZodTypeDef, OutgoingHttpHeaders>>;
354
360
  streaming: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
355
361
  }, "strip", z.ZodTypeAny, {
356
362
  headers?: OutgoingHttpHeaders | undefined;
363
+ open: boolean;
357
364
  host: string | boolean;
358
365
  port: number;
359
366
  streaming: boolean;
360
367
  }, {
368
+ open?: boolean | undefined;
361
369
  host?: string | boolean | undefined;
362
370
  port?: number | undefined;
363
371
  headers?: OutgoingHttpHeaders | undefined;
364
372
  streaming?: boolean | undefined;
365
373
  }>>>, {
366
374
  headers?: OutgoingHttpHeaders | undefined;
375
+ open: boolean;
367
376
  host: string | boolean;
368
377
  port: number;
369
378
  streaming: boolean;
@@ -397,6 +406,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
397
406
  trailingSlash: "never" | "always" | "ignore";
398
407
  server: {
399
408
  headers?: OutgoingHttpHeaders | undefined;
409
+ open: boolean;
400
410
  host: string | boolean;
401
411
  port: number;
402
412
  streaming: boolean;
@@ -493,6 +503,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: URL)
493
503
  trailingSlash: "never" | "always" | "ignore";
494
504
  server: {
495
505
  headers?: OutgoingHttpHeaders | undefined;
506
+ open: boolean;
496
507
  host: string | boolean;
497
508
  port: number;
498
509
  streaming: boolean;
@@ -19,7 +19,8 @@ const ASTRO_CONFIG_DEFAULTS = {
19
19
  server: {
20
20
  host: false,
21
21
  port: 3e3,
22
- streaming: true
22
+ streaming: true,
23
+ open: false
23
24
  },
24
25
  integrations: [],
25
26
  markdown: {
@@ -62,6 +63,7 @@ const AstroConfigSchema = z.object({
62
63
  (val) => typeof val === "function" ? val({ command: "error" }) : val,
63
64
  // validate
64
65
  z.object({
66
+ open: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
65
67
  host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
66
68
  port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
67
69
  headers: z.custom().optional()
@@ -137,6 +139,7 @@ function createRelativeSchema(cmd, fileProtocolRoot) {
137
139
  z.object({
138
140
  host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
139
141
  port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
142
+ open: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
140
143
  headers: z.custom().optional(),
141
144
  streaming: z.boolean().optional().default(true)
142
145
  }).optional().default({})
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "2.1.6";
1
+ const ASTRO_VERSION = "2.1.8";
2
2
  const SUPPORTED_MARKDOWN_FILE_EXTENSIONS = [
3
3
  ".markdown",
4
4
  ".mdown",
@@ -13,7 +13,7 @@ import { vitePluginAstroServer } from "../vite-plugin-astro-server/index.js";
13
13
  import astroVitePlugin from "../vite-plugin-astro/index.js";
14
14
  import configAliasVitePlugin from "../vite-plugin-config-alias/index.js";
15
15
  import envVitePlugin from "../vite-plugin-env/index.js";
16
- import astroHeadPropagationPlugin from "../vite-plugin-head-propagation/index.js";
16
+ import astroHeadPlugin from "../vite-plugin-head/index.js";
17
17
  import htmlVitePlugin from "../vite-plugin-html/index.js";
18
18
  import { astroInjectEnvTsPlugin } from "../vite-plugin-inject-env-ts/index.js";
19
19
  import astroIntegrationsContainerPlugin from "../vite-plugin-integrations-container/index.js";
@@ -95,7 +95,7 @@ async function createVite(commandConfig, { settings, logging, mode, command, fs
95
95
  astroPostprocessVitePlugin({ settings }),
96
96
  astroIntegrationsContainerPlugin({ settings, logging }),
97
97
  astroScriptsPageSSRPlugin({ settings }),
98
- astroHeadPropagationPlugin({ settings }),
98
+ astroHeadPlugin({ settings }),
99
99
  astroScannerPlugin({ settings }),
100
100
  astroInjectEnvTsPlugin({ settings, logging, fs }),
101
101
  astroContentVirtualModPlugin({ settings }),
@@ -34,12 +34,12 @@ async function createContainer(params = {}) {
34
34
  logging,
35
35
  isRestart
36
36
  });
37
- const { host, headers } = settings.config.server;
37
+ const { host, headers, open } = settings.config.server;
38
38
  const rendererClientEntries = settings.renderers.map((r) => r.clientEntrypoint).filter(Boolean);
39
39
  const viteConfig = await createVite(
40
40
  {
41
41
  mode: "development",
42
- server: { host, headers },
42
+ server: { host, headers, open },
43
43
  optimizeDeps: {
44
44
  include: rendererClientEntries
45
45
  },
@@ -17,6 +17,7 @@ async function dev(settings, options) {
17
17
  ["--port", `Specify which port to run on. Defaults to 3000.`],
18
18
  ["--host", `Listen on all addresses, including LAN and public addresses.`],
19
19
  ["--host <custom-address>", `Expose on a network IP address at <custom-address>`],
20
+ ["--open", "Automatically open the app in the browser on server start"],
20
21
  ["--help (-h)", "See all available flags."]
21
22
  ]
22
23
  },
@@ -52,7 +53,7 @@ async function dev(settings, options) {
52
53
  isRestart: options.isRestart
53
54
  })
54
55
  );
55
- const currentVersion = "2.1.6";
56
+ const currentVersion = "2.1.8";
56
57
  if (currentVersion.includes("-")) {
57
58
  warn(options.logging, null, msg.prerelease({ currentVersion }));
58
59
  }
@@ -466,6 +466,22 @@ export declare const AstroErrorData: {
466
466
  readonly message: (format: string, imagePath: string, supportedFormats: readonly string[]) => string;
467
467
  readonly hint: "If you do not need optimization, using an `img` tag directly instead of the `Image` component might be what you're looking for.";
468
468
  };
469
+ /**
470
+ * @docs
471
+ * @see
472
+ * - [`getStaticPaths()`](https://docs.astro.build/en/reference/api-reference/#getstaticpaths)
473
+ * - [`params`](https://docs.astro.build/en/reference/api-reference/#params)
474
+ * @description
475
+ * The endpoint is prerendered with an `undefined` param so the generated path will collide with another route.
476
+ *
477
+ * If you cannot prevent passing `undefined`, then an additional extension can be added to the endpoint file name to generate the file with a different name. For example, renaming `pages/api/[slug].ts` to `pages/api/[slug].json.ts`.
478
+ */
479
+ readonly PrerenderDynamicEndpointPathCollide: {
480
+ readonly title: "Prerendered dynamic endpoint has path collision.";
481
+ readonly code: 3026;
482
+ readonly message: (pathname: string) => string;
483
+ readonly hint: (filename: string) => string;
484
+ };
469
485
  /**
470
486
  * @docs
471
487
  * @see
@@ -479,6 +479,22 @@ Expected \`true\` value but got \`${suffix}\`.`;
479
479
  )} are supported for optimization.`,
480
480
  hint: "If you do not need optimization, using an `img` tag directly instead of the `Image` component might be what you're looking for."
481
481
  },
482
+ /**
483
+ * @docs
484
+ * @see
485
+ * - [`getStaticPaths()`](https://docs.astro.build/en/reference/api-reference/#getstaticpaths)
486
+ * - [`params`](https://docs.astro.build/en/reference/api-reference/#params)
487
+ * @description
488
+ * The endpoint is prerendered with an `undefined` param so the generated path will collide with another route.
489
+ *
490
+ * If you cannot prevent passing `undefined`, then an additional extension can be added to the endpoint file name to generate the file with a different name. For example, renaming `pages/api/[slug].ts` to `pages/api/[slug].json.ts`.
491
+ */
492
+ PrerenderDynamicEndpointPathCollide: {
493
+ title: "Prerendered dynamic endpoint has path collision.",
494
+ code: 3026,
495
+ message: (pathname) => `Could not render \`${pathname}\` with an \`undefined\` param as the generated path will collide during prerendering. Prevent passing \`undefined\` as \`params\` for the endpoint's \`getStaticPaths()\` function, or add an additional extension to the endpoint's filename.`,
496
+ hint: (filename) => `Rename \`${filename}\` to \`${filename.replace(/\.(js|ts)/, (m) => `.json` + m)}\``
497
+ },
482
498
  // No headings here, that way Vite errors are merged with Astro ones in the docs, which makes more sense to users.
483
499
  // Vite Errors - 4xxx
484
500
  /**