astro 4.10.2 → 4.11.0
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.
- package/components/Code.astro +9 -0
- package/dist/@types/astro.d.ts +43 -39
- package/dist/actions/runtime/virtual/server.d.ts +1 -1
- package/dist/assets/internal.d.ts +1 -1
- package/dist/assets/internal.js +6 -0
- package/dist/assets/types.d.ts +8 -2
- package/dist/assets/types.js +7 -0
- package/dist/container/index.d.ts +32 -1
- package/dist/container/index.js +45 -0
- package/dist/container/pipeline.d.ts +0 -1
- package/dist/container/pipeline.js +13 -32
- package/dist/container/vite-plugin-container.d.ts +2 -0
- package/dist/container/vite-plugin-container.js +15 -0
- package/dist/content/runtime-assets.d.ts +3 -3
- package/dist/content/types-generator.js +55 -34
- package/dist/content/utils.d.ts +11 -0
- package/dist/content/utils.js +49 -0
- package/dist/content/vite-plugin-content-imports.d.ts +3 -1
- package/dist/content/vite-plugin-content-imports.js +15 -4
- package/dist/core/app/index.d.ts +4 -0
- package/dist/core/app/index.js +17 -6
- package/dist/core/app/pipeline.d.ts +1 -2
- package/dist/core/app/pipeline.js +11 -39
- package/dist/core/base-pipeline.d.ts +0 -9
- package/dist/core/base-pipeline.js +1 -1
- package/dist/core/build/internal.d.ts +4 -0
- package/dist/core/build/internal.js +2 -1
- package/dist/core/build/page-data.js +2 -4
- package/dist/core/build/pipeline.d.ts +1 -2
- package/dist/core/build/pipeline.js +16 -42
- package/dist/core/build/plugins/plugin-chunks.js +6 -0
- package/dist/core/build/plugins/plugin-prerender.js +55 -48
- package/dist/core/build/plugins/plugin-ssr.js +15 -12
- package/dist/core/build/static-build.js +36 -44
- package/dist/core/build/types.d.ts +0 -1
- package/dist/core/config/schema.d.ts +4 -156
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/constants.js +3 -1
- package/dist/core/cookies/cookies.d.ts +5 -0
- package/dist/core/cookies/cookies.js +12 -0
- package/dist/core/cookies/response.d.ts +1 -0
- package/dist/core/cookies/response.js +1 -0
- package/dist/core/create-vite.js +4 -6
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/errors-data.d.ts +40 -11
- package/dist/core/errors/errors-data.js +13 -6
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.d.ts +1 -1
- package/dist/core/render-context.js +22 -6
- package/dist/core/request.js +7 -1
- package/dist/core/routing/astro-designed-error-pages.d.ts +1 -0
- package/dist/core/routing/astro-designed-error-pages.js +15 -1
- package/dist/core/routing/rewrite.d.ts +10 -0
- package/dist/core/routing/rewrite.js +41 -0
- package/dist/core/util.js +5 -2
- package/dist/env/constants.d.ts +0 -1
- package/dist/env/constants.js +0 -2
- package/dist/env/runtime.d.ts +3 -1
- package/dist/env/runtime.js +8 -1
- package/dist/env/schema.d.ts +2 -78
- package/dist/env/schema.js +1 -17
- package/dist/env/vite-plugin-env.js +15 -15
- package/dist/jsx/server.d.ts +3 -5
- package/dist/jsx/server.js +3 -1
- package/dist/vite-plugin-astro/index.js +1 -1
- package/dist/vite-plugin-astro-server/pipeline.d.ts +1 -2
- package/dist/vite-plugin-astro-server/pipeline.js +15 -42
- package/dist/vite-plugin-astro-server/request.js +1 -1
- package/dist/vite-plugin-astro-server/route.js +53 -94
- package/package.json +8 -7
- package/templates/env/module.mjs +14 -5
- package/templates/env/types.d.ts +1 -12
package/dist/content/utils.js
CHANGED
|
@@ -108,6 +108,53 @@ function getEntryConfigByExtMap(entryTypes) {
|
|
|
108
108
|
}
|
|
109
109
|
return map;
|
|
110
110
|
}
|
|
111
|
+
async function getSymlinkedContentCollections({
|
|
112
|
+
contentDir,
|
|
113
|
+
logger,
|
|
114
|
+
fs
|
|
115
|
+
}) {
|
|
116
|
+
const contentPaths = /* @__PURE__ */ new Map();
|
|
117
|
+
const contentDirPath = fileURLToPath(contentDir);
|
|
118
|
+
try {
|
|
119
|
+
if (!fs.existsSync(contentDirPath) || !fs.lstatSync(contentDirPath).isDirectory()) {
|
|
120
|
+
return contentPaths;
|
|
121
|
+
}
|
|
122
|
+
} catch {
|
|
123
|
+
return contentPaths;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const contentDirEntries = await fs.promises.readdir(contentDir, { withFileTypes: true });
|
|
127
|
+
for (const entry of contentDirEntries) {
|
|
128
|
+
if (entry.isSymbolicLink()) {
|
|
129
|
+
const entryPath = path.join(contentDirPath, entry.name);
|
|
130
|
+
const realPath = await fs.promises.realpath(entryPath);
|
|
131
|
+
contentPaths.set(normalizePath(realPath), entry.name);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch (e) {
|
|
135
|
+
logger.warn("content", `Error when reading content directory "${contentDir}"`);
|
|
136
|
+
logger.debug("content", e);
|
|
137
|
+
return /* @__PURE__ */ new Map();
|
|
138
|
+
}
|
|
139
|
+
return contentPaths;
|
|
140
|
+
}
|
|
141
|
+
function reverseSymlink({
|
|
142
|
+
entry,
|
|
143
|
+
symlinks,
|
|
144
|
+
contentDir
|
|
145
|
+
}) {
|
|
146
|
+
const entryPath = normalizePath(typeof entry === "string" ? entry : fileURLToPath(entry));
|
|
147
|
+
const contentDirPath = typeof contentDir === "string" ? contentDir : fileURLToPath(contentDir);
|
|
148
|
+
if (!symlinks || symlinks.size === 0) {
|
|
149
|
+
return entryPath;
|
|
150
|
+
}
|
|
151
|
+
for (const [realPath, symlinkName] of symlinks) {
|
|
152
|
+
if (entryPath.startsWith(realPath)) {
|
|
153
|
+
return normalizePath(path.join(contentDirPath, symlinkName, entryPath.replace(realPath, "")));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return entryPath;
|
|
157
|
+
}
|
|
111
158
|
function getEntryCollectionName({
|
|
112
159
|
contentDir,
|
|
113
160
|
entry
|
|
@@ -354,6 +401,7 @@ export {
|
|
|
354
401
|
getEntrySlug,
|
|
355
402
|
getEntryType,
|
|
356
403
|
getExtGlob,
|
|
404
|
+
getSymlinkedContentCollections,
|
|
357
405
|
globalContentConfigObserver,
|
|
358
406
|
hasAnyContentFlag,
|
|
359
407
|
hasAssetPropagationFlag,
|
|
@@ -363,5 +411,6 @@ export {
|
|
|
363
411
|
msg,
|
|
364
412
|
parseEntrySlug,
|
|
365
413
|
reloadContentConfigObserver,
|
|
414
|
+
reverseSymlink,
|
|
366
415
|
safeParseFrontmatter
|
|
367
416
|
};
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import type fsMod from 'node:fs';
|
|
3
3
|
import type { Plugin } from 'vite';
|
|
4
4
|
import type { AstroSettings } from '../@types/astro.js';
|
|
5
|
-
|
|
5
|
+
import type { Logger } from '../core/logger/core.js';
|
|
6
|
+
export declare function astroContentImportPlugin({ fs, settings, logger, }: {
|
|
6
7
|
fs: typeof fsMod;
|
|
7
8
|
settings: AstroSettings;
|
|
9
|
+
logger: Logger;
|
|
8
10
|
}): Plugin[];
|
|
@@ -16,10 +16,12 @@ import {
|
|
|
16
16
|
getEntryConfigByExtMap,
|
|
17
17
|
getEntryData,
|
|
18
18
|
getEntryType,
|
|
19
|
+
getSymlinkedContentCollections,
|
|
19
20
|
globalContentConfigObserver,
|
|
20
21
|
hasContentFlag,
|
|
21
22
|
parseEntrySlug,
|
|
22
|
-
reloadContentConfigObserver
|
|
23
|
+
reloadContentConfigObserver,
|
|
24
|
+
reverseSymlink
|
|
23
25
|
} from "./utils.js";
|
|
24
26
|
function getContentRendererByViteId(viteId, settings) {
|
|
25
27
|
let ext = viteId.split(".").pop();
|
|
@@ -35,7 +37,8 @@ const CHOKIDAR_MODIFIED_EVENTS = ["add", "unlink", "change"];
|
|
|
35
37
|
const COLLECTION_TYPES_TO_INVALIDATE_ON = ["data", "content", "config"];
|
|
36
38
|
function astroContentImportPlugin({
|
|
37
39
|
fs,
|
|
38
|
-
settings
|
|
40
|
+
settings,
|
|
41
|
+
logger
|
|
39
42
|
}) {
|
|
40
43
|
const contentPaths = getContentPaths(settings.config, fs);
|
|
41
44
|
const contentEntryExts = getContentEntryExts(settings);
|
|
@@ -44,15 +47,23 @@ function astroContentImportPlugin({
|
|
|
44
47
|
const dataEntryConfigByExt = getEntryConfigByExtMap(settings.dataEntryTypes);
|
|
45
48
|
const { contentDir } = contentPaths;
|
|
46
49
|
let shouldEmitFile = false;
|
|
50
|
+
let symlinks;
|
|
47
51
|
const plugins = [
|
|
48
52
|
{
|
|
49
53
|
name: "astro:content-imports",
|
|
50
54
|
config(_config, env) {
|
|
51
55
|
shouldEmitFile = env.command === "build";
|
|
52
56
|
},
|
|
57
|
+
async buildStart() {
|
|
58
|
+
symlinks = await getSymlinkedContentCollections({ contentDir, logger, fs });
|
|
59
|
+
},
|
|
53
60
|
async transform(_, viteId) {
|
|
54
61
|
if (hasContentFlag(viteId, DATA_FLAG)) {
|
|
55
|
-
const fileId =
|
|
62
|
+
const fileId = reverseSymlink({
|
|
63
|
+
entry: viteId.split("?")[0] ?? viteId,
|
|
64
|
+
contentDir,
|
|
65
|
+
symlinks
|
|
66
|
+
});
|
|
56
67
|
const { id, data, collection, _internal } = await getDataEntryModule({
|
|
57
68
|
fileId,
|
|
58
69
|
entryConfigByExt: dataEntryConfigByExt,
|
|
@@ -74,7 +85,7 @@ export const _internal = {
|
|
|
74
85
|
`;
|
|
75
86
|
return code;
|
|
76
87
|
} else if (hasContentFlag(viteId, CONTENT_FLAG)) {
|
|
77
|
-
const fileId = viteId.split("?")[0];
|
|
88
|
+
const fileId = reverseSymlink({ entry: viteId.split("?")[0], contentDir, symlinks });
|
|
78
89
|
const { id, slug, collection, body, data, _internal } = await getContentEntryModule({
|
|
79
90
|
fileId,
|
|
80
91
|
entryConfigByExt: contentEntryConfigByExt,
|
package/dist/core/app/index.d.ts
CHANGED
|
@@ -39,6 +39,10 @@ export interface RenderErrorOptions {
|
|
|
39
39
|
* Whether to skip middleware while rendering the error page. Defaults to false.
|
|
40
40
|
*/
|
|
41
41
|
skipMiddleware?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Allows passing an error to 500.astro. It will be available through `Astro.props.error`.
|
|
44
|
+
*/
|
|
45
|
+
error?: unknown;
|
|
42
46
|
}
|
|
43
47
|
export declare class App {
|
|
44
48
|
#private;
|
package/dist/core/app/index.js
CHANGED
|
@@ -195,8 +195,9 @@ class App {
|
|
|
195
195
|
}
|
|
196
196
|
if (locals) {
|
|
197
197
|
if (typeof locals !== "object") {
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
const error = new AstroError(AstroErrorData.LocalsNotAnObject);
|
|
199
|
+
this.#logger.error(null, error.stack);
|
|
200
|
+
return this.#renderError(request, { status: 500, error });
|
|
200
201
|
}
|
|
201
202
|
Reflect.set(request, clientLocalsSymbol, locals);
|
|
202
203
|
}
|
|
@@ -229,13 +230,16 @@ class App {
|
|
|
229
230
|
response = await renderContext.render(await mod.page());
|
|
230
231
|
} catch (err) {
|
|
231
232
|
this.#logger.error(null, err.stack || err.message || String(err));
|
|
232
|
-
return this.#renderError(request, { locals, status: 500 });
|
|
233
|
+
return this.#renderError(request, { locals, status: 500, error: err });
|
|
233
234
|
}
|
|
234
235
|
if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
|
|
235
236
|
return this.#renderError(request, {
|
|
236
237
|
locals,
|
|
237
238
|
response,
|
|
238
|
-
status: response.status
|
|
239
|
+
status: response.status,
|
|
240
|
+
// We don't have an error to report here. Passing null means we pass nothing intentionally
|
|
241
|
+
// while undefined means there's no error
|
|
242
|
+
error: response.status === 500 ? null : void 0
|
|
239
243
|
});
|
|
240
244
|
}
|
|
241
245
|
if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
|
|
@@ -276,7 +280,13 @@ class App {
|
|
|
276
280
|
* If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro).
|
|
277
281
|
* This also handles pre-rendered /404 or /500 routes
|
|
278
282
|
*/
|
|
279
|
-
async #renderError(request, {
|
|
283
|
+
async #renderError(request, {
|
|
284
|
+
locals,
|
|
285
|
+
status,
|
|
286
|
+
response: originalResponse,
|
|
287
|
+
skipMiddleware = false,
|
|
288
|
+
error
|
|
289
|
+
}) {
|
|
280
290
|
const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`;
|
|
281
291
|
const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
|
|
282
292
|
const url = new URL(request.url);
|
|
@@ -300,7 +310,8 @@ class App {
|
|
|
300
310
|
pathname: this.#getPathnameFromRequest(request),
|
|
301
311
|
request,
|
|
302
312
|
routeData: errorRouteData,
|
|
303
|
-
status
|
|
313
|
+
status,
|
|
314
|
+
props: { error }
|
|
304
315
|
});
|
|
305
316
|
const response2 = await renderContext.render(await mod.page());
|
|
306
317
|
return this.#mergeResponses(response2, originalResponse);
|
|
@@ -7,7 +7,6 @@ export declare class AppPipeline extends Pipeline {
|
|
|
7
7
|
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'>;
|
|
8
8
|
componentMetadata(): void;
|
|
9
9
|
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
|
10
|
-
tryRewrite(payload: RewritePayload, request: Request,
|
|
10
|
+
tryRewrite(payload: RewritePayload, request: Request, _sourceRoute: RouteData): Promise<[RouteData, ComponentInstance, URL]>;
|
|
11
11
|
getModuleForRoute(route: RouteData): Promise<SinglePageBuiltModule>;
|
|
12
|
-
rewriteKnownRoute(pathname: string, _sourceRoute: RouteData): ComponentInstance;
|
|
13
12
|
}
|
|
@@ -5,6 +5,7 @@ import { AstroError } from "../errors/index.js";
|
|
|
5
5
|
import { RedirectSinglePageBuiltModule } from "../redirects/component.js";
|
|
6
6
|
import { createModuleScriptElement, createStylesheetElementSet } from "../render/ssr-element.js";
|
|
7
7
|
import { DEFAULT_404_ROUTE } from "../routing/astro-designed-error-pages.js";
|
|
8
|
+
import { findRouteToRewrite } from "../routing/rewrite.js";
|
|
8
9
|
class AppPipeline extends Pipeline {
|
|
9
10
|
#manifestData;
|
|
10
11
|
static create(manifestData, {
|
|
@@ -62,38 +63,17 @@ class AppPipeline extends Pipeline {
|
|
|
62
63
|
const module = await this.getModuleForRoute(routeData);
|
|
63
64
|
return module.page();
|
|
64
65
|
}
|
|
65
|
-
async tryRewrite(payload, request,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} else {
|
|
74
|
-
finalUrl = new URL(payload, new URL(request.url).origin);
|
|
75
|
-
}
|
|
76
|
-
if (route.pattern.test(decodeURI(finalUrl.pathname))) {
|
|
77
|
-
foundRoute = route;
|
|
78
|
-
break;
|
|
79
|
-
} else if (finalUrl.pathname === "/404") {
|
|
80
|
-
foundRoute = DEFAULT_404_ROUTE;
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (foundRoute && finalUrl) {
|
|
85
|
-
if (foundRoute.pathname === "/404") {
|
|
86
|
-
const componentInstance = this.rewriteKnownRoute(foundRoute.pathname, sourceRoute);
|
|
87
|
-
return [foundRoute, componentInstance, finalUrl];
|
|
88
|
-
} else {
|
|
89
|
-
const componentInstance = await this.getComponentByRoute(foundRoute);
|
|
90
|
-
return [foundRoute, componentInstance, finalUrl];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
throw new AstroError({
|
|
94
|
-
...RewriteEncounteredAnError,
|
|
95
|
-
message: RewriteEncounteredAnError.message(payload.toString())
|
|
66
|
+
async tryRewrite(payload, request, _sourceRoute) {
|
|
67
|
+
const [foundRoute, finalUrl] = findRouteToRewrite({
|
|
68
|
+
payload,
|
|
69
|
+
request,
|
|
70
|
+
routes: this.manifest?.routes.map((r) => r.routeData),
|
|
71
|
+
trailingSlash: this.manifest.trailingSlash,
|
|
72
|
+
buildFormat: this.manifest.buildFormat,
|
|
73
|
+
base: this.manifest.base
|
|
96
74
|
});
|
|
75
|
+
const componentInstance = await this.getComponentByRoute(foundRoute);
|
|
76
|
+
return [foundRoute, componentInstance, finalUrl];
|
|
97
77
|
}
|
|
98
78
|
async getModuleForRoute(route) {
|
|
99
79
|
if (route.component === DEFAULT_404_COMPONENT) {
|
|
@@ -121,14 +101,6 @@ class AppPipeline extends Pipeline {
|
|
|
121
101
|
);
|
|
122
102
|
}
|
|
123
103
|
}
|
|
124
|
-
// We don't need to check the source route, we already are in SSR
|
|
125
|
-
rewriteKnownRoute(pathname, _sourceRoute) {
|
|
126
|
-
if (pathname === "/404") {
|
|
127
|
-
return { default: () => new Response(null, { status: 404 }) };
|
|
128
|
-
} else {
|
|
129
|
-
return { default: () => new Response(null, { status: 500 }) };
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
104
|
}
|
|
133
105
|
export {
|
|
134
106
|
AppPipeline
|
|
@@ -73,15 +73,6 @@ export declare abstract class Pipeline {
|
|
|
73
73
|
* @param routeData
|
|
74
74
|
*/
|
|
75
75
|
abstract getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
|
76
|
-
/**
|
|
77
|
-
* Attempts to execute a rewrite of a known Astro route:
|
|
78
|
-
* - /404 -> src/pages/404.astro -> template
|
|
79
|
-
* - /500 -> src/pages/500.astro
|
|
80
|
-
*
|
|
81
|
-
* @param pathname The pathname where the user wants to rewrite e.g. "/404"
|
|
82
|
-
* @param sourceRoute The original route where the first request started. This is needed in case a pipeline wants to check if the current route is pre-rendered or not
|
|
83
|
-
*/
|
|
84
|
-
abstract rewriteKnownRoute(pathname: string, sourceRoute: RouteData): ComponentInstance;
|
|
85
76
|
}
|
|
86
77
|
export interface HeadElements extends Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
|
87
78
|
}
|
|
@@ -89,6 +89,10 @@ export interface BuildInternals {
|
|
|
89
89
|
ssrSplitEntryChunks: Map<string, Rollup.OutputChunk>;
|
|
90
90
|
componentMetadata: SSRResult['componentMetadata'];
|
|
91
91
|
middlewareEntryPoint?: URL;
|
|
92
|
+
/**
|
|
93
|
+
* Chunks in the bundle that are only used in prerendering that we can delete later
|
|
94
|
+
*/
|
|
95
|
+
prerenderOnlyChunks: Rollup.OutputChunk[];
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
98
|
* Creates internal maps used to coordinate the CSS and HTML plugins.
|
|
@@ -26,7 +26,8 @@ function createBuildInternals() {
|
|
|
26
26
|
componentMetadata: /* @__PURE__ */ new Map(),
|
|
27
27
|
ssrSplitEntryChunks: /* @__PURE__ */ new Map(),
|
|
28
28
|
entryPoints: /* @__PURE__ */ new Map(),
|
|
29
|
-
cacheManifestUsed: false
|
|
29
|
+
cacheManifestUsed: false,
|
|
30
|
+
prerenderOnlyChunks: []
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
function trackPageData(internals, component, pageData, componentModuleId, componentURL) {
|
|
@@ -29,8 +29,7 @@ async function collectPagesData(opts) {
|
|
|
29
29
|
route,
|
|
30
30
|
moduleSpecifier: "",
|
|
31
31
|
styles: [],
|
|
32
|
-
hoistedScript: void 0
|
|
33
|
-
hasSharedModules: false
|
|
32
|
+
hoistedScript: void 0
|
|
34
33
|
};
|
|
35
34
|
clearInterval(routeCollectionLogTimeout);
|
|
36
35
|
if (settings.config.output === "static") {
|
|
@@ -50,8 +49,7 @@ async function collectPagesData(opts) {
|
|
|
50
49
|
route,
|
|
51
50
|
moduleSpecifier: "",
|
|
52
51
|
styles: [],
|
|
53
|
-
hoistedScript: void 0
|
|
54
|
-
hasSharedModules: false
|
|
52
|
+
hoistedScript: void 0
|
|
55
53
|
};
|
|
56
54
|
}
|
|
57
55
|
clearInterval(dataCollectionLogTimeout);
|
|
@@ -38,7 +38,6 @@ export declare class BuildPipeline extends Pipeline {
|
|
|
38
38
|
*/
|
|
39
39
|
retrieveRoutesToGenerate(): Map<PageBuildData, string>;
|
|
40
40
|
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
|
41
|
-
tryRewrite(payload: RewritePayload, request: Request,
|
|
41
|
+
tryRewrite(payload: RewritePayload, request: Request, _sourceRoute: RouteData): Promise<[RouteData, ComponentInstance, URL]>;
|
|
42
42
|
retrieveSsrEntry(route: RouteData, filePath: string): Promise<SinglePageBuiltModule>;
|
|
43
|
-
rewriteKnownRoute(_pathname: string, sourceRoute: RouteData): ComponentInstance;
|
|
44
43
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { getOutputDirectory } from "../../prerender/utils.js";
|
|
2
2
|
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import { AstroError } from "../errors/index.js";
|
|
3
|
+
import { DEFAULT_404_COMPONENT } from "../constants.js";
|
|
5
4
|
import { routeIsFallback, routeIsRedirect } from "../redirects/helpers.js";
|
|
6
5
|
import { RedirectSinglePageBuiltModule } from "../redirects/index.js";
|
|
7
6
|
import { Pipeline } from "../render/index.js";
|
|
@@ -10,7 +9,8 @@ import {
|
|
|
10
9
|
createModuleScriptsSet,
|
|
11
10
|
createStylesheetElementSet
|
|
12
11
|
} from "../render/ssr-element.js";
|
|
13
|
-
import {
|
|
12
|
+
import { default404Page } from "../routing/astro-designed-error-pages.js";
|
|
13
|
+
import { findRouteToRewrite } from "../routing/rewrite.js";
|
|
14
14
|
import { isServerLikeOutput } from "../util.js";
|
|
15
15
|
import { getOutDirWithinCwd } from "./common.js";
|
|
16
16
|
import { cssOrder, getPageData, mergeInlineCss } from "./internal.js";
|
|
@@ -201,45 +201,25 @@ class BuildPipeline extends Pipeline {
|
|
|
201
201
|
if (this.#componentsInterner.has(routeData)) {
|
|
202
202
|
const entry = this.#componentsInterner.get(routeData);
|
|
203
203
|
return await entry.page();
|
|
204
|
+
} else if (routeData.component === DEFAULT_404_COMPONENT) {
|
|
205
|
+
return { default: default404Page };
|
|
204
206
|
} else {
|
|
205
207
|
const filePath = this.#routesByFilePath.get(routeData);
|
|
206
208
|
const module = await this.retrieveSsrEntry(routeData, filePath);
|
|
207
209
|
return module.page();
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
|
-
async tryRewrite(payload, request,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (route.pattern.test(decodeURI(finalUrl.pathname))) {
|
|
222
|
-
foundRoute = route;
|
|
223
|
-
break;
|
|
224
|
-
} else if (finalUrl.pathname === "/404") {
|
|
225
|
-
foundRoute = DEFAULT_404_ROUTE;
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (foundRoute && finalUrl) {
|
|
230
|
-
if (foundRoute.pathname === "/404") {
|
|
231
|
-
const componentInstance = await this.rewriteKnownRoute(foundRoute.pathname, sourceRoute);
|
|
232
|
-
return [foundRoute, componentInstance, finalUrl];
|
|
233
|
-
} else {
|
|
234
|
-
const componentInstance = await this.getComponentByRoute(foundRoute);
|
|
235
|
-
return [foundRoute, componentInstance, finalUrl];
|
|
236
|
-
}
|
|
237
|
-
} else {
|
|
238
|
-
throw new AstroError({
|
|
239
|
-
...RewriteEncounteredAnError,
|
|
240
|
-
message: RewriteEncounteredAnError.message(payload.toString())
|
|
241
|
-
});
|
|
242
|
-
}
|
|
212
|
+
async tryRewrite(payload, request, _sourceRoute) {
|
|
213
|
+
const [foundRoute, finalUrl] = findRouteToRewrite({
|
|
214
|
+
payload,
|
|
215
|
+
request,
|
|
216
|
+
routes: this.options.manifest.routes,
|
|
217
|
+
trailingSlash: this.config.trailingSlash,
|
|
218
|
+
buildFormat: this.config.build.format,
|
|
219
|
+
base: this.config.base
|
|
220
|
+
});
|
|
221
|
+
const componentInstance = await this.getComponentByRoute(foundRoute);
|
|
222
|
+
return [foundRoute, componentInstance, finalUrl];
|
|
243
223
|
}
|
|
244
224
|
async retrieveSsrEntry(route, filePath) {
|
|
245
225
|
if (this.#componentsInterner.has(route)) {
|
|
@@ -285,12 +265,6 @@ class BuildPipeline extends Pipeline {
|
|
|
285
265
|
}
|
|
286
266
|
return RedirectSinglePageBuiltModule;
|
|
287
267
|
}
|
|
288
|
-
rewriteKnownRoute(_pathname, sourceRoute) {
|
|
289
|
-
if (!isServerLikeOutput(this.config) || sourceRoute.prerender) {
|
|
290
|
-
throw new AstroError(InvalidRewrite404);
|
|
291
|
-
}
|
|
292
|
-
throw new Error(`Unreachable, in SSG this route shouldn't be generated`);
|
|
293
|
-
}
|
|
294
268
|
}
|
|
295
269
|
function createEntryURL(filePath, outFolder) {
|
|
296
270
|
return new URL("./" + filePath + `?time=${Date.now()}`, outFolder);
|
|
@@ -8,6 +8,12 @@ function vitePluginChunks() {
|
|
|
8
8
|
if (id.includes("astro/dist/runtime/server/")) {
|
|
9
9
|
return "astro/server";
|
|
10
10
|
}
|
|
11
|
+
if (id.includes("astro/dist/runtime")) {
|
|
12
|
+
return "astro";
|
|
13
|
+
}
|
|
14
|
+
if (id.includes("astro/dist/env/setup")) {
|
|
15
|
+
return "astro/env-setup";
|
|
16
|
+
}
|
|
11
17
|
}
|
|
12
18
|
});
|
|
13
19
|
}
|
|
@@ -1,57 +1,64 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
1
|
import { getPrerenderMetadata } from "../../../prerender/metadata.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugin-pages.js";
|
|
3
|
+
import { getPagesFromVirtualModulePageName } from "./util.js";
|
|
4
|
+
function vitePluginPrerender(internals) {
|
|
5
5
|
return {
|
|
6
6
|
name: "astro:rollup-plugin-prerender",
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
// a shared modules should be inside the `src/` folder, at least
|
|
22
|
-
moduleMeta.id.startsWith(opts.settings.config.srcDir.pathname) && // and has at least two importers: the current page and something else
|
|
23
|
-
moduleMeta.importers.length > 1
|
|
24
|
-
) {
|
|
25
|
-
for (const importer of moduleMeta.importedIds) {
|
|
26
|
-
if (importer !== id) {
|
|
27
|
-
const importerModuleMeta = meta.getModuleInfo(importer);
|
|
28
|
-
if (importerModuleMeta) {
|
|
29
|
-
if (importerModuleMeta.id.includes("/pages")) {
|
|
30
|
-
if (getPrerenderMetadata(importerModuleMeta) === false) {
|
|
31
|
-
hasSharedModules = true;
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
} else if (importerModuleMeta.id.includes("/middleware")) {
|
|
35
|
-
hasSharedModules = true;
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
pageInfo.hasSharedModules = hasSharedModules;
|
|
44
|
-
pageInfo.route.prerender = true;
|
|
45
|
-
return "prerender";
|
|
46
|
-
}
|
|
47
|
-
pageInfo.route.prerender = false;
|
|
48
|
-
return `pages/${path.basename(pageInfo.component)}`;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
7
|
+
generateBundle(_, bundle) {
|
|
8
|
+
const moduleIds = this.getModuleIds();
|
|
9
|
+
for (const id of moduleIds) {
|
|
10
|
+
const pageInfo = internals.pagesByViteID.get(id);
|
|
11
|
+
if (!pageInfo) continue;
|
|
12
|
+
const moduleInfo = this.getModuleInfo(id);
|
|
13
|
+
if (!moduleInfo) continue;
|
|
14
|
+
const prerender = !!getPrerenderMetadata(moduleInfo);
|
|
15
|
+
pageInfo.route.prerender = prerender;
|
|
16
|
+
}
|
|
17
|
+
const nonPrerenderOnlyChunks = getNonPrerenderOnlyChunks(bundle, internals);
|
|
18
|
+
internals.prerenderOnlyChunks = Object.values(bundle).filter((chunk) => {
|
|
19
|
+
return chunk.type === "chunk" && !nonPrerenderOnlyChunks.has(chunk);
|
|
51
20
|
});
|
|
52
21
|
}
|
|
53
22
|
};
|
|
54
23
|
}
|
|
24
|
+
function getNonPrerenderOnlyChunks(bundle, internals) {
|
|
25
|
+
const chunks = Object.values(bundle);
|
|
26
|
+
const prerenderOnlyEntryChunks = /* @__PURE__ */ new Set();
|
|
27
|
+
const nonPrerenderOnlyEntryChunks = /* @__PURE__ */ new Set();
|
|
28
|
+
for (const chunk of chunks) {
|
|
29
|
+
if (chunk.type === "chunk" && (chunk.isEntry || chunk.isDynamicEntry)) {
|
|
30
|
+
if (chunk.facadeModuleId?.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
|
|
31
|
+
const pageDatas = getPagesFromVirtualModulePageName(
|
|
32
|
+
internals,
|
|
33
|
+
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
|
34
|
+
chunk.facadeModuleId
|
|
35
|
+
);
|
|
36
|
+
const prerender = pageDatas.every((pageData) => pageData.route.prerender);
|
|
37
|
+
if (prerender) {
|
|
38
|
+
prerenderOnlyEntryChunks.add(chunk);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
nonPrerenderOnlyEntryChunks.add(chunk);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const nonPrerenderOnlyChunks = new Set(nonPrerenderOnlyEntryChunks);
|
|
46
|
+
for (const chunk of nonPrerenderOnlyChunks) {
|
|
47
|
+
for (const importFileName of chunk.imports) {
|
|
48
|
+
const importChunk = bundle[importFileName];
|
|
49
|
+
if (importChunk?.type === "chunk") {
|
|
50
|
+
nonPrerenderOnlyChunks.add(importChunk);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const dynamicImportFileName of chunk.dynamicImports) {
|
|
54
|
+
const dynamicImportChunk = bundle[dynamicImportFileName];
|
|
55
|
+
if (dynamicImportChunk?.type === "chunk" && !prerenderOnlyEntryChunks.has(dynamicImportChunk)) {
|
|
56
|
+
nonPrerenderOnlyChunks.add(dynamicImportChunk);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return nonPrerenderOnlyChunks;
|
|
61
|
+
}
|
|
55
62
|
function pluginPrerender(opts, internals) {
|
|
56
63
|
if (opts.settings.config.output === "static") {
|
|
57
64
|
return { targets: ["server"] };
|
|
@@ -61,7 +68,7 @@ function pluginPrerender(opts, internals) {
|
|
|
61
68
|
hooks: {
|
|
62
69
|
"build:before": () => {
|
|
63
70
|
return {
|
|
64
|
-
vitePlugin: vitePluginPrerender(
|
|
71
|
+
vitePlugin: vitePluginPrerender(internals)
|
|
65
72
|
};
|
|
66
73
|
}
|
|
67
74
|
}
|
|
@@ -16,7 +16,15 @@ function vitePluginSSR(internals, adapter, options) {
|
|
|
16
16
|
name: "@astrojs/vite-plugin-astro-ssr-server",
|
|
17
17
|
enforce: "post",
|
|
18
18
|
options(opts) {
|
|
19
|
-
|
|
19
|
+
const inputs = /* @__PURE__ */ new Set();
|
|
20
|
+
for (const pageData of Object.values(options.allPages)) {
|
|
21
|
+
if (routeIsRedirect(pageData.route)) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
inputs.add(getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component));
|
|
25
|
+
}
|
|
26
|
+
inputs.add(SSR_VIRTUAL_MODULE_ID);
|
|
27
|
+
return addRollupInput(opts, Array.from(inputs));
|
|
20
28
|
},
|
|
21
29
|
resolveId(id) {
|
|
22
30
|
if (id === SSR_VIRTUAL_MODULE_ID) {
|
|
@@ -60,7 +68,6 @@ function vitePluginSSR(internals, adapter, options) {
|
|
|
60
68
|
contents.push(...ssrCode.contents);
|
|
61
69
|
return [...imports, ...contents, ...exports].join("\n");
|
|
62
70
|
}
|
|
63
|
-
return void 0;
|
|
64
71
|
},
|
|
65
72
|
async generateBundle(_opts, bundle) {
|
|
66
73
|
for (const [, chunk] of Object.entries(bundle)) {
|
|
@@ -110,21 +117,18 @@ function pluginSSR(options, internals) {
|
|
|
110
117
|
const SPLIT_MODULE_ID = "@astro-page-split:";
|
|
111
118
|
const RESOLVED_SPLIT_MODULE_ID = "\0@astro-page-split:";
|
|
112
119
|
function vitePluginSSRSplit(internals, adapter, options) {
|
|
113
|
-
const functionPerRouteEnabled = isFunctionPerRouteEnabled(options.settings.adapter);
|
|
114
120
|
return {
|
|
115
121
|
name: "@astrojs/vite-plugin-astro-ssr-split",
|
|
116
122
|
enforce: "post",
|
|
117
123
|
options(opts) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
inputs.add(getVirtualModulePageName(SPLIT_MODULE_ID, pageData.component));
|
|
124
|
+
const inputs = /* @__PURE__ */ new Set();
|
|
125
|
+
for (const pageData of Object.values(options.allPages)) {
|
|
126
|
+
if (routeIsRedirect(pageData.route)) {
|
|
127
|
+
continue;
|
|
125
128
|
}
|
|
126
|
-
|
|
129
|
+
inputs.add(getVirtualModulePageName(SPLIT_MODULE_ID, pageData.component));
|
|
127
130
|
}
|
|
131
|
+
return addRollupInput(opts, Array.from(inputs));
|
|
128
132
|
},
|
|
129
133
|
resolveId(id) {
|
|
130
134
|
if (id.startsWith(SPLIT_MODULE_ID)) {
|
|
@@ -149,7 +153,6 @@ function vitePluginSSRSplit(internals, adapter, options) {
|
|
|
149
153
|
exports.push("export { pageModule }");
|
|
150
154
|
return [...imports, ...contents, ...exports].join("\n");
|
|
151
155
|
}
|
|
152
|
-
return void 0;
|
|
153
156
|
},
|
|
154
157
|
async generateBundle(_opts, bundle) {
|
|
155
158
|
for (const [, chunk] of Object.entries(bundle)) {
|