astro 7.2.2 → 7.2.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.
- package/dist/actions/handler.d.ts +6 -12
- package/dist/actions/handler.js +30 -40
- package/dist/actions/load.d.ts +12 -0
- package/dist/actions/load.js +55 -0
- package/dist/actions/runtime/entrypoints/server.js +5 -4
- package/dist/actions/runtime/server.js +8 -6
- package/dist/assets/fonts/providers/index.d.ts +1 -1
- package/dist/assets/fonts/providers/index.js +2 -12
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/container/environment.d.ts +20 -0
- package/dist/container/environment.js +106 -0
- package/dist/container/index.js +65 -32
- package/dist/content/content-layer.js +3 -3
- package/dist/content/data-store-writer.d.ts +7 -10
- package/dist/content/data-store-writer.js +62 -27
- package/dist/content/data-store.d.ts +20 -3
- package/dist/content/data-store.js +28 -7
- package/dist/content/mutable-data-store.js +15 -10
- package/dist/content/runtime.d.ts +3 -2
- package/dist/content/runtime.js +43 -26
- package/dist/core/app/app.d.ts +0 -2
- package/dist/core/app/app.js +0 -7
- package/dist/core/app/base.d.ts +32 -20
- package/dist/core/app/base.js +76 -66
- package/dist/core/app/dev-facade.d.ts +27 -0
- package/dist/core/app/dev-facade.js +51 -0
- package/dist/core/app/entrypoints/index.d.ts +0 -1
- package/dist/core/app/entrypoints/index.js +0 -2
- package/dist/core/app/entrypoints/virtual/dev.js +24 -19
- package/dist/core/app/node.js +13 -14
- package/dist/core/app/prepare-response.d.ts +1 -1
- package/dist/core/app/validate-headers.js +7 -3
- package/dist/core/build/app.d.ts +31 -6
- package/dist/core/build/app.js +31 -13
- package/dist/core/build/environment.d.ts +25 -0
- package/dist/core/build/environment.js +157 -0
- package/dist/core/cache/handler.d.ts +13 -7
- package/dist/core/cache/handler.js +55 -51
- package/dist/core/cache/provider.d.ts +4 -0
- package/dist/core/cache/provider.js +15 -0
- package/dist/core/constants.d.ts +0 -11
- package/dist/core/constants.js +1 -5
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/environment/dev-nonrunnable.d.ts +6 -0
- package/dist/core/environment/dev-nonrunnable.js +170 -0
- package/dist/core/environment/index.d.ts +90 -0
- package/dist/core/environment/index.js +12 -0
- package/dist/core/environment/production.d.ts +6 -0
- package/dist/core/environment/production.js +117 -0
- package/dist/core/errors/build-handler.d.ts +5 -10
- package/dist/core/errors/build-handler.js +11 -17
- package/dist/core/errors/default-handler.d.ts +4 -9
- package/dist/core/errors/default-handler.js +92 -107
- package/dist/core/errors/dev-handler.d.ts +7 -11
- package/dist/core/errors/dev-handler.js +71 -69
- package/dist/core/errors/errors-data.d.ts +18 -0
- package/dist/core/errors/errors-data.js +7 -0
- package/dist/core/errors/handler.d.ts +22 -3
- package/dist/core/errors/handler.js +25 -0
- package/dist/core/fetch/default-handler.d.ts +15 -8
- package/dist/core/fetch/default-handler.js +12 -34
- package/dist/core/fetch/features.d.ts +23 -0
- package/dist/core/fetch/features.js +27 -0
- package/dist/core/fetch/fetch-state.d.ts +52 -7
- package/dist/core/fetch/fetch-state.js +92 -81
- package/dist/core/fetch/index.d.ts +9 -2
- package/dist/core/fetch/index.js +18 -79
- package/dist/core/fetch/vite-plugin.js +2 -1
- package/dist/core/i18n/handler.d.ts +28 -13
- package/dist/core/i18n/handler.js +100 -100
- package/dist/core/logger/manifest-logger.d.ts +31 -0
- package/dist/core/logger/manifest-logger.js +37 -0
- package/dist/core/manifest/ambient-source.d.ts +2 -0
- package/dist/core/manifest/ambient-source.js +4 -0
- package/dist/core/manifest/ambient.d.ts +16 -0
- package/dist/core/manifest/ambient.js +22 -0
- package/dist/core/manifest/derived.d.ts +3 -0
- package/dist/core/manifest/derived.js +10 -0
- package/dist/core/manifest/memo.d.ts +31 -0
- package/dist/core/manifest/memo.js +47 -0
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/middleware/astro-middleware.d.ts +25 -35
- package/dist/core/middleware/astro-middleware.js +61 -81
- package/dist/core/middleware/load.d.ts +19 -0
- package/dist/core/middleware/load.js +36 -0
- package/dist/core/middleware/sequence.js +15 -7
- package/dist/core/pages/handler.d.ts +18 -25
- package/dist/core/pages/handler.js +68 -84
- package/dist/core/redirects/render.js +3 -8
- package/dist/core/render/index.d.ts +0 -1
- package/dist/core/render/index.js +0 -2
- package/dist/core/render/route-cache.d.ts +6 -1
- package/dist/core/render/route-cache.js +11 -1
- package/dist/core/rewrites/handler.d.ts +4 -6
- package/dist/core/rewrites/handler.js +19 -20
- package/dist/core/routing/default.d.ts +2 -0
- package/dist/core/routing/default.js +7 -1
- package/dist/core/routing/dev.d.ts +1 -3
- package/dist/core/routing/dev.js +12 -5
- package/dist/core/routing/handler.d.ts +6 -16
- package/dist/core/routing/handler.js +126 -164
- package/dist/core/routing/helpers.d.ts +7 -1
- package/dist/core/routing/helpers.js +21 -0
- package/dist/core/routing/match-request.d.ts +10 -0
- package/dist/core/routing/match-request.js +57 -0
- package/dist/core/routing/route-table.d.ts +34 -0
- package/dist/core/routing/route-table.js +41 -0
- package/dist/core/routing/trailing-slash-handler.d.ts +4 -14
- package/dist/core/routing/trailing-slash-handler.js +39 -50
- package/dist/core/server-islands/mappings.d.ts +6 -0
- package/dist/core/server-islands/mappings.js +12 -0
- package/dist/core/session/driver.d.ts +4 -0
- package/dist/core/session/driver.js +14 -0
- package/dist/core/session/handler.d.ts +1 -1
- package/dist/core/session/handler.js +8 -8
- package/dist/core/session/provider-disabled.js +2 -2
- package/dist/entrypoints/prerender.js +5 -1
- package/dist/i18n/middleware.d.ts +4 -4
- package/dist/i18n/middleware.js +3 -3
- package/dist/manifest/serialized.d.ts +1 -0
- package/dist/manifest/serialized.js +9 -2
- package/dist/runtime/prerender/static-paths.d.ts +14 -2
- package/dist/runtime/prerender/static-paths.js +4 -3
- package/dist/types/public/config.d.ts +433 -241
- package/dist/vite-plugin-app/createAstroServerApp.js +22 -18
- package/dist/vite-plugin-app/environment.d.ts +18 -0
- package/dist/vite-plugin-app/environment.js +210 -0
- package/dist/vite-plugin-app/handle-request.d.ts +30 -0
- package/dist/vite-plugin-app/handle-request.js +129 -0
- package/dist/vite-plugin-app/index.d.ts +1 -1
- package/dist/vite-plugin-app/index.js +1 -1
- package/package.json +14 -7
- package/src/core/README.md +37 -0
- package/src/core/manifest/ambient-source.ts +9 -0
- package/src/types/README.md +5 -0
- package/dist/container/pipeline.d.ts +0 -14
- package/dist/container/pipeline.js +0 -78
- package/dist/core/app/dev/app.d.ts +0 -31
- package/dist/core/app/dev/app.js +0 -80
- package/dist/core/app/dev/pipeline.d.ts +0 -17
- package/dist/core/app/dev/pipeline.js +0 -133
- package/dist/core/app/pipeline.d.ts +0 -14
- package/dist/core/app/pipeline.js +0 -123
- package/dist/core/base-pipeline.d.ts +0 -183
- package/dist/core/base-pipeline.js +0 -293
- package/dist/core/build/pipeline.d.ts +0 -38
- package/dist/core/build/pipeline.js +0 -202
- package/dist/vite-plugin-app/app.d.ts +0 -62
- package/dist/vite-plugin-app/app.js +0 -237
- package/dist/vite-plugin-app/pipeline.d.ts +0 -25
- package/dist/vite-plugin-app/pipeline.js +0 -189
package/dist/core/app/base.js
CHANGED
|
@@ -5,23 +5,30 @@ import {
|
|
|
5
5
|
} from "@astrojs/internal-helpers/path";
|
|
6
6
|
import { matchPattern } from "@astrojs/internal-helpers/remote";
|
|
7
7
|
import { computePathnameFromDomain } from "../i18n/domain.js";
|
|
8
|
-
import { isLocalizedErrorRoute } from "../../i18n/error-routes.js";
|
|
9
|
-
import { PipelineFeatures } from "../base-pipeline.js";
|
|
10
8
|
import { ASTRO_ERROR_HEADER, clientAddressSymbol } from "../constants.js";
|
|
11
9
|
import { getSetCookiesFromResponse } from "../cookies/index.js";
|
|
12
10
|
import { AstroError, AstroErrorData } from "../errors/index.js";
|
|
13
11
|
import { AstroIntegrationLogger } from "../logger/core.js";
|
|
14
12
|
import { DefaultFetchHandler } from "../fetch/default-handler.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
13
|
+
import { getUsedFeatures, FetchFeatures } from "../fetch/features.js";
|
|
14
|
+
import { FetchState } from "../fetch/fetch-state.js";
|
|
15
|
+
import { renderErrorPage } from "../errors/handler.js";
|
|
16
|
+
import { getLogger, getResolvedLogger } from "../logger/manifest-logger.js";
|
|
17
|
+
import { handleRequest } from "../routing/handler.js";
|
|
18
|
+
import { getDefaultStatusCode } from "../routing/helpers.js";
|
|
19
|
+
import { matchRequest } from "../routing/match-request.js";
|
|
20
|
+
import { getRouteTable, matchRoute, updateRouteTable } from "../routing/route-table.js";
|
|
18
21
|
import { setRenderOptions } from "./render-options.js";
|
|
19
22
|
class BaseApp {
|
|
20
23
|
manifest;
|
|
21
|
-
manifestData;
|
|
22
|
-
pipeline;
|
|
23
24
|
#adapterLogger;
|
|
24
25
|
baseWithoutTrailingSlash;
|
|
26
|
+
/**
|
|
27
|
+
* The streaming flag passed to the constructor, surfaced through the
|
|
28
|
+
* protected `resolveStreaming()` hook and fed into the internal
|
|
29
|
+
* `FetchState` facade hooks on the fast path.
|
|
30
|
+
*/
|
|
31
|
+
#streaming;
|
|
25
32
|
/**
|
|
26
33
|
* The handler that turns incoming `Request` objects into `Response`s.
|
|
27
34
|
* Defaults to a `DefaultFetchHandler` pinned to this app and can be
|
|
@@ -42,7 +49,18 @@ class BaseApp {
|
|
|
42
49
|
*/
|
|
43
50
|
#featureCheckDone = false;
|
|
44
51
|
get logger() {
|
|
45
|
-
return this.
|
|
52
|
+
return getLogger(this.manifest);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Route data derived from the manifest, used for route matching. Reads and
|
|
56
|
+
* writes go through the single per-manifest route table, so HMR updates are
|
|
57
|
+
* visible to every consumer at once.
|
|
58
|
+
*/
|
|
59
|
+
get manifestData() {
|
|
60
|
+
return getRouteTable(this.manifest);
|
|
61
|
+
}
|
|
62
|
+
set manifestData(routesList) {
|
|
63
|
+
updateRouteTable(this.manifest, routesList.routes);
|
|
46
64
|
}
|
|
47
65
|
get adapterLogger() {
|
|
48
66
|
const currentOptions = this.logger.options;
|
|
@@ -51,14 +69,33 @@ class BaseApp {
|
|
|
51
69
|
}
|
|
52
70
|
return this.#adapterLogger;
|
|
53
71
|
}
|
|
54
|
-
constructor(manifest, streaming = true
|
|
72
|
+
constructor(manifest, streaming = true) {
|
|
55
73
|
this.manifest = manifest;
|
|
56
74
|
this.baseWithoutTrailingSlash = removeTrailingForwardSlash(manifest.base);
|
|
57
|
-
this
|
|
58
|
-
|
|
75
|
+
this.#streaming = streaming;
|
|
76
|
+
getRouteTable(manifest);
|
|
77
|
+
getLogger(manifest);
|
|
59
78
|
this.#fetchHandler = new DefaultFetchHandler(this);
|
|
60
79
|
this.#errorHandler = this.createErrorHandler();
|
|
61
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the user-configured logger destination from the manifest and
|
|
83
|
+
* returns the logger. Lazy and only resolves once; safe to call before
|
|
84
|
+
* the first render (adapters use this to log startup messages through
|
|
85
|
+
* the configured destination).
|
|
86
|
+
*/
|
|
87
|
+
getLogger() {
|
|
88
|
+
return getResolvedLogger(this.manifest);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The streaming flag fed into the internal `FetchState` facade hooks on
|
|
92
|
+
* the fast path. Returns the constructor flag by
|
|
93
|
+
* default; `BuildApp` overrides this to return `undefined` so streaming
|
|
94
|
+
* falls through to the environment default (`manifest.serverLike`).
|
|
95
|
+
*/
|
|
96
|
+
resolveStreaming() {
|
|
97
|
+
return this.#streaming;
|
|
98
|
+
}
|
|
62
99
|
/**
|
|
63
100
|
* Override the fetch handler used to dispatch requests. Entrypoints
|
|
64
101
|
* call this with the default export of `virtual:astro:fetchable` to
|
|
@@ -69,11 +106,15 @@ class BaseApp {
|
|
|
69
106
|
this.#hasCustomFetchHandler = !(handler instanceof DefaultFetchHandler);
|
|
70
107
|
}
|
|
71
108
|
/**
|
|
72
|
-
* Returns the error handler
|
|
73
|
-
*
|
|
109
|
+
* Returns the error handler used by this app. The default is a thin
|
|
110
|
+
* bridge over the functional error API — strategy selection (production
|
|
111
|
+
* default / dev / build) is environment-driven inside `renderErrorPage`.
|
|
112
|
+
* External subclasses can override this to customize error rendering.
|
|
74
113
|
*/
|
|
75
114
|
createErrorHandler() {
|
|
76
|
-
return
|
|
115
|
+
return {
|
|
116
|
+
renderError: (request, options) => renderErrorPage(this.manifest, request, options)
|
|
117
|
+
};
|
|
77
118
|
}
|
|
78
119
|
/**
|
|
79
120
|
* Resets the cached adapter logger so it picks up a new logger instance.
|
|
@@ -102,9 +143,7 @@ class BaseApp {
|
|
|
102
143
|
}
|
|
103
144
|
}
|
|
104
145
|
set setManifestData(newManifestData) {
|
|
105
|
-
this.
|
|
106
|
-
this.pipeline.manifestData = newManifestData;
|
|
107
|
-
this.pipeline.rebuildRouter();
|
|
146
|
+
updateRouteTable(this.manifest, newManifestData.routes);
|
|
108
147
|
}
|
|
109
148
|
removeBase(pathname) {
|
|
110
149
|
pathname = collapseDuplicateLeadingSlashes(pathname);
|
|
@@ -147,25 +186,7 @@ class BaseApp {
|
|
|
147
186
|
* @param allowPrerenderedRoutes
|
|
148
187
|
*/
|
|
149
188
|
match(request, allowPrerenderedRoutes = false) {
|
|
150
|
-
|
|
151
|
-
if (this.manifest.assets.has(url.pathname)) return void 0;
|
|
152
|
-
let pathname = this.computePathnameFromDomain(request);
|
|
153
|
-
if (!pathname) {
|
|
154
|
-
pathname = prependForwardSlash(this.removeBase(url.pathname));
|
|
155
|
-
}
|
|
156
|
-
const routeData = this.pipeline.matchRoute(this.safeDecodeURI(pathname));
|
|
157
|
-
if (!routeData) return void 0;
|
|
158
|
-
if (allowPrerenderedRoutes) {
|
|
159
|
-
return routeData;
|
|
160
|
-
}
|
|
161
|
-
if (routeData.prerender) {
|
|
162
|
-
if (routeData.params.length > 0) {
|
|
163
|
-
const allMatches = this.pipeline.matchAllRoutes(this.safeDecodeURI(pathname));
|
|
164
|
-
return allMatches.find((r) => !r.prerender);
|
|
165
|
-
}
|
|
166
|
-
return void 0;
|
|
167
|
-
}
|
|
168
|
-
return routeData;
|
|
189
|
+
return matchRequest(this.manifest, request, allowPrerenderedRoutes);
|
|
169
190
|
}
|
|
170
191
|
/**
|
|
171
192
|
* A matching route function to use in the development server.
|
|
@@ -195,7 +216,7 @@ class BaseApp {
|
|
|
195
216
|
routeData,
|
|
196
217
|
waitUntil
|
|
197
218
|
} = {}) {
|
|
198
|
-
await this.
|
|
219
|
+
await getResolvedLogger(this.manifest);
|
|
199
220
|
if (routeData) {
|
|
200
221
|
this.logger.debug(
|
|
201
222
|
"router",
|
|
@@ -226,7 +247,7 @@ class BaseApp {
|
|
|
226
247
|
if (!routeData) {
|
|
227
248
|
const domainPathname = this.computePathnameFromDomain(request);
|
|
228
249
|
if (domainPathname) {
|
|
229
|
-
routeData =
|
|
250
|
+
routeData = matchRoute(this.manifest, this.safeDecodeURI(domainPathname));
|
|
230
251
|
}
|
|
231
252
|
}
|
|
232
253
|
const resolvedOptions = {
|
|
@@ -239,11 +260,15 @@ class BaseApp {
|
|
|
239
260
|
};
|
|
240
261
|
let response;
|
|
241
262
|
if (this.#fetchHandler instanceof DefaultFetchHandler) {
|
|
242
|
-
|
|
243
|
-
|
|
263
|
+
response = await handleRequest(
|
|
264
|
+
new FetchState(this.manifest, request, resolvedOptions, {
|
|
265
|
+
streaming: this.resolveStreaming(),
|
|
266
|
+
renderError: (req, opts) => this.renderError(req, opts),
|
|
267
|
+
logRequest: (payload) => this.logThisRequest(payload)
|
|
268
|
+
})
|
|
269
|
+
);
|
|
244
270
|
} else {
|
|
245
271
|
setRenderOptions(request, resolvedOptions);
|
|
246
|
-
Reflect.set(request, appSymbol, this);
|
|
247
272
|
response = await this.#fetchHandler.fetch(request);
|
|
248
273
|
}
|
|
249
274
|
this.#warnMissingFeatures();
|
|
@@ -299,52 +324,37 @@ class BaseApp {
|
|
|
299
324
|
this.#featureCheckDone = true;
|
|
300
325
|
const manifest = this.manifest;
|
|
301
326
|
const missing = [];
|
|
302
|
-
const used = this.
|
|
303
|
-
if (manifest.routes.some((r) => r.routeData.type === "redirect") && !(used &
|
|
327
|
+
const used = getUsedFeatures(this.manifest);
|
|
328
|
+
if (manifest.routes.some((r) => r.routeData.type === "redirect") && !(used & FetchFeatures.redirects)) {
|
|
304
329
|
missing.push("redirects");
|
|
305
330
|
}
|
|
306
|
-
if (manifest.sessionConfig && !(used &
|
|
331
|
+
if (manifest.sessionConfig && !(used & FetchFeatures.sessions)) {
|
|
307
332
|
missing.push("sessions");
|
|
308
333
|
}
|
|
309
|
-
if (manifest.actions && !(used &
|
|
334
|
+
if (manifest.actions && !(used & FetchFeatures.actions)) {
|
|
310
335
|
missing.push("actions");
|
|
311
336
|
}
|
|
312
|
-
if (manifest.middleware && !(used &
|
|
337
|
+
if (manifest.middleware && !(used & FetchFeatures.middleware)) {
|
|
313
338
|
missing.push("middleware");
|
|
314
339
|
}
|
|
315
|
-
if (manifest.i18n && manifest.i18n.strategy !== "manual" && !(used &
|
|
340
|
+
if (manifest.i18n && manifest.i18n.strategy !== "manual" && !(used & FetchFeatures.i18n)) {
|
|
316
341
|
missing.push("i18n");
|
|
317
342
|
}
|
|
318
|
-
if (manifest.cacheConfig && !(used &
|
|
343
|
+
if (manifest.cacheConfig && !(used & FetchFeatures.cache)) {
|
|
319
344
|
missing.push("cache");
|
|
320
345
|
}
|
|
321
346
|
for (const feature of missing) {
|
|
322
347
|
this.logger.warn(
|
|
323
348
|
"router",
|
|
324
|
-
`Your project uses ${feature}, but your custom src/fetch.ts does not call the ${feature}() handler. This feature will not work unless
|
|
349
|
+
`Your project uses ${feature}, but your custom src/fetch.ts does not call the ${feature}() handler. This feature will not work unless your fetch handler calls it.`
|
|
325
350
|
);
|
|
326
351
|
}
|
|
327
352
|
}
|
|
328
353
|
getDefaultStatusCode(routeData, pathname) {
|
|
329
|
-
|
|
330
|
-
for (const fallbackRoute of routeData.fallbackRoutes) {
|
|
331
|
-
if (fallbackRoute.pattern.test(pathname)) {
|
|
332
|
-
return 302;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const route = removeTrailingForwardSlash(routeData.route);
|
|
337
|
-
const locales = this.manifest.i18n?.locales;
|
|
338
|
-
if (isRoute404(route) || isLocalizedErrorRoute(route, 404, locales)) {
|
|
339
|
-
return 404;
|
|
340
|
-
}
|
|
341
|
-
if (isRoute500(route) || isLocalizedErrorRoute(route, 500, locales)) {
|
|
342
|
-
return 500;
|
|
343
|
-
}
|
|
344
|
-
return 200;
|
|
354
|
+
return getDefaultStatusCode(this.manifest, routeData, pathname);
|
|
345
355
|
}
|
|
346
356
|
getManifest() {
|
|
347
|
-
return this.
|
|
357
|
+
return this.manifest;
|
|
348
358
|
}
|
|
349
359
|
logThisRequest({
|
|
350
360
|
pathname,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RouteData } from '../../types/public/index.js';
|
|
2
|
+
import { BaseApp, type DevMatch, type LogRequestPayload } from './base.js';
|
|
3
|
+
import type { SSRManifest } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The shared thin dev facade: used by BOTH dev paths —
|
|
6
|
+
* the workerd / non-runnable dev entrypoint (`entrypoints/virtual/dev.ts`)
|
|
7
|
+
* and the runnable dev server (`vite-plugin-app/createAstroServerApp.ts`).
|
|
8
|
+
* Everything environment-specific (module loading, error strategy, request
|
|
9
|
+
* logging behavior) comes from the `RenderEnvironment` record registered on
|
|
10
|
+
* the manifest before construction, and the runnable dev server's HTTP glue
|
|
11
|
+
* lives in `vite-plugin-app/handle-request.ts`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class DevFacadeApp extends BaseApp {
|
|
14
|
+
constructor(manifest: SSRManifest, streaming?: boolean);
|
|
15
|
+
isDev(): boolean;
|
|
16
|
+
/** Dev always allows prerendered routes to match. */
|
|
17
|
+
match(request: Request): RouteData | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* A matching route function for the development server. Contrary to
|
|
20
|
+
* `.match`, this resolves props and params, returning the correct route
|
|
21
|
+
* based on priority and segments, plus the resolved pathname.
|
|
22
|
+
*/
|
|
23
|
+
devMatch(pathname?: string, { prerenderOnly }?: {
|
|
24
|
+
prerenderOnly?: boolean;
|
|
25
|
+
}): Promise<DevMatch | undefined>;
|
|
26
|
+
logRequest({ pathname, method, statusCode, isRewrite, reqTime }: LogRequestPayload): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { req } from "../messages/runtime.js";
|
|
2
|
+
import { matchRoute as devMatchRoute } from "../routing/dev.js";
|
|
3
|
+
import { BaseApp } from "./base.js";
|
|
4
|
+
class DevFacadeApp extends BaseApp {
|
|
5
|
+
constructor(manifest, streaming = true) {
|
|
6
|
+
super(manifest, streaming);
|
|
7
|
+
}
|
|
8
|
+
isDev() {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
/** Dev always allows prerendered routes to match. */
|
|
12
|
+
match(request) {
|
|
13
|
+
return super.match(request, true);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A matching route function for the development server. Contrary to
|
|
17
|
+
* `.match`, this resolves props and params, returning the correct route
|
|
18
|
+
* based on priority and segments, plus the resolved pathname.
|
|
19
|
+
*/
|
|
20
|
+
async devMatch(pathname, { prerenderOnly } = {}) {
|
|
21
|
+
if (pathname === void 0) {
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
const matchedRoute = await devMatchRoute(this.manifest, pathname, { prerenderOnly });
|
|
25
|
+
if (!matchedRoute) {
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
routeData: matchedRoute.route,
|
|
30
|
+
resolvedPathname: matchedRoute.resolvedPathname
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
logRequest({ pathname, method, statusCode, isRewrite, reqTime }) {
|
|
34
|
+
if (pathname === "/favicon.ico") {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.logger.info(
|
|
38
|
+
null,
|
|
39
|
+
req({
|
|
40
|
+
url: pathname,
|
|
41
|
+
method,
|
|
42
|
+
statusCode,
|
|
43
|
+
isRewrite,
|
|
44
|
+
reqTime
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
DevFacadeApp
|
|
51
|
+
};
|
|
@@ -4,6 +4,5 @@ export { BaseApp, type RenderErrorOptions, type RenderOptions, type LogRequestPa
|
|
|
4
4
|
export { fromRoutingStrategy, toRoutingStrategy } from '../common.js';
|
|
5
5
|
export { createConsoleLogger } from '../../logger/impls/console.js';
|
|
6
6
|
export { deserializeManifest, deserializeRouteData, deserializeRouteInfo, serializeRouteData, serializeRouteInfo, } from '../manifest.js';
|
|
7
|
-
export { AppPipeline } from '../pipeline.js';
|
|
8
7
|
export { beginContentEntryCollection, endContentEntryCollection, } from '../../build/incremental-content-collector.js';
|
|
9
8
|
export { beginImageCollection, endImageCollection, recordStaticImage, } from '../../build/incremental-image-collector.js';
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
serializeRouteData,
|
|
12
12
|
serializeRouteInfo
|
|
13
13
|
} from "../manifest.js";
|
|
14
|
-
import { AppPipeline } from "../pipeline.js";
|
|
15
14
|
import {
|
|
16
15
|
beginContentEntryCollection,
|
|
17
16
|
endContentEntryCollection
|
|
@@ -23,7 +22,6 @@ import {
|
|
|
23
22
|
} from "../../build/incremental-image-collector.js";
|
|
24
23
|
export {
|
|
25
24
|
App,
|
|
26
|
-
AppPipeline,
|
|
27
25
|
BaseApp,
|
|
28
26
|
beginContentEntryCollection,
|
|
29
27
|
beginImageCollection,
|
|
@@ -1,40 +1,45 @@
|
|
|
1
1
|
import fetchable from "virtual:astro:fetchable";
|
|
2
2
|
import { manifest } from "virtual:astro:manifest";
|
|
3
|
-
import {
|
|
3
|
+
import { clearActions } from "../../../../actions/load.js";
|
|
4
|
+
import { createNonRunnableEnvironment } from "../../../environment/dev-nonrunnable.js";
|
|
5
|
+
import { setEnvironment } from "../../../environment/index.js";
|
|
4
6
|
import { createConsoleLogger } from "../../../logger/impls/console.js";
|
|
5
|
-
|
|
7
|
+
import { getLogger, setLogger } from "../../../logger/manifest-logger.js";
|
|
8
|
+
import { clearMiddleware } from "../../../middleware/load.js";
|
|
9
|
+
import { getRouteCache } from "../../../render/route-cache.js";
|
|
10
|
+
import { updateRouteTable } from "../../../routing/route-table.js";
|
|
11
|
+
import { DevFacadeApp } from "../../dev-facade.js";
|
|
12
|
+
let hmrWired = false;
|
|
6
13
|
const createApp = ({ streaming } = {}) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
setLogger(manifest, createConsoleLogger(manifest.logLevel));
|
|
15
|
+
setEnvironment(manifest, createNonRunnableEnvironment());
|
|
16
|
+
const app = new DevFacadeApp(manifest, streaming);
|
|
17
|
+
app.setFetchHandler(fetchable);
|
|
18
|
+
if (import.meta.hot && !hmrWired) {
|
|
19
|
+
hmrWired = true;
|
|
11
20
|
import.meta.hot.on("astro:routes-updated", async () => {
|
|
12
|
-
if (!currentDevApp) return;
|
|
13
21
|
try {
|
|
14
22
|
const { routes: newRoutes } = await import("virtual:astro:routes");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
updateRouteTable(
|
|
24
|
+
manifest,
|
|
25
|
+
newRoutes.map((r) => r.routeData)
|
|
26
|
+
);
|
|
19
27
|
} catch (e) {
|
|
20
|
-
|
|
28
|
+
getLogger(manifest).error("router", `Failed to update routes via HMR:
|
|
21
29
|
${e}`);
|
|
22
30
|
}
|
|
23
31
|
});
|
|
24
32
|
import.meta.hot.on("astro:content-changed", () => {
|
|
25
|
-
|
|
26
|
-
currentDevApp.pipeline.routeCache.clearAll();
|
|
33
|
+
getRouteCache(manifest).clearAll();
|
|
27
34
|
});
|
|
28
35
|
import.meta.hot.on("astro:middleware-updated", () => {
|
|
29
|
-
|
|
30
|
-
currentDevApp.clearMiddleware();
|
|
36
|
+
clearMiddleware(manifest);
|
|
31
37
|
});
|
|
32
38
|
import.meta.hot.on("astro:actions-updated", () => {
|
|
33
|
-
|
|
34
|
-
currentDevApp.clearActions();
|
|
39
|
+
clearActions(manifest);
|
|
35
40
|
});
|
|
36
41
|
}
|
|
37
|
-
return
|
|
42
|
+
return app;
|
|
38
43
|
};
|
|
39
44
|
export {
|
|
40
45
|
createApp
|
package/dist/core/app/node.js
CHANGED
|
@@ -19,12 +19,7 @@ function createRequestFromNodeRequest(req, {
|
|
|
19
19
|
const isEncrypted = "encrypted" in req.socket && req.socket.encrypted;
|
|
20
20
|
const protocol = isEncrypted ? "https" : "http";
|
|
21
21
|
const hostname = typeof req.headers.host === "string" ? req.headers.host : typeof req.headers[":authority"] === "string" ? req.headers[":authority"] : serverPort ? `localhost:${serverPort}` : "localhost";
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
url = new URL(`${protocol}://${hostname}${req.url}`);
|
|
25
|
-
} catch {
|
|
26
|
-
url = new URL(`${protocol}://${hostname}`);
|
|
27
|
-
}
|
|
22
|
+
const url = buildRequestUrl(protocol, hostname, req.url, serverPort);
|
|
28
23
|
const options = {
|
|
29
24
|
method: req.method || "GET",
|
|
30
25
|
headers: makeRequestHeaders(req),
|
|
@@ -80,14 +75,7 @@ function createRequest(req, {
|
|
|
80
75
|
);
|
|
81
76
|
const hostname = validated.host ?? validatedHostname ?? "localhost";
|
|
82
77
|
const port = validated.port ?? (!validated.host && !validatedHostname && serverPort ? String(serverPort) : void 0);
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
const hostnamePort = getHostnamePort(hostname, port);
|
|
86
|
-
url = new URL(`${protocol}://${hostnamePort}${req.url}`);
|
|
87
|
-
} catch {
|
|
88
|
-
const hostnamePort = getHostnamePort(hostname, port);
|
|
89
|
-
url = new URL(`${protocol}://${hostnamePort}`);
|
|
90
|
-
}
|
|
78
|
+
const url = buildRequestUrl(protocol, getHostnamePort(hostname, port), req.url, serverPort);
|
|
91
79
|
const options = {
|
|
92
80
|
method: req.method || "GET",
|
|
93
81
|
headers: makeRequestHeaders(req),
|
|
@@ -245,6 +233,17 @@ function getHostnamePort(hostname, port) {
|
|
|
245
233
|
const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`;
|
|
246
234
|
return hostnamePort;
|
|
247
235
|
}
|
|
236
|
+
function buildRequestUrl(protocol, hostnamePort, requestPath, serverPort) {
|
|
237
|
+
const path = requestPath ?? "";
|
|
238
|
+
if (URL.canParse(`${protocol}://${hostnamePort}${path}`)) {
|
|
239
|
+
return new URL(`${protocol}://${hostnamePort}${path}`);
|
|
240
|
+
}
|
|
241
|
+
if (URL.canParse(`${protocol}://${hostnamePort}`)) {
|
|
242
|
+
return new URL(`${protocol}://${hostnamePort}`);
|
|
243
|
+
}
|
|
244
|
+
const fallbackHost = serverPort ? `localhost:${serverPort}` : "localhost";
|
|
245
|
+
return new URL(`${protocol}://${fallbackHost}`);
|
|
246
|
+
}
|
|
248
247
|
function makeRequestHeaders(req) {
|
|
249
248
|
const headers = new Headers();
|
|
250
249
|
for (const [name, value] of Object.entries(req.headers)) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* and marks the response as sent.
|
|
4
4
|
*
|
|
5
5
|
* This is a pure function with no dependencies on the app; it is shared by
|
|
6
|
-
* `
|
|
6
|
+
* `handleRequest` and the various error handlers.
|
|
7
7
|
*/
|
|
8
8
|
export declare function prepareResponse(response: Response, { addCookieHeader }: {
|
|
9
9
|
addCookieHeader: boolean;
|
|
@@ -9,6 +9,7 @@ function sanitizeHost(hostname) {
|
|
|
9
9
|
}
|
|
10
10
|
function parseHost(host) {
|
|
11
11
|
const parts = host.split(":");
|
|
12
|
+
if (parts.length > 2) return void 0;
|
|
12
13
|
return {
|
|
13
14
|
hostname: parts[0],
|
|
14
15
|
port: parts[1]
|
|
@@ -28,7 +29,9 @@ function validateHost(host, protocol, allowedDomains) {
|
|
|
28
29
|
if (!allowedDomains || allowedDomains.length === 0) return void 0;
|
|
29
30
|
const sanitized = sanitizeHost(host);
|
|
30
31
|
if (!sanitized) return void 0;
|
|
31
|
-
const
|
|
32
|
+
const parsed = parseHost(sanitized);
|
|
33
|
+
if (!parsed) return void 0;
|
|
34
|
+
const { hostname, port } = parsed;
|
|
32
35
|
if (matchesAllowedDomains(hostname, protocol, port, allowedDomains)) {
|
|
33
36
|
return sanitized;
|
|
34
37
|
}
|
|
@@ -67,8 +70,9 @@ function validateForwardedHeaders(forwardedProtocol, forwardedHost, forwardedPor
|
|
|
67
70
|
if (forwardedHost && forwardedHost.length > 0 && allowedDomains && allowedDomains.length > 0) {
|
|
68
71
|
const protoForValidation = result.protocol || "https";
|
|
69
72
|
const sanitized = sanitizeHost(forwardedHost);
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
const parsed = sanitized ? parseHost(sanitized) : void 0;
|
|
74
|
+
if (sanitized && parsed) {
|
|
75
|
+
const { hostname, port: portFromHost } = parsed;
|
|
72
76
|
const portForValidation = result.port || portFromHost;
|
|
73
77
|
if (matchesAllowedDomains(hostname, protoForValidation, portForValidation, allowedDomains)) {
|
|
74
78
|
result.host = sanitized;
|
package/dist/core/build/app.d.ts
CHANGED
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
import { BaseApp } from '../app/entrypoints/index.js';
|
|
2
|
+
import type { LogRequestPayload } from '../app/base.js';
|
|
2
3
|
import type { SSRManifest } from '../app/types.js';
|
|
4
|
+
import type { ComponentInstance } from '../../types/astro.js';
|
|
5
|
+
import type { RouteData } from '../../types/public/internal.js';
|
|
6
|
+
import { type RouteCache } from '../render/route-cache.js';
|
|
7
|
+
import type { BuildEnvironmentSlots } from './environment.js';
|
|
3
8
|
import type { BuildInternals } from './internal.js';
|
|
4
|
-
import { BuildPipeline } from './pipeline.js';
|
|
5
9
|
import type { StaticBuildOptions } from './types.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The build / prerender facade: a thin shell over the
|
|
12
|
+
* build environment record. The two-phase init state (`setInternals` /
|
|
13
|
+
* `setOptions`, injected by `createDefaultPrerenderer.setup()` after the
|
|
14
|
+
* prerender bundle import) lives in the `BuildEnvironmentSlots` closure
|
|
15
|
+
* created by the prerender entrypoint; the facade only forwards across the
|
|
16
|
+
* bundle boundary into those slots.
|
|
17
|
+
*/
|
|
18
|
+
export declare class BuildApp extends BaseApp {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(manifest: SSRManifest, buildEnv: BuildEnvironmentSlots);
|
|
10
21
|
isDev(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Streaming falls through to the environment default
|
|
24
|
+
* (`manifest.serverLike` for the build environment) — we can skip
|
|
25
|
+
* streaming in SSG for performance, as writing strings is faster.
|
|
26
|
+
*/
|
|
27
|
+
protected resolveStreaming(): boolean | undefined;
|
|
11
28
|
setInternals(internals: BuildInternals): void;
|
|
12
29
|
setOptions(options: StaticBuildOptions): void;
|
|
13
30
|
getOptions(): StaticBuildOptions;
|
|
14
31
|
getSettings(): import("../../types/astro.js").AstroSettings;
|
|
15
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Route cache and component loader for `StaticPaths`. Defined on the app
|
|
34
|
+
* (rather than reached through the functional core at the call site) so
|
|
35
|
+
* they execute inside the prerender bundle's module graph: the default
|
|
36
|
+
* prerenderer constructs `StaticPaths` from a different bundle, whose
|
|
37
|
+
* copies of the core modules hold separate per-manifest state.
|
|
38
|
+
*/
|
|
39
|
+
get routeCache(): RouteCache;
|
|
40
|
+
getComponentByRoute(routeData: RouteData): Promise<ComponentInstance>;
|
|
16
41
|
logRequest(_options: LogRequestPayload): void;
|
|
17
42
|
}
|
package/dist/core/build/app.js
CHANGED
|
@@ -1,31 +1,49 @@
|
|
|
1
1
|
import { BaseApp } from "../app/entrypoints/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { getEnvironment } from "../environment/index.js";
|
|
3
|
+
import { getRouteCache } from "../render/route-cache.js";
|
|
4
4
|
class BuildApp extends BaseApp {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
#buildEnv;
|
|
6
|
+
constructor(manifest, buildEnv) {
|
|
7
|
+
super(manifest);
|
|
8
|
+
this.#buildEnv = buildEnv;
|
|
9
9
|
}
|
|
10
10
|
isDev() {
|
|
11
11
|
return true;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Streaming falls through to the environment default
|
|
15
|
+
* (`manifest.serverLike` for the build environment) — we can skip
|
|
16
|
+
* streaming in SSG for performance, as writing strings is faster.
|
|
17
|
+
*/
|
|
18
|
+
resolveStreaming() {
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
13
21
|
setInternals(internals) {
|
|
14
|
-
this.
|
|
22
|
+
this.#buildEnv.setInternals(internals);
|
|
15
23
|
}
|
|
16
24
|
setOptions(options) {
|
|
17
|
-
this.
|
|
25
|
+
this.#buildEnv.setOptions(options);
|
|
18
26
|
this.logger.setDestination(options.logger.options.destination);
|
|
19
27
|
this.resetAdapterLogger();
|
|
20
28
|
}
|
|
21
29
|
getOptions() {
|
|
22
|
-
return this.
|
|
30
|
+
return this.#buildEnv.getOptions();
|
|
23
31
|
}
|
|
24
32
|
getSettings() {
|
|
25
|
-
return this.
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
return this.#buildEnv.getSettings();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Route cache and component loader for `StaticPaths`. Defined on the app
|
|
37
|
+
* (rather than reached through the functional core at the call site) so
|
|
38
|
+
* they execute inside the prerender bundle's module graph: the default
|
|
39
|
+
* prerenderer constructs `StaticPaths` from a different bundle, whose
|
|
40
|
+
* copies of the core modules hold separate per-manifest state.
|
|
41
|
+
*/
|
|
42
|
+
get routeCache() {
|
|
43
|
+
return getRouteCache(this.manifest);
|
|
44
|
+
}
|
|
45
|
+
getComponentByRoute(routeData) {
|
|
46
|
+
return getEnvironment(this.manifest).getComponentByRoute(this.manifest, routeData);
|
|
29
47
|
}
|
|
30
48
|
logRequest(_options) {
|
|
31
49
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AstroSettings } from '../../types/astro.js';
|
|
2
|
+
import type { RenderEnvironment } from '../environment/index.js';
|
|
3
|
+
import type { BuildInternals } from './internal.js';
|
|
4
|
+
import type { StaticBuildOptions } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* The build / prerender environment record and its mutable closure slots.
|
|
7
|
+
* The build has a two-phase initialization: the prerender bundle is imported
|
|
8
|
+
* first, and `createDefaultPrerenderer.setup()` injects `BuildInternals` /
|
|
9
|
+
* `StaticBuildOptions` afterwards through the facade. The slots live in this
|
|
10
|
+
* closure; accessors throw before injection, and the environment functions
|
|
11
|
+
* close over the same slots.
|
|
12
|
+
*/
|
|
13
|
+
export interface BuildEnvironmentSlots {
|
|
14
|
+
/** The build `RenderEnvironment`; its functions close over the slots below. */
|
|
15
|
+
env: RenderEnvironment;
|
|
16
|
+
setInternals(internals: BuildInternals): void;
|
|
17
|
+
setOptions(options: StaticBuildOptions): void;
|
|
18
|
+
/** Throws `No internals defined` before injection. */
|
|
19
|
+
getInternals(): BuildInternals;
|
|
20
|
+
/** Throws `No options defined` before injection. */
|
|
21
|
+
getOptions(): StaticBuildOptions;
|
|
22
|
+
/** Throws `No options defined` before injection. */
|
|
23
|
+
getSettings(): AstroSettings;
|
|
24
|
+
}
|
|
25
|
+
export declare function createBuildEnvironment(): BuildEnvironmentSlots;
|