astro 6.0.0-alpha.2 → 6.0.0-alpha.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/cli/add/index.js +7 -10
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/config/entrypoint.d.ts +1 -0
- package/dist/config/entrypoint.js +2 -0
- package/dist/config/index.d.ts +3 -2
- package/dist/content/content-layer.js +3 -3
- package/dist/core/app/base.js +1 -1
- package/dist/core/app/dev/app.d.ts +6 -3
- package/dist/core/app/dev/app.js +6 -12
- package/dist/core/app/dev/pipeline.d.ts +6 -3
- package/dist/core/app/dev/pipeline.js +4 -4
- package/dist/core/app/types.d.ts +8 -4
- package/dist/core/base-pipeline.d.ts +5 -5
- package/dist/core/build/plugins/plugin-manifest.js +2 -1
- package/dist/core/config/schemas/base.d.ts +10 -20
- package/dist/core/config/schemas/base.js +2 -19
- package/dist/core/config/schemas/relative.d.ts +26 -25
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.d.ts +0 -8
- package/dist/core/messages.js +2 -13
- package/dist/core/preview/index.js +2 -13
- package/dist/core/render-context.d.ts +1 -1
- package/dist/core/render-context.js +7 -6
- package/dist/core/routing/helpers.d.ts +3 -0
- package/dist/core/routing/helpers.js +9 -0
- package/dist/core/session/config.d.ts +27 -0
- package/dist/core/session/config.js +33 -0
- package/dist/core/session/drivers.d.ts +34 -0
- package/dist/core/session/drivers.js +20 -0
- package/dist/core/{session.d.ts → session/runtime.d.ts} +13 -6
- package/dist/core/{session.js → session/runtime.js} +25 -19
- package/dist/core/session/types.d.ts +67 -0
- package/dist/core/session/types.js +0 -0
- package/dist/core/session/utils.d.ts +7 -0
- package/dist/core/session/utils.js +48 -0
- package/dist/core/session/vite-plugin.js +22 -27
- package/dist/manifest/serialized.js +2 -1
- package/dist/prerender/routing.d.ts +2 -2
- package/dist/runtime/server/render/page.js +2 -1
- package/dist/types/public/config.d.ts +22 -49
- package/dist/types/public/context.d.ts +1 -1
- package/dist/types/public/index.d.ts +2 -1
- package/dist/types/public/index.js +0 -4
- package/dist/types/public/preview.d.ts +1 -5
- package/dist/vite-plugin-app/app.d.ts +4 -20
- package/dist/vite-plugin-app/app.js +73 -231
- package/dist/vite-plugin-app/pipeline.d.ts +5 -2
- package/dist/vite-plugin-app/pipeline.js +4 -4
- package/dist/vite-plugin-astro-server/plugin.js +2 -1
- package/dist/vite-plugin-astro-server/response.d.ts +0 -1
- package/dist/vite-plugin-astro-server/response.js +1 -2
- package/dist/vite-plugin-environment/index.js +1 -0
- package/package.json +3 -3
|
@@ -2,23 +2,22 @@ import type { OutgoingHttpHeaders } from 'node:http';
|
|
|
2
2
|
import type { RemotePattern } from '@astrojs/internal-helpers/remote';
|
|
3
3
|
import type { RehypePlugins, RemarkPlugins, RemarkRehype, ShikiConfig, SyntaxHighlightConfigType } from '@astrojs/markdown-remark';
|
|
4
4
|
import type { Config as SvgoConfig } from 'svgo';
|
|
5
|
-
import type { BuiltinDriverName, BuiltinDriverOptions, Storage } from 'unstorage';
|
|
6
5
|
import type { UserConfig as OriginalViteUserConfig, SSROptions as ViteSSROptions } from 'vite';
|
|
7
6
|
import type { AstroFontProvider, FontFamily } from '../../assets/fonts/types.js';
|
|
8
7
|
import type { ImageFit, ImageLayout } from '../../assets/types.js';
|
|
9
8
|
import type { AssetsPrefix } from '../../core/app/types.js';
|
|
10
9
|
import type { AstroConfigType } from '../../core/config/schemas/index.js';
|
|
11
10
|
import type { REDIRECT_STATUS_CODES } from '../../core/constants.js';
|
|
12
|
-
import type { AstroCookieSetOptions } from '../../core/cookies/cookies.js';
|
|
13
11
|
import type { CspAlgorithm, CspDirective, CspHash } from '../../core/csp/config.js';
|
|
14
12
|
import type { LoggerLevel } from '../../core/logger/core.js';
|
|
13
|
+
import type { SessionConfig, SessionDriverConfig, SessionDriverName } from '../../core/session/types.js';
|
|
15
14
|
import type { EnvSchema } from '../../env/schema.js';
|
|
16
15
|
import type { AstroIntegration } from './integrations.js';
|
|
16
|
+
export type { AstroFontProvider as FontProvider };
|
|
17
17
|
export type Locales = (string | {
|
|
18
18
|
codes: [string, ...string[]];
|
|
19
19
|
path: string;
|
|
20
20
|
})[];
|
|
21
|
-
export type { AstroFontProvider as FontProvider };
|
|
22
21
|
export type { CspAlgorithm, CspHash };
|
|
23
22
|
export type { RemotePattern };
|
|
24
23
|
export type CspStyleDirective = {
|
|
@@ -114,39 +113,6 @@ export type ServerConfig = {
|
|
|
114
113
|
*/
|
|
115
114
|
open?: string | boolean;
|
|
116
115
|
};
|
|
117
|
-
export type SessionDriverName = BuiltinDriverName | 'custom' | 'test';
|
|
118
|
-
interface CommonSessionConfig {
|
|
119
|
-
/**
|
|
120
|
-
* Configures the session cookie. If set to a string, it will be used as the cookie name.
|
|
121
|
-
* Alternatively, you can pass an object with additional options.
|
|
122
|
-
*/
|
|
123
|
-
cookie?: string | (Omit<AstroCookieSetOptions, 'httpOnly' | 'expires' | 'encode'> & {
|
|
124
|
-
name?: string;
|
|
125
|
-
});
|
|
126
|
-
/**
|
|
127
|
-
* Default session duration in seconds. If not set, the session will be stored until deleted, or until the cookie expires.
|
|
128
|
-
*/
|
|
129
|
-
ttl?: number;
|
|
130
|
-
}
|
|
131
|
-
interface BuiltinSessionConfig<TDriver extends keyof BuiltinDriverOptions> extends CommonSessionConfig {
|
|
132
|
-
driver: TDriver;
|
|
133
|
-
options?: BuiltinDriverOptions[TDriver];
|
|
134
|
-
}
|
|
135
|
-
interface CustomSessionConfig extends CommonSessionConfig {
|
|
136
|
-
/** Entrypoint for a custom session driver */
|
|
137
|
-
driver?: string;
|
|
138
|
-
options?: Record<string, unknown>;
|
|
139
|
-
}
|
|
140
|
-
interface TestSessionConfig extends CommonSessionConfig {
|
|
141
|
-
driver: 'test';
|
|
142
|
-
options: {
|
|
143
|
-
mockStorage: Storage;
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
export type SessionConfig<TDriver extends SessionDriverName> = [
|
|
147
|
-
TDriver
|
|
148
|
-
] extends [never] ? CustomSessionConfig : TDriver extends keyof BuiltinDriverOptions ? BuiltinSessionConfig<TDriver> : TDriver extends 'test' ? TestSessionConfig : CustomSessionConfig;
|
|
149
|
-
export type ResolvedSessionConfig<TDriver extends SessionDriverName> = SessionConfig<TDriver>;
|
|
150
116
|
export interface ViteUserConfig extends OriginalViteUserConfig {
|
|
151
117
|
ssr?: ViteSSROptions;
|
|
152
118
|
}
|
|
@@ -156,7 +122,7 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
|
|
|
156
122
|
*
|
|
157
123
|
* Generics do not follow semver and may change at any time.
|
|
158
124
|
*/
|
|
159
|
-
export interface AstroUserConfig<TLocales extends Locales = never,
|
|
125
|
+
export interface AstroUserConfig<TLocales extends Locales = never, TDriver extends SessionDriverName | SessionDriverConfig = never> {
|
|
160
126
|
/**
|
|
161
127
|
* @docs
|
|
162
128
|
* @kind heading
|
|
@@ -833,7 +799,7 @@ export interface AstroUserConfig<TLocales extends Locales = never, TSession exte
|
|
|
833
799
|
* @version 6.0.0
|
|
834
800
|
* @description
|
|
835
801
|
*
|
|
836
|
-
* A configuration object that allows you to override the default sources for the `script-src` directive with the [`resources`](https://v6.docs.astro.build/en/reference/configuration-reference/#resources) property, or to provide additional [hashes](
|
|
802
|
+
* A configuration object that allows you to override the default sources for the `script-src` directive with the [`resources`](https://v6.docs.astro.build/en/reference/configuration-reference/#resources) property, or to provide additional [hashes](https://v6.docs.astro.build/en/reference/configuration-reference#hashes) to be rendered.
|
|
837
803
|
*/
|
|
838
804
|
scriptDirective?: {
|
|
839
805
|
/**
|
|
@@ -1311,33 +1277,36 @@ export interface AstroUserConfig<TLocales extends Locales = never, TSession exte
|
|
|
1311
1277
|
* }
|
|
1312
1278
|
* ```
|
|
1313
1279
|
*/
|
|
1314
|
-
session?: SessionConfig<
|
|
1280
|
+
session?: SessionConfig<TDriver>;
|
|
1315
1281
|
/**
|
|
1316
1282
|
* @docs
|
|
1317
1283
|
* @name session.driver
|
|
1318
|
-
* @type {
|
|
1284
|
+
* @type {SessionDriverConfig | undefined}
|
|
1319
1285
|
* @version 5.7.0
|
|
1320
1286
|
* @description
|
|
1321
1287
|
*
|
|
1322
|
-
* The
|
|
1288
|
+
* The driver to use for session storage. The [Node](https://docs.astro.build/en/guides/integrations-guide/node/#sessions),
|
|
1323
1289
|
* [Cloudflare](https://docs.astro.build/en/guides/integrations-guide/cloudflare/#sessions), and
|
|
1324
1290
|
* [Netlify](https://docs.astro.build/en/guides/integrations-guide/netlify/#sessions) adapters automatically configure a default driver for you,
|
|
1325
1291
|
* but you can specify your own if you would prefer or if you are using an adapter that does not provide one.
|
|
1326
1292
|
*
|
|
1327
|
-
*
|
|
1293
|
+
* ```js title="astro.config.mjs" ins={7-9} ins=" sessionDrivers "
|
|
1294
|
+
* import { defineConfig, sessionDrivers } from 'astro/config'
|
|
1295
|
+
* import vercel from '@astrojs/vercel'
|
|
1328
1296
|
*
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
* adapter: vercel(),
|
|
1297
|
+
* export default defineConfig({
|
|
1298
|
+
* adapter: vercel()
|
|
1332
1299
|
* session: {
|
|
1333
|
-
* driver:
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1300
|
+
* driver: sessionDrivers.redis({
|
|
1301
|
+
* url: process.env.REDIS_URL
|
|
1302
|
+
* }),
|
|
1303
|
+
* }
|
|
1304
|
+
* })
|
|
1336
1305
|
* ```
|
|
1306
|
+
*
|
|
1337
1307
|
* :::note
|
|
1338
1308
|
* Some drivers may need extra packages to be installed. Some drivers may also require environment variables or credentials to be set. See the [Unstorage documentation](https://unstorage.unjs.io/drivers) for more information.
|
|
1339
1309
|
* :::
|
|
1340
|
-
*
|
|
1341
1310
|
*/
|
|
1342
1311
|
/**
|
|
1343
1312
|
* @docs
|
|
@@ -1347,6 +1316,10 @@ export interface AstroUserConfig<TLocales extends Locales = never, TSession exte
|
|
|
1347
1316
|
* @default `{}`
|
|
1348
1317
|
* @description
|
|
1349
1318
|
*
|
|
1319
|
+
* :::caution[Deprecated]
|
|
1320
|
+
* This is deprecated and will be removed in a future major version. Instead, pass options to the driver function.
|
|
1321
|
+
* :::
|
|
1322
|
+
*
|
|
1350
1323
|
* The driver-specific options to use for session storage. The options depend on the driver you are using. See the [Unstorage documentation](https://unstorage.unjs.io/drivers)
|
|
1351
1324
|
* for more information on the options available for each driver.
|
|
1352
1325
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ActionClient, ActionReturnType } from '../../actions/runtime/types.js';
|
|
2
2
|
import type { AstroCookies } from '../../core/cookies/cookies.js';
|
|
3
3
|
import type { CspDirective, CspHash } from '../../core/csp/config.js';
|
|
4
|
-
import type { AstroSession } from '../../core/session.js';
|
|
4
|
+
import type { AstroSession } from '../../core/session/runtime.js';
|
|
5
5
|
import type { AstroComponentFactory } from '../../runtime/server/index.js';
|
|
6
6
|
import type { Params, RewritePayload } from './common.js';
|
|
7
7
|
import type { ValidRedirectStatus } from './config.js';
|
|
@@ -6,9 +6,10 @@ export type { ContainerRenderer } from '../../container/index.js';
|
|
|
6
6
|
export type { AssetsPrefix, NodeAppHeadersJson, RouteInfo, SSRManifest, } from '../../core/app/types.js';
|
|
7
7
|
export type { AstroCookieGetOptions, AstroCookieSetOptions, AstroCookies, } from '../../core/cookies/index.js';
|
|
8
8
|
export type { AstroIntegrationLogger } from '../../core/logger/core.js';
|
|
9
|
-
export { AstroSession } from '../../core/session.js';
|
|
9
|
+
export type { AstroSession } from '../../core/session/runtime.js';
|
|
10
10
|
export type { ToolbarServerHelpers } from '../../runtime/client/dev-toolbar/helpers.js';
|
|
11
11
|
export type { AstroEnvironmentNames } from '../../core/constants.js';
|
|
12
|
+
export type { SessionDriver, SessionDriverConfig } from '../../core/session/types.js';
|
|
12
13
|
export type * from './common.js';
|
|
13
14
|
export type * from './config.js';
|
|
14
15
|
export type * from './content.js';
|
|
@@ -9,17 +9,13 @@ export interface PreviewServer {
|
|
|
9
9
|
export interface PreviewServerParams {
|
|
10
10
|
outDir: URL;
|
|
11
11
|
client: URL;
|
|
12
|
+
server: URL;
|
|
12
13
|
serverEntrypoint: URL;
|
|
13
14
|
host: string | undefined;
|
|
14
15
|
port: number;
|
|
15
16
|
base: string;
|
|
16
17
|
logger: AstroIntegrationLogger;
|
|
17
18
|
headers?: OutgoingHttpHeaders;
|
|
18
|
-
/**
|
|
19
|
-
* DO NOT USE. This is for internal use only and might be removed soon.
|
|
20
|
-
* @deprecated
|
|
21
|
-
*/
|
|
22
|
-
createCodegenDir: () => URL;
|
|
23
19
|
root: URL;
|
|
24
20
|
}
|
|
25
21
|
export type CreatePreviewServer = (params: PreviewServerParams) => PreviewServer | Promise<PreviewServer>;
|
|
@@ -6,20 +6,19 @@ import type { CreateRenderContext, RenderContext } from '../core/render-context.
|
|
|
6
6
|
import type { AstroSettings, RoutesList } from '../types/astro.js';
|
|
7
7
|
import type { RouteData, SSRManifest } from '../types/public/index.js';
|
|
8
8
|
import type { DevServerController } from '../vite-plugin-astro-server/controller.js';
|
|
9
|
-
import {
|
|
10
|
-
export declare class AstroServerApp extends BaseApp<
|
|
9
|
+
import { RunnablePipeline } from './pipeline.js';
|
|
10
|
+
export declare class AstroServerApp extends BaseApp<RunnablePipeline> {
|
|
11
11
|
settings: AstroSettings;
|
|
12
12
|
logger: Logger;
|
|
13
13
|
loader: ModuleLoader;
|
|
14
14
|
manifestData: RoutesList;
|
|
15
15
|
currentRenderContext: RenderContext | undefined;
|
|
16
|
+
resolvedPathname: string | undefined;
|
|
16
17
|
constructor(manifest: SSRManifest, streaming: boolean | undefined, logger: Logger, manifestData: RoutesList, loader: ModuleLoader, settings: AstroSettings, getDebugInfo: () => Promise<string>);
|
|
17
18
|
static create(manifest: SSRManifest, routesList: RoutesList, logger: Logger, loader: ModuleLoader, settings: AstroSettings, getDebugInfo: () => Promise<string>): Promise<AstroServerApp>;
|
|
18
|
-
createPipeline(_streaming: boolean, manifest: SSRManifest, settings: AstroSettings, logger: Logger, loader: ModuleLoader, manifestData: RoutesList, getDebugInfo: () => Promise<string>):
|
|
19
|
+
createPipeline(_streaming: boolean, manifest: SSRManifest, settings: AstroSettings, logger: Logger, loader: ModuleLoader, manifestData: RoutesList, getDebugInfo: () => Promise<string>): RunnablePipeline;
|
|
19
20
|
createRenderContext(payload: CreateRenderContext): Promise<RenderContext>;
|
|
20
|
-
clearRouteCache(): void;
|
|
21
21
|
handleRequest({ controller, incomingRequest, incomingResponse, isHttps, }: HandleRequest): Promise<void>;
|
|
22
|
-
handleRoute({ matchedRoute, incomingRequest, incomingResponse, body, url, pathname, }: HandleRoute): Promise<void>;
|
|
23
22
|
match(request: Request, _allowPrerenderedRoutes: boolean): RouteData | undefined;
|
|
24
23
|
renderError(request: Request, { locals, skipMiddleware, error, clientAddress, status }: RenderErrorOptions): Promise<Response>;
|
|
25
24
|
}
|
|
@@ -29,19 +28,4 @@ type HandleRequest = {
|
|
|
29
28
|
incomingResponse: http.ServerResponse;
|
|
30
29
|
isHttps: boolean;
|
|
31
30
|
};
|
|
32
|
-
type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (...args: any) => Promise<infer R> ? R : any;
|
|
33
|
-
type HandleRoute = {
|
|
34
|
-
matchedRoute: AsyncReturnType<typeof matchRoute>;
|
|
35
|
-
url: URL;
|
|
36
|
-
pathname: string;
|
|
37
|
-
body: BodyInit | undefined;
|
|
38
|
-
incomingRequest: http.IncomingMessage;
|
|
39
|
-
incomingResponse: http.ServerResponse;
|
|
40
|
-
};
|
|
41
|
-
interface MatchedRoute {
|
|
42
|
-
route: RouteData;
|
|
43
|
-
filePath: URL;
|
|
44
|
-
resolvedPathname: string;
|
|
45
|
-
}
|
|
46
|
-
declare function matchRoute(pathname: string, routesList: RoutesList, pipeline: AstroServerPipeline, manifest: SSRManifest): Promise<MatchedRoute | undefined>;
|
|
47
31
|
export {};
|
|
@@ -1,41 +1,29 @@
|
|
|
1
1
|
import { prependForwardSlash, removeTrailingForwardSlash } from "@astrojs/internal-helpers/path";
|
|
2
2
|
import { BaseApp } from "../core/app/index.js";
|
|
3
3
|
import { shouldAppendForwardSlash } from "../core/build/util.js";
|
|
4
|
-
import {
|
|
5
|
-
clientLocalsSymbol,
|
|
6
|
-
DEFAULT_404_COMPONENT,
|
|
7
|
-
NOOP_MIDDLEWARE_HEADER,
|
|
8
|
-
REROUTE_DIRECTIVE_HEADER,
|
|
9
|
-
REWRITE_DIRECTIVE_HEADER_KEY
|
|
10
|
-
} from "../core/constants.js";
|
|
4
|
+
import { clientLocalsSymbol } from "../core/constants.js";
|
|
11
5
|
import {
|
|
12
6
|
MiddlewareNoDataOrNextCalled,
|
|
13
7
|
MiddlewareNotAResponse,
|
|
14
8
|
NoMatchingStaticPathFound
|
|
15
9
|
} from "../core/errors/errors-data.js";
|
|
16
10
|
import { createSafeError, isAstroError } from "../core/errors/index.js";
|
|
17
|
-
import { req } from "../core/messages.js";
|
|
18
11
|
import { getProps } from "../core/render/index.js";
|
|
19
12
|
import { createRequest } from "../core/request.js";
|
|
20
|
-
import {
|
|
21
|
-
import { matchAllRoutes, routeIsRedirect } from "../core/routing/index.js";
|
|
22
|
-
import { isRoute404, isRoute500 } from "../core/routing/match.js";
|
|
23
|
-
import { PERSIST_SYMBOL } from "../core/session.js";
|
|
13
|
+
import { matchAllRoutes } from "../core/routing/index.js";
|
|
24
14
|
import { getSortedPreloadedMatches } from "../prerender/routing.js";
|
|
25
15
|
import { recordServerError } from "../vite-plugin-astro-server/error.js";
|
|
26
16
|
import { runWithErrorHandling } from "../vite-plugin-astro-server/index.js";
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
writeWebResponse
|
|
31
|
-
} from "../vite-plugin-astro-server/response.js";
|
|
32
|
-
import { AstroServerPipeline } from "./pipeline.js";
|
|
17
|
+
import { handle500Response, writeSSRResult } from "../vite-plugin-astro-server/response.js";
|
|
18
|
+
import { RunnablePipeline } from "./pipeline.js";
|
|
19
|
+
import { getCustom404Route, getCustom500Route } from "../core/routing/helpers.js";
|
|
33
20
|
class AstroServerApp extends BaseApp {
|
|
34
21
|
settings;
|
|
35
22
|
logger;
|
|
36
23
|
loader;
|
|
37
24
|
manifestData;
|
|
38
25
|
currentRenderContext = void 0;
|
|
26
|
+
resolvedPathname = void 0;
|
|
39
27
|
constructor(manifest, streaming = true, logger, manifestData, loader, settings, getDebugInfo) {
|
|
40
28
|
super(manifest, streaming, settings, logger, loader, manifestData, getDebugInfo);
|
|
41
29
|
this.settings = settings;
|
|
@@ -47,7 +35,7 @@ class AstroServerApp extends BaseApp {
|
|
|
47
35
|
return new AstroServerApp(manifest, true, logger, routesList, loader, settings, getDebugInfo);
|
|
48
36
|
}
|
|
49
37
|
createPipeline(_streaming, manifest, settings, logger, loader, manifestData, getDebugInfo) {
|
|
50
|
-
return
|
|
38
|
+
return RunnablePipeline.create(manifestData, {
|
|
51
39
|
loader,
|
|
52
40
|
logger,
|
|
53
41
|
manifest,
|
|
@@ -56,12 +44,12 @@ class AstroServerApp extends BaseApp {
|
|
|
56
44
|
});
|
|
57
45
|
}
|
|
58
46
|
async createRenderContext(payload) {
|
|
59
|
-
this.currentRenderContext = await super.createRenderContext(
|
|
47
|
+
this.currentRenderContext = await super.createRenderContext({
|
|
48
|
+
...payload,
|
|
49
|
+
pathname: this.resolvedPathname ?? payload.pathname
|
|
50
|
+
});
|
|
60
51
|
return this.currentRenderContext;
|
|
61
52
|
}
|
|
62
|
-
clearRouteCache() {
|
|
63
|
-
this.pipeline.clearRouteCache();
|
|
64
|
-
}
|
|
65
53
|
async handleRequest({
|
|
66
54
|
controller,
|
|
67
55
|
incomingRequest,
|
|
@@ -102,15 +90,30 @@ class AstroServerApp extends BaseApp {
|
|
|
102
90
|
self.pipeline,
|
|
103
91
|
self.manifest
|
|
104
92
|
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
if (!matchedRoute) {
|
|
94
|
+
throw new Error("No route matched, and default 404 route was not found.");
|
|
95
|
+
}
|
|
96
|
+
self.resolvedPathname = matchedRoute.resolvedPathname;
|
|
97
|
+
const request = createRequest({
|
|
108
98
|
url,
|
|
109
|
-
|
|
99
|
+
headers: incomingRequest.headers,
|
|
100
|
+
method: incomingRequest.method,
|
|
110
101
|
body,
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
logger: self.logger,
|
|
103
|
+
isPrerendered: matchedRoute?.route.prerender,
|
|
104
|
+
routePattern: matchedRoute?.route.component
|
|
105
|
+
});
|
|
106
|
+
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);
|
|
107
|
+
for (const [name, value] of Object.entries(self.settings.config.server.headers ?? {})) {
|
|
108
|
+
if (value) incomingResponse.setHeader(name, value);
|
|
109
|
+
}
|
|
110
|
+
const clientAddress = incomingRequest.socket.remoteAddress;
|
|
111
|
+
const response = await self.render(request, {
|
|
112
|
+
locals,
|
|
113
|
+
routeData: matchedRoute.route,
|
|
114
|
+
clientAddress
|
|
113
115
|
});
|
|
116
|
+
await writeSSRResult(request, response, incomingResponse);
|
|
114
117
|
},
|
|
115
118
|
onError(_err) {
|
|
116
119
|
const error = createSafeError(_err);
|
|
@@ -127,161 +130,6 @@ class AstroServerApp extends BaseApp {
|
|
|
127
130
|
}
|
|
128
131
|
});
|
|
129
132
|
}
|
|
130
|
-
async handleRoute({
|
|
131
|
-
matchedRoute,
|
|
132
|
-
incomingRequest,
|
|
133
|
-
incomingResponse,
|
|
134
|
-
body,
|
|
135
|
-
url,
|
|
136
|
-
pathname
|
|
137
|
-
}) {
|
|
138
|
-
const timeStart = performance.now();
|
|
139
|
-
const { logger } = this.pipeline;
|
|
140
|
-
if (!matchedRoute) {
|
|
141
|
-
throw new Error("No route matched, and default 404 route was not found.");
|
|
142
|
-
}
|
|
143
|
-
let request;
|
|
144
|
-
let renderContext;
|
|
145
|
-
let route = matchedRoute.route;
|
|
146
|
-
const componentInstance = await this.pipeline.getComponentByRoute(route);
|
|
147
|
-
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);
|
|
148
|
-
request = createRequest({
|
|
149
|
-
url,
|
|
150
|
-
headers: incomingRequest.headers,
|
|
151
|
-
method: incomingRequest.method,
|
|
152
|
-
body,
|
|
153
|
-
logger,
|
|
154
|
-
isPrerendered: route.prerender,
|
|
155
|
-
routePattern: route.component
|
|
156
|
-
});
|
|
157
|
-
for (const [name, value] of Object.entries(this.settings.config.server.headers ?? {})) {
|
|
158
|
-
if (value) incomingResponse.setHeader(name, value);
|
|
159
|
-
}
|
|
160
|
-
renderContext = await this.createRenderContext({
|
|
161
|
-
locals,
|
|
162
|
-
pipeline: this.pipeline,
|
|
163
|
-
pathname,
|
|
164
|
-
skipMiddleware: isDefaultPrerendered404(matchedRoute.route),
|
|
165
|
-
request,
|
|
166
|
-
routeData: route,
|
|
167
|
-
clientAddress: incomingRequest.socket.remoteAddress,
|
|
168
|
-
shouldInjectCspMetaTags: false
|
|
169
|
-
});
|
|
170
|
-
let response;
|
|
171
|
-
let statusCode = 200;
|
|
172
|
-
let isReroute = false;
|
|
173
|
-
let isRewrite = false;
|
|
174
|
-
try {
|
|
175
|
-
response = await renderContext.render(componentInstance);
|
|
176
|
-
isReroute = response.headers.has(REROUTE_DIRECTIVE_HEADER);
|
|
177
|
-
isRewrite = response.headers.has(REWRITE_DIRECTIVE_HEADER_KEY);
|
|
178
|
-
const statusCodedMatched = getStatusByMatchedRoute(route);
|
|
179
|
-
statusCode = isRewrite ? (
|
|
180
|
-
// Ignore `matchedRoute` status for rewrites
|
|
181
|
-
response.status
|
|
182
|
-
) : (
|
|
183
|
-
// Our internal noop middleware sets a particular header. If the header isn't present, it means that the user have
|
|
184
|
-
// their own middleware, so we need to return what the user returns.
|
|
185
|
-
!response.headers.has(NOOP_MIDDLEWARE_HEADER) && !isReroute ? response.status : statusCodedMatched ?? response.status
|
|
186
|
-
);
|
|
187
|
-
} catch (err) {
|
|
188
|
-
response = await this.renderError(request, {
|
|
189
|
-
skipMiddleware: false,
|
|
190
|
-
locals,
|
|
191
|
-
status: 500,
|
|
192
|
-
prerenderedErrorPageFetch: fetch,
|
|
193
|
-
clientAddress: incomingRequest.socket.remoteAddress,
|
|
194
|
-
error: err
|
|
195
|
-
});
|
|
196
|
-
statusCode = 500;
|
|
197
|
-
} finally {
|
|
198
|
-
this.currentRenderContext?.session?.[PERSIST_SYMBOL]();
|
|
199
|
-
}
|
|
200
|
-
if (isLoggedRequest(pathname)) {
|
|
201
|
-
const timeEnd = performance.now();
|
|
202
|
-
logger.info(
|
|
203
|
-
null,
|
|
204
|
-
req({
|
|
205
|
-
url: pathname,
|
|
206
|
-
method: incomingRequest.method,
|
|
207
|
-
statusCode,
|
|
208
|
-
isRewrite,
|
|
209
|
-
reqTime: timeEnd - timeStart
|
|
210
|
-
})
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
if (statusCode === 404 && // If the body isn't null, that means the user sets the 404 status
|
|
214
|
-
// but uses the current route to handle the 404
|
|
215
|
-
response.body === null && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
|
|
216
|
-
const fourOhFourRoute = await matchRoute(
|
|
217
|
-
"/404",
|
|
218
|
-
this.manifestData,
|
|
219
|
-
this.pipeline,
|
|
220
|
-
this.manifest
|
|
221
|
-
);
|
|
222
|
-
if (fourOhFourRoute) {
|
|
223
|
-
renderContext = await this.createRenderContext({
|
|
224
|
-
locals,
|
|
225
|
-
pipeline: this.pipeline,
|
|
226
|
-
pathname,
|
|
227
|
-
skipMiddleware: isDefaultPrerendered404(fourOhFourRoute.route),
|
|
228
|
-
request,
|
|
229
|
-
routeData: fourOhFourRoute.route,
|
|
230
|
-
clientAddress: incomingRequest.socket.remoteAddress,
|
|
231
|
-
status: 404,
|
|
232
|
-
shouldInjectCspMetaTags: false
|
|
233
|
-
});
|
|
234
|
-
const component = await this.pipeline.preload(
|
|
235
|
-
fourOhFourRoute.route,
|
|
236
|
-
fourOhFourRoute.filePath
|
|
237
|
-
);
|
|
238
|
-
response = await renderContext.render(component);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (isReroute) {
|
|
242
|
-
response.headers.delete(REROUTE_DIRECTIVE_HEADER);
|
|
243
|
-
}
|
|
244
|
-
if (isRewrite) {
|
|
245
|
-
response.headers.delete(REROUTE_DIRECTIVE_HEADER);
|
|
246
|
-
}
|
|
247
|
-
if (route.type === "endpoint") {
|
|
248
|
-
await writeWebResponse(incomingResponse, response);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
if (isRewrite) {
|
|
252
|
-
await writeSSRResult(request, response, incomingResponse);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
if (response.status < 400 && response.status >= 300) {
|
|
256
|
-
if (response.status >= 300 && response.status < 400 && routeIsRedirect(route) && !this.settings.config.build.redirects && this.settings.buildOutput === "static") {
|
|
257
|
-
const location = response.headers.get("location");
|
|
258
|
-
response = new Response(
|
|
259
|
-
redirectTemplate({
|
|
260
|
-
status: response.status,
|
|
261
|
-
absoluteLocation: location,
|
|
262
|
-
relativeLocation: location,
|
|
263
|
-
from: pathname
|
|
264
|
-
}),
|
|
265
|
-
{
|
|
266
|
-
status: 200,
|
|
267
|
-
headers: {
|
|
268
|
-
...response.headers,
|
|
269
|
-
"content-type": "text/html"
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
await writeSSRResult(request, response, incomingResponse);
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (response.status !== statusCode) {
|
|
278
|
-
response = new Response(response.body, {
|
|
279
|
-
status: statusCode,
|
|
280
|
-
headers: response.headers
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
await writeSSRResult(request, response, incomingResponse);
|
|
284
|
-
}
|
|
285
133
|
match(request, _allowPrerenderedRoutes) {
|
|
286
134
|
const url = new URL(request.url);
|
|
287
135
|
if (this.manifest.assets.has(url.pathname)) return void 0;
|
|
@@ -294,53 +142,53 @@ class AstroServerApp extends BaseApp {
|
|
|
294
142
|
if (isAstroError(error) && [MiddlewareNoDataOrNextCalled.name, MiddlewareNotAResponse.name].includes(error.name)) {
|
|
295
143
|
throw error;
|
|
296
144
|
}
|
|
145
|
+
const renderRoute = async (routeData) => {
|
|
146
|
+
try {
|
|
147
|
+
const preloadedComponent = await this.pipeline.getComponentByRoute(routeData);
|
|
148
|
+
const renderContext = await this.createRenderContext({
|
|
149
|
+
locals,
|
|
150
|
+
pipeline: this.pipeline,
|
|
151
|
+
pathname: this.getPathnameFromRequest(request),
|
|
152
|
+
skipMiddleware,
|
|
153
|
+
request,
|
|
154
|
+
routeData,
|
|
155
|
+
clientAddress,
|
|
156
|
+
status,
|
|
157
|
+
shouldInjectCspMetaTags: false
|
|
158
|
+
});
|
|
159
|
+
renderContext.props.error = error;
|
|
160
|
+
const response = await renderContext.render(preloadedComponent);
|
|
161
|
+
if (error) {
|
|
162
|
+
this.logger.error("router", error.stack || error.message);
|
|
163
|
+
}
|
|
164
|
+
return response;
|
|
165
|
+
} catch (_err) {
|
|
166
|
+
if (skipMiddleware === false) {
|
|
167
|
+
return this.renderError(request, {
|
|
168
|
+
clientAddress: void 0,
|
|
169
|
+
prerenderedErrorPageFetch: fetch,
|
|
170
|
+
status: 500,
|
|
171
|
+
skipMiddleware: true,
|
|
172
|
+
error: _err
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
throw _err;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
if (status === 404) {
|
|
179
|
+
const custom404 = getCustom404Route(this.manifestData);
|
|
180
|
+
if (custom404) {
|
|
181
|
+
return renderRoute(custom404);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
297
184
|
const custom500 = getCustom500Route(this.manifestData);
|
|
298
185
|
if (!custom500) {
|
|
299
186
|
throw error;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const filePath500 = new URL(`./${custom500.component}`, this.manifest.rootDir);
|
|
303
|
-
const preloaded500Component = await this.pipeline.preload(custom500, filePath500);
|
|
304
|
-
const renderContext = await this.createRenderContext({
|
|
305
|
-
locals,
|
|
306
|
-
pipeline: this.pipeline,
|
|
307
|
-
pathname: this.getPathnameFromRequest(request),
|
|
308
|
-
skipMiddleware,
|
|
309
|
-
request,
|
|
310
|
-
routeData: custom500,
|
|
311
|
-
clientAddress,
|
|
312
|
-
status,
|
|
313
|
-
shouldInjectCspMetaTags: false
|
|
314
|
-
});
|
|
315
|
-
renderContext.props.error = error;
|
|
316
|
-
const response = await renderContext.render(preloaded500Component);
|
|
317
|
-
this.logger.error("router", error.stack || error.message);
|
|
318
|
-
return response;
|
|
319
|
-
} catch (_err) {
|
|
320
|
-
if (skipMiddleware === false) {
|
|
321
|
-
return this.renderError(request, {
|
|
322
|
-
clientAddress: void 0,
|
|
323
|
-
prerenderedErrorPageFetch: fetch,
|
|
324
|
-
status: 500,
|
|
325
|
-
skipMiddleware: true,
|
|
326
|
-
error: _err
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
throw _err;
|
|
187
|
+
} else {
|
|
188
|
+
return renderRoute(custom500);
|
|
330
189
|
}
|
|
331
190
|
}
|
|
332
191
|
}
|
|
333
|
-
function getStatusByMatchedRoute(route) {
|
|
334
|
-
if (route.route === "/404") return 404;
|
|
335
|
-
if (route.route === "/500") return 500;
|
|
336
|
-
return void 0;
|
|
337
|
-
}
|
|
338
|
-
function isDefaultPrerendered404(route) {
|
|
339
|
-
return route.route === "/404" && route.prerender && route.component === DEFAULT_404_COMPONENT;
|
|
340
|
-
}
|
|
341
|
-
function isLoggedRequest(url) {
|
|
342
|
-
return url !== "/favicon.ico";
|
|
343
|
-
}
|
|
344
192
|
async function matchRoute(pathname, routesList, pipeline, manifest) {
|
|
345
193
|
const { logger, routeCache } = pipeline;
|
|
346
194
|
const matches = matchAllRoutes(pathname, routesList);
|
|
@@ -399,12 +247,6 @@ ${NoMatchingStaticPathFound.hint(possibleRoutes)}`
|
|
|
399
247
|
}
|
|
400
248
|
return void 0;
|
|
401
249
|
}
|
|
402
|
-
function getCustom404Route(manifestData) {
|
|
403
|
-
return manifestData.routes.find((r) => isRoute404(r.route));
|
|
404
|
-
}
|
|
405
|
-
function getCustom500Route(manifestData) {
|
|
406
|
-
return manifestData.routes.find((r) => isRoute500(r.route));
|
|
407
|
-
}
|
|
408
250
|
export {
|
|
409
251
|
AstroServerApp
|
|
410
252
|
};
|
|
@@ -3,7 +3,10 @@ import type { Logger } from '../core/logger/core.js';
|
|
|
3
3
|
import type { ModuleLoader } from '../core/module-loader/index.js';
|
|
4
4
|
import type { AstroSettings, ComponentInstance, RoutesList } from '../types/astro.js';
|
|
5
5
|
import type { RewritePayload, RouteData, SSRLoadedRenderer, SSRManifest } from '../types/public/index.js';
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* This Pipeline is used when the Vite SSR environment is runnable.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RunnablePipeline extends Pipeline {
|
|
7
10
|
readonly loader: ModuleLoader;
|
|
8
11
|
readonly logger: Logger;
|
|
9
12
|
readonly manifest: SSRManifest;
|
|
@@ -20,7 +23,7 @@ export declare class AstroServerPipeline extends Pipeline {
|
|
|
20
23
|
routesList: RoutesList | undefined;
|
|
21
24
|
componentInterner: WeakMap<RouteData, ComponentInstance>;
|
|
22
25
|
private constructor();
|
|
23
|
-
static create(manifestData: RoutesList, { loader, logger, manifest, settings, getDebugInfo, }: Pick<
|
|
26
|
+
static create(manifestData: RoutesList, { loader, logger, manifest, settings, getDebugInfo, }: Pick<RunnablePipeline, 'loader' | 'logger' | 'manifest' | 'settings' | 'getDebugInfo'>): RunnablePipeline;
|
|
24
27
|
headElements(routeData: RouteData): Promise<HeadElements>;
|
|
25
28
|
componentMetadata(routeData: RouteData): Promise<Map<string, import("../types/public/internal.js").SSRComponentMetadata>>;
|
|
26
29
|
preload(routeData: RouteData, filePath: URL): Promise<ComponentInstance>;
|
|
@@ -14,7 +14,7 @@ import { getComponentMetadata } from "../vite-plugin-astro-server/metadata.js";
|
|
|
14
14
|
import { createResolve } from "../vite-plugin-astro-server/resolve.js";
|
|
15
15
|
import { PAGE_SCRIPT_ID } from "../vite-plugin-scripts/index.js";
|
|
16
16
|
import { getDevCSSModuleName } from "../vite-plugin-css/util.js";
|
|
17
|
-
class
|
|
17
|
+
class RunnablePipeline extends Pipeline {
|
|
18
18
|
constructor(loader, logger, manifest, settings, getDebugInfo, defaultRoutes = createDefaultRoutes(manifest)) {
|
|
19
19
|
const resolve = createResolve(loader, manifest.rootDir);
|
|
20
20
|
const streaming = true;
|
|
@@ -27,7 +27,7 @@ class AstroServerPipeline extends Pipeline {
|
|
|
27
27
|
this.defaultRoutes = defaultRoutes;
|
|
28
28
|
}
|
|
29
29
|
getName() {
|
|
30
|
-
return "
|
|
30
|
+
return "RunnablePipeline";
|
|
31
31
|
}
|
|
32
32
|
// renderers are loaded on every request,
|
|
33
33
|
// so it needs to be mutable here unlike in other environments
|
|
@@ -41,7 +41,7 @@ class AstroServerPipeline extends Pipeline {
|
|
|
41
41
|
settings,
|
|
42
42
|
getDebugInfo
|
|
43
43
|
}) {
|
|
44
|
-
const pipeline = new
|
|
44
|
+
const pipeline = new RunnablePipeline(loader, logger, manifest, settings, getDebugInfo);
|
|
45
45
|
pipeline.routesList = manifestData;
|
|
46
46
|
return pipeline;
|
|
47
47
|
}
|
|
@@ -162,5 +162,5 @@ class AstroServerPipeline extends Pipeline {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
export {
|
|
165
|
-
|
|
165
|
+
RunnablePipeline
|
|
166
166
|
};
|