astro 6.2.0 → 6.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/internal.js +16 -1
- package/dist/assets/services/sharp.js +9 -1
- package/dist/cli/add/index.js +7 -4
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/content/loaders/types.d.ts +1 -1
- package/dist/core/build/plugins/plugin-css.js +7 -1
- package/dist/core/build/plugins/plugin-manifest.js +11 -1
- package/dist/core/build/static-build.js +16 -2
- package/dist/core/compile/style.js +18 -1
- package/dist/core/config/index.d.ts +1 -1
- package/dist/core/config/index.js +4 -1
- package/dist/core/config/schemas/base.d.ts +4 -4
- package/dist/core/config/schemas/base.js +7 -7
- package/dist/core/config/schemas/relative.d.ts +4 -7
- package/dist/core/config/schemas/relative.js +2 -3
- package/dist/core/config/settings.js +2 -4
- package/dist/core/config/tsconfig.d.ts +24 -9
- package/dist/core/config/tsconfig.js +54 -45
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/errors/zod-error-map.js +27 -0
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/render/params-and-props.js +1 -1
- package/dist/core/render/slots.js +9 -2
- package/dist/core/routing/pattern.js +1 -1
- package/dist/core/routing/rewrite.js +1 -4
- package/dist/core/session/runtime.js +7 -2
- package/dist/i18n/middleware.js +1 -1
- package/dist/prefetch/index.js +12 -7
- package/dist/runtime/server/render/common.js +10 -4
- package/dist/runtime/server/scripts.js +6 -0
- package/dist/types/public/content.d.ts +4 -4
- package/dist/vite-plugin-app/app.js +0 -3
- package/dist/vite-plugin-astro/compile.js +2 -2
- package/dist/vite-plugin-astro/utils.d.ts +1 -0
- package/dist/vite-plugin-astro/utils.js +9 -1
- package/dist/vite-plugin-head/index.js +36 -19
- package/dist/vite-plugin-utils/index.d.ts +1 -0
- package/dist/vite-plugin-utils/index.js +3 -0
- package/package.json +7 -6
package/dist/assets/internal.js
CHANGED
|
@@ -122,8 +122,23 @@ async function getImage(options, imageConfig) {
|
|
|
122
122
|
if (resolvedOptions.fit && cssFitValues.includes(resolvedOptions.fit)) {
|
|
123
123
|
resolvedOptions["data-astro-image-fit"] = resolvedOptions.fit;
|
|
124
124
|
}
|
|
125
|
+
const currentPosition = resolvedOptions.position || "center";
|
|
126
|
+
resolvedOptions["data-astro-image-pos"] = currentPosition.replace(/\s+/g, "-");
|
|
125
127
|
if (resolvedOptions.position) {
|
|
126
|
-
resolvedOptions
|
|
128
|
+
if (typeof resolvedOptions.style === "object" && resolvedOptions.style !== null) {
|
|
129
|
+
if (!("objectPosition" in resolvedOptions.style)) {
|
|
130
|
+
resolvedOptions.style = {
|
|
131
|
+
...resolvedOptions.style,
|
|
132
|
+
objectPosition: resolvedOptions.position
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
const existingStyle = typeof resolvedOptions.style === "string" ? resolvedOptions.style : "";
|
|
137
|
+
if (!existingStyle.includes("object-position")) {
|
|
138
|
+
const positionStyle = `object-position: ${resolvedOptions.position}`;
|
|
139
|
+
resolvedOptions.style = existingStyle ? existingStyle.replace(/;?\s*$/, "; ") + positionStyle : positionStyle;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
127
142
|
}
|
|
128
143
|
}
|
|
129
144
|
const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions;
|
|
@@ -88,7 +88,15 @@ const sharpService = {
|
|
|
88
88
|
limitInputPixels: config.service.config.limitInputPixels
|
|
89
89
|
});
|
|
90
90
|
result.rotate();
|
|
91
|
-
|
|
91
|
+
let format;
|
|
92
|
+
try {
|
|
93
|
+
({ format } = await result.metadata());
|
|
94
|
+
} catch {
|
|
95
|
+
console.warn(
|
|
96
|
+
`\u26A0\uFE0F Astro could not optimize image "${transform.src}". Sharp doesn't support this format. The image will be used unoptimized. Consider converting to WebP or placing in the public/ folder.`
|
|
97
|
+
);
|
|
98
|
+
return { data: inputBuffer, format: transform.format };
|
|
99
|
+
}
|
|
92
100
|
if (transform.width && transform.height) {
|
|
93
101
|
const fit = transform.fit ? fitMap[transform.fit] ?? "inside" : void 0;
|
|
94
102
|
result.resize({
|
package/dist/cli/add/index.js
CHANGED
|
@@ -898,14 +898,17 @@ async function updateTSConfig(cwd = process.cwd(), logger, integrationsInfo, fla
|
|
|
898
898
|
}
|
|
899
899
|
let inputConfig = await loadTSConfig(cwd);
|
|
900
900
|
let inputConfigText = "";
|
|
901
|
-
if (inputConfig === "invalid-config"
|
|
901
|
+
if (inputConfig.error === "invalid-config") {
|
|
902
|
+
logger.warn(`add`, `Couldn't parse tsconfig.json or jsconfig.json: ${inputConfig.message}`);
|
|
902
903
|
return "failure";
|
|
903
|
-
} else if (inputConfig === "missing-config") {
|
|
904
|
+
} else if (inputConfig.error === "missing-config") {
|
|
904
905
|
logger.debug("add", "Couldn't find tsconfig.json or jsconfig.json, generating one");
|
|
906
|
+
const tsconfigFile = path.join(cwd, "tsconfig.json");
|
|
905
907
|
inputConfig = {
|
|
906
908
|
tsconfig: defaultTSConfig,
|
|
907
|
-
tsconfigFile
|
|
908
|
-
rawConfig: defaultTSConfig
|
|
909
|
+
tsconfigFile,
|
|
910
|
+
rawConfig: defaultTSConfig,
|
|
911
|
+
sources: [tsconfigFile]
|
|
909
912
|
};
|
|
910
913
|
} else {
|
|
911
914
|
inputConfigText = JSON.stringify(inputConfig.rawConfig, null, 2);
|
|
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
|
|
|
192
192
|
logger.info("Content config changed");
|
|
193
193
|
shouldClear = true;
|
|
194
194
|
}
|
|
195
|
-
if (previousAstroVersion && previousAstroVersion !== "6.2.
|
|
195
|
+
if (previousAstroVersion && previousAstroVersion !== "6.2.2") {
|
|
196
196
|
logger.info("Astro version changed");
|
|
197
197
|
shouldClear = true;
|
|
198
198
|
}
|
|
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
|
|
|
200
200
|
logger.info("Clearing content store");
|
|
201
201
|
this.#store.clearAll();
|
|
202
202
|
}
|
|
203
|
-
if ("6.2.
|
|
204
|
-
this.#store.metaStore().set("astro-version", "6.2.
|
|
203
|
+
if ("6.2.2") {
|
|
204
|
+
this.#store.metaStore().set("astro-version", "6.2.2");
|
|
205
205
|
}
|
|
206
206
|
if (currentConfigDigest) {
|
|
207
207
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -64,7 +64,7 @@ export interface LoadCollectionContext<TCollectionFilter = unknown> {
|
|
|
64
64
|
filter?: TCollectionFilter;
|
|
65
65
|
collection: string;
|
|
66
66
|
}
|
|
67
|
-
export interface LiveLoader<TData extends Record<string, any> = Record<string,
|
|
67
|
+
export interface LiveLoader<TData extends Record<string, any> = Record<string, any>, TEntryFilter extends Record<string, any> | never = never, TCollectionFilter extends Record<string, any> | never = never, TError extends Error = Error> {
|
|
68
68
|
/** Unique name of the loader, e.g. the npm package name */
|
|
69
69
|
name: string;
|
|
70
70
|
/** Load a single entry */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isCSSRequest } from "vite";
|
|
2
2
|
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../../constants.js";
|
|
3
3
|
import { isPropagatedAssetBoundary } from "../../head-propagation/boundary.js";
|
|
4
|
+
import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../../vite-plugin-pages/const.js";
|
|
4
5
|
import {
|
|
5
6
|
getParentExtendedModuleInfos,
|
|
6
7
|
getParentModuleInfos,
|
|
@@ -18,7 +19,12 @@ function pluginCSS(options, internals) {
|
|
|
18
19
|
function isBuildCssBoundary(id, ctx) {
|
|
19
20
|
if (isPropagatedAssetBoundary(id)) return true;
|
|
20
21
|
const info = ctx.getModuleInfo(id);
|
|
21
|
-
|
|
22
|
+
if (!info || !moduleIsTopLevelPage(info)) return false;
|
|
23
|
+
const allImporters = info.importers.concat(info.dynamicImporters);
|
|
24
|
+
const hasNonVirtualPageImporter = allImporters.some(
|
|
25
|
+
(importer) => !importer.includes(VIRTUAL_PAGE_RESOLVED_MODULE_ID)
|
|
26
|
+
);
|
|
27
|
+
return !hasNonVirtualPageImporter;
|
|
22
28
|
}
|
|
23
29
|
function rollupPluginAstroBuildCSS(options) {
|
|
24
30
|
const { internals, buildOptions } = options;
|
|
@@ -47,7 +47,8 @@ async function manifestBuildPostHook(options, internals, {
|
|
|
47
47
|
logger: options.logger,
|
|
48
48
|
middlewareEntryPoint: shouldPassMiddlewareEntryPoint ? internals.middlewareEntryPoint : void 0
|
|
49
49
|
});
|
|
50
|
-
const
|
|
50
|
+
const ssrManifest = stripPrerenderedRouteStyles(manifest);
|
|
51
|
+
const code = injectManifest(ssrManifest, ssrManifestChunk.code);
|
|
51
52
|
mutate(ssrManifestChunk.fileName, code, false);
|
|
52
53
|
}
|
|
53
54
|
const prerenderManifestChunk = chunks.find(
|
|
@@ -82,6 +83,15 @@ function injectManifest(manifest, code) {
|
|
|
82
83
|
return JSON.stringify(manifest);
|
|
83
84
|
});
|
|
84
85
|
}
|
|
86
|
+
function stripPrerenderedRouteStyles(manifest) {
|
|
87
|
+
let stripped = false;
|
|
88
|
+
const routes = manifest.routes.map((route) => {
|
|
89
|
+
if (!route.routeData.prerender || route.styles.length === 0) return route;
|
|
90
|
+
stripped = true;
|
|
91
|
+
return { ...route, styles: [] };
|
|
92
|
+
});
|
|
93
|
+
return stripped ? { ...manifest, routes } : manifest;
|
|
94
|
+
}
|
|
85
95
|
async function buildManifest(opts, internals, staticFiles, encodedKey) {
|
|
86
96
|
const { settings } = opts;
|
|
87
97
|
const routes = [];
|
|
@@ -186,7 +186,14 @@ async function buildEnvironments(opts, internals) {
|
|
|
186
186
|
}
|
|
187
187
|
return [prefix, cleanChunkName(name), suffix].join("");
|
|
188
188
|
},
|
|
189
|
-
assetFileNames
|
|
189
|
+
assetFileNames(assetInfo) {
|
|
190
|
+
const name = assetInfo.names?.[0] ?? "";
|
|
191
|
+
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
192
|
+
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
193
|
+
return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
|
|
194
|
+
}
|
|
195
|
+
return `${settings.config.build.assets}/[name].[hash][extname]`;
|
|
196
|
+
},
|
|
190
197
|
...viteConfig.build?.rollupOptions?.output,
|
|
191
198
|
entryFileNames(chunkInfo) {
|
|
192
199
|
if (chunkInfo.facadeModuleId?.startsWith(VIRTUAL_PAGE_RESOLVED_MODULE_ID)) {
|
|
@@ -289,7 +296,14 @@ async function buildEnvironments(opts, internals) {
|
|
|
289
296
|
chunkFileNames(chunkInfo) {
|
|
290
297
|
return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
|
|
291
298
|
},
|
|
292
|
-
assetFileNames
|
|
299
|
+
assetFileNames(assetInfo) {
|
|
300
|
+
const name = assetInfo.names?.[0] ?? "";
|
|
301
|
+
if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
|
|
302
|
+
const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
|
|
303
|
+
return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
|
|
304
|
+
}
|
|
305
|
+
return `${settings.config.build.assets}/[name].[hash][extname]`;
|
|
306
|
+
},
|
|
293
307
|
...viteConfig.environments?.client?.build?.rollupOptions?.output
|
|
294
308
|
}
|
|
295
309
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { preprocessCSS } from "vite";
|
|
3
4
|
import { AstroErrorData, CSSError, positionAt } from "../errors/index.js";
|
|
4
5
|
import { normalizePath } from "../viteUtils.js";
|
|
@@ -31,6 +32,21 @@ function rewriteCssUrls(css, base) {
|
|
|
31
32
|
return match;
|
|
32
33
|
});
|
|
33
34
|
}
|
|
35
|
+
function withNestingExcluded(viteConfig) {
|
|
36
|
+
let Features;
|
|
37
|
+
try {
|
|
38
|
+
const requireFromRoot = createRequire(viteConfig.root + "/");
|
|
39
|
+
Features = requireFromRoot("lightningcss").Features;
|
|
40
|
+
} catch {
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
const lcss = viteConfig.css?.lightningcss ?? {};
|
|
44
|
+
const prevExclude = lcss.exclude ?? 0;
|
|
45
|
+
return {
|
|
46
|
+
...viteConfig,
|
|
47
|
+
css: { ...viteConfig.css, lightningcss: { ...lcss, exclude: prevExclude | Features.Nesting } }
|
|
48
|
+
};
|
|
49
|
+
}
|
|
34
50
|
function createStylePreprocessor({
|
|
35
51
|
filename,
|
|
36
52
|
viteConfig,
|
|
@@ -44,7 +60,8 @@ function createStylePreprocessor({
|
|
|
44
60
|
const lang = `.${attrs?.lang || "css"}`.toLowerCase();
|
|
45
61
|
const id = `${filename}?astro&type=style&index=${index}&lang${lang}`;
|
|
46
62
|
try {
|
|
47
|
-
const
|
|
63
|
+
const effectiveViteConfig = viteConfig.css?.transformer === "lightningcss" ? withNestingExcluded(viteConfig) ?? viteConfig : viteConfig;
|
|
64
|
+
const result = await preprocessCSS(content, id, effectiveViteConfig);
|
|
48
65
|
const rewrittenCode = rewriteCssUrls(result.code, astroConfig.base);
|
|
49
66
|
cssPartialCompileResults[index] = {
|
|
50
67
|
// Use `in` operator to handle both Go compiler (boolean `true`) and
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { resolveConfig, resolveConfigPath, resolveRoot, } from './config.js';
|
|
2
2
|
export { mergeConfig } from './merge.js';
|
|
3
3
|
export { createSettings } from './settings.js';
|
|
4
|
-
export { loadTSConfig, updateTSConfigForFramework } from './tsconfig.js';
|
|
4
|
+
export { loadTSConfig, updateTSConfigForFramework, type TSConfigLoadedResult, type TSConfigResult, } from './tsconfig.js';
|
|
@@ -5,7 +5,10 @@ import {
|
|
|
5
5
|
} from "./config.js";
|
|
6
6
|
import { mergeConfig } from "./merge.js";
|
|
7
7
|
import { createSettings } from "./settings.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
loadTSConfig,
|
|
10
|
+
updateTSConfigForFramework
|
|
11
|
+
} from "./tsconfig.js";
|
|
9
12
|
export {
|
|
10
13
|
createSettings,
|
|
11
14
|
loadTSConfig,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype, Smartypants as _Smartypants, ShikiConfig } from '@astrojs/markdown-remark';
|
|
1
2
|
import type { OutgoingHttpHeaders } from 'node:http';
|
|
2
|
-
import type { RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype, ShikiConfig, Smartypants as _Smartypants } from '@astrojs/markdown-remark';
|
|
3
3
|
import * as z from 'zod/v4';
|
|
4
4
|
import type { ViteUserConfig } from '../../../types/public/config.js';
|
|
5
5
|
/** @lintignore */
|
|
@@ -103,10 +103,10 @@ export declare const AstroConfigSchema: z.ZodObject<{
|
|
|
103
103
|
name: z.ZodString;
|
|
104
104
|
hooks: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
|
|
105
105
|
}, z.core.$strip>>;
|
|
106
|
-
integrations: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.
|
|
106
|
+
integrations: z.ZodDefault<z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodArray<z.ZodObject<{
|
|
107
107
|
name: z.ZodString;
|
|
108
108
|
hooks: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
|
|
109
|
-
}, z.core.$strip
|
|
109
|
+
}, z.core.$strip>>>>>;
|
|
110
110
|
build: z.ZodPrefault<z.ZodObject<{
|
|
111
111
|
format: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"file">, z.ZodLiteral<"directory">, z.ZodLiteral<"preserve">]>>>;
|
|
112
112
|
client: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodString>>, z.ZodTransform<URL, string>>;
|
|
@@ -124,7 +124,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
|
|
|
124
124
|
}>>>;
|
|
125
125
|
concurrency: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
126
126
|
}, z.core.$strip>>;
|
|
127
|
-
server: z.ZodPipe<z.ZodTransform<any, unknown>, z.
|
|
127
|
+
server: z.ZodPrefault<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodObject<{
|
|
128
128
|
open: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
|
|
129
129
|
host: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
|
|
130
130
|
port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -2,11 +2,11 @@ import { markdownConfigDefaults, syntaxHighlightDefaults } from "@astrojs/markdo
|
|
|
2
2
|
import { bundledThemes } from "shiki";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
4
|
import { FontFamilySchema } from "../../../assets/fonts/config.js";
|
|
5
|
+
import { SvgOptimizerSchema } from "../../../assets/svg/config.js";
|
|
5
6
|
import { EnvSchema } from "../../../env/schema.js";
|
|
6
|
-
import { allowedDirectivesSchema, cspAlgorithmSchema, cspHashSchema } from "../../csp/config.js";
|
|
7
7
|
import { CacheSchema, RouteRulesSchema } from "../../cache/config.js";
|
|
8
|
+
import { allowedDirectivesSchema, cspAlgorithmSchema, cspHashSchema } from "../../csp/config.js";
|
|
8
9
|
import { SessionSchema } from "../../session/config.js";
|
|
9
|
-
import { SvgOptimizerSchema } from "../../../assets/svg/config.js";
|
|
10
10
|
const ASTRO_CONFIG_DEFAULTS = {
|
|
11
11
|
root: ".",
|
|
12
12
|
srcDir: "./src",
|
|
@@ -105,13 +105,13 @@ const AstroConfigSchema = z.object({
|
|
|
105
105
|
message: 'The `output: "hybrid"` option has been removed. Use `output: "static"` (the default) instead, which now behaves the same way.'
|
|
106
106
|
}),
|
|
107
107
|
scopedStyleStrategy: z.union([z.literal("where"), z.literal("class"), z.literal("attribute")]).optional().default("attribute"),
|
|
108
|
-
adapter: z.object({ name: z.string(), hooks: z.object({}).
|
|
108
|
+
adapter: z.object({ name: z.string(), hooks: z.object({}).loose().default({}) }).optional(),
|
|
109
109
|
integrations: z.preprocess(
|
|
110
110
|
// preprocess
|
|
111
111
|
(val) => Array.isArray(val) ? val.flat(Number.POSITIVE_INFINITY).filter(Boolean) : val,
|
|
112
112
|
// validate
|
|
113
|
-
z.array(z.object({ name: z.string(), hooks: z.object({}).
|
|
114
|
-
),
|
|
113
|
+
z.array(z.object({ name: z.string(), hooks: z.object({}).loose().default({}) }))
|
|
114
|
+
).optional().default(ASTRO_CONFIG_DEFAULTS.integrations),
|
|
115
115
|
build: z.object({
|
|
116
116
|
format: z.union([z.literal("file"), z.literal("directory"), z.literal("preserve")]).optional().default(ASTRO_CONFIG_DEFAULTS.build.format),
|
|
117
117
|
client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val)),
|
|
@@ -135,8 +135,8 @@ const AstroConfigSchema = z.object({
|
|
|
135
135
|
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
|
|
136
136
|
headers: z.custom().optional(),
|
|
137
137
|
allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts)
|
|
138
|
-
})
|
|
139
|
-
),
|
|
138
|
+
})
|
|
139
|
+
).prefault({}),
|
|
140
140
|
redirects: z.record(
|
|
141
141
|
z.string(),
|
|
142
142
|
z.union([
|
|
@@ -10,10 +10,10 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
10
10
|
name: z.ZodString;
|
|
11
11
|
hooks: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
|
|
12
12
|
}, z.core.$strip>>;
|
|
13
|
-
integrations: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.
|
|
13
|
+
integrations: z.ZodDefault<z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodArray<z.ZodObject<{
|
|
14
14
|
name: z.ZodString;
|
|
15
15
|
hooks: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
|
|
16
|
-
}, z.core.$strip
|
|
16
|
+
}, z.core.$strip>>>>>;
|
|
17
17
|
redirects: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
18
18
|
status: z.ZodUnion<readonly [z.ZodLiteral<300>, z.ZodLiteral<301>, z.ZodLiteral<302>, z.ZodLiteral<303>, z.ZodLiteral<304>, z.ZodLiteral<307>, z.ZodLiteral<308>]>;
|
|
19
19
|
destination: z.ZodString;
|
|
@@ -437,14 +437,13 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
437
437
|
}>>>;
|
|
438
438
|
concurrency: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
439
439
|
}, z.core.$strip>>>;
|
|
440
|
-
server: z.ZodPipe<z.ZodTransform<any, unknown>, z.
|
|
440
|
+
server: z.ZodPrefault<z.ZodPipe<z.ZodTransform<any, unknown>, z.ZodObject<{
|
|
441
441
|
open: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
|
|
442
442
|
host: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
|
|
443
443
|
port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
444
444
|
headers: z.ZodOptional<z.ZodCustom<OutgoingHttpHeaders, OutgoingHttpHeaders>>;
|
|
445
|
-
streaming: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
446
445
|
allowedHosts: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodLiteral<true>]>>>;
|
|
447
|
-
}, z.core.$strip
|
|
446
|
+
}, z.core.$strip>>>;
|
|
448
447
|
}, z.core.$strip>, z.ZodTransform<{
|
|
449
448
|
base: string;
|
|
450
449
|
trailingSlash: "never" | "ignore" | "always";
|
|
@@ -630,7 +629,6 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
630
629
|
open: string | boolean;
|
|
631
630
|
host: string | boolean;
|
|
632
631
|
port: number;
|
|
633
|
-
streaming: boolean;
|
|
634
632
|
allowedHosts: true | string[];
|
|
635
633
|
headers?: OutgoingHttpHeaders | undefined;
|
|
636
634
|
};
|
|
@@ -879,7 +877,6 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
879
877
|
open: string | boolean;
|
|
880
878
|
host: string | boolean;
|
|
881
879
|
port: number;
|
|
882
|
-
streaming: boolean;
|
|
883
880
|
allowedHosts: true | string[];
|
|
884
881
|
headers?: OutgoingHttpHeaders | undefined;
|
|
885
882
|
};
|
|
@@ -59,10 +59,9 @@ function createRelativeSchema(cmd, fileProtocolRoot) {
|
|
|
59
59
|
host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
|
|
60
60
|
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
|
|
61
61
|
headers: z.custom().optional(),
|
|
62
|
-
streaming: z.boolean().optional().default(true),
|
|
63
62
|
allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts)
|
|
64
|
-
})
|
|
65
|
-
)
|
|
63
|
+
})
|
|
64
|
+
).prefault({})
|
|
66
65
|
}).transform((config) => {
|
|
67
66
|
if (config.outDir.toString() !== resolveDirAsUrl(ASTRO_CONFIG_DEFAULTS.outDir, fileProtocolRoot).toString()) {
|
|
68
67
|
const outDirPath = fileURLToPath(config.outDir);
|
|
@@ -149,10 +149,8 @@ async function createSettings(config, logLevel, cwd) {
|
|
|
149
149
|
if (cwd) {
|
|
150
150
|
watchFiles.push(fileURLToPath(new URL("./package.json", pathToFileURL(cwd))));
|
|
151
151
|
}
|
|
152
|
-
if (
|
|
153
|
-
watchFiles.push(
|
|
154
|
-
...[tsconfig.tsconfigFile, ...(tsconfig.extended ?? []).map((e) => e.tsconfigFile)]
|
|
155
|
-
);
|
|
152
|
+
if (!tsconfig.error) {
|
|
153
|
+
watchFiles.push(...tsconfig.sources);
|
|
156
154
|
settings.tsConfig = tsconfig.tsconfig;
|
|
157
155
|
settings.tsConfigPath = tsconfig.tsconfigFile;
|
|
158
156
|
}
|
|
@@ -1,17 +1,32 @@
|
|
|
1
|
-
import { type TSConfckParseResult } from 'tsconfck';
|
|
2
1
|
import type { CompilerOptions, TypeAcquisition } from 'typescript';
|
|
3
2
|
export declare const defaultTSConfig: TSConfig;
|
|
4
3
|
export type frameworkWithTSSettings = 'vue' | 'react' | 'preact' | 'solid-js';
|
|
5
4
|
export declare const presets: Map<frameworkWithTSSettings, TSConfig>;
|
|
6
|
-
|
|
5
|
+
export interface TSConfigLoadedResult {
|
|
6
|
+
error?: undefined;
|
|
7
|
+
/** Absolute path of the root tsconfig/jsconfig file that was loaded. */
|
|
8
|
+
tsconfigFile: string;
|
|
9
|
+
/** The merged/resolved config (after `extends` are walked). */
|
|
10
|
+
tsconfig: TSConfig;
|
|
11
|
+
/** The user-written, un-merged config. Used by `astro add` to round-trip. */
|
|
12
|
+
rawConfig: TSConfig;
|
|
13
|
+
/**
|
|
14
|
+
* Every tsconfig file that contributed via `extends`, root-first.
|
|
15
|
+
* Includes `tsconfigFile`. Used to populate the dev-server watch list.
|
|
16
|
+
*/
|
|
17
|
+
sources: string[];
|
|
18
|
+
}
|
|
19
|
+
export type TSConfigResult = TSConfigLoadedResult | {
|
|
20
|
+
error: 'invalid-config';
|
|
21
|
+
message: string;
|
|
22
|
+
} | {
|
|
23
|
+
error: 'missing-config';
|
|
24
|
+
};
|
|
7
25
|
/**
|
|
8
|
-
* Load a tsconfig.json or jsconfig.json
|
|
9
|
-
* @param root The
|
|
10
|
-
* @param findUp Whether to search for the config file in parent directories, by default only the root directory is searched.
|
|
26
|
+
* Load a tsconfig.json or jsconfig.json if the former is not found.
|
|
27
|
+
* @param root The directory to search in, defaults to `process.cwd()`.
|
|
11
28
|
*/
|
|
12
|
-
export declare function loadTSConfig(root: string | undefined
|
|
13
|
-
rawConfig: TSConfig;
|
|
14
|
-
}>>;
|
|
29
|
+
export declare function loadTSConfig(root: string | undefined): Promise<TSConfigResult>;
|
|
15
30
|
export declare function updateTSConfigForFramework(target: TSConfig, framework: frameworkWithTSSettings): TSConfig;
|
|
16
31
|
type StripEnums<T extends Record<string, any>> = {
|
|
17
32
|
[K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array<any> ? T[K] : T[K] extends undefined ? undefined : any;
|
|
@@ -19,7 +34,7 @@ type StripEnums<T extends Record<string, any>> = {
|
|
|
19
34
|
export interface TSConfig {
|
|
20
35
|
compilerOptions?: StripEnums<CompilerOptions>;
|
|
21
36
|
compileOnSave?: boolean;
|
|
22
|
-
extends?: string;
|
|
37
|
+
extends?: string | string[];
|
|
23
38
|
files?: string[];
|
|
24
39
|
include?: string[];
|
|
25
40
|
exclude?: string[];
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
parse,
|
|
6
|
-
TSConfckParseError,
|
|
7
|
-
toJson
|
|
8
|
-
} from "tsconfck";
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join, normalize } from "node:path";
|
|
3
|
+
import { readTsconfig } from "get-tsconfig";
|
|
4
|
+
import { parse as parseJsonc } from "jsonc-parser";
|
|
9
5
|
const defaultTSConfig = { extends: "astro/tsconfigs/base" };
|
|
10
6
|
const presets = /* @__PURE__ */ new Map([
|
|
11
7
|
[
|
|
@@ -48,50 +44,63 @@ const presets = /* @__PURE__ */ new Map([
|
|
|
48
44
|
}
|
|
49
45
|
]
|
|
50
46
|
]);
|
|
51
|
-
async function loadTSConfig(root
|
|
52
|
-
const safeCwd = root
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
configName
|
|
60
|
-
})
|
|
61
|
-
)
|
|
62
|
-
)
|
|
63
|
-
);
|
|
64
|
-
if (tsconfig) {
|
|
65
|
-
const parsedConfig = await safeParse(tsconfig, { root });
|
|
66
|
-
if (typeof parsedConfig === "string") {
|
|
67
|
-
return parsedConfig;
|
|
47
|
+
async function loadTSConfig(root) {
|
|
48
|
+
const safeCwd = root || process.cwd();
|
|
49
|
+
let tsconfigPath;
|
|
50
|
+
for (const configName of ["tsconfig.json", "jsconfig.json"]) {
|
|
51
|
+
const possiblePath = join(safeCwd, configName);
|
|
52
|
+
if (existsSync(possiblePath)) {
|
|
53
|
+
tsconfigPath = possiblePath;
|
|
54
|
+
break;
|
|
68
55
|
}
|
|
69
|
-
const rawConfig = await readFile(tsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
|
|
70
|
-
return { ...parsedConfig, rawConfig };
|
|
71
56
|
}
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
const rawConfig = await readFile(jsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
|
|
78
|
-
return { ...parsedConfig, rawConfig };
|
|
57
|
+
if (!tsconfigPath) {
|
|
58
|
+
return {
|
|
59
|
+
error: "missing-config"
|
|
60
|
+
};
|
|
79
61
|
}
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
async function safeParse(tsconfigPath, options = {}) {
|
|
62
|
+
let rawConfig;
|
|
83
63
|
try {
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
64
|
+
const text = readFileSync(tsconfigPath, "utf-8");
|
|
65
|
+
const errors = [];
|
|
66
|
+
const parsed = parseJsonc(text, errors, { allowTrailingComma: true });
|
|
67
|
+
if (errors.length > 0) {
|
|
68
|
+
const first = errors[0];
|
|
69
|
+
return {
|
|
70
|
+
error: "invalid-config",
|
|
71
|
+
message: `Failed to parse ${tsconfigPath}: Malformed JSONC (error code ${first.error}) at offset ${first.offset}`
|
|
72
|
+
};
|
|
87
73
|
}
|
|
88
|
-
|
|
74
|
+
rawConfig = parsed;
|
|
89
75
|
} catch (e) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
77
|
+
return {
|
|
78
|
+
error: "invalid-config",
|
|
79
|
+
message: `Failed to parse ${tsconfigPath}: ${message}`
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (!rawConfig) {
|
|
83
|
+
return {
|
|
84
|
+
error: "invalid-config",
|
|
85
|
+
message: `Failed to parse ${tsconfigPath}: Unknown error`
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
let resolved;
|
|
89
|
+
try {
|
|
90
|
+
resolved = readTsconfig(tsconfigPath);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
93
|
+
return {
|
|
94
|
+
error: "invalid-config",
|
|
95
|
+
message: `Failed to resolve ${tsconfigPath}: ${message}`
|
|
96
|
+
};
|
|
94
97
|
}
|
|
98
|
+
return {
|
|
99
|
+
tsconfigFile: normalize(resolved.path),
|
|
100
|
+
tsconfig: resolved.config,
|
|
101
|
+
rawConfig,
|
|
102
|
+
sources: (resolved.sources || [resolved.path]).map(normalize)
|
|
103
|
+
};
|
|
95
104
|
}
|
|
96
105
|
function updateTSConfigForFramework(target, framework) {
|
|
97
106
|
if (!presets.has(framework)) {
|
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.2.
|
|
40
|
+
const currentVersion = "6.2.2";
|
|
41
41
|
const isPrerelease = currentVersion.includes("-");
|
|
42
42
|
if (!isPrerelease) {
|
|
43
43
|
try {
|
|
@@ -24,6 +24,17 @@ const errorMap = (issue) => {
|
|
|
24
24
|
`> ${getTypeOrLiteralMsg(error)}`
|
|
25
25
|
) : `> ${prefix(key, getTypeOrLiteralMsg(error))}`
|
|
26
26
|
);
|
|
27
|
+
if (details.length === 0) {
|
|
28
|
+
if ("discriminator" in issue && issue.discriminator && "options" in issue) {
|
|
29
|
+
const options = issue.options;
|
|
30
|
+
if (Array.isArray(options)) {
|
|
31
|
+
details.push(
|
|
32
|
+
`> Expected \`${issue.discriminator}\` to be ${options.map((o) => `\`${stringify(o)}\``).join(" | ")}`
|
|
33
|
+
);
|
|
34
|
+
details.push("> Received `" + stringify(issue.input) + "`");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
27
38
|
if (details.length === 0) {
|
|
28
39
|
const expectedShapes = [];
|
|
29
40
|
for (const unionErrors of issue.errors) {
|
|
@@ -59,6 +70,22 @@ const errorMap = (issue) => {
|
|
|
59
70
|
return {
|
|
60
71
|
message: messages.concat(details).join("\n")
|
|
61
72
|
};
|
|
73
|
+
} else if (issue.code === "invalid_key") {
|
|
74
|
+
const keyIssues = issue.issues;
|
|
75
|
+
if (Array.isArray(keyIssues) && keyIssues.length > 0) {
|
|
76
|
+
const firstIssue = keyIssues[0];
|
|
77
|
+
const msg = firstIssue.message || "Invalid key in record";
|
|
78
|
+
return { message: prefix(baseErrorPath, msg) };
|
|
79
|
+
}
|
|
80
|
+
return { message: prefix(baseErrorPath, "Invalid key in record") };
|
|
81
|
+
} else if (issue.code === "invalid_element") {
|
|
82
|
+
const elementIssues = issue.issues;
|
|
83
|
+
if (Array.isArray(elementIssues) && elementIssues.length > 0) {
|
|
84
|
+
const firstIssue = elementIssues[0];
|
|
85
|
+
const msg = firstIssue.message || "Invalid element";
|
|
86
|
+
return { message: prefix(baseErrorPath, msg) };
|
|
87
|
+
}
|
|
88
|
+
return { message: prefix(baseErrorPath, "Invalid element") };
|
|
62
89
|
} else if (issue.code === "invalid_type") {
|
|
63
90
|
return {
|
|
64
91
|
message: prefix(
|
|
@@ -44,7 +44,7 @@ async function getProps(opts) {
|
|
|
44
44
|
}
|
|
45
45
|
function getParams(route, pathname) {
|
|
46
46
|
if (!route.params.length) return {};
|
|
47
|
-
const path = pathname.endsWith(".html") && !routeHasHtmlExtension(route) ? pathname.slice(0, -5) : pathname;
|
|
47
|
+
const path = pathname.endsWith(".html") && route.type === "page" && !routeHasHtmlExtension(route) ? pathname.slice(0, -5) : pathname;
|
|
48
48
|
const allPatterns = [route, ...route.fallbackRoutes].map((r) => r.pattern);
|
|
49
49
|
const paramsMatch = allPatterns.map((pattern) => pattern.exec(path)).find((x) => x);
|
|
50
50
|
if (!paramsMatch) return {};
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { renderSlotToString } from "../../runtime/server/index.js";
|
|
2
2
|
import { renderJSX } from "../../runtime/server/jsx.js";
|
|
3
|
+
import { isRenderTemplateResult } from "../../runtime/server/render/astro/index.js";
|
|
3
4
|
import { chunkToString } from "../../runtime/server/render/index.js";
|
|
4
5
|
import { isRenderInstruction } from "../../runtime/server/render/instruction.js";
|
|
5
6
|
import { AstroError, AstroErrorData } from "../errors/index.js";
|
|
6
7
|
function getFunctionExpression(slot) {
|
|
7
8
|
if (!slot) return;
|
|
8
|
-
const expressions = slot?.expressions?.filter(
|
|
9
|
+
const expressions = slot?.expressions?.filter(
|
|
10
|
+
(e) => isRenderInstruction(e) === false || isRenderTemplateResult(e)
|
|
11
|
+
);
|
|
9
12
|
if (expressions?.length !== 1) return;
|
|
10
|
-
|
|
13
|
+
const expression = expressions[0];
|
|
14
|
+
if (isRenderTemplateResult(expression)) {
|
|
15
|
+
return getFunctionExpression(expression);
|
|
16
|
+
}
|
|
17
|
+
return expression;
|
|
11
18
|
}
|
|
12
19
|
class Slots {
|
|
13
20
|
#result;
|
|
@@ -16,7 +16,7 @@ function getPattern(segments, base, addTrailingSlash) {
|
|
|
16
16
|
}).join("");
|
|
17
17
|
const trailing = addTrailingSlash && segments.length ? getTrailingSlashPattern(addTrailingSlash) : "$";
|
|
18
18
|
let initial = "\\/";
|
|
19
|
-
if (addTrailingSlash === "never" && base !== "/") {
|
|
19
|
+
if (addTrailingSlash === "never" && base !== "/" && pathname !== "") {
|
|
20
20
|
initial = "";
|
|
21
21
|
}
|
|
22
22
|
return new RegExp(`^${pathname || initial}${trailing}`);
|
|
@@ -134,7 +134,7 @@ function normalizeRewritePathname(urlPathname, base, trailingSlash, buildFormat)
|
|
|
134
134
|
if (base !== "/") {
|
|
135
135
|
const isBasePathRequest = urlPathname === base || urlPathname === removeTrailingForwardSlash(base);
|
|
136
136
|
if (isBasePathRequest) {
|
|
137
|
-
pathname =
|
|
137
|
+
pathname = "/";
|
|
138
138
|
} else if (urlPathname.startsWith(base)) {
|
|
139
139
|
pathname = shouldAppendSlash ? appendForwardSlash(urlPathname) : removeTrailingForwardSlash(urlPathname);
|
|
140
140
|
pathname = pathname.slice(base.length);
|
|
@@ -143,9 +143,6 @@ function normalizeRewritePathname(urlPathname, base, trailingSlash, buildFormat)
|
|
|
143
143
|
if (!pathname.startsWith("/") && shouldAppendSlash && urlPathname.endsWith("/")) {
|
|
144
144
|
pathname = prependForwardSlash(pathname);
|
|
145
145
|
}
|
|
146
|
-
if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
|
|
147
|
-
pathname = "";
|
|
148
|
-
}
|
|
149
146
|
if (buildFormat === "file") {
|
|
150
147
|
pathname = pathname.replace(/\.html$/, "");
|
|
151
148
|
}
|
|
@@ -121,7 +121,8 @@ class AstroSession {
|
|
|
121
121
|
* Deletes a session value.
|
|
122
122
|
*/
|
|
123
123
|
delete(key) {
|
|
124
|
-
this.#data
|
|
124
|
+
this.#data ??= /* @__PURE__ */ new Map();
|
|
125
|
+
this.#data.delete(key);
|
|
125
126
|
if (this.#partial) {
|
|
126
127
|
this.#toDelete.add(key);
|
|
127
128
|
}
|
|
@@ -272,11 +273,15 @@ class AstroSession {
|
|
|
272
273
|
* If there is existing partial data, it will be merged into the new data object.
|
|
273
274
|
*/
|
|
274
275
|
async #ensureData() {
|
|
275
|
-
const storage = await this.#ensureStorage();
|
|
276
276
|
if (this.#data && !this.#partial) {
|
|
277
277
|
return this.#data;
|
|
278
278
|
}
|
|
279
279
|
this.#data ??= /* @__PURE__ */ new Map();
|
|
280
|
+
if (!this.#sessionID && !this.#cookies.get(this.#cookieName)?.value) {
|
|
281
|
+
this.#partial = false;
|
|
282
|
+
return this.#data;
|
|
283
|
+
}
|
|
284
|
+
const storage = await this.#ensureStorage();
|
|
280
285
|
const raw = await storage.get(this.#ensureSessionID());
|
|
281
286
|
if (!raw) {
|
|
282
287
|
if (this.#sessionIDFromCookie) {
|
package/dist/i18n/middleware.js
CHANGED
|
@@ -71,7 +71,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, format) {
|
|
|
71
71
|
if (i18n.fallback && i18n.fallbackType) {
|
|
72
72
|
const fallbackDecision = computeFallbackRoute({
|
|
73
73
|
pathname: context.url.pathname,
|
|
74
|
-
responseStatus: response.status,
|
|
74
|
+
responseStatus: typeHeader === "fallback" ? 404 : response.status,
|
|
75
75
|
currentLocale: context.currentLocale,
|
|
76
76
|
fallback: i18n.fallback,
|
|
77
77
|
fallbackType: i18n.fallbackType,
|
package/dist/prefetch/index.js
CHANGED
|
@@ -24,8 +24,9 @@ function initTapStrategy() {
|
|
|
24
24
|
document.addEventListener(
|
|
25
25
|
event,
|
|
26
26
|
(e) => {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const anchor = e.target.closest("a");
|
|
28
|
+
if (elMatchesStrategy(anchor, "tap")) {
|
|
29
|
+
prefetch(anchor.href, { ignoreSlowConnection: true });
|
|
29
30
|
}
|
|
30
31
|
},
|
|
31
32
|
{ passive: true }
|
|
@@ -37,8 +38,9 @@ function initHoverStrategy() {
|
|
|
37
38
|
document.body.addEventListener(
|
|
38
39
|
"focusin",
|
|
39
40
|
(e) => {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
const anchor = e.target.closest("a");
|
|
42
|
+
if (elMatchesStrategy(anchor, "hover")) {
|
|
43
|
+
handleHoverIn(anchor.href);
|
|
42
44
|
}
|
|
43
45
|
},
|
|
44
46
|
{ passive: true }
|
|
@@ -49,13 +51,16 @@ function initHoverStrategy() {
|
|
|
49
51
|
if (listenedAnchors.has(anchor)) continue;
|
|
50
52
|
if (elMatchesStrategy(anchor, "hover")) {
|
|
51
53
|
listenedAnchors.add(anchor);
|
|
52
|
-
anchor.addEventListener(
|
|
54
|
+
anchor.addEventListener(
|
|
55
|
+
"mouseenter",
|
|
56
|
+
(e) => handleHoverIn(e.currentTarget.href),
|
|
57
|
+
{ passive: true }
|
|
58
|
+
);
|
|
53
59
|
anchor.addEventListener("mouseleave", handleHoverOut, { passive: true });
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
});
|
|
57
|
-
function handleHoverIn(
|
|
58
|
-
const href = e.target.href;
|
|
63
|
+
function handleHoverIn(href) {
|
|
59
64
|
if (timeout) {
|
|
60
65
|
clearTimeout(timeout);
|
|
61
66
|
}
|
|
@@ -19,13 +19,13 @@ function stringifyChunk(result, chunk) {
|
|
|
19
19
|
switch (instruction.type) {
|
|
20
20
|
case "directive": {
|
|
21
21
|
const { hydration } = instruction;
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const needsHydrationScript = hydration && determineIfNeedsHydrationScript(result);
|
|
23
|
+
const needsDirectiveScript = hydration && determinesIfNeedsDirectiveScript(result, hydration.directive);
|
|
24
24
|
if (needsHydrationScript) {
|
|
25
|
-
|
|
25
|
+
const prescripts = getPrescripts(result, "both", hydration.directive);
|
|
26
26
|
return markHTMLString(prescripts);
|
|
27
27
|
} else if (needsDirectiveScript) {
|
|
28
|
-
|
|
28
|
+
const prescripts = getPrescripts(result, "directive", hydration.directive);
|
|
29
29
|
return markHTMLString(prescripts);
|
|
30
30
|
} else {
|
|
31
31
|
return "";
|
|
@@ -46,6 +46,9 @@ function stringifyChunk(result, chunk) {
|
|
|
46
46
|
case "renderer-hydration-script": {
|
|
47
47
|
const { rendererSpecificHydrationScripts } = result._metadata;
|
|
48
48
|
const { rendererName } = instruction;
|
|
49
|
+
if (result._metadata.templateDepth > 0) {
|
|
50
|
+
return instruction.render();
|
|
51
|
+
}
|
|
49
52
|
if (!rendererSpecificHydrationScripts.has(rendererName)) {
|
|
50
53
|
rendererSpecificHydrationScripts.add(rendererName);
|
|
51
54
|
return instruction.render();
|
|
@@ -53,6 +56,9 @@ function stringifyChunk(result, chunk) {
|
|
|
53
56
|
return "";
|
|
54
57
|
}
|
|
55
58
|
case "server-island-runtime": {
|
|
59
|
+
if (result._metadata.templateDepth > 0) {
|
|
60
|
+
return renderServerIslandRuntime();
|
|
61
|
+
}
|
|
56
62
|
if (result._metadata.hasRenderedServerIslandRuntime) {
|
|
57
63
|
return "";
|
|
58
64
|
}
|
|
@@ -2,12 +2,18 @@ import islandScript from "./astro-island.prebuilt.js";
|
|
|
2
2
|
import islandScriptDev from "./astro-island.prebuilt-dev.js";
|
|
3
3
|
import { ISLAND_STYLES } from "./astro-island-styles.js";
|
|
4
4
|
function determineIfNeedsHydrationScript(result) {
|
|
5
|
+
if (result._metadata.templateDepth > 0) {
|
|
6
|
+
return !result._metadata.hasHydrationScript;
|
|
7
|
+
}
|
|
5
8
|
if (result._metadata.hasHydrationScript) {
|
|
6
9
|
return false;
|
|
7
10
|
}
|
|
8
11
|
return result._metadata.hasHydrationScript = true;
|
|
9
12
|
}
|
|
10
13
|
function determinesIfNeedsDirectiveScript(result, directive) {
|
|
14
|
+
if (result._metadata.templateDepth > 0) {
|
|
15
|
+
return !result._metadata.hasDirectives.has(directive);
|
|
16
|
+
}
|
|
11
17
|
if (result._metadata.hasDirectives.has(directive)) {
|
|
12
18
|
return false;
|
|
13
19
|
}
|
|
@@ -142,7 +142,7 @@ export interface CacheHint {
|
|
|
142
142
|
/** Last modified time of the content */
|
|
143
143
|
lastModified?: Date;
|
|
144
144
|
}
|
|
145
|
-
export interface LiveDataEntry<TData extends Record<string, any> = Record<string,
|
|
145
|
+
export interface LiveDataEntry<TData extends Record<string, any> = Record<string, any>> {
|
|
146
146
|
/** The ID of the entry. Unique per collection. */
|
|
147
147
|
id: string;
|
|
148
148
|
/** The parsed entry data */
|
|
@@ -154,17 +154,17 @@ export interface LiveDataEntry<TData extends Record<string, any> = Record<string
|
|
|
154
154
|
/** A hint for how to cache this entry */
|
|
155
155
|
cacheHint?: CacheHint;
|
|
156
156
|
}
|
|
157
|
-
export interface LiveDataCollection<TData extends Record<string, any> = Record<string,
|
|
157
|
+
export interface LiveDataCollection<TData extends Record<string, any> = Record<string, any>> {
|
|
158
158
|
entries: Array<LiveDataEntry<TData>>;
|
|
159
159
|
/** A hint for how to cache this collection. Individual entries can also have cache hints */
|
|
160
160
|
cacheHint?: CacheHint;
|
|
161
161
|
}
|
|
162
|
-
export interface LiveDataCollectionResult<TData extends Record<string, any> = Record<string,
|
|
162
|
+
export interface LiveDataCollectionResult<TData extends Record<string, any> = Record<string, any>, TError extends Error = Error> {
|
|
163
163
|
entries?: Array<LiveDataEntry<TData>>;
|
|
164
164
|
error?: TError | LiveCollectionError;
|
|
165
165
|
cacheHint?: CacheHint;
|
|
166
166
|
}
|
|
167
|
-
export interface LiveDataEntryResult<TData extends Record<string, any> = Record<string,
|
|
167
|
+
export interface LiveDataEntryResult<TData extends Record<string, any> = Record<string, any>, TError extends Error = Error> {
|
|
168
168
|
entry?: LiveDataEntry<TData>;
|
|
169
169
|
error?: TError | LiveCollectionError;
|
|
170
170
|
cacheHint?: CacheHint;
|
|
@@ -108,9 +108,6 @@ class AstroServerApp extends BaseApp {
|
|
|
108
108
|
} else {
|
|
109
109
|
pathname = decodeURI(url.pathname);
|
|
110
110
|
}
|
|
111
|
-
if (this.manifest.trailingSlash === "never" && pathname === "/" && this.manifest.base !== "/") {
|
|
112
|
-
pathname = "";
|
|
113
|
-
}
|
|
114
111
|
url.pathname = removeTrailingForwardSlash(this.manifest.base) + url.pathname;
|
|
115
112
|
if (url.pathname.endsWith("/") && !shouldAppendForwardSlash(this.manifest.trailingSlash, this.manifest.buildFormat)) {
|
|
116
113
|
url.pathname = url.pathname.slice(0, -1);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { transformWithEsbuild } from "vite";
|
|
2
2
|
import { compile } from "../core/compile/index.js";
|
|
3
3
|
import { getFileInfo } from "../vite-plugin-utils/index.js";
|
|
4
|
-
import { frontmatterRE } from "./utils.js";
|
|
4
|
+
import { frontmatterRE, replaceTopLevelReturns } from "./utils.js";
|
|
5
5
|
async function compileAstro({
|
|
6
6
|
compileProps,
|
|
7
7
|
astroFileToCompileMetadata,
|
|
@@ -70,7 +70,7 @@ async function enhanceCompileError({
|
|
|
70
70
|
const lineText = err.loc?.lineText;
|
|
71
71
|
const scannedFrontmatter = frontmatterRE.exec(source);
|
|
72
72
|
if (scannedFrontmatter) {
|
|
73
|
-
const frontmatter = scannedFrontmatter[1]
|
|
73
|
+
const frontmatter = replaceTopLevelReturns(scannedFrontmatter[1]);
|
|
74
74
|
if (lineText && !frontmatter.includes(lineText)) throw err;
|
|
75
75
|
try {
|
|
76
76
|
await transformWithEsbuild(frontmatter, id, {
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
const frontmatterRE = /^---(.*?)^---/ms;
|
|
3
|
+
const RETURN_REPLACE_RE = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')|(?<!\.)\breturn(\s*;|\b)/g;
|
|
4
|
+
function replaceTopLevelReturns(code) {
|
|
5
|
+
return code.replace(RETURN_REPLACE_RE, (_match, skip, tail) => {
|
|
6
|
+
if (skip !== void 0) return skip;
|
|
7
|
+
return tail.trim() === ";" ? "throw 0;" : "throw ";
|
|
8
|
+
});
|
|
9
|
+
}
|
|
3
10
|
async function loadId(pluginContainer, id) {
|
|
4
11
|
const result = await pluginContainer.load(id, { ssr: true });
|
|
5
12
|
if (result) {
|
|
@@ -16,5 +23,6 @@ async function loadId(pluginContainer, id) {
|
|
|
16
23
|
}
|
|
17
24
|
export {
|
|
18
25
|
frontmatterRE,
|
|
19
|
-
loadId
|
|
26
|
+
loadId,
|
|
27
|
+
replaceTopLevelReturns
|
|
20
28
|
};
|
|
@@ -9,11 +9,20 @@ import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
|
|
|
9
9
|
const VIRTUAL_COMPONENT_METADATA = "virtual:astro:component-metadata";
|
|
10
10
|
const RESOLVED_VIRTUAL_COMPONENT_METADATA = `\0${VIRTUAL_COMPONENT_METADATA}`;
|
|
11
11
|
function configHeadVitePlugin() {
|
|
12
|
-
let
|
|
12
|
+
let environments = [];
|
|
13
|
+
function findModule(id) {
|
|
14
|
+
for (const env of environments) {
|
|
15
|
+
const mod = env.moduleGraph.getModuleById(id);
|
|
16
|
+
if (mod) return mod;
|
|
17
|
+
}
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
13
20
|
function invalidateComponentMetadataModule() {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
for (const env of environments) {
|
|
22
|
+
const virtualMod = env.moduleGraph.getModuleById(RESOLVED_VIRTUAL_COMPONENT_METADATA);
|
|
23
|
+
if (virtualMod) {
|
|
24
|
+
env.moduleGraph.invalidateModule(virtualMod);
|
|
25
|
+
}
|
|
17
26
|
}
|
|
18
27
|
}
|
|
19
28
|
function buildImporterGraphFromEnvironment(seed) {
|
|
@@ -23,7 +32,7 @@ function configHeadVitePlugin() {
|
|
|
23
32
|
const current = queue.pop();
|
|
24
33
|
if (collected.has(current)) continue;
|
|
25
34
|
collected.add(current);
|
|
26
|
-
const mod =
|
|
35
|
+
const mod = findModule(current);
|
|
27
36
|
for (const importer of mod?.importers ?? []) {
|
|
28
37
|
if (importer.id) {
|
|
29
38
|
queue.push(importer.id);
|
|
@@ -31,7 +40,7 @@ function configHeadVitePlugin() {
|
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
return buildImporterGraphFromModuleInfo(collected, (id) => {
|
|
34
|
-
const mod =
|
|
43
|
+
const mod = findModule(id);
|
|
35
44
|
if (!mod) return null;
|
|
36
45
|
return {
|
|
37
46
|
importers: Array.from(mod.importers).map((importer) => importer.id).filter((moduleId) => !!moduleId),
|
|
@@ -61,7 +70,10 @@ function configHeadVitePlugin() {
|
|
|
61
70
|
enforce: "pre",
|
|
62
71
|
apply: "serve",
|
|
63
72
|
configureServer(devServer) {
|
|
64
|
-
|
|
73
|
+
environments = [
|
|
74
|
+
devServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr],
|
|
75
|
+
devServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.prerender]
|
|
76
|
+
].filter((e) => !!e);
|
|
65
77
|
devServer.watcher.on("add", invalidateComponentMetadataModule);
|
|
66
78
|
devServer.watcher.on("unlink", invalidateComponentMetadataModule);
|
|
67
79
|
devServer.watcher.on("change", invalidateComponentMetadataModule);
|
|
@@ -70,19 +82,24 @@ function configHeadVitePlugin() {
|
|
|
70
82
|
if (id !== RESOLVED_VIRTUAL_COMPONENT_METADATA) {
|
|
71
83
|
return;
|
|
72
84
|
}
|
|
85
|
+
const seen = /* @__PURE__ */ new Set();
|
|
73
86
|
const componentMetadataEntries = [];
|
|
74
|
-
for (const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
for (const env of environments) {
|
|
88
|
+
for (const [moduleId, mod] of env.moduleGraph.idToModuleMap) {
|
|
89
|
+
if (seen.has(moduleId)) continue;
|
|
90
|
+
const info = this.getModuleInfo(moduleId) ?? (mod.id ? this.getModuleInfo(mod.id) : null);
|
|
91
|
+
if (!info) continue;
|
|
92
|
+
const astro = getAstroMetadata(info);
|
|
93
|
+
if (!astro) continue;
|
|
94
|
+
seen.add(moduleId);
|
|
95
|
+
componentMetadataEntries.push([
|
|
96
|
+
moduleId,
|
|
97
|
+
{
|
|
98
|
+
containsHead: astro.containsHead,
|
|
99
|
+
propagation: astro.propagation
|
|
100
|
+
}
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
86
103
|
}
|
|
87
104
|
return {
|
|
88
105
|
code: `export const componentMetadataEntries = ${JSON.stringify(componentMetadataEntries)};`
|
|
@@ -23,6 +23,9 @@ function getFileInfo(id, config) {
|
|
|
23
23
|
function normalizeFilename(filename, root) {
|
|
24
24
|
if (filename.startsWith("/@fs")) {
|
|
25
25
|
filename = filename.slice("/@fs".length);
|
|
26
|
+
} else if (filename.startsWith(".")) {
|
|
27
|
+
const url = new URL(filename, root);
|
|
28
|
+
filename = viteID(url);
|
|
26
29
|
} else if (filename.startsWith("/") && !commonAncestorPath(filename, fileURLToPath(root))) {
|
|
27
30
|
const url = new URL("." + filename, root);
|
|
28
31
|
filename = viteID(url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.2",
|
|
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",
|
|
@@ -124,10 +124,12 @@
|
|
|
124
124
|
"esbuild": "^0.27.3",
|
|
125
125
|
"flattie": "^1.1.1",
|
|
126
126
|
"fontace": "~0.4.1",
|
|
127
|
+
"get-tsconfig": "5.0.0-beta.4",
|
|
127
128
|
"github-slugger": "^2.0.0",
|
|
128
129
|
"html-escaper": "3.0.3",
|
|
129
130
|
"http-cache-semantics": "^4.2.0",
|
|
130
131
|
"js-yaml": "^4.1.1",
|
|
132
|
+
"jsonc-parser": "^3.3.1",
|
|
131
133
|
"magic-string": "^0.30.21",
|
|
132
134
|
"magicast": "^0.5.2",
|
|
133
135
|
"mrmime": "^2.0.1",
|
|
@@ -146,7 +148,6 @@
|
|
|
146
148
|
"tinyclip": "^0.1.12",
|
|
147
149
|
"tinyexec": "^1.0.4",
|
|
148
150
|
"tinyglobby": "^0.2.15",
|
|
149
|
-
"tsconfck": "^3.1.6",
|
|
150
151
|
"ultrahtml": "^1.6.0",
|
|
151
152
|
"unifont": "~0.7.4",
|
|
152
153
|
"unist-util-visit": "^5.1.0",
|
|
@@ -158,8 +159,8 @@
|
|
|
158
159
|
"yargs-parser": "^22.0.0",
|
|
159
160
|
"zod": "^4.3.6",
|
|
160
161
|
"@astrojs/internal-helpers": "0.9.0",
|
|
161
|
-
"@astrojs/
|
|
162
|
-
"@astrojs/
|
|
162
|
+
"@astrojs/markdown-remark": "7.1.1",
|
|
163
|
+
"@astrojs/telemetry": "3.3.1"
|
|
163
164
|
},
|
|
164
165
|
"optionalDependencies": {
|
|
165
166
|
"sharp": "^0.34.0"
|
|
@@ -194,8 +195,8 @@
|
|
|
194
195
|
"undici": "^7.22.0",
|
|
195
196
|
"unified": "^11.0.5",
|
|
196
197
|
"vitest": "^4.1.0",
|
|
197
|
-
"
|
|
198
|
-
"
|
|
198
|
+
"@astrojs/check": "0.9.9",
|
|
199
|
+
"astro-scripts": "0.0.14"
|
|
199
200
|
},
|
|
200
201
|
"engines": {
|
|
201
202
|
"node": ">=22.12.0",
|