astro 5.8.2 → 5.9.1
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/index.js +9 -3
- 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/merge.js +1 -6
- 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/render-context.d.ts +1 -0
- package/dist/core/render-context.js +77 -5
- package/dist/core/util.d.ts +1 -0
- package/dist/core/util.js +6 -1
- 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/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 -7
- 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/css.js +3 -3
- package/dist/vite-plugin-astro-server/plugin.js +26 -4
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { encryptString } from "../../../core/encryption.js";
|
|
1
|
+
import { encryptString, generateCspDigest } from "../../../core/encryption.js";
|
|
2
2
|
import { markHTMLString } from "../escape.js";
|
|
3
3
|
import { renderChild } from "./any.js";
|
|
4
|
+
import { createThinHead } from "./astro/head-and-content.js";
|
|
4
5
|
import { createRenderInstruction } from "./instruction.js";
|
|
5
6
|
import { renderSlotToString } from "./slot.js";
|
|
6
7
|
const internalProps = /* @__PURE__ */ new Set([
|
|
@@ -31,54 +32,63 @@ function isWithinURLLimit(pathname, params) {
|
|
|
31
32
|
const chars = url.length;
|
|
32
33
|
return chars < 2048;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
class ServerIslandComponent {
|
|
36
|
+
result;
|
|
37
|
+
props;
|
|
38
|
+
slots;
|
|
39
|
+
displayName;
|
|
40
|
+
hostId;
|
|
41
|
+
islandContent;
|
|
42
|
+
constructor(result, props, slots, displayName) {
|
|
43
|
+
this.result = result;
|
|
44
|
+
this.props = props;
|
|
45
|
+
this.slots = slots;
|
|
46
|
+
this.displayName = displayName;
|
|
47
|
+
}
|
|
48
|
+
async init() {
|
|
49
|
+
const componentPath = this.props["server:component-path"];
|
|
50
|
+
const componentExport = this.props["server:component-export"];
|
|
51
|
+
const componentId = this.result.serverIslandNameMap.get(componentPath);
|
|
52
|
+
if (!componentId) {
|
|
53
|
+
throw new Error(`Could not find server component name`);
|
|
54
|
+
}
|
|
55
|
+
for (const key2 of Object.keys(this.props)) {
|
|
56
|
+
if (internalProps.has(key2)) {
|
|
57
|
+
delete this.props[key2];
|
|
47
58
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
renderedSlots[name] = content.toString();
|
|
55
|
-
} else {
|
|
56
|
-
await renderChild(destination, slots.fallback(result));
|
|
57
|
-
}
|
|
59
|
+
}
|
|
60
|
+
const renderedSlots = {};
|
|
61
|
+
for (const name in this.slots) {
|
|
62
|
+
if (name !== "fallback") {
|
|
63
|
+
const content2 = await renderSlotToString(this.result, this.slots[name]);
|
|
64
|
+
renderedSlots[name] = content2.toString();
|
|
58
65
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
}
|
|
67
|
+
const key = await this.result.key;
|
|
68
|
+
const propsEncrypted = Object.keys(this.props).length === 0 ? "" : await encryptString(key, JSON.stringify(this.props));
|
|
69
|
+
const hostId = crypto.randomUUID();
|
|
70
|
+
const slash = this.result.base.endsWith("/") ? "" : "/";
|
|
71
|
+
let serverIslandUrl = `${this.result.base}${slash}_server-islands/${componentId}${this.result.trailingSlash === "always" ? "/" : ""}`;
|
|
72
|
+
const potentialSearchParams = createSearchParams(
|
|
73
|
+
componentExport,
|
|
74
|
+
propsEncrypted,
|
|
75
|
+
safeJsonStringify(renderedSlots)
|
|
76
|
+
);
|
|
77
|
+
const useGETRequest = isWithinURLLimit(serverIslandUrl, potentialSearchParams);
|
|
78
|
+
if (useGETRequest) {
|
|
79
|
+
serverIslandUrl += "?" + potentialSearchParams.toString();
|
|
80
|
+
this.result._metadata.extraHead.push(
|
|
81
|
+
markHTMLString(
|
|
73
82
|
`<link rel="preload" as="fetch" href="${serverIslandUrl}" crossorigin="anonymous">`
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
const method = useGETRequest ? (
|
|
87
|
+
// GET request
|
|
88
|
+
`let response = await fetch('${serverIslandUrl}');`
|
|
89
|
+
) : (
|
|
90
|
+
// POST request
|
|
91
|
+
`let data = {
|
|
82
92
|
componentExport: ${safeJsonStringify(componentExport)},
|
|
83
93
|
encryptedProps: ${safeJsonStringify(propsEncrypted)},
|
|
84
94
|
slots: ${safeJsonStringify(renderedSlots)},
|
|
@@ -87,33 +97,54 @@ let response = await fetch('${serverIslandUrl}', {
|
|
|
87
97
|
method: 'POST',
|
|
88
98
|
body: JSON.stringify(data),
|
|
89
99
|
});`
|
|
90
|
-
|
|
91
|
-
replaceServerIsland('${hostId}', response)
|
|
100
|
+
);
|
|
101
|
+
const content = `${method}replaceServerIsland('${hostId}', response);`;
|
|
102
|
+
if (this.result.shouldInjectCspMetaTags) {
|
|
103
|
+
this.result._metadata.extraScriptHashes.push(
|
|
104
|
+
await generateCspDigest(SERVER_ISLAND_REPLACER, this.result.cspAlgorithm)
|
|
105
|
+
);
|
|
106
|
+
const contentDigest = await generateCspDigest(content, this.result.cspAlgorithm);
|
|
107
|
+
this.result._metadata.extraScriptHashes.push(contentDigest);
|
|
92
108
|
}
|
|
93
|
-
|
|
109
|
+
this.islandContent = content;
|
|
110
|
+
this.hostId = hostId;
|
|
111
|
+
return createThinHead();
|
|
112
|
+
}
|
|
113
|
+
async render(destination) {
|
|
114
|
+
destination.write(createRenderInstruction({ type: "server-island-runtime" }));
|
|
115
|
+
destination.write("<!--[if astro]>server-island-start<![endif]-->");
|
|
116
|
+
for (const name in this.slots) {
|
|
117
|
+
if (name === "fallback") {
|
|
118
|
+
await renderChild(destination, this.slots.fallback(this.result));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
destination.write(
|
|
122
|
+
`<script type="module" data-astro-rerun data-island-id="${this.hostId}">${this.islandContent}</script>`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
94
125
|
}
|
|
95
|
-
const renderServerIslandRuntime = () =>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
126
|
+
const renderServerIslandRuntime = () => {
|
|
127
|
+
return `<script>${SERVER_ISLAND_REPLACER}</script>`;
|
|
128
|
+
};
|
|
129
|
+
const SERVER_ISLAND_REPLACER = markHTMLString(
|
|
130
|
+
`async function replaceServerIsland(id, r) {
|
|
131
|
+
let s = document.querySelector(\`script[data-island-id="\${id}"]\`);
|
|
132
|
+
// If there's no matching script, or the request fails then return
|
|
133
|
+
if (!s || r.status !== 200 || r.headers.get('content-type')?.split(';')[0].trim() !== 'text/html') return;
|
|
134
|
+
// Load the HTML before modifying the DOM in case of errors
|
|
135
|
+
let html = await r.text();
|
|
136
|
+
// Remove any placeholder content before the island script
|
|
137
|
+
while (s.previousSibling && s.previousSibling.nodeType !== 8 && s.previousSibling.data !== '[if astro]>server-island-start<![endif]')
|
|
138
|
+
s.previousSibling.remove();
|
|
139
|
+
s.previousSibling?.remove();
|
|
140
|
+
// Insert the new HTML
|
|
141
|
+
s.before(document.createRange().createContextualFragment(html));
|
|
142
|
+
// Remove the script. Prior to v5.4.2, this was the trick to force rerun of scripts. Keeping it to minimize change to the existing behavior.
|
|
143
|
+
s.remove();
|
|
144
|
+
}`.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("//")).join(" ")
|
|
114
145
|
);
|
|
115
146
|
export {
|
|
147
|
+
ServerIslandComponent,
|
|
116
148
|
containsServerDirective,
|
|
117
|
-
renderServerIsland,
|
|
118
149
|
renderServerIslandRuntime
|
|
119
150
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SSRResult } from '../../types/public/internal.js';
|
|
2
2
|
export declare function determineIfNeedsHydrationScript(result: SSRResult): boolean;
|
|
3
3
|
export declare function determinesIfNeedsDirectiveScript(result: SSRResult, directive: string): boolean;
|
|
4
|
-
export type PrescriptType =
|
|
4
|
+
export type PrescriptType = 'both' | 'directive';
|
|
5
5
|
export declare function getPrescripts(result: SSRResult, type: PrescriptType, directive: string): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { ISLAND_STYLES } from "./astro-island-styles.js";
|
|
1
2
|
import islandScriptDev from "./astro-island.prebuilt-dev.js";
|
|
2
3
|
import islandScript from "./astro-island.prebuilt.js";
|
|
3
|
-
const ISLAND_STYLES = `<style>astro-island,astro-slot,astro-static-slot{display:contents}</style>`;
|
|
4
4
|
function determineIfNeedsHydrationScript(result) {
|
|
5
5
|
if (result._metadata.hasHydrationScript) {
|
|
6
6
|
return false;
|
|
@@ -25,13 +25,10 @@ function getDirectiveScriptText(result, directive) {
|
|
|
25
25
|
function getPrescripts(result, type, directive) {
|
|
26
26
|
switch (type) {
|
|
27
27
|
case "both":
|
|
28
|
-
return
|
|
28
|
+
return `<style>${ISLAND_STYLES}</style><script>${getDirectiveScriptText(result, directive)}</script><script>${process.env.NODE_ENV === "development" ? islandScriptDev : islandScript}</script>`;
|
|
29
29
|
case "directive":
|
|
30
30
|
return `<script>${getDirectiveScriptText(result, directive)}</script>`;
|
|
31
|
-
case null:
|
|
32
|
-
break;
|
|
33
31
|
}
|
|
34
|
-
return "";
|
|
35
32
|
}
|
|
36
33
|
export {
|
|
37
34
|
determineIfNeedsHydrationScript,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SSRResult } from '../../types/public/internal.js';
|
|
2
2
|
import type { TransitionAnimationPair, TransitionAnimationValue } from '../../types/public/view-transitions.js';
|
|
3
3
|
export declare function createTransitionScope(result: SSRResult, hash: string): string;
|
|
4
|
-
export declare function renderTransition(result: SSRResult, hash: string, animationName: TransitionAnimationValue | undefined, transitionName: string): string
|
|
4
|
+
export declare function renderTransition(result: SSRResult, hash: string, animationName: TransitionAnimationValue | undefined, transitionName: string): Promise<string>;
|
|
5
5
|
export declare function createAnimationScope(transitionName: string, animations: Record<string, TransitionAnimationPair>): {
|
|
6
6
|
scope: string;
|
|
7
7
|
styles: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import cssesc from "cssesc";
|
|
2
|
+
import { generateCspDigest } from "../../core/encryption.js";
|
|
2
3
|
import { fade, slide } from "../../transitions/index.js";
|
|
3
4
|
import { markHTMLString } from "./escape.js";
|
|
4
5
|
const transitionNameMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -39,7 +40,7 @@ function reEncode(s) {
|
|
|
39
40
|
}
|
|
40
41
|
return reEncodeInValidStart[result.codePointAt(0) ?? 0] ? "_" + result : result;
|
|
41
42
|
}
|
|
42
|
-
function renderTransition(result, hash, animationName, transitionName) {
|
|
43
|
+
async function renderTransition(result, hash, animationName, transitionName) {
|
|
43
44
|
if (typeof (transitionName ?? "") !== "string") {
|
|
44
45
|
throw new Error(`Invalid transition name {${transitionName}}`);
|
|
45
46
|
}
|
|
@@ -56,7 +57,11 @@ function renderTransition(result, hash, animationName, transitionName) {
|
|
|
56
57
|
sheet.addAnimationRaw("new", "animation: none; mix-blend-mode: normal;");
|
|
57
58
|
sheet.addModern("group", "animation: none");
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
const css = sheet.toString();
|
|
61
|
+
if (result.shouldInjectCspMetaTags) {
|
|
62
|
+
result._metadata.extraStyleHashes.push(await generateCspDigest(css, result.cspAlgorithm));
|
|
63
|
+
}
|
|
64
|
+
result._metadata.extraHead.push(markHTMLString(`<style>${css}</style>`));
|
|
60
65
|
return scope;
|
|
61
66
|
}
|
|
62
67
|
function createAnimationScope(transitionName, animations) {
|
|
@@ -9,6 +9,7 @@ import type { AssetsPrefix } from '../../core/app/types.js';
|
|
|
9
9
|
import type { AstroConfigType } from '../../core/config/schemas/index.js';
|
|
10
10
|
import type { REDIRECT_STATUS_CODES } from '../../core/constants.js';
|
|
11
11
|
import type { AstroCookieSetOptions } from '../../core/cookies/cookies.js';
|
|
12
|
+
import type { CspAlgorithm, CspDirective, CspHash } from '../../core/csp/config.js';
|
|
12
13
|
import type { LoggerLevel } from '../../core/logger/core.js';
|
|
13
14
|
import type { EnvSchema } from '../../env/schema.js';
|
|
14
15
|
import type { AstroIntegration } from './integrations.js';
|
|
@@ -17,6 +18,7 @@ export type Locales = (string | {
|
|
|
17
18
|
path: string;
|
|
18
19
|
})[];
|
|
19
20
|
export type { AstroFontProvider as FontProvider };
|
|
21
|
+
export type { CspAlgorithm };
|
|
20
22
|
type NormalizeLocales<T extends Locales> = {
|
|
21
23
|
[K in keyof T]: T[K] extends string ? T[K] : T[K] extends {
|
|
22
24
|
codes: Array<string>;
|
|
@@ -1747,8 +1749,6 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
|
|
|
1747
1749
|
*/
|
|
1748
1750
|
domains?: [TLocales] extends [never] ? Record<string, string> : Partial<Record<NormalizeLocales<NoInfer<TLocales>>, string>>;
|
|
1749
1751
|
};
|
|
1750
|
-
/** ! WARNING: SUBJECT TO CHANGE */
|
|
1751
|
-
db?: Config.Database;
|
|
1752
1752
|
/**
|
|
1753
1753
|
* @docs
|
|
1754
1754
|
* @kind heading
|
|
@@ -2118,6 +2118,244 @@ export interface ViteUserConfig extends OriginalViteUserConfig {
|
|
|
2118
2118
|
* include a trailing `-`, matching standard behavior in other Markdown tooling.
|
|
2119
2119
|
*/
|
|
2120
2120
|
headingIdCompat?: boolean;
|
|
2121
|
+
/**
|
|
2122
|
+
* @name experimental.csp
|
|
2123
|
+
* @type {boolean | object}
|
|
2124
|
+
* @default `false`
|
|
2125
|
+
* @version 5.9.0
|
|
2126
|
+
* @description
|
|
2127
|
+
*
|
|
2128
|
+
* Enables built-in support for Content Security Policy (CSP). For more information,
|
|
2129
|
+
* refer to the [experimental CSP documentation](https://docs.astro.build/en/reference/experimental-flags/csp/)
|
|
2130
|
+
*
|
|
2131
|
+
*/
|
|
2132
|
+
csp?: boolean | {
|
|
2133
|
+
/**
|
|
2134
|
+
* @name experimental.csp.algorithm
|
|
2135
|
+
* @type {"SHA-256" | "SHA-384" | "SHA-512"}
|
|
2136
|
+
* @default `'SHA-256'`
|
|
2137
|
+
* @version 5.9.0
|
|
2138
|
+
* @description
|
|
2139
|
+
*
|
|
2140
|
+
* The [hash function](https://developer.mozilla.org/en-US/docs/Glossary/Hash_function) to use to generate the hashes of the styles and scripts emitted by Astro.
|
|
2141
|
+
*
|
|
2142
|
+
* ```js
|
|
2143
|
+
* import { defineConfig } from 'astro/config';
|
|
2144
|
+
*
|
|
2145
|
+
* export default defineConfig({
|
|
2146
|
+
* experimental: {
|
|
2147
|
+
* csp: {
|
|
2148
|
+
* algorithm: 'SHA-512'
|
|
2149
|
+
* }
|
|
2150
|
+
* }
|
|
2151
|
+
* });
|
|
2152
|
+
* ```
|
|
2153
|
+
*/
|
|
2154
|
+
algorithm?: CspAlgorithm;
|
|
2155
|
+
/**
|
|
2156
|
+
* @name experimental.csp.styleDirective
|
|
2157
|
+
* @type {{ hashes?: CspHash[], resources?: string[] }}
|
|
2158
|
+
* @default `undefined`
|
|
2159
|
+
* @version 5.9.0
|
|
2160
|
+
* @description
|
|
2161
|
+
*
|
|
2162
|
+
* A configuration object that allows you to override the default sources for the `style-src` directive
|
|
2163
|
+
* with the `resources` property, or to provide additional `hashes` to be rendered.
|
|
2164
|
+
*
|
|
2165
|
+
* These properties are added to all pages and completely override Astro's default resources, not add to them.
|
|
2166
|
+
* Therefore, you must explicitly specify any default values that you want to be included.
|
|
2167
|
+
*/
|
|
2168
|
+
styleDirective?: {
|
|
2169
|
+
/**
|
|
2170
|
+
* @name experimental.csp.styleDirective.hashes
|
|
2171
|
+
* @type {CspHash[]}
|
|
2172
|
+
* @default `[]`
|
|
2173
|
+
* @version 5.9.0
|
|
2174
|
+
* @description
|
|
2175
|
+
*
|
|
2176
|
+
* A list of additional hashes added to the `style-src` directive.
|
|
2177
|
+
*
|
|
2178
|
+
* If you have external styles that aren't generated by Astro, this configuration option allows you to provide additional hashes to be rendered.
|
|
2179
|
+
*
|
|
2180
|
+
* You must provide hashes that start with `sha384-`, `sha512-` or `sha256-`. Other values will cause a validation error. These hashes are added to all pages.
|
|
2181
|
+
*
|
|
2182
|
+
* ```js
|
|
2183
|
+
* import { defineConfig } from 'astro/config';
|
|
2184
|
+
*
|
|
2185
|
+
* export default defineConfig({
|
|
2186
|
+
* experimental: {
|
|
2187
|
+
* csp: {
|
|
2188
|
+
* styleDirective: {
|
|
2189
|
+
* hashes: [
|
|
2190
|
+
* "sha384-styleHash",
|
|
2191
|
+
* "sha512-styleHash",
|
|
2192
|
+
* "sha256-styleHash"
|
|
2193
|
+
* ]
|
|
2194
|
+
* }
|
|
2195
|
+
* }
|
|
2196
|
+
* }
|
|
2197
|
+
* });
|
|
2198
|
+
* ```
|
|
2199
|
+
*/
|
|
2200
|
+
hashes?: CspHash[];
|
|
2201
|
+
/**
|
|
2202
|
+
* @name experimental.csp.styleDirective.resources
|
|
2203
|
+
* @type {string[]}
|
|
2204
|
+
* @default `[]`
|
|
2205
|
+
* @version 5.9.0
|
|
2206
|
+
* @description
|
|
2207
|
+
*
|
|
2208
|
+
* A list of resources applied to the `style-src` directive. These resources are added to all pages and will override Astro's defaults.
|
|
2209
|
+
*
|
|
2210
|
+
* ```js
|
|
2211
|
+
* import { defineConfig } from 'astro/config';
|
|
2212
|
+
*
|
|
2213
|
+
* export default defineConfig({
|
|
2214
|
+
* experimental: {
|
|
2215
|
+
* csp: {
|
|
2216
|
+
* styleDirective: {
|
|
2217
|
+
* resources: [
|
|
2218
|
+
* "self",
|
|
2219
|
+
* "https://styles.cdn.example.com"
|
|
2220
|
+
* ]
|
|
2221
|
+
* }
|
|
2222
|
+
* }
|
|
2223
|
+
* }
|
|
2224
|
+
* });
|
|
2225
|
+
* ```
|
|
2226
|
+
*/
|
|
2227
|
+
resources?: string[];
|
|
2228
|
+
};
|
|
2229
|
+
/**
|
|
2230
|
+
* @name experimental.csp.scriptDirective
|
|
2231
|
+
* @type {{ hashes?: CspHash[], resources?: string[], strictDynamic?: boolean }}
|
|
2232
|
+
* @default `undefined`
|
|
2233
|
+
* @version 5.9.0
|
|
2234
|
+
* @description
|
|
2235
|
+
*
|
|
2236
|
+
* A configuration object that allows you to override the default sources for the `script-src` directive
|
|
2237
|
+
* with the `resources` property, or to provide additional `hashes` to be rendered.
|
|
2238
|
+
*
|
|
2239
|
+
* These properties are added to all pages and completely override Astro's default resources, not add to them.
|
|
2240
|
+
* Therefore, you must explicitly specify any default values that you want to be included.
|
|
2241
|
+
*
|
|
2242
|
+
*/
|
|
2243
|
+
scriptDirective?: {
|
|
2244
|
+
/**
|
|
2245
|
+
* @name experimental.csp.scriptDirective.hashes
|
|
2246
|
+
* @type {CspHash[]}
|
|
2247
|
+
* @default `[]`
|
|
2248
|
+
* @version 5.9.0
|
|
2249
|
+
* @description
|
|
2250
|
+
*
|
|
2251
|
+
* A list of additional hashes added to the `script-src` directive.
|
|
2252
|
+
*
|
|
2253
|
+
* If you have external scripts that aren't generated by Astro, or inline scripts, this configuration option allows you to provide additional hashes to be rendered.
|
|
2254
|
+
*
|
|
2255
|
+
* You must provide hashes that start with `sha384-`, `sha512-` or `sha256-`. Other values will cause a validation error. These hashes are added to all pages.
|
|
2256
|
+
*
|
|
2257
|
+
* ```js
|
|
2258
|
+
* import { defineConfig } from 'astro/config';
|
|
2259
|
+
*
|
|
2260
|
+
* export default defineConfig({
|
|
2261
|
+
* experimental: {
|
|
2262
|
+
* csp: {
|
|
2263
|
+
* scriptDirective: {
|
|
2264
|
+
* hashes: [
|
|
2265
|
+
* "sha384-scriptHash",
|
|
2266
|
+
* "sha512-scriptHash",
|
|
2267
|
+
* "sha256-scriptHash"
|
|
2268
|
+
* ]
|
|
2269
|
+
* }
|
|
2270
|
+
* }
|
|
2271
|
+
* }
|
|
2272
|
+
* });
|
|
2273
|
+
* ```
|
|
2274
|
+
*/
|
|
2275
|
+
hashes?: CspHash[];
|
|
2276
|
+
/**
|
|
2277
|
+
* @name experimental.csp.scriptDirective.resources
|
|
2278
|
+
* @type {string[]}
|
|
2279
|
+
* @default `[]`
|
|
2280
|
+
* @version 5.9.0
|
|
2281
|
+
* @description
|
|
2282
|
+
*
|
|
2283
|
+
* A list of resources applied to the `script-src` directive. These resources are added to all pages and will override Astro's defaults.
|
|
2284
|
+
*
|
|
2285
|
+
* ```js
|
|
2286
|
+
* import { defineConfig } from 'astro/config';
|
|
2287
|
+
*
|
|
2288
|
+
* export default defineConfig({
|
|
2289
|
+
* experimental: {
|
|
2290
|
+
* csp: {
|
|
2291
|
+
* scriptDirective: {
|
|
2292
|
+
* resources: [
|
|
2293
|
+
* "self",
|
|
2294
|
+
* "https://cdn.example.com"
|
|
2295
|
+
* ]
|
|
2296
|
+
* }
|
|
2297
|
+
* }
|
|
2298
|
+
* }
|
|
2299
|
+
* });
|
|
2300
|
+
* ```
|
|
2301
|
+
*
|
|
2302
|
+
*/
|
|
2303
|
+
resources?: string[];
|
|
2304
|
+
/**
|
|
2305
|
+
* @name experimental.csp.scriptDirective.strictDynamic
|
|
2306
|
+
* @type {boolean}
|
|
2307
|
+
* @default `false`
|
|
2308
|
+
* @version 5.9.0
|
|
2309
|
+
* @description
|
|
2310
|
+
*
|
|
2311
|
+
* Enables the keyword `strict-dynamic` to support the dynamic injection of scripts.
|
|
2312
|
+
*
|
|
2313
|
+
* ```js
|
|
2314
|
+
* import { defineConfig } from 'astro/config';
|
|
2315
|
+
*
|
|
2316
|
+
* export default defineConfig({
|
|
2317
|
+
* experimental: {
|
|
2318
|
+
* csp: {
|
|
2319
|
+
* scriptDirective: {
|
|
2320
|
+
* strictDynamic: true
|
|
2321
|
+
* }
|
|
2322
|
+
* }
|
|
2323
|
+
* }
|
|
2324
|
+
* });
|
|
2325
|
+
* ```
|
|
2326
|
+
*/
|
|
2327
|
+
strictDynamic?: boolean;
|
|
2328
|
+
};
|
|
2329
|
+
/**
|
|
2330
|
+
* @name experimental.csp.directives
|
|
2331
|
+
* @type {string[]}
|
|
2332
|
+
* @default `[]`
|
|
2333
|
+
* @version 5.9.0
|
|
2334
|
+
* @description
|
|
2335
|
+
*
|
|
2336
|
+
* An array of additional directives to add the content of the `Content-Security-Policy` `<meta>` element.
|
|
2337
|
+
*
|
|
2338
|
+
* Use this configuration to add other directive definitions such as `default-src`, `image-src`, etc.
|
|
2339
|
+
*
|
|
2340
|
+
* ##### Example
|
|
2341
|
+
*
|
|
2342
|
+
* You can define a directive to fetch images only from a CDN `cdn.example.com`.
|
|
2343
|
+
*
|
|
2344
|
+
* ```js
|
|
2345
|
+
* export default defineConfig({
|
|
2346
|
+
* experimental: {
|
|
2347
|
+
* csp: {
|
|
2348
|
+
* directives: [
|
|
2349
|
+
* "image-src 'https://cdn.example.com"
|
|
2350
|
+
* ]
|
|
2351
|
+
* }
|
|
2352
|
+
* }
|
|
2353
|
+
* })
|
|
2354
|
+
* ```
|
|
2355
|
+
*
|
|
2356
|
+
*/
|
|
2357
|
+
directives?: CspDirective[];
|
|
2358
|
+
};
|
|
2121
2359
|
/**
|
|
2122
2360
|
* @name experimental.preserveScriptOrder
|
|
2123
2361
|
* @type {boolean}
|
|
@@ -2212,8 +2450,3 @@ export interface AstroInlineOnlyConfig {
|
|
|
2212
2450
|
*/
|
|
2213
2451
|
force?: boolean;
|
|
2214
2452
|
}
|
|
2215
|
-
declare global {
|
|
2216
|
-
namespace Config {
|
|
2217
|
-
type Database = Record<string, any>;
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
@@ -2,6 +2,7 @@ import type { z } from 'zod';
|
|
|
2
2
|
import type { ActionAccept, ActionClient, ActionReturnType } from '../../actions/runtime/virtual/server.js';
|
|
3
3
|
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../core/constants.js';
|
|
4
4
|
import type { AstroCookies } from '../../core/cookies/cookies.js';
|
|
5
|
+
import type { CspDirective, CspHash } from '../../core/csp/config.js';
|
|
5
6
|
import type { AstroSession } from '../../core/session.js';
|
|
6
7
|
import type { AstroComponentFactory } from '../../runtime/server/index.js';
|
|
7
8
|
import type { Params, RewritePayload } from './common.js';
|
|
@@ -310,6 +311,56 @@ export interface AstroSharedContext<Props extends Record<string, any> = Record<s
|
|
|
310
311
|
* Whether the current route is prerendered or not.
|
|
311
312
|
*/
|
|
312
313
|
isPrerendered: boolean;
|
|
314
|
+
/**
|
|
315
|
+
* It adds a specific CSP directive to the route being rendered.
|
|
316
|
+
*
|
|
317
|
+
* ## Example
|
|
318
|
+
*
|
|
319
|
+
* ```js
|
|
320
|
+
* ctx.insertDirective("default-src 'self' 'unsafe-inline' https://example.com")
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
insertDirective: (directive: CspDirective) => void;
|
|
324
|
+
/**
|
|
325
|
+
* It set the resource for the directive `style-src` in the route being rendered. It overrides Astro's default.
|
|
326
|
+
*
|
|
327
|
+
* ## Example
|
|
328
|
+
*
|
|
329
|
+
* ```js
|
|
330
|
+
* ctx.insertStyleResource("https://styles.cdn.example.com/")
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
insertStyleResource: (payload: string) => void;
|
|
334
|
+
/**
|
|
335
|
+
* Insert a single style hash to the route being rendered.
|
|
336
|
+
*
|
|
337
|
+
* ## Example
|
|
338
|
+
*
|
|
339
|
+
* ```js
|
|
340
|
+
* ctx.insertStyleHash("sha256-1234567890abcdef1234567890")
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
insertStyleHash: (hash: CspHash) => void;
|
|
344
|
+
/**
|
|
345
|
+
* It set the resource for the directive `script-src` in the route being rendered.
|
|
346
|
+
*
|
|
347
|
+
* ## Example
|
|
348
|
+
*
|
|
349
|
+
* ```js
|
|
350
|
+
* ctx.insertScriptResource("https://scripts.cdn.example.com/")
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
insertScriptResource: (resource: string) => void;
|
|
354
|
+
/**
|
|
355
|
+
* Insert a single script hash to the route being rendered.
|
|
356
|
+
*
|
|
357
|
+
* ## Example
|
|
358
|
+
*
|
|
359
|
+
* ```js
|
|
360
|
+
* ctx.insertScriptHash("sha256-1234567890abcdef1234567890")
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
insertScriptHash: (hash: CspHash) => void;
|
|
313
364
|
}
|
|
314
365
|
/**
|
|
315
366
|
* The `APIContext` is the object made available to endpoints and middleware.
|
|
@@ -53,6 +53,15 @@ export type AdapterSupportsKind = (typeof AdapterFeatureStability)[keyof typeof
|
|
|
53
53
|
export type AdapterSupportWithMessage = {
|
|
54
54
|
support: Exclude<AdapterSupportsKind, 'stable'>;
|
|
55
55
|
message: string;
|
|
56
|
+
/**
|
|
57
|
+
* Determines if a feature support warning/error in the adapter should be suppressed:
|
|
58
|
+
* - `"default"`: Suppresses the default warning/error message.
|
|
59
|
+
* - `"all"`: Suppresses both the custom and the default warning/error message.
|
|
60
|
+
*
|
|
61
|
+
* This is useful when the warning/error might not be applicable in certain contexts,
|
|
62
|
+
* or the default message might cause confusion and conflict with a custom one.
|
|
63
|
+
*/
|
|
64
|
+
suppress?: 'all' | 'default';
|
|
56
65
|
};
|
|
57
66
|
export type AdapterSupport = AdapterSupportsKind | AdapterSupportWithMessage;
|
|
58
67
|
export interface AstroAdapterFeatures {
|