astro 5.8.1 → 5.9.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/actions/runtime/utils.d.ts +1 -1
- package/dist/assets/fonts/config.d.ts +21 -21
- package/dist/container/index.js +2 -1
- package/dist/content/content-layer.js +14 -3
- package/dist/content/loaders/types.d.ts +3 -0
- package/dist/content/utils.d.ts +26 -10
- package/dist/content/utils.js +1 -0
- package/dist/core/app/types.d.ts +12 -1
- package/dist/core/base-pipeline.js +3 -3
- package/dist/core/build/generate.d.ts +1 -1
- package/dist/core/build/generate.js +38 -4
- package/dist/core/build/internal.d.ts +1 -0
- package/dist/core/build/internal.js +2 -1
- package/dist/core/build/plugins/index.js +1 -1
- package/dist/core/build/plugins/plugin-internals.d.ts +2 -1
- package/dist/core/build/plugins/plugin-internals.js +7 -4
- package/dist/core/build/plugins/plugin-manifest.js +37 -3
- package/dist/core/config/schemas/base.d.ts +435 -331
- package/dist/core/config/schemas/base.js +20 -2
- package/dist/core/config/schemas/index.d.ts +1 -1
- package/dist/core/config/schemas/index.js +4 -1
- package/dist/core/config/schemas/relative.d.ts +681 -552
- package/dist/core/constants.js +1 -1
- package/dist/core/csp/common.d.ts +16 -0
- package/dist/core/csp/common.js +116 -0
- package/dist/core/csp/config.d.ts +16 -0
- package/dist/core/csp/config.js +52 -0
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/encryption.d.ts +8 -0
- package/dist/core/encryption.js +7 -0
- package/dist/core/errors/errors-data.d.ts +12 -0
- package/dist/core/errors/errors-data.js +6 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/middleware/index.js +10 -0
- package/dist/core/middleware/sequence.js +2 -2
- package/dist/core/render-context.d.ts +1 -0
- package/dist/core/render-context.js +77 -5
- package/dist/env/schema.d.ts +34 -34
- package/dist/integrations/features-validation.js +36 -30
- package/dist/integrations/hooks.d.ts +3 -2
- package/dist/runtime/server/astro-island-styles.d.ts +1 -0
- package/dist/runtime/server/astro-island-styles.js +4 -0
- package/dist/runtime/server/index.d.ts +1 -0
- package/dist/runtime/server/render/astro/factory.d.ts +3 -2
- package/dist/runtime/server/render/astro/factory.js +6 -1
- package/dist/runtime/server/render/astro/head-and-content.d.ts +7 -0
- package/dist/runtime/server/render/astro/head-and-content.js +6 -0
- package/dist/runtime/server/render/astro/render.d.ts +1 -0
- package/dist/runtime/server/render/astro/render.js +2 -1
- package/dist/runtime/server/render/common.d.ts +1 -1
- package/dist/runtime/server/render/common.js +5 -3
- package/dist/runtime/server/render/component.js +8 -2
- package/dist/runtime/server/render/csp.d.ts +2 -0
- package/dist/runtime/server/render/csp.js +35 -0
- package/dist/runtime/server/render/head.js +14 -0
- package/dist/runtime/server/render/page.d.ts +1 -1
- package/dist/runtime/server/render/page.js +1 -1
- package/dist/runtime/server/render/server-islands.d.ts +14 -3
- package/dist/runtime/server/render/server-islands.js +100 -69
- package/dist/runtime/server/render/util.js +3 -0
- package/dist/runtime/server/scripts.d.ts +1 -1
- package/dist/runtime/server/scripts.js +2 -5
- package/dist/runtime/server/transition.d.ts +1 -1
- package/dist/runtime/server/transition.js +7 -2
- package/dist/types/public/config.d.ts +240 -0
- package/dist/types/public/context.d.ts +51 -0
- package/dist/types/public/integrations.d.ts +9 -0
- package/dist/types/public/internal.d.ts +24 -2
- package/dist/vite-plugin-astro-server/plugin.js +26 -4
- package/package.json +2 -2
package/dist/core/constants.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AstroSettings } from '../../types/astro.js';
|
|
2
|
+
import type { AstroConfig, CspAlgorithm } from '../../types/public/index.js';
|
|
3
|
+
import type { BuildInternals } from '../build/internal.js';
|
|
4
|
+
import type { CspDirective } from './config.js';
|
|
5
|
+
type EnabledCsp = Exclude<AstroConfig['experimental']['csp'], false>;
|
|
6
|
+
export declare function shouldTrackCspHashes(csp: any): csp is EnabledCsp;
|
|
7
|
+
export declare function getAlgorithm(csp: EnabledCsp): CspAlgorithm;
|
|
8
|
+
export declare function getScriptHashes(csp: EnabledCsp): string[];
|
|
9
|
+
export declare function getScriptResources(csp: EnabledCsp): string[];
|
|
10
|
+
export declare function getStyleHashes(csp: EnabledCsp): string[];
|
|
11
|
+
export declare function getStyleResources(csp: EnabledCsp): string[];
|
|
12
|
+
export declare function getDirectives(csp: EnabledCsp): CspDirective[];
|
|
13
|
+
export declare function getStrictDynamic(csp: EnabledCsp): boolean;
|
|
14
|
+
export declare function trackStyleHashes(internals: BuildInternals, settings: AstroSettings, algorithm: CspAlgorithm): Promise<string[]>;
|
|
15
|
+
export declare function trackScriptHashes(internals: BuildInternals, settings: AstroSettings, algorithm: CspAlgorithm): Promise<string[]>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { ISLAND_STYLES } from "../../runtime/server/astro-island-styles.js";
|
|
4
|
+
import astroIslandPrebuiltDev from "../../runtime/server/astro-island.prebuilt-dev.js";
|
|
5
|
+
import astroIslandPrebuilt from "../../runtime/server/astro-island.prebuilt.js";
|
|
6
|
+
import { generateCspDigest } from "../encryption.js";
|
|
7
|
+
function shouldTrackCspHashes(csp) {
|
|
8
|
+
return csp === true || typeof csp === "object";
|
|
9
|
+
}
|
|
10
|
+
function getAlgorithm(csp) {
|
|
11
|
+
if (csp === true) {
|
|
12
|
+
return "SHA-256";
|
|
13
|
+
}
|
|
14
|
+
return csp.algorithm;
|
|
15
|
+
}
|
|
16
|
+
function getScriptHashes(csp) {
|
|
17
|
+
if (csp === true) {
|
|
18
|
+
return [];
|
|
19
|
+
} else {
|
|
20
|
+
return csp.scriptDirective?.hashes ?? [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getScriptResources(csp) {
|
|
24
|
+
if (csp === true) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return csp.scriptDirective?.resources ?? [];
|
|
28
|
+
}
|
|
29
|
+
function getStyleHashes(csp) {
|
|
30
|
+
if (csp === true) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return csp.styleDirective?.hashes ?? [];
|
|
34
|
+
}
|
|
35
|
+
function getStyleResources(csp) {
|
|
36
|
+
if (csp === true) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
return csp.styleDirective?.resources ?? [];
|
|
40
|
+
}
|
|
41
|
+
function getDirectives(csp) {
|
|
42
|
+
if (csp === true) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
return csp.directives ?? [];
|
|
46
|
+
}
|
|
47
|
+
function getStrictDynamic(csp) {
|
|
48
|
+
if (csp === true) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return csp.scriptDirective?.strictDynamic ?? false;
|
|
52
|
+
}
|
|
53
|
+
async function trackStyleHashes(internals, settings, algorithm) {
|
|
54
|
+
const clientStyleHashes = [];
|
|
55
|
+
for (const [_, page] of internals.pagesByViteID.entries()) {
|
|
56
|
+
for (const style of page.styles) {
|
|
57
|
+
if (style.sheet.type === "inline") {
|
|
58
|
+
clientStyleHashes.push(await generateCspDigest(style.sheet.content, algorithm));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const clientAsset in internals.clientChunksAndAssets) {
|
|
63
|
+
const contents = readFileSync(
|
|
64
|
+
fileURLToPath(new URL(clientAsset, settings.config.build.client)),
|
|
65
|
+
"utf-8"
|
|
66
|
+
);
|
|
67
|
+
if (clientAsset.endsWith(".css") || clientAsset.endsWith(".css")) {
|
|
68
|
+
clientStyleHashes.push(await generateCspDigest(contents, algorithm));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (settings.renderers.length > 0) {
|
|
72
|
+
clientStyleHashes.push(await generateCspDigest(ISLAND_STYLES, algorithm));
|
|
73
|
+
}
|
|
74
|
+
return clientStyleHashes;
|
|
75
|
+
}
|
|
76
|
+
async function trackScriptHashes(internals, settings, algorithm) {
|
|
77
|
+
const clientScriptHashes = [];
|
|
78
|
+
for (const script of internals.inlinedScripts.values()) {
|
|
79
|
+
clientScriptHashes.push(await generateCspDigest(script, algorithm));
|
|
80
|
+
}
|
|
81
|
+
for (const directiveContent of Array.from(settings.clientDirectives.values())) {
|
|
82
|
+
clientScriptHashes.push(await generateCspDigest(directiveContent, algorithm));
|
|
83
|
+
}
|
|
84
|
+
for (const clientAsset in internals.clientChunksAndAssets) {
|
|
85
|
+
const contents = readFileSync(
|
|
86
|
+
fileURLToPath(new URL(clientAsset, settings.config.build.client)),
|
|
87
|
+
"utf-8"
|
|
88
|
+
);
|
|
89
|
+
if (clientAsset.endsWith(".js") || clientAsset.endsWith(".mjs")) {
|
|
90
|
+
clientScriptHashes.push(await generateCspDigest(contents, algorithm));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const script of settings.scripts) {
|
|
94
|
+
const { content, stage } = script;
|
|
95
|
+
if (stage === "head-inline" || stage === "before-hydration") {
|
|
96
|
+
clientScriptHashes.push(await generateCspDigest(content, algorithm));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (settings.renderers.length > 0) {
|
|
100
|
+
clientScriptHashes.push(await generateCspDigest(astroIslandPrebuilt, algorithm));
|
|
101
|
+
clientScriptHashes.push(await generateCspDigest(astroIslandPrebuiltDev, algorithm));
|
|
102
|
+
}
|
|
103
|
+
return clientScriptHashes;
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
getAlgorithm,
|
|
107
|
+
getDirectives,
|
|
108
|
+
getScriptHashes,
|
|
109
|
+
getScriptResources,
|
|
110
|
+
getStrictDynamic,
|
|
111
|
+
getStyleHashes,
|
|
112
|
+
getStyleResources,
|
|
113
|
+
shouldTrackCspHashes,
|
|
114
|
+
trackScriptHashes,
|
|
115
|
+
trackStyleHashes
|
|
116
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const ALGORITHMS: {
|
|
3
|
+
readonly 'SHA-256': "sha256-";
|
|
4
|
+
readonly 'SHA-384': "sha384-";
|
|
5
|
+
readonly 'SHA-512': "sha512-";
|
|
6
|
+
};
|
|
7
|
+
type Algorithms = typeof ALGORITHMS;
|
|
8
|
+
export type CspAlgorithm = keyof Algorithms;
|
|
9
|
+
export declare const cspAlgorithmSchema: z.ZodDefault<z.ZodOptional<z.ZodEnum<["SHA-256", "SHA-384", "SHA-512"]>>>;
|
|
10
|
+
export declare const cspHashSchema: z.ZodType<`sha256-${string}` | `sha384-${string}` | `sha512-${string}`, z.ZodTypeDef, `sha256-${string}` | `sha384-${string}` | `sha512-${string}`>;
|
|
11
|
+
export type CspHash = z.infer<typeof cspHashSchema>;
|
|
12
|
+
declare const ALLOWED_DIRECTIVES: readonly ["base-uri", "child-src", "connect-src", "default-src", "fenced-frame-src", "font-src", "form-action", "frame-ancestors", "frame-src", "img-src", "manifest-src", "media-src", "object-src", "referrer", "report-to", "require-trusted-types-for", "sandbox", "trusted-types", "upgrade-insecure-requests", "worker-src"];
|
|
13
|
+
export type CspDirective = `${AllowedDirectives} ${string}`;
|
|
14
|
+
export declare const allowedDirectivesSchema: z.ZodType<`base-uri ${string}` | `child-src ${string}` | `connect-src ${string}` | `default-src ${string}` | `fenced-frame-src ${string}` | `font-src ${string}` | `form-action ${string}` | `frame-ancestors ${string}` | `frame-src ${string}` | `img-src ${string}` | `manifest-src ${string}` | `media-src ${string}` | `object-src ${string}` | `referrer ${string}` | `report-to ${string}` | `require-trusted-types-for ${string}` | `sandbox ${string}` | `trusted-types ${string}` | `upgrade-insecure-requests ${string}` | `worker-src ${string}`, z.ZodTypeDef, `base-uri ${string}` | `child-src ${string}` | `connect-src ${string}` | `default-src ${string}` | `fenced-frame-src ${string}` | `font-src ${string}` | `form-action ${string}` | `frame-ancestors ${string}` | `frame-src ${string}` | `img-src ${string}` | `manifest-src ${string}` | `media-src ${string}` | `object-src ${string}` | `referrer ${string}` | `report-to ${string}` | `require-trusted-types-for ${string}` | `sandbox ${string}` | `trusted-types ${string}` | `upgrade-insecure-requests ${string}` | `worker-src ${string}`>;
|
|
15
|
+
type AllowedDirectives = (typeof ALLOWED_DIRECTIVES)[number];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const ALGORITHMS = {
|
|
3
|
+
"SHA-256": "sha256-",
|
|
4
|
+
"SHA-384": "sha384-",
|
|
5
|
+
"SHA-512": "sha512-"
|
|
6
|
+
};
|
|
7
|
+
const ALGORITHM_VALUES = Object.values(ALGORITHMS);
|
|
8
|
+
const cspAlgorithmSchema = z.enum(Object.keys(ALGORITHMS)).optional().default("SHA-256");
|
|
9
|
+
const cspHashSchema = z.custom((value) => {
|
|
10
|
+
if (typeof value !== "string") {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return ALGORITHM_VALUES.some((allowedValue) => {
|
|
14
|
+
return value.startsWith(allowedValue);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
const ALLOWED_DIRECTIVES = [
|
|
18
|
+
"base-uri",
|
|
19
|
+
"child-src",
|
|
20
|
+
"connect-src",
|
|
21
|
+
"default-src",
|
|
22
|
+
"fenced-frame-src",
|
|
23
|
+
"font-src",
|
|
24
|
+
"form-action",
|
|
25
|
+
"frame-ancestors",
|
|
26
|
+
"frame-src",
|
|
27
|
+
"img-src",
|
|
28
|
+
"manifest-src",
|
|
29
|
+
"media-src",
|
|
30
|
+
"object-src",
|
|
31
|
+
"referrer",
|
|
32
|
+
"report-to",
|
|
33
|
+
"require-trusted-types-for",
|
|
34
|
+
"sandbox",
|
|
35
|
+
"trusted-types",
|
|
36
|
+
"upgrade-insecure-requests",
|
|
37
|
+
"worker-src"
|
|
38
|
+
];
|
|
39
|
+
const allowedDirectivesSchema = z.custom((value) => {
|
|
40
|
+
if (typeof value !== "string") {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return ALLOWED_DIRECTIVES.some((allowedValue) => {
|
|
44
|
+
return value.startsWith(allowedValue);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
export {
|
|
48
|
+
ALGORITHMS,
|
|
49
|
+
allowedDirectivesSchema,
|
|
50
|
+
cspAlgorithmSchema,
|
|
51
|
+
cspHashSchema
|
|
52
|
+
};
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
|
|
|
22
22
|
await telemetry.record([]);
|
|
23
23
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
24
24
|
const logger = restart.container.logger;
|
|
25
|
-
const currentVersion = "5.
|
|
25
|
+
const currentVersion = "5.9.0";
|
|
26
26
|
const isPrerelease = currentVersion.includes("-");
|
|
27
27
|
if (!isPrerelease) {
|
|
28
28
|
try {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { CspAlgorithm } from '../types/public/index.js';
|
|
2
|
+
import { type CspHash } from './csp/config.js';
|
|
1
3
|
/**
|
|
2
4
|
* Creates a CryptoKey object that can be used to encrypt any string.
|
|
3
5
|
*/
|
|
@@ -26,3 +28,9 @@ export declare function encryptString(key: CryptoKey, raw: string): Promise<stri
|
|
|
26
28
|
* Takes a base64 encoded string, decodes it and returns the decrypted text.
|
|
27
29
|
*/
|
|
28
30
|
export declare function decryptString(key: CryptoKey, encoded: string): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Generates an SHA-256 digest of the given string.
|
|
33
|
+
* @param {string} data The string to hash.
|
|
34
|
+
* @param {CspAlgorithm} algorithm The algorithm to use.
|
|
35
|
+
*/
|
|
36
|
+
export declare function generateCspDigest(data: string, algorithm: CspAlgorithm): Promise<CspHash>;
|
package/dist/core/encryption.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { decodeBase64, decodeHex, encodeBase64, encodeHexUpperCase } from "@oslojs/encoding";
|
|
2
|
+
import { ALGORITHMS } from "./csp/config.js";
|
|
2
3
|
const ALGORITHM = "AES-GCM";
|
|
3
4
|
async function createKey() {
|
|
4
5
|
const key = await crypto.subtle.generateKey(
|
|
@@ -66,12 +67,18 @@ async function decryptString(key, encoded) {
|
|
|
66
67
|
const decryptedString = decoder.decode(decryptedBuffer);
|
|
67
68
|
return decryptedString;
|
|
68
69
|
}
|
|
70
|
+
async function generateCspDigest(data, algorithm) {
|
|
71
|
+
const hashBuffer = await crypto.subtle.digest(algorithm, encoder.encode(data));
|
|
72
|
+
const hash = encodeBase64(new Uint8Array(hashBuffer));
|
|
73
|
+
return `${ALGORITHMS[algorithm]}${hash}`;
|
|
74
|
+
}
|
|
69
75
|
export {
|
|
70
76
|
createKey,
|
|
71
77
|
decodeKey,
|
|
72
78
|
decryptString,
|
|
73
79
|
encodeKey,
|
|
74
80
|
encryptString,
|
|
81
|
+
generateCspDigest,
|
|
75
82
|
getEnvironmentKey,
|
|
76
83
|
hasEnvironmentKey
|
|
77
84
|
};
|
|
@@ -1230,6 +1230,18 @@ export declare const FontFamilyNotFound: {
|
|
|
1230
1230
|
message: (family: string) => string;
|
|
1231
1231
|
hint: string;
|
|
1232
1232
|
};
|
|
1233
|
+
/**
|
|
1234
|
+
* @docs
|
|
1235
|
+
* @description
|
|
1236
|
+
* The CSP feature isn't enabled
|
|
1237
|
+
* @message
|
|
1238
|
+
* The `experimental.csp` configuration isn't enabled.
|
|
1239
|
+
*/
|
|
1240
|
+
export declare const CspNotEnabled: {
|
|
1241
|
+
name: string;
|
|
1242
|
+
title: string;
|
|
1243
|
+
message: string;
|
|
1244
|
+
};
|
|
1233
1245
|
/**
|
|
1234
1246
|
* @docs
|
|
1235
1247
|
* @kind heading
|
|
@@ -464,6 +464,11 @@ const FontFamilyNotFound = {
|
|
|
464
464
|
message: (family) => `No data was found for the \`"${family}"\` family passed to the \`<Font>\` component.`,
|
|
465
465
|
hint: "This is often caused by a typo. Check that your Font component is using a `cssVariable` specified in your config."
|
|
466
466
|
};
|
|
467
|
+
const CspNotEnabled = {
|
|
468
|
+
name: "CspNotEnabled",
|
|
469
|
+
title: "CSP feature isn't enabled",
|
|
470
|
+
message: "The `experimental.csp` configuration isn't enabled."
|
|
471
|
+
};
|
|
467
472
|
const UnknownCSSError = {
|
|
468
473
|
name: "UnknownCSSError",
|
|
469
474
|
title: "Unknown CSS Error."
|
|
@@ -736,6 +741,7 @@ export {
|
|
|
736
741
|
ContentLoaderReturnsInvalidId,
|
|
737
742
|
ContentSchemaContainsSlugError,
|
|
738
743
|
CouldNotTransformImage,
|
|
744
|
+
CspNotEnabled,
|
|
739
745
|
DataCollectionEntryParseError,
|
|
740
746
|
DuplicateContentEntrySlugError,
|
|
741
747
|
EndpointDidNotReturnAResponse,
|
package/dist/core/messages.js
CHANGED
|
@@ -37,7 +37,7 @@ function serverStart({
|
|
|
37
37
|
host,
|
|
38
38
|
base
|
|
39
39
|
}) {
|
|
40
|
-
const version = "5.
|
|
40
|
+
const version = "5.9.0";
|
|
41
41
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
42
42
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
43
43
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -274,7 +274,7 @@ function printHelp({
|
|
|
274
274
|
message.push(
|
|
275
275
|
linebreak(),
|
|
276
276
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
277
|
-
`v${"5.
|
|
277
|
+
`v${"5.9.0"}`
|
|
278
278
|
)} ${headline}`
|
|
279
279
|
);
|
|
280
280
|
}
|
|
@@ -82,6 +82,16 @@ function createContext({
|
|
|
82
82
|
},
|
|
83
83
|
set locals(_) {
|
|
84
84
|
throw new AstroError(AstroErrorData.LocalsReassigned);
|
|
85
|
+
},
|
|
86
|
+
insertDirective() {
|
|
87
|
+
},
|
|
88
|
+
insertScriptResource() {
|
|
89
|
+
},
|
|
90
|
+
insertStyleResource() {
|
|
91
|
+
},
|
|
92
|
+
insertScriptHash() {
|
|
93
|
+
},
|
|
94
|
+
insertStyleHash() {
|
|
85
95
|
}
|
|
86
96
|
};
|
|
87
97
|
return Object.assign(context, {
|
|
@@ -25,11 +25,11 @@ function sequence(...handlers) {
|
|
|
25
25
|
if (payload instanceof Request) {
|
|
26
26
|
newRequest = payload;
|
|
27
27
|
} else if (payload instanceof URL) {
|
|
28
|
-
newRequest = new Request(payload, handleContext.request);
|
|
28
|
+
newRequest = new Request(payload, handleContext.request.clone());
|
|
29
29
|
} else {
|
|
30
30
|
newRequest = new Request(
|
|
31
31
|
new URL(payload, handleContext.url.origin),
|
|
32
|
-
handleContext.request
|
|
32
|
+
handleContext.request.clone()
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
const oldPathname = handleContext.url.pathname;
|
|
@@ -38,6 +38,7 @@ export declare class RenderContext {
|
|
|
38
38
|
* A safety net in case of loops
|
|
39
39
|
*/
|
|
40
40
|
counter: number;
|
|
41
|
+
result: SSRResult | undefined;
|
|
41
42
|
static create({ locals, middleware, pathname, pipeline, request, routeData, clientAddress, status, props, partial, actions, }: Pick<RenderContext, 'pathname' | 'pipeline' | 'request' | 'routeData' | 'clientAddress'> & Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status' | 'props' | 'partial' | 'actions'>>): Promise<RenderContext>;
|
|
42
43
|
/**
|
|
43
44
|
* The main function of the RenderContext.
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./constants.js";
|
|
21
21
|
import { AstroCookies, attachCookiesToResponse } from "./cookies/index.js";
|
|
22
22
|
import { getCookiesFromResponse } from "./cookies/response.js";
|
|
23
|
-
import { ForbiddenRewrite } from "./errors/errors-data.js";
|
|
23
|
+
import { CspNotEnabled, ForbiddenRewrite } from "./errors/errors-data.js";
|
|
24
24
|
import { AstroError, AstroErrorData } from "./errors/index.js";
|
|
25
25
|
import { callMiddleware } from "./middleware/callMiddleware.js";
|
|
26
26
|
import { sequence } from "./middleware/index.js";
|
|
@@ -56,6 +56,7 @@ class RenderContext {
|
|
|
56
56
|
* A safety net in case of loops
|
|
57
57
|
*/
|
|
58
58
|
counter = 0;
|
|
59
|
+
result = void 0;
|
|
59
60
|
static async create({
|
|
60
61
|
locals = {},
|
|
61
62
|
middleware,
|
|
@@ -181,10 +182,10 @@ class RenderContext {
|
|
|
181
182
|
case "redirect":
|
|
182
183
|
return renderRedirect(this);
|
|
183
184
|
case "page": {
|
|
184
|
-
|
|
185
|
+
this.result = await this.createResult(componentInstance, actionApiContext);
|
|
185
186
|
try {
|
|
186
187
|
response2 = await renderPage(
|
|
187
|
-
result,
|
|
188
|
+
this.result,
|
|
188
189
|
componentInstance?.default,
|
|
189
190
|
props,
|
|
190
191
|
slots,
|
|
@@ -192,7 +193,7 @@ class RenderContext {
|
|
|
192
193
|
this.routeData
|
|
193
194
|
);
|
|
194
195
|
} catch (e) {
|
|
195
|
-
result.cancelled = true;
|
|
196
|
+
this.result.cancelled = true;
|
|
196
197
|
throw e;
|
|
197
198
|
}
|
|
198
199
|
response2.headers.set(ROUTE_TYPE_HEADER, "page");
|
|
@@ -324,6 +325,36 @@ class RenderContext {
|
|
|
324
325
|
return void 0;
|
|
325
326
|
}
|
|
326
327
|
return renderContext.session;
|
|
328
|
+
},
|
|
329
|
+
insertDirective(payload) {
|
|
330
|
+
if (!pipeline.manifest.csp) {
|
|
331
|
+
throw new AstroError(CspNotEnabled);
|
|
332
|
+
}
|
|
333
|
+
renderContext.result?.directives.push(payload);
|
|
334
|
+
},
|
|
335
|
+
insertScriptResource(resource) {
|
|
336
|
+
if (!pipeline.manifest.csp) {
|
|
337
|
+
throw new AstroError(CspNotEnabled);
|
|
338
|
+
}
|
|
339
|
+
renderContext.result?.scriptResources.push(resource);
|
|
340
|
+
},
|
|
341
|
+
insertStyleResource(resource) {
|
|
342
|
+
if (!pipeline.manifest.csp) {
|
|
343
|
+
throw new AstroError(CspNotEnabled);
|
|
344
|
+
}
|
|
345
|
+
renderContext.result?.styleResources.push(resource);
|
|
346
|
+
},
|
|
347
|
+
insertStyleHash(hash) {
|
|
348
|
+
if (!pipeline.manifest.csp) {
|
|
349
|
+
throw new AstroError(CspNotEnabled);
|
|
350
|
+
}
|
|
351
|
+
renderContext.result?.styleHashes.push(hash);
|
|
352
|
+
},
|
|
353
|
+
insertScriptHash(hash) {
|
|
354
|
+
if (!!pipeline.manifest.csp === false) {
|
|
355
|
+
throw new AstroError(CspNotEnabled);
|
|
356
|
+
}
|
|
357
|
+
renderContext.result?.scriptHashes.push(hash);
|
|
327
358
|
}
|
|
328
359
|
};
|
|
329
360
|
}
|
|
@@ -380,8 +411,19 @@ class RenderContext {
|
|
|
380
411
|
hasRenderedServerIslandRuntime: false,
|
|
381
412
|
headInTree: false,
|
|
382
413
|
extraHead: [],
|
|
414
|
+
extraStyleHashes: [],
|
|
415
|
+
extraScriptHashes: [],
|
|
383
416
|
propagators: /* @__PURE__ */ new Set()
|
|
384
|
-
}
|
|
417
|
+
},
|
|
418
|
+
shouldInjectCspMetaTags: !!manifest.csp,
|
|
419
|
+
cspAlgorithm: manifest.csp?.algorithm ?? "SHA-256",
|
|
420
|
+
// The following arrays must be cloned, otherwise they become mutable across routes.
|
|
421
|
+
scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [],
|
|
422
|
+
scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [],
|
|
423
|
+
styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [],
|
|
424
|
+
styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [],
|
|
425
|
+
directives: manifest.csp?.directives ? [...manifest.csp.directives] : [],
|
|
426
|
+
isStrictDynamic: manifest.csp?.isStrictDynamic ?? false
|
|
385
427
|
};
|
|
386
428
|
return result;
|
|
387
429
|
}
|
|
@@ -494,6 +536,36 @@ class RenderContext {
|
|
|
494
536
|
url,
|
|
495
537
|
get originPathname() {
|
|
496
538
|
return getOriginPathname(renderContext.request);
|
|
539
|
+
},
|
|
540
|
+
insertDirective(payload) {
|
|
541
|
+
if (!pipeline.manifest.csp) {
|
|
542
|
+
throw new AstroError(CspNotEnabled);
|
|
543
|
+
}
|
|
544
|
+
renderContext.result?.directives.push(payload);
|
|
545
|
+
},
|
|
546
|
+
insertScriptResource(resource) {
|
|
547
|
+
if (!pipeline.manifest.csp) {
|
|
548
|
+
throw new AstroError(CspNotEnabled);
|
|
549
|
+
}
|
|
550
|
+
renderContext.result?.scriptResources.push(resource);
|
|
551
|
+
},
|
|
552
|
+
insertStyleResource(resource) {
|
|
553
|
+
if (!pipeline.manifest.csp) {
|
|
554
|
+
throw new AstroError(CspNotEnabled);
|
|
555
|
+
}
|
|
556
|
+
renderContext.result?.styleResources.push(resource);
|
|
557
|
+
},
|
|
558
|
+
insertStyleHash(hash) {
|
|
559
|
+
if (!pipeline.manifest.csp) {
|
|
560
|
+
throw new AstroError(CspNotEnabled);
|
|
561
|
+
}
|
|
562
|
+
renderContext.result?.styleHashes.push(hash);
|
|
563
|
+
},
|
|
564
|
+
insertScriptHash(hash) {
|
|
565
|
+
if (!!pipeline.manifest.csp === false) {
|
|
566
|
+
throw new AstroError(CspNotEnabled);
|
|
567
|
+
}
|
|
568
|
+
renderContext.result?.scriptHashes.push(hash);
|
|
497
569
|
}
|
|
498
570
|
};
|
|
499
571
|
}
|