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.
Files changed (54) hide show
  1. package/dist/cli/add/index.js +7 -10
  2. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  3. package/dist/config/entrypoint.d.ts +1 -0
  4. package/dist/config/entrypoint.js +2 -0
  5. package/dist/config/index.d.ts +3 -2
  6. package/dist/content/content-layer.js +3 -3
  7. package/dist/core/app/base.js +1 -1
  8. package/dist/core/app/dev/app.d.ts +6 -3
  9. package/dist/core/app/dev/app.js +6 -12
  10. package/dist/core/app/dev/pipeline.d.ts +6 -3
  11. package/dist/core/app/dev/pipeline.js +4 -4
  12. package/dist/core/app/types.d.ts +8 -4
  13. package/dist/core/base-pipeline.d.ts +5 -5
  14. package/dist/core/build/plugins/plugin-manifest.js +2 -1
  15. package/dist/core/config/schemas/base.d.ts +10 -20
  16. package/dist/core/config/schemas/base.js +2 -19
  17. package/dist/core/config/schemas/relative.d.ts +26 -25
  18. package/dist/core/constants.js +1 -1
  19. package/dist/core/dev/dev.js +1 -1
  20. package/dist/core/messages.d.ts +0 -8
  21. package/dist/core/messages.js +2 -13
  22. package/dist/core/preview/index.js +2 -13
  23. package/dist/core/render-context.d.ts +1 -1
  24. package/dist/core/render-context.js +7 -6
  25. package/dist/core/routing/helpers.d.ts +3 -0
  26. package/dist/core/routing/helpers.js +9 -0
  27. package/dist/core/session/config.d.ts +27 -0
  28. package/dist/core/session/config.js +33 -0
  29. package/dist/core/session/drivers.d.ts +34 -0
  30. package/dist/core/session/drivers.js +20 -0
  31. package/dist/core/{session.d.ts → session/runtime.d.ts} +13 -6
  32. package/dist/core/{session.js → session/runtime.js} +25 -19
  33. package/dist/core/session/types.d.ts +67 -0
  34. package/dist/core/session/types.js +0 -0
  35. package/dist/core/session/utils.d.ts +7 -0
  36. package/dist/core/session/utils.js +48 -0
  37. package/dist/core/session/vite-plugin.js +22 -27
  38. package/dist/manifest/serialized.js +2 -1
  39. package/dist/prerender/routing.d.ts +2 -2
  40. package/dist/runtime/server/render/page.js +2 -1
  41. package/dist/types/public/config.d.ts +22 -49
  42. package/dist/types/public/context.d.ts +1 -1
  43. package/dist/types/public/index.d.ts +2 -1
  44. package/dist/types/public/index.js +0 -4
  45. package/dist/types/public/preview.d.ts +1 -5
  46. package/dist/vite-plugin-app/app.d.ts +4 -20
  47. package/dist/vite-plugin-app/app.js +73 -231
  48. package/dist/vite-plugin-app/pipeline.d.ts +5 -2
  49. package/dist/vite-plugin-app/pipeline.js +4 -4
  50. package/dist/vite-plugin-astro-server/plugin.js +2 -1
  51. package/dist/vite-plugin-astro-server/response.d.ts +0 -1
  52. package/dist/vite-plugin-astro-server/response.js +1 -2
  53. package/dist/vite-plugin-environment/index.js +1 -0
  54. package/package.json +3 -3
@@ -4,11 +4,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import { AstroIntegrationLogger } from "../../core/logger/core.js";
5
5
  import { telemetry } from "../../events/index.js";
6
6
  import { eventCliSession } from "../../events/session.js";
7
- import {
8
- normalizeCodegenDir,
9
- runHookConfigDone,
10
- runHookConfigSetup
11
- } from "../../integrations/hooks.js";
7
+ import { runHookConfigDone, runHookConfigSetup } from "../../integrations/hooks.js";
12
8
  import { resolveConfig } from "../config/config.js";
13
9
  import { createNodeLogger } from "../config/logging.js";
14
10
  import { createSettings } from "../config/settings.js";
@@ -62,20 +58,13 @@ async function preview(inlineConfig) {
62
58
  const server = await previewModule.default({
63
59
  outDir: settings.config.outDir,
64
60
  client: settings.config.build.client,
61
+ server: settings.config.build.server,
65
62
  serverEntrypoint: new URL(settings.config.build.serverEntry, settings.config.build.server),
66
63
  host: getResolvedHostForHttpServer(settings.config.server.host),
67
64
  port: settings.config.server.port,
68
65
  base: settings.config.base,
69
66
  logger: new AstroIntegrationLogger(logger.options, settings.adapter.name),
70
67
  headers: settings.config.server.headers,
71
- createCodegenDir: () => {
72
- const codegenDir = new URL(
73
- normalizeCodegenDir(settings.adapter ? settings.adapter.name : "_temp"),
74
- settings.dotAstroDir
75
- );
76
- fs.mkdirSync(codegenDir, { recursive: true });
77
- return codegenDir;
78
- },
79
68
  root: settings.config.root
80
69
  });
81
70
  return server;
@@ -6,7 +6,7 @@ import type { RouteData, SSRResult } from '../types/public/internal.js';
6
6
  import type { ServerIslandMappings, SSRActions } from './app/types.js';
7
7
  import { AstroCookies } from './cookies/index.js';
8
8
  import { type Pipeline } from './render/index.js';
9
- import { AstroSession } from './session.js';
9
+ import { AstroSession } from './session/runtime.js';
10
10
  /**
11
11
  * Each request is rendered using a `RenderContext`.
12
12
  * It contains data unique to each request. It is responsible for executing middleware, calling endpoints, and rendering the page by gathering necessary data from a `Pipeline`.
@@ -30,7 +30,7 @@ import { renderRedirect } from "./redirects/render.js";
30
30
  import { getParams, getProps, Slots } from "./render/index.js";
31
31
  import { isRoute404or500, isRouteExternalRedirect, isRouteServerIsland } from "./routing/match.js";
32
32
  import { copyRequest, getOriginPathname, setOriginPathname } from "./routing/rewrite.js";
33
- import { AstroSession } from "./session.js";
33
+ import { AstroSession } from "./session/runtime.js";
34
34
  import { validateAndDecodePathname } from "./util/pathname.js";
35
35
  class RenderContext {
36
36
  constructor(pipeline, locals, middleware, actions, serverIslands, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = RenderContext.#createNormalizedUrl(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = !!pipeline.manifest.csp, session = void 0, skipMiddleware = false) {
@@ -98,12 +98,13 @@ class RenderContext {
98
98
  pipeline.manifest.buildFormat
99
99
  );
100
100
  const cookies = new AstroCookies(request);
101
- const session = pipeline.manifest.sessionConfig && pipelineSessionDriver ? new AstroSession(
101
+ const session = pipeline.manifest.sessionConfig && pipelineSessionDriver ? new AstroSession({
102
102
  cookies,
103
- pipeline.manifest.sessionConfig,
104
- pipeline.runtimeMode,
105
- pipelineSessionDriver
106
- ) : void 0;
103
+ config: pipeline.manifest.sessionConfig,
104
+ runtimeMode: pipeline.runtimeMode,
105
+ driverFactory: pipelineSessionDriver,
106
+ mockStorage: null
107
+ }) : void 0;
107
108
  return new RenderContext(
108
109
  pipeline,
109
110
  locals,
@@ -1,5 +1,6 @@
1
1
  import type { RouteData } from '../../types/public/internal.js';
2
2
  import type { RouteInfo } from '../app/types.js';
3
+ import type { RoutesList } from '../../types/astro.js';
3
4
  type RedirectRouteData = RouteData & {
4
5
  redirect: string;
5
6
  };
@@ -19,4 +20,6 @@ export declare function routeIsFallback(route: RouteData | undefined): boolean;
19
20
  * @param routeList
20
21
  */
21
22
  export declare function getFallbackRoute(route: RouteData, routeList: RouteInfo[]): RouteData;
23
+ export declare function getCustom404Route(manifestData: RoutesList): RouteData | undefined;
24
+ export declare function getCustom500Route(manifestData: RoutesList): RouteData | undefined;
22
25
  export {};
@@ -1,3 +1,4 @@
1
+ import { isRoute404, isRoute500 } from "./match.js";
1
2
  function routeIsRedirect(route) {
2
3
  return route?.type === "redirect";
3
4
  }
@@ -18,7 +19,15 @@ function getFallbackRoute(route, routeList) {
18
19
  }
19
20
  return fallbackRoute.routeData;
20
21
  }
22
+ function getCustom404Route(manifestData) {
23
+ return manifestData.routes.find((r) => isRoute404(r.route));
24
+ }
25
+ function getCustom500Route(manifestData) {
26
+ return manifestData.routes.find((r) => isRoute500(r.route));
27
+ }
21
28
  export {
29
+ getCustom404Route,
30
+ getCustom500Route,
22
31
  getFallbackRoute,
23
32
  routeIsFallback,
24
33
  routeIsRedirect
@@ -0,0 +1,27 @@
1
+ import z from 'zod/v4';
2
+ export declare const SessionDriverConfigSchema: z.ZodObject<{
3
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
4
+ entrypoint: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<URL, URL>]>;
5
+ }, z.core.$strip>;
6
+ export declare const SessionSchema: z.ZodObject<{
7
+ driver: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
8
+ config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
9
+ entrypoint: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<URL, URL>]>;
10
+ }, z.core.$strip>]>;
11
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
12
+ cookie: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
13
+ name: z.ZodOptional<z.ZodString>;
14
+ domain: z.ZodOptional<z.ZodString>;
15
+ path: z.ZodOptional<z.ZodString>;
16
+ maxAge: z.ZodOptional<z.ZodNumber>;
17
+ sameSite: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
18
+ strict: "strict";
19
+ lax: "lax";
20
+ none: "none";
21
+ }>, z.ZodBoolean]>>;
22
+ secure: z.ZodOptional<z.ZodBoolean>;
23
+ }, z.core.$strip>, z.ZodPipe<z.ZodString, z.ZodTransform<{
24
+ name: string;
25
+ }, string>>]>>;
26
+ ttl: z.ZodOptional<z.ZodNumber>;
27
+ }, z.core.$strip>;
@@ -0,0 +1,33 @@
1
+ import z from "zod/v4";
2
+ const SessionDriverConfigSchema = z.object({
3
+ config: z.record(z.string(), z.any()).optional(),
4
+ entrypoint: z.union([z.string(), z.instanceof(URL)])
5
+ });
6
+ const SessionSchema = z.object({
7
+ driver: z.union([
8
+ z.string().superRefine(() => {
9
+ console.warn(
10
+ // TODO: update link to stable docs
11
+ `Using deprecated \`session.driver\` string signature. Learn how to migrate: https://v6.docs.astro.build/en/guides/upgrade-to/v6/#deprecated-session-driver-string-signature`
12
+ );
13
+ }),
14
+ SessionDriverConfigSchema
15
+ ]),
16
+ options: z.record(z.string(), z.any()).optional(),
17
+ cookie: z.union([
18
+ z.object({
19
+ name: z.string().optional(),
20
+ domain: z.string().optional(),
21
+ path: z.string().optional(),
22
+ maxAge: z.number().optional(),
23
+ sameSite: z.union([z.enum(["strict", "lax", "none"]), z.boolean()]).optional(),
24
+ secure: z.boolean().optional()
25
+ }),
26
+ z.string().transform((name) => ({ name }))
27
+ ]).optional(),
28
+ ttl: z.number().optional()
29
+ });
30
+ export {
31
+ SessionDriverConfigSchema,
32
+ SessionSchema
33
+ };
@@ -0,0 +1,34 @@
1
+ import type { SessionDriverConfig } from './types.js';
2
+ export declare const sessionDrivers: {
3
+ http: (config?: import("unstorage/drivers/http").HTTPOptions | undefined) => SessionDriverConfig;
4
+ azureAppConfiguration: (config?: import("unstorage/drivers/azure-app-configuration").AzureAppConfigurationOptions | undefined) => SessionDriverConfig;
5
+ azureCosmos: (config?: import("unstorage/drivers/azure-cosmos").AzureCosmosOptions | undefined) => SessionDriverConfig;
6
+ azureKeyVault: (config?: import("unstorage/drivers/azure-key-vault").AzureKeyVaultOptions | undefined) => SessionDriverConfig;
7
+ azureStorageBlob: (config?: import("unstorage/drivers/azure-storage-blob").AzureStorageBlobOptions | undefined) => SessionDriverConfig;
8
+ azureStorageTable: (config?: import("unstorage/drivers/azure-storage-table").AzureStorageTableOptions | undefined) => SessionDriverConfig;
9
+ capacitorPreferences: (config?: import("unstorage/drivers/capacitor-preferences").CapacitorPreferencesOptions | undefined) => SessionDriverConfig;
10
+ cloudflareKVBinding: (config?: import("unstorage/drivers/cloudflare-kv-binding").KVOptions | undefined) => SessionDriverConfig;
11
+ cloudflareKVHttp: (config?: import("unstorage/drivers/cloudflare-kv-http").KVHTTPOptions | undefined) => SessionDriverConfig;
12
+ cloudflareR2Binding: (config?: import("unstorage/drivers/cloudflare-r2-binding").CloudflareR2Options | undefined) => SessionDriverConfig;
13
+ db0: (config?: import("unstorage/drivers/db0").DB0DriverOptions | undefined) => SessionDriverConfig;
14
+ denoKVNode: (config?: import("unstorage/drivers/deno-kv-node").DenoKvNodeOptions | undefined) => SessionDriverConfig;
15
+ denoKV: (config?: import("unstorage/drivers/deno-kv").DenoKvOptions | undefined) => SessionDriverConfig;
16
+ fsLite: (config?: import("unstorage/drivers/fs-lite").FSStorageOptions | undefined) => SessionDriverConfig;
17
+ fs: (config?: import("unstorage/drivers/fs").FSStorageOptions | undefined) => SessionDriverConfig;
18
+ github: (config?: import("unstorage/drivers/github").GithubOptions | undefined) => SessionDriverConfig;
19
+ indexedb: (config?: import("unstorage/drivers/indexedb").IDBKeyvalOptions | undefined) => SessionDriverConfig;
20
+ localstorage: (config?: import("unstorage/drivers/localstorage").LocalStorageOptions | undefined) => SessionDriverConfig;
21
+ lruCache: (config?: import("unstorage/drivers/lru-cache").LRUDriverOptions | undefined) => SessionDriverConfig;
22
+ mongodb: (config?: import("unstorage/drivers/mongodb").MongoDbOptions | undefined) => SessionDriverConfig;
23
+ netlifyBlobs: (config?: import("unstorage/drivers/netlify-blobs").NetlifyStoreOptions | undefined) => SessionDriverConfig;
24
+ overlay: (config?: import("unstorage/drivers/overlay").OverlayStorageOptions | undefined) => SessionDriverConfig;
25
+ planetscale: (config?: import("unstorage/drivers/planetscale").PlanetscaleDriverOptions | undefined) => SessionDriverConfig;
26
+ redis: (config?: import("unstorage/drivers/redis").RedisOptions | undefined) => SessionDriverConfig;
27
+ s3: (config?: import("unstorage/drivers/s3").S3DriverOptions | undefined) => SessionDriverConfig;
28
+ sessionStorage: (config?: import("unstorage/drivers/session-storage").SessionStorageOptions | undefined) => SessionDriverConfig;
29
+ uploadthing: (config?: import("unstorage/drivers/uploadthing").UploadThingOptions | undefined) => SessionDriverConfig;
30
+ upstash: (config?: import("unstorage/drivers/upstash").UpstashOptions | undefined) => SessionDriverConfig;
31
+ vercelBlob: (config?: import("unstorage/drivers/vercel-blob").VercelBlobOptions | undefined) => SessionDriverConfig;
32
+ vercelKV: (config?: import("unstorage/drivers/vercel-kv").VercelKVOptions | undefined) => SessionDriverConfig;
33
+ vercelRuntimeCache: (config?: import("unstorage/drivers/vercel-runtime-cache").VercelCacheOptions | undefined) => SessionDriverConfig;
34
+ };
@@ -0,0 +1,20 @@
1
+ import { builtinDrivers } from "unstorage";
2
+ const unstorageDrivers = Object.fromEntries(
3
+ Object.entries(builtinDrivers).filter(([name]) => !name.includes("-")).map(([name, entrypoint]) => [
4
+ name,
5
+ name === "fs" ? (config) => ({
6
+ entrypoint: builtinDrivers.fsLite,
7
+ config: {
8
+ base: ".astro/session",
9
+ ...config
10
+ }
11
+ }) : (config) => ({
12
+ entrypoint,
13
+ config
14
+ })
15
+ ])
16
+ );
17
+ const sessionDrivers = unstorageDrivers;
18
+ export {
19
+ sessionDrivers
20
+ };
@@ -1,11 +1,18 @@
1
- import { type Driver } from 'unstorage';
2
- import type { ResolvedSessionConfig, RuntimeMode, SessionConfig, SessionDriverName } from '../types/public/config.js';
3
- import type { AstroCookies } from './cookies/cookies.js';
1
+ import type { RuntimeMode } from '../../types/public/config.js';
2
+ import type { AstroCookies } from '../cookies/cookies.js';
3
+ import type { SessionDriverFactory } from './types.js';
4
+ import type { SSRManifestSession } from '../app/types.js';
5
+ import { type Storage } from 'unstorage';
4
6
  export declare const PERSIST_SYMBOL: unique symbol;
5
- export type SessionDriver<TDriver extends SessionDriverName = any> = (config: SessionConfig<TDriver>['options']) => import('unstorage').Driver;
6
- export declare class AstroSession<TDriver extends SessionDriverName = any> {
7
+ export declare class AstroSession {
7
8
  #private;
8
- constructor(cookies: AstroCookies, { cookie: cookieConfig, ...config }: NonNullable<ResolvedSessionConfig<TDriver>>, runtimeMode?: RuntimeMode, driverFactory?: ((config: SessionConfig<TDriver>['options']) => Driver) | null);
9
+ constructor({ cookies, config, runtimeMode, driverFactory, mockStorage, }: {
10
+ cookies: AstroCookies;
11
+ config: SSRManifestSession | undefined;
12
+ runtimeMode: RuntimeMode;
13
+ driverFactory: SessionDriverFactory | null;
14
+ mockStorage: Storage | null;
15
+ });
9
16
  /**
10
17
  * Gets a session value. Returns `undefined` if the session or value does not exist.
11
18
  */
@@ -1,7 +1,7 @@
1
1
  import { stringify as rawStringify, unflatten as rawUnflatten } from "devalue";
2
+ import { SessionStorageInitError, SessionStorageSaveError } from "../errors/errors-data.js";
3
+ import { AstroError } from "../errors/index.js";
2
4
  import { createStorage } from "unstorage";
3
- import { SessionStorageInitError, SessionStorageSaveError } from "./errors/errors-data.js";
4
- import { AstroError } from "./errors/index.js";
5
5
  const PERSIST_SYMBOL = Symbol();
6
6
  const DEFAULT_COOKIE_NAME = "astro-session";
7
7
  const VALID_COOKIE_REGEX = /^[\w-]+$/;
@@ -47,12 +47,14 @@ class AstroSession {
47
47
  // The driver factory function provided by the pipeline
48
48
  #driverFactory;
49
49
  static #sharedStorage = /* @__PURE__ */ new Map();
50
- constructor(cookies, {
51
- cookie: cookieConfig = DEFAULT_COOKIE_NAME,
52
- ...config
53
- }, runtimeMode, driverFactory) {
54
- const { driver } = config;
55
- if (!driver) {
50
+ constructor({
51
+ cookies,
52
+ config,
53
+ runtimeMode,
54
+ driverFactory,
55
+ mockStorage
56
+ }) {
57
+ if (!config) {
56
58
  throw new AstroError({
57
59
  ...SessionStorageInitError,
58
60
  message: SessionStorageInitError.message(
@@ -62,6 +64,7 @@ class AstroSession {
62
64
  }
63
65
  this.#cookies = cookies;
64
66
  this.#driverFactory = driverFactory;
67
+ const { cookie: cookieConfig = DEFAULT_COOKIE_NAME, ...configRest } = config;
65
68
  let cookieConfigObject;
66
69
  if (typeof cookieConfig === "object") {
67
70
  const { name = DEFAULT_COOKIE_NAME, ...rest } = cookieConfig;
@@ -77,7 +80,10 @@ class AstroSession {
77
80
  ...cookieConfigObject,
78
81
  httpOnly: true
79
82
  };
80
- this.#config = { ...config, driver };
83
+ this.#config = configRest;
84
+ if (mockStorage) {
85
+ this.#storage = mockStorage;
86
+ }
81
87
  }
82
88
  /**
83
89
  * Gets a session value. Returns `undefined` if the session or value does not exist.
@@ -328,15 +334,6 @@ class AstroSession {
328
334
  this.#storage = AstroSession.#sharedStorage.get(this.#config.driver);
329
335
  return this.#storage;
330
336
  }
331
- if (this.#config.driver === "test") {
332
- this.#storage = this.#config.options.mockStorage;
333
- return this.#storage;
334
- }
335
- if (this.#config.driver === "fs" || this.#config.driver === "fsLite" || this.#config.driver === "fs-lite") {
336
- this.#config.options ??= {};
337
- this.#config.driver = "fs-lite";
338
- this.#config.options.base ??= ".astro/session";
339
- }
340
337
  if (!this.#driverFactory) {
341
338
  throw new AstroError({
342
339
  ...SessionStorageInitError,
@@ -349,7 +346,16 @@ class AstroSession {
349
346
  const driver = this.#driverFactory;
350
347
  try {
351
348
  this.#storage = createStorage({
352
- driver: driver(this.#config.options)
349
+ driver: {
350
+ ...driver(this.#config.options),
351
+ // Unused methods
352
+ hasItem() {
353
+ return false;
354
+ },
355
+ getKeys() {
356
+ return [];
357
+ }
358
+ }
353
359
  });
354
360
  AstroSession.#sharedStorage.set(this.#config.driver, this.#storage);
355
361
  return this.#storage;
@@ -0,0 +1,67 @@
1
+ import type { BuiltinDriverOptions } from 'unstorage';
2
+ import type { AstroCookieSetOptions } from '../cookies/cookies.js';
3
+ export interface SessionDriver {
4
+ removeItem: (key: string) => Promise<void>;
5
+ getItem: (key: string) => Promise<any>;
6
+ setItem: (key: string, value: any) => Promise<void>;
7
+ }
8
+ export type SessionDriverFactory = (config: Record<string, any> | undefined) => SessionDriver;
9
+ export interface SessionDriverConfig {
10
+ /** Serializable options used by the driver implementation */
11
+ config?: Record<string, any> | undefined;
12
+ /** URL or package import */
13
+ entrypoint: string | URL;
14
+ }
15
+ export interface NormalizedSessionDriverConfig {
16
+ config: Record<string, any> | undefined;
17
+ entrypoint: string;
18
+ }
19
+ /** @deprecated */
20
+ export type SessionDriverName = keyof BuiltinDriverOptions | (string & {});
21
+ export interface BaseSessionConfig {
22
+ /**
23
+ * Configures the session cookie. If set to a string, it will be used as the cookie name.
24
+ * Alternatively, you can pass an object with additional options.
25
+ */
26
+ cookie?: string | (Omit<AstroCookieSetOptions, 'httpOnly' | 'expires' | 'encode'> & {
27
+ name?: string;
28
+ });
29
+ /**
30
+ * Default session duration in seconds. If not set, the session will be stored until deleted, or until the cookie expires.
31
+ */
32
+ ttl?: number;
33
+ }
34
+ interface DriverConfig<TDriver extends SessionDriverConfig> extends BaseSessionConfig {
35
+ /** Config object for a session driver */
36
+ driver: TDriver;
37
+ /** @deprecated Pass options to the driver function directly. This will be removed in Astro 7 */
38
+ options?: never;
39
+ }
40
+ interface UnstorageConfig<TDriver extends keyof BuiltinDriverOptions> extends BaseSessionConfig {
41
+ /**
42
+ * Entrypoint for an unstorage session driver
43
+ * @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro 7
44
+ */
45
+ driver: TDriver;
46
+ /**
47
+ * Options for the unstorage driver
48
+ * @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro 7
49
+ */
50
+ options?: NoInfer<BuiltinDriverOptions[TDriver]>;
51
+ }
52
+ interface CustomConfig extends BaseSessionConfig {
53
+ /**
54
+ * Entrypoint for a custom session driver
55
+ * @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro 7
56
+ */
57
+ driver?: string;
58
+ /**
59
+ * Options for the custom session driver
60
+ * @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro 7
61
+ */
62
+ options?: Record<string, unknown>;
63
+ }
64
+ export type SessionConfig<TDriver extends SessionDriverName | SessionDriverConfig> = [
65
+ TDriver
66
+ ] extends [never] ? UnstorageConfig<keyof BuiltinDriverOptions> : TDriver extends SessionDriverConfig ? DriverConfig<TDriver> : TDriver extends keyof BuiltinDriverOptions ? UnstorageConfig<TDriver> : CustomConfig;
67
+ export {};
File without changes
@@ -0,0 +1,7 @@
1
+ import type { NormalizedSessionDriverConfig, SessionDriverConfig } from './types.js';
2
+ import type { SSRManifestSession } from '../app/types.js';
3
+ import type { AstroConfig } from '../../types/public/index.js';
4
+ export declare function normalizeSessionDriverConfig(driver: string | SessionDriverConfig,
5
+ /** @deprecated */
6
+ options?: Record<string, any>): NormalizedSessionDriverConfig;
7
+ export declare function sessionConfigToManifest(config: AstroConfig['session']): SSRManifestSession | undefined;
@@ -0,0 +1,48 @@
1
+ import { builtinDrivers } from "unstorage";
2
+ import { fileURLToPath } from "node:url";
3
+ function isUnstorageDriver(driver) {
4
+ return driver in builtinDrivers;
5
+ }
6
+ function normalizeSessionDriverConfig(driver, options) {
7
+ if (typeof driver !== "string") {
8
+ return {
9
+ entrypoint: driver.entrypoint instanceof URL ? fileURLToPath(driver.entrypoint) : driver.entrypoint,
10
+ config: driver.config
11
+ };
12
+ }
13
+ if (["fs", "fs-lite", "fsLite"].includes(driver)) {
14
+ return {
15
+ entrypoint: builtinDrivers.fsLite,
16
+ config: {
17
+ base: ".astro/session",
18
+ ...options
19
+ }
20
+ };
21
+ }
22
+ if (isUnstorageDriver(driver)) {
23
+ return {
24
+ entrypoint: builtinDrivers[driver],
25
+ config: options
26
+ };
27
+ }
28
+ return {
29
+ entrypoint: driver,
30
+ config: options
31
+ };
32
+ }
33
+ function sessionConfigToManifest(config) {
34
+ if (!config) {
35
+ return void 0;
36
+ }
37
+ const driver = normalizeSessionDriverConfig(config.driver);
38
+ return {
39
+ driver: driver.entrypoint,
40
+ options: driver.config,
41
+ cookie: config.cookie,
42
+ ttl: config.ttl
43
+ };
44
+ }
45
+ export {
46
+ normalizeSessionDriverConfig,
47
+ sessionConfigToManifest
48
+ };
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath } from "node:url";
2
- import { builtinDrivers } from "unstorage";
3
2
  import { SessionStorageInitError } from "../errors/errors-data.js";
4
3
  import { AstroError } from "../errors/index.js";
4
+ import { normalizeSessionDriverConfig } from "./utils.js";
5
5
  const VIRTUAL_SESSION_DRIVER_ID = "virtual:astro:session-driver";
6
6
  const RESOLVED_VIRTUAL_SESSION_DRIVER_ID = "\0" + VIRTUAL_SESSION_DRIVER_ID;
7
7
  function vitePluginSessionDriver({ settings }) {
@@ -21,34 +21,29 @@ function vitePluginSessionDriver({ settings }) {
21
21
  id: new RegExp(`^${RESOLVED_VIRTUAL_SESSION_DRIVER_ID}$`)
22
22
  },
23
23
  async handler() {
24
- if (settings.config.session) {
25
- let sessionDriver;
26
- if (settings.config.session.driver === "fs") {
27
- sessionDriver = builtinDrivers.fsLite;
28
- } else if (settings.config.session.driver && settings.config.session.driver in builtinDrivers) {
29
- sessionDriver = builtinDrivers[settings.config.session.driver];
30
- } else {
31
- return { code: "export default null;" };
32
- }
33
- const importerPath = fileURLToPath(import.meta.url);
34
- const resolved = await this.resolve(sessionDriver, importerPath);
35
- if (!resolved) {
36
- throw new AstroError({
37
- ...SessionStorageInitError,
38
- message: SessionStorageInitError.message(
39
- `Failed to resolve session driver: ${sessionDriver}`,
40
- settings.config.session.driver
41
- )
42
- });
43
- }
44
- return {
45
- code: `import { default as _default } from '${resolved.id}';
46
- export * from '${resolved.id}';
47
- export default _default;`
48
- };
49
- } else {
24
+ if (!settings.config.session) {
50
25
  return { code: "export default null;" };
51
26
  }
27
+ const driver = normalizeSessionDriverConfig(
28
+ settings.config.session.driver,
29
+ settings.config.session.options
30
+ );
31
+ const importerPath = fileURLToPath(import.meta.url);
32
+ const resolved = await this.resolve(driver.entrypoint, importerPath);
33
+ if (!resolved) {
34
+ throw new AstroError({
35
+ ...SessionStorageInitError,
36
+ message: SessionStorageInitError.message(
37
+ `Failed to resolve session driver: ${driver.entrypoint}`,
38
+ driver.entrypoint
39
+ )
40
+ });
41
+ }
42
+ return {
43
+ code: `import { default as _default } from '${resolved.id}';
44
+ export * from '${resolved.id}';
45
+ export default _default;`
46
+ };
52
47
  }
53
48
  }
54
49
  };
@@ -19,6 +19,7 @@ import { VIRTUAL_SESSION_DRIVER_ID } from "../core/session/vite-plugin.js";
19
19
  import { VIRTUAL_PAGES_MODULE_ID } from "../vite-plugin-pages/index.js";
20
20
  import { ASTRO_RENDERERS_MODULE_ID } from "../vite-plugin-renderers/index.js";
21
21
  import { ASTRO_ROUTES_MODULE_ID } from "../vite-plugin-routes/index.js";
22
+ import { sessionConfigToManifest } from "../core/session/utils.js";
22
23
  const SERIALIZED_MANIFEST_ID = "virtual:astro:manifest";
23
24
  const SERIALIZED_MANIFEST_RESOLVED_ID = "\0" + SERIALIZED_MANIFEST_ID;
24
25
  function serializedManifestPlugin({
@@ -133,7 +134,7 @@ async function createSerializedManifest(settings) {
133
134
  i18n: i18nManifest,
134
135
  checkOrigin: (settings.config.security?.checkOrigin && settings.buildOutput === "server") ?? false,
135
136
  key: await encodeKey(hasEnvironmentKey() ? await getEnvironmentKey() : await createKey()),
136
- sessionConfig: settings.config.session,
137
+ sessionConfig: sessionConfigToManifest(settings.config.session),
137
138
  csp,
138
139
  devToolbar: {
139
140
  enabled: settings.config.devToolbar.enabled && await settings.preferences.get("devToolbar.enabled"),
@@ -1,7 +1,7 @@
1
1
  import type { RouteData, SSRManifest } from '../types/public/internal.js';
2
- import type { AstroServerPipeline } from '../vite-plugin-app/pipeline.js';
2
+ import type { RunnablePipeline } from '../vite-plugin-app/pipeline.js';
3
3
  type GetSortedPreloadedMatchesParams = {
4
- pipeline: AstroServerPipeline;
4
+ pipeline: RunnablePipeline;
5
5
  matches: RouteData[];
6
6
  manifest: SSRManifest;
7
7
  };
@@ -26,7 +26,8 @@ async function renderPage(result, componentFactory, props, children, streaming,
26
26
  headers2.set("content-security-policy", renderCspContent(result));
27
27
  }
28
28
  return new Response(bytes, {
29
- headers: headers2
29
+ headers: headers2,
30
+ status: result.response.status
30
31
  });
31
32
  }
32
33
  result._metadata.headInTree = result.componentMetadata.get(componentFactory.moduleId)?.containsHead ?? false;