astro 2.5.5 → 2.5.7

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 (63) hide show
  1. package/dist/@types/astro.d.ts +9 -2
  2. package/dist/assets/services/service.js +6 -0
  3. package/dist/assets/utils/emitAsset.d.ts +1 -3
  4. package/dist/assets/utils/emitAsset.js +4 -15
  5. package/dist/assets/vite-plugin-assets.js +5 -5
  6. package/dist/config/index.js +11 -3
  7. package/dist/config/vite-plugin-content-listen.d.ts +18 -0
  8. package/dist/config/vite-plugin-content-listen.js +26 -0
  9. package/dist/content/consts.d.ts +2 -1
  10. package/dist/content/consts.js +8 -1
  11. package/dist/content/runtime-assets.d.ts +1 -2
  12. package/dist/content/runtime-assets.js +2 -3
  13. package/dist/content/runtime.js +67 -47
  14. package/dist/content/types-generator.js +9 -5
  15. package/dist/content/utils.d.ts +2 -2
  16. package/dist/content/utils.js +4 -4
  17. package/dist/content/vite-plugin-content-assets.js +26 -10
  18. package/dist/content/vite-plugin-content-imports.js +113 -150
  19. package/dist/content/vite-plugin-content-virtual-mod.d.ts +3 -3
  20. package/dist/content/vite-plugin-content-virtual-mod.js +21 -8
  21. package/dist/core/app/index.d.ts +0 -2
  22. package/dist/core/app/index.js +5 -7
  23. package/dist/core/app/node.js +4 -3
  24. package/dist/core/app/types.d.ts +3 -2
  25. package/dist/core/build/generate.js +16 -11
  26. package/dist/core/build/graph.js +3 -2
  27. package/dist/core/build/internal.d.ts +8 -4
  28. package/dist/core/build/internal.js +19 -1
  29. package/dist/core/build/plugins/plugin-css.js +9 -14
  30. package/dist/core/build/plugins/plugin-middleware.d.ts +0 -1
  31. package/dist/core/build/plugins/plugin-middleware.js +3 -16
  32. package/dist/core/build/plugins/plugin-pages.d.ts +10 -0
  33. package/dist/core/build/plugins/plugin-pages.js +40 -24
  34. package/dist/core/build/plugins/plugin-ssr.d.ts +2 -2
  35. package/dist/core/build/plugins/plugin-ssr.js +46 -20
  36. package/dist/core/build/static-build.js +18 -5
  37. package/dist/core/build/types.d.ts +2 -2
  38. package/dist/core/config/schema.d.ts +170 -170
  39. package/dist/core/constants.js +1 -1
  40. package/dist/core/dev/dev.js +1 -1
  41. package/dist/core/errors/errors-data.d.ts +57 -8
  42. package/dist/core/errors/errors-data.js +57 -12
  43. package/dist/core/messages.js +2 -2
  44. package/dist/core/render/dev/index.js +1 -2
  45. package/dist/core/render/dev/vite.js +12 -13
  46. package/dist/prerender/routing.d.ts +13 -0
  47. package/dist/prerender/routing.js +49 -0
  48. package/dist/runtime/server/astro-global.js +11 -1
  49. package/dist/runtime/server/index.d.ts +1 -1
  50. package/dist/runtime/server/index.js +9 -1
  51. package/dist/runtime/server/render/any.js +4 -2
  52. package/dist/runtime/server/render/astro/instance.js +3 -0
  53. package/dist/runtime/server/render/astro/render-template.d.ts +1 -1
  54. package/dist/runtime/server/render/astro/render-template.js +5 -9
  55. package/dist/runtime/server/render/util.d.ts +6 -0
  56. package/dist/runtime/server/render/util.js +8 -0
  57. package/dist/runtime/server/scripts.js +1 -1
  58. package/dist/vite-plugin-astro-server/route.js +3 -11
  59. package/dist/vite-plugin-head/index.js +1 -1
  60. package/dist/vite-plugin-markdown/content-entry-type.js +6 -1
  61. package/dist/vite-plugin-utils/index.js +1 -1
  62. package/package.json +4 -4
  63. package/src/content/template/virtual-mod.mjs +1 -1
@@ -3,16 +3,16 @@ import { extname } from "node:path";
3
3
  import { pathToFileURL } from "url";
4
4
  import { AstroErrorData } from "../core/errors/errors-data.js";
5
5
  import { AstroError } from "../core/errors/errors.js";
6
- import { escapeViteEnvReferences, getFileInfo } from "../vite-plugin-utils/index.js";
6
+ import { escapeViteEnvReferences } from "../vite-plugin-utils/index.js";
7
7
  import { CONTENT_FLAG, DATA_FLAG } from "./consts.js";
8
8
  import {
9
- getContentEntryConfigByExtMap,
10
9
  getContentEntryExts,
11
10
  getContentEntryIdAndSlug,
12
11
  getContentPaths,
13
12
  getDataEntryExts,
14
13
  getDataEntryId,
15
14
  getEntryCollectionName,
15
+ getEntryConfigByExtMap,
16
16
  getEntryData,
17
17
  getEntryType,
18
18
  globalContentConfigObserver,
@@ -40,13 +40,9 @@ function astroContentImportPlugin({
40
40
  const contentPaths = getContentPaths(settings.config, fs);
41
41
  const contentEntryExts = getContentEntryExts(settings);
42
42
  const dataEntryExts = getDataEntryExts(settings);
43
- const contentEntryConfigByExt = getContentEntryConfigByExtMap(settings);
44
- const dataEntryExtToParser = /* @__PURE__ */ new Map();
45
- for (const entryType of settings.dataEntryTypes) {
46
- for (const ext of entryType.extensions) {
47
- dataEntryExtToParser.set(ext, entryType.getEntryInfo);
48
- }
49
- }
43
+ const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
44
+ const dataEntryConfigByExt = getEntryConfigByExtMap(settings.dataEntryTypes);
45
+ const { contentDir } = contentPaths;
50
46
  const plugins = [
51
47
  {
52
48
  name: "astro:content-imports",
@@ -55,9 +51,9 @@ function astroContentImportPlugin({
55
51
  const fileId = viteId.split("?")[0] ?? viteId;
56
52
  const { id, data, collection, _internal } = await getDataEntryModule({
57
53
  fileId,
58
- dataEntryExtToParser,
59
- contentPaths,
60
- settings,
54
+ entryConfigByExt: dataEntryConfigByExt,
55
+ contentDir,
56
+ config: settings.config,
61
57
  fs,
62
58
  pluginContext: this
63
59
  });
@@ -74,8 +70,12 @@ export const _internal = {
74
70
  return code;
75
71
  } else if (hasContentFlag(viteId, CONTENT_FLAG)) {
76
72
  const fileId = viteId.split("?")[0];
77
- const { id, slug, collection, body, data, _internal } = await setContentEntryModuleCache({
73
+ const { id, slug, collection, body, data, _internal } = await getContentEntryModule({
78
74
  fileId,
75
+ entryConfigByExt: contentEntryConfigByExt,
76
+ contentDir,
77
+ config: settings.config,
78
+ fs,
79
79
  pluginContext: this
80
80
  });
81
81
  const code = escapeViteEnvReferences(`
@@ -123,103 +123,115 @@ export const _internal = {
123
123
  if (settings.contentEntryTypes.some((t) => t.getRenderModule)) {
124
124
  plugins.push({
125
125
  name: "astro:content-render-imports",
126
- async transform(_, viteId) {
126
+ async transform(contents, viteId) {
127
127
  const contentRenderer = getContentRendererByViteId(viteId, settings);
128
128
  if (!contentRenderer)
129
129
  return;
130
- const { fileId } = getFileInfo(viteId, settings.config);
131
- const entry = await getContentEntryModuleFromCache(fileId);
132
- if (!entry) {
133
- throw new AstroError({
134
- ...AstroErrorData.UnknownContentCollectionError,
135
- message: `Unable to render ${JSON.stringify(
136
- fileId
137
- )}. Did you import this module directly without using a content collection query?`
138
- });
139
- }
140
- return contentRenderer.bind(this)({ entry, viteId });
130
+ const fileId = viteId.split("?")[0];
131
+ return contentRenderer.bind(this)({ viteId, contents, fileUrl: pathToFileURL(fileId) });
141
132
  }
142
133
  });
143
134
  }
144
- const contentEntryModuleByIdCache = /* @__PURE__ */ new Map();
145
- function isAwaitingQueue(cacheEntry) {
146
- return typeof cacheEntry === "object" && cacheEntry != null && "awaitingQueue" in cacheEntry;
147
- }
148
- function getContentEntryModuleFromCache(id) {
149
- const cacheEntry = contentEntryModuleByIdCache.get(id);
150
- if (isAwaitingQueue(cacheEntry)) {
151
- return new Promise((resolve, reject) => {
152
- cacheEntry.awaitingQueue.push(resolve);
153
- });
154
- } else if (cacheEntry) {
155
- return Promise.resolve(cacheEntry);
156
- }
157
- return Promise.resolve(void 0);
158
- }
159
- async function setContentEntryModuleCache({
160
- fileId,
161
- pluginContext
162
- }) {
163
- contentEntryModuleByIdCache.set(fileId, { awaitingQueue: [] });
164
- const contentConfig = await getContentConfigFromGlobal();
165
- const rawContents = await fs.promises.readFile(fileId, "utf-8");
166
- const fileExt = extname(fileId);
167
- if (!contentEntryConfigByExt.has(fileExt)) {
168
- throw new AstroError({
169
- ...AstroErrorData.UnknownContentCollectionError,
170
- message: `No parser found for content entry ${JSON.stringify(
171
- fileId
172
- )}. Did you apply an integration for this file type?`
173
- });
174
- }
175
- const contentEntryConfig = contentEntryConfigByExt.get(fileExt);
176
- const {
177
- rawData,
178
- body,
179
- slug: frontmatterSlug,
180
- data: unvalidatedData
181
- } = await contentEntryConfig.getEntryInfo({
182
- fileUrl: pathToFileURL(fileId),
183
- contents: rawContents
135
+ return plugins;
136
+ }
137
+ async function getContentEntryModule(params) {
138
+ const { fileId, contentDir, pluginContext, config } = params;
139
+ const { collectionConfig, entryConfig, entry, rawContents, collection } = await getEntryModuleBaseInfo(params);
140
+ const {
141
+ rawData,
142
+ data: unvalidatedData,
143
+ body,
144
+ slug: frontmatterSlug
145
+ } = await entryConfig.getEntryInfo({
146
+ fileUrl: pathToFileURL(fileId),
147
+ contents: rawContents
148
+ });
149
+ const _internal = { filePath: fileId, rawData };
150
+ const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ entry, contentDir, collection });
151
+ const slug = parseEntrySlug({
152
+ id,
153
+ collection,
154
+ generatedSlug,
155
+ frontmatterSlug
156
+ });
157
+ const data = collectionConfig ? await getEntryData(
158
+ { id, collection, _internal, unvalidatedData },
159
+ collectionConfig,
160
+ pluginContext,
161
+ config
162
+ ) : unvalidatedData;
163
+ const contentEntryModule = {
164
+ id,
165
+ slug,
166
+ collection,
167
+ data,
168
+ body,
169
+ _internal
170
+ };
171
+ return contentEntryModule;
172
+ }
173
+ async function getDataEntryModule(params) {
174
+ const { fileId, contentDir, pluginContext, config } = params;
175
+ const { collectionConfig, entryConfig, entry, rawContents, collection } = await getEntryModuleBaseInfo(params);
176
+ const { rawData = "", data: unvalidatedData } = await entryConfig.getEntryInfo({
177
+ fileUrl: pathToFileURL(fileId),
178
+ contents: rawContents
179
+ });
180
+ const _internal = { filePath: fileId, rawData };
181
+ const id = getDataEntryId({ entry, contentDir, collection });
182
+ const data = collectionConfig ? await getEntryData(
183
+ { id, collection, _internal, unvalidatedData },
184
+ collectionConfig,
185
+ pluginContext,
186
+ config
187
+ ) : unvalidatedData;
188
+ const dataEntryModule = {
189
+ id,
190
+ collection,
191
+ data,
192
+ _internal
193
+ };
194
+ return dataEntryModule;
195
+ }
196
+ async function getEntryModuleBaseInfo({
197
+ fileId,
198
+ entryConfigByExt,
199
+ contentDir,
200
+ fs
201
+ }) {
202
+ const contentConfig = await getContentConfigFromGlobal();
203
+ let rawContents;
204
+ try {
205
+ rawContents = await fs.promises.readFile(fileId, "utf-8");
206
+ } catch (e) {
207
+ throw new AstroError({
208
+ ...AstroErrorData.UnknownContentCollectionError,
209
+ message: `Unexpected error reading entry ${JSON.stringify(fileId)}.`,
210
+ stack: e instanceof Error ? e.stack : void 0
184
211
  });
185
- const entry = pathToFileURL(fileId);
186
- const { contentDir } = contentPaths;
187
- const collection = getEntryCollectionName({ entry, contentDir });
188
- if (collection === void 0)
189
- throw new AstroError(AstroErrorData.UnknownContentCollectionError);
190
- const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ entry, contentDir, collection });
191
- const _internal = { filePath: fileId, rawData };
192
- const slug = parseEntrySlug({
193
- id,
194
- collection,
195
- generatedSlug,
196
- frontmatterSlug
212
+ }
213
+ const fileExt = extname(fileId);
214
+ const entryConfig = entryConfigByExt.get(fileExt);
215
+ if (!entryConfig) {
216
+ throw new AstroError({
217
+ ...AstroErrorData.UnknownContentCollectionError,
218
+ message: `No parser found for data entry ${JSON.stringify(
219
+ fileId
220
+ )}. Did you apply an integration for this file type?`
197
221
  });
198
- const collectionConfig = contentConfig == null ? void 0 : contentConfig.collections[collection];
199
- let data = collectionConfig ? await getEntryData(
200
- { id, collection, _internal, unvalidatedData },
201
- collectionConfig,
202
- pluginContext,
203
- settings.config
204
- ) : unvalidatedData;
205
- const contentEntryModule = {
206
- id,
207
- slug,
208
- collection,
209
- data,
210
- body,
211
- _internal
212
- };
213
- const cacheEntry = contentEntryModuleByIdCache.get(fileId);
214
- if (isAwaitingQueue(cacheEntry)) {
215
- for (const resolve of cacheEntry.awaitingQueue) {
216
- resolve(contentEntryModule);
217
- }
218
- }
219
- contentEntryModuleByIdCache.set(fileId, contentEntryModule);
220
- return contentEntryModule;
221
222
  }
222
- return plugins;
223
+ const entry = pathToFileURL(fileId);
224
+ const collection = getEntryCollectionName({ entry, contentDir });
225
+ if (collection === void 0)
226
+ throw new AstroError(AstroErrorData.UnknownContentCollectionError);
227
+ const collectionConfig = contentConfig == null ? void 0 : contentConfig.collections[collection];
228
+ return {
229
+ collectionConfig,
230
+ entry,
231
+ entryConfig,
232
+ collection,
233
+ rawContents
234
+ };
223
235
  }
224
236
  async function getContentConfigFromGlobal() {
225
237
  const observable = globalContentConfigObserver.get();
@@ -249,55 +261,6 @@ async function getContentConfigFromGlobal() {
249
261
  }
250
262
  return contentConfig;
251
263
  }
252
- async function getDataEntryModule({
253
- fileId,
254
- dataEntryExtToParser,
255
- contentPaths,
256
- fs,
257
- pluginContext,
258
- settings
259
- }) {
260
- const contentConfig = await getContentConfigFromGlobal();
261
- let rawContents;
262
- try {
263
- rawContents = await fs.promises.readFile(fileId, "utf-8");
264
- } catch (e) {
265
- throw new AstroError({
266
- ...AstroErrorData.UnknownContentCollectionError,
267
- message: `Unexpected error reading entry ${JSON.stringify(fileId)}.`,
268
- stack: e instanceof Error ? e.stack : void 0
269
- });
270
- }
271
- const fileExt = extname(fileId);
272
- const dataEntryParser = dataEntryExtToParser.get(fileExt);
273
- if (!dataEntryParser) {
274
- throw new AstroError({
275
- ...AstroErrorData.UnknownContentCollectionError,
276
- message: `No parser found for data entry ${JSON.stringify(
277
- fileId
278
- )}. Did you apply an integration for this file type?`
279
- });
280
- }
281
- const { data: unvalidatedData, rawData = "" } = await dataEntryParser({
282
- fileUrl: pathToFileURL(fileId),
283
- contents: rawContents
284
- });
285
- const entry = pathToFileURL(fileId);
286
- const { contentDir } = contentPaths;
287
- const collection = getEntryCollectionName({ entry, contentDir });
288
- if (collection === void 0)
289
- throw new AstroError(AstroErrorData.UnknownContentCollectionError);
290
- const id = getDataEntryId({ entry, contentDir, collection });
291
- const _internal = { filePath: fileId, rawData };
292
- const collectionConfig = contentConfig == null ? void 0 : contentConfig.collections[collection];
293
- const data = collectionConfig ? await getEntryData(
294
- { id, collection, _internal, unvalidatedData },
295
- collectionConfig,
296
- pluginContext,
297
- settings.config
298
- ) : unvalidatedData;
299
- return { id, collection, data, _internal };
300
- }
301
264
  export {
302
265
  astroContentImportPlugin
303
266
  };
@@ -1,8 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  import fsMod from 'node:fs';
3
3
  import type { Plugin } from 'vite';
4
- import type { AstroSettings } from '../@types/astro.js';
5
- import { getContentEntryConfigByExtMap, type ContentPaths } from './utils.js';
4
+ import type { AstroSettings, ContentEntryType } from '../@types/astro.js';
5
+ import { type ContentPaths } from './utils.js';
6
6
  interface AstroContentVirtualModPluginParams {
7
7
  settings: AstroSettings;
8
8
  }
@@ -13,7 +13,7 @@ export declare function astroContentVirtualModPlugin({ settings, }: AstroContent
13
13
  * @see `src/content/virtual-mod.mjs`
14
14
  */
15
15
  export declare function getStringifiedLookupMap({ contentPaths, contentEntryConfigByExt, dataEntryExts, root, fs, }: {
16
- contentEntryConfigByExt: ReturnType<typeof getContentEntryConfigByExtMap>;
16
+ contentEntryConfigByExt: Map<string, ContentEntryType>;
17
17
  dataEntryExts: string[];
18
18
  contentPaths: Pick<ContentPaths, 'contentDir' | 'config'>;
19
19
  root: URL;
@@ -7,12 +7,12 @@ import { AstroError, AstroErrorData } from "../core/errors/index.js";
7
7
  import { rootRelativePath } from "../core/util.js";
8
8
  import { VIRTUAL_MODULE_ID } from "./consts.js";
9
9
  import {
10
- getContentEntryConfigByExtMap,
11
10
  getContentEntryIdAndSlug,
12
11
  getContentPaths,
13
12
  getDataEntryExts,
14
13
  getDataEntryId,
15
14
  getEntryCollectionName,
15
+ getEntryConfigByExtMap,
16
16
  getEntrySlug,
17
17
  getEntryType,
18
18
  getExtGlob
@@ -22,18 +22,27 @@ function astroContentVirtualModPlugin({
22
22
  }) {
23
23
  const contentPaths = getContentPaths(settings.config);
24
24
  const relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir);
25
- const contentEntryConfigByExt = getContentEntryConfigByExtMap(settings);
25
+ const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
26
26
  const contentEntryExts = [...contentEntryConfigByExt.keys()];
27
27
  const dataEntryExts = getDataEntryExts(settings);
28
28
  const virtualModContents = fsMod.readFileSync(contentPaths.virtualModTemplate, "utf-8").replace(
29
29
  "@@COLLECTION_NAME_BY_REFERENCE_KEY@@",
30
30
  new URL("reference-map.json", contentPaths.cacheDir).pathname
31
- ).replace("@@CONTENT_DIR@@", relContentDir).replace("@@CONTENT_ENTRY_GLOB_PATH@@", `${relContentDir}**/*${getExtGlob(contentEntryExts)}`).replace("@@DATA_ENTRY_GLOB_PATH@@", `${relContentDir}**/*${getExtGlob(dataEntryExts)}`).replace(
32
- "@@RENDER_ENTRY_GLOB_PATH@@",
33
- `${relContentDir}**/*${getExtGlob(
34
- /** Note: data collections excluded */
35
- contentEntryExts
36
- )}`
31
+ ).replace("@@CONTENT_DIR@@", relContentDir).replace(
32
+ "'@@CONTENT_ENTRY_GLOB_PATH@@'",
33
+ JSON.stringify(globWithUnderscoresIgnored(relContentDir, contentEntryExts))
34
+ ).replace(
35
+ "'@@DATA_ENTRY_GLOB_PATH@@'",
36
+ JSON.stringify(globWithUnderscoresIgnored(relContentDir, dataEntryExts))
37
+ ).replace(
38
+ "'@@RENDER_ENTRY_GLOB_PATH@@'",
39
+ JSON.stringify(
40
+ globWithUnderscoresIgnored(
41
+ relContentDir,
42
+ /** Note: data collections excluded */
43
+ contentEntryExts
44
+ )
45
+ )
37
46
  );
38
47
  const astroContentVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
39
48
  return {
@@ -146,6 +155,10 @@ const UnexpectedLookupMapError = new AstroError({
146
155
  ...AstroErrorData.UnknownContentCollectionError,
147
156
  message: `Unexpected error while parsing content entry IDs and slugs.`
148
157
  });
158
+ function globWithUnderscoresIgnored(relContentDir, exts) {
159
+ const extGlob = getExtGlob(exts);
160
+ return [`${relContentDir}/**/*${extGlob}`, `!**/_*/**${extGlob}`, `!**/_*${extGlob}`];
161
+ }
149
162
  export {
150
163
  astroContentVirtualModPlugin,
151
164
  getStringifiedLookupMap
@@ -1,8 +1,6 @@
1
1
  import type { RouteData } from '../../@types/astro';
2
2
  import type { SSRManifest as Manifest } from './types';
3
3
  export { deserializeManifest } from './common.js';
4
- export declare const pagesVirtualModuleId = "@astrojs-pages-virtual-entry";
5
- export declare const resolvedPagesVirtualModuleId: string;
6
4
  export interface MatchOptions {
7
5
  matchNotFound?: boolean | undefined;
8
6
  }
@@ -19,8 +19,6 @@ import {
19
19
  import { matchRoute } from "../routing/match.js";
20
20
  import { deserializeManifest } from "./common.js";
21
21
  const clientLocalsSymbol = Symbol.for("astro.locals");
22
- const pagesVirtualModuleId = "@astrojs-pages-virtual-entry";
23
- const resolvedPagesVirtualModuleId = "\0" + pagesVirtualModuleId;
24
22
  const responseSentSymbol = Symbol.for("astro.responseSent");
25
23
  class App {
26
24
  #env;
@@ -115,13 +113,15 @@ class App {
115
113
  if (routeData.route === "/404") {
116
114
  defaultStatus = 404;
117
115
  }
118
- let mod = await this.#manifest.pageMap.get(routeData.component)();
116
+ let page = await this.#manifest.pageMap.get(routeData.component)();
117
+ let mod = await page.page();
119
118
  if (routeData.type === "page") {
120
119
  let response = await this.#renderPage(request, routeData, mod, defaultStatus);
121
120
  if (response.status === 500 || response.status === 404) {
122
121
  const errorPageData = matchRoute("/" + response.status, this.#manifestData);
123
122
  if (errorPageData && errorPageData.route !== routeData.route) {
124
- mod = await this.#manifest.pageMap.get(errorPageData.component)();
123
+ page = await this.#manifest.pageMap.get(errorPageData.component)();
124
+ mod = await page.page();
125
125
  try {
126
126
  let errorResponse = await this.#renderPage(
127
127
  request,
@@ -265,7 +265,5 @@ class App {
265
265
  }
266
266
  export {
267
267
  App,
268
- deserializeManifest,
269
- pagesVirtualModuleId,
270
- resolvedPagesVirtualModuleId
268
+ deserializeManifest
271
269
  };
@@ -7,11 +7,12 @@ const clientAddressSymbol = Symbol.for("astro.clientAddress");
7
7
  function createRequestFromNodeRequest(req, body) {
8
8
  var _a;
9
9
  const protocol = req.socket instanceof TLSSocket || req.headers["x-forwarded-proto"] === "https" ? "https" : "http";
10
- let url = `${protocol}://${req.headers.host}${req.url}`;
11
- let rawHeaders = req.headers;
10
+ const hostname = req.headers.host || req.headers[":authority"];
11
+ const url = `${protocol}://${hostname}${req.url}`;
12
+ const rawHeaders = req.headers;
12
13
  const entries = Object.entries(rawHeaders);
13
14
  const method = req.method || "GET";
14
- let request = new Request(url, {
15
+ const request = new Request(url, {
15
16
  method,
16
17
  headers: new Headers(entries),
17
18
  body: ["HEAD", "GET"].includes(method) ? null : body
@@ -1,5 +1,6 @@
1
1
  import type { MarkdownRenderingOptions } from '@astrojs/markdown-remark';
2
- import type { AstroMiddlewareInstance, ComponentInstance, RouteData, SerializedRouteData, SSRComponentMetadata, SSRLoadedRenderer, SSRResult } from '../../@types/astro';
2
+ import type { AstroMiddlewareInstance, RouteData, SerializedRouteData, SSRComponentMetadata, SSRLoadedRenderer, SSRResult } from '../../@types/astro';
3
+ import type { SinglePageBuiltModule } from '../build/types';
3
4
  export type ComponentPath = string;
4
5
  export type StylesheetAsset = {
5
6
  type: 'inline';
@@ -24,7 +25,7 @@ export interface RouteInfo {
24
25
  export type SerializedRouteInfo = Omit<RouteInfo, 'routeData'> & {
25
26
  routeData: SerializedRouteData;
26
27
  };
27
- type ImportComponentInstance = () => Promise<ComponentInstance>;
28
+ type ImportComponentInstance = () => Promise<SinglePageBuiltModule>;
28
29
  export interface SSRManifest {
29
30
  adapterName: string;
30
31
  routes: RouteInfo[];
@@ -6,7 +6,10 @@ import {
6
6
  generateImage as generateImageInternal,
7
7
  getStaticImageList
8
8
  } from "../../assets/generate.js";
9
- import { hasPrerenderedPages } from "../../core/build/internal.js";
9
+ import {
10
+ eachPageDataFromEntryPoint,
11
+ hasPrerenderedPages
12
+ } from "../../core/build/internal.js";
10
13
  import {
11
14
  prependForwardSlash,
12
15
  removeLeadingForwardSlash,
@@ -30,7 +33,7 @@ import { createRequest } from "../request.js";
30
33
  import { matchRoute } from "../routing/match.js";
31
34
  import { getOutputFilename } from "../util.js";
32
35
  import { getOutDirWithinCwd, getOutFile, getOutFolder } from "./common.js";
33
- import { cssOrder, eachPageData, getPageDataByComponent, mergeInlineCss } from "./internal.js";
36
+ import { cssOrder, getPageDataByComponent, mergeInlineCss } from "./internal.js";
34
37
  import { getTimeStat } from "./util.js";
35
38
  function shouldSkipDraft(pageModule, settings) {
36
39
  var _a;
@@ -66,17 +69,20 @@ async function generatePages(opts, internals) {
66
69
  const verb = ssr ? "prerendering" : "generating";
67
70
  info(opts.logging, null, `
68
71
  ${bgGreen(black(` ${verb} static routes `))}`);
69
- const ssrEntryURL = new URL("./" + serverEntry + `?time=${Date.now()}`, outFolder);
70
- const ssrEntry = await import(ssrEntryURL.toString());
71
72
  const builtPaths = /* @__PURE__ */ new Set();
72
73
  if (ssr) {
73
- for (const pageData of eachPageData(internals)) {
74
- if (pageData.route.prerender)
75
- await generatePage(opts, internals, pageData, ssrEntry, builtPaths);
74
+ for (const [pageData, filePath] of eachPageDataFromEntryPoint(internals)) {
75
+ if (pageData.route.prerender) {
76
+ const ssrEntryURLPage = new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
77
+ const ssrEntryPage = await import(ssrEntryURLPage.toString());
78
+ await generatePage(opts, internals, pageData, ssrEntryPage, builtPaths);
79
+ }
76
80
  }
77
81
  } else {
78
- for (const pageData of eachPageData(internals)) {
79
- await generatePage(opts, internals, pageData, ssrEntry, builtPaths);
82
+ for (const [pageData, filePath] of eachPageDataFromEntryPoint(internals)) {
83
+ const ssrEntryURLPage = new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
84
+ const ssrEntryPage = await import(ssrEntryURLPage.toString());
85
+ await generatePage(opts, internals, pageData, ssrEntryPage, builtPaths);
80
86
  }
81
87
  }
82
88
  if (opts.settings.config.experimental.assets) {
@@ -108,14 +114,13 @@ async function generateImage(opts, transform, path) {
108
114
  info(opts.logging, null, ` ${green("\u25B6")} ${path} ${dim(statsText)} ${dim(timeIncrease)}`);
109
115
  }
110
116
  async function generatePage(opts, internals, pageData, ssrEntry, builtPaths) {
111
- var _a;
112
117
  let timeStart = performance.now();
113
118
  const renderers = ssrEntry.renderers;
114
119
  const pageInfo = getPageDataByComponent(internals, pageData.route.component);
115
120
  const linkIds = [];
116
121
  const scripts = (pageInfo == null ? void 0 : pageInfo.hoistedScript) ?? null;
117
122
  const styles = pageData.styles.sort(cssOrder).map(({ sheet }) => sheet).reduce(mergeInlineCss, []);
118
- const pageModulePromise = (_a = ssrEntry.pageMap) == null ? void 0 : _a.get(pageData.component);
123
+ const pageModulePromise = ssrEntry.page;
119
124
  const middleware = ssrEntry.middleware;
120
125
  if (!pageModulePromise) {
121
126
  throw new Error(
@@ -1,4 +1,4 @@
1
- import { resolvedPagesVirtualModuleId } from "../app/index.js";
1
+ import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
2
2
  function* walkParentInfos(id, ctx, until, depth = 0, order = 0, seen = /* @__PURE__ */ new Set(), childId = "") {
3
3
  seen.add(id);
4
4
  const info = ctx.getModuleInfo(id);
@@ -25,7 +25,8 @@ function* walkParentInfos(id, ctx, until, depth = 0, order = 0, seen = /* @__PUR
25
25
  }
26
26
  }
27
27
  function moduleIsTopLevelPage(info) {
28
- return info.importers[0] === resolvedPagesVirtualModuleId || info.dynamicImporters[0] == resolvedPagesVirtualModuleId;
28
+ var _a, _b;
29
+ return ((_a = info.importers[0]) == null ? void 0 : _a.includes(ASTRO_PAGE_RESOLVED_MODULE_ID)) || ((_b = info.dynamicImporters[0]) == null ? void 0 : _b.includes(ASTRO_PAGE_RESOLVED_MODULE_ID));
29
30
  }
30
31
  function* getTopLevelPages(id, ctx) {
31
32
  for (const res of walkParentInfos(id, ctx)) {
@@ -1,13 +1,16 @@
1
1
  import type { Rollup } from 'vite';
2
- import type { PageBuildData, StylesheetAsset, ViteID } from './types';
3
2
  import type { SSRResult } from '../../@types/astro';
4
3
  import type { PageOptions } from '../../vite-plugin-astro/types';
4
+ import type { PageBuildData, StylesheetAsset, ViteID } from './types';
5
5
  export interface BuildInternals {
6
6
  /**
7
- * The module ids of all CSS chunks, used to deduplicate CSS assets between
8
- * SSR build and client build in vite-plugin-css.
7
+ * Each CSS module is named with a chunk id derived from the Astro pages they
8
+ * are used in by default. It's easy to crawl this relation in the SSR build as
9
+ * the Astro pages are the entrypoint, but not for the client build as hydratable
10
+ * components are the entrypoint instead. This map is used as a cache from the SSR
11
+ * build so the client can pick up the same information and use the same chunk ids.
9
12
  */
10
- cssChunkModuleIds: Set<string>;
13
+ cssModuleToChunkIdMap: Map<string, string>;
11
14
  hoistedScriptIdToHoistedMap: Map<string, Set<string>>;
12
15
  hoistedScriptIdToPagesMap: Map<string, Set<string>>;
13
16
  entrySpecifierToBundleMap: Map<string, string>;
@@ -76,6 +79,7 @@ export declare function getPageDataByComponent(internals: BuildInternals, compon
76
79
  export declare function getPageDataByViteID(internals: BuildInternals, viteid: ViteID): PageBuildData | undefined;
77
80
  export declare function hasPageDataByViteID(internals: BuildInternals, viteid: ViteID): boolean;
78
81
  export declare function eachPageData(internals: BuildInternals): Generator<PageBuildData, void, undefined>;
82
+ export declare function eachPageDataFromEntryPoint(internals: BuildInternals): Generator<[PageBuildData, string]>;
79
83
  export declare function hasPrerenderedPages(internals: BuildInternals): boolean;
80
84
  interface OrderInfo {
81
85
  depth: number;
@@ -1,10 +1,11 @@
1
1
  import { prependForwardSlash, removeFileExtension } from "../path.js";
2
2
  import { viteID } from "../util.js";
3
+ import { ASTRO_PAGE_EXTENSION_POST_PATTERN, ASTRO_PAGE_MODULE_ID } from "./plugins/plugin-pages.js";
3
4
  function createBuildInternals() {
4
5
  const hoistedScriptIdToHoistedMap = /* @__PURE__ */ new Map();
5
6
  const hoistedScriptIdToPagesMap = /* @__PURE__ */ new Map();
6
7
  return {
7
- cssChunkModuleIds: /* @__PURE__ */ new Set(),
8
+ cssModuleToChunkIdMap: /* @__PURE__ */ new Map(),
8
9
  hoistedScriptIdToHoistedMap,
9
10
  hoistedScriptIdToPagesMap,
10
11
  entrySpecifierToBundleMap: /* @__PURE__ */ new Map(),
@@ -82,6 +83,22 @@ function hasPageDataByViteID(internals, viteid) {
82
83
  function* eachPageData(internals) {
83
84
  yield* internals.pagesByComponent.values();
84
85
  }
86
+ function* eachPageDataFromEntryPoint(internals) {
87
+ for (const [entryPoint, filePath] of internals.entrySpecifierToBundleMap) {
88
+ if (entryPoint.includes(ASTRO_PAGE_MODULE_ID)) {
89
+ const [, pageName] = entryPoint.split(":");
90
+ const pageData = internals.pagesByComponent.get(
91
+ `${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".")}`
92
+ );
93
+ if (!pageData) {
94
+ throw new Error(
95
+ "Build failed. Astro couldn't find the emitted page from " + pageName + " pattern"
96
+ );
97
+ }
98
+ yield [pageData, filePath];
99
+ }
100
+ }
101
+ }
85
102
  function hasPrerenderedPages(internals) {
86
103
  for (const pageData of eachPageData(internals)) {
87
104
  if (pageData.route.prerender) {
@@ -140,6 +157,7 @@ export {
140
157
  createBuildInternals,
141
158
  cssOrder,
142
159
  eachPageData,
160
+ eachPageDataFromEntryPoint,
143
161
  getPageDataByComponent,
144
162
  getPageDataByViteID,
145
163
  getPageDatasByChunk,