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
|
@@ -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
|
-
|
|
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 {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
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
|
|
6
|
-
export declare class AstroSession<TDriver extends SessionDriverName = any> {
|
|
7
|
+
export declare class AstroSession {
|
|
7
8
|
#private;
|
|
8
|
-
constructor(
|
|
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(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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 =
|
|
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:
|
|
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 {
|
|
2
|
+
import type { RunnablePipeline } from '../vite-plugin-app/pipeline.js';
|
|
3
3
|
type GetSortedPreloadedMatchesParams = {
|
|
4
|
-
pipeline:
|
|
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;
|