astro 7.1.5 → 7.2.0
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/assets/build/generate.d.ts +8 -1
- package/dist/assets/build/generate.js +21 -1
- package/dist/assets/fonts/providers/index.js +12 -2
- package/dist/assets/types.d.ts +13 -0
- package/dist/assets/vite-plugin-assets.js +8 -0
- package/dist/cli/add/index.js +1 -1
- package/dist/cli/agent.d.ts +1 -0
- package/dist/cli/agent.js +11 -0
- package/dist/cli/dev/background.d.ts +3 -16
- package/dist/cli/dev/background.js +7 -93
- package/dist/cli/dev/index.d.ts +12 -0
- package/dist/cli/dev/index.js +30 -23
- package/dist/cli/dev/logs.js +2 -64
- package/dist/cli/dev/status.d.ts +2 -9
- package/dist/cli/dev/status.js +6 -24
- package/dist/cli/dev/stop.d.ts +2 -6
- package/dist/cli/dev/stop.js +6 -14
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/cli/install-package.js +1 -1
- package/dist/cli/preview/index.js +77 -3
- package/dist/cli/server.d.ts +60 -0
- package/dist/cli/server.js +274 -0
- package/dist/content/consts.d.ts +4 -0
- package/dist/content/consts.js +8 -0
- package/dist/content/content-layer.js +3 -3
- package/dist/content/data-store-writer.d.ts +1 -1
- package/dist/content/data-store-writer.js +4 -3
- package/dist/content/data-store.d.ts +3 -3
- package/dist/content/data-store.js +3 -3
- package/dist/content/mutable-data-store.d.ts +3 -3
- package/dist/content/mutable-data-store.js +5 -5
- package/dist/content/paths.d.ts +2 -1
- package/dist/content/paths.js +11 -0
- package/dist/content/runtime.d.ts +2 -0
- package/dist/content/runtime.js +2 -0
- package/dist/content/types-generator.js +1 -0
- package/dist/content/vite-plugin-content-assets.js +6 -1
- package/dist/content/vite-plugin-content-imports.js +12 -3
- package/dist/content/vite-plugin-content-virtual-mod.js +69 -31
- package/dist/core/app/entrypoints/index.d.ts +2 -0
- package/dist/core/app/entrypoints/index.js +14 -0
- package/dist/core/build/config-hash/index.d.ts +8 -0
- package/dist/core/build/config-hash/index.js +23 -0
- package/dist/core/build/config-hash/input.d.ts +199 -0
- package/dist/core/build/config-hash/input.js +43 -0
- package/dist/core/build/generate.d.ts +3 -1
- package/dist/core/build/generate.js +204 -62
- package/dist/core/build/incremental-content-collector.d.ts +10 -0
- package/dist/core/build/incremental-content-collector.js +33 -0
- package/dist/core/build/incremental-image-collector.d.ts +11 -0
- package/dist/core/build/incremental-image-collector.js +32 -0
- package/dist/core/build/incremental-metadata.d.ts +9 -0
- package/dist/core/build/incremental-metadata.js +17 -0
- package/dist/core/build/incremental.d.ts +123 -0
- package/dist/core/build/incremental.js +178 -0
- package/dist/core/build/index.d.ts +3 -0
- package/dist/core/build/index.js +6 -2
- package/dist/core/build/internal.d.ts +19 -0
- package/dist/core/build/lockfile/finder.d.ts +22 -0
- package/dist/core/build/lockfile/finder.js +45 -0
- package/dist/core/build/lockfile/hasher.d.ts +16 -0
- package/dist/core/build/lockfile/hasher.js +46 -0
- package/dist/core/build/lockfile/index.d.ts +9 -0
- package/dist/core/build/lockfile/index.js +16 -0
- package/dist/core/build/plugins/index.js +3 -1
- package/dist/core/build/plugins/plugin-incremental.d.ts +14 -0
- package/dist/core/build/plugins/plugin-incremental.js +134 -0
- package/dist/core/build/types.d.ts +2 -0
- package/dist/core/config/schemas/base.d.ts +7 -6
- package/dist/core/config/schemas/base.js +9 -1
- package/dist/core/config/schemas/defaults.d.ts +1 -0
- package/dist/core/config/schemas/defaults.js +1 -0
- package/dist/core/config/schemas/relative.d.ts +19 -10
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +2 -1
- package/dist/core/dev/dev.js +5 -4
- package/dist/core/dev/lockfile.d.ts +8 -7
- package/dist/core/dev/lockfile.js +13 -13
- package/dist/core/encryption.d.ts +6 -0
- package/dist/core/encryption.js +14 -2
- package/dist/core/errors/default-handler.js +4 -5
- package/dist/core/fetch/index.js +1 -1
- package/dist/core/logger/config.d.ts +1 -1
- package/dist/core/logger/load.d.ts +3 -1
- package/dist/core/logger/load.js +3 -3
- package/dist/core/logger/utils.d.ts +6 -4
- package/dist/core/logger/utils.js +13 -5
- package/dist/core/logger/vite-plugin.js +1 -1
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/preview/static-preview-server.d.ts +2 -0
- package/dist/core/preview/static-preview-server.js +1 -0
- package/dist/core/routing/handler.js +1 -1
- package/dist/core/session/config.d.ts +2 -2
- package/dist/core/session/config.js +2 -1
- package/dist/core/session/provider-disabled.d.ts +2 -0
- package/dist/core/session/provider-disabled.js +7 -0
- package/dist/core/session/provider.d.ts +1 -0
- package/dist/core/session/provider.js +4 -0
- package/dist/core/session/utils.js +3 -0
- package/dist/core/session/vite-plugin.d.ts +3 -0
- package/dist/core/session/vite-plugin.js +41 -6
- package/dist/core/sync/index.js +5 -4
- package/dist/integrations/hooks.js +3 -1
- package/dist/runtime/prerender/static-paths.js +5 -1
- package/dist/runtime/server/render/util.js +3 -0
- package/dist/types/public/common.d.ts +1 -0
- package/dist/types/public/config.d.ts +73 -7
- package/dist/types/public/integrations.d.ts +29 -2
- package/dist/types/public/preview.d.ts +2 -0
- package/dist/vite-plugin-config-alias/index.js +1 -0
- package/dist/vite-plugin-environment/index.js +4 -1
- package/dist/vite-plugin-hmr-reload/index.js +60 -18
- package/package.json +2 -3
|
@@ -345,7 +345,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
345
345
|
}, z.core.$strip>]>>>>>;
|
|
346
346
|
validateSecrets: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
347
347
|
}, z.core.$strict>>>;
|
|
348
|
-
session: z.ZodOptional<z.ZodObject<{
|
|
348
|
+
session: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
349
349
|
driver: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
350
350
|
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
351
351
|
entrypoint: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<URL, URL>]>;
|
|
@@ -366,7 +366,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
366
366
|
name: string;
|
|
367
367
|
}, string>>]>>;
|
|
368
368
|
ttl: z.ZodOptional<z.ZodNumber>;
|
|
369
|
-
}, z.core.$strip>>;
|
|
369
|
+
}, z.core.$strip>]>>;
|
|
370
370
|
prerenderConflictBehavior: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
371
371
|
error: "error";
|
|
372
372
|
ignore: "ignore";
|
|
@@ -436,14 +436,15 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
436
436
|
clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
437
437
|
contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
438
438
|
chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
439
|
+
incrementalBuild: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
439
440
|
svgOptimizer: z.ZodOptional<z.ZodObject<{
|
|
440
441
|
name: z.ZodString;
|
|
441
442
|
optimize: z.ZodCustom<(contents: string) => string | Promise<string>, (contents: string) => string | Promise<string>>;
|
|
442
443
|
}, z.core.$strip>>;
|
|
443
|
-
collectionStorage: z.ZodDefault<z.ZodOptional<z.
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}>>>;
|
|
444
|
+
collectionStorage: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"single-file">, z.ZodLiteral<"chunked">, z.ZodObject<{
|
|
445
|
+
type: z.ZodLiteral<"chunked">;
|
|
446
|
+
chunkSize: z.ZodNumber;
|
|
447
|
+
}, z.core.$strict>]>>>;
|
|
447
448
|
}, z.core.$strict>>;
|
|
448
449
|
legacy: z.ZodPrefault<z.ZodObject<{
|
|
449
450
|
collectionsBackwardsCompat: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -630,7 +631,11 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
630
631
|
clientPrerender: boolean;
|
|
631
632
|
contentIntellisense: boolean;
|
|
632
633
|
chromeDevtoolsWorkspace: boolean;
|
|
633
|
-
|
|
634
|
+
incrementalBuild: boolean;
|
|
635
|
+
collectionStorage: "single-file" | "chunked" | {
|
|
636
|
+
type: "chunked";
|
|
637
|
+
chunkSize: number;
|
|
638
|
+
};
|
|
634
639
|
svgOptimizer?: {
|
|
635
640
|
name: string;
|
|
636
641
|
optimize: (contents: string) => string | Promise<string>;
|
|
@@ -690,7 +695,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
690
695
|
domains?: Record<string, string> | undefined;
|
|
691
696
|
fallback?: Record<string, string> | undefined;
|
|
692
697
|
} | undefined;
|
|
693
|
-
session?: {
|
|
698
|
+
session?: false | {
|
|
694
699
|
driver?: string | {
|
|
695
700
|
entrypoint: string | URL;
|
|
696
701
|
config?: Record<string, any> | undefined;
|
|
@@ -893,7 +898,11 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
893
898
|
clientPrerender: boolean;
|
|
894
899
|
contentIntellisense: boolean;
|
|
895
900
|
chromeDevtoolsWorkspace: boolean;
|
|
896
|
-
|
|
901
|
+
incrementalBuild: boolean;
|
|
902
|
+
collectionStorage: "single-file" | "chunked" | {
|
|
903
|
+
type: "chunked";
|
|
904
|
+
chunkSize: number;
|
|
905
|
+
};
|
|
897
906
|
svgOptimizer?: {
|
|
898
907
|
name: string;
|
|
899
908
|
optimize: (contents: string) => string | Promise<string>;
|
|
@@ -953,7 +962,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
953
962
|
domains?: Record<string, string> | undefined;
|
|
954
963
|
fallback?: Record<string, string> | undefined;
|
|
955
964
|
} | undefined;
|
|
956
|
-
session?: {
|
|
965
|
+
session?: false | {
|
|
957
966
|
driver?: string | {
|
|
958
967
|
entrypoint: string | URL;
|
|
959
968
|
config?: Record<string, any> | undefined;
|
package/dist/core/constants.js
CHANGED
package/dist/core/create-vite.js
CHANGED
|
@@ -47,7 +47,7 @@ import { joinPaths } from "./path.js";
|
|
|
47
47
|
import { ServerIslandsState } from "./server-islands/shared-state.js";
|
|
48
48
|
import { vitePluginServerIslands } from "./server-islands/vite-plugin-server-islands.js";
|
|
49
49
|
import { vitePluginCacheProvider } from "./cache/vite-plugin.js";
|
|
50
|
-
import { vitePluginSessionDriver } from "./session/vite-plugin.js";
|
|
50
|
+
import { vitePluginSessionDriver, vitePluginSessionProvider } from "./session/vite-plugin.js";
|
|
51
51
|
import { vitePluginLogger } from "./logger/vite-plugin.js";
|
|
52
52
|
import { isObject } from "./util-runtime.js";
|
|
53
53
|
import { vitePluginEnvironment } from "../vite-plugin-environment/index.js";
|
|
@@ -180,6 +180,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
|
|
|
180
180
|
vitePluginActions({ fs, settings }),
|
|
181
181
|
vitePluginServerIslands({ settings, logger, serverIslandsState }),
|
|
182
182
|
vitePluginSessionDriver({ settings }),
|
|
183
|
+
vitePluginSessionProvider({ settings }),
|
|
183
184
|
vitePluginCacheProvider({ settings }),
|
|
184
185
|
vitePluginLogger({ settings }),
|
|
185
186
|
astroContainer(),
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import { performance } from "node:perf_hooks";
|
|
3
3
|
import colors from "piccolore";
|
|
4
4
|
import { gt, major, minor, patch } from "semver";
|
|
5
|
-
import { getDataStoreDir, getDataStoreFile } from "../../content/paths.js";
|
|
5
|
+
import { getDataStoreChunkSize, getDataStoreDir, getDataStoreFile } from "../../content/paths.js";
|
|
6
6
|
import { globalContentLayer } from "../../content/instance.js";
|
|
7
7
|
import { attachContentServerListeners } from "../../content/index.js";
|
|
8
8
|
import { MutableDataStore } from "../../content/mutable-data-store.js";
|
|
@@ -26,7 +26,7 @@ async function dev(inlineConfig) {
|
|
|
26
26
|
await telemetry.record([]);
|
|
27
27
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
28
28
|
const logger = restart.container.logger;
|
|
29
|
-
const currentVersion = "7.
|
|
29
|
+
const currentVersion = "7.2.0";
|
|
30
30
|
const isPrerelease = currentVersion.includes("-");
|
|
31
31
|
if (!isPrerelease) {
|
|
32
32
|
try {
|
|
@@ -56,9 +56,10 @@ async function dev(inlineConfig) {
|
|
|
56
56
|
}
|
|
57
57
|
let store;
|
|
58
58
|
try {
|
|
59
|
-
|
|
59
|
+
const chunkSize = getDataStoreChunkSize(restart.container.settings);
|
|
60
|
+
if (chunkSize !== void 0) {
|
|
60
61
|
const dataStoreDir = getDataStoreDir(restart.container.settings, true);
|
|
61
|
-
store = await MutableDataStore.fromDir(dataStoreDir);
|
|
62
|
+
store = await MutableDataStore.fromDir(dataStoreDir, chunkSize);
|
|
62
63
|
} else {
|
|
63
64
|
const dataStoreFile = getDataStoreFile(restart.container.settings, true);
|
|
64
65
|
store = await MutableDataStore.fromFile(dataStoreFile);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ResolvedServerUrls } from 'vite';
|
|
2
|
+
export type ServerCommand = 'dev' | 'preview';
|
|
2
3
|
/** Maximum time (ms) to wait for a process to exit after SIGTERM before escalating to SIGKILL. */
|
|
3
4
|
export declare const GRACEFUL_SHUTDOWN_TIMEOUT = 5000;
|
|
4
5
|
export interface LockFileData {
|
|
@@ -14,9 +15,9 @@ export interface ExistingServer {
|
|
|
14
15
|
stale: boolean;
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
|
-
* Get the URL of
|
|
18
|
+
* Get the URL of a server log file for a given project root.
|
|
18
19
|
*/
|
|
19
|
-
export declare function getLogFileURL(root: URL): URL;
|
|
20
|
+
export declare function getLogFileURL(root: URL, command?: ServerCommand): URL;
|
|
20
21
|
/**
|
|
21
22
|
* Parse a lock file JSON string into a LockFileData object.
|
|
22
23
|
* Returns null if the content is invalid.
|
|
@@ -34,15 +35,15 @@ export declare function isProcessAlive(pid: number): boolean;
|
|
|
34
35
|
/**
|
|
35
36
|
* Read the lock file from disk. Returns null if it doesn't exist or is invalid.
|
|
36
37
|
*/
|
|
37
|
-
export declare function readLockFile(root: URL): LockFileData | null;
|
|
38
|
+
export declare function readLockFile(root: URL, command?: ServerCommand): LockFileData | null;
|
|
38
39
|
/**
|
|
39
40
|
* Write the lock file to disk.
|
|
40
41
|
*/
|
|
41
|
-
export declare function writeLockFile(root: URL, data: LockFileData): void;
|
|
42
|
+
export declare function writeLockFile(root: URL, data: LockFileData, command?: ServerCommand): void;
|
|
42
43
|
/**
|
|
43
44
|
* Remove the lock file from disk. No-op if it doesn't exist.
|
|
44
45
|
*/
|
|
45
|
-
export declare function removeLockFile(root: URL): void;
|
|
46
|
+
export declare function removeLockFile(root: URL, command?: ServerCommand): void;
|
|
46
47
|
/**
|
|
47
48
|
* Given lock file data and a liveness result, determine the state of the existing server.
|
|
48
49
|
* This is the pure decision logic, separated from I/O for testability.
|
|
@@ -57,8 +58,8 @@ export declare function evaluateExistingServer(data: LockFileData | null, alive:
|
|
|
57
58
|
*/
|
|
58
59
|
export declare function killDevServer(root: URL, data: LockFileData): Promise<void>;
|
|
59
60
|
/**
|
|
60
|
-
* Check for an existing
|
|
61
|
+
* Check for an existing server by reading the lock file and checking process liveness.
|
|
61
62
|
* Automatically cleans up stale lock files.
|
|
62
63
|
* Returns the server info if a live server is found, null otherwise.
|
|
63
64
|
*/
|
|
64
|
-
export declare function checkExistingServer(root: URL): LockFileData | null;
|
|
65
|
+
export declare function checkExistingServer(root: URL, command?: ServerCommand): LockFileData | null;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync, unlinkSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
const GRACEFUL_SHUTDOWN_TIMEOUT = 5e3;
|
|
4
|
-
function getLockFileURL(root) {
|
|
5
|
-
return new URL(
|
|
4
|
+
function getLockFileURL(root, command = "dev") {
|
|
5
|
+
return new URL(`.astro/${command}.json`, root);
|
|
6
6
|
}
|
|
7
|
-
function getLogFileURL(root) {
|
|
8
|
-
return new URL(
|
|
7
|
+
function getLogFileURL(root, command = "dev") {
|
|
8
|
+
return new URL(`.astro/${command}.log`, root);
|
|
9
9
|
}
|
|
10
10
|
function isStringArray(value) {
|
|
11
11
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
@@ -42,8 +42,8 @@ function isProcessAlive(pid) {
|
|
|
42
42
|
return false;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
function readLockFile(root) {
|
|
46
|
-
const lockFileURL = getLockFileURL(root);
|
|
45
|
+
function readLockFile(root, command = "dev") {
|
|
46
|
+
const lockFileURL = getLockFileURL(root, command);
|
|
47
47
|
try {
|
|
48
48
|
const content = readFileSync(lockFileURL, "utf-8");
|
|
49
49
|
return parseLockFile(content);
|
|
@@ -51,8 +51,8 @@ function readLockFile(root) {
|
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
function writeLockFile(root, data) {
|
|
55
|
-
const lockFileURL = getLockFileURL(root);
|
|
54
|
+
function writeLockFile(root, data, command = "dev") {
|
|
55
|
+
const lockFileURL = getLockFileURL(root, command);
|
|
56
56
|
const dirPath = fileURLToPath(new URL(".astro/", root));
|
|
57
57
|
try {
|
|
58
58
|
if (!existsSync(dirPath)) {
|
|
@@ -64,8 +64,8 @@ function writeLockFile(root, data) {
|
|
|
64
64
|
throw new Error(`Failed to write lock file: ${message}`);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
function removeLockFile(root) {
|
|
68
|
-
const lockFileURL = getLockFileURL(root);
|
|
67
|
+
function removeLockFile(root, command = "dev") {
|
|
68
|
+
const lockFileURL = getLockFileURL(root, command);
|
|
69
69
|
try {
|
|
70
70
|
unlinkSync(lockFileURL);
|
|
71
71
|
} catch (err) {
|
|
@@ -98,14 +98,14 @@ async function killDevServer(root, data) {
|
|
|
98
98
|
}
|
|
99
99
|
removeLockFile(root);
|
|
100
100
|
}
|
|
101
|
-
function checkExistingServer(root) {
|
|
102
|
-
const data = readLockFile(root);
|
|
101
|
+
function checkExistingServer(root, command = "dev") {
|
|
102
|
+
const data = readLockFile(root, command);
|
|
103
103
|
const result = evaluateExistingServer(data, data !== null && isProcessAlive(data.pid));
|
|
104
104
|
if (result === null) {
|
|
105
105
|
return null;
|
|
106
106
|
}
|
|
107
107
|
if (result.stale) {
|
|
108
|
-
removeLockFile(root);
|
|
108
|
+
removeLockFile(root, command);
|
|
109
109
|
return null;
|
|
110
110
|
}
|
|
111
111
|
return result.data;
|
|
@@ -12,6 +12,12 @@ export declare function hasEnvironmentKey(): boolean;
|
|
|
12
12
|
* Get the environment variable key and decode it into a CryptoKey.
|
|
13
13
|
*/
|
|
14
14
|
export declare function getEnvironmentKey(): Promise<CryptoKey>;
|
|
15
|
+
/**
|
|
16
|
+
* Hash a CryptoKey into a one-way hex digest safe to persist. Server-island
|
|
17
|
+
* ciphertext is bound to the key, so the incremental build cache uses this to
|
|
18
|
+
* detect when the key changed between builds.
|
|
19
|
+
*/
|
|
20
|
+
export declare function hashCryptoKey(key: CryptoKey): Promise<string>;
|
|
15
21
|
/**
|
|
16
22
|
* Encodes a CryptoKey to base64 string, so that it can be embedded in JSON / JavaScript
|
|
17
23
|
*/
|
package/dist/core/encryption.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
decodeBase64,
|
|
3
|
+
decodeHex,
|
|
4
|
+
encodeBase64,
|
|
5
|
+
encodeHexLowerCase,
|
|
6
|
+
encodeHexUpperCase
|
|
7
|
+
} from "@oslojs/encoding";
|
|
2
8
|
import { ALGORITHMS } from "./csp/config.js";
|
|
3
9
|
const ALGORITHM = "AES-GCM";
|
|
4
10
|
async function createKey() {
|
|
@@ -28,6 +34,11 @@ async function getEnvironmentKey() {
|
|
|
28
34
|
const encodedKey = getEncodedEnvironmentKey();
|
|
29
35
|
return decodeKey(encodedKey);
|
|
30
36
|
}
|
|
37
|
+
async function hashCryptoKey(key) {
|
|
38
|
+
const exported = await crypto.subtle.exportKey("raw", key);
|
|
39
|
+
const digest = await crypto.subtle.digest("SHA-256", exported);
|
|
40
|
+
return encodeHexLowerCase(new Uint8Array(digest));
|
|
41
|
+
}
|
|
31
42
|
async function encodeKey(key) {
|
|
32
43
|
const exported = await crypto.subtle.exportKey("raw", key);
|
|
33
44
|
const encodedKey = encodeBase64(new Uint8Array(exported));
|
|
@@ -83,5 +94,6 @@ export {
|
|
|
83
94
|
generateContentHash,
|
|
84
95
|
generateCspDigest,
|
|
85
96
|
getEnvironmentKey,
|
|
86
|
-
hasEnvironmentKey
|
|
97
|
+
hasEnvironmentKey,
|
|
98
|
+
hashCryptoKey
|
|
87
99
|
};
|
|
@@ -5,7 +5,7 @@ import { getCookiesFromResponse } from "../cookies/response.js";
|
|
|
5
5
|
import { AstroMiddleware } from "../middleware/astro-middleware.js";
|
|
6
6
|
import { PagesHandler } from "../pages/handler.js";
|
|
7
7
|
import { matchRoute } from "../routing/match.js";
|
|
8
|
-
import { provideSession } from "../session/
|
|
8
|
+
import { provideSession } from "../session/provider.js";
|
|
9
9
|
import { validateHost } from "../app/validate-headers.js";
|
|
10
10
|
import { getErrorRoutePath } from "../../i18n/error-routes.js";
|
|
11
11
|
import { getOutputFilename } from "../output-filename.js";
|
|
@@ -152,7 +152,8 @@ function mergeResponses(newResponse, originalResponse, override) {
|
|
|
152
152
|
seen.add(name.toLowerCase());
|
|
153
153
|
}
|
|
154
154
|
for (const [name, value] of newResponseHeaders) {
|
|
155
|
-
|
|
155
|
+
const lower = name.toLowerCase();
|
|
156
|
+
if (!seen.has(lower) || lower === "set-cookie") {
|
|
156
157
|
newHeaders.append(name, value);
|
|
157
158
|
}
|
|
158
159
|
}
|
|
@@ -170,9 +171,7 @@ function mergeResponses(newResponse, originalResponse, override) {
|
|
|
170
171
|
const newCookies = getCookiesFromResponse(newResponse);
|
|
171
172
|
if (originalCookies) {
|
|
172
173
|
if (newCookies) {
|
|
173
|
-
|
|
174
|
-
originalResponse.headers.append("set-cookie", cookieValue);
|
|
175
|
-
}
|
|
174
|
+
originalCookies.merge(newCookies);
|
|
176
175
|
}
|
|
177
176
|
attachCookiesToResponse(mergedResponse, originalCookies);
|
|
178
177
|
} else if (newCookies) {
|
package/dist/core/fetch/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { AstroMiddleware } from "../middleware/astro-middleware.js";
|
|
|
7
7
|
import { PagesHandler } from "../pages/handler.js";
|
|
8
8
|
import { renderRedirect } from "../redirects/render.js";
|
|
9
9
|
import { AstroHandler } from "../routing/handler.js";
|
|
10
|
-
import { provideSession } from "../session/
|
|
10
|
+
import { provideSession } from "../session/provider.js";
|
|
11
11
|
import { TrailingSlashHandler } from "../routing/trailing-slash-handler.js";
|
|
12
12
|
function getApp(request) {
|
|
13
13
|
const app = Reflect.get(request, appSymbol);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface LoggerHandlerConfig {
|
|
2
2
|
/** Serializable options used by the driver implementation */
|
|
3
3
|
config?: Record<string, any> | undefined;
|
|
4
|
-
/**
|
|
4
|
+
/** A package import, a path relative to the project root, or a URL */
|
|
5
5
|
entrypoint: string | URL;
|
|
6
6
|
}
|
|
@@ -5,7 +5,9 @@ import type { AstroConfig, AstroInlineConfig } from '../../types/public/index.js
|
|
|
5
5
|
* Loads a logger destination in a Node context, i.e. outside of a built server bundle.
|
|
6
6
|
* Inside the bundle, the destination comes from the `virtual:astro:logger` module instead.
|
|
7
7
|
*/
|
|
8
|
-
export declare function loadLoggerDestination(config: LoggerHandlerConfig
|
|
8
|
+
export declare function loadLoggerDestination(config: LoggerHandlerConfig,
|
|
9
|
+
/** The project root, which relative entrypoints are resolved against */
|
|
10
|
+
root: URL): Promise<AstroLoggerDestination>;
|
|
9
11
|
/**
|
|
10
12
|
* It attempts to load a logger from the entrypoint.
|
|
11
13
|
* If not provided, it creates a new logger instance on the fly.
|
package/dist/core/logger/load.js
CHANGED
|
@@ -19,8 +19,8 @@ async function createDestination(config) {
|
|
|
19
19
|
}
|
|
20
20
|
return logger.default(config.config);
|
|
21
21
|
}
|
|
22
|
-
async function loadLoggerDestination(config) {
|
|
23
|
-
const normalized = normalizeLoggerConfig(config);
|
|
22
|
+
async function loadLoggerDestination(config, root) {
|
|
23
|
+
const normalized = normalizeLoggerConfig(config, root);
|
|
24
24
|
try {
|
|
25
25
|
return await createDestination(normalized);
|
|
26
26
|
} catch (e) {
|
|
@@ -39,7 +39,7 @@ async function loadOrCreateNodeLogger(astroConfig, inlineAstroConfig) {
|
|
|
39
39
|
try {
|
|
40
40
|
if (astroConfig.logger) {
|
|
41
41
|
return new AstroLogger({
|
|
42
|
-
destination: await loadLoggerDestination(astroConfig.logger),
|
|
42
|
+
destination: await loadLoggerDestination(astroConfig.logger, astroConfig.root),
|
|
43
43
|
level: inlineAstroConfig.logLevel ?? "info"
|
|
44
44
|
});
|
|
45
45
|
} else {
|
|
@@ -14,8 +14,10 @@ export interface NormalizedLoggerConfig {
|
|
|
14
14
|
* (see `loadLoggerDestination`), and by applying the same treatment to the handlers
|
|
15
15
|
* composed through `astro/logger/compose`.
|
|
16
16
|
*
|
|
17
|
-
* Concretely,
|
|
18
|
-
* drivers do, since both Vite and `import()` can handle those — while
|
|
19
|
-
* e.g. a package specifier, is left untouched.
|
|
17
|
+
* Concretely, `URL` and relative entrypoints become absolute file paths — mirroring what
|
|
18
|
+
* session drivers do, since both Vite and `import()` can handle those — while any other
|
|
19
|
+
* string entrypoint, e.g. a package specifier, is left untouched.
|
|
20
20
|
*/
|
|
21
|
-
export declare function normalizeLoggerConfig(logger: LoggerHandlerConfig
|
|
21
|
+
export declare function normalizeLoggerConfig(logger: LoggerHandlerConfig,
|
|
22
|
+
/** The project root, which relative entrypoints are resolved against */
|
|
23
|
+
root: URL): NormalizedLoggerConfig;
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
1
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { isRelativePath } from "../path.js";
|
|
2
4
|
const COMPOSE_LOGGER_ENTRYPOINT = "astro/logger/compose";
|
|
3
|
-
function normalizeLoggerConfig(logger) {
|
|
4
|
-
const entrypoint = normalizeEntrypoint(logger.entrypoint);
|
|
5
|
+
function normalizeLoggerConfig(logger, root) {
|
|
6
|
+
const entrypoint = normalizeEntrypoint(logger.entrypoint, root);
|
|
5
7
|
if (entrypoint === COMPOSE_LOGGER_ENTRYPOINT) {
|
|
6
8
|
const loggers = logger.config?.loggers ?? [];
|
|
7
9
|
return {
|
|
8
10
|
entrypoint,
|
|
9
|
-
loggers: loggers.map((nested) => normalizeLoggerConfig(nested))
|
|
11
|
+
loggers: loggers.map((nested) => normalizeLoggerConfig(nested, root))
|
|
10
12
|
};
|
|
11
13
|
}
|
|
12
14
|
return { entrypoint, config: logger.config };
|
|
13
15
|
}
|
|
14
|
-
function normalizeEntrypoint(entrypoint) {
|
|
15
|
-
|
|
16
|
+
function normalizeEntrypoint(entrypoint, root) {
|
|
17
|
+
if (entrypoint instanceof URL) {
|
|
18
|
+
return fileURLToPath(entrypoint);
|
|
19
|
+
}
|
|
20
|
+
if (isRelativePath(entrypoint)) {
|
|
21
|
+
return resolve(fileURLToPath(root), entrypoint);
|
|
22
|
+
}
|
|
23
|
+
return entrypoint;
|
|
16
24
|
}
|
|
17
25
|
export {
|
|
18
26
|
COMPOSE_LOGGER_ENTRYPOINT,
|
|
@@ -60,7 +60,7 @@ function vitePluginLogger({
|
|
|
60
60
|
async handler() {
|
|
61
61
|
const importerPath = fileURLToPath(new URL("package.json", settings.config.root));
|
|
62
62
|
const { expression, imports } = await emitDestination(
|
|
63
|
-
normalizeLoggerConfig(loggerConfig),
|
|
63
|
+
normalizeLoggerConfig(loggerConfig, settings.config.root),
|
|
64
64
|
async (entrypoint) => (await this.resolve(entrypoint, importerPath))?.id ?? null
|
|
65
65
|
);
|
|
66
66
|
return {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type http from 'node:http';
|
|
2
|
+
import type * as vite from 'vite';
|
|
2
3
|
import type { AstroSettings } from '../../types/astro.js';
|
|
3
4
|
import type { AstroLogger } from '../logger/core.js';
|
|
4
5
|
interface PreviewServer {
|
|
5
6
|
host?: string;
|
|
6
7
|
port: number;
|
|
8
|
+
urls?: vite.ResolvedServerUrls;
|
|
7
9
|
server: http.Server;
|
|
8
10
|
closed(): Promise<void>;
|
|
9
11
|
stop(): Promise<void>;
|
|
@@ -73,6 +73,7 @@ async function createStaticPreviewServer(settings, logger) {
|
|
|
73
73
|
return {
|
|
74
74
|
host: getResolvedHostForHttpServer(settings.config.server.host),
|
|
75
75
|
port: actualPort,
|
|
76
|
+
urls: previewServer.resolvedUrls ?? { local: [], network: [] },
|
|
76
77
|
closed,
|
|
77
78
|
server: previewServer.httpServer,
|
|
78
79
|
stop: previewServer.close.bind(previewServer)
|
|
@@ -6,7 +6,7 @@ import { I18n } from "../i18n/handler.js";
|
|
|
6
6
|
import { AstroMiddleware } from "../middleware/astro-middleware.js";
|
|
7
7
|
import { PagesHandler } from "../pages/handler.js";
|
|
8
8
|
import { renderRedirect } from "../redirects/render.js";
|
|
9
|
-
import { provideSession } from "../session/
|
|
9
|
+
import { provideSession } from "../session/provider.js";
|
|
10
10
|
import { prepareResponse } from "../app/prepare-response.js";
|
|
11
11
|
import { ALL_PIPELINE_FEATURES, PipelineFeatures } from "../base-pipeline.js";
|
|
12
12
|
class AstroHandler {
|
|
@@ -3,7 +3,7 @@ export declare const SessionDriverConfigSchema: z.ZodObject<{
|
|
|
3
3
|
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
4
4
|
entrypoint: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<URL, URL>]>;
|
|
5
5
|
}, z.core.$strip>;
|
|
6
|
-
export declare const SessionSchema: z.ZodObject<{
|
|
6
|
+
export declare const SessionSchema: z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
7
7
|
driver: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
8
8
|
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
9
9
|
entrypoint: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<URL, URL>]>;
|
|
@@ -24,4 +24,4 @@ export declare const SessionSchema: z.ZodObject<{
|
|
|
24
24
|
name: string;
|
|
25
25
|
}, string>>]>>;
|
|
26
26
|
ttl: z.ZodOptional<z.ZodNumber>;
|
|
27
|
-
}, z.core.$strip>;
|
|
27
|
+
}, z.core.$strip>]>;
|
|
@@ -3,7 +3,7 @@ const SessionDriverConfigSchema = z.object({
|
|
|
3
3
|
config: z.record(z.string(), z.any()).optional(),
|
|
4
4
|
entrypoint: z.union([z.string(), z.instanceof(URL)])
|
|
5
5
|
});
|
|
6
|
-
const
|
|
6
|
+
const SessionObjectSchema = z.object({
|
|
7
7
|
driver: z.union([
|
|
8
8
|
z.string().superRefine(() => {
|
|
9
9
|
console.warn(
|
|
@@ -26,6 +26,7 @@ const SessionSchema = z.object({
|
|
|
26
26
|
]).optional(),
|
|
27
27
|
ttl: z.number().optional()
|
|
28
28
|
});
|
|
29
|
+
const SessionSchema = z.union([z.literal(false), SessionObjectSchema]);
|
|
29
30
|
export {
|
|
30
31
|
SessionDriverConfigSchema,
|
|
31
32
|
SessionSchema
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { provideSession } from './handler.js';
|
|
@@ -31,6 +31,9 @@ function normalizeSessionDriverConfig(driver, options) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function sessionConfigToManifest(config) {
|
|
34
|
+
if (config === false) {
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
34
37
|
const sessionDriver = config?.driver;
|
|
35
38
|
if (!config || !sessionDriver) {
|
|
36
39
|
return void 0;
|
|
@@ -4,3 +4,6 @@ export declare const VIRTUAL_SESSION_DRIVER_ID = "virtual:astro:session-driver";
|
|
|
4
4
|
export declare function vitePluginSessionDriver({ settings }: {
|
|
5
5
|
settings: AstroSettings;
|
|
6
6
|
}): VitePlugin;
|
|
7
|
+
export declare function vitePluginSessionProvider({ settings }: {
|
|
8
|
+
settings: AstroSettings;
|
|
9
|
+
}): VitePlugin;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
1
2
|
import { fileURLToPath } from "node:url";
|
|
2
3
|
import { SessionStorageInitError } from "../errors/errors-data.js";
|
|
3
4
|
import { AstroError } from "../errors/index.js";
|
|
5
|
+
import { normalizePath } from "../viteUtils.js";
|
|
4
6
|
import { normalizeSessionDriverConfig } from "./utils.js";
|
|
5
7
|
const VIRTUAL_SESSION_DRIVER_ID = "virtual:astro:session-driver";
|
|
6
8
|
const RESOLVED_VIRTUAL_SESSION_DRIVER_ID = "\0" + VIRTUAL_SESSION_DRIVER_ID;
|
|
@@ -21,13 +23,11 @@ function vitePluginSessionDriver({ settings }) {
|
|
|
21
23
|
id: new RegExp(`^${RESOLVED_VIRTUAL_SESSION_DRIVER_ID}$`)
|
|
22
24
|
},
|
|
23
25
|
async handler() {
|
|
24
|
-
|
|
26
|
+
const session = settings.config.session;
|
|
27
|
+
if (session === false || !session?.driver) {
|
|
25
28
|
return { code: "export default null;" };
|
|
26
29
|
}
|
|
27
|
-
const driver = normalizeSessionDriverConfig(
|
|
28
|
-
settings.config.session.driver,
|
|
29
|
-
settings.config.session.options
|
|
30
|
-
);
|
|
30
|
+
const driver = normalizeSessionDriverConfig(session.driver, session.options);
|
|
31
31
|
const importerPath = fileURLToPath(import.meta.url);
|
|
32
32
|
const resolved = await this.resolve(driver.entrypoint, importerPath);
|
|
33
33
|
if (!resolved) {
|
|
@@ -48,7 +48,42 @@ export default _default;`
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
+
const PROVIDER_FILENAME = "provider.js";
|
|
52
|
+
const DISABLED_PROVIDER_FILENAME = "provider-disabled.js";
|
|
53
|
+
function canonicalizePath(filePath) {
|
|
54
|
+
try {
|
|
55
|
+
return normalizePath(realpathSync(filePath));
|
|
56
|
+
} catch {
|
|
57
|
+
return normalizePath(filePath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function vitePluginSessionProvider({ settings }) {
|
|
61
|
+
const providerPath = canonicalizePath(
|
|
62
|
+
fileURLToPath(new URL(`./${PROVIDER_FILENAME}`, import.meta.url))
|
|
63
|
+
);
|
|
64
|
+
const disabledProviderPath = canonicalizePath(
|
|
65
|
+
fileURLToPath(new URL(`./${DISABLED_PROVIDER_FILENAME}`, import.meta.url))
|
|
66
|
+
);
|
|
67
|
+
return {
|
|
68
|
+
name: "astro:session-provider",
|
|
69
|
+
enforce: "pre",
|
|
70
|
+
async resolveId(id, importer) {
|
|
71
|
+
const session = settings.config.session;
|
|
72
|
+
const hasSessionDriver = session !== false && !!session?.driver;
|
|
73
|
+
if (hasSessionDriver) return null;
|
|
74
|
+
if (!normalizePath(id).endsWith(`/session/${PROVIDER_FILENAME}`)) return null;
|
|
75
|
+
if (canonicalizePath(id) === providerPath) return disabledProviderPath;
|
|
76
|
+
if (!importer) return null;
|
|
77
|
+
const resolved = await this.resolve(id, importer, { skipSelf: true });
|
|
78
|
+
if (resolved && canonicalizePath(resolved.id) === providerPath) {
|
|
79
|
+
return disabledProviderPath;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
51
85
|
export {
|
|
52
86
|
VIRTUAL_SESSION_DRIVER_ID,
|
|
53
|
-
vitePluginSessionDriver
|
|
87
|
+
vitePluginSessionDriver,
|
|
88
|
+
vitePluginSessionProvider
|
|
54
89
|
};
|