astro 6.1.2 → 6.1.3

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
  import { AstroError } from "../core/errors/errors.js";
2
2
  import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
3
- import { hasNonPrerenderedProjectRoute } from "../core/routing/helpers.js";
3
+ import { hasNonPrerenderedRoute } from "../core/routing/helpers.js";
4
4
  import { viteID } from "../core/util.js";
5
5
  import { ACTION_RPC_ROUTE_PATTERN, ACTIONS_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
6
6
  function astroIntegrationActionsRouteHandler({
@@ -30,7 +30,7 @@ function astroIntegrationActionsRouteHandler({
30
30
  });
31
31
  },
32
32
  "astro:routes:resolved": ({ routes }) => {
33
- if (!hasNonPrerenderedProjectRoute(routes)) {
33
+ if (!hasNonPrerenderedRoute(routes)) {
34
34
  const error = new AstroError(ActionsWithoutServerOutputError);
35
35
  error.stack = void 0;
36
36
  throw error;
@@ -1,6 +1,6 @@
1
1
  class BuildTimeAstroVersionProvider {
2
2
  // Injected during the build through esbuild define
3
- version = "6.1.2";
3
+ version = "6.1.3";
4
4
  }
5
5
  export {
6
6
  BuildTimeAstroVersionProvider
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
192
192
  logger.info("Content config changed");
193
193
  shouldClear = true;
194
194
  }
195
- if (previousAstroVersion && previousAstroVersion !== "6.1.2") {
195
+ if (previousAstroVersion && previousAstroVersion !== "6.1.3") {
196
196
  logger.info("Astro version changed");
197
197
  shouldClear = true;
198
198
  }
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
200
200
  logger.info("Clearing content store");
201
201
  this.#store.clearAll();
202
202
  }
203
- if ("6.1.2") {
204
- this.#store.metaStore().set("astro-version", "6.1.2");
203
+ if ("6.1.3") {
204
+ this.#store.metaStore().set("astro-version", "6.1.3");
205
205
  }
206
206
  if (currentConfigDigest) {
207
207
  this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -242,8 +242,12 @@ function glob(globOptions) {
242
242
  const entryType = configForFile(changedPath);
243
243
  const baseUrl = pathToFileURL(basePath);
244
244
  const oldId = fileToIdMap.get(changedPath);
245
- await syncData(entry, baseUrl, entryType, oldId);
246
- logger.info(`Reloaded data from ${colors.green(entry)}`);
245
+ try {
246
+ await syncData(entry, baseUrl, entryType, oldId);
247
+ logger.info(`Reloaded data from ${colors.green(entry)}`);
248
+ } catch (e) {
249
+ logger.error(`Failed to reload ${entry}: ${e.message}`);
250
+ }
247
251
  }
248
252
  watcher.on("change", onChange);
249
253
  watcher.on("add", onChange);
@@ -35,15 +35,18 @@ class MutableDataStore extends ImmutableDataStore {
35
35
  if (collection) {
36
36
  collection.delete(String(key));
37
37
  this.#saveToDiskDebounced();
38
+ this.#writeAssetsImportsDebounced();
38
39
  }
39
40
  }
40
41
  clear(collectionName) {
41
42
  this._collections.delete(collectionName);
42
43
  this.#saveToDiskDebounced();
44
+ this.#writeAssetsImportsDebounced();
43
45
  }
44
46
  clearAll() {
45
47
  this._collections.clear();
46
48
  this.#saveToDiskDebounced();
49
+ this.#writeAssetsImportsDebounced();
47
50
  }
48
51
  addAssetImport(assetImport, filePath) {
49
52
  const id = imageSrcToImportId(assetImport, filePath);
@@ -62,8 +65,31 @@ class MutableDataStore extends ImmutableDataStore {
62
65
  this.#writeModulesImportsDebounced();
63
66
  }
64
67
  }
68
+ /**
69
+ * Rebuilds #assetImports from the current entries in _collections.
70
+ * This ensures stale import IDs are removed when entries are updated or deleted,
71
+ * preventing unrecoverable ImageNotFound errors in astro dev after a content entry's
72
+ * image path is temporarily set to an invalid value and then restored.
73
+ */
74
+ #rebuildAssetImports() {
75
+ this.#assetImports.clear();
76
+ for (const collection of this._collections.values()) {
77
+ for (const entry of collection.values()) {
78
+ const typedEntry = entry;
79
+ if (typedEntry.assetImports?.length) {
80
+ for (const assetImport of typedEntry.assetImports) {
81
+ const id = imageSrcToImportId(assetImport, typedEntry.filePath);
82
+ if (id) {
83
+ this.#assetImports.add(id);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
65
90
  async writeAssetImports(filePath) {
66
91
  this.#assetsFile = filePath;
92
+ this.#rebuildAssetImports();
67
93
  if (this.#assetImports.size === 0) {
68
94
  try {
69
95
  await this.#writeFileAtomic(filePath, "export default new Map();");
@@ -42,6 +42,10 @@ class NonRunnablePipeline extends Pipeline {
42
42
  return pipeline;
43
43
  }
44
44
  async headElements(routeData) {
45
+ const { componentMetadataEntries } = await import("virtual:astro:component-metadata");
46
+ for (const [id, entry] of componentMetadataEntries) {
47
+ this.manifest.componentMetadata.set(id, entry);
48
+ }
45
49
  const { assetsPrefix, base } = this.manifest;
46
50
  const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
47
51
  const links = /* @__PURE__ */ new Set();
@@ -8,6 +8,7 @@ import { pluginMiddleware } from "./plugin-middleware.js";
8
8
  import { pluginPrerender } from "./plugin-prerender.js";
9
9
  import { pluginScripts } from "./plugin-scripts.js";
10
10
  import { pluginSSR } from "./plugin-ssr.js";
11
+ import { pluginChunkImports } from "./plugin-chunk-imports.js";
11
12
  import { pluginNoop } from "./plugin-noop.js";
12
13
  import { vitePluginSSRAssets } from "../vite-plugin-ssr-assets.js";
13
14
  function getAllBuildPlugins(internals, options) {
@@ -23,7 +24,8 @@ function getAllBuildPlugins(internals, options) {
23
24
  pluginScripts(internals),
24
25
  ...pluginSSR(options, internals),
25
26
  pluginNoop(),
26
- vitePluginSSRAssets(internals)
27
+ vitePluginSSRAssets(internals),
28
+ pluginChunkImports(options)
27
29
  ].filter(Boolean);
28
30
  }
29
31
  export {
@@ -0,0 +1,10 @@
1
+ import type { Plugin as VitePlugin } from 'vite';
2
+ import type { StaticBuildOptions } from '../types.js';
3
+ /**
4
+ * Appends assetQueryParams (e.g., ?dpl=<VERCEL_DEPLOYMENT_ID>) to relative
5
+ * JS import paths inside client chunks. Without this, inter-chunk imports
6
+ * bypass the HTML rendering pipeline and miss skew protection query params.
7
+ *
8
+ * Uses es-module-lexer to reliably parse both static and dynamic imports.
9
+ */
10
+ export declare function pluginChunkImports(options: StaticBuildOptions): VitePlugin | undefined;
@@ -0,0 +1,38 @@
1
+ import { init, parse } from "es-module-lexer";
2
+ import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../../constants.js";
3
+ function pluginChunkImports(options) {
4
+ const assetQueryParams = options.settings.adapter?.client?.assetQueryParams;
5
+ if (!assetQueryParams || assetQueryParams.toString() === "") {
6
+ return void 0;
7
+ }
8
+ const queryString = assetQueryParams.toString();
9
+ return {
10
+ name: "@astro/plugin-chunk-imports",
11
+ enforce: "post",
12
+ applyToEnvironment(environment) {
13
+ return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client;
14
+ },
15
+ async renderChunk(code, _chunk) {
16
+ if (!code.includes("./")) {
17
+ return null;
18
+ }
19
+ await init;
20
+ const [imports] = parse(code);
21
+ const relativeImports = imports.filter(
22
+ (imp) => imp.n && /^\.\.?\//.test(imp.n) && /\.(?:js|mjs)$/.test(imp.n)
23
+ );
24
+ if (relativeImports.length === 0) {
25
+ return null;
26
+ }
27
+ let rewritten = code;
28
+ for (let i = relativeImports.length - 1; i >= 0; i--) {
29
+ const imp = relativeImports[i];
30
+ rewritten = rewritten.slice(0, imp.e) + "?" + queryString + rewritten.slice(imp.e);
31
+ }
32
+ return { code: rewritten, map: null };
33
+ }
34
+ };
35
+ }
36
+ export {
37
+ pluginChunkImports
38
+ };
@@ -15,6 +15,11 @@ function pluginCSS(options, internals) {
15
15
  internals
16
16
  });
17
17
  }
18
+ function isBuildCssBoundary(id, ctx) {
19
+ if (isPropagatedAssetBoundary(id)) return true;
20
+ const info = ctx.getModuleInfo(id);
21
+ return info ? moduleIsTopLevelPage(info) : false;
22
+ }
18
23
  function rollupPluginAstroBuildCSS(options) {
19
24
  const { internals, buildOptions } = options;
20
25
  const { settings } = buildOptions;
@@ -95,7 +100,7 @@ function rollupPluginAstroBuildCSS(options) {
95
100
  const parentModuleInfos = getParentExtendedModuleInfos(
96
101
  scopedToModule,
97
102
  this,
98
- isPropagatedAssetBoundary
103
+ (moduleId) => isBuildCssBoundary(moduleId, this)
99
104
  );
100
105
  for (const { info: pageInfo, depth, order } of parentModuleInfos) {
101
106
  if (moduleIsTopLevelPage(pageInfo)) {
@@ -155,7 +160,7 @@ function rollupPluginAstroBuildCSS(options) {
155
160
  const parentModuleInfos = getParentExtendedModuleInfos(
156
161
  id,
157
162
  this,
158
- isPropagatedAssetBoundary
163
+ (importer) => isBuildCssBoundary(importer, this)
159
164
  );
160
165
  for (const { info: pageInfo, depth, order } of parentModuleInfos) {
161
166
  if (isPropagatedAssetBoundary(pageInfo.id)) {
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "6.1.2";
1
+ const ASTRO_VERSION = "6.1.3";
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";
@@ -3,7 +3,7 @@ export type AstroCookieSetOptions = Pick<SerializeOptions, 'domain' | 'path' | '
3
3
  export interface AstroCookieGetOptions {
4
4
  decode?: (value: string) => string;
5
5
  }
6
- type AstroCookieDeleteOptions = Omit<AstroCookieSetOptions, 'expires' | 'maxAge' | 'encode'>;
6
+ export type AstroCookieDeleteOptions = Omit<AstroCookieSetOptions, 'expires' | 'maxAge' | 'encode'>;
7
7
  interface AstroCookieInterface {
8
8
  value: string;
9
9
  json(): Record<string, any>;
@@ -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.1.2";
40
+ const currentVersion = "6.1.3";
41
41
  const isPrerelease = currentVersion.includes("-");
42
42
  if (!isPrerelease) {
43
43
  try {
@@ -276,7 +276,7 @@ function printHelp({
276
276
  message.push(
277
277
  linebreak(),
278
278
  ` ${bgGreen(black(` ${commandName} `))} ${green(
279
- `v${"6.1.2"}`
279
+ `v${"6.1.3"}`
280
280
  )} ${headline}`
281
281
  );
282
282
  }
@@ -8,7 +8,6 @@ async function matchRoute(pathname, routesList, pipeline, manifest) {
8
8
  const { logger, routeCache } = pipeline;
9
9
  const matches = matchAllRoutes(pathname, routesList);
10
10
  const preloadedMatches = getSortedPreloadedMatches({
11
- pipeline,
12
11
  matches,
13
12
  manifest
14
13
  });
@@ -38,10 +38,12 @@ export declare function getCustom500Route(manifestData: RoutesList): RouteData |
38
38
  * `.html` suffix from pathnames that intentionally include it.
39
39
  */
40
40
  export declare function routeHasHtmlExtension(route: RouteData): boolean;
41
- export declare function hasNonPrerenderedProjectRoute(routes: Array<Pick<RouteData, 'type' | 'origin' | 'prerender'>>, options?: {
41
+ export declare function hasNonPrerenderedRoute(routes: Array<Pick<RouteData, 'type' | 'origin' | 'prerender'>>, options?: {
42
42
  includeEndpoints?: boolean;
43
+ includeExternal?: boolean;
43
44
  }): boolean;
44
- export declare function hasNonPrerenderedProjectRoute(routes: Array<Pick<IntegrationResolvedRoute, 'type' | 'origin' | 'isPrerendered'>>, options?: {
45
+ export declare function hasNonPrerenderedRoute(routes: Array<Pick<IntegrationResolvedRoute, 'type' | 'origin' | 'isPrerendered'>>, options?: {
45
46
  includeEndpoints?: boolean;
47
+ includeExternal?: boolean;
46
48
  }): boolean;
47
49
  export {};
@@ -30,19 +30,21 @@ function routeHasHtmlExtension(route) {
30
30
  (segment) => segment.some((part) => !part.dynamic && part.content.includes(".html"))
31
31
  );
32
32
  }
33
- function hasNonPrerenderedProjectRoute(routes, options) {
33
+ function hasNonPrerenderedRoute(routes, options) {
34
34
  const includeEndpoints = options?.includeEndpoints ?? true;
35
+ const includeExternal = options?.includeExternal ?? false;
35
36
  const routeTypes = includeEndpoints ? ["page", "endpoint"] : ["page"];
37
+ const origins = includeExternal ? ["project", "external"] : ["project"];
36
38
  return routes.some((route) => {
37
39
  const isPrerendered = "isPrerendered" in route ? route.isPrerendered : route.prerender;
38
- return routeTypes.includes(route.type) && route.origin === "project" && !isPrerendered;
40
+ return routeTypes.includes(route.type) && origins.includes(route.origin) && !isPrerendered;
39
41
  });
40
42
  }
41
43
  export {
42
44
  getCustom404Route,
43
45
  getCustom500Route,
44
46
  getFallbackRoute,
45
- hasNonPrerenderedProjectRoute,
47
+ hasNonPrerenderedRoute,
46
48
  routeHasHtmlExtension,
47
49
  routeIsFallback,
48
50
  routeIsRedirect
@@ -1,11 +1,9 @@
1
1
  import type { RouteData, SSRManifest } from '../types/public/internal.js';
2
- import type { RunnablePipeline } from '../vite-plugin-app/pipeline.js';
3
2
  type GetSortedPreloadedMatchesParams = {
4
- pipeline: RunnablePipeline;
5
3
  matches: RouteData[];
6
4
  manifest: SSRManifest;
7
5
  };
8
- export declare function getSortedPreloadedMatches({ pipeline, matches, manifest, }: GetSortedPreloadedMatchesParams): PreloadAndSetPrerenderStatusResult[];
6
+ export declare function getSortedPreloadedMatches({ matches, manifest }: GetSortedPreloadedMatchesParams): PreloadAndSetPrerenderStatusResult[];
9
7
  type PreloadAndSetPrerenderStatusResult = {
10
8
  filePath: URL;
11
9
  route: RouteData;
@@ -1,12 +1,7 @@
1
1
  import { routeIsRedirect } from "../core/routing/helpers.js";
2
2
  import { routeComparator } from "../core/routing/priority.js";
3
- function getSortedPreloadedMatches({
4
- pipeline,
5
- matches,
6
- manifest
7
- }) {
3
+ function getSortedPreloadedMatches({ matches, manifest }) {
8
4
  return preloadAndSetPrerenderStatus({
9
- pipeline,
10
5
  matches,
11
6
  manifest
12
7
  }).sort((a, b) => routeComparator(a.route, b.route)).sort((a, b) => prioritizePrerenderedMatchesComparator(a.route, b.route));
@@ -1,12 +1,13 @@
1
1
  export declare const escapeHTML: (str: string) => string;
2
2
  export declare class HTMLBytes extends Uint8Array {
3
3
  }
4
+ declare const htmlStringSymbol: unique symbol;
4
5
  /**
5
6
  * A "blessed" extension of String that tells Astro that the string
6
7
  * has already been escaped. This helps prevent double-escaping of HTML.
7
8
  */
8
9
  export declare class HTMLString extends String {
9
- get [Symbol.toStringTag](): string;
10
+ [htmlStringSymbol]: boolean;
10
11
  }
11
12
  type BlessedType = string | HTMLBytes;
12
13
  /**
@@ -8,13 +8,12 @@ Object.defineProperty(HTMLBytes.prototype, Symbol.toStringTag, {
8
8
  return "HTMLBytes";
9
9
  }
10
10
  });
11
+ const htmlStringSymbol = /* @__PURE__ */ Symbol.for("astro:html-string");
11
12
  class HTMLString extends String {
12
- get [Symbol.toStringTag]() {
13
- return "HTMLString";
14
- }
13
+ [htmlStringSymbol] = true;
15
14
  }
16
15
  const markHTMLString = (value) => {
17
- if (value instanceof HTMLString) {
16
+ if (isHTMLString(value)) {
18
17
  return value;
19
18
  }
20
19
  if (typeof value === "string") {
@@ -23,7 +22,7 @@ const markHTMLString = (value) => {
23
22
  return value;
24
23
  };
25
24
  function isHTMLString(value) {
26
- return value instanceof HTMLString;
25
+ return !!value?.[htmlStringSymbol];
27
26
  }
28
27
  function markHTMLBytes(bytes) {
29
28
  return new HTMLBytes(bytes);
@@ -1,5 +1,4 @@
1
1
  import type * as vite from 'vite';
2
- import type { SSRManifest } from '../core/app/types.js';
3
2
  import type { Logger } from '../core/logger/core.js';
4
3
  import type { AstroSettings } from '../types/astro.js';
5
4
  interface AstroPluginOptions {
@@ -7,11 +6,4 @@ interface AstroPluginOptions {
7
6
  logger: Logger;
8
7
  }
9
8
  export default function createVitePluginAstroServer({ settings, logger, }: AstroPluginOptions): vite.Plugin;
10
- /**
11
- * It creates a `SSRManifest` from the `AstroSettings`.
12
- *
13
- * Renderers needs to be pulled out from the page module emitted during the build.
14
- * @param settings
15
- */
16
- export declare function createDevelopmentManifest(settings: AstroSettings): Promise<SSRManifest>;
17
9
  export {};
@@ -1,26 +1,11 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import { IncomingMessage } from "node:http";
3
3
  import { isRunnableDevEnvironment } from "vite";
4
- import { toFallbackType } from "../core/app/common.js";
5
- import { toRoutingStrategy } from "../core/app/entrypoints/index.js";
6
4
  import { ASTRO_VITE_ENVIRONMENT_NAMES, devPrerenderMiddlewareSymbol } from "../core/constants.js";
7
- import {
8
- getAlgorithm,
9
- getDirectives,
10
- getScriptHashes,
11
- getScriptResources,
12
- getStrictDynamic,
13
- getStyleHashes,
14
- getStyleResources,
15
- shouldTrackCspHashes
16
- } from "../core/csp/common.js";
17
- import { createKey, getEnvironmentKey, hasEnvironmentKey } from "../core/encryption.js";
18
5
  import { getViteErrorPayload } from "../core/errors/dev/index.js";
19
6
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
20
- import { NOOP_MIDDLEWARE_FN } from "../core/middleware/noop-middleware.js";
21
7
  import { createViteLoader } from "../core/module-loader/index.js";
22
8
  import { matchAllRoutes } from "../core/routing/match.js";
23
- import { resolveMiddlewareMode } from "../integrations/adapter-utils.js";
24
9
  import { SERIALIZED_MANIFEST_ID } from "../manifest/serialized.js";
25
10
  import { ASTRO_DEV_SERVER_APP_ID } from "../vite-plugin-app/index.js";
26
11
  import { baseMiddleware } from "./base.js";
@@ -30,7 +15,6 @@ import { setRouteError } from "./server-state.js";
30
15
  import { routeGuardMiddleware } from "./route-guard.js";
31
16
  import { secFetchMiddleware } from "./sec-fetch.js";
32
17
  import { trailingSlashMiddleware } from "./trailing-slash.js";
33
- import { sessionConfigToManifest } from "../core/session/utils.js";
34
18
  function createVitePluginAstroServer({
35
19
  settings,
36
20
  logger
@@ -154,97 +138,6 @@ function createVitePluginAstroServer({
154
138
  }
155
139
  };
156
140
  }
157
- async function createDevelopmentManifest(settings) {
158
- let i18nManifest;
159
- let csp;
160
- if (settings.config.i18n) {
161
- i18nManifest = {
162
- fallback: settings.config.i18n.fallback,
163
- strategy: toRoutingStrategy(settings.config.i18n.routing, settings.config.i18n.domains),
164
- defaultLocale: settings.config.i18n.defaultLocale,
165
- locales: settings.config.i18n.locales,
166
- domainLookupTable: {},
167
- fallbackType: toFallbackType(settings.config.i18n.routing),
168
- domains: settings.config.i18n.domains
169
- };
170
- }
171
- if (shouldTrackCspHashes(settings.config.security.csp)) {
172
- const styleHashes = [
173
- ...getStyleHashes(settings.config.security.csp),
174
- ...settings.injectedCsp.styleHashes
175
- ];
176
- csp = {
177
- cspDestination: settings.adapter?.adapterFeatures?.staticHeaders ? "adapter" : void 0,
178
- scriptHashes: getScriptHashes(settings.config.security.csp),
179
- scriptResources: getScriptResources(settings.config.security.csp),
180
- styleHashes,
181
- styleResources: getStyleResources(settings.config.security.csp),
182
- algorithm: getAlgorithm(settings.config.security.csp),
183
- directives: getDirectives(settings),
184
- isStrictDynamic: getStrictDynamic(settings.config.security.csp)
185
- };
186
- }
187
- return {
188
- rootDir: settings.config.root,
189
- srcDir: settings.config.srcDir,
190
- cacheDir: settings.config.cacheDir,
191
- outDir: settings.config.outDir,
192
- buildServerDir: settings.config.build.server,
193
- buildClientDir: settings.config.build.client,
194
- publicDir: settings.config.publicDir,
195
- trailingSlash: settings.config.trailingSlash,
196
- buildFormat: settings.config.build.format,
197
- compressHTML: settings.config.compressHTML,
198
- assetsDir: settings.config.build.assets,
199
- serverLike: settings.buildOutput === "server",
200
- middlewareMode: resolveMiddlewareMode(settings.adapter?.adapterFeatures),
201
- assets: /* @__PURE__ */ new Set(),
202
- entryModules: {},
203
- routes: [],
204
- adapterName: settings?.adapter?.name ?? "",
205
- clientDirectives: settings.clientDirectives,
206
- renderers: [],
207
- base: settings.config.base,
208
- userAssetsBase: settings.config?.vite?.base,
209
- assetsPrefix: settings.config.build.assetsPrefix,
210
- site: settings.config.site,
211
- componentMetadata: /* @__PURE__ */ new Map(),
212
- inlinedScripts: /* @__PURE__ */ new Map(),
213
- i18n: i18nManifest,
214
- checkOrigin: settings.config.security?.checkOrigin ?? false,
215
- allowedDomains: settings.config.security?.allowedDomains,
216
- actionBodySizeLimit: settings.config.security?.actionBodySizeLimit ? settings.config.security.actionBodySizeLimit : 1024 * 1024,
217
- // 1mb default
218
- serverIslandBodySizeLimit: settings.config.security?.serverIslandBodySizeLimit ? settings.config.security.serverIslandBodySizeLimit : 1024 * 1024,
219
- // 1mb default
220
- key: hasEnvironmentKey() ? getEnvironmentKey() : createKey(),
221
- middleware() {
222
- return {
223
- onRequest: NOOP_MIDDLEWARE_FN
224
- };
225
- },
226
- sessionConfig: sessionConfigToManifest(settings.config.session),
227
- csp,
228
- image: {
229
- objectFit: settings.config.image.objectFit,
230
- objectPosition: settings.config.image.objectPosition,
231
- layout: settings.config.image.layout
232
- },
233
- devToolbar: {
234
- enabled: settings.config.devToolbar.enabled && await settings.preferences.get("devToolbar.enabled"),
235
- latestAstroVersion: settings.latestAstroVersion,
236
- debugInfoOutput: "",
237
- placement: settings.config.devToolbar.placement
238
- },
239
- logLevel: settings.logLevel,
240
- shouldInjectCspMetaTags: false,
241
- experimentalQueuedRendering: {
242
- enabled: !!settings.config.experimental?.queuedRendering,
243
- poolSize: settings.config.experimental?.queuedRendering?.poolSize ?? 1e3
244
- }
245
- };
246
- }
247
141
  export {
248
- createDevelopmentManifest,
249
142
  createVitePluginAstroServer as default
250
143
  };
@@ -6,8 +6,16 @@ import {
6
6
  import { getTopLevelPageModuleInfos } from "../core/build/graph.js";
7
7
  import { getAstroMetadata } from "../vite-plugin-astro/index.js";
8
8
  import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
9
+ const VIRTUAL_COMPONENT_METADATA = "virtual:astro:component-metadata";
10
+ const RESOLVED_VIRTUAL_COMPONENT_METADATA = `\0${VIRTUAL_COMPONENT_METADATA}`;
9
11
  function configHeadVitePlugin() {
10
12
  let environment;
13
+ function invalidateComponentMetadataModule() {
14
+ const virtualMod = environment.moduleGraph.getModuleById(RESOLVED_VIRTUAL_COMPONENT_METADATA);
15
+ if (virtualMod) {
16
+ environment.moduleGraph.invalidateModule(virtualMod);
17
+ }
18
+ }
11
19
  function buildImporterGraphFromEnvironment(seed) {
12
20
  const queue = [seed];
13
21
  const collected = /* @__PURE__ */ new Set();
@@ -46,15 +54,44 @@ function configHeadVitePlugin() {
46
54
  }
47
55
  }
48
56
  }
57
+ invalidateComponentMetadataModule();
49
58
  }
50
59
  return {
51
60
  name: "astro:head-metadata",
52
61
  enforce: "pre",
53
62
  apply: "serve",
54
- configureServer(server) {
55
- environment = server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
63
+ configureServer(devServer) {
64
+ environment = devServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
65
+ devServer.watcher.on("add", invalidateComponentMetadataModule);
66
+ devServer.watcher.on("unlink", invalidateComponentMetadataModule);
67
+ devServer.watcher.on("change", invalidateComponentMetadataModule);
68
+ },
69
+ load(id) {
70
+ if (id !== RESOLVED_VIRTUAL_COMPONENT_METADATA) {
71
+ return;
72
+ }
73
+ const componentMetadataEntries = [];
74
+ for (const [moduleId, mod] of environment.moduleGraph.idToModuleMap) {
75
+ const info = this.getModuleInfo(moduleId) ?? (mod.id ? this.getModuleInfo(mod.id) : null);
76
+ if (!info) continue;
77
+ const astro = getAstroMetadata(info);
78
+ if (!astro) continue;
79
+ componentMetadataEntries.push([
80
+ moduleId,
81
+ {
82
+ containsHead: astro.containsHead,
83
+ propagation: astro.propagation
84
+ }
85
+ ]);
86
+ }
87
+ return {
88
+ code: `export const componentMetadataEntries = ${JSON.stringify(componentMetadataEntries)};`
89
+ };
56
90
  },
57
91
  resolveId(source, importer) {
92
+ if (source === VIRTUAL_COMPONENT_METADATA) {
93
+ return RESOLVED_VIRTUAL_COMPONENT_METADATA;
94
+ }
58
95
  if (importer) {
59
96
  return this.resolve(source, importer, { skipSelf: true }).then((result) => {
60
97
  if (result) {
@@ -81,6 +118,7 @@ function configHeadVitePlugin() {
81
118
  if (hasHeadInjectComment(source)) {
82
119
  propagateMetadata.call(this, id, "propagation", "in-tree");
83
120
  }
121
+ invalidateComponentMetadataModule();
84
122
  }
85
123
  };
86
124
  }
@@ -1,6 +1,6 @@
1
- import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
2
1
  import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../vite-plugin-pages/const.js";
3
2
  import { getDevCssModuleNameFromPageVirtualModuleName } from "../vite-plugin-css/util.js";
3
+ import { isAstroServerEnvironment } from "../environments.js";
4
4
  function hmrReload() {
5
5
  return {
6
6
  name: "astro:hmr-reload",
@@ -8,7 +8,7 @@ function hmrReload() {
8
8
  hotUpdate: {
9
9
  order: "post",
10
10
  handler({ modules, server, timestamp }) {
11
- if (this.environment.name !== ASTRO_VITE_ENVIRONMENT_NAMES.ssr) return;
11
+ if (!isAstroServerEnvironment(this.environment)) return;
12
12
  let hasSsrOnlyModules = false;
13
13
  const invalidatedModules = /* @__PURE__ */ new Set();
14
14
  for (const mod of modules) {
@@ -1,5 +1,5 @@
1
1
  import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
2
- import { hasNonPrerenderedProjectRoute } from "../core/routing/helpers.js";
2
+ import { hasNonPrerenderedRoute } from "../core/routing/helpers.js";
3
3
  const ASTRO_RENDERERS_MODULE_ID = "virtual:astro:renderers";
4
4
  const RESOLVED_ASTRO_RENDERERS_MODULE_ID = `\0${ASTRO_RENDERERS_MODULE_ID}`;
5
5
  function vitePluginRenderers(options) {
@@ -20,8 +20,9 @@ function vitePluginRenderers(options) {
20
20
  id: new RegExp(`^${RESOLVED_ASTRO_RENDERERS_MODULE_ID}$`)
21
21
  },
22
22
  handler() {
23
- if (options.command === "build" && this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr && renderers.length > 0 && !options.serverIslandsState.hasIslands() && !hasNonPrerenderedProjectRoute(options.routesList.routes, {
24
- includeEndpoints: false
23
+ if (options.command === "build" && this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr && renderers.length > 0 && !options.serverIslandsState.hasIslands() && !hasNonPrerenderedRoute(options.routesList.routes, {
24
+ includeEndpoints: false,
25
+ includeExternal: true
25
26
  })) {
26
27
  return { code: `export const renderers = [];` };
27
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "6.1.2",
3
+ "version": "6.1.3",
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",
@@ -175,7 +175,7 @@
175
175
  "cheerio": "1.2.0",
176
176
  "eol": "^0.10.0",
177
177
  "expect-type": "^1.3.0",
178
- "fs-fixture": "^2.11.0",
178
+ "fs-fixture": "^2.13.0",
179
179
  "mdast-util-mdx": "^3.0.0",
180
180
  "mdast-util-mdx-jsx": "^3.2.0",
181
181
  "node-mocks-http": "^1.17.2",