astro 7.2.3 → 7.2.5
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/bin/astro.mjs +15 -0
- package/client.d.ts +8 -4
- package/dist/assets/consts.d.ts +1 -1
- package/dist/assets/consts.js +1 -0
- package/dist/assets/fonts/infra/remote-runtime-font-file-url-resolver.d.ts +6 -4
- package/dist/assets/fonts/infra/remote-runtime-font-file-url-resolver.js +14 -7
- package/dist/assets/utils/node.js +3 -0
- package/dist/assets/utils/vendor/image-size/types/heif.js +8 -3
- package/dist/assets/utils/vendor/image-size/types/icns.js +10 -2
- package/dist/assets/utils/vendor/image-size/types/jp2.js +2 -2
- package/dist/assets/utils/vendor/image-size/types/jxl.js +5 -2
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +1 -1
- package/dist/assets/utils/vendor/image-size/types/utils.js +20 -6
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/cli/server.js +13 -0
- package/dist/container/index.js +8 -5
- package/dist/content/config.d.ts +2 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/loaders/glob.js +3 -3
- package/dist/content/mutable-data-store.js +49 -2
- package/dist/core/app/base.js +3 -7
- package/dist/core/build/plugins/plugin-incremental.js +8 -2
- package/dist/core/build/vite-build-config.js +15 -6
- package/dist/core/cache/memory-provider.js +6 -1
- package/dist/core/compile/compile.js +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/lockfile.js +3 -0
- package/dist/core/errors/dev/utils.js +3 -3
- package/dist/core/fetch/fetch-state.js +11 -14
- package/dist/core/i18n/domain.js +4 -11
- package/dist/core/i18n/handler.js +5 -1
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/routing/match-request.js +2 -13
- package/dist/core/session/runtime.js +4 -2
- package/dist/core/session/types.d.ts +5 -5
- package/dist/core/util/normalized-url.d.ts +8 -0
- package/dist/core/util/normalized-url.js +10 -4
- package/dist/i18n/utils.js +3 -4
- package/dist/runtime/server/astro-global.js +2 -2
- package/dist/runtime/server/render/csp.js +13 -5
- package/dist/transitions/swap-functions.js +4 -2
- package/dist/types/public/config.d.ts +1 -1
- package/dist/vite-plugin-routes/index.js +1 -1
- package/package.json +7 -7
- package/templates/content/module.mjs +3 -3
- package/types/content.d.ts +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import picomatch from "picomatch";
|
|
2
|
+
import { getCookiesFromResponse } from "../cookies/response.js";
|
|
2
3
|
import { AstroError } from "../errors/errors.js";
|
|
3
4
|
import { CacheQueryConfigConflict } from "../errors/errors-data.js";
|
|
4
5
|
function parseCdnCacheControl(header) {
|
|
@@ -110,8 +111,12 @@ function matchesVary(request, entry) {
|
|
|
110
111
|
}
|
|
111
112
|
return true;
|
|
112
113
|
}
|
|
114
|
+
function hasAtLeastOneCookie(cookies) {
|
|
115
|
+
return cookies ? !cookies.headers().next().done : false;
|
|
116
|
+
}
|
|
113
117
|
function hasSetCookieHeader(response) {
|
|
114
|
-
|
|
118
|
+
if (response.headers.has("set-cookie")) return true;
|
|
119
|
+
return hasAtLeastOneCookie(getCookiesFromResponse(response));
|
|
115
120
|
}
|
|
116
121
|
function warnSkippedSetCookie(url) {
|
|
117
122
|
console.warn(
|
|
@@ -31,7 +31,7 @@ async function compile({
|
|
|
31
31
|
normalizedFilename: normalizeFilename(filename, astroConfig.root),
|
|
32
32
|
sourcemap: "both",
|
|
33
33
|
internalURL: "astro/compiler-runtime",
|
|
34
|
-
// TODO: remove in Astro
|
|
34
|
+
// TODO: remove in Astro v8
|
|
35
35
|
astroGlobalArgs: JSON.stringify(astroConfig.site),
|
|
36
36
|
scopedStyleStrategy: astroConfig.scopedStyleStrategy,
|
|
37
37
|
resultScopedSlot: true,
|
package/dist/core/constants.js
CHANGED
package/dist/core/create-vite.js
CHANGED
|
@@ -223,7 +223,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
|
|
|
223
223
|
find: "astro:middleware",
|
|
224
224
|
replacement: "astro/virtual-modules/middleware.js"
|
|
225
225
|
},
|
|
226
|
-
// TODO: remove in Astro
|
|
226
|
+
// TODO: remove in Astro 8
|
|
227
227
|
{
|
|
228
228
|
find: "astro:schema",
|
|
229
229
|
replacement: "astro/zod"
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -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.2.
|
|
29
|
+
const currentVersion = "7.2.5";
|
|
30
30
|
const isPrerelease = currentVersion.includes("-");
|
|
31
31
|
if (!isPrerelease) {
|
|
32
32
|
try {
|
|
@@ -48,6 +48,9 @@ function isAstroCommand(command) {
|
|
|
48
48
|
return ASTRO_COMMAND_PATTERN.test(command);
|
|
49
49
|
}
|
|
50
50
|
async function isLockFileProcessAlive(data, find = findProcess) {
|
|
51
|
+
if (data.pid === process.pid) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
51
54
|
if (!isProcessAlive(data.pid)) {
|
|
52
55
|
return false;
|
|
53
56
|
}
|
|
@@ -12,8 +12,8 @@ import { normalizeLF } from "../utils.js";
|
|
|
12
12
|
function collectErrorMetadata(e, rootFolder) {
|
|
13
13
|
const err = AggregateError.is(e) || Array.isArray(e.errors) ? e.errors : [e];
|
|
14
14
|
err.forEach((error) => {
|
|
15
|
-
if (
|
|
16
|
-
const stackInfo = collectInfoFromStacktrace(
|
|
15
|
+
if (error.stack) {
|
|
16
|
+
const stackInfo = collectInfoFromStacktrace(error);
|
|
17
17
|
try {
|
|
18
18
|
error.stack = stripVTControlCharacters(stackInfo.stack);
|
|
19
19
|
} catch {
|
|
@@ -40,7 +40,7 @@ function collectErrorMetadata(e, rootFolder) {
|
|
|
40
40
|
} catch {
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
error.hint = generateHint(
|
|
43
|
+
error.hint = generateHint(error);
|
|
44
44
|
if (error.message) {
|
|
45
45
|
try {
|
|
46
46
|
error.message = stripVTControlCharacters(error.message);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import colors from "piccolore";
|
|
2
2
|
import {
|
|
3
|
-
collapseDuplicateLeadingSlashes,
|
|
4
3
|
collapseDuplicateSlashes,
|
|
5
4
|
prependForwardSlash,
|
|
6
|
-
|
|
5
|
+
stripRequestBase
|
|
7
6
|
} from "@astrojs/internal-helpers/path";
|
|
8
7
|
import { deserializeActionResult } from "../../actions/runtime/client.js";
|
|
9
8
|
import { createCallAction, createGetActionResult, hasActionPayload } from "../../actions/utils.js";
|
|
@@ -28,6 +27,7 @@ import { getParams, getProps } from "../render/index.js";
|
|
|
28
27
|
import { executeRewrite } from "../rewrites/handler.js";
|
|
29
28
|
import { isRoute404or500, isRouteServerIsland } from "../routing/match.js";
|
|
30
29
|
import { MultiLevelEncodingError, validateAndDecodePathname } from "../util/pathname.js";
|
|
30
|
+
import { setPathname } from "../util/normalized-url.js";
|
|
31
31
|
import { getOriginPathname, setOriginPathname } from "../routing/rewrite.js";
|
|
32
32
|
import { computePathnameFromDomain } from "../i18n/domain.js";
|
|
33
33
|
import { getCustom404Route, routeHasHtmlExtension } from "../routing/helpers.js";
|
|
@@ -211,8 +211,8 @@ class FetchState {
|
|
|
211
211
|
const url = new URL(request.url);
|
|
212
212
|
const publicPathname = this.#normalizePathname(url.pathname);
|
|
213
213
|
const pathname = this.#computePathname(publicPathname);
|
|
214
|
-
url
|
|
215
|
-
url
|
|
214
|
+
setPathname(url, publicPathname);
|
|
215
|
+
setPathname(url, collapseDuplicateSlashes(url.pathname));
|
|
216
216
|
const domainPathname = computePathnameFromDomain(
|
|
217
217
|
request,
|
|
218
218
|
url,
|
|
@@ -723,6 +723,9 @@ class FetchState {
|
|
|
723
723
|
#stripHtmlExtension() {
|
|
724
724
|
if (this.routeData && this.routeData.type === "page" && !routeHasHtmlExtension(this.routeData)) {
|
|
725
725
|
this.pathname = this.pathname.replace(/\/index\.html$/, "/").replace(/\.html$/, "");
|
|
726
|
+
if (this.manifest.trailingSlash === "always" && this.pathname !== "" && !this.pathname.endsWith("/")) {
|
|
727
|
+
this.pathname += "/";
|
|
728
|
+
}
|
|
726
729
|
}
|
|
727
730
|
}
|
|
728
731
|
#resolveRouteData() {
|
|
@@ -760,18 +763,12 @@ class FetchState {
|
|
|
760
763
|
* Strips the manifest's base from a normalized request pathname and prepends
|
|
761
764
|
* a forward slash.
|
|
762
765
|
*
|
|
763
|
-
* Mirrors `BaseApp.removeBase
|
|
764
|
-
* `
|
|
765
|
-
*
|
|
766
|
+
* Mirrors `BaseApp.removeBase`: the router matches against this stripped path
|
|
767
|
+
* while middleware reads the un-stripped `context.url.pathname`, so both must
|
|
768
|
+
* strip the base identically.
|
|
766
769
|
*/
|
|
767
770
|
#computePathname(normalizedPathname) {
|
|
768
|
-
|
|
769
|
-
const base = this.manifest.base;
|
|
770
|
-
if (pathname.startsWith(base)) {
|
|
771
|
-
const baseWithoutTrailingSlash = removeTrailingForwardSlash(base);
|
|
772
|
-
pathname = pathname.slice(baseWithoutTrailingSlash.length + 1);
|
|
773
|
-
}
|
|
774
|
-
return prependForwardSlash(pathname);
|
|
771
|
+
return prependForwardSlash(stripRequestBase(normalizedPathname, this.manifest.base));
|
|
775
772
|
}
|
|
776
773
|
/**
|
|
777
774
|
* Decodes and normalizes the public request pathname before deriving the
|
package/dist/core/i18n/domain.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
appendForwardSlash,
|
|
3
|
-
collapseDuplicateLeadingSlashes,
|
|
4
3
|
joinPaths,
|
|
5
4
|
prependForwardSlash,
|
|
6
|
-
removeTrailingForwardSlash
|
|
5
|
+
removeTrailingForwardSlash,
|
|
6
|
+
stripRequestBase
|
|
7
7
|
} from "@astrojs/internal-helpers/path";
|
|
8
8
|
import { normalizeTheLocale } from "../../i18n/path.js";
|
|
9
9
|
function computePathnameFromDomain(request, url, i18n, base, trailingSlash, logger, pathnameFromRequest) {
|
|
@@ -32,13 +32,13 @@ function computePathnameFromDomain(request, url, i18n, base, trailingSlash, logg
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
if (locale) {
|
|
35
|
-
const requestPathname = pathnameFromRequest ??
|
|
35
|
+
const requestPathname = pathnameFromRequest ?? stripRequestBase(url.pathname, base);
|
|
36
36
|
pathname = prependForwardSlash(joinPaths(normalizeTheLocale(locale), requestPathname));
|
|
37
37
|
if (trailingSlash === "always") {
|
|
38
38
|
pathname = appendForwardSlash(pathname);
|
|
39
39
|
} else if (trailingSlash === "never") {
|
|
40
40
|
pathname = removeTrailingForwardSlash(pathname);
|
|
41
|
-
} else if (
|
|
41
|
+
} else if (url.pathname.endsWith("/")) {
|
|
42
42
|
pathname = appendForwardSlash(pathname);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -53,13 +53,6 @@ function computePathnameFromDomain(request, url, i18n, base, trailingSlash, logg
|
|
|
53
53
|
}
|
|
54
54
|
return pathname;
|
|
55
55
|
}
|
|
56
|
-
function removeBase(pathname, base) {
|
|
57
|
-
pathname = collapseDuplicateLeadingSlashes(pathname);
|
|
58
|
-
if (pathname.startsWith(base)) {
|
|
59
|
-
return pathname.slice(removeTrailingForwardSlash(base).length + 1);
|
|
60
|
-
}
|
|
61
|
-
return pathname;
|
|
62
|
-
}
|
|
63
56
|
export {
|
|
64
57
|
computePathnameFromDomain
|
|
65
58
|
};
|
|
@@ -102,7 +102,11 @@ async function finalizeI18n(compiled, state, response) {
|
|
|
102
102
|
headers: { Location: fallbackDecision.pathname + url.search }
|
|
103
103
|
});
|
|
104
104
|
case "rewrite":
|
|
105
|
-
|
|
105
|
+
try {
|
|
106
|
+
return await state.rewrite(fallbackDecision.pathname + url.search);
|
|
107
|
+
} catch {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
106
110
|
case "none":
|
|
107
111
|
break;
|
|
108
112
|
}
|
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collapseDuplicateLeadingSlashes,
|
|
3
|
-
prependForwardSlash,
|
|
4
|
-
removeTrailingForwardSlash
|
|
5
|
-
} from "@astrojs/internal-helpers/path";
|
|
1
|
+
import { prependForwardSlash, stripRequestBase } from "@astrojs/internal-helpers/path";
|
|
6
2
|
import { computePathnameFromDomain } from "../i18n/domain.js";
|
|
7
3
|
import { AstroIntegrationLogger } from "../logger/core.js";
|
|
8
4
|
import { getLogger } from "../logger/manifest-logger.js";
|
|
9
5
|
import { matchAllRoutes, matchRoute } from "./route-table.js";
|
|
10
|
-
function removeBase(manifest, pathname) {
|
|
11
|
-
pathname = collapseDuplicateLeadingSlashes(pathname);
|
|
12
|
-
if (pathname.startsWith(manifest.base)) {
|
|
13
|
-
return pathname.slice(removeTrailingForwardSlash(manifest.base).length + 1);
|
|
14
|
-
}
|
|
15
|
-
return pathname;
|
|
16
|
-
}
|
|
17
6
|
function safeDecodeURI(manifest, pathname) {
|
|
18
7
|
try {
|
|
19
8
|
return decodeURI(pathname);
|
|
@@ -36,7 +25,7 @@ function matchRequest(manifest, request, allowPrerenderedRoutes = false) {
|
|
|
36
25
|
getLogger(manifest)
|
|
37
26
|
);
|
|
38
27
|
if (!pathname) {
|
|
39
|
-
pathname = prependForwardSlash(
|
|
28
|
+
pathname = prependForwardSlash(stripRequestBase(url.pathname, manifest.base));
|
|
40
29
|
}
|
|
41
30
|
const routeData = matchRoute(manifest, safeDecodeURI(manifest, pathname));
|
|
42
31
|
if (!routeData) return void 0;
|
|
@@ -5,6 +5,7 @@ import { createStorage } from "unstorage";
|
|
|
5
5
|
const PERSIST_SYMBOL = /* @__PURE__ */ Symbol();
|
|
6
6
|
const DEFAULT_COOKIE_NAME = "astro-session";
|
|
7
7
|
const VALID_COOKIE_REGEX = /^[\w-]+$/;
|
|
8
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8
9
|
const unflatten = (parsed, _) => {
|
|
9
10
|
return rawUnflatten(parsed, {
|
|
10
11
|
URL: (href) => new URL(href)
|
|
@@ -170,7 +171,8 @@ class AstroSession {
|
|
|
170
171
|
* Destroys the session, clearing the cookie and storage if it exists.
|
|
171
172
|
*/
|
|
172
173
|
destroy() {
|
|
173
|
-
const
|
|
174
|
+
const cookieValue = this.#cookies.get(this.#cookieName)?.value;
|
|
175
|
+
const sessionId = this.#sessionID ?? (cookieValue && UUID_REGEX.test(cookieValue) ? cookieValue : void 0);
|
|
174
176
|
if (sessionId) {
|
|
175
177
|
this.#toDestroy.add(sessionId);
|
|
176
178
|
}
|
|
@@ -340,7 +342,7 @@ class AstroSession {
|
|
|
340
342
|
#ensureSessionID() {
|
|
341
343
|
if (!this.#sessionID) {
|
|
342
344
|
const cookieValue = this.#cookies.get(this.#cookieName)?.value;
|
|
343
|
-
if (cookieValue) {
|
|
345
|
+
if (cookieValue && UUID_REGEX.test(cookieValue)) {
|
|
344
346
|
this.#sessionID = cookieValue;
|
|
345
347
|
this.#sessionIDFromCookie = true;
|
|
346
348
|
} else {
|
|
@@ -34,30 +34,30 @@ export interface BaseSessionConfig {
|
|
|
34
34
|
interface DriverConfig<TDriver extends SessionDriverConfig> extends BaseSessionConfig {
|
|
35
35
|
/** Config object for a session driver */
|
|
36
36
|
driver: TDriver;
|
|
37
|
-
/** @deprecated Pass options to the driver function directly. This will be removed in Astro
|
|
37
|
+
/** @deprecated Pass options to the driver function directly. This will be removed in Astro 8 */
|
|
38
38
|
options?: never;
|
|
39
39
|
}
|
|
40
40
|
interface UnstorageConfig<TDriver extends keyof BuiltinDriverOptions | undefined, TOptions = TDriver extends keyof BuiltinDriverOptions ? NoInfer<BuiltinDriverOptions[TDriver]> : undefined> extends BaseSessionConfig {
|
|
41
41
|
/**
|
|
42
42
|
* Entrypoint for an unstorage session driver
|
|
43
|
-
* @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro
|
|
43
|
+
* @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro 8
|
|
44
44
|
*/
|
|
45
45
|
driver?: TDriver;
|
|
46
46
|
/**
|
|
47
47
|
* Options for the unstorage driver
|
|
48
|
-
* @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro
|
|
48
|
+
* @deprecated Use `import { sessionDrivers } from 'astro/config'` instead. This will be removed in Astro 8
|
|
49
49
|
*/
|
|
50
50
|
options?: TOptions;
|
|
51
51
|
}
|
|
52
52
|
interface CustomConfig extends BaseSessionConfig {
|
|
53
53
|
/**
|
|
54
54
|
* Entrypoint for a custom session driver
|
|
55
|
-
* @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro
|
|
55
|
+
* @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro 8
|
|
56
56
|
*/
|
|
57
57
|
driver?: string;
|
|
58
58
|
/**
|
|
59
59
|
* Options for the custom session driver
|
|
60
|
-
* @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro
|
|
60
|
+
* @deprecated Use the object shape (type `SessionDriverConfig`). This will be removed in Astro 8
|
|
61
61
|
*/
|
|
62
62
|
options?: Record<string, unknown>;
|
|
63
63
|
}
|
|
@@ -3,8 +3,16 @@
|
|
|
3
3
|
* Decodes and validates the pathname, collapses duplicate slashes.
|
|
4
4
|
*/
|
|
5
5
|
export declare function createNormalizedUrl(requestUrl: string): URL;
|
|
6
|
+
/**
|
|
7
|
+
* Assigns `url.pathname` only when the value differs.
|
|
8
|
+
* The setter re-parses the whole URL, so a no-op write is still expensive.
|
|
9
|
+
*/
|
|
10
|
+
export declare function setPathname(url: URL, pathname: string): void;
|
|
6
11
|
/**
|
|
7
12
|
* Normalizes an already-parsed URL in place: decodes and validates the
|
|
8
13
|
* pathname, collapses duplicate slashes. Returns the same URL object.
|
|
14
|
+
*
|
|
15
|
+
* Collapse runs after the decode is written back: the pathname setter
|
|
16
|
+
* rewrites `\` to `/`, so a decoded backslash only becomes `//` once assigned.
|
|
9
17
|
*/
|
|
10
18
|
export declare function normalizeUrl(url: URL): URL;
|
|
@@ -3,19 +3,25 @@ import { validateAndDecodePathname } from "./pathname.js";
|
|
|
3
3
|
function createNormalizedUrl(requestUrl) {
|
|
4
4
|
return normalizeUrl(new URL(requestUrl));
|
|
5
5
|
}
|
|
6
|
+
function setPathname(url, pathname) {
|
|
7
|
+
if (url.pathname !== pathname) {
|
|
8
|
+
url.pathname = pathname;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
6
11
|
function normalizeUrl(url) {
|
|
7
12
|
try {
|
|
8
|
-
url
|
|
13
|
+
setPathname(url, validateAndDecodePathname(url.pathname));
|
|
9
14
|
} catch {
|
|
10
15
|
try {
|
|
11
|
-
url
|
|
16
|
+
setPathname(url, decodeURI(url.pathname));
|
|
12
17
|
} catch {
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
|
-
url
|
|
20
|
+
setPathname(url, collapseDuplicateSlashes(url.pathname));
|
|
16
21
|
return url;
|
|
17
22
|
}
|
|
18
23
|
export {
|
|
19
24
|
createNormalizedUrl,
|
|
20
|
-
normalizeUrl
|
|
25
|
+
normalizeUrl,
|
|
26
|
+
setPathname
|
|
21
27
|
};
|
package/dist/i18n/utils.js
CHANGED
|
@@ -43,10 +43,9 @@ function sortAndFilterLocales(browserLocaleList, locales) {
|
|
|
43
43
|
}
|
|
44
44
|
return true;
|
|
45
45
|
}).sort((a, b) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return 0;
|
|
46
|
+
const qa = a.locale === "*" ? a.qualityValue ?? 0 : a.qualityValue ?? 1;
|
|
47
|
+
const qb = b.locale === "*" ? b.qualityValue ?? 0 : b.qualityValue ?? 1;
|
|
48
|
+
return qb - qa;
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
function computePreferredLocale(request, locales) {
|
|
@@ -8,14 +8,14 @@ function createError(name) {
|
|
|
8
8
|
}
|
|
9
9
|
function createAstro(site) {
|
|
10
10
|
return {
|
|
11
|
-
// TODO: throw in Astro
|
|
11
|
+
// TODO: throw in Astro 8
|
|
12
12
|
get site() {
|
|
13
13
|
console.warn(
|
|
14
14
|
`Astro.site inside getStaticPaths is deprecated and will be removed in a future major version of Astro. Use import.meta.env.SITE instead`
|
|
15
15
|
);
|
|
16
16
|
return site ? new URL(site) : void 0;
|
|
17
17
|
},
|
|
18
|
-
// TODO: throw in Astro
|
|
18
|
+
// TODO: throw in Astro 8
|
|
19
19
|
get generator() {
|
|
20
20
|
console.warn(
|
|
21
21
|
`Astro.generator inside getStaticPaths is deprecated and will be removed in a future major version of Astro.`
|
|
@@ -28,12 +28,14 @@ function renderCspContent(result) {
|
|
|
28
28
|
const scriptElemActive = isEnabled(script.element);
|
|
29
29
|
const styleElemActive = isEnabled(style.element);
|
|
30
30
|
const strictDynamicSuffix = scriptDirective.strictDynamic ? ` 'strict-dynamic'` : "";
|
|
31
|
+
const scriptDefaultHasUnsafeInline = hasUnsafeInline(script.default.resources);
|
|
32
|
+
const styleDefaultHasUnsafeInline = hasUnsafeInline(style.default.resources);
|
|
31
33
|
const scriptBaselineTokens = [
|
|
32
|
-
...scriptElemActive ? [] : [...finalScriptHashes],
|
|
34
|
+
...scriptElemActive || scriptDefaultHasUnsafeInline ? [] : [...finalScriptHashes],
|
|
33
35
|
...scriptDirective.strictDynamic ? [`'strict-dynamic'`] : []
|
|
34
36
|
];
|
|
35
37
|
const scriptSrc = `script-src ${scriptResources} ${scriptBaselineTokens.join(" ")};`;
|
|
36
|
-
const styleSrc = `style-src ${styleResources} ${(styleElemActive ? [] : [...finalStyleHashes]).join(" ")};`;
|
|
38
|
+
const styleSrc = `style-src ${styleResources} ${(styleElemActive || styleDefaultHasUnsafeInline ? [] : [...finalStyleHashes]).join(" ")};`;
|
|
37
39
|
const scriptSrcElem = scriptElemActive ? renderSpecificDirective(
|
|
38
40
|
"script-src-elem",
|
|
39
41
|
script.element.resources,
|
|
@@ -73,13 +75,19 @@ function renderCspContent(result) {
|
|
|
73
75
|
styleSrcAttr
|
|
74
76
|
].filter(Boolean).join(" ");
|
|
75
77
|
}
|
|
78
|
+
function hasUnsafeInline(resources) {
|
|
79
|
+
return resources.includes("'unsafe-inline'");
|
|
80
|
+
}
|
|
76
81
|
function isEnabled(sources) {
|
|
77
82
|
return sources.resources.length > 0 || sources.hashes.length > 0;
|
|
78
83
|
}
|
|
79
84
|
function renderSpecificDirective(name, resources, defaultResource, sharedHashes, ownHashes, suffix = "") {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
const unsafeInline = hasUnsafeInline(resources);
|
|
86
|
+
const hashes = new Set(unsafeInline ? void 0 : sharedHashes);
|
|
87
|
+
if (!unsafeInline) {
|
|
88
|
+
for (const hash of ownHashes) {
|
|
89
|
+
hashes.add(`'${hash}'`);
|
|
90
|
+
}
|
|
83
91
|
}
|
|
84
92
|
let finalResources;
|
|
85
93
|
if (resources.length > 0) {
|
|
@@ -93,6 +93,7 @@ function swapHeadElements(doc) {
|
|
|
93
93
|
function swapBodyElement(newElement, oldElement) {
|
|
94
94
|
const persistPairs = [];
|
|
95
95
|
const docEl = oldElement.ownerDocument.documentElement;
|
|
96
|
+
const liveMedia = new Set(oldElement.querySelectorAll("video, audio"));
|
|
96
97
|
const moveBefore = typeof docEl.moveBefore === "function" ? (parent, node, child) => parent.moveBefore(node, child) : null;
|
|
97
98
|
for (const el of oldElement.querySelectorAll(`[${PERSIST_ATTR}]`)) {
|
|
98
99
|
const id = el.getAttribute(PERSIST_ATTR);
|
|
@@ -119,10 +120,11 @@ function swapBodyElement(newElement, oldElement) {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
attachShadowRoots(newElement);
|
|
122
|
-
reifyMediaElements(newElement);
|
|
123
|
+
reifyMediaElements(newElement, liveMedia);
|
|
123
124
|
}
|
|
124
|
-
function reifyMediaElements(root) {
|
|
125
|
+
function reifyMediaElements(root, liveMedia) {
|
|
125
126
|
for (const media of root.querySelectorAll("video, audio")) {
|
|
127
|
+
if (liveMedia.has(media)) continue;
|
|
126
128
|
const fresh = document.createElement(media.localName);
|
|
127
129
|
for (const attr of media.attributes) {
|
|
128
130
|
fresh.setAttribute(attr.name, attr.value);
|
|
@@ -749,7 +749,7 @@ export interface AstroUserConfig<TLocales extends Locales = never, TDriver exten
|
|
|
749
749
|
* - External scripts and external styles are not supported out of the box, but you can [provide your own hashes](https://docs.astro.build/en/reference/configuration-reference/#securitycspscriptdirectivehashes).
|
|
750
750
|
* - [Astro's view transitions](https://docs.astro.build/en/guides/view-transitions/) using the `<ClientRouter />` are not supported, but you can [consider migrating to the browser native View Transition API](https://events-3bg.pages.dev/jotter/astro-view-transitions/) instead if you are not using Astro's enhancements to the native View Transitions and Navigation APIs.
|
|
751
751
|
* - Shiki isn't currently supported. By design, Shiki functions use inline styles that cannot work with Astro CSP implementation. Consider [using `<Prism />`](https://docs.astro.build/en/guides/syntax-highlighting/#prism-) when your project requires both CSP and syntax highlighting.
|
|
752
|
-
* - `unsafe-inline`
|
|
752
|
+
* - When `'unsafe-inline'` is included as a resource in a directive, Astro will not emit hashes on that directive. Per the CSP spec, browsers ignore `'unsafe-inline'` when a hash or nonce is present in the same directive, so Astro suppresses hashes to preserve `'unsafe-inline'` behavior. Note that this reduces the security of that directive to the level of `'unsafe-inline'`.
|
|
753
753
|
*
|
|
754
754
|
* :::note
|
|
755
755
|
* Due to the nature of the Vite dev server, this feature isn't supported while working in `dev` mode. Instead, you can test this in your Astro project using `build` and `preview`.
|
|
@@ -137,7 +137,7 @@ async function astroPluginRoutes({
|
|
|
137
137
|
return true;
|
|
138
138
|
});
|
|
139
139
|
const code = `
|
|
140
|
-
import { deserializeRouteInfo } from 'astro/app';
|
|
140
|
+
import { deserializeRouteInfo } from 'astro/app/manifest';
|
|
141
141
|
const serializedData = ${JSON.stringify(filteredRoutes)};
|
|
142
142
|
const routes = serializedData.map(deserializeRouteInfo);
|
|
143
143
|
export { routes };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.5",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"README.md"
|
|
104
104
|
],
|
|
105
105
|
"dependencies": {
|
|
106
|
-
"@astrojs/compiler-rs": "^0.
|
|
106
|
+
"@astrojs/compiler-rs": "^0.4.0",
|
|
107
107
|
"@capsizecss/unpack": "^4.0.0",
|
|
108
108
|
"@clack/prompts": "^1.1.0",
|
|
109
109
|
"@oslojs/encoding": "^1.1.0",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"common-ancestor-path": "^2.0.0",
|
|
116
116
|
"cookie": "^2.0.1",
|
|
117
117
|
"devalue": "^5.8.1",
|
|
118
|
-
"diff": "^
|
|
118
|
+
"diff": "^9.0.0",
|
|
119
119
|
"dset": "^3.1.4",
|
|
120
120
|
"es-module-lexer": "^2.0.0",
|
|
121
121
|
"esbuild": "^0.28.0",
|
|
@@ -153,15 +153,15 @@
|
|
|
153
153
|
"xxhash-wasm": "^1.1.0",
|
|
154
154
|
"yargs-parser": "^22.0.0",
|
|
155
155
|
"zod": "^4.3.6",
|
|
156
|
-
"@astrojs/internal-helpers": "0.10.
|
|
157
|
-
"@astrojs/markdown-satteri": "0.3.
|
|
156
|
+
"@astrojs/internal-helpers": "0.10.4",
|
|
157
|
+
"@astrojs/markdown-satteri": "0.3.8",
|
|
158
158
|
"@astrojs/telemetry": "3.3.3"
|
|
159
159
|
},
|
|
160
160
|
"optionalDependencies": {
|
|
161
161
|
"sharp": "^0.34.0 || ^0.35.0"
|
|
162
162
|
},
|
|
163
163
|
"peerDependencies": {
|
|
164
|
-
"@astrojs/markdown-remark": "7.2.
|
|
164
|
+
"@astrojs/markdown-remark": "7.2.4"
|
|
165
165
|
},
|
|
166
166
|
"peerDependenciesMeta": {
|
|
167
167
|
"@astrojs/markdown-remark": {
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
"undici": "^7.22.0",
|
|
195
195
|
"vitest": "^4.1.0",
|
|
196
196
|
"@astrojs/check": "0.9.10",
|
|
197
|
-
"@astrojs/markdown-remark": "7.2.
|
|
197
|
+
"@astrojs/markdown-remark": "7.2.4",
|
|
198
198
|
"astro-scripts": "0.0.14"
|
|
199
199
|
},
|
|
200
200
|
"engines": {
|
|
@@ -13,7 +13,7 @@ export {
|
|
|
13
13
|
defineLiveCollection,
|
|
14
14
|
renderEntry as render,
|
|
15
15
|
} from 'astro/content/runtime';
|
|
16
|
-
// TODO: remove in Astro
|
|
16
|
+
// TODO: remove in Astro 8
|
|
17
17
|
export { z } from 'astro/zod';
|
|
18
18
|
|
|
19
19
|
/* @@LIVE_CONTENT_CONFIG@@ */
|
|
@@ -38,8 +38,8 @@ export const getLiveEntry = createGetLiveEntry({
|
|
|
38
38
|
liveCollections,
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
// TODO: remove in Astro
|
|
41
|
+
// TODO: remove in Astro 8
|
|
42
42
|
export const getEntryBySlug = createDeprecatedFunction('getEntryBySlug');
|
|
43
43
|
|
|
44
|
-
// TODO: remove in Astro
|
|
44
|
+
// TODO: remove in Astro 8
|
|
45
45
|
export const getDataEntryById = createDeprecatedFunction('getDataEntryById');
|
package/types/content.d.ts
CHANGED
|
@@ -10,11 +10,11 @@ declare module 'astro:content' {
|
|
|
10
10
|
} from 'astro/content/config';
|
|
11
11
|
export { defineLiveCollection, defineCollection } from 'astro/content/config';
|
|
12
12
|
|
|
13
|
-
// TODO: remove in Astro
|
|
13
|
+
// TODO: remove in Astro 8
|
|
14
14
|
/**
|
|
15
15
|
* @deprecated
|
|
16
16
|
* `import { z } from 'astro:content'` is deprecated and will be removed
|
|
17
|
-
* in Astro
|
|
17
|
+
* in Astro 8. Use `import { z } from 'astro/zod'` instead.
|
|
18
18
|
*/
|
|
19
19
|
export const z = zod.z;
|
|
20
20
|
|