astro 6.3.6 → 6.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/core/app/node.js +3 -0
- package/dist/core/base-pipeline.js +2 -1
- package/dist/core/build/internal.d.ts +7 -0
- package/dist/core/build/plugins/plugin-chunk-imports.d.ts +6 -0
- package/dist/core/build/plugins/plugin-chunk-imports.js +16 -17
- package/dist/core/build/plugins/plugin-css.js +33 -0
- package/dist/core/build/vite-build-config.js +7 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/errors-data.d.ts +8 -3
- package/dist/core/errors/errors-data.js +8 -2
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/render/route-cache.d.ts +1 -1
- package/dist/core/render/route-cache.js +1 -1
- package/dist/core/routing/create-manifest.js +10 -0
- package/dist/core/util/pathname.js +5 -3
- package/dist/manifest/virtual-module.js +2 -1
- package/dist/runtime/server/jsx.js +1 -1
- package/dist/runtime/server/render/component.js +5 -3
- package/dist/types/public/config.d.ts +1 -1
- package/dist/virtual-modules/i18n.js +1 -1
- package/package.json +1 -1
|
@@ -191,7 +191,7 @@ ${contentConfig.error.message}`
|
|
|
191
191
|
logger.info("Content config changed");
|
|
192
192
|
shouldClear = true;
|
|
193
193
|
}
|
|
194
|
-
if (previousAstroVersion && previousAstroVersion !== "6.3.
|
|
194
|
+
if (previousAstroVersion && previousAstroVersion !== "6.3.8") {
|
|
195
195
|
logger.info("Astro version changed");
|
|
196
196
|
shouldClear = true;
|
|
197
197
|
}
|
|
@@ -199,8 +199,8 @@ ${contentConfig.error.message}`
|
|
|
199
199
|
logger.info("Clearing content store");
|
|
200
200
|
this.#store.clearAll();
|
|
201
201
|
}
|
|
202
|
-
if ("6.3.
|
|
203
|
-
this.#store.metaStore().set("astro-version", "6.3.
|
|
202
|
+
if ("6.3.8") {
|
|
203
|
+
this.#store.metaStore().set("astro-version", "6.3.8");
|
|
204
204
|
}
|
|
205
205
|
if (currentConfigDigest) {
|
|
206
206
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
package/dist/core/app/node.js
CHANGED
|
@@ -219,6 +219,9 @@ function makeRequestBody(req, bodySizeLimit) {
|
|
|
219
219
|
if (typeof req.body === "string" && req.body.length > 0) {
|
|
220
220
|
return { body: Buffer.from(req.body) };
|
|
221
221
|
}
|
|
222
|
+
if (req.body instanceof ArrayBuffer || ArrayBuffer.isView(req.body)) {
|
|
223
|
+
return { body: req.body };
|
|
224
|
+
}
|
|
222
225
|
if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) {
|
|
223
226
|
return { body: Buffer.from(JSON.stringify(req.body)) };
|
|
224
227
|
}
|
|
@@ -182,7 +182,8 @@ class Pipeline {
|
|
|
182
182
|
if (this.resolvedActions) {
|
|
183
183
|
return this.resolvedActions;
|
|
184
184
|
} else if (this.actions) {
|
|
185
|
-
|
|
185
|
+
this.resolvedActions = await this.actions();
|
|
186
|
+
return this.resolvedActions;
|
|
186
187
|
}
|
|
187
188
|
return NOOP_ACTIONS_MOD;
|
|
188
189
|
}
|
|
@@ -92,6 +92,13 @@ export interface BuildInternals {
|
|
|
92
92
|
moduleIds: string[];
|
|
93
93
|
prerender: boolean;
|
|
94
94
|
}>;
|
|
95
|
+
/**
|
|
96
|
+
* Component exports that were rendered during the SSR build.
|
|
97
|
+
* Used by the client build's cssScopeTo recovery to distinguish between
|
|
98
|
+
* CSS that was tree-shaken because the component wasn't rendered in SSR
|
|
99
|
+
* vs CSS that was included in SSR.
|
|
100
|
+
*/
|
|
101
|
+
ssrRenderedExports?: Map<string, Set<string>>;
|
|
95
102
|
}
|
|
96
103
|
/**
|
|
97
104
|
* Creates internal maps used to coordinate the CSS and HTML plugins.
|
|
@@ -6,5 +6,11 @@ import type { StaticBuildOptions } from '../types.js';
|
|
|
6
6
|
* bypass the HTML rendering pipeline and miss skew protection query params.
|
|
7
7
|
*
|
|
8
8
|
* Uses es-module-lexer to reliably parse both static and dynamic imports.
|
|
9
|
+
*
|
|
10
|
+
* This runs in `generateBundle` (not `renderChunk`) so that Vite's CSS plugin
|
|
11
|
+
* can first remove pure-CSS wrapper chunks and replace their imports with
|
|
12
|
+
* `/* empty css * /` comments. If we rewrote imports earlier (in `renderChunk`),
|
|
13
|
+
* the appended query params would break Vite's regex-based CSS chunk cleanup,
|
|
14
|
+
* leaving dangling imports to deleted chunks that 404 at runtime.
|
|
9
15
|
*/
|
|
10
16
|
export declare function pluginChunkImports(options: StaticBuildOptions): VitePlugin | undefined;
|
|
@@ -12,25 +12,24 @@ function pluginChunkImports(options) {
|
|
|
12
12
|
applyToEnvironment(environment) {
|
|
13
13
|
return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client;
|
|
14
14
|
},
|
|
15
|
-
async
|
|
16
|
-
if (!code.includes("./")) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
15
|
+
async generateBundle(_options, bundle) {
|
|
19
16
|
await init;
|
|
20
|
-
const [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
for (const [, chunk] of Object.entries(bundle)) {
|
|
18
|
+
if (chunk.type !== "chunk") continue;
|
|
19
|
+
if (!chunk.code.includes("./")) continue;
|
|
20
|
+
const [imports] = parse(chunk.code);
|
|
21
|
+
const relativeImports = imports.filter(
|
|
22
|
+
(imp) => imp.n && /^\.\.?\//.test(imp.n) && /\.(?:js|mjs)$/.test(imp.n)
|
|
23
|
+
);
|
|
24
|
+
if (relativeImports.length === 0) continue;
|
|
25
|
+
let rewritten = chunk.code;
|
|
26
|
+
for (let i = relativeImports.length - 1; i >= 0; i--) {
|
|
27
|
+
const imp = relativeImports[i];
|
|
28
|
+
const insertAt = imp.d > -1 ? imp.e - 1 : imp.e;
|
|
29
|
+
rewritten = rewritten.slice(0, insertAt) + "?" + queryString + rewritten.slice(insertAt);
|
|
30
|
+
}
|
|
31
|
+
chunk.code = rewritten;
|
|
32
32
|
}
|
|
33
|
-
return { code: rewritten, map: null };
|
|
34
33
|
}
|
|
35
34
|
};
|
|
36
35
|
}
|
|
@@ -46,10 +46,25 @@ function rollupPluginAstroBuildCSS(options) {
|
|
|
46
46
|
internals.cssModuleToChunkIdMap.set(moduleId, chunk.fileName);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
for (const [moduleId, moduleInfo] of Object.entries(chunk.modules || {})) {
|
|
50
|
+
if (moduleInfo.renderedExports.length > 0) {
|
|
51
|
+
const existing = internals.ssrRenderedExports?.get(moduleId);
|
|
52
|
+
if (existing) {
|
|
53
|
+
for (const exp of moduleInfo.renderedExports) {
|
|
54
|
+
existing.add(exp);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
internals.ssrRenderedExports ??= /* @__PURE__ */ new Map();
|
|
58
|
+
internals.ssrRenderedExports.set(moduleId, new Set(moduleInfo.renderedExports));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
49
62
|
}
|
|
50
63
|
}
|
|
51
64
|
const renderedComponentExports = /* @__PURE__ */ new Map();
|
|
52
65
|
const componentToPages = /* @__PURE__ */ new Map();
|
|
66
|
+
const deletedCssAssets = /* @__PURE__ */ new Map();
|
|
67
|
+
const cssScopeToAddedCss = /* @__PURE__ */ new Set();
|
|
53
68
|
if (this.environment?.name === ASTRO_VITE_ENVIRONMENT_NAMES.client) {
|
|
54
69
|
for (const [, item] of Object.entries(bundle)) {
|
|
55
70
|
if (item.type !== "chunk") continue;
|
|
@@ -76,6 +91,9 @@ function rollupPluginAstroBuildCSS(options) {
|
|
|
76
91
|
);
|
|
77
92
|
if (allCssInSSR && shouldDeleteCSSChunk(allModules, internals)) {
|
|
78
93
|
for (const cssId of meta.importedCss) {
|
|
94
|
+
if (bundle[cssId]) {
|
|
95
|
+
deletedCssAssets.set(cssId, bundle[cssId]);
|
|
96
|
+
}
|
|
79
97
|
delete bundle[cssId];
|
|
80
98
|
}
|
|
81
99
|
}
|
|
@@ -157,6 +175,14 @@ function rollupPluginAstroBuildCSS(options) {
|
|
|
157
175
|
}
|
|
158
176
|
}
|
|
159
177
|
}
|
|
178
|
+
const ssrExports = internals.ssrRenderedExports?.get(scopedToModule);
|
|
179
|
+
if (!ssrExports || !ssrExports.has(scopedToExport)) {
|
|
180
|
+
for (const cssId of meta.importedCss) {
|
|
181
|
+
if (deletedCssAssets.has(cssId)) {
|
|
182
|
+
cssScopeToAddedCss.add(cssId);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
160
186
|
}
|
|
161
187
|
}
|
|
162
188
|
}
|
|
@@ -191,6 +217,13 @@ function rollupPluginAstroBuildCSS(options) {
|
|
|
191
217
|
}
|
|
192
218
|
}
|
|
193
219
|
}
|
|
220
|
+
if (cssScopeToAddedCss.size > 0) {
|
|
221
|
+
for (const cssId of cssScopeToAddedCss) {
|
|
222
|
+
if (deletedCssAssets.has(cssId) && !bundle[cssId]) {
|
|
223
|
+
bundle[cssId] = deletedCssAssets.get(cssId);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
194
227
|
}
|
|
195
228
|
};
|
|
196
229
|
const singleCssPlugin = {
|
|
@@ -118,11 +118,16 @@ function createViteBuildConfig(opts) {
|
|
|
118
118
|
target: "esnext",
|
|
119
119
|
outDir: fileURLToPath(getClientOutputDirectory(settings)),
|
|
120
120
|
copyPublicDir: true,
|
|
121
|
-
sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? false,
|
|
122
|
-
minify: true,
|
|
121
|
+
sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? viteConfig.build?.sourcemap ?? false,
|
|
122
|
+
minify: viteConfig.environments?.client?.build?.minify ?? viteConfig.build?.minify ?? true,
|
|
123
123
|
rollupOptions: {
|
|
124
124
|
preserveEntrySignatures: "exports-only",
|
|
125
125
|
output: {
|
|
126
|
+
// Inherit top-level rollup output options (e.g. compact) as a
|
|
127
|
+
// base, then layer Astro defaults on top so that Astro's
|
|
128
|
+
// naming functions are preserved unless explicitly overridden
|
|
129
|
+
// via the environment-specific config.
|
|
130
|
+
...viteConfig.build?.rollupOptions?.output,
|
|
126
131
|
entryFileNames(chunkInfo) {
|
|
127
132
|
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
128
133
|
},
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -37,7 +37,7 @@ async function dev(inlineConfig) {
|
|
|
37
37
|
await telemetry.record([]);
|
|
38
38
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
39
39
|
const logger = restart.container.logger;
|
|
40
|
-
const currentVersion = "6.3.
|
|
40
|
+
const currentVersion = "6.3.8";
|
|
41
41
|
const isPrerelease = currentVersion.includes("-");
|
|
42
42
|
if (!isPrerelease) {
|
|
43
43
|
try {
|
|
@@ -946,17 +946,22 @@ export declare const UnsupportedExternalRedirect: {
|
|
|
946
946
|
};
|
|
947
947
|
/**
|
|
948
948
|
* @docs
|
|
949
|
+
* @message
|
|
950
|
+
* **Example error message:**<br/>
|
|
951
|
+
* InvalidRedirectDestination: The redirect from "/posts" to "/blog" is invalid. The destination "/blog" does not match any existing route in your project.
|
|
949
952
|
* @see
|
|
950
953
|
* - [Configured redirects](https://docs.astro.build/en/guides/routing/#configured-redirects)
|
|
951
954
|
* @description
|
|
952
|
-
* A dynamic redirect destination must match an existing route pattern
|
|
955
|
+
* A dynamic redirect destination must match an existing route pattern and include
|
|
956
|
+
* all dynamic parameters from the source route.
|
|
953
957
|
* This error occurs when a redirect with dynamic parameters points to a destination
|
|
954
|
-
* that doesn't correspond to any page in your project
|
|
958
|
+
* that doesn't correspond to any page in your project, or when the destination route
|
|
959
|
+
* has fewer dynamic parameters than the source route.
|
|
955
960
|
*/
|
|
956
961
|
export declare const InvalidRedirectDestination: {
|
|
957
962
|
name: string;
|
|
958
963
|
title: string;
|
|
959
|
-
message
|
|
964
|
+
message(from: string, to: string, missingParams?: string[]): string;
|
|
960
965
|
hint: string;
|
|
961
966
|
};
|
|
962
967
|
/**
|
|
@@ -335,8 +335,14 @@ const UnsupportedExternalRedirect = {
|
|
|
335
335
|
const InvalidRedirectDestination = {
|
|
336
336
|
name: "InvalidRedirectDestination",
|
|
337
337
|
title: "Invalid redirect destination.",
|
|
338
|
-
message
|
|
339
|
-
|
|
338
|
+
message(from, to, missingParams) {
|
|
339
|
+
if (missingParams && missingParams.length > 0) {
|
|
340
|
+
const formatted = missingParams.map((p) => `[${p}]`).join(", ");
|
|
341
|
+
return `The redirect from "${from}" to "${to}" is invalid. The destination route is missing dynamic parameter(s) ${formatted} required by the source route "${from}".`;
|
|
342
|
+
}
|
|
343
|
+
return `The redirect from "${from}" to "${to}" is invalid. The destination "${to}" does not match any existing route in your project.`;
|
|
344
|
+
},
|
|
345
|
+
hint: 'The destination of a dynamic redirect must include all dynamic parameters from the source route. For example, a redirect from "/old/[slug]" must go to a route that also has a [slug] parameter, like "/new/[slug]".'
|
|
340
346
|
};
|
|
341
347
|
const InvalidDynamicRoute = {
|
|
342
348
|
name: "InvalidDynamicRoute",
|
|
@@ -13,7 +13,7 @@ interface CallGetStaticPathsOptions {
|
|
|
13
13
|
}
|
|
14
14
|
export declare function callGetStaticPaths({ mod, route, routeCache, ssr, base, trailingSlash, }: CallGetStaticPathsOptions): Promise<GetStaticPathsResultKeyed>;
|
|
15
15
|
interface RouteCacheEntry {
|
|
16
|
-
mod
|
|
16
|
+
mod: ComponentInstance;
|
|
17
17
|
staticPaths: GetStaticPathsResultKeyed;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
@@ -19,7 +19,7 @@ async function callGetStaticPaths({
|
|
|
19
19
|
validateDynamicRouteModule(mod, { ssr, route });
|
|
20
20
|
if (ssr && !route.prerender) {
|
|
21
21
|
const entry = Object.assign([], { keyed: /* @__PURE__ */ new Map() });
|
|
22
|
-
routeCache.set(route, { ...cached, staticPaths: entry });
|
|
22
|
+
routeCache.set(route, { ...cached, mod, staticPaths: entry });
|
|
23
23
|
return entry;
|
|
24
24
|
}
|
|
25
25
|
let staticPaths = [];
|
|
@@ -388,6 +388,16 @@ function createRedirectRoutes({ settings }, routeMap) {
|
|
|
388
388
|
message: InvalidRedirectDestination.message(from, destination)
|
|
389
389
|
});
|
|
390
390
|
}
|
|
391
|
+
if (params.length > 0 && redirectRoute && !URL.canParse(destination) && getPrerenderDefault(config)) {
|
|
392
|
+
const destParams = redirectRoute.params ?? [];
|
|
393
|
+
const missingParams = params.filter((p) => !destParams.includes(p));
|
|
394
|
+
if (missingParams.length > 0) {
|
|
395
|
+
throw new AstroError({
|
|
396
|
+
...InvalidRedirectDestination,
|
|
397
|
+
message: InvalidRedirectDestination.message(from, destination, missingParams)
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
391
401
|
routes.push({
|
|
392
402
|
type: "redirect",
|
|
393
403
|
// For backwards compatibility, a redirect is never considered an index route.
|
|
@@ -4,16 +4,18 @@ class MultiLevelEncodingError extends Error {
|
|
|
4
4
|
this.name = "MultiLevelEncodingError";
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
|
+
const ENCODING_REGEX = /%25[0-9a-fA-F]{2}/;
|
|
7
8
|
function validateAndDecodePathname(pathname) {
|
|
9
|
+
if (ENCODING_REGEX.test(pathname)) {
|
|
10
|
+
throw new MultiLevelEncodingError();
|
|
11
|
+
}
|
|
8
12
|
let decoded;
|
|
9
13
|
try {
|
|
10
14
|
decoded = decodeURI(pathname);
|
|
11
15
|
} catch (_e) {
|
|
12
16
|
throw new Error("Invalid URL encoding");
|
|
13
17
|
}
|
|
14
|
-
|
|
15
|
-
const decodedStillHasEncoding = /%[0-9a-fA-F]{2}/.test(decoded);
|
|
16
|
-
if (hasDecoding && decodedStillHasEncoding) {
|
|
18
|
+
if (ENCODING_REGEX.test(decoded)) {
|
|
17
19
|
throw new MultiLevelEncodingError();
|
|
18
20
|
}
|
|
19
21
|
return decoded;
|
|
@@ -17,7 +17,8 @@ function virtualModulePlugin({ settings }) {
|
|
|
17
17
|
defaultLocale: ${JSON.stringify(config.i18n.defaultLocale)},
|
|
18
18
|
locales: ${JSON.stringify(config.i18n.locales)},
|
|
19
19
|
routing: ${JSON.stringify(routing)},
|
|
20
|
-
fallback: ${JSON.stringify(config.i18n.fallback)}
|
|
20
|
+
fallback: ${JSON.stringify(config.i18n.fallback)},
|
|
21
|
+
domains: ${JSON.stringify(config.i18n.domains)}
|
|
21
22
|
};`;
|
|
22
23
|
}
|
|
23
24
|
let imageCode = "const image = undefined;";
|
|
@@ -75,7 +75,7 @@ Did you forget to import the component or is it possible there is a typo?`);
|
|
|
75
75
|
}
|
|
76
76
|
case (!vnode.type && vnode.type !== 0):
|
|
77
77
|
return "";
|
|
78
|
-
case (typeof vnode.type === "string" && vnode.type !== ClientOnlyPlaceholder):
|
|
78
|
+
case (typeof vnode.type === "string" && vnode.type !== ClientOnlyPlaceholder && !vnode.type.includes("-")):
|
|
79
79
|
return markHTMLString(await renderElement(result, vnode.type, vnode.props ?? {}));
|
|
80
80
|
}
|
|
81
81
|
if (vnode.type) {
|
|
@@ -18,7 +18,8 @@ import { componentIsHTMLElement, renderHTMLElement } from "./dom.js";
|
|
|
18
18
|
import { maybeRenderHead } from "./head.js";
|
|
19
19
|
import { createRenderInstruction } from "./instruction.js";
|
|
20
20
|
import { containsServerDirective, ServerIslandComponent } from "./server-islands.js";
|
|
21
|
-
import {
|
|
21
|
+
import { renderChild } from "./any.js";
|
|
22
|
+
import { renderSlots, renderSlotToString } from "./slot.js";
|
|
22
23
|
import { formatList, internalSpreadAttributes, renderElement, voidElementNames } from "./util.js";
|
|
23
24
|
const needsHeadRenderingSymbol = /* @__PURE__ */ Symbol.for("astro.needsHeadRendering");
|
|
24
25
|
const rendererAliases = /* @__PURE__ */ new Map([["solid", "solid-js"]]);
|
|
@@ -333,10 +334,11 @@ function sanitizeElementName(tag) {
|
|
|
333
334
|
}
|
|
334
335
|
function renderFragmentComponent(result, slots = {}) {
|
|
335
336
|
const slot = slots?.default;
|
|
337
|
+
const preRendered = slot?.(result);
|
|
336
338
|
return {
|
|
337
339
|
render(destination) {
|
|
338
|
-
if (
|
|
339
|
-
return
|
|
340
|
+
if (preRendered == null) return;
|
|
341
|
+
return renderChild(destination, preRendered);
|
|
340
342
|
}
|
|
341
343
|
};
|
|
342
344
|
}
|
|
@@ -426,7 +426,7 @@ export interface AstroUserConfig<TLocales extends Locales = never, TDriver exten
|
|
|
426
426
|
*
|
|
427
427
|
* By default, Astro removes whitespace from your HTML, including line breaks, in a lossless manner from `.astro` components. Some whitespace may be preserved as needed to maintain the visual rendering of your HTML.
|
|
428
428
|
*
|
|
429
|
-
*
|
|
429
|
+
* Since 6.2.0, this option can also be set to `"jsx"`, Astro will apply the JSX whitespace stripping rules used by frameworks like React. Leading and trailing whitespace is only preserved when explicitly included in the source code through constructs such as `{" "}`, and is otherwise removed entirely.
|
|
430
430
|
*
|
|
431
431
|
* Setting this option to false disables HTML compression and preserves all whitespace.
|
|
432
432
|
*
|