astro 7.2.2 → 7.2.4
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/assets/utils/vendor/image-size/types/heif.js +8 -3
- package/dist/assets/utils/vendor/image-size/types/icns.js +10 -2
- package/dist/assets/utils/vendor/image-size/types/jp2.js +2 -2
- package/dist/assets/utils/vendor/image-size/types/jxl.js +5 -2
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +1 -1
- package/dist/assets/utils/vendor/image-size/types/utils.js +20 -6
- 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 +73 -37
- 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 +79 -73
- 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 +99 -92
- 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/domain.js +4 -11
- 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 +46 -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
|
@@ -1,46 +1,36 @@
|
|
|
1
1
|
import type { FetchState } from '../fetch/fetch-state.js';
|
|
2
2
|
import type { APIContext } from '../../types/public/context.js';
|
|
3
|
-
import type { BaseApp } from '../app/base.js';
|
|
4
|
-
import { type Pipeline } from '../base-pipeline.js';
|
|
5
3
|
/**
|
|
6
4
|
* Callback invoked at the bottom of the middleware chain to dispatch the
|
|
7
5
|
* request to the matched route (endpoint / redirect / page / fallback).
|
|
8
6
|
*
|
|
9
|
-
* Callers of `
|
|
10
|
-
*
|
|
11
|
-
* middleware layer.
|
|
7
|
+
* Callers of `handleMiddleware` pass `handlePages` (or a wrapper around it)
|
|
8
|
+
* so route dispatch logic stays out of the middleware layer.
|
|
12
9
|
*/
|
|
13
10
|
export type RenderRouteCallback = (state: FetchState, ctx: APIContext) => Promise<Response>;
|
|
14
11
|
/**
|
|
15
|
-
*
|
|
16
|
-
* single render
|
|
17
|
-
*
|
|
12
|
+
* Runs Astro's middleware chain (origin check + user `onRequest`) for a
|
|
13
|
+
* single render, reading the composed middleware from the manifest and
|
|
14
|
+
* per-request data (componentInstance, slots, props, API contexts) off the
|
|
15
|
+
* supplied `FetchState`. The actual route dispatch (endpoint / redirect /
|
|
16
|
+
* page / fallback) is supplied by the caller as `renderRouteCallback` —
|
|
17
|
+
* typically `handlePages`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleMiddleware(state: FetchState, renderRouteCallback: RenderRouteCallback): Promise<Response>;
|
|
20
|
+
/**
|
|
21
|
+
* Like `handleMiddleware`, but mirrors the app-level error handling that
|
|
22
|
+
* `handleRequest` provides on the standard path, the same way
|
|
23
|
+
* `handlePagesWithErrorFallback` does for `pages()`. When no route matched
|
|
24
|
+
* it returns a 404 marked with `X-Astro-Error` for the app's post-check;
|
|
25
|
+
* when Astro's own middleware chain throws it logs the error and renders
|
|
26
|
+
* the custom `500.astro`.
|
|
27
|
+
*
|
|
28
|
+
* Errors surfaced through `renderRouteCallback` (the host framework's
|
|
29
|
+
* `next`, e.g. host middleware mounted below `middleware()`) are re-thrown
|
|
30
|
+
* instead, so the host's own error handling still runs rather than being
|
|
31
|
+
* swallowed into Astro's 500 page. A sentinel tells the two apart.
|
|
18
32
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* redirect / page / fallback) is supplied by the caller as
|
|
22
|
-
* `renderRouteCallback` — typically bound to a `PagesHandler.handle`.
|
|
33
|
+
* Used by the composable `astro/fetch` `middleware()` entry point, where
|
|
34
|
+
* there is no surrounding `handleRequest` to supply this fallback.
|
|
23
35
|
*/
|
|
24
|
-
export declare
|
|
25
|
-
#private;
|
|
26
|
-
constructor(pipeline: Pipeline);
|
|
27
|
-
handle(state: FetchState, renderRouteCallback: RenderRouteCallback): Promise<Response>;
|
|
28
|
-
/**
|
|
29
|
-
* Like `handle`, but mirrors the app-level error handling that
|
|
30
|
-
* `AstroHandler` provides on the standard path, the same way
|
|
31
|
-
* `PagesHandler.handleWithErrorFallback` does for `pages()`. When no
|
|
32
|
-
* route matched it returns a 404 marked with `X-Astro-Error` for the
|
|
33
|
-
* app's post-check; when Astro's own middleware chain throws it logs the
|
|
34
|
-
* error and renders the custom `500.astro`.
|
|
35
|
-
*
|
|
36
|
-
* Errors surfaced through `renderRouteCallback` (the host framework's
|
|
37
|
-
* `next`, e.g. host middleware mounted below `middleware()`) are
|
|
38
|
-
* re-thrown instead, so the host's own error handling still runs rather
|
|
39
|
-
* than being swallowed into Astro's 500 page. A sentinel tells the two
|
|
40
|
-
* apart.
|
|
41
|
-
*
|
|
42
|
-
* Used by the composable `astro/fetch` `middleware()` entry point, where
|
|
43
|
-
* there is no surrounding `AstroHandler` to supply this fallback.
|
|
44
|
-
*/
|
|
45
|
-
handleWithErrorFallback(app: BaseApp<Pipeline>, state: FetchState, renderRouteCallback: RenderRouteCallback): Promise<Response>;
|
|
46
|
-
}
|
|
36
|
+
export declare function handleMiddlewareWithErrorFallback(state: FetchState, renderRouteCallback: RenderRouteCallback): Promise<Response>;
|
|
@@ -1,94 +1,74 @@
|
|
|
1
|
-
import { PipelineFeatures } from "../base-pipeline.js";
|
|
2
1
|
import { ASTRO_ERROR_HEADER } from "../constants.js";
|
|
3
2
|
import { attachCookiesToResponse } from "../cookies/index.js";
|
|
3
|
+
import { getEnvironment } from "../environment/index.js";
|
|
4
|
+
import { renderErrorFromState } from "../errors/handler.js";
|
|
5
|
+
import { markFeatureUsed, FetchFeatures } from "../fetch/features.js";
|
|
4
6
|
import { applyRewriteToState } from "../rewrites/handler.js";
|
|
5
7
|
import { callMiddleware } from "./callMiddleware.js";
|
|
8
|
+
import { getMiddleware } from "./load.js";
|
|
6
9
|
import { sequence } from "./index.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
async function handleMiddleware(state, renderRouteCallback) {
|
|
11
|
+
markFeatureUsed(state.manifest, FetchFeatures.middleware);
|
|
12
|
+
await state.getProps();
|
|
13
|
+
const apiContext = state.getAPIContext();
|
|
14
|
+
state.counter++;
|
|
15
|
+
if (state.counter === 4) {
|
|
16
|
+
return new Response("Loop Detected", {
|
|
17
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508
|
|
18
|
+
status: 508,
|
|
19
|
+
statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times."
|
|
20
|
+
});
|
|
11
21
|
}
|
|
12
|
-
async
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
status: 508,
|
|
22
|
-
statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times."
|
|
23
|
-
});
|
|
22
|
+
const next = async (ctx, payload) => {
|
|
23
|
+
if (payload) {
|
|
24
|
+
state.logger.debug("router", "Called rewriting to:", payload);
|
|
25
|
+
const result = await getEnvironment(state.manifest).tryRewrite(
|
|
26
|
+
state.manifest,
|
|
27
|
+
payload,
|
|
28
|
+
state.request
|
|
29
|
+
);
|
|
30
|
+
applyRewriteToState(state, payload, result);
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (state.skipMiddleware) {
|
|
35
|
-
response = await next(apiContext);
|
|
36
|
-
} else {
|
|
37
|
-
const pipelineMiddleware = await pipeline.getMiddleware();
|
|
38
|
-
const composed = sequence(...pipeline.internalMiddleware, pipelineMiddleware);
|
|
39
|
-
response = await callMiddleware(composed, apiContext, next);
|
|
40
|
-
}
|
|
41
|
-
response = this.#finalize(state, response);
|
|
42
|
-
state.response = response;
|
|
43
|
-
return response;
|
|
32
|
+
return renderRouteCallback(state, ctx);
|
|
33
|
+
};
|
|
34
|
+
let response;
|
|
35
|
+
if (state.skipMiddleware) {
|
|
36
|
+
response = await next(apiContext);
|
|
37
|
+
} else {
|
|
38
|
+
const middleware = await getMiddleware(state.manifest);
|
|
39
|
+
const composed = sequence(middleware);
|
|
40
|
+
response = await callMiddleware(composed, apiContext, next);
|
|
44
41
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*
|
|
53
|
-
* Errors surfaced through `renderRouteCallback` (the host framework's
|
|
54
|
-
* `next`, e.g. host middleware mounted below `middleware()`) are
|
|
55
|
-
* re-thrown instead, so the host's own error handling still runs rather
|
|
56
|
-
* than being swallowed into Astro's 500 page. A sentinel tells the two
|
|
57
|
-
* apart.
|
|
58
|
-
*
|
|
59
|
-
* Used by the composable `astro/fetch` `middleware()` entry point, where
|
|
60
|
-
* there is no surrounding `AstroHandler` to supply this fallback.
|
|
61
|
-
*/
|
|
62
|
-
async handleWithErrorFallback(app, state, renderRouteCallback) {
|
|
63
|
-
if (!state.routeData) {
|
|
64
|
-
return new Response(null, { status: 404, headers: { [ASTRO_ERROR_HEADER]: "true" } });
|
|
65
|
-
}
|
|
66
|
-
let nextError;
|
|
67
|
-
try {
|
|
68
|
-
return await this.handle(state, async (s, ctx) => {
|
|
69
|
-
try {
|
|
70
|
-
return await renderRouteCallback(s, ctx);
|
|
71
|
-
} catch (err) {
|
|
72
|
-
nextError = err;
|
|
73
|
-
throw err;
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
} catch (err) {
|
|
77
|
-
if (err === nextError) throw err;
|
|
78
|
-
app.logger.error(null, err.stack || err.message || String(err));
|
|
79
|
-
return app.renderError(state.request, {
|
|
80
|
-
...state.renderOptions,
|
|
81
|
-
status: 500,
|
|
82
|
-
error: err,
|
|
83
|
-
pathname: state.pathname
|
|
84
|
-
});
|
|
85
|
-
}
|
|
42
|
+
attachCookiesToResponse(response, state.cookies);
|
|
43
|
+
state.response = response;
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
async function handleMiddlewareWithErrorFallback(state, renderRouteCallback) {
|
|
47
|
+
if (!state.routeData) {
|
|
48
|
+
return new Response(null, { status: 404, headers: { [ASTRO_ERROR_HEADER]: "true" } });
|
|
86
49
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
50
|
+
let nextError;
|
|
51
|
+
try {
|
|
52
|
+
return await handleMiddleware(state, async (s, ctx) => {
|
|
53
|
+
try {
|
|
54
|
+
return await renderRouteCallback(s, ctx);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
nextError = err;
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err === nextError) throw err;
|
|
62
|
+
state.logger.error(null, err.stack || err.message || String(err));
|
|
63
|
+
return renderErrorFromState(state, state.request, {
|
|
64
|
+
...state.renderOptions,
|
|
65
|
+
status: 500,
|
|
66
|
+
error: err,
|
|
67
|
+
pathname: state.pathname
|
|
68
|
+
});
|
|
90
69
|
}
|
|
91
70
|
}
|
|
92
71
|
export {
|
|
93
|
-
|
|
72
|
+
handleMiddleware,
|
|
73
|
+
handleMiddlewareWithErrorFallback
|
|
94
74
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from '../../types/public/common.js';
|
|
2
|
+
import type { SSRManifest } from '../app/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the middleware from the manifest and returns the `onRequest`
|
|
5
|
+
* function (prefixed with the origin-check middleware when configured). If
|
|
6
|
+
* `onRequest` isn't there, it returns a no-op function.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getMiddleware(manifest: SSRManifest): Promise<MiddlewareHandler>;
|
|
9
|
+
/**
|
|
10
|
+
* The already-resolved middleware for a manifest, or `undefined` when
|
|
11
|
+
* `getMiddleware` has not settled yet. Sync — used where a synchronous
|
|
12
|
+
* snapshot is required (the container's `insertRoute`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function peekMiddleware(manifest: SSRManifest): MiddlewareHandler | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Clears the cached middleware so it is re-resolved on the next request.
|
|
17
|
+
* Called via HMR when middleware files change during development.
|
|
18
|
+
*/
|
|
19
|
+
export declare function clearMiddleware(manifest: SSRManifest): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createOriginCheckMiddleware } from "../app/origin-check.js";
|
|
2
|
+
import { createAsyncManifestMemo } from "../manifest/memo.js";
|
|
3
|
+
import { NOOP_MIDDLEWARE_FN } from "./noop-middleware.js";
|
|
4
|
+
import { sequence } from "./sequence.js";
|
|
5
|
+
const resolvedMiddleware = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
const middlewareMemo = createAsyncManifestMemo(async (manifest) => {
|
|
7
|
+
let handler;
|
|
8
|
+
if (manifest.middleware) {
|
|
9
|
+
const middlewareInstance = await manifest.middleware();
|
|
10
|
+
const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN;
|
|
11
|
+
const internalMiddlewares = [onRequest];
|
|
12
|
+
if (manifest.checkOrigin) {
|
|
13
|
+
internalMiddlewares.unshift(createOriginCheckMiddleware());
|
|
14
|
+
}
|
|
15
|
+
handler = sequence(...internalMiddlewares);
|
|
16
|
+
} else {
|
|
17
|
+
handler = NOOP_MIDDLEWARE_FN;
|
|
18
|
+
}
|
|
19
|
+
resolvedMiddleware.set(manifest, handler);
|
|
20
|
+
return handler;
|
|
21
|
+
});
|
|
22
|
+
function getMiddleware(manifest) {
|
|
23
|
+
return middlewareMemo.get(manifest);
|
|
24
|
+
}
|
|
25
|
+
function peekMiddleware(manifest) {
|
|
26
|
+
return resolvedMiddleware.get(manifest);
|
|
27
|
+
}
|
|
28
|
+
function clearMiddleware(manifest) {
|
|
29
|
+
middlewareMemo.invalidate(manifest);
|
|
30
|
+
resolvedMiddleware.delete(manifest);
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
clearMiddleware,
|
|
34
|
+
getMiddleware,
|
|
35
|
+
peekMiddleware
|
|
36
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fetchStateSymbol } from "../constants.js";
|
|
2
|
+
import { getEnvironment } from "../environment/index.js";
|
|
2
3
|
import { ForbiddenRewrite } from "../errors/errors-data.js";
|
|
3
4
|
import { AstroError } from "../errors/index.js";
|
|
4
|
-
import { getParams } from "../render/
|
|
5
|
+
import { getParams } from "../render/params-and-props.js";
|
|
5
6
|
import { setOriginPathname } from "../routing/rewrite.js";
|
|
6
7
|
import { defineMiddleware } from "./defineMiddleware.js";
|
|
7
8
|
function sequence(...handlers) {
|
|
@@ -32,12 +33,19 @@ function sequence(...handlers) {
|
|
|
32
33
|
);
|
|
33
34
|
}
|
|
34
35
|
const oldPathname = handleContext.url.pathname;
|
|
35
|
-
const
|
|
36
|
-
|
|
36
|
+
const state = Reflect.get(handleContext, fetchStateSymbol);
|
|
37
|
+
if (!state) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"FetchState not found on APIContext. `next(payload)` rewrites require a context created through Astro's request pipeline."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const manifest = state.manifest;
|
|
43
|
+
const { routeData, pathname } = await getEnvironment(manifest).tryRewrite(
|
|
44
|
+
manifest,
|
|
37
45
|
payload,
|
|
38
46
|
handleContext.request
|
|
39
47
|
);
|
|
40
|
-
if (
|
|
48
|
+
if (manifest.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) {
|
|
41
49
|
throw new AstroError({
|
|
42
50
|
...ForbiddenRewrite,
|
|
43
51
|
message: ForbiddenRewrite.message(
|
|
@@ -56,8 +64,8 @@ function sequence(...handlers) {
|
|
|
56
64
|
setOriginPathname(
|
|
57
65
|
handleContext.request,
|
|
58
66
|
oldPathname,
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
manifest.trailingSlash,
|
|
68
|
+
manifest.buildFormat
|
|
61
69
|
);
|
|
62
70
|
}
|
|
63
71
|
return applyHandle(i + 1, handleContext);
|
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
import type { APIContext } from '../../types/public/context.js';
|
|
2
|
-
import type { BaseApp } from '../app/base.js';
|
|
3
2
|
import type { FetchState } from '../fetch/fetch-state.js';
|
|
4
|
-
import type { Pipeline } from '../base-pipeline.js';
|
|
5
3
|
/**
|
|
6
4
|
* Handles dispatch of a matched route (endpoint / redirect / page / fallback)
|
|
7
5
|
* at the bottom of the middleware chain. This is a pure dispatch layer — it
|
|
8
6
|
* renders whatever route the `FetchState` currently points to without any
|
|
9
|
-
* rewrite logic. Rewrites are handled upstream: `
|
|
10
|
-
* `Astro.rewrite()` and `
|
|
7
|
+
* rewrite logic. Rewrites are handled upstream: `executeRewrite()` for
|
|
8
|
+
* `Astro.rewrite()` and `handleMiddleware` for `next(payload)`.
|
|
11
9
|
*
|
|
12
|
-
* `
|
|
13
|
-
* the end of the middleware chain.
|
|
14
|
-
*
|
|
15
|
-
* container also use `PagesHandler` directly for the same dispatch behavior.
|
|
10
|
+
* `handlePages` is the `next` callback that `handleMiddleware` invokes at
|
|
11
|
+
* the end of the middleware chain. Error handlers and the container also
|
|
12
|
+
* use it directly for the same dispatch behavior.
|
|
16
13
|
*/
|
|
17
|
-
export declare
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* there is no surrounding `AstroHandler` to supply this fallback.
|
|
31
|
-
*/
|
|
32
|
-
handleWithErrorFallback(app: BaseApp<Pipeline>, state: FetchState): Promise<Response>;
|
|
33
|
-
}
|
|
14
|
+
export declare function handlePages(state: FetchState, ctx: APIContext): Promise<Response>;
|
|
15
|
+
/**
|
|
16
|
+
* Like `handlePages`, but mirrors the app-level error handling that
|
|
17
|
+
* `handleRequest` provides on the standard path: unmatched routes
|
|
18
|
+
* return a 404 marked with `X-Astro-Error` for the app's post-check
|
|
19
|
+
* to render the 404 error page, and render-time errors are logged
|
|
20
|
+
* and render the 500 error page instead of propagating to the host
|
|
21
|
+
* framework.
|
|
22
|
+
*
|
|
23
|
+
* Used by the composable `astro/fetch` `pages()` entry point, where
|
|
24
|
+
* there is no surrounding `handleRequest` to supply this fallback.
|
|
25
|
+
*/
|
|
26
|
+
export declare function handlePagesWithErrorFallback(state: FetchState): Promise<Response>;
|
|
@@ -6,99 +6,83 @@ import {
|
|
|
6
6
|
isForbiddenCrossOriginRequest
|
|
7
7
|
} from "../app/origin-check.js";
|
|
8
8
|
import { getCookiesFromResponse } from "../cookies/response.js";
|
|
9
|
+
import { renderErrorFromState } from "../errors/handler.js";
|
|
9
10
|
const EMPTY_SLOTS = Object.freeze({});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
11
|
+
async function handlePages(state, ctx) {
|
|
12
|
+
const { logger, streaming } = state;
|
|
13
|
+
state.resetResponseMetadata();
|
|
14
|
+
let response;
|
|
15
|
+
const componentInstance = await state.loadComponentInstance();
|
|
16
|
+
switch (state.routeData.type) {
|
|
17
|
+
case "endpoint": {
|
|
18
|
+
response = await renderEndpoint(
|
|
19
|
+
componentInstance,
|
|
20
|
+
ctx,
|
|
21
|
+
state.routeData.prerender,
|
|
22
|
+
logger,
|
|
23
|
+
state
|
|
24
|
+
);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case "page": {
|
|
28
|
+
const props = await state.getProps();
|
|
29
|
+
const actionApiContext = state.getActionAPIContext();
|
|
30
|
+
const result = await state.createResult(componentInstance, actionApiContext);
|
|
31
|
+
try {
|
|
32
|
+
response = await renderPage(
|
|
33
|
+
result,
|
|
34
|
+
componentInstance?.default,
|
|
35
|
+
props,
|
|
36
|
+
state.slots ?? EMPTY_SLOTS,
|
|
37
|
+
streaming,
|
|
38
|
+
state.routeData
|
|
29
39
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const props = await state.getProps();
|
|
34
|
-
const actionApiContext = state.getActionAPIContext();
|
|
35
|
-
const result = await state.createResult(componentInstance, actionApiContext);
|
|
36
|
-
try {
|
|
37
|
-
response = await renderPage(
|
|
38
|
-
result,
|
|
39
|
-
componentInstance?.default,
|
|
40
|
-
props,
|
|
41
|
-
state.slots ?? EMPTY_SLOTS,
|
|
42
|
-
streaming,
|
|
43
|
-
state.routeData
|
|
44
|
-
);
|
|
45
|
-
} catch (e) {
|
|
46
|
-
result.cancelled = true;
|
|
47
|
-
throw e;
|
|
48
|
-
}
|
|
49
|
-
state.responseRouteType = "page";
|
|
50
|
-
if (state.routeData.route === "/404" || state.routeData.route === "/500") {
|
|
51
|
-
state.skipErrorReroute = true;
|
|
52
|
-
}
|
|
53
|
-
break;
|
|
40
|
+
} catch (e) {
|
|
41
|
+
result.cancelled = true;
|
|
42
|
+
throw e;
|
|
54
43
|
}
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
state.responseRouteType = "page";
|
|
45
|
+
if (state.routeData.route === "/404" || state.routeData.route === "/500") {
|
|
46
|
+
state.skipErrorReroute = true;
|
|
57
47
|
}
|
|
58
|
-
|
|
59
|
-
state.responseRouteType = "fallback";
|
|
60
|
-
return new Response(null, { status: 500 });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const responseCookies = getCookiesFromResponse(response);
|
|
64
|
-
if (responseCookies) {
|
|
65
|
-
state.cookies.merge(responseCookies);
|
|
48
|
+
break;
|
|
66
49
|
}
|
|
67
|
-
|
|
68
|
-
return response;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Like `handle`, but mirrors the app-level error handling that
|
|
72
|
-
* `AstroHandler` provides on the standard path: unmatched routes
|
|
73
|
-
* return a 404 marked with `X-Astro-Error` for the app's post-check
|
|
74
|
-
* to render the 404 error page, and render-time errors are logged
|
|
75
|
-
* and render the 500 error page instead of propagating to the host
|
|
76
|
-
* framework.
|
|
77
|
-
*
|
|
78
|
-
* Used by the composable `astro/fetch` `pages()` entry point, where
|
|
79
|
-
* there is no surrounding `AstroHandler` to supply this fallback.
|
|
80
|
-
*/
|
|
81
|
-
async handleWithErrorFallback(app, state) {
|
|
82
|
-
if (!state.routeData) {
|
|
50
|
+
case "redirect": {
|
|
83
51
|
return new Response(null, { status: 404, headers: { [ASTRO_ERROR_HEADER]: "true" } });
|
|
84
52
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
return await this.handle(state, ctx);
|
|
91
|
-
} catch (err) {
|
|
92
|
-
app.logger.error(null, err.stack || err.message || String(err));
|
|
93
|
-
return app.renderError(state.request, {
|
|
94
|
-
...state.renderOptions,
|
|
95
|
-
status: 500,
|
|
96
|
-
error: err,
|
|
97
|
-
pathname: state.pathname
|
|
98
|
-
});
|
|
53
|
+
case "fallback": {
|
|
54
|
+
state.responseRouteType = "fallback";
|
|
55
|
+
return new Response(null, { status: 500 });
|
|
99
56
|
}
|
|
100
57
|
}
|
|
58
|
+
const responseCookies = getCookiesFromResponse(response);
|
|
59
|
+
if (responseCookies) {
|
|
60
|
+
state.cookies.merge(responseCookies);
|
|
61
|
+
}
|
|
62
|
+
state.response = response;
|
|
63
|
+
return response;
|
|
64
|
+
}
|
|
65
|
+
async function handlePagesWithErrorFallback(state) {
|
|
66
|
+
if (!state.routeData) {
|
|
67
|
+
return new Response(null, { status: 404, headers: { [ASTRO_ERROR_HEADER]: "true" } });
|
|
68
|
+
}
|
|
69
|
+
const ctx = state.getAPIContext();
|
|
70
|
+
if (state.manifest.checkOrigin && isForbiddenCrossOriginRequest(ctx.request, ctx.url, ctx.isPrerendered)) {
|
|
71
|
+
return createCrossOriginForbiddenResponse(ctx.request);
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
return await handlePages(state, ctx);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
state.logger.error(null, err.stack || err.message || String(err));
|
|
77
|
+
return renderErrorFromState(state, state.request, {
|
|
78
|
+
...state.renderOptions,
|
|
79
|
+
status: 500,
|
|
80
|
+
error: err,
|
|
81
|
+
pathname: state.pathname
|
|
82
|
+
});
|
|
83
|
+
}
|
|
101
84
|
}
|
|
102
85
|
export {
|
|
103
|
-
|
|
86
|
+
handlePages,
|
|
87
|
+
handlePagesWithErrorFallback
|
|
104
88
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { markFeatureUsed, FetchFeatures } from "../fetch/features.js";
|
|
2
2
|
import { getRouteGenerator } from "../routing/generator.js";
|
|
3
3
|
function isExternalURL(url) {
|
|
4
4
|
return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//");
|
|
@@ -34,18 +34,13 @@ function resolveRedirectTarget(params, redirect, redirectRoute, trailingSlash) {
|
|
|
34
34
|
return redirect.destination;
|
|
35
35
|
}
|
|
36
36
|
async function renderRedirect(state) {
|
|
37
|
-
state.
|
|
37
|
+
markFeatureUsed(state.manifest, FetchFeatures.redirects);
|
|
38
38
|
const routeData = state.routeData;
|
|
39
39
|
const { redirect, redirectRoute } = routeData;
|
|
40
40
|
const status = computeRedirectStatus(state.request.method, redirect, redirectRoute);
|
|
41
41
|
const headers = {
|
|
42
42
|
location: encodeURI(
|
|
43
|
-
resolveRedirectTarget(
|
|
44
|
-
state.params,
|
|
45
|
-
redirect,
|
|
46
|
-
redirectRoute,
|
|
47
|
-
state.pipeline.manifest.trailingSlash
|
|
48
|
-
)
|
|
43
|
+
resolveRedirectTarget(state.params, redirect, redirectRoute, state.manifest.trailingSlash)
|
|
49
44
|
)
|
|
50
45
|
};
|
|
51
46
|
if (redirect && redirectIsExternal(redirect)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentInstance } from '../../types/astro.js';
|
|
2
2
|
import type { GetStaticPathsItem, GetStaticPathsResultKeyed, Params } from '../../types/public/common.js';
|
|
3
3
|
import type { AstroConfig, RuntimeMode } from '../../types/public/config.js';
|
|
4
|
-
import type { RouteData } from '../../types/public/internal.js';
|
|
4
|
+
import type { RouteData, SSRManifest } from '../../types/public/internal.js';
|
|
5
5
|
import type { AstroLogger } from '../logger/core.js';
|
|
6
6
|
interface CallGetStaticPathsOptions {
|
|
7
7
|
mod: ComponentInstance | undefined;
|
|
@@ -37,5 +37,10 @@ export declare class RouteCache {
|
|
|
37
37
|
get(route: RouteData): RouteCacheEntry | undefined;
|
|
38
38
|
key(route: RouteData): string;
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* The `RouteCache` for a manifest. Cleared via
|
|
42
|
+
* `getRouteCache(manifest).clearAll()` on dev `astro:content-changed`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getRouteCache(manifest: SSRManifest): RouteCache;
|
|
40
45
|
export declare function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, params: Params, route: RouteData, logger: AstroLogger, trailingSlash: AstroConfig['trailingSlash']): GetStaticPathsItem | undefined;
|
|
41
46
|
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { getEnvironment } from "../environment/index.js";
|
|
2
|
+
import { getLogger } from "../logger/manifest-logger.js";
|
|
3
|
+
import { createManifestMemo } from "../manifest/memo.js";
|
|
1
4
|
import { stringifyParams } from "../routing/params.js";
|
|
2
5
|
import { validateDynamicRouteModule, validateGetStaticPathsResult } from "../routing/validation.js";
|
|
3
6
|
import { generatePaginateFunction } from "./paginate.js";
|
|
@@ -68,6 +71,12 @@ class RouteCache {
|
|
|
68
71
|
return `${route.route}_${route.component}`;
|
|
69
72
|
}
|
|
70
73
|
}
|
|
74
|
+
const routeCaches = createManifestMemo(
|
|
75
|
+
(manifest) => new RouteCache(getLogger(manifest), getEnvironment(manifest).runtimeMode)
|
|
76
|
+
);
|
|
77
|
+
function getRouteCache(manifest) {
|
|
78
|
+
return routeCaches.get(manifest);
|
|
79
|
+
}
|
|
71
80
|
function findPathItemByKey(staticPaths, params, route, logger, trailingSlash) {
|
|
72
81
|
const paramsKey = stringifyParams(params, route, trailingSlash);
|
|
73
82
|
const matchedStaticPath = staticPaths.keyed.get(paramsKey);
|
|
@@ -79,5 +88,6 @@ function findPathItemByKey(staticPaths, params, route, logger, trailingSlash) {
|
|
|
79
88
|
export {
|
|
80
89
|
RouteCache,
|
|
81
90
|
callGetStaticPaths,
|
|
82
|
-
findPathItemByKey
|
|
91
|
+
findPathItemByKey,
|
|
92
|
+
getRouteCache
|
|
83
93
|
};
|